gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnurl] branch master updated (55ddc6582 -> 7179f6d6c)


From: gnunet
Subject: [gnurl] branch master updated (55ddc6582 -> 7179f6d6c)
Date: Thu, 30 Apr 2020 16:05:03 +0200

This is an automated email from the git hooks/post-receive script.

nikita pushed a change to branch master
in repository gnurl.

    from 55ddc6582 script: fix path
     new f0f3952f5 configure: document 'compiler_num' for gcc
     new 77b62fe6e configure: fix -pedantic-errors for GCC 5 and later
     new 27ea8fc2f configure: convert -I to -isystem as a last step
     new 0cc66ff5a Makefile: run the cd commands in a subshell
     new c0fe3b326 tests/data: Fix some XML formatting issues in test cases
     new 467426963 RELEASE-NOTES: synced
     new d5c01d779 smbserver: fix Python version specific ConfigParser import
     new af07875c0 cleanup: fix some text/comment typos
     new ba0e6fbd3 smbserver: pin Python version to 2 since we are not yet 3 
compatible
     new a7e24c736 impacket: some more Python 3 code compatibility updates
     new fe8ba5120 server/getpart: make the "XML-parser" stricter
     new 0845ecbb6 docs: add warnings about FILE: URLs on Windows
     new 3bfda0700 easy: Fix curl_easy_duphandle for builds missing IPv6 that 
use c-ares
     new 67f3f6cff Makefile.m32: Improve windres parameter compatibility
     new 4be2560e0 tests: remove python_dependencies for smbserver from our tree
     new ac5668343 ci/tests: install test suite dependencies stunnel and 
impacket
     new dc595210a ci/tests: fix and align setting TFLAGS for make test-nonflaky
     new dbd16c3e2 connect: happy eyeballs cleanup
     new c52b34205 select: move duplicate select preparation code into 
Curl_select
     new 041e778f1 select: fix 'pending_ms' is assigned a value that is never 
used
     new 696cfc0f6 select: add 'timeout_ms' wrap-around precaution to 
Curl_select
     new 51fde3374 TODO: TLS-PSK with OpenSSL
     new f38c7290b transfer: cap retries of "dead connections" to 5
     new 92f129cd9 tests/README: add note about manually installing 
python-impacket
     new 49fbe0190 ci/tests: install impacket for SMB tests on FreeBSD using 
CirrusCI
     new dda8babd0 tests: fix verification of stdout in test 1452 due to newline
     new 083603c63 gskit: use our internal select wrapper for portability
     new 92c152c2e gskit: update the copyright year range
     new 404d5f200 ci/tests: fix Azure Pipelines not running for pull requests
     new 2eba5e4c7 vtls: free ssl_config leftovers on out-of-memory
     new 95c36fff7 tool_operate: fix add_parallel_transfers when more are in 
queue
     new 37a054188 cmake: add support for building with wolfSSL
     new 45008cb48 ci/tests: increase timeouts for torture builds on Azure 
Pipelines
     new 8a2b36df5 DISABLED: disable test 323
     new d83402813 CI: stop ignoring 323, it is disabled
     new 04c03416e writeout: support to generate JSON output
     new 7631f2b75 test 970: verify --write-out '%{json}'
     new ab9dc5ae2 writeout_json: add missing comma to fix the HTTP version
     new 728406136 windows: suppress UI in all CryptAcquireContext() calls
     new a268ad5d7 multi: Improve parameter check for curl_multi_remove_handle
     new 545042849 schannel: add "best effort" revocation check option
     new 0ae463ffd tool_setopt: correct the copyright year range
     new 347a374c5 http2: Fix erroneous debug message that h2 connection closed
     new 1a46b218d RELEASE-NOTES: synced
     new daf1eee11 RELEASE-NOTES: synced
     new 8d9802b0a writeout_json: use curl_off_t printf() option for the time 
output
     new 3c9066fce tests: make Python-based servers compatible with Python 2 
and 3
     new aec0b49df openssl: remove the BACKEND define kludge
     new 89865c149 gnutls: remove the BACKEND define kludge
     new 259d62c7c nss: remove the BACKEND define kludge
     new 5076b8668 wolfssl: remove the BACKEND define kludge
     new 52182e4b8 bearssl: remove the BACKEND define kludge
     new 2efc3a424 mbedtls: remove the BACKEND define kludge
     new cb2f57c0c secure transport: remove the BACKEND define kludge
     new 9c2aaf3d3 test970: fix static ip:port instead of dynamic values being 
used
     new 3d77d089a test2100: fix static port instead of dynamic value being used
     new 4e0b4fee4 cmdline: fix handling of OperationConfig linked list (--next)
     new ab18027d6 tests: add test 430, 431 and 432 to verify the --config fix
     new 9b4990f06 ci/tests: fix Azure Pipelines not running Windows containers
     new f25f602ff curl-functions.m4: remove inappropriate AC_REQUIRE
     new d820224b8 curl_setup: define _WIN32_WINNT_[OS] symbols
     new 21b3893a1 lib/curl_setup: adjust the copyright year range
     new 4b355dd13 TODO: Use "random" ports for the test servers
     new 485266142 CURLINFO_NUM_CONNECTS: improve accuracy
     new 9a7e62e7c test970: improve the test
     new c448c4840 getinfo: provide CURLINFO_HEADER_SIZE and 
CURLINFO_REQUEST_SIZE override
     new 12585bf9a Revert "cirrus-ci: disable the FreeBSD 13 builds"
     new e3d1700cc cirrus: move the sanitizer build from freebsd 13 to freebsd 
12
     new 3d1fcf6cd cirrus: make freebsd ignore the tests instead of skipping
     new a08425444 OS400: Update strings for ccsid-ifier
     new 4f6fdc903 RELEASE-NOTES: synced
     new 12144fdda nghttp2: 1.12.0 required
     new 18c7084c7 packages: add OS400/chkstrings.c to the dist
     new 9a8b3b3e1 copyright: fix out-of-date copyright ranges and missing 
headers
     new 2edeb1045 config: remove all defines of HAVE_DES_H
     new 840df8b0d CI: migrate macOS jobs from Azure and Travis CI to GitHub 
Actions
     new fd7afa7d3 CI: bring GitHub Actions fuzzing job in line with macOS jobs
     new 7e8a1a087 CI: remove default Ubuntu build from GitHub Actions
     new c4c0b0458 travis: update the ngtcp2 build to use the latest OpenSSL 
patch
     new 35318218b dist: add mail-rcpt-allowfails.d to the tarball
     new 02174e41f openssl: adapt to functions marked as deprecated since 
version 3
     new 361d4f3fd docs/make: generate curl.1 from listed files only
     new 6d45588ba sockfilt: add logmsg output to select_ws_wait_thread on 
Windows
     new 0d0537aea SSLCERTS.md: Fix example code for setting CA cert file
     new 62112d2bb RELEASE-NOTES: synced
     new 6de756c9b version: add 'cainfo' and 'capath' to version info struct
     new d973bdf88 mailmap: fixup a few author names/fields
     new 884de1a76 writeout_json: Fix data type issues
     new 37b6cc2fe TODO: Set custom client ip when using haproxy protocol
     new bbe476d58 KNOWN_BUGS: "stick to same family over SOCKS pro" is 
presumed fixed
     new 6be2804cd KNOWN_BUGS: "FTPS needs session reuse"
     new 34696ab5a KNOWN_BUGS: DoH leaks memory after followlocation
     new 96a617b14 KNOWN_BUGS: DoH doesn't inherit all transfer options
     new 93fafb93d curl.h: remnove CURL_VERSION_ESNI. Never supported nor 
documented
     new a97d826f6 test1177: verify that all the CURL_VERSION_ bits are 
documented
     new a3a5e2eaa dist: add tests/version-scan.pl to tarball
     new c79e42894 output.d: quote the URL when globbing
     new 69d5d183d SECURITY.md: minor rephrase
     new 8efd26afb ngtcp2: update to git master for the key installation API 
change
     new 6d65a1917 cmake: add CMAKE_MSVC_RUNTIME_LIBRARY
     new 529add48b checksrc: warn on obvious conditional blocks on the same 
line as if()
     new 0e607542d cleanup: insert newline after if() conditions
     new 14dd0c020 memdebug: don't log free(NULL)
     new 7a71965e9 build: fixed build for systems with select() in unistd.h
     new d1369fe21 misc: copyright year updates
     new e37dc71ea examples/sessioninfo.c: add include to fix compiler warning
     new 0736ee73d vquic: add support for GnuTLS backend of ngtcp2
     new c3b865ea3 CI: add build with ngtcp2 + gnutls on Travis CI
     new 75fac5088 vquic/ngtcp2.h: update copyright year range
     new a67b7bdda RELEASE-PROCEDURE.md: run the copyright.pl script!
     new a30237e3d RELEASE-NOTES: synced
     new 7208a989b ftpserver.pl: log before and after data connection is closed
     new b023008e7 runtests.pl: log host OS as detected by Perl environment
     new e1dc86fe8 CI: increase Azure Pipelines timeouts due to performance 
issues
     new 4506607b4 CI-fuzz: increase fuzz time to 40 minutes
     new 9657ecb15 sockfilt: fix race-condition of waiting threads and event 
handling
     new 3d1f35eb1 sockfilt: fix handling of ready closed sockets on Windows
     new 57476a91e sockfilt: remove redundancy in timeout handling
     new 0c511b44f KNOWN_BUGS: Store TLS context per transfer instead of per 
connection
     new 23a870f2f windows: enable UnixSockets with all build toolchains
     new a448a4ce2 curl: allow both --etag-compare and --etag-save with same 
file name
     new 54ecc11cc CURLINFO_CONDITION_UNMET: return true for 304 http status 
code
     new 6bc1040d5 test1566: verify --etag-compare that gets a 304 back
     new 62f5e3887 KNOWN_BUGS: fixed "USE_UNIX_SOCKETS on Windows"
     new 49b652dac appveyor: turn disabled tests into ignored result tests
     new 4ba6ba2d9 appveyor: show failed tests in log even if test is ignored
     new b667bbe2c appveyor: sort builds by type and add two new variants
     new 45b843cbb appveyor: use random test server ports based upon 
APPVEYOR_API_URL
     new f50bc76c9 lib670: use the same Win32 API check as all other lib tests
     new 66828f4fd lib: never define CURL_CA_BUNDLE with a getenv
     new 920dfacbf TODO: Option to make -Z merge lined based outputs on stdout
     new 2ebc1236a configure: don't check for Security.framework when 
cross-compiling
     new 17211ade2 scripts/release-notes.pl: add helper script for 
RELEASE-NOTES maintenance
     new fcf955aca RELEASE-NOTES: synced
     new 298a8235f dist: add missing setup-win32.h
     new ae57e27b3 warnless: remove code block for icc that didn't work
     new efa830f9f configure: remove use of -vec-report0 from CFLAGS with icc
     new fef433409 cleanup: correct copyright year range on a few files
     new 9b23a1da7 release-notes: output trailing references sorted numerically
     new 946a71a14 CURLOPT_WRITEFUNCTION.3: add inline example and new see-also
     new 88436786c select: remove typecast from SOCKET_WRITABLE/READABLE macros
     new 860eaebae tests/README: update the port numbers list
     new 0bcf975c3 connect: store connection info for QUIC connections
     new 3e376059b http: allow Curl_add_buffer_send() to do a short first send 
by force
     new 0ef54abf5 http: don't consider upload done if the request isn't 
completely sent off
     new 741cb81d0 tests: verify split initial HTTP requests with 
CURL_SMALLREQSEND
     new 0fdf96512 schannel: support .P12 or .PFX client certificates
     new 4d939ef6c runtests: provide nicer errormsg when protocol "dump" file 
is empty
     new 6435aaa70 github actions: run when pushed to master or */ci + PRs
     new 3f704083b release-notes: fix the initial reference list output
     new 07778542b runtests: fix warning about using an undefined variable
     new cb232b13d server/resolve: remove AI_CANONNAME to make macos tell the 
truth
     new d4afa0fc2 url: allow non-HTTPS altsvc-matching for debug builds
     new 638b8558d CI/macos: convert CRLF to LF and align indentation
     new 3413a1109 appveyor: ignore failing 'connect to non-listening proxy' 
tests
     new 3e36af2cf appveyor: partially revert 3413a110 to keep build without 
proxy
     new 8c92f7e82 sshserver.pl: use cached Win32 environment check variable
     new 17c18fbc3 test1148: tolerate progress updates better (again)
     new 53f407082 lib: fix conversion warnings for SOCKET_WRITABLE/READABLE
     new 5afa07fab Revert "file: on Windows, refuse paths that start with \\"
     new 20f281293 release-notes.pl: detect the start of the references in 
cleanup mode
     new 6d13ef532 RELEASE-NOTES: synced
     new 3f60a9e99 tests: fix conflict between Cygwin/msys and Windows PIDs
     new 2a9302175 tests: add Windows compatible pidwait like pidkill and 
pidterm
     new c1951cdb3 tests: use Cygwin/msys PIDs for stunnel and sshd on Windows
     new dd0365d56 tests/server/util.c: use curl_off_t instead of long for pid
     new b9a0804ad compressed.d: stress that the headers are not modified
     new 9869f6dc5 tests/server: move all signal handling routines to util.[ch]
     new 30c8ef7d6 tests/server: add CTRL event handler for Win32 consoles
     new ac1e20627 tests/server: add hidden window to gracefully handle WM_CLOSE
     new d59090831 gnutls: ensure TLS 1.3 when SRP isn't requested
     new be28bc224 gopher: check remaining time left during write busy loop
     new 0510cce8c socks: Fix blocking timeout logic
     new c35af2922 schannel: Fix blocking timeout logic
     new ac343fed7 test1908: avoid using fixed port number in test data
     new 93772465b appveyor: completely disable tests that fail to timeout early
     new 50842c1b3 cirrus: no longer ignore test 504 which is working again
     new f62bd9db9 version: increase buffer space for ssl version output
     new 7fa157847 cmake: add aliases so exported target names are available in 
tree
     new 878214df4 tool: do not declare functions with Curl_ prefix
     new 890986519 TODO: Consider convenience options for JSON and XML?
     new 2522903b7 mqtt: add new experimental protocol
     new 675f5fb66 tests: support hex encoded data and mqtt server
     new 5e855bbd1 tests: add the mqtt test server mqttd
     new 41f5b66a0 tests: add four MQTT tests 1190 - 1193
     new 42ff0d9bd travis: add mqtt job on Linux
     new f80dfd225 azure: add mqtt support to one of the Windows builds
     new 23a3ab9dd github/workflow: enable MQTT in the macOS debug build
     new 66212a302 scripts/release-notes: fix duplicate output header
     new 7bade50b6 RELEASE-NOTES: synced
     new 8a2038a3a sockfilt: fix broken pipe on Windows to be ready in select_ws
     new a6f7b2f2a test2043: use revoked.badssl.com instead of revoked.grc.com
     new 42e18528f KNOWN_BUGS: Add entry 'Blocking socket operations'
     new 89f1e639f cmake: Avoid MSVC C4273 warnings in send/recv checks
     new 19ec94d94 docs/MQTT: replace confusing 80 by 75
     new d1479716b scripts/release-notes.pl: accept colon after the 
Fixes/Closes keywords
     new 4cd239fbf copyright: bump the copyright year range
     new 1e41bec96 buildconf: avoid using tempfile when removing files
     new c71200983 buildconf: use find -execdir instead, remove -print and the 
ares files
     new de2126b18 mqttd: s/errno/SOCKERRNO
     new 9c703ead3 appveyor: add Unicode winbuild jobs
     new 14bf7eb6e libssh: Use new ECDSA key types to check known hosts
     new e91749204 sockfilt: tidy variable naming and data structure in 
select_ws
     new 80d651541 tests: run the sws server on "any port"
     new 5e2f4a33f tests: make 2006-2010 handle different port number lengths
     new d009bc2e5 tests: introduce preprocessed test cases
     new 721f24d6f test1448: work with dynamic HTTP server port
     new f99b007cd test1056: work with dynamic HTTP ipv6 port
     new 7e359bccd tests: move pingpong server to dynamic listening port
     new 85e727d43 test1028: make it run on dynamic FTP server port
     new b1c7073a7 test1055: make it work with dynamic FTP port
     new 003a7b526 test1245: make it work with dynamic FTP server port
     new 7e5397460 tests/FILEFORMAT: converted to markdown and extended
     new d7471c136 mime: properly check Content-Type even if it has parameters
     new 0f5db7b26 runtests: dummy init the ports variables to avoid warnings
     new 207a6cbb9 src: Remove C99 constructs to ensure C89 compliance
     new ebb07f3c5 runtests: use a unix domain socket path with the pid in the 
name
     new d2969c7ae test1247: use http server to get the port number set
     new aa98c66e5 add more alt-svc test coverage
     new 4d925eee0 ensure all references to ports are replaced by vars
     new 3c77e280c release-notes.pl: fix parsing typo
     new 8dea78205 RELEASE-NOTES: synced
     new d1a2816b4 runtests: always put test number in servercmd file
     new 5811beba3 mqtt: improve the state machine
     new 369ce38ac tests: run the TFTP test server on a dynamic port number
     new ff7a3107e multi-ssl: reset the SSL backend on `Curl_global_cleanup()`
     new bcd981358 tests: run the SOCKS test server on a dynamic port number
     new 10822c652 lib: fix typos in comments and errormessages
     new df28ed611 http: free memory when Alt-Used header creation fails due to 
OOM
     new fa7daafdb server/tftpd: fix compiler warning
     new 96c149685 mqtt: fix Curl_read()  error handling while reading 
remaining length
     new 093a9e001 mqtt: remove code with no purpose
     new 018dd775c tests: add %NOLISTENPORT and use it
     new bae87dc0d tests: run the RTSP test server on a dynamic port number
     new 10fece336 mqtt: make NOSTATE get within the debug name array
     new 0891fe7ad gnutls: bump lowest supported version to 3.1.10
     new 2d137dedb GnuTLS: Don't skip really long certificate fields
     new f807d163c curl.h: update comment typo
     new ae15bfc9c RELEASE-NOTES: synced
     new 3fdc4bdb5 version: skip idn2_check_version() check and add precaution
     new bffa11653 lib/mk-ca-bundle: skip empty certs
     new c0e139a60 transfer: Switch PUT to GET/HEAD on 303 redirect
     new b1b969261 libcurl-multi.3: added missing full stop
     new a96c7529e select: make Curl_socket_check take timediff_t timeout
     new 1ae586005 test1154: set a proper name
     new 75e8feb6f tests: make runtests check that disabled tests exists
     new ba7b94b1e tests/git: ignore mqttd and port files
     new 4298b9702 docs: fix two typos
     new 11091cd4d runtests: when <killserver> mentions http, kill http/2 too
     new 7bc709f67 libssh: avoid options override by configuration files
     new 6ad062ae7 lib: clean up whitespace
     new 446fb0518 smtp: set auth correctly
     new 2a33417e1 runtests: revert commenting out a line I did for debugging
     new 2fc1c9d7e runtests: check for the disabled tests relative srcdir
     new cca20cb00 CI: do not include */ci branches in PR builds
     new b7135f58f copyright updates: adjust year ranges
     new e2b1ccb99 travis: bump the wolfssl CI build to use 4.4.0
     new cad15b9f9 nss: check for PK11_CreateDigestContext() returning NULL
     new fc0e29dd5 doh: Constify some input pointers
     new 6370e4315 headers: copyright range fix
     new c5d862955 THANKS: synced with the 7.70.0 release
     new 53cdc2c96 RELEASE-NOTES: 7.70.0
     new e78a29c1d Merge tag 'curl-7_70_0'
     new 7179f6d6c make gnurl-aux

The 264 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .azure-pipelines.yml                               |  187 +-
 .cirrus.yml                                        |   37 +-
 .dir-locals.el                                     |   21 +
 .lgtm.yml                                          |   21 +
 .mailmap                                           |   14 +-
 .travis.yml                                        |   46 +-
 CMake/CMakeConfigurableFile.in                     |   21 +
 CMake/CurlSymbolHiding.cmake                       |   21 +
 CMake/FindBearSSL.cmake                            |   21 +
 CMake/FindGSS.cmake                                |   21 +
 CMake/FindNSS.cmake                                |   21 +
 plan9/lib/mkfile => CMake/FindWolfSSL.cmake        |   29 +-
 CMake/Macros.cmake                                 |   21 +
 CMake/OtherTests.cmake                             |   27 +
 CMake/Platforms/WindowsCache.cmake                 |   21 +
 CMake/Utilities.cmake                              |   21 +
 CMake/cmake_uninstall.cmake.in                     |   21 +
 CMake/gnurl-config.cmake.in                        |   21 +
 CMakeLists.txt                                     |   22 +-
 MacOSX-Framework                                   |   21 +
 Makefile.am                                        |   48 +-
 RELEASE-NOTES                                      |  332 +-
 SECURITY.md                                        |    2 +-
 acinclude.m4                                       |    4 +
 appveyor.yml                                       |  141 +-
 buildconf                                          |   16 +-
 configure.ac                                       |  137 +-
 docs/CMakeLists.txt                                |   21 +
 docs/EXPERIMENTAL.md                               |    1 +
 docs/FEATURES                                      |    3 +
 docs/HTTP2.md                                      |    2 +-
 docs/HTTP3.md                                      |   42 +-
 docs/INTERNALS.md                                  |    2 +-
 docs/KNOWN_BUGS                                    |   54 +-
 docs/MQTT.md                                       |   61 +
 docs/Makefile.am                                   |    6 +-
 docs/README.cmake                                  |   16 -
 docs/README.netware                                |   24 -
 docs/README.win32                                  |   23 -
 docs/RELEASE-PROCEDURE.md                          |    2 +
 docs/SSLCERTS.md                                   |    4 +-
 docs/THANKS                                        |   36 +
 docs/THANKS-filter                                 |   22 +
 docs/TODO                                          |   68 +-
 docs/cmdline-opts/CMakeLists.txt                   |   21 +
 docs/cmdline-opts/Makefile.am                      |    5 +-
 docs/cmdline-opts/Makefile.inc                     |   27 +-
 docs/cmdline-opts/compressed.d                     |    6 +-
 docs/cmdline-opts/cookie.d                         |    2 +-
 docs/cmdline-opts/data.d                           |    2 +-
 docs/cmdline-opts/gen.pl                           |   95 +-
 docs/cmdline-opts/output.d                         |   10 +-
 docs/cmdline-opts/page-header                      |   10 +-
 docs/cmdline-opts/ssl-revoke-best-effort.d         |    7 +
 docs/cmdline-opts/url.d                            |    3 +
 docs/cmdline-opts/write-out.d                      |    3 +
 docs/examples/Makefile.example                     |    2 +-
 docs/examples/Makefile.m32                         |    4 +-
 docs/examples/Makefile.netware                     |   21 +
 docs/examples/adddocsref.pl                        |   21 +
 docs/examples/crawler.c                            |    5 +-
 docs/examples/makefile.dj                          |    2 +-
 docs/examples/sessioninfo.c                        |    3 +-
 docs/examples/version-check.pl                     |    2 +-
 docs/gnurl-config.1                                |    6 +-
 docs/libcurl/CMakeLists.txt                        |   21 +
 docs/libcurl/Makefile.inc                          |   22 +
 docs/libcurl/getinfo-times                         |   27 -
 docs/libcurl/gnurl_easy_getinfo.3                  |    4 +-
 docs/libcurl/gnurl_easy_init.3                     |    2 +-
 docs/libcurl/gnurl_easy_perform.3                  |    2 +-
 docs/libcurl/gnurl_easy_strerror.3                 |    2 +-
 docs/libcurl/gnurl_escape.3                        |    2 +-
 docs/libcurl/gnurl_formadd.3                       |    2 +-
 docs/libcurl/gnurl_getenv.3                        |    2 +-
 docs/libcurl/gnurl_mime_type.3                     |    2 +-
 docs/libcurl/gnurl_multi_assign.3                  |    2 +-
 docs/libcurl/gnurl_multi_info_read.3               |    2 +-
 docs/libcurl/gnurl_multi_init.3                    |    2 +-
 docs/libcurl/gnurl_multi_strerror.3                |    2 +-
 docs/libcurl/gnurl_multi_timeout.3                 |    2 +-
 docs/libcurl/gnurl_share_init.3                    |    2 +-
 docs/libcurl/gnurl_share_setopt.3                  |    2 +-
 docs/libcurl/gnurl_share_strerror.3                |    2 +-
 docs/libcurl/gnurl_unescape.3                      |    2 +-
 docs/libcurl/gnurl_version.3                       |    2 +-
 docs/libcurl/gnurl_version_info.3                  |   25 +-
 docs/libcurl/libgnurl-easy.3                       |    2 +-
 docs/libcurl/libgnurl-errors.3                     |    6 +-
 docs/libcurl/libgnurl-multi.3                      |    4 +-
 docs/libcurl/libgnurl-security.3                   |   28 +-
 docs/libcurl/libgnurl.3                            |    2 +-
 docs/libcurl/libgnurl.m4                           |    2 +-
 docs/libcurl/mksymbolsmanpage.pl                   |    2 +-
 docs/libcurl/opts/CMakeLists.txt                   |   21 +
 docs/libcurl/opts/GNURLINFO_CERTINFO.3             |    2 +-
 docs/libcurl/opts/GNURLINFO_CONDITION_UNMET.3      |    8 +-
 .../opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3     |    2 +-
 .../opts/GNURLINFO_CONTENT_LENGTH_UPLOAD_T.3       |    2 +-
 docs/libcurl/opts/GNURLINFO_COOKIELIST.3           |    2 +-
 docs/libcurl/opts/GNURLINFO_OS_ERRNO.3             |    2 +-
 docs/libcurl/opts/GNURLINFO_PROTOCOL.3             |    2 +-
 docs/libcurl/opts/GNURLINFO_REDIRECT_TIME.3        |    2 +-
 docs/libcurl/opts/GNURLINFO_RESPONSE_CODE.3        |    2 +-
 docs/libcurl/opts/GNURLINFO_RETRY_AFTER.3          |    2 +-
 docs/libcurl/opts/GNURLINFO_SCHEME.3               |    2 +-
 docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD_T.3      |    2 +-
 docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD_T.3        |    2 +-
 docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD_T.3     |    2 +-
 docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD_T.3       |    2 +-
 docs/libcurl/opts/GNURLMOPT_MAXCONNECTS.3          |    2 +-
 docs/libcurl/opts/GNURLMOPT_PUSHFUNCTION.3         |    2 +-
 docs/libcurl/opts/GNURLOPT_CHUNK_DATA.3            |    2 +-
 docs/libcurl/opts/GNURLOPT_CLOSESOCKETDATA.3       |    2 +-
 docs/libcurl/opts/GNURLOPT_CLOSESOCKETFUNCTION.3   |    2 +-
 docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT_MS.3     |    2 +-
 docs/libcurl/opts/GNURLOPT_CONNECT_TO.3            |    2 +-
 docs/libcurl/opts/GNURLOPT_COOKIE.3                |    2 +-
 docs/libcurl/opts/GNURLOPT_COPYPOSTFIELDS.3        |    2 +-
 docs/libcurl/opts/GNURLOPT_CUSTOMREQUEST.3         |    2 +-
 docs/libcurl/opts/GNURLOPT_DEBUGDATA.3             |    2 +-
 docs/libcurl/opts/GNURLOPT_DEBUGFUNCTION.3         |    2 +-
 docs/libcurl/opts/GNURLOPT_DEFAULT_PROTOCOL.3      |    2 +-
 docs/libcurl/opts/GNURLOPT_ERRORBUFFER.3           |    2 +-
 docs/libcurl/opts/GNURLOPT_EXPECT_100_TIMEOUT_MS.3 |    2 +-
 docs/libcurl/opts/GNURLOPT_FAILONERROR.3           |    2 +-
 docs/libcurl/opts/GNURLOPT_FTP_USE_EPRT.3          |    2 +-
 .../opts/GNURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3      |    2 +-
 docs/libcurl/opts/GNURLOPT_HTTPHEADER.3            |    2 +-
 docs/libcurl/opts/GNURLOPT_HTTPPROXYTUNNEL.3       |    2 +-
 docs/libcurl/opts/GNURLOPT_IGNORE_CONTENT_LENGTH.3 |    2 +-
 docs/libcurl/opts/GNURLOPT_INFILESIZE.3            |    2 +-
 docs/libcurl/opts/GNURLOPT_INFILESIZE_LARGE.3      |    2 +-
 docs/libcurl/opts/GNURLOPT_INTERLEAVEFUNCTION.3    |    2 +-
 docs/libcurl/opts/GNURLOPT_IOCTLFUNCTION.3         |    2 +-
 docs/libcurl/opts/GNURLOPT_MAXREDIRS.3             |    2 +-
 docs/libcurl/opts/GNURLOPT_NETRC.3                 |    2 +-
 docs/libcurl/opts/GNURLOPT_NOSIGNAL.3              |    2 +-
 docs/libcurl/opts/GNURLOPT_PASSWORD.3              |    2 +-
 docs/libcurl/opts/GNURLOPT_PATH_AS_IS.3            |    2 +-
 docs/libcurl/opts/GNURLOPT_POSTFIELDS.3            |    2 +-
 docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE.3         |    2 +-
 docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE_LARGE.3   |    2 +-
 docs/libcurl/opts/GNURLOPT_POSTQUOTE.3             |    2 +-
 docs/libcurl/opts/GNURLOPT_POSTREDIR.3             |    2 +-
 docs/libcurl/opts/GNURLOPT_PREQUOTE.3              |    2 +-
 docs/libcurl/opts/GNURLOPT_PRE_PROXY.3             |    2 +-
 docs/libcurl/opts/GNURLOPT_PRIVATE.3               |    2 +-
 docs/libcurl/opts/GNURLOPT_PROGRESSDATA.3          |    2 +-
 docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3      |    2 +-
 docs/libcurl/opts/GNURLOPT_PROTOCOLS.3             |    2 +-
 docs/libcurl/opts/GNURLOPT_PROXY_CAINFO.3          |    2 +-
 docs/libcurl/opts/GNURLOPT_PROXY_CRLFILE.3         |    2 +-
 docs/libcurl/opts/GNURLOPT_PROXY_KEYPASSWD.3       |    2 +-
 docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT.3         |    2 +-
 docs/libcurl/opts/GNURLOPT_PROXY_SSLCERTTYPE.3     |    2 +-
 docs/libcurl/opts/GNURLOPT_PROXY_SSLKEYTYPE.3      |    2 +-
 docs/libcurl/opts/GNURLOPT_PROXY_SSL_CIPHER_LIST.3 |    2 +-
 docs/libcurl/opts/GNURLOPT_PROXY_SSL_OPTIONS.3     |    9 +-
 docs/libcurl/opts/GNURLOPT_PROXY_TRANSFER_MODE.3   |    2 +-
 docs/libcurl/opts/GNURLOPT_PUT.3                   |    2 +-
 docs/libcurl/opts/GNURLOPT_QUOTE.3                 |    2 +-
 docs/libcurl/opts/GNURLOPT_READDATA.3              |    2 +-
 docs/libcurl/opts/GNURLOPT_READFUNCTION.3          |    2 +-
 docs/libcurl/opts/GNURLOPT_REFERER.3               |    2 +-
 docs/libcurl/opts/GNURLOPT_RESOLVE.3               |    2 +-
 docs/libcurl/opts/GNURLOPT_RESUME_FROM.3           |    2 +-
 docs/libcurl/opts/GNURLOPT_RESUME_FROM_LARGE.3     |    2 +-
 docs/libcurl/opts/GNURLOPT_RTSP_CLIENT_CSEQ.3      |    2 +-
 docs/libcurl/opts/GNURLOPT_SEEKFUNCTION.3          |    2 +-
 docs/libcurl/opts/GNURLOPT_SSL_CIPHER_LIST.3       |    2 +-
 docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3           |    8 +-
 docs/libcurl/opts/GNURLOPT_STDERR.3                |    2 +-
 docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS_E.3      |    2 +-
 docs/libcurl/opts/GNURLOPT_STREAM_WEIGHT.3         |    2 +-
 docs/libcurl/opts/GNURLOPT_TCP_KEEPALIVE.3         |    2 +-
 docs/libcurl/opts/GNURLOPT_TCP_KEEPIDLE.3          |    2 +-
 docs/libcurl/opts/GNURLOPT_TCP_KEEPINTVL.3         |    2 +-
 docs/libcurl/opts/GNURLOPT_TCP_NODELAY.3           |    2 +-
 docs/libcurl/opts/GNURLOPT_TIMEOUT_MS.3            |    2 +-
 docs/libcurl/opts/GNURLOPT_UNIX_SOCKET_PATH.3      |    2 +-
 docs/libcurl/opts/GNURLOPT_UPLOAD.3                |    2 +-
 docs/libcurl/opts/GNURLOPT_URL.3                   |    6 +-
 docs/libcurl/opts/GNURLOPT_USERAGENT.3             |    2 +-
 docs/libcurl/opts/GNURLOPT_USE_SSL.3               |    2 +-
 docs/libcurl/opts/GNURLOPT_WRITEDATA.3             |    2 +-
 docs/libcurl/opts/GNURLOPT_WRITEFUNCTION.3         |   37 +-
 docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3      |    2 +-
 docs/libcurl/opts/GNURLOPT_XOAUTH2_BEARER.3        |    2 +-
 docs/libcurl/opts/Makefile.inc                     |   21 +
 docs/libcurl/opts/template.3                       |    2 +-
 docs/libcurl/symbols-in-versions                   |    4 +-
 docs/libcurl/symbols.pl                            |    2 +-
 docs/mk-ca-bundle.1                                |    2 +-
 include/Makefile.am                                |   21 +
 include/gnurl/curl.h                               |   20 +-
 include/gnurl/curlver.h                            |    8 +-
 lib/CMakeLists.txt                                 |   28 +-
 lib/Makefile.Watcom                                |    2 +-
 lib/Makefile.am                                    |    6 +-
 lib/Makefile.inc                                   |  101 +-
 lib/Makefile.m32                                   |    2 +-
 lib/Makefile.netware                               |    2 -
 lib/Makefile.vxworks                               |   21 +
 lib/checksrc.pl                                    |   28 +-
 lib/config-dos.h                                   |    2 -
 lib/config-os400.h                                 |    5 +-
 lib/config-riscos.h                                |    5 +-
 lib/config-symbian.h                               |    3 -
 lib/config-tpf.h                                   |    4 -
 lib/config-vxworks.h                               |    3 -
 lib/config-win32.h                                 |   13 +-
 lib/connect.c                                      |  187 +-
 lib/curl_addrinfo.c                                |    6 +-
 lib/curl_config.h.cmake                            |   30 +-
 lib/curl_ntlm_core.c                               |    2 +-
 lib/curl_setup.h                                   |   60 +-
 lib/dict.c                                         |    4 +-
 lib/doh.c                                          |   31 +-
 lib/doh.h                                          |    4 +-
 lib/easy.c                                         |   27 +-
 lib/file.c                                         |    6 +-
 lib/firefox-db2pem.sh                              |    2 +-
 lib/ftp.h                                          |    1 -
 lib/getinfo.c                                      |   80 +-
 lib/gopher.c                                       |   23 +-
 lib/http.c                                         |   30 +-
 lib/http2.c                                        |    2 -
 lib/if2ip.c                                        |   12 +-
 lib/makefile.amiga                                 |   21 +
 lib/makefile.dj                                    |    2 +-
 lib/md4.c                                          |    6 +-
 lib/md5.c                                          |    4 +-
 lib/memdebug.c                                     |    4 +-
 lib/mime.c                                         |   21 +-
 lib/mk-ca-bundle.pl                                |    7 +-
 lib/mk-ca-bundle.vbs                               |    2 +-
 lib/mqtt.c                                         |  627 +++
 lib/mqtt.h                                         |   59 +
 lib/multi.c                                        |    4 +
 lib/select.c                                       |  178 +-
 lib/select.h                                       |   12 +-
 lib/setopt.c                                       |    3 +
 lib/setup-win32.h                                  |  123 +
 lib/sha256.c                                       |    4 +-
 lib/smb.h                                          |    3 +-
 lib/smtp.c                                         |   11 +-
 lib/socks.c                                        |    8 +-
 lib/socks_gssapi.c                                 |    3 +-
 lib/transfer.c                                     |   56 +-
 lib/url.c                                          |   14 +-
 lib/urldata.h                                      |   11 +-
 lib/version.c                                      |   52 +-
 lib/vquic/ngtcp2.c                                 |  332 +-
 lib/vquic/ngtcp2.h                                 |   11 +-
 lib/vssh/libssh.c                                  |   69 +-
 lib/vtls/bearssl.c                                 |  100 +-
 lib/vtls/gskit.c                                   |    5 +-
 lib/vtls/gtls.c                                    |  500 +--
 lib/vtls/mbedtls.c                                 |  145 +-
 lib/vtls/nss.c                                     |  119 +-
 lib/vtls/openssl.c                                 |  252 +-
 lib/vtls/schannel.c                                |  178 +-
 lib/vtls/schannel_verify.c                         |    9 +
 lib/vtls/sectransp.c                               |  191 +-
 lib/vtls/vtls.c                                    |    7 +
 lib/vtls/wolfssl.c                                 |  124 +-
 lib/warnless.h                                     |   15 +-
 libgnurl.pc.in                                     |    2 +-
 m4/curl-compilers.m4                               |   29 +-
 m4/curl-functions.m4                               |    2 -
 m4/curl-openssl.m4                                 |    2 +-
 m4/curl-override.m4                                |   21 +
 m4/curl-reentrant.m4                               |    2 +-
 m4/xc-am-iface.m4                                  |    2 +-
 m4/xc-cc-check.m4                                  |    2 +-
 m4/xc-lt-iface.m4                                  |    2 +-
 m4/xc-translit.m4                                  |    2 +-
 m4/xc-val-flgs.m4                                  |    2 +-
 m4/zz50-xc-ovr.m4                                  |    2 +-
 m4/zz60-xc-ovr.m4                                  |    2 +-
 packages/Android/Android.mk                        |   21 +
 packages/DOS/common.dj                             |   21 +
 packages/Makefile.am                               |   22 +
 packages/OS400/ccsidcurl.c                         |    5 +-
 packages/OS400/chkstrings.c                        |   10 +-
 packages/OS400/curl.inc.in                         |    4 +-
 packages/OS400/initscript.sh                       |   21 +
 packages/OS400/make-include.sh                     |   21 +
 packages/OS400/make-lib.sh                         |   21 +
 packages/OS400/make-src.sh                         |   21 +
 packages/OS400/make-tests.sh                       |   21 +
 packages/OS400/makefile.sh                         |   21 +
 packages/OS400/os400sys.h                          |    2 +-
 packages/Symbian/group/curl.mmp                    |    1 +
 packages/TPF/curl.mak                              |   21 +
 packages/TPF/maketpf.env_curl                      |   21 +
 packages/TPF/maketpf.env_curllib                   |   21 +
 packages/vms/Makefile.am                           |   21 +
 packages/vms/backup_gnv_curl_src.com               |    2 +-
 packages/vms/build_gnv_curl.com                    |    2 +-
 packages/vms/build_gnv_curl_pcsi_desc.com          |    2 +-
 packages/vms/build_gnv_curl_pcsi_text.com          |    2 +-
 packages/vms/build_gnv_curl_release_notes.com      |    2 +-
 packages/vms/build_libcurl_pc.com                  |    2 +-
 packages/vms/clean_gnv_curl.com                    |    2 +-
 packages/vms/compare_curl_source.com               |    2 +-
 packages/vms/config_h.com                          |    2 +-
 packages/vms/curl_crtl_init.c                      |   21 +
 packages/vms/curl_gnv_build_steps.txt              |    4 +-
 packages/vms/curl_startup.com                      |    2 +-
 packages/vms/curlmsg.h                             |    2 +-
 packages/vms/curlmsg.msg                           |   21 +
 packages/vms/curlmsg_vms.h                         |    2 +-
 packages/vms/generate_vax_transfer.com             |    2 +-
 packages/vms/gnv_conftest.c_first                  |    2 +-
 packages/vms/gnv_curl_configure.sh                 |    2 +-
 packages/vms/gnv_libcurl_symbols.opt               |    2 +-
 packages/vms/gnv_link_curl.com                     |    2 +-
 packages/vms/make_gnv_curl_install.sh              |    2 +-
 packages/vms/make_pcsi_curl_kit_name.com           |    2 +-
 packages/vms/pcsi_gnv_curl_file_list.txt           |    2 +-
 packages/vms/pcsi_product_gnv_curl.com             |    2 +-
 packages/vms/setup_gnv_curl_build.com              |    2 +-
 packages/vms/stage_curl_install.com                |    2 +-
 packages/vms/vms_eco_level.h                       |    2 +-
 plan9/{BUILD.PLAN9.txt => README}                  |    0
 scripts/Makefile.am                                |    2 +-
 scripts/completion.pl                              |   21 +
 scripts/contrithanks.sh                            |    2 +-
 scripts/copyright.pl                               |  187 +
 scripts/coverage.sh                                |   21 +
 scripts/installcheck.sh                            |   21 +
 scripts/log2changes.pl                             |   21 +
 scripts/release-notes.pl                           |  213 +
 scripts/travis/before_script.sh                    |   23 +-
 scripts/travis/iconv-env.sh                        |   21 +
 scripts/travis/script.sh                           |   28 +-
 scripts/updatemanpages.pl                          |    2 +-
 src/CMakeLists.txt                                 |   28 +-
 src/Makefile.Watcom                                |    2 +-
 src/Makefile.inc                                   |   23 +
 src/Makefile.m32                                   |    4 +-
 src/macos/src/macos_main.cpp                       |    2 +-
 src/makefile.amiga                                 |   23 +-
 src/makefile.dj                                    |    2 +-
 src/tool_cfgable.h                                 |    3 +
 src/tool_doswin.c                                  |   10 +-
 src/tool_getparam.c                                |    7 +
 src/tool_help.c                                    |    5 +-
 src/tool_hugehelp.c.cvs                            |    2 +-
 src/tool_metalink.c                                |   50 +-
 src/tool_metalink.h                                |   28 +-
 src/tool_operate.c                                 |   68 +-
 src/tool_parsecfg.c                                |    5 +-
 src/tool_setopt.c                                  |    6 +-
 src/tool_sleep.c                                   |    4 +-
 src/tool_util.c                                    |   12 +-
 src/tool_writeout.c                                |  160 +-
 src/tool_writeout.h                                |   58 +-
 src/tool_writeout_json.c                           |  195 +
 src/{tool_writeout.h => tool_writeout_json.h}      |   10 +-
 tests/.gitignore                                   |    2 +-
 tests/CMakeLists.txt                               |   21 +
 tests/FILEFORMAT                                   |  479 ---
 tests/FILEFORMAT.md                                |  473 +++
 tests/Makefile.am                                  |   19 +-
 tests/README                                       |   65 +-
 tests/appveyor.pm                                  |   13 +-
 tests/certs/Makefile.am                            |    2 +-
 tests/certs/scripts/Makefile.am                    |    2 +-
 tests/certs/scripts/genroot.sh                     |    2 +-
 tests/certs/scripts/genserv.sh                     |    2 +-
 tests/convsrctest.pl                               |    2 +-
 tests/curl_test_data.py.in                         |    4 +-
 tests/data/CMakeLists.txt                          |   21 +
 tests/data/DISABLED                                |    6 +-
 tests/data/Makefile.am                             |   21 +
 tests/data/Makefile.inc                            |   70 +-
 tests/data/test1028                                |    6 +-
 tests/data/test1055                                |    6 +-
 tests/data/test1056                                |    8 +-
 tests/data/test1148                                |   14 +-
 tests/data/test1154                                |    2 +-
 tests/data/{test1165 => test1177}                  |    6 +-
 tests/data/test1190                                |   56 +
 tests/data/test1191                                |   50 +
 tests/data/{test46 => test1192}                    |   97 +-
 tests/data/test1193                                |   72 +
 tests/data/test1194                                |   59 +
 tests/data/test1195                                |   63 +
 tests/data/test1196                                |   62 +
 tests/data/test1245                                |    6 +-
 tests/data/test1247                                |    2 +-
 tests/data/test1294                                |   65 +
 tests/data/test1295                                |   68 +
 tests/data/test1448                                |    4 +-
 tests/data/test1451                                |   17 +-
 tests/data/test1452                                |    5 +-
 tests/data/{test1413 => test1524}                  |   56 +-
 tests/data/{test1455 => test1566}                  |   40 +-
 tests/data/test19                                  |    2 +-
 tests/data/test1908                                |    2 +-
 tests/data/test2006                                |   12 +-
 tests/data/test2007                                |    5 +-
 tests/data/test2008                                |    5 +-
 tests/data/test2009                                |    5 +-
 tests/data/test2010                                |    5 +-
 tests/data/test2043                                |    2 +-
 tests/data/{test2041 => test2070}                  |   16 +-
 tests/data/test2100                                |  Bin 1642 -> 1647 bytes
 tests/data/test309                                 |    8 +-
 tests/data/test335                                 |    2 +-
 tests/data/test338                                 |    2 +-
 tests/data/{test343 => test344}                    |   13 +-
 tests/data/{test343 => test345}                    |   10 +-
 tests/data/test358                                 |   94 +
 tests/data/test359                                 |   94 +
 tests/data/test430                                 |  101 +
 tests/data/test431                                 |   95 +
 tests/data/test432                                 |  100 +
 tests/data/test504                                 |    2 +-
 tests/data/test663                                 |    2 +-
 tests/data/{test277 => test669}                    |   30 +-
 tests/data/test702                                 |    2 +-
 tests/data/test703                                 |    2 +-
 tests/data/test704                                 |    2 +-
 tests/data/test705                                 |    2 +-
 tests/data/test970                                 |   66 +
 tests/dictserver.py.in                             |   32 +-
 tests/directories.pm                               |    2 +-
 tests/extern-scan.pl                               |    2 +-
 tests/ftp.pm                                       |  110 +-
 tests/ftpserver.pl                                 |   38 +-
 tests/fuzz/download_fuzzer.sh                      |   21 +
 tests/getpart.pm                                   |   59 +-
 tests/http2-server.pl                              |    2 +-
 tests/httpserver.pl                                |   20 +-
 tests/libtest/CMakeLists.txt                       |   21 +
 tests/libtest/Makefile.inc                         |   21 +
 tests/libtest/lib1507.c                            |    2 +-
 tests/libtest/lib1508.c                            |    2 +-
 tests/libtest/lib1509.c                            |    2 +-
 tests/libtest/lib1514.c                            |    2 +-
 tests/libtest/lib1515.c                            |    2 +-
 tests/libtest/lib1520.c                            |    2 +-
 tests/libtest/lib1525.c                            |    2 +-
 tests/libtest/lib1526.c                            |    2 +-
 tests/libtest/lib1527.c                            |    2 +-
 tests/libtest/lib1531.c                            |    2 +-
 tests/libtest/lib1533.c                            |    2 +-
 tests/libtest/lib1535.c                            |    2 +-
 tests/libtest/lib1536.c                            |    2 +-
 tests/libtest/lib1540.c                            |    2 +-
 tests/libtest/lib1554.c                            |    2 +-
 tests/libtest/lib500.c                             |    2 +-
 tests/libtest/lib501.c                             |    2 +-
 tests/libtest/lib502.c                             |    2 +-
 tests/libtest/lib503.c                             |    2 +-
 tests/libtest/lib504.c                             |    2 +-
 tests/libtest/lib512.c                             |    2 +-
 tests/libtest/lib519.c                             |    2 +-
 tests/libtest/lib521.c                             |    2 +-
 tests/libtest/lib523.c                             |    2 +-
 tests/libtest/lib524.c                             |    2 +-
 tests/libtest/lib543.c                             |    2 +-
 tests/libtest/lib547.c                             |    2 +-
 tests/libtest/lib549.c                             |    2 +-
 tests/libtest/lib558.c                             |    2 +-
 tests/libtest/lib559.c                             |    2 +-
 tests/libtest/lib560.c                             |    2 +-
 tests/libtest/lib566.c                             |    2 +-
 tests/libtest/lib567.c                             |    2 +-
 tests/libtest/lib568.c                             |    2 +-
 tests/libtest/lib570.c                             |    2 +-
 tests/libtest/lib572.c                             |    2 +-
 tests/libtest/lib573.c                             |    2 +-
 tests/libtest/lib579.c                             |    2 +-
 tests/libtest/lib582.c                             |    2 +-
 tests/libtest/lib583.c                             |    2 +-
 tests/libtest/lib586.c                             |    2 +-
 tests/libtest/lib590.c                             |    2 +-
 tests/libtest/lib591.c                             |    2 +-
 tests/libtest/lib598.c                             |    2 +-
 tests/libtest/lib670.c                             |    2 +-
 tests/libtest/notexists.pl                         |   21 +
 tests/libtest/sethostname.c                        |    2 +-
 tests/libtest/sethostname.h                        |    2 +-
 tests/libtest/stub_gssapi.h                        |    2 +-
 tests/libtest/test.h                               |   14 +-
 tests/libtest/test1013.pl                          |   21 +
 tests/libtest/test1022.pl                          |   21 +
 tests/libtest/test307.pl                           |   21 +
 tests/libtest/test610.pl                           |   21 +
 tests/libtest/test613.pl                           |   21 +
 tests/libtest/test75.pl                            |   21 +
 tests/libtest/testtrace.h                          |    2 +-
 tests/libtest/testutil.c                           |    2 +-
 tests/libtest/testutil.h                           |    2 +-
 tests/mem-include-scan.pl                          |    2 +-
 tests/negtelnetserver.py.in                        |   40 +-
 tests/nroff-scan.pl                                |    2 +-
 tests/objnames.inc                                 |    2 +-
 tests/pathhelp.pm                                  |    2 +-
 tests/python_dependencies/impacket/LICENSE         |   84 -
 tests/python_dependencies/impacket/__init__.py     |   25 -
 tests/python_dependencies/impacket/nmb.py          |  982 -----
 tests/python_dependencies/impacket/nt_errors.py    | 3586 -----------------
 tests/python_dependencies/impacket/ntlm.py         |  973 -----
 tests/python_dependencies/impacket/smb.py          | 4099 -------------------
 tests/python_dependencies/impacket/smb3.py         | 1630 --------
 tests/python_dependencies/impacket/smb3structs.py  | 1363 -------
 tests/python_dependencies/impacket/smbserver.py    | 4177 --------------------
 tests/python_dependencies/impacket/spnego.py       |  372 --
 tests/python_dependencies/impacket/structure.py    |  744 ----
 tests/python_dependencies/impacket/uuid.py         |   73 -
 tests/python_dependencies/impacket/version.py      |   12 -
 tests/rtspserver.pl                                |   13 +-
 tests/runtests.pl                                  |  689 ++--
 tests/secureserver.pl                              |    7 +-
 tests/server/.gitignore                            |    1 +
 tests/server/CMakeLists.txt                        |   21 +
 tests/server/Makefile.inc                          |   31 +-
 tests/server/base64.pl                             |   21 +
 tests/server/fake_ntlm.c                           |   17 +-
 tests/server/getpart.c                             |    2 +-
 tests/server/getpart.h                             |    2 +-
 tests/server/mqttd.c                               | 1018 +++++
 tests/server/resolve.c                             |    4 +-
 tests/server/rtspd.c                               |  215 +-
 tests/server/server_setup.h                        |    2 +-
 tests/server/server_sockaddr.h                     |    2 +-
 tests/server/sockfilt.c                            |  604 ++-
 tests/server/socksd.c                              |  143 +-
 tests/server/sws.c                                 |  214 +-
 tests/server/testpart.c                            |    2 +-
 tests/server/tftp.h                                |    2 +-
 tests/server/tftpd.c                               |  250 +-
 tests/server/util.c                                |  322 +-
 tests/server/util.h                                |   21 +-
 tests/serverhelp.pm                                |   14 +-
 tests/smbserver.py.in                              |   33 +-
 tests/sshhelp.pm                                   |    2 +-
 tests/sshserver.pl                                 |   40 +-
 tests/symbol-scan.pl                               |    2 +-
 tests/testcurl.pl                                  |    2 +-
 tests/tftpserver.pl                                |   17 +-
 tests/unit/CMakeLists.txt                          |   21 +
 tests/unit/curlcheck.h                             |    2 +-
 tests/unit/unit1300.c                              |    2 +-
 tests/unit/unit1302.c                              |    2 +-
 tests/unit/unit1330.c                              |    2 +-
 tests/unit/unit1394.c                              |    8 +-
 tests/unit/unit1395.c                              |    2 +-
 tests/unit/unit1600.c                              |    2 +-
 tests/unit/unit1605.c                              |    2 +-
 tests/unit/unit1650.c                              |   10 +-
 tests/unit/unit1655.c                              |    5 +-
 tests/valgrind.pm                                  |    2 +-
 tests/{extern-scan.pl => version-scan.pl}          |   62 +-
 560 files changed, 10893 insertions(+), 22590 deletions(-)
 copy plan9/lib/mkfile => CMake/FindWolfSSL.cmake (66%)
 create mode 100644 docs/MQTT.md
 delete mode 100644 docs/README.cmake
 delete mode 100644 docs/README.netware
 delete mode 100644 docs/README.win32
 create mode 100644 docs/cmdline-opts/ssl-revoke-best-effort.d
 delete mode 100644 docs/libcurl/getinfo-times
 create mode 100644 lib/mqtt.c
 create mode 100644 lib/mqtt.h
 create mode 100644 lib/setup-win32.h
 rename plan9/{BUILD.PLAN9.txt => README} (100%)
 create mode 100755 scripts/copyright.pl
 create mode 100755 scripts/release-notes.pl
 create mode 100644 src/tool_writeout_json.c
 copy src/{tool_writeout.h => tool_writeout_json.h} (78%)
 delete mode 100644 tests/FILEFORMAT
 create mode 100644 tests/FILEFORMAT.md
 copy tests/data/{test1165 => test1177} (53%)
 create mode 100644 tests/data/test1190
 create mode 100644 tests/data/test1191
 copy tests/data/{test46 => test1192} (72%)
 create mode 100644 tests/data/test1193
 create mode 100644 tests/data/test1194
 create mode 100644 tests/data/test1195
 create mode 100644 tests/data/test1196
 create mode 100644 tests/data/test1294
 create mode 100644 tests/data/test1295
 copy tests/data/{test1413 => test1524} (58%)
 copy tests/data/{test1455 => test1566} (53%)
 copy tests/data/{test2041 => test2070} (69%)
 copy tests/data/{test343 => test344} (70%)
 copy tests/data/{test343 => test345} (75%)
 create mode 100644 tests/data/test358
 create mode 100644 tests/data/test359
 create mode 100644 tests/data/test430
 create mode 100644 tests/data/test431
 create mode 100644 tests/data/test432
 copy tests/data/{test277 => test669} (54%)
 create mode 100644 tests/data/test970
 delete mode 100644 tests/python_dependencies/impacket/LICENSE
 delete mode 100644 tests/python_dependencies/impacket/__init__.py
 delete mode 100644 tests/python_dependencies/impacket/nmb.py
 delete mode 100644 tests/python_dependencies/impacket/nt_errors.py
 delete mode 100644 tests/python_dependencies/impacket/ntlm.py
 delete mode 100644 tests/python_dependencies/impacket/smb.py
 delete mode 100644 tests/python_dependencies/impacket/smb3.py
 delete mode 100644 tests/python_dependencies/impacket/smb3structs.py
 delete mode 100644 tests/python_dependencies/impacket/smbserver.py
 delete mode 100644 tests/python_dependencies/impacket/spnego.py
 delete mode 100644 tests/python_dependencies/impacket/structure.py
 delete mode 100644 tests/python_dependencies/impacket/uuid.py
 delete mode 100644 tests/python_dependencies/impacket/version.py
 create mode 100644 tests/server/mqttd.c
 copy tests/{extern-scan.pl => version-scan.pl} (55%)

diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 9e2d74e99..29f278c65 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -1,11 +1,39 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Starter pipeline
 # Start with a minimal pipeline that you can customize to build and deploy 
your code.
 # Add steps that build, run tests, deploy, and more:
 # https://aka.ms/yaml
 
 trigger:
-- 'master'
-- '*/ci'
+  branches:
+    include:
+    - 'master'
+    - '*/ci'
+
+pr:
+  branches:
+    include:
+    - 'master'
 
 stages:
 
@@ -22,6 +50,9 @@ stages:
     pool:
       vmImage: 'ubuntu-latest'
     steps:
+    - script: sudo apt install stunnel4 python-impacket
+      displayName: 'apt install'
+
     - script: ./buildconf && ./configure --enable-debug --enable-werror
       displayName: 'configure debug'
 
@@ -32,6 +63,7 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: ""
 
   - job: disable_ipv6
     displayName: ubuntu w/o IPv6
@@ -39,6 +71,9 @@ stages:
     pool:
       vmImage: 'ubuntu-latest'
     steps:
+    - script: sudo apt install stunnel4 python-impacket
+      displayName: 'apt install'
+
     - script: ./buildconf && ./configure --disable-ipv6
       displayName: 'configure disable ipv6'
 
@@ -49,6 +84,7 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: ""
 
   - job: disable_http_smtp_imap
     displayName: ubuntu w/o HTTP/SMTP/IMAP
@@ -56,6 +92,9 @@ stages:
     pool:
       vmImage: 'ubuntu-latest'
     steps:
+    - script: sudo apt install stunnel4 python-impacket
+      displayName: 'apt install'
+
     - script: ./buildconf && ./configure --disable-http --disable-smtp 
--disable-imap
       displayName: 'configure disable http/smtp/imap'
 
@@ -73,6 +112,9 @@ stages:
     pool:
       vmImage: 'ubuntu-latest'
     steps:
+    - script: sudo apt install stunnel4 python-impacket
+      displayName: 'apt install'
+
     - script: ./buildconf && ./configure --disable-threaded-resolver
       displayName: 'configure disable threaded-resolver'
 
@@ -83,6 +125,7 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: ""
 
   - job: http_only
     displayName: ubuntu HTTP only
@@ -90,6 +133,9 @@ stages:
     pool:
       vmImage: 'ubuntu-latest'
     steps:
+    - script: sudo apt install stunnel4 python-impacket
+      displayName: 'apt install'
+
     - script: ./buildconf && ./configure --disable-dict --disable-file 
--disable-ftp --disable-gopher --disable-imap --disable-ldap --disable-pop3 
--disable-rtmp --disable-rtsp --disable-scp --disable-sftp --disable-smb 
--disable-smtp --disable-telnet --disable-tftp
       displayName: 'configure disable non-http'
 
@@ -100,17 +146,18 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: ""
 
 - stage: linux_torture
   dependsOn: linux
   jobs:
   - job: torture
     displayName: ubuntu torture tests
-    timeoutInMinutes: 50
+    timeoutInMinutes: 60
     pool:
       vmImage: 'ubuntu-latest'
     steps:
-    - script: sudo apt install libnghttp2-dev
+    - script: sudo apt install stunnel4 python-impacket libnghttp2-dev
       displayName: 'apt install'
 
     - script: ./buildconf && ./configure --enable-debug --disable-shared 
--disable-threaded-resolver --enable-alt-svc
@@ -119,88 +166,10 @@ stages:
     - script: make
       displayName: 'make'
 
-    - script: make "TFLAGS=-n -t --shallow=40 '!FTP'" test-nonflaky
-      displayName: 'torture test'
-
-##########################################
-### macOS jobs below
-##########################################
-
-- stage: macos
-  dependsOn: []
-  jobs:
-  - job: macos_vanilla
-    displayName: macos default
-    timeoutInMinutes: 30
-    pool:
-      vmImage: 'macOS-latest'
-    steps:
-    - script: brew update && brew install libtool autoconf automake nghttp2 
pkg-config
-      displayName: 'brew install'
-
-    - script: ./buildconf && ./configure --enable-debug --enable-werror 
--without-brotli
-      displayName: 'configure debug without brotli'
-
-    - script: make
-      displayName: 'make'
-
-    - script: make test-nonflaky
-      displayName: 'test'
-      env:
-        AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
-
-  - job: macos_libssh2
-    displayName: macos libssh2
-    timeoutInMinutes: 30
-    pool:
-      vmImage: 'macOS-latest'
-    steps:
-    - script: brew update && brew install libtool autoconf automake nghttp2 
pkg-config libssh2
-      displayName: 'brew install'
-
-    - script: ./buildconf && ./configure --enable-debug --with-libssh2
-      displayName: 'configure debug with libssh2'
-
-    - script: make
-      displayName: 'make'
-
     - script: make test-nonflaky
-      displayName: 'test'
-      env:
-        AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
-
-  - job: macos_cmake
-    displayName: macos cmake openssl
-    timeoutInMinutes: 20
-    pool:
-      vmImage: 'macOS-latest'
-    steps:
-    - script: brew update && brew install libtool autoconf automake nghttp2 
pkg-config openssl
-      displayName: 'brew install'
-
-    - script: cmake -H. -Bbuild -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl 
-DCURL_DISABLE_LDAP=ON -DCURL_DISABLE_LDAPS=ON && cmake --build build
-      displayName: 'cmake build'
-
-- stage: macos_torture
-  dependsOn: macos
-  jobs:
-  - job: macos_torture
-    displayName: macos torture
-    timeoutInMinutes: 50
-    pool:
-      vmImage: 'macOS-latest'
-    steps:
-    - script: brew update && brew install libtool autoconf automake nghttp2 
pkg-config
-      displayName: 'brew install'
-
-    - script: ./buildconf && ./configure --enable-debug --disable-shared 
--disable-threaded-resolver --enable-alt-svc
-      displayName: 'configure torture'
-
-    - script: make
-      displayName: 'make'
-
-    - script: make "TFLAGS=-n -t --shallow=25 '!FTP'" test-nonflaky
       displayName: 'torture test'
+      env:
+        TFLAGS: "-n -t --shallow=40 !FTP"
 
 ##########################################
 ### Windows jobs below
@@ -208,10 +177,12 @@ stages:
 
 - stage: windows
   dependsOn: []
+  variables:
+    agent.preferPowerShellOnContainers: true
   jobs:
   - job: windows_msys2_mingw32_debug_openssl
     displayName: msys2 mingw32 debug openssl
-    timeoutInMinutes: 70
+    timeoutInMinutes: 90
     pool:
       vmImage: 'windows-2019'
     container:
@@ -219,7 +190,6 @@ stages:
       env:
         MSYSTEM: MINGW32
         MSYS2_PATH_TYPE: inherit
-        TFLAGS: "~323 ~1056 ~1299"
     steps:
     - script: C:\msys64\usr\bin\sh -l -c "cd $(echo '%cd%') && ./buildconf && 
./configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 --enable-debug 
--enable-werror"
       displayName: 'configure debug'
@@ -231,10 +201,11 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: "~1056 ~1299"
 
   - job: windows_msys2_mingw64_debug_openssl
     displayName: msys2 mingw64 debug openssl
-    timeoutInMinutes: 70
+    timeoutInMinutes: 90
     pool:
       vmImage: 'windows-2019'
     container:
@@ -242,7 +213,6 @@ stages:
       env:
         MSYSTEM: MINGW64
         MSYS2_PATH_TYPE: inherit
-        TFLAGS: "~323 ~1056 ~1299"
     steps:
     - script: C:\msys64\usr\bin\sh -l -c "cd $(echo '%cd%') && ./buildconf && 
./configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --enable-debug 
--enable-werror"
       displayName: 'configure debug'
@@ -254,16 +224,15 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: "~1056 ~1299"
 
   - job: windows_msys1_mingw_debug_openssl
     displayName: msys1 mingw debug openssl
-    timeoutInMinutes: 70
+    timeoutInMinutes: 90
     pool:
       vmImage: 'windows-2019'
     container:
       image: mback2k/curl-docker-winbuildenv-msys1-mingw:ltsc2019
-      env:
-        TFLAGS: "~203 ~1056 ~1143"
     steps:
     - script: C:\MinGW\msys\1.0\bin\sh -l -c "cd $(echo '%cd%') && ./buildconf 
&& ./configure --host=i686-pc-mingw32 --build=i686-pc-mingw32 --prefix=/mingw 
--enable-debug"
       displayName: 'configure debug'
@@ -275,18 +244,17 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: "~203 ~1056 ~1143"
 
   - job: windows_msys1_mingw32_debug_openssl
     displayName: msys1 mingw32 debug openssl
-    timeoutInMinutes: 70
+    timeoutInMinutes: 90
     pool:
       vmImage: 'windows-2019'
     container:
       image: mback2k/curl-docker-winbuildenv-msys1-mingw32:ltsc2019
-      env:
-        TFLAGS: "~203 ~1056 ~1143 ~1299"
     steps:
-    - script: C:\MinGW\msys\1.0\bin\sh -l -c "cd $(echo '%cd%') && ./buildconf 
&& ./configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 
--prefix=/mingw32 --enable-debug --enable-werror --without-zlib"
+    - script: C:\MinGW\msys\1.0\bin\sh -l -c "cd $(echo '%cd%') && ./buildconf 
&& ./configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 
--prefix=/mingw32 --enable-debug --enable-werror --without-zlib --enable-mqtt"
       displayName: 'configure debug without zlib'
 
     - script: C:\MinGW\msys\1.0\bin\sh -l -c "cd $(echo '%cd%') && make"
@@ -296,16 +264,15 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: "~203 ~1056 ~1143 ~1299"
 
   - job: windows_msys1_mingw64_debug_openssl
     displayName: msys1 mingw64 debug openssl
-    timeoutInMinutes: 70
+    timeoutInMinutes: 90
     pool:
       vmImage: 'windows-2019'
     container:
       image: mback2k/curl-docker-winbuildenv-msys1-mingw64:ltsc2019
-      env:
-        TFLAGS: "~203 ~1056 ~1143 ~1299"
     steps:
     - script: C:\MinGW\msys\1.0\bin\sh -l -c "cd $(echo '%cd%') && ./buildconf 
&& ./configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 
--prefix=/mingw64 --enable-debug --enable-werror --without-zlib"
       displayName: 'configure debug without zlib'
@@ -317,10 +284,11 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: "~203 ~1056 ~1143 ~1299"
 
   - job: windows_msys2_mingw32_debug_schannel
     displayName: msys2 mingw32 debug schannel
-    timeoutInMinutes: 70
+    timeoutInMinutes: 90
     pool:
       vmImage: 'windows-2019'
     container:
@@ -328,7 +296,6 @@ stages:
       env:
         MSYSTEM: MINGW32
         MSYS2_PATH_TYPE: inherit
-        TFLAGS: "~165 ~310 ~1013 ~1056 ~1299 ~1448 ~2034 ~2037 ~2041 ~2046 
~2047 ~3000 ~3001"
     steps:
     - script: C:\msys64\usr\bin\sh -l -c "cd $(echo '%cd%') && ./buildconf && 
./configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 --enable-debug 
--enable-werror --enable-sspi --without-ssl --with-schannel --with-winidn"
       displayName: 'configure debug with sspi/schannel/winidn'
@@ -340,10 +307,11 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: "~165 ~310 ~1013 ~1056 ~1299 ~1448 ~2034 ~2037 ~2041 ~2046 
~2047 ~3000 ~3001"
 
   - job: windows_msys2_mingw64_debug_schannel
     displayName: msys2 mingw64 debug schannel
-    timeoutInMinutes: 70
+    timeoutInMinutes: 90
     pool:
       vmImage: 'windows-2019'
     container:
@@ -351,7 +319,6 @@ stages:
       env:
         MSYSTEM: MINGW64
         MSYS2_PATH_TYPE: inherit
-        TFLAGS: "~165 ~310 ~1013 ~1056 ~1299 ~1448 ~2034 ~2037 ~2041 ~2046 
~2047 ~3000 ~3001"
     steps:
     - script: C:\msys64\usr\bin\sh -l -c "cd $(echo '%cd%') && ./buildconf && 
./configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --enable-debug 
--enable-werror --enable-sspi --without-ssl --with-schannel --with-winidn"
       displayName: 'configure debug with sspi/schannel/winidn'
@@ -363,16 +330,15 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: "~165 ~310 ~1013 ~1056 ~1299 ~1448 ~2034 ~2037 ~2041 ~2046 
~2047 ~3000 ~3001"
 
   - job: windows_msys1_mingw_debug_schannel
     displayName: msys1 mingw debug schannel
-    timeoutInMinutes: 70
+    timeoutInMinutes: 90
     pool:
       vmImage: 'windows-2019'
     container:
       image: mback2k/curl-docker-winbuildenv-msys1-mingw:ltsc2019
-      env:
-        TFLAGS: "~203 ~305 ~310 ~311 ~312 ~313 ~404 ~1013 ~1056 ~1143 ~2034 
~2035 ~2037 ~2038 ~2041 ~2042 ~2048 ~3000 ~3001"
     steps:
     - script: C:\MinGW\msys\1.0\bin\sh -l -c "cd $(echo '%cd%') && ./buildconf 
&& ./configure --host=i686-pc-mingw32 --build=i686-pc-mingw32 --prefix=/mingw 
--enable-debug --enable-sspi --without-ssl --with-schannel --with-winidn"
       displayName: 'configure debug with sspi/schannel/winidn'
@@ -384,16 +350,15 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: "~203 ~305 ~310 ~311 ~312 ~313 ~404 ~1013 ~1056 ~1143 ~2034 
~2035 ~2037 ~2038 ~2041 ~2042 ~2048 ~3000 ~3001"
 
   - job: windows_msys1_mingw32_debug_schannel
     displayName: msys1 mingw32 debug schannel
-    timeoutInMinutes: 70
+    timeoutInMinutes: 90
     pool:
       vmImage: 'windows-2019'
     container:
       image: mback2k/curl-docker-winbuildenv-msys1-mingw32:ltsc2019
-      env:
-        TFLAGS: "~203 ~310 ~1013 ~1056 ~1143 ~1299 ~2034 ~2037 ~2041 ~3000 
~3001"
     steps:
     - script: C:\MinGW\msys\1.0\bin\sh -l -c "cd $(echo '%cd%') && ./buildconf 
&& ./configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 
--prefix=/mingw32 --enable-debug --enable-werror --enable-sspi --without-ssl 
--with-schannel --with-winidn --without-zlib"
       displayName: 'configure debug with sspi/schannel/winidn without zlib'
@@ -405,16 +370,15 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: "~203 ~310 ~1013 ~1056 ~1143 ~1299 ~2034 ~2037 ~2041 ~3000 
~3001"
 
   - job: windows_msys1_mingw64_debug_schannel
     displayName: msys1 mingw64 debug schannel
-    timeoutInMinutes: 70
+    timeoutInMinutes: 90
     pool:
       vmImage: 'windows-2019'
     container:
       image: mback2k/curl-docker-winbuildenv-msys1-mingw64:ltsc2019
-      env:
-        TFLAGS: "~203 ~310 ~1013 ~1056 ~1143 ~1299 ~2034 ~2037 ~2041 ~3000 
~3001"
     steps:
     - script: C:\MinGW\msys\1.0\bin\sh -l -c "cd $(echo '%cd%') && ./buildconf 
&& ./configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 
--prefix=/mingw64  --enable-debug --enable-werror --enable-sspi --without-ssl 
--with-schannel --with-winidn --without-zlib"
       displayName: 'configure debug with sspi/schannel/winidn without zlib'
@@ -426,3 +390,4 @@ stages:
       displayName: 'test'
       env:
         AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
+        TFLAGS: "~203 ~310 ~1013 ~1056 ~1143 ~1299 ~2034 ~2037 ~2041 ~3000 
~3001"
diff --git a/.cirrus.yml b/.cirrus.yml
index a19b26238..5456395ef 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Cirrus CI configuration
 # https://cirrus-ci.com/github/teknokatze/gnurl
 
@@ -6,7 +27,7 @@ task:
   freebsd_instance:
     matrix:
       # A stable 13.0 image likely won't be available before early 2021
-      # image_family: freebsd-13-0-snap
+      image_family: freebsd-13-0-snap
       image_family: freebsd-12-1
       # The stable 11.3 image causes "Agent is not responding" so use a 
snapshot
       image_family: freebsd-11-3-snap
@@ -16,12 +37,17 @@ task:
     MAKE_FLAGS: -j 2
 
   pkginstall_script:
+    - pkg update -f
     - pkg install -y autoconf automake libtool pkgconf brotli openldap-client 
heimdal libpsl libmetalink libssh2 openssh-portable libidn2 librtmp libnghttp2 
nghttp2 stunnel
+    - case `python -V` in
+        Python?3.7*) pkg install -y py37-impacket ;;
+        Python?2.7*) pkg install -y py27-impacket ;;
+      esac
     - pkg delete -y curl
   configure_script:
     - ./buildconf
     - case `uname -r` in
-        13.0*)
+        12.1*)
         export CC=clang;
         export CFLAGS="-fsanitize=address,undefined,signed-integer-overflow 
-fno-sanitize-recover=undefined,integer -Wformat -Werror=format-security 
-Werror=array-bounds -g";
         export CXXFLAGS="-fsanitize=address,undefined 
-fno-sanitize-recover=undefined,integer -Wformat -Werror=format-security 
-Werror=array-bounds -g";
@@ -43,10 +69,9 @@ task:
     - SKIP_TESTS=''
     - uname -r
     - case `uname -r` in
-        13.0*) SKIP_TESTS='!323 !1242 !1243 !2002 !2003';;
-        12.1*) SKIP_TESTS='!323 !1242 !1243 !2002 !2003';;
-        11.3*) SKIP_TESTS='!504 !1242 !1243 !2002 !2003';;
-        10.4*) SKIP_TESTS='!310 !311 !312 !313 !1082 !1242 !1243 !2002 !2003 
!2034 !2035 !2037 !2038 !2041 !2042 !2048 !3000 !3001';;
+        13.0*) SKIP_TESTS='~1242 ~1243 ~2002 ~2003';;
+        12.1*) SKIP_TESTS='~1242 ~1243 ~2002 ~2003';;
+        11.3*) SKIP_TESTS='~1242 ~1243 ~2002 ~2003';;
       esac
     - sudo -u nobody make V=1 TFLAGS="-n -a -p !flaky ${SKIP_TESTS}" 
test-nonflaky
   install_script:
diff --git a/.dir-locals.el b/.dir-locals.el
index ed91b128c..7c209357d 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -1,3 +1,24 @@
+;;;***************************************************************************
+;;;                                  _   _ ____  _
+;;;  Project                     ___| | | |  _ \| |
+;;;                             / __| | | | |_) | |
+;;;                            | (__| |_| |  _ <| |___
+;;;                             \___|\___/|_| \_\_____|
+;;;
+;;; Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+;;;
+;;; This software is licensed as described in the file COPYING, which
+;;; you should have received as part of this distribution. The terms
+;;; are also available at https://curl.haxx.se/docs/copyright.html.
+;;;
+;;; You may opt to use, copy, modify, merge, publish, distribute and/or sell
+;;; copies of the Software, and permit persons to whom the Software is
+;;; furnished to do so, under the terms of the COPYING file.
+;;;
+;;; This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+;;; KIND, either express or implied.
+;;;
+;;;***************************************************************************
 ;;; Directory Local Variables
 ;;; See Info node `(emacs) Directory Variables' for more information.
 
diff --git a/.lgtm.yml b/.lgtm.yml
index 030c563bd..4063cd3a7 100644
--- a/.lgtm.yml
+++ b/.lgtm.yml
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 extraction:
   cpp:
     prepare:
diff --git a/.mailmap b/.mailmap
index 25a370132..468b90992 100644
--- a/.mailmap
+++ b/.mailmap
@@ -59,7 +59,13 @@ Niall O'Reilly <address@hidden>
 Mohammad Hasbini <address@hidden>
 Andrew Ishchuk <address@hidden>
 Nicolas Guillier <address@hidden>
-Nikita Gillmann <address@hidden>
-Nikita Gillmann <address@hidden> ng0 <address@hidden>
-Nikita Gillmann <address@hidden> ng0 <address@hidden>
-Nikita Gillmann <address@hidden> Nils Gillmann <address@hidden>
+nikita <address@hidden>
+nikita <address@hidden> Nikita Gillmann <address@hidden>
+nikita <address@hidden> ng0 <address@hidden>
+nikita <address@hidden> ng0 <address@hidden>
+nikita <address@hidden> Nils Gillmann <address@hidden>
+Julian Z <address@hidden> <address@hidden>
+Jessa Chandler <address@hidden>
+Gökhan Şengün <address@hidden> <address@hidden>
+Svyatoslav Mishyn <address@hidden>
+Douglas Steinwand <address@hidden>
diff --git a/.travis.yml b/.travis.yml
index 791783c2b..116472f5e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 language: c
 sudo: required
 
@@ -23,6 +44,7 @@ addons:
             - libidn2-0-dev
             - gnutls-bin
             - libgnutls28-dev
+            - python-impacket
 
 matrix:
     include:
@@ -32,6 +54,11 @@ matrix:
           env:
               - T=normal C="" CHECKSRC=1
               - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
+        - os: linux
+          compiler: gcc
+          dist: trusty
+          env:
+              - T=normal C="--enable-mqtt"
         - os: linux
           compiler: gcc
           dist: bionic
@@ -110,22 +137,6 @@ matrix:
           env:
               - T=iconv
               - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
-        - os: osx
-          compiler: gcc
-          env: T=debug C="--disable-dict --disable-file --disable-ftp 
--disable-gopher --disable-imap --disable-ldap --disable-pop3 --disable-rtmp 
--disable-rtsp --disable-scp --disable-sftp --disable-smb --disable-smtp 
--disable-telnet --disable-tftp --disable-unix-sockets --disable-shared 
--enable-debug --enable-maintainer-mode --without-brotli --without-gssapi 
--without-libidn2 --without-libmetalink --without-libpsl --without-librtmp 
--without-libssh2 --without-nghttp2 --without-ntlm- [...]
-        - os: osx
-          compiler: gcc
-          env: T=debug C=--enable-ares
-        - os: osx
-          compiler: clang
-          osx_image: xcode10
-          env: T=debug
-        - os: osx
-          compiler: clang
-          env: T=normal
-        - os: osx
-          compiler: clang
-          env: T=cmake
         - os: linux
           compiler: gcc
           dist: bionic
@@ -246,9 +257,6 @@ before_install:
 
 install:
   - if [ "$T" = "coverage" ]; then pip2 install --user cpp-coveralls; fi
-  - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update > /dev/null; fi
-  - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew reinstall libtool > 
/dev/null; fi
-  - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install c-ares; fi
 
 # before_script and script:
 # Travis isn't reliable catching errors in inline script commands (#3730).
diff --git a/CMake/CMakeConfigurableFile.in b/CMake/CMakeConfigurableFile.in
index df2c382e9..2bafe2c10 100644
--- a/CMake/CMakeConfigurableFile.in
+++ b/CMake/CMakeConfigurableFile.in
@@ -1 +1,22 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 @CMAKE_CONFIGURABLE_FILE_CONTENT@
diff --git a/CMake/CurlSymbolHiding.cmake b/CMake/CurlSymbolHiding.cmake
index 8e5fd67a0..aaac9fead 100644
--- a/CMake/CurlSymbolHiding.cmake
+++ b/CMake/CurlSymbolHiding.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 include(CheckCSourceCompiles)
 
 option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide 
all symbols that aren't officially external)." ON)
diff --git a/CMake/FindBearSSL.cmake b/CMake/FindBearSSL.cmake
index 20d239a4f..a8f72c92d 100644
--- a/CMake/FindBearSSL.cmake
+++ b/CMake/FindBearSSL.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 find_path(BEARSSL_INCLUDE_DIRS bearssl.h)
 
 find_library(BEARSSL_LIBRARY bearssl)
diff --git a/CMake/FindGSS.cmake b/CMake/FindGSS.cmake
index a2f150cda..02111a20f 100644
--- a/CMake/FindGSS.cmake
+++ b/CMake/FindGSS.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # - Try to find the GSS Kerberos library
 # Once done this will define
 #
diff --git a/CMake/FindNSS.cmake b/CMake/FindNSS.cmake
index 0043ce853..5fdb2b776 100644
--- a/CMake/FindNSS.cmake
+++ b/CMake/FindNSS.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 if(UNIX)
   find_package(PkgConfig QUIET)
   pkg_search_module(PC_NSS nss)
diff --git a/plan9/lib/mkfile b/CMake/FindWolfSSL.cmake
similarity index 66%
copy from plan9/lib/mkfile
copy to CMake/FindWolfSSL.cmake
index d7a7ac5e2..54df1a86c 100644
--- a/plan9/lib/mkfile
+++ b/CMake/FindWolfSSL.cmake
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -19,21 +19,16 @@
 # KIND, either express or implied.
 #
 ###########################################################################
+find_path(WolfSSL_INCLUDE_DIR NAMES wolfssl/ssl.h)
+find_library(WolfSSL_LIBRARY NAMES wolfssl)
+mark_as_advanced(WolfSSL_INCLUDE_DIR WolfSSL_LIBRARY)
 
-<../mkfile.proto
-<|mkfile.inc
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(WolfSSL
+  REQUIRED_VARS WolfSSL_INCLUDE_DIR WolfSSL_LIBRARY
+  )
 
-CFLAGS=$CFLAGS -I../include -I. -c
-
-OFILES=${CSOURCES:%.c=%.$O}
-HFILES=$HHEADERS
-LIB=/$objtype/lib/ape/libcurl.a
-
-CLEANFILES=\
-       ${LIB_VAUTH_CFILES:%.c=%.$O}\
-       ${LIB_VTLS_CFILES:%.c=%.$O}\
-
-</sys/src/cmd/mklib
-
-%.$O: %.c
-       $CC $CFLAGS -o $target $stem.c
+if(WolfSSL_FOUND)
+  set(WolfSSL_INCLUDE_DIRS ${WolfSSL_INCLUDE_DIR})
+  set(WolfSSL_LIBRARIES ${WolfSSL_LIBRARY})
+endif()
diff --git a/CMake/Macros.cmake b/CMake/Macros.cmake
index f5a34dbb3..e11f11155 100644
--- a/CMake/Macros.cmake
+++ b/CMake/Macros.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #File defines convenience macros for available feature testing
 
 # This macro checks if the symbol exists in the library and if it
diff --git a/CMake/OtherTests.cmake b/CMake/OtherTests.cmake
index 8b150290c..7cec6da6d 100644
--- a/CMake/OtherTests.cmake
+++ b/CMake/OtherTests.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 include(CheckCSourceCompiles)
 # The begin of the sources (macros and includes)
 set(_source_epilogue "#undef inline")
@@ -42,6 +63,9 @@ if(curl_cv_recv)
                 unset(curl_cv_func_recv_test CACHE)
                 check_c_source_compiles("
                   ${_source_epilogue}
+                  #ifdef WINSOCK_API_LINKAGE
+                  WINSOCK_API_LINKAGE
+                  #endif
                   extern ${recv_retv} ${signature_call_conv}
                   recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4});
                   int main(void) {
@@ -106,6 +130,9 @@ if(curl_cv_send)
                 unset(curl_cv_func_send_test CACHE)
                 check_c_source_compiles("
                   ${_source_epilogue}
+                  #ifdef WINSOCK_API_LINKAGE
+                  WINSOCK_API_LINKAGE
+                  #endif
                   extern ${send_retv} ${signature_call_conv}
                   send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4});
                   int main(void) {
diff --git a/CMake/Platforms/WindowsCache.cmake 
b/CMake/Platforms/WindowsCache.cmake
index ead4115a3..9ae9b56f0 100644
--- a/CMake/Platforms/WindowsCache.cmake
+++ b/CMake/Platforms/WindowsCache.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 if(NOT UNIX)
   if(WIN32)
     set(HAVE_LIBDL 0)
diff --git a/CMake/Utilities.cmake b/CMake/Utilities.cmake
index ffc411ae9..59b17d074 100644
--- a/CMake/Utilities.cmake
+++ b/CMake/Utilities.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # File containing various utilities
 
 # Returns a list of arguments that evaluate to true
diff --git a/CMake/cmake_uninstall.cmake.in b/CMake/cmake_uninstall.cmake.in
index db8e5367d..4a0de5e6b 100644
--- a/CMake/cmake_uninstall.cmake.in
+++ b/CMake/cmake_uninstall.cmake.in
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
   message(FATAL_ERROR "Cannot find install manifest: 
@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
 endif()
diff --git a/CMake/gnurl-config.cmake.in b/CMake/gnurl-config.cmake.in
index 0e1ee5f95..240c3a96e 100644
--- a/CMake/gnurl-config.cmake.in
+++ b/CMake/gnurl-config.cmake.in
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 @PACKAGE_INIT@
 
 include(CMakeFindDependencyMacro)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 97483ca8e..a499d25d2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -184,6 +184,8 @@ mark_as_advanced(CURL_DISABLE_SMTP)
 
 option(CURL_DISABLE_GOPHER "to disable Gopher" ON)
 mark_as_advanced(CURL_DISABLE_GOPHER)
+option(CURL_ENABLE_MQTT "to enable MQTT" OFF)
+mark_as_advanced(CURL_ENABLE_MQTT)
 
 if(HTTP_ONLY)
   set(CURL_DISABLE_FTP ON)
@@ -248,6 +250,7 @@ set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
 set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
 
 if(CURL_STATIC_CRT)
+  set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
   set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
   set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
 endif()
@@ -314,7 +317,7 @@ if(WIN32)
 endif()
 
 # check SSL libraries
-# TODO support GnuTLS and WolfSSL
+# TODO support GnuTLS
 
 if(APPLE)
   option(CMAKE_USE_SECTRANSP "enable Apple OS native SSL/TLS" OFF)
@@ -327,9 +330,10 @@ endif()
 option(CMAKE_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF)
 option(CMAKE_USE_BEARSSL "Enable BearSSL for SSL/TLS" OFF)
 option(CMAKE_USE_NSS "Enable NSS for SSL/TLS" OFF)
+option(CMAKE_USE_WOLFSSL "enable wolfSSL for SSL/TLS" OFF)
 
 set(openssl_default OFF)
-if(WIN32 OR CMAKE_USE_SECTRANSP OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS OR 
CMAKE_USE_NSS)
+if(WIN32 OR CMAKE_USE_SECTRANSP OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS OR 
CMAKE_USE_NSS OR CMAKE_USE_WOLFSSL)
   set(openssl_default OFF)
 endif()
 option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default})
@@ -344,6 +348,7 @@ count_true(enabled_ssl_options_count
   CMAKE_USE_MBEDTLS
   CMAKE_USE_BEARSSL
   CMAKE_USE_NSS
+  CMAKE_USE_WOLFSSL
 )
 if(enabled_ssl_options_count GREATER "1")
   set(CURL_WITH_MULTI_SSL ON)
@@ -445,6 +450,14 @@ if(CMAKE_USE_BEARSSL)
   include_directories(${BEARSSL_INCLUDE_DIRS})
 endif()
 
+if(CMAKE_USE_WOLFSSL)
+  find_package(WolfSSL REQUIRED)
+  set(SSL_ENABLED ON)
+  set(USE_WOLFSSL ON)
+  list(APPEND CURL_LIBS ${WolfSSL_LIBRARIES})
+  include_directories(${WolfSSL_INCLUDE_DIRS})
+endif()
+
 if(CMAKE_USE_NSS)
   find_package(NSS REQUIRED)
   include_directories(${NSS_INCLUDE_DIRS})
@@ -757,7 +770,7 @@ elseif(CURL_CA_PATH_AUTODETECT OR CURL_CA_BUNDLE_AUTODETECT)
 endif()
 
 if(CURL_CA_PATH_SET AND NOT USE_OPENSSL AND NOT USE_MBEDTLS)
-  message(FATAL_ERROR
+  message(STATUS
           "CA path only supported by OpenSSL, GnuTLS or mbed TLS. "
           "Set CURL_CA_PATH=none or enable one of those TLS backends.")
 endif()
@@ -795,7 +808,6 @@ check_include_file_concat("arpa/inet.h"      
HAVE_ARPA_INET_H)
 check_include_file_concat("arpa/tftp.h"      HAVE_ARPA_TFTP_H)
 check_include_file_concat("assert.h"         HAVE_ASSERT_H)
 check_include_file_concat("crypto.h"         HAVE_CRYPTO_H)
-check_include_file_concat("des.h"            HAVE_DES_H)
 check_include_file_concat("err.h"            HAVE_ERR_H)
 check_include_file_concat("errno.h"          HAVE_ERRNO_H)
 check_include_file_concat("fcntl.h"          HAVE_FCNTL_H)
@@ -1310,6 +1322,7 @@ _add_if("SCP"           USE_LIBSSH2)
 _add_if("SFTP"          USE_LIBSSH2)
 _add_if("RTSP"          NOT CURL_DISABLE_RTSP)
 _add_if("RTMP"          USE_LIBRTMP)
+_add_if("MQTT"          CURL_ENABLE_MQTT)
 if(_items)
   list(SORT _items)
 endif()
@@ -1324,6 +1337,7 @@ _add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP)
 _add_if("mbedTLS"          SSL_ENABLED AND USE_MBEDTLS)
 _add_if("BearSSL"          SSL_ENABLED AND USE_BEARSSL)
 _add_if("NSS"              SSL_ENABLED AND USE_NSS)
+_add_if("wolfSSL"          SSL_ENABLED AND USE_WOLFSSL)
 if(_items)
   list(SORT _items)
 endif()
diff --git a/MacOSX-Framework b/MacOSX-Framework
index c0f91e6b9..fb9983e63 100755
--- a/MacOSX-Framework
+++ b/MacOSX-Framework
@@ -1,4 +1,25 @@
 #!/bin/bash
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # This script performs all of the steps needed to build a
 # universal binary libcurl.framework for Mac OS X 10.4 or greater.
 #
diff --git a/Makefile.am b/Makefile.am
index 29fbc003f..4979ee61e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -27,19 +27,27 @@ AUTOMAKE_OPTIONS = foreign
 
 ACLOCAL_AMFLAGS = -I m4
 
-CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in      \
- CMake/CurlTests.c CMake/FindGSS.cmake CMake/OtherTests.cmake   \
- CMake/Platforms/WindowsCache.cmake CMake/Utilities.cmake       \
- CMake/Macros.cmake              \
- CMake/CurlSymbolHiding.cmake             \
- CMake/FindBearSSL.cmake                \
- CMake/cmake_uninstall.cmake.in CMake/gnurl-config.cmake.in
+CMAKE_DIST =                                    \
+ CMake/cmake_uninstall.cmake.in                 \
+ CMake/CMakeConfigurableFile.in                 \
+ CMake/gnurl-config.cmake.in                    \
+ CMake/CurlSymbolHiding.cmake                   \
+ CMake/CurlTests.c                              \
+ CMake/FindBearSSL.cmake                        \
+ CMake/FindGSS.cmake                            \
+ CMake/FindWolfSSL.cmake                        \
+ CMake/Macros.cmake                             \
+ CMake/OtherTests.cmake                         \
+ CMake/Platforms/WindowsCache.cmake             \
+ CMake/Utilities.cmake                          \
+ CMakeLists.txt
+
 
 PLAN9_DIST = plan9/include/mkfile \
  plan9/include/mkfile             \
  plan9/mkfile.proto               \
  plan9/mkfile                     \
- plan9/BUILD.PLAN9.txt            \
+ plan9/README                     \
  plan9/lib/mkfile.inc             \
  plan9/lib/mkfile                 \
  plan9/src/mkfile.inc             \
@@ -164,15 +172,15 @@ cygwinbin:
 
 # We extend the standard install with a custom hook:
 install-data-hook:
-       cd include && $(MAKE) install
-       cd docs && $(MAKE) install
-       cd docs/libcurl && $(MAKE) install
+       (cd include && $(MAKE) install)
+       (cd docs && $(MAKE) install)
+       (cd docs/libcurl && $(MAKE) install)
 
 # We extend the standard uninstall with a custom hook:
 uninstall-hook:
-       cd include && $(MAKE) uninstall
-       cd docs && $(MAKE) uninstall
-       cd docs/libcurl && $(MAKE) uninstall
+       (cd include && $(MAKE) uninstall)
+       (cd docs && $(MAKE) uninstall)
+       (cd docs/libcurl && $(MAKE) uninstall)
 
 ca-bundle: lib/mk-ca-bundle.pl
        @echo "generating a fresh ca-bundle.crt"
@@ -183,11 +191,11 @@ ca-firefox: lib/firefox-db2pem.sh
        ./lib/firefox-db2pem.sh lib/ca-bundle.crt
 
 checksrc:
-       cd lib && $(MAKE) checksrc
-       cd src && $(MAKE) checksrc
-       cd tests && $(MAKE) checksrc
-       cd include/gnurl && $(MAKE) checksrc
-       cd docs/examples && $(MAKE) checksrc
+       (cd lib && $(MAKE) checksrc)
+       (cd src && $(MAKE) checksrc)
+       (cd tests && $(MAKE) checksrc)
+       (cd include/gnurl && $(MAKE) checksrc)
+       (cd docs/examples && $(MAKE) checksrc)
 
 tidy:
        (cd src && $(MAKE) tidy)
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index ef3e38d14..6880318d6 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -1,40 +1,155 @@
-curl and libcurl 7.69.1
+curl and libcurl 7.70.0
 
- Public curl releases:         190
- Command line options:         230
+ Public curl releases:         191
+ Command line options:         231
  curl_easy_setopt() options:   270
  Public functions in libcurl:  82
- Contributors:                 2133
+ Contributors:                 2169
+
+This release includes the following changes:
+
+ o curl: add --ssl-revoke-best-effort to allow a "best effort" revocation 
check [5]
+ o mqtt: add new experimental protocol [57]
+ o schannel: add "best effort" revocation check option: 
CURLSSLOPT_REVOKE_BEST_EFFORT [5]
+ o writeout: support to generate JSON output with '%{json}' [8]
 
 This release includes the following bugfixes:
 
- o ares: store dns parameters for duphandle [20]
- o cirrus-ci: disable the FreeBSD 13 builds [3]
- o curl_share_setopt.3: Note sharing cookies doesn't enable the engine [11]
- o lib1564: reduce number of mid-wait wakeup calls [16]
- o libssh: Fix matching user-specified MD5 hex key [7]
- o MANUAL: update a dict-using command line
- o mime: do not perform more than one read in a row [18]
- o mime: fix the binary encoder to handle large data properly [17]
- o mime: latch last read callback status [19]
- o multi: skip EINTR check on wakeup socket if it was closed [12]
- o pause: bail out on bad input [8]
- o pause: force a connection recheck after unpausing (take 2) [5]
- o pause: return early for calls that don't change pause state [10]
- o runtests.1: rephrase how to specify what tests to run [2]
- o runtests: fix missing use of exe_ext helper function
- o seek: fix fall back for missing ftruncate on Windows [4]
- o sftp: fix segfault regression introduced by #4747 in 7.69.0 [22]
- o sha256: Added SecureTransport implementation [15]
- o sha256: Added WinCrypt implementation [15]
- o socks4: fix host resolve regression [14]
- o socks5: host name resolv regression fix [6]
- o tests/server: fix missing use of exe_ext helper function [24]
- o tests: fix static ip:port instead of dynamic values being used [23]
- o tests: make sleeping portable by avoiding select [1]
- o unit1612: fix the inclusion and compilation of the HMAC unit test [9]
- o urldata: remove the 'stream_was_rewound' connectdata struct member [13]
- o version: make curl_version* thread-safe without using global context [21]
+ o appveyor: add Unicode winbuild jobs [88]
+ o appveyor: completely disable tests that fail to timeout early
+ o appveyor: show failed tests in log even if test is ignored
+ o appveyor: sort builds by type and add two new variants
+ o appveyor: turn disabled tests into ignored result tests
+ o appveyor: use random test server ports based upon APPVEYOR_API_URL [52]
+ o build: fixed build for systems with select() in unistd.h [43]
+ o buildconf: avoid using tempfile when removing files [90]
+ o checksrc: warn on obvious conditional blocks on the same line as if() [44]
+ o CI-fuzz: increase fuzz time to 40 minutes [59]
+ o ci/tests: fix Azure Pipelines not running Windows containers [25]
+ o CI: add build with ngtcp2 + gnutls on Travis CI
+ o CI: bring GitHub Actions fuzzing job in line with macOS jobs
+ o CI: migrate macOS jobs from Azure and Travis CI to GitHub Actions [36]
+ o CI: remove default Ubuntu build from GitHub Actions
+ o cirrus: no longer ignore test 504 which is working again
+ o cirrus: re-enable the FreeBSD 13 CI builds [29]
+ o cleanup: insert newline after if() conditions
+ o cmake: add aliases so exported target names are available in tree [73]
+ o cmake: add CMAKE_MSVC_RUNTIME_LIBRARY [45]
+ o cmake: add support for building with wolfSSL [9]
+ o cmake: Avoid MSVC C4273 warnings in send/recv checks [92]
+ o cmdline: fix handling of OperationConfig linked list (--next) [24]
+ o compressed.d: stress that the headers are not modified [80]
+ o config: remove all defines of HAVE_DES_H [37]
+ o configure: convert -I to -isystem as a last step [2]
+ o configure: document 'compiler_num' for gcc [4]
+ o configure: don't check for Security.framework when cross-compiling [47]
+ o configure: fix -pedantic-errors for GCC 5 and later [3]
+ o configure: remove use of -vec-report0 from CFLAGS with icc [71]
+ o connect: happy eyeballs cleanup [15]
+ o connect: store connection info for QUIC connections [68]
+ o copyright: fix out-of-date copyright ranges and missing headers [38]
+ o curl-functions.m4: remove inappropriate AC_REQUIRE [26]
+ o curl.h: remnove CURL_VERSION_ESNI. Never supported nor documented [49]
+ o curl.h: update comment typo [61]
+ o curl: allow both --etag-compare and --etag-save with same file name [56]
+ o curl_setup: define _WIN32_WINNT_[OS] symbols [27]
+ o CURLINFO_CONDITION_UNMET: return true for 304 http status code [54]
+ o CURLINFO_NUM_CONNECTS: improve accuracy [28]
+ o CURLOPT_WRITEFUNCTION.3: add inline example and new see-also [70]
+ o dist: add mail-rcpt-allowfails.d to the tarball [35]
+ o docs/make: generate curl.1 from listed files only [33]
+ o docs: add warnings about FILE: URLs on Windows [19]
+ o easy: fix curl_easy_duphandle for builds missing IPv6 that use c-ares [18]
+ o examples/sessioninfo.c: add include to fix compiler warning [42]
+ o github actions: run when pushed to master or */ci + PRs [64]
+ o gnutls: bump lowest supported version to 3.1.10 [89]
+ o gnutls: Don't skip really long certificate fields [86]
+ o gnutls: ensure TLS 1.3 when SRP isn't requested [79]
+ o gopher: check remaining time left during write busy loop [78]
+ o gskit: use our internal select wrapper for portability [12]
+ o http2: Fix erroneous debug message that h2 connection closed [21]
+ o http: don't consider upload done if the request isn't completely sent off 
[67]
+ o http: free memory when Alt-Used header creation fails due to OOM [98]
+ o lib/mk-ca-bundle: skip empty certs [112]
+ o lib670: use the same Win32 API check as all other lib tests
+ o lib: fix typos in comments and errormessages
+ o lib: never define CURL_CA_BUNDLE with a getenv [51]
+ o libcurl-multi.3: added missing full stop [110]
+ o libssh: avoid options override by configuration files [104]
+ o libssh: Use new ECDSA key types to check known hosts [87]
+ o mailmap: fixup a few author names/fields
+ o Makefile.m32: Improve windres parameter compatibility [17]
+ o Makefile: run the cd commands in a subshell [1]
+ o memdebug: don't log free(NULL)
+ o mime: properly check Content-Type even if it has parameters [83]
+ o multi-ssl: reset the SSL backend on `Curl_global_cleanup()` [100]
+ o multi: improve parameter check for curl_multi_remove_handle [6]
+ o nghttp2: 1.12.0 required [40]
+ o ngtcp2: update to git master for the key installation API change [46]
+ o nss: check for PK11_CreateDigestContext() returning NULL [96]
+ o openssl: adapt to functions marked as deprecated since version 3 [34]
+ o OS400: update strings for ccsid-ifier (fixes the build) [30]
+ o output.d: quote the URL when globbing [48]
+ o packages: add OS400/chkstrings.c to the dist [39]
+ o RELEASE-PROCEDURE.md: run the copyright.pl script!
+ o Revert "file: on Windows, refuse paths that start with \\" [50]
+ o runtests: always put test number in servercmd file
+ o runtests: provide nicer errormsg when protocol "dump" file is empty
+ o schannel: Fix blocking timeout logic [76]
+ o schannel: support .P12 or .PFX client certificates [65]
+ o scripts/release-notes.pl: add helper script for RELEASE-NOTES maintenance
+ o select: make Curl_socket_check take timediff_t timeout [109]
+ o select: move duplicate select preparation code into Curl_select [14]
+ o select: remove typecast from SOCKET_WRITABLE/READABLE macros [69]
+ o server/getpart: make the "XML-parser" stricter [20]
+ o server/resolve: remove AI_CANONNAME to make macos tell the truth [63]
+ o smtp: set auth correctly [103]
+ o sockfilt: add logmsg output to select_ws_wait_thread on Windows [32]
+ o sockfilt: fix broken pipe on Windows to be ready in select_ws [95]
+ o sockfilt: fix handling of ready closed sockets on Windows
+ o sockfilt: fix race-condition of waiting threads and event handling [58]
+ o socks: Fix blocking timeout logic [77]
+ o src: Remove C99 constructs to ensure C89 compliance [82]
+ o SSLCERTS.md: Fix example code for setting CA cert file [31]
+ o test1148: tolerate progress updates better (again) [60]
+ o test1154: set a proper name
+ o test1177: verify that all the CURL_VERSION_ bits are documented
+ o test1566: verify --etag-compare that gets a 304 back [53]
+ o test1908: avoid using fixed port number in test data [75]
+ o test2043: use revoked.badssl.com instead of revoked.grc.com [94]
+ o test2100: fix static port instead of dynamic value being used
+ o tests/data: fix some XML formatting issues in test cases
+ o tests/FILEFORMAT: converted to markdown and extended [84]
+ o tests/server/util.c: use curl_off_t instead of long for pid
+ o tests: add %NOLISTENPORT and use it [93]
+ o tests: add Windows compatible pidwait like pidkill and pidterm
+ o tests: fix conflict between Cygwin/msys and Windows PIDs [81]
+ o tests: introduce preprocessed test cases
+ o tests: make Python-based servers compatible with Python 2 and 3 [22]
+ o tests: make runtests check that disabled tests exists [108]
+ o tests: move pingpong server to dynamic listening port
+ o tests: remove python_dependencies for smbserver from our tree [16]
+ o tests: run the RTSP test server on a dynamic port number [91]
+ o tests: run the SOCKS test server on a dynamic port number [99]
+ o tests: run the sws server on "any port" [85]
+ o tests: run the TFTP test server on a dynamic port number [101]
+ o tests: use Cygwin/msys PIDs for stunnel and sshd on Windows
+ o tls: remove the BACKEND define kludge from most backends [23]
+ o tool: do not declare functions with Curl_ prefix [66]
+ o tool_operate: fix add_parallel_transfers when more are in queue [10]
+ o transfer: cap retries of "dead connections" to 5 [13]
+ o transfer: Switch PUT to GET/HEAD on 303 redirect [111]
+ o travis: bump the wolfssl CI build to use 4.4.0 [97]
+ o travis: update the ngtcp2 build to use the latest OpenSSL patch
+ o url: allow non-HTTPS altsvc-matching for debug builds [62]
+ o version: add 'cainfo' and 'capath' to version info struct [55]
+ o version: increase buffer space for ssl version output [74]
+ o version: skip idn2_check_version() check and add precaution [113]
+ o vquic: add support for GnuTLS backend of ngtcp2 [41]
+ o vtls: fix ssl_config memory-leak on out-of-memory [11]
+ o warnless: remove code block for icc that didn't work [72]
+ o windows: enable UnixSockets with all build toolchains
+ o windows: suppress UI in all CryptAcquireContext() calls [7]
 
 This release includes the following known bugs:
 
@@ -43,38 +158,133 @@ This release includes the following known bugs:
 This release would not have looked like this without help, code, reports and
 advice from friends like these:
 
-  amishmm on github, Anders Berg, Andy Fiddaman, Christopher Reid,
-  Dan Fandrich, Daniel Stenberg, Ernst Sjöstrand, fds242 on github,
-  Fedor Korotkov, Felipe Gasper, Jim Fuller, Marcel Raad, Marc Hörsken,
-  MrdUkk on github, Patrick Monnerat, Ray Satiro, RuurdBeerstra on github,
-  Steve Holme, vitaha85 on github,
-  (19 contributors)
+  Alain Miniussi, Alexander V. Tikhonov, Alex Gaynor,
+  Anderson Toshiyuki Sasaki, Andrew Kurushin, Ashwin Metpalli, Björn Stenberg,
+  Brad King, Brian Bergeron, Calvin Buckley, Chris Roberts, Christoph Krey,
+  Clément Notin, Daiki Ueno, Dan Fandrich, Daniel Gustafsson, Daniel Stenberg,
+  davidedec on github, Dennis Felsing, Dima Tisnek, Dirkjan Bussink,
+  Emil Engler, Eric Sauvageau, Eylem Ugurel, Frank Gevaerts,
+  FuccDucc on github, Gavin Wong, Gilles Vollant, Gisle Vanem, Hao Wu,
+  Harry Sintonen, hydra3333 on github, James Fuller, Johannes Schindelin,
+  Jon Rumsey, JP Mens, Kamil Dudka, Karl Chen, Kwon-Young Choi, Leo Neat,
+  Maksim Stsepanenka, Marcel Raad, Marc Hörsken, Markus Olsson, Mathias Gumz,
+  Michael Kaufmann, Michael Osipov, Muhammad Herdiansyah, Nathaniel R. Lewis,
+  Patrick Monnerat, Paul Vixie, Ray Satiro, Rici Lake, Rikard Falkeborn,
+  Roger Orr, Ross Burton, Simon Chalifoux, Stepan Efremov, Steven Penny,
+  thanhchungbtc on github, Timothe Litt, Tim Sedlmeyer, Tommy Petty,
+  Viktor Szakats, Yuri Slobodyanyuk,
+  (65 contributors)
 
         Thanks! (and sorry if I forgot to mention someone)
 
 References to bug reports and discussions on issues:
 
- [1] = https://curl.haxx.se/bug/?i=5035
- [2] = https://curl.haxx.se/bug/?i=5033
- [3] = https://curl.haxx.se/bug/?i=5028
- [4] = https://curl.haxx.se/bug/?i=5055
- [5] = https://curl.haxx.se/bug/?i=5049
- [6] = https://curl.haxx.se/bug/?i=5053
- [7] = https://curl.haxx.se/bug/?i=4971
- [8] = https://curl.haxx.se/bug/?i=5050
- [9] = https://curl.haxx.se/bug/?i=5024
- [10] = https://curl.haxx.se/bug/?i=5026
- [11] = https://curl.haxx.se/mail/lib-2020-03/0019.html
- [12] = https://curl.haxx.se/bug/?i=5047
- [13] = https://curl.haxx.se/bug/?i=5046
- [14] = https://curl.haxx.se/bug/?i=5061
- [15] = https://curl.haxx.se/bug/?i=5030
- [16] = https://curl.haxx.se/bug/?i=5037
- [17] = https://curl.haxx.se/bug/?i=4860
- [18] = https://curl.haxx.se/bug/?i=4826
- [19] = https://curl.haxx.se/bug/?i=4813
- [20] = https://curl.haxx.se/bug/?i=4893
- [21] = https://curl.haxx.se/bug/?i=5010
- [22] = https://curl.haxx.se/bug/?i=5041
- [23] = https://curl.haxx.se/bug/?i=5065
- [24] = https://curl.haxx.se/bug/?i=5064
+ [1] = https://curl.haxx.se/bug/?i=5073
+ [2] = https://curl.haxx.se/bug/?i=5060
+ [3] = https://curl.haxx.se/bug/?i=5067
+ [4] = https://curl.haxx.se/bug/?i=5069
+ [5] = https://curl.haxx.se/bug/?i=4981
+ [6] = https://curl.haxx.se/bug/?i=5116
+ [7] = https://curl.haxx.se/bug/?i=5088
+ [8] = https://curl.haxx.se/bug/?i=4870
+ [9] = https://curl.haxx.se/bug/?i=5095
+ [10] = https://curl.haxx.se/bug/?i=4937
+ [11] = https://curl.haxx.se/bug/?i=5108
+ [12] = https://curl.haxx.se/bug/?i=5106
+ [13] = https://curl.haxx.se/mail/lib-2020-03/0044.html
+ [14] = https://curl.haxx.se/bug/?i=5078
+ [15] = https://curl.haxx.se/bug/?i=4954
+ [16] = https://curl.haxx.se/bug/?i=5094
+ [17] = https://curl.haxx.se/bug/?i=5099
+ [18] = https://curl.haxx.se/bug/?i=5097
+ [19] = https://curl.haxx.se/bug/?i=5066
+ [20] = https://curl.haxx.se/bug/?i=5071
+ [21] = https://curl.haxx.se/bug/?i=5118
+ [22] = https://curl.haxx.se/bug/?i=5104
+ [23] = https://curl.haxx.se/bug/?i=5122
+ [24] = https://curl.haxx.se/bug/?i=5120
+ [25] = https://curl.haxx.se/bug/?i=5117
+ [26] = https://curl.haxx.se/bug/?i=5126
+ [27] = https://curl.haxx.se/bug/?i=4995
+ [28] = https://curl.haxx.se/bug/?i=5135
+ [29] = https://curl.haxx.se/bug/?i=5091
+ [30] = https://curl.haxx.se/bug/?i=5132
+ [31] = https://curl.haxx.se/mail/lib-2020-03/0121.html
+ [32] = https://curl.haxx.se/bug/?i=5086
+ [33] = https://curl.haxx.se/bug/?i=5149
+ [34] = https://curl.haxx.se/bug/?i=5139
+ [35] = https://curl.haxx.se/bug/?i=5146
+ [36] = https://curl.haxx.se/bug/?i=5124
+ [37] = https://curl.haxx.se/bug/?i=5144
+ [38] = https://curl.haxx.se/bug/?i=5141
+ [39] = https://curl.haxx.se/bug/?i=5142
+ [40] = https://curl.haxx.se/bug/?i=5140
+ [41] = https://curl.haxx.se/bug/?i=5148
+ [42] = https://curl.haxx.se/bug/?i=5171
+ [43] = https://curl.haxx.se/bug/?i=5169
+ [44] = https://curl.haxx.se/bug/?i=5164
+ [45] = https://curl.haxx.se/bug/?i=5165
+ [46] = https://curl.haxx.se/bug/?i=5166
+ [47] = https://curl.haxx.se/bug/?i=5189
+ [48] = https://curl.haxx.se/bug/?i=5160
+ [49] = https://curl.haxx.se/bug/?i=5157
+ [50] = https://curl.haxx.se/mail/archive-2020-04/0013.html
+ [51] = https://github.com/curl/curl/commit/6de756c#r38127030
+ [52] = https://curl.haxx.se/bug/?i=5034
+ [53] = https://curl.haxx.se/bug/?i=5186
+ [54] = https://curl.haxx.se/bug/?i=5181
+ [55] = https://curl.haxx.se/bug/?i=5150
+ [56] = https://curl.haxx.se/bug/?i=5179
+ [57] = https://curl.haxx.se/bug/?i=5173
+ [58] = https://curl.haxx.se/bug/?i=5156
+ [59] = https://curl.haxx.se/bug/?i=5174
+ [60] = https://curl.haxx.se/bug/?i=5194
+ [61] = https://curl.haxx.se/bug/?i=5279
+ [62] = https://curl.haxx.se/bug/?i=5205
+ [63] = https://curl.haxx.se/bug/?i=5202
+ [64] = https://curl.haxx.se/bug/?i=5201
+ [65] = https://curl.haxx.se/bug/?i=5193
+ [66] = https://curl.haxx.se/bug/?i=5219
+ [67] = https://curl.haxx.se/bug/?i=4919
+ [68] = https://curl.haxx.se/bug/?i=5196
+ [69] = https://curl.haxx.se/bug/?i=5190
+ [70] = https://curl.haxx.se/bug/?i=5192
+ [71] = https://curl.haxx.se/bug/?i=5096
+ [72] = https://curl.haxx.se/bug/?i=5096
+ [73] = https://curl.haxx.se/bug/?i=5206
+ [74] = https://curl.haxx.se/bug/?i=5222
+ [75] = https://curl.haxx.se/bug/?i=5225
+ [76] = https://curl.haxx.se/bug/?i=5177
+ [77] = https://curl.haxx.se/bug/?i=5220
+ [78] = https://curl.haxx.se/bug/?i=5214
+ [79] = https://curl.haxx.se/bug/?i=5223
+ [80] = https://github.com/curl/curl/issues/5182#issuecomment-611638008
+ [81] = https://curl.haxx.se/bug/?i=5188
+ [82] = https://curl.haxx.se/bug/?i=5254
+ [83] = https://curl.haxx.se/bug/?i=5256
+ [84] = https://curl.haxx.se/bug/?i=5261
+ [85] = https://curl.haxx.se/bug/?i=5247
+ [86] = https://curl.haxx.se/bug/?i=5271
+ [87] = https://curl.haxx.se/bug/?i=5252
+ [88] = https://curl.haxx.se/bug/?i=5063
+ [89] = https://curl.haxx.se/bug/?i=5276
+ [90] = https://curl.haxx.se/bug/?i=5213
+ [91] = https://curl.haxx.se/bug/?i=5272
+ [92] = https://curl.haxx.se/bug/?i=4764
+ [93] = https://curl.haxx.se/bug/?i=5270
+ [94] = https://curl.haxx.se/bug/?i=5233
+ [95] = https://curl.haxx.se/bug/?i=5228
+ [96] = https://curl.haxx.se/bug/?i=5302
+ [97] = https://curl.haxx.se/bug/?i=5301
+ [98] = https://curl.haxx.se/bug/?i=5268
+ [99] = https://curl.haxx.se/bug/?i=5266
+ [100] = https://curl.haxx.se/bug/?i=5255
+ [101] = https://curl.haxx.se/bug/?i=5265
+ [103] = https://curl.haxx.se/bug/?i=5294
+ [104] = https://curl.haxx.se/bug/?i=4972
+ [108] = https://curl.haxx.se/bug/?i=5288
+ [109] = https://curl.haxx.se/bug/?i=5240
+ [110] = https://curl.haxx.se/bug/?i=5285
+ [111] = https://curl.haxx.se/bug/?i=5237
+ [112] = https://curl.haxx.se/bug/?i=5278
+ [113] = https://curl.haxx.se/bug/?i=5281
diff --git a/SECURITY.md b/SECURITY.md
index 871c06a50..4e84fbefc 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -7,4 +7,4 @@ See [docs/SECURITY-PROCESS.md](docs/SECURITY-PROCESS.md) for 
full details.
 If you have found or just suspect a security problem somewhere in curl or 
libcurl,
 report it on [https://hackerone.com/curl](https://hackerone.com/curl).
 
-We treat security issuse with confidentiality until disclosed controlled and 
responsibly.
+We treat security issues with confidentiality until controlled and disclosed 
responsibly.
diff --git a/acinclude.m4 b/acinclude.m4
index 3ad55c388..089449bac 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1887,6 +1887,8 @@ struct Library *SocketBase = NULL;
 #endif
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#include <unistd.h>
 #endif
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
@@ -1950,6 +1952,8 @@ struct Library *SocketBase = NULL;
 #endif
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#include <unistd.h>
 #endif
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
diff --git a/appveyor.yml b/appveyor.yml
index 25361a0b6..b092480c5 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,7 +1,30 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
 version: 7.50.0.{build}
 
 environment:
     matrix:
+      # generated CMake-based Visual Studio Release builds
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
         BUILD_SYSTEM: CMake
         PRJ_GEN: "Visual Studio 9 2008"
@@ -17,26 +40,27 @@ environment:
         BUILD_SYSTEM: CMake
         PRJ_GEN: "Visual Studio 16 2019"
         TARGET: "-A x64"
-        PRJ_CFG: Debug
-        OPENSSL: OFF
-        WINSSL: ON
+        PRJ_CFG: Release
+        OPENSSL: ON
+        WINSSL: OFF
         HTTP_ONLY: OFF
-        TESTING: ON
-        SHARED: OFF
-        DISABLED_TESTS: "!1139"
+        TESTING: OFF
+        SHARED: ON
+        DISABLED_TESTS: ""
         COMPILER_PATH: ""
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
         BUILD_SYSTEM: CMake
         PRJ_GEN: "Visual Studio 16 2019"
-        TARGET: "-A x64"
+        TARGET: "-A ARM64"
         PRJ_CFG: Release
-        OPENSSL: ON
-        WINSSL: OFF
+        OPENSSL: OFF
+        WINSSL: ON
         HTTP_ONLY: OFF
         TESTING: OFF
-        SHARED: ON
+        SHARED: OFF
         DISABLED_TESTS: ""
         COMPILER_PATH: ""
+      # generated CMake-based Visual Studio Debug builds
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
         BUILD_SYSTEM: CMake
         PRJ_GEN: "Visual Studio 10 2010 Win64"
@@ -46,7 +70,19 @@ environment:
         HTTP_ONLY: OFF
         TESTING: ON
         SHARED: OFF
-        DISABLED_TESTS: "!1139"
+        DISABLED_TESTS: "~1139"
+        COMPILER_PATH: ""
+      - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
+        BUILD_SYSTEM: CMake
+        PRJ_GEN: "Visual Studio 16 2019"
+        TARGET: "-A x64"
+        PRJ_CFG: Debug
+        OPENSSL: OFF
+        WINSSL: ON
+        HTTP_ONLY: OFF
+        TESTING: ON
+        SHARED: OFF
+        DISABLED_TESTS: "~1139"
         COMPILER_PATH: ""
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
         BUILD_SYSTEM: CMake
@@ -58,7 +94,7 @@ environment:
         HTTP_ONLY: OFF
         TESTING: ON
         SHARED: OFF
-        DISABLED_TESTS: "!1139"
+        DISABLED_TESTS: "~1139"
         COMPILER_PATH: ""
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
         BUILD_SYSTEM: CMake
@@ -70,21 +106,35 @@ environment:
         HTTP_ONLY: ON
         TESTING: ON
         SHARED: OFF
-        DISABLED_TESTS: "!1139"
+        DISABLED_TESTS: "~1139"
         COMPILER_PATH: ""
+      # generated CMake-based MSYS Makefiles builds
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
         BUILD_SYSTEM: CMake
         PRJ_GEN: "MSYS Makefiles"
         PRJ_CFG: Debug
         OPENSSL: OFF
-        WINSSL: OFF
+        WINSSL: ON
         HTTP_ONLY: OFF
         TESTING: ON
         SHARED: OFF
-        DISABLED_TESTS: "!1139"
+        DISABLED_TESTS: "~1139"
         COMPILER_PATH: 
"C:\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin"
         MSYS2_ARG_CONV_EXCL: "/*"
         BUILD_OPT: -k
+      - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+        BUILD_SYSTEM: CMake
+        PRJ_GEN: "MSYS Makefiles"
+        PRJ_CFG: Debug
+        OPENSSL: OFF
+        WINSSL: ON
+        HTTP_ONLY: OFF
+        TESTING: ON
+        SHARED: OFF
+        DISABLED_TESTS: "~1139"
+        COMPILER_PATH: 
"C:\\mingw-w64\\x86_64-7.2.0-posix-seh-rt_v5-rev1\\mingw64\\bin"
+        MSYS2_ARG_CONV_EXCL: "/*"
+        BUILD_OPT: -k
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
         BUILD_SYSTEM: CMake
         PRJ_GEN: "MSYS Makefiles"
@@ -94,7 +144,7 @@ environment:
         HTTP_ONLY: OFF
         TESTING: ON
         SHARED: OFF
-        DISABLED_TESTS: "!1139"
+        DISABLED_TESTS: "~1139"
         COMPILER_PATH: 
"C:\\mingw-w64\\i686-6.3.0-posix-dwarf-rt_v5-rev1\\mingw32\\bin"
         MSYS2_ARG_CONV_EXCL: "/*"
         BUILD_OPT: -k
@@ -107,52 +157,76 @@ environment:
         HTTP_ONLY: OFF
         TESTING: ON
         SHARED: OFF
-        DISABLED_TESTS: "!1139"
+        DISABLED_TESTS: "~1139"
         COMPILER_PATH: "C:\\MinGW\\bin"
         MSYS2_ARG_CONV_EXCL: "/*"
         BUILD_OPT: -k
+      # winbuild-based builds
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
         BUILD_SYSTEM: winbuild_vs2015
         DEBUG: yes
         PATHPART: debug
         TESTING: OFF
+        ENABLE_UNICODE: no
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
         BUILD_SYSTEM: winbuild_vs2015
         DEBUG: no
         PATHPART: release
         TESTING: OFF
+        ENABLE_UNICODE: no
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
         BUILD_SYSTEM: winbuild_vs2017
         DEBUG: yes
         PATHPART: debug
         TESTING: OFF
+        ENABLE_UNICODE: no
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
         BUILD_SYSTEM: winbuild_vs2017
         DEBUG: no
         PATHPART: release
         TESTING: OFF
+        ENABLE_UNICODE: no
+      - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+        BUILD_SYSTEM: winbuild_vs2015
+        DEBUG: yes
+        PATHPART: debug
+        TESTING: OFF
+        ENABLE_UNICODE: yes
+      - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+        BUILD_SYSTEM: winbuild_vs2015
+        DEBUG: no
+        PATHPART: release
+        TESTING: OFF
+        ENABLE_UNICODE: yes
+      - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+        BUILD_SYSTEM: winbuild_vs2017
+        DEBUG: yes
+        PATHPART: debug
+        TESTING: OFF
+        ENABLE_UNICODE: yes
+      - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+        BUILD_SYSTEM: winbuild_vs2017
+        DEBUG: no
+        PATHPART: release
+        TESTING: OFF
+        ENABLE_UNICODE: yes
+      # generated VisualStudioSolution-based builds
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
         BUILD_SYSTEM: VisualStudioSolution
         PRJ_CFG: "DLL Debug - DLL Windows SSPI - DLL WinIDN"
         TESTING: OFF
         VC_VERSION: VC15
-      - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
-        BUILD_SYSTEM: CMake
-        PRJ_GEN: "Visual Studio 16 2019"
-        TARGET: "-A ARM64"
-        PRJ_CFG: Release
-        OPENSSL: OFF
-        WINSSL: ON
-        HTTP_ONLY: OFF
-        TESTING: OFF
-        SHARED: OFF
-        DISABLED_TESTS: ""
-        COMPILER_PATH: ""
+      # autotools-based builds
       - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
         BUILD_SYSTEM: autotools
         TESTING: ON
-        DISABLED_TESTS: "!19 !1056 !1233 !1242 !1243 !2002 !2003"
+        DISABLED_TESTS: "!19 !1233 ~1242 ~1243 ~2002 ~2003"
         CONFIG_ARGS: "--enable-debug --enable-werror --enable-alt-svc 
--disable-threaded-resolver --disable-proxy"
+      - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
+        BUILD_SYSTEM: autotools
+        TESTING: ON
+        DISABLED_TESTS: "!19 !504 !704 !705 !1233 ~1242 ~1243 ~2002 ~2003"
+        CONFIG_ARGS: "--enable-debug --enable-werror --enable-alt-svc 
--disable-threaded-resolver"
 
 install:
     - set "PATH=C:\msys64\usr\bin;%PATH%"
@@ -187,14 +261,14 @@ build_script:
         cd winbuild &&
         call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" 
/x64 &&
         call "C:\Program Files (x86)\Microsoft Visual Studio 
14.0\VC\vcvarsall.bat" x86_amd64 &&
-        nmake /f Makefile.vc mode=dll VC=14 "SSL_PATH=C:\OpenSSL-v111-Win64" 
WITH_SSL=dll MACHINE=x64 DEBUG=%DEBUG% &&
+        nmake /f Makefile.vc mode=dll VC=14 "SSL_PATH=C:\OpenSSL-v111-Win64" 
WITH_SSL=dll MACHINE=x64 DEBUG=%DEBUG% ENABLE_UNICODE=%ENABLE_UNICODE% &&
         
..\builds\libcurl-vc14-x64-%PATHPART%-dll-ssl-dll-ipv6-sspi\bin\curl.exe -V
       ) else (
       if %BUILD_SYSTEM%==winbuild_vs2017 (
         call buildconf.bat &&
         cd winbuild &&
         call "C:\Program Files (x86)\Microsoft Visual 
Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" &&
-        nmake /f Makefile.vc mode=dll VC=15 "SSL_PATH=C:\OpenSSL-v111-Win64" 
WITH_SSL=dll MACHINE=x64 DEBUG=%DEBUG% &&
+        nmake /f Makefile.vc mode=dll VC=15 "SSL_PATH=C:\OpenSSL-v111-Win64" 
WITH_SSL=dll MACHINE=x64 DEBUG=%DEBUG% ENABLE_UNICODE=%ENABLE_UNICODE% &&
         
..\builds\libcurl-vc15-x64-%PATHPART%-dll-ssl-dll-ipv6-sspi\bin\curl.exe -V
       ) else (
       if %BUILD_SYSTEM%==autotools (
@@ -203,7 +277,8 @@ build_script:
 
 test_script:
     - if %TESTING%==ON (
-        bash.exe -e -l -c "cd /c/projects/curl/tests && ./runtests.pl -a -p 
!flaky %DISABLED_TESTS%" )
+        echo APPVEYOR_API_URL=%APPVEYOR_API_URL% &&
+        bash.exe -e -l -c "cd /c/projects/curl/tests && ./runtests.pl -a 
-b$(($(echo '%APPVEYOR_API_URL%' | cut -d'/' -f3 | cut -d':' -f2)+1)) -p !flaky 
%DISABLED_TESTS%" )
 
 # whitelist branches to avoid testing feature branches twice (as branch and as 
pull request)
 branches:
diff --git a/buildconf b/buildconf
index 2005383e4..c9c8a8e8a 100755
--- a/buildconf
+++ b/buildconf
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -64,16 +64,7 @@ findtool(){
 #
 removethis(){
   if test "$#" = "1"; then
-    find . -depth -name $1 -print > buildconf.tmp.$$
-    while read fdname
-    do
-      if test -f "$fdname"; then
-        rm -f "$fdname"
-      elif test -d "$fdname"; then
-        rm -f -r "$fdname"
-      fi
-    done < buildconf.tmp.$$
-    rm -f buildconf.tmp.$$
+    find . -depth -name $1 -execdir rm -rf {} \;
   fi
 }
 
@@ -293,9 +284,6 @@ for fname in .deps \
     Makefile.in \
     aclocal.m4 \
     aclocal.m4.bak \
-    ares_build.h \
-    ares_config.h \
-    ares_config.h.in \
     autom4te.cache \
     compile \
     config.guess \
diff --git a/configure.ac b/configure.ac
index a7fec097f..741b4249b 100755
--- a/configure.ac
+++ b/configure.ac
@@ -59,19 +59,6 @@ XC_CHECK_PATH_SEPARATOR
 CONFIGURE_OPTIONS="\"$ac_configure_args\""
 AC_SUBST(CONFIGURE_OPTIONS)
 
-CURL_CFLAG_EXTRAS=""
-if test X"$want_werror" = Xyes; then
-  CURL_CFLAG_EXTRAS="-Werror"
-  if test "$compiler_id" = "GNU_C"; then
-    dnl enable -pedantic-errors for GCC 5 and later,
-    dnl as before that it was the same as -Werror=pedantic
-    if test "$compiler_num" -ge "500"; then
-      CURL_CFLAG_EXTRAS="$CURL_CFLAG_EXTRAS -pedantic-errors"
-    fi
-  fi
-fi
-AC_SUBST(CURL_CFLAG_EXTRAS)
-
 dnl SED is mandatory for configure process and libtool.
 dnl Set it now, allowing it to be changed later.
 if test -z "$SED"; then
@@ -311,6 +298,19 @@ if test "$compiler_id" = "INTEL_UNIX_C"; then
   #
 fi
 
+CURL_CFLAG_EXTRAS=""
+if test X"$want_werror" = Xyes; then
+  CURL_CFLAG_EXTRAS="-Werror"
+  if test "$compiler_id" = "GNU_C"; then
+    dnl enable -pedantic-errors for GCC 5 and later,
+    dnl as before that it was the same as -Werror=pedantic
+    if test "$compiler_num" -ge "500"; then
+      CURL_CFLAG_EXTRAS="$CURL_CFLAG_EXTRAS -pedantic-errors"
+    fi
+  fi
+fi
+AC_SUBST(CURL_CFLAG_EXTRAS)
+
 CURL_CHECK_COMPILER_HALT_ON_ERROR
 CURL_CHECK_COMPILER_ARRAY_SIZE_NEGATIVE
 CURL_CHECK_COMPILER_PROTOTYPE_MISMATCH
@@ -718,6 +718,22 @@ AC_HELP_STRING([--disable-gopher],[Disable Gopher 
support]),
        AC_MSG_RESULT(yes)
 )
 
+AC_MSG_CHECKING([whether to support mqtt])
+AC_ARG_ENABLE(mqtt,
+AC_HELP_STRING([--enable-mqtt],[Enable MQTT support])
+AC_HELP_STRING([--disable-mqtt],[Disable MQTT support]),
+[ case "$enableval" in
+  no)
+       AC_MSG_RESULT(no)
+       ;;
+  *)   AC_MSG_RESULT(yes)
+       experimental="$experimental MQTT"
+       AC_DEFINE(CURL_ENABLE_MQTT, 1, [to enable MQTT])
+       AC_SUBST(CURL_ENABLE_MQTT, [1])
+       ;;
+  esac ],
+       AC_MSG_RESULT(no)
+)
 
 dnl **********************************************************************
 dnl Check for built-in manual
@@ -1637,7 +1653,7 @@ AC_HELP_STRING([--without-secure-transport], [disable 
Apple OS native SSL/TLS]),
 AC_MSG_CHECKING([whether to enable Secure Transport])
 if test -z "$ssl_backends" -o "x$OPT_SECURETRANSPORT" != xno; then
   if test "x$OPT_SECURETRANSPORT" != "xno" &&
-     test -d "/System/Library/Frameworks/Security.framework"; then
+     (test "x$cross_compiling" != "xno" || test -d 
"/System/Library/Frameworks/Security.framework"); then
     AC_MSG_RESULT(yes)
     AC_DEFINE(USE_SECTRANSP, 1, [enable Secure Transport])
     AC_SUBST(USE_SECTRANSP, [1])
@@ -1960,6 +1976,31 @@ if test -z "$ssl_backends" -o "x$OPT_SSL" != xno &&
     ],[
       AC_MSG_RESULT([no])
     ])
+
+    AC_MSG_CHECKING([for OpenSSL >= v3])
+    AC_COMPILE_IFELSE([
+      AC_LANG_PROGRAM([[
+#include <openssl/opensslv.h>
+      ]],[[
+        #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
+        return 0;
+        #else
+        #error older than 3
+        #endif
+      ]])
+    ],[
+      AC_MSG_RESULT([yes])
+      AC_DEFINE_UNQUOTED(HAVE_OPENSSL3, 1,
+        [Define to 1 if using OpenSSL 3 or later.])
+      dnl OpenSSLv3 marks the DES functions deprecated but we have no
+      dnl replacements (yet) so tell the compiler to not warn for them
+      dnl
+      dnl Ask OpenSSL to suppress the warnings.
+      CPPFLAGS="$CPPFLAGS -DOPENSSL_SUPPRESS_DEPRECATED"
+      ssl_msg="OpenSSL v3+"
+    ],[
+      AC_MSG_RESULT([no])
+    ])
   fi
 
   if test "$OPENSSL_ENABLED" = "1"; then
@@ -2130,7 +2171,8 @@ if test -z "$ssl_backends" -o "x$OPT_GNUTLS" != xno; then
          CPPFLAGS="$CPPFLAGS $addcflags"
       fi
 
-      AC_CHECK_LIB(gnutls, gnutls_check_version,
+      dnl this function is selected since it was introduced in 3.1.10
+      AC_CHECK_LIB(gnutls, gnutls_x509_crt_get_dn2,
        [
        AC_DEFINE(USE_GNUTLS, 1, [if GnuTLS is enabled])
        AC_SUBST(USE_GNUTLS, [1])
@@ -2158,7 +2200,6 @@ if test -z "$ssl_backends" -o "x$OPT_GNUTLS" != xno; then
             AC_MSG_NOTICE([Added $gtlslib to CURL_LIBRARY_PATH])
           fi
         fi
-        AC_CHECK_FUNCS([gnutls_certificate_set_x509_key_file2 
gnutls_alpn_set_protocols gnutls_ocsp_req_init])
       fi
 
     fi
@@ -3600,7 +3641,7 @@ if test X"$want_tcp2" != Xno; then
 
 fi
 
-if test "x$NGTCP2_ENABLED" = "x1"; then
+if test "x$NGTCP2_ENABLED" = "x1" -a "x$OPENSSL_ENABLED" = "x1"; then
   dnl backup the pre-ngtcp2_crypto_openssl variables
   CLEANLDFLAGS="$LDFLAGS"
   CLEANCPPFLAGS="$CPPFLAGS"
@@ -3655,6 +3696,61 @@ if test "x$NGTCP2_ENABLED" = "x1"; then
   fi
 fi
 
+if test "x$NGTCP2_ENABLED" = "x1" -a "x$GNUTLS_ENABLED" = "x1"; then
+  dnl backup the pre-ngtcp2_crypto_gnutls variables
+  CLEANLDFLAGS="$LDFLAGS"
+  CLEANCPPFLAGS="$CPPFLAGS"
+  CLEANLIBS="$LIBS"
+
+  CURL_CHECK_PKGCONFIG(libngtcp2_crypto_gnutls, $want_tcp2_path)
+
+  if test "$PKGCONFIG" != "no" ; then
+    LIB_NGTCP2_CRYPTO_GNUTLS=`CURL_EXPORT_PCDIR([$want_tcp2_path])
+      $PKGCONFIG --libs-only-l libngtcp2_crypto_gnutls`
+    AC_MSG_NOTICE([-l is $LIB_NGTCP2_CRYPTO_GNUTLS])
+
+    CPP_NGTCP2_CRYPTO_GNUTLS=`CURL_EXPORT_PCDIR([$want_tcp2_path]) dnl
+      $PKGCONFIG --cflags-only-I libngtcp2_crypto_gnutls`
+    AC_MSG_NOTICE([-I is $CPP_NGTCP2_CRYPTO_GNUTLS])
+
+    LD_NGTCP2_CRYPTO_GNUTLS=`CURL_EXPORT_PCDIR([$want_tcp2_path])
+      $PKGCONFIG --libs-only-L libngtcp2_crypto_gnutls`
+    AC_MSG_NOTICE([-L is $LD_NGTCP2_CRYPTO_GNUTLS])
+
+    LDFLAGS="$LDFLAGS $LD_NGTCP2_CRYPTO_GNUTLS"
+    CPPFLAGS="$CPPFLAGS $CPP_NGTCP2_CRYPTO_GNUTLS"
+    LIBS="$LIB_NGTCP2_CRYPTO_GNUTLS $LIBS"
+
+    if test "x$cross_compiling" != "xyes"; then
+      DIR_NGTCP2_CRYPTO_GNUTLS=`echo $LD_NGTCP2_CRYPTO_GNUTLS | $SED -e 
's/-L//'`
+    fi
+    AC_CHECK_LIB(ngtcp2_crypto_gnutls, ngtcp2_crypto_ctx_initial,
+      [
+       AC_CHECK_HEADERS(ngtcp2/ngtcp2_crypto.h,
+          NGTCP2_ENABLED=1
+          AC_DEFINE(USE_NGTCP2_CRYPTO_GNUTLS, 1, [if ngtcp2_crypto_gnutls is 
in use])
+          AC_SUBST(USE_NGTCP2_CRYPTO_GNUTLS, [1])
+          CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_NGTCP2_CRYPTO_GNUTLS"
+          export CURL_LIBRARY_PATH
+          AC_MSG_NOTICE([Added $DIR_NGTCP2_CRYPTO_GNUTLS to CURL_LIBRARY_PATH])
+       )
+      ],
+        dnl not found, revert back to clean variables
+        LDFLAGS=$CLEANLDFLAGS
+        CPPFLAGS=$CLEANCPPFLAGS
+        LIBS=$CLEANLIBS
+    )
+
+  else
+    dnl no ngtcp2_crypto_gnutls pkg-config found, deal with it
+    if test X"$want_tcp2" != Xdefault; then
+      dnl To avoid link errors, we do not allow --with-ngtcp2 without
+      dnl a pkgconfig file
+      AC_MSG_ERROR([--with-ngtcp2 was specified but could not find 
ngtcp2_crypto_gnutls pkg-config file.])
+    fi
+  fi
+fi
+
 dnl **********************************************************************
 dnl Check for nghttp3 (HTTP/3 with ngtcp2)
 dnl **********************************************************************
@@ -3959,6 +4055,8 @@ dnl default includes
 #endif
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#include <unistd.h>
 #endif
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
@@ -4363,6 +4461,8 @@ if test "$want_thres" = "yes" && test 
"x$USE_THREADS_POSIX" != "x1"; then
   fi
 fi
 
+CURL_CONVERT_INCLUDE_TO_ISYSTEM
+
 dnl ************************************************************
 dnl disable verbose text strings
 dnl
@@ -4863,6 +4963,9 @@ fi
 if test "x$CURL_DISABLE_GOPHER" != "x1"; then
   SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS GOPHER"
 fi
+if test "x$CURL_ENABLE_MQTT" = "x1"; then
+  SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS MQTT"
+fi
 if test "x$CURL_DISABLE_POP3" != "x1"; then
   SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS POP3"
   if test "x$SSL_ENABLED" = "x1"; then
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
index 694861725..22863bc0f 100644
--- a/docs/CMakeLists.txt
+++ b/docs/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #add_subdirectory(examples)
 add_subdirectory(libcurl)
 add_subdirectory(cmdline-opts)
diff --git a/docs/EXPERIMENTAL.md b/docs/EXPERIMENTAL.md
index 6c33bcf53..34974fba8 100644
--- a/docs/EXPERIMENTAL.md
+++ b/docs/EXPERIMENTAL.md
@@ -20,3 +20,4 @@ Experimental support in curl means:
 
  - HTTP/3 support and options
  - alt-svc support and options
+ - MQTT
diff --git a/docs/FEATURES b/docs/FEATURES
index 68d38fc27..1d23fccbf 100644
--- a/docs/FEATURES
+++ b/docs/FEATURES
@@ -180,6 +180,9 @@ IMAPS (*1)
  - explicit "STARTTLS" usage to "upgrade" plain imap:// connections to use SSL
  - via http-proxy
 
+MQTT
+ - Subscribe to and publish topics using url scheme mqtt://broker/topic
+
 FOOTNOTES
 =========
 
diff --git a/docs/HTTP2.md b/docs/HTTP2.md
index 5b4435f88..4c72a29b2 100644
--- a/docs/HTTP2.md
+++ b/docs/HTTP2.md
@@ -18,7 +18,7 @@ parts. The reason for this is that HTTP/2 is much more 
complex at that layer
 than HTTP/1.1 (which we implement on our own) and that nghttp2 is an already
 existing and well functional library.
 
-We require at least version 1.0.0.
+We require at least version 1.12.0.
 
 Over an http:// URL
 -------------------
diff --git a/docs/HTTP3.md b/docs/HTTP3.md
index 55bdd0263..2769439d6 100644
--- a/docs/HTTP3.md
+++ b/docs/HTTP3.md
@@ -29,7 +29,7 @@ in the master branch using pull-requests, just like ordinary 
changes.
 
 # ngtcp2 version
 
-## Build
+## Build with OpenSSL
 
 Build (patched) OpenSSL
 
@@ -68,6 +68,46 @@ Build curl
      % LDFLAGS="-Wl,-rpath,<somewhere1>/lib" ./configure 
--with-ssl=<somewhere1> --with-nghttp3=<somewhere2> --with-ngtcp2=<somewhere3> 
--enable-alt-svc
      % make
 
+## Build with GnuTLS
+
+Build (patched) GnuTLS
+
+     % git clone --depth 1 -b tmp-quic https://gitlab.com/gnutls/gnutls.git
+     % cd gnutls
+     % ./bootstrap
+     % ./configure --disable-doc --prefix=<somewhere1>
+     % make
+     % make install
+
+Build nghttp3
+
+     % cd ..
+     % git clone https://github.com/ngtcp2/nghttp3
+     % cd nghttp3
+     % autoreconf -i
+     % ./configure --prefix=<somewhere2> --enable-lib-only
+     % make
+     % make install
+
+Build ngtcp2
+
+     % cd ..
+     % git clone https://github.com/ngtcp2/ngtcp2
+     % cd ngtcp2
+     % autoreconf -i
+     % ./configure 
PKG_CONFIG_PATH=<somewhere1>/lib/pkgconfig:<somewhere2>/lib/pkgconfig 
LDFLAGS="-Wl,-rpath,<somewhere1>/lib" --prefix=<somewhere3>
+     % make
+     % make install
+
+Build curl
+
+     % cd ..
+     % git clone https://github.com/curl/curl
+     % cd curl
+     % ./buildconf
+     % ./configure --without-ssl --with-gnutls=<somewhere1> 
--with-nghttp3=<somewhere2> --with-ngtcp2=<somewhere3> --enable-alt-svc
+     % make
+
 # quiche version
 
 ## build
diff --git a/docs/INTERNALS.md b/docs/INTERNALS.md
index add8b417f..635e7b2d1 100644
--- a/docs/INTERNALS.md
+++ b/docs/INTERNALS.md
@@ -85,7 +85,7 @@ Dependencies
 ------------
 
  - OpenSSL      0.9.7
- - GnuTLS       2.11.3
+ - GnuTLS       3.1.10
  - zlib         1.1.4
  - libssh2      0.16
  - c-ares       1.6.0
diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS
index 26f21dc67..93cb36902 100644
--- a/docs/KNOWN_BUGS
+++ b/docs/KNOWN_BUGS
@@ -25,13 +25,13 @@ problems may have been fixed or changed somewhat since this 
was written!
  2. TLS
  2.1 CURLINFO_SSL_VERIFYRESULT has limited support
  2.2 DER in keychain
- 2.3 GnuTLS backend skips really long certificate fields
  2.4 DarwinSSL won't import PKCS#12 client certificates without a password
  2.5 Client cert handling with Issuer DN differs between backends
  2.6 CURL_GLOBAL_SSL
  2.7 Client cert (MTLS) issues with Schannel
  2.8 Schannel disable CURLOPT_SSL_VERIFYPEER and verify hostname
  2.9 TLS session cache doesn't work with TFO
+ 2.10 Store TLS context per transfer instead of per connection
 
  3. Email protocols
  3.1 IMAP SEARCH ALL truncated response
@@ -47,7 +47,6 @@ problems may have been fixed or changed somewhat since this 
was written!
  4.5 Improve --data-urlencode space encoding
 
  5. Build and portability issues
- 5.1 USE_UNIX_SOCKETS on Windows
  5.2 curl-config --libs contains private details
  5.3 curl compiled on OSX 10.13 failed to run on OSX 10.10
  5.4 Cannot compile against a static build of OpenLDAP
@@ -78,7 +77,7 @@ problems may have been fixed or changed somewhat since this 
was written!
  7.7 FTP and empty path parts in the URL
  7.8 Premature transfer end but healthy control channel
  7.9 Passive transfer tries only one IP address
- 7.10 Stick to same family over SOCKS proxy
+ 7.10 FTPS needs session reuse
 
  8. TELNET
  8.1 TELNET and time limitations don't work
@@ -99,6 +98,9 @@ problems may have been fixed or changed somewhat since this 
was written!
  11.5 Connection information when using TCP Fast Open
  11.6 slow connect to localhost on Windows
  11.7 signal-based resolver timeouts
+ 11.8 DoH leaks memory after followlocation
+ 11.9 DoH doesn't inherit all transfer options
+ 11.10 Blocking socket operations in non-blocking API
 
  12. LDAP and OpenLDAP
  12.1 OpenLDAP hangs after returning results
@@ -206,12 +208,6 @@ problems may have been fixed or changed somewhat since 
this was written!
  Curl doesn't recognize certificates in DER format in keychain, but it works
  with PEM.  https://curl.haxx.se/bug/view.cgi?id=1065
 
-2.3 GnuTLS backend skips really long certificate fields
-
- libcurl calls gnutls_x509_crt_get_dn() with a fixed buffer size and if the
- field is too long in the cert, it'll just return an error and the field will
- be displayed blank.
-
 2.4 DarwinSSL won't import PKCS#12 client certificates without a password
 
  libcurl calls SecPKCS12Import with the PKCS#12 client certificate, but that
@@ -268,6 +264,16 @@ problems may have been fixed or changed somewhat since 
this was written!
 
  See https://github.com/curl/curl/issues/4301
 
+2.10 Store TLS context per transfer instead of per connection
+
+ The GnuTLS `backend->cred` and the OpenSSL `backend->ctx` data and their
+ proxy versions (and possibly other TLS backends), could be better moved to be
+ stored in the Curl_easy handle instead of in per connection so that a single
+ transfer that makes multiple connections can reuse the context and reduce
+ memory consumption.
+
+ https://github.com/curl/curl/issues/5102
+
 3. Email protocols
 
 3.1 IMAP SEARCH ALL truncated response
@@ -348,13 +354,6 @@ problems may have been fixed or changed somewhat since 
this was written!
 
 5. Build and portability issues
 
-5.1 USE_UNIX_SOCKETS on Windows
-
- Due to incorrect CMake checks for the presence of the feature, it will never
- be enabled for windows in a cmake build.
-
- See https://github.com/curl/curl/issues/4040
-
 5.2 curl-config --libs contains private details
 
  "curl-config --libs" will include details set in LDFLAGS when configure is
@@ -589,15 +588,13 @@ problems may have been fixed or changed somewhat since 
this was written!
 
  See https://github.com/curl/curl/issues/1508
 
-7.10 Stick to same family over SOCKS proxy
+7.10 FTPS needs session reuse
 
- When asked to do FTP over a SOCKS proxy, it might connect to the proxy (and
- then subsequently to the remote server) using for example IPv4. When doing
- the second connection, curl should make sure that the second connection is
- using the same IP protocol version as the first connection did and not try
- others, since the remote server will only accept the same.
+ When the control connection is reused for a subsequent transfer, some FTPS
+ servers complain about "missing session reuse" for the data channel for the
+ second transfer.
 
- See https://curl.haxx.se/mail/archive-2018-07/0000.html
+ https://github.com/curl/curl/issues/4654
 
 8. TELNET
 
@@ -705,6 +702,17 @@ problems may have been fixed or changed somewhat since 
this was written!
  Also, alarm() provides timeout resolution only to the nearest second. alarm
  ought to be replaced by setitimer on systems that support it.
 
+11.8 DoH leaks memory after followlocation
+
+ https://github.com/curl/curl/issues/4592
+
+11.9 DoH doesn't inherit all transfer options
+
+ https://github.com/curl/curl/issues/4578
+
+11.10 Blocking socket operations in non-blocking API
+
+ The list of blocking socket operations is in TODO section "More non-blocking".
 
 12. LDAP and OpenLDAP
 
diff --git a/docs/MQTT.md b/docs/MQTT.md
new file mode 100644
index 000000000..a40971474
--- /dev/null
+++ b/docs/MQTT.md
@@ -0,0 +1,61 @@
+# MQTT in curl
+
+## Experimental!
+
+MQTT support in curl is considered **EXPERIMENTAL** until further notice. It
+needs to be enabled at build-time. See below.
+
+After the initial merge, further development and tweaking of the MQTT support
+in curl will happen in the master branch using pull-requests, just like
+ordinary changes.
+
+Experimental support for MQTT means that we **do not guarantee** that the
+current protocol functionality will remain or remain this way going forward.
+There are no API or ABI promises for experimental features as for regular curl
+features.
+
+Do not ship anything with this enabled.
+
+## Build
+
+    ./configure --enable-mqtt
+
+## Usage
+
+A plain "GET" subscribes to the topic and prints all published messages.
+Doing a "POST" publishes the post data to the topic and exits.
+
+Example subscribe:
+
+    curl mqtt://host/home/bedroom/temp
+
+Example publish:
+
+    curl -d 75 mqtt://host/home/bedroom/dimmer
+
+## What does curl deliver as a response to a subscribe
+
+It outputs two bytes topic length (MSB | LSB), the topic followed by the
+payload.
+
+## Caveats
+
+Remaining limitations:
+ - No username support
+ - Only QoS level 0 is implemented for publish
+ - No way to set retain flag for publish
+ - No username/password support
+ - No TLS (mqtts) support
+ - Naive EAGAIN handling won't handle split messages
+
+## Work
+
+1. Write a mqtt server for the test suite
+2. Create a few tests verifying the existing mqtt functionality
+3. Work on fixing some of the worst limitations - with accompanying tests
+4. Consider replacing the client-side MQTT code with wolfMQTT
+
+## Credits
+
+The initial MQTT patch was authored by Björn Stenberg. This work is built upon
+that patch and has been expanded since.
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 1f9f83911..63460b1ff 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -66,11 +66,9 @@ EXTRA_DIST =                                    \
  KNOWN_BUGS                                     \
  LICENSE-MIXING.md                              \
  MAIL-ETIQUETTE                                 \
+ MQTT.md                                        \
  PARALLEL-TRANSFERS.md                          \
- README.cmake                                   \
  README.md                                      \
- README.netware                                 \
- README.win32                                   \
  RELEASE-PROCEDURE.md                           \
  RESOURCES                                      \
  ROADMAP.md                                     \
diff --git a/docs/README.cmake b/docs/README.cmake
deleted file mode 100644
index 084c1de6d..000000000
--- a/docs/README.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-                                  _   _ ____  _
-                              ___| | | |  _ \| |
-                             / __| | | | |_) | |
-                            | (__| |_| |  _ <| |___
-                             \___|\___/|_| \_\_____|
-
-README.cmake
-  Read the README file first.
-
-  Curl contains CMake build files that provide a way to build Curl with the
-  CMake build tool (www.cmake.org). CMake is a cross platform meta build tool
-  that generates native makefiles and IDE project files. The CMake build
-  system can be used to build Curl on any of its supported platforms.
-
-  Read the INSTALL.cmake file for instructions on how to compile curl with
-  CMake.
diff --git a/docs/README.netware b/docs/README.netware
deleted file mode 100644
index e6e1e0002..000000000
--- a/docs/README.netware
+++ /dev/null
@@ -1,24 +0,0 @@
-                                  _   _ ____  _
-                              ___| | | |  _ \| |
-                             / __| | | | |_) | |
-                            | (__| |_| |  _ <| |___
-                             \___|\___/|_| \_\_____|
-
-README.netware
-
-  Read the README file first.
-
-  Curl has been successfully compiled with gcc / nlmconv on different flavours
-  of Linux as well as with the official Metrowerks CodeWarrior compiler.
-  While not being the main development target, a continuously growing share of
-  curl users are NetWare-based, especially also consuming the lib from PHP.
-
-  The unix-style man pages are tricky to read on windows, so therefore all
-  those pages are also provided as web pages on the curl web site.
-
-  The main curl.1 man page is also "built-in" in the command line tool. Use a
-  command line similar to this in order to extract a separate text file:
-
-        curl -M >manual.txt
-
-  Read the INSTALL file for instructions on how to compile curl self.
diff --git a/docs/README.win32 b/docs/README.win32
deleted file mode 100644
index ca34dd162..000000000
--- a/docs/README.win32
+++ /dev/null
@@ -1,23 +0,0 @@
-                                  _   _ ____  _
-                              ___| | | |  _ \| |
-                             / __| | | | |_) | |
-                            | (__| |_| |  _ <| |___
-                             \___|\___/|_| \_\_____|
-
-README.win32
-
-  Read the README file first.
-
-  Curl has been compiled, built and run on all sorts of Windows and win32
-  systems. While not being the main develop target, a fair share of curl users
-  are win32-based.
-
-  The unix-style man pages are tricky to read on windows, so therefore all
-  those pages are also provided as web pages on the curl web site.
-
-  The main curl.1 man page is also "built-in" in the command line tool. Use a
-  command line similar to this in order to extract a separate text file:
-
-        curl -M >manual.txt
-
-  Read the INSTALL file for instructions on how to compile curl self.
diff --git a/docs/RELEASE-PROCEDURE.md b/docs/RELEASE-PROCEDURE.md
index f2b4343bd..8ab4e3f13 100644
--- a/docs/RELEASE-PROCEDURE.md
+++ b/docs/RELEASE-PROCEDURE.md
@@ -4,6 +4,8 @@ curl release procedure - how to do a release
 in the source code repo
 -----------------------
 
+- run `./scripts/copyright.pl` and correct possible omissions
+
 - edit `RELEASE-NOTES` to be accurate
 
 - update `docs/THANKS`
diff --git a/docs/SSLCERTS.md b/docs/SSLCERTS.md
index 2c5be68e6..fcbc4646e 100644
--- a/docs/SSLCERTS.md
+++ b/docs/SSLCERTS.md
@@ -55,7 +55,7 @@ server, do one of the following:
 
  2. Get a CA certificate that can verify the remote server and use the proper
     option to point out this CA cert for verification when connecting. For
-    libcurl hackers: `curl_easy_setopt(curl, CURLOPT_CAPATH, capath);`
+    libcurl hackers: `curl_easy_setopt(curl, CURLOPT_CAINFO, cacert);`
 
     With the curl command line tool: --cacert [file]
 
@@ -104,7 +104,7 @@ server, do one of the following:
        the security is no better than the way you obtained the certificate.
 
  4. If you're using the curl command line tool, you can specify your own CA
-    cert path by setting the environment variable `CURL_CA_BUNDLE` to the path
+    cert file by setting the environment variable `CURL_CA_BUNDLE` to the path
     of your choice.
 
     If you're using the curl command line tool on Windows, curl will search
diff --git a/docs/THANKS b/docs/THANKS
index 53735cb6f..d39deffbf 100644
--- a/docs/THANKS
+++ b/docs/THANKS
@@ -37,6 +37,7 @@ Aki Koskinen
 Akos Pasztory
 Akshay Vernekar
 Alain Danteny
+Alain Miniussi
 Alan Jenkins
 Alan Pinstein
 Albert Chin-A-Young
@@ -54,6 +55,7 @@ Alex Baines
 Alex Bligh
 Alex Chan
 Alex Fishman
+Alex Gaynor
 Alex Grebenschikov
 Alex Gruz
 Alex Konev
@@ -78,6 +80,7 @@ Alexander Pepper
 Alexander Peslyak
 Alexander Sinditskiy
 Alexander Traud
+Alexander V. Tikhonov
 Alexander Zhuravlev
 Alexey Borzov
 Alexey Eremikhin
@@ -183,6 +186,7 @@ Arve Knudsen
 Arvid Norberg
 asavah on github
 Ashish Shukla
+Ashwin Metpalli
 Ask Bjørn Hansen
 Askar Safin
 Ates Goral
@@ -266,6 +270,7 @@ Brandon Wang
 Brendan Jurd
 Brent Beardsley
 Brian Akins
+Brian Bergeron
 Brian Carpenter
 Brian Chaplin
 Brian Childs
@@ -291,6 +296,7 @@ bxac on github
 Bylon2 on github
 Byrial Jensen
 Caleb Raitto
+Calvin Buckley
 Cameron Kaiser
 Cameron MacMinn
 Camille Moncelier
@@ -326,6 +332,7 @@ Chris Flerackers
 Chris Gaukroger
 Chris Maltby
 Chris Mumford
+Chris Roberts
 Chris Smowton
 Chris Young
 Christian Fillion
@@ -339,6 +346,7 @@ Christian Schmitz
 Christian Stewart
 Christian Vogt
 Christian Weisgerber
+Christoph Krey
 Christoph M. Becker
 Christophe Demory
 Christophe Dervieux
@@ -394,6 +402,7 @@ Da-Yoon Chung
 daboul on github
 Dag Ekengren
 Dagobert Michelsen
+Daiki Ueno
 Dair Grant
 Dambaev Alexander
 Damian Dixon
@@ -486,12 +495,14 @@ David Walser
 David Woodhouse
 David Wright
 David Yan
+davidedec on github
 dbrowndan on github
 Dengminwen
 Denis Chaplygin
 Denis Feklushkin
 Denis Ollier
 Dennis Clarke
+Dennis Felsing
 Derek Higgins
 Desmond O. Chang
 destman on github
@@ -513,6 +524,7 @@ Dinar
 Dirk Eddelbuettel
 Dirk Feytons
 Dirk Manske
+Dirkjan Bussink
 dkjjr89 on github
 dkwolfe4 on github
 Dmitri Shubin
@@ -606,6 +618,7 @@ Eric Rescorla
 Eric Ridge
 Eric Rosenquist
 Eric S. Raymond
+Eric Sauvageau
 Eric Thelin
 Eric Vergnaud
 Eric Wong
@@ -630,6 +643,7 @@ Evgeny Grin
 Evgeny Turnaev
 eXeC64 on github
 Eygene Ryabinkin
+Eylem Ugurel
 Fabian Frank
 Fabian Hiernaux
 Fabian Keil
@@ -677,6 +691,7 @@ Fred Stluka
 Frederic Lepied
 Frederik B
 Fredrik Thulin
+FuccDucc on github
 Gabriel Kuri
 Gabriel Sjoberg
 Garrett Holmstrom
@@ -684,6 +699,7 @@ Gary Maxwell
 Gaurav Malhotra
 Gautam Kachroo
 Gautam Mani
+Gavin Wong
 Gavrie Philipson
 Gaz Iqbal
 Gaël Portay
@@ -757,6 +773,7 @@ Hanno Böck
 Hanno Kranzhoff
 Hans Steegers
 Hans-Jurgen May
+Hao Wu
 Hardeep Singh
 Haris Okanovic
 Harold Stuart
@@ -786,6 +803,7 @@ Howard Chu
 hsiao yi
 Hubert Kario
 Huzaifa Sidhpurwala
+hydra3333 on github
 Hzhijun
 Ian D Allen
 Ian Fette
@@ -1019,6 +1037,7 @@ Joshua Swink
 Josie Huddleston
 Josue Andrade Gomes
 Jozef Kralik
+JP Mens
 Juan Barreto
 Juan F. Codagnone
 Juan Ignacio Hervás
@@ -1061,6 +1080,7 @@ Kalle Vahlman
 Kamil Dudka
 Kang Lin
 Kang-Jin Lee
+Karl Chen
 Karl Moerder
 Karol Pietrzak
 Kartik Mahajan
@@ -1111,6 +1131,7 @@ Kristiyan Tsaklev
 Kristoffer Gleditsch
 Kunal Ekawde
 Kurt Fankhauser
+Kwon-Young Choi
 Kyle Abramowitz
 Kyle Edwards
 Kyle J. McKay
@@ -1254,6 +1275,7 @@ Markus Elfring
 Markus Koetter
 Markus Moeller
 Markus Oberhumer
+Markus Olsson
 Markus Westerlind
 Maros Priputen
 Marquis de Muesli
@@ -1283,6 +1305,7 @@ Massimiliano Ziccardi
 Massimo Callegari
 Mateusz Loskot
 Mathias Axelsson
+Mathias Gumz
 Mathieu Legare
 Mats Lidell
 Matt Arsenault
@@ -1404,6 +1427,7 @@ Mostyn Bramley-Moore
 Moti Avrahami
 MrdUkk on github
 MrSorcus on github
+Muhammad Herdiansyah
 Muz Dima
 Myk Taylor
 Nach M. S.
@@ -1414,6 +1438,7 @@ Nathan Coulter
 Nathan O'Sullivan
 Nathanael Nerode
 Nathaniel J. Smith
+Nathaniel R. Lewis
 Nathaniel Waisbrot
 Naveen Chandran
 Naveen Noel
@@ -1536,6 +1561,7 @@ Paul Nolan
 Paul Oliver
 Paul Querna
 Paul Saab
+Paul Vixie
 Paulo Roberto Tomasi
 Pavel Cenek
 Pavel Gushchin
@@ -1688,6 +1714,7 @@ Richard Prescott
 Richard Silverman
 Richard van den Berg
 Richy Kim
+Rici Lake
 Rick Deist
 Rick Jones
 Rick Richardson
@@ -1728,6 +1755,7 @@ Rodney Simmons
 Rodric Glaser
 Rodrigo Silva
 Roger Leigh
+Roger Orr
 Roland Blom
 Roland Hieber
 Roland Krikava
@@ -1745,6 +1773,7 @@ Ron Parker
 Ron Zapp
 Ronnie Mose
 Rosimildo da Silva
+Ross Burton
 Roy Bellingan
 Roy Shan
 Rune Kleveland
@@ -1832,6 +1861,7 @@ Siddhartha Prakash Jain
 Sidney San Martín
 Siegfried Gyuricsko
 silveja1 on github
+Simon Chalifoux
 Simon Dick
 Simon H.
 Simon Josefsson
@@ -1869,6 +1899,7 @@ Stefano Simonelli
 Steinar H. Gunderson
 steini2000 on github
 Stepan Broz
+Stepan Efremov
 Stephan Bergmann
 Stephan Lagerholm
 Stephan Mühlstrasser
@@ -1894,6 +1925,7 @@ Steven G. Johnson
 Steven Gu
 Steven M. Schweda
 Steven Parkes
+Steven Penny
 Stian Soiland-Reyes
 Stoned Elipot
 stootill on github
@@ -1924,6 +1956,7 @@ Teemu Yli-Elsila
 Temprimus
 Terri Oda
 Terry Wu
+thanhchungbtc on github
 The Infinnovation team
 TheAssassin on github
 Theodore Dubois
@@ -1954,6 +1987,7 @@ Tim Heckman
 Tim Mcdonough
 Tim Newsome
 Tim Rühsen
+Tim Sedlmeyer
 Tim Sneddon
 Tim Stack
 Tim Starling
@@ -2003,6 +2037,7 @@ Tomasz Kojm
 Tomasz Lacki
 Tommie Gannert
 tommink[at]post.pl
+Tommy Petty
 Tommy Tam
 Ton Voon
 Toni Moreno
@@ -2116,6 +2151,7 @@ Yousuke Kimoto
 Yu Xin
 Yukihiro Kawada
 Yun SangHo
+Yuri Slobodyanyuk
 Yuriy Sosov
 Yves Arrouye
 Yves Lejeune
diff --git a/docs/THANKS-filter b/docs/THANKS-filter
index cabc93933..6a036acc1 100644
--- a/docs/THANKS-filter
+++ b/docs/THANKS-filter
@@ -1,3 +1,25 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+#
 # This is a list of names we have recorded that already are thanked
 # appropriately in THANKS. This list contains variations of their names and
 # their "canonical" name. This file is used for scripting purposes to avoid
diff --git a/docs/TODO b/docs/TODO
index b288e4dbb..dfc36b8cf 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -66,6 +66,7 @@
 
  5. HTTP
  5.1 Better persistency for HTTP 1.0
+ 5.2 Set custom client ip when using haproxy protocol
  5.3 Rearrange request header order
  5.4 Allow SAN names in HTTP/2 server push
  5.5 auth= in URLs
@@ -99,6 +100,7 @@
  12. New protocols
 
  13. SSL
+ 13.1 TLS-PSK with OpenSSL
  13.2 Provide mutex locking API
  13.3 Support in-memory certs/ca certs/keys
  13.4 Cache/share OpenSSL contexts
@@ -136,7 +138,9 @@
  18.3 prevent file overwriting
  18.4 --proxycommand
  18.5 UTF-8 filenames in Content-Disposition
+ 18.6 Option to make -Z merge lined based outputs on stdout
  18.7 at least N milliseconds between requests
+ 18.8 Consider convenience options for JSON and XML?
  18.9 Choose the name of file in braces for complex URLs
  18.10 improve how curl works in a windows console window
  18.11 Windows: set attribute 'archive' for completed downloads
@@ -162,6 +166,7 @@
  20.6 Use the RFC6265 test suite
  20.7 Support LD_PRELOAD on macOS
  20.8 Run web-platform-tests url tests
+ 20.9 Use "random" ports for the test servers
 
  21. Next SONAME bump
  21.1 http-style HEAD output for FTP
@@ -405,11 +410,21 @@
  Make sure we don't ever loop because of non-blocking sockets returning
  EWOULDBLOCK or similar. Blocking cases include:
 
- - Name resolves on non-windows unless c-ares or the threaded resolver is used
+ - Name resolves on non-windows unless c-ares or the threaded resolver is used.
+
+ - The threaded resolver may block on cleanup:
+ https://github.com/curl/curl/issues/4852
+
  - file:// transfers
+
  - TELNET transfers
+
+ - GSSAPI authentication for FTP transfers
+
  - The "DONE" operation (post transfer protocol-specific actions) for the
-   protocols SFTP, SMTP, FTP. Fixing Curl_done() for this is a worthy task.
+ protocols SFTP, SMTP, FTP. Fixing Curl_done() for this is a worthy task.
+
+ - curl_multi_remove_handle for any of the above. See section 2.3.
 
 2.2 Better support for same name resolves
 
@@ -510,6 +525,13 @@
  "Better" support for persistent connections over HTTP 1.0
  https://curl.haxx.se/bug/feature.cgi?id=1089001
 
+5.2 Set custom client ip when using haproxy protocol
+
+ This would allow testing servers with different client ip addresses (without
+ using x-forward-for header).
+
+ https://github.com/curl/curl/issues/5125
+
 5.3 Rearrange request header order
 
  Server implementors often make an effort to detect browser and to reject
@@ -640,6 +662,15 @@ that doesn't exist on the server, just like 
--ftp-create-dirs.
 
 13. SSL
 
+13.1 TLS-PSK with OpenSSL
+
+ Transport Layer Security pre-shared key ciphersuites (TLS-PSK) is a set of
+ cryptographic protocols that provide secure communication based on pre-shared
+ keys (PSKs). These pre-shared keys are symmetric keys shared in advance among
+ the communicating parties.
+
+ https://github.com/curl/curl/issues/5081
+
 13.2 Provide mutex locking API
 
  Provide a libcurl API for setting mutex callbacks in the underlying SSL
@@ -887,6 +918,14 @@ that doesn't exist on the server, just like 
--ftp-create-dirs.
 
  https://github.com/curl/curl/issues/1888
 
+18.6 Option to make -Z merge lined based outputs on stdout
+
+ When a user requests multiple lined based files using -Z and sends them to
+ stdout, curl will not "merge" and send complete lines fine but may very well
+ send partial lines from several sources.
+
+ https://github.com/curl/curl/issues/5175
+
 18.7 at least N milliseconds between requests
 
  Allow curl command lines issue a lot of request against services that limit
@@ -898,6 +937,20 @@ that doesn't exist on the server, just like 
--ftp-create-dirs.
 
  See https://github.com/curl/curl/issues/3920
 
+18.8 Consider convenience options for JSON and XML?
+
+ Could we add `--xml` or `--json` to add headers needed to call rest API:
+
+ `--xml` adds -H 'Content-Type: application/xml' -H "Accept: application/xml" 
and
+ `--json` adds -H 'Content-Type: application/json' -H "Accept: 
application/json"
+
+ Setting Content-Type when doing a GET or any other method without a body
+ would be a bit strange I think - so maybe only add CT for requests with body?
+ Maybe plain `--xml` and ` --json` are a bit too brief and generic. Maybe
+ `--http-json` etc?
+
+ See https://github.com/curl/curl/issues/5203
+
 18.9 Choose the name of file in braces for complex URLs
 
  When using braces to download a list of URLs and you use complicated names
@@ -1086,6 +1139,17 @@ that doesn't exist on the server, just like 
--ftp-create-dirs.
 
  See https://github.com/curl/curl/issues/4477
 
+20.9 Use "random" ports for the test servers
+
+ Instead of insisting and using fixed port numbers for the tests (even though
+ they can be changed with a switch), consider letting each server pick a
+ random available one at start-up, store that info in a file and let the test
+ suite use that.
+
+ We could then remove the "check that it is our server that's running"-check
+ and we would immediately detect when we write tests wrongly to use hard-coded
+ port numbers.
+
 21. Next SONAME bump
 
 21.1 http-style HEAD output for FTP
diff --git a/docs/cmdline-opts/CMakeLists.txt b/docs/cmdline-opts/CMakeLists.txt
index 3c020d418..a63f4eddf 100644
--- a/docs/cmdline-opts/CMakeLists.txt
+++ b/docs/cmdline-opts/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 set(MANPAGE "${CURL_BINARY_DIR}/docs/curl.1")
 
 # Load DPAGES and OTHERPAGES from shared file
diff --git a/docs/cmdline-opts/Makefile.am b/docs/cmdline-opts/Makefile.am
index edc585538..d778fb062 100644
--- a/docs/cmdline-opts/Makefile.am
+++ b/docs/cmdline-opts/Makefile.am
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -32,4 +32,5 @@ all:
        @echo man page generation no longer required
 
 $(MANPAGE): $(DPAGES) $(OTHERPAGES) Makefile.inc
-       @PERL@ $(srcdir)/gen.pl mainpage $(srcdir) > $(MANPAGE)
+       @echo "generate $(MANPAGE)"
+       @(cd $(srcdir) && @PERL@ ./gen.pl mainpage $(DPAGES)) > $(MANPAGE)
diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc
index 829551ff6..5b7439e4a 100644
--- a/docs/cmdline-opts/Makefile.inc
+++ b/docs/cmdline-opts/Makefile.inc
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Shared between Makefile.am and CMakeLists.txt
 
 DPAGES =                                       \
@@ -38,8 +59,8 @@ DPAGES =                                      \
   dump-header.d                                        \
   egd-file.d                                   \
   engine.d                                     \
-  etag-save.d                   \
   etag-compare.d                \
+  etag-save.d                   \
   expect100-timeout.d                          \
   fail-early.d                                 \
   fail.d                                       \
@@ -85,6 +106,7 @@ DPAGES =                                     \
   login-options.d                              \
   mail-auth.d                                  \
   mail-from.d                                  \
+  mail-rcpt-allowfails.d                        \
   mail-rcpt.d                                  \
   manual.d                                     \
   max-filesize.d                               \
@@ -162,7 +184,7 @@ DPAGES =                                    \
   retry-delay.d                                        \
   retry-max-time.d                             \
   retry.d                                      \
-  sasl-authzid.d                                       \
+  sasl-authzid.d                               \
   sasl-ir.d                                    \
   service-name.d                               \
   show-error.d                                 \
@@ -179,6 +201,7 @@ DPAGES =                                    \
   ssl-allow-beast.d                            \
   ssl-no-revoke.d                              \
   ssl-reqd.d                                   \
+  ssl-revoke-best-effort.d                     \
   ssl.d                                                \
   sslv2.d sslv3.d                              \
   stderr.d                                     \
diff --git a/docs/cmdline-opts/compressed.d b/docs/cmdline-opts/compressed.d
index dc130c1f0..3aca92c32 100644
--- a/docs/cmdline-opts/compressed.d
+++ b/docs/cmdline-opts/compressed.d
@@ -3,5 +3,7 @@ Help: Request compressed response
 Protocols: HTTP
 ---
 Request a compressed response using one of the algorithms curl supports, and
-save the uncompressed document.  If this option is used and the server sends
-an unsupported encoding, curl will report an error.
+automatically decompress the content. Headers are not modified.
+
+If this option is used and the server sends an unsupported encoding, curl will
+report an error.
diff --git a/docs/cmdline-opts/cookie.d b/docs/cmdline-opts/cookie.d
index 1e9906977..467e05663 100644
--- a/docs/cmdline-opts/cookie.d
+++ b/docs/cmdline-opts/cookie.d
@@ -13,7 +13,7 @@ to read previously stored cookie from. This option also 
activates the cookie
 engine which will make curl record incoming cookies, which may be handy if
 you're using this in combination with the --location option or do multiple URL
 transfers on the same invoke. If the file name is exactly a minus ("-"), curl
-will instead the contents from stdin.
+will instead read the contents from stdin.
 
 The file format of the file to read cookies from should be plain HTTP headers
 (Set-Cookie style) or the Netscape/Mozilla cookie file format.
diff --git a/docs/cmdline-opts/data.d b/docs/cmdline-opts/data.d
index 8b5200d34..280d38bc0 100644
--- a/docs/cmdline-opts/data.d
+++ b/docs/cmdline-opts/data.d
@@ -2,7 +2,7 @@ Long: data
 Short: d
 Arg: <data>
 Help: HTTP POST data
-Protocols: HTTP
+Protocols: HTTP MQTT
 See-also: data-binary data-urlencode data-raw
 Mutexed: form head upload-file
 ---
diff --git a/docs/cmdline-opts/gen.pl b/docs/cmdline-opts/gen.pl
index 329fdc02b..ef19e2448 100755
--- a/docs/cmdline-opts/gen.pl
+++ b/docs/cmdline-opts/gen.pl
@@ -1,10 +1,31 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
 =begin comment
 
 This script generates the manpage.
 
-Example: gen.pl mainpage > gnurl.1
+Example: gen.pl <command> [files] > gnurl.1
 
 Dev notes:
 
@@ -16,12 +37,6 @@ Unfortunately it seems some perls like msysgit can't handle 
a global input-only
 =end comment
 =cut
 
-my $some_dir=$ARGV[1] || ".";
-
-opendir(my $dh, $some_dir) || die "Can't opendir $some_dir: $!";
-my @s = grep { /\.d$/ && -f "$some_dir/$_" } readdir($dh);
-closedir $dh;
-
 my %optshort;
 my %optlong;
 my %helplong;
@@ -101,7 +116,7 @@ sub added {
 
 sub single {
     my ($f, $standalone)=@_;
-    open(F, "<:crlf", "$some_dir/$f") ||
+    open(F, "<:crlf", "$f") ||
         return 1;
     my $short;
     my $long;
@@ -243,7 +258,7 @@ sub single {
 
 sub getshortlong {
     my ($f)=@_;
-    open(F, "<:crlf", "$some_dir/$f");
+    open(F, "<:crlf", "$f");
     my $short;
     my $long;
     my $help;
@@ -282,14 +297,15 @@ sub getshortlong {
 }
 
 sub indexoptions {
-  foreach my $f (@s) {
-    getshortlong($f);
-  }
+    my (@files) = @_;
+    foreach my $f (@files) {
+        getshortlong($f);
+    }
 }
 
 sub header {
     my ($f)=@_;
-    open(F, "<:crlf", "$some_dir/$f");
+    open(F, "<:crlf", "$f");
     my @d;
     while(<F>) {
         push @d, $_;
@@ -328,12 +344,15 @@ sub listhelp {
 }
 
 sub mainpage {
+    my (@files) = @_;
     # show the page header
     header("page-header");
 
     # output docs for all options
-    foreach my $f (sort @s) {
-        single($f, 0);
+    foreach my $f (sort @files) {
+        if(single($f, 0)) {
+            print STDERR "Can't read $f?\n";
+        }
     }
 
     header("page-footer");
@@ -360,33 +379,33 @@ sub showprotocols {
 }
 
 sub getargs {
-    my $f;
-    do {
-        $f = shift @ARGV;
-        if($f eq "mainpage") {
-            mainpage();
-            return;
-        }
-        elsif($f eq "listhelp") {
-            listhelp();
-            return;
-        }
-        elsif($f eq "single") {
-            showonly(shift @ARGV);
-            return;
-        }
-        elsif($f eq "protos") {
-            showprotocols();
-            return;
-        }
-    } while($f);
+    my ($f, @s) = @_;
+    if($f eq "mainpage") {
+        mainpage(@s);
+        return;
+    }
+    elsif($f eq "listhelp") {
+        listhelp();
+        return;
+    }
+    elsif($f eq "single") {
+        showonly($s[0]);
+        return;
+    }
+    elsif($f eq "protos") {
+        showprotocols();
+        return;
+    }
 
-    print "Usage: gen.pl <mainpage/listhelp/single FILE/protos> [srcdir]\n";
+    print "Usage: gen.pl <mainpage/listhelp/single FILE/protos> [files]\n";
 }
 
 #------------------------------------------------------------------------
 
+my $cmd = shift @ARGV;
+my @files = @ARGV; # the rest are the files
+
 # learn all existing options
-indexoptions();
+indexoptions(@files);
 
-getargs();
+getargs($cmd, @files);
diff --git a/docs/cmdline-opts/output.d b/docs/cmdline-opts/output.d
index 35f52a213..f310c267d 100644
--- a/docs/cmdline-opts/output.d
+++ b/docs/cmdline-opts/output.d
@@ -5,15 +5,15 @@ Help: Write to file instead of stdout
 See-also: remote-name remote-name-all remote-header-name
 ---
 Write output to <file> instead of stdout. If you are using {} or [] to fetch
-multiple documents, you can use '#' followed by a number in the <file>
-specifier. That variable will be replaced with the current string for the URL
-being fetched. Like in:
+multiple documents, you should quote the URL and you can use '#' followed by a
+number in the <file> specifier. That variable will be replaced with the current
+string for the URL being fetched. Like in:
 
- curl http://{one,two}.example.com -o "file_#1.txt"
+ curl "http://{one,two}.example.com"; -o "file_#1.txt"
 
 or use several variables like:
 
- curl http://{site,host}.host[1-5].com -o "#1_#2"
+ curl "http://{site,host}.host[1-5].com"; -o "#1_#2"
 
 You may use this option as many times as the number of URLs you have. For
 example, if you specify two URLs on the same command line, you can use it like
diff --git a/docs/cmdline-opts/page-header b/docs/cmdline-opts/page-header
index 51f45edad..60c3b07fe 100644
--- a/docs/cmdline-opts/page-header
+++ b/docs/cmdline-opts/page-header
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -31,8 +31,8 @@ curl \- transfer a URL
 .B curl
 is a tool to transfer data from or to a server, using one of the supported
 protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP,
-LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET
-and TFTP). The command is designed to work without user interaction.
+LDAPS, MQTT, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS,
+TELNET and TFTP). The command is designed to work without user interaction.
 
 curl offers a busload of useful tricks like proxy support, user
 authentication, FTP upload, HTTP post, SSL connections, cookies, file transfer
@@ -46,9 +46,9 @@ The URL syntax is protocol-dependent. You'll find a detailed 
description in
 RFC 3986.
 
 You can specify multiple URLs or parts of URLs by writing part sets within
-braces as in:
+braces and quoting the URL as in:
 
-  http://site.{one,two,three}.com
+  "http://site.{one,two,three}.com";
 
 or you can get sequences of alphanumeric series by using [] as in:
 
diff --git a/docs/cmdline-opts/ssl-revoke-best-effort.d 
b/docs/cmdline-opts/ssl-revoke-best-effort.d
new file mode 100644
index 000000000..9b55699db
--- /dev/null
+++ b/docs/cmdline-opts/ssl-revoke-best-effort.d
@@ -0,0 +1,7 @@
+Long: ssl-revoke-best-effort
+Help: Ignore missing/offline cert CRL distribution points (Schannel)
+Added: 7.70.0
+---
+(Schannel) This option tells curl to ignore certificate revocation checks when
+they failed due to missing/offline distribution points for the revocation check
+lists.
diff --git a/docs/cmdline-opts/url.d b/docs/cmdline-opts/url.d
index ce52cdf06..991f1f27c 100644
--- a/docs/cmdline-opts/url.d
+++ b/docs/cmdline-opts/url.d
@@ -13,3 +13,6 @@ setting a default protocol, see --proto-default for details.
 
 This option may be used any number of times. To control where this URL is
 written, use the --output or the --remote-name options.
+
+Warning: On Windows, particular file:// accesses can be converted to network
+accesses by the operating system. Beware!
diff --git a/docs/cmdline-opts/write-out.d b/docs/cmdline-opts/write-out.d
index 2fc0ff21a..9024d32e0 100644
--- a/docs/cmdline-opts/write-out.d
+++ b/docs/cmdline-opts/write-out.d
@@ -50,6 +50,9 @@ curl CONNECT request. (Added in 7.12.4)
 .B http_version
 The http version that was effectively used. (Added in 7.50.0)
 .TP
+.B json
+A JSON object with all available keys.
+.TP
 .B local_ip
 The IP address of the local end of the most recently done connection - can be
 either IPv4 or IPv6 (Added in 7.29.0)
diff --git a/docs/examples/Makefile.example b/docs/examples/Makefile.example
index 17e614ea1..72e762fbb 100644
--- a/docs/examples/Makefile.example
+++ b/docs/examples/Makefile.example
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/docs/examples/Makefile.m32 b/docs/examples/Makefile.m32
index 160afb62f..d0694cfa3 100644
--- a/docs/examples/Makefile.m32
+++ b/docs/examples/Makefile.m32
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -106,7 +106,7 @@ CFLAGS += -fno-strict-aliasing
 # comment LDFLAGS below to keep debug info
 LDFLAGS = $(CURL_LDFLAG_EXTRAS) $(CURL_LDFLAG_EXTRAS_EXE) -s
 RC = $(CROSSPREFIX)windres
-RCFLAGS = --include-dir=$(PROOT)/include -O COFF
+RCFLAGS = --include-dir=$(PROOT)/include -O coff
 
 # Set environment var ARCH to your architecture to override autodetection.
 ifndef ARCH
diff --git a/docs/examples/Makefile.netware b/docs/examples/Makefile.netware
index 1f50a9266..260c55773 100644
--- a/docs/examples/Makefile.netware
+++ b/docs/examples/Makefile.netware
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2008 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #################################################################
 #
 ## Makefile for building curl.nlm (NetWare version - gnu make)
diff --git a/docs/examples/adddocsref.pl b/docs/examples/adddocsref.pl
index ce6f58287..3b01e36a2 100755
--- a/docs/examples/adddocsref.pl
+++ b/docs/examples/adddocsref.pl
@@ -1,4 +1,25 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2004 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
 # pass files as argument(s)
 
diff --git a/docs/examples/crawler.c b/docs/examples/crawler.c
index a16256d39..eb5de9d8d 100644
--- a/docs/examples/crawler.c
+++ b/docs/examples/crawler.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Web crawler based on curl and libxml2.
- * Copyright (C) 2018 - 2019 Jeroen Ooms <address@hidden>
+ * Copyright (C) 2018 - 2020 Jeroen Ooms <address@hidden>
  * License: MIT
  *
  * To compile:
@@ -116,7 +116,8 @@ size_t follow_links(CURLM *multi_handle, memory *mem, char 
*url)
     return 0;
   }
   size_t count = 0;
-  for(int i = 0; i < nodeset->nodeNr; i++) {
+  int i;
+  for(i = 0; i < nodeset->nodeNr; i++) {
     double r = rand();
     int x = r * nodeset->nodeNr / RAND_MAX;
     const xmlNode *node = nodeset->nodeTab[x]->xmlChildrenNode;
diff --git a/docs/examples/makefile.dj b/docs/examples/makefile.dj
index 17d93ab89..eca16b8a6 100644
--- a/docs/examples/makefile.dj
+++ b/docs/examples/makefile.dj
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/docs/examples/sessioninfo.c b/docs/examples/sessioninfo.c
index 3c0b143e8..3941dc924 100644
--- a/docs/examples/sessioninfo.c
+++ b/docs/examples/sessioninfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,6 +31,7 @@
 
 #include <gnurl/curl.h>
 #include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
 
 static CURL *curl;
 
diff --git a/docs/examples/version-check.pl b/docs/examples/version-check.pl
index a6e7874e3..c8bc3a849 100755
--- a/docs/examples/version-check.pl
+++ b/docs/examples/version-check.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2010, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/docs/gnurl-config.1 b/docs/gnurl-config.1
index 4a23e6a92..84fd0576f 100644
--- a/docs/gnurl-config.1
+++ b/docs/gnurl-config.1
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -74,8 +74,8 @@ to link your application with libcurl statically. (Added in 
7.17.1)
 Outputs version information about the installed libcurl.
 .IP "--vernum"
 Outputs version information about the installed libcurl, in numerical mode.
-This outputs the version number, in hexadecimal, with 8 bits for each part;
-major, minor, patch. So that libcurl 7.7.4 would appear as 070704 and libcurl
+This outputs the version number, in hexadecimal, with 8 bits for each part:
+major, minor, and patch. So that libcurl 7.7.4 would appear as 070704 and 
libcurl
 12.13.14 would appear as 0c0d0e... Note that the initial zero might be
 omitted. (This option was broken in the 7.15.0 release.)
 .SH "EXAMPLES"
diff --git a/docs/libcurl/CMakeLists.txt b/docs/libcurl/CMakeLists.txt
index 0b32c5054..8ef604a42 100644
--- a/docs/libcurl/CMakeLists.txt
+++ b/docs/libcurl/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Load man_MANS from shared file
 transform_makefile_inc("Makefile.inc" 
"${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
 include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
diff --git a/docs/libcurl/Makefile.inc b/docs/libcurl/Makefile.inc
index 6a99f8e46..fe3dd65a8 100644
--- a/docs/libcurl/Makefile.inc
+++ b/docs/libcurl/Makefile.inc
@@ -1,3 +1,25 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2008 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
 # Shared between Makefile.am and CMakeLists.txt
 
 man_MANS = \
diff --git a/docs/libcurl/getinfo-times b/docs/libcurl/getinfo-times
deleted file mode 100644
index bb0fdcb1c..000000000
--- a/docs/libcurl/getinfo-times
+++ /dev/null
@@ -1,27 +0,0 @@
-An overview of the six time values available from curl_easy_getinfo()
-
-curl_easy_perform()
-    |
-    |--NT
-    |--|--CT
-    |--|--|--PT
-    |--|--|--|--ST
-          |--|--|--TT
-    |--|--|--|--|--RT
-
-NT = CURLINFO_NAMELOOKUP_TIME. The time it took from the start until the name
-     resolving was completed.
-CT = CURLINFO_CONNECT_TIME. The time it took from the start until the connect
-     to the remote host (or proxy) was completed.
-PT = CURLINFO_PRETRANSFER_TIME. The time it took from the start until the file
-     transfer is just about to begin. This includes all pre-transfer commands
-     and negotiations that are specific to the particular protocol(s)
-     involved.
-ST = CURLINFO_STARTTRANSFER_TIME. The time it took from the start until the
-     first byte is just about to be transferred.
-TT = CURLINFO_TOTAL_TIME. Time of the previous transfer. This time does not
-     include the connect time (CT), so if you want the complete operation
-     time, you should add that.
-RT = CURLINFO_REDIRECT_TIME. The time it took for all redirection steps
-     include name lookup, connect, pretransfer and transfer before final
-     transaction was started. So, this is zero if no redirection took place.
diff --git a/docs/libcurl/gnurl_easy_getinfo.3 
b/docs/libcurl/gnurl_easy_getinfo.3
index 3c3d4779e..7ffd6b308 100644
--- a/docs/libcurl/gnurl_easy_getinfo.3
+++ b/docs/libcurl/gnurl_easy_getinfo.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -210,7 +210,7 @@ TLS session info that can be used for further processing.  
See
 \fICURLINFO_TLS_SESSION(3)\fP. Deprecated option, use
 \fICURLINFO_TLS_SSL_PTR(3)\fP instead!
 .IP CURLINFO_CONDITION_UNMET
-Whether or not a time conditional was met.
+Whether or not a time conditional was met or 304 HTTP response.
 See \fICURLINFO_CONDITION_UNMET(3)\fP
 .IP CURLINFO_RTSP_SESSION_ID
 RTSP session ID.
diff --git a/docs/libcurl/gnurl_easy_init.3 b/docs/libcurl/gnurl_easy_init.3
index 3253fe1c0..a17400dc5 100644
--- a/docs/libcurl/gnurl_easy_init.3
+++ b/docs/libcurl/gnurl_easy_init.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_easy_perform.3 
b/docs/libcurl/gnurl_easy_perform.3
index c0ace9921..36c6675f0 100644
--- a/docs/libcurl/gnurl_easy_perform.3
+++ b/docs/libcurl/gnurl_easy_perform.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_easy_strerror.3 
b/docs/libcurl/gnurl_easy_strerror.3
index f38b8acb5..c20bcb9d3 100644
--- a/docs/libcurl/gnurl_easy_strerror.3
+++ b/docs/libcurl/gnurl_easy_strerror.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_escape.3 b/docs/libcurl/gnurl_escape.3
index 58c4e0c1a..8017ca7c9 100644
--- a/docs/libcurl/gnurl_escape.3
+++ b/docs/libcurl/gnurl_escape.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_formadd.3 b/docs/libcurl/gnurl_formadd.3
index dbfd43214..e3a48e49d 100644
--- a/docs/libcurl/gnurl_formadd.3
+++ b/docs/libcurl/gnurl_formadd.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_getenv.3 b/docs/libcurl/gnurl_getenv.3
index 98d928582..2d84a727f 100644
--- a/docs/libcurl/gnurl_getenv.3
+++ b/docs/libcurl/gnurl_getenv.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_mime_type.3 b/docs/libcurl/gnurl_mime_type.3
index b1cf0a378..eeb688aba 100644
--- a/docs/libcurl/gnurl_mime_type.3
+++ b/docs/libcurl/gnurl_mime_type.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_multi_assign.3 
b/docs/libcurl/gnurl_multi_assign.3
index f10e7832e..7cb2bf29b 100644
--- a/docs/libcurl/gnurl_multi_assign.3
+++ b/docs/libcurl/gnurl_multi_assign.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_multi_info_read.3 
b/docs/libcurl/gnurl_multi_info_read.3
index cb1d731fd..daa754a9a 100644
--- a/docs/libcurl/gnurl_multi_info_read.3
+++ b/docs/libcurl/gnurl_multi_info_read.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_multi_init.3 b/docs/libcurl/gnurl_multi_init.3
index f711015cd..d06c12f4e 100644
--- a/docs/libcurl/gnurl_multi_init.3
+++ b/docs/libcurl/gnurl_multi_init.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_multi_strerror.3 
b/docs/libcurl/gnurl_multi_strerror.3
index 3dcd63a5d..c2ee1e4e2 100644
--- a/docs/libcurl/gnurl_multi_strerror.3
+++ b/docs/libcurl/gnurl_multi_strerror.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_multi_timeout.3 
b/docs/libcurl/gnurl_multi_timeout.3
index db84e69bc..e2620dd8f 100644
--- a/docs/libcurl/gnurl_multi_timeout.3
+++ b/docs/libcurl/gnurl_multi_timeout.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_share_init.3 b/docs/libcurl/gnurl_share_init.3
index 7bf00c183..4b479a614 100644
--- a/docs/libcurl/gnurl_share_init.3
+++ b/docs/libcurl/gnurl_share_init.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_share_setopt.3 
b/docs/libcurl/gnurl_share_setopt.3
index b58bef623..052308360 100644
--- a/docs/libcurl/gnurl_share_setopt.3
+++ b/docs/libcurl/gnurl_share_setopt.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_share_strerror.3 
b/docs/libcurl/gnurl_share_strerror.3
index 8b93a2451..bbb0a0d00 100644
--- a/docs/libcurl/gnurl_share_strerror.3
+++ b/docs/libcurl/gnurl_share_strerror.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_unescape.3 b/docs/libcurl/gnurl_unescape.3
index 6f3dce495..60c337816 100644
--- a/docs/libcurl/gnurl_unescape.3
+++ b/docs/libcurl/gnurl_unescape.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_version.3 b/docs/libcurl/gnurl_version.3
index 2d3f02635..56ea8051f 100644
--- a/docs/libcurl/gnurl_version.3
+++ b/docs/libcurl/gnurl_version.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/gnurl_version_info.3 
b/docs/libcurl/gnurl_version_info.3
index 1ba8d8401..8ad92b435 100644
--- a/docs/libcurl/gnurl_version_info.3
+++ b/docs/libcurl/gnurl_version_info.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -49,7 +49,6 @@ The curl_version_info_data struct looks like this
 typedef struct {
   CURLversion age;          /* see description below */
 
-  /* when 'age' is 0 or higher, the members below also exist: */
   const char *version;      /* human readable string */
   unsigned int version_num; /* numeric representation */
   const char *host;         /* human readable string */
@@ -59,27 +58,27 @@ typedef struct {
   const char *libz_version; /* human readable string */
   const char * const *protocols; /* protocols */
 
-  /* when 'age' is 1 or higher, the members below also exist: */
+  /* when 'age' is CURLVERSION_SECOND or higher, the members below exist */
   const char *ares;         /* human readable string */
   int ares_num;             /* number */
 
-  /* when 'age' is 2 or higher, the member below also exists: */
+  /* when 'age' is CURLVERSION_THIRD or higher, the members below exist */
   const char *libidn;       /* human readable string */
 
-  /* when 'age' is 3 or higher (7.16.1 or later), the members below also
-     exist  */
+  /* when 'age' is CURLVERSION_FOURTH or higher (>= 7.16.1), the members
+     below exist */
   int iconv_ver_num;       /* '_libiconv_version' if iconv support enabled */
 
   const char *libssh_version; /* human readable string */
 
-  /* when 'age' is 4 or higher (7.57.0 or later), the members below also
-     exist  */
+  /* when 'age' is CURLVERSION_FIFTH or higher (>= 7.57.0), the members
+     below exist */
   unsigned int brotli_ver_num; /* Numeric Brotli version
                                   (MAJOR << 24) | (MINOR << 12) | PATCH */
   const char *brotli_version; /* human readable string. */
 
-  /* when 'age is CURLVERSION_SIXTH or alter (7.66.0 or later), these fields
-     also exist */
+  /* when 'age' is CURLVERSION_SIXTH or higher (>= 7.66.0), the members
+     below exist */
   unsigned int nghttp2_ver_num; /* Numeric nghttp2 version
                                    (MAJOR << 16) | (MINOR << 8) | PATCH */
   const char *nghttp2_version; /* human readable string. */
@@ -87,6 +86,12 @@ typedef struct {
   const char *quic_version;    /* human readable quic (+ HTTP/3) library +
                                   version or NULL */
 
+  /* when 'age' is CURLVERSION_SEVENTH or higher (>= 7.70.0), the members
+     below exist */
+  const char *cainfo;          /* the built-in default CURLOPT_CAINFO, might
+                                  be NULL */
+  const char *capath;          /* the built-in default CURLOPT_CAPATH, might
+                                  be NULL */
 } curl_version_info_data;
 .fi
 
diff --git a/docs/libcurl/libgnurl-easy.3 b/docs/libcurl/libgnurl-easy.3
index d112632fa..7ba0b683e 100644
--- a/docs/libcurl/libgnurl-easy.3
+++ b/docs/libcurl/libgnurl-easy.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/libgnurl-errors.3 b/docs/libcurl/libgnurl-errors.3
index eff6544b6..6f7d87d73 100644
--- a/docs/libcurl/libgnurl-errors.3
+++ b/docs/libcurl/libgnurl-errors.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -283,8 +283,8 @@ Things are fine.
 The passed-in handle is not a valid CURLM handle.
 .IP "CURLM_BAD_EASY_HANDLE (2)"
 An easy handle was not good/valid. It could mean that it isn't an easy handle
-at all, or possibly that the handle already is in used by this or another
-multi handle.
+at all, or possibly that the handle already is in use by this or another multi
+handle.
 .IP "CURLM_OUT_OF_MEMORY (3)"
 You are doomed.
 .IP "CURLM_INTERNAL_ERROR (4)"
diff --git a/docs/libcurl/libgnurl-multi.3 b/docs/libcurl/libgnurl-multi.3
index 4674abdce..5176aebf0 100644
--- a/docs/libcurl/libgnurl-multi.3
+++ b/docs/libcurl/libgnurl-multi.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -90,7 +90,7 @@ call libcurl again. The older API to accomplish the same 
thing is
 \fIcurl_multi_fdset(3)\fP that extracts fd_sets from libcurl to use in
 select() or poll() calls in order to get to know when the transfers in the
 multi stack might need attention. Both these APIs allow for your program to
-wait for input on your own private file descriptors at the same time
+wait for input on your own private file descriptors at the same time.
 \fIcurl_multi_timeout(3)\fP also helps you with providing a suitable timeout
 period for your select() calls.
 
diff --git a/docs/libcurl/libgnurl-security.3 b/docs/libcurl/libgnurl-security.3
index da45ed7f6..f340facd3 100644
--- a/docs/libcurl/libgnurl-security.3
+++ b/docs/libcurl/libgnurl-security.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -217,6 +217,32 @@ avoid that, keep control of what URLs to use and/or 
prevent curl/libcurl from
 using the protocol.
 
 By default, libcurl prohibits redirects to file:// URLs.
+
+.SH "Warning: file:// on Windows"
+The Windows operating system will automatically, and without any way for
+applications to disable it, try to establish a connection to another host over
+the network and access it (over SMB or other protocols), if only the correct
+file path is accessed.
+
+When first realizing this, the curl team tried to filter out such attempts in
+order to protect applications for inadvertent probes of for example internal
+networks etc. This resulted in CVE-2019-15601 and the associated security fix.
+
+However, we've since been made aware of the fact that the previous fix was far
+from adequate as there are several other ways to accomplish more or less the
+same thing: accessing a remote host over the network instead of the local file
+system.
+
+The conclusion we have come to is that this is a weakness or feature in the
+Windows operating system itself, that we as an application cannot safely
+protect users against. It would just be a whack-a-mole race we don't want to
+participate in. There are too many ways to do it and there's no knob we can
+use to turn off the practice.
+
+If you use curl or libcurl on Windows (any version), disable the use of the
+FILE protocol in curl or be prepared that accesses to a range of "magic paths"
+will potentially make your system try to access other hosts on your
+network. curl cannot protect you against this.
 .SH "What if the user can set the URL"
 Applications may find it tempting to let users set the URL that it can work
 on. That's probably fine, but opens up for mischief and trickery that you as
diff --git a/docs/libcurl/libgnurl.3 b/docs/libcurl/libgnurl.3
index e8ecc31da..d4ed70349 100644
--- a/docs/libcurl/libgnurl.3
+++ b/docs/libcurl/libgnurl.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/libgnurl.m4 b/docs/libcurl/libgnurl.m4
index 7e79629d5..c4f484813 100644
--- a/docs/libcurl/libgnurl.m4
+++ b/docs/libcurl/libgnurl.m4
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2006, David Shaw <address@hidden>
+# Copyright (C) 2006 - 2020, David Shaw <address@hidden>
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/mksymbolsmanpage.pl b/docs/libcurl/mksymbolsmanpage.pl
index b0b8480ad..7ac6fac88 100755
--- a/docs/libcurl/mksymbolsmanpage.pl
+++ b/docs/libcurl/mksymbolsmanpage.pl
@@ -6,7 +6,7 @@
 # *                            | (__| |_| |  _ <| |___
 # *                             \___|\___/|_| \_\_____|
 # *
-# * Copyright (C) 2015, Daniel Stenberg, <address@hidden>, et al.
+# * Copyright (C) 2015 - 2020, Daniel Stenberg, <address@hidden>, et al.
 # *
 # * This software is licensed as described in the file COPYING, which
 # * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/CMakeLists.txt b/docs/libcurl/opts/CMakeLists.txt
index 709d3e4b8..98acedf2a 100644
--- a/docs/libcurl/opts/CMakeLists.txt
+++ b/docs/libcurl/opts/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2009 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Load man_MANS from shared file
 transform_makefile_inc("Makefile.inc" 
"${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
 include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
diff --git a/docs/libcurl/opts/GNURLINFO_CERTINFO.3 
b/docs/libcurl/opts/GNURLINFO_CERTINFO.3
index e60aeed96..42482c473 100644
--- a/docs/libcurl/opts/GNURLINFO_CERTINFO.3
+++ b/docs/libcurl/opts/GNURLINFO_CERTINFO.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_CONDITION_UNMET.3 
b/docs/libcurl/opts/GNURLINFO_CONDITION_UNMET.3
index f39ae8f27..dcd6fc0e5 100644
--- a/docs/libcurl/opts/GNURLINFO_CONDITION_UNMET.3
+++ b/docs/libcurl/opts/GNURLINFO_CONDITION_UNMET.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -22,7 +22,7 @@
 .\"
 .TH GNURLINFO_CONDITION_UNMET 3 "1 Sep 2015" "libcurl 7.44.0" 
"curl_easy_getinfo options"
 .SH NAME
-CURLINFO_CONDITION_UNMET \- get info on unmet time conditional
+CURLINFO_CONDITION_UNMET \- get info on unmet time conditional or 304 HTTP 
response.
 .SH SYNOPSIS
 #include <gnurl/curl.h>
 
@@ -32,7 +32,9 @@ Pass a pointer to a long to receive the number 1 if the 
condition provided in
 the previous request didn't match (see \fICURLOPT_TIMECONDITION(3)\fP). Alas,
 if this returns a 1 you know that the reason you didn't get data in return is
 because it didn't fulfill the condition. The long this argument points to will
-get a zero stored if the condition instead was met.
+get a zero stored if the condition instead was met. This can also return 1 if
+the server responded with a 304 HTTP status code, for example after sending a
+custom "If-Match-*" header.
 .SH PROTOCOLS
 HTTP and some
 .SH EXAMPLE
diff --git a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3 
b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3
index 74d34b706..74ca85049 100644
--- a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD_T.3 
b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD_T.3
index d11c1da92..f6c033fb8 100644
--- a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD_T.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_COOKIELIST.3 
b/docs/libcurl/opts/GNURLINFO_COOKIELIST.3
index 2335f71db..e82ddb8a3 100644
--- a/docs/libcurl/opts/GNURLINFO_COOKIELIST.3
+++ b/docs/libcurl/opts/GNURLINFO_COOKIELIST.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_OS_ERRNO.3 
b/docs/libcurl/opts/GNURLINFO_OS_ERRNO.3
index 543df569f..2e987b1ae 100644
--- a/docs/libcurl/opts/GNURLINFO_OS_ERRNO.3
+++ b/docs/libcurl/opts/GNURLINFO_OS_ERRNO.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_PROTOCOL.3 
b/docs/libcurl/opts/GNURLINFO_PROTOCOL.3
index 794435aaa..ff6546379 100644
--- a/docs/libcurl/opts/GNURLINFO_PROTOCOL.3
+++ b/docs/libcurl/opts/GNURLINFO_PROTOCOL.3
@@ -38,7 +38,7 @@ CURLPROTO_IMAPS, CURLPROTO_LDAP, CURLPROTO_LDAPS, 
CURLPROTO_POP3,
 CURLPROTO_POP3S, CURLPROTO_RTMP, CURLPROTO_RTMPE, CURLPROTO_RTMPS,
 CURLPROTO_RTMPT, CURLPROTO_RTMPTE, CURLPROTO_RTMPTS, CURLPROTO_RTSP,
 CURLPROTO_SCP, CURLPROTO_SFTP, CURLPROTO_SMB, CURLPROTO_SMBS, CURLPROTO_SMTP,
-CURLPROTO_SMTPS, CURLPROTO_TELNET, CURLPROTO_TFTP
+CURLPROTO_SMTPS, CURLPROTO_TELNET, CURLPROTO_TFTP, CURLPROTO_MQTT
 .SH PROTOCOLS
 All
 .SH EXAMPLE
diff --git a/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME.3 
b/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME.3
index f1224a873..26f3f5117 100644
--- a/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME.3
+++ b/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_RESPONSE_CODE.3 
b/docs/libcurl/opts/GNURLINFO_RESPONSE_CODE.3
index 6a413235a..9632fd837 100644
--- a/docs/libcurl/opts/GNURLINFO_RESPONSE_CODE.3
+++ b/docs/libcurl/opts/GNURLINFO_RESPONSE_CODE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_RETRY_AFTER.3 
b/docs/libcurl/opts/GNURLINFO_RETRY_AFTER.3
index 52d926cd3..785c6b4df 100644
--- a/docs/libcurl/opts/GNURLINFO_RETRY_AFTER.3
+++ b/docs/libcurl/opts/GNURLINFO_RETRY_AFTER.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_SCHEME.3 
b/docs/libcurl/opts/GNURLINFO_SCHEME.3
index 7307370bf..69f20a9f4 100644
--- a/docs/libcurl/opts/GNURLINFO_SCHEME.3
+++ b/docs/libcurl/opts/GNURLINFO_SCHEME.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD_T.3 
b/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD_T.3
index b77009c9f..bee15f477 100644
--- a/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD_T.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD_T.3 
b/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD_T.3
index 5a75103fd..d042d7d7e 100644
--- a/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD_T.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD_T.3 
b/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD_T.3
index 488d1923e..2c574b44e 100644
--- a/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD_T.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD_T.3 
b/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD_T.3
index 0a4a1829e..7959222d3 100644
--- a/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD_T.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLMOPT_MAXCONNECTS.3 
b/docs/libcurl/opts/GNURLMOPT_MAXCONNECTS.3
index 6d16bb60b..942918aca 100644
--- a/docs/libcurl/opts/GNURLMOPT_MAXCONNECTS.3
+++ b/docs/libcurl/opts/GNURLMOPT_MAXCONNECTS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLMOPT_PUSHFUNCTION.3 
b/docs/libcurl/opts/GNURLMOPT_PUSHFUNCTION.3
index 9177a8ba2..ee4872336 100644
--- a/docs/libcurl/opts/GNURLMOPT_PUSHFUNCTION.3
+++ b/docs/libcurl/opts/GNURLMOPT_PUSHFUNCTION.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_CHUNK_DATA.3 
b/docs/libcurl/opts/GNURLOPT_CHUNK_DATA.3
index 57065e827..04572f405 100644
--- a/docs/libcurl/opts/GNURLOPT_CHUNK_DATA.3
+++ b/docs/libcurl/opts/GNURLOPT_CHUNK_DATA.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_CLOSESOCKETDATA.3 
b/docs/libcurl/opts/GNURLOPT_CLOSESOCKETDATA.3
index d81d30aa6..dd9e69594 100644
--- a/docs/libcurl/opts/GNURLOPT_CLOSESOCKETDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_CLOSESOCKETDATA.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_CLOSESOCKETFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_CLOSESOCKETFUNCTION.3
index ebb1b7c61..f7d8d45b4 100644
--- a/docs/libcurl/opts/GNURLOPT_CLOSESOCKETFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_CLOSESOCKETFUNCTION.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT_MS.3 
b/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT_MS.3
index cc4be2902..da836e0c8 100644
--- a/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT_MS.3
+++ b/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT_MS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_CONNECT_TO.3 
b/docs/libcurl/opts/GNURLOPT_CONNECT_TO.3
index 999fca1a5..a54121001 100644
--- a/docs/libcurl/opts/GNURLOPT_CONNECT_TO.3
+++ b/docs/libcurl/opts/GNURLOPT_CONNECT_TO.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_COOKIE.3 
b/docs/libcurl/opts/GNURLOPT_COOKIE.3
index 45b3517e9..d38dd2c07 100644
--- a/docs/libcurl/opts/GNURLOPT_COOKIE.3
+++ b/docs/libcurl/opts/GNURLOPT_COOKIE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_COPYPOSTFIELDS.3 
b/docs/libcurl/opts/GNURLOPT_COPYPOSTFIELDS.3
index 91b76ef33..16f12f28a 100644
--- a/docs/libcurl/opts/GNURLOPT_COPYPOSTFIELDS.3
+++ b/docs/libcurl/opts/GNURLOPT_COPYPOSTFIELDS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_CUSTOMREQUEST.3 
b/docs/libcurl/opts/GNURLOPT_CUSTOMREQUEST.3
index 3b701c07b..84064876e 100644
--- a/docs/libcurl/opts/GNURLOPT_CUSTOMREQUEST.3
+++ b/docs/libcurl/opts/GNURLOPT_CUSTOMREQUEST.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_DEBUGDATA.3 
b/docs/libcurl/opts/GNURLOPT_DEBUGDATA.3
index b6c54d021..1435ee039 100644
--- a/docs/libcurl/opts/GNURLOPT_DEBUGDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_DEBUGDATA.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_DEBUGFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_DEBUGFUNCTION.3
index 46f0187e7..7479034e3 100644
--- a/docs/libcurl/opts/GNURLOPT_DEBUGFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_DEBUGFUNCTION.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_DEFAULT_PROTOCOL.3 
b/docs/libcurl/opts/GNURLOPT_DEFAULT_PROTOCOL.3
index eb8564c1e..92f4fc253 100644
--- a/docs/libcurl/opts/GNURLOPT_DEFAULT_PROTOCOL.3
+++ b/docs/libcurl/opts/GNURLOPT_DEFAULT_PROTOCOL.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_ERRORBUFFER.3 
b/docs/libcurl/opts/GNURLOPT_ERRORBUFFER.3
index 593061d78..caf21ba21 100644
--- a/docs/libcurl/opts/GNURLOPT_ERRORBUFFER.3
+++ b/docs/libcurl/opts/GNURLOPT_ERRORBUFFER.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_EXPECT_100_TIMEOUT_MS.3 
b/docs/libcurl/opts/GNURLOPT_EXPECT_100_TIMEOUT_MS.3
index 51c52ee25..ce0dbcf64 100644
--- a/docs/libcurl/opts/GNURLOPT_EXPECT_100_TIMEOUT_MS.3
+++ b/docs/libcurl/opts/GNURLOPT_EXPECT_100_TIMEOUT_MS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_FAILONERROR.3 
b/docs/libcurl/opts/GNURLOPT_FAILONERROR.3
index 1a1217a32..2e9662c0e 100644
--- a/docs/libcurl/opts/GNURLOPT_FAILONERROR.3
+++ b/docs/libcurl/opts/GNURLOPT_FAILONERROR.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_USE_EPRT.3 
b/docs/libcurl/opts/GNURLOPT_FTP_USE_EPRT.3
index a26587d89..9c6cd6365 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_USE_EPRT.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_USE_EPRT.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 
b/docs/libcurl/opts/GNURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3
index fc980486a..9c8ed42f1 100644
--- a/docs/libcurl/opts/GNURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3
+++ b/docs/libcurl/opts/GNURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_HTTPHEADER.3 
b/docs/libcurl/opts/GNURLOPT_HTTPHEADER.3
index 454f9c103..017cb0a37 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTPHEADER.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTPHEADER.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_HTTPPROXYTUNNEL.3 
b/docs/libcurl/opts/GNURLOPT_HTTPPROXYTUNNEL.3
index a183cb0bf..d4975406f 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTPPROXYTUNNEL.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTPPROXYTUNNEL.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_IGNORE_CONTENT_LENGTH.3 
b/docs/libcurl/opts/GNURLOPT_IGNORE_CONTENT_LENGTH.3
index 3ce98ebcb..bee16681c 100644
--- a/docs/libcurl/opts/GNURLOPT_IGNORE_CONTENT_LENGTH.3
+++ b/docs/libcurl/opts/GNURLOPT_IGNORE_CONTENT_LENGTH.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_INFILESIZE.3 
b/docs/libcurl/opts/GNURLOPT_INFILESIZE.3
index 1bb55118d..197f9cd46 100644
--- a/docs/libcurl/opts/GNURLOPT_INFILESIZE.3
+++ b/docs/libcurl/opts/GNURLOPT_INFILESIZE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_INFILESIZE_LARGE.3 
b/docs/libcurl/opts/GNURLOPT_INFILESIZE_LARGE.3
index 2aefeb44c..8a5acfc04 100644
--- a/docs/libcurl/opts/GNURLOPT_INFILESIZE_LARGE.3
+++ b/docs/libcurl/opts/GNURLOPT_INFILESIZE_LARGE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_INTERLEAVEFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_INTERLEAVEFUNCTION.3
index bd5995963..c2c267e7f 100644
--- a/docs/libcurl/opts/GNURLOPT_INTERLEAVEFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_INTERLEAVEFUNCTION.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, 2017, Daniel Stenberg, <address@hidden>, et 
al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_IOCTLFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_IOCTLFUNCTION.3
index 5d8a72fd1..f37f9c036 100644
--- a/docs/libcurl/opts/GNURLOPT_IOCTLFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_IOCTLFUNCTION.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_MAXREDIRS.3 
b/docs/libcurl/opts/GNURLOPT_MAXREDIRS.3
index 8740fe7f8..159bf7b71 100644
--- a/docs/libcurl/opts/GNURLOPT_MAXREDIRS.3
+++ b/docs/libcurl/opts/GNURLOPT_MAXREDIRS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_NETRC.3 
b/docs/libcurl/opts/GNURLOPT_NETRC.3
index b0c681c48..67b1772bf 100644
--- a/docs/libcurl/opts/GNURLOPT_NETRC.3
+++ b/docs/libcurl/opts/GNURLOPT_NETRC.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_NOSIGNAL.3 
b/docs/libcurl/opts/GNURLOPT_NOSIGNAL.3
index f5f71aa0f..8a38d8f34 100644
--- a/docs/libcurl/opts/GNURLOPT_NOSIGNAL.3
+++ b/docs/libcurl/opts/GNURLOPT_NOSIGNAL.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PASSWORD.3 
b/docs/libcurl/opts/GNURLOPT_PASSWORD.3
index 397af1b2e..01b7cf7c6 100644
--- a/docs/libcurl/opts/GNURLOPT_PASSWORD.3
+++ b/docs/libcurl/opts/GNURLOPT_PASSWORD.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PATH_AS_IS.3 
b/docs/libcurl/opts/GNURLOPT_PATH_AS_IS.3
index 4b62e0b1a..eb03d0ed1 100644
--- a/docs/libcurl/opts/GNURLOPT_PATH_AS_IS.3
+++ b/docs/libcurl/opts/GNURLOPT_PATH_AS_IS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_POSTFIELDS.3 
b/docs/libcurl/opts/GNURLOPT_POSTFIELDS.3
index 80b746320..88b16a302 100644
--- a/docs/libcurl/opts/GNURLOPT_POSTFIELDS.3
+++ b/docs/libcurl/opts/GNURLOPT_POSTFIELDS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE.3 
b/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE.3
index df30744f7..c3603e00e 100644
--- a/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE.3
+++ b/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE_LARGE.3 
b/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE_LARGE.3
index f8f025c8f..8d4750a20 100644
--- a/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE_LARGE.3
+++ b/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE_LARGE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_POSTQUOTE.3 
b/docs/libcurl/opts/GNURLOPT_POSTQUOTE.3
index f4ebeb00a..1e82453be 100644
--- a/docs/libcurl/opts/GNURLOPT_POSTQUOTE.3
+++ b/docs/libcurl/opts/GNURLOPT_POSTQUOTE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_POSTREDIR.3 
b/docs/libcurl/opts/GNURLOPT_POSTREDIR.3
index f0215bcbb..1729c843f 100644
--- a/docs/libcurl/opts/GNURLOPT_POSTREDIR.3
+++ b/docs/libcurl/opts/GNURLOPT_POSTREDIR.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PREQUOTE.3 
b/docs/libcurl/opts/GNURLOPT_PREQUOTE.3
index 10bb993a6..16d3cc0b6 100644
--- a/docs/libcurl/opts/GNURLOPT_PREQUOTE.3
+++ b/docs/libcurl/opts/GNURLOPT_PREQUOTE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PRE_PROXY.3 
b/docs/libcurl/opts/GNURLOPT_PRE_PROXY.3
index 9d53222d5..f1640e444 100644
--- a/docs/libcurl/opts/GNURLOPT_PRE_PROXY.3
+++ b/docs/libcurl/opts/GNURLOPT_PRE_PROXY.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PRIVATE.3 
b/docs/libcurl/opts/GNURLOPT_PRIVATE.3
index 1269f8e3e..7074cb8a1 100644
--- a/docs/libcurl/opts/GNURLOPT_PRIVATE.3
+++ b/docs/libcurl/opts/GNURLOPT_PRIVATE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PROGRESSDATA.3 
b/docs/libcurl/opts/GNURLOPT_PROGRESSDATA.3
index c9e36ef3d..8156eaa38 100644
--- a/docs/libcurl/opts/GNURLOPT_PROGRESSDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_PROGRESSDATA.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3
index 47ca33b27..bfa566ec6 100644
--- a/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PROTOCOLS.3 
b/docs/libcurl/opts/GNURLOPT_PROTOCOLS.3
index 5f9ea295d..fe540720f 100644
--- a/docs/libcurl/opts/GNURLOPT_PROTOCOLS.3
+++ b/docs/libcurl/opts/GNURLOPT_PROTOCOLS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_CAINFO.3 
b/docs/libcurl/opts/GNURLOPT_PROXY_CAINFO.3
index b365cf471..bcff39f75 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_CAINFO.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_CAINFO.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_CRLFILE.3 
b/docs/libcurl/opts/GNURLOPT_PROXY_CRLFILE.3
index 064d6d8e5..68451777b 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_CRLFILE.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_CRLFILE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_KEYPASSWD.3 
b/docs/libcurl/opts/GNURLOPT_PROXY_KEYPASSWD.3
index d72dae1fa..b5134f5b4 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_KEYPASSWD.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_KEYPASSWD.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT.3 
b/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT.3
index 305f8b2c0..38f558349 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERTTYPE.3 
b/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERTTYPE.3
index a0ff85e3f..6c6cb5e38 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERTTYPE.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERTTYPE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEYTYPE.3 
b/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEYTYPE.3
index 1c6ac5149..7826e1d44 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEYTYPE.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEYTYPE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_CIPHER_LIST.3 
b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_CIPHER_LIST.3
index cfe20446e..59440c8c4 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_CIPHER_LIST.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_CIPHER_LIST.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_OPTIONS.3 
b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_OPTIONS.3
index 9b6e3b09e..46e926c97 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_OPTIONS.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_OPTIONS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -49,6 +49,13 @@ Tells libcurl to not accept "partial" certificate chains, 
which it otherwise
 does by default. This option is only supported for OpenSSL and will fail the
 certificate verification if the chain ends with an intermediate certificate
 and not with a root cert. (Added in 7.68.0)
+
+.IP CURLSSLOPT_REVOKE_BEST_EFFORT
+Tells libcurl to ignore certificate revocation checks in case of missing or
+offline distribution points for those SSL backends where such behavior is
+present. This option is only supported for Schannel (the native Windows SSL
+library). If combined with \fICURLSSLOPT_NO_REVOKE\fP, the latter takes
+precedence. (Added in 7.70.0)
 .SH DEFAULT
 0
 .SH PROTOCOLS
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_TRANSFER_MODE.3 
b/docs/libcurl/opts/GNURLOPT_PROXY_TRANSFER_MODE.3
index 760c39678..66fbdcc65 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_TRANSFER_MODE.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_TRANSFER_MODE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_PUT.3 b/docs/libcurl/opts/GNURLOPT_PUT.3
index 76dd9bf4f..54cf0400c 100644
--- a/docs/libcurl/opts/GNURLOPT_PUT.3
+++ b/docs/libcurl/opts/GNURLOPT_PUT.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_QUOTE.3 
b/docs/libcurl/opts/GNURLOPT_QUOTE.3
index 7740d1d6a..a429b72b0 100644
--- a/docs/libcurl/opts/GNURLOPT_QUOTE.3
+++ b/docs/libcurl/opts/GNURLOPT_QUOTE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_READDATA.3 
b/docs/libcurl/opts/GNURLOPT_READDATA.3
index 167fca583..9b532248d 100644
--- a/docs/libcurl/opts/GNURLOPT_READDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_READDATA.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_READFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_READFUNCTION.3
index e269b438c..ff07c5212 100644
--- a/docs/libcurl/opts/GNURLOPT_READFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_READFUNCTION.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_REFERER.3 
b/docs/libcurl/opts/GNURLOPT_REFERER.3
index 72331e56a..26ce192aa 100644
--- a/docs/libcurl/opts/GNURLOPT_REFERER.3
+++ b/docs/libcurl/opts/GNURLOPT_REFERER.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_RESOLVE.3 
b/docs/libcurl/opts/GNURLOPT_RESOLVE.3
index b738241b7..5a064eca4 100644
--- a/docs/libcurl/opts/GNURLOPT_RESOLVE.3
+++ b/docs/libcurl/opts/GNURLOPT_RESOLVE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_RESUME_FROM.3 
b/docs/libcurl/opts/GNURLOPT_RESUME_FROM.3
index 2c06999bf..4e3d06f91 100644
--- a/docs/libcurl/opts/GNURLOPT_RESUME_FROM.3
+++ b/docs/libcurl/opts/GNURLOPT_RESUME_FROM.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_RESUME_FROM_LARGE.3 
b/docs/libcurl/opts/GNURLOPT_RESUME_FROM_LARGE.3
index 8077637d5..1f38993f4 100644
--- a/docs/libcurl/opts/GNURLOPT_RESUME_FROM_LARGE.3
+++ b/docs/libcurl/opts/GNURLOPT_RESUME_FROM_LARGE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_RTSP_CLIENT_CSEQ.3 
b/docs/libcurl/opts/GNURLOPT_RTSP_CLIENT_CSEQ.3
index 1ccc71fa9..2dd0a545a 100644
--- a/docs/libcurl/opts/GNURLOPT_RTSP_CLIENT_CSEQ.3
+++ b/docs/libcurl/opts/GNURLOPT_RTSP_CLIENT_CSEQ.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_SEEKFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_SEEKFUNCTION.3
index 85eca1d68..3d4ad7403 100644
--- a/docs/libcurl/opts/GNURLOPT_SEEKFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_SEEKFUNCTION.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_CIPHER_LIST.3 
b/docs/libcurl/opts/GNURLOPT_SSL_CIPHER_LIST.3
index f80caad60..05e42fa47 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_CIPHER_LIST.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_CIPHER_LIST.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3 
b/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3
index bf7fee028..19bfbd910 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -49,6 +49,12 @@ Tells libcurl to not accept "partial" certificate chains, 
which it otherwise
 does by default. This option is only supported for OpenSSL and will fail the
 certificate verification if the chain ends with an intermediate certificate
 and not with a root cert. (Added in 7.68.0)
+.IP CURLSSLOPT_REVOKE_BEST_EFFORT
+Tells libcurl to ignore certificate revocation checks in case of missing or
+offline distribution points for those SSL backends where such behavior is
+present. This option is only supported for Schannel (the native Windows SSL
+library). If combined with \fICURLSSLOPT_NO_REVOKE\fP, the latter takes
+precedence. (Added in 7.70.0)
 .SH DEFAULT
 0
 .SH PROTOCOLS
diff --git a/docs/libcurl/opts/GNURLOPT_STDERR.3 
b/docs/libcurl/opts/GNURLOPT_STDERR.3
index 6855e412f..c2758d54a 100644
--- a/docs/libcurl/opts/GNURLOPT_STDERR.3
+++ b/docs/libcurl/opts/GNURLOPT_STDERR.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS_E.3 
b/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS_E.3
index ff2c72442..128ae5e65 100644
--- a/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS_E.3
+++ b/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS_E.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_STREAM_WEIGHT.3 
b/docs/libcurl/opts/GNURLOPT_STREAM_WEIGHT.3
index 7348c35bc..2d4fa9f6b 100644
--- a/docs/libcurl/opts/GNURLOPT_STREAM_WEIGHT.3
+++ b/docs/libcurl/opts/GNURLOPT_STREAM_WEIGHT.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_TCP_KEEPALIVE.3 
b/docs/libcurl/opts/GNURLOPT_TCP_KEEPALIVE.3
index cf781ea22..155f5e1c5 100644
--- a/docs/libcurl/opts/GNURLOPT_TCP_KEEPALIVE.3
+++ b/docs/libcurl/opts/GNURLOPT_TCP_KEEPALIVE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_TCP_KEEPIDLE.3 
b/docs/libcurl/opts/GNURLOPT_TCP_KEEPIDLE.3
index ffe82d41d..08f7934c1 100644
--- a/docs/libcurl/opts/GNURLOPT_TCP_KEEPIDLE.3
+++ b/docs/libcurl/opts/GNURLOPT_TCP_KEEPIDLE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_TCP_KEEPINTVL.3 
b/docs/libcurl/opts/GNURLOPT_TCP_KEEPINTVL.3
index f658b0164..d9e23b603 100644
--- a/docs/libcurl/opts/GNURLOPT_TCP_KEEPINTVL.3
+++ b/docs/libcurl/opts/GNURLOPT_TCP_KEEPINTVL.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_TCP_NODELAY.3 
b/docs/libcurl/opts/GNURLOPT_TCP_NODELAY.3
index 6a87ab89a..dd6fb6251 100644
--- a/docs/libcurl/opts/GNURLOPT_TCP_NODELAY.3
+++ b/docs/libcurl/opts/GNURLOPT_TCP_NODELAY.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_TIMEOUT_MS.3 
b/docs/libcurl/opts/GNURLOPT_TIMEOUT_MS.3
index 62c719e2e..8bd7b8651 100644
--- a/docs/libcurl/opts/GNURLOPT_TIMEOUT_MS.3
+++ b/docs/libcurl/opts/GNURLOPT_TIMEOUT_MS.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_UNIX_SOCKET_PATH.3 
b/docs/libcurl/opts/GNURLOPT_UNIX_SOCKET_PATH.3
index a42958772..355cf576e 100644
--- a/docs/libcurl/opts/GNURLOPT_UNIX_SOCKET_PATH.3
+++ b/docs/libcurl/opts/GNURLOPT_UNIX_SOCKET_PATH.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_UPLOAD.3 
b/docs/libcurl/opts/GNURLOPT_UPLOAD.3
index 5d0e90933..970b1281c 100644
--- a/docs/libcurl/opts/GNURLOPT_UPLOAD.3
+++ b/docs/libcurl/opts/GNURLOPT_UPLOAD.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_URL.3 b/docs/libcurl/opts/GNURLOPT_URL.3
index 473ea4f8a..25c52c25f 100644
--- a/docs/libcurl/opts/GNURLOPT_URL.3
+++ b/docs/libcurl/opts/GNURLOPT_URL.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -152,6 +152,10 @@ path.
 ftp://user:address@hidden//readme.txt - This retrieves the readme.txt
 from the root directory when logging in as a specified user.
 
+.IP FILE
+When a FILE:// URL is accessed on Windows systems, it can be crafted in a way
+so that Windows attempts to connect to a (remote) machine when curl wants to
+read or write such a path.
 .IP SMTP
 The path part of a SMTP request specifies the host name to present during
 communication with the mail server. If the path is omitted then libcurl will
diff --git a/docs/libcurl/opts/GNURLOPT_USERAGENT.3 
b/docs/libcurl/opts/GNURLOPT_USERAGENT.3
index d05588890..8bb754cc2 100644
--- a/docs/libcurl/opts/GNURLOPT_USERAGENT.3
+++ b/docs/libcurl/opts/GNURLOPT_USERAGENT.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_USE_SSL.3 
b/docs/libcurl/opts/GNURLOPT_USE_SSL.3
index 6e5d276f3..ee1f1c7e2 100644
--- a/docs/libcurl/opts/GNURLOPT_USE_SSL.3
+++ b/docs/libcurl/opts/GNURLOPT_USE_SSL.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_WRITEDATA.3 
b/docs/libcurl/opts/GNURLOPT_WRITEDATA.3
index 6862cd1ce..f875f40ee 100644
--- a/docs/libcurl/opts/GNURLOPT_WRITEDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_WRITEDATA.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_WRITEFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_WRITEFUNCTION.3
index 543bbc037..e76d26a6b 100644
--- a/docs/libcurl/opts/GNURLOPT_WRITEFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_WRITEFUNCTION.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -76,8 +76,37 @@ Support for the CURL_WRITEFUNC_PAUSE return code was added 
in version 7.18.0.
 .SH RETURN VALUE
 This will return CURLE_OK.
 .SH EXAMPLE
-A common technique is to use this callback to store the incoming data into a
-dynamically growing allocated buffer. Like in the getinmemory example:
-https://curl.haxx.se/libcurl/c/getinmemory.html
+.NF
+ struct memory {
+   char *response;
+   size_t size;
+ };
+
+ static size_t cb(void *data, size_t size, size_t nmemb, void *userp)
+ {
+   size_t realsize = size * nmemb;
+   struct memory *mem = (struct memory *)userp;
+
+   char *ptr = realloc(mem->response, mem->size + realsize + 1);
+   if(ptr == NULL)
+     return 0;  /* out of memory! */
+
+   mem->response = ptr;
+   memcpy(&(mem->response[mem->size]), data, realsize);
+   mem->size += realsize;
+   mem->response[mem->size] = 0;
+
+   return realsize;
+ }
+
+ struct memory chunk;
+
+ /* send all data to this function  */
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, cb);
+
+ /* we pass our 'chunk' struct to the callback function */
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
+.FI
 .SH "SEE ALSO"
 .BR CURLOPT_WRITEDATA "(3), " CURLOPT_READFUNCTION "(3), "
+.BR CURLOPT_HEADERFUNCTION "(3), "
diff --git a/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3
index 02f471535..777732b21 100644
--- a/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/GNURLOPT_XOAUTH2_BEARER.3 
b/docs/libcurl/opts/GNURLOPT_XOAUTH2_BEARER.3
index 6bcefa5c4..60e4c88ee 100644
--- a/docs/libcurl/opts/GNURLOPT_XOAUTH2_BEARER.3
+++ b/docs/libcurl/opts/GNURLOPT_XOAUTH2_BEARER.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/opts/Makefile.inc b/docs/libcurl/opts/Makefile.inc
index f8a9f2cfa..1355df8ff 100644
--- a/docs/libcurl/opts/Makefile.inc
+++ b/docs/libcurl/opts/Makefile.inc
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Shared between Makefile.am and CMakeLists.txt
 
 man_MANS =                                      \
diff --git a/docs/libcurl/opts/template.3 b/docs/libcurl/opts/template.3
index 244ec10bc..8ed63bc6d 100644
--- a/docs/libcurl/opts/template.3
+++ b/docs/libcurl/opts/template.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index 93930c435..3b340ed8e 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -676,6 +676,7 @@ CURLPROTO_IMAP                  7.20.0
 CURLPROTO_IMAPS                 7.20.0
 CURLPROTO_LDAP                  7.19.4
 CURLPROTO_LDAPS                 7.19.4
+CURLPROTO_MQTT                  7.71.0
 CURLPROTO_POP3                  7.20.0
 CURLPROTO_POP3S                 7.20.0
 CURLPROTO_RTMP                  7.21.0
@@ -746,6 +747,7 @@ CURLSSLOPT_NO_PARTIALCHAIN      7.68.0
 CURLSSLOPT_NO_REVOKE            7.44.0
 CURLSSLSET_NO_BACKENDS          7.56.0
 CURLSSLSET_OK                   7.56.0
+CURLSSLOPT_REVOKE_BEST_EFFORT   7.70.0
 CURLSSLSET_TOO_LATE             7.56.0
 CURLSSLSET_UNKNOWN_BACKEND      7.56.0
 CURLUE_BAD_HANDLE               7.62.0
@@ -797,6 +799,7 @@ CURLVERSION_FIRST               7.10
 CURLVERSION_FOURTH              7.16.1
 CURLVERSION_NOW                 7.10
 CURLVERSION_SECOND              7.11.1
+CURLVERSION_SEVENTH             7.70.0
 CURLVERSION_SIXTH               7.66.0
 CURLVERSION_THIRD               7.12.0
 CURL_CHUNK_BGN_FUNC_FAIL        7.21.0
@@ -936,7 +939,6 @@ CURL_VERSION_BROTLI             7.57.0
 CURL_VERSION_CONV               7.15.4
 CURL_VERSION_CURLDEBUG          7.19.6
 CURL_VERSION_DEBUG              7.10.6
-CURL_VERSION_ESNI               7.67.0
 CURL_VERSION_GSSAPI             7.38.0
 CURL_VERSION_GSSNEGOTIATE       7.10.6        7.38.0
 CURL_VERSION_HTTP2              7.33.0
diff --git a/docs/libcurl/symbols.pl b/docs/libcurl/symbols.pl
index b8add8ca1..7e92ea052 100755
--- a/docs/libcurl/symbols.pl
+++ b/docs/libcurl/symbols.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2011, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2011 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/docs/mk-ca-bundle.1 b/docs/mk-ca-bundle.1
index 0cdfb6498..d491cb914 100644
--- a/docs/mk-ca-bundle.1
+++ b/docs/mk-ca-bundle.1
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 2008 - 2016, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 2008 - 2020, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
diff --git a/include/Makefile.am b/include/Makefile.am
index 3d036b8ff..1f722ddda 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 SUBDIRS = gnurl
 
 EXTRA_DIST = README
diff --git a/include/gnurl/curl.h b/include/gnurl/curl.h
index b7cb30a58..11246ea30 100644
--- a/include/gnurl/curl.h
+++ b/include/gnurl/curl.h
@@ -833,6 +833,11 @@ typedef enum {
    if possible. The OpenSSL backend has this ability. */
 #define CURLSSLOPT_NO_PARTIALCHAIN (1<<2)
 
+/* - REVOKE_BEST_EFFORT tells libcurl to ignore certificate revocation offline
+   checks and ignore missing revocation list for those SSL backends where such
+   behavior is present. */
+#define CURLSSLOPT_REVOKE_BEST_EFFORT (1<<3)
+
 /* The default connection attempt delay in milliseconds for happy eyeballs.
    CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
    this value, keep them in sync. */
@@ -932,6 +937,7 @@ typedef enum {
 #define CURLPROTO_GOPHER (1<<25)
 #define CURLPROTO_SMB    (1<<26)
 #define CURLPROTO_SMBS   (1<<27)
+#define CURLPROTO_MQTT   (1<<28)
 #define CURLPROTO_ALL    (~0) /* enable everything */
 
 /* long may be 32 or 64 bits, but we should never depend on anything else
@@ -2428,7 +2434,7 @@ CURL_EXTERN CURLcode curl_global_init(long flags);
  * initialize libcurl and set user defined memory management callback
  * functions.  Users can implement memory management routines to check for
  * memory leaks, check for mis-use of the curl library etc.  User registered
- * callback routines with be invoked by this library instead of the system
+ * callback routines will be invoked by this library instead of the system
  * memory management routines like malloc, free etc.
  */
 CURL_EXTERN CURLcode curl_global_init_mem(long flags,
@@ -2724,6 +2730,7 @@ typedef enum {
   CURLVERSION_FOURTH,
   CURLVERSION_FIFTH,
   CURLVERSION_SIXTH,
+  CURLVERSION_SEVENTH,
   CURLVERSION_LAST /* never actually use this */
 } CURLversion;
 
@@ -2732,7 +2739,7 @@ typedef enum {
    meant to be a built-in version number for what kind of struct the caller
    expects. If the struct ever changes, we redefine the NOW to another enum
    from above. */
-#define CURLVERSION_NOW CURLVERSION_SIXTH
+#define CURLVERSION_NOW CURLVERSION_SEVENTH
 
 typedef struct {
   CURLversion age;          /* age of the returned struct */
@@ -2771,6 +2778,13 @@ typedef struct {
   const char *nghttp2_version; /* human readable string. */
   const char *quic_version;    /* human readable quic (+ HTTP/3) library +
                                   version or NULL */
+
+  /* These fields were added in CURLVERSION_SEVENTH */
+  const char *cainfo;          /* the built-in default CURLOPT_CAINFO, might
+                                  be NULL */
+  const char *capath;          /* the built-in default CURLOPT_CAPATH, might
+                                  be NULL */
+
 } curl_version_info_data;
 
 #define CURL_VERSION_IPV6         (1<<0)  /* IPv6-enabled */
@@ -2805,8 +2819,6 @@ typedef struct {
 #define CURL_VERSION_ALTSVC       (1<<24) /* Alt-Svc handling built-in */
 #define CURL_VERSION_HTTP3        (1<<25) /* HTTP3 support built-in */
 
-#define CURL_VERSION_ESNI         (1<<26) /* ESNI support */
-
  /*
  * NAME curl_version_info()
  *
diff --git a/include/gnurl/curlver.h b/include/gnurl/curlver.h
index aeb39d01c..92c3fd84b 100644
--- a/include/gnurl/curlver.h
+++ b/include/gnurl/curlver.h
@@ -30,13 +30,13 @@
 
 /* This is the version number of the libcurl package from which this header
    file origins: */
-#define LIBCURL_VERSION "7.69.1-DEV"
+#define LIBCURL_VERSION "7.70.0-DEV"
 
 /* The numeric version number is also available "in parts" by using these
    defines: */
 #define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 69
-#define LIBCURL_VERSION_PATCH 1
+#define LIBCURL_VERSION_MINOR 70
+#define LIBCURL_VERSION_PATCH 0
 
 /* This is the numeric version of the libcurl version number, meant for easier
    parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
@@ -57,7 +57,7 @@
    CURL_VERSION_BITS() macro since curl's own configure script greps for it
    and needs it to contain the full number.
 */
-#define LIBCURL_VERSION_NUM 0x074501
+#define LIBCURL_VERSION_NUM 0x074600
 
 /*
  * This is the date and time when the full source package was created. The
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index dcedbc56d..94f59159d 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 set(LIB_NAME libgnurl)
 
 if(BUILD_SHARED_LIBS)
@@ -71,6 +92,11 @@ add_library(
   ${HHEADERS} ${CSOURCES}
   )
 
+add_library(
+  ${PROJECT_NAME}::${LIB_NAME}
+  ALIAS ${LIB_NAME}
+  )
+
 if(MSVC AND NOT BUILD_SHARED_LIBS)
   set_target_properties(${LIB_NAME} PROPERTIES STATIC_LIBRARY_FLAGS 
${CMAKE_EXE_LINKER_FLAGS})
 endif()
@@ -122,5 +148,5 @@ install(TARGETS ${LIB_NAME}
 
 export(TARGETS ${LIB_NAME}
        APPEND FILE ${PROJECT_BINARY_DIR}/libgnurl-target.cmake
-       NAMESPACE GNURL::
+       NAMESPACE ${PROJECT_NAME}::
 )
diff --git a/lib/Makefile.Watcom b/lib/Makefile.Watcom
index 942cd0c7b..6ea975b53 100644
--- a/lib/Makefile.Watcom
+++ b/lib/Makefile.Watcom
@@ -6,7 +6,7 @@
 #                             \___|\___/|_| \_\_____|
 #
 # Copyright (C) 2005 - 2009, Gisle Vanem <address@hidden>.
-# Copyright (C) 2005 - 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2005 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/lib/Makefile.am b/lib/Makefile.am
index a6c361414..ada137ffe 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -26,8 +26,8 @@ ED_2 = config-plan9.h config-riscos.h config-mac.h 
curl_config.h.in
 ED_3 = makefile.dj config-dos.h libgnurl.plist libcurl.rc config-amigaos.h
 ED_4 = makefile.amiga Makefile.netware nwlib.c nwos.c config-win32ce.h
 ED_5 = config-os400.h setup-os400.h config-symbian.h Makefile.Watcom
-ED_6 = config-tpf.h mk-ca-bundle.pl mk-ca-bundle.vbs
-ED_7 = firefox-db2pem.sh config-vxworks.h Makefile.vxworks checksrc.pl
+ED_6 = config-tpf.h mk-ca-bundle.pl mk-ca-bundle.vbs $(CMAKE_DIST)
+ED_7 = firefox-db2pem.sh config-vxworks.h Makefile.vxworks checksrc.pl 
setup-win32.h
 
 EXTRA_DIST = $(ED_1) $(ED_2) $(ED_3) $(ED_4) $(ED_5) $(ED_6) $(ED_7)
 
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index 46ded90bb..e3cf41891 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -20,71 +20,66 @@
 #
 ###########################################################################
 
-LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c         \
-  vauth/digest.c vauth/digest_sspi.c vauth/krb5_gssapi.c                \
-  vauth/krb5_sspi.c vauth/ntlm.c vauth/ntlm_sspi.c vauth/oauth2.c       \
-  vauth/spnego_gssapi.c vauth/spnego_sspi.c
+LIB_VAUTH_CFILES = vauth/cleartext.c vauth/cram.c vauth/digest.c             \
+  vauth/digest_sspi.c vauth/krb5_gssapi.c vauth/krb5_sspi.c vauth/ntlm.c     \
+  vauth/ntlm_sspi.c vauth/oauth2.c vauth/spnego_gssapi.c vauth/spnego_sspi.c \
+  vauth/vauth.c
 
-LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
+LIB_VAUTH_HFILES = vauth/digest.h vauth/ntlm.h vauth/vauth.h
 
-LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c     \
-  vtls/mbedtls_threadlock.c vtls/wolfssl.c vtls/schannel.c              \
-  vtls/schannel_verify.c vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c   \
-  vtls/mesalink.c vtls/bearssl.c
+LIB_VTLS_CFILES = vtls/bearssl.c vtls/gskit.c vtls/gtls.c vtls/mbedtls.c \
+  vtls/mbedtls_threadlock.c vtls/mesalink.c vtls/nss.c vtls/openssl.c    \
+  vtls/schannel.c vtls/schannel_verify.c vtls/sectransp.c vtls/vtls.c    \
+  vtls/wolfssl.c
 
-LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h vtls/nssg.h    \
-  vtls/mbedtls_threadlock.h vtls/wolfssl.h vtls/schannel.h              \
-  vtls/sectransp.h vtls/gskit.h vtls/mbedtls.h vtls/mesalink.h          \
-  vtls/bearssl.h
+LIB_VTLS_HFILES = vtls/bearssl.h vtls/gskit.h vtls/gtls.h vtls/mbedtls.h \
+  vtls/mbedtls_threadlock.h vtls/mesalink.h vtls/nssg.h vtls/openssl.h   \
+  vtls/schannel.h vtls/sectransp.h vtls/vtls.h vtls/wolfssl.h
 
 LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c
 
 LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h
 
-LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.c vssh/wolfssh.c
+LIB_VSSH_CFILES = vssh/libssh.c vssh/libssh2.c vssh/wolfssh.c
 
 LIB_VSSH_HFILES = vssh/ssh.h
 
-LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c   \
-  cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c       \
-  ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c         \
-  getinfo.c transfer.c strcase.c easy.c security.c curl_fnmatch.c       \
-  fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \
-  strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c  \
-  http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c    \
-  strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c         \
-  inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c      \
-  curl_addrinfo.c socks_gssapi.c socks_sspi.c                           \
-  curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c    \
-  pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c        \
-  openldap.c curl_gethostname.c gopher.c idn_win32.c                    \
-  http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c      \
-  http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c        \
-  curl_multibyte.c hostcheck.c conncache.c dotdot.c                     \
-  x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c      \
-  mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c  \
-  doh.c urlapi.c curl_get_line.c altsvc.c socketpair.c rename.c
+LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.c            \
+  conncache.c connect.c content_encoding.c cookie.c curl_addrinfo.c           \
+  curl_ctype.c curl_des.c curl_endian.c curl_fnmatch.c curl_get_line.c        \
+  curl_gethostname.c curl_gssapi.c curl_memrchr.c curl_multibyte.c            \
+  curl_ntlm_core.c curl_ntlm_wb.c curl_path.c curl_range.c curl_rtmp.c        \
+  curl_sasl.c curl_sspi.c curl_threads.c dict.c dotdot.c easy.c escape.c      \
+  file.c fileinfo.c formdata.c ftp.c url.c ftplistparser.c getenv.c getinfo.c \
+  gopher.c hash.c hmac.c hostasyn.c hostcheck.c hostip.c hostip4.c hostip6.c  \
+  hostsyn.c http.c http2.c http_chunks.c http_digest.c http_negotiate.c       \
+  http_ntlm.c http_proxy.c idn_win32.c if2ip.c imap.c inet_ntop.c inet_pton.c \
+  krb5.c ldap.c llist.c md4.c md5.c memdebug.c mime.c mprintf.c mqtt.c        \
+  multi.c netrc.c non-ascii.c nonblock.c openldap.c parsedate.c pingpong.c    \
+  pop3.c progress.c psl.c doh.c rand.c rename.c rtsp.c security.c select.c    \
+  sendf.c setopt.c sha256.c share.c slist.c smb.c smtp.c socketpair.c socks.c \
+  socks_gssapi.c socks_sspi.c speedcheck.c splay.c strcase.c strdup.c         \
+  strerror.c strtok.c strtoofft.c system_win32.c telnet.c tftp.c timeval.c    \
+  transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c
 
-LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
-  formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h         \
-  speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h        \
-  strcase.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h          \
-  wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h      \
-  hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \
-  http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h         \
-  inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h    \
-  easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h     \
-  socks.h curl_base64.h curl_addrinfo.h curl_sspi.h                     \
-  slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h     \
-  rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h              \
-  curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h           \
-  http_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h             \
-  curl_sasl.h curl_multibyte.h hostcheck.h conncache.h                  \
-  curl_setup_once.h multihandle.h setup-vms.h dotdot.h                  \
-  x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h           \
-  curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h     \
-  curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h        \
-  curl_get_line.h altsvc.h quic.h socketpair.h rename.h
+LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h    \
+  content_encoding.h cookie.h curl_addrinfo.h curl_base64.h curl_ctype.h      \
+  curl_des.h curl_endian.h curl_fnmatch.h curl_get_line.h curl_gethostname.h  \
+  curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memory.h   \
+  curl_memrchr.h curl_multibyte.h curl_ntlm_core.h curl_ntlm_wb.h curl_path.h \
+  curl_printf.h curl_range.h curl_rtmp.h curl_sasl.h curl_sec.h curl_setup.h  \
+  curl_setup_once.h curl_sha256.h curl_sspi.h curl_threads.h curlx.h dict.h   \
+  dotdot.h easyif.h escape.h file.h fileinfo.h formdata.h ftp.h url.h         \
+  ftplistparser.h getinfo.h gopher.h hash.h hostcheck.h hostip.h http.h       \
+  http2.h http_chunks.h http_digest.h http_negotiate.h http_ntlm.h            \
+  http_proxy.h if2ip.h imap.h inet_ntop.h inet_pton.h llist.h memdebug.h      \
+  mime.h mqtt.h multihandle.h multiif.h netrc.h non-ascii.h nonblock.h        \
+  parsedate.h pingpong.h pop3.h progress.h psl.h doh.h quic.h rand.h rename.h \
+  rtsp.h select.h sendf.h setopt.h setup-vms.h share.h sigpipe.h slist.h      \
+  smb.h smtp.h sockaddr.h socketpair.h socks.h speedcheck.h splay.h strcase.h \
+  strdup.h strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h     \
+  timeval.h transfer.h urlapi-int.h urldata.h warnless.h wildcard.h           \
+  x509asn1.h
 
 LIB_RCFILES = libcurl.rc
 
diff --git a/lib/Makefile.m32 b/lib/Makefile.m32
index ac6b3de63..fe8701bdb 100644
--- a/lib/Makefile.m32
+++ b/lib/Makefile.m32
@@ -99,7 +99,7 @@ LDFLAGS = $(CURL_LDFLAG_EXTRAS) $(CURL_LDFLAG_EXTRAS_DLL) -s
 AR = $(CURL_AR)
 RANLIB = $(CURL_RANLIB)
 RC = $(CROSSPREFIX)windres
-RCFLAGS = --include-dir=$(PROOT)/include -DDEBUGBUILD=0 -O COFF
+RCFLAGS = --include-dir=$(PROOT)/include -DDEBUGBUILD=0 -O coff
 STRIP   = $(CROSSPREFIX)strip -g
 
 # Set environment var ARCH to your architecture to override autodetection.
diff --git a/lib/Makefile.netware b/lib/Makefile.netware
index f066fd02e..625f88df1 100644
--- a/lib/Makefile.netware
+++ b/lib/Makefile.netware
@@ -669,8 +669,6 @@ endif
        @echo $(DL)#endif$(DL) >> $@
 ifdef CABUNDLE
        @echo $(DL)#define CURL_CA_BUNDLE "$(CABUNDLE)"$(DL) >> $@
-else
-       @echo $(DL)#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")$(DL) >> $@
 endif
 
 $(EXPORTF): $(CURL_INC)/gnurl/curl.h $(CURL_INC)/gnurl/easy.h 
$(CURL_INC)/gnurl/multi.h $(CURL_INC)/gnurl/mprintf.h
diff --git a/lib/Makefile.vxworks b/lib/Makefile.vxworks
index 7ff197f03..ada87fbd3 100644
--- a/lib/Makefile.vxworks
+++ b/lib/Makefile.vxworks
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #*****************************************************************************
 #
 #
diff --git a/lib/checksrc.pl b/lib/checksrc.pl
index e1bb1a633..b074f2744 100755
--- a/lib/checksrc.pl
+++ b/lib/checksrc.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2011 - 2019, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2011 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -80,6 +80,7 @@ my %warnings = (
     'MULTISPACE'       => 'multiple spaces used when not suitable',
     'SIZEOFNOPAREN'    => 'use of sizeof without parentheses',
     'SNPRINTF'         => 'use of snprintf',
+    'ONELINECONDITION' => 'conditional block on the same line as the if()',
     );
 
 sub readwhitelist {
@@ -457,13 +458,34 @@ sub scanfile {
             }
         }
 
-        if($nostr =~ /^((.*)(if) *\()(.*)\)/) {
+        if($nostr =~ /^((.*\s)(if) *\()(.*)\)(.*)/) {
             my $pos = length($1);
-            if($4 =~ / = /) {
+            my $postparen = $5;
+            my $cond = $4;
+            if($cond =~ / = /) {
                 checkwarn("ASSIGNWITHINCONDITION",
                           $line, $pos+1, $file, $l,
                           "assignment within conditional expression");
             }
+            my $temp = $cond;
+            $temp =~ s/\(//g; # remove open parens
+            my $openc = length($cond) - length($temp);
+
+            $temp = $cond;
+            $temp =~ s/\)//g; # remove close parens
+            my $closec = length($cond) - length($temp);
+            my $even = $openc == $closec;
+
+            if($l =~ / *\#/) {
+                # this is a #if, treat it differently
+            }
+            elsif($even && $postparen &&
+               ($postparen !~ /^ *$/) && ($postparen !~ /^ *[,{&|\\]+/)) {
+                print STDERR "5: '$postparen'\n";
+                checkwarn("ONELINECONDITION",
+                          $line, length($l)-length($postparen), $file, $l,
+                          "conditional block on the same line");
+            }
         }
         # check spaces after open parentheses
         if($l =~ /^(.*[a-z])\( /i) {
diff --git a/lib/config-dos.h b/lib/config-dos.h
index aa83c4be5..349e75639 100644
--- a/lib/config-dos.h
+++ b/lib/config-dos.h
@@ -151,8 +151,6 @@
   #define ssize_t  int
 #endif
 
-#define CURL_CA_BUNDLE  getenv("CURL_CA_BUNDLE")
-
 /* Target HAVE_x section */
 
 #if defined(DJGPP)
diff --git a/lib/config-os400.h b/lib/config-os400.h
index a302828e2..7beb81faf 100644
--- a/lib/config-os400.h
+++ b/lib/config-os400.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -97,9 +97,6 @@
 /* Define if you have the <crypto.h> header file. */
 #undef HAVE_CRYPTO_H
 
-/* Define if you have the <des.h> header file. */
-#undef HAVE_DES_H
-
 /* Define if you have the <errno.h> header file. */
 #define HAVE_ERRNO_H
 
diff --git a/lib/config-riscos.h b/lib/config-riscos.h
index 4af94981c..0ddf487e8 100644
--- a/lib/config-riscos.h
+++ b/lib/config-riscos.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -98,9 +98,6 @@
 /* Define if you have the <crypto.h> header file. */
 #undef HAVE_CRYPTO_H
 
-/* Define if you have the <des.h> header file. */
-#undef HAVE_DES_H
-
 /* Define if you have the <errno.h> header file. */
 #define HAVE_ERRNO_H
 
diff --git a/lib/config-symbian.h b/lib/config-symbian.h
index 82a27bfef..7f17dce25 100644
--- a/lib/config-symbian.h
+++ b/lib/config-symbian.h
@@ -122,9 +122,6 @@
 /* Define to 1 if you have the <crypto.h> header file. */
 /* #undef HAVE_CRYPTO_H */
 
-/* Define to 1 if you have the <des.h> header file. */
-/* #undef HAVE_DES_H */
-
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #define HAVE_DLFCN_H 1
 
diff --git a/lib/config-tpf.h b/lib/config-tpf.h
index a79afae6d..199dfbcd5 100644
--- a/lib/config-tpf.h
+++ b/lib/config-tpf.h
@@ -115,10 +115,6 @@
 /* #undef HAVE_CRYPTO_H */
 #define HAVE_CRYPTO_H 1
 
-/* Define to 1 if you have the <des.h> header file. */
-/* #undef HAVE_DES_H */
-#define HAVE_DES_H 1
-
 /* Define to 1 if you have the <errno.h> header file. */
 #define HAVE_ERRNO_H 1
 
diff --git a/lib/config-vxworks.h b/lib/config-vxworks.h
index 2769cdfd9..14bf0be46 100644
--- a/lib/config-vxworks.h
+++ b/lib/config-vxworks.h
@@ -137,9 +137,6 @@
 /* Define to 1 if you have the <crypto.h> header file. */
 /* #undef HAVE_CRYPTO_H */
 
-/* Define to 1 if you have the <des.h> header file. */
-/* #undef HAVE_DES_H */
-
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #define HAVE_DLFCN_H 1
 
diff --git a/lib/config-win32.h b/lib/config-win32.h
index d19665d71..516baca02 100644
--- a/lib/config-win32.h
+++ b/lib/config-win32.h
@@ -719,12 +719,15 @@ Vista
 #endif
 
 /* Define to use Unix sockets. */
-#if defined(_MSC_VER) && (_MSC_VER >= 1500)
-/* sdkddkver.h first shipped with Platform SDK v6.0A included with VS2008 */
-#include <sdkddkver.h>
-#if defined(NTDDI_WIN10_RS4)
 #define USE_UNIX_SOCKETS
-#endif
+#if !defined(UNIX_PATH_MAX)
+  /* Replicating logic present in afunix.h of newer Windows 10 SDK versions */
+# define UNIX_PATH_MAX 108
+# include <ws2tcpip.h>
+  typedef struct sockaddr_un {
+    ADDRESS_FAMILY sun_family;
+    char sun_path[UNIX_PATH_MAX];
+  } SOCKADDR_UN, *PSOCKADDR_UN;
 #endif
 
 /* ---------------------------------------------------------------- */
diff --git a/lib/connect.c b/lib/connect.c
index 0a7475cb6..421f90415 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -167,11 +167,12 @@ tcpkeepalive(struct Curl_easy *data,
 static CURLcode
 singleipconnect(struct connectdata *conn,
                 const Curl_addrinfo *ai, /* start connecting to this */
-                int sockindex);          /* 0 or 1 among the temp ones */
+                int tempindex);          /* 0 or 1 among the temp ones */
 
 /*
  * Curl_timeleft() returns the amount of milliseconds left allowed for the
- * transfer/connection. If the value is negative, the timeout time has already
+ * transfer/connection. If the value is 0, there's no timeout (ie there's
+ * infinite time left). If the value is negative, the timeout time has already
  * elapsed.
  *
  * The start time is stored in progress.t_startsingle - as set with
@@ -555,13 +556,27 @@ static bool verifyconnect(curl_socket_t sockfd, int 
*error)
   return rc;
 }
 
+/* update tempaddr[tempindex] (to the next entry), makes sure to stick
+   to the correct family */
+static Curl_addrinfo *ainext(struct connectdata *conn,
+                             int tempindex,
+                             bool next) /* use current or next entry */
+{
+  Curl_addrinfo *ai = conn->tempaddr[tempindex];
+  if(ai && next)
+    ai = ai->ai_next;
+  while(ai && (ai->ai_family != conn->tempfamily[tempindex]))
+    ai = ai->ai_next;
+  conn->tempaddr[tempindex] = ai;
+  return ai;
+}
+
 /* Used within the multi interface. Try next IP address, return TRUE if no
    more address exists or error */
 static CURLcode trynextip(struct connectdata *conn,
                           int sockindex,
                           int tempindex)
 {
-  const int other = tempindex ^ 1;
   CURLcode result = CURLE_COULDNT_CONNECT;
 
   /* First clean up after the failed socket.
@@ -572,38 +587,15 @@ static CURLcode trynextip(struct connectdata *conn,
   conn->tempsock[tempindex] = CURL_SOCKET_BAD;
 
   if(sockindex == FIRSTSOCKET) {
-    Curl_addrinfo *ai = NULL;
-    int family = AF_UNSPEC;
-
-    if(conn->tempaddr[tempindex]) {
-      /* find next address in the same protocol family */
-      family = conn->tempaddr[tempindex]->ai_family;
-      ai = conn->tempaddr[tempindex]->ai_next;
-    }
-#ifdef ENABLE_IPV6
-    else if(conn->tempaddr[0]) {
-      /* happy eyeballs - try the other protocol family */
-      int firstfamily = conn->tempaddr[0]->ai_family;
-      family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
-      ai = conn->tempaddr[0]->ai_next;
-    }
-#endif
+    Curl_addrinfo *ai = conn->tempaddr[tempindex];
 
     while(ai) {
-      if(conn->tempaddr[other]) {
-        /* we can safely skip addresses of the other protocol family */
-        while(ai && ai->ai_family != family)
-          ai = ai->ai_next;
-      }
-
       if(ai) {
         result = singleipconnect(conn, ai, tempindex);
         if(result == CURLE_COULDNT_CONNECT) {
-          ai = ai->ai_next;
+          ai = ainext(conn, tempindex, TRUE);
           continue;
         }
-
-        conn->tempaddr[tempindex] = ai;
       }
       break;
     }
@@ -688,58 +680,56 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t 
salen,
    connection */
 void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
 {
-  if(conn->transport != TRNSPRT_TCP)
-    /* there's no TCP connection! */
-    return;
-
+  if(conn->transport == TRNSPRT_TCP) {
 #if defined(HAVE_GETPEERNAME) || defined(HAVE_GETSOCKNAME)
-  if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
-    struct Curl_easy *data = conn->data;
-    char buffer[STRERROR_LEN];
-    struct Curl_sockaddr_storage ssrem;
-    struct Curl_sockaddr_storage ssloc;
-    curl_socklen_t plen;
-    curl_socklen_t slen;
+    if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
+      struct Curl_easy *data = conn->data;
+      char buffer[STRERROR_LEN];
+      struct Curl_sockaddr_storage ssrem;
+      struct Curl_sockaddr_storage ssloc;
+      curl_socklen_t plen;
+      curl_socklen_t slen;
 #ifdef HAVE_GETPEERNAME
-    plen = sizeof(struct Curl_sockaddr_storage);
-    if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
-      int error = SOCKERRNO;
-      failf(data, "getpeername() failed with errno %d: %s",
-            error, Curl_strerror(error, buffer, sizeof(buffer)));
-      return;
-    }
+      plen = sizeof(struct Curl_sockaddr_storage);
+      if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
+        int error = SOCKERRNO;
+        failf(data, "getpeername() failed with errno %d: %s",
+              error, Curl_strerror(error, buffer, sizeof(buffer)));
+        return;
+      }
 #endif
 #ifdef HAVE_GETSOCKNAME
-    slen = sizeof(struct Curl_sockaddr_storage);
-    memset(&ssloc, 0, sizeof(ssloc));
-    if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
-      int error = SOCKERRNO;
-      failf(data, "getsockname() failed with errno %d: %s",
-            error, Curl_strerror(error, buffer, sizeof(buffer)));
-      return;
-    }
+      slen = sizeof(struct Curl_sockaddr_storage);
+      memset(&ssloc, 0, sizeof(ssloc));
+      if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
+        int error = SOCKERRNO;
+        failf(data, "getsockname() failed with errno %d: %s",
+              error, Curl_strerror(error, buffer, sizeof(buffer)));
+        return;
+      }
 #endif
 #ifdef HAVE_GETPEERNAME
-    if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
-                         conn->primary_ip, &conn->primary_port)) {
-      failf(data, "ssrem inet_ntop() failed with errno %d: %s",
-            errno, Curl_strerror(errno, buffer, sizeof(buffer)));
-      return;
-    }
-    memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
+      if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
+                           conn->primary_ip, &conn->primary_port)) {
+        failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+              errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+        return;
+      }
+      memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
 #endif
 #ifdef HAVE_GETSOCKNAME
-    if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
-                         conn->local_ip, &conn->local_port)) {
-      failf(data, "ssloc inet_ntop() failed with errno %d: %s",
-            errno, Curl_strerror(errno, buffer, sizeof(buffer)));
-      return;
-    }
+      if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
+                           conn->local_ip, &conn->local_port)) {
+        failf(data, "ssloc inet_ntop() failed with errno %d: %s",
+              errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+        return;
+      }
 #endif
-  }
+    }
 #else /* !HAVE_GETSOCKNAME && !HAVE_GETPEERNAME */
-  (void)sockfd; /* unused */
+    (void)sockfd; /* unused */
 #endif
+  } /* end of TCP-only section */
 
   /* persist connection info in session handle */
   Curl_persistconninfo(conn);
@@ -816,6 +806,7 @@ static void post_SOCKS(struct connectdata *conn,
     Curl_pgrsTime(conn->data, TIMER_CONNECT); /* connect done */
   Curl_updateconninfo(conn, conn->sock[sockindex]);
   Curl_verboseconnect(conn);
+  conn->data->info.numconnects++; /* to track the number of connections made */
 }
 
 /*
@@ -880,6 +871,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
         conn->sock[sockindex] = conn->tempsock[i];
         conn->ip_addr = conn->tempaddr[i];
         conn->tempsock[i] = CURL_SOCKET_BAD;
+        post_SOCKS(conn, sockindex, connected);
         connkeep(conn, "HTTP/3 default");
       }
       return result;
@@ -905,9 +897,10 @@ CURLcode Curl_is_connected(struct connectdata *conn,
       }
 
       /* should we try another protocol family? */
-      if(i == 0 && conn->tempaddr[1] == NULL &&
+      if(i == 0 && !conn->parallel_connect &&
          (Curl_timediff(now, conn->connecttime) >=
           data->set.happy_eyeballs_timeout)) {
+        conn->parallel_connect = TRUE; /* starting now */
         trynextip(conn, sockindex, 1);
       }
     }
@@ -967,7 +960,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
 
         conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
           allow : allow / 2;
-
+        ainext(conn, i, TRUE);
         status = trynextip(conn, sockindex, i);
         if((status != CURLE_COULDNT_CONNECT) ||
            conn->tempsock[other] == CURL_SOCKET_BAD)
@@ -984,7 +977,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
 
     /* if the first address family runs out of addresses to try before
        the happy eyeball timeout, go ahead and try the next family now */
-    if(conn->tempaddr[1] == NULL) {
+    {
       result = trynextip(conn, sockindex, 1);
       if(!result)
         return result;
@@ -1113,7 +1106,7 @@ void Curl_sndbufset(curl_socket_t sockfd)
  */
 static CURLcode singleipconnect(struct connectdata *conn,
                                 const Curl_addrinfo *ai,
-                                int sockindex)
+                                int tempindex)
 {
   struct Curl_sockaddr_ex addr;
   int rc = -1;
@@ -1129,15 +1122,12 @@ static CURLcode singleipconnect(struct connectdata 
*conn,
   int optval = 1;
 #endif
   char buffer[STRERROR_LEN];
-  curl_socket_t *sockp = &conn->tempsock[sockindex];
+  curl_socket_t *sockp = &conn->tempsock[tempindex];
   *sockp = CURL_SOCKET_BAD;
 
   result = Curl_socket(conn, ai, &addr, &sockfd);
   if(result)
-    /* Failed to create the socket, but still return OK since we signal the
-       lack of socket as well. This allows the parent function to keep looping
-       over alternative addresses/socket families etc. */
-    return CURLE_OK;
+    return result;
 
   /* store remote address and port used in this connection attempt */
   if(!Curl_addr2string((struct sockaddr*)&addr.sa_addr, addr.addrlen,
@@ -1257,7 +1247,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
     else if(conn->transport == TRNSPRT_QUIC) {
       /* pass in 'sockfd' separately since it hasn't been put into the
          tempsock array at this point */
-      result = Curl_quic_connect(conn, sockfd, sockindex,
+      result = Curl_quic_connect(conn, sockfd, tempindex,
                                  &addr.sa_addr, addr.addrlen);
       if(result)
         error = SOCKERRNO;
@@ -1315,7 +1305,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* 
context */
   struct Curl_easy *data = conn->data;
   struct curltime before = Curl_now();
   CURLcode result = CURLE_COULDNT_CONNECT;
-
+  int i;
   timediff_t timeout_ms = Curl_timeleft(data, &before, TRUE);
 
   if(timeout_ms < 0) {
@@ -1325,30 +1315,35 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* 
context */
   }
 
   conn->num_addr = Curl_num_addresses(remotehost->addr);
-  conn->tempaddr[0] = remotehost->addr;
-  conn->tempaddr[1] = NULL;
-  conn->tempsock[0] = CURL_SOCKET_BAD;
-  conn->tempsock[1] = CURL_SOCKET_BAD;
+  conn->tempaddr[0] = conn->tempaddr[1] = remotehost->addr;
+  conn->tempsock[0] = conn->tempsock[1] = CURL_SOCKET_BAD;
 
   /* Max time for the next connection attempt */
   conn->timeoutms_per_addr =
     conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
 
-  /* start connecting to first IP */
-  while(conn->tempaddr[0]) {
-    result = singleipconnect(conn, conn->tempaddr[0], 0);
-    if(!result)
-      break;
-    conn->tempaddr[0] = conn->tempaddr[0]->ai_next;
-  }
+  conn->tempfamily[0] = conn->tempaddr[0]?
+    conn->tempaddr[0]->ai_family:0;
+  conn->tempfamily[1] = conn->tempfamily[0] == AF_INET6 ?
+    AF_INET : AF_INET6;
+  ainext(conn, 1, FALSE); /* assigns conn->tempaddr[1] accordingly */
 
-  if(conn->tempsock[0] == CURL_SOCKET_BAD) {
-    if(!result)
-      result = CURLE_COULDNT_CONNECT;
-    return result;
+  DEBUGF(infof(data, "family0 == %s, family1 == %s\n",
+               conn->tempfamily[0] == AF_INET ? "v4" : "v6",
+               conn->tempfamily[1] == AF_INET ? "v4" : "v6"));
+
+  /* get through the list in family order in case of quick failures */
+  for(i = 0; (i < 2) && result; i++) {
+    while(conn->tempaddr[i]) {
+      result = singleipconnect(conn, conn->tempaddr[i], i);
+      if(!result)
+        break;
+      ainext(conn, i, TRUE);
+    }
   }
+  if(result)
+    return result;
 
-  data->info.numconnects++; /* to track the number of connections made */
   Curl_expire(conn->data, data->set.happy_eyeballs_timeout,
               EXPIRE_HAPPY_EYEBALLS);
 
diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c
index 05287fa9e..a9daeeda6 100644
--- a/lib/curl_addrinfo.c
+++ b/lib/curl_addrinfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -50,10 +50,6 @@
 #  define in_addr_t unsigned long
 #endif
 
-#if defined(WIN32) && defined(USE_UNIX_SOCKETS)
-#include <afunix.h>
-#endif
-
 #include <stddef.h>
 
 #include "curl_addrinfo.h"
diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake
index 98cdf5145..57a86e50a 100644
--- a/lib/curl_config.h.cmake
+++ b/lib/curl_config.h.cmake
@@ -1,3 +1,24 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
 /* lib/curl_config.h.in.  Generated somehow by cmake.  */
 
 /* when building libcurl itself */
@@ -42,6 +63,9 @@
 /* to disable LDAPS */
 #cmakedefine CURL_DISABLE_LDAPS 1
 
+/* to enable MQTT */
+#undef CURL_ENABLE_MQTT
+
 /* to disable POP3 */
 #cmakedefine CURL_DISABLE_POP3 1
 
@@ -145,9 +169,6 @@
 /* Define to 1 if you have the <crypto.h> header file. */
 #cmakedefine HAVE_CRYPTO_H 1
 
-/* Define to 1 if you have the <des.h> header file. */
-#cmakedefine HAVE_DES_H 1
-
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #cmakedefine HAVE_DLFCN_H 1
 
@@ -945,6 +966,9 @@ ${SIZEOF_TIME_T_CODE}
 /* if BearSSL is enabled */
 #cmakedefine USE_BEARSSL 1
 
+/* if WolfSSL is enabled */
+#cmakedefine USE_WOLFSSL 1
+
 /* if libSSH2 is in use */
 #cmakedefine USE_LIBSSH2 1
 
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index f9b823b4f..32e29a933 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -342,7 +342,7 @@ static bool encrypt_des(const unsigned char *in, unsigned 
char *out,
 
   /* Acquire the crypto provider */
   if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
-                          CRYPT_VERIFYCONTEXT))
+                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
     return FALSE;
 
   /* Setup the key blob structure */
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index e015e3e3b..e09d6521e 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -231,64 +231,20 @@
 #endif
 
 /*
- * Use getaddrinfo to resolve the IPv4 address literal. If the current network
- * interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
- * performing this task will result in a synthesized IPv6 address.
- */
-#ifdef  __APPLE__
-#define USE_RESOLVE_ON_IPS 1
-#endif
-
-/*
- * Include header files for windows builds before redefining anything.
- * Use this preprocessor block only to include or exclude windows.h,
- * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
- * to any other further and independent block.  Under Cygwin things work
- * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
- * never be included when __CYGWIN__ is defined.  configure script takes
- * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
- * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
+ * Windows setup file includes some system headers.
  */
 
 #ifdef HAVE_WINDOWS_H
-#  if defined(UNICODE) && !defined(_UNICODE)
-#    define _UNICODE
-#  endif
-#  if defined(_UNICODE) && !defined(UNICODE)
-#    define UNICODE
-#  endif
-#  include <winerror.h>
-#  include <windows.h>
-#  ifdef HAVE_WINSOCK2_H
-#    include <winsock2.h>
-#    ifdef HAVE_WS2TCPIP_H
-#      include <ws2tcpip.h>
-#    endif
-#  else
-#    ifdef HAVE_WINSOCK_H
-#      include <winsock.h>
-#    endif
-#  endif
-#  include <tchar.h>
-#  ifdef UNICODE
-     typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
-#  endif
+#  include "setup-win32.h"
 #endif
 
 /*
- * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
- * define USE_WINSOCK to 1 if we have and use WINSOCK  API, else
- * undefine USE_WINSOCK.
+ * Use getaddrinfo to resolve the IPv4 address literal. If the current network
+ * interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
+ * performing this task will result in a synthesized IPv6 address.
  */
-
-#undef USE_WINSOCK
-
-#ifdef HAVE_WINSOCK2_H
-#  define USE_WINSOCK 2
-#else
-#  ifdef HAVE_WINSOCK_H
-#    define USE_WINSOCK 1
-#  endif
+#ifdef  __APPLE__
+#define USE_RESOLVE_ON_IPS 1
 #endif
 
 #ifdef USE_LWIPSOCK
diff --git a/lib/dict.c b/lib/dict.c
index c93bf575a..20790d273 100644
--- a/lib/dict.c
+++ b/lib/dict.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -46,6 +46,8 @@
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#include <unistd.h>
 #endif
 
 #include "urldata.h"
diff --git a/lib/doh.c b/lib/doh.c
index aaa8f15ca..10867cc34 100644
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -174,7 +174,7 @@ UNITTEST DOHcode doh_encode(const char *host,
 }
 
 static size_t
-doh_write_cb(void *contents, size_t size, size_t nmemb, void *userp)
+doh_write_cb(const void *contents, size_t size, size_t nmemb, void *userp)
 {
   size_t realsize = size * nmemb;
   struct dohresponse *mem = (struct dohresponse *)userp;
@@ -318,6 +318,9 @@ static CURLcode dohprobe(struct Curl_easy *data,
     }
     if(data->set.proxy_ssl.no_revoke)
       ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
+    else if(data->set.proxy_ssl.revoke_best_effort)
+      ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS,
+                         CURLSSLOPT_REVOKE_BEST_EFFORT);
     if(data->set.str[STRING_SSL_CAPATH_PROXY]) {
       ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH,
         data->set.str[STRING_SSL_CAPATH_PROXY]);
@@ -351,6 +354,8 @@ static CURLcode dohprobe(struct Curl_easy *data,
     }
     if(data->set.ssl.no_revoke)
       ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
+    else if(data->set.ssl.revoke_best_effort)
+      ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_REVOKE_BEST_EFFORT);
     if(data->set.ssl.fsslctx)
       ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx);
     if(data->set.ssl.fsslctxp)
@@ -434,7 +439,7 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn,
   return NULL;
 }
 
-static DOHcode skipqname(unsigned char *doh, size_t dohlen,
+static DOHcode skipqname(const unsigned char *doh, size_t dohlen,
                          unsigned int *indexp)
 {
   unsigned char length;
@@ -458,12 +463,12 @@ static DOHcode skipqname(unsigned char *doh, size_t 
dohlen,
   return DOH_OK;
 }
 
-static unsigned short get16bit(unsigned char *doh, int index)
+static unsigned short get16bit(const unsigned char *doh, int index)
 {
   return (unsigned short)((doh[index] << 8) | doh[index + 1]);
 }
 
-static unsigned int get32bit(unsigned char *doh, int index)
+static unsigned int get32bit(const unsigned char *doh, int index)
 {
    /* make clang and gcc optimize this to bswap by incrementing
       the pointer first. */
@@ -475,7 +480,7 @@ static unsigned int get32bit(unsigned char *doh, int index)
   return ( (unsigned)doh[0] << 24) | (doh[1] << 16) |(doh[2] << 8) | doh[3];
 }
 
-static DOHcode store_a(unsigned char *doh, int index, struct dohentry *d)
+static DOHcode store_a(const unsigned char *doh, int index, struct dohentry *d)
 {
   /* silently ignore addresses over the limit */
   if(d->numaddr < DOH_MAX_ADDR) {
@@ -487,7 +492,9 @@ static DOHcode store_a(unsigned char *doh, int index, 
struct dohentry *d)
   return DOH_OK;
 }
 
-static DOHcode store_aaaa(unsigned char *doh, int index, struct dohentry *d)
+static DOHcode store_aaaa(const unsigned char *doh,
+                          int index,
+                          struct dohentry *d)
 {
   /* silently ignore addresses over the limit */
   if(d->numaddr < DOH_MAX_ADDR) {
@@ -500,7 +507,7 @@ static DOHcode store_aaaa(unsigned char *doh, int index, 
struct dohentry *d)
 }
 
 static DOHcode cnameappend(struct cnamestore *c,
-                           unsigned char *src,
+                           const unsigned char *src,
                            size_t len)
 {
   if(!c->alloc) {
@@ -525,7 +532,7 @@ static DOHcode cnameappend(struct cnamestore *c,
   return DOH_OK;
 }
 
-static DOHcode store_cname(unsigned char *doh,
+static DOHcode store_cname(const unsigned char *doh,
                            size_t dohlen,
                            unsigned int index,
                            struct dohentry *d)
@@ -580,7 +587,7 @@ static DOHcode store_cname(unsigned char *doh,
   return DOH_OK;
 }
 
-static DOHcode rdata(unsigned char *doh,
+static DOHcode rdata(const unsigned char *doh,
                      size_t dohlen,
                      unsigned short rdlength,
                      unsigned short type,
@@ -630,7 +637,7 @@ static void init_dohentry(struct dohentry *de)
 }
 
 
-UNITTEST DOHcode doh_decode(unsigned char *doh,
+UNITTEST DOHcode doh_decode(const unsigned char *doh,
                             size_t dohlen,
                             DNStype dnstype,
                             struct dohentry *d)
@@ -770,12 +777,12 @@ UNITTEST DOHcode doh_decode(unsigned char *doh,
 
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
 static void showdoh(struct Curl_easy *data,
-                    struct dohentry *d)
+                    const struct dohentry *d)
 {
   int i;
   infof(data, "TTL: %u seconds\n", d->ttl);
   for(i = 0; i < d->numaddr; i++) {
-    struct dohaddr *a = &d->addr[i];
+    const struct dohaddr *a = &d->addr[i];
     if(a->type == DNS_TYPE_A) {
       infof(data, "DOH A: %u.%u.%u.%u\n",
             a->ip.v4[0], a->ip.v4[1],
diff --git a/lib/doh.h b/lib/doh.h
index fc053eddf..f6154ffd4 100644
--- a/lib/doh.h
+++ b/lib/doh.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2018 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -99,7 +99,7 @@ DOHcode doh_encode(const char *host,
                    unsigned char *dnsp, /* buffer */
                    size_t len,  /* buffer size */
                    size_t *olen); /* output length */
-DOHcode doh_decode(unsigned char *doh,
+DOHcode doh_decode(const unsigned char *doh,
                    size_t dohlen,
                    DNStype dnstype,
                    struct dohentry *d);
diff --git a/lib/easy.c b/lib/easy.c
index 762669179..42b7b7181 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -884,14 +884,25 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy 
*data)
     goto fail;
 
 #ifdef USE_ARES
-  if(Curl_set_dns_servers(outcurl, data->set.str[STRING_DNS_SERVERS]))
-    goto fail;
-  if(Curl_set_dns_interface(outcurl, data->set.str[STRING_DNS_INTERFACE]))
-    goto fail;
-  if(Curl_set_dns_local_ip4(outcurl, data->set.str[STRING_DNS_LOCAL_IP4]))
-    goto fail;
-  if(Curl_set_dns_local_ip6(outcurl, data->set.str[STRING_DNS_LOCAL_IP6]))
-    goto fail;
+  {
+    CURLcode rc;
+
+    rc = Curl_set_dns_servers(outcurl, data->set.str[STRING_DNS_SERVERS]);
+    if(rc && rc != CURLE_NOT_BUILT_IN)
+      goto fail;
+
+    rc = Curl_set_dns_interface(outcurl, data->set.str[STRING_DNS_INTERFACE]);
+    if(rc && rc != CURLE_NOT_BUILT_IN)
+      goto fail;
+
+    rc = Curl_set_dns_local_ip4(outcurl, data->set.str[STRING_DNS_LOCAL_IP4]);
+    if(rc && rc != CURLE_NOT_BUILT_IN)
+      goto fail;
+
+    rc = Curl_set_dns_local_ip6(outcurl, data->set.str[STRING_DNS_LOCAL_IP6]);
+    if(rc && rc != CURLE_NOT_BUILT_IN)
+      goto fail;
+  }
 #endif /* USE_ARES */
 
   Curl_convert_setup(outcurl);
diff --git a/lib/file.c b/lib/file.c
index 43e1ad001..bb3923989 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -136,7 +136,7 @@ static CURLcode file_connect(struct connectdata *conn, bool 
*done)
   struct Curl_easy *data = conn->data;
   char *real_path;
   struct FILEPROTO *file = data->req.protop;
-  int fd = -1;
+  int fd;
 #ifdef DOS_FILESYSTEM
   size_t i;
   char *actual_path;
@@ -181,9 +181,7 @@ static CURLcode file_connect(struct connectdata *conn, bool 
*done)
       return CURLE_URL_MALFORMAT;
     }
 
-  if(strncmp("\\\\", actual_path, 2))
-    /* refuse to open path that starts with two backslashes */
-    fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
+  fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
   file->path = actual_path;
 #else
   if(memchr(real_path, 0, real_path_len)) {
diff --git a/lib/firefox-db2pem.sh b/lib/firefox-db2pem.sh
index 454893244..ee820261e 100644
--- a/lib/firefox-db2pem.sh
+++ b/lib/firefox-db2pem.sh
@@ -6,7 +6,7 @@
 # *                            | (__| |_| |  _ <| |___
 # *                             \___|\___/|_| \_\_____|
 # *
-# * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+# * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 # *
 # * This software is licensed as described in the file COPYING, which
 # * you should have received as part of this distribution. The terms
diff --git a/lib/ftp.h b/lib/ftp.h
index 984347f2a..06421c6a4 100644
--- a/lib/ftp.h
+++ b/lib/ftp.h
@@ -150,7 +150,6 @@ struct ftp_conn {
      connection to */
   char *newhost;          /* this is the pair to connect the DATA... */
   unsigned short newport; /* connection to */
-
 };
 
 #define DEFAULT_ACCEPT_TIMEOUT   60000 /* milliseconds == one minute */
diff --git a/lib/getinfo.c b/lib/getinfo.c
index b383bfefd..ae29a44f9 100644
--- a/lib/getinfo.c
+++ b/lib/getinfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -147,6 +147,33 @@ static CURLcode getinfo_long(struct Curl_easy *data, 
CURLINFO info,
     long          *to_long;
   } lptr;
 
+#ifdef DEBUGBUILD
+  char *timestr = getenv("CURL_TIME");
+  if(timestr) {
+    unsigned long val = strtol(timestr, NULL, 10);
+    switch(info) {
+    case CURLINFO_LOCAL_PORT:
+      *param_longp = (long)val;
+      return CURLE_OK;
+    default:
+      break;
+    }
+  }
+  /* use another variable for this to allow different values */
+  timestr = getenv("CURL_DEBUG_SIZE");
+  if(timestr) {
+    unsigned long val = strtol(timestr, NULL, 10);
+    switch(info) {
+    case CURLINFO_HEADER_SIZE:
+    case CURLINFO_REQUEST_SIZE:
+      *param_longp = (long)val;
+      return CURLE_OK;
+    default:
+      break;
+    }
+  }
+#endif
+
   switch(info) {
   case CURLINFO_RESPONSE_CODE:
     *param_longp = data->info.httpcode;
@@ -212,8 +239,11 @@ static CURLcode getinfo_long(struct Curl_easy *data, 
CURLINFO info,
     *param_longp = data->info.conn_local_port;
     break;
   case CURLINFO_CONDITION_UNMET:
-    /* return if the condition prevented the document to get transferred */
-    *param_longp = data->info.timecond ? 1L : 0L;
+    if(data->info.httpcode == 304)
+      *param_longp = 1L;
+    else
+      /* return if the condition prevented the document to get transferred */
+      *param_longp = data->info.timecond ? 1L : 0L;
     break;
   case CURLINFO_RTSP_CLIENT_CSEQ:
     *param_longp = data->state.rtsp_next_client_CSeq;
@@ -258,6 +288,27 @@ static CURLcode getinfo_long(struct Curl_easy *data, 
CURLINFO info,
 static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
                              curl_off_t *param_offt)
 {
+#ifdef DEBUGBUILD
+  char *timestr = getenv("CURL_TIME");
+  if(timestr) {
+    unsigned long val = strtol(timestr, NULL, 10);
+    switch(info) {
+    case CURLINFO_TOTAL_TIME_T:
+    case CURLINFO_NAMELOOKUP_TIME_T:
+    case CURLINFO_CONNECT_TIME_T:
+    case CURLINFO_APPCONNECT_TIME_T:
+    case CURLINFO_PRETRANSFER_TIME_T:
+    case CURLINFO_STARTTRANSFER_TIME_T:
+    case CURLINFO_REDIRECT_TIME_T:
+    case CURLINFO_SPEED_DOWNLOAD_T:
+    case CURLINFO_SPEED_UPLOAD_T:
+      *param_offt = (curl_off_t)val;
+      return CURLE_OK;
+    default:
+      break;
+    }
+  }
+#endif
   switch(info) {
   case CURLINFO_FILETIME_T:
     *param_offt = (curl_off_t)data->info.filetime;
@@ -282,7 +333,7 @@ static CURLcode getinfo_offt(struct Curl_easy *data, 
CURLINFO info,
     *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
       data->progress.size_ul:-1;
     break;
-  case CURLINFO_TOTAL_TIME_T:
+   case CURLINFO_TOTAL_TIME_T:
     *param_offt = data->progress.timespent;
     break;
   case CURLINFO_NAMELOOKUP_TIME_T:
@@ -316,6 +367,27 @@ static CURLcode getinfo_offt(struct Curl_easy *data, 
CURLINFO info,
 static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
                                double *param_doublep)
 {
+#ifdef DEBUGBUILD
+  char *timestr = getenv("CURL_TIME");
+  if(timestr) {
+    unsigned long val = strtol(timestr, NULL, 10);
+    switch(info) {
+    case CURLINFO_TOTAL_TIME:
+    case CURLINFO_NAMELOOKUP_TIME:
+    case CURLINFO_CONNECT_TIME:
+    case CURLINFO_APPCONNECT_TIME:
+    case CURLINFO_PRETRANSFER_TIME:
+    case CURLINFO_STARTTRANSFER_TIME:
+    case CURLINFO_REDIRECT_TIME:
+    case CURLINFO_SPEED_DOWNLOAD:
+    case CURLINFO_SPEED_UPLOAD:
+      *param_doublep = (double)val;
+      return CURLE_OK;
+    default:
+      break;
+    }
+  }
+#endif
   switch(info) {
   case CURLINFO_TOTAL_TIME:
     *param_doublep = DOUBLE_SECS(data->progress.timespent);
diff --git a/lib/gopher.c b/lib/gopher.c
index a7e3ebb08..3b47b1803 100644
--- a/lib/gopher.c
+++ b/lib/gopher.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -28,6 +28,7 @@
 #include <gnurl/curl.h>
 #include "transfer.h"
 #include "sendf.h"
+#include "connect.h"
 #include "progress.h"
 #include "gopher.h"
 #include "select.h"
@@ -83,8 +84,10 @@ static CURLcode gopher_do(struct connectdata *conn, bool 
*done)
   char *query = data->state.up.query;
   char *sel = NULL;
   char *sel_org = NULL;
+  timediff_t timeout_ms;
   ssize_t amount, k;
   size_t len;
+  int what;
 
   *done = TRUE; /* unconditionally */
 
@@ -139,19 +142,29 @@ static CURLcode gopher_do(struct connectdata *conn, bool 
*done)
     else
       break;
 
+    timeout_ms = Curl_timeleft(conn->data, NULL, FALSE);
+    if(timeout_ms < 0) {
+      result = CURLE_OPERATION_TIMEDOUT;
+      break;
+    }
+    if(!timeout_ms)
+      timeout_ms = TIMEDIFF_T_MAX;
+
     /* Don't busyloop. The entire loop thing is a work-around as it causes a
        BLOCKING behavior which is a NO-NO. This function should rather be
        split up in a do and a doing piece where the pieces that aren't
        possible to send now will be sent in the doing function repeatedly
        until the entire request is sent.
-
-       Wait a while for the socket to be writable. Note that this doesn't
-       acknowledge the timeout.
     */
-    if(SOCKET_WRITABLE(sockfd, 100) < 0) {
+    what = SOCKET_WRITABLE(sockfd, timeout_ms);
+    if(what < 0) {
       result = CURLE_SEND_ERROR;
       break;
     }
+    else if(!what) {
+      result = CURLE_OPERATION_TIMEDOUT;
+      break;
+    }
   }
 
   free(sel_org);
diff --git a/lib/http.c b/lib/http.c
index 0d25f037c..b27f1556f 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -1229,8 +1229,21 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
     memcpy(data->state.ulbuf, ptr, sendsize);
     ptr = data->state.ulbuf;
   }
-  else
+  else {
+#ifdef CURLDEBUG
+    /* Allow debug builds override this logic to force short initial sends */
+    char *p = getenv("CURL_SMALLREQSEND");
+    if(p) {
+      size_t altsize = (size_t)strtoul(p, NULL, 10);
+      if(altsize)
+        sendsize = CURLMIN(size, altsize);
+      else
+        sendsize = size;
+    }
+    else
+#endif
     sendsize = size;
+  }
 
   result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
 
@@ -1320,7 +1333,6 @@ CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const 
char *fmt, ...)
 {
   char *s;
   va_list ap;
-  Curl_send_buffer *in = *inp;
   va_start(ap, fmt);
   s = vaprintf(fmt, ap); /* this allocs a new string to append */
   va_end(ap);
@@ -1331,9 +1343,7 @@ CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const 
char *fmt, ...)
     return result;
   }
   /* If we failed, we cleanup the whole buffer and return error */
-  free(in->buffer);
-  free(in);
-  *inp = NULL;
+  Curl_add_buffer_free(inp);
   return CURLE_OUT_OF_MEMORY;
 }
 
@@ -1350,9 +1360,7 @@ CURLcode Curl_add_buffer(Curl_send_buffer **inp, const 
void *inptr,
     /* If resulting used size of send buffer would wrap size_t, cleanup
        the whole buffer and return error. Otherwise the required buffer
        size will fit into a single allocatable memory chunk */
-    Curl_safefree(in->buffer);
-    free(in);
-    *inp = NULL;
+    Curl_add_buffer_free(inp);
     return CURLE_OUT_OF_MEMORY;
   }
 
@@ -2602,8 +2610,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   if(conn->bits.altused && !Curl_checkheaders(conn, "Alt-Used")) {
     altused = aprintf("Alt-Used: %s:%d\r\n",
                       conn->conn_to_host.name, conn->conn_to_port);
-    if(!altused)
+    if(!altused) {
+      Curl_add_buffer_free(&req_buffer);
       return CURLE_OUT_OF_MEMORY;
+    }
   }
 #endif
   result =
@@ -3044,7 +3054,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   }
   if(result)
     return result;
-  if(!postsize)
+  if(!postsize && (http->sending != HTTPSEND_REQUEST))
     data->req.upload_done = TRUE;
 
   if(data->req.writebytecount) {
diff --git a/lib/http2.c b/lib/http2.c
index bc1d1ea1a..21d829922 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -1727,8 +1727,6 @@ static ssize_t http2_recv(struct connectdata *conn, int 
sockindex,
 
     return retlen;
   }
-  /* If this stream is closed, return 0 to signal the http routine to close
-     the connection */
   if(stream->closed)
     return 0;
   *err = CURLE_AGAIN;
diff --git a/lib/if2ip.c b/lib/if2ip.c
index d003de678..b283f67f8 100644
--- a/lib/if2ip.c
+++ b/lib/if2ip.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -129,11 +129,11 @@ if2ip_result_t Curl_if2ip(int af, unsigned int 
remote_scope,
               unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr);
 
               if(ifscope != remote_scope) {
-                /* We are interested only in interface addresses whose
-                   scope matches the remote address we want to
-                   connect to: global for global, link-local for
-                   link-local, etc... */
-                if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED;
+                /* We are interested only in interface addresses whose scope
+                   matches the remote address we want to connect to: global
+                   for global, link-local for link-local, etc... */
+                if(res == IF2IP_NOT_FOUND)
+                  res = IF2IP_AF_NOT_SUPPORTED;
                 continue;
               }
 
diff --git a/lib/makefile.amiga b/lib/makefile.amiga
index 673b147c1..29df65438 100644
--- a/lib/makefile.amiga
+++ b/lib/makefile.amiga
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #
 # libcurl Makefile for AmigaOS ...
 #
diff --git a/lib/makefile.dj b/lib/makefile.dj
index 941f8ce68..6ea79e4be 100644
--- a/lib/makefile.dj
+++ b/lib/makefile.dj
@@ -6,7 +6,7 @@
 #                             \___|\___/|_| \_\_____|
 #
 # Copyright (C) 2003 - 2008, Gisle Vanem <address@hidden>.
-# Copyright (C) 2003 - 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2003 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/lib/md4.c b/lib/md4.c
index 38f1b2bc9..10e6fc537 100644
--- a/lib/md4.c
+++ b/lib/md4.c
@@ -29,6 +29,10 @@
 
 #ifdef USE_OPENSSL
 #include <openssl/opensslconf.h>
+#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
+/* OpenSSL 3.0.0 marks the MD4 functions as deprecated */
+#define OPENSSL_NO_MD4
+#endif
 #endif /* USE_OPENSSL */
 
 #ifdef USE_MBEDTLS
@@ -146,7 +150,7 @@ static void MD4_Init(MD4_CTX *ctx)
   ctx->hHash = 0;
 
   if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
-                         CRYPT_VERIFYCONTEXT)) {
+                         CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
     CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash);
   }
 }
diff --git a/lib/md5.c b/lib/md5.c
index d5624326f..0fec32bc3 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -186,8 +186,8 @@ typedef struct {
 
 static void MD5_Init(MD5_CTX *ctx)
 {
-  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
-                         PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
+                         CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
     CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
   }
 }
diff --git a/lib/memdebug.c b/lib/memdebug.c
index c3635772b..6cc2d1f6c 100644
--- a/lib/memdebug.c
+++ b/lib/memdebug.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -328,7 +328,7 @@ void curl_dbg_free(void *ptr, int line, const char *source)
     (Curl_cfree)(mem);
   }
 
-  if(source)
+  if(source && ptr)
     curl_dbg_log("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
 }
 
diff --git a/lib/mime.c b/lib/mime.c
index e93e425a2..7518c029e 100644
--- a/lib/mime.c
+++ b/lib/mime.c
@@ -1778,6 +1778,23 @@ const char *Curl_mime_contenttype(const char *filename)
   return NULL;
 }
 
+static bool content_type_match(const char *contenttype, const char *target)
+{
+  size_t len = strlen(target);
+
+  if(contenttype && strncasecompare(contenttype, target, len))
+    switch(contenttype[len]) {
+    case '\0':
+    case '\t':
+    case '\r':
+    case '\n':
+    case ' ':
+    case ';':
+      return TRUE;
+    }
+  return FALSE;
+}
+
 CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
                                    const char *contenttype,
                                    const char *disposition,
@@ -1829,7 +1846,7 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
       boundary = mime->boundary;
   }
   else if(contenttype && !customct &&
-          strcasecompare(contenttype, "text/plain"))
+          content_type_match(contenttype, "text/plain"))
     if(strategy == MIMESTRATEGY_MAIL || !part->filename)
       contenttype = NULL;
 
@@ -1905,7 +1922,7 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
     curl_mimepart *subpart;
 
     disposition = NULL;
-    if(strcasecompare(contenttype, "multipart/form-data"))
+    if(content_type_match(contenttype, "multipart/form-data"))
       disposition = "form-data";
     for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) {
       ret = Curl_mime_prepare_headers(subpart, NULL, disposition, strategy);
diff --git a/lib/mk-ca-bundle.pl b/lib/mk-ca-bundle.pl
index 09e8e5b9b..b9c7ed257 100755
--- a/lib/mk-ca-bundle.pl
+++ b/lib/mk-ca-bundle.pl
@@ -63,7 +63,7 @@ $opt_d = 'release';
 # If the OpenSSL commandline is not in search path you can configure it here!
 my $openssl = 'openssl';
 
-my $version = '1.27';
+my $version = '1.28';
 
 $opt_w = 76; # default base64 encoded lines length
 
@@ -531,6 +531,11 @@ while (<TXT>) {
     } else {
       my $data = $cka_value;
       $cka_value = "";
+
+      if(!length($data)) {
+          # if empty, skip
+          next;
+      }
       my $encoded = MIME::Base64::encode_base64($data, '');
       $encoded =~ s/(.{1,${opt_w}})/$1\n/g;
       my $pem = "-----BEGIN CERTIFICATE-----\n"
diff --git a/lib/mk-ca-bundle.vbs b/lib/mk-ca-bundle.vbs
index 8da279268..34871711d 100755
--- a/lib/mk-ca-bundle.vbs
+++ b/lib/mk-ca-bundle.vbs
@@ -5,7 +5,7 @@
 '*                            | (__| |_| |  _ <| |___
 '*                             \___|\___/|_| \_\_____|
 '*
-'* Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+'* Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 '*
 '* This software is licensed as described in the file COPYING, which
 '* you should have received as part of this distribution. The terms
diff --git a/lib/mqtt.c b/lib/mqtt.c
new file mode 100644
index 000000000..73ccf4a82
--- /dev/null
+++ b/lib/mqtt.c
@@ -0,0 +1,627 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2019, Björn Stenberg, <address@hidden>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef CURL_ENABLE_MQTT
+
+#include "urldata.h"
+#include <gnurl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "progress.h"
+#include "mqtt.h"
+#include "select.h"
+#include "strdup.h"
+#include "url.h"
+#include "escape.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "multiif.h"
+#include "rand.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#define MQTT_MSG_CONNECT   0x10
+#define MQTT_MSG_CONNACK   0x20
+#define MQTT_MSG_PUBLISH   0x30
+#define MQTT_MSG_SUBSCRIBE 0x82
+#define MQTT_MSG_SUBACK    0x90
+#define MQTT_MSG_DISCONNECT 0xe0
+
+#define MQTT_CONNACK_LEN 2
+#define MQTT_SUBACK_LEN 3
+#define MQTT_CLIENTID_LEN 12 /* "curl0123abcd" */
+
+/*
+ * Forward declarations.
+ */
+
+static CURLcode mqtt_do(struct connectdata *conn, bool *done);
+static CURLcode mqtt_doing(struct connectdata *conn, bool *done);
+static int mqtt_getsock(struct connectdata *conn, curl_socket_t *sock);
+static CURLcode mqtt_setup_conn(struct connectdata *conn);
+
+/*
+ * MQTT protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_mqtt = {
+  "MQTT",                             /* scheme */
+  mqtt_setup_conn,                    /* setup_connection */
+  mqtt_do,                            /* do_it */
+  ZERO_NULL,                          /* done */
+  ZERO_NULL,                          /* do_more */
+  ZERO_NULL,                          /* connect_it */
+  ZERO_NULL,                          /* connecting */
+  mqtt_doing,                         /* doing */
+  ZERO_NULL,                          /* proto_getsock */
+  mqtt_getsock,                       /* doing_getsock */
+  ZERO_NULL,                          /* domore_getsock */
+  ZERO_NULL,                          /* perform_getsock */
+  ZERO_NULL,                          /* disconnect */
+  ZERO_NULL,                          /* readwrite */
+  ZERO_NULL,                          /* connection_check */
+  PORT_MQTT,                          /* defport */
+  CURLPROTO_MQTT,                     /* protocol */
+  PROTOPT_NONE                        /* flags */
+};
+
+static CURLcode mqtt_setup_conn(struct connectdata *conn)
+{
+  /* allocate the HTTP-specific struct for the Curl_easy, only to survive
+     during this request */
+  struct MQTT *mq;
+  struct Curl_easy *data = conn->data;
+  DEBUGASSERT(data->req.protop == NULL);
+
+  mq = calloc(1, sizeof(struct MQTT));
+  if(!mq)
+    return CURLE_OUT_OF_MEMORY;
+  data->req.protop = mq;
+  return CURLE_OK;
+}
+
+static CURLcode mqtt_send(struct connectdata *conn,
+                          char *buf, size_t len)
+{
+  CURLcode result = CURLE_OK;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  struct Curl_easy *data = conn->data;
+  struct MQTT *mq = data->req.protop;
+  ssize_t n;
+  result = Curl_write(conn, sockfd, buf, len, &n);
+  if(!result && data->set.verbose)
+    Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)n);
+  if(len != (size_t)n) {
+    size_t nsend = len - n;
+    char *sendleftovers = Curl_memdup(&buf[n], nsend);
+    if(!sendleftovers)
+      return CURLE_OUT_OF_MEMORY;
+    mq->sendleftovers = sendleftovers;
+    mq->nsend = nsend;
+  }
+  return result;
+}
+
+/* Generic function called by the multi interface to figure out what socket(s)
+   to wait for and for what actions during the DOING and PROTOCONNECT
+   states */
+static int mqtt_getsock(struct connectdata *conn,
+                        curl_socket_t *sock)
+{
+  sock[0] = conn->sock[FIRSTSOCKET];
+  return GETSOCK_READSOCK(FIRSTSOCKET);
+}
+
+static CURLcode mqtt_connect(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  const size_t client_id_offset = 14;
+  const size_t packetlen = client_id_offset + MQTT_CLIENTID_LEN;
+  char client_id[MQTT_CLIENTID_LEN + 1] = "curl";
+  const size_t curl_len = strlen("curl");
+  char packet[32] = {
+    MQTT_MSG_CONNECT,  /* packet type */
+    0x00,              /* remaining length */
+    0x00, 0x04,        /* protocol length */
+    'M','Q','T','T',   /* protocol name */
+    0x04,              /* protocol level */
+    0x02,              /* CONNECT flag: CleanSession */
+    0x00, 0x3c,        /* keep-alive 0 = disabled */
+    0x00, 0x00         /* payload1 length */
+  };
+  packet[1] = (packetlen - 2) & 0x7f;
+  packet[client_id_offset - 1] = MQTT_CLIENTID_LEN;
+
+  result = Curl_rand_hex(conn->data, (unsigned char *)&client_id[curl_len],
+                         MQTT_CLIENTID_LEN - curl_len + 1);
+  memcpy(&packet[client_id_offset], client_id, MQTT_CLIENTID_LEN);
+  infof(conn->data, "Using client id '%s'\n", client_id);
+  if(!result)
+    result = mqtt_send(conn, packet, packetlen);
+  return result;
+}
+
+static CURLcode mqtt_disconnect(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  result = mqtt_send(conn, (char *)"\xe0\x00", 2);
+  return result;
+}
+
+static CURLcode mqtt_verify_connack(struct connectdata *conn)
+{
+  CURLcode result;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  unsigned char readbuf[MQTT_CONNACK_LEN];
+  ssize_t nread;
+  struct Curl_easy *data = conn->data;
+
+  result = Curl_read(conn, sockfd, (char *)readbuf, MQTT_CONNACK_LEN, &nread);
+  if(result)
+    goto fail;
+
+  if(data->set.verbose)
+    Curl_debug(data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
+
+  /* fixme */
+  if(nread < MQTT_CONNACK_LEN) {
+    result = CURLE_WEIRD_SERVER_REPLY;
+    goto fail;
+  }
+
+  /* verify CONNACK */
+  if(readbuf[0] != 0x00 || readbuf[1] != 0x00) {
+    failf(data, "Expected %02x%02x but got %02x%02x",
+          0x00, 0x00, readbuf[0], readbuf[1]);
+    result = CURLE_WEIRD_SERVER_REPLY;
+  }
+
+fail:
+  return result;
+}
+
+static CURLcode mqtt_get_topic(struct connectdata *conn,
+                               char **topic, size_t *topiclen)
+{
+  CURLcode result = CURLE_OK;
+  char *path = conn->data->state.up.path;
+
+  if(strlen(path) > 1) {
+    result = Curl_urldecode(conn->data, path + 1, 0, topic, topiclen, FALSE);
+  }
+  else {
+    failf(conn->data, "Error: No topic specified.");
+    result = CURLE_URL_MALFORMAT;
+  }
+  return result;
+}
+
+
+static int mqtt_encode_len(char *buf, size_t len)
+{
+  unsigned char encoded;
+  int i;
+
+  for(i = 0; (len > 0) && (i<4); i++) {
+    encoded = len % 0x80;
+    len /= 0x80;
+    if(len)
+      encoded |= 0x80;
+    buf[i] = encoded;
+  }
+
+  return i;
+}
+
+static CURLcode mqtt_subscribe(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  char *topic = NULL;
+  size_t topiclen;
+  unsigned char *packet = NULL;
+  size_t packetlen;
+  char encodedsize[4];
+  size_t n;
+
+  result = mqtt_get_topic(conn, &topic, &topiclen);
+  if(result)
+    goto fail;
+
+  conn->proto.mqtt.packetid++;
+
+  packetlen = topiclen + 5; /* packetid + topic (has a two byte length field)
+                               + 2 bytes topic length + QoS byte */
+  n = mqtt_encode_len((char *)encodedsize, packetlen);
+  packetlen += n + 1; /* add one for the control packet type byte */
+
+  packet = malloc(packetlen);
+  if(!packet) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto fail;
+  }
+
+  packet[0] = MQTT_MSG_SUBSCRIBE;
+  memcpy(&packet[1], encodedsize, n);
+  packet[1 + n] = (conn->proto.mqtt.packetid >> 8) & 0xff;
+  packet[2 + n] = conn->proto.mqtt.packetid & 0xff;
+  packet[3 + n] = (topiclen >> 8) & 0xff;
+  packet[4 + n ] = topiclen & 0xff;
+  memcpy(&packet[5 + n], topic, topiclen);
+  packet[5 + n + topiclen] = 0; /* QoS zero */
+
+  result = mqtt_send(conn, (char *)packet, packetlen);
+
+fail:
+  free(topic);
+  free(packet);
+  return result;
+}
+
+/*
+ * Called when the first byte was already read.
+ */
+static CURLcode mqtt_verify_suback(struct connectdata *conn)
+{
+  CURLcode result;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  unsigned char readbuf[MQTT_SUBACK_LEN];
+  ssize_t nread;
+  struct mqtt_conn *mqtt = &conn->proto.mqtt;
+
+  result = Curl_read(conn, sockfd, (char *)readbuf, MQTT_SUBACK_LEN, &nread);
+  if(result)
+    goto fail;
+
+  if(conn->data->set.verbose)
+    Curl_debug(conn->data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
+
+  /* fixme */
+  if(nread < MQTT_SUBACK_LEN) {
+    result = CURLE_WEIRD_SERVER_REPLY;
+    goto fail;
+  }
+
+  /* verify SUBACK */
+  if(readbuf[0] != ((mqtt->packetid >> 8) & 0xff) ||
+     readbuf[1] != (mqtt->packetid & 0xff) ||
+     readbuf[2] != 0x00)
+    result = CURLE_WEIRD_SERVER_REPLY;
+
+fail:
+  return result;
+}
+
+static CURLcode mqtt_publish(struct connectdata *conn)
+{
+  CURLcode result;
+  char *payload = conn->data->set.postfields;
+  size_t payloadlen = (size_t)conn->data->set.postfieldsize;
+  char *topic = NULL;
+  size_t topiclen;
+  unsigned char *pkt = NULL;
+  size_t i = 0;
+  size_t remaininglength;
+  size_t encodelen;
+  char encodedbytes[4];
+
+  result = mqtt_get_topic(conn, &topic, &topiclen);
+  if(result)
+    goto fail;
+
+  remaininglength = payloadlen + 2 + topiclen;
+  encodelen = mqtt_encode_len(encodedbytes, remaininglength);
+
+  /* add the control byte and the encoded remaining length */
+  pkt = malloc(remaininglength + 1 + encodelen);
+  if(!pkt) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto fail;
+  }
+
+  /* assemble packet */
+  pkt[i++] = MQTT_MSG_PUBLISH;
+  memcpy(&pkt[i], encodedbytes, encodelen);
+  i += encodelen;
+  pkt[i++] = (topiclen >> 8) & 0xff;
+  pkt[i++] = (topiclen & 0xff);
+  memcpy(&pkt[i], topic, topiclen);
+  i += topiclen;
+  memcpy(&pkt[i], payload, payloadlen);
+  i += payloadlen;
+  result = mqtt_send(conn, (char *)pkt, i);
+
+fail:
+  free(pkt);
+  free(topic);
+  return result;
+}
+
+static size_t mqtt_decode_len(unsigned char *buf,
+                              size_t buflen, size_t *lenbytes)
+{
+  size_t len = 0;
+  size_t mult = 1;
+  size_t i;
+  unsigned char encoded = 128;
+
+  for(i = 0; (i < buflen) && (encoded & 128); i++) {
+    encoded = buf[i];
+    len += (encoded & 127) * mult;
+    mult *= 128;
+  }
+
+  if(lenbytes)
+    *lenbytes = i;
+
+  return len;
+}
+
+#ifdef CURLDEBUG
+static const char *statenames[]={
+  "MQTT_FIRST",
+  "MQTT_REMAINING_LENGTH",
+  "MQTT_CONNACK",
+  "MQTT_SUBACK",
+  "MQTT_SUBACK_COMING",
+  "MQTT_PUBWAIT",
+  "MQTT_PUB_REMAIN",
+
+  "NOT A STATE"
+};
+#endif
+
+/* The only way to change state */
+static void mqstate(struct connectdata *conn,
+                    enum mqttstate state,
+                    enum mqttstate nextstate) /* used if state == FIRST */
+{
+  struct mqtt_conn *mqtt = &conn->proto.mqtt;
+#ifdef CURLDEBUG
+  infof(conn->data, "%s (from %s) (next is %s)\n",
+        statenames[state],
+        statenames[mqtt->state],
+        (state == MQTT_FIRST)? statenames[nextstate] : "");
+#endif
+  mqtt->state = state;
+  if(state == MQTT_FIRST)
+    mqtt->nextstate = nextstate;
+}
+
+
+/* for the publish packet */
+#define MQTT_HEADER_LEN 5    /* max 5 bytes */
+
+static CURLcode mqtt_read_publish(struct connectdata *conn,
+                                  bool *done)
+{
+  CURLcode result = CURLE_OK;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  ssize_t nread;
+  struct Curl_easy *data = conn->data;
+  unsigned char *pkt = (unsigned char *)data->state.buffer;
+  size_t remlen;
+  struct mqtt_conn *mqtt = &conn->proto.mqtt;
+  struct MQTT *mq = data->req.protop;
+  unsigned char packet;
+
+  switch(mqtt->state) {
+  MQTT_SUBACK_COMING:
+  case MQTT_SUBACK_COMING:
+    result = mqtt_verify_suback(conn);
+    if(result)
+      break;
+
+    mqstate(conn, MQTT_FIRST, MQTT_PUBWAIT);
+    break;
+
+  case MQTT_SUBACK:
+  case MQTT_PUBWAIT:
+    /* we are expecting PUBLISH or SUBACK */
+    packet = mq->firstbyte & 0xf0;
+    if(packet == MQTT_MSG_PUBLISH)
+      mqstate(conn, MQTT_PUB_REMAIN, MQTT_NOSTATE);
+    else if(packet == MQTT_MSG_SUBACK) {
+      mqstate(conn, MQTT_SUBACK_COMING, MQTT_NOSTATE);
+      goto MQTT_SUBACK_COMING;
+    }
+    else if(packet == MQTT_MSG_DISCONNECT) {
+      infof(data, "Got DISCONNECT\n");
+      *done = TRUE;
+      goto end;
+    }
+    else {
+      result = CURLE_WEIRD_SERVER_REPLY;
+      goto end;
+    }
+
+    /* -- switched state -- */
+    remlen = mq->remaining_length;
+    infof(data, "Remaining length: %zd bytes\n", remlen);
+    Curl_pgrsSetDownloadSize(data, remlen);
+    data->req.bytecount = 0;
+    data->req.size = remlen;
+    mq->npacket = remlen; /* get this many bytes */
+    /* FALLTHROUGH */
+  case MQTT_PUB_REMAIN: {
+    /* read rest of packet, but no more. Cap to buffer size */
+    struct SingleRequest *k = &data->req;
+    size_t rest = mq->npacket;
+    if(rest > (size_t)data->set.buffer_size)
+      rest = (size_t)data->set.buffer_size;
+    result = Curl_read(conn, sockfd, (char *)pkt, rest, &nread);
+    if(result) {
+      if(CURLE_AGAIN == result) {
+        infof(data, "EEEE AAAAGAIN\n");
+      }
+      goto end;
+    }
+    if(!nread) {
+      infof(data, "server disconnected\n");
+      result = CURLE_PARTIAL_FILE;
+      goto end;
+    }
+    if(data->set.verbose)
+      Curl_debug(data, CURLINFO_DATA_IN, (char *)pkt, (size_t)nread);
+
+    mq->npacket -= nread;
+    k->bytecount += nread;
+    Curl_pgrsSetDownloadCounter(data, k->bytecount);
+
+    /* if QoS is set, message contains packet id */
+
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)pkt, nread);
+    if(result)
+      goto end;
+
+    if(!mq->npacket)
+      /* no more PUBLISH payload, back to subscribe wait state */
+      mqstate(conn, MQTT_FIRST, MQTT_PUBWAIT);
+    break;
+  }
+  default:
+    DEBUGASSERT(NULL); /* illegal state */
+    result = CURLE_WEIRD_SERVER_REPLY;
+    goto end;
+  }
+  end:
+  return result;
+}
+
+static CURLcode mqtt_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  *done = FALSE; /* unconditionally */
+
+  result = mqtt_connect(conn);
+  if(result) {
+    failf(data, "Error %d sending MQTT CONN request", result);
+    return result;
+  }
+  mqstate(conn, MQTT_FIRST, MQTT_CONNACK);
+  return CURLE_OK;
+}
+
+static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct mqtt_conn *mqtt = &conn->proto.mqtt;
+  struct Curl_easy *data = conn->data;
+  struct MQTT *mq = data->req.protop;
+  ssize_t nread;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  unsigned char *pkt = (unsigned char *)data->state.buffer;
+  unsigned char byte;
+
+  *done = FALSE;
+
+  if(mq->nsend) {
+    /* send the remainder of an outgoing packet */
+    char *ptr = mq->sendleftovers;
+    result = mqtt_send(conn, mq->sendleftovers, mq->nsend);
+    free(ptr);
+    if(result)
+      return result;
+  }
+
+  infof(data, "mqtt_doing: state [%d]\n", (int) mqtt->state);
+  switch(mqtt->state) {
+  case MQTT_FIRST:
+    /* Read the initial byte only */
+    result = Curl_read(conn, sockfd, (char *)&mq->firstbyte, 1, &nread);
+    if(result)
+      break;
+    if(data->set.verbose)
+      Curl_debug(data, CURLINFO_HEADER_IN, (char *)&mq->firstbyte, 1);
+    /* remember the first byte */
+    mq->npacket = 0;
+    mqstate(conn, MQTT_REMAINING_LENGTH, MQTT_NOSTATE);
+    /* FALLTHROUGH */
+  case MQTT_REMAINING_LENGTH:
+    do {
+      result = Curl_read(conn, sockfd, (char *)&byte, 1, &nread);
+      if(result)
+        break;
+      if(data->set.verbose)
+        Curl_debug(data, CURLINFO_HEADER_IN, (char *)&byte, 1);
+      pkt[mq->npacket++] = byte;
+    } while((byte & 0x80) && (mq->npacket < 4));
+    if(result)
+      break;
+    mq->remaining_length = mqtt_decode_len(&pkt[0], mq->npacket, NULL);
+    mq->npacket = 0;
+    if(mq->remaining_length) {
+      mqstate(conn, mqtt->nextstate, MQTT_NOSTATE);
+      break;
+    }
+    mqstate(conn, MQTT_FIRST, MQTT_FIRST);
+
+    if(mq->firstbyte == MQTT_MSG_DISCONNECT) {
+      infof(data, "Got DISCONNECT\n");
+      *done = TRUE;
+    }
+    break;
+  case MQTT_CONNACK:
+    result = mqtt_verify_connack(conn);
+    if(result)
+      break;
+
+    if(conn->data->set.httpreq == HTTPREQ_POST) {
+      result = mqtt_publish(conn);
+      if(!result) {
+        result = mqtt_disconnect(conn);
+        *done = TRUE;
+      }
+      mqtt->nextstate = MQTT_FIRST;
+    }
+    else {
+      result = mqtt_subscribe(conn);
+      if(!result) {
+        mqstate(conn, MQTT_FIRST, MQTT_SUBACK);
+      }
+    }
+    break;
+
+  case MQTT_SUBACK:
+  case MQTT_PUBWAIT:
+  case MQTT_PUB_REMAIN:
+    result = mqtt_read_publish(conn, done);
+    break;
+
+  default:
+    failf(conn->data, "State not handled yet");
+    *done = TRUE;
+    break;
+  }
+
+  if(result == CURLE_AGAIN)
+    result = CURLE_OK;
+  return result;
+}
+
+#endif /* CURL_ENABLE_MQTT */
diff --git a/lib/mqtt.h b/lib/mqtt.h
new file mode 100644
index 000000000..37463d58a
--- /dev/null
+++ b/lib/mqtt.h
@@ -0,0 +1,59 @@
+#ifndef HEADER_CURL_MQTT_H
+#define HEADER_CURL_MQTT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019 - 2020, Björn Stenberg, <address@hidden>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef CURL_ENABLE_MQTT
+extern const struct Curl_handler Curl_handler_mqtt;
+#endif
+
+enum mqttstate {
+  MQTT_FIRST,             /* 0 */
+  MQTT_REMAINING_LENGTH,  /* 1 */
+  MQTT_CONNACK,           /* 2 */
+  MQTT_SUBACK,            /* 3 */
+  MQTT_SUBACK_COMING,     /* 4 - the SUBACK remainder */
+  MQTT_PUBWAIT,    /* 5 - wait for publish */
+  MQTT_PUB_REMAIN,  /* 6 - wait for the remainder of the publish */
+
+  MQTT_NOSTATE /* 7 - never used an actual state */
+};
+
+struct mqtt_conn {
+  enum mqttstate state;
+  enum mqttstate nextstate; /* switch to this after remaining length is
+                               done */
+  unsigned int packetid;
+};
+
+/* protocol-specific transfer-related data */
+struct MQTT {
+  char *sendleftovers;
+  size_t nsend; /* size of sendleftovers */
+
+  /* when receiving */
+  size_t npacket; /* byte counter */
+  unsigned char firstbyte;
+  size_t remaining_length;
+};
+
+#endif /* HEADER_CURL_MQTT_H */
diff --git a/lib/multi.c b/lib/multi.c
index c89fe79a4..36cf5f346 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -700,6 +700,10 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi 
*multi,
   if(!data->multi)
     return CURLM_OK; /* it is already removed so let's say it is fine! */
 
+  /* Prevent users from trying to remove an easy handle from the wrong multi */
+  if(data->multi != multi)
+    return CURLM_BAD_EASY_HANDLE;
+
   if(multi->in_callback)
     return CURLM_RECURSIVE_API_CALL;
 
diff --git a/lib/select.c b/lib/select.c
index b836698f3..2ff95e1f4 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -24,6 +24,8 @@
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#include <unistd.h>
 #endif
 
 #if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
@@ -100,6 +102,82 @@ int Curl_wait_ms(int timeout_ms)
   return r;
 }
 
+/*
+ * This is a wrapper around select() to aid in Windows compatibility.
+ * A negative timeout value makes this function wait indefinitely,
+ * unless no valid file descriptor is given, when this happens the
+ * negative timeout is ignored and the function times out immediately.
+ *
+ * Return values:
+ *   -1 = system call error or fd >= FD_SETSIZE
+ *    0 = timeout
+ *    N = number of signalled file descriptors
+ */
+int Curl_select(curl_socket_t maxfd,
+                fd_set *fds_read,
+                fd_set *fds_write,
+                fd_set *fds_err,
+                time_t timeout_ms)     /* milliseconds to wait */
+{
+  struct timeval pending_tv;
+  struct timeval *ptimeout;
+  int pending_ms;
+  int r;
+
+#if SIZEOF_TIME_T != SIZEOF_INT
+  /* wrap-around precaution */
+  if(timeout_ms >= INT_MAX)
+    timeout_ms = INT_MAX;
+#endif
+
+#ifdef USE_WINSOCK
+  /* WinSock select() can't handle zero events.  See the comment below. */
+  if((!fds_read || fds_read->fd_count == 0) &&
+     (!fds_write || fds_write->fd_count == 0) &&
+     (!fds_err || fds_err->fd_count == 0)) {
+    r = Curl_wait_ms((int)timeout_ms);
+    return r;
+  }
+#endif
+
+  ptimeout = &pending_tv;
+
+  if(timeout_ms < 0) {
+    ptimeout = NULL;
+  }
+  else if(timeout_ms > 0) {
+    pending_ms = (int)timeout_ms;
+    pending_tv.tv_sec = pending_ms / 1000;
+    pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+  }
+  else if(!timeout_ms) {
+    pending_tv.tv_sec = 0;
+    pending_tv.tv_usec = 0;
+  }
+
+#ifdef USE_WINSOCK
+  /* WinSock select() must not be called with an fd_set that contains zero
+    fd flags, or it will return WSAEINVAL.  But, it also can't be called
+    with no fd_sets at all!  From the documentation:
+
+    Any two of the parameters, readfds, writefds, or exceptfds, can be
+    given as null. At least one must be non-null, and any non-null
+    descriptor set must contain at least one handle to a socket.
+
+    It is unclear why WinSock doesn't just handle this for us instead of
+    calling this an error.
+  */
+  r = select((int)maxfd + 1,
+             fds_read && fds_read->fd_count ? fds_read : NULL,
+             fds_write && fds_write->fd_count ? fds_write : NULL,
+             fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout);
+#else
+  r = select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout);
+#endif
+
+  return r;
+}
+
 /*
  * Wait for read or write events on a set of file descriptors. It uses poll()
  * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
@@ -123,20 +201,18 @@ int Curl_wait_ms(int timeout_ms)
 int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
                       curl_socket_t readfd1,
                       curl_socket_t writefd, /* socket to write to */
-                      time_t timeout_ms)     /* milliseconds to wait */
+                      timediff_t timeout_ms)     /* milliseconds to wait */
 {
 #ifdef HAVE_POLL_FINE
   struct pollfd pfd[3];
+  int pending_ms;
   int num;
 #else
-  struct timeval pending_tv;
-  struct timeval *ptimeout;
   fd_set fds_read;
   fd_set fds_write;
   fd_set fds_err;
   curl_socket_t maxfd;
 #endif
-  int pending_ms = 0;
   int r;
   int ret;
 
@@ -158,10 +234,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two 
sockets to read from */
      when function is called with a zero timeout or a negative timeout
      value indicating a blocking call should be performed. */
 
-  if(timeout_ms > 0) {
-    pending_ms = (int)timeout_ms;
-  }
-
 #ifdef HAVE_POLL_FINE
 
   num = 0;
@@ -184,9 +256,11 @@ int Curl_socket_check(curl_socket_t readfd0, /* two 
sockets to read from */
     num++;
   }
 
-  if(timeout_ms < 0)
+  if(timeout_ms > 0)
+    pending_ms = (int)timeout_ms;
+  else if(timeout_ms < 0)
     pending_ms = -1;
-  else if(!timeout_ms)
+  else
     pending_ms = 0;
   r = poll(pfd, num, pending_ms);
 
@@ -249,46 +323,17 @@ int Curl_socket_check(curl_socket_t readfd0, /* two 
sockets to read from */
       maxfd = writefd;
   }
 
-  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
-
-  if(timeout_ms > 0) {
-    pending_tv.tv_sec = pending_ms / 1000;
-    pending_tv.tv_usec = (pending_ms % 1000) * 1000;
-  }
-  else if(!timeout_ms) {
-    pending_tv.tv_sec = 0;
-    pending_tv.tv_usec = 0;
-  }
-
-  /* WinSock select() must not be called with an fd_set that contains zero
-     fd flags, or it will return WSAEINVAL.  But, it also can't be called
-     with no fd_sets at all!  From the documentation:
-
-     Any two of the parameters, readfds, writefds, or exceptfds, can be
-     given as null. At least one must be non-null, and any non-null
-     descriptor set must contain at least one handle to a socket.
-
-     We know that we have at least one bit set in at least two fd_sets in
+  /* We know that we have at least one bit set in at least two fd_sets in
      this case, but we may have no bits set in either fds_read or fd_write,
      so check for that and handle it.  Luckily, with WinSock, we can _also_
      ask how many bits are set on an fd_set.
 
-     It is unclear why WinSock doesn't just handle this for us instead of
-     calling this an error.
-
      Note also that WinSock ignores the first argument, so we don't worry
      about the fact that maxfd is computed incorrectly with WinSock (since
      curl_socket_t is unsigned in such cases and thus -1 is the largest
      value).
   */
-#ifdef USE_WINSOCK
-  r = select((int)maxfd + 1,
-             fds_read.fd_count ? &fds_read : NULL,
-             fds_write.fd_count ? &fds_write : NULL,
-             &fds_err, ptimeout);
-#else
-  r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
-#endif
+  r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, (time_t)timeout_ms);
 
   if(r < 0)
     return -1;
@@ -336,9 +381,9 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets 
to read from */
  */
 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
 {
-#ifndef HAVE_POLL_FINE
-  struct timeval pending_tv;
-  struct timeval *ptimeout;
+#ifdef HAVE_POLL_FINE
+  int pending_ms;
+#else
   fd_set fds_read;
   fd_set fds_write;
   fd_set fds_err;
@@ -346,7 +391,6 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int 
timeout_ms)
 #endif
   bool fds_none = TRUE;
   unsigned int i;
-  int pending_ms = 0;
   int r;
 
   if(ufds) {
@@ -367,15 +411,13 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, 
int timeout_ms)
      when function is called with a zero timeout or a negative timeout
      value indicating a blocking call should be performed. */
 
-  if(timeout_ms > 0) {
-    pending_ms = timeout_ms;
-  }
-
 #ifdef HAVE_POLL_FINE
 
-  if(timeout_ms < 0)
+  if(timeout_ms > 0)
+    pending_ms = timeout_ms;
+  else if(timeout_ms < 0)
     pending_ms = -1;
-  else if(!timeout_ms)
+  else
     pending_ms = 0;
   r = poll(ufds, nfds, pending_ms);
 
@@ -418,39 +460,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int 
timeout_ms)
     }
   }
 
-#ifdef USE_WINSOCK
-  /* WinSock select() can't handle zero events.  See the comment about this in
-     Curl_check_socket(). */
-  if(fds_read.fd_count == 0 && fds_write.fd_count == 0
-     && fds_err.fd_count == 0) {
-    r = Curl_wait_ms(timeout_ms);
-    return r;
-  }
-#endif
-
-  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
-
-  if(timeout_ms > 0) {
-    pending_tv.tv_sec = pending_ms / 1000;
-    pending_tv.tv_usec = (pending_ms % 1000) * 1000;
-  }
-  else if(!timeout_ms) {
-    pending_tv.tv_sec = 0;
-    pending_tv.tv_usec = 0;
-  }
-
-#ifdef USE_WINSOCK
-  r = select((int)maxfd + 1,
-             /* WinSock select() can't handle fd_sets with zero bits set, so
-                don't give it such arguments.  See the comment about this in
-                Curl_check_socket().
-             */
-             fds_read.fd_count ? &fds_read : NULL,
-             fds_write.fd_count ? &fds_write : NULL,
-             fds_err.fd_count ? &fds_err : NULL, ptimeout);
-#else
-  r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
-#endif
+  r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
 
   if(r < 0)
     return -1;
diff --git a/lib/select.h b/lib/select.h
index ec3021aac..0fd8ed515 100644
--- a/lib/select.h
+++ b/lib/select.h
@@ -72,13 +72,19 @@ struct pollfd
    therefore defined here */
 #define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1)
 
+int Curl_select(curl_socket_t maxfd,
+                fd_set *fds_read,
+                fd_set *fds_write,
+                fd_set *fds_err,
+                time_t timeout_ms);
+
 int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
                       curl_socket_t writefd,
-                      time_t timeout_ms);
+                      timediff_t timeout_ms);
 #define SOCKET_READABLE(x,z) \
-  Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, (time_t)z)
+  Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, z)
 #define SOCKET_WRITABLE(x,z) \
-  Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, (time_t)z)
+  Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z)
 
 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
 int Curl_wait_ms(int timeout_ms);
diff --git a/lib/setopt.c b/lib/setopt.c
index 20acfc4ef..12ed72ea6 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -2134,6 +2134,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption 
option, va_list param)
       (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
     data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
     data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
+    data->set.ssl.revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
     break;
 
 #ifndef CURL_DISABLE_PROXY
@@ -2143,6 +2144,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption 
option, va_list param)
       (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
     data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
     data->set.proxy_ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
+    data->set.proxy_ssl.revoke_best_effort =
+      !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
     break;
 #endif
 
diff --git a/lib/setup-win32.h b/lib/setup-win32.h
new file mode 100644
index 000000000..45b584766
--- /dev/null
+++ b/lib/setup-win32.h
@@ -0,0 +1,123 @@
+#ifndef HEADER_CURL_SETUP_WIN32_H
+#define HEADER_CURL_SETUP_WIN32_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Include header files for windows builds before redefining anything.
+ * Use this preprocessor block only to include or exclude windows.h,
+ * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
+ * to any other further and independent block.  Under Cygwin things work
+ * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
+ * never be included when __CYGWIN__ is defined.  configure script takes
+ * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
+ * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
+ */
+
+#ifdef HAVE_WINDOWS_H
+#  if defined(UNICODE) && !defined(_UNICODE)
+#    define _UNICODE
+#  endif
+#  if defined(_UNICODE) && !defined(UNICODE)
+#    define UNICODE
+#  endif
+#  include <winerror.h>
+#  include <windows.h>
+#  ifdef HAVE_WINSOCK2_H
+#    include <winsock2.h>
+#    ifdef HAVE_WS2TCPIP_H
+#      include <ws2tcpip.h>
+#    endif
+#  else
+#    ifdef HAVE_WINSOCK_H
+#      include <winsock.h>
+#    endif
+#  endif
+#  include <tchar.h>
+#  ifdef UNICODE
+     typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
+#  endif
+#endif
+
+/*
+ * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
+ * define USE_WINSOCK to 1 if we have and use WINSOCK  API, else
+ * undefine USE_WINSOCK.
+ */
+
+#undef USE_WINSOCK
+
+#ifdef HAVE_WINSOCK2_H
+#  define USE_WINSOCK 2
+#else
+#  ifdef HAVE_WINSOCK_H
+#    define USE_WINSOCK 1
+#  endif
+#endif
+
+/*
+ * Define _WIN32_WINNT_[OS] symbols because not all Windows build systems have
+ * those symbols to compare against, and even those that do may be missing
+ * newer symbols.
+ */
+
+#ifndef _WIN32_WINNT_NT4
+#define _WIN32_WINNT_NT4            0x0400   /* Windows NT 4.0 */
+#endif
+#ifndef _WIN32_WINNT_WIN2K
+#define _WIN32_WINNT_WIN2K          0x0500   /* Windows 2000 */
+#endif
+#ifndef _WIN32_WINNT_WINXP
+#define _WIN32_WINNT_WINXP          0x0501   /* Windows XP */
+#endif
+#ifndef _WIN32_WINNT_WS03
+#define _WIN32_WINNT_WS03           0x0502   /* Windows Server 2003 */
+#endif
+#ifndef _WIN32_WINNT_WIN6
+#define _WIN32_WINNT_WIN6           0x0600   /* Windows Vista */
+#endif
+#ifndef _WIN32_WINNT_VISTA
+#define _WIN32_WINNT_VISTA          0x0600   /* Windows Vista */
+#endif
+#ifndef _WIN32_WINNT_WS08
+#define _WIN32_WINNT_WS08           0x0600   /* Windows Server 2008 */
+#endif
+#ifndef _WIN32_WINNT_LONGHORN
+#define _WIN32_WINNT_LONGHORN       0x0600   /* Windows Vista */
+#endif
+#ifndef _WIN32_WINNT_WIN7
+#define _WIN32_WINNT_WIN7           0x0601   /* Windows 7 */
+#endif
+#ifndef _WIN32_WINNT_WIN8
+#define _WIN32_WINNT_WIN8           0x0602   /* Windows 8 */
+#endif
+#ifndef _WIN32_WINNT_WINBLUE
+#define _WIN32_WINNT_WINBLUE        0x0603   /* Windows 8.1 */
+#endif
+#ifndef _WIN32_WINNT_WINTHRESHOLD
+#define _WIN32_WINNT_WINTHRESHOLD   0x0A00   /* Windows 10 */
+#endif
+#ifndef _WIN32_WINNT_WIN10
+#define _WIN32_WINNT_WIN10          0x0A00   /* Windows 10 */
+#endif
+
+#endif /* HEADER_CURL_SETUP_WIN32_H */
diff --git a/lib/sha256.c b/lib/sha256.c
index 352d577e8..00d98ce46 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -207,8 +207,8 @@ typedef struct {
 
 static void SHA256_Init(SHA256_CTX *ctx)
 {
-  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
-                         PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES,
+                         CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
     CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
   }
 }
diff --git a/lib/smb.h b/lib/smb.h
index 9ce6b5615..136a89ce9 100644
--- a/lib/smb.h
+++ b/lib/smb.h
@@ -8,7 +8,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2014, Bill Nagel <address@hidden>, Exacq Technologies
- * Copyright (C) 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -193,7 +193,6 @@ struct smb_nt_create_response {
   unsigned int ext_file_attributes;
   curl_off_t allocation_size;
   curl_off_t end_of_file;
-
 } PACK;
 
 struct smb_read {
diff --git a/lib/smtp.c b/lib/smtp.c
index 7d71a2201..dc511292b 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -625,8 +625,7 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
         utf8 = TRUE;
 
       if(host.name) {
-        free(from);
-        from = aprintf("<%s@%s>", address, host.name);
+        auth = aprintf("<%s@%s>", address, host.name);
 
         Curl_free_idnconverted_hostname(&host);
       }
@@ -636,8 +635,6 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
         auth = aprintf("<%s>", address);
 
       free(address);
-      if(!from)
-        return CURLE_OUT_OF_MEMORY;
     }
     else
       /* Empty AUTH, RFC-2554, sect. 5 */
@@ -1741,10 +1738,10 @@ static CURLcode smtp_parse_custom_request(struct 
connectdata *conn)
  * Notes:
  *
  * Should a UTF-8 host name require conversion to IDN ACE and we cannot honor
- * that convertion then we shall return success. This allow the caller to send
+ * that conversion then we shall return success. This allow the caller to send
  * the data to the server as a U-label (as per RFC-6531 sect. 3.2).
  *
- * If an mailbox '@' seperator cannot be located then the mailbox is considered
+ * If an mailbox '@' separator cannot be located then the mailbox is considered
  * to be either a local mailbox or an invalid mailbox (depending on what the
  * calling function deems it to be) then the input will simply be returned in
  * the address part with the host name being NULL.
@@ -1765,7 +1762,7 @@ static CURLcode smtp_parse_address(struct connectdata 
*conn, const char *fqma,
   if(dup[length - 1] == '>')
     dup[length - 1] = '\0';
 
-  /* Extract the host name from the addresss (if we can) */
+  /* Extract the host name from the address (if we can) */
   host->name = strpbrk(dup, "@");
   if(host->name) {
     *host->name = '\0';
diff --git a/lib/socks.c b/lib/socks.c
index 37099130e..18affbc96 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -62,13 +62,15 @@ int Curl_blockread_all(struct connectdata *conn, /* 
connection data */
   int result;
   *n = 0;
   for(;;) {
-    timediff_t timeleft = Curl_timeleft(conn->data, NULL, TRUE);
-    if(timeleft < 0) {
+    timediff_t timeout_ms = Curl_timeleft(conn->data, NULL, TRUE);
+    if(timeout_ms < 0) {
       /* we already got the timeout */
       result = CURLE_OPERATION_TIMEDOUT;
       break;
     }
-    if(SOCKET_READABLE(sockfd, timeleft) <= 0) {
+    if(!timeout_ms)
+      timeout_ms = TIME_T_MAX;
+    if(SOCKET_READABLE(sockfd, timeout_ms) <= 0) {
       result = ~CURLE_OK;
       break;
     }
diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c
index 97ee7183e..7f66675fc 100644
--- a/lib/socks_gssapi.c
+++ b/lib/socks_gssapi.c
@@ -227,7 +227,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
 
     gss_release_buffer(&gss_status, &gss_send_token);
     gss_release_buffer(&gss_status, &gss_recv_token);
-    if(gss_major_status != GSS_S_CONTINUE_NEEDED) break;
+    if(gss_major_status != GSS_S_CONTINUE_NEEDED)
+      break;
 
     /* analyse response */
 
diff --git a/lib/transfer.c b/lib/transfer.c
index ac895cc08..fe61dc1f1 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -48,6 +48,8 @@
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#include <unistd.h>
 #endif
 
 #ifndef HAVE_SOCKET
@@ -568,17 +570,20 @@ static CURLcode readwrite_data(struct Curl_easy *data,
     bool is_empty_data = FALSE;
     size_t buffersize = data->set.buffer_size;
     size_t bytestoread = buffersize;
+#ifdef USE_NGHTTP2
+    bool is_http2 = ((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+                     (conn->httpversion == 20));
+#endif
 
     if(
-#if defined(USE_NGHTTP2)
+#ifdef USE_NGHTTP2
        /* For HTTP/2, read data without caring about the content
           length. This is safe because body in HTTP/2 is always
           segmented thanks to its framing layer. Meanwhile, we have to
           call Curl_read to ensure that http2_handle_stream_close is
           called when we read all incoming bytes for a particular
           stream. */
-       !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
-         conn->httpversion == 20) &&
+       !is_http2 &&
 #endif
        k->size != -1 && !k->header) {
       /* make sure we don't read too much */
@@ -621,9 +626,14 @@ static CURLcode readwrite_data(struct Curl_easy *data,
       k->buf[nread] = 0;
     }
     else {
-      /* if we receive 0 or less here, the server closed the connection
-         and we bail out from this! */
-      DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
+      /* if we receive 0 or less here, either the http2 stream is closed or the
+         server closed the connection and we bail out from this! */
+#ifdef USE_NGHTTP2
+      if(is_http2 && !nread)
+        DEBUGF(infof(data, "nread == 0, stream closed, bailing\n"));
+      else
+#endif
+        DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
       k->keepon &= ~KEEP_RECV;
       break;
     }
@@ -1707,12 +1717,19 @@ CURLcode Curl_follow(struct Curl_easy *data,
     break;
 
   case 303: /* See Other */
-    /* Disable both types of POSTs, unless the user explicitly
-       asks for POST after POST */
-    if(data->set.httpreq != HTTPREQ_GET
-      && !(data->set.keep_post & CURL_REDIR_POST_303)) {
-      data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
-      infof(data, "Disables POST, goes with %s\n",
+    /* 'See Other' location is not the resource but a substitute for the
+     * resource. In this case we switch the method to GET/HEAD, unless the
+     * method is POST and the user specified to keep it as POST.
+     * https://github.com/curl/curl/issues/5237#issuecomment-614641049
+     */
+    if(data->set.httpreq != HTTPREQ_GET &&
+       ((data->set.httpreq != HTTPREQ_POST &&
+         data->set.httpreq != HTTPREQ_POST_FORM &&
+         data->set.httpreq != HTTPREQ_POST_MIME) ||
+        !(data->set.keep_post & CURL_REDIR_POST_303))) {
+      data->set.httpreq = HTTPREQ_GET;
+      data->set.upload = false;
+      infof(data, "Switch to %s\n",
             data->set.opt_no_body?"HEAD":"GET");
     }
     break;
@@ -1779,6 +1796,12 @@ CURLcode Curl_retry_request(struct connectdata *conn,
     retry = TRUE;
   }
   if(retry) {
+#define CONN_MAX_RETRIES 5
+    if(conn->retrycount++ >= CONN_MAX_RETRIES) {
+      failf(data, "Connection died, tried %d times before giving up",
+            CONN_MAX_RETRIES);
+      return CURLE_SEND_ERROR;
+    }
     infof(conn->data, "Connection died, retrying a fresh connect\n");
     *url = strdup(conn->data->change.url);
     if(!*url)
@@ -1821,15 +1844,21 @@ Curl_setup_transfer(
 {
   struct SingleRequest *k = &data->req;
   struct connectdata *conn = data->conn;
+  struct HTTP *http = data->req.protop;
+  bool httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
+                      (http->sending == HTTPSEND_REQUEST));
   DEBUGASSERT(conn != NULL);
   DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
 
-  if(conn->bits.multiplex || conn->httpversion == 20) {
+  if(conn->bits.multiplex || conn->httpversion == 20 || httpsending) {
     /* when multiplexing, the read/write sockets need to be the same! */
     conn->sockfd = sockindex == -1 ?
       ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) :
       conn->sock[sockindex];
     conn->writesockfd = conn->sockfd;
+    if(httpsending)
+      /* special and very HTTP-specific */
+      writesockindex = FIRSTSOCKET;
   }
   else {
     conn->sockfd = sockindex == -1 ?
@@ -1857,7 +1886,6 @@ Curl_setup_transfer(
       k->keepon |= KEEP_RECV;
 
     if(writesockindex != -1) {
-      struct HTTP *http = data->req.protop;
       /* HTTP 1.1 magic:
 
          Even if we require a 100-return code before uploading data, we might
diff --git a/lib/url.c b/lib/url.c
index 47fc66aed..03c274438 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -114,6 +114,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
 #include "http_ntlm.h"
 #include "curl_rtmp.h"
 #include "gopher.h"
+#include "mqtt.h"
 #include "http_proxy.h"
 #include "conncache.h"
 #include "multihandle.h"
@@ -232,6 +233,10 @@ static const struct Curl_handler * const protocols[] = {
   &Curl_handler_gopher,
 #endif
 
+#ifdef CURL_ENABLE_MQTT
+  &Curl_handler_mqtt,
+#endif
+
 #ifdef USE_LIBRTMP
   &Curl_handler_rtmp,
   &Curl_handler_rtmpt,
@@ -3040,7 +3045,14 @@ static CURLcode parse_connect_to_slist(struct Curl_easy 
*data,
 
 #ifdef USE_ALTSVC
   if(data->asi && !host && (port == -1) &&
-     (conn->handler->protocol == CURLPROTO_HTTPS)) {
+     ((conn->handler->protocol == CURLPROTO_HTTPS) ||
+#ifdef CURLDEBUG
+      /* allow debug builds to circumvent the HTTPS restriction */
+      getenv("CURL_ALTSVC_HTTP")
+#else
+      0
+#endif
+       )) {
     /* no connect_to match, try alt-svc! */
     enum alpnid srcalpnid;
     bool hit;
diff --git a/lib/urldata.h b/lib/urldata.h
index d1394fb84..23e7ffe71 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -49,6 +49,7 @@
 #define PORT_RTMPT PORT_HTTP
 #define PORT_RTMPS PORT_HTTPS
 #define PORT_GOPHER 70
+#define PORT_MQTT 1883
 
 #define DICT_MATCH "/MATCH:"
 #define DICT_MATCH2 "/M:"
@@ -128,6 +129,7 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* 
connection data */
 #include "http.h"
 #include "rtsp.h"
 #include "smb.h"
+#include "mqtt.h"
 #include "wildcard.h"
 #include "multihandle.h"
 #include "quic.h"
@@ -259,6 +261,8 @@ struct ssl_config_data {
   BIT(enable_beast); /* allow this flaw for interoperability's sake*/
   BIT(no_revoke);    /* disable SSL certificate revocation checks */
   BIT(no_partialchain); /* don't accept partial certificate chains */
+  BIT(revoke_best_effort); /* ignore SSL revocation offline/missing revocation
+                              list errors */
 };
 
 struct ssl_general_config {
@@ -958,6 +962,7 @@ struct connectdata {
   curl_socket_t sock[2]; /* two sockets, the second is used for the data
                             transfer when doing FTP */
   curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */
+  int tempfamily[2]; /* family used for the temp sockets */
   Curl_recv *recv[2];
   Curl_send *send[2];
 
@@ -1079,6 +1084,7 @@ struct connectdata {
     struct smb_conn smbc;
     void *rtmp;
     struct ldapconninfo *ldapc;
+    struct mqtt_conn mqtt;
   } proto;
 
   int cselect_bits; /* bitmask of socket events */
@@ -1099,7 +1105,7 @@ struct connectdata {
   struct http_connect_state *connect_state; /* for HTTP CONNECT */
   struct connectbundle *bundle; /* The bundle we are member of */
   int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */
-
+  int retrycount; /* number of retries on a new connection */
 #ifdef USE_UNIX_SOCKETS
   char *unix_domain_socket;
   BIT(abstract_unix_socket);
@@ -1114,6 +1120,8 @@ struct connectdata {
                               handle */
   BIT(sock_accepted); /* TRUE if the SECONDARYSOCKET was created with
                          accept() */
+  BIT(parallel_connect); /* set TRUE when a parallel connect attempt has
+                            started (happy eyeballs) */
 };
 
 /* The end of connectdata. */
@@ -1326,7 +1334,6 @@ struct urlpieces {
 };
 
 struct UrlState {
-
   /* Points to the connection cache */
   struct conncache *conn_cache;
 
diff --git a/lib/version.c b/lib/version.c
index ca4ab5717..3724c3392 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -85,14 +85,17 @@ static size_t brotli_version(char *buf, size_t bufsz)
  * generate the exact same string and never write any temporary data like
  * zeros in the data.
  */
+
+#define VERSION_PARTS 14 /* number of substrings we can concatenate */
+
 char *curl_version(void)
 {
-  static char out[250];
+  static char out[300];
   char *outp;
   size_t outlen;
-  const char *src[14];
+  const char *src[VERSION_PARTS];
 #ifdef USE_SSL
-  char ssl_version[40];
+  char ssl_version[200];
 #endif
 #ifdef HAVE_LIBZ
   char z_version[40];
@@ -103,7 +106,7 @@ char *curl_version(void)
 #ifdef USE_ARES
   char cares_version[40];
 #endif
-#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN)
+#if defined(USE_LIBIDN2)
   char idn_version[40];
 #endif
 #ifdef USE_LIBPSL
@@ -127,6 +130,16 @@ char *curl_version(void)
   int i = 0;
   int j;
 
+#ifdef DEBUGBUILD
+  /* Override version string when environment variable CURL_VERSION is set */
+  const char *debugversion = getenv("CURL_VERSION");
+  if(debugversion) {
+    strncpy(out, debugversion, sizeof(out)-1);
+    out[sizeof(out)-1] = '\0';
+    return out;
+  }
+#endif
+
   src[i++] = LIBCURL_NAME "/" LIBCURL_VERSION;
 #ifdef USE_SSL
   Curl_ssl_version(ssl_version, sizeof(ssl_version));
@@ -146,14 +159,11 @@ char *curl_version(void)
   src[i++] = cares_version;
 #endif
 #ifdef USE_LIBIDN2
-  if(idn2_check_version(IDN2_VERSION)) {
-    msnprintf(idn_version, sizeof(idn_version),
-              "libidn2/%s", idn2_check_version(NULL));
-    src[i++] = idn_version;
-  }
-#elif defined(USE_WIN32_IDN)
-  msnprintf(idn_version, sizeof(idn_version), "WinIDN");
+  msnprintf(idn_version, sizeof(idn_version),
+            "libidn2/%s", idn2_check_version(NULL));
   src[i++] = idn_version;
+#elif defined(USE_WIN32_IDN)
+  src[i++] = (char *)"WinIDN";
 #endif
 
 #ifdef USE_LIBPSL
@@ -198,6 +208,8 @@ char *curl_version(void)
   }
 #endif
 
+  DEBUGASSERT(i <= VERSION_PARTS);
+
   outp = &out[0];
   outlen = sizeof(out);
   for(j = 0; j < i; j++) {
@@ -261,6 +273,9 @@ static const char * const protocols[] = {
   "ldaps",
 #endif
 #endif
+#ifdef CURL_ENABLE_MQTT
+  "mqtt",
+#endif
 #ifndef CURL_DISABLE_POP3
   "pop3",
 #endif
@@ -376,9 +391,6 @@ static curl_version_info_data version_info = {
 #endif
 #if defined(USE_ALTSVC)
   | CURL_VERSION_ALTSVC
-#endif
-#ifdef USE_ESNI
-  | CURL_VERSION_ESNI
 #endif
   ,
   NULL, /* ssl_version */
@@ -394,7 +406,17 @@ static curl_version_info_data version_info = {
   NULL, /* brotli version */
   0,    /* nghttp2 version number */
   NULL, /* nghttp2 version string */
-  NULL  /* quic library string */
+  NULL, /* quic library string */
+#ifdef CURL_CA_BUNDLE
+  CURL_CA_BUNDLE, /* cainfo */
+#else
+  NULL,
+#endif
+#ifdef CURL_CA_PATH
+  CURL_CA_PATH  /* capath */
+#else
+  NULL
+#endif
 };
 
 curl_version_info_data *curl_version_info(CURLversion stamp)
diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c
index 2f6ee8bdf..5f7b6e2e0 100644
--- a/lib/vquic/ngtcp2.c
+++ b/lib/vquic/ngtcp2.c
@@ -26,7 +26,9 @@
 #include <ngtcp2/ngtcp2.h>
 #include <ngtcp2/ngtcp2_crypto.h>
 #include <nghttp3/nghttp3.h>
+#ifdef USE_OPENSSL
 #include <openssl/err.h>
+#endif
 #include "urldata.h"
 #include "sendf.h"
 #include "strdup.h"
@@ -69,10 +71,18 @@ struct h3out {
 #define QUIC_MAX_STREAMS (256*1024)
 #define QUIC_MAX_DATA (1*1024*1024)
 #define QUIC_IDLE_TIMEOUT 60000 /* milliseconds */
+
+#ifdef USE_OPENSSL
 #define QUIC_CIPHERS                                                          \
   "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_"               \
   "POLY1305_SHA256:TLS_AES_128_CCM_SHA256"
 #define QUIC_GROUPS "P-256:X25519:P-384:P-521"
+#elif defined(USE_GNUTLS)
+#define QUIC_PRIORITY \
+  "NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:" \
+  "+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \
+  "+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1"
+#endif
 
 static CURLcode ng_process_ingress(struct connectdata *conn,
                                    curl_socket_t sockfd,
@@ -101,6 +111,7 @@ static void quic_printf(void *user_data, const char *fmt, 
...)
 }
 #endif
 
+#ifdef USE_OPENSSL
 static ngtcp2_crypto_level
 quic_from_ossl_level(OSSL_ENCRYPTION_LEVEL ossl_level)
 {
@@ -117,14 +128,32 @@ quic_from_ossl_level(OSSL_ENCRYPTION_LEVEL ossl_level)
     assert(0);
   }
 }
+#elif defined(USE_GNUTLS)
+static ngtcp2_crypto_level
+quic_from_gtls_level(gnutls_record_encryption_level_t gtls_level)
+{
+  switch(gtls_level) {
+  case GNUTLS_ENCRYPTION_LEVEL_INITIAL:
+    return NGTCP2_CRYPTO_LEVEL_INITIAL;
+  case GNUTLS_ENCRYPTION_LEVEL_EARLY:
+    return NGTCP2_CRYPTO_LEVEL_EARLY;
+  case GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE:
+    return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
+  case GNUTLS_ENCRYPTION_LEVEL_APPLICATION:
+    return NGTCP2_CRYPTO_LEVEL_APP;
+  default:
+    assert(0);
+  }
+}
+#endif
 
 static int setup_initial_crypto_context(struct quicsocket *qs)
 {
   const ngtcp2_cid *dcid = ngtcp2_conn_get_dcid(qs->qconn);
 
   if(ngtcp2_crypto_derive_and_install_initial_key(
-         qs->qconn, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, dcid,
-         NGTCP2_CRYPTO_SIDE_CLIENT) != 0)
+         qs->qconn, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         dcid) != 0)
     return -1;
 
   return 0;
@@ -150,6 +179,7 @@ static void quic_settings(ngtcp2_settings *s,
 }
 
 static FILE *keylog_file; /* not thread-safe */
+#ifdef USE_OPENSSL
 static void keylog_callback(const SSL *ssl, const char *line)
 {
   (void)ssl;
@@ -157,37 +187,52 @@ static void keylog_callback(const SSL *ssl, const char 
*line)
   fputc('\n', keylog_file);
   fflush(keylog_file);
 }
-
-static int init_ngh3_conn(struct quicsocket *qs);
-
-static int quic_set_encryption_secrets(SSL *ssl,
-                                       OSSL_ENCRYPTION_LEVEL ossl_level,
-                                       const uint8_t *rx_secret,
-                                       const uint8_t *tx_secret,
-                                       size_t secretlen)
+#elif defined(USE_GNUTLS)
+static int keylog_callback(gnutls_session_t session, const char *label,
+                    const gnutls_datum_t *secret)
 {
-  struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
-  int level = quic_from_ossl_level(ossl_level);
+  gnutls_datum_t crandom;
+  gnutls_datum_t srandom;
+  gnutls_datum_t crandom_hex = { NULL, 0 };
+  gnutls_datum_t secret_hex = { NULL, 0 };
+  int rc = 0;
+
+  gnutls_session_get_random(session, &crandom, &srandom);
+  if(crandom.size != 32) {
+    return -1;
+  }
 
-  if(ngtcp2_crypto_derive_and_install_key(
-         qs->qconn, ssl, NULL, NULL, NULL, NULL, NULL, NULL, level, rx_secret,
-         tx_secret, secretlen, NGTCP2_CRYPTO_SIDE_CLIENT) != 0)
-    return 0;
+  rc = gnutls_hex_encode2(&crandom, &crandom_hex);
+  if(rc < 0) {
+    fprintf(stderr, "gnutls_hex_encode2 failed: %s\n",
+            gnutls_strerror(rc));
+    goto out;
+  }
 
-  if(level == NGTCP2_CRYPTO_LEVEL_APP) {
-    if(init_ngh3_conn(qs) != CURLE_OK)
-      return 0;
+  rc = gnutls_hex_encode2(secret, &secret_hex);
+  if(rc < 0) {
+    fprintf(stderr, "gnutls_hex_encode2 failed: %s\n",
+            gnutls_strerror(rc));
+    goto out;
   }
 
-  return 1;
+  fprintf(keylog_file, "%s %s %s\n", label, crandom_hex.data, secret_hex.data);
+  fflush(keylog_file);
+
+ out:
+  gnutls_free(crandom_hex.data);
+  gnutls_free(secret_hex.data);
+  return rc;
 }
+#endif
 
-static int quic_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
-                                   const uint8_t *data, size_t len)
+static int init_ngh3_conn(struct quicsocket *qs);
+
+static int write_client_handshake(struct quicsocket *qs,
+                                  ngtcp2_crypto_level level,
+                                  const uint8_t *data, size_t len)
 {
-  struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
   struct quic_handshake *crypto_data;
-  ngtcp2_crypto_level level = quic_from_ossl_level(ossl_level);
   int rv;
 
   crypto_data = &qs->crypto_data[level];
@@ -216,6 +261,42 @@ static int quic_add_handshake_data(SSL *ssl, 
OSSL_ENCRYPTION_LEVEL ossl_level,
   return 1;
 }
 
+#ifdef USE_OPENSSL
+static int quic_set_encryption_secrets(SSL *ssl,
+                                       OSSL_ENCRYPTION_LEVEL ossl_level,
+                                       const uint8_t *rx_secret,
+                                       const uint8_t *tx_secret,
+                                       size_t secretlen)
+{
+  struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
+  int level = quic_from_ossl_level(ossl_level);
+
+  if(level != NGTCP2_CRYPTO_LEVEL_EARLY &&
+     ngtcp2_crypto_derive_and_install_rx_key(
+         qs->qconn, ssl, NULL, NULL, NULL, level, rx_secret, secretlen) != 0)
+    return 0;
+
+  if(ngtcp2_crypto_derive_and_install_tx_key(
+         qs->qconn, ssl, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
+    return 0;
+
+  if(level == NGTCP2_CRYPTO_LEVEL_APP) {
+    if(init_ngh3_conn(qs) != CURLE_OK)
+      return 0;
+  }
+
+  return 1;
+}
+
+static int quic_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
+                                   const uint8_t *data, size_t len)
+{
+  struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
+  ngtcp2_crypto_level level = quic_from_ossl_level(ossl_level);
+
+  return write_client_handshake(qs, level, data, len);
+}
+
 static int quic_flush_flight(SSL *ssl)
 {
   (void)ssl;
@@ -303,6 +384,193 @@ static int quic_init_ssl(struct quicsocket *qs)
   SSL_set_tlsext_host_name(qs->ssl, hostname);
   return 0;
 }
+#elif defined(USE_GNUTLS)
+static int secret_func(gnutls_session_t ssl,
+                       gnutls_record_encryption_level_t gtls_level,
+                       const void *rx_secret,
+                       const void *tx_secret, size_t secretlen)
+{
+  struct quicsocket *qs = gnutls_session_get_ptr(ssl);
+  int level = quic_from_gtls_level(gtls_level);
+
+  if(level != NGTCP2_CRYPTO_LEVEL_EARLY &&
+     ngtcp2_crypto_derive_and_install_rx_key(
+         qs->qconn, ssl, NULL, NULL, NULL, level, rx_secret, secretlen) != 0)
+    return 0;
+
+  if(ngtcp2_crypto_derive_and_install_tx_key(
+         qs->qconn, ssl, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
+    return 0;
+
+  if(level == NGTCP2_CRYPTO_LEVEL_APP) {
+    if(init_ngh3_conn(qs) != CURLE_OK)
+      return -1;
+  }
+
+  return 0;
+}
+
+static int read_func(gnutls_session_t ssl,
+                     gnutls_record_encryption_level_t gtls_level,
+                     gnutls_handshake_description_t htype, const void *data,
+                     size_t len)
+{
+  struct quicsocket *qs = gnutls_session_get_ptr(ssl);
+  ngtcp2_crypto_level level = quic_from_gtls_level(gtls_level);
+  int rv;
+
+  if(htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC)
+    return 0;
+
+  rv = write_client_handshake(qs, level, data, len);
+  if(rv == 0)
+    return -1;
+
+  return 0;
+}
+
+static int alert_read_func(gnutls_session_t ssl,
+                           gnutls_record_encryption_level_t gtls_level,
+                           gnutls_alert_level_t alert_level,
+                           gnutls_alert_description_t alert_desc)
+{
+  struct quicsocket *qs = gnutls_session_get_ptr(ssl);
+  (void)gtls_level;
+  (void)alert_level;
+
+  qs->tls_alert = alert_desc;
+  return 1;
+}
+
+static int tp_recv_func(gnutls_session_t ssl, const uint8_t *data,
+                        size_t data_size)
+{
+  struct quicsocket *qs = gnutls_session_get_ptr(ssl);
+  ngtcp2_transport_params params;
+
+  if(ngtcp2_decode_transport_params(
+         &params, NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS,
+         data, data_size) != 0)
+    return -1;
+
+  if(ngtcp2_conn_set_remote_transport_params(qs->qconn, &params) != 0)
+    return -1;
+
+  return 0;
+}
+
+static int tp_send_func(gnutls_session_t ssl, gnutls_buffer_t extdata)
+{
+  struct quicsocket *qs = gnutls_session_get_ptr(ssl);
+  uint8_t paramsbuf[64];
+  ngtcp2_transport_params params;
+  ssize_t nwrite;
+  int rc;
+
+  ngtcp2_conn_get_local_transport_params(qs->qconn, &params);
+  nwrite = ngtcp2_encode_transport_params(
+    paramsbuf, sizeof(paramsbuf), NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO,
+    &params);
+  if(nwrite < 0) {
+    fprintf(stderr, "ngtcp2_encode_transport_params: %s\n",
+          ngtcp2_strerror((int)nwrite));
+    return -1;
+  }
+
+  rc = gnutls_buffer_append_data(extdata, paramsbuf, nwrite);
+  if(rc < 0)
+    return rc;
+
+  return (int)nwrite;
+}
+
+static int quic_init_ssl(struct quicsocket *qs)
+{
+  gnutls_datum_t alpn = {NULL, 0};
+  /* this will need some attention when HTTPS proxy over QUIC get fixed */
+  const char * const hostname = qs->conn->host.name;
+  const char *keylog_filename;
+  int rc;
+
+  if(qs->ssl)
+    gnutls_deinit(qs->ssl);
+
+  gnutls_init(&qs->ssl, GNUTLS_CLIENT);
+  gnutls_session_set_ptr(qs->ssl, qs);
+
+  rc = gnutls_priority_set_direct(qs->ssl, QUIC_PRIORITY, NULL);
+  if(rc < 0) {
+    fprintf(stderr, "gnutls_priority_set_direct failed: %s\n",
+            gnutls_strerror(rc));
+    return 1;
+  }
+
+  gnutls_handshake_set_secret_function(qs->ssl, secret_func);
+  gnutls_handshake_set_read_function(qs->ssl, read_func);
+  gnutls_alert_set_read_function(qs->ssl, alert_read_func);
+
+  rc = gnutls_session_ext_register(qs->ssl, "QUIC Transport Parameters",
+                                   0xffa5, GNUTLS_EXT_TLS,
+                                   tp_recv_func, tp_send_func,
+                                   NULL, NULL, NULL,
+                                   GNUTLS_EXT_FLAG_TLS |
+                                   GNUTLS_EXT_FLAG_CLIENT_HELLO |
+                                   GNUTLS_EXT_FLAG_EE);
+  if(rc < 0) {
+    fprintf(stderr, "gnutls_session_ext_register failed: %s\n",
+            gnutls_strerror(rc));
+    return 1;
+  }
+
+  keylog_filename = getenv("SSLKEYLOGFILE");
+  if(keylog_filename) {
+    keylog_file = fopen(keylog_filename, "wb");
+    if(keylog_file) {
+      gnutls_session_set_keylog_function(qs->ssl, keylog_callback);
+    }
+  }
+
+  if(qs->cred)
+    gnutls_certificate_free_credentials(qs->cred);
+
+  rc = gnutls_certificate_allocate_credentials(&qs->cred);
+  if(rc < 0) {
+    fprintf(stderr, "gnutls_certificate_allocate_credentials failed: %s\n",
+            gnutls_strerror(rc));
+    return 1;
+  }
+
+  rc = gnutls_certificate_set_x509_system_trust(qs->cred);
+  if(rc < 0) {
+    fprintf(stderr, "gnutls_certificate_set_x509_system_trust failed: %s\n",
+            gnutls_strerror(rc));
+    return 1;
+  }
+
+  rc = gnutls_credentials_set(qs->ssl, GNUTLS_CRD_CERTIFICATE, qs->cred);
+  if(rc < 0) {
+    fprintf(stderr, "gnutls_credentials_set failed: %s\n",
+            gnutls_strerror(rc));
+    return 1;
+  }
+
+  switch(qs->version) {
+#ifdef NGTCP2_PROTO_VER
+  case NGTCP2_PROTO_VER:
+    /* strip the first byte from NGTCP2_ALPN_H3 */
+    alpn.data = (unsigned char *)NGTCP2_ALPN_H3 + 1;
+    alpn.size = sizeof(NGTCP2_ALPN_H3) - 2;
+    break;
+#endif
+  }
+  if(alpn.data)
+    gnutls_alpn_set_protocols(qs->ssl, &alpn, 1, 0);
+
+  /* set SNI */
+  gnutls_server_name_set(qs->ssl, GNUTLS_NAME_DNS, hostname, strlen(hostname));
+  return 0;
+}
+#endif
 
 static int cb_initial(ngtcp2_conn *quic, void *user_data)
 {
@@ -556,9 +824,11 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
   struct quicsocket *qs = &conn->hequic[sockindex];
   char ipbuf[40];
   long port;
+#ifdef USE_OPENSSL
   uint8_t paramsbuf[64];
   ngtcp2_transport_params params;
   ssize_t nwrite;
+#endif
 
   qs->conn = conn;
 
@@ -574,9 +844,11 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
         sockfd, ipbuf, port);
 
   qs->version = NGTCP2_PROTO_VER;
+#ifdef USE_OPENSSL
   qs->sslctx = quic_ssl_ctx(data);
   if(!qs->sslctx)
     return CURLE_QUIC_CONNECT_ERROR;
+#endif
 
   if(quic_init_ssl(qs))
     return CURLE_QUIC_CONNECT_ERROR;
@@ -613,6 +885,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
   if(rc)
     return CURLE_QUIC_CONNECT_ERROR;
 
+#ifdef USE_OPENSSL
   ngtcp2_conn_get_local_transport_params(qs->qconn, &params);
   nwrite = ngtcp2_encode_transport_params(
     paramsbuf, sizeof(paramsbuf), NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO,
@@ -625,6 +898,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
 
   if(!SSL_set_quic_transport_params(qs->ssl, paramsbuf, nwrite))
     return CURLE_QUIC_CONNECT_ERROR;
+#endif
 
   rc = setup_initial_crypto_context(qs);
   if(rc)
@@ -676,12 +950,22 @@ static CURLcode ng_disconnect(struct connectdata *conn,
   struct quicsocket *qs = &conn->hequic[0];
   (void)dead_connection;
   if(qs->ssl)
+#ifdef USE_OPENSSL
     SSL_free(qs->ssl);
+#elif defined(USE_GNUTLS)
+    gnutls_deinit(qs->ssl);
+#endif
+#ifdef USE_GNUTLS
+  if(qs->cred)
+    gnutls_certificate_free_credentials(qs->cred);
+#endif
   for(i = 0; i < 3; i++)
     free(qs->crypto_data[i].buf);
   nghttp3_conn_del(qs->h3conn);
   ngtcp2_conn_del(qs->qconn);
+#ifdef USE_OPENSSL
   SSL_CTX_free(qs->sslctx);
+#endif
   return CURLE_OK;
 }
 
diff --git a/lib/vquic/ngtcp2.h b/lib/vquic/ngtcp2.h
index 30d442fdd..06337f6f9 100644
--- a/lib/vquic/ngtcp2.h
+++ b/lib/vquic/ngtcp2.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -28,7 +28,11 @@
 
 #include <ngtcp2/ngtcp2.h>
 #include <nghttp3/nghttp3.h>
+#ifdef USE_OPENSSL
 #include <openssl/ssl.h>
+#elif defined(USE_GNUTLS)
+#include <gnutls/gnutls.h>
+#endif
 
 struct quic_handshake {
   char *buf;       /* pointer to the buffer */
@@ -44,8 +48,13 @@ struct quicsocket {
   ngtcp2_cid scid;
   uint32_t version;
   ngtcp2_settings settings;
+#ifdef USE_OPENSSL
   SSL_CTX *sslctx;
   SSL *ssl;
+#elif defined(USE_GNUTLS)
+  gnutls_certificate_credentials_t cred;
+  gnutls_session_t ssl;
+#endif
   struct quic_handshake crypto_data[3];
   /* the last TLS alert description generated by the local endpoint */
   uint8_t tls_alert;
diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c
index 5717d12fa..434904ff9 100644
--- a/lib/vssh/libssh.c
+++ b/lib/vssh/libssh.c
@@ -403,6 +403,9 @@ static int myssh_is_known(struct connectdata *conn)
           knownkey.keytype = CURLKHTYPE_RSA1;
           break;
         case SSH_KEYTYPE_ECDSA:
+        case SSH_KEYTYPE_ECDSA_P256:
+        case SSH_KEYTYPE_ECDSA_P384:
+        case SSH_KEYTYPE_ECDSA_P521:
           knownkey.keytype = CURLKHTYPE_ECDSA;
           break;
         case SSH_KEYTYPE_ED25519:
@@ -470,6 +473,11 @@ static int myssh_is_known(struct connectdata *conn)
         foundkey.keytype = CURLKHTYPE_RSA1;
         break;
       case SSH_KEYTYPE_ECDSA:
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
+      case SSH_KEYTYPE_ECDSA_P256:
+      case SSH_KEYTYPE_ECDSA_P384:
+      case SSH_KEYTYPE_ECDSA_P521:
+#endif
         foundkey.keytype = CURLKHTYPE_ECDSA;
         break;
 #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,7,0)
@@ -2141,6 +2149,7 @@ static CURLcode myssh_connect(struct connectdata *conn, 
bool *done)
   CURLcode result;
   curl_socket_t sock = conn->sock[FIRSTSOCKET];
   struct Curl_easy *data = conn->data;
+  int rc;
 
   /* initialize per-handle data if not already */
   if(!data->req.protop)
@@ -2167,38 +2176,70 @@ static CURLcode myssh_connect(struct connectdata *conn, 
bool *done)
     return CURLE_FAILED_INIT;
   }
 
-  ssh_options_set(ssh->ssh_session, SSH_OPTIONS_FD, &sock);
+  rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, conn->host.name);
+  if(rc != SSH_OK) {
+    failf(data, "Could not set remote host");
+    return CURLE_FAILED_INIT;
+  }
+
+  rc = ssh_options_parse_config(ssh->ssh_session, NULL);
+  if(rc != SSH_OK) {
+    infof(data, "Could not parse SSH configuration files");
+    /* ignore */
+  }
+
+  rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_FD, &sock);
+  if(rc != SSH_OK) {
+    failf(data, "Could not set socket");
+    return CURLE_FAILED_INIT;
+  }
 
-  if(conn->user) {
+  if(conn->user && conn->user[0] != '\0') {
     infof(data, "User: %s\n", conn->user);
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user);
+    rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user);
+    if(rc != SSH_OK) {
+      failf(data, "Could not set user");
+      return CURLE_FAILED_INIT;
+    }
   }
 
   if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
     infof(data, "Known hosts: %s\n", data->set.str[STRING_SSH_KNOWNHOSTS]);
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_KNOWNHOSTS,
-                    data->set.str[STRING_SSH_KNOWNHOSTS]);
+    rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_KNOWNHOSTS,
+                         data->set.str[STRING_SSH_KNOWNHOSTS]);
+    if(rc != SSH_OK) {
+      failf(data, "Could not set known hosts file path");
+      return CURLE_FAILED_INIT;
+    }
   }
 
-  ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, conn->host.name);
-  if(conn->remote_port)
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_PORT,
-                    &conn->remote_port);
+  if(conn->remote_port) {
+    rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_PORT,
+                         &conn->remote_port);
+    if(rc != SSH_OK) {
+      failf(data, "Could not set remote port");
+      return CURLE_FAILED_INIT;
+    }
+  }
 
   if(data->set.ssh_compression) {
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_COMPRESSION,
-                    "zlib,address@hidden,none");
+    rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_COMPRESSION,
+                         "zlib,address@hidden,none");
+    if(rc != SSH_OK) {
+      failf(data, "Could not set compression");
+      return CURLE_FAILED_INIT;
+    }
   }
 
   ssh->privkey = NULL;
   ssh->pubkey = NULL;
 
   if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
-    int rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY],
-                                        &ssh->pubkey);
+    rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY],
+                                    &ssh->pubkey);
     if(rc != SSH_OK) {
       failf(data, "Could not load public key file");
-      /* ignore */
+      return CURLE_FAILED_INIT;
     }
   }
 
diff --git a/lib/vtls/bearssl.c b/lib/vtls/bearssl.c
index 67f945831..1a6530c81 100644
--- a/lib/vtls/bearssl.c
+++ b/lib/vtls/bearssl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2019, Michael Forney, <address@hidden>
+ * Copyright (C) 2019 - 2020, Michael Forney, <address@hidden>
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -56,8 +56,6 @@ struct ssl_backend_data {
   size_t pending_write;
 };
 
-#define BACKEND connssl->backend
-
 struct cafile_parser {
   CURLcode err;
   bool in_cert;
@@ -300,6 +298,7 @@ static CURLcode bearssl_connect_step1(struct connectdata 
*conn, int sockindex)
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
   const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
@@ -343,7 +342,7 @@ static CURLcode bearssl_connect_step1(struct connectdata 
*conn, int sockindex)
   }
 
   if(ssl_cafile) {
-    ret = load_cafile(ssl_cafile, &BACKEND->anchors, &BACKEND->anchors_len);
+    ret = load_cafile(ssl_cafile, &backend->anchors, &backend->anchors_len);
     if(ret != CURLE_OK) {
       if(verifypeer) {
         failf(data, "error setting certificate verify locations:\n"
@@ -356,24 +355,24 @@ static CURLcode bearssl_connect_step1(struct connectdata 
*conn, int sockindex)
   }
 
   /* initialize SSL context */
-  br_ssl_client_init_full(&BACKEND->ctx, &BACKEND->x509.minimal,
-                          BACKEND->anchors, BACKEND->anchors_len);
-  br_ssl_engine_set_versions(&BACKEND->ctx.eng, version_min, version_max);
-  br_ssl_engine_set_buffer(&BACKEND->ctx.eng, BACKEND->buf,
-                           sizeof(BACKEND->buf), 1);
+  br_ssl_client_init_full(&backend->ctx, &backend->x509.minimal,
+                          backend->anchors, backend->anchors_len);
+  br_ssl_engine_set_versions(&backend->ctx.eng, version_min, version_max);
+  br_ssl_engine_set_buffer(&backend->ctx.eng, backend->buf,
+                           sizeof(backend->buf), 1);
 
   /* initialize X.509 context */
-  BACKEND->x509.vtable = &x509_vtable;
-  BACKEND->x509.verifypeer = verifypeer;
-  BACKEND->x509.verifyhost = verifyhost;
-  br_ssl_engine_set_x509(&BACKEND->ctx.eng, &BACKEND->x509.vtable);
+  backend->x509.vtable = &x509_vtable;
+  backend->x509.verifypeer = verifypeer;
+  backend->x509.verifyhost = verifyhost;
+  br_ssl_engine_set_x509(&backend->ctx.eng, &backend->x509.vtable);
 
   if(SSL_SET_OPTION(primary.sessionid)) {
     void *session;
 
     Curl_ssl_sessionid_lock(conn);
     if(!Curl_ssl_getsessionid(conn, &session, NULL, sockindex)) {
-      br_ssl_engine_set_session_parameters(&BACKEND->ctx.eng, session);
+      br_ssl_engine_set_session_parameters(&backend->ctx.eng, session);
       infof(data, "BearSSL: re-using session ID\n");
     }
     Curl_ssl_sessionid_unlock(conn);
@@ -389,16 +388,16 @@ static CURLcode bearssl_connect_step1(struct connectdata 
*conn, int sockindex)
 #ifdef USE_NGHTTP2
     if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
        (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
-      BACKEND->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
+      backend->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
       infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
     }
 #endif
 
-    BACKEND->protocols[cur++] = ALPN_HTTP_1_1;
+    backend->protocols[cur++] = ALPN_HTTP_1_1;
     infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
 
-    br_ssl_engine_set_protocol_names(&BACKEND->ctx.eng,
-                                     BACKEND->protocols, cur);
+    br_ssl_engine_set_protocol_names(&backend->ctx.eng,
+                                     backend->protocols, cur);
   }
 
   if((1 == Curl_inet_pton(AF_INET, hostname, &addr))
@@ -414,9 +413,9 @@ static CURLcode bearssl_connect_step1(struct connectdata 
*conn, int sockindex)
     hostname = NULL;
   }
 
-  if(!br_ssl_client_reset(&BACKEND->ctx, hostname, 0))
+  if(!br_ssl_client_reset(&backend->ctx, hostname, 0))
     return CURLE_FAILED_INIT;
-  BACKEND->active = TRUE;
+  backend->active = TRUE;
 
   connssl->connecting_state = ssl_connect_2;
 
@@ -428,6 +427,7 @@ static CURLcode bearssl_run_until(struct connectdata *conn, 
int sockindex,
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   curl_socket_t sockfd = conn->sock[sockindex];
   unsigned state;
   unsigned char *buf;
@@ -436,9 +436,9 @@ static CURLcode bearssl_run_until(struct connectdata *conn, 
int sockindex,
   int err;
 
   for(;;) {
-    state = br_ssl_engine_current_state(&BACKEND->ctx.eng);
+    state = br_ssl_engine_current_state(&backend->ctx.eng);
     if(state & BR_SSL_CLOSED) {
-      err = br_ssl_engine_last_error(&BACKEND->ctx.eng);
+      err = br_ssl_engine_last_error(&backend->ctx.eng);
       switch(err) {
       case BR_ERR_OK:
         /* TLS close notify */
@@ -468,7 +468,7 @@ static CURLcode bearssl_run_until(struct connectdata *conn, 
int sockindex,
     if(state & target)
       return CURLE_OK;
     if(state & BR_SSL_SENDREC) {
-      buf = br_ssl_engine_sendrec_buf(&BACKEND->ctx.eng, &len);
+      buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len);
       ret = swrite(sockfd, buf, len);
       if(ret == -1) {
         if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
@@ -478,10 +478,10 @@ static CURLcode bearssl_run_until(struct connectdata 
*conn, int sockindex,
         }
         return CURLE_WRITE_ERROR;
       }
-      br_ssl_engine_sendrec_ack(&BACKEND->ctx.eng, ret);
+      br_ssl_engine_sendrec_ack(&backend->ctx.eng, ret);
     }
     else if(state & BR_SSL_RECVREC) {
-      buf = br_ssl_engine_recvrec_buf(&BACKEND->ctx.eng, &len);
+      buf = br_ssl_engine_recvrec_buf(&backend->ctx.eng, &len);
       ret = sread(sockfd, buf, len);
       if(ret == 0) {
         failf(data, "SSL: EOF without close notify");
@@ -495,7 +495,7 @@ static CURLcode bearssl_run_until(struct connectdata *conn, 
int sockindex,
         }
         return CURLE_READ_ERROR;
       }
-      br_ssl_engine_recvrec_ack(&BACKEND->ctx.eng, ret);
+      br_ssl_engine_recvrec_ack(&backend->ctx.eng, ret);
     }
   }
 }
@@ -504,13 +504,14 @@ static CURLcode bearssl_connect_step2(struct connectdata 
*conn, int sockindex)
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   CURLcode ret;
 
   ret = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP | BR_SSL_RECVAPP);
   if(ret == CURLE_AGAIN)
     return CURLE_OK;
   if(ret == CURLE_OK) {
-    if(br_ssl_engine_current_state(&BACKEND->ctx.eng) == BR_SSL_CLOSED) {
+    if(br_ssl_engine_current_state(&backend->ctx.eng) == BR_SSL_CLOSED) {
       failf(data, "SSL: connection closed during handshake");
       return CURLE_SSL_CONNECT_ERROR;
     }
@@ -523,6 +524,7 @@ static CURLcode bearssl_connect_step3(struct connectdata 
*conn, int sockindex)
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   CURLcode ret;
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
@@ -530,7 +532,7 @@ static CURLcode bearssl_connect_step3(struct connectdata 
*conn, int sockindex)
   if(conn->bits.tls_enable_alpn) {
     const char *protocol;
 
-    protocol = br_ssl_engine_get_selected_protocol(&BACKEND->ctx.eng);
+    protocol = br_ssl_engine_get_selected_protocol(&backend->ctx.eng);
     if(protocol) {
       infof(data, "ALPN, server accepted to use %s\n", protocol);
 
@@ -558,7 +560,7 @@ static CURLcode bearssl_connect_step3(struct connectdata 
*conn, int sockindex)
     session = malloc(sizeof(*session));
     if(!session)
       return CURLE_OUT_OF_MEMORY;
-    br_ssl_engine_get_session_parameters(&BACKEND->ctx.eng, session);
+    br_ssl_engine_get_session_parameters(&backend->ctx.eng, session);
     Curl_ssl_sessionid_lock(conn);
     incache = !(Curl_ssl_getsessionid(conn, &oldsession, NULL, sockindex));
     if(incache)
@@ -581,6 +583,7 @@ static ssize_t bearssl_send(struct connectdata *conn, int 
sockindex,
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   unsigned char *app;
   size_t applen;
 
@@ -588,23 +591,23 @@ static ssize_t bearssl_send(struct connectdata *conn, int 
sockindex,
     *err = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP);
     if (*err != CURLE_OK)
       return -1;
-    app = br_ssl_engine_sendapp_buf(&BACKEND->ctx.eng, &applen);
+    app = br_ssl_engine_sendapp_buf(&backend->ctx.eng, &applen);
     if(!app) {
       failf(data, "SSL: connection closed during write");
       *err = CURLE_SEND_ERROR;
       return -1;
     }
-    if(BACKEND->pending_write) {
-      applen = BACKEND->pending_write;
-      BACKEND->pending_write = 0;
+    if(backend->pending_write) {
+      applen = backend->pending_write;
+      backend->pending_write = 0;
       return applen;
     }
     if(applen > len)
       applen = len;
     memcpy(app, buf, applen);
-    br_ssl_engine_sendapp_ack(&BACKEND->ctx.eng, applen);
-    br_ssl_engine_flush(&BACKEND->ctx.eng, 0);
-    BACKEND->pending_write = applen;
+    br_ssl_engine_sendapp_ack(&backend->ctx.eng, applen);
+    br_ssl_engine_flush(&backend->ctx.eng, 0);
+    backend->pending_write = applen;
   }
 }
 
@@ -612,19 +615,20 @@ static ssize_t bearssl_recv(struct connectdata *conn, int 
sockindex,
                             char *buf, size_t len, CURLcode *err)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   unsigned char *app;
   size_t applen;
 
   *err = bearssl_run_until(conn, sockindex, BR_SSL_RECVAPP);
   if(*err != CURLE_OK)
     return -1;
-  app = br_ssl_engine_recvapp_buf(&BACKEND->ctx.eng, &applen);
+  app = br_ssl_engine_recvapp_buf(&backend->ctx.eng, &applen);
   if(!app)
     return 0;
   if(applen > len)
     applen = len;
   memcpy(buf, app, applen);
-  br_ssl_engine_recvapp_ack(&BACKEND->ctx.eng, applen);
+  br_ssl_engine_recvapp_ack(&backend->ctx.eng, applen);
 
   return applen;
 }
@@ -739,8 +743,8 @@ static bool Curl_bearssl_data_pending(const struct 
connectdata *conn,
                                       int connindex)
 {
   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
-
-  return br_ssl_engine_current_state(&BACKEND->ctx.eng) & BR_SSL_RECVAPP;
+  struct ssl_backend_data *backend = connssl->backend;
+  return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP;
 }
 
 static CURLcode Curl_bearssl_random(struct Curl_easy *data UNUSED_PARAM,
@@ -786,21 +790,23 @@ static CURLcode Curl_bearssl_connect_nonblocking(struct 
connectdata *conn,
 static void *Curl_bearssl_get_internals(struct ssl_connect_data *connssl,
                                         CURLINFO info UNUSED_PARAM)
 {
-  return &BACKEND->ctx;
+  struct ssl_backend_data *backend = connssl->backend;
+  return &backend->ctx;
 }
 
 static void Curl_bearssl_close(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   size_t i;
 
-  if(BACKEND->active) {
-    br_ssl_engine_close(&BACKEND->ctx.eng);
+  if(backend->active) {
+    br_ssl_engine_close(&backend->ctx.eng);
     (void)bearssl_run_until(conn, sockindex, BR_SSL_CLOSED);
   }
-  for(i = 0; i < BACKEND->anchors_len; ++i)
-    free(BACKEND->anchors[i].dn.data);
-  free(BACKEND->anchors);
+  for(i = 0; i < backend->anchors_len; ++i)
+    free(backend->anchors[i].dn.data);
+  free(backend->anchors);
 }
 
 static void Curl_bearssl_session_free(void *ptr)
@@ -836,9 +842,7 @@ static CURLcode Curl_bearssl_sha256sum(const unsigned char 
*input,
 
 const struct Curl_ssl Curl_ssl_bearssl = {
   { CURLSSLBACKEND_BEARSSL, "bearssl" },
-
   0,
-
   sizeof(struct ssl_backend_data),
 
   Curl_none_init,
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
index c1b3a2653..96db9364d 100644
--- a/lib/vtls/gskit.c
+++ b/lib/vtls/gskit.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -524,7 +524,6 @@ static int pipe_ssloverssl(struct connectdata *conn, int 
sockindex,
   int m;
   int i;
   int ret = 0;
-  struct timeval tv = {0, 0};
   char buf[CURL_MAX_WRITE_SIZE];
 
   if(!connssl->use || !connproxyssl->use)
@@ -544,7 +543,7 @@ static int pipe_ssloverssl(struct connectdata *conn, int 
sockindex,
     if(n < conn->sock[sockindex])
       n = conn->sock[sockindex];
   }
-  i = select(n + 1, &fds_read, &fds_write, NULL, &tv);
+  i = Curl_select(n + 1, &fds_read, &fds_write, NULL, 0);
   if(i < 0)
     return -1;  /* Select error. */
 
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 5f740eeba..4ed3ea5cf 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -72,36 +72,11 @@ static void tls_log_func(int level, const char *str)
 #endif
 static bool gtls_inited = FALSE;
 
-#if defined(GNUTLS_VERSION_NUMBER)
-#  if (GNUTLS_VERSION_NUMBER >= 0x020c00)
-#    undef gnutls_transport_set_lowat
-#    define gnutls_transport_set_lowat(A,B) Curl_nop_stmt
-#    define USE_GNUTLS_PRIORITY_SET_DIRECT 1
-#  endif
-#  if (GNUTLS_VERSION_NUMBER >= 0x020c03)
-#    define GNUTLS_MAPS_WINSOCK_ERRORS 1
-#  endif
-
-#  if HAVE_GNUTLS_ALPN_SET_PROTOCOLS
-#    define HAS_ALPN
-#  endif
-
-#  if HAVE_GNUTLS_OCSP_REQ_INIT
-#    define HAS_OCSP
-#  endif
-
-#  if (GNUTLS_VERSION_NUMBER >= 0x030306)
-#    define HAS_CAPATH
-#  endif
+#if !defined(GNUTLS_VERSION_NUMBER) || (GNUTLS_VERSION_NUMBER < 0x03010a)
+#error "too old GnuTLS version"
 #endif
 
-#if (GNUTLS_VERSION_NUMBER >= 0x030603)
-#define HAS_TLS13
-#endif
-
-#ifdef HAS_OCSP
 # include <gnutls/ocsp.h>
-#endif
 
 struct ssl_backend_data {
   gnutls_session_t session;
@@ -111,58 +86,10 @@ struct ssl_backend_data {
 #endif
 };
 
-#define BACKEND connssl->backend
-
-/*
- * Custom push and pull callback functions used by GNU TLS to read and write
- * to the socket.  These functions are simple wrappers to send() and recv()
- * (although here using the sread/swrite macros as defined by
- * curl_setup_once.h).
- * We use custom functions rather than the GNU TLS defaults because it allows
- * us to get specific about the fourth "flags" argument, and to use arbitrary
- * private data with gnutls_transport_set_ptr if we wish.
- *
- * When these custom push and pull callbacks fail, GNU TLS checks its own
- * session-specific error variable, and when not set also its own global
- * errno variable, in order to take appropriate action. GNU TLS does not
- * require that the transport is actually a socket. This implies that for
- * Windows builds these callbacks should ideally set the session-specific
- * error variable using function gnutls_transport_set_errno or as a last
- * resort global errno variable using gnutls_transport_set_global_errno,
- * with a transport agnostic error value. This implies that some winsock
- * error translation must take place in these callbacks.
- *
- * Paragraph above applies to GNU TLS versions older than 2.12.3, since
- * this version GNU TLS does its own internal winsock error translation
- * using system_errno() function.
- */
-
-#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
-#  define gtls_EINTR  4
-#  define gtls_EIO    5
-#  define gtls_EAGAIN 11
-static int gtls_mapped_sockerrno(void)
-{
-  switch(SOCKERRNO) {
-  case WSAEWOULDBLOCK:
-    return gtls_EAGAIN;
-  case WSAEINTR:
-    return gtls_EINTR;
-  default:
-    break;
-  }
-  return gtls_EIO;
-}
-#endif
-
 static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
 {
   curl_socket_t sock = *(curl_socket_t *)s;
   ssize_t ret = swrite(sock, buf, len);
-#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
-  if(ret < 0)
-    gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
-#endif
   return ret;
 }
 
@@ -170,10 +97,6 @@ static ssize_t Curl_gtls_pull(void *s, void *buf, size_t 
len)
 {
   curl_socket_t sock = *(curl_socket_t *)s;
   ssize_t ret = sread(sock, buf, len);
-#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
-  if(ret < 0)
-    gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
-#endif
   return ret;
 }
 
@@ -284,7 +207,8 @@ static CURLcode handshake(struct connectdata *conn,
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  gnutls_session_t session = BACKEND->session;
+  struct ssl_backend_data *backend = connssl->backend;
+  gnutls_session_t session = backend->session;
   curl_socket_t sockfd = conn->sock[sockindex];
 
   for(;;) {
@@ -383,51 +307,6 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type)
   return -1;
 }
 
-#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
-static CURLcode
-set_ssl_version_min_max(int *list, size_t list_size, struct connectdata *conn)
-{
-  struct Curl_easy *data = conn->data;
-  long ssl_version = SSL_CONN_CONFIG(version);
-  long ssl_version_max = SSL_CONN_CONFIG(version_max);
-  long i = ssl_version;
-  long protocol_priority_idx = 0;
-
-  switch(ssl_version_max) {
-    case CURL_SSLVERSION_MAX_NONE:
-    case CURL_SSLVERSION_MAX_DEFAULT:
-#ifdef HAS_TLS13
-      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3;
-#endif
-      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
-      break;
-  }
-
-  for(; i <= (ssl_version_max >> 16) &&
-        protocol_priority_idx < list_size; ++i) {
-    switch(i) {
-      case CURL_SSLVERSION_TLSv1_0:
-        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_0;
-        break;
-      case CURL_SSLVERSION_TLSv1_1:
-        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_1;
-        break;
-      case CURL_SSLVERSION_TLSv1_2:
-        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_2;
-        break;
-      case CURL_SSLVERSION_TLSv1_3:
-#ifdef HAS_TLS13
-        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_3;
-        break;
-#else
-        failf(data, "GnuTLS: TLS 1.3 is not yet supported");
-        return CURLE_SSL_CONNECT_ERROR;
-#endif
-    }
-  }
-  return CURLE_OK;
-}
-#else
 #define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
 /* If GnuTLS was compiled without support for SRP it will error out if SRP is
    requested in the priority string, so treat it specially
@@ -445,77 +324,59 @@ set_ssl_version_min_max(const char **prioritylist, struct 
connectdata *conn)
     ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT;
   }
   switch(ssl_version | ssl_version_max) {
-    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.0:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.0:+VERS-TLS1.1:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.1:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.2:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_TLSv1_3:
-#ifdef HAS_TLS13
-       *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                       "+VERS-TLS1.3:" GNUTLS_SRP;
-      return CURLE_OK;
-#else
-       failf(data, "GnuTLS: TLS 1.3 is not yet supported");
-      return CURLE_SSL_CONNECT_ERROR;
-#endif
-    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:"
-#ifdef HAS_TLS13
-                      "+VERS-TLS1.3:"
-#endif
-                      GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.1:+VERS-TLS1.2:"
-#ifdef HAS_TLS13
-                      "+VERS-TLS1.3:"
-#endif
-                      GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.2:"
-#ifdef HAS_TLS13
-                      "+VERS-TLS1.3:"
-#endif
-                      GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_DEFAULT:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.2:"
-#ifdef HAS_TLS13
-                      "+VERS-TLS1.3:"
-#endif
-                      GNUTLS_SRP;
-      return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.0";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.0:+VERS-TLS1.1";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.1";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.1:+VERS-TLS1.2";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.2";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_TLSv1_3:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.3";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2"
+      ":+VERS-TLS1.3";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.1:+VERS-TLS1.2"
+      ":+VERS-TLS1.3";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.2"
+      ":+VERS-TLS1.3";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_DEFAULT:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.2"
+      ":+VERS-TLS1.3";
+    return CURLE_OK;
   }
 
   failf(data, "GnuTLS: cannot set ssl protocol");
   return CURLE_SSL_CONNECT_ERROR;
 }
-#endif
 
 static CURLcode
 gtls_connect_step1(struct connectdata *conn,
@@ -523,6 +384,7 @@ gtls_connect_step1(struct connectdata *conn,
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   unsigned int init_flags;
   gnutls_session_t session;
   int rc;
@@ -535,26 +397,8 @@ gtls_connect_step1(struct connectdata *conn,
 #else
   struct in_addr addr;
 #endif
-#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
-  static const int cipher_priority[] = {
-  /* These two ciphers were added to GnuTLS as late as ver. 3.0.1,
-     but this code path is only ever used for ver. < 2.12.0.
-     GNUTLS_CIPHER_AES_128_GCM,
-     GNUTLS_CIPHER_AES_256_GCM,
-  */
-    GNUTLS_CIPHER_AES_128_CBC,
-    GNUTLS_CIPHER_AES_256_CBC,
-    GNUTLS_CIPHER_CAMELLIA_128_CBC,
-    GNUTLS_CIPHER_CAMELLIA_256_CBC,
-    GNUTLS_CIPHER_3DES_CBC,
-  };
-  static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
-  int protocol_priority[] = { 0, 0, 0, 0 };
-#else
   const char *prioritylist;
   const char *err = NULL;
-#endif
-
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
 
@@ -574,7 +418,7 @@ gtls_connect_step1(struct connectdata *conn,
     sni = FALSE; /* SSLv3 has no SNI */
 
   /* allocate a cred struct */
-  rc = gnutls_certificate_allocate_credentials(&BACKEND->cred);
+  rc = gnutls_certificate_allocate_credentials(&backend->cred);
   if(rc != GNUTLS_E_SUCCESS) {
     failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
     return CURLE_SSL_CONNECT_ERROR;
@@ -585,14 +429,14 @@ gtls_connect_step1(struct connectdata *conn,
     infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username));
 
     rc = gnutls_srp_allocate_client_credentials(
-           &BACKEND->srp_client_cred);
+           &backend->srp_client_cred);
     if(rc != GNUTLS_E_SUCCESS) {
       failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
             gnutls_strerror(rc));
       return CURLE_OUT_OF_MEMORY;
     }
 
-    rc = gnutls_srp_set_client_credentials(BACKEND->srp_client_cred,
+    rc = gnutls_srp_set_client_credentials(backend->srp_client_cred,
                                            SSL_SET_OPTION(username),
                                            SSL_SET_OPTION(password));
     if(rc != GNUTLS_E_SUCCESS) {
@@ -605,10 +449,10 @@ gtls_connect_step1(struct connectdata *conn,
 
   if(SSL_CONN_CONFIG(CAfile)) {
     /* set the trusted CA cert bundle file */
-    gnutls_certificate_set_verify_flags(BACKEND->cred,
+    gnutls_certificate_set_verify_flags(backend->cred,
                                         GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
 
-    rc = gnutls_certificate_set_x509_trust_file(BACKEND->cred,
+    rc = gnutls_certificate_set_x509_trust_file(backend->cred,
                                                 SSL_CONN_CONFIG(CAfile),
                                                 GNUTLS_X509_FMT_PEM);
     if(rc < 0) {
@@ -622,10 +466,9 @@ gtls_connect_step1(struct connectdata *conn,
             SSL_CONN_CONFIG(CAfile));
   }
 
-#ifdef HAS_CAPATH
   if(SSL_CONN_CONFIG(CApath)) {
     /* set the trusted CA cert directory */
-    rc = gnutls_certificate_set_x509_trust_dir(BACKEND->cred,
+    rc = gnutls_certificate_set_x509_trust_dir(backend->cred,
                                                SSL_CONN_CONFIG(CApath),
                                                GNUTLS_X509_FMT_PEM);
     if(rc < 0) {
@@ -638,19 +481,18 @@ gtls_connect_step1(struct connectdata *conn,
       infof(data, "found %d certificates in %s\n",
             rc, SSL_CONN_CONFIG(CApath));
   }
-#endif
 
 #ifdef CURL_CA_FALLBACK
   /* use system ca certificate store as fallback */
   if(SSL_CONN_CONFIG(verifypeer) &&
      !(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) {
-    gnutls_certificate_set_x509_system_trust(BACKEND->cred);
+    gnutls_certificate_set_x509_system_trust(backend->cred);
   }
 #endif
 
   if(SSL_SET_OPTION(CRLfile)) {
     /* set the CRL list file */
-    rc = gnutls_certificate_set_x509_crl_file(BACKEND->cred,
+    rc = gnutls_certificate_set_x509_crl_file(backend->cred,
                                               SSL_SET_OPTION(CRLfile),
                                               GNUTLS_X509_FMT_PEM);
     if(rc < 0) {
@@ -675,14 +517,14 @@ gtls_connect_step1(struct connectdata *conn,
   init_flags |= GNUTLS_NO_TICKETS;
 #endif
 
-  rc = gnutls_init(&BACKEND->session, init_flags);
+  rc = gnutls_init(&backend->session, init_flags);
   if(rc != GNUTLS_E_SUCCESS) {
     failf(data, "gnutls_init() failed: %d", rc);
     return CURLE_SSL_CONNECT_ERROR;
   }
 
   /* convenient assign */
-  session = BACKEND->session;
+  session = backend->session;
 
   if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
 #ifdef ENABLE_IPV6
@@ -699,62 +541,6 @@ gtls_connect_step1(struct connectdata *conn,
   if(rc != GNUTLS_E_SUCCESS)
     return CURLE_SSL_CONNECT_ERROR;
 
-#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
-  rc = gnutls_cipher_set_priority(session, cipher_priority);
-  if(rc != GNUTLS_E_SUCCESS)
-    return CURLE_SSL_CONNECT_ERROR;
-
-  /* Sets the priority on the certificate types supported by gnutls. Priority
-   is higher for types specified before others. After specifying the types
-   you want, you must append a 0. */
-  rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
-  if(rc != GNUTLS_E_SUCCESS)
-    return CURLE_SSL_CONNECT_ERROR;
-
-  if(SSL_CONN_CONFIG(cipher_list) != NULL) {
-    failf(data, "can't pass a custom cipher list to older GnuTLS"
-          " versions");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  switch(SSL_CONN_CONFIG(version)) {
-    case CURL_SSLVERSION_SSLv3:
-      protocol_priority[0] = GNUTLS_SSL3;
-      break;
-    case CURL_SSLVERSION_DEFAULT:
-    case CURL_SSLVERSION_TLSv1:
-      protocol_priority[0] = GNUTLS_TLS1_0;
-      protocol_priority[1] = GNUTLS_TLS1_1;
-      protocol_priority[2] = GNUTLS_TLS1_2;
-#ifdef HAS_TLS13
-      protocol_priority[3] = GNUTLS_TLS1_3;
-#endif
-      break;
-    case CURL_SSLVERSION_TLSv1_0:
-    case CURL_SSLVERSION_TLSv1_1:
-    case CURL_SSLVERSION_TLSv1_2:
-    case CURL_SSLVERSION_TLSv1_3:
-      {
-        CURLcode result = set_ssl_version_min_max(protocol_priority,
-                sizeof(protocol_priority)/sizeof(protocol_priority[0]), conn);
-        if(result != CURLE_OK)
-          return result;
-        break;
-      }
-    case CURL_SSLVERSION_SSLv2:
-      failf(data, "GnuTLS does not support SSLv2");
-      return CURLE_SSL_CONNECT_ERROR;
-    default:
-      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
-      return CURLE_SSL_CONNECT_ERROR;
-  }
-  rc = gnutls_protocol_set_priority(session, protocol_priority);
-  if(rc != GNUTLS_E_SUCCESS) {
-    failf(data, "Did you pass a valid GnuTLS cipher list?");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-#else
   /* Ensure +SRP comes at the *end* of all relevant strings so that it can be
    * removed if a run-time error indicates that SRP is not supported by this
    * GnuTLS version */
@@ -764,11 +550,11 @@ gtls_connect_step1(struct connectdata *conn,
       break;
     case CURL_SSLVERSION_DEFAULT:
     case CURL_SSLVERSION_TLSv1:
-      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:"
+      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0"
 #ifdef HAS_TLS13
-                     "+VERS-TLS1.3:"
+                     ":+VERS-TLS1.3"
 #endif
-                     GNUTLS_SRP;
+                     ;
       break;
     case CURL_SSLVERSION_TLSv1_0:
     case CURL_SSLVERSION_TLSv1_1:
@@ -787,32 +573,39 @@ gtls_connect_step1(struct connectdata *conn,
       failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
       return CURLE_SSL_CONNECT_ERROR;
   }
-  rc = gnutls_priority_set_direct(session, prioritylist, &err);
-  if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
-    if(!strcmp(err, GNUTLS_SRP)) {
-      /* This GnuTLS was probably compiled without support for SRP.
-       * Note that fact and try again without it. */
-      int validprioritylen = curlx_uztosi(err - prioritylist);
-      char *prioritycopy = strdup(prioritylist);
-      if(!prioritycopy)
-        return CURLE_OUT_OF_MEMORY;
 
+#ifdef USE_TLS_SRP
+  /* Only add SRP to the cipher list if SRP is requested. Otherwise
+   * GnuTLS will disable TLS 1.3 support. */
+  if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
+    size_t len = strlen(prioritylist);
+
+    char *prioritysrp = malloc(len + sizeof(GNUTLS_SRP) + 1);
+    if(!prioritysrp)
+      return CURLE_OUT_OF_MEMORY;
+    strcpy(prioritysrp, prioritylist);
+    strcpy(prioritysrp + len, ":" GNUTLS_SRP);
+
+    rc = gnutls_priority_set_direct(session, prioritysrp, &err);
+    free(prioritysrp);
+
+    if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
       infof(data, "This GnuTLS does not support SRP\n");
-      if(validprioritylen)
-        /* Remove the :+SRP */
-        prioritycopy[validprioritylen - 1] = 0;
-      rc = gnutls_priority_set_direct(session, prioritycopy, &err);
-      free(prioritycopy);
     }
   }
+  else {
+#endif
+    rc = gnutls_priority_set_direct(session, prioritylist, &err);
+#ifdef USE_TLS_SRP
+  }
+#endif
+
   if(rc != GNUTLS_E_SUCCESS) {
     failf(data, "Error %d setting GnuTLS cipher list starting with %s",
           rc, err);
     return CURLE_SSL_CONNECT_ERROR;
   }
-#endif
 
-#ifdef HAS_ALPN
   if(conn->bits.tls_enable_alpn) {
     int cur = 0;
     gnutls_datum_t protocols[2];
@@ -834,18 +627,16 @@ gtls_connect_step1(struct connectdata *conn,
 
     gnutls_alpn_set_protocols(session, protocols, cur, 0);
   }
-#endif
 
   if(SSL_SET_OPTION(cert)) {
     if(SSL_SET_OPTION(key_passwd)) {
-#if HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2
       const unsigned int supported_key_encryption_algorithms =
         GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
         GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
         GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
         GNUTLS_PKCS_USE_PBES2_AES_256;
       rc = gnutls_certificate_set_x509_key_file2(
-           BACKEND->cred,
+           backend->cred,
            SSL_SET_OPTION(cert),
            SSL_SET_OPTION(key) ?
            SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
@@ -858,14 +649,10 @@ gtls_connect_step1(struct connectdata *conn,
               gnutls_strerror(rc));
         return CURLE_SSL_CONNECT_ERROR;
       }
-#else
-      failf(data, "gnutls lacks support for encrypted key files");
-      return CURLE_SSL_CONNECT_ERROR;
-#endif
     }
     else {
       if(gnutls_certificate_set_x509_key_file(
-           BACKEND->cred,
+           backend->cred,
            SSL_SET_OPTION(cert),
            SSL_SET_OPTION(key) ?
            SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
@@ -881,7 +668,7 @@ gtls_connect_step1(struct connectdata *conn,
   /* put the credentials to the current session */
   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
     rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
-                                BACKEND->srp_client_cred);
+                                backend->srp_client_cred);
     if(rc != GNUTLS_E_SUCCESS) {
       failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
       return CURLE_SSL_CONNECT_ERROR;
@@ -891,7 +678,7 @@ gtls_connect_step1(struct connectdata *conn,
 #endif
   {
     rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
-                                BACKEND->cred);
+                                backend->cred);
     if(rc != GNUTLS_E_SUCCESS) {
       failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
       return CURLE_SSL_CONNECT_ERROR;
@@ -917,10 +704,6 @@ gtls_connect_step1(struct connectdata *conn,
   gnutls_transport_set_push_function(session, gnutls_transport_push);
   gnutls_transport_set_pull_function(session, gnutls_transport_pull);
 
-  /* lowat must be set to zero when using custom push and pull functions. */
-  gnutls_transport_set_lowat(session, 0);
-
-#ifdef HAS_OCSP
   if(SSL_CONN_CONFIG(verifystatus)) {
     rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
     if(rc != GNUTLS_E_SUCCESS) {
@@ -928,7 +711,6 @@ gtls_connect_step1(struct connectdata *conn,
       return CURLE_SSL_CONNECT_ERROR;
     }
   }
-#endif
 
   /* This might be a reconnect, so we check for a session ID in the cache
      to speed up things */
@@ -1020,17 +802,17 @@ gtls_connect_step3(struct connectdata *conn,
   unsigned int verify_status = 0;
   gnutls_x509_crt_t x509_cert, x509_issuer;
   gnutls_datum_t issuerp;
-  char certbuf[256] = ""; /* big enough? */
+  gnutls_datum_t certfields;
+  char certname[65] = ""; /* limited to 64 chars by ASN.1 */
   size_t size;
   time_t certclock;
   const char *ptr;
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  gnutls_session_t session = BACKEND->session;
+  struct ssl_backend_data *backend = connssl->backend;
+  gnutls_session_t session = backend->session;
   int rc;
-#ifdef HAS_ALPN
   gnutls_datum_t proto;
-#endif
   CURLcode result = CURLE_OK;
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
   unsigned int algo;
@@ -1127,7 +909,6 @@ gtls_connect_step3(struct connectdata *conn,
   else
     infof(data, "\t server certificate verification SKIPPED\n");
 
-#ifdef HAS_OCSP
   if(SSL_CONN_CONFIG(verifystatus)) {
     if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
       gnutls_datum_t status_request;
@@ -1230,7 +1011,6 @@ gtls_connect_step3(struct connectdata *conn,
   }
   else
     infof(data, "\t server certificate status verification SKIPPED\n");
-#endif
 
   /* initialize an X.509 certificate structure. */
   gnutls_x509_crt_init(&x509_cert);
@@ -1257,11 +1037,11 @@ gtls_connect_step3(struct connectdata *conn,
           SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none");
   }
 
-  size = sizeof(certbuf);
+  size = sizeof(certname);
   rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
                                      0, /* the first and only one */
                                      FALSE,
-                                     certbuf,
+                                     certname,
                                      &size);
   if(rc) {
     infof(data, "error fetching CN from cert:%s\n",
@@ -1322,16 +1102,16 @@ gtls_connect_step3(struct connectdata *conn,
 
     if(SSL_CONN_CONFIG(verifyhost)) {
       failf(data, "SSL: certificate subject name (%s) does not match "
-            "target host name '%s'", certbuf, dispname);
+            "target host name '%s'", certname, dispname);
       gnutls_x509_crt_deinit(x509_cert);
       return CURLE_PEER_FAILED_VERIFICATION;
     }
     else
       infof(data, "\t common name: %s (does not match '%s')\n",
-            certbuf, dispname);
+            certname, dispname);
   }
   else
-    infof(data, "\t common name: %s (matched)\n", certbuf);
+    infof(data, "\t common name: %s (matched)\n", certname);
 
   /* Check for time-based validity */
   certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
@@ -1416,9 +1196,10 @@ gtls_connect_step3(struct connectdata *conn,
         gnutls_x509_crt_get_version(x509_cert));
 
 
-  size = sizeof(certbuf);
-  gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
-  infof(data, "\t subject: %s\n", certbuf);
+  rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields);
+  if(rc != 0)
+    return CURLE_OUT_OF_MEMORY;
+  infof(data, "\t subject: %s\n", certfields.data);
 
   certclock = gnutls_x509_crt_get_activation_time(x509_cert);
   showtime(data, "start date", certclock);
@@ -1426,14 +1207,14 @@ gtls_connect_step3(struct connectdata *conn,
   certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
   showtime(data, "expire date", certclock);
 
-  size = sizeof(certbuf);
-  gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
-  infof(data, "\t issuer: %s\n", certbuf);
+  rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields);
+  if(rc != 0)
+    return CURLE_OUT_OF_MEMORY;
+  infof(data, "\t issuer: %s\n", certfields.data);
 #endif
 
   gnutls_x509_crt_deinit(x509_cert);
 
-#ifdef HAS_ALPN
   if(conn->bits.tls_enable_alpn) {
     rc = gnutls_alpn_get_selected_protocol(session, &proto);
     if(rc == 0) {
@@ -1459,7 +1240,6 @@ gtls_connect_step3(struct connectdata *conn,
     Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
                         BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
   }
-#endif
 
   conn->ssl[sockindex].state = ssl_connection_complete;
   conn->recv[sockindex] = gtls_recv;
@@ -1577,13 +1357,14 @@ static bool Curl_gtls_data_pending(const struct 
connectdata *conn,
 {
   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
   bool res = FALSE;
-  if(BACKEND->session &&
-     0 != gnutls_record_check_pending(BACKEND->session))
+  struct ssl_backend_data *backend = connssl->backend;
+  if(backend->session &&
+     0 != gnutls_record_check_pending(backend->session))
     res = TRUE;
 
   connssl = &conn->proxy_ssl[connindex];
-  if(BACKEND->session &&
-     0 != gnutls_record_check_pending(BACKEND->session))
+  if(backend->session &&
+     0 != gnutls_record_check_pending(backend->session))
     res = TRUE;
 
   return res;
@@ -1596,7 +1377,8 @@ static ssize_t gtls_send(struct connectdata *conn,
                          CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  ssize_t rc = gnutls_record_send(BACKEND->session, mem, len);
+  struct ssl_backend_data *backend = connssl->backend;
+  ssize_t rc = gnutls_record_send(backend->session, mem, len);
 
   if(rc < 0) {
     *curlcode = (rc == GNUTLS_E_AGAIN)
@@ -1611,19 +1393,20 @@ static ssize_t gtls_send(struct connectdata *conn,
 
 static void close_one(struct ssl_connect_data *connssl)
 {
-  if(BACKEND->session) {
-    gnutls_bye(BACKEND->session, GNUTLS_SHUT_WR);
-    gnutls_deinit(BACKEND->session);
-    BACKEND->session = NULL;
+  struct ssl_backend_data *backend = connssl->backend;
+  if(backend->session) {
+    gnutls_bye(backend->session, GNUTLS_SHUT_WR);
+    gnutls_deinit(backend->session);
+    backend->session = NULL;
   }
-  if(BACKEND->cred) {
-    gnutls_certificate_free_credentials(BACKEND->cred);
-    BACKEND->cred = NULL;
+  if(backend->cred) {
+    gnutls_certificate_free_credentials(backend->cred);
+    backend->cred = NULL;
   }
 #ifdef USE_TLS_SRP
-  if(BACKEND->srp_client_cred) {
-    gnutls_srp_free_client_credentials(BACKEND->srp_client_cred);
-    BACKEND->srp_client_cred = NULL;
+  if(backend->srp_client_cred) {
+    gnutls_srp_free_client_credentials(backend->srp_client_cred);
+    backend->srp_client_cred = NULL;
   }
 #endif
 }
@@ -1641,6 +1424,7 @@ static void Curl_gtls_close(struct connectdata *conn, int 
sockindex)
 static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   int retval = 0;
   struct Curl_easy *data = conn->data;
 
@@ -1651,10 +1435,10 @@ static int Curl_gtls_shutdown(struct connectdata *conn, 
int sockindex)
      we do not send one. Let's hope other servers do the same... */
 
   if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
-      gnutls_bye(BACKEND->session, GNUTLS_SHUT_WR);
+    gnutls_bye(backend->session, GNUTLS_SHUT_WR);
 #endif
 
-  if(BACKEND->session) {
+  if(backend->session) {
     ssize_t result;
     bool done = FALSE;
     char buf[120];
@@ -1665,7 +1449,7 @@ static int Curl_gtls_shutdown(struct connectdata *conn, 
int sockindex)
       if(what > 0) {
         /* Something to read, let's do it and hope that it is the close
            notify alert from the server */
-        result = gnutls_record_recv(BACKEND->session,
+        result = gnutls_record_recv(backend->session,
                                     buf, sizeof(buf));
         switch(result) {
         case 0:
@@ -1695,18 +1479,18 @@ static int Curl_gtls_shutdown(struct connectdata *conn, 
int sockindex)
         done = TRUE;
       }
     }
-    gnutls_deinit(BACKEND->session);
+    gnutls_deinit(backend->session);
   }
-  gnutls_certificate_free_credentials(BACKEND->cred);
+  gnutls_certificate_free_credentials(backend->cred);
 
 #ifdef USE_TLS_SRP
   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
      && SSL_SET_OPTION(username) != NULL)
-    gnutls_srp_free_client_credentials(BACKEND->srp_client_cred);
+    gnutls_srp_free_client_credentials(backend->srp_client_cred);
 #endif
 
-  BACKEND->cred = NULL;
-  BACKEND->session = NULL;
+  backend->cred = NULL;
+  backend->session = NULL;
 
   return retval;
 }
@@ -1718,9 +1502,10 @@ static ssize_t gtls_recv(struct connectdata *conn, /* 
connection data */
                          CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct ssl_backend_data *backend = connssl->backend;
   ssize_t ret;
 
-  ret = gnutls_record_recv(BACKEND->session, buf, buffersize);
+  ret = gnutls_record_recv(backend->session, buf, buffersize);
   if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
     *curlcode = CURLE_AGAIN;
     return -1;
@@ -1836,18 +1621,15 @@ static CURLcode Curl_gtls_sha256sum(const unsigned char 
*tmp, /* input */
 
 static bool Curl_gtls_cert_status_request(void)
 {
-#ifdef HAS_OCSP
   return TRUE;
-#else
-  return FALSE;
-#endif
 }
 
 static void *Curl_gtls_get_internals(struct ssl_connect_data *connssl,
                                      CURLINFO info UNUSED_PARAM)
 {
+  struct ssl_backend_data *backend = connssl->backend;
   (void)info;
-  return BACKEND->session;
+  return backend->session;
 }
 
 const struct Curl_ssl Curl_ssl_gnutls = {
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index f057315f3..cbf3d3dec 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -75,8 +75,6 @@ struct ssl_backend_data {
   const char *protocols[3];
 };
 
-#define BACKEND connssl->backend
-
 /* apply threading? */
 #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
 #define THREADING_SUPPORT
@@ -196,6 +194,7 @@ set_ssl_version_min_max(struct connectdata *conn, int 
sockindex)
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1;
   int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1;
   long ssl_version = SSL_CONN_CONFIG(version);
@@ -227,9 +226,9 @@ set_ssl_version_min_max(struct connectdata *conn, int 
sockindex)
     return result;
   }
 
-  mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+  mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                mbedtls_ver_min);
-  mbedtls_ssl_conf_max_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+  mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                mbedtls_ver_max);
 
   return result;
@@ -241,6 +240,7 @@ mbed_connect_step1(struct connectdata *conn,
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
   const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
@@ -261,9 +261,9 @@ mbed_connect_step1(struct connectdata *conn,
 
 #ifdef THREADING_SUPPORT
   entropy_init_mutex(&ts_entropy);
-  mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg);
+  mbedtls_ctr_drbg_init(&backend->ctr_drbg);
 
-  ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, entropy_func_mutex,
+  ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex,
                               &ts_entropy, NULL, 0);
   if(ret) {
 #ifdef MBEDTLS_ERROR_C
@@ -273,11 +273,11 @@ mbed_connect_step1(struct connectdata *conn,
           -ret, errorbuf);
   }
 #else
-  mbedtls_entropy_init(&BACKEND->entropy);
-  mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg);
+  mbedtls_entropy_init(&backend->entropy);
+  mbedtls_ctr_drbg_init(&backend->ctr_drbg);
 
-  ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, mbedtls_entropy_func,
-                              &BACKEND->entropy, NULL, 0);
+  ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func,
+                              &backend->entropy, NULL, 0);
   if(ret) {
 #ifdef MBEDTLS_ERROR_C
     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
@@ -288,10 +288,10 @@ mbed_connect_step1(struct connectdata *conn,
 #endif /* THREADING_SUPPORT */
 
   /* Load the trusted CA */
-  mbedtls_x509_crt_init(&BACKEND->cacert);
+  mbedtls_x509_crt_init(&backend->cacert);
 
   if(ssl_cafile) {
-    ret = mbedtls_x509_crt_parse_file(&BACKEND->cacert, ssl_cafile);
+    ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile);
 
     if(ret<0) {
 #ifdef MBEDTLS_ERROR_C
@@ -306,7 +306,7 @@ mbed_connect_step1(struct connectdata *conn,
   }
 
   if(ssl_capath) {
-    ret = mbedtls_x509_crt_parse_path(&BACKEND->cacert, ssl_capath);
+    ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath);
 
     if(ret<0) {
 #ifdef MBEDTLS_ERROR_C
@@ -321,10 +321,10 @@ mbed_connect_step1(struct connectdata *conn,
   }
 
   /* Load the client certificate */
-  mbedtls_x509_crt_init(&BACKEND->clicert);
+  mbedtls_x509_crt_init(&backend->clicert);
 
   if(ssl_cert) {
-    ret = mbedtls_x509_crt_parse_file(&BACKEND->clicert, ssl_cert);
+    ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert);
 
     if(ret) {
 #ifdef MBEDTLS_ERROR_C
@@ -338,13 +338,13 @@ mbed_connect_step1(struct connectdata *conn,
   }
 
   /* Load the client private key */
-  mbedtls_pk_init(&BACKEND->pk);
+  mbedtls_pk_init(&backend->pk);
 
   if(SSL_SET_OPTION(key)) {
-    ret = mbedtls_pk_parse_keyfile(&BACKEND->pk, SSL_SET_OPTION(key),
+    ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key),
                                    SSL_SET_OPTION(key_passwd));
-    if(ret == 0 && !(mbedtls_pk_can_do(&BACKEND->pk, MBEDTLS_PK_RSA) ||
-                     mbedtls_pk_can_do(&BACKEND->pk, MBEDTLS_PK_ECKEY)))
+    if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) ||
+                     mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY)))
       ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
 
     if(ret) {
@@ -359,10 +359,10 @@ mbed_connect_step1(struct connectdata *conn,
   }
 
   /* Load the CRL */
-  mbedtls_x509_crl_init(&BACKEND->crl);
+  mbedtls_x509_crl_init(&backend->crl);
 
   if(ssl_crlfile) {
-    ret = mbedtls_x509_crl_parse_file(&BACKEND->crl, ssl_crlfile);
+    ret = mbedtls_x509_crl_parse_file(&backend->crl, ssl_crlfile);
 
     if(ret) {
 #ifdef MBEDTLS_ERROR_C
@@ -377,14 +377,14 @@ mbed_connect_step1(struct connectdata *conn,
 
   infof(data, "mbedTLS: Connecting to %s:%ld\n", hostname, port);
 
-  mbedtls_ssl_config_init(&BACKEND->config);
+  mbedtls_ssl_config_init(&backend->config);
 
-  mbedtls_ssl_init(&BACKEND->ssl);
-  if(mbedtls_ssl_setup(&BACKEND->ssl, &BACKEND->config)) {
+  mbedtls_ssl_init(&backend->ssl);
+  if(mbedtls_ssl_setup(&backend->ssl, &backend->config)) {
     failf(data, "mbedTLS: ssl_init failed");
     return CURLE_SSL_CONNECT_ERROR;
   }
-  ret = mbedtls_ssl_config_defaults(&BACKEND->config,
+  ret = mbedtls_ssl_config_defaults(&backend->config,
                                     MBEDTLS_SSL_IS_CLIENT,
                                     MBEDTLS_SSL_TRANSPORT_STREAM,
                                     MBEDTLS_SSL_PRESET_DEFAULT);
@@ -394,20 +394,20 @@ mbed_connect_step1(struct connectdata *conn,
   }
 
   /* new profile with RSA min key len = 1024 ... */
-  mbedtls_ssl_conf_cert_profile(&BACKEND->config,
+  mbedtls_ssl_conf_cert_profile(&backend->config,
                                 &mbedtls_x509_crt_profile_fr);
 
   switch(SSL_CONN_CONFIG(version)) {
   case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
-    mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+    mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                  MBEDTLS_SSL_MINOR_VERSION_1);
     infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n");
     break;
   case CURL_SSLVERSION_SSLv3:
-    mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+    mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                  MBEDTLS_SSL_MINOR_VERSION_0);
-    mbedtls_ssl_conf_max_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+    mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                  MBEDTLS_SSL_MINOR_VERSION_0);
     infof(data, "mbedTLS: Set SSL version to SSLv3\n");
     break;
@@ -426,25 +426,25 @@ mbed_connect_step1(struct connectdata *conn,
     return CURLE_SSL_CONNECT_ERROR;
   }
 
-  mbedtls_ssl_conf_authmode(&BACKEND->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
+  mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
 
-  mbedtls_ssl_conf_rng(&BACKEND->config, mbedtls_ctr_drbg_random,
-                       &BACKEND->ctr_drbg);
-  mbedtls_ssl_set_bio(&BACKEND->ssl, &conn->sock[sockindex],
+  mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random,
+                       &backend->ctr_drbg);
+  mbedtls_ssl_set_bio(&backend->ssl, &conn->sock[sockindex],
                       mbedtls_net_send,
                       mbedtls_net_recv,
                       NULL /*  rev_timeout() */);
 
-  mbedtls_ssl_conf_ciphersuites(&BACKEND->config,
+  mbedtls_ssl_conf_ciphersuites(&backend->config,
                                 mbedtls_ssl_list_ciphersuites());
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
-  mbedtls_ssl_conf_renegotiation(&BACKEND->config,
+  mbedtls_ssl_conf_renegotiation(&backend->config,
                                  MBEDTLS_SSL_RENEGOTIATION_ENABLED);
 #endif
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
-  mbedtls_ssl_conf_session_tickets(&BACKEND->config,
+  mbedtls_ssl_conf_session_tickets(&backend->config,
                                    MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
 #endif
 
@@ -454,7 +454,7 @@ mbed_connect_step1(struct connectdata *conn,
 
     Curl_ssl_sessionid_lock(conn);
     if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
-      ret = mbedtls_ssl_set_session(&BACKEND->ssl, old_session);
+      ret = mbedtls_ssl_set_session(&backend->ssl, old_session);
       if(ret) {
         Curl_ssl_sessionid_unlock(conn);
         failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret);
@@ -465,15 +465,15 @@ mbed_connect_step1(struct connectdata *conn,
     Curl_ssl_sessionid_unlock(conn);
   }
 
-  mbedtls_ssl_conf_ca_chain(&BACKEND->config,
-                            &BACKEND->cacert,
-                            &BACKEND->crl);
+  mbedtls_ssl_conf_ca_chain(&backend->config,
+                            &backend->cacert,
+                            &backend->crl);
 
   if(SSL_SET_OPTION(key)) {
-    mbedtls_ssl_conf_own_cert(&BACKEND->config,
-                              &BACKEND->clicert, &BACKEND->pk);
+    mbedtls_ssl_conf_own_cert(&backend->config,
+                              &backend->clicert, &backend->pk);
   }
-  if(mbedtls_ssl_set_hostname(&BACKEND->ssl, hostname)) {
+  if(mbedtls_ssl_set_hostname(&backend->ssl, hostname)) {
     /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and*
        the name to set in the SNI extension. So even if curl connects to a
        host specified as an IP address, this function must be used. */
@@ -483,7 +483,7 @@ mbed_connect_step1(struct connectdata *conn,
 
 #ifdef HAS_ALPN
   if(conn->bits.tls_enable_alpn) {
-    const char **p = &BACKEND->protocols[0];
+    const char **p = &backend->protocols[0];
 #ifdef USE_NGHTTP2
     if(data->set.httpversion >= CURL_HTTP_VERSION_2)
       *p++ = NGHTTP2_PROTO_VERSION_ID;
@@ -492,19 +492,19 @@ mbed_connect_step1(struct connectdata *conn,
     *p = NULL;
     /* this function doesn't clone the protocols array, which is why we need
        to keep it around */
-    if(mbedtls_ssl_conf_alpn_protocols(&BACKEND->config,
-                                       &BACKEND->protocols[0])) {
+    if(mbedtls_ssl_conf_alpn_protocols(&backend->config,
+                                       &backend->protocols[0])) {
       failf(data, "Failed setting ALPN protocols");
       return CURLE_SSL_CONNECT_ERROR;
     }
-    for(p = &BACKEND->protocols[0]; *p; ++p)
+    for(p = &backend->protocols[0]; *p; ++p)
       infof(data, "ALPN, offering %s\n", *p);
   }
 #endif
 
 #ifdef MBEDTLS_DEBUG
   /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */
-  mbedtls_ssl_conf_dbg(&BACKEND->config, mbed_debug, data);
+  mbedtls_ssl_conf_dbg(&backend->config, mbed_debug, data);
   /* - 0 No debug
    * - 1 Error
    * - 2 State change
@@ -516,7 +516,7 @@ mbed_connect_step1(struct connectdata *conn,
 
   /* give application a chance to interfere with mbedTLS set up. */
   if(data->set.ssl.fsslctx) {
-    ret = (*data->set.ssl.fsslctx)(data, &BACKEND->config,
+    ret = (*data->set.ssl.fsslctx)(data, &backend->config,
                                    data->set.ssl.fsslctxp);
     if(ret) {
       failf(data, "error signaled by ssl ctx callback");
@@ -536,15 +536,16 @@ mbed_connect_step2(struct connectdata *conn,
   int ret;
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   const mbedtls_x509_crt *peercert;
   const char * const pinnedpubkey = SSL_IS_PROXY() ?
-        data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
-        data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+    data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+    data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
 
   conn->recv[sockindex] = mbed_recv;
   conn->send[sockindex] = mbed_send;
 
-  ret = mbedtls_ssl_handshake(&BACKEND->ssl);
+  ret = mbedtls_ssl_handshake(&backend->ssl);
 
   if(ret == MBEDTLS_ERR_SSL_WANT_READ) {
     connssl->connecting_state = ssl_connect_2_reading;
@@ -566,10 +567,10 @@ mbed_connect_step2(struct connectdata *conn,
   }
 
   infof(data, "mbedTLS: Handshake complete, cipher is %s\n",
-        mbedtls_ssl_get_ciphersuite(&BACKEND->ssl)
+        mbedtls_ssl_get_ciphersuite(&backend->ssl)
     );
 
-  ret = mbedtls_ssl_get_verify_result(&BACKEND->ssl);
+  ret = mbedtls_ssl_get_verify_result(&backend->ssl);
 
   if(!SSL_CONN_CONFIG(verifyhost))
     /* Ignore hostname errors if verifyhost is disabled */
@@ -594,7 +595,7 @@ mbed_connect_step2(struct connectdata *conn,
     return CURLE_PEER_FAILED_VERIFICATION;
   }
 
-  peercert = mbedtls_ssl_get_peer_cert(&BACKEND->ssl);
+  peercert = mbedtls_ssl_get_peer_cert(&backend->ssl);
 
   if(peercert && data->set.verbose) {
     const size_t bufsize = 16384;
@@ -664,7 +665,7 @@ mbed_connect_step2(struct connectdata *conn,
 
 #ifdef HAS_ALPN
   if(conn->bits.tls_enable_alpn) {
-    const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&BACKEND->ssl);
+    const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&backend->ssl);
 
     if(next_protocol) {
       infof(data, "ALPN, server accepted to use %s\n", next_protocol);
@@ -701,6 +702,7 @@ mbed_connect_step3(struct connectdata *conn,
 {
   CURLcode retcode = CURLE_OK;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   struct Curl_easy *data = conn->data;
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
@@ -716,7 +718,7 @@ mbed_connect_step3(struct connectdata *conn,
 
     mbedtls_ssl_session_init(our_ssl_sessionid);
 
-    ret = mbedtls_ssl_get_session(&BACKEND->ssl, our_ssl_sessionid);
+    ret = mbedtls_ssl_get_session(&backend->ssl, our_ssl_sessionid);
     if(ret) {
       if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED)
         mbedtls_ssl_session_free(our_ssl_sessionid);
@@ -750,9 +752,10 @@ static ssize_t mbed_send(struct connectdata *conn, int 
sockindex,
                          CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   int ret = -1;
 
-  ret = mbedtls_ssl_write(&BACKEND->ssl,
+  ret = mbedtls_ssl_write(&backend->ssl,
                           (unsigned char *)mem, len);
 
   if(ret < 0) {
@@ -772,15 +775,16 @@ static void Curl_mbedtls_close_all(struct Curl_easy *data)
 static void Curl_mbedtls_close(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  mbedtls_pk_free(&BACKEND->pk);
-  mbedtls_x509_crt_free(&BACKEND->clicert);
-  mbedtls_x509_crt_free(&BACKEND->cacert);
-  mbedtls_x509_crl_free(&BACKEND->crl);
-  mbedtls_ssl_config_free(&BACKEND->config);
-  mbedtls_ssl_free(&BACKEND->ssl);
-  mbedtls_ctr_drbg_free(&BACKEND->ctr_drbg);
+  struct ssl_backend_data *backend = connssl->backend;
+  mbedtls_pk_free(&backend->pk);
+  mbedtls_x509_crt_free(&backend->clicert);
+  mbedtls_x509_crt_free(&backend->cacert);
+  mbedtls_x509_crl_free(&backend->crl);
+  mbedtls_ssl_config_free(&backend->config);
+  mbedtls_ssl_free(&backend->ssl);
+  mbedtls_ctr_drbg_free(&backend->ctr_drbg);
 #ifndef THREADING_SUPPORT
-  mbedtls_entropy_free(&BACKEND->entropy);
+  mbedtls_entropy_free(&backend->entropy);
 #endif /* THREADING_SUPPORT */
 }
 
@@ -789,11 +793,12 @@ static ssize_t mbed_recv(struct connectdata *conn, int 
num,
                          CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct ssl_backend_data *backend = connssl->backend;
   int ret = -1;
   ssize_t len = -1;
 
   memset(buf, 0, buffersize);
-  ret = mbedtls_ssl_read(&BACKEND->ssl, (unsigned char *)buf,
+  ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf,
                          buffersize);
 
   if(ret <= 0) {
@@ -1029,7 +1034,8 @@ static bool Curl_mbedtls_data_pending(const struct 
connectdata *conn,
                                       int sockindex)
 {
   const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  return mbedtls_ssl_get_bytes_avail(&BACKEND->ssl) != 0;
+  struct ssl_backend_data *backend = connssl->backend;
+  return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0;
 }
 
 static CURLcode Curl_mbedtls_sha256sum(const unsigned char *input,
@@ -1051,8 +1057,9 @@ static CURLcode Curl_mbedtls_sha256sum(const unsigned 
char *input,
 static void *Curl_mbedtls_get_internals(struct ssl_connect_data *connssl,
                                         CURLINFO info UNUSED_PARAM)
 {
+  struct ssl_backend_data *backend = connssl->backend;
   (void)info;
-  return &BACKEND->ssl;
+  return &backend->ssl;
 }
 
 const struct Curl_ssl Curl_ssl_mbedtls = {
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index ef51b0d91..16ec409e9 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -87,8 +87,6 @@ struct ssl_backend_data {
   PK11GenericObject *obj_clicert;
 };
 
-#define BACKEND connssl->backend
-
 static PRLock *nss_initlock = NULL;
 static PRLock *nss_crllock = NULL;
 static PRLock *nss_findslot_lock = NULL;
@@ -462,6 +460,7 @@ static CURLcode nss_create_object(struct ssl_connect_data 
*connssl,
 
   const int slot_id = (cacert) ? 0 : 1;
   char *slot_name = aprintf("PEM Token #%d", slot_id);
+  struct ssl_backend_data *backend = connssl->backend;
   if(!slot_name)
     return CURLE_OUT_OF_MEMORY;
 
@@ -495,14 +494,14 @@ static CURLcode nss_create_object(struct ssl_connect_data 
*connssl,
   if(!obj)
     return result;
 
-  if(insert_wrapped_ptr(&BACKEND->obj_list, obj) != CURLE_OK) {
+  if(insert_wrapped_ptr(&backend->obj_list, obj) != CURLE_OK) {
     PK11_DestroyGenericObject(obj);
     return CURLE_OUT_OF_MEMORY;
   }
 
   if(!cacert && CKO_CERTIFICATE == obj_class)
     /* store reference to a client certificate */
-    BACKEND->obj_clicert = obj;
+    backend->obj_clicert = obj;
 
   return CURLE_OK;
 }
@@ -1084,7 +1083,8 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data 
*connssl,
                                 const char *pinnedpubkey)
 {
   CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
-  struct Curl_easy *data = BACKEND->data;
+  struct ssl_backend_data *backend = connssl->backend;
+  struct Curl_easy *data = backend->data;
   CERTCertificate *cert;
 
   if(!pinnedpubkey)
@@ -1092,7 +1092,7 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data 
*connssl,
     return CURLE_OK;
 
   /* get peer certificate */
-  cert = SSL_PeerCertificate(BACKEND->handle);
+  cert = SSL_PeerCertificate(backend->handle);
   if(cert) {
     /* extract public key from peer certificate */
     SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
@@ -1136,11 +1136,12 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc 
*sock,
                                   struct SECKEYPrivateKeyStr **pRetKey)
 {
   struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
-  struct Curl_easy *data = BACKEND->data;
-  const char *nickname = BACKEND->client_nickname;
+  struct ssl_backend_data *backend = connssl->backend;
+  struct Curl_easy *data = backend->data;
+  const char *nickname = backend->client_nickname;
   static const char pem_slotname[] = "PEM Token #1";
 
-  if(BACKEND->obj_clicert) {
+  if(backend->obj_clicert) {
     /* use the cert/key provided by PEM reader */
     SECItem cert_der = { 0, NULL, 0 };
     void *proto_win = SSL_RevealPinArg(sock);
@@ -1153,7 +1154,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc 
*sock,
       return SECFailure;
     }
 
-    if(PK11_ReadRawAttribute(PK11_TypeGeneric, BACKEND->obj_clicert, CKA_VALUE,
+    if(PK11_ReadRawAttribute(PK11_TypeGeneric, backend->obj_clicert, CKA_VALUE,
                              &cert_der) != SECSuccess) {
       failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
       PK11_FreeSlot(slot);
@@ -1503,11 +1504,12 @@ static void Curl_nss_cleanup(void)
 static int Curl_nss_check_cxn(struct connectdata *conn)
 {
   struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+  struct ssl_backend_data *backend = connssl->backend;
   int rc;
   char buf;
 
   rc =
-    PR_Recv(BACKEND->handle, (void *)&buf, 1, PR_MSG_PEEK,
+    PR_Recv(backend->handle, (void *)&buf, 1, PR_MSG_PEEK,
             PR_SecondsToInterval(1));
   if(rc > 0)
     return 1; /* connection still in place */
@@ -1521,26 +1523,27 @@ static int Curl_nss_check_cxn(struct connectdata *conn)
 static void nss_close(struct ssl_connect_data *connssl)
 {
   /* before the cleanup, check whether we are using a client certificate */
-  const bool client_cert = (BACKEND->client_nickname != NULL)
-    || (BACKEND->obj_clicert != NULL);
+  struct ssl_backend_data *backend = connssl->backend;
+  const bool client_cert = (backend->client_nickname != NULL)
+    || (backend->obj_clicert != NULL);
 
-  free(BACKEND->client_nickname);
-  BACKEND->client_nickname = NULL;
+  free(backend->client_nickname);
+  backend->client_nickname = NULL;
 
   /* destroy all NSS objects in order to avoid failure of NSS shutdown */
-  Curl_llist_destroy(&BACKEND->obj_list, NULL);
-  BACKEND->obj_clicert = NULL;
+  Curl_llist_destroy(&backend->obj_list, NULL);
+  backend->obj_clicert = NULL;
 
-  if(BACKEND->handle) {
+  if(backend->handle) {
     if(client_cert)
       /* A server might require different authentication based on the
        * particular path being requested by the client.  To support this
        * scenario, we must ensure that a connection will never reuse the
        * authentication data from a previous connection. */
-      SSL_InvalidateSession(BACKEND->handle);
+      SSL_InvalidateSession(backend->handle);
 
-    PR_Close(BACKEND->handle);
-    BACKEND->handle = NULL;
+    PR_Close(backend->handle);
+    backend->handle = NULL;
   }
 }
 
@@ -1551,15 +1554,16 @@ static void Curl_nss_close(struct connectdata *conn, 
int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
-  if(BACKEND->handle || connssl_proxy->backend->handle) {
+  if(backend->handle || connssl_proxy->backend->handle) {
     /* NSS closes the socket we previously handed to it, so we must mark it
        as closed to avoid double close */
     fake_sclose(conn->sock[sockindex]);
     conn->sock[sockindex] = CURL_SOCKET_BAD;
   }
 
-  if(BACKEND->handle)
+  if(backend->handle)
     /* nss_close(connssl) will transitively close also
        connssl_proxy->backend->handle if both are used. Clear it to avoid
        a double close leading to crash. */
@@ -1773,6 +1777,7 @@ static CURLcode nss_fail_connect(struct ssl_connect_data 
*connssl,
                                  CURLcode curlerr)
 {
   PRErrorCode err = 0;
+  struct ssl_backend_data *backend = connssl->backend;
 
   if(is_nss_error(curlerr)) {
     /* read NSPR error code */
@@ -1788,7 +1793,7 @@ static CURLcode nss_fail_connect(struct ssl_connect_data 
*connssl,
   }
 
   /* cleanup on connection failure */
-  Curl_llist_destroy(&BACKEND->obj_list, NULL);
+  Curl_llist_destroy(&backend->obj_list, NULL);
 
   return curlerr;
 }
@@ -1799,10 +1804,11 @@ static CURLcode nss_set_blocking(struct 
ssl_connect_data *connssl,
                                  bool blocking)
 {
   static PRSocketOptionData sock_opt;
+  struct ssl_backend_data *backend = connssl->backend;
   sock_opt.option = PR_SockOpt_Nonblocking;
   sock_opt.value.non_blocking = !blocking;
 
-  if(PR_SetSocketOption(BACKEND->handle, &sock_opt) != PR_SUCCESS)
+  if(PR_SetSocketOption(backend->handle, &sock_opt) != PR_SUCCESS)
     return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
 
   return CURLE_OK;
@@ -1818,6 +1824,7 @@ static CURLcode nss_setup_connect(struct connectdata 
*conn, int sockindex)
   struct Curl_easy *data = conn->data;
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   CURLcode result;
   bool second_layer = FALSE;
   SSLVersionRange sslver_supported;
@@ -1835,10 +1842,10 @@ static CURLcode nss_setup_connect(struct connectdata 
*conn, int sockindex)
 #endif
   };
 
-  BACKEND->data = data;
+  backend->data = data;
 
   /* list of all NSS objects we need to destroy in Curl_nss_close() */
-  Curl_llist_init(&BACKEND->obj_list, nss_destroy_object);
+  Curl_llist_init(&backend->obj_list, nss_destroy_object);
 
   PR_Lock(nss_initlock);
   result = nss_init(conn->data);
@@ -1960,7 +1967,7 @@ static CURLcode nss_setup_connect(struct connectdata 
*conn, int sockindex)
     char *nickname = dup_nickname(data, SSL_SET_OPTION(cert));
     if(nickname) {
       /* we are not going to use libnsspem.so to read the client cert */
-      BACKEND->obj_clicert = NULL;
+      backend->obj_clicert = NULL;
     }
     else {
       CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert),
@@ -1973,10 +1980,10 @@ static CURLcode nss_setup_connect(struct connectdata 
*conn, int sockindex)
     }
 
     /* store the nickname for SelectClientCert() called during handshake */
-    BACKEND->client_nickname = nickname;
+    backend->client_nickname = nickname;
   }
   else
-    BACKEND->client_nickname = NULL;
+    backend->client_nickname = NULL;
 
   if(SSL_GetClientAuthDataHook(model, SelectClientCert,
                                (void *)connssl) != SECSuccess) {
@@ -2017,8 +2024,8 @@ static CURLcode nss_setup_connect(struct connectdata 
*conn, int sockindex)
   }
 
   /* import our model socket onto the current I/O stack */
-  BACKEND->handle = SSL_ImportFD(model, nspr_io);
-  if(!BACKEND->handle) {
+  backend->handle = SSL_ImportFD(model, nspr_io);
+  if(!backend->handle) {
     if(!second_layer)
       PR_Close(nspr_io);
     goto error;
@@ -2029,36 +2036,36 @@ static CURLcode nss_setup_connect(struct connectdata 
*conn, int sockindex)
 
   /* This is the password associated with the cert that we're using */
   if(SSL_SET_OPTION(key_passwd)) {
-    SSL_SetPKCS11PinArg(BACKEND->handle, SSL_SET_OPTION(key_passwd));
+    SSL_SetPKCS11PinArg(backend->handle, SSL_SET_OPTION(key_passwd));
   }
 
 #ifdef SSL_ENABLE_OCSP_STAPLING
   if(SSL_CONN_CONFIG(verifystatus)) {
-    if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
+    if(SSL_OptionSet(backend->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
         != SECSuccess)
       goto error;
   }
 #endif
 
 #ifdef SSL_ENABLE_NPN
-  if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
+  if(SSL_OptionSet(backend->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
                    ? PR_TRUE : PR_FALSE) != SECSuccess)
     goto error;
 #endif
 
 #ifdef SSL_ENABLE_ALPN
-  if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
+  if(SSL_OptionSet(backend->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
                    ? PR_TRUE : PR_FALSE) != SECSuccess)
     goto error;
 #endif
 
 #if NSSVERNUM >= 0x030f04 /* 3.15.4 */
   if(data->set.ssl.falsestart) {
-    if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
+    if(SSL_OptionSet(backend->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
         != SECSuccess)
       goto error;
 
-    if(SSL_SetCanFalseStartCallback(BACKEND->handle, CanFalseStartCallback,
+    if(SSL_SetCanFalseStartCallback(backend->handle, CanFalseStartCallback,
         conn) != SECSuccess)
       goto error;
   }
@@ -2082,24 +2089,24 @@ static CURLcode nss_setup_connect(struct connectdata 
*conn, int sockindex)
     memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
     cur += ALPN_HTTP_1_1_LENGTH;
 
-    if(SSL_SetNextProtoNego(BACKEND->handle, protocols, cur) != SECSuccess)
+    if(SSL_SetNextProtoNego(backend->handle, protocols, cur) != SECSuccess)
       goto error;
   }
 #endif
 
 
   /* Force handshake on next I/O */
-  if(SSL_ResetHandshake(BACKEND->handle, /* asServer */ PR_FALSE)
+  if(SSL_ResetHandshake(backend->handle, /* asServer */ PR_FALSE)
       != SECSuccess)
     goto error;
 
   /* propagate hostname to the TLS layer */
-  if(SSL_SetURL(BACKEND->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
+  if(SSL_SetURL(backend->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
                 conn->host.name) != SECSuccess)
     goto error;
 
   /* prevent NSS from re-using the session for a different hostname */
-  if(SSL_SetSockPeerID(BACKEND->handle, SSL_IS_PROXY() ?
+  if(SSL_SetSockPeerID(backend->handle, SSL_IS_PROXY() ?
                        conn->http_proxy.host.name : conn->host.name)
      != SECSuccess)
     goto error;
@@ -2116,6 +2123,7 @@ error:
 static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_SSL_CONNECT_ERROR;
   PRUint32 timeout;
@@ -2136,7 +2144,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, 
int sockindex)
 
   /* Force the handshake now */
   timeout = PR_MillisecondsToInterval((PRUint32) time_left);
-  if(SSL_ForceHandshakeWithTimeout(BACKEND->handle, timeout) != SECSuccess) {
+  if(SSL_ForceHandshakeWithTimeout(backend->handle, timeout) != SECSuccess) {
     if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
       /* blocking direction is updated by nss_update_connecting_state() */
       return CURLE_AGAIN;
@@ -2147,7 +2155,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, 
int sockindex)
     goto error;
   }
 
-  result = display_conn_info(conn, BACKEND->handle);
+  result = display_conn_info(conn, backend->handle);
   if(result)
     goto error;
 
@@ -2156,7 +2164,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, 
int sockindex)
     char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert));
     if(nickname) {
       /* we support only nicknames in case of issuercert for now */
-      ret = check_issuer_cert(BACKEND->handle, nickname);
+      ret = check_issuer_cert(backend->handle, nickname);
       free(nickname);
     }
 
@@ -2260,13 +2268,14 @@ static ssize_t nss_send(struct connectdata *conn,  /* 
connection data */
                         CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   ssize_t rc;
 
   /* The SelectClientCert() hook uses this for infof() and failf() but the
      handle stored in nss_setup_connect() could have already been freed. */
-  BACKEND->data = conn->data;
+  backend->data = conn->data;
 
-  rc = PR_Send(BACKEND->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
+  rc = PR_Send(backend->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
   if(rc < 0) {
     PRInt32 err = PR_GetError();
     if(err == PR_WOULD_BLOCK_ERROR)
@@ -2297,13 +2306,14 @@ static ssize_t nss_recv(struct connectdata *conn,  /* 
connection data */
                         CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   ssize_t nread;
 
   /* The SelectClientCert() hook uses this for infof() and failf() but the
      handle stored in nss_setup_connect() could have already been freed. */
-  BACKEND->data = conn->data;
+  backend->data = conn->data;
 
-  nread = PR_Recv(BACKEND->handle, buf, (int)buffersize, 0,
+  nread = PR_Recv(backend->handle, buf, (int)buffersize, 0,
                   PR_INTERVAL_NO_WAIT);
   if(nread < 0) {
     /* failed SSL read */
@@ -2364,6 +2374,9 @@ static CURLcode Curl_nss_md5sum(unsigned char *tmp, /* 
input */
   PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
   unsigned int MD5out;
 
+  if(!MD5pw)
+    return CURLE_NOT_BUILT_IN;
+
   PK11_DigestOp(MD5pw, tmp, curlx_uztoui(tmplen));
   PK11_DigestFinal(MD5pw, md5sum, &MD5out, curlx_uztoui(md5len));
   PK11_DestroyContext(MD5pw, PR_TRUE);
@@ -2379,6 +2392,9 @@ static CURLcode Curl_nss_sha256sum(const unsigned char 
*tmp, /* input */
   PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256);
   unsigned int SHA256out;
 
+  if(!SHA256pw)
+    return CURLE_NOT_BUILT_IN;
+
   PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen));
   PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len));
   PK11_DestroyContext(SHA256pw, PR_TRUE);
@@ -2407,8 +2423,9 @@ static bool Curl_nss_false_start(void)
 static void *Curl_nss_get_internals(struct ssl_connect_data *connssl,
                                     CURLINFO info UNUSED_PARAM)
 {
+  struct ssl_backend_data *backend = connssl->backend;
   (void)info;
-  return BACKEND->handle;
+  return backend->handle;
 }
 
 const struct Curl_ssl Curl_ssl_nss = {
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 1d09cadca..176fa522a 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -228,8 +228,6 @@ struct ssl_backend_data {
 #endif
 };
 
-#define BACKEND connssl->backend
-
 /*
  * Number of bytes to read from the random number seed file. This must be
  * a finite value (because some entropy "files" like /dev/urandom have
@@ -1269,19 +1267,19 @@ static struct curl_slist *Curl_ossl_engines_list(struct 
Curl_easy *data)
   return list;
 }
 
-
 static void ossl_close(struct ssl_connect_data *connssl)
 {
-  if(BACKEND->handle) {
-    (void)SSL_shutdown(BACKEND->handle);
-    SSL_set_connect_state(BACKEND->handle);
+  struct ssl_backend_data *backend = connssl->backend;
+  if(backend->handle) {
+    (void)SSL_shutdown(backend->handle);
+    SSL_set_connect_state(backend->handle);
 
-    SSL_free(BACKEND->handle);
-    BACKEND->handle = NULL;
+    SSL_free(backend->handle);
+    backend->handle = NULL;
   }
-  if(BACKEND->ctx) {
-    SSL_CTX_free(BACKEND->ctx);
-    BACKEND->ctx = NULL;
+  if(backend->ctx) {
+    SSL_CTX_free(backend->ctx);
+    backend->ctx = NULL;
   }
 }
 
@@ -1310,6 +1308,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, 
int sockindex)
   int buffsize;
   int err;
   bool done = FALSE;
+  struct ssl_backend_data *backend = connssl->backend;
 
 #ifndef CURL_DISABLE_FTP
   /* This has only been tested on the proftpd server, and the mod_tls code
@@ -1318,10 +1317,10 @@ static int Curl_ossl_shutdown(struct connectdata *conn, 
int sockindex)
      we do not send one. Let's hope other servers do the same... */
 
   if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
-      (void)SSL_shutdown(BACKEND->handle);
+      (void)SSL_shutdown(backend->handle);
 #endif
 
-  if(BACKEND->handle) {
+  if(backend->handle) {
     buffsize = (int)sizeof(buf);
     while(!done) {
       int what = SOCKET_READABLE(conn->sock[sockindex],
@@ -1331,8 +1330,8 @@ static int Curl_ossl_shutdown(struct connectdata *conn, 
int sockindex)
 
         /* Something to read, let's do it and hope that it is the close
            notify alert from the server */
-        nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize);
-        err = SSL_get_error(BACKEND->handle, (int)nread);
+        nread = (ssize_t)SSL_read(backend->handle, buf, buffsize);
+        err = SSL_get_error(backend->handle, (int)nread);
 
         switch(err) {
         case SSL_ERROR_NONE: /* this is not an error */
@@ -1377,7 +1376,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, 
int sockindex)
 
     if(data->set.verbose) {
 #ifdef HAVE_SSL_GET_SHUTDOWN
-      switch(SSL_get_shutdown(BACKEND->handle)) {
+      switch(SSL_get_shutdown(backend->handle)) {
       case SSL_SENT_SHUTDOWN:
         infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
         break;
@@ -1392,8 +1391,8 @@ static int Curl_ossl_shutdown(struct connectdata *conn, 
int sockindex)
 #endif
     }
 
-    SSL_free(BACKEND->handle);
-    BACKEND->handle = NULL;
+    SSL_free(backend->handle);
+    backend->handle = NULL;
   }
   return retval;
 }
@@ -1712,13 +1711,13 @@ static CURLcode verifystatus(struct connectdata *conn,
   const unsigned char *p;
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-
   OCSP_RESPONSE *rsp = NULL;
   OCSP_BASICRESP *br = NULL;
   X509_STORE     *st = NULL;
   STACK_OF(X509) *ch = NULL;
+  struct ssl_backend_data *backend = connssl->backend;
 
-  long len = SSL_get_tlsext_status_ocsp_resp(BACKEND->handle, &status);
+  long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status);
 
   if(!status) {
     failf(data, "No OCSP response received");
@@ -1748,8 +1747,8 @@ static CURLcode verifystatus(struct connectdata *conn,
     goto end;
   }
 
-  ch = SSL_get_peer_cert_chain(BACKEND->handle);
-  st = SSL_CTX_get_cert_store(BACKEND->ctx);
+  ch = SSL_get_peer_cert_chain(backend->handle);
+  st = SSL_CTX_get_cert_store(backend->ctx);
 
 #if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \
      (defined(LIBRESSL_VERSION_NUMBER) &&                               \
@@ -1825,7 +1824,8 @@ static CURLcode verifystatus(struct connectdata *conn,
   }
 
 end:
-  if(br) OCSP_BASICRESP_free(br);
+  if(br)
+    OCSP_BASICRESP_free(br);
   OCSP_RESPONSE_free(rsp);
 
   return result;
@@ -2270,7 +2270,7 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
 #ifdef TLS1_3_VERSION
     {
       struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-      SSL_CTX_set_max_proto_version(BACKEND->ctx, TLS1_3_VERSION);
+      SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION);
       *ctx_options |= SSL_OP_NO_TLSv1_2;
     }
 #else
@@ -2419,6 +2419,7 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
   const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
   char error_buffer[256];
+  struct ssl_backend_data *backend = connssl->backend;
 
   DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
 
@@ -2477,25 +2478,25 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
     return CURLE_SSL_CONNECT_ERROR;
   }
 
-  if(BACKEND->ctx)
-    SSL_CTX_free(BACKEND->ctx);
-  BACKEND->ctx = SSL_CTX_new(req_method);
+  if(backend->ctx)
+    SSL_CTX_free(backend->ctx);
+  backend->ctx = SSL_CTX_new(req_method);
 
-  if(!BACKEND->ctx) {
+  if(!backend->ctx) {
     failf(data, "SSL: couldn't create a context: %s",
           ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer)));
     return CURLE_OUT_OF_MEMORY;
   }
 
 #ifdef SSL_MODE_RELEASE_BUFFERS
-  SSL_CTX_set_mode(BACKEND->ctx, SSL_MODE_RELEASE_BUFFERS);
+  SSL_CTX_set_mode(backend->ctx, SSL_MODE_RELEASE_BUFFERS);
 #endif
 
 #ifdef SSL_CTRL_SET_MSG_CALLBACK
   if(data->set.fdebug && data->set.verbose) {
     /* the SSL trace callback is only used for verbose logging */
-    SSL_CTX_set_msg_callback(BACKEND->ctx, ssl_tls_trace);
-    SSL_CTX_set_msg_callback_arg(BACKEND->ctx, conn);
+    SSL_CTX_set_msg_callback(backend->ctx, ssl_tls_trace);
+    SSL_CTX_set_msg_callback_arg(backend->ctx, conn);
   }
 #endif
 
@@ -2561,8 +2562,8 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
     /* "--sslv2" option means SSLv2 only, disable all others */
     case CURL_SSLVERSION_SSLv2:
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
-      SSL_CTX_set_min_proto_version(BACKEND->ctx, SSL2_VERSION);
-      SSL_CTX_set_max_proto_version(BACKEND->ctx, SSL2_VERSION);
+      SSL_CTX_set_min_proto_version(backend->ctx, SSL2_VERSION);
+      SSL_CTX_set_max_proto_version(backend->ctx, SSL2_VERSION);
 #else
       ctx_options |= SSL_OP_NO_SSLv3;
       ctx_options |= SSL_OP_NO_TLSv1;
@@ -2579,8 +2580,8 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
     /* "--sslv3" option means SSLv3 only, disable all others */
     case CURL_SSLVERSION_SSLv3:
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
-      SSL_CTX_set_min_proto_version(BACKEND->ctx, SSL3_VERSION);
-      SSL_CTX_set_max_proto_version(BACKEND->ctx, SSL3_VERSION);
+      SSL_CTX_set_min_proto_version(backend->ctx, SSL3_VERSION);
+      SSL_CTX_set_max_proto_version(backend->ctx, SSL3_VERSION);
 #else
       ctx_options |= SSL_OP_NO_SSLv2;
       ctx_options |= SSL_OP_NO_TLSv1;
@@ -2607,7 +2608,7 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
       ctx_options |= SSL_OP_NO_SSLv3;
 
 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
-      result = set_ssl_version_min_max(BACKEND->ctx, conn);
+      result = set_ssl_version_min_max(backend->ctx, conn);
 #else
       result = set_ssl_version_min_max_legacy(&ctx_options, conn, sockindex);
 #endif
@@ -2620,11 +2621,11 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
       return CURLE_SSL_CONNECT_ERROR;
   }
 
-  SSL_CTX_set_options(BACKEND->ctx, ctx_options);
+  SSL_CTX_set_options(backend->ctx, ctx_options);
 
 #ifdef HAS_NPN
   if(conn->bits.tls_enable_npn)
-    SSL_CTX_set_next_proto_select_cb(BACKEND->ctx, select_next_proto_cb, conn);
+    SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, conn);
 #endif
 
 #ifdef HAS_ALPN
@@ -2652,12 +2653,12 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
     /* expects length prefixed preference ordered list of protocols in wire
      * format
      */
-    SSL_CTX_set_alpn_protos(BACKEND->ctx, protocols, cur);
+    SSL_CTX_set_alpn_protos(backend->ctx, protocols, cur);
   }
 #endif
 
   if(ssl_cert || ssl_cert_type) {
-    if(!cert_stuff(conn, BACKEND->ctx, ssl_cert, ssl_cert_type,
+    if(!cert_stuff(conn, backend->ctx, ssl_cert, ssl_cert_type,
                    SSL_SET_OPTION(key), SSL_SET_OPTION(key_type),
                    SSL_SET_OPTION(key_passwd))) {
       /* failf() is already done in cert_stuff() */
@@ -2669,7 +2670,7 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
   if(!ciphers)
     ciphers = (char *)DEFAULT_CIPHER_SELECTION;
   if(ciphers) {
-    if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
+    if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) {
       failf(data, "failed setting cipher list: %s", ciphers);
       return CURLE_SSL_CIPHER;
     }
@@ -2680,7 +2681,7 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
   {
     char *ciphers13 = SSL_CONN_CONFIG(cipher_list13);
     if(ciphers13) {
-      if(!SSL_CTX_set_ciphersuites(BACKEND->ctx, ciphers13)) {
+      if(!SSL_CTX_set_ciphersuites(backend->ctx, ciphers13)) {
         failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13);
         return CURLE_SSL_CIPHER;
       }
@@ -2691,7 +2692,7 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
 
 #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
   /* OpenSSL 1.1.1 requires clients to opt-in for PHA */
-  SSL_CTX_set_post_handshake_auth(BACKEND->ctx, 1);
+  SSL_CTX_set_post_handshake_auth(backend->ctx, 1);
 #endif
 
 #ifdef USE_TLS_SRP
@@ -2700,18 +2701,18 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
 
     infof(data, "Using TLS-SRP username: %s\n", ssl_username);
 
-    if(!SSL_CTX_set_srp_username(BACKEND->ctx, ssl_username)) {
+    if(!SSL_CTX_set_srp_username(backend->ctx, ssl_username)) {
       failf(data, "Unable to set SRP user name");
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
-    if(!SSL_CTX_set_srp_password(BACKEND->ctx, SSL_SET_OPTION(password))) {
+    if(!SSL_CTX_set_srp_password(backend->ctx, SSL_SET_OPTION(password))) {
       failf(data, "failed setting SRP password");
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
     if(!SSL_CONN_CONFIG(cipher_list)) {
       infof(data, "Setting cipher list SRP\n");
 
-      if(!SSL_CTX_set_cipher_list(BACKEND->ctx, "SRP")) {
+      if(!SSL_CTX_set_cipher_list(backend->ctx, "SRP")) {
         failf(data, "failed setting SRP cipher list");
         return CURLE_SSL_CIPHER;
       }
@@ -2719,10 +2720,37 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
   }
 #endif
 
+#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
+  /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */
+  if(ssl_cafile) {
+    if(!SSL_CTX_load_verify_file(backend->ctx, ssl_cafile)) {
+      if(verifypeer) {
+        /* Fail if we insist on successfully verifying the server. */
+        failf(data, "error setting certificate file: %s", ssl_cafile);
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+      /* Continue with a warning if no certificate verification is required. */
+      infof(data, "error setting certificate file, continuing anyway\n");
+    }
+    infof(data, "  CAfile: %s\n", ssl_cafile);
+  }
+  if(ssl_capath) {
+    if(!SSL_CTX_load_verify_dir(backend->ctx, ssl_capath)) {
+      if(verifypeer) {
+        /* Fail if we insist on successfully verifying the server. */
+        failf(data, "error setting certificate path: %s", ssl_capath);
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+      /* Continue with a warning if no certificate verification is required. */
+      infof(data, "error setting certificate path, continuing anyway\n");
+    }
+    infof(data, "  CApath: %s\n", ssl_capath);
+  }
+#else
   if(ssl_cafile || ssl_capath) {
     /* tell SSL where to find CA certificates that are used to verify
        the servers certificate. */
-    if(!SSL_CTX_load_verify_locations(BACKEND->ctx, ssl_cafile, ssl_capath)) {
+    if(!SSL_CTX_load_verify_locations(backend->ctx, ssl_cafile, ssl_capath)) {
       if(verifypeer) {
         /* Fail if we insist on successfully verifying the server. */
         failf(data, "error setting certificate verify locations:\n"
@@ -2746,18 +2774,20 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
           ssl_cafile ? ssl_cafile : "none",
           ssl_capath ? ssl_capath : "none");
   }
+#endif
+
 #ifdef CURL_CA_FALLBACK
   else if(verifypeer) {
     /* verifying the peer without any CA certificates won't
        work so use openssl's built in default as fallback */
-    SSL_CTX_set_default_verify_paths(BACKEND->ctx);
+    SSL_CTX_set_default_verify_paths(backend->ctx);
   }
 #endif
 
   if(ssl_crlfile) {
     /* tell SSL where to find CRL file that is used to check certificate
      * revocation */
-    lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(BACKEND->ctx),
+    lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(backend->ctx),
                                  X509_LOOKUP_file());
     if(!lookup ||
        (!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) {
@@ -2766,7 +2796,7 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
     }
     /* Everything is fine. */
     infof(data, "successfully load CRL file:\n");
-    X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx),
+    X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx),
                          X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
 
     infof(data, "  CRLfile: %s\n", ssl_crlfile);
@@ -2781,7 +2811,7 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
        https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
     */
 #if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS)
-    X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx),
+    X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx),
                          X509_V_FLAG_TRUSTED_FIRST);
 #endif
 #ifdef X509_V_FLAG_PARTIAL_CHAIN
@@ -2790,7 +2820,7 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
          trust-anchors, in the same way as self-signed root CA certificates
          are. This allows users to verify servers using the intermediate cert
          only, instead of needing the whole chain. */
-      X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx),
+      X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx),
                            X509_V_FLAG_PARTIAL_CHAIN);
     }
 #endif
@@ -2800,13 +2830,13 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
    * fail to connect if the verification fails, or if it should continue
    * anyway. In the latter case the result of the verification is checked with
    * SSL_get_verify_result() below. */
-  SSL_CTX_set_verify(BACKEND->ctx,
+  SSL_CTX_set_verify(backend->ctx,
                      verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
 
   /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */
 #if defined(ENABLE_SSLKEYLOGFILE) && defined(HAVE_KEYLOG_CALLBACK)
   if(keylog_file_fp) {
-    SSL_CTX_set_keylog_callback(BACKEND->ctx, ossl_keylog_callback);
+    SSL_CTX_set_keylog_callback(backend->ctx, ossl_keylog_callback);
   }
 #endif
 
@@ -2814,14 +2844,14 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
    * callback. Use the "external storage" mode to avoid that OpenSSL creates
    * an internal session cache.
    */
-  SSL_CTX_set_session_cache_mode(BACKEND->ctx,
+  SSL_CTX_set_session_cache_mode(backend->ctx,
       SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
-  SSL_CTX_sess_set_new_cb(BACKEND->ctx, ossl_new_session_cb);
+  SSL_CTX_sess_set_new_cb(backend->ctx, ossl_new_session_cb);
 
   /* give application a chance to interfere with SSL set up. */
   if(data->set.ssl.fsslctx) {
     Curl_set_in_callback(data, true);
-    result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx,
+    result = (*data->set.ssl.fsslctx)(data, backend->ctx,
                                       data->set.ssl.fsslctxp);
     Curl_set_in_callback(data, false);
     if(result) {
@@ -2831,10 +2861,10 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
   }
 
   /* Lets make an SSL structure */
-  if(BACKEND->handle)
-    SSL_free(BACKEND->handle);
-  BACKEND->handle = SSL_new(BACKEND->ctx);
-  if(!BACKEND->handle) {
+  if(backend->handle)
+    SSL_free(backend->handle);
+  backend->handle = SSL_new(backend->ctx);
+  if(!backend->handle) {
     failf(data, "SSL: couldn't create a context (handle)!");
     return CURLE_OUT_OF_MEMORY;
   }
@@ -2842,23 +2872,23 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
 #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
     !defined(OPENSSL_NO_OCSP)
   if(SSL_CONN_CONFIG(verifystatus))
-    SSL_set_tlsext_status_type(BACKEND->handle, TLSEXT_STATUSTYPE_ocsp);
+    SSL_set_tlsext_status_type(backend->handle, TLSEXT_STATUSTYPE_ocsp);
 #endif
 
 #if defined(OPENSSL_IS_BORINGSSL) && defined(ALLOW_RENEG)
-  SSL_set_renegotiate_mode(BACKEND->handle, ssl_renegotiate_freely);
+  SSL_set_renegotiate_mode(backend->handle, ssl_renegotiate_freely);
 #endif
 
-  SSL_set_connect_state(BACKEND->handle);
+  SSL_set_connect_state(backend->handle);
 
-  BACKEND->server_cert = 0x0;
+  backend->server_cert = 0x0;
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
   if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
 #ifdef ENABLE_IPV6
      (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
 #endif
      sni &&
-     !SSL_set_tlsext_host_name(BACKEND->handle, hostname))
+     !SSL_set_tlsext_host_name(backend->handle, hostname))
     infof(data, "WARNING: failed to configure server name indication (SNI) "
           "TLS extension\n");
 #endif
@@ -2872,14 +2902,14 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
     if(connectdata_idx >= 0 && sockindex_idx >= 0) {
       /* Store the data needed for the "new session" callback.
        * The sockindex is stored as a pointer to an array element. */
-      SSL_set_ex_data(BACKEND->handle, connectdata_idx, conn);
-      SSL_set_ex_data(BACKEND->handle, sockindex_idx, conn->sock + sockindex);
+      SSL_set_ex_data(backend->handle, connectdata_idx, conn);
+      SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex);
     }
 
     Curl_ssl_sessionid_lock(conn);
     if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
       /* we got a session id, use it! */
-      if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
+      if(!SSL_set_session(backend->handle, ssl_sessionid)) {
         Curl_ssl_sessionid_unlock(conn);
         failf(data, "SSL: SSL_set_session failed: %s",
               ossl_strerror(ERR_get_error(), error_buffer,
@@ -2899,9 +2929,9 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
     DEBUGASSERT(handle != NULL);
     DEBUGASSERT(bio != NULL);
     BIO_set_ssl(bio, handle, FALSE);
-    SSL_set_bio(BACKEND->handle, bio, bio);
+    SSL_set_bio(backend->handle, bio, bio);
   }
-  else if(!SSL_set_fd(BACKEND->handle, (int)sockfd)) {
+  else if(!SSL_set_fd(backend->handle, (int)sockfd)) {
     /* pass the raw socket into the SSL layers */
     failf(data, "SSL: SSL_set_fd failed: %s",
           ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)));
@@ -2920,24 +2950,25 @@ static CURLcode ossl_connect_step2(struct connectdata 
*conn, int sockindex)
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   long * const certverifyresult = SSL_IS_PROXY() ?
     &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+  struct ssl_backend_data *backend = connssl->backend;
   DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
               || ssl_connect_2_reading == connssl->connecting_state
               || ssl_connect_2_writing == connssl->connecting_state);
 
   ERR_clear_error();
 
-  err = SSL_connect(BACKEND->handle);
+  err = SSL_connect(backend->handle);
   /* If keylogging is enabled but the keylog callback is not supported then log
      secrets here, immediately after SSL_connect by using tap_ssl_key. */
 #if defined(ENABLE_SSLKEYLOGFILE) && !defined(HAVE_KEYLOG_CALLBACK)
-  tap_ssl_key(BACKEND->handle, &BACKEND->tap_state);
+  tap_ssl_key(backend->handle, &backend->tap_state);
 #endif
 
   /* 1  is fine
      0  is "not successful but was shut down controlled"
      <0 is "handshake was not successful, because a fatal error occurred" */
   if(1 != err) {
-    int detail = SSL_get_error(BACKEND->handle, err);
+    int detail = SSL_get_error(backend->handle, err);
 
     if(SSL_ERROR_WANT_READ == detail) {
       connssl->connecting_state = ssl_connect_2_reading;
@@ -2977,7 +3008,7 @@ static CURLcode ossl_connect_step2(struct connectdata 
*conn, int sockindex)
          (reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
         result = CURLE_PEER_FAILED_VERIFICATION;
 
-        lerr = SSL_get_verify_result(BACKEND->handle);
+        lerr = SSL_get_verify_result(backend->handle);
         if(lerr != X509_V_OK) {
           *certverifyresult = lerr;
           msnprintf(error_buffer, sizeof(error_buffer),
@@ -3026,8 +3057,8 @@ static CURLcode ossl_connect_step2(struct connectdata 
*conn, int sockindex)
 
     /* Informational message */
     infof(data, "SSL connection using %s / %s\n",
-          get_ssl_version_txt(BACKEND->handle),
-          SSL_get_cipher(BACKEND->handle));
+          get_ssl_version_txt(backend->handle),
+          SSL_get_cipher(backend->handle));
 
 #ifdef HAS_ALPN
     /* Sets data and len to negotiated protocol, len is 0 if no protocol was
@@ -3036,7 +3067,7 @@ static CURLcode ossl_connect_step2(struct connectdata 
*conn, int sockindex)
     if(conn->bits.tls_enable_alpn) {
       const unsigned char *neg_protocol;
       unsigned int len;
-      SSL_get0_alpn_selected(BACKEND->handle, &neg_protocol, &len);
+      SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len);
       if(len != 0) {
         infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol);
 
@@ -3171,8 +3202,9 @@ static CURLcode get_cert_chain(struct connectdata *conn,
   struct Curl_easy *data = conn->data;
   numcert_t numcerts;
   BIO *mem;
+  struct ssl_backend_data *backend = connssl->backend;
 
-  sk = SSL_get_peer_cert_chain(BACKEND->handle);
+  sk = SSL_get_peer_cert_chain(backend->handle);
   if(!sk) {
     return CURLE_OUT_OF_MEMORY;
   }
@@ -3458,13 +3490,14 @@ static CURLcode servercert(struct connectdata *conn,
   long * const certverifyresult = SSL_IS_PROXY() ?
     &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
   BIO *mem = BIO_new(BIO_s_mem());
+  struct ssl_backend_data *backend = connssl->backend;
 
   if(data->set.ssl.certinfo)
     /* we've been asked to gather certificate info! */
     (void)get_cert_chain(conn, connssl);
 
-  BACKEND->server_cert = SSL_get_peer_certificate(BACKEND->handle);
-  if(!BACKEND->server_cert) {
+  backend->server_cert = SSL_get_peer_certificate(backend->handle);
+  if(!backend->server_cert) {
     BIO_free(mem);
     if(!strict)
       return CURLE_OK;
@@ -3475,19 +3508,19 @@ static CURLcode servercert(struct connectdata *conn,
 
   infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server");
 
-  rc = x509_name_oneline(X509_get_subject_name(BACKEND->server_cert),
+  rc = x509_name_oneline(X509_get_subject_name(backend->server_cert),
                          buffer, sizeof(buffer));
   infof(data, " subject: %s\n", rc?"[NONE]":buffer);
 
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
   {
     long len;
-    ASN1_TIME_print(mem, X509_get0_notBefore(BACKEND->server_cert));
+    ASN1_TIME_print(mem, X509_get0_notBefore(backend->server_cert));
     len = BIO_get_mem_data(mem, (char **) &ptr);
     infof(data, " start date: %.*s\n", len, ptr);
     (void)BIO_reset(mem);
 
-    ASN1_TIME_print(mem, X509_get0_notAfter(BACKEND->server_cert));
+    ASN1_TIME_print(mem, X509_get0_notAfter(backend->server_cert));
     len = BIO_get_mem_data(mem, (char **) &ptr);
     infof(data, " expire date: %.*s\n", len, ptr);
     (void)BIO_reset(mem);
@@ -3497,15 +3530,15 @@ static CURLcode servercert(struct connectdata *conn,
   BIO_free(mem);
 
   if(SSL_CONN_CONFIG(verifyhost)) {
-    result = verifyhost(conn, BACKEND->server_cert);
+    result = verifyhost(conn, backend->server_cert);
     if(result) {
-      X509_free(BACKEND->server_cert);
-      BACKEND->server_cert = NULL;
+      X509_free(backend->server_cert);
+      backend->server_cert = NULL;
       return result;
     }
   }
 
-  rc = x509_name_oneline(X509_get_issuer_name(BACKEND->server_cert),
+  rc = x509_name_oneline(X509_get_issuer_name(backend->server_cert),
                          buffer, sizeof(buffer));
   if(rc) {
     if(strict)
@@ -3527,8 +3560,8 @@ static CURLcode servercert(struct connectdata *conn,
               " error %s",
               ossl_strerror(ERR_get_error(), error_buffer,
                             sizeof(error_buffer)) );
-        X509_free(BACKEND->server_cert);
-        BACKEND->server_cert = NULL;
+        X509_free(backend->server_cert);
+        backend->server_cert = NULL;
         return CURLE_OUT_OF_MEMORY;
       }
 
@@ -3537,8 +3570,8 @@ static CURLcode servercert(struct connectdata *conn,
           failf(data, "SSL: Unable to open issuer cert (%s)",
                 SSL_SET_OPTION(issuercert));
         BIO_free(fp);
-        X509_free(BACKEND->server_cert);
-        BACKEND->server_cert = NULL;
+        X509_free(backend->server_cert);
+        backend->server_cert = NULL;
         return CURLE_SSL_ISSUER_ERROR;
       }
 
@@ -3549,19 +3582,19 @@ static CURLcode servercert(struct connectdata *conn,
                 SSL_SET_OPTION(issuercert));
         BIO_free(fp);
         X509_free(issuer);
-        X509_free(BACKEND->server_cert);
-        BACKEND->server_cert = NULL;
+        X509_free(backend->server_cert);
+        backend->server_cert = NULL;
         return CURLE_SSL_ISSUER_ERROR;
       }
 
-      if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) {
+      if(X509_check_issued(issuer, backend->server_cert) != X509_V_OK) {
         if(strict)
           failf(data, "SSL: Certificate issuer check failed (%s)",
                 SSL_SET_OPTION(issuercert));
         BIO_free(fp);
         X509_free(issuer);
-        X509_free(BACKEND->server_cert);
-        BACKEND->server_cert = NULL;
+        X509_free(backend->server_cert);
+        backend->server_cert = NULL;
         return CURLE_SSL_ISSUER_ERROR;
       }
 
@@ -3571,7 +3604,7 @@ static CURLcode servercert(struct connectdata *conn,
       X509_free(issuer);
     }
 
-    lerr = *certverifyresult = SSL_get_verify_result(BACKEND->handle);
+    lerr = *certverifyresult = SSL_get_verify_result(backend->handle);
 
     if(*certverifyresult != X509_V_OK) {
       if(SSL_CONN_CONFIG(verifypeer)) {
@@ -3596,8 +3629,8 @@ static CURLcode servercert(struct connectdata *conn,
   if(SSL_CONN_CONFIG(verifystatus)) {
     result = verifystatus(conn, connssl);
     if(result) {
-      X509_free(BACKEND->server_cert);
-      BACKEND->server_cert = NULL;
+      X509_free(backend->server_cert);
+      backend->server_cert = NULL;
       return result;
     }
   }
@@ -3610,13 +3643,13 @@ static CURLcode servercert(struct connectdata *conn,
   ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
                          data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
   if(!result && ptr) {
-    result = pkp_pin_peer_pubkey(data, BACKEND->server_cert, ptr);
+    result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
     if(result)
       failf(data, "SSL: public key does not match pinned public key!");
   }
 
-  X509_free(BACKEND->server_cert);
-  BACKEND->server_cert = NULL;
+  X509_free(backend->server_cert);
+  backend->server_cert = NULL;
   connssl->connecting_state = ssl_connect_done;
 
   return result;
@@ -3810,14 +3843,15 @@ static ssize_t ossl_send(struct connectdata *conn,
   int memlen;
   int rc;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
   ERR_clear_error();
 
   memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
-  rc = SSL_write(BACKEND->handle, mem, memlen);
+  rc = SSL_write(backend->handle, mem, memlen);
 
   if(rc <= 0) {
-    err = SSL_get_error(BACKEND->handle, rc);
+    err = SSL_get_error(backend->handle, rc);
 
     switch(err) {
     case SSL_ERROR_WANT_READ:
@@ -3884,14 +3918,15 @@ static ssize_t ossl_recv(struct connectdata *conn, /* 
connection data */
   ssize_t nread;
   int buffsize;
   struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct ssl_backend_data *backend = connssl->backend;
 
   ERR_clear_error();
 
   buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
-  nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize);
+  nread = (ssize_t)SSL_read(backend->handle, buf, buffsize);
   if(nread <= 0) {
     /* failed SSL_read */
-    int err = SSL_get_error(BACKEND->handle, (int)nread);
+    int err = SSL_get_error(backend->handle, (int)nread);
 
     switch(err) {
     case SSL_ERROR_NONE: /* this is not an error */
@@ -4097,8 +4132,9 @@ static void *Curl_ossl_get_internals(struct 
ssl_connect_data *connssl,
                                      CURLINFO info)
 {
   /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
+  struct ssl_backend_data *backend = connssl->backend;
   return info == CURLINFO_TLS_SESSION ?
-         (void *)BACKEND->ctx : (void *)BACKEND->handle;
+         (void *)backend->ctx : (void *)backend->handle;
 }
 
 const struct Curl_ssl Curl_ssl_openssl = {
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index f665ee340..49659bb7a 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -520,8 +520,15 @@ schannel_connect_step1(struct connectdata *conn, int 
sockindex)
         DEBUGF(infof(data, "schannel: disabled server certificate revocation "
                      "checks\n"));
       }
+      else if(data->set.ssl.revoke_best_effort) {
+        schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+          SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN;
+
+        DEBUGF(infof(data, "schannel: ignore revocation offline errors"));
+      }
       else {
         schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
+
         DEBUGF(infof(data,
                      "schannel: checking server certificate revocation\n"));
       }
@@ -578,11 +585,12 @@ schannel_connect_step1(struct connectdata *conn, int 
sockindex)
     /* client certificate */
     if(data->set.ssl.cert) {
       DWORD cert_store_name;
-      TCHAR *cert_store_path;
+      TCHAR *cert_store_path = NULL;
       TCHAR *cert_thumbprint_str;
       CRYPT_HASH_BLOB cert_thumbprint;
       BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN];
       HCERTSTORE cert_store;
+      FILE *fInCert = NULL;
 
       TCHAR *cert_path = Curl_convert_UTF8_to_tchar(data->set.ssl.cert);
       if(!cert_path)
@@ -590,54 +598,143 @@ schannel_connect_step1(struct connectdata *conn, int 
sockindex)
 
       result = get_cert_location(cert_path, &cert_store_name,
                                  &cert_store_path, &cert_thumbprint_str);
-      if(result != CURLE_OK) {
-        failf(data, "schannel: Failed to get certificate location for %s",
-              cert_path);
+      if((result != CURLE_OK) && (data->set.ssl.cert[0]!='\0'))
+        fInCert = fopen(data->set.ssl.cert, "rb");
+
+      if((result != CURLE_OK) && (fInCert == NULL)) {
+        failf(data, "schannel: Failed to get certificate location"
+              " or file for %s",
+              data->set.ssl.cert);
         Curl_unicodefree(cert_path);
         return result;
       }
 
-      cert_store =
-        CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0,
-                      (HCRYPTPROV)NULL,
-                      CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name,
-                      cert_store_path);
-      if(!cert_store) {
-        failf(data, "schannel: Failed to open cert store %x %s, "
-              "last error is %x",
-              cert_store_name, cert_store_path, GetLastError());
-        free(cert_store_path);
+      if(fInCert) {
+        /* Reading a .P12 or .pfx file, like the example at bottom of
+           https://social.msdn.microsoft.com/Forums/windowsdesktop/
+           en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5
+        */
+        void *certdata = NULL;
+        long filesize = 0;
+        CRYPT_DATA_BLOB datablob;
+        WCHAR* pszPassword;
+        size_t pwd_len = 0;
+        int str_w_len = 0;
+        int continue_reading = fseek(fInCert, 0, SEEK_END) == 0;
+        if(continue_reading)
+          filesize = ftell(fInCert);
+        if(filesize < 0)
+          continue_reading = 0;
+        if(continue_reading)
+          continue_reading = fseek(fInCert, 0, SEEK_SET) == 0;
+        if(continue_reading)
+          certdata = malloc(((size_t)filesize) + 1);
+        if((certdata == NULL) ||
+           ((int) fread(certdata, (size_t)filesize, 1, fInCert) != 1))
+          continue_reading = 0;
+        fclose(fInCert);
         Curl_unicodefree(cert_path);
-        return CURLE_SSL_CERTPROBLEM;
-      }
-      free(cert_store_path);
 
-      cert_thumbprint.pbData = cert_thumbprint_data;
-      cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN;
+        if(!continue_reading) {
+          failf(data, "schannel: Failed to read cert file %s",
+                data->set.ssl.cert);
+          free(certdata);
+          return CURLE_SSL_CERTPROBLEM;
+        }
 
-      if(!CryptStringToBinary(cert_thumbprint_str, CERT_THUMBPRINT_STR_LEN,
-                              CRYPT_STRING_HEX,
-                              cert_thumbprint_data, &cert_thumbprint.cbData,
-                              NULL, NULL)) {
-        Curl_unicodefree(cert_path);
-        return CURLE_SSL_CERTPROBLEM;
-      }
+        /* Convert key-pair data to the in-memory certificate store */
+        datablob.pbData = (BYTE*)certdata;
+        datablob.cbData = (DWORD)filesize;
+
+        if(data->set.ssl.key_passwd != NULL)
+          pwd_len = strlen(data->set.ssl.key_passwd);
+        pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1));
+        if(pwd_len > 0)
+          str_w_len =
+            MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+                                data->set.ssl.key_passwd, (int)pwd_len,
+                                pszPassword, (int)(pwd_len + 1));
+
+        if((str_w_len >= 0) && (str_w_len <= (int)pwd_len))
+          pszPassword[str_w_len] = 0;
+        else
+          pszPassword[0] = 0;
+
+        cert_store = PFXImportCertStore(&datablob, pszPassword, 0);
+        free(pszPassword);
+        free(certdata);
+        if(cert_store == NULL) {
+          DWORD errorcode = GetLastError();
+          if(errorcode == ERROR_INVALID_PASSWORD)
+            failf(data, "schannel: Failed to import cert file %s, "
+                  "password is bad", data->set.ssl.cert);
+          else
+            failf(data, "schannel: Failed to import cert file %s, "
+                  "last error is 0x%x", data->set.ssl.cert, errorcode);
+          return CURLE_SSL_CERTPROBLEM;
+        }
 
-      client_certs[0] = CertFindCertificateInStore(
-        cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
-        CERT_FIND_HASH, &cert_thumbprint, NULL);
+        client_certs[0] = CertFindCertificateInStore(
+            cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
+            CERT_FIND_ANY, NULL, NULL);
 
-      Curl_unicodefree(cert_path);
+        if(client_certs[0] == NULL) {
+          failf(data, "schannel: Failed to get certificate from file %s"
+                ", last error is 0x%x",
+                data->set.ssl.cert, GetLastError());
+          CertCloseStore(cert_store, 0);
+          return CURLE_SSL_CERTPROBLEM;
+        }
 
-      if(client_certs[0]) {
         schannel_cred.cCreds = 1;
         schannel_cred.paCred = client_certs;
       }
       else {
-        /* CRYPT_E_NOT_FOUND / E_INVALIDARG */
-        return CURLE_SSL_CERTPROBLEM;
-      }
+        cert_store =
+          CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0,
+                        (HCRYPTPROV)NULL,
+                        CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name,
+                        cert_store_path);
+        if(!cert_store) {
+          failf(data, "schannel: Failed to open cert store %x %s, "
+                "last error is 0x%x",
+                cert_store_name, cert_store_path, GetLastError());
+          free(cert_store_path);
+          Curl_unicodefree(cert_path);
+          return CURLE_SSL_CERTPROBLEM;
+        }
+        free(cert_store_path);
+
+        cert_thumbprint.pbData = cert_thumbprint_data;
+        cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN;
+
+        if(!CryptStringToBinary(cert_thumbprint_str,
+                                CERT_THUMBPRINT_STR_LEN,
+                                CRYPT_STRING_HEX,
+                                cert_thumbprint_data,
+                                &cert_thumbprint.cbData,
+                                NULL, NULL)) {
+          Curl_unicodefree(cert_path);
+          CertCloseStore(cert_store, 0);
+          return CURLE_SSL_CERTPROBLEM;
+        }
+
+        client_certs[0] = CertFindCertificateInStore(
+          cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
+          CERT_FIND_HASH, &cert_thumbprint, NULL);
+
+        Curl_unicodefree(cert_path);
 
+        if(client_certs[0]) {
+          schannel_cred.cCreds = 1;
+          schannel_cred.paCred = client_certs;
+        }
+        else {
+          /* CRYPT_E_NOT_FOUND / E_INVALIDARG */
+          CertCloseStore(cert_store, 0);
+          return CURLE_SSL_CERTPROBLEM;
+        }
+      }
       CertCloseStore(cert_store, 0);
     }
 #else
@@ -1534,13 +1631,13 @@ schannel_send(struct connectdata *conn, int sockindex,
     /* send entire message or fail */
     while(len > (size_t)written) {
       ssize_t this_write;
-      timediff_t timeleft;
+      timediff_t timeout_ms;
       int what;
 
       this_write = 0;
 
-      timeleft = Curl_timeleft(conn->data, NULL, FALSE);
-      if(timeleft < 0) {
+      timeout_ms = Curl_timeleft(conn->data, NULL, FALSE);
+      if(timeout_ms < 0) {
         /* we already got the timeout */
         failf(conn->data, "schannel: timed out sending data "
               "(bytes sent: %zd)", written);
@@ -1548,8 +1645,9 @@ schannel_send(struct connectdata *conn, int sockindex,
         written = -1;
         break;
       }
-
-      what = SOCKET_WRITABLE(conn->sock[sockindex], timeleft);
+      if(!timeout_ms)
+        timeout_ms = TIMEDIFF_T_MAX;
+      what = SOCKET_WRITABLE(conn->sock[sockindex], timeout_ms);
       if(what < 0) {
         /* fatal error */
         failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
@@ -2203,7 +2301,7 @@ static void Curl_schannel_checksum(const unsigned char 
*input,
   memset(checksum, 0, checksumlen);
 
   if(!CryptAcquireContext(&hProv, NULL, NULL, provType,
-                          CRYPT_VERIFYCONTEXT))
+                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
     return; /* failed */
 
   do {
diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c
index e75132cad..3dbc11f05 100644
--- a/lib/vtls/schannel_verify.c
+++ b/lib/vtls/schannel_verify.c
@@ -636,6 +636,15 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, 
int sockindex)
       CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
       DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED);
       dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
+
+      if(data->set.ssl.revoke_best_effort) {
+        /* Ignore errors when root certificates are missing the revocation
+         * list URL, or when the list could not be downloaded because the
+         * server is currently unreachable. */
+        dwTrustErrorMask &= ~(DWORD)(CERT_TRUST_REVOCATION_STATUS_UNKNOWN |
+          CERT_TRUST_IS_OFFLINE_REVOCATION);
+      }
+
       if(dwTrustErrorMask) {
         if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED)
           failf(data, "schannel: CertGetCertificateChain trust error"
diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c
index 7dd028fb7..6b2d436fc 100644
--- a/lib/vtls/sectransp.c
+++ b/lib/vtls/sectransp.c
@@ -138,8 +138,6 @@ struct ssl_backend_data {
   size_t ssl_write_buffered_length;
 };
 
-#define BACKEND connssl->backend
-
 /* pinned public key support tests */
 
 /* version 1 supports macOS 10.12+ and iOS 10+ */
@@ -201,7 +199,8 @@ static OSStatus SocketRead(SSLConnectionRef connection,
   UInt8 *currData = (UInt8 *)data;
   /*int sock = *(int *)connection;*/
   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
-  int sock = BACKEND->ssl_sockfd;
+  struct ssl_backend_data *backend = connssl->backend;
+  int sock = backend->ssl_sockfd;
   OSStatus rtn = noErr;
   size_t bytesRead;
   ssize_t rrtn;
@@ -230,7 +229,7 @@ static OSStatus SocketRead(SSLConnectionRef connection,
             break;
           case EAGAIN:
             rtn = errSSLWouldBlock;
-            BACKEND->ssl_direction = false;
+            backend->ssl_direction = false;
             break;
           default:
             rtn = ioErr;
@@ -261,7 +260,8 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
   size_t bytesSent = 0;
   /*int sock = *(int *)connection;*/
   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
-  int sock = BACKEND->ssl_sockfd;
+  struct ssl_backend_data *backend = connssl->backend;
+  int sock = backend->ssl_sockfd;
   ssize_t length;
   size_t dataLen = *dataLength;
   const UInt8 *dataPtr = (UInt8 *)data;
@@ -281,7 +281,7 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
     theErr = errno;
     if(theErr == EAGAIN) {
       ortn = errSSLWouldBlock;
-      BACKEND->ssl_direction = true;
+      backend->ssl_direction = true;
     }
     else {
       ortn = ioErr;
@@ -1276,6 +1276,7 @@ set_ssl_version_min_max(struct connectdata *conn, int 
sockindex)
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   long ssl_version = SSL_CONN_CONFIG(version);
   long ssl_version_max = SSL_CONN_CONFIG(version_max);
   long max_supported_version_by_os;
@@ -1326,30 +1327,30 @@ set_ssl_version_min_max(struct connectdata *conn, int 
sockindex)
       return result;
     }
 
-    (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, darwin_ver_min);
-    (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, darwin_ver_max);
+    (void)SSLSetProtocolVersionMin(backend->ssl_ctx, darwin_ver_min);
+    (void)SSLSetProtocolVersionMax(backend->ssl_ctx, darwin_ver_max);
     return result;
   }
   else {
 #if CURL_SUPPORT_MAC_10_8
     long i = ssl_version;
-    (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+    (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                        kSSLProtocolAll,
                                        false);
     for(; i <= (ssl_version_max >> 16); i++) {
       switch(i) {
         case CURL_SSLVERSION_TLSv1_0:
-          (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+          (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                             kTLSProtocol1,
                                             true);
           break;
         case CURL_SSLVERSION_TLSv1_1:
-          (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+          (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                             kTLSProtocol11,
                                             true);
           break;
         case CURL_SSLVERSION_TLSv1_2:
-          (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+          (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                             kTLSProtocol12,
                                             true);
           break;
@@ -1373,6 +1374,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
   struct Curl_easy *data = conn->data;
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
   char * const ssl_cert = SSL_SET_OPTION(cert);
@@ -1395,10 +1397,10 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
 
 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
   if(SSLCreateContext != NULL) {  /* use the newer API if available */
-    if(BACKEND->ssl_ctx)
-      CFRelease(BACKEND->ssl_ctx);
-    BACKEND->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
-    if(!BACKEND->ssl_ctx) {
+    if(backend->ssl_ctx)
+      CFRelease(backend->ssl_ctx);
+    backend->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
+    if(!backend->ssl_ctx) {
       failf(data, "SSL: couldn't create a context!");
       return CURLE_OUT_OF_MEMORY;
     }
@@ -1406,9 +1408,9 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
   else {
   /* The old ST API does not exist under iOS, so don't compile it: */
 #if CURL_SUPPORT_MAC_10_8
-    if(BACKEND->ssl_ctx)
-      (void)SSLDisposeContext(BACKEND->ssl_ctx);
-    err = SSLNewContext(false, &(BACKEND->ssl_ctx));
+    if(backend->ssl_ctx)
+      (void)SSLDisposeContext(backend->ssl_ctx);
+    err = SSLNewContext(false, &(backend->ssl_ctx));
     if(err != noErr) {
       failf(data, "SSL: couldn't create a context: OSStatus %d", err);
       return CURLE_OUT_OF_MEMORY;
@@ -1416,31 +1418,31 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
 #endif /* CURL_SUPPORT_MAC_10_8 */
   }
 #else
-  if(BACKEND->ssl_ctx)
-    (void)SSLDisposeContext(BACKEND->ssl_ctx);
-  err = SSLNewContext(false, &(BACKEND->ssl_ctx));
+  if(backend->ssl_ctx)
+    (void)SSLDisposeContext(backend->ssl_ctx);
+  err = SSLNewContext(false, &(backend->ssl_ctx));
   if(err != noErr) {
     failf(data, "SSL: couldn't create a context: OSStatus %d", err);
     return CURLE_OUT_OF_MEMORY;
   }
 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
-  BACKEND->ssl_write_buffered_length = 0UL; /* reset buffered write length */
+  backend->ssl_write_buffered_length = 0UL; /* reset buffered write length */
 
   /* check to see if we've been told to use an explicit SSL/TLS version */
 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
   if(SSLSetProtocolVersionMax != NULL) {
     switch(conn->ssl_config.version) {
     case CURL_SSLVERSION_TLSv1:
-      (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kTLSProtocol1);
+      (void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1);
 #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
       if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
-        (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol13);
+        (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol13);
       }
       else {
-        (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
+        (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12);
       }
 #else
-      (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
+      (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12);
 #endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
           HAVE_BUILTIN_AVAILABLE == 1 */
       break;
@@ -1456,20 +1458,20 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
         break;
       }
     case CURL_SSLVERSION_SSLv3:
-      err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol3);
+      err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol3);
       if(err != noErr) {
         failf(data, "Your version of the OS does not support SSLv3");
         return CURLE_SSL_CONNECT_ERROR;
       }
-      (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol3);
+      (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol3);
       break;
     case CURL_SSLVERSION_SSLv2:
-      err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol2);
+      err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol2);
       if(err != noErr) {
         failf(data, "Your version of the OS does not support SSLv2");
         return CURLE_SSL_CONNECT_ERROR;
       }
-      (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol2);
+      (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol2);
       break;
     default:
       failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
@@ -1478,19 +1480,19 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
   }
   else {
 #if CURL_SUPPORT_MAC_10_8
-    (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+    (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                        kSSLProtocolAll,
                                        false);
     switch(conn->ssl_config.version) {
     case CURL_SSLVERSION_DEFAULT:
     case CURL_SSLVERSION_TLSv1:
-      (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+      (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                          kTLSProtocol1,
                                          true);
-      (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+      (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                          kTLSProtocol11,
                                          true);
-      (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+      (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                          kTLSProtocol12,
                                          true);
       break;
@@ -1505,7 +1507,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
         break;
       }
     case CURL_SSLVERSION_SSLv3:
-      err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+      err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                          kSSLProtocol3,
                                          true);
       if(err != noErr) {
@@ -1514,7 +1516,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
       }
       break;
     case CURL_SSLVERSION_SSLv2:
-      err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+      err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                          kSSLProtocol2,
                                          true);
       if(err != noErr) {
@@ -1534,12 +1536,12 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
                 " SSL/TLS version");
     return CURLE_SSL_CONNECT_ERROR;
   }
-  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, kSSLProtocolAll, false);
+  (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false);
   switch(conn->ssl_config.version) {
   case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
   case CURL_SSLVERSION_TLSv1_0:
-    (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+    (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                        kTLSProtocol1,
                                        true);
     break;
@@ -1553,7 +1555,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
     failf(data, "Your version of the OS does not support TLSv1.3");
     return CURLE_SSL_CONNECT_ERROR;
   case CURL_SSLVERSION_SSLv2:
-    err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+    err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                        kSSLProtocol2,
                                        true);
     if(err != noErr) {
@@ -1562,7 +1564,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
     }
     break;
   case CURL_SSLVERSION_SSLv3:
-    err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+    err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                        kSSLProtocol3,
                                        true);
     if(err != noErr) {
@@ -1596,7 +1598,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
       /* expects length prefixed preference ordered list of protocols in wire
        * format
        */
-      err = SSLSetALPNProtocols(BACKEND->ssl_ctx, alpnArr);
+      err = SSLSetALPNProtocols(backend->ssl_ctx, alpnArr);
       if(err != noErr)
         infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d\n",
               err);
@@ -1657,7 +1659,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
       certs_c[0] = cert_and_key;
       certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
                             &kCFTypeArrayCallBacks);
-      err = SSLSetCertificate(BACKEND->ssl_ctx, certs);
+      err = SSLSetCertificate(backend->ssl_ctx, certs);
       if(certs)
         CFRelease(certs);
       if(err != noErr) {
@@ -1720,7 +1722,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
   if(SSLSetSessionOption != NULL) {
 #endif /* CURL_BUILD_MAC */
     bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile;
-    err = SSLSetSessionOption(BACKEND->ssl_ctx,
+    err = SSLSetSessionOption(backend->ssl_ctx,
                               kSSLSessionOptionBreakOnServerAuth,
                               break_on_auth);
     if(err != noErr) {
@@ -1730,7 +1732,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
   }
   else {
 #if CURL_SUPPORT_MAC_10_8
-    err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
+    err = SSLSetEnableCertVerify(backend->ssl_ctx,
                                  conn->ssl_config.verifypeer?true:false);
     if(err != noErr) {
       failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
@@ -1739,7 +1741,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
 #endif /* CURL_SUPPORT_MAC_10_8 */
   }
 #else
-  err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
+  err = SSLSetEnableCertVerify(backend->ssl_ctx,
                                conn->ssl_config.verifypeer?true:false);
   if(err != noErr) {
     failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
@@ -1760,7 +1762,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
    * Both hostname check and SNI require SSLSetPeerDomainName().
    * Also: the verifyhost setting influences SNI usage */
   if(conn->ssl_config.verifyhost) {
-    err = SSLSetPeerDomainName(BACKEND->ssl_ctx, hostname,
+    err = SSLSetPeerDomainName(backend->ssl_ctx, hostname,
     strlen(hostname));
 
     if(err != noErr) {
@@ -1786,7 +1788,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
      higher priority, but it's probably better that we not connect at all than
      to give the user a false sense of security if the server only supports
      insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
-  err = SSLGetNumberSupportedCiphers(BACKEND->ssl_ctx, &all_ciphers_count);
+  err = SSLGetNumberSupportedCiphers(backend->ssl_ctx, &all_ciphers_count);
   if(err != noErr) {
     failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d",
           err);
@@ -1803,7 +1805,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
     failf(data, "SSL: Failed to allocate memory for allowed ciphers");
     return CURLE_OUT_OF_MEMORY;
   }
-  err = SSLGetSupportedCiphers(BACKEND->ssl_ctx, all_ciphers,
+  err = SSLGetSupportedCiphers(backend->ssl_ctx, all_ciphers,
                                &all_ciphers_count);
   if(err != noErr) {
     Curl_safefree(all_ciphers);
@@ -1890,7 +1892,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
         break;
     }
   }
-  err = SSLSetEnabledCiphers(BACKEND->ssl_ctx, allowed_ciphers,
+  err = SSLSetEnabledCiphers(backend->ssl_ctx, allowed_ciphers,
                              allowed_ciphers_count);
   Curl_safefree(all_ciphers);
   Curl_safefree(allowed_ciphers);
@@ -1903,9 +1905,9 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
   /* We want to enable 1/n-1 when using a CBC cipher unless the user
      specifically doesn't want us doing that: */
   if(SSLSetSessionOption != NULL) {
-    SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
+    SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
                       !data->set.ssl.enable_beast);
-    SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionFalseStart,
+    SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart,
                       data->set.ssl.falsestart); /* false start support */
   }
 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
@@ -1919,7 +1921,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
     if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
                               &ssl_sessionid_len, sockindex)) {
       /* we got a session id, use it! */
-      err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+      err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
       Curl_ssl_sessionid_unlock(conn);
       if(err != noErr) {
         failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
@@ -1937,7 +1939,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
                 verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
       ssl_sessionid_len = strlen(ssl_sessionid);
 
-      err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+      err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
       if(err != noErr) {
         Curl_ssl_sessionid_unlock(conn);
         failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
@@ -1954,7 +1956,7 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
     }
   }
 
-  err = SSLSetIOFuncs(BACKEND->ssl_ctx, SocketRead, SocketWrite);
+  err = SSLSetIOFuncs(backend->ssl_ctx, SocketRead, SocketWrite);
   if(err != noErr) {
     failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
     return CURLE_SSL_CONNECT_ERROR;
@@ -1964,8 +1966,8 @@ static CURLcode sectransp_connect_step1(struct 
connectdata *conn,
   /* We need to store the FD in a constant memory address, because
    * SSLSetConnection() will not copy that address. I've found that
    * conn->sock[sockindex] may change on its own. */
-  BACKEND->ssl_sockfd = sockfd;
-  err = SSLSetConnection(BACKEND->ssl_ctx, connssl);
+  backend->ssl_sockfd = sockfd;
+  err = SSLSetConnection(backend->ssl_ctx, connssl);
   if(err != noErr) {
     failf(data, "SSL: SSLSetConnection() failed: %d", err);
     return CURLE_SSL_CONNECT_ERROR;
@@ -2346,6 +2348,7 @@ sectransp_connect_step2(struct connectdata *conn, int 
sockindex)
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   OSStatus err;
   SSLCipherSuite cipher;
   SSLProtocol protocol = 0;
@@ -2357,12 +2360,12 @@ sectransp_connect_step2(struct connectdata *conn, int 
sockindex)
               || ssl_connect_2_writing == connssl->connecting_state);
 
   /* Here goes nothing: */
-  err = SSLHandshake(BACKEND->ssl_ctx);
+  err = SSLHandshake(backend->ssl_ctx);
 
   if(err != noErr) {
     switch(err) {
       case errSSLWouldBlock:  /* they're not done with us yet */
-        connssl->connecting_state = BACKEND->ssl_direction ?
+        connssl->connecting_state = backend->ssl_direction ?
             ssl_connect_2_writing : ssl_connect_2_reading;
         return CURLE_OK;
 
@@ -2371,7 +2374,7 @@ sectransp_connect_step2(struct connectdata *conn, int 
sockindex)
       case -9841:
         if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
           CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data,
-                                        BACKEND->ssl_ctx);
+                                        backend->ssl_ctx);
           if(result)
             return result;
         }
@@ -2580,7 +2583,7 @@ sectransp_connect_step2(struct connectdata *conn, int 
sockindex)
 
 #ifdef SECTRANSP_PINNEDPUBKEY
     if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) {
-      CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx,
+      CURLcode result = pkp_pin_peer_pubkey(data, backend->ssl_ctx,
                             data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]);
       if(result) {
         failf(data, "SSL: public key does not match pinned public key!");
@@ -2590,8 +2593,8 @@ sectransp_connect_step2(struct connectdata *conn, int 
sockindex)
 #endif /* SECTRANSP_PINNEDPUBKEY */
 
     /* Informational message */
-    (void)SSLGetNegotiatedCipher(BACKEND->ssl_ctx, &cipher);
-    (void)SSLGetNegotiatedProtocolVersion(BACKEND->ssl_ctx, &protocol);
+    (void)SSLGetNegotiatedCipher(backend->ssl_ctx, &cipher);
+    (void)SSLGetNegotiatedProtocolVersion(backend->ssl_ctx, &protocol);
     switch(protocol) {
       case kSSLProtocol2:
         infof(data, "SSL 2.0 connection using %s\n",
@@ -2631,7 +2634,7 @@ sectransp_connect_step2(struct connectdata *conn, int 
sockindex)
       if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
         CFArrayRef alpnArr = NULL;
         CFStringRef chosenProtocol = NULL;
-        err = SSLCopyALPNProtocols(BACKEND->ssl_ctx, &alpnArr);
+        err = SSLCopyALPNProtocols(backend->ssl_ctx, &alpnArr);
 
         if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1)
           chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0);
@@ -2674,19 +2677,20 @@ show_verbose_server_cert(struct connectdata *conn,
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   CFArrayRef server_certs = NULL;
   SecCertificateRef server_cert;
   OSStatus err;
   CFIndex i, count;
   SecTrustRef trust = NULL;
 
-  if(!BACKEND->ssl_ctx)
+  if(!backend->ssl_ctx)
     return;
 
 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
 #if CURL_BUILD_IOS
 #pragma unused(server_certs)
-  err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
+  err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
   /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
      a null trust, so be on guard for that: */
   if(err == noErr && trust) {
@@ -2712,7 +2716,7 @@ show_verbose_server_cert(struct connectdata *conn,
      Lion or later. */
   if(SecTrustEvaluateAsync != NULL) {
 #pragma unused(server_certs)
-    err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
+    err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
     /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
        a null trust, so be on guard for that: */
     if(err == noErr && trust) {
@@ -2732,7 +2736,7 @@ show_verbose_server_cert(struct connectdata *conn,
   }
   else {
 #if CURL_SUPPORT_MAC_10_8
-    err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
+    err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
     /* Just in case SSLCopyPeerCertificates() returns null too... */
     if(err == noErr && server_certs) {
       count = CFArrayGetCount(server_certs);
@@ -2754,7 +2758,7 @@ show_verbose_server_cert(struct connectdata *conn,
 #endif /* CURL_BUILD_IOS */
 #else
 #pragma unused(trust)
-  err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
+  err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
   if(err == noErr) {
     count = CFArrayGetCount(server_certs);
     for(i = 0L ; i < count ; i++) {
@@ -2933,34 +2937,36 @@ static CURLcode Curl_sectransp_connect(struct 
connectdata *conn, int sockindex)
 static void Curl_sectransp_close(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
-  if(BACKEND->ssl_ctx) {
-    (void)SSLClose(BACKEND->ssl_ctx);
+  if(backend->ssl_ctx) {
+    (void)SSLClose(backend->ssl_ctx);
 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
     if(SSLCreateContext != NULL)
-      CFRelease(BACKEND->ssl_ctx);
+      CFRelease(backend->ssl_ctx);
 #if CURL_SUPPORT_MAC_10_8
     else
-      (void)SSLDisposeContext(BACKEND->ssl_ctx);
+      (void)SSLDisposeContext(backend->ssl_ctx);
 #endif  /* CURL_SUPPORT_MAC_10_8 */
 #else
-    (void)SSLDisposeContext(BACKEND->ssl_ctx);
+    (void)SSLDisposeContext(backend->ssl_ctx);
 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
-    BACKEND->ssl_ctx = NULL;
+    backend->ssl_ctx = NULL;
   }
-  BACKEND->ssl_sockfd = 0;
+  backend->ssl_sockfd = 0;
 }
 
 static int Curl_sectransp_shutdown(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   struct Curl_easy *data = conn->data;
   ssize_t nread;
   int what;
   int rc;
   char buf[120];
 
-  if(!BACKEND->ssl_ctx)
+  if(!backend->ssl_ctx)
     return 0;
 
 #ifndef CURL_DISABLE_FTP
@@ -3033,11 +3039,12 @@ static size_t Curl_sectransp_version(char *buffer, 
size_t size)
 static int Curl_sectransp_check_cxn(struct connectdata *conn)
 {
   struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+  struct ssl_backend_data *backend = connssl->backend;
   OSStatus err;
   SSLSessionState state;
 
-  if(BACKEND->ssl_ctx) {
-    err = SSLGetSessionState(BACKEND->ssl_ctx, &state);
+  if(backend->ssl_ctx) {
+    err = SSLGetSessionState(backend->ssl_ctx, &state);
     if(err == noErr)
       return state == kSSLConnected || state == kSSLHandshake;
     return -1;
@@ -3049,11 +3056,12 @@ static bool Curl_sectransp_data_pending(const struct 
connectdata *conn,
                                         int connindex)
 {
   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+  struct ssl_backend_data *backend = connssl->backend;
   OSStatus err;
   size_t buffer;
 
-  if(BACKEND->ssl_ctx) {  /* SSL is in use */
-    err = SSLGetBufferedReadSize(BACKEND->ssl_ctx, &buffer);
+  if(backend->ssl_ctx) {  /* SSL is in use */
+    err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer);
     if(err == noErr)
       return buffer > 0UL;
     return false;
@@ -3119,6 +3127,7 @@ static ssize_t sectransp_send(struct connectdata *conn,
 {
   /*struct Curl_easy *data = conn->data;*/
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   size_t processed = 0UL;
   OSStatus err;
 
@@ -3137,15 +3146,15 @@ static ssize_t sectransp_send(struct connectdata *conn,
      over again with no new data until it quits returning errSSLWouldBlock. */
 
   /* Do we have buffered data to write from the last time we were called? */
-  if(BACKEND->ssl_write_buffered_length) {
+  if(backend->ssl_write_buffered_length) {
     /* Write the buffered data: */
-    err = SSLWrite(BACKEND->ssl_ctx, NULL, 0UL, &processed);
+    err = SSLWrite(backend->ssl_ctx, NULL, 0UL, &processed);
     switch(err) {
       case noErr:
         /* processed is always going to be 0 because we didn't write to
            the buffer, so return how much was written to the socket */
-        processed = BACKEND->ssl_write_buffered_length;
-        BACKEND->ssl_write_buffered_length = 0UL;
+        processed = backend->ssl_write_buffered_length;
+        backend->ssl_write_buffered_length = 0UL;
         break;
       case errSSLWouldBlock: /* argh, try again */
         *curlcode = CURLE_AGAIN;
@@ -3158,13 +3167,13 @@ static ssize_t sectransp_send(struct connectdata *conn,
   }
   else {
     /* We've got new data to write: */
-    err = SSLWrite(BACKEND->ssl_ctx, mem, len, &processed);
+    err = SSLWrite(backend->ssl_ctx, mem, len, &processed);
     if(err != noErr) {
       switch(err) {
         case errSSLWouldBlock:
           /* Data was buffered but not sent, we have to tell the caller
              to try sending again, and remember how much was buffered */
-          BACKEND->ssl_write_buffered_length = len;
+          backend->ssl_write_buffered_length = len;
           *curlcode = CURLE_AGAIN;
           return -1L;
         default:
@@ -3185,11 +3194,12 @@ static ssize_t sectransp_recv(struct connectdata *conn,
 {
   /*struct Curl_easy *data = conn->data;*/
   struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct ssl_backend_data *backend = connssl->backend;
   size_t processed = 0UL;
   OSStatus err;
 
   again:
-  err = SSLRead(BACKEND->ssl_ctx, buf, buffersize, &processed);
+  err = SSLRead(backend->ssl_ctx, buf, buffersize, &processed);
 
   if(err != noErr) {
     switch(err) {
@@ -3215,7 +3225,7 @@ static ssize_t sectransp_recv(struct connectdata *conn,
       case -9841:
         if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
           CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), conn->data,
-                                        BACKEND->ssl_ctx);
+                                        backend->ssl_ctx);
           if(result)
             return result;
         }
@@ -3233,8 +3243,9 @@ static ssize_t sectransp_recv(struct connectdata *conn,
 static void *Curl_sectransp_get_internals(struct ssl_connect_data *connssl,
                                           CURLINFO info UNUSED_PARAM)
 {
+  struct ssl_backend_data *backend = connssl->backend;
   (void)info;
-  return BACKEND->ssl_ctx;
+  return backend->ssl_ctx;
 }
 
 const struct Curl_ssl Curl_ssl_sectransp = {
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index dfefa1bd5..f1b525227 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -174,6 +174,9 @@ int Curl_ssl_init(void)
   return Curl_ssl->init();
 }
 
+#if defined(CURL_WITH_MULTI_SSL)
+static const struct Curl_ssl Curl_ssl_multi;
+#endif
 
 /* Global cleanup */
 void Curl_ssl_cleanup(void)
@@ -181,6 +184,9 @@ void Curl_ssl_cleanup(void)
   if(init_ssl) {
     /* only cleanup if we did a previous init */
     Curl_ssl->cleanup();
+#if defined(CURL_WITH_MULTI_SSL)
+    Curl_ssl = &Curl_ssl_multi;
+#endif
     init_ssl = FALSE;
   }
 }
@@ -489,6 +495,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
   store->scheme = conn->handler->scheme;
 
   if(!Curl_clone_primary_ssl_config(ssl_config, &store->ssl_config)) {
+    Curl_free_primary_ssl_config(&store->ssl_config);
     store->sessionid = NULL; /* let caller free sessionid */
     free(clone_host);
     free(clone_conn_to_host);
diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c
index 8c2d3f4a2..5040b0592 100644
--- a/lib/vtls/wolfssl.c
+++ b/lib/vtls/wolfssl.c
@@ -96,12 +96,9 @@ struct ssl_backend_data {
   SSL*     handle;
 };
 
-#define BACKEND connssl->backend
-
 static Curl_recv wolfssl_recv;
 static Curl_send wolfssl_send;
 
-
 static int do_file_type(const char *type)
 {
   if(!type || !type[0])
@@ -124,6 +121,7 @@ wolfssl_connect_step1(struct connectdata *conn,
   char *ciphers;
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   SSL_METHOD* req_method = NULL;
   curl_socket_t sockfd = conn->sock[sockindex];
 #ifdef HAVE_SNI
@@ -203,11 +201,11 @@ wolfssl_connect_step1(struct connectdata *conn,
     return CURLE_OUT_OF_MEMORY;
   }
 
-  if(BACKEND->ctx)
-    SSL_CTX_free(BACKEND->ctx);
-  BACKEND->ctx = SSL_CTX_new(req_method);
+  if(backend->ctx)
+    SSL_CTX_free(backend->ctx);
+  backend->ctx = SSL_CTX_new(req_method);
 
-  if(!BACKEND->ctx) {
+  if(!backend->ctx) {
     failf(data, "SSL: couldn't create a context!");
     return CURLE_OUT_OF_MEMORY;
   }
@@ -222,11 +220,11 @@ wolfssl_connect_step1(struct connectdata *conn,
      * defaults to TLS 1.1) so we have this short circuit evaluation to find
      * the minimum supported TLS version.
     */
-    if((wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1) != 1) &&
-       (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_1) != 1) &&
-       (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_2) != 1)
+    if((wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1) != 1) &&
+       (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_1) != 1) &&
+       (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_2) != 1)
 #ifdef WOLFSSL_TLS13
-       && (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_3) != 1)
+       && (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_3) != 1)
 #endif
       ) {
       failf(data, "SSL: couldn't set the minimum protocol version");
@@ -238,7 +236,7 @@ wolfssl_connect_step1(struct connectdata *conn,
 
   ciphers = SSL_CONN_CONFIG(cipher_list);
   if(ciphers) {
-    if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
+    if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) {
       failf(data, "failed setting cipher list: %s", ciphers);
       return CURLE_SSL_CIPHER;
     }
@@ -248,7 +246,7 @@ wolfssl_connect_step1(struct connectdata *conn,
 #ifndef NO_FILESYSTEM
   /* load trusted cacert */
   if(SSL_CONN_CONFIG(CAfile)) {
-    if(1 != SSL_CTX_load_verify_locations(BACKEND->ctx,
+    if(1 != SSL_CTX_load_verify_locations(backend->ctx,
                                       SSL_CONN_CONFIG(CAfile),
                                       SSL_CONN_CONFIG(CApath))) {
       if(SSL_CONN_CONFIG(verifypeer)) {
@@ -285,7 +283,7 @@ wolfssl_connect_step1(struct connectdata *conn,
   if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
     int file_type = do_file_type(SSL_SET_OPTION(cert_type));
 
-    if(SSL_CTX_use_certificate_file(BACKEND->ctx, SSL_SET_OPTION(cert),
+    if(SSL_CTX_use_certificate_file(backend->ctx, SSL_SET_OPTION(cert),
                                      file_type) != 1) {
       failf(data, "unable to use client certificate (no key or wrong pass"
             " phrase?)");
@@ -293,7 +291,7 @@ wolfssl_connect_step1(struct connectdata *conn,
     }
 
     file_type = do_file_type(SSL_SET_OPTION(key_type));
-    if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key),
+    if(SSL_CTX_use_PrivateKey_file(backend->ctx, SSL_SET_OPTION(key),
                                     file_type) != 1) {
       failf(data, "unable to set private key");
       return CURLE_SSL_CONNECT_ERROR;
@@ -305,7 +303,7 @@ wolfssl_connect_step1(struct connectdata *conn,
    * fail to connect if the verification fails, or if it should continue
    * anyway. In the latter case the result of the verification is checked with
    * SSL_get_verify_result() below. */
-  SSL_CTX_set_verify(BACKEND->ctx,
+  SSL_CTX_set_verify(backend->ctx,
                      SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER:
                                                  SSL_VERIFY_NONE,
                      NULL);
@@ -324,7 +322,7 @@ wolfssl_connect_step1(struct connectdata *conn,
 #ifdef ENABLE_IPV6
        (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) &&
 #endif
-       (wolfSSL_CTX_UseSNI(BACKEND->ctx, WOLFSSL_SNI_HOST_NAME, hostname,
+       (wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, hostname,
                           (unsigned short)hostname_len) != 1)) {
       infof(data, "WARNING: failed to configure server name indication (SNI) "
             "TLS extension\n");
@@ -334,7 +332,7 @@ wolfssl_connect_step1(struct connectdata *conn,
 
   /* give application a chance to interfere with SSL set up. */
   if(data->set.ssl.fsslctx) {
-    CURLcode result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx,
+    CURLcode result = (*data->set.ssl.fsslctx)(data, backend->ctx,
                                                data->set.ssl.fsslctxp);
     if(result) {
       failf(data, "error signaled by ssl ctx callback");
@@ -352,10 +350,10 @@ wolfssl_connect_step1(struct connectdata *conn,
 #endif
 
   /* Let's make an SSL structure */
-  if(BACKEND->handle)
-    SSL_free(BACKEND->handle);
-  BACKEND->handle = SSL_new(BACKEND->ctx);
-  if(!BACKEND->handle) {
+  if(backend->handle)
+    SSL_free(backend->handle);
+  backend->handle = SSL_new(backend->ctx);
+  if(!backend->handle) {
     failf(data, "SSL: couldn't create a context (handle)!");
     return CURLE_OUT_OF_MEMORY;
   }
@@ -378,7 +376,7 @@ wolfssl_connect_step1(struct connectdata *conn,
     strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1);
     infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
 
-    if(wolfSSL_UseALPN(BACKEND->handle, protocols,
+    if(wolfSSL_UseALPN(backend->handle, protocols,
                        (unsigned)strlen(protocols),
                        WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) {
       failf(data, "SSL: failed setting ALPN protocols");
@@ -394,11 +392,11 @@ wolfssl_connect_step1(struct connectdata *conn,
     Curl_ssl_sessionid_lock(conn);
     if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
       /* we got a session id, use it! */
-      if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
+      if(!SSL_set_session(backend->handle, ssl_sessionid)) {
         char error_buffer[WOLFSSL_MAX_ERROR_SZ];
         Curl_ssl_sessionid_unlock(conn);
         failf(data, "SSL: SSL_set_session failed: %s",
-              ERR_error_string(SSL_get_error(BACKEND->handle, 0),
+              ERR_error_string(SSL_get_error(backend->handle, 0),
                                error_buffer));
         return CURLE_SSL_CONNECT_ERROR;
       }
@@ -409,7 +407,7 @@ wolfssl_connect_step1(struct connectdata *conn,
   }
 
   /* pass the raw socket into the SSL layer */
-  if(!SSL_set_fd(BACKEND->handle, (int)sockfd)) {
+  if(!SSL_set_fd(backend->handle, (int)sockfd)) {
     failf(data, "SSL: SSL_set_fd failed");
     return CURLE_SSL_CONNECT_ERROR;
   }
@@ -426,6 +424,7 @@ wolfssl_connect_step2(struct connectdata *conn,
   int ret = -1;
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
   const char * const dispname = SSL_IS_PROXY() ?
@@ -439,15 +438,15 @@ wolfssl_connect_step2(struct connectdata *conn,
 
   /* Enable RFC2818 checks */
   if(SSL_CONN_CONFIG(verifyhost)) {
-    ret = wolfSSL_check_domain_name(BACKEND->handle, hostname);
+    ret = wolfSSL_check_domain_name(backend->handle, hostname);
     if(ret == SSL_FAILURE)
       return CURLE_OUT_OF_MEMORY;
   }
 
-  ret = SSL_connect(BACKEND->handle);
+  ret = SSL_connect(backend->handle);
   if(ret != 1) {
     char error_buffer[WOLFSSL_MAX_ERROR_SZ];
-    int  detail = SSL_get_error(BACKEND->handle, ret);
+    int  detail = SSL_get_error(backend->handle, ret);
 
     if(SSL_ERROR_WANT_READ == detail) {
       connssl->connecting_state = ssl_connect_2_reading;
@@ -516,7 +515,7 @@ wolfssl_connect_step2(struct connectdata *conn,
     curl_asn1Element *pubkey;
     CURLcode result;
 
-    x509 = SSL_get_peer_certificate(BACKEND->handle);
+    x509 = SSL_get_peer_certificate(backend->handle);
     if(!x509) {
       failf(data, "SSL: failed retrieving server certificate");
       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
@@ -558,7 +557,7 @@ wolfssl_connect_step2(struct connectdata *conn,
     char *protocol = NULL;
     unsigned short protocol_len = 0;
 
-    rc = wolfSSL_ALPN_GetProtocol(BACKEND->handle, &protocol, &protocol_len);
+    rc = wolfSSL_ALPN_GetProtocol(backend->handle, &protocol, &protocol_len);
 
     if(rc == SSL_SUCCESS) {
       infof(data, "ALPN, server accepted to use %.*s\n", protocol_len,
@@ -592,8 +591,8 @@ wolfssl_connect_step2(struct connectdata *conn,
   connssl->connecting_state = ssl_connect_3;
 #if (LIBWOLFSSL_VERSION_HEX >= 0x03009010)
   infof(data, "SSL connection using %s / %s\n",
-        wolfSSL_get_version(BACKEND->handle),
-        wolfSSL_get_cipher_name(BACKEND->handle));
+        wolfSSL_get_version(backend->handle),
+        wolfSSL_get_cipher_name(backend->handle));
 #else
   infof(data, "SSL connected\n");
 #endif
@@ -609,6 +608,7 @@ wolfssl_connect_step3(struct connectdata *conn,
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
@@ -617,7 +617,7 @@ wolfssl_connect_step3(struct connectdata *conn,
     SSL_SESSION *our_ssl_sessionid;
     void *old_ssl_sessionid = NULL;
 
-    our_ssl_sessionid = SSL_get_session(BACKEND->handle);
+    our_ssl_sessionid = SSL_get_session(backend->handle);
 
     Curl_ssl_sessionid_lock(conn);
     incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
@@ -655,12 +655,13 @@ static ssize_t wolfssl_send(struct connectdata *conn,
                            CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   char error_buffer[WOLFSSL_MAX_ERROR_SZ];
-  int  memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
-  int  rc     = SSL_write(BACKEND->handle, mem, memlen);
+  int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
+  int rc = SSL_write(backend->handle, mem, memlen);
 
   if(rc < 0) {
-    int err = SSL_get_error(BACKEND->handle, rc);
+    int err = SSL_get_error(backend->handle, rc);
 
     switch(err) {
     case SSL_ERROR_WANT_READ:
@@ -682,31 +683,33 @@ static ssize_t wolfssl_send(struct connectdata *conn,
 static void Curl_wolfssl_close(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
-  if(BACKEND->handle) {
-    (void)SSL_shutdown(BACKEND->handle);
-    SSL_free(BACKEND->handle);
-    BACKEND->handle = NULL;
+  if(backend->handle) {
+    (void)SSL_shutdown(backend->handle);
+    SSL_free(backend->handle);
+    backend->handle = NULL;
   }
-  if(BACKEND->ctx) {
-    SSL_CTX_free(BACKEND->ctx);
-    BACKEND->ctx = NULL;
+  if(backend->ctx) {
+    SSL_CTX_free(backend->ctx);
+    backend->ctx = NULL;
   }
 }
 
 static ssize_t wolfssl_recv(struct connectdata *conn,
-                           int num,
-                           char *buf,
-                           size_t buffersize,
-                           CURLcode *curlcode)
+                            int num,
+                            char *buf,
+                            size_t buffersize,
+                            CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct ssl_backend_data *backend = connssl->backend;
   char error_buffer[WOLFSSL_MAX_ERROR_SZ];
-  int  buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
-  int  nread    = SSL_read(BACKEND->handle, buf, buffsize);
+  int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
+  int nread = SSL_read(backend->handle, buf, buffsize);
 
   if(nread < 0) {
-    int err = SSL_get_error(BACKEND->handle, nread);
+    int err = SSL_get_error(backend->handle, nread);
 
     switch(err) {
     case SSL_ERROR_ZERO_RETURN: /* no more data */
@@ -758,11 +761,12 @@ static void Curl_wolfssl_cleanup(void)
 
 
 static bool Curl_wolfssl_data_pending(const struct connectdata* conn,
-                                     int connindex)
+                                      int connindex)
 {
   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
-  if(BACKEND->handle)   /* SSL is in use */
-    return (0 != SSL_pending(BACKEND->handle)) ? TRUE : FALSE;
+  struct ssl_backend_data *backend = connssl->backend;
+  if(backend->handle)   /* SSL is in use */
+    return (0 != SSL_pending(backend->handle)) ? TRUE : FALSE;
   else
     return FALSE;
 }
@@ -776,10 +780,11 @@ static int Curl_wolfssl_shutdown(struct connectdata 
*conn, int sockindex)
 {
   int retval = 0;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
-  if(BACKEND->handle) {
-    SSL_free(BACKEND->handle);
-    BACKEND->handle = NULL;
+  if(backend->handle) {
+    SSL_free(backend->handle);
+    backend->handle = NULL;
   }
   return retval;
 }
@@ -950,10 +955,11 @@ static CURLcode Curl_wolfssl_sha256sum(const unsigned 
char *tmp, /* input */
 }
 
 static void *Curl_wolfssl_get_internals(struct ssl_connect_data *connssl,
-                                       CURLINFO info UNUSED_PARAM)
+                                        CURLINFO info UNUSED_PARAM)
 {
+  struct ssl_backend_data *backend = connssl->backend;
   (void)info;
-  return BACKEND->handle;
+  return backend->handle;
 }
 
 const struct Curl_ssl Curl_ssl_wolfssl = {
diff --git a/lib/warnless.h b/lib/warnless.h
index 08792c2e1..42b012ed0 100644
--- a/lib/warnless.h
+++ b/lib/warnless.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -94,19 +94,6 @@ unsigned short curlx_htons(unsigned short usnum);
 
 unsigned short curlx_ntohs(unsigned short usnum);
 
-#ifndef BUILDING_WARNLESS_C
-#  undef  FD_ISSET
-#  define FD_ISSET(a,b) curlx_FD_ISSET((a),(b))
-#  undef  FD_SET
-#  define FD_SET(a,b)   curlx_FD_SET((a),(b))
-#  undef  FD_ZERO
-#  define FD_ZERO(a)    curlx_FD_ZERO((a))
-#  undef  htons
-#  define htons(a)      curlx_htons((a))
-#  undef  ntohs
-#  define ntohs(a)      curlx_ntohs((a))
-#endif
-
 #endif /* __INTEL_COMPILER && __unix__ */
 
 #endif /* HEADER_CURL_WARNLESS_H */
diff --git a/libgnurl.pc.in b/libgnurl.pc.in
index f61d6ab04..1d3bce263 100644
--- a/libgnurl.pc.in
+++ b/libgnurl.pc.in
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/m4/curl-compilers.m4 b/m4/curl-compilers.m4
index c64db4bc6..e732a8722 100644
--- a/m4/curl-compilers.m4
+++ b/m4/curl-compilers.m4
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -151,8 +151,17 @@ AC_DEFUN([CURL_CHECK_COMPILER_DEC_C], [
 
 dnl CURL_CHECK_COMPILER_GNU_C
 dnl -------------------------------------------------
-dnl Verify if compiler being used is GNU C.
-
+dnl Verify if compiler being used is GNU C
+dnl
+dnl $compiler_num will be set to MAJOR * 100 + MINOR for gcc less than version
+dnl 7 and just $MAJOR * 100 for gcc version 7 and later.
+dnl
+dnl Examples:
+dnl Version 1.2.3 => 102
+dnl Version 2.95  => 295
+dnl Version 4.7 =>   407
+dnl Version 9.2.1 => 900
+dnl
 AC_DEFUN([CURL_CHECK_COMPILER_GNU_C], [
   AC_REQUIRE([CURL_CHECK_COMPILER_INTEL_C])dnl
   AC_REQUIRE([CURL_CHECK_COMPILER_CLANG])dnl
@@ -443,8 +452,10 @@ dnl GNUC versions these warnings are not silenced.
 AC_DEFUN([CURL_CONVERT_INCLUDE_TO_ISYSTEM], [
   AC_REQUIRE([CURL_SHFUNC_SQUEEZE])dnl
   AC_REQUIRE([CURL_CHECK_COMPILER])dnl
+  AC_MSG_CHECKING([convert -I options to -isystem])
   if test "$compiler_id" = "GNU_C" ||
     test "$compiler_id" = "CLANG"; then
+    AC_MSG_RESULT([yes])
     tmp_has_include="no"
     tmp_chg_FLAGS="$CFLAGS"
     for word1 in $tmp_chg_FLAGS; do
@@ -475,6 +486,8 @@ AC_DEFUN([CURL_CONVERT_INCLUDE_TO_ISYSTEM], [
       CPPFLAGS="$tmp_chg_FLAGS"
       squeeze CPPFLAGS
     fi
+  else
+    AC_MSG_RESULT([no])
   fi
 ])
 
@@ -560,11 +573,6 @@ AC_DEFUN([CURL_SET_COMPILER_BASIC_OPTS], [
   AC_REQUIRE([CURL_SHFUNC_SQUEEZE])dnl
   #
   if test "$compiler_id" != "unknown"; then
-    #
-    if test "$compiler_id" = "GNU_C" ||
-      test "$compiler_id" = "CLANG"; then
-      CURL_CONVERT_INCLUDE_TO_ISYSTEM
-    fi
     #
     tmp_save_CPPFLAGS="$CPPFLAGS"
     tmp_save_CFLAGS="$CFLAGS"
@@ -1156,11 +1164,6 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [
         tmp_CFLAGS="$tmp_CFLAGS -fno-strict-aliasing"
         dnl Value-safe optimizations on floating-point data
         tmp_CFLAGS="$tmp_CFLAGS -fp-model precise"
-        dnl Only icc 10.0 or later
-        if test "$compiler_num" -ge "1000"; then
-          dnl Disable vectorizer diagnostic information
-          tmp_CFLAGS="$tmp_CFLAGS -vec-report0"
-        fi
         ;;
         #
       INTEL_WINDOWS_C)
diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4
index e773f6700..b4e64cf33 100644
--- a/m4/curl-functions.m4
+++ b/m4/curl-functions.m4
@@ -7289,8 +7289,6 @@ dnl CURL_LIBRARY_PATH variable. It keeps the 
LD_LIBRARY_PATH
 dnl changes contained within this macro.
 
 AC_DEFUN([CURL_RUN_IFELSE], [
-   AC_REQUIRE([AC_RUN_IFELSE])dnl
-
    old=$LD_LIBRARY_PATH
    LD_LIBRARY_PATH=$CURL_LIBRARY_PATH:$old
    export LD_LIBRARY_PATH
diff --git a/m4/curl-openssl.m4 b/m4/curl-openssl.m4
index d55827861..24f33aa11 100644
--- a/m4/curl-openssl.m4
+++ b/m4/curl-openssl.m4
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/m4/curl-override.m4 b/m4/curl-override.m4
index a03504982..18e4e2091 100644
--- a/m4/curl-override.m4
+++ b/m4/curl-override.m4
@@ -1,4 +1,25 @@
 #***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+#***************************************************************************
 #***************************************************************************
 
 # File version for 'aclocal' use. Keep it a single number.
diff --git a/m4/curl-reentrant.m4 b/m4/curl-reentrant.m4
index 8b5ca124b..32cbaf854 100644
--- a/m4/curl-reentrant.m4
+++ b/m4/curl-reentrant.m4
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2009, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/m4/xc-am-iface.m4 b/m4/xc-am-iface.m4
index 8fc2ea869..7070193aa 100644
--- a/m4/xc-am-iface.m4
+++ b/m4/xc-am-iface.m4
@@ -2,7 +2,7 @@
 #
 # xc-am-iface.m4
 #
-# Copyright (c) 2013 Daniel Stenberg <address@hidden>
+# Copyright (c) 2013 - 2020 Daniel Stenberg <address@hidden>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
diff --git a/m4/xc-cc-check.m4 b/m4/xc-cc-check.m4
index f95f25933..fd58ca2ce 100644
--- a/m4/xc-cc-check.m4
+++ b/m4/xc-cc-check.m4
@@ -2,7 +2,7 @@
 #
 # xc-cc-check.m4
 #
-# Copyright (c) 2013 Daniel Stenberg <address@hidden>
+# Copyright (c) 2013 - 2020, Daniel Stenberg <address@hidden>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
diff --git a/m4/xc-lt-iface.m4 b/m4/xc-lt-iface.m4
index afbd990d6..465767fc3 100644
--- a/m4/xc-lt-iface.m4
+++ b/m4/xc-lt-iface.m4
@@ -2,7 +2,7 @@
 #
 # xc-lt-iface.m4
 #
-# Copyright (c) 2013 Daniel Stenberg <address@hidden>
+# Copyright (c) 2013 - 2020, Daniel Stenberg <address@hidden>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
diff --git a/m4/xc-translit.m4 b/m4/xc-translit.m4
index 456e72782..18b63ecc8 100644
--- a/m4/xc-translit.m4
+++ b/m4/xc-translit.m4
@@ -2,7 +2,7 @@
 #
 # xc-translit.m4
 #
-# Copyright (c) 2011 Daniel Stenberg <address@hidden>
+# Copyright (c) 2011 - 2020, Daniel Stenberg <address@hidden>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
diff --git a/m4/xc-val-flgs.m4 b/m4/xc-val-flgs.m4
index 95b450b23..775c149cc 100644
--- a/m4/xc-val-flgs.m4
+++ b/m4/xc-val-flgs.m4
@@ -2,7 +2,7 @@
 #
 # xc-val-flgs.m4
 #
-# Copyright (c) 2013 Daniel Stenberg <address@hidden>
+# Copyright (c) 2013 - 2020, Daniel Stenberg <address@hidden>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
diff --git a/m4/zz50-xc-ovr.m4 b/m4/zz50-xc-ovr.m4
index 7f530dead..cf8604dcb 100644
--- a/m4/zz50-xc-ovr.m4
+++ b/m4/zz50-xc-ovr.m4
@@ -2,7 +2,7 @@
 #
 # zz50-xc-ovr.m4
 #
-# Copyright (c) 2011 Daniel Stenberg <address@hidden>
+# Copyright (c) 2011 - 2020, Daniel Stenberg <address@hidden>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
diff --git a/m4/zz60-xc-ovr.m4 b/m4/zz60-xc-ovr.m4
index 45ed8b69a..126ac0fd7 100644
--- a/m4/zz60-xc-ovr.m4
+++ b/m4/zz60-xc-ovr.m4
@@ -2,7 +2,7 @@
 #
 # zz60-xc-ovr.m4
 #
-# Copyright (c) 2013 Daniel Stenberg <address@hidden>
+# Copyright (c) 2013 - 2020, Daniel Stenberg <address@hidden>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/Android/Android.mk b/packages/Android/Android.mk
index 2b95dddff..adb6336fe 100644
--- a/packages/Android/Android.mk
+++ b/packages/Android/Android.mk
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Google Android makefile for curl and libcurl
 #
 # This file can be used when building curl using the full Android source
diff --git a/packages/DOS/common.dj b/packages/DOS/common.dj
index c97b216eb..b0e15d676 100644
--- a/packages/DOS/common.dj
+++ b/packages/DOS/common.dj
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #
 # Common defines for curl (djgpp/Watt-32)
 #
diff --git a/packages/Makefile.am b/packages/Makefile.am
index 9a2af064d..d8a92abbb 100644
--- a/packages/Makefile.am
+++ b/packages/Makefile.am
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 SUBDIRS = vms
 
 EXTRA_DIST = README \
@@ -6,6 +27,7 @@ EXTRA_DIST = README \
   OS400/README.OS400 \
   OS400/ccsidcurl.c \
   OS400/ccsidcurl.h \
+  OS400/chkstrings.c \
   OS400/curl.inc.in \
   OS400/initscript.sh \
   OS400/make-include.sh \
diff --git a/packages/OS400/ccsidcurl.c b/packages/OS400/ccsidcurl.c
index 64fb7393d..4e04927b0 100644
--- a/packages/OS400/ccsidcurl.c
+++ b/packages/OS400/ccsidcurl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -1148,6 +1148,9 @@ curl_easy_setopt_ccsid(CURL *curl, CURLoption tag, ...)
   case CURLOPT_CUSTOMREQUEST:
   case CURLOPT_DEFAULT_PROTOCOL:
   case CURLOPT_DNS_SERVERS:
+  case CURLOPT_DNS_INTERFACE:
+  case CURLOPT_DNS_LOCAL_IP4:
+  case CURLOPT_DNS_LOCAL_IP6:
   case CURLOPT_DOH_URL:
   case CURLOPT_EGDSOCKET:
   case CURLOPT_ENCODING:
diff --git a/packages/OS400/chkstrings.c b/packages/OS400/chkstrings.c
index 613540e42..083263640 100644
--- a/packages/OS400/chkstrings.c
+++ b/packages/OS400/chkstrings.c
@@ -28,13 +28,13 @@
 /* The following defines indicate the expected dupstring enum values
  * in curl_easy_setopt_ccsid() in packages/OS400/ccsidcurl.c. If a
  * mismatch is flagged during the build, it indicates that 
curl_easy_setopt_ccsid()
- * may need updating to perform data EBCDIC to ASCII data conversion on 
+ * may need updating to perform data EBCDIC to ASCII data conversion on
  * the string.
  * Once any applicable changes to curl_easy_setopt_ccsid() have been
  * made, the EXPECTED_STRING_LASTZEROTERMINATED/EXPECTED_STRING_LAST
  * values can be updated to match the latest enum values in urldata.h.
  */
-#define EXPECTED_STRING_LASTZEROTERMINATED  (STRING_TEMP_URL + 1)
+#define EXPECTED_STRING_LASTZEROTERMINATED  (STRING_DNS_LOCAL_IP6 + 1)
 #define EXPECTED_STRING_LAST                (STRING_COPYPOSTFIELDS + 1)
 
 int main(int argc, char *argv[])
@@ -43,13 +43,13 @@ int main(int argc, char *argv[])
 
   if (STRING_LASTZEROTERMINATED != EXPECTED_STRING_LASTZEROTERMINATED)
   {
-    fprintf(stderr,"STRING_LASTZEROTERMINATED(%d) is not expected 
value(%d).\n", 
+    fprintf(stderr,"STRING_LASTZEROTERMINATED(%d) is not expected 
value(%d).\n",
             STRING_LASTZEROTERMINATED, EXPECTED_STRING_LASTZEROTERMINATED);
     rc += 1;
   }
   if (STRING_LAST != EXPECTED_STRING_LAST)
   {
-    fprintf(stderr,"STRING_LAST(%d) is not expected value(%d).\n", 
+    fprintf(stderr,"STRING_LAST(%d) is not expected value(%d).\n",
             STRING_LAST, EXPECTED_STRING_LAST);
     rc += 2;
   }
@@ -59,4 +59,4 @@ int main(int argc, char *argv[])
             " may need updating if new strings are provided as input via the 
curl API.\n");
   }
   return rc;
-}
\ No newline at end of file
+}
diff --git a/packages/OS400/curl.inc.in b/packages/OS400/curl.inc.in
index a160f1085..5b3b2c059 100644
--- a/packages/OS400/curl.inc.in
+++ b/packages/OS400/curl.inc.in
@@ -5,7 +5,7 @@
       *                            | (__| |_| |  _ <| |___
       *                             \___|\___/|_| \_\_____|
       *
-      * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+      * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
       *
       * This software is licensed as described in the file COPYING, which
       * you should have received as part of this distribution. The terms
@@ -770,6 +770,8 @@
      d                 c                   X'0002'
      d CURLSSLOPT_NO_PARTIALCHAIN...
      d                 c                   X'0004'
+     d CURLSSLOPT_REVOKE_BEST_EFFORT...
+     d                 c                   X'0008'
       *
      d CURL_HET_DEFAULT...
      d                 c                   200
diff --git a/packages/OS400/initscript.sh b/packages/OS400/initscript.sh
index c9932c49b..6ae7e6e11 100644
--- a/packages/OS400/initscript.sh
+++ b/packages/OS400/initscript.sh
@@ -1,4 +1,25 @@
 #!/bin/sh
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
 
 setenv()
diff --git a/packages/OS400/make-include.sh b/packages/OS400/make-include.sh
index 3b0900ff9..336e6ae65 100644
--- a/packages/OS400/make-include.sh
+++ b/packages/OS400/make-include.sh
@@ -1,4 +1,25 @@
 #!/bin/sh
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #
 #       Installation of the header files in the OS/400 library.
 #
diff --git a/packages/OS400/make-lib.sh b/packages/OS400/make-lib.sh
index 8b97f6b67..20e190245 100644
--- a/packages/OS400/make-lib.sh
+++ b/packages/OS400/make-lib.sh
@@ -1,4 +1,25 @@
 #!/bin/sh
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #
 #       libcurl compilation script for the OS/400.
 #
diff --git a/packages/OS400/make-src.sh b/packages/OS400/make-src.sh
index 090ae1287..dbe039b2c 100644
--- a/packages/OS400/make-src.sh
+++ b/packages/OS400/make-src.sh
@@ -1,4 +1,25 @@
 #!/bin/sh
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #
 #
 #       Not implemented yet on OS/400.
diff --git a/packages/OS400/make-tests.sh b/packages/OS400/make-tests.sh
index 9240b7ff6..54cdd2fea 100644
--- a/packages/OS400/make-tests.sh
+++ b/packages/OS400/make-tests.sh
@@ -1,4 +1,25 @@
 #!/bin/sh
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #
 #       tests compilation script for the OS/400.
 #
diff --git a/packages/OS400/makefile.sh b/packages/OS400/makefile.sh
index 7c6bcd7c6..3ff151202 100644
--- a/packages/OS400/makefile.sh
+++ b/packages/OS400/makefile.sh
@@ -1,4 +1,25 @@
 #!/bin/sh
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #
 #       curl compilation script for the OS/400.
 #
diff --git a/packages/OS400/os400sys.h b/packages/OS400/os400sys.h
index c98e198cc..8dafd6491 100644
--- a/packages/OS400/os400sys.h
+++ b/packages/OS400/os400sys.h
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/packages/Symbian/group/curl.mmp b/packages/Symbian/group/curl.mmp
index e802205b4..af12d8b1f 100644
--- a/packages/Symbian/group/curl.mmp
+++ b/packages/Symbian/group/curl.mmp
@@ -45,6 +45,7 @@ SOURCE \
     tool_vms.c \
     tool_writeenv.c \
     tool_writeout.c \
+    tool_writeout_json.c \
     tool_xattr.c
 
 SOURCEPATH  ../../../lib
diff --git a/packages/TPF/curl.mak b/packages/TPF/curl.mak
index 176abec24..d8d55a805 100644
--- a/packages/TPF/curl.mak
+++ b/packages/TPF/curl.mak
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #######################################################################
 #                                                                     #
 #  MAKEFILE NAME.....  curl.mak                                       #
diff --git a/packages/TPF/maketpf.env_curl b/packages/TPF/maketpf.env_curl
index de3da637b..fc6e46fca 100644
--- a/packages/TPF/maketpf.env_curl
+++ b/packages/TPF/maketpf.env_curl
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
################################################################################
 
################################################################################
 #env TPF CURL Includes
diff --git a/packages/TPF/maketpf.env_curllib b/packages/TPF/maketpf.env_curllib
index 2810738c8..45c68d739 100644
--- a/packages/TPF/maketpf.env_curllib
+++ b/packages/TPF/maketpf.env_curllib
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
################################################################################
 
################################################################################
 #env TPF CURL Library Source and Output
diff --git a/packages/vms/Makefile.am b/packages/vms/Makefile.am
index 38f65859a..f5cf9a93f 100644
--- a/packages/vms/Makefile.am
+++ b/packages/vms/Makefile.am
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 EXTRA_DIST = \
  backup_gnv_curl_src.com \
  build_curl-config_script.com \
diff --git a/packages/vms/backup_gnv_curl_src.com 
b/packages/vms/backup_gnv_curl_src.com
index 38575710b..fcf3061c2 100644
--- a/packages/vms/backup_gnv_curl_src.com
+++ b/packages/vms/backup_gnv_curl_src.com
@@ -17,7 +17,7 @@ $! This file is created from a template file for the purpose 
of making it
 $! easier to port Unix code, particularly open source code to VMS.
 $! Therefore permission is freely granted for any use.
 $!
-$! Copyright 2009, John Malmberg
+$! Copyright 2009 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/build_gnv_curl.com b/packages/vms/build_gnv_curl.com
index 1eaa7d5f3..ede38548d 100644
--- a/packages/vms/build_gnv_curl.com
+++ b/packages/vms/build_gnv_curl.com
@@ -4,7 +4,7 @@ $! $Id$
 $!
 $! All in one build procedure
 $!
-$! Copyright 2009, John Malmberg
+$! Copyright 2009 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/build_gnv_curl_pcsi_desc.com 
b/packages/vms/build_gnv_curl_pcsi_desc.com
index fab2c823c..941875ab4 100644
--- a/packages/vms/build_gnv_curl_pcsi_desc.com
+++ b/packages/vms/build_gnv_curl_pcsi_desc.com
@@ -31,7 +31,7 @@ $! A rename action section is needed to make sure that the 
files are
 $! created in the GNV$GNU: in the correct case, and to create the alias
 $! link [usr.bin]curl. for [usr.bin]curl.exe.
 $!
-$! Copyright 2009, John Malmberg
+$! Copyright 2009 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/build_gnv_curl_pcsi_text.com 
b/packages/vms/build_gnv_curl_pcsi_text.com
index df98f6301..94ca7eb44 100644
--- a/packages/vms/build_gnv_curl_pcsi_text.com
+++ b/packages/vms/build_gnv_curl_pcsi_text.com
@@ -12,7 +12,7 @@ $!    4. Generated Producer section.
 $!
 $! Set the name of the release notes from the GNV_PCSI_FILENAME_BASE
 $!
-$! Copyright 2009, John Malmberg
+$! Copyright 2009 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/build_gnv_curl_release_notes.com 
b/packages/vms/build_gnv_curl_release_notes.com
index da0276f58..8342ef978 100644
--- a/packages/vms/build_gnv_curl_release_notes.com
+++ b/packages/vms/build_gnv_curl_release_notes.com
@@ -11,7 +11,7 @@ $!
 $! Set the name of the release notes from the GNV_PCSI_FILENAME_BASE
 $! logical name.
 $!
-$! Copyright 2009, John Malmberg
+$! Copyright 2009 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/build_libcurl_pc.com 
b/packages/vms/build_libcurl_pc.com
index 97e6ae643..5b2315e2a 100644
--- a/packages/vms/build_libcurl_pc.com
+++ b/packages/vms/build_libcurl_pc.com
@@ -4,7 +4,7 @@ $! $Id:$
 $!
 $! Build the libcurl.pc file from the libcurl.pc.in file
 $!
-$! Copyright 2013, John Malmberg
+$! Copyright 2013 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/clean_gnv_curl.com b/packages/vms/clean_gnv_curl.com
index 4e58356b1..5846739e4 100644
--- a/packages/vms/clean_gnv_curl.com
+++ b/packages/vms/clean_gnv_curl.com
@@ -15,7 +15,7 @@ $! Parameter P1: REALCLEAN
 $!   This removes all build products and brings the environment back to
 $!   the point where the gnv_curl_configure.sh procedure needs to be run again.
 $!
-$! Copyright 2009, John Malmberg
+$! Copyright 2009 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/compare_curl_source.com 
b/packages/vms/compare_curl_source.com
index 66f6a4598..a720afc63 100644
--- a/packages/vms/compare_curl_source.com
+++ b/packages/vms/compare_curl_source.com
@@ -69,7 +69,7 @@ $!
 $!   This is to make sure that the backup save set for the unmodified
 $!   source is up to date.
 $!
-$! Copyright 2011, John Malmberg
+$! Copyright 2011 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/config_h.com b/packages/vms/config_h.com
index 9bfb40b95..4049d9f06 100644
--- a/packages/vms/config_h.com
+++ b/packages/vms/config_h.com
@@ -28,7 +28,7 @@ $!
 $! This procedure may not guess the options correctly for all architectures,
 $! and is a work in progress.
 $!
-$! Copyright 2011, John Malmberg
+$! Copyright 2011 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/curl_crtl_init.c b/packages/vms/curl_crtl_init.c
index 9f7cf66c7..b8e5f7f50 100644
--- a/packages/vms/curl_crtl_init.c
+++ b/packages/vms/curl_crtl_init.c
@@ -1,3 +1,24 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
 /* File: curl_crtl_init.c
  *
  * This file makes sure that the DECC Unix settings are correct for
diff --git a/packages/vms/curl_gnv_build_steps.txt 
b/packages/vms/curl_gnv_build_steps.txt
index 9072b20a2..52dc32881 100644
--- a/packages/vms/curl_gnv_build_steps.txt
+++ b/packages/vms/curl_gnv_build_steps.txt
@@ -1,6 +1,6 @@
 From File: curl_gnv_build_steps.txt
 
- Copyright 2009, John Malmberg
+ Copyright 2009 - 2020, John Malmberg
 
  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
@@ -125,7 +125,7 @@ or
   $ @build_gnv_curl.com.
 
 The GNV configure procedure takes considerably longer than the DCL build
-procecure takes.  It is of use for testing the GNV build environment, and
+procedure takes.  It is of use for testing the GNV build environment, and
 may not have been kept up to date.
 
 The pcsi_product_gnv_curl.com needs the following logical names which
diff --git a/packages/vms/curl_startup.com b/packages/vms/curl_startup.com
index 84760a0af..b94ee7f44 100644
--- a/packages/vms/curl_startup.com
+++ b/packages/vms/curl_startup.com
@@ -5,7 +5,7 @@ $!
 $! Procedure to setup the CURL libraries for use by programs from the
 $! VMS SYSTARTUP*.COM procedure.
 $!
-$! Copyright 2009, John Malmberg
+$! Copyright 2009 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/curlmsg.h b/packages/vms/curlmsg.h
index 424a382f0..55c9ee5cb 100644
--- a/packages/vms/curlmsg.h
+++ b/packages/vms/curlmsg.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/packages/vms/curlmsg.msg b/packages/vms/curlmsg.msg
index 492657c02..73bc763e8 100644
--- a/packages/vms/curlmsg.msg
+++ b/packages/vms/curlmsg.msg
@@ -1,3 +1,24 @@
+!***************************************************************************
+!                                  _   _ ____  _
+!  Project                     ___| | | |  _ \| |
+!                             / __| | | | |_) | |
+!                            | (__| |_| |  _ <| |___
+!                             \___|\___/|_| \_\_____|
+!
+! Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+!
+! This software is licensed as described in the file COPYING, which
+! you should have received as part of this distribution. The terms
+! are also available at https://curl.haxx.se/docs/copyright.html.
+!
+! You may opt to use, copy, modify, merge, publish, distribute and/or sell
+! copies of the Software, and permit persons to whom the Software is
+! furnished to do so, under the terms of the COPYING file.
+!
+! This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+! KIND, either express or implied.
+!
+!##########################################################################
 !
 ! These VMS error codes are generated by taking apart the curl.h
 ! file and putting all the CURLE_* enum stuff into this file,
diff --git a/packages/vms/curlmsg_vms.h b/packages/vms/curlmsg_vms.h
index b7ff7a0cb..9dbc6ab71 100644
--- a/packages/vms/curlmsg_vms.h
+++ b/packages/vms/curlmsg_vms.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/packages/vms/generate_vax_transfer.com 
b/packages/vms/generate_vax_transfer.com
index 92391f92e..00020810f 100644
--- a/packages/vms/generate_vax_transfer.com
+++ b/packages/vms/generate_vax_transfer.com
@@ -14,7 +14,7 @@ $!     gnv_libcurl_xfer.obj
 $!     gnv_libcurl_xfer.opt
 $!     macro32_exactcase.exe
 $!
-$! Copyright 2013, John Malmberg
+$! Copyright 2013 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/gnv_conftest.c_first 
b/packages/vms/gnv_conftest.c_first
index f47469c5b..1d69600a2 100644
--- a/packages/vms/gnv_conftest.c_first
+++ b/packages/vms/gnv_conftest.c_first
@@ -2,7 +2,7 @@
  *
  * $Id$
  *
- * Copyright 2009, John Malmberg
+ * Copyright 2009 - 2020, John Malmberg
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/gnv_curl_configure.sh 
b/packages/vms/gnv_curl_configure.sh
index 2eeb209c8..839a40bff 100644
--- a/packages/vms/gnv_curl_configure.sh
+++ b/packages/vms/gnv_curl_configure.sh
@@ -5,7 +5,7 @@
 # Set up and run the configure script for Curl so that it can find the
 # proper options for VMS.
 #
-# Copyright 2009, John Malmberg
+# Copyright 2009 - 2020, John Malmberg
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/gnv_libcurl_symbols.opt 
b/packages/vms/gnv_libcurl_symbols.opt
index 84655926c..cae2a754b 100644
--- a/packages/vms/gnv_libcurl_symbols.opt
+++ b/packages/vms/gnv_libcurl_symbols.opt
@@ -41,7 +41,7 @@
 ! maintaining multiple versions as long as the routine can be called with
 ! the old number of parameters.
 !
-! Copyright 2009, John Malmberg
+! Copyright 2009 - 2020, John Malmberg
 !
 ! Permission to use, copy, modify, and/or distribute this software for any
 ! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/gnv_link_curl.com b/packages/vms/gnv_link_curl.com
index 7ec4ecb09..c9db8d90d 100644
--- a/packages/vms/gnv_link_curl.com
+++ b/packages/vms/gnv_link_curl.com
@@ -4,7 +4,7 @@ $! $Id$
 $!
 $! File to build images using gnv$libcurl.exe
 $!
-$! Copyright 2009, John Malmberg
+$! Copyright 2009 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/make_gnv_curl_install.sh 
b/packages/vms/make_gnv_curl_install.sh
index 5099fe447..699c8d2f2 100644
--- a/packages/vms/make_gnv_curl_install.sh
+++ b/packages/vms/make_gnv_curl_install.sh
@@ -7,7 +7,7 @@
 # This makes the library, the curl binary and attempts an install.
 # A search list should be set up for GNU (GNV$GNU).
 #
-# Copyright 2009, John Malmberg
+# Copyright 2009 - 2020, John Malmberg
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/make_pcsi_curl_kit_name.com 
b/packages/vms/make_pcsi_curl_kit_name.com
index f644fe3ec..2061429ae 100644
--- a/packages/vms/make_pcsi_curl_kit_name.com
+++ b/packages/vms/make_pcsi_curl_kit_name.com
@@ -8,7 +8,7 @@ $!
 $! The results are stored in as logical names so that other procedures
 $! can use them.
 $!
-$! Copyright 2009, John Malmberg
+$! Copyright 2009 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/pcsi_gnv_curl_file_list.txt 
b/packages/vms/pcsi_gnv_curl_file_list.txt
index 07539b2cd..6eb69c384 100644
--- a/packages/vms/pcsi_gnv_curl_file_list.txt
+++ b/packages/vms/pcsi_gnv_curl_file_list.txt
@@ -15,7 +15,7 @@
 !
 ! [xxx.yyy]file.ext is a file for the rename and add phases.
 !
-! Copyright 2009, John Malmberg
+! Copyright 2009 - 2020, John Malmberg
 !
 ! Permission to use, copy, modify, and/or distribute this software for any
 ! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/pcsi_product_gnv_curl.com 
b/packages/vms/pcsi_product_gnv_curl.com
index 747cbd63a..0f9961f49 100644
--- a/packages/vms/pcsi_product_gnv_curl.com
+++ b/packages/vms/pcsi_product_gnv_curl.com
@@ -5,7 +5,7 @@ $!
 $! This command file packages up the product CURL into a sequential
 $! format kit
 $!
-$! Copyright 2009, John Malmberg
+$! Copyright 2009 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/setup_gnv_curl_build.com 
b/packages/vms/setup_gnv_curl_build.com
index 03d5c0b4d..45dcf0fb8 100644
--- a/packages/vms/setup_gnv_curl_build.com
+++ b/packages/vms/setup_gnv_curl_build.com
@@ -7,7 +7,7 @@ $!
 $! GNV needs some files moved into the other directories to help with
 $! the configure script and the build.
 $!
-$! Copyright 2009, John Malmberg
+$! Copyright 2009 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/stage_curl_install.com 
b/packages/vms/stage_curl_install.com
index 84540d739..d79c9e33e 100644
--- a/packages/vms/stage_curl_install.com
+++ b/packages/vms/stage_curl_install.com
@@ -24,7 +24,7 @@ $!     [usr.share.man.man3]curl*.3
 $!     [usr.share.man.man3]libcurl*.3
 $! Future: A symbolic link to the release notes?
 $!
-$! Copyright 2012, John Malmberg
+$! Copyright 2012 - 2020, John Malmberg
 $!
 $! Permission to use, copy, modify, and/or distribute this software for any
 $! purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/vms/vms_eco_level.h b/packages/vms/vms_eco_level.h
index 354875bbb..05abe9101 100644
--- a/packages/vms/vms_eco_level.h
+++ b/packages/vms/vms_eco_level.h
@@ -2,7 +2,7 @@
  *
  * $Id$
  *
- * Copyright 2012, John Malmberg
+ * Copyright 2012 - 2020, John Malmberg
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
diff --git a/plan9/BUILD.PLAN9.txt b/plan9/README
similarity index 100%
rename from plan9/BUILD.PLAN9.txt
rename to plan9/README
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index ec4747705..3b39796ae 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/scripts/completion.pl b/scripts/completion.pl
index 1c41755b4..c717c6d43 100755
--- a/scripts/completion.pl
+++ b/scripts/completion.pl
@@ -1,4 +1,25 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
 use strict;
 use warnings;
diff --git a/scripts/contrithanks.sh b/scripts/contrithanks.sh
index 44e461455..641259216 100755
--- a/scripts/contrithanks.sh
+++ b/scripts/contrithanks.sh
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2013-2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2013 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/scripts/copyright.pl b/scripts/copyright.pl
new file mode 100755
index 000000000..bdf23dd7a
--- /dev/null
+++ b/scripts/copyright.pl
@@ -0,0 +1,187 @@
+#!/usr/bin/perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+#
+# Invoke script in the root of the git checkout. Scans all files in git unless
+# given a specific single file.
+#
+# Usage: copyright.pl [file]
+#
+
+# regexes of files to not scan
+my @whitelist=(
+    '^tests\/data\/test(\d+)$', # test case data
+    '^docs\/cmdline-opts\/[a-z]+(.*)\.d$', # curl.1 pieces
+    '(\/|^)[A-Z0-9_.-]+$', # all uppercase file name, possibly with dot and 
dash
+    '(\/|^)[A-Z0-9_-]+\.md$', # all uppercase file name with .md extension
+    '.gitignore', # whereever they are
+    '.gitattributes', # whereever they are
+    '^tests/certs/.*', # generated certs
+    '^tests/stunnel.pem', # generated cert
+    '^tests/valgrind.supp', # valgrind suppressions
+    '^projects/Windows/.*.dsw$', # generated MSVC file
+    '^projects/Windows/.*.sln$', # generated MSVC file
+    '^projects/Windows/.*.tmpl$', # generated MSVC file
+    '^projects/Windows/.*.vcxproj.filters$', # generated MSVC file
+    '^m4/ax_compile_check_sizeof.m4$', # imported, leave be
+    '^.mailmap', # git control file
+    '^winbuild/BUILD.WINDOWS.txt$', # instructions
+    '\/readme',
+    '^.github/', # github instruction files
+
+    # docs/ files we're okay with without copyright
+    'INSTALL.cmake',
+    'TheArtOfHttpScripting',
+    'page-footer',
+    'curl_multi_socket_all.3',
+    'curl_strnequal.3',
+    'symbols-in-versions',
+
+    # macos-framework files
+    '^lib\/libcurl.plist',
+    '^lib\/libcurl.vers.in',
+
+    # symbian build files we know little about
+    '^packages\/Symbian\/bwins\/libcurlu.def',
+    '^packages\/Symbian\/eabi\/libcurlu.def',
+    '^packages\/Symbian\/group\/bld.inf',
+    '^packages\/Symbian\/group\/curl.iby',
+    '^packages\/Symbian\/group\/curl.mmp',
+    '^packages\/Symbian\/group\/curl.pkg',
+    '^packages\/Symbian\/group\/libcurl.iby',
+    '^packages\/Symbian\/group\/libcurl.mmp',
+    '^packages\/Symbian\/group\/libcurl.pkg',
+
+    # vms files
+    '^packages\/vms\/build_vms.com',
+    '^packages\/vms\/curl_release_note_start.txt',
+    '^packages\/vms\/curlmsg.sdl',
+    '^packages\/vms\/macro32_exactcase.patch',
+
+    # XML junk
+    '^projects\/wolfssl_override.props',
+
+    # macos framework generated files
+    '^src\/macos\/curl.mcp.xml.sit.hqx',
+    '^src\/macos\/src\/curl_GUSIConfig.cpp',
+
+    );
+
+sub scanfile {
+    my ($f) = @_;
+    my $line=1;
+    my $found = 0;
+    open(F, "<$f") ||
+        print ERROR "can't open $f\n";
+    while (<F>) {
+        chomp;
+        my $l = $_;
+        # check for a copyright statement and save the years
+        if($l =~ /.* +copyright .* *\d\d\d\d/i) {
+            while($l =~ /([\d]{4})/g) {
+                push @copyright, {
+                  year => $1,
+                  line => $line,
+                  col => index($l, $1),
+                  code => $l
+                };
+                $found++;
+            }
+        }
+        # allow within the first 100 lines
+        if(++$line > 100) {
+            last;
+        }
+    }
+    close(F);
+    return $found;
+}
+
+sub checkfile {
+    my ($file) = @_;
+    my $fine = 0;
+    @copyright=();
+    my $found = scanfile($file);
+
+    if(!$found) {
+        print "$file: missing copyright range\n";
+        return 2;
+    }
+
+    my $commityear = undef;
+    @copyright = sort {$$b{year} cmp $$a{year}} @copyright;
+
+    # if the file is modified, assume commit year this year
+    if(`git status -s -- $file` =~ /^ [MARCU]/) {
+        $commityear = (localtime(time))[5] + 1900;
+    }
+    else {
+        # min-parents=1 to ignore wrong initial commit in truncated repos
+        my $grl = `git rev-list --max-count=1 --min-parents=1 --timestamp HEAD 
-- $file`;
+        if($grl) {
+            chomp $grl;
+            $commityear = (localtime((split(/ /, $grl))[0]))[5] + 1900;
+        }
+    }
+
+    if(defined($commityear) && scalar(@copyright) &&
+       $copyright[0]{year} != $commityear) {
+        print "$file: copyright year out of date, should be $commityear, " .
+            "is $copyright[0]{year}\n";
+    }
+    else {
+        $fine = 1;
+    }
+    return $fine;
+}
+
+my @all;
+if($ARGV[0]) {
+    push @all, $ARGV[0];
+}
+else {
+    @all = `git ls-files`;
+}
+for my $f (@all) {
+    chomp $f;
+    my $skipped = 0;
+    for my $skip (@whitelist) {
+        #print "$f matches $skip ?\n";
+        if($f =~ /$skip/) {
+            $whitelisted++;
+            $skipped = 1;
+            #print "$f: SKIPPED ($skip)\n";
+            last;
+        }
+    }
+    if(!$skipped) {
+        my $r = checkfile($f);
+        $missing++ if($r == 2);
+        $wrong++ if(!$r);
+    }
+}
+
+print STDERR "$missing files have no copyright\n" if($missing);
+print STDERR "$wrong files have wrong copyright year\n" if ($wrong);
+print STDERR "$whitelisted files are whitelisted\n" if ($whitelisted);
+
+exit 1 if($missing || $wrong);
diff --git a/scripts/coverage.sh b/scripts/coverage.sh
index 86cd7a122..cae5e028f 100755
--- a/scripts/coverage.sh
+++ b/scripts/coverage.sh
@@ -1,4 +1,25 @@
 #!/bin/sh
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
 ./buildconf
 mkdir -p cvr
diff --git a/scripts/installcheck.sh b/scripts/installcheck.sh
index b3aad68c8..bc3e6c208 100644
--- a/scripts/installcheck.sh
+++ b/scripts/installcheck.sh
@@ -1,4 +1,25 @@
 #!/bin/sh
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
 PREFIX=$1
 
diff --git a/scripts/log2changes.pl b/scripts/log2changes.pl
index 283822513..ec470c967 100755
--- a/scripts/log2changes.pl
+++ b/scripts/log2changes.pl
@@ -1,4 +1,25 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
 # git log --pretty=fuller --no-color --date=short --decorate=full
 
diff --git a/scripts/release-notes.pl b/scripts/release-notes.pl
new file mode 100755
index 000000000..2be0eab8f
--- /dev/null
+++ b/scripts/release-notes.pl
@@ -0,0 +1,213 @@
+#!/usr/bin/perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+###############################################
+#
+# ==== How to use this script ====
+#
+# 1. Get recent commits added to RELEASE-NOTES:
+#
+# $ ./scripts/release-notes.pl
+#
+# 2. Edit RELEASE-NOTES and remove all entries that don't belong.  Unused
+# references below will be cleaned up in the next step. Make sure to move
+# "changes" up to the changes section. All entries will by default be listed
+# under bug-fixes as this script can't know where to put them.
+#
+# 3. Run the cleanup script and let it sort the entries and remove unused
+# references from lines you removed in step (2):
+#
+# $ ./script/release-notes.pl cleanup
+#
+# 4. Reload RELEASE-NOTES and verify that things look okay. The cleanup
+# procedure can and should be re-run when lines are removed or rephrased.
+#
+# 5. Run ./scripts/contributors.sh and update the contributor list of names
+# The list can also be extended or edited manually.
+#
+# 6. Run ./scripts/delta and update the contributor count at the top, and
+# double-check/update the other counters.
+#
+# 7. Commit the file using "RELEASE-NOTES: synced" as commit message.
+#
+################################################
+
+my $cleanup = ($ARGV[0] eq "cleanup");
+my @gitlog=`git log @^{/RELEASE-NOTES:.synced}..` if(!$cleanup);
+my @releasenotes=`cat RELEASE-NOTES`;
+
+my @o; # the entire new RELEASE-NOTES
+my @refused; # [num] = [2 bits of use info]
+my @refs; # [number] = [URL]
+for my $l (@releasenotes) {
+    if($l =~ /^ o .*\[(\d+)\]/) {
+        # referenced, set bit 0
+        $refused[$1]=1;
+    }
+    elsif($l =~ /^ \[(\d+)\] = (.*)/) {
+        # listed in a refernce, set bit 1
+        $refused[$1] |= 2;
+        $refs[$1] = $2;
+    }
+}
+
+# Return a new fresh reference number
+sub getref {
+    for my $r (1 .. $#refs) {
+        if(!$refused[$r] & 1) {
+            return $r;
+        }
+    }
+    # add at the end
+    return $#refs + 1;
+}
+
+my $short;
+my $first;
+for my $l (@gitlog) {
+    chomp $l;
+    if($l =~ /^commit/) {
+        if($first) {
+            onecommit($short);
+        }
+        # starts a new commit
+        undef @fixes;
+        undef @closes;
+        undef @bug;
+        $short = "";
+        $first = 0;
+    }
+    elsif(($l =~ /^    (.*)/) && !$first) {
+        # first line
+        $short = $1;
+        $first = 1;
+        push @line, $short;
+    }
+    elsif(($l =~ /^    (.*)/) && $first) {
+        # not the first
+        my $line = $1;
+
+        if($line =~ /^Fixes(:|) .*[^0-9](\d+)/i) {
+            push @fixes, $2;
+        }
+        elsif($line =~ /^Closes(:|) .*[^0-9](\d+)/i) {
+            push @closes, $2;
+        }
+        elsif($line =~ /^Bug: (.*)/i) {
+            push @bug, $1;
+        }
+    }
+}
+if($first) {
+    onecommit($short);
+}
+
+# call at the end of a parsed commit
+sub onecommit {
+    my ($short)=@_;
+    my $ref;
+
+    if($bug[0]) {
+        $ref = $bug[0];
+    }
+    elsif($fixes[0]) {
+        $ref = $fixes[0];
+    }
+    elsif($closes[0]) {
+        $ref = $closes[0];
+    }
+
+    if($ref =~ /^(\d+)/) {
+        $ref = "https://curl.haxx.se/bug/?i=$1";
+    }
+    if($ref) {
+        my $r = getref();
+        $refs[$r] = $ref;
+        $moreinfo{$short}=$r;
+        $refused[$r] |= 1;
+    }
+}
+
+#### Output the new RELEASE-NOTES
+
+my @bullets;
+for my $l (@releasenotes) {
+    if(($l =~ /^This release includes the following bugfixes:/) && !$cleanup) {
+        push @o, $l;
+        push @o, "\n";
+        for my $f (@line) {
+            push @o, sprintf " o $f%s\n", $moreinfo{$f}? sprintf(" [%d]", 
$moreinfo{$f}): "";
+            $refused[$moreinfo{$f}]=3;
+        }
+        push @o, " --- new entries are listed above this ---";
+        next;
+    }
+    elsif($cleanup) {
+        if($l =~ /^ --- new entries are listed/) {
+            # ignore this if still around
+            next;
+        }
+        elsif($l =~ /^ o .*/) {
+            push @bullets, $l;
+            next;
+        }
+        elsif($bullets[0]) {
+            # output them case insensitively
+            for my $b (sort { "\L$a" cmp "\L$b" } @bullets) {
+                push @o, $b;
+            }
+            undef @bullets;
+        }
+    }
+    if($l =~ /^ \[(\d+)\] = /) {
+        # stop now
+        last;
+    }
+    else {
+        push @o, $l;
+    }
+}
+
+my @srefs;
+my $ln;
+for my $n (1 .. $#refs) {
+    my $r = $refs[$n];
+    if($r && ($refused[$n] & 1)) {
+        push @o, sprintf " [%d] = %s\n", $n, $r;
+    }
+}
+
+open(O, ">RELEASE-NOTES");
+for my $l (@o) {
+    print O $l;
+}
+close(O);
+
+exit;
+
+# Debug: show unused references
+for my $r (1 .. $#refs) {
+    if($refused[$r] != 3) {
+        printf "$r is %d!\n", $refused[$r];
+    }
+}
diff --git a/scripts/travis/before_script.sh b/scripts/travis/before_script.sh
index 8b5497ebe..c71007857 100755
--- a/scripts/travis/before_script.sh
+++ b/scripts/travis/before_script.sh
@@ -1,4 +1,25 @@
-#!/bin/bash
+#!/bin/sh
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 set -eo pipefail
 
 ./buildconf
diff --git a/scripts/travis/iconv-env.sh b/scripts/travis/iconv-env.sh
index bb7dcf422..129eb10a9 100755
--- a/scripts/travis/iconv-env.sh
+++ b/scripts/travis/iconv-env.sh
@@ -1 +1,22 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 export CPPFLAGS="-DCURL_DOES_CONVERSIONS -DHAVE_ICONV 
-DCURL_ICONV_CODESET_OF_HOST='\"ISO8859-1\"'"
diff --git a/scripts/travis/script.sh b/scripts/travis/script.sh
index 864e1e07e..dc694881b 100755
--- a/scripts/travis/script.sh
+++ b/scripts/travis/script.sh
@@ -1,4 +1,25 @@
 #!/bin/bash
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 set -eo pipefail
 
 ./buildconf
@@ -28,12 +49,7 @@ if [ "$T" = "debug" ]; then
   make
   make examples
   if [ -z $NOTESTS ]; then
-    if [ "$TRAVIS_ARCH" = "aarch64" ] ; then
-      # TODO: find out why this test is failing on arm64
-      make "TFLAGS=-n !323" test-nonflaky
-    else
-      make TFLAGS=-n test-nonflaky
-    fi
+    make TFLAGS=-n test-nonflaky
   fi
 fi
 
diff --git a/scripts/updatemanpages.pl b/scripts/updatemanpages.pl
index e144bad11..21a7df174 100755
--- a/scripts/updatemanpages.pl
+++ b/scripts/updatemanpages.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 838e3b78a..2f4f2c5b1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 set(EXE_NAME gnurl)
 
 if(USE_MANUAL)
@@ -46,6 +67,11 @@ add_executable(
   ${GNURL_FILES}
   )
 
+add_executable(
+  ${PROJECT_NAME}::${EXE_NAME}
+  ALIAS ${EXE_NAME}
+  )
+
 if(CURL_HAS_LTO)
   set_target_properties(${EXE_NAME} PROPERTIES
     INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
@@ -78,5 +104,5 @@ target_link_libraries(${EXE_NAME} libgnurl ${GNURL_LIBS})
 install(TARGETS ${EXE_NAME} EXPORT ${TARGETS_EXPORT_NAME} DESTINATION 
${CMAKE_INSTALL_BINDIR})
 export(TARGETS ${EXE_NAME}
        APPEND FILE ${PROJECT_BINARY_DIR}/gnurl-target.cmake
-       NAMESPACE GNURL::
+       NAMESPACE ${PROJECT_NAME}::
 )
diff --git a/src/Makefile.Watcom b/src/Makefile.Watcom
index 67e542d7a..795fd5b1a 100644
--- a/src/Makefile.Watcom
+++ b/src/Makefile.Watcom
@@ -6,7 +6,7 @@
 #                             \___|\___/|_| \_\_____|
 #
 # Copyright (C) 2005 - 2008, Gisle Vanem <address@hidden>.
-# Copyright (C) 2005 - 2015, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2005 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/src/Makefile.inc b/src/Makefile.inc
index c7cbba090..e90e6d670 100644
--- a/src/Makefile.inc
+++ b/src/Makefile.inc
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # ./src/Makefile.inc
 # Using the backslash as line continuation character might be problematic
 # with some make flavours, as Watcom's wmake showed us already. If we
@@ -62,6 +83,7 @@ GNURL_CFILES = \
   tool_util.c \
   tool_vms.c \
   tool_writeout.c \
+  tool_writeout_json.c \
   tool_xattr.c
 
 GNURL_HFILES = \
@@ -107,6 +129,7 @@ GNURL_HFILES = \
   tool_version.h \
   tool_vms.h \
   tool_writeout.h \
+  tool_writeout_json.h \
   tool_xattr.h
 
 GNURL_RCFILES = curl.rc
diff --git a/src/Makefile.m32 b/src/Makefile.m32
index 853ab7bcd..0c811a4d2 100644
--- a/src/Makefile.m32
+++ b/src/Makefile.m32
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1999 - 2018, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1999 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -107,7 +107,7 @@ CFLAGS += -fno-strict-aliasing
 LDFLAGS = $(CURL_LDFLAG_EXTRAS) $(CURL_LDFLAG_EXTRAS_EXE) -s
 AR = $(CURL_AR)
 RC = $(CROSSPREFIX)windres
-RCFLAGS = --include-dir=$(PROOT)/include -O COFF -DCURL_EMBED_MANIFEST
+RCFLAGS = --include-dir=$(PROOT)/include -O coff -DCURL_EMBED_MANIFEST
 STRIP   = $(CROSSPREFIX)strip -g
 
 # We may need these someday
diff --git a/src/macos/src/macos_main.cpp b/src/macos/src/macos_main.cpp
index cf3075ffc..51cf894b1 100644
--- a/src/macos/src/macos_main.cpp
+++ b/src/macos/src/macos_main.cpp
@@ -1 +1 @@
-/* =========================================================================
        Copyright (C) 2001 Eric Lavigne

        Permission is granted to anyone to use this software for any purpose on 
any
        computer system, and to redistribute it freely, subject to the 
following 
        restrictions:
        - The author is not responsible for the consequences of use of this 
        software, no matter how awful, even if they arise from defects in it.
        - The origin of this software must not be misrepresented, either by 
        explicit claim or by omission.
        - You are allowed to distributed modified copies of the software, in 
source 
        and binary form, provided they are marked plainly as altered versions, 
and
        are not misrepresented as being the original software.
   ========================================================================= */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <Memory.h>
#include <GUSICommandLine.h>
#include <stdlib.h>

/* =====================================================
 ==================== */

DECLARE_MAIN(curl)

REGISTER_MAIN_START
REGISTER_MAIN(curl)
REGISTER_MAIN_END

/* ========================================================================= */

int main()
{
        ::MaxApplZone();
        for (int i = 1; i <= 10; i++)
                ::MoreMasters();

        (void) exec_commands();
        
        return 0;
}
\ No newline at end of file
+/* =========================================================================
   Copyright (C) 2001 - 2020, Eric Lavigne

   Permission is granted to anyone to use this software for any purpose on any
   computer system, and to redistribute it freely, subject to the following
   restrictions:
   - The author is not responsible for the consequences of use of this
   software, no matter how awful, even if they arise from defects in it.
   - The origin of this software must not be misrepresented, either by
   explicit claim or by omission.
   - You are allowed to distributed modified copies of the software, in source
   and binary form, provided they are marked plainly as altered versions, and
   are not misrepresented as being the original software.
   ========================================================================= */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <Memory.h>
#include <GUSICommandLine.h>
#include <stdlib.h>

/* ===========================
 ============================================== */

DECLARE_MAIN(curl)

REGISTER_MAIN_START
REGISTER_MAIN(curl)
REGISTER_MAIN_END

/* ========================================================================= */

int main()
{
        ::MaxApplZone();
        for (int i = 1; i <= 10; i++)
                ::MoreMasters();

        (void) exec_commands();

        return 0;
}
\ No newline at end of file
diff --git a/src/makefile.amiga b/src/makefile.amiga
index 3bc0080f8..38c426834 100644
--- a/src/makefile.amiga
+++ b/src/makefile.amiga
@@ -1,5 +1,26 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
 #
-# $VER: curl Makefile for AmigaOS ...
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+#
+# curl Makefile for AmigaOS ...
 #
 
 # change the follow to where you have the AmiTCP SDK v4.3 includes:
diff --git a/src/makefile.dj b/src/makefile.dj
index a9f5d3a5e..259d4c908 100644
--- a/src/makefile.dj
+++ b/src/makefile.dj
@@ -6,7 +6,7 @@
 #                             \___|\___/|_| \_\_____|
 #
 # Copyright (C) 2003 - 2007, Gisle Vanem <address@hidden>.
-# Copyright (C) 2003 - 2015, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2003 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index e093b2c84..2ae7944e3 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -254,6 +254,9 @@ struct OperationConfig {
   bool ssl_no_revoke;       /* disable SSL certificate revocation checks */
   /*bool proxy_ssl_no_revoke; */
 
+  bool ssl_revoke_best_effort; /* ignore SSL revocation offline/missing
+                                  revocation list errors */
+
   bool use_metalink;        /* process given URLs as metalink XML file */
   metalinkfile *metalinkfile_list; /* point to the first node */
   metalinkfile *metalinkfile_last; /* point to the last/current node */
diff --git a/src/tool_doswin.c b/src/tool_doswin.c
index 221e3864b..b7df3e615 100644
--- a/src/tool_doswin.c
+++ b/src/tool_doswin.c
@@ -697,8 +697,8 @@ cleanup:
   return slist;
 }
 
-LARGE_INTEGER Curl_freq;
-bool Curl_isVistaOrGreater;
+LARGE_INTEGER tool_freq;
+bool tool_isVistaOrGreater;
 
 CURLcode win32_init(void)
 {
@@ -713,13 +713,13 @@ CURLcode win32_init(void)
   VER_SET_CONDITION(mask, VER_MINORVERSION, op);
 
   if(VerifyVersionInfoA(&osvi, (VER_MAJORVERSION | VER_MINORVERSION), mask))
-    Curl_isVistaOrGreater = true;
+    tool_isVistaOrGreater = true;
   else if(GetLastError() == ERROR_OLD_WIN_VERSION)
-    Curl_isVistaOrGreater = false;
+    tool_isVistaOrGreater = false;
   else
     return CURLE_FAILED_INIT;
 
-  QueryPerformanceFrequency(&Curl_freq);
+  QueryPerformanceFrequency(&tool_freq);
   return CURLE_OK;
 }
 
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 764caa203..0252ee029 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -249,6 +249,7 @@ static const struct LongShort aliases[]= {
   {"Eq", "cert-status",              ARG_BOOL},
   {"Er", "false-start",              ARG_BOOL},
   {"Es", "ssl-no-revoke",            ARG_BOOL},
+  {"ES", "ssl-revoke-best-effort",   ARG_BOOL},
   {"Et", "tcp-fastopen",             ARG_BOOL},
   {"Eu", "proxy-tlsuser",            ARG_STRING},
   {"Ev", "proxy-tlspassword",        ARG_STRING},
@@ -1606,6 +1607,11 @@ ParameterError getparameter(const char *flag, /* f or 
-long-flag */
           config->ssl_no_revoke = TRUE;
         break;
 
+      case 'S': /* --ssl-revoke-best-effort */
+        if(curlinfo->features & CURL_VERSION_SSL)
+          config->ssl_revoke_best_effort = TRUE;
+        break;
+
       case 't': /* --tcp-fastopen */
         config->tcp_fastopen = TRUE;
         break;
@@ -2252,6 +2258,7 @@ ParameterError parse_args(struct GlobalConfig *global, 
int argc,
         char *nextarg = (i < (argc - 1)) ? argv[i + 1] : NULL;
 
         result = getparameter(flag, nextarg, &passarg, global, config);
+        config = global->last;
         if(result == PARAM_NEXT_OPERATION) {
           /* Reset result as PARAM_NEXT_OPERATION is only used here and not
              returned from this function */
diff --git a/src/tool_help.c b/src/tool_help.c
index 9ee99d174..5afaf822e 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -40,7 +40,7 @@
  ---------------------------------------------------------
 
   cd $srcroot/docs/cmdline-opts
-  ./gen.pl listhelp
+  ./gen.pl listhelp *.d
  */
 
 struct helptxt {
@@ -437,6 +437,8 @@ static const struct helptxt helptext[] = {
    "Allow security flaw to improve interop"},
   {"    --ssl-no-revoke",
    "Disable cert revocation checks (Schannel)"},
+  {"    --ssl-revoke-best-effort",
+   "Ignore revocation offline or missing revocation list errors (Schannel)"},
   {"    --ssl-reqd",
    "Require SSL/TLS"},
   {"-2, --sslv2",
@@ -550,7 +552,6 @@ static const struct feat feats[] = {
   {"MultiSSL",       CURL_VERSION_MULTI_SSL},
   {"PSL",            CURL_VERSION_PSL},
   {"alt-svc",        CURL_VERSION_ALTSVC},
-  {"ESNI",           CURL_VERSION_ESNI},
 };
 
 void tool_help(void)
diff --git a/src/tool_hugehelp.c.cvs b/src/tool_hugehelp.c.cvs
index 6ec5e9149..d1fb41b86 100644
--- a/src/tool_hugehelp.c.cvs
+++ b/src/tool_hugehelp.c.cvs
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/src/tool_metalink.c b/src/tool_metalink.c
index f87f686f1..fce18d5a4 100644
--- a/src/tool_metalink.c
+++ b/src/tool_metalink.c
@@ -336,8 +336,8 @@ static void win32_crypto_final(struct win32_crypto_hash 
*ctx,
 
 static int MD5_Init(MD5_CTX *ctx)
 {
-  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
-                         PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
+                         CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
     CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
   }
   return 1;
@@ -357,8 +357,8 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX 
*ctx)
 
 static int SHA1_Init(SHA_CTX *ctx)
 {
-  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
-                         PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
+                         CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
     CryptCreateHash(ctx->hCryptProv, CALG_SHA1, 0, 0, &ctx->hHash);
   }
   return 1;
@@ -378,8 +378,8 @@ static void SHA1_Final(unsigned char digest[20], SHA_CTX 
*ctx)
 
 static int SHA256_Init(SHA256_CTX *ctx)
 {
-  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
-                         PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES,
+                         CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
     CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
   }
   return 1;
@@ -401,9 +401,9 @@ static void SHA256_Final(unsigned char digest[32], 
SHA256_CTX *ctx)
 
 const digest_params MD5_DIGEST_PARAMS[] = {
   {
-    CURLX_FUNCTION_CAST(Curl_digest_init_func, MD5_Init),
-    CURLX_FUNCTION_CAST(Curl_digest_update_func, MD5_Update),
-    CURLX_FUNCTION_CAST(Curl_digest_final_func, MD5_Final),
+    CURLX_FUNCTION_CAST(digest_init_func, MD5_Init),
+    CURLX_FUNCTION_CAST(digest_update_func, MD5_Update),
+    CURLX_FUNCTION_CAST(digest_final_func, MD5_Final),
     sizeof(MD5_CTX),
     16
   }
@@ -411,9 +411,9 @@ const digest_params MD5_DIGEST_PARAMS[] = {
 
 const digest_params SHA1_DIGEST_PARAMS[] = {
   {
-    CURLX_FUNCTION_CAST(Curl_digest_init_func, SHA1_Init),
-    CURLX_FUNCTION_CAST(Curl_digest_update_func, SHA1_Update),
-    CURLX_FUNCTION_CAST(Curl_digest_final_func, SHA1_Final),
+    CURLX_FUNCTION_CAST(digest_init_func, SHA1_Init),
+    CURLX_FUNCTION_CAST(digest_update_func, SHA1_Update),
+    CURLX_FUNCTION_CAST(digest_final_func, SHA1_Final),
     sizeof(SHA_CTX),
     20
   }
@@ -421,9 +421,9 @@ const digest_params SHA1_DIGEST_PARAMS[] = {
 
 const digest_params SHA256_DIGEST_PARAMS[] = {
   {
-    CURLX_FUNCTION_CAST(Curl_digest_init_func, SHA256_Init),
-    CURLX_FUNCTION_CAST(Curl_digest_update_func, SHA256_Update),
-    CURLX_FUNCTION_CAST(Curl_digest_final_func, SHA256_Final),
+    CURLX_FUNCTION_CAST(digest_init_func, SHA256_Init),
+    CURLX_FUNCTION_CAST(digest_update_func, SHA256_Update),
+    CURLX_FUNCTION_CAST(digest_final_func, SHA256_Final),
     sizeof(SHA256_CTX),
     32
   }
@@ -457,7 +457,7 @@ static const metalink_digest_alias digest_aliases[] = {
   {NULL, NULL}
 };
 
-digest_context *Curl_digest_init(const digest_params *dparams)
+static digest_context *digest_init(const digest_params *dparams)
 {
   digest_context *ctxt;
 
@@ -485,16 +485,16 @@ digest_context *Curl_digest_init(const digest_params 
*dparams)
   return ctxt;
 }
 
-int Curl_digest_update(digest_context *context,
-                       const unsigned char *data,
-                       unsigned int len)
+static int digest_update(digest_context *context,
+                         const unsigned char *data,
+                         unsigned int len)
 {
   (*context->digest_hash->digest_update)(context->digest_hashctx, data, len);
 
   return 0;
 }
 
-int Curl_digest_final(digest_context *context, unsigned char *result)
+static int digest_final(digest_context *context, unsigned char *result)
 {
   if(result)
     (*context->digest_hash->digest_final)(result, context->digest_hashctx);
@@ -551,7 +551,7 @@ static int check_hash(const char *filename,
     return -1;
   }
 
-  dctx = Curl_digest_init(digest_def->dparams);
+  dctx = digest_init(digest_def->dparams);
   if(!dctx) {
     fprintf(error, "Metalink: validating (%s) [%s] FAILED (%s)\n", filename,
             digest_def->hash_name, "failed to initialize hash algorithm");
@@ -562,7 +562,7 @@ static int check_hash(const char *filename,
   result = malloc(digest_def->dparams->digest_resultlen);
   if(!result) {
     close(fd);
-    Curl_digest_final(dctx, NULL);
+    digest_final(dctx, NULL);
     return -1;
   }
   while(1) {
@@ -574,13 +574,13 @@ static int check_hash(const char *filename,
     else if(len == -1) {
       fprintf(error, "Metalink: validating (%s) [%s] FAILED (%s)\n", filename,
               digest_def->hash_name, strerror(errno));
-      Curl_digest_final(dctx, result);
+      digest_final(dctx, result);
       close(fd);
       return -1;
     }
-    Curl_digest_update(dctx, buf, (unsigned int)len);
+    digest_update(dctx, buf, (unsigned int)len);
   }
-  Curl_digest_final(dctx, result);
+  digest_final(dctx, result);
   check_ok = memcmp(result, digest,
                     digest_def->dparams->digest_resultlen) == 0;
   /* sha*sum style verdict output */
diff --git a/src/tool_metalink.h b/src/tool_metalink.h
index f5ec306f7..db2f702e5 100644
--- a/src/tool_metalink.h
+++ b/src/tool_metalink.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -28,19 +28,19 @@ struct GlobalConfig;
 struct OperationConfig;
 
 /* returns 1 for success, 0 otherwise (we use OpenSSL *_Init fncs directly) */
-typedef int (* Curl_digest_init_func)(void *context);
+typedef int (*digest_init_func)(void *context);
 
-typedef void (* Curl_digest_update_func)(void *context,
-                                         const unsigned char *data,
-                                         unsigned int len);
-typedef void (* Curl_digest_final_func)(unsigned char *result, void *context);
+typedef void (*digest_update_func)(void *context,
+                                   const unsigned char *data,
+                                   unsigned int len);
+typedef void (*digest_final_func)(unsigned char *result, void *context);
 
 typedef struct {
-  Curl_digest_init_func     digest_init;   /* Initialize context procedure */
-  Curl_digest_update_func   digest_update; /* Update context with data */
-  Curl_digest_final_func    digest_final;  /* Get final result procedure */
-  unsigned int           digest_ctxtsize;  /* Context structure size */
-  unsigned int           digest_resultlen; /* Result length (bytes) */
+  digest_init_func     digest_init;   /* Initialize context procedure */
+  digest_update_func   digest_update; /* Update context with data */
+  digest_final_func    digest_final;  /* Get final result procedure */
+  unsigned int         digest_ctxtsize;  /* Context structure size */
+  unsigned int         digest_resultlen; /* Result length (bytes) */
 } digest_params;
 
 typedef struct {
@@ -48,12 +48,6 @@ typedef struct {
   void                  *digest_hashctx;   /* Hash function context */
 } digest_context;
 
-digest_context * Curl_digest_init(const digest_params *dparams);
-int Curl_digest_update(digest_context *context,
-                       const unsigned char *data,
-                       unsigned int len);
-int Curl_digest_final(digest_context *context, unsigned char *result);
-
 typedef struct {
   const char *hash_name;
   const digest_params *dparams;
diff --git a/src/tool_operate.c b/src/tool_operate.c
index cb877986c..3f83136af 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -31,6 +31,8 @@
 
 #ifdef HAVE_SYS_SELECT_H
 #  include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#  include <unistd.h>
 #endif
 
 #ifdef __VMS
@@ -903,35 +905,6 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
         /* default output stream is stdout */
         outs->stream = stdout;
 
-        /* --etag-save */
-        etag_save = &per->etag_save;
-        etag_save->stream = stdout;
-
-        if(config->etag_save_file) {
-          /* open file for output: */
-          if(strcmp(config->etag_save_file, "-")) {
-            FILE *newfile = fopen(config->etag_save_file, "wb");
-            if(!newfile) {
-              warnf(
-                config->global,
-                "Failed to open %s\n", config->etag_save_file);
-
-              result = CURLE_WRITE_ERROR;
-              break;
-            }
-            else {
-              etag_save->filename = config->etag_save_file;
-              etag_save->s_isreg = TRUE;
-              etag_save->fopened = TRUE;
-              etag_save->stream = newfile;
-            }
-          }
-          else {
-            /* always use binary mode for protocol header output */
-            set_binmode(etag_save->stream);
-          }
-        }
-
         /* --etag-compare */
         if(config->etag_compare_file) {
           char *etag_from_file = NULL;
@@ -939,7 +912,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
 
           /* open file for reading: */
           FILE *file = fopen(config->etag_compare_file, FOPEN_READTEXT);
-          if(!file) {
+          if(!file && !config->etag_save_file) {
             errorf(config->global,
                    "Failed to open %s\n", config->etag_compare_file);
             result = CURLE_READ_ERROR;
@@ -973,6 +946,35 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
           }
         }
 
+        /* --etag-save */
+        etag_save = &per->etag_save;
+        etag_save->stream = stdout;
+
+        if(config->etag_save_file) {
+          /* open file for output: */
+          if(strcmp(config->etag_save_file, "-")) {
+            FILE *newfile = fopen(config->etag_save_file, "wb");
+            if(!newfile) {
+              warnf(
+                config->global,
+                "Failed to open %s\n", config->etag_save_file);
+
+              result = CURLE_WRITE_ERROR;
+              break;
+            }
+            else {
+              etag_save->filename = config->etag_save_file;
+              etag_save->s_isreg = TRUE;
+              etag_save->fopened = TRUE;
+              etag_save->stream = newfile;
+            }
+          }
+          else {
+            /* always use binary mode for protocol header output */
+            set_binmode(etag_save->stream);
+          }
+        }
+
         if(metalink) {
           /* For Metalink download, use name in Metalink file as
              filename. */
@@ -1898,9 +1900,11 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
           my_setopt_str(curl, CURLOPT_GSSAPI_DELEGATION,
                         config->gssapi_delegation);
 
-        /* new in 7.25.0 and 7.44.0 */
+        /* new in 7.25.0, 7.44.0 and 7.70.0 */
         {
           long mask = (config->ssl_allow_beast ? CURLSSLOPT_ALLOW_BEAST : 0) |
+                      (config->ssl_revoke_best_effort ?
+                       CURLSSLOPT_REVOKE_BEST_EFFORT : 0) |
                       (config->ssl_no_revoke ? CURLSSLOPT_NO_REVOKE : 0);
           if(mask)
             my_setopt_bitmask(curl, CURLOPT_SSL_OPTIONS, mask);
@@ -2055,7 +2059,7 @@ static CURLcode add_parallel_transfers(struct 
GlobalConfig *global,
   *addedp = FALSE;
   *morep = FALSE;
   result = create_transfer(global, share, addedp);
-  if(result || !*addedp)
+  if(result)
     return result;
   for(per = transfers; per && (all_added < global->parallel_max);
       per = per->next) {
diff --git a/src/tool_parsecfg.c b/src/tool_parsecfg.c
index a9057ea31..efb9159e7 100644
--- a/src/tool_parsecfg.c
+++ b/src/tool_parsecfg.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -76,7 +76,7 @@ int parseconfig(const char *filename, struct GlobalConfig 
*global)
   FILE *file = NULL;
   bool usedarg = FALSE;
   int rc = 0;
-  struct OperationConfig *operation = global->first;
+  struct OperationConfig *operation = global->last;
   char *pathalloc = NULL;
 
   if(!filename || !*filename) {
@@ -233,6 +233,7 @@ int parseconfig(const char *filename, struct GlobalConfig 
*global)
       fprintf(stderr, "PARAM: \"%s\"\n",(param ? param : "(null)"));
 #endif
       res = getparameter(option, param, &usedarg, global, operation);
+      operation = global->last;
 
       if(!res && param && *param && !usedarg)
         /* we passed in a parameter that wasn't used! */
diff --git a/src/tool_setopt.c b/src/tool_setopt.c
index 9b308bf4a..f244ba490 100644
--- a/src/tool_setopt.c
+++ b/src/tool_setopt.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -125,6 +125,7 @@ const NameValueUnsigned setopt_nv_CURLSSLOPT[] = {
   NV(CURLSSLOPT_ALLOW_BEAST),
   NV(CURLSSLOPT_NO_REVOKE),
   NV(CURLSSLOPT_NO_PARTIALCHAIN),
+  NV(CURLSSLOPT_REVOKE_BEST_EFFORT),
   NVEND,
 };
 
@@ -284,7 +285,8 @@ CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig 
*config,
     /* we only use this for real if --libcurl was used */
     const NameValue *nv = NULL;
     for(nv = nvlist; nv->name; nv++) {
-      if(nv->value == lval) break; /* found it */
+      if(nv->value == lval)
+        break; /* found it */
     }
     if(! nv->name) {
       /* If no definition was found, output an explicit value.
diff --git a/src/tool_sleep.c b/src/tool_sleep.c
index 67a54435f..0fd74a6d9 100644
--- a/src/tool_sleep.c
+++ b/src/tool_sleep.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,6 +23,8 @@
 
 #ifdef HAVE_SYS_SELECT_H
 #  include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#  include <unistd.h>
 #endif
 
 #ifdef HAVE_POLL_H
diff --git a/src/tool_util.c b/src/tool_util.c
index 8bbfae03e..3ca13e7cb 100644
--- a/src/tool_util.c
+++ b/src/tool_util.c
@@ -28,19 +28,19 @@
 #if defined(WIN32) && !defined(MSDOS)
 
 /* set in win32_init() */
-extern LARGE_INTEGER Curl_freq;
-extern bool Curl_isVistaOrGreater;
+extern LARGE_INTEGER tool_freq;
+extern bool tool_isVistaOrGreater;
 
 /* In case of bug fix this function has a counterpart in timeval.c */
 struct timeval tvnow(void)
 {
   struct timeval now;
-  if(Curl_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */
+  if(tool_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */
     LARGE_INTEGER count;
     QueryPerformanceCounter(&count);
-    now.tv_sec = (long)(count.QuadPart / Curl_freq.QuadPart);
-    now.tv_usec = (long)((count.QuadPart % Curl_freq.QuadPart) * 1000000 /
-                         Curl_freq.QuadPart);
+    now.tv_sec = (long)(count.QuadPart / tool_freq.QuadPart);
+    now.tv_usec = (long)((count.QuadPart % tool_freq.QuadPart) * 1000000 /
+                         tool_freq.QuadPart);
   }
   else {
     /* Disable /analyze warning that GetTickCount64 is preferred  */
diff --git a/src/tool_writeout.c b/src/tool_writeout.c
index 27b2ac50d..32c95b45f 100644
--- a/src/tool_writeout.c
+++ b/src/tool_writeout.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,87 +25,81 @@
 #include "curlx.h"
 #include "tool_cfgable.h"
 #include "tool_writeout.h"
+#include "tool_writeout_json.h"
 
 #include "memdebug.h" /* keep this as LAST include */
 
-typedef enum {
-  VAR_NONE,       /* must be the first */
-  VAR_TOTAL_TIME,
-  VAR_NAMELOOKUP_TIME,
-  VAR_CONNECT_TIME,
-  VAR_APPCONNECT_TIME,
-  VAR_PRETRANSFER_TIME,
-  VAR_STARTTRANSFER_TIME,
-  VAR_SIZE_DOWNLOAD,
-  VAR_SIZE_UPLOAD,
-  VAR_SPEED_DOWNLOAD,
-  VAR_SPEED_UPLOAD,
-  VAR_HTTP_CODE,
-  VAR_HTTP_CODE_PROXY,
-  VAR_HEADER_SIZE,
-  VAR_REQUEST_SIZE,
-  VAR_EFFECTIVE_URL,
-  VAR_CONTENT_TYPE,
-  VAR_NUM_CONNECTS,
-  VAR_REDIRECT_TIME,
-  VAR_REDIRECT_COUNT,
-  VAR_FTP_ENTRY_PATH,
-  VAR_REDIRECT_URL,
-  VAR_SSL_VERIFY_RESULT,
-  VAR_PROXY_SSL_VERIFY_RESULT,
-  VAR_EFFECTIVE_FILENAME,
-  VAR_PRIMARY_IP,
-  VAR_PRIMARY_PORT,
-  VAR_LOCAL_IP,
-  VAR_LOCAL_PORT,
-  VAR_HTTP_VERSION,
-  VAR_SCHEME,
-  VAR_STDOUT,
-  VAR_STDERR,
-  VAR_NUM_OF_VARS /* must be the last */
-} replaceid;
-
-struct variable {
-  const char *name;
-  replaceid id;
-};
-
-
-static const struct variable replacements[]={
-  {"url_effective", VAR_EFFECTIVE_URL},
-  {"http_code", VAR_HTTP_CODE},
-  {"response_code", VAR_HTTP_CODE},
-  {"http_connect", VAR_HTTP_CODE_PROXY},
-  {"time_total", VAR_TOTAL_TIME},
-  {"time_namelookup", VAR_NAMELOOKUP_TIME},
-  {"time_connect", VAR_CONNECT_TIME},
-  {"time_appconnect", VAR_APPCONNECT_TIME},
-  {"time_pretransfer", VAR_PRETRANSFER_TIME},
-  {"time_starttransfer", VAR_STARTTRANSFER_TIME},
-  {"size_header", VAR_HEADER_SIZE},
-  {"size_request", VAR_REQUEST_SIZE},
-  {"size_download", VAR_SIZE_DOWNLOAD},
-  {"size_upload", VAR_SIZE_UPLOAD},
-  {"speed_download", VAR_SPEED_DOWNLOAD},
-  {"speed_upload", VAR_SPEED_UPLOAD},
-  {"content_type", VAR_CONTENT_TYPE},
-  {"num_connects", VAR_NUM_CONNECTS},
-  {"time_redirect", VAR_REDIRECT_TIME},
-  {"num_redirects", VAR_REDIRECT_COUNT},
-  {"ftp_entry_path", VAR_FTP_ENTRY_PATH},
-  {"redirect_url", VAR_REDIRECT_URL},
-  {"ssl_verify_result", VAR_SSL_VERIFY_RESULT},
-  {"proxy_ssl_verify_result", VAR_PROXY_SSL_VERIFY_RESULT},
-  {"filename_effective", VAR_EFFECTIVE_FILENAME},
-  {"remote_ip", VAR_PRIMARY_IP},
-  {"remote_port", VAR_PRIMARY_PORT},
-  {"local_ip", VAR_LOCAL_IP},
-  {"local_port", VAR_LOCAL_PORT},
-  {"http_version", VAR_HTTP_VERSION},
-  {"scheme", VAR_SCHEME},
-  {"stdout", VAR_STDOUT},
-  {"stderr", VAR_STDERR},
-  {NULL, VAR_NONE}
+static const struct writeoutvar variables[] = {
+  {"url_effective", VAR_EFFECTIVE_URL, 0,
+   CURLINFO_EFFECTIVE_URL, JSON_STRING},
+  {"http_code", VAR_HTTP_CODE, 0,
+   CURLINFO_RESPONSE_CODE, JSON_LONG},
+  {"response_code", VAR_HTTP_CODE, 0,
+   CURLINFO_RESPONSE_CODE, JSON_LONG},
+  {"http_connect", VAR_HTTP_CODE_PROXY, 0,
+   CURLINFO_HTTP_CONNECTCODE, JSON_LONG},
+  {"time_total", VAR_TOTAL_TIME, 0,
+   CURLINFO_TOTAL_TIME_T, JSON_TIME},
+  {"time_namelookup", VAR_NAMELOOKUP_TIME, 0,
+   CURLINFO_NAMELOOKUP_TIME_T, JSON_TIME},
+  {"time_connect", VAR_CONNECT_TIME, 0,
+   CURLINFO_CONNECT_TIME_T, JSON_TIME},
+  {"time_appconnect", VAR_APPCONNECT_TIME, 0,
+   CURLINFO_APPCONNECT_TIME_T, JSON_TIME},
+  {"time_pretransfer", VAR_PRETRANSFER_TIME, 0,
+   CURLINFO_PRETRANSFER_TIME_T, JSON_TIME},
+  {"time_starttransfer", VAR_STARTTRANSFER_TIME, 0,
+   CURLINFO_STARTTRANSFER_TIME_T, JSON_TIME},
+  {"size_header", VAR_HEADER_SIZE, 0,
+   CURLINFO_HEADER_SIZE, JSON_LONG},
+  {"size_request", VAR_REQUEST_SIZE, 0,
+   CURLINFO_REQUEST_SIZE, JSON_LONG},
+  {"size_download", VAR_SIZE_DOWNLOAD, 0,
+   CURLINFO_SIZE_DOWNLOAD_T, JSON_OFFSET},
+  {"size_upload", VAR_SIZE_UPLOAD, 0,
+   CURLINFO_SIZE_UPLOAD_T, JSON_OFFSET},
+  {"speed_download", VAR_SPEED_DOWNLOAD, 0,
+   CURLINFO_SPEED_DOWNLOAD_T, JSON_OFFSET},
+  {"speed_upload", VAR_SPEED_UPLOAD, 0,
+   CURLINFO_SPEED_UPLOAD_T, JSON_OFFSET},
+  {"content_type", VAR_CONTENT_TYPE, 0,
+   CURLINFO_CONTENT_TYPE, JSON_STRING},
+  {"num_connects", VAR_NUM_CONNECTS, 0,
+   CURLINFO_NUM_CONNECTS, JSON_LONG},
+  {"time_redirect", VAR_REDIRECT_TIME, 0,
+   CURLINFO_REDIRECT_TIME_T, JSON_TIME},
+  {"num_redirects", VAR_REDIRECT_COUNT, 0,
+   CURLINFO_REDIRECT_COUNT, JSON_LONG},
+  {"ftp_entry_path", VAR_FTP_ENTRY_PATH, 0,
+   CURLINFO_FTP_ENTRY_PATH, JSON_STRING},
+  {"redirect_url", VAR_REDIRECT_URL, 0,
+   CURLINFO_REDIRECT_URL, JSON_STRING},
+  {"ssl_verify_result", VAR_SSL_VERIFY_RESULT, 0,
+   CURLINFO_SSL_VERIFYRESULT, JSON_LONG},
+  {"proxy_ssl_verify_result", VAR_PROXY_SSL_VERIFY_RESULT, 0,
+   CURLINFO_PROXY_SSL_VERIFYRESULT, JSON_LONG},
+  {"filename_effective", VAR_EFFECTIVE_FILENAME, 0,
+   0, JSON_FILENAME},
+  {"remote_ip", VAR_PRIMARY_IP, 0,
+   CURLINFO_PRIMARY_IP, JSON_STRING},
+  {"remote_port", VAR_PRIMARY_PORT, 0,
+   CURLINFO_PRIMARY_PORT, JSON_LONG},
+  {"local_ip", VAR_LOCAL_IP, 0,
+   CURLINFO_LOCAL_IP, JSON_STRING},
+  {"local_port", VAR_LOCAL_PORT, 0,
+   CURLINFO_LOCAL_PORT, JSON_LONG},
+  {"http_version", VAR_HTTP_VERSION, 0,
+   CURLINFO_HTTP_VERSION, JSON_VERSION},
+  {"scheme", VAR_SCHEME, 0,
+   CURLINFO_SCHEME, JSON_STRING},
+  {"stdout", VAR_STDOUT, 1,
+   0, JSON_NONE},
+  {"stderr", VAR_STDERR, 1,
+   0, JSON_NONE},
+  {"json", VAR_JSON, 1,
+   0, JSON_NONE},
+  {NULL, VAR_NONE, 1,
+   0, JSON_NONE}
 };
 
 void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
@@ -138,10 +132,10 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, 
const char *writeinfo)
           }
           keepit = *end;
           *end = 0; /* zero terminate */
-          for(i = 0; replacements[i].name; i++) {
-            if(curl_strequal(ptr, replacements[i].name)) {
+          for(i = 0; variables[i].name; i++) {
+            if(curl_strequal(ptr, variables[i].name)) {
               match = TRUE;
-              switch(replacements[i].id) {
+              switch(variables[i].id) {
               case VAR_EFFECTIVE_URL:
                 if((CURLE_OK ==
                     curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &stringp))
@@ -334,6 +328,8 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const 
char *writeinfo)
               case VAR_STDERR:
                 stream = stderr;
                 break;
+              case VAR_JSON:
+                ourWriteOutJSON(variables, curl, outs, stream);
               default:
                 break;
               }
diff --git a/src/tool_writeout.h b/src/tool_writeout.h
index ee8990f77..a21787ab9 100644
--- a/src/tool_writeout.h
+++ b/src/tool_writeout.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,6 +23,62 @@
  ***************************************************************************/
 #include "tool_setup.h"
 
+typedef enum {
+  VAR_NONE,       /* must be the first */
+  VAR_TOTAL_TIME,
+  VAR_NAMELOOKUP_TIME,
+  VAR_CONNECT_TIME,
+  VAR_APPCONNECT_TIME,
+  VAR_PRETRANSFER_TIME,
+  VAR_STARTTRANSFER_TIME,
+  VAR_SIZE_DOWNLOAD,
+  VAR_SIZE_UPLOAD,
+  VAR_SPEED_DOWNLOAD,
+  VAR_SPEED_UPLOAD,
+  VAR_HTTP_CODE,
+  VAR_HTTP_CODE_PROXY,
+  VAR_HEADER_SIZE,
+  VAR_REQUEST_SIZE,
+  VAR_EFFECTIVE_URL,
+  VAR_CONTENT_TYPE,
+  VAR_NUM_CONNECTS,
+  VAR_REDIRECT_TIME,
+  VAR_REDIRECT_COUNT,
+  VAR_FTP_ENTRY_PATH,
+  VAR_REDIRECT_URL,
+  VAR_SSL_VERIFY_RESULT,
+  VAR_PROXY_SSL_VERIFY_RESULT,
+  VAR_EFFECTIVE_FILENAME,
+  VAR_PRIMARY_IP,
+  VAR_PRIMARY_PORT,
+  VAR_LOCAL_IP,
+  VAR_LOCAL_PORT,
+  VAR_HTTP_VERSION,
+  VAR_SCHEME,
+  VAR_STDOUT,
+  VAR_STDERR,
+  VAR_JSON,
+  VAR_NUM_OF_VARS /* must be the last */
+} writeoutid;
+
+typedef enum {
+  JSON_NONE,
+  JSON_STRING,
+  JSON_LONG,
+  JSON_OFFSET,
+  JSON_TIME,
+  JSON_VERSION,
+  JSON_FILENAME
+} jsontype;
+
+struct writeoutvar {
+  const char *name;
+  writeoutid id;
+  int is_ctrl;
+  CURLINFO cinfo;
+  jsontype jsontype;
+};
+
 void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo);
 
 #endif /* HEADER_CURL_TOOL_WRITEOUT_H */
diff --git a/src/tool_writeout_json.c b/src/tool_writeout_json.c
new file mode 100644
index 000000000..dfe51b9ff
--- /dev/null
+++ b/src/tool_writeout_json.c
@@ -0,0 +1,195 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#define ENABLE_CURLX_PRINTF
+
+/* use our own printf() functions */
+#include "curlx.h"
+#include "tool_cfgable.h"
+#include "tool_writeout_json.h"
+#include "tool_writeout.h"
+
+
+static const char *http_version[] = {
+  "0",   /* CURL_HTTP_VERSION_NONE */
+  "1",   /* CURL_HTTP_VERSION_1_0 */
+  "1.1", /* CURL_HTTP_VERSION_1_1 */
+  "2",   /* CURL_HTTP_VERSION_2 */
+  "3"    /* CURL_HTTP_VERSION_3 */
+};
+
+static void jsonEscape(FILE *stream, const char *in)
+{
+  const char *i = in;
+  const char *in_end = in + strlen(in);
+
+  for(; i < in_end; i++) {
+    switch(*i) {
+    case '\\':
+      fputs("\\\\", stream);
+      break;
+    case '\"':
+      fputs("\\\"", stream);
+      break;
+    case '\b':
+      fputs("\\b", stream);
+      break;
+    case '\f':
+      fputs("\\f", stream);
+      break;
+    case '\n':
+      fputs("\\n", stream);
+      break;
+    case '\r':
+      fputs("\\r", stream);
+      break;
+    case '\t':
+      fputs("\\t", stream);
+      break;
+    default:
+      if (*i < 32) {
+        fprintf(stream, "u%04x", *i);
+      }
+      else {
+        fputc(*i, stream);
+      }
+      break;
+    };
+  }
+}
+
+static int writeTime(FILE *str, CURL *curl, const char *key, CURLINFO ci)
+{
+  curl_off_t val = 0;
+  if(CURLE_OK == curl_easy_getinfo(curl, ci, &val)) {
+    curl_off_t s = val / 1000000l;
+    curl_off_t ms = val % 1000000l;
+    fprintf(str, "\"%s\":%" CURL_FORMAT_CURL_OFF_T
+            ".%06" CURL_FORMAT_CURL_OFF_T, key, s, ms);
+    return 1;
+  }
+  return 0;
+}
+
+static int writeString(FILE *str, CURL *curl, const char *key, CURLINFO ci)
+{
+  char *valp = NULL;
+  if((CURLE_OK == curl_easy_getinfo(curl, ci, &valp)) && valp) {
+    fprintf(str, "\"%s\":\"", key);
+    jsonEscape(str, valp);
+    fprintf(str, "\"");
+    return 1;
+  }
+  return 0;
+}
+
+static int writeLong(FILE *str, CURL *curl, const char *key, CURLINFO ci)
+{
+  long val = 0;
+  if(CURLE_OK == curl_easy_getinfo(curl, ci, &val)) {
+    fprintf(str, "\"%s\":%ld", key, val);
+    return 1;
+  }
+  return 0;
+}
+
+static int writeOffset(FILE *str, CURL *curl, const char *key, CURLINFO ci)
+{
+  curl_off_t val = 0;
+  if(CURLE_OK == curl_easy_getinfo(curl, ci, &val)) {
+    fprintf(str, "\"%s\":%" CURL_FORMAT_CURL_OFF_T, key, val);
+    return 1;
+  }
+  return 0;
+}
+
+static int writeFilename(FILE *str, const char *key, const char *filename)
+{
+  if(filename) {
+    fprintf(str, "\"%s\":\"", key);
+    jsonEscape(str, filename);
+    fprintf(str, "\"");
+  }
+  else {
+    fprintf(str, "\"%s\":null", key);
+  }
+  return 1;
+}
+
+static int writeVersion(FILE *str, CURL *curl, const char *key, CURLINFO ci)
+{
+  long version = 0;
+  if(CURLE_OK == curl_easy_getinfo(curl, ci, &version) &&
+     (version >= 0) &&
+     (version < (long)(sizeof(http_version)/sizeof(char *)))) {
+    fprintf(str, "\"%s\":\"%s\"", key, http_version[version]);
+    return 1;
+  }
+  return 0;
+}
+
+void ourWriteOutJSON(const struct writeoutvar mappings[], CURL *curl,
+        struct OutStruct *outs, FILE *stream)
+{
+  int i;
+
+  fputs("{", stream);
+  for(i = 0; mappings[i].name != NULL; i++) {
+    const char *name = mappings[i].name;
+    CURLINFO cinfo = mappings[i].cinfo;
+    int ok = 0;
+
+    if(mappings[i].is_ctrl == 1) {
+      continue;
+    }
+
+    switch(mappings[i].jsontype) {
+    case JSON_STRING:
+      ok = writeString(stream, curl, name, cinfo);
+      break;
+    case JSON_LONG:
+      ok = writeLong(stream, curl, name, cinfo);
+      break;
+    case JSON_OFFSET:
+      ok = writeOffset(stream, curl, name, cinfo);
+      break;
+    case JSON_TIME:
+      ok = writeTime(stream, curl, name, cinfo);
+      break;
+    case JSON_FILENAME:
+      ok = writeFilename(stream, name, outs->filename);
+      break;
+    case JSON_VERSION:
+      ok = writeVersion(stream, curl, name, cinfo);
+      break;
+    default:
+      break;
+    }
+
+    if(ok) {
+      fputs(",", stream);
+    }
+  }
+
+  fprintf(stream, "\"curl_version\":\"%s\"}", curl_version());
+}
diff --git a/src/tool_writeout.h b/src/tool_writeout_json.h
similarity index 78%
copy from src/tool_writeout.h
copy to src/tool_writeout_json.h
index ee8990f77..d3988d521 100644
--- a/src/tool_writeout.h
+++ b/src/tool_writeout_json.h
@@ -1,5 +1,5 @@
-#ifndef HEADER_CURL_TOOL_WRITEOUT_H
-#define HEADER_CURL_TOOL_WRITEOUT_H
+#ifndef HEADER_CURL_TOOL_WRITEOUT_JSON_H
+#define HEADER_CURL_TOOL_WRITEOUT_JSON_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,7 +22,9 @@
  *
  ***************************************************************************/
 #include "tool_setup.h"
+#include "tool_writeout.h"
 
-void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo);
+void ourWriteOutJSON(const struct writeoutvar mappings[],
+        CURL *curl, struct OutStruct *outs, FILE *stream);
 
 #endif /* HEADER_CURL_TOOL_WRITEOUT_H */
diff --git a/tests/.gitignore b/tests/.gitignore
index cfd109379..be918f327 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -18,8 +18,8 @@ runtests.html
 runtests.pdf
 testcurl.html
 testcurl.pdf
-
 dictserver.py
 smbserver.py
 curl_test_data.py
 negtelnetserver.py
+*.port
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 63b4cda03..a145b2b04 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 add_subdirectory(data)
 add_subdirectory(libtest)
 add_subdirectory(server)
diff --git a/tests/FILEFORMAT b/tests/FILEFORMAT
deleted file mode 100644
index 16e7d3092..000000000
--- a/tests/FILEFORMAT
+++ /dev/null
@@ -1,479 +0,0 @@
- The test suite's file format is very simple and extensible, closely
-resembling XML. All data for a single test case resides in a single
-ASCII file. Labels mark the beginning and the end of all sections, and each
-label must be written in its own line.  Comments are either XML-style
-(enclosed with <!-- and -->) or C-style (beginning with #) and must appear
-on their own lines and not alongside actual test data.  Most test data files
-are syntactically valid XML, although a few files are not (lack of
-support for character entities and the preservation of CR/LF characters at
-the end of lines are the biggest differences).
-
- The file begins with a 'testcase' tag, which encompasses the remainder of
-the file.
-
-<testcase>
-
- Each file is split up in three main sections: reply, client and verify. The
-reply section is used for the server to know what to send as a reply for the
-requests curl sends, the client section defines how the client should behave
-while the verify section defines how to verify that the data stored after a
-command has been run ended up correctly.
-
- Each main section has a number of available subsections that can be
-specified, that will be checked/used if specified. This document includes all
-the subsections currently supported.
-
-Main sections are 'info', 'reply', 'client' and 'verify'.
-
-<info>
-<keywords>
-A newline-separated list of keywords describing what this test case uses and
-tests. Try to use an already used keyword.  These keywords will be used for
-statistical/informational purposes and for choosing or skipping classes
-of tests.  "Keywords" must begin with an alphabetic character, "-", "["
-or "{" and may actually consist of multiple words separated by spaces
-which are treated together as a single identifier.
-</keywords>
-</info>
-
-<reply>
-<data [nocheck="yes"] [sendzero="yes"] [base64="yes"]>
-data to be sent to the client on its request and later verified that it arrived
-safely. Set nocheck="yes" to prevent the test script from verifying the arrival
-of this data.
-
-If the data contains 'swsclose' anywhere within the start and end tag, and
-this is a HTTP test, then the connection will be closed by the server after
-this response is sent. If not, the connection will be kept persistent.
-
-If the data contains 'swsbounce' anywhere within the start and end tag, the
-HTTP server will detect if this is a second request using the same test and
-part number and will then increase the part number with one. This is useful
-for auth tests and similar.
-
-'sendzero' set to yes means that the (FTP) server will "send" the data even if
-the size is zero bytes. Used to verify curl's behaviour on zero bytes
-transfers.
-
-'base64' set to yes means that the data provided in the test-file is a chunk
-of data encoded with base64. It is the only way a test case can contain binary
-data. (This attribute can in fact be used on any section, but it doesn't make
-much sense for other sections than "data").
-
-For FTP file listings, the <data> section will be used *only* if you make sure
-that there has been a CWD done first to a directory named 'test-[num]' where
-[num] is the test case number. Otherwise the ftp server can't know from which
-test file to load the list content.
-
-</data>
-<dataNUM>
-Send back this contents instead of the <data> one. The num is set by:
-A) The test number in the request line is >10000 and this is the remainder
-of [test case number]%10000.
-B) The request was HTTP and included digest details, which adds 1000 to NUM
-C) If a HTTP request is NTLM type-1, it adds 1001 to num
-D) If a HTTP request is NTLM type-3, it adds 1002 to num
-E) If a HTTP request is Basic and num is already >=1000, it adds 1 to num
-F) If a HTTP request is Negotiate, num gets incremented by one for each
-request with Negotiate authorization header on the same test case.
-
-Dynamically changing num in this way allows the test harness to be used to
-test authentication negotiation where several different requests must be sent
-to complete a transfer. The response to each request is found in its own data
-section.  Validating the entire negotiation sequence can be done by
-specifying a datacheck section.
-</dataNUM>
-<connect>
-The connect section is used instead of the 'data' for all CONNECT
-requests. The remainder of the rules for the data section then apply but with
-a connect prefix.
-</connect>
-<datacheck [mode="text"] [nonewline="yes"]>
-if the data is sent but this is what should be checked afterwards. If
-'nonewline' is set, we will cut off the trailing newline of this given data
-before comparing with the one actually received by the client.
-
-Use the mode="text" attribute if the output is in text mode on platforms that
-have a text/binary difference.
-</datacheck>
-<datacheckNUM [nonewline="yes"] [mode="text"]>
-The contents of numbered datacheck sections are appended to the non-numbered
-one.
-</datacheckNUM>
-<size>
-number to return on a ftp SIZE command (set to -1 to make this command fail)
-</size>
-<mdtm>
-what to send back if the client sends a (FTP) MDTM command, set to -1 to
-have it return that the file doesn't exist
-</mdtm>
-<postcmd>
-special purpose server-command to control its behavior *after* the
-reply is sent
-For HTTP/HTTPS, these are supported:
-
-wait [secs]
- - Pause for the given time
-</postcmd>
-<servercmd>
-Special-commands for the server.
-For FTP/SMTP/POP/IMAP, these are supported:
-
-REPLY [command] [return value] [response string]
- - Changes how the server responds to the [command]. [response string] is
-   evaluated as a perl string, so it can contain embedded \r\n, for example.
-   There's a special [command] named "welcome" (without quotes) which is the
-   string sent immediately on connect as a welcome.
-REPLYLF (like above but sends the response terminated with LF-only and not
-   CRLF)
-COUNT [command] [num]
- - Do the REPLY change for [command] only [num] times and then go back to the
-   built-in approach
-DELAY [command] [secs]
- - Delay responding to this command for the given time
-RETRWEIRDO
- - Enable the "weirdo" RETR case when multiple response lines appear at once
-   when a file is transferred
-RETRNOSIZE
- - Make sure the RETR response doesn't contain the size of the file
-NOSAVE
- - Don't actually save what is received
-SLOWDOWN
- - Send FTP responses with 0.01 sec delay between each byte
-PASVBADIP
- - makes PASV send back an illegal IP in its 227 response
-CAPA [capabilities]
- - Enables support for and specifies a list of space separated capabilities to
-   return to the client for the IMAP CAPABILITY, POP3 CAPA and SMTP EHLO
-   commands
-AUTH [mechanisms]
- - Enables support for SASL authentication and specifies a list of space
-   separated mechanisms for IMAP, POP3 and SMTP
-
-For HTTP/HTTPS:
-auth_required   if this is set and a POST/PUT is made without auth, the
-                server will NOT wait for the full request body to get sent
-idle            do nothing after receiving the request, just "sit idle"
-stream          continuously send data to the client, never-ending
-writedelay: [secs] delay this amount between reply packets
-skip: [num]     instructs the server to ignore reading this many bytes from a
-                PUT or POST request
-rtp: part [num] channel [num] size [num]
-               stream a fake RTP packet for the given part on a chosen channel
-               with the given payload size
-connection-monitor When used, this will log [DISCONNECT] to the server.input
-               log when the connection is disconnected.
-upgrade        when an HTTP upgrade header is found, the server will upgrade
-               to http2
-swsclose       instruct server to close connection after response
-no-expect      don't read the request body if Expect: is present
-
-For TFTP:
-writedelay: [secs] delay this amount between reply packets (each packet being
-                   512 bytes payload)
-</servercmd>
-</reply>
-
-<client>
-
-<server>
-What server(s) this test case requires/uses:
-
-file
-ftp
-ftp-ipv6
-ftps
-http
-http-ipv6
-http-proxy
-http-unix
-https
-httptls+srp
-httptls+srp-ipv6
-http/2
-imap
-none
-pop3
-rtsp
-rtsp-ipv6
-scp
-sftp
-smtp
-socks4
-socks5
-
-Give only one per line.  This subsection is mandatory.
-</server>
-
-<features>
-A list of features that MUST be present in the client/library for this test to
-be able to run. If a required feature is not present then the test will be
-SKIPPED.
-
-Alternatively a feature can be prefixed with an exclamation mark to indicate a
-feature is NOT required. If the feature is present then the test will be
-SKIPPED.
-
-Features testable here are:
-
-alt-svc
-crypto
-debug
-getrlimit
-GnuTLS
-GSS-API
-http/2
-idn
-ipv6
-Kerberos
-large_file
-ld_preload
-libz
-manual
-Metalink
-NSS
-NTLM
-OpenSSL
-PSL
-socks
-SPNEGO
-SSL
-SSLpinning
-SSPI
-threaded-resolver
-TLS-SRP
-TrackMemory
-unittest
-unix-sockets
-win32
-WinSSL
-
-as well as each protocol that curl supports.  A protocol only needs to be
-specified if it is different from the server (useful when the server
-is 'none').
-</features>
-
-<killserver>
-Using the same syntax as in <server> but when mentioned here these servers
-are explicitly KILLED when this test case is completed. Only use this if there
-is no other alternatives. Using this of course requires subsequent tests to
-restart servers.
-</killserver>
-
-<precheck>
-A command line that if set gets run by the test script before the test. If an
-output is displayed by the command or if the return code is non-zero, the test
-will be skipped and the (single-line) output will be displayed as reason for
-not running the test.  Variables are substituted as in the <command> section.
-</precheck>
-
-<postcheck>
-A command line that if set gets run by the test script after the test. If
-the command exists with a non-zero status code, the test will be considered
-to have failed. Variables are substituted as in the <command> section.
-</postcheck>
-
-<tool>
-Name of tool to use instead of "curl". This tool must be built and exist
-either in the libtest/ directory (if the tool starts with 'lib') or in the
-unit/ directory (if the tool starts with 'unit').
-</tool>
-
-<name>
-test case description
-</name>
-
-<setenv>
-variable1=contents1
-variable2=contents2
-
-Set the given environment variables to the specified value before the actual
-command is run. They are cleared again after the command has been run.
-Variables are first substituted as in the <command> section.
-</setenv>
-
-<command [option="no-output/no-include/force-output"] [timeout="secs"]
-         [delay="secs"][type="perl"]>
-command line to run, there's a bunch of %variables that get replaced
-accordingly.
-
-Note that the URL that gets passed to the server actually controls what data
-that is returned. The last slash in the URL must be followed by a number. That
-number (N) will be used by the test-server to load test case N and return the
-data that is defined within the <reply><data></data></reply> section.
-
-If there's no test number found above, the HTTP test server will use the
-number following the last dot in the given hostname (made so that a CONNECT
-can still pass on test number) so that "foo.bar.123" gets treated as test case
-123. Alternatively, if an IPv6 address is provided to CONNECT, the last
-hexadecimal group in the address will be used as the test number! For example
-the address "[1234::ff]" would be treated as test case 255.
-
-Set type="perl" to write the test case as a perl script. It implies that
-there's no memory debugging and valgrind gets shut off for this test.
-
-Set option="no-output" to prevent the test script to slap on the --output
-argument that directs the output to a file. The --output is also not added if
-the verify/stdout section is used.
-
-Set option="force-output" to make use of --output even when the test is
-otherwise written to verify stdout.
-
-Set option="no-include" to prevent the test script to slap on the --include
-argument.
-
-Set timeout="secs" to override default server logs advisor read lock timeout.
-This timeout is used by the test harness, once that the command has completed
-execution, to wait for the test server to write out server side log files and
-remove the lock that advised not to read them. The "secs" parameter is the not
-negative integer number of seconds for the timeout. This 'timeout' attribute
-is documented for completeness sake, but is deep test harness stuff and only
-needed for very singular and specific test cases. Avoid using it.
-
-Set delay="secs" to introduce a time delay once that the command has completed
-execution and before the <postcheck> section runs. The "secs" parameter is the
-not negative integer number of seconds for the delay. This 'delay' attribute
-is intended for very specific test cases, and normally not needed.
-
-Available substitute variables include:
-%CLIENT6IP - IPv6 address of the client running curl
-%CLIENTIP  - IPv4 address of the client running curl
-%CURL      - Path to the curl executable
-%FTP2PORT  - Port number of the FTP server 2
-%FTP6PORT  - IPv6 port number of the FTP server
-%FTPPORT   - Port number of the FTP server
-%FTPSPORT  - Port number of the FTPS server
-%FTPTIME2  - Timeout in seconds that should be just sufficient to receive
-             a response from the test FTP server
-%FTPTIME3  - Even longer than %FTPTIME2
-%GOPHER6PORT  - IPv6 port number of the Gopher server
-%GOPHERPORT   - Port number of the Gopher server
-%HOST6IP      - IPv6 address of the host running this test
-%HOSTIP       - IPv4 address of the host running this test
-%HTTP6PORT    - IPv6 port number of the HTTP server
-%HTTPUNIXPATH - Path to the Unix socket of the HTTP server
-%HTTPPORT     - Port number of the HTTP server
-%HTTPSPORT    - Port number of the HTTPS server
-%HTTPTLS6PORT - IPv6 port number of the HTTP TLS server
-%HTTPTLSPORT  - Port number of the HTTP TLS server
-%IMAP6PORT - IPv6 port number of the IMAP server
-%IMAPPORT  - Port number of the IMAP server
-%POP36PORT - IPv6 port number of the POP3 server
-%POP3PORT  - Port number of the POP3 server
-%PROXYPORT - Port number of the HTTP proxy
-%PWD       - Current directory
-%POSIX_PWD - Current directory somewhat mingw friendly
-%FILE_PWD  - Current directory, on windows prefixed with a slash
-%RTSP6PORT - IPv6 port number of the RTSP server
-%RTSPPORT  - Port number of the RTSP server
-%SSHSRVMD5 - MD5 of SSH server's public key
-%SMTP6PORT - IPv6 port number of the SMTP server
-%SMTPPORT  - Port number of the SMTP server
-%SOCKSPORT - Port number of the SOCKS4/5 server
-%SRCDIR    - Full path to the source dir
-%SSHPORT   - Port number of the SCP/SFTP server
-%TFTP6PORT - IPv6 port number of the TFTP server
-%TFTPPORT  - Port number of the TFTP server
-%USER      - Login ID of the user running the test
-</command>
-
-<file name="log/filename">
-This creates the named file with this content before the test case is run,
-which is useful if the test case needs a file to act on.
-Variables are substituted on the contents of the file as in the <command>
-section.
-</file>
-
-<stdin [nonewline="yes"]>
-Pass this given data on stdin to the tool.
-
-If 'nonewline' is set, we will cut off the trailing newline of this given data
-before comparing with the one actually received by the client
-</stdin>
-
-</client>
-
-<verify>
-<errorcode>
-numerical error code curl is supposed to return. Specify a list of accepted
-error codes by separating multiple numbers with comma. See test 237 for an
-example.
-</errorcode>
-<strip>
-One regex per line that is removed from the protocol dumps before the
-comparison is made. This is very useful to remove dependencies on dynamically
-changing protocol data such as port numbers or user-agent strings.
-</strip>
-<strippart>
-One perl op per line that operates on the protocol dump. This is pretty
-advanced. Example: "s/^EPRT .*/EPRT stripped/"
-</strippart>
-
-<protocol [nonewline="yes"]>
-
-the protocol dump curl should transmit, if 'nonewline' is set, we will cut off
-the trailing newline of this given data before comparing with the one actually
-sent by the client Variables are substituted as in the <command> section.  The
-<strip> and <strippart> rules are applied before comparisons are made.
-
-</protocol>
-
-<proxy [nonewline="yes"]>
-
-The protocol dump curl should transmit to a HTTP proxy (when the http-proxy
-server is used), if 'nonewline' is set, we will cut off the trailing newline
-of this given data before comparing with the one actually sent by the client
-Variables are substituted as in the <command> section. The <strip> and
-<strippart> rules are applied before comparisons are made.
-
-</proxy>
-
-<stdout [mode="text"] [nonewline="yes"]>
-This verifies that this data was passed to stdout.  Variables are
-substituted as in the <command> section.
-
-Use the mode="text" attribute if the output is in text mode on platforms that
-have a text/binary difference.
-
-If 'nonewline' is set, we will cut off the trailing newline of this given data
-before comparing with the one actually received by the client
-</stdout>
-<file name="log/filename" [mode="text"]>
-The file's contents must be identical to this after the test is complete.
-Use the mode="text" attribute if the output is in text mode on platforms that
-have a text/binary difference.
-Variables are substituted as in the <command> section.
-</file>
-<file1>
-1 to 4 can be appended to 'file' to compare more files.
-</file1>
-<file2>
-</file2>
-<file3>
-</file3>
-<file4>
-</file4>
-<stripfile>
-One perl op per line that operates on the output file or stdout before being
-compared with what is stored in the test file. This is pretty
-advanced. Example: "s/^EPRT .*/EPRT stripped/"
-</stripfile>
-<stripfile1>
-1 to 4 can be appended to 'stripfile' to strip the correspending <fileN>
-content
-</stripfile1>
-<stripfile2>
-</stripfile2>
-<stripfile3>
-</stripfile3>
-<stripfile4>
-</stripfile4>
-<upload>
-the contents of the upload data curl should have sent
-</upload>
-<valgrind>
-disable - disables the valgrind log check for this test
-</valgrind>
-</verify>
-
-</testcase>
diff --git a/tests/FILEFORMAT.md b/tests/FILEFORMAT.md
new file mode 100644
index 000000000..034b1a73c
--- /dev/null
+++ b/tests/FILEFORMAT.md
@@ -0,0 +1,473 @@
+# curl test suite file format
+
+The curl test suite's file format is very simple and extensible, closely
+resembling XML. All data for a single test case resides in a single ASCII
+file. Labels mark the beginning and the end of all sections, and each label
+must be written in its own line.  Comments are either XML-style (enclosed with
+`<!--` and `-->`) or shell script style (beginning with `#`) and must appear
+on their own lines and not alongside actual test data.  Most test data files
+are syntactically valid XML, although a few files are not (lack of support for
+character entities and the preservation of CR/LF characters at the end of
+lines are the biggest differences).
+
+Each test case exists as a file matching the format `tests/data/testNUM`,
+where NUM is considered the unique test number.
+
+The file begins with a 'testcase' tag, which encompasses the remainder of the
+file.
+
+# `<testcase>`
+
+Each test is always within the testcase tag. Each test case is split up in
+four main sections: `info`, `reply`, `client` and `verify`.
+
+- **info** provides information about the test case
+
+- **reply** is used for the server to know what to send as a reply for the
+requests curl sends
+
+- **client** defines how the client should behave
+
+- **verify** defines how to verify that the data stored after a command has
+been run ended up correctly
+
+Each main section has a number of available subsections that can be specified,
+that will be checked/used if specified.
+
+## `<info>`
+
+### `<keywords>`
+A newline-separated list of keywords describing what this test case uses and
+tests. Try to use an already used keyword.  These keywords will be used for
+statistical/informational purposes and for choosing or skipping classes
+of tests.  "Keywords" must begin with an alphabetic character, "-", "["
+or "{" and may actually consist of multiple words separated by spaces
+which are treated together as a single identifier.
+
+## `<reply>`
+
+### `<data [nocheck="yes"] [sendzero="yes"] [base64="yes"] [hex="yes"]>`
+
+data to be sent to the client on its request and later verified that it
+arrived safely. Set `nocheck="yes"` to prevent the test script from verifying
+the arrival of this data.
+
+If the data contains `swsclose` anywhere within the start and end tag, and
+this is a HTTP test, then the connection will be closed by the server after
+this response is sent. If not, the connection will be kept persistent.
+
+If the data contains `swsbounce` anywhere within the start and end tag, the
+HTTP server will detect if this is a second request using the same test and
+part number and will then increase the part number with one. This is useful
+for auth tests and similar.
+
+`sendzero=yes` means that the (FTP) server will "send" the data even if the
+size is zero bytes. Used to verify curl's behaviour on zero bytes transfers.
+
+`base64=yes` means that the data provided in the test-file is a chunk of data
+encoded with base64. It is the only way a test case can contain binary
+data. (This attribute can in fact be used on any section, but it doesn't make
+much sense for other sections than "data").
+
+`hex=yes` means that the data is a sequence of hex pairs. It will get decoded
+and used as "raw" data.
+
+For FTP file listings, the `<data>` section will be used *only* if you make
+sure that there has been a CWD done first to a directory named `test-[num]`
+where [num] is the test case number. Otherwise the ftp server can't know from
+which test file to load the list content.
+
+### `<dataNUM>`
+
+Send back this contents instead of the <data> one. The num is set by:
+
+ - The test number in the request line is >10000 and this is the remainder
+   of [test case number]%10000.
+ - The request was HTTP and included digest details, which adds 1000 to NUM
+ - If a HTTP request is NTLM type-1, it adds 1001 to num
+ - If a HTTP request is NTLM type-3, it adds 1002 to num
+ - If a HTTP request is Basic and num is already >=1000, it adds 1 to num
+ - If a HTTP request is Negotiate, num gets incremented by one for each
+   request with Negotiate authorization header on the same test case.
+
+Dynamically changing num in this way allows the test harness to be used to
+test authentication negotiation where several different requests must be sent
+to complete a transfer. The response to each request is found in its own data
+section.  Validating the entire negotiation sequence can be done by specifying
+a datacheck section.
+
+### `<connect>`
+The connect section is used instead of the 'data' for all CONNECT
+requests. The remainder of the rules for the data section then apply but with
+a connect prefix.
+
+### `<datacheck [mode="text"] [nonewline="yes"]>`
+if the data is sent but this is what should be checked afterwards. If
+`nonewline=yes` is set, runtests will cut off the trailing newline from the
+data before comparing with the one actually received by the client.
+
+Use the `mode="text"` attribute if the output is in text mode on platforms
+that have a text/binary difference.
+
+### `<datacheckNUM [nonewline="yes"] [mode="text"]>`
+The contents of numbered datacheck sections are appended to the non-numbered
+one.
+
+### `<size>`
+number to return on a ftp SIZE command (set to -1 to make this command fail)
+
+### `<mdtm>`
+what to send back if the client sends a (FTP) MDTM command, set to -1 to
+have it return that the file doesn't exist
+
+### `<postcmd>`
+special purpose server-command to control its behavior *after* the
+reply is sent
+For HTTP/HTTPS, these are supported:
+
+`wait [secs]` - Pause for the given time
+
+### `<servercmd>`
+Special-commands for the server.
+
+The first line of this file will always be set to `Testnum [number]` by the
+test script, to allow servers to read that to know what test the client is
+about to issue.
+
+#### For FTP/SMTP/POP/IMAP
+
+- `REPLY [command] [return value] [response string]` - Changes how the server
+  responds to the [command]. [response string] is evaluated as a perl string,
+  so it can contain embedded \r\n, for example. There's a special [command]
+  named "welcome" (without quotes) which is the string sent immediately on
+  connect as a welcome.
+- `REPLYLF` (like above but sends the response terminated with LF-only and not
+   CRLF)
+- `COUNT [command] [num]` - Do the `REPLY` change for `[command]` only `[num]`
+  times and then go back to the built-in approach
+- `DELAY [command] [secs]` - Delay responding to this command for the given
+  time
+- `RETRWEIRDO` - Enable the "weirdo" RETR case when multiple response lines
+   appear at once when a file is transferred
+- `RETRNOSIZE` - Make sure the RETR response doesn't contain the size of the
+  file
+- `NOSAVE` - Don't actually save what is received
+- `SLOWDOWN` - Send FTP responses with 0.01 sec delay between each byte
+- `PASVBADIP` - makes PASV send back an illegal IP in its 227 response
+- `CAPA [capabilities]` - Enables support for and specifies a list of space
+   separated capabilities to return to the client for the IMAP `CAPABILITY`,
+   POP3 `CAPA` and SMTP `EHLO` commands
+- `AUTH [mechanisms]` - Enables support for SASL authentication and specifies
+   a list of space separated mechanisms for IMAP, POP3 and SMTP
+
+#### For HTTP/HTTPS
+
+- `auth_required` if this is set and a POST/PUT is made without auth, the
+  server will NOT wait for the full request body to get sent
+- `idle` - do nothing after receiving the request, just "sit idle"
+- `stream` - continuously send data to the client, never-ending
+- `writedelay: [secs]` delay this amount between reply packets
+- `skip: [num]` - instructs the server to ignore reading this many bytes from
+  a PUT or POST request
+- `rtp: part [num] channel [num] size [num]` - stream a fake RTP packet for
+  the given part on a chosen channel with the given payload size
+- `connection-monitor` - When used, this will log `[DISCONNECT]` to the
+  `server.input` log when the connection is disconnected.
+- `upgrade` - when an HTTP upgrade header is found, the server will upgrade to
+  http2
+- `swsclose` - instruct server to close connection after response
+- `no-expect` - don't read the request body if Expect: is present
+
+#### For TFTP
+`writedelay: [secs]` delay this amount between reply packets (each packet
+  being 512 bytes payload)
+
+## `<client>`
+
+### `<server>`
+What server(s) this test case requires/uses. Available servers:
+
+- `file`
+- `ftp-ipv6`
+- `ftp`
+- `ftps`
+- `http-ipv6`
+- `http-proxy`
+- `http-unix`
+- `http/2`
+- `http`
+- `https`
+- `httptls+srp-ipv6`
+- `httptls+srp`
+- `imap`
+- `mqtt`
+- `none`
+- `pop3`
+- `rtsp-ipv6`
+- `rtsp`
+- `scp`
+- `sftp`
+- `smtp`
+- `socks4`
+- `socks5`
+
+Give only one per line.  This subsection is mandatory.
+
+### `<features>`
+A list of features that MUST be present in the client/library for this test to
+be able to run. If a required feature is not present then the test will be
+SKIPPED.
+
+Alternatively a feature can be prefixed with an exclamation mark to indicate a
+feature is NOT required. If the feature is present then the test will be
+SKIPPED.
+
+Features testable here are:
+
+- `alt-svc`
+- `crypto`
+- `debug`
+- `getrlimit`
+- `GnuTLS`
+- `GSS-API`
+- `http/2`
+- `idn`
+- `ipv6`
+- `Kerberos`
+- `large_file`
+- `ld_preload`
+- `libz`
+- `manual`
+- `Metalink`
+- `NSS`
+- `NTLM`
+- `OpenSSL`
+- `PSL`
+- `socks`
+- `SPNEGO`
+- `SSL`
+- `SSLpinning`
+- `SSPI`
+- `threaded-resolver`
+- `TLS-SRP`
+- `TrackMemory`
+- `unittest`
+- `unix-sockets`
+- `win32`
+- `WinSSL`
+
+as well as each protocol that curl supports.  A protocol only needs to be
+specified if it is different from the server (useful when the server
+is `none`).
+
+### `<killserver>`
+Using the same syntax as in `<server>` but when mentioned here these servers
+are explicitly KILLED when this test case is completed. Only use this if there
+is no other alternatives. Using this of course requires subsequent tests to
+restart servers.
+
+### `<precheck>`
+A command line that if set gets run by the test script before the test. If an
+output is displayed by the command or if the return code is non-zero, the test
+will be skipped and the (single-line) output will be displayed as reason for
+not running the test.  Variables are substituted as in the `<command>`
+  section.
+
+### `<postcheck>`
+A command line that if set gets run by the test script after the test. If
+the command exists with a non-zero status code, the test will be considered
+to have failed. Variables are substituted as in the `<command>` section.
+
+### `<tool>`
+Name of tool to invoke instead of "curl". This tool must be built and exist
+either in the libtest/ directory (if the tool name starts with 'lib') or in
+the unit/ directory (if the tool name starts with 'unit').
+
+### `<name>`
+Brief test case description, shown when the test runs.
+
+### `<setenv>`
+    variable1=contents1
+    variable2=contents2
+
+Set the given environment variables to the specified value before the actual
+command is run. They are cleared again after the command has been run.
+Variables are first substituted as in the `<command>` section.
+### `<command [option="no-output/no-include/force-output/binary-trace"] 
[timeout="secs"][delay="secs"][type="perl"]>`
+Command line to run. There's a bunch of %variables that get replaced
+accordingly.
+
+Note that the URL that gets passed to the server actually controls what data
+that is returned. The last slash in the URL must be followed by a number. That
+number (N) will be used by the test-server to load test case N and return the
+data that is defined within the `<reply><data></data></reply>` section.
+
+If there's no test number found above, the HTTP test server will use the
+number following the last dot in the given hostname (made so that a CONNECT
+can still pass on test number) so that "foo.bar.123" gets treated as test case
+123. Alternatively, if an IPv6 address is provided to CONNECT, the last
+hexadecimal group in the address will be used as the test number! For example
+the address "[1234::ff]" would be treated as test case 255.
+
+Set `type="perl"` to write the test case as a perl script. It implies that
+there's no memory debugging and valgrind gets shut off for this test.
+
+Set `option="no-output"` to prevent the test script to slap on the `--output`
+argument that directs the output to a file. The `--output` is also not added
+if the verify/stdout section is used.
+
+Set `option="force-output"` to make use of `--output` even when the test is
+otherwise written to verify stdout.
+
+Set `option="no-include"` to prevent the test script to slap on the
+`--include` argument.
+
+Set `option="binary-trace"` to use `--trace` instead of `--trace-ascii` for
+tracing.  Suitable for binary-oriented protocols such as MQTT.
+
+Set `timeout="secs"` to override default server logs advisor read lock
+timeout.  This timeout is used by the test harness, once that the command has
+completed execution, to wait for the test server to write out server side log
+files and remove the lock that advised not to read them. The "secs" parameter
+is the not negative integer number of seconds for the timeout. This `timeout`
+attribute is documented for completeness sake, but is deep test harness stuff
+and only needed for very singular and specific test cases. Avoid using it.
+
+Set `delay="secs"` to introduce a time delay once that the command has
+completed execution and before the `<postcheck>` section runs. The "secs"
+parameter is the not negative integer number of seconds for the delay. This
+'delay' attribute is intended for very specific test cases, and normally not
+needed.
+
+Available substitute variables include:
+
+- `%CLIENT6IP` - IPv6 address of the client running curl
+- `%CLIENTIP` - IPv4 address of the client running curl
+- `%CURL` - Path to the curl executable
+- `%FILE_PWD` - Current directory, on windows prefixed with a slash
+- `%FTP2PORT` - Port number of the FTP server 2
+- `%FTP6PORT` - IPv6 port number of the FTP server
+- `%FTPPORT` - Port number of the FTP server
+- `%FTPSPORT` - Port number of the FTPS server
+- `%FTPTIME2` - Timeout in seconds that should be just sufficient to receive a 
response from the test FTP server
+- `%FTPTIME3` - Even longer than %FTPTIME2
+- `%GOPHER6PORT` - IPv6 port number of the Gopher server
+- `%GOPHERPORT` - Port number of the Gopher server
+- `%HOST6IP` - IPv6 address of the host running this test
+- `%HOSTIP` - IPv4 address of the host running this test
+- `%HTTP6PORT` - IPv6 port number of the HTTP server
+- `%HTTPPORT` - Port number of the HTTP server
+- `%HTTPSPORT` - Port number of the HTTPS server
+- `%HTTPTLS6PORT` - IPv6 port number of the HTTP TLS server
+- `%HTTPTLSPORT` - Port number of the HTTP TLS server
+- `%HTTPUNIXPATH` - Path to the Unix socket of the HTTP server
+- `%IMAP6PORT` - IPv6 port number of the IMAP server
+- `%IMAPPORT` - Port number of the IMAP server
+- `%MQTTPORT` - Port number of the MQTT server
+- `%NEGTELNETPORT` - Port number of the telnet server
+- `%NOLISTENPORT` - Port number where no service is listening
+- `%POP36PORT` - IPv6 port number of the POP3 server
+- `%POP3PORT` - Port number of the POP3 server
+- `%POSIX_PWD` - Current directory somewhat mingw friendly
+- `%PROXYPORT` - Port number of the HTTP proxy
+- `%PWD` - Current directory
+- `%RTSP6PORT` - IPv6 port number of the RTSP server
+- `%RTSPPORT` - Port number of the RTSP server
+- `%SMBPORT` - Port number of the SMB server
+- `%SMBSPORT` - Port number of the SMBS server
+- `%SMTP6PORT` - IPv6 port number of the SMTP server
+- `%SMTPPORT` - Port number of the SMTP server
+- `%SOCKSPORT` - Port number of the SOCKS4/5 server
+- `%SRCDIR` - Full path to the source dir
+- `%SSHPORT` - Port number of the SCP/SFTP server
+- `%SSHSRVMD5` - MD5 of SSH server's public key
+- `%TFTP6PORT` - IPv6 port number of the TFTP server
+- `%TFTPPORT` - Port number of the TFTP server
+- `%USER` - Login ID of the user running the test
+
+### `<file name="log/filename">`
+This creates the named file with this content before the test case is run,
+which is useful if the test case needs a file to act on.  Variables are
+substituted on the contents of the file as in the `<command>` section.
+
+### `<stdin [nonewline="yes"]>`
+Pass this given data on stdin to the tool.
+
+If 'nonewline' is set, we will cut off the trailing newline of this given data
+before comparing with the one actually received by the client
+
+## `<verify>`
+### `<errorcode>`
+numerical error code curl is supposed to return. Specify a list of accepted
+error codes by separating multiple numbers with comma. See test 237 for an
+example.
+
+### `<strip>`
+One regex per line that is removed from the protocol dumps before the
+comparison is made. This is very useful to remove dependencies on dynamically
+changing protocol data such as port numbers or user-agent strings.
+
+### `<strippart>`
+One perl op per line that operates on the protocol dump. This is pretty
+advanced. Example: `s/^EPRT .*/EPRT stripped/`.
+
+### `<protocol [nonewline="yes"]>`
+
+the protocol dump curl should transmit, if 'nonewline' is set, we will cut off
+the trailing newline of this given data before comparing with the one actually
+sent by the client Variables are substituted as in the `<command>` section.
+The `<strip>` and `<strippart>` rules are applied before comparisons are made.
+
+### `<proxy [nonewline="yes"]>`
+
+The protocol dump curl should transmit to a HTTP proxy (when the http-proxy
+server is used), if 'nonewline' is set, we will cut off the trailing newline
+of this given data before comparing with the one actually sent by the client
+Variables are substituted as in the `<command>` section. The `<strip>` and
+`<strippart>` rules are applied before comparisons are made.
+
+### `<stdout [mode="text"] [nonewline="yes"]>`
+This verifies that this data was passed to stdout.  Variables are
+substituted as in the `<command>` section.
+
+Use the mode="text" attribute if the output is in text mode on platforms that
+have a text/binary difference.
+
+If 'nonewline' is set, we will cut off the trailing newline of this given data
+before comparing with the one actually received by the client
+
+### `<file name="log/filename" [mode="text"]>`
+The file's contents must be identical to this after the test is complete.  Use
+the mode="text" attribute if the output is in text mode on platforms that have
+a text/binary difference.  Variables are substituted as in the `<command>`
+section.
+
+### `<file1>`
+1 to 4 can be appended to 'file' to compare more files.
+
+### `<file2>`
+
+### `<file3>`
+
+### `<file4>`
+
+### `<stripfile>`
+One perl op per line that operates on the output file or stdout before being
+compared with what is stored in the test file. This is pretty
+advanced. Example: "s/^EPRT .*/EPRT stripped/"
+
+### `<stripfile1>`
+1 to 4 can be appended to 'stripfile' to strip the corresponding <fileN>
+content
+
+### `<stripfile2>`
+
+### `<stripfile3>`
+
+### `<stripfile4>`
+
+### `<upload>`
+the contents of the upload data curl should have sent
+
+### `<valgrind>`
+disable - disables the valgrind log check for this test
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 16cb9ae1b..c6fe764b3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -22,24 +22,15 @@
 
 MANDISTPAGES = runtests.1.dist testcurl.1.dist
 
-# the path to the impacket python lib used for SMB tests
-IMP = python_dependencies/impacket
-
-SMB_1 = $(IMP)/__init__.py $(IMP)/nmb.py $(IMP)/nt_errors.py
-SMB_2 = $(IMP)/ntlm.py $(IMP)/smb.py $(IMP)/smb3.py $(IMP)/smb3structs.py
-SMB_3 = $(IMP)/smbserver.py $(IMP)/spnego.py $(IMP)/structure.py
-SMB_4 = $(IMP)/uuid.py $(IMP)/version.py smbserver.py.in curl_test_data.py.in
-SMBDEPS = $(SMB_1) $(SMB_2) $(SMB_3) $(SMB_4)
-
 ED_1 = ftpserver.pl httpserver.pl secureserver.pl runtests.pl
-ED_2 = getpart.pm FILEFORMAT README stunnel.pem memanalyze.pl testcurl.pl
+ED_2 = getpart.pm FILEFORMAT.md README stunnel.pem memanalyze.pl testcurl.pl
 ED_3 = valgrind.pm ftp.pm sshserver.pl sshhelp.pm pathhelp.pm testcurl.1 
runtests.1
 ED_4 = serverhelp.pm tftpserver.pl rtspserver.pl directories.pm symbol-scan.pl
-ED_5 = mem-include-scan.pl valgrind.supp extern-scan.pl
+ED_5 = CMakeLists.txt mem-include-scan.pl valgrind.supp extern-scan.pl
 ED_6 = manpage-scan.pl nroff-scan.pl http2-server.pl dictserver.py.in
-ED_7 = negtelnetserver.py.in $(SMBDEPS) objnames-test08.sh objnames-test10.sh
-ED_8 = objnames.inc disable-scan.pl error-codes.pl CMakeLists.txt
-ED_9 = badsymbols.pl azure.pm appveyor.pm
+ED_7 = negtelnetserver.py.in smbserver.py.in curl_test_data.py.in 
objnames-test08.sh objnames-test10.sh
+ED_8 = objnames.inc disable-scan.pl error-codes.pl
+ED_9 = badsymbols.pl azure.pm appveyor.pm version-scan.pl
 
 EXTRA_DIST = $(ED_1) $(ED_2) $(ED_3) $(ED_4) $(ED_5) $(ED_6) $(ED_7) $(ED_8) 
$(ED_9)
 
diff --git a/tests/README b/tests/README
index bfd234a10..209887dfc 100644
--- a/tests/README
+++ b/tests/README
@@ -39,45 +39,48 @@ The curl Test Suite
  1.1 Requires to run
 
   perl (and a unix-style shell)
-  python (and a unix-style shell)
+  python (and a unix-style shell, for SMB and TELNET tests)
+  python-impacket (for SMB tests)
   diff (when a test fails, a diff is shown)
   stunnel (for HTTPS and FTPS tests)
   OpenSSH or SunSSH (for SCP, SFTP and SOCKS4/5 tests)
   nghttpx (for HTTP/2 tests)
   nroff (for --manual tests)
 
+ 1.1.1 Installation of python-impacket
+
+  The Python-based test servers support both recent Python 2 and 3.
+  You can figure out your default Python interpreter with python -V
+
+  Please install python-impacket in the correct Python environment.
+  You can use pip or your OS' package manager to install 'impacket'.
+
+  On Debian/Ubuntu the package names are:
+    Python 2: 'python-impacket'
+    Python 3: 'python3-impacket'
+
+  On FreeBSD the package names are:
+    Python 2: 'py27-impacket'
+    Python 3: 'py37-impacket'
+
+  On any system where pip is available:
+    Python 2: 'pip2 install impacket'
+    Python 3: 'pip3 install impacket'
+
+  You may also need to manually install the Python package 'six'
+  as that may be a missing requirement for impacket on Python 3.
+
  1.2 Port numbers used by test servers
 
-  - TCP/8990 for HTTP
-  - TCP/8991 for HTTPS
-  - TCP/8992 for FTP
-  - TCP/8993 for FTPS
-  - TCP/8994 for HTTP IPv6
-  - TCP/8995 for FTP (2)
-  - TCP/8996 for FTP IPv6
-  - UDP/8997 for TFTP
-  - UDP/8998 for TFTP IPv6
-  - TCP/8999 for SCP/SFTP
-  - TCP/9000 for SOCKS
-  - TCP/9001 for POP3
-  - TCP/9002 for POP3 IPv6
-  - TCP/9003 for IMAP
-  - TCP/9004 for IMAP IPv6
-  - TCP/9005 for SMTP
-  - TCP/9006 for SMTP IPv6
-  - TCP/9007 for RTSP
-  - TCP/9008 for RTSP IPv6
-  - TCP/9009 for GOPHER
-  - TCP/9010 for GOPHER IPv6
-  - TCP/9011 for HTTPS server with TLS-SRP support
-  - TCP/9012 for HTTPS IPv6 server with TLS-SRP support
-  - TCP/9013 for HTTP proxy server for CONNECT
-  - TCP/9014 for HTTP pipelining server
-  - TCP/9015 for HTTP/2 server
-  - TCP/9016 for DICT server
-  - TCP/9017 for SMB server
-  - TCP/9018 for SMBS server (reserved)
-  - TCP/9019 for TELNET server with negotiation support
+  Tests are written to use as few fixed fixed port numbers as possible and all
+  tests should be written to use suitable variables instead of port numbers so
+  that test cases continue to work independent on what port numbers the test
+  servers actually use.
+
+  The remaining fixed-port test servers that are still used, use the port
+  range 8890 - 8904 by default, but can be moved with runtests' -b option.
+
+  See the FILEFORMAT for a listing of existing port number variables.
 
  1.3 Test servers
 
diff --git a/tests/appveyor.pm b/tests/appveyor.pm
index 4906d2c8c..64b2ab3ba 100644
--- a/tests/appveyor.pm
+++ b/tests/appveyor.pm
@@ -50,7 +50,7 @@ sub appveyor_create_test_result {
         }
     " \\
     "$appveyor_baseurl/api/tests"`;
-    print $appveyor_result;
+    print "AppVeyor API result: $appveyor_result\n" if ($appveyor_result);
     $APPVEYOR_TEST_NAMES{$testnum}=$testname;
 }
 
@@ -68,7 +68,7 @@ sub appveyor_update_test_result {
     my $appveyor_category;
     if($error == 2) {
         $appveyor_outcome = 'Ignored';
-        $appveyor_category = 'Warning';
+        $appveyor_category = 'Error';
     }
     elsif($error < 0) {
         $appveyor_outcome = 'NotRunnable';
@@ -91,23 +91,24 @@ sub appveyor_update_test_result {
             'testFramework': 'runtests.pl',
             'fileName': 'tests/data/test$testnum',
             'outcome': '$appveyor_outcome',
-            'durationMilliseconds': $appveyor_duration
+            'durationMilliseconds': $appveyor_duration,
+            'ErrorMessage': 'Test $testnum $appveyor_outcome'
         }
     " \\
     "$appveyor_baseurl/api/tests"`;
-    print $appveyor_result;
+    print "AppVeyor API result: $appveyor_result\n" if ($appveyor_result);
     if($appveyor_category eq 'Error') {
         $appveyor_result=`curl --silent --noproxy "*" \\
         --header "Content-Type: application/json" \\
         --data "
             {
-                'message': '$testname $appveyor_outcome',
+                'message': '$appveyor_outcome: $testname',
                 'category': '$appveyor_category',
                 'details': 'Test $testnum $appveyor_outcome'
             }
         " \\
         "$appveyor_baseurl/api/build/messages"`;
-        print $appveyor_result;
+        print "AppVeyor API result: $appveyor_result\n" if ($appveyor_result);
     }
 }
 
diff --git a/tests/certs/Makefile.am b/tests/certs/Makefile.am
index 6a1c22aa6..f5665f7fa 100644
--- a/tests/certs/Makefile.am
+++ b/tests/certs/Makefile.am
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2013, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/certs/scripts/Makefile.am b/tests/certs/scripts/Makefile.am
index 1db622204..271fb0e4f 100644
--- a/tests/certs/scripts/Makefile.am
+++ b/tests/certs/scripts/Makefile.am
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2013, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/certs/scripts/genroot.sh b/tests/certs/scripts/genroot.sh
index 40fbd365a..0c7d13bbc 100755
--- a/tests/certs/scripts/genroot.sh
+++ b/tests/certs/scripts/genroot.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# (c) CopyRight EdelWeb for EdelKey and OpenEvidence, 2000-2004, 2009
+# (c) CopyRight 2000 - 2020, EdelWeb for EdelKey and OpenEvidence
 # Author: Peter Sylvester
 
 # "libre" for integration with curl
diff --git a/tests/certs/scripts/genserv.sh b/tests/certs/scripts/genserv.sh
index d09ab0559..f1638071d 100755
--- a/tests/certs/scripts/genserv.sh
+++ b/tests/certs/scripts/genserv.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# (c) CopyRight EdelWeb for EdelKey and OpenEvidence, 2000-2004, 2009
+# (c) CopyRight 2000 - 2020, EdelWeb for EdelKey and OpenEvidence
 # Author: Peter Sylvester
 
 # "libre" for integration with curl
diff --git a/tests/convsrctest.pl b/tests/convsrctest.pl
index 11237448f..5c70f2139 100755
--- a/tests/convsrctest.pl
+++ b/tests/convsrctest.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/curl_test_data.py.in b/tests/curl_test_data.py.in
index 6928b2c2b..9e21ca122 100755
--- a/tests/curl_test_data.py.in
+++ b/tests/curl_test_data.py.in
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2017 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -30,7 +30,7 @@ import logging
 log = logging.getLogger(__name__)
 
 
-REPLY_DATA = re.compile("<reply>\s*<data>(.*?)</data>", re.MULTILINE | 
re.DOTALL)
+REPLY_DATA = re.compile("<reply>[ \t\n\r]*<data[^<]*>(.*?)</data>", 
re.MULTILINE | re.DOTALL)
 
 
 class TestData(object):
diff --git a/tests/data/CMakeLists.txt b/tests/data/CMakeLists.txt
index dec92e544..480dee62d 100644
--- a/tests/data/CMakeLists.txt
+++ b/tests/data/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Loads 'TESTCASES' from for the 'make show' target in runtests.pl
 transform_makefile_inc("Makefile.inc" 
"${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
 include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
diff --git a/tests/data/DISABLED b/tests/data/DISABLED
index f0d6f8c7f..da7663e89 100644
--- a/tests/data/DISABLED
+++ b/tests/data/DISABLED
@@ -22,11 +22,13 @@
 1307
 # Pipelining is deprecated
 530
-536
 584
 1900
 1901
 1902
 2033
 # Unused in gnurl
-test1173
+1173
+# Uses SRP to "a server not supporting it" but modern stunnel versions
+# will silently accept it and remain happy
+323
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index a4b281f3c..24e8529a9 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 iall:
 install:
 test:
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 651f21643..c9ae94056 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -58,13 +58,16 @@ test307 test308 test309 test310 test311 test312 test313 
test314 test315 \
 test316 test317 test318 test319 test320 test321 test322 test323 test324 \
 test325 test326 test327 test328 test329 test330 test331 test332 test333 \
 test334 test335 test336 test337 test338 test339 test340 test341 test342 \
-test343 \
-test350 test351 test352 test353 test354 test355 test356 test357 \
+test343 test344 test345 \
+test350 test351 test352 test353 test354 test355 test356 test357 test358 \
+test359 \
 test393 test394 test395 \
 \
 test400 test401 test402 test403 test404 test405 test406 test407 test408 \
 test409 \
 \
+test430 test431 test432 \
+\
 test490 test491 test492 \
 \
 test500 test501 test502 test503 test504 test505 test506 test507 test508 \
@@ -85,7 +88,7 @@ test626 test627 test628 test629 test630 test631 test632 
test633 test634 \
 test635 test636 test637 test638 test639 test640 test641 test642 \
 test643 test644 test645 test646 test647 test648 test649 test650 test651 \
 test652 test653 test654 test655 test656 test658 test659 test660 test661 \
-test662 test663 test664 test665 test666 test667 test668 \
+test662 test663 test664 test665 test666 test667 test668 test669 \
 test670 test671 test672 test673 \
 \
 test700 test701 test702 test703 test704 test705 test706 test707 test708 \
@@ -110,7 +113,7 @@ test927 test928 test929 test930 test931 test932 test933 
test934 test935 \
 test936 test937 test938 test939 test940 test941 test942 test943 test944 \
 test945 test946 test947 test948 test949 test950 test951 test952 test953 \
 test954 test955 test956 test957 test958 test959 test960 test961 test962 \
-test963 test964 test965 test966 test967 test968 test969 \
+test963 test964 test965 test966 test967 test968 test969 test970 \
 \
 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \
 test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \
@@ -134,7 +137,9 @@ test1144 test1145 test1146 test1147 test1148 test1149 
test1150 test1151 \
 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 \
 test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 \
 \
-test1170 test1171 test1172 test1173 test1174 test1175 test1176 \
+test1170 test1171 test1172 test1173 test1174 test1175 test1176 test1177 \
+\
+test1190 test1191 test1192 test1193 test1194 test1195 test1196 \
 \
 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
 test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
@@ -148,39 +153,39 @@ test1260 test1261 test1262 test1263 test1264 test1265 
test1266 test1267 \
 test1268 test1269 test1270 test1271 \
 \
 test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 \
-test1288 test1289 test1290 test1291 test1292 test1293 \
-test1298 test1299 \
-test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 \
-test1308 test1309 test1310 test1311 test1312 test1313 test1314 test1315 \
-test1316 test1317 test1318 test1319 test1320 test1321 test1322 test1323 \
-test1324 test1325 test1326 test1327 test1328 test1329 test1330 test1331 \
-test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 \
-test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 \
-test1348 test1349 test1350 test1351 test1352 test1353 test1354 test1355 \
-test1356 test1357 test1358 test1359 test1360 test1361 test1362 test1363 \
-test1364 test1365 test1366 test1367 test1368 test1369 test1370 test1371 \
-test1372 test1373 test1374 test1375 test1376 test1377 test1378 test1379 \
-test1380 test1381 test1382 test1383 test1384 test1385 test1386 test1387 \
-test1388 test1389 test1390 test1391 test1392 test1393 test1394 test1395 \
-test1396 test1397 test1398 test1399 \
-\
-test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
-test1408 test1409 test1410 test1411 test1412 test1413 test1414 test1415 \
-test1416 test1417 test1418 test1419 test1420 test1421 test1422 test1423 \
-test1424 test1425 test1426 test1427 \
-test1428 test1429 test1430 test1431 test1432 test1433 test1434 test1435 \
-test1436 test1437 test1438 test1439 test1440 test1441 test1442 test1443 \
-test1444 test1445 test1446 test1447 test1448 test1449 test1450 test1451 \
-test1452 test1453 test1454 test1455 test1456 test1457 test1458 test1459 \
-test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
-test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \
-test1516 test1517 test1518 test1519 test1520 test1521 test1522 test1523 \
+test1288 test1289 test1290 test1291 test1292 test1293 test1294 test1295 \
+\
+test1298 test1299 test1300 test1301 test1302 test1303 test1304 test1305 \
+test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
+test1314 test1315 test1316 test1317 test1318 test1319 test1320 test1321 \
+test1322 test1323 test1324 test1325 test1326 test1327 test1328 test1329 \
+test1330 test1331 test1332 test1333 test1334 test1335 test1336 test1337 \
+test1338 test1339 test1340 test1341 test1342 test1343 test1344 test1345 \
+test1346 test1347 test1348 test1349 test1350 test1351 test1352 test1353 \
+test1354 test1355 test1356 test1357 test1358 test1359 test1360 test1361 \
+test1362 test1363 test1364 test1365 test1366 test1367 test1368 test1369 \
+test1370 test1371 test1372 test1373 test1374 test1375 test1376 test1377 \
+test1378 test1379 test1380 test1381 test1382 test1383 test1384 test1385 \
+test1386 test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
+test1394 test1395 test1396 test1397 test1398 test1399 test1400 test1401 \
+test1402 test1403 test1404 test1405 test1406 test1407 test1408 test1409 \
+test1410 test1411 test1412 test1413 test1414 test1415 test1416 test1417 \
+test1418 test1419 test1420 test1421 test1422 test1423 test1424 test1425 \
+test1426 test1427 test1428 test1429 test1430 test1431 test1432 test1433 \
+test1434 test1435 test1436 test1437 test1438 test1439 test1440 test1441 \
+test1442 test1443 test1444 test1445 test1446 test1447 test1448 test1449 \
+test1450 test1451 test1452 test1453 test1454 test1455 test1456 test1457 \
+test1458 test1459 test1500 test1501 test1502 test1503 test1504 test1505 \
+test1506 test1507 test1508 test1509 test1510 test1511 test1512 test1513 \
+test1514 test1515 test1516 test1517 test1518 test1519 test1520 test1521 \
+test1522 test1523 test1524 \
 \
 test1525 test1526 test1527 test1528 test1529 test1530 test1531 test1532 \
 test1533 test1534 test1535 test1536 test1537 test1538 \
 test1540 test1541 \
 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \
 test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \
+test1566 \
 \
 test1590 test1591 test1592 test1593 test1594 test1595 test1596 \
 \
@@ -207,6 +212,7 @@ test2040 test2041 test2042 test2043 test2044 test2045 
test2046 test2047 \
 test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \
 test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \
 test2064 test2065 test2066 test2067 test2068 test2069 \
+test2064 test2065 test2066 test2067 test2068 test2069 test2070 \
          test2071 test2072 test2073 test2074 test2075 test2076 test2077 \
 test2078 \
 test2080 \
diff --git a/tests/data/test1028 b/tests/data/test1028
index fd5162a70..b154372af 100644
--- a/tests/data/test1028
+++ b/tests/data/test1028
@@ -19,7 +19,7 @@ Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake swsclose
 Content-Type: text/html
 Funny-head: yesyes
-Location: ftp://127.0.0.1:8992/10280002
+Location: ftp://%HOSTIP:%FTPPORT/10280002
 Content-Length: 0
 Connection: close
 
@@ -47,10 +47,6 @@ HTTP Location: redirect to FTP URL
  <command>
 http://%HOSTIP:%HTTPPORT/10280001 -L
 </command>
-# The data section doesn't do variable substitution, so we must assert this
-<precheck>
-perl -e "print 'Test requires default test server host and port' if ( 
'%HOSTIP' ne '127.0.0.1' || '%FTPPORT' ne '8992' );"
-</precheck>
 </client>
 
 #
diff --git a/tests/data/test1055 b/tests/data/test1055
index 510d490f4..f25db8f42 100644
--- a/tests/data/test1055
+++ b/tests/data/test1055
@@ -18,7 +18,7 @@ HTTP/1.1 307 OK
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake swsclose
 Content-Type: text/html
-Location: ftp://127.0.0.1:8992/1055
+Location: ftp://%HOSTIP:%FTPPORT/1055
 Content-Length: 0
 Connection: close
 
@@ -38,10 +38,6 @@ HTTP PUT Location: redirect to FTP URL
  <command>
 http://%HOSTIP:%HTTPPORT/1055 -L -T log/test1055.txt
 </command>
-# The data section doesn't do variable substitution, so we must assert this
-<precheck>
-perl -e "print 'Test requires default test server host and port' if ( 
'%HOSTIP' ne '127.0.0.1' || '%FTPPORT' ne '8992' );"
-</precheck>
 <file name="log/test1055.txt">
 Weird
      file
diff --git a/tests/data/test1056 b/tests/data/test1056
index 52b013614..756d0f27f 100644
--- a/tests/data/test1056
+++ b/tests/data/test1056
@@ -13,7 +13,7 @@ IPv6
 <reply>
 <data>
 HTTP/1.1 302 OK swsclose
-Location: http://[::1%259999]:8994/moo/10560002
+Location: http://[::1%259999]:%HTTP6PORT/moo/10560002
 Date: Thu, 31 Jul 2008 14:49:00 GMT
 Connection: close
 
@@ -27,7 +27,7 @@ body
 </data2>
 <datacheck>
 HTTP/1.1 302 OK swsclose
-Location: http://[::1%259999]:8994/moo/10560002
+Location: http://[::1%259999]:%HTTP6PORT/moo/10560002
 Date: Thu, 31 Jul 2008 14:49:00 GMT
 Connection: close
 
@@ -55,10 +55,6 @@ HTTP follow redirect from IPv4 to IPv6 with scope
  <command>
 http://%HOSTIP:%HTTPPORT/we/are/all/twits/1056 -L
 </command>
-# The data section doesn't do variable substitution, so we must assert this
-<precheck>
-perl -e "print 'Test requires default test server host and port' if ( 
'%HOST6IP' ne '[::1]' || '%HTTP6PORT' ne '8994' );"
-</precheck>
 </client>
 
 #
diff --git a/tests/data/test1148 b/tests/data/test1148
index ba498698a..c4232f083 100644
--- a/tests/data/test1148
+++ b/tests/data/test1148
@@ -37,9 +37,6 @@ progress-bar
  <command>
 http://%HOSTIP:%HTTPPORT/1148 -# --stderr log/stderrlog1148
 </command>
-<precheck>
-perl -e '$ENV{"LC_NUMERIC"} = "en_US.UTF-8"; print "Test requires point as 
decimal separator" if system("./libtest/chkdecimalpoint");'
-</precheck>
 <setenv>
 LC_ALL=
 LC_NUMERIC=en_US.UTF-8
@@ -57,13 +54,16 @@ Host: %HOSTIP:%HTTPPORT
 Accept: */*
 
 </protocol>
-# This allows the last 4 letters of the bar to get updated without it
-# matters. We're mostly checking the width of it anyway.
+
+# Check that the progress finished at 100% and has the right bar width.
+# Note the dot in 100.0% is regex to match any character since different
+# locales use different separators.
 <file name="log/stderrlog1148" mode="text">
-
bar 100.0%
+correct
 </file>
 <stripfile>
-s/####################################################################..../bar/
+s/.*\r#{72} 100.0%/correct/
 </stripfile>
+
 </verify>
 </testcase>
diff --git a/tests/data/test1154 b/tests/data/test1154
index cb056d1a8..3582eb99a 100644
--- a/tests/data/test1154
+++ b/tests/data/test1154
@@ -30,7 +30,7 @@ Long: 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 http
 </server>
  <name>
-HTTP GET
+HTTP GET with 100K (too long) response header
  </name>
  <command>
 http://%HOSTIP:%HTTPPORT/1154
diff --git a/tests/data/test1165 b/tests/data/test1177
similarity index 53%
copy from tests/data/test1165
copy to tests/data/test1177
index 24c1c3eb1..2747223cc 100644
--- a/tests/data/test1165
+++ b/tests/data/test1177
@@ -2,7 +2,7 @@
 <info>
 <keywords>
 source analysis
-CURL_DISABLE
+CURL_VERSION
 </keywords>
 </info>
 
@@ -14,11 +14,11 @@ none
 </server>
 
  <name>
-Verify configure.ac and source code CURL_DISABLE_-sync
+Verify that CURL_VERSION_* in headers and docs are in sync
  </name>
 
 <command type="perl">
-%SRCDIR/disable-scan.pl %SRCDIR/..
+%SRCDIR/version-scan.pl %SRCDIR/../docs/libcurl/curl_version_info.3 
../include/gnurl/curl.h
 </command>
 </client>
 
diff --git a/tests/data/test1190 b/tests/data/test1190
new file mode 100644
index 000000000..007a15013
--- /dev/null
+++ b/tests/data/test1190
@@ -0,0 +1,56 @@
+<testcase>
+<info>
+<keywords>
+MQTT
+MQTT SUBSCRIBE
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+hello
+</data>
+<datacheck hex="yes">
+00 04 31 31 39 30   68 65 6c 6c 6f 5b 4c 46 5d 0a
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+mqtt
+</features>
+<server>
+mqtt
+</server>
+<name>
+MQTT SUBSCRIBE
+</name>
+<command option="binary-trace">
+mqtt://%HOSTIP:%MQTTPORT/1190
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# These are hexadecimal protocol dumps from the client
+#
+# Strip out the random part of the client id from the CONNECT message
+# before comparison
+<strippart>
+s/^(.* 00044d5154540402003c000c6375726c).*/$1/
+</strippart>
+<protocol>
+client CONNECT 18 00044d5154540402003c000c6375726c
+server CONNACK 2 20020000
+client SUBSCRIBE 9 000100043131393000
+server SUBACK 3 9003000100
+server PUBLISH c 300c00043131393068656c6c6f0a
+server DISCONNECT 0 e000
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1191 b/tests/data/test1191
new file mode 100644
index 000000000..a36bc3113
--- /dev/null
+++ b/tests/data/test1191
@@ -0,0 +1,50 @@
+<testcase>
+<info>
+<keywords>
+MQTT
+MQTT PUBLISH
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+mqtt
+</features>
+<server>
+mqtt
+</server>
+<name>
+MQTT PUBLISH
+</name>
+<command option="binary-trace">
+mqtt://%HOSTIP:%MQTTPORT/1191 -d something
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# These are hexadecimal protocol dumps from the client
+#
+# Strip out the random part of the client id from the CONNECT message
+# before comparison
+<strippart>
+s/^(.* 00044d5154540402003c000c6375726c).*/$1/
+</strippart>
+<protocol>
+client CONNECT 18 00044d5154540402003c000c6375726c
+server CONNACK 2 20020000
+client PUBLISH f 000431313931736f6d657468696e67
+client DISCONNECT 0 e000
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test46 b/tests/data/test1192
similarity index 72%
copy from tests/data/test46
copy to tests/data/test1192
index 4ea259255..691c7783f 100644
--- a/tests/data/test46
+++ b/tests/data/test1192
@@ -1,89 +1,56 @@
 <testcase>
 <info>
 <keywords>
-HTTP
-HTTP GET
-cookies
-cookiejar
+MQTT
+MQTT SUBSCRIBE
 </keywords>
 </info>
 
+#
 # Server-side
 <reply>
-<data>
-HTTP/1.1 200 OK
-Server: Microsoft-IIS/4.0
-Date: Tue, 25 Sep 2001 19:37:44 GMT
-Content-Type: text/html
-Set-Cookie: ckyPersistent=permanent; expires=Fri, 13-Feb-2037 11:56:27 GMT; 
path=/
-Set-Cookie: ckySession=temporary; path=/
-Set-Cookie: ASPSESSIONIDQGGQQSJJ=GKNBDIFAAOFDPDAIEAKDIBKE; path=/
-Set-Cookie: justaname=; path=/;
-Set-Cookie: 
simplyhuge=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
 [...]
-Cache-control: private
-Content-Length: 41
-
-This server reply is for testing cookies
+<data nocheck="yes">
+hello
 </data>
+<datacheck hex="yes">
+00 04 31 31 39 30   68 65 6c 6c 6f 5b 4c 46 5d 0a
+</datacheck>
 </reply>
 
+#
 # Client-side
 <client>
+<features>
+mqtt
+</features>
 <server>
-http
+mqtt
 </server>
- <name>
-HTTP with bad domain name, get cookies and store in cookie jar
- </name>
-# Explicitly set the time zone to a known good one, in case the user is
-# using one of the 'right' zones that take into account leap seconds
-# which causes the cookie expiry times to be different from what we expect.
-<setenv>
-TZ=GMT
-</setenv>
- <command>
-domain..tld:%HTTPPORT/want/46 --resolve domain..tld:%HTTPPORT:%HOSTIP -c 
log/jar46 -b log/injar46
+<name>
+MQTT SUBSCRIBE 2k topic
+</name>
+<command option="binary-trace">
+mqtt://%HOSTIP:%MQTTPORT/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 [...]
 </command>
-<file name="log/injar46">
-# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
-# This is generated by libcurl!  Do not edit.
-
-www.fake.come  FALSE   /       FALSE   2147483647      cookiecliente   si
-www.loser.com  FALSE   /       FALSE   2139150993      UID     99
-domain..tld    FALSE   /       FALSE   2139150993      mooo    indeed
-#HttpOnly_domain..tld  FALSE   /want   FALSE   2139150993      mooo2   indeed2
-domain..tld    FALSE   /want   FALSE   0       empty   
-</file>
 </client>
 
+#
 # Verify data after the test has been "shot"
 <verify>
-<strip>
-^User-Agent:.*
-</strip>
+# These are hexadecimal protocol dumps from the client
+#
+# Strip out the random part of the client id from the CONNECT message
+# before comparison
+<strippart>
+s/^(.* 00044d5154540402003c000c6375726c).*/$1/
+</strippart>
 <protocol>
-GET /want/46 HTTP/1.1
-Host: domain..tld:%HTTPPORT
-Accept: */*
-Cookie: empty=; mooo2=indeed2; mooo=indeed
-
+client CONNECT 18 00044d5154540402003c000c6375726c
+server CONNACK 2 20020000
+client SUBSCRIBE 80a 
000108054141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414
 [...]
+server SUBACK 3 9003000100
+server PUBLISH 80d 
308d1008054141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414
 [...]
+server DISCONNECT 0 e000
 </protocol>
-<file name="log/jar46" mode="text">
-# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
-# This file was generated by libcurl! Edit at your own risk.
-
-domain..tld    FALSE   /want/  FALSE   0       simplyhuge      
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
 [...]
-domain..tld    FALSE   /       FALSE   0       justaname       
-domain..tld    FALSE   /       FALSE   0       ASPSESSIONIDQGGQQSJJ    
GKNBDIFAAOFDPDAIEAKDIBKE
-domain..tld    FALSE   /       FALSE   0       ckySession      temporary
-domain..tld    FALSE   /       FALSE   2118138987      ckyPersistent   
permanent
-domain..tld    FALSE   /want   FALSE   0       empty   
-#HttpOnly_domain..tld  FALSE   /want   FALSE   2139150993      mooo2   indeed2
-domain..tld    FALSE   /       FALSE   2139150993      mooo    indeed
-www.loser.com  FALSE   /       FALSE   2139150993      UID     99
-www.fake.come  FALSE   /       FALSE   2147483647      cookiecliente   si
-</file>
 </verify>
 </testcase>
diff --git a/tests/data/test1193 b/tests/data/test1193
new file mode 100644
index 000000000..8da9abb21
--- /dev/null
+++ b/tests/data/test1193
@@ -0,0 +1,72 @@
+<testcase>
+<info>
+<keywords>
+MQTT
+MQTT PUBLISH
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+mqtt
+</features>
+<server>
+mqtt
+</server>
+<name>
+MQTT PUBLISH 2k payload
+</name>
+<command option="binary-trace">
+mqtt://%HOSTIP:%MQTTPORT/1193 -d @log/payload1193
+</command>
+<file name="log/payload1193">
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+</file>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# These are hexadecimal protocol dumps from the client
+#
+# Strip out the random part of the client id from the CONNECT message
+# before comparison
+<strippart>
+s/^(.* 00044d5154540402003c000c6375726c).*/$1/
+</strippart>
+<protocol>
+client CONNECT 18 00044d5154540402003c000c6375726c
+server CONNACK 2 20020000
+client PUBLISH 7c2 
00043131393331323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383931323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383931323334353637383930313233343536373839303132333435363738393031323
 [...]
+client DISCONNECT 0 e000
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1194 b/tests/data/test1194
new file mode 100644
index 000000000..497891add
--- /dev/null
+++ b/tests/data/test1194
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+MQTT
+MQTT SUBSCRIBE
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+hello
+</data>
+<datacheck hex="yes">
+00 04 31 31 39 30   68 65 6c 6c 6f 5b 4c 46 5d 0a
+</datacheck>
+<servercmd>
+PUBLISH-before-SUBACK TRUE
+</servercmd>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+mqtt
+</features>
+<server>
+mqtt
+</server>
+<name>
+MQTT SUBSCRIBE with PUBLISH befoire SUBACK
+</name>
+<command option="binary-trace">
+mqtt://%HOSTIP:%MQTTPORT/1194
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# These are hexadecimal protocol dumps from the client
+#
+# Strip out the random part of the client id from the CONNECT message
+# before comparison
+<strippart>
+s/^(.* 00044d5154540402003c000c6375726c).*/$1/
+</strippart>
+<protocol>
+client CONNECT 18 00044d5154540402003c000c6375726c
+server CONNACK 2 20020000
+client SUBSCRIBE 9 000100043131393400
+server PUBLISH c 300c00043131393468656c6c6f0a
+server SUBACK 3 9003000100
+server DISCONNECT 0 e000
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1195 b/tests/data/test1195
new file mode 100644
index 000000000..0dfaccd53
--- /dev/null
+++ b/tests/data/test1195
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+MQTT
+MQTT SUBSCRIBE
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+hello
+</data>
+<datacheck hex="yes">
+00 04 31 31 39 30   68 65 6c 6c 6f 5b 4c 46 5d 0a
+</datacheck>
+<servercmd>
+PUBLISH-before-SUBACK TRUE
+short-PUBLISH TRUE
+</servercmd>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+mqtt
+</features>
+<server>
+mqtt
+</server>
+<name>
+MQTT SUBSCRIBE with short PUBLISH
+</name>
+<command option="binary-trace">
+mqtt://%HOSTIP:%MQTTPORT/1195
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# These are hexadecimal protocol dumps from the client
+#
+# Strip out the random part of the client id from the CONNECT message
+# before comparison
+<strippart>
+s/^(.* 00044d5154540402003c000c6375726c).*/$1/
+</strippart>
+<protocol>
+client CONNECT 18 00044d5154540402003c000c6375726c
+server CONNACK 2 20020000
+client SUBSCRIBE 9 000100043131393500
+server PUBLISH c 300c00043131393568656c6c
+</protocol>
+
+# 18 is CURLE_PARTIAL_FILE
+<errorcode>
+18
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test1196 b/tests/data/test1196
new file mode 100644
index 000000000..c07efd927
--- /dev/null
+++ b/tests/data/test1196
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+MQTT
+MQTT SUBSCRIBE
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+hello
+</data>
+<datacheck hex="yes">
+00 04 31 31 39 30   68 65 6c 6c 6f 5b 4c 46 5d 0a
+</datacheck>
+
+# error 1 - "Connection Refused, unacceptable protocol version"
+<servercmd>
+error-CONNACK 1
+</servercmd>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+mqtt
+</features>
+<server>
+mqtt
+</server>
+<name>
+MQTT with error in CONNACK
+</name>
+<command option="binary-trace">
+mqtt://%HOSTIP:%MQTTPORT/1196
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# These are hexadecimal protocol dumps from the client
+#
+# Strip out the random part of the client id from the CONNECT message
+# before comparison
+<strippart>
+s/^(.* 00044d5154540402003c000c6375726c).*/$1/
+</strippart>
+<protocol>
+client CONNECT 18 00044d5154540402003c000c6375726c
+server CONNACK 2 20020001
+</protocol>
+
+# 8 is CURLE_WEIRD_SERVER_REPLY
+<errorcode>
+8
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test1245 b/tests/data/test1245
index 851d78d3b..8924bff97 100644
--- a/tests/data/test1245
+++ b/tests/data/test1245
@@ -18,7 +18,7 @@ HTTP/1.1 301 OK swsclose
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake
 Content-Length: 0
-Location: ftp://127.0.0.1:8992/1245
+Location: ftp://%HOSTIP:%FTPPORT/1245
 Connection: close
 
 </data>
@@ -37,10 +37,6 @@ ftp
 <command>
 --location --proto +all,-ftp --proto-redir -all,+ftp 
http://%HOSTIP:%HTTPPORT/1245
 </command>
-# The data section doesn't do variable substitution, so we must assert this
-<precheck>
-perl -e "print 'Test requires default test server host and port' if ( 
'%HOSTIP' ne '127.0.0.1' || '%FTPPORT' ne '8992' );"
-</precheck>
 </client>
 
 #
diff --git a/tests/data/test1247 b/tests/data/test1247
index 48c5ccdf4..ff127eb57 100644
--- a/tests/data/test1247
+++ b/tests/data/test1247
@@ -17,7 +17,7 @@ HTTP
 # Client-side
 <client>
 <server>
-none
+http
 </server>
  <name>
 --fail-early
diff --git a/tests/data/test1294 b/tests/data/test1294
new file mode 100644
index 000000000..1c2c0ef95
--- /dev/null
+++ b/tests/data/test1294
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+debug
+</features>
+<server>
+http
+</server>
+<name>
+HTTP GET with split initial request send
+</name>
+<setenv>
+# Oliver Twist
+
+# make the first send cut off after this amount of data
+CURL_SMALLREQSEND=128
+</setenv>
+<command>
+http://%HOSTIP:%HTTPPORT/012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679/1294
 -H "Among other public buildings in a certain town, which for many reasons it 
will be prudent to refrain from mentioning, and to which I will assign no 
fictitious name, there is one anciently [...]
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET 
/012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679/1294
 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+Among other public buildings in a certain town, which for many reasons it will 
be prudent to refrain from mentioning, and to which I will assign no fictitious 
name, there is one anciently common to most towns, great or small to wit, a 
workhouse; and in this workhouse was born; on a day and date which I need not 
trouble myself to repeat, inasmuch as it can be of no possible consequence to 
the reader, in this stage of the business at all events; the item of mortality 
whose name is prefixed [...]
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1295 b/tests/data/test1295
new file mode 100644
index 000000000..b929e3c6d
--- /dev/null
+++ b/tests/data/test1295
@@ -0,0 +1,68 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+debug
+</features>
+<server>
+http
+</server>
+<name>
+HTTP POST with split initial request send
+</name>
+<setenv>
+# The Hound of the Baskervilles
+#
+# make the first send cut off after this amount of data
+CURL_SMALLREQSEND=100
+</setenv>
+<command>
+http://%HOSTIP:%HTTPPORT/012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679/1295
 -H 
"0123456790123456790123456790123456790123456790123456790123456790123456790123456790123456790123456790123456790123456790123456790123456790123456790123456790123456790123456790123456790123456
 [...]
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol nonewline="yes">
+POST 
/012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679/1295
 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679:
 300
+Content-Length: 165
+Content-Type: application/x-www-form-urlencoded
+
+Mr. Sherlock Holmes, who was usually very late in the mornings, save upon 
those not infrequent occasions when he was up all night, was seated at the 
breakfast table.
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1448 b/tests/data/test1448
index 8de2fd1c6..87ffed60d 100644
--- a/tests/data/test1448
+++ b/tests/data/test1448
@@ -17,7 +17,7 @@ HTTP/1.1 302 OK swsbounce
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Content-Length: 9
 Content-Type: text/plain
-Location: http://åäö.se:8990/14480001
+Location: http://åäö.se:%HTTPPORT/14480001
 
 redirect
 </data>
@@ -52,7 +52,7 @@ Redirect following to UTF-8 IDN host name
  </name>
 
  <command>
-http://åäö.se:%HTTPPORT/1448 --resolve xn--4cab6c.se:%HTTPPORT:%HOSTIP -L 
--connect-to %HOSTIP:8990:%HOSTIP:%HTTPPORT
+http://åäö.se:%HTTPPORT/1448 --resolve xn--4cab6c.se:%HTTPPORT:%HOSTIP -L 
--connect-to %HOSTIP:%HTTPPORT:%HOSTIP:%HTTPPORT
 </command>
 </client>
 
diff --git a/tests/data/test1451 b/tests/data/test1451
index 0c114e186..9337b8b99 100644
--- a/tests/data/test1451
+++ b/tests/data/test1451
@@ -8,7 +8,9 @@ SMB
 #
 # Server-side
 <reply>
-<data>Basic SMB test complete</data>
+<data nocheck="yes">
+Basic SMB test complete
+</data>
 </reply>
 
 #
@@ -20,17 +22,22 @@ smb
 <features>
 smb
 </features>
- <name>
+<name>
 Basic SMB request
- </name>
- <command>
+</name>
+<command>
 -u 'curltest:curltest' smb://%HOSTIP:%SMBPORT/TESTS/1451
 </command>
+<precheck>
+python -c "__import__('pkgutil').find_loader('impacket') or 
(__import__('sys').stdout.write('Test only works if Python package impacket is 
installed\n'), __import__('sys').exit(1))"
+</precheck>
 </client>
 
 #
 # Verify data after the test has been "shot"
 <verify>
-<stdout>Basic SMB test complete</stdout>
+<stdout>
+Basic SMB test complete
+</stdout>
 </verify>
 </testcase>
diff --git a/tests/data/test1452 b/tests/data/test1452
index 76b0eba0c..0a84cf8ce 100644
--- a/tests/data/test1452
+++ b/tests/data/test1452
@@ -3,7 +3,6 @@
 <keywords>
 TELNET
 UPLOAD
-flaky
 </keywords>
 </info>
 
@@ -37,6 +36,8 @@ telnet://%HOSTIP:%NEGTELNETPORT --upload-file -
 #
 # Verify data after the test has been "shot"
 <verify>
-<stdout>test1452</stdout>
+<stdout nonewline="yes">
+test1452
+</stdout>
 </verify>
 </testcase>
diff --git a/tests/data/test1413 b/tests/data/test1524
similarity index 58%
copy from tests/data/test1413
copy to tests/data/test1524
index 6e889a8a2..ed0c0476e 100644
--- a/tests/data/test1413
+++ b/tests/data/test1524
@@ -2,7 +2,7 @@
 <info>
 <keywords>
 HTTP
-HTTP GET
+HTTP PUT
 followlocation
 </keywords>
 </info>
@@ -10,31 +10,27 @@ followlocation
 # Server-side
 <reply>
 <data>
-HTTP/1.1 302 OK swsclose
-Location: moo.html/14130002#fragmentpart
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-Connection: close
-
+HTTP/1.1 303 OK swsclose
+Location: moo.html&testcase=/15240002
+Connection: close
+
 </data>
 <data2>
-HTTP/1.1 200 OK swsclose
-Location: this should be ignored
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-Connection: close
-
+HTTP/1.1 200 OK swsclose
+Location: this should be ignored
+Connection: close
+
 body
 </data2>
 <datacheck>
-HTTP/1.1 302 OK swsclose
-Location: moo.html/14130002#fragmentpart
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-Connection: close
-
-HTTP/1.1 200 OK swsclose
-Location: this should be ignored
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-Connection: close
-
+HTTP/1.1 303 OK swsclose
+Location: moo.html&testcase=/15240002
+Connection: close
+
+HTTP/1.1 200 OK swsclose
+Location: this should be ignored
+Connection: close
+
 body
 </datacheck>
 </reply>
@@ -46,11 +42,14 @@ body
 http
 </server>
  <name>
-HTTP redirect with fragment in new URL
+HTTP PUT with 303 redirect
  </name>
  <command>
-http://%HOSTIP:%HTTPPORT/this/1413 -L
+http://%HOSTIP:%HTTPPORT/blah/1524 -L -T log/upload1524.txt
 </command>
+<file name="log/upload1524.txt">
+moo
+</file>
 </client>
 
 #
@@ -59,15 +58,20 @@ http://%HOSTIP:%HTTPPORT/this/1413 -L
 <strip>
 ^User-Agent:.*
 </strip>
-<protocol>
-GET /this/1413 HTTP/1.1
+<protocol nonewline="yes">
+PUT /blah/1524 HTTP/1.1
 Host: %HOSTIP:%HTTPPORT
 Accept: */*
+Content-Length: 4
+Expect: 100-continue
 
-GET /this/moo.html/14130002 HTTP/1.1
+moo
+GET /blah/moo.html&testcase=/15240002 HTTP/1.1
+User-Agent: this should be ignored
 Host: %HOSTIP:%HTTPPORT
 Accept: */*
 
+
 </protocol>
 </verify>
 </testcase>
diff --git a/tests/data/test1455 b/tests/data/test1566
similarity index 53%
copy from tests/data/test1455
copy to tests/data/test1566
index 8483d7bb8..e6f81711d 100644
--- a/tests/data/test1455
+++ b/tests/data/test1566
@@ -3,27 +3,22 @@
 <keywords>
 HTTP
 HTTP GET
-proxy
-haproxy
+--etag-compare
 </keywords>
 </info>
 
 #
 # Server-side
-<reply name="1455">
+<reply>
 <data nocheck="yes">
-HTTP/1.1 200 OK
+HTTP/1.1 304 Not modified
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake
 Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
 ETag: "21025-dc7-39462498"
-Accept-Ranges: bytes
-Content-Length: 6
 Connection: close
 Content-Type: text/html
-Funny-head: barkbark
 
--foo-
 </data>
 </reply>
 
@@ -34,14 +29,18 @@ Funny-head: barkbark
 http
 </server>
 <name>
-HTTP GET when PROXY Protocol enabled
+--etag-compare that gets a 304 back shouldn't overwrite the file
 </name>
-<command>
-http://%HOSTIP:%HTTPPORT/1455 --haproxy-protocol -H "Testno: 1455"
+<command option="no-output,no-include">
+http://%HOSTIP:%HTTPPORT/1566 -o log/output1566 --etag-compare log/etag1566
 </command>
-<features>
-proxy
-</features>
+<file name="log/etag1566">
+123456
+</file>
+<file1 name="log/output1566">
+downloaded already
+</file1>
+
 </client>
 
 #
@@ -50,16 +49,17 @@ proxy
 <strip>
 ^User-Agent:.*
 </strip>
-<strippart>
-s/^PROXY TCP4 %CLIENTIP %HOSTIP (\d*) %HTTPPORT/proxy-line/
-</strippart>
 <protocol>
-proxy-line
-GET /1455 HTTP/1.1
+GET /1566 HTTP/1.1
 Host: %HOSTIP:%HTTPPORT
 Accept: */*
-Testno: 1455
+If-None-Match: "123456"
 
 </protocol>
+
+# verify that the target file is untouched
+<file name="log/output1566">
+downloaded already
+</file>
 </verify>
 </testcase>
diff --git a/tests/data/test19 b/tests/data/test19
index 8e1bf5eb4..f053baf08 100644
--- a/tests/data/test19
+++ b/tests/data/test19
@@ -24,7 +24,7 @@ http
 attempt connect to non-listening socket
  </name>
  <command>
-%HOSTIP:2
+%HOSTIP:%NOLISTENPORT
 </command>
 </client>
 
diff --git a/tests/data/test1908 b/tests/data/test1908
index de34d0ee2..236bd4af0 100644
--- a/tests/data/test1908
+++ b/tests/data/test1908
@@ -65,7 +65,7 @@ s/\"([^\"]*)\"/TIMESTAMP/
 <file name="log/altsvc-1908">
 # Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html
 # This file was generated by libcurl! Edit at your own risk.
-h1 127.0.0.1 8990 h2 3dbbdetxoyw4nsp6c3cc456oj2ays6s43ezxzsfxxri3h5xqd.example 
443 TIMESTAMP 1 0
+h1 127.0.0.1 %HTTPPORT h2 
3dbbdetxoyw4nsp6c3cc456oj2ays6s43ezxzsfxxri3h5xqd.example 443 TIMESTAMP 1 0
 </file>
 </verify>
 </testcase>
diff --git a/tests/data/test2006 b/tests/data/test2006
index 0b84937ed..4cb61192d 100644
--- a/tests/data/test2006
+++ b/tests/data/test2006
@@ -85,8 +85,15 @@ Accept: */*
 <file1 name="log/download2006">
 Some data delivered from an HTTP resource
 </file1>
+
+# The Content-Length replace here is to handle with 4/5 digit port number in
+# the content
+<stripfile2>
+s/Last-Modified:.*//
+s/Content-Length: 49[67]/Content-Length: yeps/
+</stripfile2>
 <file2 name="log/heads2006">
-Content-Length: 496
+Content-Length: yeps
 Accept-ranges: bytes
 
 
@@ -110,9 +117,6 @@ Metalink: fetching (log/download2006) from 
(http://%HOSTIP:%HTTPPORT/2006) OK
 Metalink: validating (log/download2006)...
 Metalink: validating (log/download2006) [sha-256] OK
 </file4>
-<stripfile2>
-s/Last-Modified:.*//
-</stripfile2>
 <stripfile4>
 $_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
 </stripfile4>
diff --git a/tests/data/test2007 b/tests/data/test2007
index c8c023efb..738ac35f9 100644
--- a/tests/data/test2007
+++ b/tests/data/test2007
@@ -86,11 +86,14 @@ Accept: */*
 <file1 name="log/download2007">
 Something delivered from an HTTP resource
 </file1>
+# The Content-Length replace here is to handle with 4/5 digit port number in
+# the content
 <stripfile2>
 s/Last-Modified:.*//
+s/Content-Length: 49[67]/Content-Length: yeps/
 </stripfile2>
 <file2 name="log/heads2007">
-Content-Length: 496
+Content-Length: yeps
 Accept-ranges: bytes
 
 
diff --git a/tests/data/test2008 b/tests/data/test2008
index 570cdba7d..b29ba911b 100644
--- a/tests/data/test2008
+++ b/tests/data/test2008
@@ -78,11 +78,14 @@ Accept: */*
 <file1 name="log/download2008">
 Some stuff delivered from an HTTP resource
 </file1>
+# The Content-Length replace here is to handle with 4/5 digit port number in
+# the content
 <stripfile2>
 s/Last-Modified:.*//
+s/Content-Length: 49[67]/Content-Length: yeps/
 </stripfile2>
 <file2 name="log/heads2008">
-Content-Length: 496
+Content-Length: yeps
 Accept-ranges: bytes
 
 
diff --git a/tests/data/test2009 b/tests/data/test2009
index 10f95df4c..3cf4e4c48 100644
--- a/tests/data/test2009
+++ b/tests/data/test2009
@@ -79,11 +79,14 @@ Accept: */*
 <file1 name="log/download2009">
 Some contents delivered from an HTTP resource
 </file1>
+# The Content-Length replace here is to handle with 4/5 digit port number in
+# the content
 <stripfile2>
 s/Last-Modified:.*//
+s/Content-Length: 49[67]/Content-Length: yeps/
 </stripfile2>
 <file2 name="log/heads2009">
-Content-Length: 496
+Content-Length: yeps
 Accept-ranges: bytes
 
 
diff --git a/tests/data/test2010 b/tests/data/test2010
index d43f4f1e1..08f1bfaa4 100644
--- a/tests/data/test2010
+++ b/tests/data/test2010
@@ -78,11 +78,14 @@ Accept: */*
 <file1 name="log/download2010">
 Contents delivered from an HTTP resource
 </file1>
+# The Content-Length replace here is to handle with 4/5 digit port number in
+# the content
 <stripfile2>
 s/Last-Modified:.*//
+s/Content-Length: 49[67]/Content-Length: yeps/
 </stripfile2>
 <file2 name="log/heads2010">
-Content-Length: 496
+Content-Length: yeps
 Accept-ranges: bytes
 
 
diff --git a/tests/data/test2043 b/tests/data/test2043
index 7a91f5b60..34f53b72e 100644
--- a/tests/data/test2043
+++ b/tests/data/test2043
@@ -19,7 +19,7 @@ none
 Disable certificate revocation checks
  </name>
  <command>
---ssl-no-revoke -I https://revoked.grc.com/
+--ssl-no-revoke -I https://revoked.badssl.com/
 </command>
 </client>
 
diff --git a/tests/data/test2041 b/tests/data/test2070
similarity index 69%
copy from tests/data/test2041
copy to tests/data/test2070
index 50018e401..4a21512ba 100644
--- a/tests/data/test2041
+++ b/tests/data/test2070
@@ -5,7 +5,7 @@ HTTPS
 HTTP GET
 PEM certificate
 </keywords>
-</info>
+</info>type
 
 #
 # Server-side
@@ -24,17 +24,21 @@ MooMoo
 # Client-side
 <client>
 <features>
-SSL
-SSLpinning
+WinSSL
+!MinGW
 </features>
 <server>
 https Server-localhost-sv.pem
 </server>
  <name>
-simple HTTPS GET with base64-sha256 public key pinning
+Ignore certificate revocation "best effort" strategy
  </name>
+  <setenv>
+# This test is pointless if we're not using the schannel backend
+CURL_SSL_BACKEND=schannel
+ </setenv>
  <command>
---cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey 
sha256//+JYNkp2GTGRgrvZMUkOxbFJQQqYpwNE6toGmBjz00D8= 
https://localhost:%HTTPSPORT/2041
+--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --ssl-revoke-best-effort 
https://localhost:%HTTPSPORT/2070
 </command>
 # Ensure that we're running on localhost because we're checking the host name
 <precheck>
@@ -49,7 +53,7 @@ perl -e "print 'Test requires default test server host' if ( 
'%HOSTIP' ne '127.0
 ^User-Agent:.*
 </strip>
 <protocol>
-GET /2041 HTTP/1.1
+GET /2070 HTTP/1.1
 Host: localhost:%HTTPSPORT
 Accept: */*
 
diff --git a/tests/data/test2100 b/tests/data/test2100
index 0deedbd74..83aa7287b 100644
Binary files a/tests/data/test2100 and b/tests/data/test2100 differ
diff --git a/tests/data/test309 b/tests/data/test309
index dd0431206..80246a9c0 100644
--- a/tests/data/test309
+++ b/tests/data/test309
@@ -14,7 +14,7 @@ followlocation
 HTTP/1.1 301 This is a weirdo text message swsclose
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake
-Location: https://127.0.0.1:8991/data/3090002.txt?coolsite=yes
+Location: https://127.0.0.1:%HTTPSPORT/data/3090002.txt?coolsite=yes
 Connection: close
 
 This server reply is for testing a simple Location: following to HTTPS URL
@@ -33,7 +33,7 @@ If this is received, the location following worked
 HTTP/1.1 301 This is a weirdo text message swsclose
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake
-Location: https://127.0.0.1:8991/data/3090002.txt?coolsite=yes
+Location: https://127.0.0.1:%HTTPSPORT/data/3090002.txt?coolsite=yes
 Connection: close
 
 HTTP/1.1 200 Followed here fine swsclose
@@ -61,10 +61,6 @@ HTTP Location: redirect to HTTPS URL
  <command>
 -k http://%HOSTIP:%HTTPPORT/want/309 -L
 </command>
-# The data section doesn't do variable substitution, so we must assert this
-<precheck>
-perl -e "print 'Test requires default test server host and port' if ( 
'%HOSTIP' ne '127.0.0.1' || '%HTTPSPORT' ne '8991' );"
-</precheck>
 </client>
 
 # Verify data after the test has been "shot"
diff --git a/tests/data/test335 b/tests/data/test335
index 5817365e3..91d981827 100644
--- a/tests/data/test335
+++ b/tests/data/test335
@@ -1,5 +1,5 @@
-# Mostly a duplicate of test168
 <testcase>
+# Mostly a duplicate of test168
 <info>
 <keywords>
 HTTP
diff --git a/tests/data/test338 b/tests/data/test338
index f8dab6528..0c040c28a 100644
--- a/tests/data/test338
+++ b/tests/data/test338
@@ -1,5 +1,5 @@
-# See https://github.com/curl/curl/issues/4499
 <testcase>
+# See https://github.com/curl/curl/issues/4499
 <info>
 <keywords>
 HTTP
diff --git a/tests/data/test343 b/tests/data/test344
similarity index 70%
copy from tests/data/test343
copy to tests/data/test344
index e55a181d8..054d0351b 100644
--- a/tests/data/test343
+++ b/tests/data/test344
@@ -31,13 +31,10 @@ Funny-head: yesyes
 http
 </server>
 <name>
-Both --etag-compare and --etag-save to save new Etag
+Both --etag-compare and -save store new Etag using non-existing file
 </name>
-<file name="log/etag343">
-21025-dc7-39462498
-</file>
 <command>
-http://%HOSTIP:%HTTPPORT/343 --etag-compare log/etag343 --etag-save log/out343
+http://%HOSTIP:%HTTPPORT/344 --etag-compare log/etag344 --etag-save log/etag344
 </command>
 </client>
 
@@ -48,13 +45,13 @@ http://%HOSTIP:%HTTPPORT/343 --etag-compare log/etag343 
--etag-save log/out343
 ^User-Agent:.*
 </strip>
 <protocol>
-GET /343 HTTP/1.1
+GET /344 HTTP/1.1
 Host: %HOSTIP:%HTTPPORT
 Accept: */*
-If-None-Match: "21025-dc7-39462498"
+If-None-Match: ""
 
 </protocol>
-<file name="log/out343">
+<file name="log/etag344">
 21025-dc7-11111
 </file>
 </verify>
diff --git a/tests/data/test343 b/tests/data/test345
similarity index 75%
copy from tests/data/test343
copy to tests/data/test345
index e55a181d8..135e0c26a 100644
--- a/tests/data/test343
+++ b/tests/data/test345
@@ -31,13 +31,13 @@ Funny-head: yesyes
 http
 </server>
 <name>
-Both --etag-compare and --etag-save to save new Etag
+Both --etag-compare and -save store new Etag using one pre-existing file
 </name>
-<file name="log/etag343">
+<file name="log/etag345">
 21025-dc7-39462498
 </file>
 <command>
-http://%HOSTIP:%HTTPPORT/343 --etag-compare log/etag343 --etag-save log/out343
+http://%HOSTIP:%HTTPPORT/345 --etag-compare log/etag345 --etag-save log/etag345
 </command>
 </client>
 
@@ -48,13 +48,13 @@ http://%HOSTIP:%HTTPPORT/343 --etag-compare log/etag343 
--etag-save log/out343
 ^User-Agent:.*
 </strip>
 <protocol>
-GET /343 HTTP/1.1
+GET /345 HTTP/1.1
 Host: %HOSTIP:%HTTPPORT
 Accept: */*
 If-None-Match: "21025-dc7-39462498"
 
 </protocol>
-<file name="log/out343">
+<file name="log/etag345">
 21025-dc7-11111
 </file>
 </verify>
diff --git a/tests/data/test358 b/tests/data/test358
new file mode 100644
index 000000000..82ff8adf7
--- /dev/null
+++ b/tests/data/test358
@@ -0,0 +1,94 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+Alt-Svc
+HTTP/2
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+Alt-Svc: h2=":%HTTP2PORT", ma=315360000; persist=0
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+alt-svc
+debug
+</features>
+<server>
+http
+http/2
+</server>
+ <name>
+HTTPS GET translated by alt-svc lookup to HTTP/2 GET
+ </name>
+<setenv>
+# make debug-curl accept Alt-Svc over plain HTTP
+CURL_ALTSVC_HTTP="yeah"
+</setenv>
+ <command>
+--http2 --alt-svc "log/altsvc-358" "http://%HOSTIP:%HTTPPORT/358"; 
"http://%HOSTIP:%HTTPPORT/358";
+</command>
+<file name="log/altsvc-358">
+h2 %HOSTIP %HTTPPORT h2 %HOSTIP %HTTP2PORT "20290222 22:19:28" 0 0
+</file>
+
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<stdout>
+HTTP/1.1 101 Switching Protocols
+Connection: Upgrade
+Upgrade: h2c
+
+HTTP/2 200 
+date: Thu, 09 Nov 2010 14:49:00 GMT
+content-length: 6
+content-type: text/html
+funny-head: yesyes
+alt-svc: h2=":%HTTP2PORT", ma=315360000; persist=0
+server: nghttpx
+via: 1.1 nghttpx
+
+-foo-
+HTTP/2 200 
+date: Thu, 09 Nov 2010 14:49:00 GMT
+content-length: 6
+content-type: text/html
+funny-head: yesyes
+alt-svc: h2=":%HTTP2PORT", ma=315360000; persist=0
+server: nghttpx
+via: 1.1 nghttpx
+
+-foo-
+</stdout>
+<stripfile>
+# strip out the (dynamic) expire date from the file so that the rest
+# matches
+s/\"2([^\"]*)\"/TIMESTAMP/
+</stripfile>
+<file name="log/altsvc-358" mode="text">
+# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html
+# This file was generated by libcurl! Edit at your own risk.
+h2 %HOSTIP %HTTPPORT h2 %HOSTIP %HTTP2PORT TIMESTAMP 0 0
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test359 b/tests/data/test359
new file mode 100644
index 000000000..c0faee21d
--- /dev/null
+++ b/tests/data/test359
@@ -0,0 +1,94 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTPS GET
+Alt-Svc
+HTTP/2
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+Alt-Svc: h2=":%HTTP2PORT", ma=315360000; persist=0
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+alt-svc
+debug
+</features>
+<server>
+https
+http/2
+</server>
+ <name>
+HTTPS GET translated by alt-svc lookup to HTTP/2 GET
+ </name>
+<setenv>
+# make debug-curl accept Alt-Svc over plain HTTP
+CURL_ALTSVC_HTTP="yeah"
+</setenv>
+ <command>
+--http2 --alt-svc "log/altsvc-359" "http://%HOSTIP:%HTTPSPORT/359"; 
"http://%HOSTIP:%HTTPSPORT/359";
+</command>
+<file name="log/altsvc-359">
+h2 %HOSTIP %HTTPSPORT h2 %HOSTIP %HTTP2PORT "20290222 22:19:28" 0 0
+</file>
+
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<stdout>
+HTTP/1.1 101 Switching Protocols
+Connection: Upgrade
+Upgrade: h2c
+
+HTTP/2 200 
+date: Thu, 09 Nov 2010 14:49:00 GMT
+content-length: 6
+content-type: text/html
+funny-head: yesyes
+alt-svc: h2=":%HTTP2PORT", ma=315360000; persist=0
+server: nghttpx
+via: 1.1 nghttpx
+
+-foo-
+HTTP/2 200 
+date: Thu, 09 Nov 2010 14:49:00 GMT
+content-length: 6
+content-type: text/html
+funny-head: yesyes
+alt-svc: h2=":%HTTP2PORT", ma=315360000; persist=0
+server: nghttpx
+via: 1.1 nghttpx
+
+-foo-
+</stdout>
+<stripfile>
+# strip out the (dynamic) expire date from the file so that the rest
+# matches
+s/\"2([^\"]*)\"/TIMESTAMP/
+</stripfile>
+<file name="log/altsvc-359" mode="text">
+# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html
+# This file was generated by libcurl! Edit at your own risk.
+h2 %HOSTIP %HTTPSPORT h2 %HOSTIP %HTTP2PORT TIMESTAMP 0 0
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test430 b/tests/data/test430
new file mode 100644
index 000000000..d4dc530dd
--- /dev/null
+++ b/tests/data/test430
@@ -0,0 +1,101 @@
+<testcase>
+# Derived from on https://github.com/curl/curl/issues/5120
+<info>
+<keywords>
+--next
+--config
+POST
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data1>
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/1
+
+-foo-
+</data1>
+<data2>
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/2
+
+-foo-
+</data2>
+<data3>
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/3
+
+-foo-
+</data3>
+</reply>
+
+#
+# Client-side
+<client>
+<file1 name="log/config430-a">
+--next
+url = %HOSTIP:%HTTPPORT/4300001
+header = "a: a"
+data = "a"
+</file1>
+<file2 name="log/config430-b">
+--next
+url = %HOSTIP:%HTTPPORT/4300002
+header = "b: b"
+data = "b"
+</file2>
+<file3 name="log/config430-c">
+--next
+url = %HOSTIP:%HTTPPORT/4300003
+header = "c: c"
+data = "c"
+</file3>
+
+<server>
+http
+</server>
+ <name>
+Three -K uses with --next and --data in each
+ </name>
+ <command>
+-K log/config430-a -K log/config430-b -K log/config430-c
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol nonewline="yes">
+POST /4300001 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+a: a
+Content-Length: 1
+Content-Type: application/x-www-form-urlencoded
+
+aPOST /4300002 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+b: b
+Content-Length: 1
+Content-Type: application/x-www-form-urlencoded
+
+bPOST /4300003 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+c: c
+Content-Length: 1
+Content-Type: application/x-www-form-urlencoded
+
+c
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test431 b/tests/data/test431
new file mode 100644
index 000000000..48a1b20a1
--- /dev/null
+++ b/tests/data/test431
@@ -0,0 +1,95 @@
+<testcase>
+# Derived from on https://github.com/curl/curl/issues/5120
+<info>
+<keywords>
+--next
+--config
+POST
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data1>
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/1
+
+-foo-
+</data1>
+<data2>
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/2
+
+-foo-
+</data2>
+<data3>
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/3
+
+-foo-
+</data3>
+</reply>
+
+#
+# Client-side
+<client>
+<file1 name="log/config431-a">
+--next
+url = %HOSTIP:%HTTPPORT/4310001
+header = "a: a"
+data = "a"
+</file1>
+<file2 name="log/config431-b">
+--next
+url = %HOSTIP:%HTTPPORT/4310002
+header = "b: b"
+data = "b"
+</file2>
+
+<server>
+http
+</server>
+ <name>
+Two -K uses with --next and then one on cmdline
+ </name>
+ <command>
+-K log/config431-a -K log/config431-b --next -d c %HOSTIP:%HTTPPORT/4310003 -H 
"c: c"
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol nonewline="yes">
+POST /4310001 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+a: a
+Content-Length: 1
+Content-Type: application/x-www-form-urlencoded
+
+aPOST /4310002 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+b: b
+Content-Length: 1
+Content-Type: application/x-www-form-urlencoded
+
+bPOST /4310003 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+c: c
+Content-Length: 1
+Content-Type: application/x-www-form-urlencoded
+
+c
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test432 b/tests/data/test432
new file mode 100644
index 000000000..b3401b687
--- /dev/null
+++ b/tests/data/test432
@@ -0,0 +1,100 @@
+<testcase>
+# Derived from on https://github.com/curl/curl/issues/5120
+<info>
+<keywords>
+--next
+--config
+POST
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data1>
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/1
+
+-foo-
+</data1>
+<data2>
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/2
+
+-foo-
+</data2>
+<data3>
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/3
+
+-foo-
+</data3>
+</reply>
+
+#
+# Client-side
+<client>
+<file1 name="log/config432">
+--next
+url = %HOSTIP:%HTTPPORT/4320001
+header = "a: a"
+data = "a"
+--next
+url = %HOSTIP:%HTTPPORT/4320002
+header = "b: b"
+data = "b"
+config = "log/config432-c"
+</file1>
+<file2 name="log/config432-c">
+--next
+url = %HOSTIP:%HTTPPORT/4320003
+header = "c: c"
+data = "c"
+</file2>
+
+<server>
+http
+</server>
+ <name>
+Use -K with --next and --config from within
+ </name>
+ <command>
+-K log/config432
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol nonewline="yes">
+POST /4320001 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+a: a
+Content-Length: 1
+Content-Type: application/x-www-form-urlencoded
+
+aPOST /4320002 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+b: b
+Content-Length: 1
+Content-Type: application/x-www-form-urlencoded
+
+bPOST /4320003 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+c: c
+Content-Length: 1
+Content-Type: application/x-www-form-urlencoded
+
+c
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test504 b/tests/data/test504
index 7c92209cd..be8f95e2b 100644
--- a/tests/data/test504
+++ b/tests/data/test504
@@ -32,7 +32,7 @@ lib504
 simple multi through local proxy without listener
  </name>
  <command>
-http://%HOSTIP:%HTTPSPORT/504 %HOSTIP:55555
+http://%HOSTIP:%HTTPSPORT/504 %HOSTIP:%NOLISTENPORT
 </command>
 </client>
 
diff --git a/tests/data/test663 b/tests/data/test663
index 6743b3258..c9c05a02d 100644
--- a/tests/data/test663
+++ b/tests/data/test663
@@ -1,8 +1,8 @@
+<testcase>
 #
 # This test is crafted to reproduce oss-fuzz bug
 # https://crbug.com/oss-fuzz/17954
 #
-<testcase>
 <info>
 <keywords>
 HTTP
diff --git a/tests/data/test277 b/tests/data/test669
similarity index 54%
copy from tests/data/test277
copy to tests/data/test669
index d3e9d0fa4..aaae2c51d 100644
--- a/tests/data/test277
+++ b/tests/data/test669
@@ -2,16 +2,17 @@
 <info>
 <keywords>
 HTTP
+HTTP POST
+HTTP MIME POST
 HTTP FORMPOST
 </keywords>
 </info>
 # Server-side
 <reply>
 <data>
-HTTP/1.1 200 OK swsclose
+HTTP/1.0 200 OK swsclose
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake
-Content-Length: 11
 
 blablabla
 
@@ -24,11 +25,12 @@ blablabla
 http
 </server>
  <name>
-HTTP RFC1867-type formposting with custom Content-Type
+HTTP custom Content-Type with parameter
  </name>
  <command>
-http://%HOSTIP:%HTTPPORT/want/277 -F name=daniel -H "Content-Type: text/info"
+http://%HOSTIP:%HTTPPORT/we/want/669 -H 'Content-type: multipart/form-data; 
charset=utf-8' -F name=daniel -F tool=curl
 </command>
+</file>
 </client>
 
 # Verify data after the test has been "shot"
@@ -37,22 +39,26 @@ http://%HOSTIP:%HTTPPORT/want/277 -F name=daniel -H 
"Content-Type: text/info"
 ^User-Agent:.*
 </strip>
 <strippart>
-s/^--------------------------[a-z0-9]*/--------------------------/
-s/boundary=------------------------[a-z0-9]*/boundary=------------------------/
+s/^--------------------------[a-z0-9]*/------------------------------/
+s/boundary=------------------------[a-z0-9]*/boundary=----------------------------/
 </strippart>
 <protocol>
-POST /want/277 HTTP/1.1
+POST /we/want/669 HTTP/1.1
 User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 
zlib/1.1.3
 Host: %HOSTIP:%HTTPPORT
 Accept: */*
-Content-Length: 146
-Content-Type: text/info; boundary=------------------------
+Content-Length: 242
+Content-Type: multipart/form-data; charset=utf-8; 
boundary=----------------------------
 
---------------------------
-Content-Disposition: attachment; name="name"
+------------------------------
+Content-Disposition: form-data; name="name"
 
 daniel
-----------------------------
+------------------------------
+Content-Disposition: form-data; name="tool"
+
+curl
+--------------------------------
 </protocol>
 </verify>
 </testcase>
diff --git a/tests/data/test702 b/tests/data/test702
index c03723676..1c18d0976 100644
--- a/tests/data/test702
+++ b/tests/data/test702
@@ -31,7 +31,7 @@ proxy
 Attempt connect to non-listening HTTP server via SOCKS4 proxy
  </name>
  <command>
---socks4 %HOSTIP:%SOCKSPORT http://%HOSTIP:60000
+--socks4 %HOSTIP:%SOCKSPORT http://%HOSTIP:%NOLISTENPORT
 </command>
 </client>
 
diff --git a/tests/data/test703 b/tests/data/test703
index 53d6a0222..d7be71393 100644
--- a/tests/data/test703
+++ b/tests/data/test703
@@ -31,7 +31,7 @@ proxy
 Attempt connect to non-listening HTTP server via SOCKS5 proxy
  </name>
  <command>
---socks5 %HOSTIP:%SOCKSPORT http://%HOSTIP:60000
+--socks5 %HOSTIP:%SOCKSPORT http://%HOSTIP:%NOLISTENPORT
 </command>
 </client>
 
diff --git a/tests/data/test704 b/tests/data/test704
index 7f891fa95..9e821c608 100644
--- a/tests/data/test704
+++ b/tests/data/test704
@@ -23,7 +23,7 @@ http
 Attempt connect to non-listening SOCKS4 proxy
  </name>
  <command>
---socks4 %HOSTIP:2 http://%HOSTIP:%HTTPPORT/704
+--socks4 %HOSTIP:%NOLISTENPORT http://%HOSTIP:%HTTPPORT/704
 </command>
 <features>
 proxy
diff --git a/tests/data/test705 b/tests/data/test705
index cfbf3419f..e7ba01220 100644
--- a/tests/data/test705
+++ b/tests/data/test705
@@ -23,7 +23,7 @@ http
 Attempt connect to non-listening SOCKS5 proxy
  </name>
  <command>
---socks5 %HOSTIP:2 http://%HOSTIP:%HTTPPORT/705
+--socks5 %HOSTIP:%NOLISTENPORT http://%HOSTIP:%HTTPPORT/705
 </command>
 <features>
 proxy
diff --git a/tests/data/test970 b/tests/data/test970
new file mode 100644
index 000000000..54e34cc5b
--- /dev/null
+++ b/tests/data/test970
@@ -0,0 +1,66 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 445
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 
culpa qui officia deserunt mollit anim id est laborum
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+debug
+</features>
+<setenv>
+CURL_TIME=13
+CURL_DEBUG_SIZE=4019
+CURL_VERSION=curl-unit-test-fake-version
+</setenv>
+<name>
+HTTP GET with JSON output
+</name>
+<command option="no-include">
+http://%HOSTIP:%HTTPPORT/970 --write-out '%{json}' -o log/out970
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /970 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+<stdout nonewline="yes">
+{"url_effective":"http://%HOSTIP:%HTTPPORT/970","http_code":200,"response_code":200,"http_connect":0,"time_total":0.000013,"time_namelookup":0.000013,"time_connect":0.000013,"time_appconnect":0.000013,"time_pretransfer":0.000013,"time_starttransfer":0.000013,"size_header":4019,"size_request":4019,"size_download":445,"size_upload":0,"speed_download":13,"speed_upload":13,"content_type":"text/html","num_connects":1,"time_redirect":0.000013,"num_redirects":0,"ssl_verify_result":0,"proxy_ssl_
 [...]
+</stdout>
+</verify>
+</testcase>
diff --git a/tests/dictserver.py.in b/tests/dictserver.py.in
index 9f2cc984b..e08617f5e 100755
--- a/tests/dictserver.py.in
+++ b/tests/dictserver.py.in
@@ -1,5 +1,26 @@
 #!AWKPYTHON
 # -*- coding: utf-8 -*-
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2008 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #
 """ DICT server """
 
@@ -30,8 +51,11 @@ def dictserver(options):
     """
     if options.pidfile:
         pid = os.getpid()
+        # see tests/server/util.c function write_pidfile
+        if os.name == "nt":
+            pid += 65536
         with open(options.pidfile, "w") as f:
-            f.write("{0}".format(pid))
+            f.write(str(pid))
 
     local_bind = (options.host, options.port)
     log.info("[DICT] Listening on %s", local_bind)
@@ -64,7 +88,11 @@ class DictHandler(socketserver.BaseRequestHandler):
             if VERIFIED_REQ in data:
                 log.debug("[DICT] Received verification request from test "
                           "framework")
-                response_data = VERIFIED_RSP.format(pid=os.getpid())
+                pid = os.getpid()
+                # see tests/server/util.c function write_pidfile
+                if os.name == "nt":
+                    pid += 65536
+                response_data = VERIFIED_RSP.format(pid=pid)
             else:
                 log.debug("[DICT] Received normal request")
                 response_data = "No matches"
diff --git a/tests/directories.pm b/tests/directories.pm
index e3327c128..da6c76746 100644
--- a/tests/directories.pm
+++ b/tests/directories.pm
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/extern-scan.pl b/tests/extern-scan.pl
index 1b22410f5..99b096ba2 100755
--- a/tests/extern-scan.pl
+++ b/tests/extern-scan.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2010-2015, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2010 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/ftp.pm b/tests/ftp.pm
index 5e92ce7f9..971be199f 100644
--- a/tests/ftp.pm
+++ b/tests/ftp.pm
@@ -42,12 +42,16 @@ use serverhelp qw(
     datasockf_pidfilename
     );
 
+use pathhelp qw(
+    os_is_win
+    );
+
 #######################################################################
 # portable_sleep uses Time::HiRes::sleep if available and falls back
 # to the classic approach of using select(undef, undef, undef, ...).
 # even though that one is not portable due to being implemented using
 # select on Windows: https://perldoc.perl.org/perlport.html#select
-# On Windows it also just uses full-second sleep for waits >1 second.
+# Therefore it uses Win32::Sleep on Windows systems instead.
 #
 sub portable_sleep {
     my ($seconds) = @_;
@@ -55,7 +59,7 @@ sub portable_sleep {
     if($Time::HiRes::VERSION) {
         Time::HiRes::sleep($seconds);
     }
-    elsif ($^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys') {
+    elsif (os_is_win()) {
         Win32::Sleep($seconds*1000);
     }
     else {
@@ -91,19 +95,23 @@ sub pidexists {
     my $pid = $_[0];
 
     if($pid > 0) {
+        # verify if currently existing Windows process
+        if ($pid > 65536 && os_is_win()) {
+            $pid -= 65536;
+            if($^O ne 'MSWin32') {
+                my $filter = "PID eq $pid";
+                my $result = `tasklist -fi \"$filter\" 2>nul`;
+                if(index($result, "$pid") != -1) {
+                    return -$pid;
+                }
+                return 0;
+            }
+        }
+
         # verify if currently existing and alive
         if(kill(0, $pid)) {
             return $pid;
         }
-
-        # verify if currently existing Windows process
-        if($^O eq "msys") {
-            my $filter = "PID eq $pid";
-            my $result = `tasklist -fi \"$filter\" 2>nul`;
-            if(index($result, "$pid") != -1) {
-                return -$pid;
-            }
-        }
     }
 
     return 0;
@@ -116,41 +124,71 @@ sub pidterm {
     my $pid = $_[0];
 
     if($pid > 0) {
-        # signal the process to terminate
-        kill("TERM", $pid);
-
         # request the process to quit
-        if($^O eq "msys") {
-            my $filter = "PID eq $pid";
-            my $result = `tasklist -fi \"$filter\" 2>nul`;
-            if(index($result, "$pid") != -1) {
-                system("taskkill -fi \"$filter\" >nul 2>&1");
+        if ($pid > 65536 && os_is_win()) {
+            $pid -= 65536;
+            if($^O ne 'MSWin32') {
+                my $filter = "PID eq $pid";
+                my $result = `tasklist -fi \"$filter\" 2>nul`;
+                if(index($result, "$pid") != -1) {
+                    system("taskkill -fi \"$filter\" >nul 2>&1");
+                }
+                return;
             }
         }
+
+        # signal the process to terminate
+        kill("TERM", $pid);
     }
 }
 
 #######################################################################
-# pidkill kills the process with a given pid mercilessly andforcefully.
+# pidkill kills the process with a given pid mercilessly and forcefully.
 #
 sub pidkill {
     my $pid = $_[0];
 
     if($pid > 0) {
+        # request the process to quit
+        if ($pid > 65536 && os_is_win()) {
+            $pid -= 65536;
+            if($^O ne 'MSWin32') {
+                my $filter = "PID eq $pid";
+                my $result = `tasklist -fi \"$filter\" 2>nul`;
+                if(index($result, "$pid") != -1) {
+                    system("taskkill -f -fi \"$filter\" >nul 2>&1");
+                    # Windows XP Home compatibility
+                    system("tskill $pid >nul 2>&1");
+                }
+                return;
+            }
+        }
+
         # signal the process to terminate
         kill("KILL", $pid);
+    }
+}
 
-        # request the process to quit
-        if($^O eq "msys") {
-            my $filter = "PID eq $pid";
-            my $result = `tasklist -fi \"$filter\" 2>nul`;
-            if(index($result, "$pid") != -1) {
-                system("taskkill -f -fi \"$filter\" >nul 2>&1");
-                # Windows XP Home compatibility
-                system("tskill $pid >nul 2>&1");
-            }
+#######################################################################
+# pidwait waits for the process with a given pid to be terminated.
+#
+sub pidwait {
+    my $pid = $_[0];
+    my $flags = $_[1];
+
+    # check if the process exists
+    if ($pid > 65536 && os_is_win()) {
+        if($flags == &WNOHANG) {
+            return pidexists($pid)?0:$pid;
         }
+        while(pidexists($pid)) {
+            portable_sleep(0.01);
+        }
+        return $pid;
     }
+
+    # wait on the process to terminate
+    return waitpid($pid, $flags);
 }
 
 #######################################################################
@@ -177,7 +215,7 @@ sub processexists {
             # get rid of the certainly invalid pidfile
             unlink($pidfile) if($pid == pidfromfile($pidfile));
             # reap its dead children, if not done yet
-            waitpid($pid, &WNOHANG);
+            pidwait($pid, &WNOHANG);
             # negative return value means dead process
             return -$pid;
         }
@@ -227,7 +265,7 @@ sub killpid {
                     print("RUN: Process with pid $pid already dead\n")
                         if($verbose);
                     # if possible reap its dead children
-                    waitpid($pid, &WNOHANG);
+                    pidwait($pid, &WNOHANG);
                     push @reapchild, $pid;
                 }
             }
@@ -245,7 +283,7 @@ sub killpid {
                         if($verbose);
                     splice @signalled, $i, 1;
                     # if possible reap its dead children
-                    waitpid($pid, &WNOHANG);
+                    pidwait($pid, &WNOHANG);
                     push @reapchild, $pid;
                 }
             }
@@ -262,7 +300,7 @@ sub killpid {
                     if($verbose);
                 pidkill($pid);
                 # if possible reap its dead children
-                waitpid($pid, &WNOHANG);
+                pidwait($pid, &WNOHANG);
                 push @reapchild, $pid;
             }
         }
@@ -272,7 +310,7 @@ sub killpid {
     if(@reapchild) {
         foreach my $pid (@reapchild) {
             if($pid > 0) {
-                waitpid($pid, 0);
+                pidwait($pid, 0);
             }
         }
     }
@@ -301,7 +339,7 @@ sub killsockfilters {
             printf("* kill pid for %s-%s => %d\n", $server,
                 ($proto eq 'ftp')?'ctrl':'filt', $pid) if($verbose);
             pidkill($pid);
-            waitpid($pid, 0);
+            pidwait($pid, 0);
         }
         unlink($pidfile) if(-f $pidfile);
     }
@@ -315,7 +353,7 @@ sub killsockfilters {
             printf("* kill pid for %s-data => %d\n", $server,
                 $pid) if($verbose);
             pidkill($pid);
-            waitpid($pid, 0);
+            pidwait($pid, 0);
         }
         unlink($pidfile) if(-f $pidfile);
     }
diff --git a/tests/ftpserver.pl b/tests/ftpserver.pl
index 431bd2586..92420ea4b 100755
--- a/tests/ftpserver.pl
+++ b/tests/ftpserver.pl
@@ -96,6 +96,7 @@ my $listenaddr = '127.0.0.1';  # default address for listener 
port
 # global vars used for file names
 #
 my $pidfile;            # server pid file name
+my $portfile=".ftpserver.port"; # server port file name
 my $logfile;            # server log file name
 my $mainsockf_pidfile;  # pid file for primary connection sockfilt process
 my $mainsockf_logfile;  # log file for primary connection sockfilt process
@@ -191,6 +192,7 @@ sub exit_signal_handler {
     # For now, simply mimic old behavior.
     killsockfilters($proto, $ipvnum, $idnum, $verbose);
     unlink($pidfile);
+    unlink($portfile);
     if($serverlogslocked) {
         $serverlogslocked = 0;
         clear_advisor_read_lock($SERVERLOGS_LOCK);
@@ -333,7 +335,7 @@ sub eXsysread {
 sub read_mainsockf {
     my $scalar  = shift;
     my $nbytes  = shift;
-    my $timeout = shift; # Optional argument, if zero blocks indefinitively
+    my $timeout = shift; # Optional argument, if zero blocks indefinitely
     my $FH = \*SFREAD;
 
     if(not defined $timeout) {
@@ -357,7 +359,7 @@ sub read_mainsockf {
 sub read_datasockf {
     my $scalar = shift;
     my $nbytes = shift;
-    my $timeout = shift; # Optional argument, if zero blocks indefinitively
+    my $timeout = shift; # Optional argument, if zero blocks indefinitely
     my $FH = \*DREAD;
 
     if(not defined $timeout) {
@@ -390,6 +392,7 @@ sub sysread_or_die {
                "line $lcaller. $srvrname server, sysread error: $!\n";
         killsockfilters($proto, $ipvnum, $idnum, $verbose);
         unlink($pidfile);
+        unlink($portfile);
         if($serverlogslocked) {
             $serverlogslocked = 0;
             clear_advisor_read_lock($SERVERLOGS_LOCK);
@@ -404,6 +407,7 @@ sub sysread_or_die {
                "line $lcaller. $srvrname server, read zero\n";
         killsockfilters($proto, $ipvnum, $idnum, $verbose);
         unlink($pidfile);
+        unlink($portfile);
         if($serverlogslocked) {
             $serverlogslocked = 0;
             clear_advisor_read_lock($SERVERLOGS_LOCK);
@@ -418,6 +422,7 @@ sub startsf {
     my $mainsockfcmd = "./server/sockfilt".exe_ext('SRV')." " .
         "--ipv$ipvnum --port $port " .
         "--pidfile \"$mainsockf_pidfile\" " .
+        "--portfile \"$portfile\" " .
         "--logfile \"$mainsockf_logfile\"";
     $sfpid = open2(*SFREAD, *SFWRITE, $mainsockfcmd);
 
@@ -431,6 +436,7 @@ sub startsf {
         logmsg "Failed sockfilt command: $mainsockfcmd\n";
         killsockfilters($proto, $ipvnum, $idnum, $verbose);
         unlink($pidfile);
+        unlink($portfile);
         if($serverlogslocked) {
             $serverlogslocked = 0;
             clear_advisor_read_lock($SERVERLOGS_LOCK);
@@ -687,6 +693,7 @@ sub close_dataconn {
             print DWRITE "DISC\n";
             my $i;
             sysread DREAD, $i, 5;
+            logmsg "Server disconnected $datasockf_mode DATA connection\n";
         }
         else {
             logmsg "Server finds $datasockf_mode DATA connection already ".
@@ -699,10 +706,12 @@ sub close_dataconn {
     }
 
     if($datapid > 0) {
+        logmsg "DATA sockfilt for $datasockf_mode data channel quits ".
+               "(pid $datapid)\n";
         print DWRITE "QUIT\n";
-        waitpid($datapid, 0);
+        pidwait($datapid, 0);
         unlink($datasockf_pidfile) if(-f $datasockf_pidfile);
-        logmsg "DATA sockfilt for $datasockf_mode data channel quits ".
+        logmsg "DATA sockfilt for $datasockf_mode data channel quit ".
                "(pid $datapid)\n";
     }
     else {
@@ -2897,6 +2906,7 @@ sub customize {
 # --id        # server instance number
 # --proto     # server protocol
 # --pidfile   # server pid file
+# --portfile  # server port file
 # --logfile   # server log file
 # --ipv4      # server IP version 4
 # --ipv6      # server IP version 6
@@ -2934,6 +2944,12 @@ while(@ARGV) {
             shift @ARGV;
         }
     }
+    elsif($ARGV[0] eq '--portfile') {
+        if($ARGV[1]) {
+            $portfile = $ARGV[1];
+            shift @ARGV;
+        }
+    }
     elsif($ARGV[0] eq '--logfile') {
         if($ARGV[1]) {
             $logfile = $ARGV[1];
@@ -2949,8 +2965,8 @@ while(@ARGV) {
         $listenaddr = '::1' if($listenaddr eq '127.0.0.1');
     }
     elsif($ARGV[0] eq '--port') {
-        if($ARGV[1] && ($ARGV[1] =~ /^(\d+)$/)) {
-            $port = $1 if($1 > 1024);
+        if($ARGV[1] =~ /^(\d+)$/) {
+            $port = $1;
             shift @ARGV;
         }
     }
@@ -3010,6 +3026,15 @@ $SIG{TERM} = \&exit_signal_handler;
 
 startsf();
 
+# actual port
+if($portfile && !$port) {
+    my $aport;
+    open(P, "<$portfile");
+    $aport = <P>;
+    close(P);
+    $port = 0 + $aport;
+}
+
 logmsg sprintf("%s server listens on port IPv${ipvnum}/${port}\n", uc($proto));
 
 open(PID, ">$pidfile");
@@ -3018,7 +3043,6 @@ close(PID);
 
 logmsg("logged pid $$ in $pidfile\n");
 
-
 while(1) {
 
     # kill previous data connection sockfilt when alive
diff --git a/tests/fuzz/download_fuzzer.sh b/tests/fuzz/download_fuzzer.sh
index b19fbb7ba..a0669e169 100755
--- a/tests/fuzz/download_fuzzer.sh
+++ b/tests/fuzz/download_fuzzer.sh
@@ -1,4 +1,25 @@
 #!/bin/sh
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
 # If any commands fail, fail the script immediately.
 set -ex
diff --git a/tests/getpart.pm b/tests/getpart.pm
index 7080bf4b7..9519888ee 100644
--- a/tests/getpart.pm
+++ b/tests/getpart.pm
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -23,6 +23,7 @@
 #use strict;
 
 my @xml;
+my $xmlfile;
 
 my $warning=0;
 my $trace=0;
@@ -34,6 +35,15 @@ sub decode_base64 {
   return unpack("u", $len . $_);         # uudecode and print
 }
 
+sub decode_hex {
+    my $s = $_;
+    # remove everything not hex
+    $s =~ s/[^A-Fa-f0-9]//g;
+    # encode everything
+    $s =~ s/([a-fA-F0-9][a-fA-F0-9])/chr(hex($1))/eg;
+    return $s;
+}
+
 sub getpartattr {
     # if $part is undefined (ie only one argument) then
     # return the attributes of the section
@@ -80,11 +90,11 @@ sub getpart {
     my @this;
     my $inside=0;
     my $base64=0;
-
- #   print "Section: $section, part: $part\n";
+    my $hex=0;
+    my $line;
 
     for(@xml) {
- #       print "$inside: $_";
+        $line++;
         if(!$inside && ($_ =~ /^ *\<$section/)) {
             $inside++;
         }
@@ -96,6 +106,10 @@ sub getpart {
                 # attempt to detect our base64 encoded part
                 $base64=1;
             }
+            elsif($_ =~ /$part [^>]*hex=/) {
+                # attempt to detect a hex-encoded part
+                $hex=1;
+            }
             $inside++;
         }
         elsif(($inside >= 2) && ($_ =~ /^ *\<\/$part[ \>]/)) {
@@ -105,6 +119,10 @@ sub getpart {
             $inside--;
         }
         elsif(($inside >= 1) && ($_ =~ /^ *\<\/$section/)) {
+            if($inside > 1) {
+                print STDERR "$xmlfile:$line:1: error: missing </$part> tag 
before </$section>\n";
+                @this = ("format error in $xmlfile");
+            }
             if($trace && @this) {
                 print STDERR "*** getpart.pm: $section/$part returned data!\n";
             }
@@ -118,6 +136,13 @@ sub getpart {
                     $_ = $decoded;
                 }
             }
+            elsif($hex) {
+                # decode the whole array before returning it!
+                for(@this) {
+                    my $decoded = decode_hex($_);
+                    $_ = $decoded;
+                }
+            }
             return @this;
         }
         elsif($inside >= 2) {
@@ -165,6 +190,7 @@ sub loadtest {
     my ($file)=@_;
 
     undef @xml;
+    $xmlfile = $file;
 
     if(open(XML, "<$file")) {
         binmode XML; # for crapage systems, use binary
@@ -183,6 +209,31 @@ sub loadtest {
     return 0;
 }
 
+sub fulltest {
+    return @xml;
+}
+
+# write the test to the given file
+sub savetest {
+    my ($file)=@_;
+
+    if(open(XML, ">$file")) {
+        binmode XML; # for crapage systems, use binary
+        for(@xml) {
+            print XML $_;
+        }
+        close(XML);
+    }
+    else {
+        # failure
+        if($warning) {
+            print STDERR "file $file wouldn't open!\n";
+        }
+        return 1;
+    }
+    return 0;
+}
+
 #
 # Strip off all lines that match the specified pattern and return
 # the new array.
diff --git a/tests/http2-server.pl b/tests/http2-server.pl
index 086d5aa76..4dbb0d854 100755
--- a/tests/http2-server.pl
+++ b/tests/http2-server.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2016, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2016 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/httpserver.pl b/tests/httpserver.pl
index 8b789a9b9..58ab5d460 100755
--- a/tests/httpserver.pl
+++ b/tests/httpserver.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -44,8 +44,9 @@ my $unix_socket;     # location to place a listening Unix 
socket
 my $ipvnum = 4;      # default IP version of http server
 my $idnum = 1;       # default http server instance number
 my $proto = 'http';  # protocol the http server speaks
-my $pidfile;         # http server pid file
-my $logfile;         # http server log file
+my $pidfile;         # pid file
+my $portfile;        # port number file
+my $logfile;         # log file
 my $connect;         # IP to connect to on CONNECT
 my $srcdir;
 my $gopher = 0;
@@ -61,6 +62,12 @@ while(@ARGV) {
             shift @ARGV;
         }
     }
+    elsif($ARGV[0] eq '--portfile') {
+        if($ARGV[1]) {
+            $portfile = $ARGV[1];
+            shift @ARGV;
+        }
+    }
     elsif($ARGV[0] eq '--logfile') {
         if($ARGV[1]) {
             $logfile = $ARGV[1];
@@ -122,11 +129,16 @@ if(!$srcdir) {
 if(!$pidfile) {
     $pidfile = "$path/". server_pidfilename($proto, $ipvnum, $idnum);
 }
+if(!$portfile) {
+    $portfile = "$path/". server_portfilename($proto, $ipvnum, $idnum);
+}
 if(!$logfile) {
     $logfile = server_logfilename($logdir, $proto, $ipvnum, $idnum);
 }
 
-$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
+$flags .= "--pidfile \"$pidfile\" ".
+    "--logfile \"$logfile\" ".
+    "--portfile \"$portfile\" ";
 $flags .= "--gopher " if($gopher);
 $flags .= "--connect $connect " if($connect);
 if($ipvnum eq 'unix') {
diff --git a/tests/libtest/CMakeLists.txt b/tests/libtest/CMakeLists.txt
index 1dcebb1a2..380580690 100644
--- a/tests/libtest/CMakeLists.txt
+++ b/tests/libtest/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 set(TARGET_LABEL_PREFIX "Test ")
 
 function(setup_test TEST_NAME)          # ARGN are the files in the test
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
index ab2680c97..1651308b1 100644
--- a/tests/libtest/Makefile.inc
+++ b/tests/libtest/Makefile.inc
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # files used only in some libcurl test programs
 TESTUTIL = testutil.c testutil.h
 
diff --git a/tests/libtest/lib1507.c b/tests/libtest/lib1507.c
index dc023a079..20cc5f0a4 100644
--- a/tests/libtest/lib1507.c
+++ b/tests/libtest/lib1507.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1508.c b/tests/libtest/lib1508.c
index f536422cb..09d24d8dc 100644
--- a/tests/libtest/lib1508.c
+++ b/tests/libtest/lib1508.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2013, Linus Nielsen Feltzing <address@hidden>
+ * Copyright (C) 2013 - 2020, Linus Nielsen Feltzing <address@hidden>
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1509.c b/tests/libtest/lib1509.c
index 63bc589b1..2bc8c9ffa 100644
--- a/tests/libtest/lib1509.c
+++ b/tests/libtest/lib1509.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1514.c b/tests/libtest/lib1514.c
index b4ab9dcc3..d01a5d4fb 100644
--- a/tests/libtest/lib1514.c
+++ b/tests/libtest/lib1514.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1515.c b/tests/libtest/lib1515.c
index b879836f9..4e578a42e 100644
--- a/tests/libtest/lib1515.c
+++ b/tests/libtest/lib1515.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1520.c b/tests/libtest/lib1520.c
index c6ac64bb4..779aeafcd 100644
--- a/tests/libtest/lib1520.c
+++ b/tests/libtest/lib1520.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2014, Steve Holme, <address@hidden>.
+ * Copyright (C) 2014 - 2020, Steve Holme, <address@hidden>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1525.c b/tests/libtest/lib1525.c
index a76494589..551d04e02 100644
--- a/tests/libtest/lib1525.c
+++ b/tests/libtest/lib1525.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  * Copyright (C) 2014, Vijay Panghal, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
diff --git a/tests/libtest/lib1526.c b/tests/libtest/lib1526.c
index 663465799..d94c03cf4 100644
--- a/tests/libtest/lib1526.c
+++ b/tests/libtest/lib1526.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Vijay Panghal, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Vijay Panghal, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1527.c b/tests/libtest/lib1527.c
index 689839e3d..c50c2fa23 100644
--- a/tests/libtest/lib1527.c
+++ b/tests/libtest/lib1527.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Vijay Panghal, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Vijay Panghal, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1531.c b/tests/libtest/lib1531.c
index 5c9399559..73b3f0a91 100644
--- a/tests/libtest/lib1531.c
+++ b/tests/libtest/lib1531.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1533.c b/tests/libtest/lib1533.c
index 962a222ec..7a4aafc64 100644
--- a/tests/libtest/lib1533.c
+++ b/tests/libtest/lib1533.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1535.c b/tests/libtest/lib1535.c
index 6ff03467d..b448466dd 100644
--- a/tests/libtest/lib1535.c
+++ b/tests/libtest/lib1535.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1536.c b/tests/libtest/lib1536.c
index 0c04bbf8e..5bee299cc 100644
--- a/tests/libtest/lib1536.c
+++ b/tests/libtest/lib1536.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1540.c b/tests/libtest/lib1540.c
index c3f855490..d0e4ca9b6 100644
--- a/tests/libtest/lib1540.c
+++ b/tests/libtest/lib1540.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib1554.c b/tests/libtest/lib1554.c
index df12fe52e..a8198803b 100644
--- a/tests/libtest/lib1554.c
+++ b/tests/libtest/lib1554.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib500.c b/tests/libtest/lib500.c
index 8d9b92129..96dde3279 100644
--- a/tests/libtest/lib500.c
+++ b/tests/libtest/lib500.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib501.c b/tests/libtest/lib501.c
index 4549cb648..95ffc0ae0 100644
--- a/tests/libtest/lib501.c
+++ b/tests/libtest/lib501.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib502.c b/tests/libtest/lib502.c
index df8905c84..bfd45919b 100644
--- a/tests/libtest/lib502.c
+++ b/tests/libtest/lib502.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib503.c b/tests/libtest/lib503.c
index 00791edf5..a1c851fb3 100644
--- a/tests/libtest/lib503.c
+++ b/tests/libtest/lib503.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib504.c b/tests/libtest/lib504.c
index 8d1fe506e..9843393d9 100644
--- a/tests/libtest/lib504.c
+++ b/tests/libtest/lib504.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib512.c b/tests/libtest/lib512.c
index 8a6f0e149..84e2a9740 100644
--- a/tests/libtest/lib512.c
+++ b/tests/libtest/lib512.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib519.c b/tests/libtest/lib519.c
index 73da7d5ca..f6b367922 100644
--- a/tests/libtest/lib519.c
+++ b/tests/libtest/lib519.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib521.c b/tests/libtest/lib521.c
index 8d9aa2e2c..32819113e 100644
--- a/tests/libtest/lib521.c
+++ b/tests/libtest/lib521.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib523.c b/tests/libtest/lib523.c
index 450438939..1708e1419 100644
--- a/tests/libtest/lib523.c
+++ b/tests/libtest/lib523.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib524.c b/tests/libtest/lib524.c
index fe0a8ed21..fe195fd5e 100644
--- a/tests/libtest/lib524.c
+++ b/tests/libtest/lib524.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib543.c b/tests/libtest/lib543.c
index 957839f7a..5fe5cd1ce 100644
--- a/tests/libtest/lib543.c
+++ b/tests/libtest/lib543.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib547.c b/tests/libtest/lib547.c
index 3cfc81d29..85e8e0c1e 100644
--- a/tests/libtest/lib547.c
+++ b/tests/libtest/lib547.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib549.c b/tests/libtest/lib549.c
index bb41cd619..886625427 100644
--- a/tests/libtest/lib549.c
+++ b/tests/libtest/lib549.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib558.c b/tests/libtest/lib558.c
index d9969738a..52340d720 100644
--- a/tests/libtest/lib558.c
+++ b/tests/libtest/lib558.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib559.c b/tests/libtest/lib559.c
index be112b8f3..2203cff3b 100644
--- a/tests/libtest/lib559.c
+++ b/tests/libtest/lib559.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib560.c b/tests/libtest/lib560.c
index 16045e6da..56ee2001e 100644
--- a/tests/libtest/lib560.c
+++ b/tests/libtest/lib560.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib566.c b/tests/libtest/lib566.c
index 257738a4f..04e3032ed 100644
--- a/tests/libtest/lib566.c
+++ b/tests/libtest/lib566.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib567.c b/tests/libtest/lib567.c
index 7a730d26a..f6af06191 100644
--- a/tests/libtest/lib567.c
+++ b/tests/libtest/lib567.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib568.c b/tests/libtest/lib568.c
index c1388f16f..128e6d2eb 100644
--- a/tests/libtest/lib568.c
+++ b/tests/libtest/lib568.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib570.c b/tests/libtest/lib570.c
index d88f100f3..016ed1098 100644
--- a/tests/libtest/lib570.c
+++ b/tests/libtest/lib570.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib572.c b/tests/libtest/lib572.c
index 82d5049d0..0352fdb7f 100644
--- a/tests/libtest/lib572.c
+++ b/tests/libtest/lib572.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib573.c b/tests/libtest/lib573.c
index e80824d16..f512e2d3c 100644
--- a/tests/libtest/lib573.c
+++ b/tests/libtest/lib573.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib579.c b/tests/libtest/lib579.c
index 4977a03cb..64ef16021 100644
--- a/tests/libtest/lib579.c
+++ b/tests/libtest/lib579.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib582.c b/tests/libtest/lib582.c
index 2f9242a85..c0678b0e5 100644
--- a/tests/libtest/lib582.c
+++ b/tests/libtest/lib582.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib583.c b/tests/libtest/lib583.c
index f0a088b70..86dd8b55a 100644
--- a/tests/libtest/lib583.c
+++ b/tests/libtest/lib583.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib586.c b/tests/libtest/lib586.c
index 247422483..3b77ef7eb 100644
--- a/tests/libtest/lib586.c
+++ b/tests/libtest/lib586.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib590.c b/tests/libtest/lib590.c
index db433fb9e..ca54e3070 100644
--- a/tests/libtest/lib590.c
+++ b/tests/libtest/lib590.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib591.c b/tests/libtest/lib591.c
index 0a406cee0..9c5edd89c 100644
--- a/tests/libtest/lib591.c
+++ b/tests/libtest/lib591.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib598.c b/tests/libtest/lib598.c
index bd544701e..002f041ec 100644
--- a/tests/libtest/lib598.c
+++ b/tests/libtest/lib598.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/lib670.c b/tests/libtest/lib670.c
index 2e6040714..aecb1c01f 100644
--- a/tests/libtest/lib670.c
+++ b/tests/libtest/lib670.c
@@ -210,7 +210,7 @@ int test(char *URL)
     mres = curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcept, &maxfd);
     if(mres)
       break;
-#ifdef _WIN32
+#if defined(WIN32) || defined(_WIN32)
     if(maxfd == -1)
       Sleep(100);
     else
diff --git a/tests/libtest/notexists.pl b/tests/libtest/notexists.pl
index 31b9851ec..ed081414c 100755
--- a/tests/libtest/notexists.pl
+++ b/tests/libtest/notexists.pl
@@ -1,4 +1,25 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Check that given arguments do not exist on filesystem.
 my $code = 0;
 if ($#ARGV < 0) {
diff --git a/tests/libtest/sethostname.c b/tests/libtest/sethostname.c
index 210a60018..6929793dc 100644
--- a/tests/libtest/sethostname.c
+++ b/tests/libtest/sethostname.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/sethostname.h b/tests/libtest/sethostname.h
index 7a590428b..64624e846 100644
--- a/tests/libtest/sethostname.h
+++ b/tests/libtest/sethostname.h
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/stub_gssapi.h b/tests/libtest/stub_gssapi.h
index 95726d794..aab3449b1 100644
--- a/tests/libtest/stub_gssapi.h
+++ b/tests/libtest/stub_gssapi.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2017 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/test.h b/tests/libtest/test.h
index ff143c985..8aba00f46 100644
--- a/tests/libtest/test.h
+++ b/tests/libtest/test.h
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -36,6 +36,8 @@
 #ifdef HAVE_SYS_SELECT_H
 /* since so many tests use select(), we can just as well include it here */
 #include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#include <unistd.h>
 #endif
 
 #ifdef TPF
@@ -44,11 +46,13 @@
 
 #include "curl_printf.h"
 
-#define test_setopt(A,B,C) \
-  if((res = curl_easy_setopt((A), (B), (C))) != CURLE_OK) goto test_cleanup
+#define test_setopt(A,B,C)                                      \
+  if((res = curl_easy_setopt((A), (B), (C))) != CURLE_OK)       \
+    goto test_cleanup
 
-#define test_multi_setopt(A,B,C) \
-  if((res = curl_multi_setopt((A), (B), (C))) != CURLE_OK) goto test_cleanup
+#define test_multi_setopt(A,B,C)                                \
+  if((res = curl_multi_setopt((A), (B), (C))) != CURLE_OK)      \
+    goto test_cleanup
 
 extern char *libtest_arg2; /* set by first.c to the argv[2] or NULL */
 extern char *libtest_arg3; /* set by first.c to the argv[3] or NULL */
diff --git a/tests/libtest/test1013.pl b/tests/libtest/test1013.pl
index b680273d5..70c74c04b 100755
--- a/tests/libtest/test1013.pl
+++ b/tests/libtest/test1013.pl
@@ -1,4 +1,25 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Determine if curl-config --protocols/--features matches the
 # curl --version protocols/features
 if ( $#ARGV != 2 )
diff --git a/tests/libtest/test1022.pl b/tests/libtest/test1022.pl
index 76a11cfe7..86b956bb4 100755
--- a/tests/libtest/test1022.pl
+++ b/tests/libtest/test1022.pl
@@ -1,4 +1,25 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Determine if curl-config --version matches the curl --version
 if ( $#ARGV != 2 )
 {
diff --git a/tests/libtest/test307.pl b/tests/libtest/test307.pl
index 469af3c21..c7e989f0c 100755
--- a/tests/libtest/test307.pl
+++ b/tests/libtest/test307.pl
@@ -1,4 +1,25 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Determine if the given curl executable supports the 'openssl' SSL engine
 if ( $#ARGV != 0 )
 {
diff --git a/tests/libtest/test610.pl b/tests/libtest/test610.pl
index a900d94b4..c3df29bb7 100755
--- a/tests/libtest/test610.pl
+++ b/tests/libtest/test610.pl
@@ -1,4 +1,25 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Perform simple file and directory manipulation in a portable way
 if ( $#ARGV <= 0 )
 {
diff --git a/tests/libtest/test613.pl b/tests/libtest/test613.pl
index 03d09cb5b..ead1159ff 100755
--- a/tests/libtest/test613.pl
+++ b/tests/libtest/test613.pl
@@ -1,4 +1,25 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Prepare a directory with known files and clean up afterwards
 use Time::Local;
 
diff --git a/tests/libtest/test75.pl b/tests/libtest/test75.pl
index 31cdfb8cc..2182f5304 100755
--- a/tests/libtest/test75.pl
+++ b/tests/libtest/test75.pl
@@ -1,4 +1,25 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # Check that the length of a given URL is correct
 if ( $#ARGV != 1 )
 {
diff --git a/tests/libtest/testtrace.h b/tests/libtest/testtrace.h
index a09ce348f..54df28b1c 100644
--- a/tests/libtest/testtrace.h
+++ b/tests/libtest/testtrace.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/testutil.c b/tests/libtest/testutil.c
index 78b1a2b65..b33a2f4be 100644
--- a/tests/libtest/testutil.c
+++ b/tests/libtest/testutil.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/libtest/testutil.h b/tests/libtest/testutil.h
index 6c063ea57..ccf84dff2 100644
--- a/tests/libtest/testutil.h
+++ b/tests/libtest/testutil.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/mem-include-scan.pl b/tests/mem-include-scan.pl
index 8922bd4a3..4667f0450 100755
--- a/tests/mem-include-scan.pl
+++ b/tests/mem-include-scan.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2010-2012, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2010 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/negtelnetserver.py.in b/tests/negtelnetserver.py.in
index 1d9459926..fbe3a5f63 100755
--- a/tests/negtelnetserver.py.in
+++ b/tests/negtelnetserver.py.in
@@ -1,6 +1,24 @@
 #!AWKPYTHON
 # -*- coding: utf-8 -*-
 #
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2017 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
 """ A telnet server which negotiates"""
 
 from __future__ import (absolute_import, division, print_function,
@@ -9,11 +27,10 @@ import argparse
 import os
 import sys
 import logging
-try:  # Python 2
-    import SocketServer as socketserver
-except ImportError:  # Python 3
+if sys.version_info.major >= 3:
     import socketserver
-
+else:
+    import SocketServer as socketserver
 
 log = logging.getLogger(__name__)
 HOST = "localhost"
@@ -32,6 +49,9 @@ def telnetserver(options):
     """
     if options.pidfile:
         pid = os.getpid()
+        # see tests/server/util.c function write_pidfile
+        if os.name == "nt":
+            pid += 65536
         with open(options.pidfile, "w") as f:
             f.write(str(pid))
 
@@ -67,13 +87,17 @@ class 
NegotiatingTelnetHandler(socketserver.BaseRequestHandler):
             data = neg.recv(1024)
             log.debug("Incoming data: %r", data)
 
-            if VERIFIED_REQ.encode('ascii') in data:
+            if VERIFIED_REQ.encode('utf-8') in data:
                 log.debug("Received verification request from test framework")
-                response = VERIFIED_RSP.format(pid=os.getpid())
-                response_data = response.encode('ascii')
+                pid = os.getpid()
+                # see tests/server/util.c function write_pidfile
+                if os.name == "nt":
+                    pid += 65536
+                response = VERIFIED_RSP.format(pid=pid)
+                response_data = response.encode('utf-8')
             else:
                 log.debug("Received normal request - echoing back")
-                response_data = data.strip()
+                response_data = data.decode('utf-8').strip().encode('utf-8')
 
             if response_data:
                 log.debug("Sending %r", response_data)
diff --git a/tests/nroff-scan.pl b/tests/nroff-scan.pl
index c868dd622..a07d748ad 100755
--- a/tests/nroff-scan.pl
+++ b/tests/nroff-scan.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2016, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2016 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/objnames.inc b/tests/objnames.inc
index e362f6e8e..158f80150 100644
--- a/tests/objnames.inc
+++ b/tests/objnames.inc
@@ -5,7 +5,7 @@
 # *                            | (__| |_| |  _ <| |___
 # *                             \___|\___/|_| \_\_____|
 # *
-# * Copyright (C) 2012 - 2017, Daniel Stenberg, <address@hidden>, et al.
+# * Copyright (C) 2012 - 2020, Daniel Stenberg, <address@hidden>, et al.
 # *
 # * This software is licensed as described in the file COPYING, which
 # * you should have received as part of this distribution. The terms
diff --git a/tests/pathhelp.pm b/tests/pathhelp.pm
index 3a413b22e..f495306f6 100644
--- a/tests/pathhelp.pm
+++ b/tests/pathhelp.pm
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2016, Evgeny Grin (Karlson2k), <address@hidden>.
+# Copyright (C) 2016 - 2020, Evgeny Grin (Karlson2k), <address@hidden>.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/python_dependencies/impacket/LICENSE 
b/tests/python_dependencies/impacket/LICENSE
deleted file mode 100644
index f01250bd9..000000000
--- a/tests/python_dependencies/impacket/LICENSE
+++ /dev/null
@@ -1,84 +0,0 @@
-Licencing
----------
-
-We provide this software under a slightly modified version of the
-Apache Software License. The only changes to the document were the
-replacement of "Apache" with "Impacket" and "Apache Software Foundation"
-with "SecureAuth Corporation". Feel free to compare the resulting
-document to the official Apache license.
-
-The `Apache Software License' is an Open Source Initiative Approved
-License.
-
-
-The Apache Software License, Version 1.1
-Modifications by SecureAuth Corporation (see above)
-
-Copyright (c) 2000 The Apache Software Foundation.  All rights
-reserved.
-
-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. The end-user documentation included with the redistribution,
-   if any, must include the following acknowledgment:
-      "This product includes software developed by
-       SecureAuth Corporation (https://www.secureauth.com/)."
-   Alternately, this acknowledgment may appear in the software itself,
-   if and wherever such third-party acknowledgments normally appear.
-
-4. The names "Impacket", "SecureAuth Corporation" and "CORE Security 
Technologies" must
-   not be used to endorse or promote products derived from this
-   software without prior written permission. For written
-   permission, please contact address@hidden.
-
-5. Products derived from this software may not be called "Impacket",
-   nor may "Impacket" appear in their name, without prior written
-   permission of SecureAuth Corporation.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
-ITS 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.
-
-
-
-Smb.py and nmb.py are based on Pysmb by Michael Teo
-(https://miketeo.net/projects/pysmb/), and are distributed under the
-following license:
-
-This software is provided 'as-is', without any express or implied
-warranty.  In no event will the author be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must
-   not claim that you wrote the original software. If you use this
-   software in a product, an acknowledgment in the product
-   documentation would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and must
-   not be misrepresented as being the original software.
-
-3. This notice cannot be removed or altered from any source
-   distribution.
diff --git a/tests/python_dependencies/impacket/__init__.py 
b/tests/python_dependencies/impacket/__init__.py
deleted file mode 100644
index 92a5d6bb4..000000000
--- a/tests/python_dependencies/impacket/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (c) 2003-2016 CORE Security Technologies
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-# Author: Alberto Solino (@agsolino)
-#
-
-# Set default logging handler to avoid "No handler found" warnings.
-import logging
-try:  # Python 2.7+
-    from logging import NullHandler
-except ImportError:
-    class NullHandler(logging.Handler):
-        def emit(self, record):
-            pass
-
-# All modules inside this library MUST use this logger (impacket)
-# It is up to the library consumer to do whatever is wanted 
-# with the logger output. By default it is forwarded to the 
-# upstream logger
-
-LOG = logging.getLogger(__name__)
-LOG.addHandler(NullHandler())
diff --git a/tests/python_dependencies/impacket/nmb.py 
b/tests/python_dependencies/impacket/nmb.py
deleted file mode 100644
index 791377bc2..000000000
--- a/tests/python_dependencies/impacket/nmb.py
+++ /dev/null
@@ -1,982 +0,0 @@
-from __future__ import print_function
-from __future__ import absolute_import
-# Copyright (c) 2003-2016 CORE Security Technologies
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-
-
-# -*- mode: python; tab-width: 4 -*-
-#
-# Copyright (C) 2001 Michael Teo <address@hidden>
-# nmb.py - NetBIOS library
-#
-# This software is provided 'as-is', without any express or implied warranty. 
-# In no event will the author be held liable for any damages arising from the 
-# use of this software.
-#
-# Permission is granted to anyone to use this software for any purpose, 
-# including commercial applications, and to alter it and redistribute it 
-# freely, subject to the following restrictions:
-#
-# 1. The origin of this software must not be misrepresented; you must not 
-#    claim that you wrote the original software. If you use this software 
-#    in a product, an acknowledgment in the product documentation would be
-#    appreciated but is not required.
-#
-# 2. Altered source versions must be plainly marked as such, and must not be 
-#    misrepresented as being the original software.
-#
-# 3. This notice cannot be removed or altered from any source distribution.
-#
-# Altered source done by Alberto Solino (@agsolino)
-
-import socket
-import string
-import re
-import select
-import errno
-from random import randint
-from struct import pack, unpack
-import time
-
-from .structure import Structure
-
-CVS_REVISION = '$Revision: 526 $'
-
-# Taken from socket module reference
-INADDR_ANY = '0.0.0.0'
-BROADCAST_ADDR = '<broadcast>'
-
-# Default port for NetBIOS name service
-NETBIOS_NS_PORT = 137
-# Default port for NetBIOS session service
-NETBIOS_SESSION_PORT = 139
-
-# Default port for SMB session service
-SMB_SESSION_PORT = 445
-
-# Owner Node Type Constants
-NODE_B = 0x0000
-NODE_P = 0x2000
-NODE_M = 0x4000
-NODE_RESERVED = 0x6000
-NODE_GROUP = 0x8000
-NODE_UNIQUE = 0x0
-
-# Name Type Constants
-TYPE_UNKNOWN = 0x01
-TYPE_WORKSTATION = 0x00
-TYPE_CLIENT = 0x03
-TYPE_SERVER = 0x20
-TYPE_DOMAIN_MASTER = 0x1B
-TYPE_DOMAIN_CONTROLLER = 0x1C
-TYPE_MASTER_BROWSER = 0x1D
-TYPE_BROWSER = 0x1E
-TYPE_NETDDE  = 0x1F
-TYPE_STATUS = 0x21
-
-# Opcodes values
-OPCODE_QUERY = 0
-OPCODE_REGISTRATION = 0x5
-OPCODE_RELEASE = 0x6
-OPCODE_WACK = 0x7
-OPCODE_REFRESH = 0x8
-OPCODE_REQUEST = 0
-OPCODE_RESPONSE = 0x10
-
-# NM_FLAGS
-NM_FLAGS_BROADCAST = 0x1
-NM_FLAGS_UNICAST = 0
-NM_FLAGS_RA = 0x8
-NM_FLAGS_RD = 0x10
-NM_FLAGS_TC = 0x20
-NM_FLAGS_AA = 0x40
-
-# QUESTION_TYPE
-QUESTION_TYPE_NB = 0x20     # NetBIOS general Name Service Resource Record
-QUESTION_TYPE_NBSTAT = 0x21 # NetBIOS NODE STATUS Resource Record
-# QUESTION_CLASS
-QUESTION_CLASS_IN = 0x1     # Internet class
-
-# RR_TYPE Resource Record Type code
-RR_TYPE_A = 0x1               # IP address Resource Record
-RR_TYPE_NS = 0x2              # Name Server Resource Record
-RR_TYPE_NULL = 0xA          # NULL Resource Record
-RR_TYPE_NB = 0x20           # NetBIOS general Name Service Resource Record
-RR_TYPE_NBSTAT = 0x21       # NetBIOS NODE STATUS Resource Record
-
-# Resource Record Class
-RR_CLASS_IN = 1             # Internet class
-
-# RCODE values
-RCODE_FMT_ERR   = 0x1       # Format Error.  Request was invalidly formatted.
-RCODE_SRV_ERR   = 0x2       # Server failure.  Problem with NBNS, cannot 
process name.
-RCODE_IMP_ERR   = 0x4       # Unsupported request error.  Allowable only for 
challenging NBNS when gets an Update type
-                            # registration request.
-RCODE_RFS_ERR   = 0x5       # Refused error.  For policy reasons server will 
not register this name from this host.
-RCODE_ACT_ERR   = 0x6       # Active error.  Name is owned by another node.
-RCODE_CFT_ERR   = 0x7       # Name in conflict error.  A UNIQUE name is owned 
by more than one node.
-
-# NAME_FLAGS
-NAME_FLAGS_PRM = 0x0200       # Permanent Name Flag.  If one (1) then entry is 
for the permanent node name.  Flag is zero
-                            # (0) for all other names.
-NAME_FLAGS_ACT = 0x0400       # Active Name Flag.  All entries have this flag 
set to one (1).
-NAME_FLAG_CNF  = 0x0800       # Conflict Flag.  If one (1) then name on this 
node is in conflict.
-NAME_FLAG_DRG  = 0x1000       # Deregister Flag.  If one (1) then this name is 
in the process of being deleted.
-
-NAME_TYPES = { TYPE_UNKNOWN: 'Unknown', TYPE_WORKSTATION: 'Workstation', 
TYPE_CLIENT: 'Client',
-               TYPE_SERVER: 'Server', TYPE_MASTER_BROWSER: 'Master Browser', 
TYPE_BROWSER: 'Browser Server',
-               TYPE_DOMAIN_MASTER: 'Domain Master' , TYPE_NETDDE: 'NetDDE 
Server'}
-# NetBIOS Session Types
-NETBIOS_SESSION_MESSAGE = 0x0
-NETBIOS_SESSION_REQUEST = 0x81
-NETBIOS_SESSION_POSITIVE_RESPONSE = 0x82
-NETBIOS_SESSION_NEGATIVE_RESPONSE = 0x83
-NETBIOS_SESSION_RETARGET_RESPONSE = 0x84
-NETBIOS_SESSION_KEEP_ALIVE = 0x85
-
-
-def strerror(errclass, errcode):
-    if errclass == ERRCLASS_OS:
-        return 'OS Error', str(errcode)
-    elif errclass == ERRCLASS_QUERY:
-        return 'Query Error', QUERY_ERRORS.get(errcode, 'Unknown error')
-    elif errclass == ERRCLASS_SESSION:
-        return 'Session Error', SESSION_ERRORS.get(errcode, 'Unknown error')
-    else:
-        return 'Unknown Error Class', 'Unknown Error'
-    
-    
-
-class NetBIOSError(Exception): pass
-class NetBIOSTimeout(Exception):
-    def __init__(self, message = 'The NETBIOS connection with the remote host 
timed out.'):
-        Exception.__init__(self, message)
-
-class NBResourceRecord:
-    def __init__(self, data = 0):
-        self._data = data
-        try:
-            if self._data:
-                self.rr_name = (re.split('\x00',data))[0]
-                offset = len(self.rr_name)+1
-                self.rr_type  = unpack('>H', self._data[offset:offset+2])[0]
-                self.rr_class = unpack('>H', self._data[offset+2: offset+4])[0]
-                self.ttl = unpack('>L',self._data[offset+4:offset+8])[0]
-                self.rdlength = unpack('>H', self._data[offset+8:offset+10])[0]
-                self.rdata = self._data[offset+10:offset+10+self.rdlength]
-                offset = self.rdlength - 2
-                self.unit_id = data[offset:offset+6]
-            else:
-                self.rr_name = ''
-                self.rr_type = 0
-                self.rr_class = 0
-                self.ttl = 0
-                self.rdlength = 0
-                self.rdata = ''
-                self.unit_id = ''
-        except Exception:
-                raise NetBIOSError( 'Wrong packet format ' )
-
-    def set_rr_name(self, name):
-        self.rr_name = name
-    def set_rr_type(self, name):
-        self.rr_type = name
-    def set_rr_class(self,cl):
-        self.rr_class = cl
-    def set_ttl(self,ttl):
-        self.ttl = ttl
-    def set_rdata(self,rdata):
-        self.rdata = rdata
-        self.rdlength = len(rdata)
-    def get_unit_id(self):
-        return self.unit_id
-    def get_rr_name(self):
-        return self.rr_name
-    def get_rr_class(self):
-        return self.rr_class
-    def get_ttl(self):
-        return self.ttl
-    def get_rdlength(self):
-        return self.rdlength
-    def get_rdata(self):
-        return self.rdata
-    def rawData(self):
-        return self.rr_name + pack('!HHLH',self.rr_type, self.rr_class, 
self.ttl, self.rdlength) + self.rdata
-
-class NBNodeStatusResponse(NBResourceRecord):
-    def __init__(self, data = 0):
-        NBResourceRecord.__init__(self,data)
-        self.num_names = 0
-        self.node_names = [ ]
-        self.statstics = ''
-        self.mac = '00-00-00-00-00-00'
-        try:
-            if data:
-                self._data = self.get_rdata()
-                self.num_names = unpack('>B',self._data[:1])[0]
-                offset = 1
-                for i in range(0, self.num_names):
-                    name = self._data[offset:offset + 15]
-                    type,flags = unpack('>BH', self._data[offset + 15: offset 
+ 18])
-                    offset += 18
-                    self.node_names.append(NBNodeEntry(name, type ,flags))
-                self.set_mac_in_hexa(self.get_unit_id())
-        except Exception:
-            raise NetBIOSError( 'Wrong packet format ' )
-
-    def set_mac_in_hexa(self, data):
-        data_aux = ''
-        for d in data:
-            if data_aux == '':
-                data_aux = '%02x' % ord(d)
-            else:
-                data_aux += '-%02x' % ord(d)
-        self.mac = string.upper(data_aux)
-
-    def get_num_names(self):
-        return self.num_names
-    def get_mac(self):
-        return self.mac
-    def set_num_names(self, num):
-        self.num_names = num
-    def get_node_names(self):
-        return self.node_names
-    def add_node_name(self,node_names):
-        self.node_names.append(node_names)
-        self.num_names += 1
-    def rawData(self):
-        res = pack('!B', self.num_names )
-        for i in range(0, self.num_names):
-            res += self.node_names[i].rawData()
-
-class NBPositiveNameQueryResponse(NBResourceRecord):
-    def __init__(self, data = 0):
-        NBResourceRecord.__init__(self, data)
-        self.addr_entries = [ ]
-        if data:
-                self._data = self.get_rdata()
-                _qn_length, qn_name, qn_scope = decode_name(data)
-                self._netbios_name = string.rstrip(qn_name[:-1]) + qn_scope
-                self._name_type = ord(qn_name[-1])
-                self._nb_flags = unpack('!H', self._data[:2])
-                offset = 2
-                while offset<len(self._data):
-                    self.addr_entries.append('%d.%d.%d.%d' % unpack('4B', 
(self._data[offset:offset+4])))
-                    offset += 4
-    
-    def get_netbios_name(self):
-        return self._netbios_name
-    
-    def get_name_type(self):
-        return self._name_type
-    
-    def get_addr_entries(self):
-        return self.addr_entries
-                
-class NetBIOSPacket:
-    """ This is a packet as defined in RFC 1002 """
-    def __init__(self, data = 0):
-        self.name_trn_id = 0x0  # Transaction ID for Name Service Transaction.
-                                #   Requestor places a unique value for each 
active
-                                #   transaction.  Responder puts NAME_TRN_ID 
value
-                                #   from request packet in response packet.
-        self.opcode = 0         # Packet type code
-        self.nm_flags = 0       # Flags for operation
-        self.rcode = 0          # Result codes of request.
-        self.qdcount = 0        # Unsigned 16 bit integer specifying the 
number of entries in the question section of a Name
-        self.ancount = 0        # Unsigned 16 bit integer specifying the 
number of
-                                # resource records in the answer section of a 
Name
-                                # Service packet.
-        self.nscount = 0        # Unsigned 16 bit integer specifying the 
number of
-                                # resource records in the authority section of 
a
-                                # Name Service packet.
-        self.arcount = 0        # Unsigned 16 bit integer specifying the 
number of
-                                # resource records in the additional records
-                                # section of a Name Service packeT.
-        self.questions = ''
-        self.answers = ''
-        if data == 0:
-            self._data = ''
-        else:
-            try:
-                self._data = data
-                self.opcode = ord(data[2]) >> 3 
-                self.nm_flags = ((ord(data[2]) & 0x3) << 4) | ((ord(data[3]) & 
0xf0) >> 4)
-                self.name_trn_id = unpack('>H', self._data[:2])[0]
-                self.rcode = ord(data[3]) & 0x0f
-                self.qdcount = unpack('>H', self._data[4:6])[0]
-                self.ancount = unpack('>H', self._data[6:8])[0]
-                self.nscount = unpack('>H', self._data[8:10])[0]
-                self.arcount = unpack('>H', self._data[10:12])[0]
-                self.answers = self._data[12:]
-            except Exception:
-                raise NetBIOSError( 'Wrong packet format ' )
-            
-    def set_opcode(self, opcode):
-        self.opcode = opcode
-    def set_trn_id(self, trn):
-        self.name_trn_id = trn
-    def set_nm_flags(self, nm_flags):
-        self.nm_flags = nm_flags
-    def set_rcode(self, rcode):
-        self.rcode = rcode
-    def addQuestion(self, question, qtype, qclass):
-        self.qdcount += 1
-        self.questions += question + pack('!HH',qtype,qclass)
-    def get_trn_id(self):
-        return self.name_trn_id
-    def get_rcode(self):
-        return self.rcode
-    def get_nm_flags(self):
-        return self.nm_flags
-    def get_opcode(self):
-        return self.opcode
-    def get_qdcount(self):
-        return self.qdcount
-    def get_ancount(self):
-        return self.ancount
-    def get_nscount(self):
-        return self.nscount
-    def get_arcount(self):
-        return self.arcount
-    def rawData(self):
-        secondWord = self.opcode << 11
-        secondWord |= self.nm_flags << 4
-        secondWord |= self.rcode
-        data = pack('!HHHHHH', self.name_trn_id, secondWord , self.qdcount, 
self.ancount, self.nscount, self.arcount) + self.questions + self.answers
-        return data
-    def get_answers(self):
-        return self.answers
-
-class NBHostEntry:
-
-    def __init__(self, nbname, nametype, ip):
-        self.__nbname = nbname
-        self.__nametype = nametype
-        self.__ip = ip
-
-    def get_nbname(self):
-        return self.__nbname
-
-    def get_nametype(self):
-        return self.__nametype
-
-    def get_ip(self):
-        return self.__ip
-
-    def __repr__(self):
-        return '<NBHostEntry instance: NBname="' + self.__nbname + '", IP="' + 
self.__ip + '">'
-
-class NBNodeEntry:
-    
-    def __init__(self, nbname, nametype, flags): 
-        self.__nbname = string.ljust(nbname,17)
-        self.__nametype = nametype
-        self.__flags = flags
-        self.__isgroup = flags & 0x8000
-        self.__nodetype = flags & 0x6000
-        self.__deleting = flags & 0x1000
-        self.__isconflict = flags & 0x0800
-        self.__isactive = flags & 0x0400
-        self.__ispermanent = flags & 0x0200
-
-    def get_nbname(self):
-        return self.__nbname
-
-    def get_nametype(self):
-        return self.__nametype
-
-    def is_group(self):
-        return self.__isgroup
-
-    def get_nodetype(self):
-        return self.__nodetype
-
-    def is_deleting(self):
-        return self.__deleting
-
-    def is_conflict(self):
-        return self.__isconflict
-
-    def is_active(self):
-        return self.__isactive
-
-    def is_permanent(self):
-        return self.__ispermanent
-
-    def set_nbname(self, name):
-        self.__nbname = string.ljust(name,17)
-
-    def set_nametype(self, type):
-        self.__nametype = type
-
-    def set_flags(self,flags):
-        self.__flags = flags
-        
-    def __repr__(self):
-        s = '<NBNodeEntry instance: NBname="' + self.__nbname + '" NameType="' 
+ NAME_TYPES[self.__nametype] + '"'
-        if self.__isactive:
-            s += ' ACTIVE'
-        if self.__isgroup:
-            s += ' GROUP'
-        if self.__isconflict:
-            s += ' CONFLICT'
-        if self.__deleting:
-            s += ' DELETING'
-        return s
-    def rawData(self):
-        return self.__nbname + pack('!BH',self.__nametype, self.__flags)
-
-
-class NetBIOS:
-
-    # Creates a NetBIOS instance without specifying any default NetBIOS domain 
nameserver.
-    # All queries will be sent through the servport.
-    def __init__(self, servport = NETBIOS_NS_PORT):
-        self.__servport = NETBIOS_NS_PORT
-        self.__nameserver = None
-        self.__broadcastaddr = BROADCAST_ADDR
-        self.mac = '00-00-00-00-00-00'
-
-    def _setup_connection(self, dstaddr):
-        port = randint(10000, 60000)
-        af, socktype, proto, _canonname, _sa = socket.getaddrinfo(dstaddr, 
port, socket.AF_INET, socket.SOCK_DGRAM)[0]
-        s = socket.socket(af, socktype, proto)
-        has_bind = 1
-        for _i in range(0, 10):
-        # We try to bind to a port for 10 tries
-            try:
-                s.bind(( INADDR_ANY, randint(10000, 60000) ))
-                s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
-                has_bind = 1
-            except socket.error:
-                pass
-        if not has_bind:
-            raise NetBIOSError( 'Cannot bind to a good UDP port', ERRCLASS_OS, 
errno.EAGAIN)
-        self.__sock = s
-
-    # Set the default NetBIOS domain nameserver.
-    def set_nameserver(self, nameserver):
-        self.__nameserver = nameserver
-
-    # Return the default NetBIOS domain nameserver, or None if none is 
specified.
-    def get_nameserver(self):
-        return self.__nameserver
-
-    # Set the broadcast address to be used for query.
-    def set_broadcastaddr(self, broadcastaddr):
-        self.__broadcastaddr = broadcastaddr
-
-    # Return the broadcast address to be used, or BROADCAST_ADDR if default 
broadcast address is used.   
-    def get_broadcastaddr(self):
-        return self.__broadcastaddr
-
-    # Returns a NBPositiveNameQueryResponse instance containing the host 
information for nbname.
-    # If a NetBIOS domain nameserver has been specified, it will be used for 
the query.
-    # Otherwise, the query is broadcasted on the broadcast address.
-    def gethostbyname(self, nbname, qtype = TYPE_WORKSTATION, scope = None, 
timeout = 1):
-        return self.__queryname(nbname, self.__nameserver, qtype, scope, 
timeout)
-
-    # Returns a list of NBNodeEntry instances containing node status 
information for nbname.
-    # If destaddr contains an IP address, then this will become an unicast 
query on the destaddr.
-    # Raises NetBIOSTimeout if timeout (in secs) is reached.
-    # Raises NetBIOSError for other errors
-    def getnodestatus(self, nbname, destaddr = None, type = TYPE_WORKSTATION, 
scope = None, timeout = 1):
-        if destaddr:
-            return self.__querynodestatus(nbname, destaddr, type, scope, 
timeout)
-        else:
-            return self.__querynodestatus(nbname, self.__nameserver, type, 
scope, timeout)
-
-    def getnetbiosname(self, ip):
-        entries = self.getnodestatus('*',ip)
-        entries = filter(lambda x:x.get_nametype() == TYPE_SERVER, entries)
-        return entries[0].get_nbname().strip()
-
-    def getmacaddress(self):
-        return self.mac
-
-    def __queryname(self, nbname, destaddr, qtype, scope, timeout, retries = 
0):
-        self._setup_connection(destaddr)
-        trn_id = randint(1, 32000)
-        p = NetBIOSPacket()
-        p.set_trn_id(trn_id)
-        netbios_name = nbname.upper()
-        qn_label = encode_name(netbios_name, qtype, scope)
-        p.addQuestion(qn_label, QUESTION_TYPE_NB, QUESTION_CLASS_IN)
-        p.set_nm_flags(NM_FLAGS_RD)
-        if not destaddr:
-            p.set_nm_flags(p.get_nm_flags() | NM_FLAGS_BROADCAST)
-            destaddr = self.__broadcastaddr            
-        req = p.rawData()
-        
-        tries = retries
-        while 1:
-            self.__sock.sendto(req, ( destaddr, self.__servport ))
-            try:
-                ready, _, _ = select.select([ self.__sock.fileno() ], [ ] , [ 
], timeout)
-                if not ready:
-                    if tries:
-                        # Retry again until tries == 0
-                        tries -= 1
-                    else:
-                        raise NetBIOSTimeout
-                else:
-                    data, _ = self.__sock.recvfrom(65536, 0)
-                    
-                    res = NetBIOSPacket(data)
-                    if res.get_trn_id() == p.get_trn_id():
-                        if res.get_rcode():
-                            if res.get_rcode() == 0x03:
-                                return None
-                            else:
-                                raise NetBIOSError( 'Negative name query 
response', ERRCLASS_QUERY, res.get_rcode())
-                        
-                        if res.get_ancount() != 1:
-                            raise NetBIOSError( 'Malformed response')
-                        
-                        return NBPositiveNameQueryResponse(res.get_answers())
-            except select.error as ex:
-                if ex[0] != errno.EINTR and ex[0] != errno.EAGAIN:
-                    raise NetBIOSError( 'Error occurs while waiting for 
response', ERRCLASS_OS, ex[0])
-                raise
-
-
-    def __querynodestatus(self, nbname, destaddr, type, scope, timeout):
-        self._setup_connection(destaddr)
-        trn_id = randint(1, 32000)
-        p = NetBIOSPacket()
-        p.set_trn_id(trn_id)
-        netbios_name = string.upper(nbname)
-        qn_label = encode_name(netbios_name, type, scope)
-        p.addQuestion(qn_label, QUESTION_TYPE_NBSTAT, QUESTION_CLASS_IN)
-
-        if not destaddr:
-            p.set_nm_flags(NM_FLAGS_BROADCAST)
-            destaddr = self.__broadcastaddr            
-        req = p.rawData()
-        tries = 3
-        while 1:
-            try:
-                self.__sock.sendto(req, 0, ( destaddr, self.__servport ))
-                ready, _, _ = select.select([ self.__sock.fileno() ], [ ] , [ 
], timeout)
-                if not ready:
-                    if tries:
-                        # Retry again until tries == 0
-                        tries -= 1
-                    else:
-                        raise NetBIOSTimeout
-                else:
-                    try:
-                        data, _ = self.__sock.recvfrom(65536, 0)
-                    except Exception as e:
-                        raise NetBIOSError("recvfrom error: %s" % str(e))
-                    self.__sock.close()
-                    res = NetBIOSPacket(data)
-                    if res.get_trn_id() == p.get_trn_id():
-                        if res.get_rcode():
-                            if res.get_rcode() == 0x03:
-                                # I'm just guessing here
-                                raise NetBIOSError("Cannot get data from 
server")
-                            else:
-                                raise NetBIOSError( 'Negative name query 
response', ERRCLASS_QUERY, res.get_rcode())
-                        answ = NBNodeStatusResponse(res.get_answers())
-                        self.mac = answ.get_mac()
-                        return answ.get_node_names()
-            except select.error as ex:
-                if ex[0] != errno.EINTR and ex[0] != errno.EAGAIN:
-                    raise NetBIOSError( 'Error occurs while waiting for 
response', ERRCLASS_OS, ex[0])
-            except socket.error as ex:
-                raise NetBIOSError('Connection error: %s' % str(ex))
-
-# Perform first and second level encoding of name as specified in RFC 1001 
(Section 4)
-def encode_name(name, type, scope):
-    if name == '*':
-        name += '\0' * 15
-    elif len(name) > 15:
-        name = name[:15] + chr(type)
-    else:
-        name = string.ljust(name, 15) + chr(type)
-        
-    encoded_name = chr(len(name) * 2) + re.sub('.', _do_first_level_encoding, 
name)
-    if scope:
-        encoded_scope = ''
-        for s in string.split(scope, '.'):
-            encoded_scope = encoded_scope + chr(len(s)) + s
-        return encoded_name + encoded_scope + '\0'
-    else:
-        return encoded_name + '\0'
-
-# Internal method for use in encode_name()
-def _do_first_level_encoding(m):
-    s = ord(m.group(0))
-    return string.uppercase[s >> 4] + string.uppercase[s & 0x0f]
-
-def decode_name(name):
-    name_length = ord(name[0])
-    assert name_length == 32
-
-    decoded_name = re.sub('..', _do_first_level_decoding, name[1:33])
-    if name[33] == '\0':
-        return 34, decoded_name, ''
-    else:
-        decoded_domain = ''
-        offset = 34
-        while 1:
-            domain_length = ord(name[offset])
-            if domain_length == 0:
-                break
-            decoded_domain = '.' + name[offset:offset + domain_length]
-            offset += domain_length
-        return offset + 1, decoded_name, decoded_domain
-
-def _do_first_level_decoding(m):
-    s = m.group(0)
-    return chr(((ord(s[0]) - ord('A')) << 4) | (ord(s[1]) - ord('A')))
-
-
-
-class NetBIOSSessionPacket:
-    def __init__(self, data = 0):
-        self.type = 0x0 
-        self.flags = 0x0
-        self.length = 0x0
-        if data == 0:
-            self._trailer = ''
-        else:
-            try:
-                self.type = ord(data[0])
-                if self.type == NETBIOS_SESSION_MESSAGE:
-                    self.length = ord(data[1]) << 16 | (unpack('!H', 
data[2:4])[0])
-                else:
-                    self.flags = ord(data[1])
-                    self.length = unpack('!H', data[2:4])[0]
-
-                self._trailer = data[4:]
-            except:
-                raise NetBIOSError( 'Wrong packet format ' )
-
-    def set_type(self, type):
-        self.type = type
-    def get_type(self):
-        return self.type
-    def rawData(self):
-        if self.type == NETBIOS_SESSION_MESSAGE:
-            data = pack('!BBH',self.type,self.length >> 16,self.length & 
0xFFFF) + self._trailer
-        else:
-            data = pack('!BBH',self.type,self.flags,self.length) + 
self._trailer
-        return data
-    def set_trailer(self,data):
-        self._trailer = data
-        self.length = len(data)
-    def get_length(self):
-        return self.length
-    def get_trailer(self):
-        return self._trailer
-        
-class NetBIOSSession:
-    def __init__(self, myname, remote_name, remote_host, remote_type = 
TYPE_SERVER, sess_port = NETBIOS_SESSION_PORT, timeout = None, local_type = 
TYPE_WORKSTATION, sock = None):
-        if len(myname) > 15:
-            self.__myname = string.upper(myname[:15])
-        else:
-            self.__myname = string.upper(myname)
-        self.__local_type = local_type
-
-        assert remote_name
-        # if destination port SMB_SESSION_PORT and remote name *SMBSERVER, 
we're changing it to its IP address
-        # helping solving the client mistake ;)
-        if remote_name == '*SMBSERVER' and sess_port == SMB_SESSION_PORT:
-            remote_name = remote_host 
-        # If remote name is *SMBSERVER let's try to query its name.. if can't 
be guessed, continue and hope for the best
-        if remote_name == '*SMBSERVER':
-            nb = NetBIOS()
-            
-            try:
-                res = nb.getnetbiosname(remote_host)
-            except:
-                res = None
-                pass 
-            
-            if res is not None:
-                remote_name = res
-
-        if len(remote_name) > 15:
-            self.__remote_name = string.upper(remote_name[:15])
-        else:
-            self.__remote_name = string.upper(remote_name)
-        self.__remote_type = remote_type
-
-        self.__remote_host = remote_host
-
-        if sock is not None:
-            # We are acting as a server
-            self._sock = sock
-        else:
-            self._sock = self._setup_connection((remote_host, sess_port))
-
-        if sess_port == NETBIOS_SESSION_PORT:
-            self._request_session(remote_type, local_type, timeout)
-
-    def get_myname(self):
-        return self.__myname
-
-    def get_mytype(self):
-        return self.__local_type
-
-    def get_remote_host(self):
-        return self.__remote_host
-
-    def get_remote_name(self):
-        return self.__remote_name
-
-    def get_remote_type(self):
-        return self.__remote_type
-
-    def close(self):
-        self._sock.close()
-
-    def get_socket(self):
-        return self._sock
-
-class NetBIOSUDPSessionPacket(Structure):
-    TYPE_DIRECT_UNIQUE = 16
-    TYPE_DIRECT_GROUP  = 17
-
-    FLAGS_MORE_FRAGMENTS = 1
-    FLAGS_FIRST_FRAGMENT = 2
-    FLAGS_B_NODE         = 0
-
-    structure = (
-        ('Type','B=16'),    # Direct Unique Datagram
-        ('Flags','B=2'),    # FLAGS_FIRST_FRAGMENT
-        ('ID','<H'),
-        ('_SourceIP','>L'),
-        ('SourceIP','"'),
-        ('SourcePort','>H=138'),
-        ('DataLegth','>H-Data'),
-        ('Offset','>H=0'),
-        ('SourceName','z'),
-        ('DestinationName','z'),
-        ('Data',':'),
-    )
-
-    def getData(self):
-        addr = self['SourceIP'].split('.')
-        addr = [int(x) for x in addr]
-        addr = (((addr[0] << 8) + addr[1] << 8) + addr[2] << 8) + addr[3]
-        self['_SourceIP'] = addr
-        return Structure.getData(self)
-
-    def get_trailer(self):
-        return self['Data']
-
-class NetBIOSUDPSession(NetBIOSSession):
-    def _setup_connection(self, peer):
-        af, socktype, proto, canonname, sa = socket.getaddrinfo(peer[0], 
peer[1], 0, socket.SOCK_DGRAM)[0]
-        sock = socket.socket(af, socktype, proto)
-        sock.connect(sa)
-
-        sock = socket.socket(af, socktype, proto)
-        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-        sock.bind((INADDR_ANY, 138))
-        self.peer = peer
-        return sock
-
-    def _request_session(self, remote_type, local_type, timeout = None):
-        pass
-
-    def next_id(self):
-        if hasattr(self, '__dgram_id'):
-            answer = self.__dgram_id
-        else:
-            self.__dgram_id = randint(1,65535)
-            answer = self.__dgram_id
-        self.__dgram_id += 1
-        return answer
-
-    def send_packet(self, data):
-        # Yes... I know...
-        self._sock.connect(self.peer)
-
-        p = NetBIOSUDPSessionPacket()
-        p['ID'] = self.next_id()
-        p['SourceIP'] = self._sock.getsockname()[0]
-        p['SourceName'] = encode_name(self.get_myname(), self.get_mytype(), 
'')[:-1]
-        p['DestinationName'] = encode_name(self.get_remote_name(), 
self.get_remote_type(), '')[:-1]
-        p['Data'] = data
-
-        self._sock.sendto(str(p), self.peer)
-        self._sock.close()
-
-        self._sock = self._setup_connection(self.peer)
-
-    def recv_packet(self, timeout = None):
-        # The next loop is a workaround for a bigger problem:
-        # When data reaches higher layers, the lower headers are lost,
-        # and with them, for example, the source IP. Hence, SMB users
-        # can't know where packets are comming from... we need a better
-        # solution, right now, we will filter everything except packets
-        # coming from the remote_host specified in __init__()
-
-        while 1:
-            data, peer = self._sock.recvfrom(8192)
-#            print "peer: %r  self.peer: %r" % (peer, self.peer)
-            if peer == self.peer: break
-
-        return NetBIOSUDPSessionPacket(data)
-
-class NetBIOSTCPSession(NetBIOSSession):
-    def __init__(self, myname, remote_name, remote_host, remote_type = 
TYPE_SERVER, sess_port = NETBIOS_SESSION_PORT, timeout = None, local_type = 
TYPE_WORKSTATION, sock = None, select_poll = False):
-        self.__select_poll = select_poll
-        if self.__select_poll:
-            self.read_function = self.polling_read
-        else:
-            self.read_function = self.non_polling_read
-        NetBIOSSession.__init__(self, myname, remote_name, remote_host, 
remote_type = remote_type, sess_port = sess_port, timeout = timeout, local_type 
= local_type, sock=sock)                
-
-
-    def _setup_connection(self, peer):
-        try:
-            af, socktype, proto, canonname, sa = socket.getaddrinfo(peer[0], 
peer[1], 0, socket.SOCK_STREAM)[0]
-            sock = socket.socket(af, socktype, proto)
-            sock.connect(sa)
-        except socket.error as e:
-            raise socket.error("Connection error (%s:%s)" % (peer[0], 
peer[1]), e)
-        return sock
-
-    def send_packet(self, data):
-        p = NetBIOSSessionPacket()
-        p.set_type(NETBIOS_SESSION_MESSAGE)
-        p.set_trailer(data)
-        self._sock.send(p.rawData())
-
-    def recv_packet(self, timeout = None):
-        data = self.__read(timeout)
-        return NetBIOSSessionPacket(data)
-
-    def _request_session(self, remote_type, local_type, timeout = None):
-        p = NetBIOSSessionPacket()
-        remote_name = encode_name(self.get_remote_name(), remote_type, '')
-        myname = encode_name(self.get_myname(), local_type, '')
-        p.set_type(NETBIOS_SESSION_REQUEST)
-        p.set_trailer(remote_name + myname)
-
-        self._sock.send(p.rawData())
-        while 1:
-            p = self.recv_packet(timeout)
-            if p.get_type() == NETBIOS_SESSION_NEGATIVE_RESPONSE:
-                raise NetBIOSError( 'Cannot request session', 
ERRCLASS_SESSION, ord(p.get_trailer()[0]))
-            elif p.get_type() == NETBIOS_SESSION_POSITIVE_RESPONSE:
-                break
-            else:
-                # Ignore all other messages, most probably keepalive messages
-                pass
-
-    def polling_read(self, read_length, timeout):
-        data = ''
-        if timeout is None:
-            timeout = 3600
-
-        time_left = timeout
-        CHUNK_TIME = 0.025
-        bytes_left = read_length
-
-        while bytes_left > 0:
-            try:
-                ready, _, _ = select.select([self._sock.fileno() ], [ ], [ ], 
0)
-                
-                if not ready:
-                    if time_left <= 0:
-                        raise NetBIOSTimeout
-                    else:
-                        time.sleep(CHUNK_TIME)
-                        time_left -= CHUNK_TIME
-                        continue
-
-                received = self._sock.recv(bytes_left)
-                if len(received) == 0:
-                    raise NetBIOSError( 'Error while reading from remote', 
ERRCLASS_OS, None)
-
-                data = data + received
-                bytes_left = read_length - len(data)
-            except select.error as ex:
-                if ex[0] != errno.EINTR and ex[0] != errno.EAGAIN:
-                    raise NetBIOSError( 'Error occurs while reading from 
remote', ERRCLASS_OS, ex[0])
-
-        return data
-
-    def non_polling_read(self, read_length, timeout):
-        data = ''
-        bytes_left = read_length
-
-        while bytes_left > 0:
-            try:
-                ready, _, _ = select.select([self._sock.fileno() ], [ ], [ ], 
timeout)
-
-                if not ready:
-                        raise NetBIOSTimeout
-
-                received = self._sock.recv(bytes_left)
-                if len(received) == 0:
-                    raise NetBIOSError( 'Error while reading from remote', 
ERRCLASS_OS, None)
-
-                data = data + received
-                bytes_left = read_length - len(data)
-            except select.error as ex:
-                if ex[0] != errno.EINTR and ex[0] != errno.EAGAIN:
-                    raise NetBIOSError( 'Error occurs while reading from 
remote', ERRCLASS_OS, ex[0])
-
-        return data
-
-    def __read(self, timeout = None):
-        data = self.read_function(4, timeout)
-        type, flags, length = unpack('>ccH', data)
-        if ord(type) == NETBIOS_SESSION_MESSAGE:
-            length |= ord(flags) << 16
-        else:
-            if ord(flags) & 0x01:
-                length |= 0x10000
-        data2 = self.read_function(length, timeout)
-
-        return data + data2
-
-ERRCLASS_QUERY = 0x00
-ERRCLASS_SESSION = 0xf0
-ERRCLASS_OS = 0xff
-
-QUERY_ERRORS = { 0x01: 'Request format error. Please file a bug report.',
-                 0x02: 'Internal server error',
-                 0x03: 'Name does not exist',
-                 0x04: 'Unsupported request',
-                 0x05: 'Request refused'
-                 }
-
-SESSION_ERRORS = { 0x80: 'Not listening on called name',
-                   0x81: 'Not listening for calling name',
-                   0x82: 'Called name not present',
-                   0x83: 'Sufficient resources',
-                   0x8f: 'Unspecified error'
-                   }
-
-def main():
-    def get_netbios_host_by_name(name):
-        n = NetBIOS()
-        n.set_broadcastaddr('255.255.255.255') # To avoid use "<broadcast>" in 
socket
-        for qtype in (TYPE_WORKSTATION, TYPE_CLIENT, TYPE_SERVER, 
TYPE_DOMAIN_MASTER, TYPE_DOMAIN_CONTROLLER):
-            try:
-                addrs = n.gethostbyname(name, qtype = qtype).get_addr_entries()
-            except NetBIOSTimeout:
-                continue
-            else:
-                return addrs
-        raise Exception("Host not found")
-                
-    
-    n = get_netbios_host_by_name("some-host")
-    print(n)
-
-if __name__ == '__main__':
-    main()
diff --git a/tests/python_dependencies/impacket/nt_errors.py 
b/tests/python_dependencies/impacket/nt_errors.py
deleted file mode 100644
index cd7ef80ae..000000000
--- a/tests/python_dependencies/impacket/nt_errors.py
+++ /dev/null
@@ -1,3586 +0,0 @@
-# Copyright (c) 2003-2016 CORE Security Technologies)
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-# Author: Alberto Solino (@agsolino)
-#
-# Description:
-#   NT STATUS Errors from [MS-ERREF]. Ideally all the files
-#   should grab the error codes from here (big ToDo) 
-#
-
-ERROR_MESSAGES = {
-        0x00000000: ("STATUS_SUCCESS","The operation completed successfully."),
-        0x00000001: ("STATUS_WAIT_1","The caller specified WaitAny for 
WaitType and one of the dispatcher objects in the Object array has been set to 
the signaled state."),
-        0x00000002: ("STATUS_WAIT_2","The caller specified WaitAny for 
WaitType and one of the dispatcher objects in the Object array has been set to 
the signaled state."),
-        0x00000003: ("STATUS_WAIT_3","The caller specified WaitAny for 
WaitType and one of the dispatcher objects in the Object array has been set to 
the signaled state."),
-        0x0000003F: ("STATUS_WAIT_63","The caller specified WaitAny for 
WaitType and one of the dispatcher objects in the Object array has been set to 
the signaled state."),
-        0x00000080: ("STATUS_ABANDONED","The caller attempted to wait for a 
mutex that has been abandoned."),
-        0x00000080: ("STATUS_ABANDONED_WAIT_0","The caller attempted to wait 
for a mutex that has been abandoned."),
-        0x000000BF: ("STATUS_ABANDONED_WAIT_63","The caller attempted to wait 
for a mutex that has been abandoned."),
-        0x000000C0: ("STATUS_USER_APC","A user-mode APC was delivered before 
the given Interval expired."),
-        0x00000101: ("STATUS_ALERTED","The delay completed because the thread 
was alerted."),
-        0x00000102: ("STATUS_TIMEOUT","The given Timeout interval expired."),
-        0x00000103: ("STATUS_PENDING","The operation that was requested is 
pending completion."),
-        0x00000104: ("STATUS_REPARSE","A reparse should be performed by the 
Object Manager because the name of the file resulted in a symbolic link."),
-        0x00000105: ("STATUS_MORE_ENTRIES","Returned by enumeration APIs to 
indicate more information is available to successive calls."),
-        0x00000106: ("STATUS_NOT_ALL_ASSIGNED","Indicates not all privileges 
or groups that are referenced are assigned to the caller. This allows, for 
example, all privileges to be disabled without having to know exactly which 
privileges are assigned."),
-        0x00000107: ("STATUS_SOME_NOT_MAPPED","Some of the information to be 
translated has not been translated."),
-        0x00000108: ("STATUS_OPLOCK_BREAK_IN_PROGRESS","An open/create 
operation completed while an opportunistic lock (oplock) break is underway."),
-        0x00000109: ("STATUS_VOLUME_MOUNTED","A new volume has been mounted by 
a file system."),
-        0x0000010A: ("STATUS_RXACT_COMMITTED","This success level status 
indicates that the transaction state already exists for the registry subtree 
but that a transaction commit was previously aborted. The commit has now been 
completed."),
-        0x0000010B: ("STATUS_NOTIFY_CLEANUP","Indicates that a notify change 
request has been completed due to closing the handle that made the notify 
change request."),
-        0x0000010C: ("STATUS_NOTIFY_ENUM_DIR","Indicates that a notify change 
request is being completed and that the information is not being returned in 
the caller's buffer. The caller now needs to enumerate the files to find the 
changes."),
-        0x0000010D: ("STATUS_NO_QUOTAS_FOR_ACCOUNT","{No Quotas} No system 
quota limits are specifically set for this account."),
-        0x0000010E: ("STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED","{Connect 
Failure on Primary Transport} An attempt was made to connect to the remote 
server %hs on the primary transport, but the connection failed. The computer 
WAS able to connect on a secondary transport."),
-        0x00000110: ("STATUS_PAGE_FAULT_TRANSITION","The page fault was a 
transition fault."),
-        0x00000111: ("STATUS_PAGE_FAULT_DEMAND_ZERO","The page fault was a 
demand zero fault."),
-        0x00000112: ("STATUS_PAGE_FAULT_COPY_ON_WRITE","The page fault was a 
demand zero fault."),
-        0x00000113: ("STATUS_PAGE_FAULT_GUARD_PAGE","The page fault was a 
demand zero fault."),
-        0x00000114: ("STATUS_PAGE_FAULT_PAGING_FILE","The page fault was 
satisfied by reading from a secondary storage device."),
-        0x00000115: ("STATUS_CACHE_PAGE_LOCKED","The cached page was locked 
during operation."),
-        0x00000116: ("STATUS_CRASH_DUMP","The crash dump exists in a paging 
file."),
-        0x00000117: ("STATUS_BUFFER_ALL_ZEROS","The specified buffer contains 
all zeros."),
-        0x00000118: ("STATUS_REPARSE_OBJECT","A reparse should be performed by 
the Object Manager because the name of the file resulted in a symbolic link."),
-        0x00000119: ("STATUS_RESOURCE_REQUIREMENTS_CHANGED","The device has 
succeeded a query-stop and its resource requirements have changed."),
-        0x00000120: ("STATUS_TRANSLATION_COMPLETE","The translator has 
translated these resources into the global space and no additional translations 
should be performed."),
-        0x00000121: ("STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY","The directory 
service evaluated group memberships locally, because it was unable to contact a 
global catalog server."),
-        0x00000122: ("STATUS_NOTHING_TO_TERMINATE","A process being terminated 
has no threads to terminate."),
-        0x00000123: ("STATUS_PROCESS_NOT_IN_JOB","The specified process is not 
part of a job."),
-        0x00000124: ("STATUS_PROCESS_IN_JOB","The specified process is part of 
a job."),
-        0x00000125: ("STATUS_VOLSNAP_HIBERNATE_READY","{Volume Shadow Copy 
Service} The system is now ready for hibernation."),
-        0x00000126: ("STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY","A file 
system or file system filter driver has successfully completed an FsFilter 
operation."),
-        0x00000127: ("STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED","The 
specified interrupt vector was already connected."),
-        0x00000128: ("STATUS_INTERRUPT_STILL_CONNECTED","The specified 
interrupt vector is still connected."),
-        0x00000129: ("STATUS_PROCESS_CLONED","The current process is a cloned 
process."),
-        0x0000012A: ("STATUS_FILE_LOCKED_WITH_ONLY_READERS","The file was 
locked and all users of the file can only read."),
-        0x0000012B: ("STATUS_FILE_LOCKED_WITH_WRITERS","The file was locked 
and at least one user of the file can write."),
-        0x00000202: ("STATUS_RESOURCEMANAGER_READ_ONLY","The specified 
ResourceManager made no changes or updates to the resource under this 
transaction."),
-        0x00000367: ("STATUS_WAIT_FOR_OPLOCK","An operation is blocked and 
waiting for an oplock."),
-        0x00010001: ("DBG_EXCEPTION_HANDLED","Debugger handled the 
exception."),
-        0x00010002: ("DBG_CONTINUE","The debugger continued."),
-        0x001C0001: ("STATUS_FLT_IO_COMPLETE","The IO was completed by a 
filter."),
-        0xC0000467: ("STATUS_FILE_NOT_AVAILABLE","The file is temporarily 
unavailable."),
-        0xC0000721: ("STATUS_CALLBACK_RETURNED_THREAD_AFFINITY","A threadpool 
worker thread entered a callback at thread affinity %p and exited at affinity 
%p.  This is unexpected, indicating that the callback missed restoring the 
priority."),
-        0x40000000: ("STATUS_OBJECT_NAME_EXISTS","{Object Exists} An attempt 
was made to create an object but the object name already exists."),
-        0x40000001: ("STATUS_THREAD_WAS_SUSPENDED","{Thread Suspended} A 
thread termination occurred while the thread was suspended. The thread resumed, 
and termination proceeded."),
-        0x40000002: ("STATUS_WORKING_SET_LIMIT_RANGE","{Working Set Range 
Error} An attempt was made to set the working set minimum or maximum to values 
that are outside the allowable range."),
-        0x40000003: ("STATUS_IMAGE_NOT_AT_BASE","{Image Relocated} An image 
file could not be mapped at the address that is specified in the image file. 
Local fixes must be performed on this image."),
-        0x40000004: ("STATUS_RXACT_STATE_CREATED","This informational level 
status indicates that a specified registry subtree transaction state did not 
yet exist and had to be created."),
-        0x40000005: ("STATUS_SEGMENT_NOTIFICATION","{Segment Load} A virtual 
DOS machine (VDM) is loading, unloading, or moving an MS-DOS or Win16 program 
segment image. An exception is raised so that a debugger can load, unload, or 
track symbols and breakpoints within these 16-bit segments."),
-        0x40000006: ("STATUS_LOCAL_USER_SESSION_KEY","{Local Session Key} A 
user session key was requested for a local remote procedure call (RPC) 
connection. The session key that is returned is a constant value and not unique 
to this connection."),
-        0x40000007: ("STATUS_BAD_CURRENT_DIRECTORY","{Invalid Current 
Directory} The process cannot switch to the startup current directory %hs. 
Select OK to set the current directory to %hs, or select CANCEL to exit."),
-        0x40000008: ("STATUS_SERIAL_MORE_WRITES","{Serial IOCTL Complete} A 
serial I/O operation was completed by another write to a serial port. (The 
IOCTL_SERIAL_XOFF_COUNTER reached zero.)"),
-        0x40000009: ("STATUS_REGISTRY_RECOVERED","{Registry Recovery} One of 
the files that contains the system registry data had to be recovered by using a 
log or alternate copy. The recovery was successful."),
-        0x4000000A: ("STATUS_FT_READ_RECOVERY_FROM_BACKUP","{Redundant Read} 
To satisfy a read request, the Windows NT fault-tolerant file system 
successfully read the requested data from a redundant copy. This was done 
because the file system encountered a failure on a member of the fault-tolerant 
volume but was unable to reassign the failing area of the device."),
-        0x4000000B: ("STATUS_FT_WRITE_RECOVERY","{Redundant Write} To satisfy 
a write request, the Windows NT fault-tolerant file system successfully wrote a 
redundant copy of the information. This was done because the file system 
encountered a failure on a member of the fault-tolerant volume but was unable 
to reassign the failing area of the device."),
-        0x4000000C: ("STATUS_SERIAL_COUNTER_TIMEOUT","{Serial IOCTL Timeout} A 
serial I/O operation completed because the time-out period expired. (The 
IOCTL_SERIAL_XOFF_COUNTER had not reached zero.)"),
-        0x4000000D: ("STATUS_NULL_LM_PASSWORD","{Password Too Complex} The 
Windows password is too complex to be converted to a LAN Manager password. The 
LAN Manager password that returned is a NULL string."),
-        0x4000000E: ("STATUS_IMAGE_MACHINE_TYPE_MISMATCH","{Machine Type 
Mismatch} The image file %hs is valid but is for a machine type other than the 
current machine. Select OK to continue, or CANCEL to fail the DLL load."),
-        0x4000000F: ("STATUS_RECEIVE_PARTIAL","{Partial Data Received} The 
network transport returned partial data to its client. The remaining data will 
be sent later."),
-        0x40000010: ("STATUS_RECEIVE_EXPEDITED","{Expedited Data Received} The 
network transport returned data to its client that was marked as expedited by 
the remote system."),
-        0x40000011: ("STATUS_RECEIVE_PARTIAL_EXPEDITED","{Partial Expedited 
Data Received} The network transport returned partial data to its client and 
this data was marked as expedited by the remote system. The remaining data will 
be sent later."),
-        0x40000012: ("STATUS_EVENT_DONE","{TDI Event Done} The TDI indication 
has completed successfully."),
-        0x40000013: ("STATUS_EVENT_PENDING","{TDI Event Pending} The TDI 
indication has entered the pending state."),
-        0x40000014: ("STATUS_CHECKING_FILE_SYSTEM","Checking file system on 
%wZ."),
-        0x40000015: ("STATUS_FATAL_APP_EXIT","{Fatal Application Exit} %hs"),
-        0x40000016: ("STATUS_PREDEFINED_HANDLE","The specified registry key is 
referenced by a predefined handle."),
-        0x40000017: ("STATUS_WAS_UNLOCKED","{Page Unlocked} The page 
protection of a locked page was changed to 'No Access' and the page was 
unlocked from memory and from the process."),
-        0x40000018: ("STATUS_SERVICE_NOTIFICATION","%hs"),
-        0x40000019: ("STATUS_WAS_LOCKED","{Page Locked} One of the pages to 
lock was already locked."),
-        0x4000001A: ("STATUS_LOG_HARD_ERROR","Application popup: %1 : %2"),
-        0x4000001B: ("STATUS_ALREADY_WIN32","A Win32 process already exists."),
-        0x4000001C: ("STATUS_WX86_UNSIMULATE","An exception status code that 
is used by the Win32 x86 emulation subsystem."),
-        0x4000001D: ("STATUS_WX86_CONTINUE","An exception status code that is 
used by the Win32 x86 emulation subsystem."),
-        0x4000001E: ("STATUS_WX86_SINGLE_STEP","An exception status code that 
is used by the Win32 x86 emulation subsystem."),
-        0x4000001F: ("STATUS_WX86_BREAKPOINT","An exception status code that 
is used by the Win32 x86 emulation subsystem."),
-        0x40000020: ("STATUS_WX86_EXCEPTION_CONTINUE","An exception status 
code that is used by the Win32 x86 emulation subsystem."),
-        0x40000021: ("STATUS_WX86_EXCEPTION_LASTCHANCE","An exception status 
code that is used by the Win32 x86 emulation subsystem."),
-        0x40000022: ("STATUS_WX86_EXCEPTION_CHAIN","An exception status code 
that is used by the Win32 x86 emulation subsystem."),
-        0x40000023: ("STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE","{Machine Type 
Mismatch} The image file %hs is valid but is for a machine type other than the 
current machine."),
-        0x40000024: ("STATUS_NO_YIELD_PERFORMED","A yield execution was 
performed and no thread was available to run."),
-        0x40000025: ("STATUS_TIMER_RESUME_IGNORED","The resume flag to a timer 
API was ignored."),
-        0x40000026: ("STATUS_ARBITRATION_UNHANDLED","The arbiter has deferred 
arbitration of these resources to its parent."),
-        0x40000027: ("STATUS_CARDBUS_NOT_SUPPORTED","The device has detected a 
CardBus card in its slot."),
-        0x40000028: ("STATUS_WX86_CREATEWX86TIB","An exception status code 
that is used by the Win32 x86 emulation subsystem."),
-        0x40000029: ("STATUS_MP_PROCESSOR_MISMATCH","The CPUs in this 
multiprocessor system are not all the same revision level. To use all 
processors, the operating system restricts itself to the features of the least 
capable processor in the system. If problems occur with this system, contact 
the CPU manufacturer to see if this mix of processors is supported."),
-        0x4000002A: ("STATUS_HIBERNATED","The system was put into 
hibernation."),
-        0x4000002B: ("STATUS_RESUME_HIBERNATION","The system was resumed from 
hibernation."),
-        0x4000002C: ("STATUS_FIRMWARE_UPDATED","Windows has detected that the 
system firmware (BIOS) was updated [previous firmware date = %2, current 
firmware date %3]."),
-        0x4000002D: ("STATUS_DRIVERS_LEAKING_LOCKED_PAGES","A device driver is 
leaking locked I/O pages and is causing system degradation. The system has 
automatically enabled the tracking code to try and catch the culprit."),
-        0x4000002E: ("STATUS_MESSAGE_RETRIEVED","The ALPC message being 
canceled has already been retrieved from the queue on the other side."),
-        0x4000002F: ("STATUS_SYSTEM_POWERSTATE_TRANSITION","The system power 
state is transitioning from %2 to %3."),
-        0x40000030: ("STATUS_ALPC_CHECK_COMPLETION_LIST","The receive 
operation was successful. Check the ALPC completion list for the received 
message."),
-        0x40000031: ("STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION","The system 
power state is transitioning from %2 to %3 but could enter %4."),
-        0x40000032: ("STATUS_ACCESS_AUDIT_BY_POLICY","Access to %1 is 
monitored by policy rule %2."),
-        0x40000033: ("STATUS_ABANDON_HIBERFILE","A valid hibernation file has 
been invalidated and should be abandoned."),
-        0x40000034: ("STATUS_BIZRULES_NOT_ENABLED","Business rule scripts are 
disabled for the calling application."),
-        0x40000294: ("STATUS_WAKE_SYSTEM","The system has awoken."),
-        0x40000370: ("STATUS_DS_SHUTTING_DOWN","The directory service is 
shutting down."),
-        0x40010001: ("DBG_REPLY_LATER","Debugger will reply later."),
-        0x40010002: ("DBG_UNABLE_TO_PROVIDE_HANDLE","Debugger cannot provide a 
handle."),
-        0x40010003: ("DBG_TERMINATE_THREAD","Debugger terminated the thread."),
-        0x40010004: ("DBG_TERMINATE_PROCESS","Debugger terminated the 
process."),
-        0x40010005: ("DBG_CONTROL_C","Debugger obtained control of C."),
-        0x40010006: ("DBG_PRINTEXCEPTION_C","Debugger printed an exception on 
control C."),
-        0x40010007: ("DBG_RIPEXCEPTION","Debugger received a RIP exception."),
-        0x40010008: ("DBG_CONTROL_BREAK","Debugger received a control break."),
-        0x40010009: ("DBG_COMMAND_EXCEPTION","Debugger command communication 
exception."),
-        0x40020056: ("RPC_NT_UUID_LOCAL_ONLY","A UUID that is valid only on 
this computer has been allocated."),
-        0x400200AF: ("RPC_NT_SEND_INCOMPLETE","Some data remains to be sent in 
the request buffer."),
-        0x400A0004: ("STATUS_CTX_CDM_CONNECT","The Client Drive Mapping 
Service has connected on Terminal Connection."),
-        0x400A0005: ("STATUS_CTX_CDM_DISCONNECT","The Client Drive Mapping 
Service has disconnected on Terminal Connection."),
-        0x4015000D: ("STATUS_SXS_RELEASE_ACTIVATION_CONTEXT","A kernel mode 
component is releasing a reference on an activation context."),
-        0x40190034: ("STATUS_RECOVERY_NOT_NEEDED","The transactional resource 
manager is already consistent. Recovery is not needed."),
-        0x40190035: ("STATUS_RM_ALREADY_STARTED","The transactional resource 
manager has already been started."),
-        0x401A000C: ("STATUS_LOG_NO_RESTART","The log service encountered a 
log stream with no restart area."),
-        0x401B00EC: ("STATUS_VIDEO_DRIVER_DEBUG_REPORT_REQUEST","{Display 
Driver Recovered From Failure} The %hs display driver has detected a failure 
and recovered from it. Some graphical operations may have failed. The next time 
you restart the machine, a dialog box appears, giving you an opportunity to 
upload data about this failure to Microsoft."),
-        0x401E000A: ("STATUS_GRAPHICS_PARTIAL_DATA_POPULATED","The specified 
buffer is not big enough to contain the entire requested dataset. Partial data 
is populated up to the size of the buffer. The caller needs to provide a buffer 
of the size as specified in the partially populated buffer's content (interface 
specific)."),
-        0x401E0117: ("STATUS_GRAPHICS_DRIVER_MISMATCH","The kernel driver 
detected a version mismatch between it and the user mode driver."),
-        0x401E0307: ("STATUS_GRAPHICS_MODE_NOT_PINNED","No mode is pinned on 
the specified VidPN source/target."),
-        0x401E031E: ("STATUS_GRAPHICS_NO_PREFERRED_MODE","The specified mode 
set does not specify a preference for one of its modes."),
-        0x401E034B: ("STATUS_GRAPHICS_DATASET_IS_EMPTY","The specified dataset 
(for example, mode set, frequency range set, descriptor set, or topology) is 
empty."),
-        0x401E034C: ("STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET","The 
specified dataset (for example, mode set, frequency range set, descriptor set, 
or topology) does not contain any more elements."),
-        0x401E0351: 
("STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_PINNED","The 
specified content transformation is not pinned on the specified VidPN present 
path."),
-        0x401E042F: ("STATUS_GRAPHICS_UNKNOWN_CHILD_STATUS","The child device 
presence was not reliably detected."),
-        0x401E0437: ("STATUS_GRAPHICS_LEADLINK_START_DEFERRED","Starting the 
lead adapter in a linked configuration has been temporarily deferred."),
-        0x401E0439: ("STATUS_GRAPHICS_POLLING_TOO_FREQUENTLY","The display 
adapter is being polled for children too frequently at the same polling 
level."),
-        0x401E043A: ("STATUS_GRAPHICS_START_DEFERRED","Starting the adapter 
has been temporarily deferred."),
-        0x40230001: ("STATUS_NDIS_INDICATION_REQUIRED","The request will be 
completed later by an NDIS status indication."),
-        0x80000001: ("STATUS_GUARD_PAGE_VIOLATION","{EXCEPTION} Guard Page 
Exception A page of memory that marks the end of a data structure, such as a 
stack or an array, has been accessed."),
-        0x80000002: ("STATUS_DATATYPE_MISALIGNMENT","{EXCEPTION} Alignment 
Fault A data type misalignment was detected in a load or store instruction."),
-        0x80000003: ("STATUS_BREAKPOINT","{EXCEPTION} Breakpoint A breakpoint 
has been reached."),
-        0x80000004: ("STATUS_SINGLE_STEP","{EXCEPTION} Single Step A single 
step or trace operation has just been completed."),
-        0x80000005: ("STATUS_BUFFER_OVERFLOW","{Buffer Overflow} The data was 
too large to fit into the specified buffer."),
-        0x80000006: ("STATUS_NO_MORE_FILES","{No More Files} No more files 
were found which match the file specification."),
-        0x80000007: ("STATUS_WAKE_SYSTEM_DEBUGGER","{Kernel Debugger Awakened} 
The system debugger was awakened by an interrupt."),
-        0x8000000A: ("STATUS_HANDLES_CLOSED","{Handles Closed} Handles to 
objects have been automatically closed because of the requested operation."),
-        0x8000000B: ("STATUS_NO_INHERITANCE","{Non-Inheritable ACL} An access 
control list (ACL) contains no components that can be inherited."),
-        0x8000000C: ("STATUS_GUID_SUBSTITUTION_MADE","{GUID Substitution} 
During the translation of a globally unique identifier (GUID) to a Windows 
security ID (SID), no administratively defined GUID prefix was found. A 
substitute prefix was used, which will not compromise system security. However, 
this may provide a more restrictive access than intended."),
-        0x8000000D: ("STATUS_PARTIAL_COPY","Because of protection conflicts, 
not all the requested bytes could be copied."),
-        0x8000000E: ("STATUS_DEVICE_PAPER_EMPTY","{Out of Paper} The printer 
is out of paper."),
-        0x8000000F: ("STATUS_DEVICE_POWERED_OFF","{Device Power Is Off} The 
printer power has been turned off."),
-        0x80000010: ("STATUS_DEVICE_OFF_LINE","{Device Offline} The printer 
has been taken offline."),
-        0x80000011: ("STATUS_DEVICE_BUSY","{Device Busy} The device is 
currently busy."),
-        0x80000012: ("STATUS_NO_MORE_EAS","{No More EAs} No more extended 
attributes (EAs) were found for the file."),
-        0x80000013: ("STATUS_INVALID_EA_NAME","{Illegal EA} The specified 
extended attribute (EA) name contains at least one illegal character."),
-        0x80000014: ("STATUS_EA_LIST_INCONSISTENT","{Inconsistent EA List} The 
extended attribute (EA) list is inconsistent."),
-        0x80000015: ("STATUS_INVALID_EA_FLAG","{Invalid EA Flag} An invalid 
extended attribute (EA) flag was set."),
-        0x80000016: ("STATUS_VERIFY_REQUIRED","{Verifying Disk} The media has 
changed and a verify operation is in progress; therefore, no reads or writes 
may be performed to the device, except those that are used in the verify 
operation."),
-        0x80000017: ("STATUS_EXTRANEOUS_INFORMATION","{Too Much Information} 
The specified access control list (ACL) contained more information than was 
expected."),
-        0x80000018: ("STATUS_RXACT_COMMIT_NECESSARY","This warning level 
status indicates that the transaction state already exists for the registry 
subtree, but that a transaction commit was previously aborted. The commit has 
NOT been completed but has not been rolled back either; therefore, it may still 
be committed, if needed."),
-        0x8000001A: ("STATUS_NO_MORE_ENTRIES","{No More Entries} No more 
entries are available from an enumeration operation."),
-        0x8000001B: ("STATUS_FILEMARK_DETECTED","{Filemark Found} A filemark 
was detected."),
-        0x8000001C: ("STATUS_MEDIA_CHANGED","{Media Changed} The media may 
have changed."),
-        0x8000001D: ("STATUS_BUS_RESET","{I/O Bus Reset} An I/O bus reset was 
detected."),
-        0x8000001E: ("STATUS_END_OF_MEDIA","{End of Media} The end of the 
media was encountered."),
-        0x8000001F: ("STATUS_BEGINNING_OF_MEDIA","The beginning of a tape or 
partition has been detected."),
-        0x80000020: ("STATUS_MEDIA_CHECK","{Media Changed} The media may have 
changed."),
-        0x80000021: ("STATUS_SETMARK_DETECTED","A tape access reached a set 
mark."),
-        0x80000022: ("STATUS_NO_DATA_DETECTED","During a tape access, the end 
of the data written is reached."),
-        0x80000023: ("STATUS_REDIRECTOR_HAS_OPEN_HANDLES","The redirector is 
in use and cannot be unloaded."),
-        0x80000024: ("STATUS_SERVER_HAS_OPEN_HANDLES","The server is in use 
and cannot be unloaded."),
-        0x80000025: ("STATUS_ALREADY_DISCONNECTED","The specified connection 
has already been disconnected."),
-        0x80000026: ("STATUS_LONGJUMP","A long jump has been executed."),
-        0x80000027: ("STATUS_CLEANER_CARTRIDGE_INSTALLED","A cleaner cartridge 
is present in the tape library."),
-        0x80000028: ("STATUS_PLUGPLAY_QUERY_VETOED","The Plug and Play query 
operation was not successful."),
-        0x80000029: ("STATUS_UNWIND_CONSOLIDATE","A frame consolidation has 
been executed."),
-        0x8000002A: ("STATUS_REGISTRY_HIVE_RECOVERED","{Registry Hive 
Recovered} The registry hive (file): %hs was corrupted and it has been 
recovered. Some data might have been lost."),
-        0x8000002B: ("STATUS_DLL_MIGHT_BE_INSECURE","The application is 
attempting to run executable code from the module %hs. This may be insecure. An 
alternative, %hs, is available. Should the application use the secure module 
%hs?"),
-        0x8000002C: ("STATUS_DLL_MIGHT_BE_INCOMPATIBLE","The application is 
loading executable code from the module %hs. This is secure but may be 
incompatible with previous releases of the operating system. An alternative, 
%hs, is available. Should the application use the secure module %hs?"),
-        0x8000002D: ("STATUS_STOPPED_ON_SYMLINK","The create operation stopped 
after reaching a symbolic link."),
-        0x80000288: ("STATUS_DEVICE_REQUIRES_CLEANING","The device has 
indicated that cleaning is necessary."),
-        0x80000289: ("STATUS_DEVICE_DOOR_OPEN","The device has indicated that 
its door is open. Further operations require it closed and secured."),
-        0x80000803: ("STATUS_DATA_LOST_REPAIR","Windows discovered a 
corruption in the file %hs. This file has now been repaired. Check if any data 
in the file was lost because of the corruption."),
-        0x80010001: ("DBG_EXCEPTION_NOT_HANDLED","Debugger did not handle the 
exception."),
-        0x80130001: ("STATUS_CLUSTER_NODE_ALREADY_UP","The cluster node is 
already up."),
-        0x80130002: ("STATUS_CLUSTER_NODE_ALREADY_DOWN","The cluster node is 
already down."),
-        0x80130003: ("STATUS_CLUSTER_NETWORK_ALREADY_ONLINE","The cluster 
network is already online."),
-        0x80130004: ("STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE","The cluster 
network is already offline."),
-        0x80130005: ("STATUS_CLUSTER_NODE_ALREADY_MEMBER","The cluster node is 
already a member of the cluster."),
-        0x80190009: ("STATUS_COULD_NOT_RESIZE_LOG","The log could not be set 
to the requested size."),
-        0x80190029: ("STATUS_NO_TXF_METADATA","There is no transaction 
metadata on the file."),
-        0x80190031: ("STATUS_CANT_RECOVER_WITH_HANDLE_OPEN","The file cannot 
be recovered because there is a handle still open on it."),
-        0x80190041: ("STATUS_TXF_METADATA_ALREADY_PRESENT","Transaction 
metadata is already present on this file and cannot be superseded."),
-        0x80190042: ("STATUS_TRANSACTION_SCOPE_CALLBACKS_NOT_SET","A 
transaction scope could not be entered because the scope handler has not been 
initialized."),
-        0x801B00EB: 
("STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD_RECOVERED","{Display Driver Stopped 
Responding and recovered} The %hs display driver has stopped working normally. 
The recovery had been performed."),
-        0x801C0001: ("STATUS_FLT_BUFFER_TOO_SMALL","{Buffer too small} The 
buffer is too small to contain the entry. No information has been written to 
the buffer."),
-        0x80210001: ("STATUS_FVE_PARTIAL_METADATA","Volume metadata read or 
write is incomplete."),
-        0x80210002: ("STATUS_FVE_TRANSIENT_STATE","BitLocker encryption keys 
were ignored because the volume was in a transient state."),
-        0xC0000001: ("STATUS_UNSUCCESSFUL","{Operation Failed} The requested 
operation was unsuccessful."),
-        0xC0000002: ("STATUS_NOT_IMPLEMENTED","{Not Implemented} The requested 
operation is not implemented."),
-        0xC0000003: ("STATUS_INVALID_INFO_CLASS","{Invalid Parameter} The 
specified information class is not a valid information class for the specified 
object."),
-        0xC0000004: ("STATUS_INFO_LENGTH_MISMATCH","The specified information 
record length does not match the length that is required for the specified 
information class."),
-        0xC0000005: ("STATUS_ACCESS_VIOLATION","The instruction at 0x%08lx 
referenced memory at 0x%08lx. The memory could not be %s."),
-        0xC0000006: ("STATUS_IN_PAGE_ERROR","The instruction at 0x%08lx 
referenced memory at 0x%08lx. The required data was not placed into memory 
because of an I/O error status of 0x%08lx."),
-        0xC0000007: ("STATUS_PAGEFILE_QUOTA","The page file quota for the 
process has been exhausted."),
-        0xC0000008: ("STATUS_INVALID_HANDLE","An invalid HANDLE was 
specified."),
-        0xC0000009: ("STATUS_BAD_INITIAL_STACK","An invalid initial stack was 
specified in a call to NtCreateThread."),
-        0xC000000A: ("STATUS_BAD_INITIAL_PC","An invalid initial start address 
was specified in a call to NtCreateThread."),
-        0xC000000B: ("STATUS_INVALID_CID","An invalid client ID was 
specified."),
-        0xC000000C: ("STATUS_TIMER_NOT_CANCELED","An attempt was made to 
cancel or set a timer that has an associated APC and the specified thread is 
not the thread that originally set the timer with an associated APC routine."),
-        0xC000000D: ("STATUS_INVALID_PARAMETER","An invalid parameter was 
passed to a service or function."),
-        0xC000000E: ("STATUS_NO_SUCH_DEVICE","A device that does not exist was 
specified."),
-        0xC000000F: ("STATUS_NO_SUCH_FILE","{File Not Found} The file %hs does 
not exist."),
-        0xC0000010: ("STATUS_INVALID_DEVICE_REQUEST","The specified request is 
not a valid operation for the target device."),
-        0xC0000011: ("STATUS_END_OF_FILE","The end-of-file marker has been 
reached. There is no valid data in the file beyond this marker."),
-        0xC0000012: ("STATUS_WRONG_VOLUME","{Wrong Volume} The wrong volume is 
in the drive. Insert volume %hs into drive %hs."),
-        0xC0000013: ("STATUS_NO_MEDIA_IN_DEVICE","{No Disk} There is no disk 
in the drive. Insert a disk into drive %hs."),
-        0xC0000014: ("STATUS_UNRECOGNIZED_MEDIA","{Unknown Disk Format} The 
disk in drive %hs is not formatted properly. Check the disk, and reformat it, 
if needed."),
-        0xC0000015: ("STATUS_NONEXISTENT_SECTOR","{Sector Not Found} The 
specified sector does not exist."),
-        0xC0000016: ("STATUS_MORE_PROCESSING_REQUIRED","{Still Busy} The 
specified I/O request packet (IRP) cannot be disposed of because the I/O 
operation is not complete."),
-        0xC0000017: ("STATUS_NO_MEMORY","{Not Enough Quota} Not enough virtual 
memory or paging file quota is available to complete the specified operation."),
-        0xC0000018: ("STATUS_CONFLICTING_ADDRESSES","{Conflicting Address 
Range} The specified address range conflicts with the address space."),
-        0xC0000019: ("STATUS_NOT_MAPPED_VIEW","The address range to unmap is 
not a mapped view."),
-        0xC000001A: ("STATUS_UNABLE_TO_FREE_VM","The virtual memory cannot be 
freed."),
-        0xC000001B: ("STATUS_UNABLE_TO_DELETE_SECTION","The specified section 
cannot be deleted."),
-        0xC000001C: ("STATUS_INVALID_SYSTEM_SERVICE","An invalid system 
service was specified in a system service call."),
-        0xC000001D: ("STATUS_ILLEGAL_INSTRUCTION","{EXCEPTION} Illegal 
Instruction An attempt was made to execute an illegal instruction."),
-        0xC000001E: ("STATUS_INVALID_LOCK_SEQUENCE","{Invalid Lock Sequence} 
An attempt was made to execute an invalid lock sequence."),
-        0xC000001F: ("STATUS_INVALID_VIEW_SIZE","{Invalid Mapping} An attempt 
was made to create a view for a section that is bigger than the section."),
-        0xC0000020: ("STATUS_INVALID_FILE_FOR_SECTION","{Bad File} The 
attributes of the specified mapping file for a section of memory cannot be 
read."),
-        0xC0000021: ("STATUS_ALREADY_COMMITTED","{Already Committed} The 
specified address range is already committed."),
-        0xC0000022: ("STATUS_ACCESS_DENIED","{Access Denied} A process has 
requested access to an object but has not been granted those access rights."),
-        0xC0000023: ("STATUS_BUFFER_TOO_SMALL","{Buffer Too Small} The buffer 
is too small to contain the entry. No information has been written to the 
buffer."),
-        0xC0000024: ("STATUS_OBJECT_TYPE_MISMATCH","{Wrong Type} There is a 
mismatch between the type of object that is required by the requested operation 
and the type of object that is specified in the request."),
-        0xC0000025: ("STATUS_NONCONTINUABLE_EXCEPTION","{EXCEPTION} Cannot 
Continue Windows cannot continue from this exception."),
-        0xC0000026: ("STATUS_INVALID_DISPOSITION","An invalid exception 
disposition was returned by an exception handler."),
-        0xC0000027: ("STATUS_UNWIND","Unwind exception code."),
-        0xC0000028: ("STATUS_BAD_STACK","An invalid or unaligned stack was 
encountered during an unwind operation."),
-        0xC0000029: ("STATUS_INVALID_UNWIND_TARGET","An invalid unwind target 
was encountered during an unwind operation."),
-        0xC000002A: ("STATUS_NOT_LOCKED","An attempt was made to unlock a page 
of memory that was not locked."),
-        0xC000002B: ("STATUS_PARITY_ERROR","A device parity error on an I/O 
operation."),
-        0xC000002C: ("STATUS_UNABLE_TO_DECOMMIT_VM","An attempt was made to 
decommit uncommitted virtual memory."),
-        0xC000002D: ("STATUS_NOT_COMMITTED","An attempt was made to change the 
attributes on memory that has not been committed."),
-        0xC000002E: ("STATUS_INVALID_PORT_ATTRIBUTES","Invalid object 
attributes specified to NtCreatePort or invalid port attributes specified to 
NtConnectPort."),
-        0xC000002F: ("STATUS_PORT_MESSAGE_TOO_LONG","The length of the message 
that was passed to NtRequestPort or NtRequestWaitReplyPort is longer than the 
maximum message that is allowed by the port."),
-        0xC0000030: ("STATUS_INVALID_PARAMETER_MIX","An invalid combination of 
parameters was specified."),
-        0xC0000031: ("STATUS_INVALID_QUOTA_LOWER","An attempt was made to 
lower a quota limit below the current usage."),
-        0xC0000032: ("STATUS_DISK_CORRUPT_ERROR","{Corrupt Disk} The file 
system structure on the disk is corrupt and unusable. Run the Chkdsk utility on 
the volume %hs."),
-        0xC0000033: ("STATUS_OBJECT_NAME_INVALID","The object name is 
invalid."),
-        0xC0000034: ("STATUS_OBJECT_NAME_NOT_FOUND","The object name is not 
found."),
-        0xC0000035: ("STATUS_OBJECT_NAME_COLLISION","The object name already 
exists."),
-        0xC0000037: ("STATUS_PORT_DISCONNECTED","An attempt was made to send a 
message to a disconnected communication port."),
-        0xC0000038: ("STATUS_DEVICE_ALREADY_ATTACHED","An attempt was made to 
attach to a device that was already attached to another device."),
-        0xC0000039: ("STATUS_OBJECT_PATH_INVALID","The object path component 
was not a directory object."),
-        0xC000003A: ("STATUS_OBJECT_PATH_NOT_FOUND","{Path Not Found} The path 
%hs does not exist."),
-        0xC000003B: ("STATUS_OBJECT_PATH_SYNTAX_BAD","The object path 
component was not a directory object."),
-        0xC000003C: ("STATUS_DATA_OVERRUN","{Data Overrun} A data overrun 
error occurred."),
-        0xC000003D: ("STATUS_DATA_LATE_ERROR","{Data Late} A data late error 
occurred."),
-        0xC000003E: ("STATUS_DATA_ERROR","{Data Error} An error occurred in 
reading or writing data."),
-        0xC000003F: ("STATUS_CRC_ERROR","{Bad CRC} A cyclic redundancy check 
(CRC) checksum error occurred."),
-        0xC0000040: ("STATUS_SECTION_TOO_BIG","{Section Too Large} The 
specified section is too big to map the file."),
-        0xC0000041: ("STATUS_PORT_CONNECTION_REFUSED","The NtConnectPort 
request is refused."),
-        0xC0000042: ("STATUS_INVALID_PORT_HANDLE","The type of port handle is 
invalid for the operation that is requested."),
-        0xC0000043: ("STATUS_SHARING_VIOLATION","A file cannot be opened 
because the share access flags are incompatible."),
-        0xC0000044: ("STATUS_QUOTA_EXCEEDED","Insufficient quota exists to 
complete the operation."),
-        0xC0000045: ("STATUS_INVALID_PAGE_PROTECTION","The specified page 
protection was not valid."),
-        0xC0000046: ("STATUS_MUTANT_NOT_OWNED","An attempt to release a mutant 
object was made by a thread that was not the owner of the mutant object."),
-        0xC0000047: ("STATUS_SEMAPHORE_LIMIT_EXCEEDED","An attempt was made to 
release a semaphore such that its maximum count would have been exceeded."),
-        0xC0000048: ("STATUS_PORT_ALREADY_SET","An attempt was made to set the 
DebugPort or ExceptionPort of a process, but a port already exists in the 
process, or an attempt was made to set the CompletionPort of a file but a port 
was already set in the file, or an attempt was made to set the associated 
completion port of an ALPC port but it is already set."),
-        0xC0000049: ("STATUS_SECTION_NOT_IMAGE","An attempt was made to query 
image information on a section that does not map an image."),
-        0xC000004A: ("STATUS_SUSPEND_COUNT_EXCEEDED","An attempt was made to 
suspend a thread whose suspend count was at its maximum."),
-        0xC000004B: ("STATUS_THREAD_IS_TERMINATING","An attempt was made to 
suspend a thread that has begun termination."),
-        0xC000004C: ("STATUS_BAD_WORKING_SET_LIMIT","An attempt was made to 
set the working set limit to an invalid value (for example, the minimum greater 
than maximum)."),
-        0xC000004D: ("STATUS_INCOMPATIBLE_FILE_MAP","A section was created to 
map a file that is not compatible with an already existing section that maps 
the same file."),
-        0xC000004E: ("STATUS_SECTION_PROTECTION","A view to a section 
specifies a protection that is incompatible with the protection of the initial 
view."),
-        0xC000004F: ("STATUS_EAS_NOT_SUPPORTED","An operation involving EAs 
failed because the file system does not support EAs."),
-        0xC0000050: ("STATUS_EA_TOO_LARGE","An EA operation failed because the 
EA set is too large."),
-        0xC0000051: ("STATUS_NONEXISTENT_EA_ENTRY","An EA operation failed 
because the name or EA index is invalid."),
-        0xC0000052: ("STATUS_NO_EAS_ON_FILE","The file for which EAs were 
requested has no EAs."),
-        0xC0000053: ("STATUS_EA_CORRUPT_ERROR","The EA is corrupt and cannot 
be read."),
-        0xC0000054: ("STATUS_FILE_LOCK_CONFLICT","A requested read/write 
cannot be granted due to a conflicting file lock."),
-        0xC0000055: ("STATUS_LOCK_NOT_GRANTED","A requested file lock cannot 
be granted due to other existing locks."),
-        0xC0000056: ("STATUS_DELETE_PENDING","A non-close operation has been 
requested of a file object that has a delete pending."),
-        0xC0000057: ("STATUS_CTL_FILE_NOT_SUPPORTED","An attempt was made to 
set the control attribute on a file. This attribute is not supported in the 
destination file system."),
-        0xC0000058: ("STATUS_UNKNOWN_REVISION","Indicates a revision number 
that was encountered or specified is not one that is known by the service. It 
may be a more recent revision than the service is aware of."),
-        0xC0000059: ("STATUS_REVISION_MISMATCH","Indicates that two revision 
levels are incompatible."),
-        0xC000005A: ("STATUS_INVALID_OWNER","Indicates a particular security 
ID may not be assigned as the owner of an object."),
-        0xC000005B: ("STATUS_INVALID_PRIMARY_GROUP","Indicates a particular 
security ID may not be assigned as the primary group of an object."),
-        0xC000005C: ("STATUS_NO_IMPERSONATION_TOKEN","An attempt has been made 
to operate on an impersonation token by a thread that is not currently 
impersonating a client."),
-        0xC000005D: ("STATUS_CANT_DISABLE_MANDATORY","A mandatory group may 
not be disabled."),
-        0xC000005E: ("STATUS_NO_LOGON_SERVERS","No logon servers are currently 
available to service the logon request."),
-        0xC000005F: ("STATUS_NO_SUCH_LOGON_SESSION","A specified logon session 
does not exist. It may already have been terminated."),
-        0xC0000060: ("STATUS_NO_SUCH_PRIVILEGE","A specified privilege does 
not exist."),
-        0xC0000061: ("STATUS_PRIVILEGE_NOT_HELD","A required privilege is not 
held by the client."),
-        0xC0000062: ("STATUS_INVALID_ACCOUNT_NAME","The name provided is not a 
properly formed account name."),
-        0xC0000063: ("STATUS_USER_EXISTS","The specified account already 
exists."),
-        0xC0000064: ("STATUS_NO_SUCH_USER","The specified account does not 
exist."),
-        0xC0000065: ("STATUS_GROUP_EXISTS","The specified group already 
exists."),
-        0xC0000066: ("STATUS_NO_SUCH_GROUP","The specified group does not 
exist."),
-        0xC0000067: ("STATUS_MEMBER_IN_GROUP","The specified user account is 
already in the specified group account. Also used to indicate a group cannot be 
deleted because it contains a member."),
-        0xC0000068: ("STATUS_MEMBER_NOT_IN_GROUP","The specified user account 
is not a member of the specified group account."),
-        0xC0000069: ("STATUS_LAST_ADMIN","Indicates the requested operation 
would disable or delete the last remaining administration account. This is not 
allowed to prevent creating a situation in which the system cannot be 
administrated."),
-        0xC000006A: ("STATUS_WRONG_PASSWORD","When trying to update a 
password, this return status indicates that the value provided as the current 
password is not correct."),
-        0xC000006B: ("STATUS_ILL_FORMED_PASSWORD","When trying to update a 
password, this return status indicates that the value provided for the new 
password contains values that are not allowed in passwords."),
-        0xC000006C: ("STATUS_PASSWORD_RESTRICTION","When trying to update a 
password, this status indicates that some password update rule has been 
violated. For example, the password may not meet length criteria."),
-        0xC000006D: ("STATUS_LOGON_FAILURE","The attempted logon is invalid. 
This is either due to a bad username or authentication information."),
-        0xC000006E: ("STATUS_ACCOUNT_RESTRICTION","Indicates a referenced user 
name and authentication information are valid, but some user account 
restriction has prevented successful authentication (such as time-of-day 
restrictions)."),
-        0xC000006F: ("STATUS_INVALID_LOGON_HOURS","The user account has time 
restrictions and may not be logged onto at this time."),
-        0xC0000070: ("STATUS_INVALID_WORKSTATION","The user account is 
restricted so that it may not be used to log on from the source workstation."),
-        0xC0000071: ("STATUS_PASSWORD_EXPIRED","The user account password has 
expired."),
-        0xC0000072: ("STATUS_ACCOUNT_DISABLED","The referenced account is 
currently disabled and may not be logged on to."),
-        0xC0000073: ("STATUS_NONE_MAPPED","None of the information to be 
translated has been translated."),
-        0xC0000074: ("STATUS_TOO_MANY_LUIDS_REQUESTED","The number of LUIDs 
requested may not be allocated with a single allocation."),
-        0xC0000075: ("STATUS_LUIDS_EXHAUSTED","Indicates there are no more 
LUIDs to allocate."),
-        0xC0000076: ("STATUS_INVALID_SUB_AUTHORITY","Indicates the 
sub-authority value is invalid for the particular use."),
-        0xC0000077: ("STATUS_INVALID_ACL","Indicates the ACL structure is not 
valid."),
-        0xC0000078: ("STATUS_INVALID_SID","Indicates the SID structure is not 
valid."),
-        0xC0000079: ("STATUS_INVALID_SECURITY_DESCR","Indicates the 
SECURITY_DESCRIPTOR structure is not valid."),
-        0xC000007A: ("STATUS_PROCEDURE_NOT_FOUND","Indicates the specified 
procedure address cannot be found in the DLL."),
-        0xC000007B: ("STATUS_INVALID_IMAGE_FORMAT","{Bad Image} %hs is either 
not designed to run on Windows or it contains an error. Try installing the 
program again using the original installation media or contact your system 
administrator or the software vendor for support."),
-        0xC000007C: ("STATUS_NO_TOKEN","An attempt was made to reference a 
token that does not exist. This is typically done by referencing the token that 
is associated with a thread when the thread is not impersonating a client."),
-        0xC000007D: ("STATUS_BAD_INHERITANCE_ACL","Indicates that an attempt 
to build either an inherited ACL or ACE was not successful. This can be caused 
by a number of things. One of the more probable causes is the replacement of a 
CreatorId with a SID that did not fit into the ACE or ACL."),
-        0xC000007E: ("STATUS_RANGE_NOT_LOCKED","The range specified in 
NtUnlockFile was not locked."),
-        0xC000007F: ("STATUS_DISK_FULL","An operation failed because the disk 
was full."),
-        0xC0000080: ("STATUS_SERVER_DISABLED","The GUID allocation server is 
disabled at the moment."),
-        0xC0000081: ("STATUS_SERVER_NOT_DISABLED","The GUID allocation server 
is enabled at the moment."),
-        0xC0000082: ("STATUS_TOO_MANY_GUIDS_REQUESTED","Too many GUIDs were 
requested from the allocation server at once."),
-        0xC0000083: ("STATUS_GUIDS_EXHAUSTED","The GUIDs could not be 
allocated because the Authority Agent was exhausted."),
-        0xC0000084: ("STATUS_INVALID_ID_AUTHORITY","The value provided was an 
invalid value for an identifier authority."),
-        0xC0000085: ("STATUS_AGENTS_EXHAUSTED","No more authority agent values 
are available for the particular identifier authority value."),
-        0xC0000086: ("STATUS_INVALID_VOLUME_LABEL","An invalid volume label 
has been specified."),
-        0xC0000087: ("STATUS_SECTION_NOT_EXTENDED","A mapped section could not 
be extended."),
-        0xC0000088: ("STATUS_NOT_MAPPED_DATA","Specified section to flush does 
not map a data file."),
-        0xC0000089: ("STATUS_RESOURCE_DATA_NOT_FOUND","Indicates the specified 
image file did not contain a resource section."),
-        0xC000008A: ("STATUS_RESOURCE_TYPE_NOT_FOUND","Indicates the specified 
resource type cannot be found in the image file."),
-        0xC000008B: ("STATUS_RESOURCE_NAME_NOT_FOUND","Indicates the specified 
resource name cannot be found in the image file."),
-        0xC000008C: ("STATUS_ARRAY_BOUNDS_EXCEEDED","{EXCEPTION} Array bounds 
exceeded."),
-        0xC000008D: ("STATUS_FLOAT_DENORMAL_OPERAND","{EXCEPTION} 
Floating-point denormal operand."),
-        0xC000008E: ("STATUS_FLOAT_DIVIDE_BY_ZERO","{EXCEPTION} Floating-point 
division by zero."),
-        0xC000008F: ("STATUS_FLOAT_INEXACT_RESULT","{EXCEPTION} Floating-point 
inexact result."),
-        0xC0000090: ("STATUS_FLOAT_INVALID_OPERATION","{EXCEPTION} 
Floating-point invalid operation."),
-        0xC0000091: ("STATUS_FLOAT_OVERFLOW","{EXCEPTION} Floating-point 
overflow."),
-        0xC0000092: ("STATUS_FLOAT_STACK_CHECK","{EXCEPTION} Floating-point 
stack check."),
-        0xC0000093: ("STATUS_FLOAT_UNDERFLOW","{EXCEPTION} Floating-point 
underflow."),
-        0xC0000094: ("STATUS_INTEGER_DIVIDE_BY_ZERO","{EXCEPTION} Integer 
division by zero."),
-        0xC0000095: ("STATUS_INTEGER_OVERFLOW","{EXCEPTION} Integer 
overflow."),
-        0xC0000096: ("STATUS_PRIVILEGED_INSTRUCTION","{EXCEPTION} Privileged 
instruction."),
-        0xC0000097: ("STATUS_TOO_MANY_PAGING_FILES","An attempt was made to 
install more paging files than the system supports."),
-        0xC0000098: ("STATUS_FILE_INVALID","The volume for a file has been 
externally altered such that the opened file is no longer valid."),
-        0xC0000099: ("STATUS_ALLOTTED_SPACE_EXCEEDED","When a block of memory 
is allotted for future updates, such as the memory allocated to hold 
discretionary access control and primary group information, successive updates 
may exceed the amount of memory originally allotted. Because a quota may 
already have been charged to several processes that have handles to the object, 
it is not reasonable to alter the size of the allocated memory. Instead, a 
request that requires more memory than [...]
-        0xC000009A: ("STATUS_INSUFFICIENT_RESOURCES","Insufficient system 
resources exist to complete the API."),
-        0xC000009B: ("STATUS_DFS_EXIT_PATH_FOUND","An attempt has been made to 
open a DFS exit path control file."),
-        0xC000009C: ("STATUS_DEVICE_DATA_ERROR","There are bad blocks 
(sectors) on the hard disk."),
-        0xC000009D: ("STATUS_DEVICE_NOT_CONNECTED","There is bad cabling, 
non-termination, or the controller is not able to obtain access to the hard 
disk."),
-        0xC000009F: ("STATUS_FREE_VM_NOT_AT_BASE","Virtual memory cannot be 
freed because the base address is not the base of the region and a region size 
of zero was specified."),
-        0xC00000A0: ("STATUS_MEMORY_NOT_ALLOCATED","An attempt was made to 
free virtual memory that is not allocated."),
-        0xC00000A1: ("STATUS_WORKING_SET_QUOTA","The working set is not big 
enough to allow the requested pages to be locked."),
-        0xC00000A2: ("STATUS_MEDIA_WRITE_PROTECTED","{Write Protect Error} The 
disk cannot be written to because it is write-protected. Remove the write 
protection from the volume %hs in drive %hs."),
-        0xC00000A3: ("STATUS_DEVICE_NOT_READY","{Drive Not Ready} The drive is 
not ready for use; its door may be open. Check drive %hs and make sure that a 
disk is inserted and that the drive door is closed."),
-        0xC00000A4: ("STATUS_INVALID_GROUP_ATTRIBUTES","The specified 
attributes are invalid or are incompatible with the attributes for the group as 
a whole."),
-        0xC00000A5: ("STATUS_BAD_IMPERSONATION_LEVEL","A specified 
impersonation level is invalid. Also used to indicate that a required 
impersonation level was not provided."),
-        0xC00000A6: ("STATUS_CANT_OPEN_ANONYMOUS","An attempt was made to open 
an anonymous-level token. Anonymous tokens may not be opened."),
-        0xC00000A7: ("STATUS_BAD_VALIDATION_CLASS","The validation information 
class requested was invalid."),
-        0xC00000A8: ("STATUS_BAD_TOKEN_TYPE","The type of a token object is 
inappropriate for its attempted use."),
-        0xC00000A9: ("STATUS_BAD_MASTER_BOOT_RECORD","The type of a token 
object is inappropriate for its attempted use."),
-        0xC00000AA: ("STATUS_INSTRUCTION_MISALIGNMENT","An attempt was made to 
execute an instruction at an unaligned address and the host system does not 
support unaligned instruction references."),
-        0xC00000AB: ("STATUS_INSTANCE_NOT_AVAILABLE","The maximum named pipe 
instance count has been reached."),
-        0xC00000AC: ("STATUS_PIPE_NOT_AVAILABLE","An instance of a named pipe 
cannot be found in the listening state."),
-        0xC00000AD: ("STATUS_INVALID_PIPE_STATE","The named pipe is not in the 
connected or closing state."),
-        0xC00000AE: ("STATUS_PIPE_BUSY","The specified pipe is set to complete 
operations and there are current I/O operations queued so that it cannot be 
changed to queue operations."),
-        0xC00000AF: ("STATUS_ILLEGAL_FUNCTION","The specified handle is not 
open to the server end of the named pipe."),
-        0xC00000B0: ("STATUS_PIPE_DISCONNECTED","The specified named pipe is 
in the disconnected state."),
-        0xC00000B1: ("STATUS_PIPE_CLOSING","The specified named pipe is in the 
closing state."),
-        0xC00000B2: ("STATUS_PIPE_CONNECTED","The specified named pipe is in 
the connected state."),
-        0xC00000B3: ("STATUS_PIPE_LISTENING","The specified named pipe is in 
the listening state."),
-        0xC00000B4: ("STATUS_INVALID_READ_MODE","The specified named pipe is 
not in message mode."),
-        0xC00000B5: ("STATUS_IO_TIMEOUT","{Device Timeout} The specified I/O 
operation on %hs was not completed before the time-out period expired."),
-        0xC00000B6: ("STATUS_FILE_FORCED_CLOSED","The specified file has been 
closed by another process."),
-        0xC00000B7: ("STATUS_PROFILING_NOT_STARTED","Profiling is not 
started."),
-        0xC00000B8: ("STATUS_PROFILING_NOT_STOPPED","Profiling is not 
stopped."),
-        0xC00000B9: ("STATUS_COULD_NOT_INTERPRET","The passed ACL did not 
contain the minimum required information."),
-        0xC00000BA: ("STATUS_FILE_IS_A_DIRECTORY","The file that was specified 
as a target is a directory, and the caller specified that it could be anything 
but a directory."),
-        0xC00000BB: ("STATUS_NOT_SUPPORTED","The request is not supported."),
-        0xC00000BC: ("STATUS_REMOTE_NOT_LISTENING","This remote computer is 
not listening."),
-        0xC00000BD: ("STATUS_DUPLICATE_NAME","A duplicate name exists on the 
network."),
-        0xC00000BE: ("STATUS_BAD_NETWORK_PATH","The network path cannot be 
located."),
-        0xC00000BF: ("STATUS_NETWORK_BUSY","The network is busy."),
-        0xC00000C0: ("STATUS_DEVICE_DOES_NOT_EXIST","This device does not 
exist."),
-        0xC00000C1: ("STATUS_TOO_MANY_COMMANDS","The network BIOS command 
limit has been reached."),
-        0xC00000C2: ("STATUS_ADAPTER_HARDWARE_ERROR","An I/O adapter hardware 
error has occurred."),
-        0xC00000C3: ("STATUS_INVALID_NETWORK_RESPONSE","The network responded 
incorrectly."),
-        0xC00000C4: ("STATUS_UNEXPECTED_NETWORK_ERROR","An unexpected network 
error occurred."),
-        0xC00000C5: ("STATUS_BAD_REMOTE_ADAPTER","The remote adapter is not 
compatible."),
-        0xC00000C6: ("STATUS_PRINT_QUEUE_FULL","The print queue is full."),
-        0xC00000C7: ("STATUS_NO_SPOOL_SPACE","Space to store the file that is 
waiting to be printed is not available on the server."),
-        0xC00000C8: ("STATUS_PRINT_CANCELLED","The requested print file has 
been canceled."),
-        0xC00000C9: ("STATUS_NETWORK_NAME_DELETED","The network name was 
deleted."),
-        0xC00000CA: ("STATUS_NETWORK_ACCESS_DENIED","Network access is 
denied."),
-        0xC00000CB: ("STATUS_BAD_DEVICE_TYPE","{Incorrect Network Resource 
Type} The specified device type (LPT, for example) conflicts with the actual 
device type on the remote resource."),
-        0xC00000CC: ("STATUS_BAD_NETWORK_NAME","{Network Name Not Found} The 
specified share name cannot be found on the remote server."),
-        0xC00000CD: ("STATUS_TOO_MANY_NAMES","The name limit for the network 
adapter card of the local computer was exceeded."),
-        0xC00000CE: ("STATUS_TOO_MANY_SESSIONS","The network BIOS session 
limit was exceeded."),
-        0xC00000CF: ("STATUS_SHARING_PAUSED","File sharing has been 
temporarily paused."),
-        0xC00000D0: ("STATUS_REQUEST_NOT_ACCEPTED","No more connections can be 
made to this remote computer at this time because the computer has already 
accepted the maximum number of connections."),
-        0xC00000D1: ("STATUS_REDIRECTOR_PAUSED","Print or disk redirection is 
temporarily paused."),
-        0xC00000D2: ("STATUS_NET_WRITE_FAULT","A network data fault 
occurred."),
-        0xC00000D3: ("STATUS_PROFILING_AT_LIMIT","The number of active 
profiling objects is at the maximum and no more may be started."),
-        0xC00000D4: ("STATUS_NOT_SAME_DEVICE","{Incorrect Volume} The 
destination file of a rename request is located on a different device than the 
source of the rename request."),
-        0xC00000D5: ("STATUS_FILE_RENAMED","The specified file has been 
renamed and thus cannot be modified."),
-        0xC00000D6: ("STATUS_VIRTUAL_CIRCUIT_CLOSED","{Network Request 
Timeout} The session with a remote server has been disconnected because the 
time-out interval for a request has expired."),
-        0xC00000D7: ("STATUS_NO_SECURITY_ON_OBJECT","Indicates an attempt was 
made to operate on the security of an object that does not have security 
associated with it."),
-        0xC00000D8: ("STATUS_CANT_WAIT","Used to indicate that an operation 
cannot continue without blocking for I/O."),
-        0xC00000D9: ("STATUS_PIPE_EMPTY","Used to indicate that a read 
operation was done on an empty pipe."),
-        0xC00000DA: ("STATUS_CANT_ACCESS_DOMAIN_INFO","Configuration 
information could not be read from the domain controller, either because the 
machine is unavailable or access has been denied."),
-        0xC00000DB: ("STATUS_CANT_TERMINATE_SELF","Indicates that a thread 
attempted to terminate itself by default (called NtTerminateThread with NULL) 
and it was the last thread in the current process."),
-        0xC00000DC: ("STATUS_INVALID_SERVER_STATE","Indicates the Sam Server 
was in the wrong state to perform the desired operation."),
-        0xC00000DD: ("STATUS_INVALID_DOMAIN_STATE","Indicates the domain was 
in the wrong state to perform the desired operation."),
-        0xC00000DE: ("STATUS_INVALID_DOMAIN_ROLE","This operation is only 
allowed for the primary domain controller of the domain."),
-        0xC00000DF: ("STATUS_NO_SUCH_DOMAIN","The specified domain did not 
exist."),
-        0xC00000E0: ("STATUS_DOMAIN_EXISTS","The specified domain already 
exists."),
-        0xC00000E1: ("STATUS_DOMAIN_LIMIT_EXCEEDED","An attempt was made to 
exceed the limit on the number of domains per server for this release."),
-        0xC00000E2: ("STATUS_OPLOCK_NOT_GRANTED","An error status returned 
when the opportunistic lock (oplock) request is denied."),
-        0xC00000E3: ("STATUS_INVALID_OPLOCK_PROTOCOL","An error status 
returned when an invalid opportunistic lock (oplock) acknowledgment is received 
by a file system."),
-        0xC00000E4: ("STATUS_INTERNAL_DB_CORRUPTION","This error indicates 
that the requested operation cannot be completed due to a catastrophic media 
failure or an on-disk data structure corruption."),
-        0xC00000E5: ("STATUS_INTERNAL_ERROR","An internal error occurred."),
-        0xC00000E6: ("STATUS_GENERIC_NOT_MAPPED","Indicates generic access 
types were contained in an access mask which should already be mapped to 
non-generic access types."),
-        0xC00000E7: ("STATUS_BAD_DESCRIPTOR_FORMAT","Indicates a security 
descriptor is not in the necessary format (absolute or self-relative)."),
-        0xC00000E8: ("STATUS_INVALID_USER_BUFFER","An access to a user buffer 
failed at an expected point in time. This code is defined because the caller 
does not want to accept STATUS_ACCESS_VIOLATION in its filter."),
-        0xC00000E9: ("STATUS_UNEXPECTED_IO_ERROR","If an I/O error that is not 
defined in the standard FsRtl filter is returned, it is converted to the 
following error, which is guaranteed to be in the filter. In this case, 
information is lost; however, the filter correctly handles the exception."),
-        0xC00000EA: ("STATUS_UNEXPECTED_MM_CREATE_ERR","If an MM error that is 
not defined in the standard FsRtl filter is returned, it is converted to one of 
the following errors, which are guaranteed to be in the filter. In this case, 
information is lost; however, the filter correctly handles the exception."),
-        0xC00000EB: ("STATUS_UNEXPECTED_MM_MAP_ERROR","If an MM error that is 
not defined in the standard FsRtl filter is returned, it is converted to one of 
the following errors, which are guaranteed to be in the filter. In this case, 
information is lost; however, the filter correctly handles the exception."),
-        0xC00000EC: ("STATUS_UNEXPECTED_MM_EXTEND_ERR","If an MM error that is 
not defined in the standard FsRtl filter is returned, it is converted to one of 
the following errors, which are guaranteed to be in the filter. In this case, 
information is lost; however, the filter correctly handles the exception."),
-        0xC00000ED: ("STATUS_NOT_LOGON_PROCESS","The requested action is 
restricted for use by logon processes only. The calling process has not 
registered as a logon process."),
-        0xC00000EE: ("STATUS_LOGON_SESSION_EXISTS","An attempt has been made 
to start a new session manager or LSA logon session by using an ID that is 
already in use."),
-        0xC00000EF: ("STATUS_INVALID_PARAMETER_1","An invalid parameter was 
passed to a service or function as the first argument."),
-        0xC00000F0: ("STATUS_INVALID_PARAMETER_2","An invalid parameter was 
passed to a service or function as the second argument."),
-        0xC00000F1: ("STATUS_INVALID_PARAMETER_3","An invalid parameter was 
passed to a service or function as the third argument."),
-        0xC00000F2: ("STATUS_INVALID_PARAMETER_4","An invalid parameter was 
passed to a service or function as the fourth argument."),
-        0xC00000F3: ("STATUS_INVALID_PARAMETER_5","An invalid parameter was 
passed to a service or function as the fifth argument."),
-        0xC00000F4: ("STATUS_INVALID_PARAMETER_6","An invalid parameter was 
passed to a service or function as the sixth argument."),
-        0xC00000F5: ("STATUS_INVALID_PARAMETER_7","An invalid parameter was 
passed to a service or function as the seventh argument."),
-        0xC00000F6: ("STATUS_INVALID_PARAMETER_8","An invalid parameter was 
passed to a service or function as the eighth argument."),
-        0xC00000F7: ("STATUS_INVALID_PARAMETER_9","An invalid parameter was 
passed to a service or function as the ninth argument."),
-        0xC00000F8: ("STATUS_INVALID_PARAMETER_10","An invalid parameter was 
passed to a service or function as the tenth argument."),
-        0xC00000F9: ("STATUS_INVALID_PARAMETER_11","An invalid parameter was 
passed to a service or function as the eleventh argument."),
-        0xC00000FA: ("STATUS_INVALID_PARAMETER_12","An invalid parameter was 
passed to a service or function as the twelfth argument."),
-        0xC00000FB: ("STATUS_REDIRECTOR_NOT_STARTED","An attempt was made to 
access a network file, but the network software was not yet started."),
-        0xC00000FC: ("STATUS_REDIRECTOR_STARTED","An attempt was made to start 
the redirector, but the redirector has already been started."),
-        0xC00000FD: ("STATUS_STACK_OVERFLOW","A new guard page for the stack 
cannot be created."),
-        0xC00000FE: ("STATUS_NO_SUCH_PACKAGE","A specified authentication 
package is unknown."),
-        0xC00000FF: ("STATUS_BAD_FUNCTION_TABLE","A malformed function table 
was encountered during an unwind operation."),
-        0xC0000100: ("STATUS_VARIABLE_NOT_FOUND","Indicates the specified 
environment variable name was not found in the specified environment block."),
-        0xC0000101: ("STATUS_DIRECTORY_NOT_EMPTY","Indicates that the 
directory trying to be deleted is not empty."),
-        0xC0000102: ("STATUS_FILE_CORRUPT_ERROR","{Corrupt File} The file or 
directory %hs is corrupt and unreadable. Run the Chkdsk utility."),
-        0xC0000103: ("STATUS_NOT_A_DIRECTORY","A requested opened file is not 
a directory."),
-        0xC0000104: ("STATUS_BAD_LOGON_SESSION_STATE","The logon session is 
not in a state that is consistent with the requested operation."),
-        0xC0000105: ("STATUS_LOGON_SESSION_COLLISION","An internal LSA error 
has occurred. An authentication package has requested the creation of a logon 
session but the ID of an already existing logon session has been specified."),
-        0xC0000106: ("STATUS_NAME_TOO_LONG","A specified name string is too 
long for its intended use."),
-        0xC0000107: ("STATUS_FILES_OPEN","The user attempted to force close 
the files on a redirected drive, but there were opened files on the drive, and 
the user did not specify a sufficient level of force."),
-        0xC0000108: ("STATUS_CONNECTION_IN_USE","The user attempted to force 
close the files on a redirected drive, but there were opened directories on the 
drive, and the user did not specify a sufficient level of force."),
-        0xC0000109: ("STATUS_MESSAGE_NOT_FOUND","RtlFindMessage could not 
locate the requested message ID in the message table resource."),
-        0xC000010A: ("STATUS_PROCESS_IS_TERMINATING","An attempt was made to 
duplicate an object handle into or out of an exiting process."),
-        0xC000010B: ("STATUS_INVALID_LOGON_TYPE","Indicates an invalid value 
has been provided for the LogonType requested."),
-        0xC000010C: ("STATUS_NO_GUID_TRANSLATION","Indicates that an attempt 
was made to assign protection to a file system file or directory and one of the 
SIDs in the security descriptor could not be translated into a GUID that could 
be stored by the file system. This causes the protection attempt to fail, which 
may cause a file creation attempt to fail."),
-        0xC000010D: ("STATUS_CANNOT_IMPERSONATE","Indicates that an attempt 
has been made to impersonate via a named pipe that has not yet been read 
from."),
-        0xC000010E: ("STATUS_IMAGE_ALREADY_LOADED","Indicates that the 
specified image is already loaded."),
-        0xC0000117: ("STATUS_NO_LDT","Indicates that an attempt was made to 
change the size of the LDT for a process that has no LDT."),
-        0xC0000118: ("STATUS_INVALID_LDT_SIZE","Indicates that an attempt was 
made to grow an LDT by setting its size, or that the size was not an even 
number of selectors."),
-        0xC0000119: ("STATUS_INVALID_LDT_OFFSET","Indicates that the starting 
value for the LDT information was not an integral multiple of the selector 
size."),
-        0xC000011A: ("STATUS_INVALID_LDT_DESCRIPTOR","Indicates that the user 
supplied an invalid descriptor when trying to set up LDT descriptors."),
-        0xC000011B: ("STATUS_INVALID_IMAGE_NE_FORMAT","The specified image 
file did not have the correct format. It appears to be NE format."),
-        0xC000011C: ("STATUS_RXACT_INVALID_STATE","Indicates that the 
transaction state of a registry subtree is incompatible with the requested 
operation. For example, a request has been made to start a new transaction with 
one already in progress, or a request has been made to apply a transaction when 
one is not currently in progress."),
-        0xC000011D: ("STATUS_RXACT_COMMIT_FAILURE","Indicates an error has 
occurred during a registry transaction commit. The database has been left in an 
unknown, but probably inconsistent, state. The state of the registry 
transaction is left as COMMITTING."),
-        0xC000011E: ("STATUS_MAPPED_FILE_SIZE_ZERO","An attempt was made to 
map a file of size zero with the maximum size specified as zero."),
-        0xC000011F: ("STATUS_TOO_MANY_OPENED_FILES","Too many files are opened 
on a remote server. This error should only be returned by the Windows 
redirector on a remote drive."),
-        0xC0000120: ("STATUS_CANCELLED","The I/O request was canceled."),
-        0xC0000121: ("STATUS_CANNOT_DELETE","An attempt has been made to 
remove a file or directory that cannot be deleted."),
-        0xC0000122: ("STATUS_INVALID_COMPUTER_NAME","Indicates a name that was 
specified as a remote computer name is syntactically invalid."),
-        0xC0000123: ("STATUS_FILE_DELETED","An I/O request other than close 
was performed on a file after it was deleted, which can only happen to a 
request that did not complete before the last handle was closed via NtClose."),
-        0xC0000124: ("STATUS_SPECIAL_ACCOUNT","Indicates an operation that is 
incompatible with built-in accounts has been attempted on a built-in (special) 
SAM account. For example, built-in accounts cannot be deleted."),
-        0xC0000125: ("STATUS_SPECIAL_GROUP","The operation requested may not 
be performed on the specified group because it is a built-in special group."),
-        0xC0000126: ("STATUS_SPECIAL_USER","The operation requested may not be 
performed on the specified user because it is a built-in special user."),
-        0xC0000127: ("STATUS_MEMBERS_PRIMARY_GROUP","Indicates a member cannot 
be removed from a group because the group is currently the member's primary 
group."),
-        0xC0000128: ("STATUS_FILE_CLOSED","An I/O request other than close and 
several other special case operations was attempted using a file object that 
had already been closed."),
-        0xC0000129: ("STATUS_TOO_MANY_THREADS","Indicates a process has too 
many threads to perform the requested action. For example, assignment of a 
primary token may only be performed when a process has zero or one threads."),
-        0xC000012A: ("STATUS_THREAD_NOT_IN_PROCESS","An attempt was made to 
operate on a thread within a specific process, but the specified thread is not 
in the specified process."),
-        0xC000012B: ("STATUS_TOKEN_ALREADY_IN_USE","An attempt was made to 
establish a token for use as a primary token but the token is already in use. A 
token can only be the primary token of one process at a time."),
-        0xC000012C: ("STATUS_PAGEFILE_QUOTA_EXCEEDED","The page file quota was 
exceeded."),
-        0xC000012D: ("STATUS_COMMITMENT_LIMIT","{Out of Virtual Memory} Your 
system is low on virtual memory. To ensure that Windows runs correctly, 
increase the size of your virtual memory paging file. For more information, see 
Help."),
-        0xC000012E: ("STATUS_INVALID_IMAGE_LE_FORMAT","The specified image 
file did not have the correct format: it appears to be LE format."),
-        0xC000012F: ("STATUS_INVALID_IMAGE_NOT_MZ","The specified image file 
did not have the correct format: it did not have an initial MZ."),
-        0xC0000130: ("STATUS_INVALID_IMAGE_PROTECT","The specified image file 
did not have the correct format: it did not have a proper e_lfarlc in the MZ 
header."),
-        0xC0000131: ("STATUS_INVALID_IMAGE_WIN_16","The specified image file 
did not have the correct format: it appears to be a 16-bit Windows image."),
-        0xC0000132: ("STATUS_LOGON_SERVER_CONFLICT","The Netlogon service 
cannot start because another Netlogon service running in the domain conflicts 
with the specified role."),
-        0xC0000133: ("STATUS_TIME_DIFFERENCE_AT_DC","The time at the primary 
domain controller is different from the time at the backup domain controller or 
member server by too large an amount."),
-        0xC0000134: ("STATUS_SYNCHRONIZATION_REQUIRED","The SAM database on a 
Windows Server is significantly out of synchronization with the copy on the 
domain controller. A complete synchronization is required."),
-        0xC0000135: ("STATUS_DLL_NOT_FOUND","{Unable To Locate Component} This 
application has failed to start because %hs was not found. Reinstalling the 
application may fix this problem."),
-        0xC0000136: ("STATUS_OPEN_FAILED","The NtCreateFile API failed. This 
error should never be returned to an application; it is a place holder for the 
Windows LAN Manager Redirector to use in its internal error-mapping routines."),
-        0xC0000137: ("STATUS_IO_PRIVILEGE_FAILED","{Privilege Failed} The I/O 
permissions for the process could not be changed."),
-        0xC0000138: ("STATUS_ORDINAL_NOT_FOUND","{Ordinal Not Found} The 
ordinal %ld could not be located in the dynamic link library %hs."),
-        0xC0000139: ("STATUS_ENTRYPOINT_NOT_FOUND","{Entry Point Not Found} 
The procedure entry point %hs could not be located in the dynamic link library 
%hs."),
-        0xC000013A: ("STATUS_CONTROL_C_EXIT","{Application Exit by CTRL+C} The 
application terminated as a result of a CTRL+C."),
-        0xC000013B: ("STATUS_LOCAL_DISCONNECT","{Virtual Circuit Closed} The 
network transport on your computer has closed a network connection. There may 
or may not be I/O requests outstanding."),
-        0xC000013C: ("STATUS_REMOTE_DISCONNECT","{Virtual Circuit Closed} The 
network transport on a remote computer has closed a network connection. There 
may or may not be I/O requests outstanding."),
-        0xC000013D: ("STATUS_REMOTE_RESOURCES","{Insufficient Resources on 
Remote Computer} The remote computer has insufficient resources to complete the 
network request. For example, the remote computer may not have enough available 
memory to carry out the request at this time."),
-        0xC000013E: ("STATUS_LINK_FAILED","{Virtual Circuit Closed} An 
existing connection (virtual circuit) has been broken at the remote computer. 
There is probably something wrong with the network software protocol or the 
network hardware on the remote computer."),
-        0xC000013F: ("STATUS_LINK_TIMEOUT","{Virtual Circuit Closed} The 
network transport on your computer has closed a network connection because it 
had to wait too long for a response from the remote computer."),
-        0xC0000140: ("STATUS_INVALID_CONNECTION","The connection handle that 
was given to the transport was invalid."),
-        0xC0000141: ("STATUS_INVALID_ADDRESS","The address handle that was 
given to the transport was invalid."),
-        0xC0000142: ("STATUS_DLL_INIT_FAILED","{DLL Initialization Failed} 
Initialization of the dynamic link library %hs failed. The process is 
terminating abnormally."),
-        0xC0000143: ("STATUS_MISSING_SYSTEMFILE","{Missing System File} The 
required system file %hs is bad or missing."),
-        0xC0000144: ("STATUS_UNHANDLED_EXCEPTION","{Application Error} The 
exception %s (0x%08lx) occurred in the application at location 0x%08lx."),
-        0xC0000145: ("STATUS_APP_INIT_FAILURE","{Application Error} The 
application failed to initialize properly (0x%lx). Click OK to terminate the 
application."),
-        0xC0000146: ("STATUS_PAGEFILE_CREATE_FAILED","{Unable to Create Paging 
File} The creation of the paging file %hs failed (%lx). The requested size was 
%ld."),
-        0xC0000147: ("STATUS_NO_PAGEFILE","{No Paging File Specified} No 
paging file was specified in the system configuration."),
-        0xC0000148: ("STATUS_INVALID_LEVEL","{Incorrect System Call Level} An 
invalid level was passed into the specified system call."),
-        0xC0000149: ("STATUS_WRONG_PASSWORD_CORE","{Incorrect Password to LAN 
Manager Server} You specified an incorrect password to a LAN Manager 2.x or 
MS-NET server."),
-        0xC000014A: ("STATUS_ILLEGAL_FLOAT_CONTEXT","{EXCEPTION} A real-mode 
application issued a floating-point instruction and floating-point hardware is 
not present."),
-        0xC000014B: ("STATUS_PIPE_BROKEN","The pipe operation has failed 
because the other end of the pipe has been closed."),
-        0xC000014C: ("STATUS_REGISTRY_CORRUPT","{The Registry Is Corrupt} The 
structure of one of the files that contains registry data is corrupt; the image 
of the file in memory is corrupt; or the file could not be recovered because 
the alternate copy or log was absent or corrupt."),
-        0xC000014D: ("STATUS_REGISTRY_IO_FAILED","An I/O operation initiated 
by the Registry failed and cannot be recovered. The registry could not read in, 
write out, or flush one of the files that contain the system's image of the 
registry."),
-        0xC000014E: ("STATUS_NO_EVENT_PAIR","An event pair synchronization 
operation was performed using the thread-specific client/server event pair 
object, but no event pair object was associated with the thread."),
-        0xC000014F: ("STATUS_UNRECOGNIZED_VOLUME","The volume does not contain 
a recognized file system. Be sure that all required file system drivers are 
loaded and that the volume is not corrupt."),
-        0xC0000150: ("STATUS_SERIAL_NO_DEVICE_INITED","No serial device was 
successfully initialized. The serial driver will unload."),
-        0xC0000151: ("STATUS_NO_SUCH_ALIAS","The specified local group does 
not exist."),
-        0xC0000152: ("STATUS_MEMBER_NOT_IN_ALIAS","The specified account name 
is not a member of the group."),
-        0xC0000153: ("STATUS_MEMBER_IN_ALIAS","The specified account name is 
already a member of the group."),
-        0xC0000154: ("STATUS_ALIAS_EXISTS","The specified local group already 
exists."),
-        0xC0000155: ("STATUS_LOGON_NOT_GRANTED","A requested type of logon 
(for example, interactive, network, and service) is not granted by the local 
security policy of the target system. Ask the system administrator to grant the 
necessary form of logon."),
-        0xC0000156: ("STATUS_TOO_MANY_SECRETS","The maximum number of secrets 
that may be stored in a single system was exceeded. The length and number of 
secrets is limited to satisfy U.S. State Department export restrictions."),
-        0xC0000157: ("STATUS_SECRET_TOO_LONG","The length of a secret exceeds 
the maximum allowable length. The length and number of secrets is limited to 
satisfy U.S. State Department export restrictions."),
-        0xC0000158: ("STATUS_INTERNAL_DB_ERROR","The local security authority 
(LSA) database contains an internal inconsistency."),
-        0xC0000159: ("STATUS_FULLSCREEN_MODE","The requested operation cannot 
be performed in full-screen mode."),
-        0xC000015A: ("STATUS_TOO_MANY_CONTEXT_IDS","During a logon attempt, 
the user's security context accumulated too many security IDs. This is a very 
unusual situation. Remove the user from some global or local groups to reduce 
the number of security IDs to incorporate into the security context."),
-        0xC000015B: ("STATUS_LOGON_TYPE_NOT_GRANTED","A user has requested a 
type of logon (for example, interactive or network) that has not been granted. 
An administrator has control over who may logon interactively and through the 
network."),
-        0xC000015C: ("STATUS_NOT_REGISTRY_FILE","The system has attempted to 
load or restore a file into the registry, and the specified file is not in the 
format of a registry file."),
-        0xC000015D: ("STATUS_NT_CROSS_ENCRYPTION_REQUIRED","An attempt was 
made to change a user password in the security account manager without 
providing the necessary Windows cross-encrypted password."),
-        0xC000015E: ("STATUS_DOMAIN_CTRLR_CONFIG_ERROR","A Windows Server has 
an incorrect configuration."),
-        0xC000015F: ("STATUS_FT_MISSING_MEMBER","An attempt was made to 
explicitly access the secondary copy of information via a device control to the 
fault tolerance driver and the secondary copy is not present in the system."),
-        0xC0000160: ("STATUS_ILL_FORMED_SERVICE_ENTRY","A configuration 
registry node that represents a driver service entry was ill-formed and did not 
contain the required value entries."),
-        0xC0000161: ("STATUS_ILLEGAL_CHARACTER","An illegal character was 
encountered. For a multibyte character set, this includes a lead byte without a 
succeeding trail byte. For the Unicode character set this includes the 
characters 0xFFFF and 0xFFFE."),
-        0xC0000162: ("STATUS_UNMAPPABLE_CHARACTER","No mapping for the Unicode 
character exists in the target multibyte code page."),
-        0xC0000163: ("STATUS_UNDEFINED_CHARACTER","The Unicode character is 
not defined in the Unicode character set that is installed on the system."),
-        0xC0000164: ("STATUS_FLOPPY_VOLUME","The paging file cannot be created 
on a floppy disk."),
-        0xC0000165: ("STATUS_FLOPPY_ID_MARK_NOT_FOUND","{Floppy Disk Error} 
While accessing a floppy disk, an ID address mark was not found."),
-        0xC0000166: ("STATUS_FLOPPY_WRONG_CYLINDER","{Floppy Disk Error} While 
accessing a floppy disk, the track address from the sector ID field was found 
to be different from the track address that is maintained by the controller."),
-        0xC0000167: ("STATUS_FLOPPY_UNKNOWN_ERROR","{Floppy Disk Error} The 
floppy disk controller reported an error that is not recognized by the floppy 
disk driver."),
-        0xC0000168: ("STATUS_FLOPPY_BAD_REGISTERS","{Floppy Disk Error} While 
accessing a floppy-disk, the controller returned inconsistent results via its 
registers."),
-        0xC0000169: ("STATUS_DISK_RECALIBRATE_FAILED","{Hard Disk Error} While 
accessing the hard disk, a recalibrate operation failed, even after retries."),
-        0xC000016A: ("STATUS_DISK_OPERATION_FAILED","{Hard Disk Error} While 
accessing the hard disk, a disk operation failed even after retries."),
-        0xC000016B: ("STATUS_DISK_RESET_FAILED","{Hard Disk Error} While 
accessing the hard disk, a disk controller reset was needed, but even that 
failed."),
-        0xC000016C: ("STATUS_SHARED_IRQ_BUSY","An attempt was made to open a 
device that was sharing an interrupt request (IRQ) with other devices. At least 
one other device that uses that IRQ was already opened. Two concurrent opens of 
devices that share an IRQ and only work via interrupts is not supported for the 
particular bus type that the devices use."),
-        0xC000016D: ("STATUS_FT_ORPHANING","{FT Orphaning} A disk that is part 
of a fault-tolerant volume can no longer be accessed."),
-        0xC000016E: ("STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT","The basic 
input/output system (BIOS) failed to connect a system interrupt to the device 
or bus for which the device is connected."),
-        0xC0000172: ("STATUS_PARTITION_FAILURE","The tape could not be 
partitioned."),
-        0xC0000173: ("STATUS_INVALID_BLOCK_LENGTH","When accessing a new tape 
of a multi-volume partition, the current blocksize is incorrect."),
-        0xC0000174: ("STATUS_DEVICE_NOT_PARTITIONED","The tape partition 
information could not be found when loading a tape."),
-        0xC0000175: ("STATUS_UNABLE_TO_LOCK_MEDIA","An attempt to lock the 
eject media mechanism failed."),
-        0xC0000176: ("STATUS_UNABLE_TO_UNLOAD_MEDIA","An attempt to unload 
media failed."),
-        0xC0000177: ("STATUS_EOM_OVERFLOW","The physical end of tape was 
detected."),
-        0xC0000178: ("STATUS_NO_MEDIA","{No Media} There is no media in the 
drive. Insert media into drive %hs."),
-        0xC000017A: ("STATUS_NO_SUCH_MEMBER","A member could not be added to 
or removed from the local group because the member does not exist."),
-        0xC000017B: ("STATUS_INVALID_MEMBER","A new member could not be added 
to a local group because the member has the wrong account type."),
-        0xC000017C: ("STATUS_KEY_DELETED","An illegal operation was attempted 
on a registry key that has been marked for deletion."),
-        0xC000017D: ("STATUS_NO_LOG_SPACE","The system could not allocate the 
required space in a registry log."),
-        0xC000017E: ("STATUS_TOO_MANY_SIDS","Too many SIDs have been 
specified."),
-        0xC000017F: ("STATUS_LM_CROSS_ENCRYPTION_REQUIRED","An attempt was 
made to change a user password in the security account manager without 
providing the necessary LM cross-encrypted password."),
-        0xC0000180: ("STATUS_KEY_HAS_CHILDREN","An attempt was made to create 
a symbolic link in a registry key that already has subkeys or values."),
-        0xC0000181: ("STATUS_CHILD_MUST_BE_VOLATILE","An attempt was made to 
create a stable subkey under a volatile parent key."),
-        0xC0000182: ("STATUS_DEVICE_CONFIGURATION_ERROR","The I/O device is 
configured incorrectly or the configuration parameters to the driver are 
incorrect."),
-        0xC0000183: ("STATUS_DRIVER_INTERNAL_ERROR","An error was detected 
between two drivers or within an I/O driver."),
-        0xC0000184: ("STATUS_INVALID_DEVICE_STATE","The device is not in a 
valid state to perform this request."),
-        0xC0000185: ("STATUS_IO_DEVICE_ERROR","The I/O device reported an I/O 
error."),
-        0xC0000186: ("STATUS_DEVICE_PROTOCOL_ERROR","A protocol error was 
detected between the driver and the device."),
-        0xC0000187: ("STATUS_BACKUP_CONTROLLER","This operation is only 
allowed for the primary domain controller of the domain."),
-        0xC0000188: ("STATUS_LOG_FILE_FULL","The log file space is 
insufficient to support this operation."),
-        0xC0000189: ("STATUS_TOO_LATE","A write operation was attempted to a 
volume after it was dismounted."),
-        0xC000018A: ("STATUS_NO_TRUST_LSA_SECRET","The workstation does not 
have a trust secret for the primary domain in the local LSA database."),
-        0xC000018B: ("STATUS_NO_TRUST_SAM_ACCOUNT","The SAM database on the 
Windows Server does not have a computer account for this workstation trust 
relationship."),
-        0xC000018C: ("STATUS_TRUSTED_DOMAIN_FAILURE","The logon request failed 
because the trust relationship between the primary domain and the trusted 
domain failed."),
-        0xC000018D: ("STATUS_TRUSTED_RELATIONSHIP_FAILURE","The logon request 
failed because the trust relationship between this workstation and the primary 
domain failed."),
-        0xC000018E: ("STATUS_EVENTLOG_FILE_CORRUPT","The Eventlog log file is 
corrupt."),
-        0xC000018F: ("STATUS_EVENTLOG_CANT_START","No Eventlog log file could 
be opened. The Eventlog service did not start."),
-        0xC0000190: ("STATUS_TRUST_FAILURE","The network logon failed. This 
may be because the validation authority cannot be reached."),
-        0xC0000191: ("STATUS_MUTANT_LIMIT_EXCEEDED","An attempt was made to 
acquire a mutant such that its maximum count would have been exceeded."),
-        0xC0000192: ("STATUS_NETLOGON_NOT_STARTED","An attempt was made to 
logon, but the NetLogon service was not started."),
-        0xC0000193: ("STATUS_ACCOUNT_EXPIRED","The user account has expired."),
-        0xC0000194: ("STATUS_POSSIBLE_DEADLOCK","{EXCEPTION} Possible deadlock 
condition."),
-        0xC0000195: ("STATUS_NETWORK_CREDENTIAL_CONFLICT","Multiple 
connections to a server or shared resource by the same user, using more than 
one user name, are not allowed. Disconnect all previous connections to the 
server or shared resource and try again."),
-        0xC0000196: ("STATUS_REMOTE_SESSION_LIMIT","An attempt was made to 
establish a session to a network server, but there are already too many 
sessions established to that server."),
-        0xC0000197: ("STATUS_EVENTLOG_FILE_CHANGED","The log file has changed 
between reads."),
-        0xC0000198: ("STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT","The account 
used is an interdomain trust account. Use your global user account or local 
user account to access this server."),
-        0xC0000199: ("STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT","The account 
used is a computer account. Use your global user account or local user account 
to access this server."),
-        0xC000019A: ("STATUS_NOLOGON_SERVER_TRUST_ACCOUNT","The account used 
is a server trust account. Use your global user account or local user account 
to access this server."),
-        0xC000019B: ("STATUS_DOMAIN_TRUST_INCONSISTENT","The name or SID of 
the specified domain is inconsistent with the trust information for that 
domain."),
-        0xC000019C: ("STATUS_FS_DRIVER_REQUIRED","A volume has been accessed 
for which a file system driver is required that has not yet been loaded."),
-        0xC000019D: ("STATUS_IMAGE_ALREADY_LOADED_AS_DLL","Indicates that the 
specified image is already loaded as a DLL."),
-        0xC000019E: 
("STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING","Short name 
settings may not be changed on this volume due to the global registry 
setting."),
-        0xC000019F: ("STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME","Short names 
are not enabled on this volume."),
-        0xC00001A0: ("STATUS_SECURITY_STREAM_IS_INCONSISTENT","The security 
stream for the given volume is in an inconsistent state. Please run CHKDSK on 
the volume."),
-        0xC00001A1: ("STATUS_INVALID_LOCK_RANGE","A requested file lock 
operation cannot be processed due to an invalid byte range."),
-        0xC00001A2: ("STATUS_INVALID_ACE_CONDITION","The specified access 
control entry (ACE) contains an invalid condition."),
-        0xC00001A3: ("STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT","The subsystem 
needed to support the image type is not present."),
-        0xC00001A4: ("STATUS_NOTIFICATION_GUID_ALREADY_DEFINED","The specified 
file already has a notification GUID associated with it."),
-        0xC0000201: ("STATUS_NETWORK_OPEN_RESTRICTION","A remote open failed 
because the network open restrictions were not satisfied."),
-        0xC0000202: ("STATUS_NO_USER_SESSION_KEY","There is no user session 
key for the specified logon session."),
-        0xC0000203: ("STATUS_USER_SESSION_DELETED","The remote user session 
has been deleted."),
-        0xC0000204: ("STATUS_RESOURCE_LANG_NOT_FOUND","Indicates the specified 
resource language ID cannot be found in the image file."),
-        0xC0000205: ("STATUS_INSUFF_SERVER_RESOURCES","Insufficient server 
resources exist to complete the request."),
-        0xC0000206: ("STATUS_INVALID_BUFFER_SIZE","The size of the buffer is 
invalid for the specified operation."),
-        0xC0000207: ("STATUS_INVALID_ADDRESS_COMPONENT","The transport 
rejected the specified network address as invalid."),
-        0xC0000208: ("STATUS_INVALID_ADDRESS_WILDCARD","The transport rejected 
the specified network address due to invalid use of a wildcard."),
-        0xC0000209: ("STATUS_TOO_MANY_ADDRESSES","The transport address could 
not be opened because all the available addresses are in use."),
-        0xC000020A: ("STATUS_ADDRESS_ALREADY_EXISTS","The transport address 
could not be opened because it already exists."),
-        0xC000020B: ("STATUS_ADDRESS_CLOSED","The transport address is now 
closed."),
-        0xC000020C: ("STATUS_CONNECTION_DISCONNECTED","The transport 
connection is now disconnected."),
-        0xC000020D: ("STATUS_CONNECTION_RESET","The transport connection has 
been reset."),
-        0xC000020E: ("STATUS_TOO_MANY_NODES","The transport cannot dynamically 
acquire any more nodes."),
-        0xC000020F: ("STATUS_TRANSACTION_ABORTED","The transport aborted a 
pending transaction."),
-        0xC0000210: ("STATUS_TRANSACTION_TIMED_OUT","The transport timed out a 
request that is waiting for a response."),
-        0xC0000211: ("STATUS_TRANSACTION_NO_RELEASE","The transport did not 
receive a release for a pending response."),
-        0xC0000212: ("STATUS_TRANSACTION_NO_MATCH","The transport did not find 
a transaction that matches the specific token."),
-        0xC0000213: ("STATUS_TRANSACTION_RESPONDED","The transport had 
previously responded to a transaction request."),
-        0xC0000214: ("STATUS_TRANSACTION_INVALID_ID","The transport does not 
recognize the specified transaction request ID."),
-        0xC0000215: ("STATUS_TRANSACTION_INVALID_TYPE","The transport does not 
recognize the specified transaction request type."),
-        0xC0000216: ("STATUS_NOT_SERVER_SESSION","The transport can only 
process the specified request on the server side of a session."),
-        0xC0000217: ("STATUS_NOT_CLIENT_SESSION","The transport can only 
process the specified request on the client side of a session."),
-        0xC0000218: ("STATUS_CANNOT_LOAD_REGISTRY_FILE","{Registry File 
Failure} The registry cannot load the hive (file): %hs or its log or alternate. 
It is corrupt, absent, or not writable."),
-        0xC0000219: ("STATUS_DEBUG_ATTACH_FAILED","{Unexpected Failure in 
DebugActiveProcess} An unexpected failure occurred while processing a 
DebugActiveProcess API request. You may choose OK to terminate the process, or 
Cancel to ignore the error."),
-        0xC000021A: ("STATUS_SYSTEM_PROCESS_TERMINATED","{Fatal System Error} 
The %hs system process terminated unexpectedly with a status of 0x%08x (0x%08x 
0x%08x). The system has been shut down."),
-        0xC000021B: ("STATUS_DATA_NOT_ACCEPTED","{Data Not Accepted} The TDI 
client could not handle the data received during an indication."),
-        0xC000021C: ("STATUS_NO_BROWSER_SERVERS_FOUND","{Unable to Retrieve 
Browser Server List} The list of servers for this workgroup is not currently 
available."),
-        0xC000021D: ("STATUS_VDM_HARD_ERROR","NTVDM encountered a hard 
error."),
-        0xC000021E: ("STATUS_DRIVER_CANCEL_TIMEOUT","{Cancel Timeout} The 
driver %hs failed to complete a canceled I/O request in the allotted time."),
-        0xC000021F: ("STATUS_REPLY_MESSAGE_MISMATCH","{Reply Message Mismatch} 
An attempt was made to reply to an LPC message, but the thread specified by the 
client ID in the message was not waiting on that message."),
-        0xC0000220: ("STATUS_MAPPED_ALIGNMENT","{Mapped View Alignment 
Incorrect} An attempt was made to map a view of a file, but either the 
specified base address or the offset into the file were not aligned on the 
proper allocation granularity."),
-        0xC0000221: ("STATUS_IMAGE_CHECKSUM_MISMATCH","{Bad Image Checksum} 
The image %hs is possibly corrupt. The header checksum does not match the 
computed checksum."),
-        0xC0000222: ("STATUS_LOST_WRITEBEHIND_DATA","{Delayed Write Failed} 
Windows was unable to save all the data for the file %hs. The data has been 
lost. This error may be caused by a failure of your computer hardware or 
network connection. Try to save this file elsewhere."),
-        0xC0000223: ("STATUS_CLIENT_SERVER_PARAMETERS_INVALID","The parameters 
passed to the server in the client/server shared memory window were invalid. 
Too much data may have been put in the shared memory window."),
-        0xC0000224: ("STATUS_PASSWORD_MUST_CHANGE","The user password must be 
changed before logging on the first time."),
-        0xC0000225: ("STATUS_NOT_FOUND","The object was not found."),
-        0xC0000226: ("STATUS_NOT_TINY_STREAM","The stream is not a tiny 
stream."),
-        0xC0000227: ("STATUS_RECOVERY_FAILURE","A transaction recovery 
failed."),
-        0xC0000228: ("STATUS_STACK_OVERFLOW_READ","The request must be handled 
by the stack overflow code."),
-        0xC0000229: ("STATUS_FAIL_CHECK","A consistency check failed."),
-        0xC000022A: ("STATUS_DUPLICATE_OBJECTID","The attempt to insert the ID 
in the index failed because the ID is already in the index."),
-        0xC000022B: ("STATUS_OBJECTID_EXISTS","The attempt to set the object 
ID failed because the object already has an ID."),
-        0xC000022C: ("STATUS_CONVERT_TO_LARGE","Internal OFS status codes 
indicating how an allocation operation is handled. Either it is retried after 
the containing oNode is moved or the extent stream is converted to a large 
stream."),
-        0xC000022D: ("STATUS_RETRY","The request needs to be retried."),
-        0xC000022E: ("STATUS_FOUND_OUT_OF_SCOPE","The attempt to find the 
object found an object on the volume that matches by ID; however, it is out of 
the scope of the handle that is used for the operation."),
-        0xC000022F: ("STATUS_ALLOCATE_BUCKET","The bucket array must be grown. 
Retry the transaction after doing so."),
-        0xC0000230: ("STATUS_PROPSET_NOT_FOUND","The specified property set 
does not exist on the object."),
-        0xC0000231: ("STATUS_MARSHALL_OVERFLOW","The user/kernel marshaling 
buffer has overflowed."),
-        0xC0000232: ("STATUS_INVALID_VARIANT","The supplied variant structure 
contains invalid data."),
-        0xC0000233: ("STATUS_DOMAIN_CONTROLLER_NOT_FOUND","A domain controller 
for this domain was not found."),
-        0xC0000234: ("STATUS_ACCOUNT_LOCKED_OUT","The user account has been 
automatically locked because too many invalid logon attempts or password change 
attempts have been requested."),
-        0xC0000235: ("STATUS_HANDLE_NOT_CLOSABLE","NtClose was called on a 
handle that was protected from close via NtSetInformationObject."),
-        0xC0000236: ("STATUS_CONNECTION_REFUSED","The transport-connection 
attempt was refused by the remote system."),
-        0xC0000237: ("STATUS_GRACEFUL_DISCONNECT","The transport connection 
was gracefully closed."),
-        0xC0000238: ("STATUS_ADDRESS_ALREADY_ASSOCIATED","The transport 
endpoint already has an address associated with it."),
-        0xC0000239: ("STATUS_ADDRESS_NOT_ASSOCIATED","An address has not yet 
been associated with the transport endpoint."),
-        0xC000023A: ("STATUS_CONNECTION_INVALID","An operation was attempted 
on a nonexistent transport connection."),
-        0xC000023B: ("STATUS_CONNECTION_ACTIVE","An invalid operation was 
attempted on an active transport connection."),
-        0xC000023C: ("STATUS_NETWORK_UNREACHABLE","The remote network is not 
reachable by the transport."),
-        0xC000023D: ("STATUS_HOST_UNREACHABLE","The remote system is not 
reachable by the transport."),
-        0xC000023E: ("STATUS_PROTOCOL_UNREACHABLE","The remote system does not 
support the transport protocol."),
-        0xC000023F: ("STATUS_PORT_UNREACHABLE","No service is operating at the 
destination port of the transport on the remote system."),
-        0xC0000240: ("STATUS_REQUEST_ABORTED","The request was aborted."),
-        0xC0000241: ("STATUS_CONNECTION_ABORTED","The transport connection was 
aborted by the local system."),
-        0xC0000242: ("STATUS_BAD_COMPRESSION_BUFFER","The specified buffer 
contains ill-formed data."),
-        0xC0000243: ("STATUS_USER_MAPPED_FILE","The requested operation cannot 
be performed on a file with a user mapped section open."),
-        0xC0000244: ("STATUS_AUDIT_FAILED","{Audit Failed} An attempt to 
generate a security audit failed."),
-        0xC0000245: ("STATUS_TIMER_RESOLUTION_NOT_SET","The timer resolution 
was not previously set by the current process."),
-        0xC0000246: ("STATUS_CONNECTION_COUNT_LIMIT","A connection to the 
server could not be made because the limit on the number of concurrent 
connections for this account has been reached."),
-        0xC0000247: ("STATUS_LOGIN_TIME_RESTRICTION","Attempting to log on 
during an unauthorized time of day for this account."),
-        0xC0000248: ("STATUS_LOGIN_WKSTA_RESTRICTION","The account is not 
authorized to log on from this station."),
-        0xC0000249: ("STATUS_IMAGE_MP_UP_MISMATCH","{UP/MP Image Mismatch} The 
image %hs has been modified for use on a uniprocessor system, but you are 
running it on a multiprocessor machine. Reinstall the image file."),
-        0xC0000250: ("STATUS_INSUFFICIENT_LOGON_INFO","There is insufficient 
account information to log you on."),
-        0xC0000251: ("STATUS_BAD_DLL_ENTRYPOINT","{Invalid DLL Entrypoint} The 
dynamic link library %hs is not written correctly. The stack pointer has been 
left in an inconsistent state. The entry point should be declared as WINAPI or 
STDCALL. Select YES to fail the DLL load. Select NO to continue execution. 
Selecting NO may cause the application to operate incorrectly."),
-        0xC0000252: ("STATUS_BAD_SERVICE_ENTRYPOINT","{Invalid Service 
Callback Entrypoint} The %hs service is not written correctly. The stack 
pointer has been left in an inconsistent state. The callback entry point should 
be declared as WINAPI or STDCALL. Selecting OK will cause the service to 
continue operation. However, the service process may operate incorrectly."),
-        0xC0000253: ("STATUS_LPC_REPLY_LOST","The server received the messages 
but did not send a reply."),
-        0xC0000254: ("STATUS_IP_ADDRESS_CONFLICT1","There is an IP address 
conflict with another system on the network."),
-        0xC0000255: ("STATUS_IP_ADDRESS_CONFLICT2","There is an IP address 
conflict with another system on the network."),
-        0xC0000256: ("STATUS_REGISTRY_QUOTA_LIMIT","{Low On Registry Space} 
The system has reached the maximum size that is allowed for the system part of 
the registry. Additional storage requests will be ignored."),
-        0xC0000257: ("STATUS_PATH_NOT_COVERED","The contacted server does not 
support the indicated part of the DFS namespace."),
-        0xC0000258: ("STATUS_NO_CALLBACK_ACTIVE","A callback return system 
service cannot be executed when no callback is active."),
-        0xC0000259: ("STATUS_LICENSE_QUOTA_EXCEEDED","The service being 
accessed is licensed for a particular number of connections. No more 
connections can be made to the service at this time because the service has 
already accepted the maximum number of connections."),
-        0xC000025A: ("STATUS_PWD_TOO_SHORT","The password provided is too 
short to meet the policy of your user account. Choose a longer password."),
-        0xC000025B: ("STATUS_PWD_TOO_RECENT","The policy of your user account 
does not allow you to change passwords too frequently. This is done to prevent 
users from changing back to a familiar, but potentially discovered, password. 
If you feel your password has been compromised, contact your administrator 
immediately to have a new one assigned."),
-        0xC000025C: ("STATUS_PWD_HISTORY_CONFLICT","You have attempted to 
change your password to one that you have used in the past. The policy of your 
user account does not allow this. Select a password that you have not 
previously used."),
-        0xC000025E: ("STATUS_PLUGPLAY_NO_DEVICE","You have attempted to load a 
legacy device driver while its device instance had been disabled."),
-        0xC000025F: ("STATUS_UNSUPPORTED_COMPRESSION","The specified 
compression format is unsupported."),
-        0xC0000260: ("STATUS_INVALID_HW_PROFILE","The specified hardware 
profile configuration is invalid."),
-        0xC0000261: ("STATUS_INVALID_PLUGPLAY_DEVICE_PATH","The specified Plug 
and Play registry device path is invalid."),
-        0xC0000262: ("STATUS_DRIVER_ORDINAL_NOT_FOUND","{Driver Entry Point 
Not Found} The %hs device driver could not locate the ordinal %ld in driver 
%hs."),
-        0xC0000263: ("STATUS_DRIVER_ENTRYPOINT_NOT_FOUND","{Driver Entry Point 
Not Found} The %hs device driver could not locate the entry point %hs in driver 
%hs."),
-        0xC0000264: ("STATUS_RESOURCE_NOT_OWNED","{Application Error} The 
application attempted to release a resource it did not own. Click OK to 
terminate the application."),
-        0xC0000265: ("STATUS_TOO_MANY_LINKS","An attempt was made to create 
more links on a file than the file system supports."),
-        0xC0000266: ("STATUS_QUOTA_LIST_INCONSISTENT","The specified quota 
list is internally inconsistent with its descriptor."),
-        0xC0000267: ("STATUS_FILE_IS_OFFLINE","The specified file has been 
relocated to offline storage."),
-        0xC0000268: ("STATUS_EVALUATION_EXPIRATION","{Windows Evaluation 
Notification} The evaluation period for this installation of Windows has 
expired. This system will shutdown in 1 hour. To restore access to this 
installation of Windows, upgrade this installation by using a licensed 
distribution of this product."),
-        0xC0000269: ("STATUS_ILLEGAL_DLL_RELOCATION","{Illegal System DLL 
Relocation} The system DLL %hs was relocated in memory. The application will 
not run properly. The relocation occurred because the DLL %hs occupied an 
address range that is reserved for Windows system DLLs. The vendor supplying 
the DLL should be contacted for a new DLL."),
-        0xC000026A: ("STATUS_LICENSE_VIOLATION","{License Violation} The 
system has detected tampering with your registered product type. This is a 
violation of your software license. Tampering with the product type is not 
permitted."),
-        0xC000026B: ("STATUS_DLL_INIT_FAILED_LOGOFF","{DLL Initialization 
Failed} The application failed to initialize because the window station is 
shutting down."),
-        0xC000026C: ("STATUS_DRIVER_UNABLE_TO_LOAD","{Unable to Load Device 
Driver} %hs device driver could not be loaded. Error Status was 0x%x."),
-        0xC000026D: ("STATUS_DFS_UNAVAILABLE","DFS is unavailable on the 
contacted server."),
-        0xC000026E: ("STATUS_VOLUME_DISMOUNTED","An operation was attempted to 
a volume after it was dismounted."),
-        0xC000026F: ("STATUS_WX86_INTERNAL_ERROR","An internal error occurred 
in the Win32 x86 emulation subsystem."),
-        0xC0000270: ("STATUS_WX86_FLOAT_STACK_CHECK","Win32 x86 emulation 
subsystem floating-point stack check."),
-        0xC0000271: ("STATUS_VALIDATE_CONTINUE","The validation process needs 
to continue on to the next step."),
-        0xC0000272: ("STATUS_NO_MATCH","There was no match for the specified 
key in the index."),
-        0xC0000273: ("STATUS_NO_MORE_MATCHES","There are no more matches for 
the current index enumeration."),
-        0xC0000275: ("STATUS_NOT_A_REPARSE_POINT","The NTFS file or directory 
is not a reparse point."),
-        0xC0000276: ("STATUS_IO_REPARSE_TAG_INVALID","The Windows I/O reparse 
tag passed for the NTFS reparse point is invalid."),
-        0xC0000277: ("STATUS_IO_REPARSE_TAG_MISMATCH","The Windows I/O reparse 
tag does not match the one that is in the NTFS reparse point."),
-        0xC0000278: ("STATUS_IO_REPARSE_DATA_INVALID","The user data passed 
for the NTFS reparse point is invalid."),
-        0xC0000279: ("STATUS_IO_REPARSE_TAG_NOT_HANDLED","The layered file 
system driver for this I/O tag did not handle it when needed."),
-        0xC0000280: ("STATUS_REPARSE_POINT_NOT_RESOLVED","The NTFS symbolic 
link could not be resolved even though the initial file name is valid."),
-        0xC0000281: ("STATUS_DIRECTORY_IS_A_REPARSE_POINT","The NTFS directory 
is a reparse point."),
-        0xC0000282: ("STATUS_RANGE_LIST_CONFLICT","The range could not be 
added to the range list because of a conflict."),
-        0xC0000283: ("STATUS_SOURCE_ELEMENT_EMPTY","The specified medium 
changer source element contains no media."),
-        0xC0000284: ("STATUS_DESTINATION_ELEMENT_FULL","The specified medium 
changer destination element already contains media."),
-        0xC0000285: ("STATUS_ILLEGAL_ELEMENT_ADDRESS","The specified medium 
changer element does not exist."),
-        0xC0000286: ("STATUS_MAGAZINE_NOT_PRESENT","The specified element is 
contained in a magazine that is no longer present."),
-        0xC0000287: ("STATUS_REINITIALIZATION_NEEDED","The device requires 
re-initialization due to hardware errors."),
-        0xC000028A: ("STATUS_ENCRYPTION_FAILED","The file encryption attempt 
failed."),
-        0xC000028B: ("STATUS_DECRYPTION_FAILED","The file decryption attempt 
failed."),
-        0xC000028C: ("STATUS_RANGE_NOT_FOUND","The specified range could not 
be found in the range list."),
-        0xC000028D: ("STATUS_NO_RECOVERY_POLICY","There is no encryption 
recovery policy configured for this system."),
-        0xC000028E: ("STATUS_NO_EFS","The required encryption driver is not 
loaded for this system."),
-        0xC000028F: ("STATUS_WRONG_EFS","The file was encrypted with a 
different encryption driver than is currently loaded."),
-        0xC0000290: ("STATUS_NO_USER_KEYS","There are no EFS keys defined for 
the user."),
-        0xC0000291: ("STATUS_FILE_NOT_ENCRYPTED","The specified file is not 
encrypted."),
-        0xC0000292: ("STATUS_NOT_EXPORT_FORMAT","The specified file is not in 
the defined EFS export format."),
-        0xC0000293: ("STATUS_FILE_ENCRYPTED","The specified file is encrypted 
and the user does not have the ability to decrypt it."),
-        0xC0000295: ("STATUS_WMI_GUID_NOT_FOUND","The GUID passed was not 
recognized as valid by a WMI data provider."),
-        0xC0000296: ("STATUS_WMI_INSTANCE_NOT_FOUND","The instance name passed 
was not recognized as valid by a WMI data provider."),
-        0xC0000297: ("STATUS_WMI_ITEMID_NOT_FOUND","The data item ID passed 
was not recognized as valid by a WMI data provider."),
-        0xC0000298: ("STATUS_WMI_TRY_AGAIN","The WMI request could not be 
completed and should be retried."),
-        0xC0000299: ("STATUS_SHARED_POLICY","The policy object is shared and 
can only be modified at the root."),
-        0xC000029A: ("STATUS_POLICY_OBJECT_NOT_FOUND","The policy object does 
not exist when it should."),
-        0xC000029B: ("STATUS_POLICY_ONLY_IN_DS","The requested policy 
information only lives in the Ds."),
-        0xC000029C: ("STATUS_VOLUME_NOT_UPGRADED","The volume must be upgraded 
to enable this feature."),
-        0xC000029D: ("STATUS_REMOTE_STORAGE_NOT_ACTIVE","The remote storage 
service is not operational at this time."),
-        0xC000029E: ("STATUS_REMOTE_STORAGE_MEDIA_ERROR","The remote storage 
service encountered a media error."),
-        0xC000029F: ("STATUS_NO_TRACKING_SERVICE","The tracking (workstation) 
service is not running."),
-        0xC00002A0: ("STATUS_SERVER_SID_MISMATCH","The server process is 
running under a SID that is different from the SID that is required by 
client."),
-        0xC00002A1: ("STATUS_DS_NO_ATTRIBUTE_OR_VALUE","The specified 
directory service attribute or value does not exist."),
-        0xC00002A2: ("STATUS_DS_INVALID_ATTRIBUTE_SYNTAX","The attribute 
syntax specified to the directory service is invalid."),
-        0xC00002A3: ("STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED","The attribute type 
specified to the directory service is not defined."),
-        0xC00002A4: ("STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS","The specified 
directory service attribute or value already exists."),
-        0xC00002A5: ("STATUS_DS_BUSY","The directory service is busy."),
-        0xC00002A6: ("STATUS_DS_UNAVAILABLE","The directory service is 
unavailable."),
-        0xC00002A7: ("STATUS_DS_NO_RIDS_ALLOCATED","The directory service was 
unable to allocate a relative identifier."),
-        0xC00002A8: ("STATUS_DS_NO_MORE_RIDS","The directory service has 
exhausted the pool of relative identifiers."),
-        0xC00002A9: ("STATUS_DS_INCORRECT_ROLE_OWNER","The requested operation 
could not be performed because the directory service is not the master for that 
type of operation."),
-        0xC00002AA: ("STATUS_DS_RIDMGR_INIT_ERROR","The directory service was 
unable to initialize the subsystem that allocates relative identifiers."),
-        0xC00002AB: ("STATUS_DS_OBJ_CLASS_VIOLATION","The requested operation 
did not satisfy one or more constraints that are associated with the class of 
the object."),
-        0xC00002AC: ("STATUS_DS_CANT_ON_NON_LEAF","The directory service can 
perform the requested operation only on a leaf object."),
-        0xC00002AD: ("STATUS_DS_CANT_ON_RDN","The directory service cannot 
perform the requested operation on the Relatively Defined Name (RDN) attribute 
of an object."),
-        0xC00002AE: ("STATUS_DS_CANT_MOD_OBJ_CLASS","The directory service 
detected an attempt to modify the object class of an object."),
-        0xC00002AF: ("STATUS_DS_CROSS_DOM_MOVE_FAILED","An error occurred 
while performing a cross domain move operation."),
-        0xC00002B0: ("STATUS_DS_GC_NOT_AVAILABLE","Unable to contact the 
global catalog server."),
-        0xC00002B1: ("STATUS_DIRECTORY_SERVICE_REQUIRED","The requested 
operation requires a directory service, and none was available."),
-        0xC00002B2: ("STATUS_REPARSE_ATTRIBUTE_CONFLICT","The reparse 
attribute cannot be set because it is incompatible with an existing 
attribute."),
-        0xC00002B3: ("STATUS_CANT_ENABLE_DENY_ONLY","A group marked \"use for 
deny only\" cannot be enabled."),
-        0xC00002B4: ("STATUS_FLOAT_MULTIPLE_FAULTS","{EXCEPTION} Multiple 
floating-point faults."),
-        0xC00002B5: ("STATUS_FLOAT_MULTIPLE_TRAPS","{EXCEPTION} Multiple 
floating-point traps."),
-        0xC00002B6: ("STATUS_DEVICE_REMOVED","The device has been removed."),
-        0xC00002B7: ("STATUS_JOURNAL_DELETE_IN_PROGRESS","The volume change 
journal is being deleted."),
-        0xC00002B8: ("STATUS_JOURNAL_NOT_ACTIVE","The volume change journal is 
not active."),
-        0xC00002B9: ("STATUS_NOINTERFACE","The requested interface is not 
supported."),
-        0xC00002C1: ("STATUS_DS_ADMIN_LIMIT_EXCEEDED","A directory service 
resource limit has been exceeded."),
-        0xC00002C2: ("STATUS_DRIVER_FAILED_SLEEP","{System Standby Failed} The 
driver %hs does not support standby mode. Updating this driver may allow the 
system to go to standby mode."),
-        0xC00002C3: ("STATUS_MUTUAL_AUTHENTICATION_FAILED","Mutual 
Authentication failed. The server password is out of date at the domain 
controller."),
-        0xC00002C4: ("STATUS_CORRUPT_SYSTEM_FILE","The system file %1 has 
become corrupt and has been replaced."),
-        0xC00002C5: ("STATUS_DATATYPE_MISALIGNMENT_ERROR","{EXCEPTION} 
Alignment Error A data type misalignment error was detected in a load or store 
instruction."),
-        0xC00002C6: ("STATUS_WMI_READ_ONLY","The WMI data item or data block 
is read-only."),
-        0xC00002C7: ("STATUS_WMI_SET_FAILURE","The WMI data item or data block 
could not be changed."),
-        0xC00002C8: ("STATUS_COMMITMENT_MINIMUM","{Virtual Memory Minimum Too 
Low} Your system is low on virtual memory. Windows is increasing the size of 
your virtual memory paging file. During this process, memory requests for some 
applications may be denied. For more information, see Help."),
-        0xC00002C9: ("STATUS_REG_NAT_CONSUMPTION","{EXCEPTION} Register NaT 
consumption faults. A NaT value is consumed on a non-speculative instruction."),
-        0xC00002CA: ("STATUS_TRANSPORT_FULL","The transport element of the 
medium changer contains media, which is causing the operation to fail."),
-        0xC00002CB: ("STATUS_DS_SAM_INIT_FAILURE","Security Accounts Manager 
initialization failed because of the following error: %hs Error Status: 0x%x. 
Click OK to shut down this system and restart in Directory Services Restore 
Mode. Check the event log for more detailed information."),
-        0xC00002CC: ("STATUS_ONLY_IF_CONNECTED","This operation is supported 
only when you are connected to the server."),
-        0xC00002CD: ("STATUS_DS_SENSITIVE_GROUP_VIOLATION","Only an 
administrator can modify the membership list of an administrative group."),
-        0xC00002CE: ("STATUS_PNP_RESTART_ENUMERATION","A device was removed so 
enumeration must be restarted."),
-        0xC00002CF: ("STATUS_JOURNAL_ENTRY_DELETED","The journal entry has 
been deleted from the journal."),
-        0xC00002D0: ("STATUS_DS_CANT_MOD_PRIMARYGROUPID","Cannot change the 
primary group ID of a domain controller account."),
-        0xC00002D1: ("STATUS_SYSTEM_IMAGE_BAD_SIGNATURE","{Fatal System Error} 
The system image %s is not properly signed. The file has been replaced with the 
signed file. The system has been shut down."),
-        0xC00002D2: ("STATUS_PNP_REBOOT_REQUIRED","The device will not start 
without a reboot."),
-        0xC00002D3: ("STATUS_POWER_STATE_INVALID","The power state of the 
current device cannot support this request."),
-        0xC00002D4: ("STATUS_DS_INVALID_GROUP_TYPE","The specified group type 
is invalid."),
-        0xC00002D5: ("STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN","In a 
mixed domain, no nesting of a global group if the group is security enabled."),
-        0xC00002D6: ("STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN","In a mixed 
domain, cannot nest local groups with other local groups, if the group is 
security enabled."),
-        0xC00002D7: ("STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER","A global group 
cannot have a local group as a member."),
-        0xC00002D8: ("STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER","A global 
group cannot have a universal group as a member."),
-        0xC00002D9: ("STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER","A universal 
group cannot have a local group as a member."),
-        0xC00002DA: ("STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER","A global 
group cannot have a cross-domain member."),
-        0xC00002DB: ("STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER","A 
local group cannot have another cross-domain local group as a member."),
-        0xC00002DC: ("STATUS_DS_HAVE_PRIMARY_MEMBERS","Cannot change to a 
security-disabled group because primary members are in this group."),
-        0xC00002DD: ("STATUS_WMI_NOT_SUPPORTED","The WMI operation is not 
supported by the data block or method."),
-        0xC00002DE: ("STATUS_INSUFFICIENT_POWER","There is not enough power to 
complete the requested operation."),
-        0xC00002DF: ("STATUS_SAM_NEED_BOOTKEY_PASSWORD","The Security Accounts 
Manager needs to get the boot password."),
-        0xC00002E0: ("STATUS_SAM_NEED_BOOTKEY_FLOPPY","The Security Accounts 
Manager needs to get the boot key from the floppy disk."),
-        0xC00002E1: ("STATUS_DS_CANT_START","The directory service cannot 
start."),
-        0xC00002E2: ("STATUS_DS_INIT_FAILURE","The directory service could not 
start because of the following error: %hs Error Status: 0x%x. Click OK to shut 
down this system and restart in Directory Services Restore Mode. Check the 
event log for more detailed information."),
-        0xC00002E3: ("STATUS_SAM_INIT_FAILURE","The Security Accounts Manager 
initialization failed because of the following error: %hs Error Status: 0x%x. 
Click OK to shut down this system and restart in Safe Mode. Check the event log 
for more detailed information."),
-        0xC00002E4: ("STATUS_DS_GC_REQUIRED","The requested operation can be 
performed only on a global catalog server."),
-        0xC00002E5: ("STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY","A local group can 
only be a member of other local groups in the same domain."),
-        0xC00002E6: ("STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS","Foreign security 
principals cannot be members of universal groups."),
-        0xC00002E7: ("STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED","Your computer 
could not be joined to the domain. You have exceeded the maximum number of 
computer accounts you are allowed to create in this domain. Contact your system 
administrator to have this limit reset or increased."),
-        0xC00002E9: ("STATUS_CURRENT_DOMAIN_NOT_ALLOWED","This operation 
cannot be performed on the current domain."),
-        0xC00002EA: ("STATUS_CANNOT_MAKE","The directory or file cannot be 
created."),
-        0xC00002EB: ("STATUS_SYSTEM_SHUTDOWN","The system is in the process of 
shutting down."),
-        0xC00002EC: ("STATUS_DS_INIT_FAILURE_CONSOLE","Directory Services 
could not start because of the following error: %hs Error Status: 0x%x. Click 
OK to shut down the system. You can use the recovery console to diagnose the 
system further."),
-        0xC00002ED: ("STATUS_DS_SAM_INIT_FAILURE_CONSOLE","Security Accounts 
Manager initialization failed because of the following error: %hs Error Status: 
0x%x. Click OK to shut down the system. You can use the recovery console to 
diagnose the system further."),
-        0xC00002EE: ("STATUS_UNFINISHED_CONTEXT_DELETED","A security context 
was deleted before the context was completed. This is considered a logon 
failure."),
-        0xC00002EF: ("STATUS_NO_TGT_REPLY","The client is trying to negotiate 
a context and the server requires user-to-user but did not send a TGT reply."),
-        0xC00002F0: ("STATUS_OBJECTID_NOT_FOUND","An object ID was not found 
in the file."),
-        0xC00002F1: ("STATUS_NO_IP_ADDRESSES","Unable to accomplish the 
requested task because the local machine does not have any IP addresses."),
-        0xC00002F2: ("STATUS_WRONG_CREDENTIAL_HANDLE","The supplied credential 
handle does not match the credential that is associated with the security 
context."),
-        0xC00002F3: ("STATUS_CRYPTO_SYSTEM_INVALID","The crypto system or 
checksum function is invalid because a required function is unavailable."),
-        0xC00002F4: ("STATUS_MAX_REFERRALS_EXCEEDED","The number of maximum 
ticket referrals has been exceeded."),
-        0xC00002F5: ("STATUS_MUST_BE_KDC","The local machine must be a 
Kerberos KDC (domain controller) and it is not."),
-        0xC00002F6: ("STATUS_STRONG_CRYPTO_NOT_SUPPORTED","The other end of 
the security negotiation requires strong crypto but it is not supported on the 
local machine."),
-        0xC00002F7: ("STATUS_TOO_MANY_PRINCIPALS","The KDC reply contained 
more than one principal name."),
-        0xC00002F8: ("STATUS_NO_PA_DATA","Expected to find PA data for a hint 
of what etype to use, but it was not found."),
-        0xC00002F9: ("STATUS_PKINIT_NAME_MISMATCH","The client certificate 
does not contain a valid UPN, or does not match the client name in the logon 
request. Contact your administrator."),
-        0xC00002FA: ("STATUS_SMARTCARD_LOGON_REQUIRED","Smart card logon is 
required and was not used."),
-        0xC00002FB: ("STATUS_KDC_INVALID_REQUEST","An invalid request was sent 
to the KDC."),
-        0xC00002FC: ("STATUS_KDC_UNABLE_TO_REFER","The KDC was unable to 
generate a referral for the service requested."),
-        0xC00002FD: ("STATUS_KDC_UNKNOWN_ETYPE","The encryption type requested 
is not supported by the KDC."),
-        0xC00002FE: ("STATUS_SHUTDOWN_IN_PROGRESS","A system shutdown is in 
progress."),
-        0xC00002FF: ("STATUS_SERVER_SHUTDOWN_IN_PROGRESS","The server machine 
is shutting down."),
-        0xC0000300: ("STATUS_NOT_SUPPORTED_ON_SBS","This operation is not 
supported on a computer running Windows Server 2003 for Small Business 
Server."),
-        0xC0000301: ("STATUS_WMI_GUID_DISCONNECTED","The WMI GUID is no longer 
available."),
-        0xC0000302: ("STATUS_WMI_ALREADY_DISABLED","Collection or events for 
the WMI GUID is already disabled."),
-        0xC0000303: ("STATUS_WMI_ALREADY_ENABLED","Collection or events for 
the WMI GUID is already enabled."),
-        0xC0000304: ("STATUS_MFT_TOO_FRAGMENTED","The master file table on the 
volume is too fragmented to complete this operation."),
-        0xC0000305: ("STATUS_COPY_PROTECTION_FAILURE","Copy protection 
failure."),
-        0xC0000306: ("STATUS_CSS_AUTHENTICATION_FAILURE","Copy protection 
error-DVD CSS Authentication failed."),
-        0xC0000307: ("STATUS_CSS_KEY_NOT_PRESENT","Copy protection error-The 
specified sector does not contain a valid key."),
-        0xC0000308: ("STATUS_CSS_KEY_NOT_ESTABLISHED","Copy protection 
error-DVD session key not established."),
-        0xC0000309: ("STATUS_CSS_SCRAMBLED_SECTOR","Copy protection error-The 
read failed because the sector is encrypted."),
-        0xC000030A: ("STATUS_CSS_REGION_MISMATCH","Copy protection error-The 
region of the specified DVD does not correspond to the region setting of the 
drive."),
-        0xC000030B: ("STATUS_CSS_RESETS_EXHAUSTED","Copy protection error-The 
region setting of the drive may be permanent."),
-        0xC0000320: ("STATUS_PKINIT_FAILURE","The Kerberos protocol 
encountered an error while validating the KDC certificate during smart card 
logon. There is more information in the system event log."),
-        0xC0000321: ("STATUS_SMARTCARD_SUBSYSTEM_FAILURE","The Kerberos 
protocol encountered an error while attempting to use the smart card 
subsystem."),
-        0xC0000322: ("STATUS_NO_KERB_KEY","The target server does not have 
acceptable Kerberos credentials."),
-        0xC0000350: ("STATUS_HOST_DOWN","The transport determined that the 
remote system is down."),
-        0xC0000351: ("STATUS_UNSUPPORTED_PREAUTH","An unsupported 
pre-authentication mechanism was presented to the Kerberos package."),
-        0xC0000352: ("STATUS_EFS_ALG_BLOB_TOO_BIG","The encryption algorithm 
that is used on the source file needs a bigger key buffer than the one that is 
used on the destination file."),
-        0xC0000353: ("STATUS_PORT_NOT_SET","An attempt to remove a processes 
DebugPort was made, but a port was not already associated with the process."),
-        0xC0000354: ("STATUS_DEBUGGER_INACTIVE","An attempt to do an operation 
on a debug port failed because the port is in the process of being deleted."),
-        0xC0000355: ("STATUS_DS_VERSION_CHECK_FAILURE","This version of 
Windows is not compatible with the behavior version of the directory forest, 
domain, or domain controller."),
-        0xC0000356: ("STATUS_AUDITING_DISABLED","The specified event is 
currently not being audited."),
-        0xC0000357: ("STATUS_PRENT4_MACHINE_ACCOUNT","The machine account was 
created prior to Windows NT 4.0. The account needs to be recreated."),
-        0xC0000358: ("STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER","An account 
group cannot have a universal group as a member."),
-        0xC0000359: ("STATUS_INVALID_IMAGE_WIN_32","The specified image file 
did not have the correct format; it appears to be a 32-bit Windows image."),
-        0xC000035A: ("STATUS_INVALID_IMAGE_WIN_64","The specified image file 
did not have the correct format; it appears to be a 64-bit Windows image."),
-        0xC000035B: ("STATUS_BAD_BINDINGS","The client's supplied SSPI channel 
bindings were incorrect."),
-        0xC000035C: ("STATUS_NETWORK_SESSION_EXPIRED","The client session has 
expired; so the client must re-authenticate to continue accessing the remote 
resources."),
-        0xC000035D: ("STATUS_APPHELP_BLOCK","The AppHelp dialog box canceled; 
thus preventing the application from starting."),
-        0xC000035E: ("STATUS_ALL_SIDS_FILTERED","The SID filtering operation 
removed all SIDs."),
-        0xC000035F: ("STATUS_NOT_SAFE_MODE_DRIVER","The driver was not loaded 
because the system is starting in safe mode."),
-        0xC0000361: ("STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT","Access to %1 
has been restricted by your Administrator by the default software restriction 
policy level."),
-        0xC0000362: ("STATUS_ACCESS_DISABLED_BY_POLICY_PATH","Access to %1 has 
been restricted by your Administrator by location with policy rule %2 placed on 
path %3."),
-        0xC0000363: ("STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER","Access to 
%1 has been restricted by your Administrator by software publisher policy."),
-        0xC0000364: ("STATUS_ACCESS_DISABLED_BY_POLICY_OTHER","Access to %1 
has been restricted by your Administrator by policy rule %2."),
-        0xC0000365: ("STATUS_FAILED_DRIVER_ENTRY","The driver was not loaded 
because it failed its initialization call."),
-        0xC0000366: ("STATUS_DEVICE_ENUMERATION_ERROR","The device encountered 
an error while applying power or reading the device configuration. This may be 
caused by a failure of your hardware or by a poor connection."),
-        0xC0000368: ("STATUS_MOUNT_POINT_NOT_RESOLVED","The create operation 
failed because the name contained at least one mount point that resolves to a 
volume to which the specified device object is not attached."),
-        0xC0000369: ("STATUS_INVALID_DEVICE_OBJECT_PARAMETER","The device 
object parameter is either not a valid device object or is not attached to the 
volume that is specified by the file name."),
-        0xC000036A: ("STATUS_MCA_OCCURED","A machine check error has occurred. 
Check the system event log for additional information."),
-        0xC000036B: ("STATUS_DRIVER_BLOCKED_CRITICAL","Driver %2 has been 
blocked from loading."),
-        0xC000036C: ("STATUS_DRIVER_BLOCKED","Driver %2 has been blocked from 
loading."),
-        0xC000036D: ("STATUS_DRIVER_DATABASE_ERROR","There was error [%2] 
processing the driver database."),
-        0xC000036E: ("STATUS_SYSTEM_HIVE_TOO_LARGE","System hive size has 
exceeded its limit."),
-        0xC000036F: ("STATUS_INVALID_IMPORT_OF_NON_DLL","A dynamic link 
library (DLL) referenced a module that was neither a DLL nor the process's 
executable image."),
-        0xC0000371: ("STATUS_NO_SECRETS","The local account store does not 
contain secret material for the specified account."),
-        0xC0000372: ("STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY","Access to 
%1 has been restricted by your Administrator by policy rule %2."),
-        0xC0000373: ("STATUS_FAILED_STACK_SWITCH","The system was not able to 
allocate enough memory to perform a stack switch."),
-        0xC0000374: ("STATUS_HEAP_CORRUPTION","A heap has been corrupted."),
-        0xC0000380: ("STATUS_SMARTCARD_WRONG_PIN","An incorrect PIN was 
presented to the smart card."),
-        0xC0000381: ("STATUS_SMARTCARD_CARD_BLOCKED","The smart card is 
blocked."),
-        0xC0000382: ("STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED","No PIN was 
presented to the smart card."),
-        0xC0000383: ("STATUS_SMARTCARD_NO_CARD","No smart card is available."),
-        0xC0000384: ("STATUS_SMARTCARD_NO_KEY_CONTAINER","The requested key 
container does not exist on the smart card."),
-        0xC0000385: ("STATUS_SMARTCARD_NO_CERTIFICATE","The requested 
certificate does not exist on the smart card."),
-        0xC0000386: ("STATUS_SMARTCARD_NO_KEYSET","The requested keyset does 
not exist."),
-        0xC0000387: ("STATUS_SMARTCARD_IO_ERROR","A communication error with 
the smart card has been detected."),
-        0xC0000388: ("STATUS_DOWNGRADE_DETECTED","The system detected a 
possible attempt to compromise security. Ensure that you can contact the server 
that authenticated you."),
-        0xC0000389: ("STATUS_SMARTCARD_CERT_REVOKED","The smart card 
certificate used for authentication has been revoked. Contact your system 
administrator. There may be additional information in the event log."),
-        0xC000038A: ("STATUS_ISSUING_CA_UNTRUSTED","An untrusted certificate 
authority was detected while processing the smart card certificate that is used 
for authentication. Contact your system administrator."),
-        0xC000038B: ("STATUS_REVOCATION_OFFLINE_C","The revocation status of 
the smart card certificate that is used for authentication could not be 
determined. Contact your system administrator."),
-        0xC000038C: ("STATUS_PKINIT_CLIENT_FAILURE","The smart card 
certificate used for authentication was not trusted. Contact your system 
administrator."),
-        0xC000038D: ("STATUS_SMARTCARD_CERT_EXPIRED","The smart card 
certificate used for authentication has expired. Contact your system 
administrator."),
-        0xC000038E: ("STATUS_DRIVER_FAILED_PRIOR_UNLOAD","The driver could not 
be loaded because a previous version of the driver is still in memory."),
-        0xC000038F: ("STATUS_SMARTCARD_SILENT_CONTEXT","The smart card 
provider could not perform the action because the context was acquired as 
silent."),
-        0xC0000401: ("STATUS_PER_USER_TRUST_QUOTA_EXCEEDED","The delegated 
trust creation quota of the current user has been exceeded."),
-        0xC0000402: ("STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED","The total 
delegated trust creation quota has been exceeded."),
-        0xC0000403: ("STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED","The delegated 
trust deletion quota of the current user has been exceeded."),
-        0xC0000404: ("STATUS_DS_NAME_NOT_UNIQUE","The requested name already 
exists as a unique identifier."),
-        0xC0000405: ("STATUS_DS_DUPLICATE_ID_FOUND","The requested object has 
a non-unique identifier and cannot be retrieved."),
-        0xC0000406: ("STATUS_DS_GROUP_CONVERSION_ERROR","The group cannot be 
converted due to attribute restrictions on the requested group type."),
-        0xC0000407: ("STATUS_VOLSNAP_PREPARE_HIBERNATE","{Volume Shadow Copy 
Service} Wait while the Volume Shadow Copy Service prepares volume %hs for 
hibernation."),
-        0xC0000408: ("STATUS_USER2USER_REQUIRED","Kerberos sub-protocol 
User2User is required."),
-        0xC0000409: ("STATUS_STACK_BUFFER_OVERRUN","The system detected an 
overrun of a stack-based buffer in this application. This overrun could 
potentially allow a malicious user to gain control of this application."),
-        0xC000040A: ("STATUS_NO_S4U_PROT_SUPPORT","The Kerberos subsystem 
encountered an error. A service for user protocol request was made against a 
domain controller which does not support service for user."),
-        0xC000040B: ("STATUS_CROSSREALM_DELEGATION_FAILURE","An attempt was 
made by this server to make a Kerberos constrained delegation request for a 
target that is outside the server realm. This action is not supported and the 
resulting error indicates a misconfiguration on the allowed-to-delegate-to list 
for this server. Contact your administrator."),
-        0xC000040C: ("STATUS_REVOCATION_OFFLINE_KDC","The revocation status of 
the domain controller certificate used for smart card authentication could not 
be determined. There is additional information in the system event log. Contact 
your system administrator."),
-        0xC000040D: ("STATUS_ISSUING_CA_UNTRUSTED_KDC","An untrusted 
certificate authority was detected while processing the domain controller 
certificate used for authentication. There is additional information in the 
system event log. Contact your system administrator."),
-        0xC000040E: ("STATUS_KDC_CERT_EXPIRED","The domain controller 
certificate used for smart card logon has expired. Contact your system 
administrator with the contents of your system event log."),
-        0xC000040F: ("STATUS_KDC_CERT_REVOKED","The domain controller 
certificate used for smart card logon has been revoked. Contact your system 
administrator with the contents of your system event log."),
-        0xC0000410: ("STATUS_PARAMETER_QUOTA_EXCEEDED","Data present in one of 
the parameters is more than the function can operate on."),
-        0xC0000411: ("STATUS_HIBERNATION_FAILURE","The system has failed to 
hibernate (The error code is %hs). Hibernation will be disabled until the 
system is restarted."),
-        0xC0000412: ("STATUS_DELAY_LOAD_FAILED","An attempt to delay-load a 
.dll or get a function address in a delay-loaded .dll failed."),
-        0xC0000413: ("STATUS_AUTHENTICATION_FIREWALL_FAILED","Logon Failure: 
The machine you are logging onto is protected by an authentication firewall. 
The specified account is not allowed to authenticate to the machine."),
-        0xC0000414: ("STATUS_VDM_DISALLOWED","%hs is a 16-bit application. You 
do not have permissions to execute 16-bit applications. Check your permissions 
with your system administrator."),
-        0xC0000415: ("STATUS_HUNG_DISPLAY_DRIVER_THREAD","{Display Driver 
Stopped Responding} The %hs display driver has stopped working normally. Save 
your work and reboot the system to restore full display functionality. The next 
time you reboot the machine a dialog will be displayed giving you a chance to 
report this failure to Microsoft."),
-        0xC0000416: 
("STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE","The Desktop 
heap encountered an error while allocating session memory. There is more 
information in the system event log."),
-        0xC0000417: ("STATUS_INVALID_CRUNTIME_PARAMETER","An invalid parameter 
was passed to a C runtime function."),
-        0xC0000418: ("STATUS_NTLM_BLOCKED","The authentication failed because 
NTLM was blocked."),
-        0xC0000419: ("STATUS_DS_SRC_SID_EXISTS_IN_FOREST","The source object's 
SID already exists in destination forest."),
-        0xC000041A: ("STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST","The domain name 
of the trusted domain already exists in the forest."),
-        0xC000041B: ("STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST","The flat name of 
the trusted domain already exists in the forest."),
-        0xC000041C: ("STATUS_INVALID_USER_PRINCIPAL_NAME","The User Principal 
Name (UPN) is invalid."),
-        0xC0000420: ("STATUS_ASSERTION_FAILURE","There has been an assertion 
failure."),
-        0xC0000421: ("STATUS_VERIFIER_STOP","Application verifier has found an 
error in the current process."),
-        0xC0000423: ("STATUS_CALLBACK_POP_STACK","A user mode unwind is in 
progress."),
-        0xC0000424: ("STATUS_INCOMPATIBLE_DRIVER_BLOCKED","%2 has been blocked 
from loading due to incompatibility with this system. Contact your software 
vendor for a compatible version of the driver."),
-        0xC0000425: ("STATUS_HIVE_UNLOADED","Illegal operation attempted on a 
registry key which has already been unloaded."),
-        0xC0000426: ("STATUS_COMPRESSION_DISABLED","Compression is disabled 
for this volume."),
-        0xC0000427: ("STATUS_FILE_SYSTEM_LIMITATION","The requested operation 
could not be completed due to a file system limitation."),
-        0xC0000428: ("STATUS_INVALID_IMAGE_HASH","The hash for image %hs 
cannot be found in the system catalogs. The image is likely corrupt or the 
victim of tampering."),
-        0xC0000429: ("STATUS_NOT_CAPABLE","The implementation is not capable 
of performing the request."),
-        0xC000042A: ("STATUS_REQUEST_OUT_OF_SEQUENCE","The requested operation 
is out of order with respect to other operations."),
-        0xC000042B: ("STATUS_IMPLEMENTATION_LIMIT","An operation attempted to 
exceed an implementation-defined limit."),
-        0xC000042C: ("STATUS_ELEVATION_REQUIRED","The requested operation 
requires elevation."),
-        0xC000042D: ("STATUS_NO_SECURITY_CONTEXT","The required security 
context does not exist."),
-        0xC000042E: ("STATUS_PKU2U_CERT_FAILURE","The PKU2U protocol 
encountered an error while attempting to utilize the associated certificates."),
-        0xC0000432: ("STATUS_BEYOND_VDL","The operation was attempted beyond 
the valid data length of the file."),
-        0xC0000433: ("STATUS_ENCOUNTERED_WRITE_IN_PROGRESS","The attempted 
write operation encountered a write already in progress for some portion of the 
range."),
-        0xC0000434: ("STATUS_PTE_CHANGED","The page fault mappings changed in 
the middle of processing a fault so the operation must be retried."),
-        0xC0000435: ("STATUS_PURGE_FAILED","The attempt to purge this file 
from memory failed to purge some or all the data from memory."),
-        0xC0000440: ("STATUS_CRED_REQUIRES_CONFIRMATION","The requested 
credential requires confirmation."),
-        0xC0000441: ("STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE","The 
remote server sent an invalid response for a file being opened with Client Side 
Encryption."),
-        0xC0000442: ("STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER","Client Side 
Encryption is not supported by the remote server even though it claims to 
support it."),
-        0xC0000443: ("STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE","File is 
encrypted and should be opened in Client Side Encryption mode."),
-        0xC0000444: ("STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE","A new 
encrypted file is being created and a $EFS needs to be provided."),
-        0xC0000445: ("STATUS_CS_ENCRYPTION_FILE_NOT_CSE","The SMB client 
requested a CSE FSCTL on a non-CSE file."),
-        0xC0000446: ("STATUS_INVALID_LABEL","Indicates a particular Security 
ID may not be assigned as the label of an object."),
-        0xC0000450: ("STATUS_DRIVER_PROCESS_TERMINATED","The process hosting 
the driver for this device has terminated."),
-        0xC0000451: ("STATUS_AMBIGUOUS_SYSTEM_DEVICE","The requested system 
device cannot be identified due to multiple indistinguishable devices 
potentially matching the identification criteria."),
-        0xC0000452: ("STATUS_SYSTEM_DEVICE_NOT_FOUND","The requested system 
device cannot be found."),
-        0xC0000453: ("STATUS_RESTART_BOOT_APPLICATION","This boot application 
must be restarted."),
-        0xC0000454: ("STATUS_INSUFFICIENT_NVRAM_RESOURCES","Insufficient NVRAM 
resources exist to complete the API. A reboot might be required."),
-        0xC0000500: ("STATUS_INVALID_TASK_NAME","The specified task name is 
invalid."),
-        0xC0000501: ("STATUS_INVALID_TASK_INDEX","The specified task index is 
invalid."),
-        0xC0000502: ("STATUS_THREAD_ALREADY_IN_TASK","The specified thread is 
already joining a task."),
-        0xC0000503: ("STATUS_CALLBACK_BYPASS","A callback has requested to 
bypass native code."),
-        0xC0000602: ("STATUS_FAIL_FAST_EXCEPTION","A fail fast exception 
occurred. Exception handlers will not be invoked and the process will be 
terminated immediately."),
-        0xC0000603: ("STATUS_IMAGE_CERT_REVOKED","Windows cannot verify the 
digital signature for this file. The signing certificate for this file has been 
revoked."),
-        0xC0000700: ("STATUS_PORT_CLOSED","The ALPC port is closed."),
-        0xC0000701: ("STATUS_MESSAGE_LOST","The ALPC message requested is no 
longer available."),
-        0xC0000702: ("STATUS_INVALID_MESSAGE","The ALPC message supplied is 
invalid."),
-        0xC0000703: ("STATUS_REQUEST_CANCELED","The ALPC message has been 
canceled."),
-        0xC0000704: ("STATUS_RECURSIVE_DISPATCH","Invalid recursive dispatch 
attempt."),
-        0xC0000705: ("STATUS_LPC_RECEIVE_BUFFER_EXPECTED","No receive buffer 
has been supplied in a synchronous request."),
-        0xC0000706: ("STATUS_LPC_INVALID_CONNECTION_USAGE","The connection 
port is used in an invalid context."),
-        0xC0000707: ("STATUS_LPC_REQUESTS_NOT_ALLOWED","The ALPC port does not 
accept new request messages."),
-        0xC0000708: ("STATUS_RESOURCE_IN_USE","The resource requested is 
already in use."),
-        0xC0000709: ("STATUS_HARDWARE_MEMORY_ERROR","The hardware has reported 
an uncorrectable memory error."),
-        0xC000070A: ("STATUS_THREADPOOL_HANDLE_EXCEPTION","Status 0x%08x was 
returned, waiting on handle 0x%x for wait 0x%p, in waiter 0x%p."),
-        0xC000070B: ("STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED","After 
a callback to 0x%p(0x%p), a completion call to Set event(0x%p) failed with 
status 0x%08x."),
-        0xC000070C: 
("STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED","After a callback 
to 0x%p(0x%p), a completion call to ReleaseSemaphore(0x%p, %d) failed with 
status 0x%08x."),
-        0xC000070D: 
("STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED","After a callback to 
0x%p(0x%p), a completion call to ReleaseMutex(%p) failed with status 0x%08x."),
-        0xC000070E: 
("STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED","After a callback to 
0x%p(0x%p), a completion call to FreeLibrary(%p) failed with status 0x%08x."),
-        0xC000070F: ("STATUS_THREADPOOL_RELEASED_DURING_OPERATION","The thread 
pool 0x%p was released while a thread was posting a callback to 0x%p(0x%p) to 
it."),
-        0xC0000710: ("STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING","A thread 
pool worker thread is impersonating a client, after a callback to 0x%p(0x%p). 
This is unexpected, indicating that the callback is missing a call to revert 
the impersonation."),
-        0xC0000711: ("STATUS_APC_RETURNED_WHILE_IMPERSONATING","A thread pool 
worker thread is impersonating a client, after executing an APC. This is 
unexpected, indicating that the APC is missing a call to revert the 
impersonation."),
-        0xC0000712: ("STATUS_PROCESS_IS_PROTECTED","Either the target process, 
or the target thread's containing process, is a protected process."),
-        0xC0000713: ("STATUS_MCA_EXCEPTION","A thread is getting dispatched 
with MCA EXCEPTION because of MCA."),
-        0xC0000714: ("STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE","The client 
certificate account mapping is not unique."),
-        0xC0000715: ("STATUS_SYMLINK_CLASS_DISABLED","The symbolic link cannot 
be followed because its type is disabled."),
-        0xC0000716: ("STATUS_INVALID_IDN_NORMALIZATION","Indicates that the 
specified string is not valid for IDN normalization."),
-        0xC0000717: ("STATUS_NO_UNICODE_TRANSLATION","No mapping for the 
Unicode character exists in the target multi-byte code page."),
-        0xC0000718: ("STATUS_ALREADY_REGISTERED","The provided callback is 
already registered."),
-        0xC0000719: ("STATUS_CONTEXT_MISMATCH","The provided context did not 
match the target."),
-        0xC000071A: ("STATUS_PORT_ALREADY_HAS_COMPLETION_LIST","The specified 
port already has a completion list."),
-        0xC000071B: ("STATUS_CALLBACK_RETURNED_THREAD_PRIORITY","A threadpool 
worker thread entered a callback at thread base priority 0x%x and exited at 
priority 0x%x.  This is unexpected, indicating that the callback missed 
restoring the priority."),
-        0xC000071C: ("STATUS_INVALID_THREAD","An invalid thread, handle %p, is 
specified for this operation. Possibly, a threadpool worker thread was 
specified."),
-        0xC000071D: ("STATUS_CALLBACK_RETURNED_TRANSACTION","A threadpool 
worker thread entered a callback, which left transaction state.  This is 
unexpected, indicating that the callback missed clearing the transaction."),
-        0xC000071E: ("STATUS_CALLBACK_RETURNED_LDR_LOCK","A threadpool worker 
thread entered a callback, which left the loader lock held.  This is 
unexpected, indicating that the callback missed releasing the lock."),
-        0xC000071F: ("STATUS_CALLBACK_RETURNED_LANG","A threadpool worker 
thread entered a callback, which left with preferred languages set.  This is 
unexpected, indicating that the callback missed clearing them."),
-        0xC0000720: ("STATUS_CALLBACK_RETURNED_PRI_BACK","A threadpool worker 
thread entered a callback, which left with background priorities set.  This is 
unexpected, indicating that the callback missed restoring the original 
priorities."),
-        0xC0000800: ("STATUS_DISK_REPAIR_DISABLED","The attempted operation 
required self healing to be enabled."),
-        0xC0000801: ("STATUS_DS_DOMAIN_RENAME_IN_PROGRESS","The directory 
service cannot perform the requested operation because a domain rename 
operation is in progress."),
-        0xC0000802: ("STATUS_DISK_QUOTA_EXCEEDED","An operation failed because 
the storage quota was exceeded."),
-        0xC0000804: ("STATUS_CONTENT_BLOCKED","An operation failed because the 
content was blocked."),
-        0xC0000805: ("STATUS_BAD_CLUSTERS","The operation could not be 
completed due to bad clusters on disk."),
-        0xC0000806: ("STATUS_VOLUME_DIRTY","The operation could not be 
completed because the volume is dirty. Please run the Chkdsk utility and try 
again."),
-        0xC0000901: ("STATUS_FILE_CHECKED_OUT","This file is checked out or 
locked for editing by another user."),
-        0xC0000902: ("STATUS_CHECKOUT_REQUIRED","The file must be checked out 
before saving changes."),
-        0xC0000903: ("STATUS_BAD_FILE_TYPE","The file type being saved or 
retrieved has been blocked."),
-        0xC0000904: ("STATUS_FILE_TOO_LARGE","The file size exceeds the limit 
allowed and cannot be saved."),
-        0xC0000905: ("STATUS_FORMS_AUTH_REQUIRED","Access Denied. Before 
opening files in this location, you must first browse to the e.g. site and 
select the option to log on automatically."),
-        0xC0000906: ("STATUS_VIRUS_INFECTED","The operation did not complete 
successfully because the file contains a virus."),
-        0xC0000907: ("STATUS_VIRUS_DELETED","This file contains a virus and 
cannot be opened. Due to the nature of this virus, the file has been removed 
from this location."),
-        0xC0000908: ("STATUS_BAD_MCFG_TABLE","The resources required for this 
device conflict with the MCFG table."),
-        0xC0000909: ("STATUS_CANNOT_BREAK_OPLOCK","The operation did not 
complete successfully because it would cause an oplock to be broken. The caller 
has requested that existing oplocks not be broken."),
-        0xC0009898: ("STATUS_WOW_ASSERTION","WOW Assertion Error."),
-        0xC000A000: ("STATUS_INVALID_SIGNATURE","The cryptographic signature 
is invalid."),
-        0xC000A001: ("STATUS_HMAC_NOT_SUPPORTED","The cryptographic provider 
does not support HMAC."),
-        0xC000A010: ("STATUS_IPSEC_QUEUE_OVERFLOW","The IPsec queue 
overflowed."),
-        0xC000A011: ("STATUS_ND_QUEUE_OVERFLOW","The neighbor discovery queue 
overflowed."),
-        0xC000A012: ("STATUS_HOPLIMIT_EXCEEDED","An Internet Control Message 
Protocol (ICMP) hop limit exceeded error was received."),
-        0xC000A013: ("STATUS_PROTOCOL_NOT_SUPPORTED","The protocol is not 
installed on the local machine."),
-        0xC000A080: 
("STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED","{Delayed Write Failed} 
Windows was unable to save all the data for the file %hs; the data has been 
lost. This error may be caused by network connectivity issues. Try to save this 
file elsewhere."),
-        0xC000A081: 
("STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR","{Delayed Write Failed} 
Windows was unable to save all the data for the file %hs; the data has been 
lost. This error was returned by the server on which the file exists. Try to 
save this file elsewhere."),
-        0xC000A082: ("STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR","{Delayed 
Write Failed} Windows was unable to save all the data for the file %hs; the 
data has been lost. This error may be caused if the device has been removed or 
the media is write-protected."),
-        0xC000A083: ("STATUS_XML_PARSE_ERROR","Windows was unable to parse the 
requested XML data."),
-        0xC000A084: ("STATUS_XMLDSIG_ERROR","An error was encountered while 
processing an XML digital signature."),
-        0xC000A085: ("STATUS_WRONG_COMPARTMENT","This indicates that the 
caller made the connection request in the wrong routing compartment."),
-        0xC000A086: ("STATUS_AUTHIP_FAILURE","This indicates that there was an 
AuthIP failure when attempting to connect to the remote host."),
-        0xC000A087: ("STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS","OID 
mapped groups cannot have members."),
-        0xC000A088: ("STATUS_DS_OID_NOT_FOUND","The specified OID cannot be 
found."),
-        0xC000A100: ("STATUS_HASH_NOT_SUPPORTED","Hash generation for the 
specified version and hash type is not enabled on server."),
-        0xC000A101: ("STATUS_HASH_NOT_PRESENT","The hash requests is not 
present or not up to date with the current file contents."),
-        0xC0010001: ("DBG_NO_STATE_CHANGE","The debugger did not perform a 
state change."),
-        0xC0010002: ("DBG_APP_NOT_IDLE","The debugger found that the 
application is not idle."),
-        0xC0020001: ("RPC_NT_INVALID_STRING_BINDING","The string binding is 
invalid."),
-        0xC0020002: ("RPC_NT_WRONG_KIND_OF_BINDING","The binding handle is not 
the correct type."),
-        0xC0020003: ("RPC_NT_INVALID_BINDING","The binding handle is 
invalid."),
-        0xC0020004: ("RPC_NT_PROTSEQ_NOT_SUPPORTED","The RPC protocol sequence 
is not supported."),
-        0xC0020005: ("RPC_NT_INVALID_RPC_PROTSEQ","The RPC protocol sequence 
is invalid."),
-        0xC0020006: ("RPC_NT_INVALID_STRING_UUID","The string UUID is 
invalid."),
-        0xC0020007: ("RPC_NT_INVALID_ENDPOINT_FORMAT","The endpoint format is 
invalid."),
-        0xC0020008: ("RPC_NT_INVALID_NET_ADDR","The network address is 
invalid."),
-        0xC0020009: ("RPC_NT_NO_ENDPOINT_FOUND","No endpoint was found."),
-        0xC002000A: ("RPC_NT_INVALID_TIMEOUT","The time-out value is 
invalid."),
-        0xC002000B: ("RPC_NT_OBJECT_NOT_FOUND","The object UUID was not 
found."),
-        0xC002000C: ("RPC_NT_ALREADY_REGISTERED","The object UUID has already 
been registered."),
-        0xC002000D: ("RPC_NT_TYPE_ALREADY_REGISTERED","The type UUID has 
already been registered."),
-        0xC002000E: ("RPC_NT_ALREADY_LISTENING","The RPC server is already 
listening."),
-        0xC002000F: ("RPC_NT_NO_PROTSEQS_REGISTERED","No protocol sequences 
have been registered."),
-        0xC0020010: ("RPC_NT_NOT_LISTENING","The RPC server is not 
listening."),
-        0xC0020011: ("RPC_NT_UNKNOWN_MGR_TYPE","The manager type is unknown."),
-        0xC0020012: ("RPC_NT_UNKNOWN_IF","The interface is unknown."),
-        0xC0020013: ("RPC_NT_NO_BINDINGS","There are no bindings."),
-        0xC0020014: ("RPC_NT_NO_PROTSEQS","There are no protocol sequences."),
-        0xC0020015: ("RPC_NT_CANT_CREATE_ENDPOINT","The endpoint cannot be 
created."),
-        0xC0020016: ("RPC_NT_OUT_OF_RESOURCES","Insufficient resources are 
available to complete this operation."),
-        0xC0020017: ("RPC_NT_SERVER_UNAVAILABLE","The RPC server is 
unavailable."),
-        0xC0020018: ("RPC_NT_SERVER_TOO_BUSY","The RPC server is too busy to 
complete this operation."),
-        0xC0020019: ("RPC_NT_INVALID_NETWORK_OPTIONS","The network options are 
invalid."),
-        0xC002001A: ("RPC_NT_NO_CALL_ACTIVE","No RPCs are active on this 
thread."),
-        0xC002001B: ("RPC_NT_CALL_FAILED","The RPC failed."),
-        0xC002001C: ("RPC_NT_CALL_FAILED_DNE","The RPC failed and did not 
execute."),
-        0xC002001D: ("RPC_NT_PROTOCOL_ERROR","An RPC protocol error 
occurred."),
-        0xC002001F: ("RPC_NT_UNSUPPORTED_TRANS_SYN","The RPC server does not 
support the transfer syntax."),
-        0xC0020021: ("RPC_NT_UNSUPPORTED_TYPE","The type UUID is not 
supported."),
-        0xC0020022: ("RPC_NT_INVALID_TAG","The tag is invalid."),
-        0xC0020023: ("RPC_NT_INVALID_BOUND","The array bounds are invalid."),
-        0xC0020024: ("RPC_NT_NO_ENTRY_NAME","The binding does not contain an 
entry name."),
-        0xC0020025: ("RPC_NT_INVALID_NAME_SYNTAX","The name syntax is 
invalid."),
-        0xC0020026: ("RPC_NT_UNSUPPORTED_NAME_SYNTAX","The name syntax is not 
supported."),
-        0xC0020028: ("RPC_NT_UUID_NO_ADDRESS","No network address is available 
to construct a UUID."),
-        0xC0020029: ("RPC_NT_DUPLICATE_ENDPOINT","The endpoint is a 
duplicate."),
-        0xC002002A: ("RPC_NT_UNKNOWN_AUTHN_TYPE","The authentication type is 
unknown."),
-        0xC002002B: ("RPC_NT_MAX_CALLS_TOO_SMALL","The maximum number of calls 
is too small."),
-        0xC002002C: ("RPC_NT_STRING_TOO_LONG","The string is too long."),
-        0xC002002D: ("RPC_NT_PROTSEQ_NOT_FOUND","The RPC protocol sequence was 
not found."),
-        0xC002002E: ("RPC_NT_PROCNUM_OUT_OF_RANGE","The procedure number is 
out of range."),
-        0xC002002F: ("RPC_NT_BINDING_HAS_NO_AUTH","The binding does not 
contain any authentication information."),
-        0xC0020030: ("RPC_NT_UNKNOWN_AUTHN_SERVICE","The authentication 
service is unknown."),
-        0xC0020031: ("RPC_NT_UNKNOWN_AUTHN_LEVEL","The authentication level is 
unknown."),
-        0xC0020032: ("RPC_NT_INVALID_AUTH_IDENTITY","The security context is 
invalid."),
-        0xC0020033: ("RPC_NT_UNKNOWN_AUTHZ_SERVICE","The authorization service 
is unknown."),
-        0xC0020034: ("EPT_NT_INVALID_ENTRY","The entry is invalid."),
-        0xC0020035: ("EPT_NT_CANT_PERFORM_OP","The operation cannot be 
performed."),
-        0xC0020036: ("EPT_NT_NOT_REGISTERED","No more endpoints are available 
from the endpoint mapper."),
-        0xC0020037: ("RPC_NT_NOTHING_TO_EXPORT","No interfaces have been 
exported."),
-        0xC0020038: ("RPC_NT_INCOMPLETE_NAME","The entry name is incomplete."),
-        0xC0020039: ("RPC_NT_INVALID_VERS_OPTION","The version option is 
invalid."),
-        0xC002003A: ("RPC_NT_NO_MORE_MEMBERS","There are no more members."),
-        0xC002003B: ("RPC_NT_NOT_ALL_OBJS_UNEXPORTED","There is nothing to 
unexport."),
-        0xC002003C: ("RPC_NT_INTERFACE_NOT_FOUND","The interface was not 
found."),
-        0xC002003D: ("RPC_NT_ENTRY_ALREADY_EXISTS","The entry already 
exists."),
-        0xC002003E: ("RPC_NT_ENTRY_NOT_FOUND","The entry was not found."),
-        0xC002003F: ("RPC_NT_NAME_SERVICE_UNAVAILABLE","The name service is 
unavailable."),
-        0xC0020040: ("RPC_NT_INVALID_NAF_ID","The network address family is 
invalid."),
-        0xC0020041: ("RPC_NT_CANNOT_SUPPORT","The requested operation is not 
supported."),
-        0xC0020042: ("RPC_NT_NO_CONTEXT_AVAILABLE","No security context is 
available to allow impersonation."),
-        0xC0020043: ("RPC_NT_INTERNAL_ERROR","An internal error occurred in 
the RPC."),
-        0xC0020044: ("RPC_NT_ZERO_DIVIDE","The RPC server attempted to divide 
an integer by zero."),
-        0xC0020045: ("RPC_NT_ADDRESS_ERROR","An addressing error occurred in 
the RPC server."),
-        0xC0020046: ("RPC_NT_FP_DIV_ZERO","A floating point operation at the 
RPC server caused a divide by zero."),
-        0xC0020047: ("RPC_NT_FP_UNDERFLOW","A floating point underflow 
occurred at the RPC server."),
-        0xC0020048: ("RPC_NT_FP_OVERFLOW","A floating point overflow occurred 
at the RPC server."),
-        0xC0020049: ("RPC_NT_CALL_IN_PROGRESS","An RPC is already in progress 
for this thread."),
-        0xC002004A: ("RPC_NT_NO_MORE_BINDINGS","There are no more bindings."),
-        0xC002004B: ("RPC_NT_GROUP_MEMBER_NOT_FOUND","The group member was not 
found."),
-        0xC002004C: ("EPT_NT_CANT_CREATE","The endpoint mapper database entry 
could not be created."),
-        0xC002004D: ("RPC_NT_INVALID_OBJECT","The object UUID is the nil 
UUID."),
-        0xC002004F: ("RPC_NT_NO_INTERFACES","No interfaces have been 
registered."),
-        0xC0020050: ("RPC_NT_CALL_CANCELLED","The RPC was canceled."),
-        0xC0020051: ("RPC_NT_BINDING_INCOMPLETE","The binding handle does not 
contain all the required information."),
-        0xC0020052: ("RPC_NT_COMM_FAILURE","A communications failure occurred 
during an RPC."),
-        0xC0020053: ("RPC_NT_UNSUPPORTED_AUTHN_LEVEL","The requested 
authentication level is not supported."),
-        0xC0020054: ("RPC_NT_NO_PRINC_NAME","No principal name was 
registered."),
-        0xC0020055: ("RPC_NT_NOT_RPC_ERROR","The error specified is not a 
valid Windows RPC error code."),
-        0xC0020057: ("RPC_NT_SEC_PKG_ERROR","A security package-specific error 
occurred."),
-        0xC0020058: ("RPC_NT_NOT_CANCELLED","The thread was not canceled."),
-        0xC0020062: ("RPC_NT_INVALID_ASYNC_HANDLE","Invalid asynchronous RPC 
handle."),
-        0xC0020063: ("RPC_NT_INVALID_ASYNC_CALL","Invalid asynchronous RPC 
call handle for this operation."),
-        0xC0020064: ("RPC_NT_PROXY_ACCESS_DENIED","Access to the HTTP proxy is 
denied."),
-        0xC0030001: ("RPC_NT_NO_MORE_ENTRIES","The list of RPC servers 
available for auto-handle binding has been exhausted."),
-        0xC0030002: ("RPC_NT_SS_CHAR_TRANS_OPEN_FAIL","The file designated by 
DCERPCCHARTRANS cannot be opened."),
-        0xC0030003: ("RPC_NT_SS_CHAR_TRANS_SHORT_FILE","The file containing 
the character translation table has fewer than 512 bytes."),
-        0xC0030004: ("RPC_NT_SS_IN_NULL_CONTEXT","A null context handle is 
passed as an [in] parameter."),
-        0xC0030005: ("RPC_NT_SS_CONTEXT_MISMATCH","The context handle does not 
match any known context handles."),
-        0xC0030006: ("RPC_NT_SS_CONTEXT_DAMAGED","The context handle changed 
during a call."),
-        0xC0030007: ("RPC_NT_SS_HANDLES_MISMATCH","The binding handles passed 
to an RPC do not match."),
-        0xC0030008: ("RPC_NT_SS_CANNOT_GET_CALL_HANDLE","The stub is unable to 
get the call handle."),
-        0xC0030009: ("RPC_NT_NULL_REF_POINTER","A null reference pointer was 
passed to the stub."),
-        0xC003000A: ("RPC_NT_ENUM_VALUE_OUT_OF_RANGE","The enumeration value 
is out of range."),
-        0xC003000B: ("RPC_NT_BYTE_COUNT_TOO_SMALL","The byte count is too 
small."),
-        0xC003000C: ("RPC_NT_BAD_STUB_DATA","The stub received bad data."),
-        0xC0030059: ("RPC_NT_INVALID_ES_ACTION","Invalid operation on the 
encoding/decoding handle."),
-        0xC003005A: ("RPC_NT_WRONG_ES_VERSION","Incompatible version of the 
serializing package."),
-        0xC003005B: ("RPC_NT_WRONG_STUB_VERSION","Incompatible version of the 
RPC stub."),
-        0xC003005C: ("RPC_NT_INVALID_PIPE_OBJECT","The RPC pipe object is 
invalid or corrupt."),
-        0xC003005D: ("RPC_NT_INVALID_PIPE_OPERATION","An invalid operation was 
attempted on an RPC pipe object."),
-        0xC003005E: ("RPC_NT_WRONG_PIPE_VERSION","Unsupported RPC pipe 
version."),
-        0xC003005F: ("RPC_NT_PIPE_CLOSED","The RPC pipe object has already 
been closed."),
-        0xC0030060: ("RPC_NT_PIPE_DISCIPLINE_ERROR","The RPC call completed 
before all pipes were processed."),
-        0xC0030061: ("RPC_NT_PIPE_EMPTY","No more data is available from the 
RPC pipe."),
-        0xC0040035: ("STATUS_PNP_BAD_MPS_TABLE","A device is missing in the 
system BIOS MPS table. This device will not be used. Contact your system vendor 
for a system BIOS update."),
-        0xC0040036: ("STATUS_PNP_TRANSLATION_FAILED","A translator failed to 
translate resources."),
-        0xC0040037: ("STATUS_PNP_IRQ_TRANSLATION_FAILED","An IRQ translator 
failed to translate resources."),
-        0xC0040038: ("STATUS_PNP_INVALID_ID","Driver %2 returned an invalid ID 
for a child device (%3)."),
-        0xC0040039: ("STATUS_IO_REISSUE_AS_CACHED","Reissue the given 
operation as a cached I/O operation"),
-        0xC00A0001: ("STATUS_CTX_WINSTATION_NAME_INVALID","Session name %1 is 
invalid."),
-        0xC00A0002: ("STATUS_CTX_INVALID_PD","The protocol driver %1 is 
invalid."),
-        0xC00A0003: ("STATUS_CTX_PD_NOT_FOUND","The protocol driver %1 was not 
found in the system path."),
-        0xC00A0006: ("STATUS_CTX_CLOSE_PENDING","A close operation is pending 
on the terminal connection."),
-        0xC00A0007: ("STATUS_CTX_NO_OUTBUF","No free output buffers are 
available."),
-        0xC00A0008: ("STATUS_CTX_MODEM_INF_NOT_FOUND","The MODEM.INF file was 
not found."),
-        0xC00A0009: ("STATUS_CTX_INVALID_MODEMNAME","The modem (%1) was not 
found in the MODEM.INF file."),
-        0xC00A000A: ("STATUS_CTX_RESPONSE_ERROR","The modem did not accept the 
command sent to it. Verify that the configured modem name matches the attached 
modem."),
-        0xC00A000B: ("STATUS_CTX_MODEM_RESPONSE_TIMEOUT","The modem did not 
respond to the command sent to it. Verify that the modem cable is properly 
attached and the modem is turned on."),
-        0xC00A000C: ("STATUS_CTX_MODEM_RESPONSE_NO_CARRIER","Carrier detection 
has failed or the carrier has been dropped due to disconnection."),
-        0xC00A000D: ("STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE","A dial tone was 
not detected within the required time. Verify that the phone cable is properly 
attached and functional."),
-        0xC00A000E: ("STATUS_CTX_MODEM_RESPONSE_BUSY","A busy signal was 
detected at a remote site on callback."),
-        0xC00A000F: ("STATUS_CTX_MODEM_RESPONSE_VOICE","A voice was detected 
at a remote site on callback."),
-        0xC00A0010: ("STATUS_CTX_TD_ERROR","Transport driver error."),
-        0xC00A0012: ("STATUS_CTX_LICENSE_CLIENT_INVALID","The client you are 
using is not licensed to use this system. Your logon request is denied."),
-        0xC00A0013: ("STATUS_CTX_LICENSE_NOT_AVAILABLE","The system has 
reached its licensed logon limit. Try again later."),
-        0xC00A0014: ("STATUS_CTX_LICENSE_EXPIRED","The system license has 
expired. Your logon request is denied."),
-        0xC00A0015: ("STATUS_CTX_WINSTATION_NOT_FOUND","The specified session 
cannot be found."),
-        0xC00A0016: ("STATUS_CTX_WINSTATION_NAME_COLLISION","The specified 
session name is already in use."),
-        0xC00A0017: ("STATUS_CTX_WINSTATION_BUSY","The requested operation 
cannot be completed because the terminal connection is currently processing a 
connect, disconnect, reset, or delete operation."),
-        0xC00A0018: ("STATUS_CTX_BAD_VIDEO_MODE","An attempt has been made to 
connect to a session whose video mode is not supported by the current client."),
-        0xC00A0022: ("STATUS_CTX_GRAPHICS_INVALID","The application attempted 
to enable DOS graphics mode. DOS graphics mode is not supported."),
-        0xC00A0024: ("STATUS_CTX_NOT_CONSOLE","The requested operation can be 
performed only on the system console. This is most often the result of a driver 
or system DLL requiring direct console access."),
-        0xC00A0026: ("STATUS_CTX_CLIENT_QUERY_TIMEOUT","The client failed to 
respond to the server connect message."),
-        0xC00A0027: ("STATUS_CTX_CONSOLE_DISCONNECT","Disconnecting the 
console session is not supported."),
-        0xC00A0028: ("STATUS_CTX_CONSOLE_CONNECT","Reconnecting a disconnected 
session to the console is not supported."),
-        0xC00A002A: ("STATUS_CTX_SHADOW_DENIED","The request to control 
another session remotely was denied."),
-        0xC00A002B: ("STATUS_CTX_WINSTATION_ACCESS_DENIED","A process has 
requested access to a session, but has not been granted those access rights."),
-        0xC00A002E: ("STATUS_CTX_INVALID_WD","The terminal connection driver 
%1 is invalid."),
-        0xC00A002F: ("STATUS_CTX_WD_NOT_FOUND","The terminal connection driver 
%1 was not found in the system path."),
-        0xC00A0030: ("STATUS_CTX_SHADOW_INVALID","The requested session cannot 
be controlled remotely. You cannot control your own session, a session that is 
trying to control your session, a session that has no user logged on, or other 
sessions from the console."),
-        0xC00A0031: ("STATUS_CTX_SHADOW_DISABLED","The requested session is 
not configured to allow remote control."),
-        0xC00A0032: ("STATUS_RDP_PROTOCOL_ERROR","The RDP protocol component 
%2 detected an error in the protocol stream and has disconnected the client."),
-        0xC00A0033: ("STATUS_CTX_CLIENT_LICENSE_NOT_SET","Your request to 
connect to this terminal server has been rejected. Your terminal server client 
license number has not been entered for this copy of the terminal client. 
Contact your system administrator for help in entering a valid, unique license 
number for this terminal server client. Click OK to continue."),
-        0xC00A0034: ("STATUS_CTX_CLIENT_LICENSE_IN_USE","Your request to 
connect to this terminal server has been rejected. Your terminal server client 
license number is currently being used by another user. Contact your system 
administrator to obtain a new copy of the terminal server client with a valid, 
unique license number. Click OK to continue."),
-        0xC00A0035: ("STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE","The remote 
control of the console was terminated because the display mode was changed. 
Changing the display mode in a remote control session is not supported."),
-        0xC00A0036: ("STATUS_CTX_SHADOW_NOT_RUNNING","Remote control could not 
be terminated because the specified session is not currently being remotely 
controlled."),
-        0xC00A0037: ("STATUS_CTX_LOGON_DISABLED","Your interactive logon 
privilege has been disabled. Contact your system administrator."),
-        0xC00A0038: ("STATUS_CTX_SECURITY_LAYER_ERROR","The terminal server 
security layer detected an error in the protocol stream and has disconnected 
the client."),
-        0xC00A0039: ("STATUS_TS_INCOMPATIBLE_SESSIONS","The target session is 
incompatible with the current session."),
-        0xC00B0001: ("STATUS_MUI_FILE_NOT_FOUND","The resource loader failed 
to find an MUI file."),
-        0xC00B0002: ("STATUS_MUI_INVALID_FILE","The resource loader failed to 
load an MUI file because the file failed to pass validation."),
-        0xC00B0003: ("STATUS_MUI_INVALID_RC_CONFIG","The RC manifest is 
corrupted with garbage data, is an unsupported version, or is missing a 
required item."),
-        0xC00B0004: ("STATUS_MUI_INVALID_LOCALE_NAME","The RC manifest has an 
invalid culture name."),
-        0xC00B0005: ("STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME","The RC 
manifest has and invalid ultimate fallback name."),
-        0xC00B0006: ("STATUS_MUI_FILE_NOT_LOADED","The resource loader cache 
does not have a loaded MUI entry."),
-        0xC00B0007: ("STATUS_RESOURCE_ENUM_USER_STOP","The user stopped 
resource enumeration."),
-        0xC0130001: ("STATUS_CLUSTER_INVALID_NODE","The cluster node is not 
valid."),
-        0xC0130002: ("STATUS_CLUSTER_NODE_EXISTS","The cluster node already 
exists."),
-        0xC0130003: ("STATUS_CLUSTER_JOIN_IN_PROGRESS","A node is in the 
process of joining the cluster."),
-        0xC0130004: ("STATUS_CLUSTER_NODE_NOT_FOUND","The cluster node was not 
found."),
-        0xC0130005: ("STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND","The cluster local 
node information was not found."),
-        0xC0130006: ("STATUS_CLUSTER_NETWORK_EXISTS","The cluster network 
already exists."),
-        0xC0130007: ("STATUS_CLUSTER_NETWORK_NOT_FOUND","The cluster network 
was not found."),
-        0xC0130008: ("STATUS_CLUSTER_NETINTERFACE_EXISTS","The cluster network 
interface already exists."),
-        0xC0130009: ("STATUS_CLUSTER_NETINTERFACE_NOT_FOUND","The cluster 
network interface was not found."),
-        0xC013000A: ("STATUS_CLUSTER_INVALID_REQUEST","The cluster request is 
not valid for this object."),
-        0xC013000B: ("STATUS_CLUSTER_INVALID_NETWORK_PROVIDER","The cluster 
network provider is not valid."),
-        0xC013000C: ("STATUS_CLUSTER_NODE_DOWN","The cluster node is down."),
-        0xC013000D: ("STATUS_CLUSTER_NODE_UNREACHABLE","The cluster node is 
not reachable."),
-        0xC013000E: ("STATUS_CLUSTER_NODE_NOT_MEMBER","The cluster node is not 
a member of the cluster."),
-        0xC013000F: ("STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS","A cluster join 
operation is not in progress."),
-        0xC0130010: ("STATUS_CLUSTER_INVALID_NETWORK","The cluster network is 
not valid."),
-        0xC0130011: ("STATUS_CLUSTER_NO_NET_ADAPTERS","No network adapters are 
available."),
-        0xC0130012: ("STATUS_CLUSTER_NODE_UP","The cluster node is up."),
-        0xC0130013: ("STATUS_CLUSTER_NODE_PAUSED","The cluster node is 
paused."),
-        0xC0130014: ("STATUS_CLUSTER_NODE_NOT_PAUSED","The cluster node is not 
paused."),
-        0xC0130015: ("STATUS_CLUSTER_NO_SECURITY_CONTEXT","No cluster security 
context is available."),
-        0xC0130016: ("STATUS_CLUSTER_NETWORK_NOT_INTERNAL","The cluster 
network is not configured for internal cluster communication."),
-        0xC0130017: ("STATUS_CLUSTER_POISONED","The cluster node has been 
poisoned."),
-        0xC0140001: ("STATUS_ACPI_INVALID_OPCODE","An attempt was made to run 
an invalid AML opcode."),
-        0xC0140002: ("STATUS_ACPI_STACK_OVERFLOW","The AML interpreter stack 
has overflowed."),
-        0xC0140003: ("STATUS_ACPI_ASSERT_FAILED","An inconsistent state has 
occurred."),
-        0xC0140004: ("STATUS_ACPI_INVALID_INDEX","An attempt was made to 
access an array outside its bounds."),
-        0xC0140005: ("STATUS_ACPI_INVALID_ARGUMENT","A required argument was 
not specified."),
-        0xC0140006: ("STATUS_ACPI_FATAL","A fatal error has occurred."),
-        0xC0140007: ("STATUS_ACPI_INVALID_SUPERNAME","An invalid SuperName was 
specified."),
-        0xC0140008: ("STATUS_ACPI_INVALID_ARGTYPE","An argument with an 
incorrect type was specified."),
-        0xC0140009: ("STATUS_ACPI_INVALID_OBJTYPE","An object with an 
incorrect type was specified."),
-        0xC014000A: ("STATUS_ACPI_INVALID_TARGETTYPE","A target with an 
incorrect type was specified."),
-        0xC014000B: ("STATUS_ACPI_INCORRECT_ARGUMENT_COUNT","An incorrect 
number of arguments was specified."),
-        0xC014000C: ("STATUS_ACPI_ADDRESS_NOT_MAPPED","An address failed to 
translate."),
-        0xC014000D: ("STATUS_ACPI_INVALID_EVENTTYPE","An incorrect event type 
was specified."),
-        0xC014000E: ("STATUS_ACPI_HANDLER_COLLISION","A handler for the target 
already exists."),
-        0xC014000F: ("STATUS_ACPI_INVALID_DATA","Invalid data for the target 
was specified."),
-        0xC0140010: ("STATUS_ACPI_INVALID_REGION","An invalid region for the 
target was specified."),
-        0xC0140011: ("STATUS_ACPI_INVALID_ACCESS_SIZE","An attempt was made to 
access a field outside the defined range."),
-        0xC0140012: ("STATUS_ACPI_ACQUIRE_GLOBAL_LOCK","The global system lock 
could not be acquired."),
-        0xC0140013: ("STATUS_ACPI_ALREADY_INITIALIZED","An attempt was made to 
reinitialize the ACPI subsystem."),
-        0xC0140014: ("STATUS_ACPI_NOT_INITIALIZED","The ACPI subsystem has not 
been initialized."),
-        0xC0140015: ("STATUS_ACPI_INVALID_MUTEX_LEVEL","An incorrect mutex was 
specified."),
-        0xC0140016: ("STATUS_ACPI_MUTEX_NOT_OWNED","The mutex is not currently 
owned."),
-        0xC0140017: ("STATUS_ACPI_MUTEX_NOT_OWNER","An attempt was made to 
access the mutex by a process that was not the owner."),
-        0xC0140018: ("STATUS_ACPI_RS_ACCESS","An error occurred during an 
access to region space."),
-        0xC0140019: ("STATUS_ACPI_INVALID_TABLE","An attempt was made to use 
an incorrect table."),
-        0xC0140020: ("STATUS_ACPI_REG_HANDLER_FAILED","The registration of an 
ACPI event failed."),
-        0xC0140021: ("STATUS_ACPI_POWER_REQUEST_FAILED","An ACPI power object 
failed to transition state."),
-        0xC0150001: ("STATUS_SXS_SECTION_NOT_FOUND","The requested section is 
not present in the activation context."),
-        0xC0150002: ("STATUS_SXS_CANT_GEN_ACTCTX","Windows was unble to 
process the application binding information. Refer to the system event log for 
further information."),
-        0xC0150003: ("STATUS_SXS_INVALID_ACTCTXDATA_FORMAT","The application 
binding data format is invalid."),
-        0xC0150004: ("STATUS_SXS_ASSEMBLY_NOT_FOUND","The referenced assembly 
is not installed on the system."),
-        0xC0150005: ("STATUS_SXS_MANIFEST_FORMAT_ERROR","The manifest file 
does not begin with the required tag and format information."),
-        0xC0150006: ("STATUS_SXS_MANIFEST_PARSE_ERROR","The manifest file 
contains one or more syntax errors."),
-        0xC0150007: ("STATUS_SXS_ACTIVATION_CONTEXT_DISABLED","The application 
attempted to activate a disabled activation context."),
-        0xC0150008: ("STATUS_SXS_KEY_NOT_FOUND","The requested lookup key was 
not found in any active activation context."),
-        0xC0150009: ("STATUS_SXS_VERSION_CONFLICT","A component version 
required by the application conflicts with another component version that is 
already active."),
-        0xC015000A: ("STATUS_SXS_WRONG_SECTION_TYPE","The type requested 
activation context section does not match the query API used."),
-        0xC015000B: ("STATUS_SXS_THREAD_QUERIES_DISABLED","Lack of system 
resources has required isolated activation to be disabled for the current 
thread of execution."),
-        0xC015000C: ("STATUS_SXS_ASSEMBLY_MISSING","The referenced assembly 
could not be found."),
-        0xC015000E: ("STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET","An attempt to 
set the process default activation context failed because the process default 
activation context was already set."),
-        0xC015000F: ("STATUS_SXS_EARLY_DEACTIVATION","The activation context 
being deactivated is not the most recently activated one."),
-        0xC0150010: ("STATUS_SXS_INVALID_DEACTIVATION","The activation context 
being deactivated is not active for the current thread of execution."),
-        0xC0150011: ("STATUS_SXS_MULTIPLE_DEACTIVATION","The activation 
context being deactivated has already been deactivated."),
-        0xC0150012: ("STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY","The 
activation context of the system default assembly could not be generated."),
-        0xC0150013: ("STATUS_SXS_PROCESS_TERMINATION_REQUESTED","A component 
used by the isolation facility has requested that the process be terminated."),
-        0xC0150014: ("STATUS_SXS_CORRUPT_ACTIVATION_STACK","The activation 
context activation stack for the running thread of execution is corrupt."),
-        0xC0150015: ("STATUS_SXS_CORRUPTION","The application isolation 
metadata for this process or thread has become corrupt."),
-        0xC0150016: ("STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE","The value 
of an attribute in an identity is not within the legal range."),
-        0xC0150017: ("STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME","The name of 
an attribute in an identity is not within the legal range."),
-        0xC0150018: ("STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE","An identity 
contains two definitions for the same attribute."),
-        0xC0150019: ("STATUS_SXS_IDENTITY_PARSE_ERROR","The identity string is 
malformed. This may be due to a trailing comma, more than two unnamed 
attributes, a missing attribute name, or a missing attribute value."),
-        0xC015001A: ("STATUS_SXS_COMPONENT_STORE_CORRUPT","The component store 
has become corrupted."),
-        0xC015001B: ("STATUS_SXS_FILE_HASH_MISMATCH","A component's file does 
not match the verification information present in the component manifest."),
-        0xC015001C: 
("STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT","The identities of 
the manifests are identical, but their contents are different."),
-        0xC015001D: ("STATUS_SXS_IDENTITIES_DIFFERENT","The component 
identities are different."),
-        0xC015001E: ("STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT","The assembly 
is not a deployment."),
-        0xC015001F: ("STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY","The file is not a 
part of the assembly."),
-        0xC0150020: ("STATUS_ADVANCED_INSTALLER_FAILED","An advanced installer 
failed during setup or servicing."),
-        0xC0150021: ("STATUS_XML_ENCODING_MISMATCH","The character encoding in 
the XML declaration did not match the encoding used in the document."),
-        0xC0150022: ("STATUS_SXS_MANIFEST_TOO_BIG","The size of the manifest 
exceeds the maximum allowed."),
-        0xC0150023: ("STATUS_SXS_SETTING_NOT_REGISTERED","The setting is not 
registered."),
-        0xC0150024: ("STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE","One or more 
required transaction members are not present."),
-        0xC0150025: ("STATUS_SMI_PRIMITIVE_INSTALLER_FAILED","The SMI 
primitive installer failed during setup or servicing."),
-        0xC0150026: ("STATUS_GENERIC_COMMAND_FAILED","A generic command 
executable returned a result that indicates failure."),
-        0xC0150027: ("STATUS_SXS_FILE_HASH_MISSING","A component is missing 
file verification information in its manifest."),
-        0xC0190001: ("STATUS_TRANSACTIONAL_CONFLICT","The function attempted 
to use a name that is reserved for use by another transaction."),
-        0xC0190002: ("STATUS_INVALID_TRANSACTION","The transaction handle 
associated with this operation is invalid."),
-        0xC0190003: ("STATUS_TRANSACTION_NOT_ACTIVE","The requested operation 
was made in the context of a transaction that is no longer active."),
-        0xC0190004: ("STATUS_TM_INITIALIZATION_FAILED","The transaction 
manager was unable to be successfully initialized. Transacted operations are 
not supported."),
-        0xC0190005: ("STATUS_RM_NOT_ACTIVE","Transaction support within the 
specified file system resource manager was not started or was shut down due to 
an error."),
-        0xC0190006: ("STATUS_RM_METADATA_CORRUPT","The metadata of the 
resource manager has been corrupted. The resource manager will not function."),
-        0xC0190007: ("STATUS_TRANSACTION_NOT_JOINED","The resource manager 
attempted to prepare a transaction that it has not successfully joined."),
-        0xC0190008: ("STATUS_DIRECTORY_NOT_RM","The specified directory does 
not contain a file system resource manager."),
-        0xC019000A: ("STATUS_TRANSACTIONS_UNSUPPORTED_REMOTE","The remote 
server or share does not support transacted file operations."),
-        0xC019000B: ("STATUS_LOG_RESIZE_INVALID_SIZE","The requested log size 
for the file system resource manager is invalid."),
-        0xC019000C: ("STATUS_REMOTE_FILE_VERSION_MISMATCH","The remote server 
sent mismatching version number or Fid for a file opened with transactions."),
-        0xC019000F: ("STATUS_CRM_PROTOCOL_ALREADY_EXISTS","The resource 
manager tried to register a protocol that already exists."),
-        0xC0190010: ("STATUS_TRANSACTION_PROPAGATION_FAILED","The attempt to 
propagate the transaction failed."),
-        0xC0190011: ("STATUS_CRM_PROTOCOL_NOT_FOUND","The requested 
propagation protocol was not registered as a CRM."),
-        0xC0190012: ("STATUS_TRANSACTION_SUPERIOR_EXISTS","The transaction 
object already has a superior enlistment, and the caller attempted an operation 
that would have created a new superior. Only a single superior enlistment is 
allowed."),
-        0xC0190013: ("STATUS_TRANSACTION_REQUEST_NOT_VALID","The requested 
operation is not valid on the transaction object in its current state."),
-        0xC0190014: ("STATUS_TRANSACTION_NOT_REQUESTED","The caller has called 
a response API, but the response is not expected because the transaction 
manager did not issue the corresponding request to the caller."),
-        0xC0190015: ("STATUS_TRANSACTION_ALREADY_ABORTED","It is too late to 
perform the requested operation, because the transaction has already been 
aborted."),
-        0xC0190016: ("STATUS_TRANSACTION_ALREADY_COMMITTED","It is too late to 
perform the requested operation, because the transaction has already been 
committed."),
-        0xC0190017: ("STATUS_TRANSACTION_INVALID_MARSHALL_BUFFER","The buffer 
passed in to NtPushTransaction or NtPullTransaction is not in a valid format."),
-        0xC0190018: ("STATUS_CURRENT_TRANSACTION_NOT_VALID","The current 
transaction context associated with the thread is not a valid handle to a 
transaction object."),
-        0xC0190019: ("STATUS_LOG_GROWTH_FAILED","An attempt to create space in 
the transactional resource manager's log failed. The failure status has been 
recorded in the event log."),
-        0xC0190021: ("STATUS_OBJECT_NO_LONGER_EXISTS","The object (file, 
stream, or link) that corresponds to the handle has been deleted by a 
transaction savepoint rollback."),
-        0xC0190022: ("STATUS_STREAM_MINIVERSION_NOT_FOUND","The specified file 
miniversion was not found for this transacted file open."),
-        0xC0190023: ("STATUS_STREAM_MINIVERSION_NOT_VALID","The specified file 
miniversion was found but has been invalidated. The most likely cause is a 
transaction savepoint rollback."),
-        0xC0190024: 
("STATUS_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION","A miniversion 
may be opened only in the context of the transaction that created it."),
-        0xC0190025: ("STATUS_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT","It is 
not possible to open a miniversion with modify access."),
-        0xC0190026: ("STATUS_CANT_CREATE_MORE_STREAM_MINIVERSIONS","It is not 
possible to create any more miniversions for this stream."),
-        0xC0190028: ("STATUS_HANDLE_NO_LONGER_VALID","The handle has been 
invalidated by a transaction. The most likely cause is the presence of memory 
mapping on a file or an open handle when the transaction ended or rolled back 
to savepoint."),
-        0xC0190030: ("STATUS_LOG_CORRUPTION_DETECTED","The log data is 
corrupt."),
-        0xC0190032: ("STATUS_RM_DISCONNECTED","The transaction outcome is 
unavailable because the resource manager responsible for it is disconnected."),
-        0xC0190033: ("STATUS_ENLISTMENT_NOT_SUPERIOR","The request was 
rejected because the enlistment in question is not a superior enlistment."),
-        0xC0190036: ("STATUS_FILE_IDENTITY_NOT_PERSISTENT","The file cannot be 
opened in a transaction because its identity depends on the outcome of an 
unresolved transaction."),
-        0xC0190037: ("STATUS_CANT_BREAK_TRANSACTIONAL_DEPENDENCY","The 
operation cannot be performed because another transaction is depending on this 
property not changing."),
-        0xC0190038: ("STATUS_CANT_CROSS_RM_BOUNDARY","The operation would 
involve a single file with two transactional resource managers and is, 
therefore, not allowed."),
-        0xC0190039: ("STATUS_TXF_DIR_NOT_EMPTY","The $Txf directory must be 
empty for this operation to succeed."),
-        0xC019003A: ("STATUS_INDOUBT_TRANSACTIONS_EXIST","The operation would 
leave a transactional resource manager in an inconsistent state and is 
therefore not allowed."),
-        0xC019003B: ("STATUS_TM_VOLATILE","The operation could not be 
completed because the transaction manager does not have a log."),
-        0xC019003C: ("STATUS_ROLLBACK_TIMER_EXPIRED","A rollback could not be 
scheduled because a previously scheduled rollback has already executed or been 
queued for execution."),
-        0xC019003D: ("STATUS_TXF_ATTRIBUTE_CORRUPT","The transactional 
metadata attribute on the file or directory %hs is corrupt and unreadable."),
-        0xC019003E: ("STATUS_EFS_NOT_ALLOWED_IN_TRANSACTION","The encryption 
operation could not be completed because a transaction is active."),
-        0xC019003F: ("STATUS_TRANSACTIONAL_OPEN_NOT_ALLOWED","This object is 
not allowed to be opened in a transaction."),
-        0xC0190040: ("STATUS_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE","Memory 
mapping (creating a mapped section) a remote file under a transaction is not 
supported."),
-        0xC0190043: ("STATUS_TRANSACTION_REQUIRED_PROMOTION","Promotion was 
required to allow the resource manager to enlist, but the transaction was set 
to disallow it."),
-        0xC0190044: ("STATUS_CANNOT_EXECUTE_FILE_IN_TRANSACTION","This file is 
open for modification in an unresolved transaction and may be opened for 
execute only by a transacted reader."),
-        0xC0190045: ("STATUS_TRANSACTIONS_NOT_FROZEN","The request to thaw 
frozen transactions was ignored because transactions were not previously 
frozen."),
-        0xC0190046: ("STATUS_TRANSACTION_FREEZE_IN_PROGRESS","Transactions 
cannot be frozen because a freeze is already in progress."),
-        0xC0190047: ("STATUS_NOT_SNAPSHOT_VOLUME","The target volume is not a 
snapshot volume. This operation is valid only on a volume mounted as a 
snapshot."),
-        0xC0190048: ("STATUS_NO_SAVEPOINT_WITH_OPEN_FILES","The savepoint 
operation failed because files are open on the transaction, which is not 
permitted."),
-        0xC0190049: ("STATUS_SPARSE_NOT_ALLOWED_IN_TRANSACTION","The sparse 
operation could not be completed because a transaction is active on the file."),
-        0xC019004A: ("STATUS_TM_IDENTITY_MISMATCH","The call to create a 
transaction manager object failed because the Tm Identity that is stored in the 
log file does not match the Tm Identity that was passed in as an argument."),
-        0xC019004B: ("STATUS_FLOATED_SECTION","I/O was attempted on a section 
object that has been floated as a result of a transaction ending. There is no 
valid data."),
-        0xC019004C: ("STATUS_CANNOT_ACCEPT_TRANSACTED_WORK","The transactional 
resource manager cannot currently accept transacted work due to a transient 
condition, such as low resources."),
-        0xC019004D: ("STATUS_CANNOT_ABORT_TRANSACTIONS","The transactional 
resource manager had too many transactions outstanding that could not be 
aborted. The transactional resource manager has been shut down."),
-        0xC019004E: ("STATUS_TRANSACTION_NOT_FOUND","The specified transaction 
was unable to be opened because it was not found."),
-        0xC019004F: ("STATUS_RESOURCEMANAGER_NOT_FOUND","The specified 
resource manager was unable to be opened because it was not found."),
-        0xC0190050: ("STATUS_ENLISTMENT_NOT_FOUND","The specified enlistment 
was unable to be opened because it was not found."),
-        0xC0190051: ("STATUS_TRANSACTIONMANAGER_NOT_FOUND","The specified 
transaction manager was unable to be opened because it was not found."),
-        0xC0190052: ("STATUS_TRANSACTIONMANAGER_NOT_ONLINE","The specified 
resource manager was unable to create an enlistment because its associated 
transaction manager is not online."),
-        0xC0190053: ("STATUS_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION","The 
specified transaction manager was unable to create the objects contained in its 
log file in the Ob namespace. Therefore, the transaction manager was unable to 
recover."),
-        0xC0190054: ("STATUS_TRANSACTION_NOT_ROOT","The call to create a 
superior enlistment on this transaction object could not be completed because 
the transaction object specified for the enlistment is a subordinate branch of 
the transaction. Only the root of the transaction can be enlisted as a 
superior."),
-        0xC0190055: ("STATUS_TRANSACTION_OBJECT_EXPIRED","Because the 
associated transaction manager or resource manager has been closed, the handle 
is no longer valid."),
-        0xC0190056: ("STATUS_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION","The 
compression operation could not be completed because a transaction is active on 
the file."),
-        0xC0190057: ("STATUS_TRANSACTION_RESPONSE_NOT_ENLISTED","The specified 
operation could not be performed on this superior enlistment because the 
enlistment was not created with the corresponding completion response in the 
NotificationMask."),
-        0xC0190058: ("STATUS_TRANSACTION_RECORD_TOO_LONG","The specified 
operation could not be performed because the record to be logged was too long. 
This can occur because either there are too many enlistments on this 
transaction or the combined RecoveryInformation being logged on behalf of those 
enlistments is too long."),
-        0xC0190059: ("STATUS_NO_LINK_TRACKING_IN_TRANSACTION","The 
link-tracking operation could not be completed because a transaction is 
active."),
-        0xC019005A: ("STATUS_OPERATION_NOT_SUPPORTED_IN_TRANSACTION","This 
operation cannot be performed in a transaction."),
-        0xC019005B: ("STATUS_TRANSACTION_INTEGRITY_VIOLATED","The kernel 
transaction manager had to abort or forget the transaction because it blocked 
forward progress."),
-        0xC0190060: ("STATUS_EXPIRED_HANDLE","The handle is no longer properly 
associated with its transaction. It may have been opened in a transactional 
resource manager that was subsequently forced to restart. Please close the 
handle and open a new one."),
-        0xC0190061: ("STATUS_TRANSACTION_NOT_ENLISTED","The specified 
operation could not be performed because the resource manager is not enlisted 
in the transaction."),
-        0xC01A0001: ("STATUS_LOG_SECTOR_INVALID","The log service found an 
invalid log sector."),
-        0xC01A0002: ("STATUS_LOG_SECTOR_PARITY_INVALID","The log service 
encountered a log sector with invalid block parity."),
-        0xC01A0003: ("STATUS_LOG_SECTOR_REMAPPED","The log service encountered 
a remapped log sector."),
-        0xC01A0004: ("STATUS_LOG_BLOCK_INCOMPLETE","The log service 
encountered a partial or incomplete log block."),
-        0xC01A0005: ("STATUS_LOG_INVALID_RANGE","The log service encountered 
an attempt to access data outside the active log range."),
-        0xC01A0006: ("STATUS_LOG_BLOCKS_EXHAUSTED","The log service user-log 
marshaling buffers are exhausted."),
-        0xC01A0007: ("STATUS_LOG_READ_CONTEXT_INVALID","The log service 
encountered an attempt to read from a marshaling area with an invalid read 
context."),
-        0xC01A0008: ("STATUS_LOG_RESTART_INVALID","The log service encountered 
an invalid log restart area."),
-        0xC01A0009: ("STATUS_LOG_BLOCK_VERSION","The log service encountered 
an invalid log block version."),
-        0xC01A000A: ("STATUS_LOG_BLOCK_INVALID","The log service encountered 
an invalid log block."),
-        0xC01A000B: ("STATUS_LOG_READ_MODE_INVALID","The log service 
encountered an attempt to read the log with an invalid read mode."),
-        0xC01A000D: ("STATUS_LOG_METADATA_CORRUPT","The log service 
encountered a corrupted metadata file."),
-        0xC01A000E: ("STATUS_LOG_METADATA_INVALID","The log service 
encountered a metadata file that could not be created by the log file system."),
-        0xC01A000F: ("STATUS_LOG_METADATA_INCONSISTENT","The log service 
encountered a metadata file with inconsistent data."),
-        0xC01A0010: ("STATUS_LOG_RESERVATION_INVALID","The log service 
encountered an attempt to erroneously allocate or dispose reservation space."),
-        0xC01A0011: ("STATUS_LOG_CANT_DELETE","The log service cannot delete 
the log file or the file system container."),
-        0xC01A0012: ("STATUS_LOG_CONTAINER_LIMIT_EXCEEDED","The log service 
has reached the maximum allowable containers allocated to a log file."),
-        0xC01A0013: ("STATUS_LOG_START_OF_LOG","The log service has attempted 
to read or write backward past the start of the log."),
-        0xC01A0014: ("STATUS_LOG_POLICY_ALREADY_INSTALLED","The log policy 
could not be installed because a policy of the same type is already present."),
-        0xC01A0015: ("STATUS_LOG_POLICY_NOT_INSTALLED","The log policy in 
question was not installed at the time of the request."),
-        0xC01A0016: ("STATUS_LOG_POLICY_INVALID","The installed set of 
policies on the log is invalid."),
-        0xC01A0017: ("STATUS_LOG_POLICY_CONFLICT","A policy on the log in 
question prevented the operation from completing."),
-        0xC01A0018: ("STATUS_LOG_PINNED_ARCHIVE_TAIL","The log space cannot be 
reclaimed because the log is pinned by the archive tail."),
-        0xC01A0019: ("STATUS_LOG_RECORD_NONEXISTENT","The log record is not a 
record in the log file."),
-        0xC01A001A: ("STATUS_LOG_RECORDS_RESERVED_INVALID","The number of 
reserved log records or the adjustment of the number of reserved log records is 
invalid."),
-        0xC01A001B: ("STATUS_LOG_SPACE_RESERVED_INVALID","The reserved log 
space or the adjustment of the log space is invalid."),
-        0xC01A001C: ("STATUS_LOG_TAIL_INVALID","A new or existing archive tail 
or the base of the active log is invalid."),
-        0xC01A001D: ("STATUS_LOG_FULL","The log space is exhausted."),
-        0xC01A001E: ("STATUS_LOG_MULTIPLEXED","The log is multiplexed; no 
direct writes to the physical log are allowed."),
-        0xC01A001F: ("STATUS_LOG_DEDICATED","The operation failed because the 
log is dedicated."),
-        0xC01A0020: ("STATUS_LOG_ARCHIVE_NOT_IN_PROGRESS","The operation 
requires an archive context."),
-        0xC01A0021: ("STATUS_LOG_ARCHIVE_IN_PROGRESS","Log archival is in 
progress."),
-        0xC01A0022: ("STATUS_LOG_EPHEMERAL","The operation requires a 
nonephemeral log, but the log is ephemeral."),
-        0xC01A0023: ("STATUS_LOG_NOT_ENOUGH_CONTAINERS","The log must have at 
least two containers before it can be read from or written to."),
-        0xC01A0024: ("STATUS_LOG_CLIENT_ALREADY_REGISTERED","A log client has 
already registered on the stream."),
-        0xC01A0025: ("STATUS_LOG_CLIENT_NOT_REGISTERED","A log client has not 
been registered on the stream."),
-        0xC01A0026: ("STATUS_LOG_FULL_HANDLER_IN_PROGRESS","A request has 
already been made to handle the log full condition."),
-        0xC01A0027: ("STATUS_LOG_CONTAINER_READ_FAILED","The log service 
encountered an error when attempting to read from a log container."),
-        0xC01A0028: ("STATUS_LOG_CONTAINER_WRITE_FAILED","The log service 
encountered an error when attempting to write to a log container."),
-        0xC01A0029: ("STATUS_LOG_CONTAINER_OPEN_FAILED","The log service 
encountered an error when attempting to open a log container."),
-        0xC01A002A: ("STATUS_LOG_CONTAINER_STATE_INVALID","The log service 
encountered an invalid container state when attempting a requested action."),
-        0xC01A002B: ("STATUS_LOG_STATE_INVALID","The log service is not in the 
correct state to perform a requested action."),
-        0xC01A002C: ("STATUS_LOG_PINNED","The log space cannot be reclaimed 
because the log is pinned."),
-        0xC01A002D: ("STATUS_LOG_METADATA_FLUSH_FAILED","The log metadata 
flush failed."),
-        0xC01A002E: ("STATUS_LOG_INCONSISTENT_SECURITY","Security on the log 
and its containers is inconsistent."),
-        0xC01A002F: ("STATUS_LOG_APPENDED_FLUSH_FAILED","Records were appended 
to the log or reservation changes were made, but the log could not be 
flushed."),
-        0xC01A0030: ("STATUS_LOG_PINNED_RESERVATION","The log is pinned due to 
reservation consuming most of the log space. Free some reserved records to make 
space available."),
-        0xC01B00EA: ("STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD","{Display 
Driver Stopped Responding} The %hs display driver has stopped working normally. 
Save your work and reboot the system to restore full display functionality. The 
next time you reboot the computer, a dialog box will allow you to upload data 
about this failure to Microsoft."),
-        0xC01C0001: ("STATUS_FLT_NO_HANDLER_DEFINED","A handler was not 
defined by the filter for this operation."),
-        0xC01C0002: ("STATUS_FLT_CONTEXT_ALREADY_DEFINED","A context is 
already defined for this object."),
-        0xC01C0003: ("STATUS_FLT_INVALID_ASYNCHRONOUS_REQUEST","Asynchronous 
requests are not valid for this operation."),
-        0xC01C0004: ("STATUS_FLT_DISALLOW_FAST_IO","This is an internal error 
code used by the filter manager to determine if a fast I/O operation should be 
forced down the input/output request packet (IRP) path. Minifilters should 
never return this value."),
-        0xC01C0005: ("STATUS_FLT_INVALID_NAME_REQUEST","An invalid name 
request was made. The name requested cannot be retrieved at this time."),
-        0xC01C0006: ("STATUS_FLT_NOT_SAFE_TO_POST_OPERATION","Posting this 
operation to a worker thread for further processing is not safe at this time 
because it could lead to a system deadlock."),
-        0xC01C0007: ("STATUS_FLT_NOT_INITIALIZED","The Filter Manager was not 
initialized when a filter tried to register. Make sure that the Filter Manager 
is loaded as a driver."),
-        0xC01C0008: ("STATUS_FLT_FILTER_NOT_READY","The filter is not ready 
for attachment to volumes because it has not finished initializing 
(FltStartFiltering has not been called)."),
-        0xC01C0009: ("STATUS_FLT_POST_OPERATION_CLEANUP","The filter must 
clean up any operation-specific context at this time because it is being 
removed from the system before the operation is completed by the lower 
drivers."),
-        0xC01C000A: ("STATUS_FLT_INTERNAL_ERROR","The Filter Manager had an 
internal error from which it cannot recover; therefore, the operation has 
failed. This is usually the result of a filter returning an invalid value from 
a pre-operation callback."),
-        0xC01C000B: ("STATUS_FLT_DELETING_OBJECT","The object specified for 
this action is in the process of being deleted; therefore, the action requested 
cannot be completed at this time."),
-        0xC01C000C: ("STATUS_FLT_MUST_BE_NONPAGED_POOL","A nonpaged pool must 
be used for this type of context."),
-        0xC01C000D: ("STATUS_FLT_DUPLICATE_ENTRY","A duplicate handler 
definition has been provided for an operation."),
-        0xC01C000E: ("STATUS_FLT_CBDQ_DISABLED","The callback data queue has 
been disabled."),
-        0xC01C000F: ("STATUS_FLT_DO_NOT_ATTACH","Do not attach the filter to 
the volume at this time."),
-        0xC01C0010: ("STATUS_FLT_DO_NOT_DETACH","Do not detach the filter from 
the volume at this time."),
-        0xC01C0011: ("STATUS_FLT_INSTANCE_ALTITUDE_COLLISION","An instance 
already exists at this altitude on the volume specified."),
-        0xC01C0012: ("STATUS_FLT_INSTANCE_NAME_COLLISION","An instance already 
exists with this name on the volume specified."),
-        0xC01C0013: ("STATUS_FLT_FILTER_NOT_FOUND","The system could not find 
the filter specified."),
-        0xC01C0014: ("STATUS_FLT_VOLUME_NOT_FOUND","The system could not find 
the volume specified."),
-        0xC01C0015: ("STATUS_FLT_INSTANCE_NOT_FOUND","The system could not 
find the instance specified."),
-        0xC01C0016: ("STATUS_FLT_CONTEXT_ALLOCATION_NOT_FOUND","No registered 
context allocation definition was found for the given request."),
-        0xC01C0017: ("STATUS_FLT_INVALID_CONTEXT_REGISTRATION","An invalid 
parameter was specified during context registration."),
-        0xC01C0018: ("STATUS_FLT_NAME_CACHE_MISS","The name requested was not 
found in the Filter Manager name cache and could not be retrieved from the file 
system."),
-        0xC01C0019: ("STATUS_FLT_NO_DEVICE_OBJECT","The requested device 
object does not exist for the given volume."),
-        0xC01C001A: ("STATUS_FLT_VOLUME_ALREADY_MOUNTED","The specified volume 
is already mounted."),
-        0xC01C001B: ("STATUS_FLT_ALREADY_ENLISTED","The specified transaction 
context is already enlisted in a transaction."),
-        0xC01C001C: ("STATUS_FLT_CONTEXT_ALREADY_LINKED","The specified 
context is already attached to another object."),
-        0xC01C0020: ("STATUS_FLT_NO_WAITER_FOR_REPLY","No waiter is present 
for the filter's reply to this message."),
-        0xC01D0001: ("STATUS_MONITOR_NO_DESCRIPTOR","A monitor descriptor 
could not be obtained."),
-        0xC01D0002: ("STATUS_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT","This release 
does not support the format of the obtained monitor descriptor."),
-        0xC01D0003: ("STATUS_MONITOR_INVALID_DESCRIPTOR_CHECKSUM","The 
checksum of the obtained monitor descriptor is invalid."),
-        0xC01D0004: ("STATUS_MONITOR_INVALID_STANDARD_TIMING_BLOCK","The 
monitor descriptor contains an invalid standard timing block."),
-        0xC01D0005: ("STATUS_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED","WMI 
data-block registration failed for one of the MSMonitorClass WMI subclasses."),
-        0xC01D0006: ("STATUS_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK","The 
provided monitor descriptor block is either corrupted or does not contain the 
monitor's detailed serial number."),
-        0xC01D0007: ("STATUS_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK","The 
provided monitor descriptor block is either corrupted or does not contain the 
monitor's user-friendly name."),
-        0xC01D0008: ("STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA","There is no 
monitor descriptor data at the specified (offset or size) region."),
-        0xC01D0009: ("STATUS_MONITOR_INVALID_DETAILED_TIMING_BLOCK","The 
monitor descriptor contains an invalid detailed timing block."),
-        0xC01D000A: ("STATUS_MONITOR_INVALID_MANUFACTURE_DATE","Monitor 
descriptor contains invalid manufacture date."),
-        0xC01E0000: ("STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER","Exclusive 
mode ownership is needed to create an unmanaged primary allocation."),
-        0xC01E0001: ("STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER","The driver 
needs more DMA buffer space to complete the requested operation."),
-        0xC01E0002: ("STATUS_GRAPHICS_INVALID_DISPLAY_ADAPTER","The specified 
display adapter handle is invalid."),
-        0xC01E0003: ("STATUS_GRAPHICS_ADAPTER_WAS_RESET","The specified 
display adapter and all of its state have been reset."),
-        0xC01E0004: ("STATUS_GRAPHICS_INVALID_DRIVER_MODEL","The driver stack 
does not match the expected driver model."),
-        0xC01E0005: ("STATUS_GRAPHICS_PRESENT_MODE_CHANGED","Present happened 
but ended up into the changed desktop mode."),
-        0xC01E0006: ("STATUS_GRAPHICS_PRESENT_OCCLUDED","Nothing to present 
due to desktop occlusion."),
-        0xC01E0007: ("STATUS_GRAPHICS_PRESENT_DENIED","Not able to present due 
to denial of desktop access."),
-        0xC01E0008: ("STATUS_GRAPHICS_CANNOTCOLORCONVERT","Not able to present 
with color conversion."),
-        0xC01E000B: ("STATUS_GRAPHICS_PRESENT_REDIRECTION_DISABLED","Present 
redirection is disabled (desktop windowing management subsystem is off)."),
-        0xC01E000C: ("STATUS_GRAPHICS_PRESENT_UNOCCLUDED","Previous exclusive 
VidPn source owner has released its ownership"),
-        0xC01E0100: ("STATUS_GRAPHICS_NO_VIDEO_MEMORY","Not enough video 
memory is available to complete the operation."),
-        0xC01E0101: ("STATUS_GRAPHICS_CANT_LOCK_MEMORY","Could not probe and 
lock the underlying memory of an allocation."),
-        0xC01E0102: ("STATUS_GRAPHICS_ALLOCATION_BUSY","The allocation is 
currently busy."),
-        0xC01E0103: ("STATUS_GRAPHICS_TOO_MANY_REFERENCES","An object being 
referenced has already reached the maximum reference count and cannot be 
referenced further."),
-        0xC01E0104: ("STATUS_GRAPHICS_TRY_AGAIN_LATER","A problem could not be 
solved due to an existing condition. Try again later."),
-        0xC01E0105: ("STATUS_GRAPHICS_TRY_AGAIN_NOW","A problem could not be 
solved due to an existing condition. Try again now."),
-        0xC01E0106: ("STATUS_GRAPHICS_ALLOCATION_INVALID","The allocation is 
invalid."),
-        0xC01E0107: ("STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE","No 
more unswizzling apertures are currently available."),
-        0xC01E0108: ("STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED","The 
current allocation cannot be unswizzled by an aperture."),
-        0xC01E0109: ("STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION","The 
request failed because a pinned allocation cannot be evicted."),
-        0xC01E0110: ("STATUS_GRAPHICS_INVALID_ALLOCATION_USAGE","The 
allocation cannot be used from its current segment location for the specified 
operation."),
-        0xC01E0111: ("STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION","A locked 
allocation cannot be used in the current command buffer."),
-        0xC01E0112: ("STATUS_GRAPHICS_ALLOCATION_CLOSED","The allocation being 
referenced has been closed permanently."),
-        0xC01E0113: ("STATUS_GRAPHICS_INVALID_ALLOCATION_INSTANCE","An invalid 
allocation instance is being referenced."),
-        0xC01E0114: ("STATUS_GRAPHICS_INVALID_ALLOCATION_HANDLE","An invalid 
allocation handle is being referenced."),
-        0xC01E0115: ("STATUS_GRAPHICS_WRONG_ALLOCATION_DEVICE","The allocation 
being referenced does not belong to the current device."),
-        0xC01E0116: ("STATUS_GRAPHICS_ALLOCATION_CONTENT_LOST","The specified 
allocation lost its content."),
-        0xC01E0200: ("STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE","A GPU 
exception was detected on the given device. The device cannot be scheduled."),
-        0xC01E0300: ("STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY","The specified 
VidPN topology is invalid."),
-        0xC01E0301: ("STATUS_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED","The 
specified VidPN topology is valid but is not supported by this model of the 
display adapter."),
-        0xC01E0302: 
("STATUS_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED","The specified VidPN 
topology is valid but is not currently supported by the display adapter due to 
allocation of its resources."),
-        0xC01E0303: ("STATUS_GRAPHICS_INVALID_VIDPN","The specified VidPN 
handle is invalid."),
-        0xC01E0304: ("STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE","The 
specified video present source is invalid."),
-        0xC01E0305: ("STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET","The 
specified video present target is invalid."),
-        0xC01E0306: ("STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED","The 
specified VidPN modality is not supported (for example, at least two of the 
pinned modes are not co-functional)."),
-        0xC01E0308: ("STATUS_GRAPHICS_INVALID_VIDPN_SOURCEMODESET","The 
specified VidPN source mode set is invalid."),
-        0xC01E0309: ("STATUS_GRAPHICS_INVALID_VIDPN_TARGETMODESET","The 
specified VidPN target mode set is invalid."),
-        0xC01E030A: ("STATUS_GRAPHICS_INVALID_FREQUENCY","The specified video 
signal frequency is invalid."),
-        0xC01E030B: ("STATUS_GRAPHICS_INVALID_ACTIVE_REGION","The specified 
video signal active region is invalid."),
-        0xC01E030C: ("STATUS_GRAPHICS_INVALID_TOTAL_REGION","The specified 
video signal total region is invalid."),
-        0xC01E0310: ("STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE","The 
specified video present source mode is invalid."),
-        0xC01E0311: ("STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE","The 
specified video present target mode is invalid."),
-        0xC01E0312: ("STATUS_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET","The 
pinned mode must remain in the set on the VidPN's co-functional modality 
enumeration."),
-        0xC01E0313: ("STATUS_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY","The specified 
video present path is already in the VidPN's topology."),
-        0xC01E0314: ("STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET","The specified 
mode is already in the mode set."),
-        0xC01E0315: ("STATUS_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET","The 
specified video present source set is invalid."),
-        0xC01E0316: ("STATUS_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET","The 
specified video present target set is invalid."),
-        0xC01E0317: ("STATUS_GRAPHICS_SOURCE_ALREADY_IN_SET","The specified 
video present source is already in the video present source set."),
-        0xC01E0318: ("STATUS_GRAPHICS_TARGET_ALREADY_IN_SET","The specified 
video present target is already in the video present target set."),
-        0xC01E0319: ("STATUS_GRAPHICS_INVALID_VIDPN_PRESENT_PATH","The 
specified VidPN present path is invalid."),
-        0xC01E031A: ("STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY","The 
miniport has no recommendation for augmenting the specified VidPN's topology."),
-        0xC01E031B: ("STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET","The 
specified monitor frequency range set is invalid."),
-        0xC01E031C: ("STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE","The 
specified monitor frequency range is invalid."),
-        0xC01E031D: ("STATUS_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET","The 
specified frequency range is not in the specified monitor frequency range 
set."),
-        0xC01E031F: ("STATUS_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET","The 
specified frequency range is already in the specified monitor frequency range 
set."),
-        0xC01E0320: ("STATUS_GRAPHICS_STALE_MODESET","The specified mode set 
is stale. Reacquire the new mode set."),
-        0xC01E0321: ("STATUS_GRAPHICS_INVALID_MONITOR_SOURCEMODESET","The 
specified monitor source mode set is invalid."),
-        0xC01E0322: ("STATUS_GRAPHICS_INVALID_MONITOR_SOURCE_MODE","The 
specified monitor source mode is invalid."),
-        0xC01E0323: ("STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN","The 
miniport does not have a recommendation regarding the request to provide a 
functional VidPN given the current display adapter configuration."),
-        0xC01E0324: ("STATUS_GRAPHICS_MODE_ID_MUST_BE_UNIQUE","The ID of the 
specified mode is being used by another mode in the set."),
-        0xC01E0325: 
("STATUS_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION","The system 
failed to determine a mode that is supported by both the display adapter and 
the monitor connected to it."),
-        0xC01E0326: 
("STATUS_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES","The number of video 
present targets must be greater than or equal to the number of video present 
sources."),
-        0xC01E0327: ("STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY","The specified 
present path is not in the VidPN's topology."),
-        0xC01E0328: 
("STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE","The display adapter 
must have at least one video present source."),
-        0xC01E0329: 
("STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET","The display adapter 
must have at least one video present target."),
-        0xC01E032A: ("STATUS_GRAPHICS_INVALID_MONITORDESCRIPTORSET","The 
specified monitor descriptor set is invalid."),
-        0xC01E032B: ("STATUS_GRAPHICS_INVALID_MONITORDESCRIPTOR","The 
specified monitor descriptor is invalid."),
-        0xC01E032C: ("STATUS_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET","The 
specified descriptor is not in the specified monitor descriptor set."),
-        0xC01E032D: ("STATUS_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET","The 
specified descriptor is already in the specified monitor descriptor set."),
-        0xC01E032E: 
("STATUS_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE","The ID of the specified 
monitor descriptor is being used by another descriptor in the set."),
-        0xC01E032F: ("STATUS_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE","The 
specified video present target subset type is invalid."),
-        0xC01E0330: ("STATUS_GRAPHICS_RESOURCES_NOT_RELATED","Two or more of 
the specified resources are not related to each other, as defined by the 
interface semantics."),
-        0xC01E0331: ("STATUS_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE","The ID of the 
specified video present source is being used by another source in the set."),
-        0xC01E0332: ("STATUS_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE","The ID of the 
specified video present target is being used by another target in the set."),
-        0xC01E0333: ("STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET","The 
specified VidPN source cannot be used because there is no available VidPN 
target to connect it to."),
-        0xC01E0334: 
("STATUS_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER","The newly 
arrived monitor could not be associated with a display adapter."),
-        0xC01E0335: ("STATUS_GRAPHICS_NO_VIDPNMGR","The particular display 
adapter does not have an associated VidPN manager."),
-        0xC01E0336: ("STATUS_GRAPHICS_NO_ACTIVE_VIDPN","The VidPN manager of 
the particular display adapter does not have an active VidPN."),
-        0xC01E0337: ("STATUS_GRAPHICS_STALE_VIDPN_TOPOLOGY","The specified 
VidPN topology is stale; obtain the new topology."),
-        0xC01E0338: ("STATUS_GRAPHICS_MONITOR_NOT_CONNECTED","No monitor is 
connected on the specified video present target."),
-        0xC01E0339: ("STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY","The specified 
source is not part of the specified VidPN's topology."),
-        0xC01E033A: ("STATUS_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE","The 
specified primary surface size is invalid."),
-        0xC01E033B: ("STATUS_GRAPHICS_INVALID_VISIBLEREGION_SIZE","The 
specified visible region size is invalid."),
-        0xC01E033C: ("STATUS_GRAPHICS_INVALID_STRIDE","The specified stride is 
invalid."),
-        0xC01E033D: ("STATUS_GRAPHICS_INVALID_PIXELFORMAT","The specified 
pixel format is invalid."),
-        0xC01E033E: ("STATUS_GRAPHICS_INVALID_COLORBASIS","The specified color 
basis is invalid."),
-        0xC01E033F: ("STATUS_GRAPHICS_INVALID_PIXELVALUEACCESSMODE","The 
specified pixel value access mode is invalid."),
-        0xC01E0340: ("STATUS_GRAPHICS_TARGET_NOT_IN_TOPOLOGY","The specified 
target is not part of the specified VidPN's topology."),
-        0xC01E0341: 
("STATUS_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT","Failed to acquire the 
display mode management interface."),
-        0xC01E0342: ("STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE","The specified 
VidPN source is already owned by a DMM client and cannot be used until that 
client releases it."),
-        0xC01E0343: ("STATUS_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN","The specified 
VidPN is active and cannot be accessed."),
-        0xC01E0344: ("STATUS_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL","The 
specified VidPN's present path importance ordinal is invalid."),
-        0xC01E0345: 
("STATUS_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION","The specified 
VidPN's present path content geometry transformation is invalid."),
-        0xC01E0346: 
("STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED","The 
specified content geometry transformation is not supported on the respective 
VidPN present path."),
-        0xC01E0347: ("STATUS_GRAPHICS_INVALID_GAMMA_RAMP","The specified gamma 
ramp is invalid."),
-        0xC01E0348: ("STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED","The specified 
gamma ramp is not supported on the respective VidPN present path."),
-        0xC01E0349: 
("STATUS_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED","Multisampling is not supported 
on the respective VidPN present path."),
-        0xC01E034A: ("STATUS_GRAPHICS_MODE_NOT_IN_MODESET","The specified mode 
is not in the specified mode set."),
-        0xC01E034D: 
("STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON","The specified 
VidPN topology recommendation reason is invalid."),
-        0xC01E034E: ("STATUS_GRAPHICS_INVALID_PATH_CONTENT_TYPE","The 
specified VidPN present path content type is invalid."),
-        0xC01E034F: ("STATUS_GRAPHICS_INVALID_COPYPROTECTION_TYPE","The 
specified VidPN present path copy protection type is invalid."),
-        0xC01E0350: ("STATUS_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS","Only 
one unassigned mode set can exist at any one time for a particular VidPN source 
or target."),
-        0xC01E0352: ("STATUS_GRAPHICS_INVALID_SCANLINE_ORDERING","The 
specified scan line ordering type is invalid."),
-        0xC01E0353: ("STATUS_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED","The 
topology changes are not allowed for the specified VidPN."),
-        0xC01E0354: ("STATUS_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS","All 
available importance ordinals are being used in the specified topology."),
-        0xC01E0355: ("STATUS_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT","The 
specified primary surface has a different private-format attribute than the 
current primary surface."),
-        0xC01E0356: ("STATUS_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM","The 
specified mode-pruning algorithm is invalid."),
-        0xC01E0357: ("STATUS_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN","The 
specified monitor-capability origin is invalid."),
-        0xC01E0358: 
("STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT","The specified 
monitor-frequency range constraint is invalid."),
-        0xC01E0359: ("STATUS_GRAPHICS_MAX_NUM_PATHS_REACHED","The maximum 
supported number of present paths has been reached."),
-        0xC01E035A: ("STATUS_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION","The 
miniport requested that augmentation be canceled for the specified source of 
the specified VidPN's topology."),
-        0xC01E035B: ("STATUS_GRAPHICS_INVALID_CLIENT_TYPE","The specified 
client type was not recognized."),
-        0xC01E035C: ("STATUS_GRAPHICS_CLIENTVIDPN_NOT_SET","The client VidPN 
is not set on this adapter (for example, no user mode-initiated mode changes 
have taken place on this adapter)."),
-        0xC01E0400: ("STATUS_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED","The 
specified display adapter child device already has an external device connected 
to it."),
-        0xC01E0401: ("STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED","The 
display adapter child device does not support reporting a descriptor."),
-        0xC01E0430: ("STATUS_GRAPHICS_NOT_A_LINKED_ADAPTER","The display 
adapter is not linked to any other adapters."),
-        0xC01E0431: ("STATUS_GRAPHICS_LEADLINK_NOT_ENUMERATED","The lead 
adapter in a linked configuration was not enumerated yet."),
-        0xC01E0432: ("STATUS_GRAPHICS_CHAINLINKS_NOT_ENUMERATED","Some chain 
adapters in a linked configuration have not yet been enumerated."),
-        0xC01E0433: ("STATUS_GRAPHICS_ADAPTER_CHAIN_NOT_READY","The chain of 
linked adapters is not ready to start because of an unknown failure."),
-        0xC01E0434: ("STATUS_GRAPHICS_CHAINLINKS_NOT_STARTED","An attempt was 
made to start a lead link display adapter when the chain links had not yet 
started."),
-        0xC01E0435: ("STATUS_GRAPHICS_CHAINLINKS_NOT_POWERED_ON","An attempt 
was made to turn on a lead link display adapter when the chain links were 
turned off."),
-        0xC01E0436: ("STATUS_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE","The 
adapter link was found in an inconsistent state. Not all adapters are in an 
expected PNP/power state."),
-        0xC01E0438: ("STATUS_GRAPHICS_NOT_POST_DEVICE_DRIVER","The driver 
trying to start is not the same as the driver for the posted display adapter."),
-        0xC01E043B: ("STATUS_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED","An 
operation is being attempted that requires the display adapter to be in a 
quiescent state."),
-        0xC01E0500: ("STATUS_GRAPHICS_OPM_NOT_SUPPORTED","The driver does not 
support OPM."),
-        0xC01E0501: ("STATUS_GRAPHICS_COPP_NOT_SUPPORTED","The driver does not 
support COPP."),
-        0xC01E0502: ("STATUS_GRAPHICS_UAB_NOT_SUPPORTED","The driver does not 
support UAB."),
-        0xC01E0503: ("STATUS_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS","The 
specified encrypted parameters are invalid."),
-        0xC01E0504: ("STATUS_GRAPHICS_OPM_PARAMETER_ARRAY_TOO_SMALL","An array 
passed to a function cannot hold all of the data that the function wants to put 
in it."),
-        0xC01E0505: ("STATUS_GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST","The GDI 
display device passed to this function does not have any active protected 
outputs."),
-        0xC01E0506: 
("STATUS_GRAPHICS_PVP_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME","The PVP cannot 
find an actual GDI display device that corresponds to the passed-in GDI display 
device name."),
-        0xC01E0507: 
("STATUS_GRAPHICS_PVP_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP","This function 
failed because the GDI display device passed to it was not attached to the 
Windows desktop."),
-        0xC01E0508: 
("STATUS_GRAPHICS_PVP_MIRRORING_DEVICES_NOT_SUPPORTED","The PVP does not 
support mirroring display devices because they do not have any protected 
outputs."),
-        0xC01E050A: ("STATUS_GRAPHICS_OPM_INVALID_POINTER","The function 
failed because an invalid pointer parameter was passed to it. A pointer 
parameter is invalid if it is null, is not correctly aligned, or it points to 
an invalid address or a kernel mode address."),
-        0xC01E050B: ("STATUS_GRAPHICS_OPM_INTERNAL_ERROR","An internal error 
caused an operation to fail."),
-        0xC01E050C: ("STATUS_GRAPHICS_OPM_INVALID_HANDLE","The function failed 
because the caller passed in an invalid OPM user-mode handle."),
-        0xC01E050D: 
("STATUS_GRAPHICS_PVP_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE","This function 
failed because the GDI device passed to it did not have any monitors associated 
with it."),
-        0xC01E050E: ("STATUS_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH","A 
certificate could not be returned because the certificate buffer passed to the 
function was too small."),
-        0xC01E050F: 
("STATUS_GRAPHICS_OPM_SPANNING_MODE_ENABLED","DxgkDdiOpmCreateProtectedOutput() 
could not create a protected output because the video present yarget is in 
spanning mode."),
-        0xC01E0510: 
("STATUS_GRAPHICS_OPM_THEATER_MODE_ENABLED","DxgkDdiOpmCreateProtectedOutput() 
could not create a protected output because the video present target is in 
theater mode."),
-        0xC01E0511: ("STATUS_GRAPHICS_PVP_HFS_FAILED","The function call 
failed because the display adapter's hardware functionality scan (HFS) failed 
to validate the graphics hardware."),
-        0xC01E0512: ("STATUS_GRAPHICS_OPM_INVALID_SRM","The HDCP SRM passed to 
this function did not comply with section 5 of the HDCP 1.1 specification."),
-        0xC01E0513: ("STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP","The 
protected output cannot enable the HDCP system because it does not support 
it."),
-        0xC01E0514: ("STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP","The 
protected output cannot enable analog copy protection because it does not 
support it."),
-        0xC01E0515: ("STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA","The 
protected output cannot enable the CGMS-A protection technology because it does 
not support it."),
-        0xC01E0516: 
("STATUS_GRAPHICS_OPM_HDCP_SRM_NEVER_SET","DxgkDdiOPMGetInformation() cannot 
return the version of the SRM being used because the application never 
successfully passed an SRM to the protected output."),
-        0xC01E0517: 
("STATUS_GRAPHICS_OPM_RESOLUTION_TOO_HIGH","DxgkDdiOPMConfigureProtectedOutput()
 cannot enable the specified output protection technology because the output's 
screen resolution is too high."),
-        0xC01E0518: 
("STATUS_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE","DxgkDdiOPMConfigureProtectedOutput()
 cannot enable HDCP because other physical outputs are using the display 
adapter's HDCP hardware."),
-        0xC01E051A: 
("STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS","The operating system 
asynchronously destroyed this OPM-protected output because the operating system 
state changed. This error typically occurs because the monitor PDO associated 
with this protected output was removed or stopped, the protected output's 
session became a nonconsole session, or the protected output's desktop became 
inactive."),
-        0xC01E051B: 
("STATUS_GRAPHICS_OPM_SESSION_TYPE_CHANGE_IN_PROGRESS","OPM functions cannot be 
called when a session is changing its type. Three types of sessions currently 
exist: console, disconnected, and remote (RDP or ICA)."),
-        0xC01E051C: 
("STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS","The 
DxgkDdiOPMGetCOPPCompatibleInformation, DxgkDdiOPMGetInformation, or 
DxgkDdiOPMConfigureProtectedOutput function failed. This error is returned only 
if a protected output has OPM semantics.  
DxgkDdiOPMGetCOPPCompatibleInformation always returns this error if a protected 
output has OPM semantics.  DxgkDdiOPMGetInformation returns this error code if 
the caller requested COPP-specific information.  [...]
-        0xC01E051D: ("STATUS_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST","The 
DxgkDdiOPMGetInformation and DxgkDdiOPMGetCOPPCompatibleInformation functions 
return this error code if the passed-in sequence number is not the expected 
sequence number or the passed-in OMAC value is invalid."),
-        0xC01E051E: ("STATUS_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR","The function 
failed because an unexpected error occurred inside a display driver."),
-        0xC01E051F: 
("STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS","The 
DxgkDdiOPMGetCOPPCompatibleInformation, DxgkDdiOPMGetInformation, or 
DxgkDdiOPMConfigureProtectedOutput function failed. This error is returned only 
if a protected output has COPP semantics.  
DxgkDdiOPMGetCOPPCompatibleInformation returns this error code if the caller 
requested OPM-specific information.  DxgkDdiOPMGetInformation always returns 
this error if a protected output has COPP semantics.  [...]
-        0xC01E0520: ("STATUS_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED","The 
DxgkDdiOPMGetCOPPCompatibleInformation and DxgkDdiOPMConfigureProtectedOutput 
functions return this error if the display driver does not support the 
DXGKMDT_OPM_GET_ACP_AND_CGMSA_SIGNALING and 
DXGKMDT_OPM_SET_ACP_AND_CGMSA_SIGNALING GUIDs."),
-        0xC01E0521: ("STATUS_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST","The 
DxgkDdiOPMConfigureProtectedOutput function returns this error code if the 
passed-in sequence number is not the expected sequence number or the passed-in 
OMAC value is invalid."),
-        0xC01E0580: ("STATUS_GRAPHICS_I2C_NOT_SUPPORTED","The monitor 
connected to the specified video output does not have an I2C bus."),
-        0xC01E0581: ("STATUS_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST","No device on 
the I2C bus has the specified address."),
-        0xC01E0582: ("STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA","An error 
occurred while transmitting data to the device on the I2C bus."),
-        0xC01E0583: ("STATUS_GRAPHICS_I2C_ERROR_RECEIVING_DATA","An error 
occurred while receiving data from the device on the I2C bus."),
-        0xC01E0584: ("STATUS_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED","The monitor 
does not support the specified VCP code."),
-        0xC01E0585: ("STATUS_GRAPHICS_DDCCI_INVALID_DATA","The data received 
from the monitor is invalid."),
-        0xC01E0586: 
("STATUS_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE","A 
function call failed because a monitor returned an invalid timing status byte 
when the operating system used the DDC/CI get timing report and timing message 
command to get a timing report from a monitor."),
-        0xC01E0587: ("STATUS_GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING","A 
monitor returned a DDC/CI capabilities string that did not comply with the 
ACCESS.bus 3.0, DDC/CI 1.1, or MCCS 2 Revision 1 specification."),
-        0xC01E0588: ("STATUS_GRAPHICS_MCA_INTERNAL_ERROR","An internal error 
caused an operation to fail."),
-        0xC01E0589: ("STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND","An 
operation failed because a DDC/CI message had an invalid value in its command 
field."),
-        0xC01E058A: ("STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH","This 
error occurred because a DDC/CI message had an invalid value in its length 
field."),
-        0xC01E058B: ("STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM","This 
error occurred because the value in a DDC/CI message's checksum field did not 
match the message's computed checksum value. This error implies that the data 
was corrupted while it was being transmitted from a monitor to a computer."),
-        0xC01E058C: ("STATUS_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE","This 
function failed because an invalid monitor handle was passed to it."),
-        0xC01E058D: ("STATUS_GRAPHICS_MONITOR_NO_LONGER_EXISTS","The operating 
system asynchronously destroyed the monitor that corresponds to this handle 
because the operating system's state changed. This error typically occurs 
because the monitor PDO associated with this handle was removed or stopped, or 
a display mode change occurred. A display mode change occurs when Windows sends 
a WM_DISPLAYCHANGE message to applications."),
-        0xC01E05E0: ("STATUS_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED","This 
function can be used only if a program is running in the local console session. 
It cannot be used if a program is running on a remote desktop session or on a 
terminal server session."),
-        0xC01E05E1: 
("STATUS_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME","This function cannot 
find an actual GDI display device that corresponds to the specified GDI display 
device name."),
-        0xC01E05E2: 
("STATUS_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP","The function failed 
because the specified GDI display device was not attached to the Windows 
desktop."),
-        0xC01E05E3: ("STATUS_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED","This 
function does not support GDI mirroring display devices because GDI mirroring 
display devices do not have any physical monitors associated with them."),
-        0xC01E05E4: ("STATUS_GRAPHICS_INVALID_POINTER","The function failed 
because an invalid pointer parameter was passed to it. A pointer parameter is 
invalid if it is null, is not correctly aligned, or points to an invalid 
address or to a kernel mode address."),
-        0xC01E05E5: 
("STATUS_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE","This function 
failed because the GDI device passed to it did not have a monitor associated 
with it."),
-        0xC01E05E6: ("STATUS_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL","An array 
passed to the function cannot hold all of the data that the function must copy 
into the array."),
-        0xC01E05E7: ("STATUS_GRAPHICS_INTERNAL_ERROR","An internal error 
caused an operation to fail."),
-        0xC01E05E8: ("STATUS_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS","The 
function failed because the current session is changing its type. This function 
cannot be called when the current session is changing its type. Three types of 
sessions currently exist: console, disconnected, and remote (RDP or ICA)."),
-        0xC0210000: ("STATUS_FVE_LOCKED_VOLUME","The volume must be unlocked 
before it can be used."),
-        0xC0210001: ("STATUS_FVE_NOT_ENCRYPTED","The volume is fully decrypted 
and no key is available."),
-        0xC0210002: ("STATUS_FVE_BAD_INFORMATION","The control block for the 
encrypted volume is not valid."),
-        0xC0210003: ("STATUS_FVE_TOO_SMALL","Not enough free space remains on 
the volume to allow encryption."),
-        0xC0210004: ("STATUS_FVE_FAILED_WRONG_FS","The partition cannot be 
encrypted because the file system is not supported."),
-        0xC0210005: ("STATUS_FVE_FAILED_BAD_FS","The file system is 
inconsistent. Run the Check Disk utility."),
-        0xC0210006: ("STATUS_FVE_FS_NOT_EXTENDED","The file system does not 
extend to the end of the volume."),
-        0xC0210007: ("STATUS_FVE_FS_MOUNTED","This operation cannot be 
performed while a file system is mounted on the volume."),
-        0xC0210008: ("STATUS_FVE_NO_LICENSE","BitLocker Drive Encryption is 
not included with this version of Windows."),
-        0xC0210009: ("STATUS_FVE_ACTION_NOT_ALLOWED","The requested action was 
denied by the FVE control engine."),
-        0xC021000A: ("STATUS_FVE_BAD_DATA","The data supplied is malformed."),
-        0xC021000B: ("STATUS_FVE_VOLUME_NOT_BOUND","The volume is not bound to 
the system."),
-        0xC021000C: ("STATUS_FVE_NOT_DATA_VOLUME","The volume specified is not 
a data volume."),
-        0xC021000D: ("STATUS_FVE_CONV_READ_ERROR","A read operation failed 
while converting the volume."),
-        0xC021000E: ("STATUS_FVE_CONV_WRITE_ERROR","A write operation failed 
while converting the volume."),
-        0xC021000F: ("STATUS_FVE_OVERLAPPED_UPDATE","The control block for the 
encrypted volume was updated by another thread. Try again."),
-        0xC0210010: ("STATUS_FVE_FAILED_SECTOR_SIZE","The volume encryption 
algorithm cannot be used on this sector size."),
-        0xC0210011: ("STATUS_FVE_FAILED_AUTHENTICATION","BitLocker recovery 
authentication failed."),
-        0xC0210012: ("STATUS_FVE_NOT_OS_VOLUME","The volume specified is not 
the boot operating system volume."),
-        0xC0210013: ("STATUS_FVE_KEYFILE_NOT_FOUND","The BitLocker startup key 
or recovery password could not be read from external media."),
-        0xC0210014: ("STATUS_FVE_KEYFILE_INVALID","The BitLocker startup key 
or recovery password file is corrupt or invalid."),
-        0xC0210015: ("STATUS_FVE_KEYFILE_NO_VMK","The BitLocker encryption key 
could not be obtained from the startup key or the recovery password."),
-        0xC0210016: ("STATUS_FVE_TPM_DISABLED","The TPM is disabled."),
-        0xC0210017: ("STATUS_FVE_TPM_SRK_AUTH_NOT_ZERO","The authorization 
data for the SRK of the TPM is not zero."),
-        0xC0210018: ("STATUS_FVE_TPM_INVALID_PCR","The system boot information 
changed or the TPM locked out access to BitLocker encryption keys until the 
computer is restarted."),
-        0xC0210019: ("STATUS_FVE_TPM_NO_VMK","The BitLocker encryption key 
could not be obtained from the TPM."),
-        0xC021001A: ("STATUS_FVE_PIN_INVALID","The BitLocker encryption key 
could not be obtained from the TPM and PIN."),
-        0xC021001B: ("STATUS_FVE_AUTH_INVALID_APPLICATION","A boot application 
hash does not match the hash computed when BitLocker was turned on."),
-        0xC021001C: ("STATUS_FVE_AUTH_INVALID_CONFIG","The Boot Configuration 
Data (BCD) settings are not supported or have changed because BitLocker was 
enabled."),
-        0xC021001D: ("STATUS_FVE_DEBUGGER_ENABLED","Boot debugging is enabled. 
Run Windows Boot Configuration Data Store Editor (bcdedit.exe) to turn it 
off."),
-        0xC021001E: ("STATUS_FVE_DRY_RUN_FAILED","The BitLocker encryption key 
could not be obtained."),
-        0xC021001F: ("STATUS_FVE_BAD_METADATA_POINTER","The metadata disk 
region pointer is incorrect."),
-        0xC0210020: ("STATUS_FVE_OLD_METADATA_COPY","The backup copy of the 
metadata is out of date."),
-        0xC0210021: ("STATUS_FVE_REBOOT_REQUIRED","No action was taken because 
a system restart is required."),
-        0xC0210022: ("STATUS_FVE_RAW_ACCESS","No action was taken because 
BitLocker Drive Encryption is in RAW access mode."),
-        0xC0210023: ("STATUS_FVE_RAW_BLOCKED","BitLocker Drive Encryption 
cannot enter RAW access mode for this volume."),
-        0xC0210026: ("STATUS_FVE_NO_FEATURE_LICENSE","This feature of 
BitLocker Drive Encryption is not included with this version of Windows."),
-        0xC0210027: ("STATUS_FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED","Group 
policy does not permit turning off BitLocker Drive Encryption on roaming data 
volumes."),
-        0xC0210028: ("STATUS_FVE_CONV_RECOVERY_FAILED","Bitlocker Drive 
Encryption failed to recover from aborted conversion. This could be due to 
either all conversion logs being corrupted or the media being 
write-protected."),
-        0xC0210029: ("STATUS_FVE_VIRTUALIZED_SPACE_TOO_BIG","The requested 
virtualization size is too big."),
-        0xC0210030: ("STATUS_FVE_VOLUME_TOO_SMALL","The drive is too small to 
be protected using BitLocker Drive Encryption."),
-        0xC0220001: ("STATUS_FWP_CALLOUT_NOT_FOUND","The callout does not 
exist."),
-        0xC0220002: ("STATUS_FWP_CONDITION_NOT_FOUND","The filter condition 
does not exist."),
-        0xC0220003: ("STATUS_FWP_FILTER_NOT_FOUND","The filter does not 
exist."),
-        0xC0220004: ("STATUS_FWP_LAYER_NOT_FOUND","The layer does not exist."),
-        0xC0220005: ("STATUS_FWP_PROVIDER_NOT_FOUND","The provider does not 
exist."),
-        0xC0220006: ("STATUS_FWP_PROVIDER_CONTEXT_NOT_FOUND","The provider 
context does not exist."),
-        0xC0220007: ("STATUS_FWP_SUBLAYER_NOT_FOUND","The sublayer does not 
exist."),
-        0xC0220008: ("STATUS_FWP_NOT_FOUND","The object does not exist."),
-        0xC0220009: ("STATUS_FWP_ALREADY_EXISTS","An object with that GUID or 
LUID already exists."),
-        0xC022000A: ("STATUS_FWP_IN_USE","The object is referenced by other 
objects and cannot be deleted."),
-        0xC022000B: ("STATUS_FWP_DYNAMIC_SESSION_IN_PROGRESS","The call is not 
allowed from within a dynamic session."),
-        0xC022000C: ("STATUS_FWP_WRONG_SESSION","The call was made from the 
wrong session and cannot be completed."),
-        0xC022000D: ("STATUS_FWP_NO_TXN_IN_PROGRESS","The call must be made 
from within an explicit transaction."),
-        0xC022000E: ("STATUS_FWP_TXN_IN_PROGRESS","The call is not allowed 
from within an explicit transaction."),
-        0xC022000F: ("STATUS_FWP_TXN_ABORTED","The explicit transaction has 
been forcibly canceled."),
-        0xC0220010: ("STATUS_FWP_SESSION_ABORTED","The session has been 
canceled."),
-        0xC0220011: ("STATUS_FWP_INCOMPATIBLE_TXN","The call is not allowed 
from within a read-only transaction."),
-        0xC0220012: ("STATUS_FWP_TIMEOUT","The call timed out while waiting to 
acquire the transaction lock."),
-        0xC0220013: ("STATUS_FWP_NET_EVENTS_DISABLED","The collection of 
network diagnostic events is disabled."),
-        0xC0220014: ("STATUS_FWP_INCOMPATIBLE_LAYER","The operation is not 
supported by the specified layer."),
-        0xC0220015: ("STATUS_FWP_KM_CLIENTS_ONLY","The call is allowed for 
kernel-mode callers only."),
-        0xC0220016: ("STATUS_FWP_LIFETIME_MISMATCH","The call tried to 
associate two objects with incompatible lifetimes."),
-        0xC0220017: ("STATUS_FWP_BUILTIN_OBJECT","The object is built-in and 
cannot be deleted."),
-        0xC0220018: ("STATUS_FWP_TOO_MANY_BOOTTIME_FILTERS","The maximum 
number of boot-time filters has been reached."),
-        0xC0220018: ("STATUS_FWP_TOO_MANY_CALLOUTS","The maximum number of 
callouts has been reached."),
-        0xC0220019: ("STATUS_FWP_NOTIFICATION_DROPPED","A notification could 
not be delivered because a message queue has reached maximum capacity."),
-        0xC022001A: ("STATUS_FWP_TRAFFIC_MISMATCH","The traffic parameters do 
not match those for the security association context."),
-        0xC022001B: ("STATUS_FWP_INCOMPATIBLE_SA_STATE","The call is not 
allowed for the current security association state."),
-        0xC022001C: ("STATUS_FWP_NULL_POINTER","A required pointer is null."),
-        0xC022001D: ("STATUS_FWP_INVALID_ENUMERATOR","An enumerator is not 
valid."),
-        0xC022001E: ("STATUS_FWP_INVALID_FLAGS","The flags field contains an 
invalid value."),
-        0xC022001F: ("STATUS_FWP_INVALID_NET_MASK","A network mask is not 
valid."),
-        0xC0220020: ("STATUS_FWP_INVALID_RANGE","An FWP_RANGE is not valid."),
-        0xC0220021: ("STATUS_FWP_INVALID_INTERVAL","The time interval is not 
valid."),
-        0xC0220022: ("STATUS_FWP_ZERO_LENGTH_ARRAY","An array that must 
contain at least one element has a zero length."),
-        0xC0220023: ("STATUS_FWP_NULL_DISPLAY_NAME","The displayData.name 
field cannot be null."),
-        0xC0220024: ("STATUS_FWP_INVALID_ACTION_TYPE","The action type is not 
one of the allowed action types for a filter."),
-        0xC0220025: ("STATUS_FWP_INVALID_WEIGHT","The filter weight is not 
valid."),
-        0xC0220026: ("STATUS_FWP_MATCH_TYPE_MISMATCH","A filter condition 
contains a match type that is not compatible with the operands."),
-        0xC0220027: ("STATUS_FWP_TYPE_MISMATCH","An FWP_VALUE or 
FWPM_CONDITION_VALUE is of the wrong type."),
-        0xC0220028: ("STATUS_FWP_OUT_OF_BOUNDS","An integer value is outside 
the allowed range."),
-        0xC0220029: ("STATUS_FWP_RESERVED","A reserved field is nonzero."),
-        0xC022002A: ("STATUS_FWP_DUPLICATE_CONDITION","A filter cannot contain 
multiple conditions operating on a single field."),
-        0xC022002B: ("STATUS_FWP_DUPLICATE_KEYMOD","A policy cannot contain 
the same keying module more than once."),
-        0xC022002C: ("STATUS_FWP_ACTION_INCOMPATIBLE_WITH_LAYER","The action 
type is not compatible with the layer."),
-        0xC022002D: ("STATUS_FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER","The 
action type is not compatible with the sublayer."),
-        0xC022002E: ("STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER","The raw 
context or the provider context is not compatible with the layer."),
-        0xC022002F: ("STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT","The raw 
context or the provider context is not compatible with the callout."),
-        0xC0220030: ("STATUS_FWP_INCOMPATIBLE_AUTH_METHOD","The authentication 
method is not compatible with the policy type."),
-        0xC0220031: ("STATUS_FWP_INCOMPATIBLE_DH_GROUP","The Diffie-Hellman 
group is not compatible with the policy type."),
-        0xC0220032: ("STATUS_FWP_EM_NOT_SUPPORTED","An IKE policy cannot 
contain an Extended Mode policy."),
-        0xC0220033: ("STATUS_FWP_NEVER_MATCH","The enumeration template or 
subscription will never match any objects."),
-        0xC0220034: ("STATUS_FWP_PROVIDER_CONTEXT_MISMATCH","The provider 
context is of the wrong type."),
-        0xC0220035: ("STATUS_FWP_INVALID_PARAMETER","The parameter is 
incorrect."),
-        0xC0220036: ("STATUS_FWP_TOO_MANY_SUBLAYERS","The maximum number of 
sublayers has been reached."),
-        0xC0220037: ("STATUS_FWP_CALLOUT_NOTIFICATION_FAILED","The 
notification function for a callout returned an error."),
-        0xC0220038: ("STATUS_FWP_INCOMPATIBLE_AUTH_CONFIG","The IPsec 
authentication configuration is not compatible with the authentication type."),
-        0xC0220039: ("STATUS_FWP_INCOMPATIBLE_CIPHER_CONFIG","The IPsec cipher 
configuration is not compatible with the cipher type."),
-        0xC022003C: ("STATUS_FWP_DUPLICATE_AUTH_METHOD","A policy cannot 
contain the same auth method more than once."),
-        0xC0220100: ("STATUS_FWP_TCPIP_NOT_READY","The TCP/IP stack is not 
ready."),
-        0xC0220101: ("STATUS_FWP_INJECT_HANDLE_CLOSING","The injection handle 
is being closed by another thread."),
-        0xC0220102: ("STATUS_FWP_INJECT_HANDLE_STALE","The injection handle is 
stale."),
-        0xC0220103: ("STATUS_FWP_CANNOT_PEND","The classify cannot be 
pended."),
-        0xC0230002: ("STATUS_NDIS_CLOSING","The binding to the network 
interface is being closed."),
-        0xC0230004: ("STATUS_NDIS_BAD_VERSION","An invalid version was 
specified."),
-        0xC0230005: ("STATUS_NDIS_BAD_CHARACTERISTICS","An invalid 
characteristics table was used."),
-        0xC0230006: ("STATUS_NDIS_ADAPTER_NOT_FOUND","Failed to find the 
network interface or the network interface is not ready."),
-        0xC0230007: ("STATUS_NDIS_OPEN_FAILED","Failed to open the network 
interface."),
-        0xC0230008: ("STATUS_NDIS_DEVICE_FAILED","The network interface has 
encountered an internal unrecoverable failure."),
-        0xC0230009: ("STATUS_NDIS_MULTICAST_FULL","The multicast list on the 
network interface is full."),
-        0xC023000A: ("STATUS_NDIS_MULTICAST_EXISTS","An attempt was made to 
add a duplicate multicast address to the list."),
-        0xC023000B: ("STATUS_NDIS_MULTICAST_NOT_FOUND","At attempt was made to 
remove a multicast address that was never added."),
-        0xC023000C: ("STATUS_NDIS_REQUEST_ABORTED","The network interface 
aborted the request."),
-        0xC023000D: ("STATUS_NDIS_RESET_IN_PROGRESS","The network interface 
cannot process the request because it is being reset."),
-        0xC023000F: ("STATUS_NDIS_INVALID_PACKET","An attempt was made to send 
an invalid packet on a network interface."),
-        0xC0230010: ("STATUS_NDIS_INVALID_DEVICE_REQUEST","The specified 
request is not a valid operation for the target device."),
-        0xC0230011: ("STATUS_NDIS_ADAPTER_NOT_READY","The network interface is 
not ready to complete this operation."),
-        0xC0230014: ("STATUS_NDIS_INVALID_LENGTH","The length of the buffer 
submitted for this operation is not valid."),
-        0xC0230015: ("STATUS_NDIS_INVALID_DATA","The data used for this 
operation is not valid."),
-        0xC0230016: ("STATUS_NDIS_BUFFER_TOO_SHORT","The length of the 
submitted buffer for this operation is too small."),
-        0xC0230017: ("STATUS_NDIS_INVALID_OID","The network interface does not 
support this object identifier."),
-        0xC0230018: ("STATUS_NDIS_ADAPTER_REMOVED","The network interface has 
been removed."),
-        0xC0230019: ("STATUS_NDIS_UNSUPPORTED_MEDIA","The network interface 
does not support this media type."),
-        0xC023001A: ("STATUS_NDIS_GROUP_ADDRESS_IN_USE","An attempt was made 
to remove a token ring group address that is in use by other components."),
-        0xC023001B: ("STATUS_NDIS_FILE_NOT_FOUND","An attempt was made to map 
a file that cannot be found."),
-        0xC023001C: ("STATUS_NDIS_ERROR_READING_FILE","An error occurred while 
NDIS tried to map the file."),
-        0xC023001D: ("STATUS_NDIS_ALREADY_MAPPED","An attempt was made to map 
a file that is already mapped."),
-        0xC023001E: ("STATUS_NDIS_RESOURCE_CONFLICT","An attempt to allocate a 
hardware resource failed because the resource is used by another component."),
-        0xC023001F: ("STATUS_NDIS_MEDIA_DISCONNECTED","The I/O operation 
failed because the network media is disconnected or the wireless access point 
is out of range."),
-        0xC0230022: ("STATUS_NDIS_INVALID_ADDRESS","The network address used 
in the request is invalid."),
-        0xC023002A: ("STATUS_NDIS_PAUSED","The offload operation on the 
network interface has been paused."),
-        0xC023002B: ("STATUS_NDIS_INTERFACE_NOT_FOUND","The network interface 
was not found."),
-        0xC023002C: ("STATUS_NDIS_UNSUPPORTED_REVISION","The revision number 
specified in the structure is not supported."),
-        0xC023002D: ("STATUS_NDIS_INVALID_PORT","The specified port does not 
exist on this network interface."),
-        0xC023002E: ("STATUS_NDIS_INVALID_PORT_STATE","The current state of 
the specified port on this network interface does not support the requested 
operation."),
-        0xC023002F: ("STATUS_NDIS_LOW_POWER_STATE","The miniport adapter is in 
a lower power state."),
-        0xC02300BB: ("STATUS_NDIS_NOT_SUPPORTED","The network interface does 
not support this request."),
-        0xC023100F: ("STATUS_NDIS_OFFLOAD_POLICY","The TCP connection is not 
offloadable because of a local policy setting."),
-        0xC0231012: ("STATUS_NDIS_OFFLOAD_CONNECTION_REJECTED","The TCP 
connection is not offloadable by the Chimney offload target."),
-        0xC0231013: ("STATUS_NDIS_OFFLOAD_PATH_REJECTED","The IP Path object 
is not in an offloadable state."),
-        0xC0232000: ("STATUS_NDIS_DOT11_AUTO_CONFIG_ENABLED","The wireless LAN 
interface is in auto-configuration mode and does not support the requested 
parameter change operation."),
-        0xC0232001: ("STATUS_NDIS_DOT11_MEDIA_IN_USE","The wireless LAN 
interface is busy and cannot perform the requested operation."),
-        0xC0232002: ("STATUS_NDIS_DOT11_POWER_STATE_INVALID","The wireless LAN 
interface is power down and does not support the requested operation."),
-        0xC0232003: ("STATUS_NDIS_PM_WOL_PATTERN_LIST_FULL","The list of wake 
on LAN patterns is full."),
-        0xC0232004: ("STATUS_NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL","The list of 
low power protocol offloads is full."),
-        0xC0360001: ("STATUS_IPSEC_BAD_SPI","The SPI in the packet does not 
match a valid IPsec SA."),
-        0xC0360002: ("STATUS_IPSEC_SA_LIFETIME_EXPIRED","The packet was 
received on an IPsec SA whose lifetime has expired."),
-        0xC0360003: ("STATUS_IPSEC_WRONG_SA","The packet was received on an 
IPsec SA that does not match the packet characteristics."),
-        0xC0360004: ("STATUS_IPSEC_REPLAY_CHECK_FAILED","The packet sequence 
number replay check failed."),
-        0xC0360005: ("STATUS_IPSEC_INVALID_PACKET","The IPsec header and/or 
trailer in the packet is invalid."),
-        0xC0360006: ("STATUS_IPSEC_INTEGRITY_CHECK_FAILED","The IPsec 
integrity check failed."),
-        0xC0360007: ("STATUS_IPSEC_CLEAR_TEXT_DROP","IPsec dropped a clear 
text packet."),
-        0xC0360008: ("STATUS_IPSEC_AUTH_FIREWALL_DROP","IPsec dropped an 
incoming ESP packet in authenticated firewall mode. This drop is benign."),
-        0xC0360009: ("STATUS_IPSEC_THROTTLE_DROP","IPsec dropped a packet due 
to DOS throttle."),
-        0xC0368000: ("STATUS_IPSEC_DOSP_BLOCK","IPsec Dos Protection matched 
an explicit block rule."),
-        0xC0368001: ("STATUS_IPSEC_DOSP_RECEIVED_MULTICAST","IPsec Dos 
Protection received an IPsec specific multicast packet which is not allowed."),
-        0xC0368002: ("STATUS_IPSEC_DOSP_INVALID_PACKET","IPsec Dos Protection 
received an incorrectly formatted packet."),
-        0xC0368003: ("STATUS_IPSEC_DOSP_STATE_LOOKUP_FAILED","IPsec Dos 
Protection failed to lookup state."),
-        0xC0368004: ("STATUS_IPSEC_DOSP_MAX_ENTRIES","IPsec Dos Protection 
failed to create state because there are already maximum number of entries 
allowed by policy."),
-        0xC0368005: ("STATUS_IPSEC_DOSP_KEYMOD_NOT_ALLOWED","IPsec Dos 
Protection received an IPsec negotiation packet for a keying module which is 
not allowed by policy."),
-        0xC0368006: ("STATUS_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES","IPsec 
Dos Protection failed to create per internal IP ratelimit queue because there 
is already maximum number of queues allowed by policy."),
-        0xC038005B: ("STATUS_VOLMGR_MIRROR_NOT_SUPPORTED","The system does not 
support mirrored volumes."),
-        0xC038005C: ("STATUS_VOLMGR_RAID5_NOT_SUPPORTED","The system does not 
support RAID-5 volumes."),
-        0xC03A0014: ("STATUS_VIRTDISK_PROVIDER_NOT_FOUND","A virtual disk 
support provider for the specified file was not found."),
-        0xC03A0015: ("STATUS_VIRTDISK_NOT_VIRTUAL_DISK","The specified disk is 
not a virtual disk."),
-        0xC03A0016: ("STATUS_VHD_PARENT_VHD_ACCESS_DENIED","The chain of 
virtual hard disks is inaccessible. The process has not been granted access 
rights to the parent virtual hard disk for the differencing disk."),
-        0xC03A0017: ("STATUS_VHD_CHILD_PARENT_SIZE_MISMATCH","The chain of 
virtual hard disks is corrupted. There is a mismatch in the virtual sizes of 
the parent virtual hard disk and differencing disk."),
-        0xC03A0018: ("STATUS_VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED","The chain 
of virtual hard disks is corrupted. A differencing disk is indicated in its own 
parent chain."),
-        0xC03A0019: ("STATUS_VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT","The 
chain of virtual hard disks is inaccessible. There was an error opening a 
virtual hard disk further up the chain."),
-}
-
-# Error Codes
-
-STATUS_SUCCESS                                                    = 0x00000000
-STATUS_WAIT_1                                                     = 0x00000001
-STATUS_WAIT_2                                                     = 0x00000002
-STATUS_WAIT_3                                                     = 0x00000003
-STATUS_WAIT_63                                                    = 0x0000003F
-STATUS_ABANDONED                                                  = 0x00000080
-STATUS_ABANDONED_WAIT_0                                           = 0x00000080
-STATUS_ABANDONED_WAIT_63                                          = 0x000000BF
-STATUS_USER_APC                                                   = 0x000000C0
-STATUS_ALERTED                                                    = 0x00000101
-STATUS_TIMEOUT                                                    = 0x00000102
-STATUS_PENDING                                                    = 0x00000103
-STATUS_REPARSE                                                    = 0x00000104
-STATUS_MORE_ENTRIES                                               = 0x00000105
-STATUS_NOT_ALL_ASSIGNED                                           = 0x00000106
-STATUS_SOME_NOT_MAPPED                                            = 0x00000107
-STATUS_OPLOCK_BREAK_IN_PROGRESS                                   = 0x00000108
-STATUS_VOLUME_MOUNTED                                             = 0x00000109
-STATUS_RXACT_COMMITTED                                            = 0x0000010A
-STATUS_NOTIFY_CLEANUP                                             = 0x0000010B
-STATUS_NOTIFY_ENUM_DIR                                            = 0x0000010C
-STATUS_NO_QUOTAS_FOR_ACCOUNT                                      = 0x0000010D
-STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED                           = 0x0000010E
-STATUS_PAGE_FAULT_TRANSITION                                      = 0x00000110
-STATUS_PAGE_FAULT_DEMAND_ZERO                                     = 0x00000111
-STATUS_PAGE_FAULT_COPY_ON_WRITE                                   = 0x00000112
-STATUS_PAGE_FAULT_GUARD_PAGE                                      = 0x00000113
-STATUS_PAGE_FAULT_PAGING_FILE                                     = 0x00000114
-STATUS_CACHE_PAGE_LOCKED                                          = 0x00000115
-STATUS_CRASH_DUMP                                                 = 0x00000116
-STATUS_BUFFER_ALL_ZEROS                                           = 0x00000117
-STATUS_REPARSE_OBJECT                                             = 0x00000118
-STATUS_RESOURCE_REQUIREMENTS_CHANGED                              = 0x00000119
-STATUS_TRANSLATION_COMPLETE                                       = 0x00000120
-STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY                            = 0x00000121
-STATUS_NOTHING_TO_TERMINATE                                       = 0x00000122
-STATUS_PROCESS_NOT_IN_JOB                                         = 0x00000123
-STATUS_PROCESS_IN_JOB                                             = 0x00000124
-STATUS_VOLSNAP_HIBERNATE_READY                                    = 0x00000125
-STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY                         = 0x00000126
-STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED                         = 0x00000127
-STATUS_INTERRUPT_STILL_CONNECTED                                  = 0x00000128
-STATUS_PROCESS_CLONED                                             = 0x00000129
-STATUS_FILE_LOCKED_WITH_ONLY_READERS                              = 0x0000012A
-STATUS_FILE_LOCKED_WITH_WRITERS                                   = 0x0000012B
-STATUS_RESOURCEMANAGER_READ_ONLY                                  = 0x00000202
-STATUS_WAIT_FOR_OPLOCK                                            = 0x00000367
-DBG_EXCEPTION_HANDLED                                             = 0x00010001
-DBG_CONTINUE                                                      = 0x00010002
-STATUS_FLT_IO_COMPLETE                                            = 0x001C0001
-STATUS_FILE_NOT_AVAILABLE                                         = 0xC0000467
-STATUS_CALLBACK_RETURNED_THREAD_AFFINITY                          = 0xC0000721
-STATUS_OBJECT_NAME_EXISTS                                         = 0x40000000
-STATUS_THREAD_WAS_SUSPENDED                                       = 0x40000001
-STATUS_WORKING_SET_LIMIT_RANGE                                    = 0x40000002
-STATUS_IMAGE_NOT_AT_BASE                                          = 0x40000003
-STATUS_RXACT_STATE_CREATED                                        = 0x40000004
-STATUS_SEGMENT_NOTIFICATION                                       = 0x40000005
-STATUS_LOCAL_USER_SESSION_KEY                                     = 0x40000006
-STATUS_BAD_CURRENT_DIRECTORY                                      = 0x40000007
-STATUS_SERIAL_MORE_WRITES                                         = 0x40000008
-STATUS_REGISTRY_RECOVERED                                         = 0x40000009
-STATUS_FT_READ_RECOVERY_FROM_BACKUP                               = 0x4000000A
-STATUS_FT_WRITE_RECOVERY                                          = 0x4000000B
-STATUS_SERIAL_COUNTER_TIMEOUT                                     = 0x4000000C
-STATUS_NULL_LM_PASSWORD                                           = 0x4000000D
-STATUS_IMAGE_MACHINE_TYPE_MISMATCH                                = 0x4000000E
-STATUS_RECEIVE_PARTIAL                                            = 0x4000000F
-STATUS_RECEIVE_EXPEDITED                                          = 0x40000010
-STATUS_RECEIVE_PARTIAL_EXPEDITED                                  = 0x40000011
-STATUS_EVENT_DONE                                                 = 0x40000012
-STATUS_EVENT_PENDING                                              = 0x40000013
-STATUS_CHECKING_FILE_SYSTEM                                       = 0x40000014
-STATUS_FATAL_APP_EXIT                                             = 0x40000015
-STATUS_PREDEFINED_HANDLE                                          = 0x40000016
-STATUS_WAS_UNLOCKED                                               = 0x40000017
-STATUS_SERVICE_NOTIFICATION                                       = 0x40000018
-STATUS_WAS_LOCKED                                                 = 0x40000019
-STATUS_LOG_HARD_ERROR                                             = 0x4000001A
-STATUS_ALREADY_WIN32                                              = 0x4000001B
-STATUS_WX86_UNSIMULATE                                            = 0x4000001C
-STATUS_WX86_CONTINUE                                              = 0x4000001D
-STATUS_WX86_SINGLE_STEP                                           = 0x4000001E
-STATUS_WX86_BREAKPOINT                                            = 0x4000001F
-STATUS_WX86_EXCEPTION_CONTINUE                                    = 0x40000020
-STATUS_WX86_EXCEPTION_LASTCHANCE                                  = 0x40000021
-STATUS_WX86_EXCEPTION_CHAIN                                       = 0x40000022
-STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE                            = 0x40000023
-STATUS_NO_YIELD_PERFORMED                                         = 0x40000024
-STATUS_TIMER_RESUME_IGNORED                                       = 0x40000025
-STATUS_ARBITRATION_UNHANDLED                                      = 0x40000026
-STATUS_CARDBUS_NOT_SUPPORTED                                      = 0x40000027
-STATUS_WX86_CREATEWX86TIB                                         = 0x40000028
-STATUS_MP_PROCESSOR_MISMATCH                                      = 0x40000029
-STATUS_HIBERNATED                                                 = 0x4000002A
-STATUS_RESUME_HIBERNATION                                         = 0x4000002B
-STATUS_FIRMWARE_UPDATED                                           = 0x4000002C
-STATUS_DRIVERS_LEAKING_LOCKED_PAGES                               = 0x4000002D
-STATUS_MESSAGE_RETRIEVED                                          = 0x4000002E
-STATUS_SYSTEM_POWERSTATE_TRANSITION                               = 0x4000002F
-STATUS_ALPC_CHECK_COMPLETION_LIST                                 = 0x40000030
-STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION                       = 0x40000031
-STATUS_ACCESS_AUDIT_BY_POLICY                                     = 0x40000032
-STATUS_ABANDON_HIBERFILE                                          = 0x40000033
-STATUS_BIZRULES_NOT_ENABLED                                       = 0x40000034
-STATUS_WAKE_SYSTEM                                                = 0x40000294
-STATUS_DS_SHUTTING_DOWN                                           = 0x40000370
-DBG_REPLY_LATER                                                   = 0x40010001
-DBG_UNABLE_TO_PROVIDE_HANDLE                                      = 0x40010002
-DBG_TERMINATE_THREAD                                              = 0x40010003
-DBG_TERMINATE_PROCESS                                             = 0x40010004
-DBG_CONTROL_C                                                     = 0x40010005
-DBG_PRINTEXCEPTION_C                                              = 0x40010006
-DBG_RIPEXCEPTION                                                  = 0x40010007
-DBG_CONTROL_BREAK                                                 = 0x40010008
-DBG_COMMAND_EXCEPTION                                             = 0x40010009
-RPC_NT_UUID_LOCAL_ONLY                                            = 0x40020056
-RPC_NT_SEND_INCOMPLETE                                            = 0x400200AF
-STATUS_CTX_CDM_CONNECT                                            = 0x400A0004
-STATUS_CTX_CDM_DISCONNECT                                         = 0x400A0005
-STATUS_SXS_RELEASE_ACTIVATION_CONTEXT                             = 0x4015000D
-STATUS_RECOVERY_NOT_NEEDED                                        = 0x40190034
-STATUS_RM_ALREADY_STARTED                                         = 0x40190035
-STATUS_LOG_NO_RESTART                                             = 0x401A000C
-STATUS_VIDEO_DRIVER_DEBUG_REPORT_REQUEST                          = 0x401B00EC
-STATUS_GRAPHICS_PARTIAL_DATA_POPULATED                            = 0x401E000A
-STATUS_GRAPHICS_DRIVER_MISMATCH                                   = 0x401E0117
-STATUS_GRAPHICS_MODE_NOT_PINNED                                   = 0x401E0307
-STATUS_GRAPHICS_NO_PREFERRED_MODE                                 = 0x401E031E
-STATUS_GRAPHICS_DATASET_IS_EMPTY                                  = 0x401E034B
-STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET                       = 0x401E034C
-STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_PINNED   = 0x401E0351
-STATUS_GRAPHICS_UNKNOWN_CHILD_STATUS                              = 0x401E042F
-STATUS_GRAPHICS_LEADLINK_START_DEFERRED                           = 0x401E0437
-STATUS_GRAPHICS_POLLING_TOO_FREQUENTLY                            = 0x401E0439
-STATUS_GRAPHICS_START_DEFERRED                                    = 0x401E043A
-STATUS_NDIS_INDICATION_REQUIRED                                   = 0x40230001
-STATUS_GUARD_PAGE_VIOLATION                                       = 0x80000001
-STATUS_DATATYPE_MISALIGNMENT                                      = 0x80000002
-STATUS_BREAKPOINT                                                 = 0x80000003
-STATUS_SINGLE_STEP                                                = 0x80000004
-STATUS_BUFFER_OVERFLOW                                            = 0x80000005
-STATUS_NO_MORE_FILES                                              = 0x80000006
-STATUS_WAKE_SYSTEM_DEBUGGER                                       = 0x80000007
-STATUS_HANDLES_CLOSED                                             = 0x8000000A
-STATUS_NO_INHERITANCE                                             = 0x8000000B
-STATUS_GUID_SUBSTITUTION_MADE                                     = 0x8000000C
-STATUS_PARTIAL_COPY                                               = 0x8000000D
-STATUS_DEVICE_PAPER_EMPTY                                         = 0x8000000E
-STATUS_DEVICE_POWERED_OFF                                         = 0x8000000F
-STATUS_DEVICE_OFF_LINE                                            = 0x80000010
-STATUS_DEVICE_BUSY                                                = 0x80000011
-STATUS_NO_MORE_EAS                                                = 0x80000012
-STATUS_INVALID_EA_NAME                                            = 0x80000013
-STATUS_EA_LIST_INCONSISTENT                                       = 0x80000014
-STATUS_INVALID_EA_FLAG                                            = 0x80000015
-STATUS_VERIFY_REQUIRED                                            = 0x80000016
-STATUS_EXTRANEOUS_INFORMATION                                     = 0x80000017
-STATUS_RXACT_COMMIT_NECESSARY                                     = 0x80000018
-STATUS_NO_MORE_ENTRIES                                            = 0x8000001A
-STATUS_FILEMARK_DETECTED                                          = 0x8000001B
-STATUS_MEDIA_CHANGED                                              = 0x8000001C
-STATUS_BUS_RESET                                                  = 0x8000001D
-STATUS_END_OF_MEDIA                                               = 0x8000001E
-STATUS_BEGINNING_OF_MEDIA                                         = 0x8000001F
-STATUS_MEDIA_CHECK                                                = 0x80000020
-STATUS_SETMARK_DETECTED                                           = 0x80000021
-STATUS_NO_DATA_DETECTED                                           = 0x80000022
-STATUS_REDIRECTOR_HAS_OPEN_HANDLES                                = 0x80000023
-STATUS_SERVER_HAS_OPEN_HANDLES                                    = 0x80000024
-STATUS_ALREADY_DISCONNECTED                                       = 0x80000025
-STATUS_LONGJUMP                                                   = 0x80000026
-STATUS_CLEANER_CARTRIDGE_INSTALLED                                = 0x80000027
-STATUS_PLUGPLAY_QUERY_VETOED                                      = 0x80000028
-STATUS_UNWIND_CONSOLIDATE                                         = 0x80000029
-STATUS_REGISTRY_HIVE_RECOVERED                                    = 0x8000002A
-STATUS_DLL_MIGHT_BE_INSECURE                                      = 0x8000002B
-STATUS_DLL_MIGHT_BE_INCOMPATIBLE                                  = 0x8000002C
-STATUS_STOPPED_ON_SYMLINK                                         = 0x8000002D
-STATUS_DEVICE_REQUIRES_CLEANING                                   = 0x80000288
-STATUS_DEVICE_DOOR_OPEN                                           = 0x80000289
-STATUS_DATA_LOST_REPAIR                                           = 0x80000803
-DBG_EXCEPTION_NOT_HANDLED                                         = 0x80010001
-STATUS_CLUSTER_NODE_ALREADY_UP                                    = 0x80130001
-STATUS_CLUSTER_NODE_ALREADY_DOWN                                  = 0x80130002
-STATUS_CLUSTER_NETWORK_ALREADY_ONLINE                             = 0x80130003
-STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE                            = 0x80130004
-STATUS_CLUSTER_NODE_ALREADY_MEMBER                                = 0x80130005
-STATUS_COULD_NOT_RESIZE_LOG                                       = 0x80190009
-STATUS_NO_TXF_METADATA                                            = 0x80190029
-STATUS_CANT_RECOVER_WITH_HANDLE_OPEN                              = 0x80190031
-STATUS_TXF_METADATA_ALREADY_PRESENT                               = 0x80190041
-STATUS_TRANSACTION_SCOPE_CALLBACKS_NOT_SET                        = 0x80190042
-STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD_RECOVERED                 = 0x801B00EB
-STATUS_FLT_BUFFER_TOO_SMALL                                       = 0x801C0001
-STATUS_FVE_PARTIAL_METADATA                                       = 0x80210001
-STATUS_FVE_TRANSIENT_STATE                                        = 0x80210002
-STATUS_UNSUCCESSFUL                                               = 0xC0000001
-STATUS_NOT_IMPLEMENTED                                            = 0xC0000002
-STATUS_INVALID_INFO_CLASS                                         = 0xC0000003
-STATUS_INFO_LENGTH_MISMATCH                                       = 0xC0000004
-STATUS_ACCESS_VIOLATION                                           = 0xC0000005
-STATUS_IN_PAGE_ERROR                                              = 0xC0000006
-STATUS_PAGEFILE_QUOTA                                             = 0xC0000007
-STATUS_INVALID_HANDLE                                             = 0xC0000008
-STATUS_BAD_INITIAL_STACK                                          = 0xC0000009
-STATUS_BAD_INITIAL_PC                                             = 0xC000000A
-STATUS_INVALID_CID                                                = 0xC000000B
-STATUS_TIMER_NOT_CANCELED                                         = 0xC000000C
-STATUS_INVALID_PARAMETER                                          = 0xC000000D
-STATUS_NO_SUCH_DEVICE                                             = 0xC000000E
-STATUS_NO_SUCH_FILE                                               = 0xC000000F
-STATUS_INVALID_DEVICE_REQUEST                                     = 0xC0000010
-STATUS_END_OF_FILE                                                = 0xC0000011
-STATUS_WRONG_VOLUME                                               = 0xC0000012
-STATUS_NO_MEDIA_IN_DEVICE                                         = 0xC0000013
-STATUS_UNRECOGNIZED_MEDIA                                         = 0xC0000014
-STATUS_NONEXISTENT_SECTOR                                         = 0xC0000015
-STATUS_MORE_PROCESSING_REQUIRED                                   = 0xC0000016
-STATUS_NO_MEMORY                                                  = 0xC0000017
-STATUS_CONFLICTING_ADDRESSES                                      = 0xC0000018
-STATUS_NOT_MAPPED_VIEW                                            = 0xC0000019
-STATUS_UNABLE_TO_FREE_VM                                          = 0xC000001A
-STATUS_UNABLE_TO_DELETE_SECTION                                   = 0xC000001B
-STATUS_INVALID_SYSTEM_SERVICE                                     = 0xC000001C
-STATUS_ILLEGAL_INSTRUCTION                                        = 0xC000001D
-STATUS_INVALID_LOCK_SEQUENCE                                      = 0xC000001E
-STATUS_INVALID_VIEW_SIZE                                          = 0xC000001F
-STATUS_INVALID_FILE_FOR_SECTION                                   = 0xC0000020
-STATUS_ALREADY_COMMITTED                                          = 0xC0000021
-STATUS_ACCESS_DENIED                                              = 0xC0000022
-STATUS_BUFFER_TOO_SMALL                                           = 0xC0000023
-STATUS_OBJECT_TYPE_MISMATCH                                       = 0xC0000024
-STATUS_NONCONTINUABLE_EXCEPTION                                   = 0xC0000025
-STATUS_INVALID_DISPOSITION                                        = 0xC0000026
-STATUS_UNWIND                                                     = 0xC0000027
-STATUS_BAD_STACK                                                  = 0xC0000028
-STATUS_INVALID_UNWIND_TARGET                                      = 0xC0000029
-STATUS_NOT_LOCKED                                                 = 0xC000002A
-STATUS_PARITY_ERROR                                               = 0xC000002B
-STATUS_UNABLE_TO_DECOMMIT_VM                                      = 0xC000002C
-STATUS_NOT_COMMITTED                                              = 0xC000002D
-STATUS_INVALID_PORT_ATTRIBUTES                                    = 0xC000002E
-STATUS_PORT_MESSAGE_TOO_LONG                                      = 0xC000002F
-STATUS_INVALID_PARAMETER_MIX                                      = 0xC0000030
-STATUS_INVALID_QUOTA_LOWER                                        = 0xC0000031
-STATUS_DISK_CORRUPT_ERROR                                         = 0xC0000032
-STATUS_OBJECT_NAME_INVALID                                        = 0xC0000033
-STATUS_OBJECT_NAME_NOT_FOUND                                      = 0xC0000034
-STATUS_OBJECT_NAME_COLLISION                                      = 0xC0000035
-STATUS_PORT_DISCONNECTED                                          = 0xC0000037
-STATUS_DEVICE_ALREADY_ATTACHED                                    = 0xC0000038
-STATUS_OBJECT_PATH_INVALID                                        = 0xC0000039
-STATUS_OBJECT_PATH_NOT_FOUND                                      = 0xC000003A
-STATUS_OBJECT_PATH_SYNTAX_BAD                                     = 0xC000003B
-STATUS_DATA_OVERRUN                                               = 0xC000003C
-STATUS_DATA_LATE_ERROR                                            = 0xC000003D
-STATUS_DATA_ERROR                                                 = 0xC000003E
-STATUS_CRC_ERROR                                                  = 0xC000003F
-STATUS_SECTION_TOO_BIG                                            = 0xC0000040
-STATUS_PORT_CONNECTION_REFUSED                                    = 0xC0000041
-STATUS_INVALID_PORT_HANDLE                                        = 0xC0000042
-STATUS_SHARING_VIOLATION                                          = 0xC0000043
-STATUS_QUOTA_EXCEEDED                                             = 0xC0000044
-STATUS_INVALID_PAGE_PROTECTION                                    = 0xC0000045
-STATUS_MUTANT_NOT_OWNED                                           = 0xC0000046
-STATUS_SEMAPHORE_LIMIT_EXCEEDED                                   = 0xC0000047
-STATUS_PORT_ALREADY_SET                                           = 0xC0000048
-STATUS_SECTION_NOT_IMAGE                                          = 0xC0000049
-STATUS_SUSPEND_COUNT_EXCEEDED                                     = 0xC000004A
-STATUS_THREAD_IS_TERMINATING                                      = 0xC000004B
-STATUS_BAD_WORKING_SET_LIMIT                                      = 0xC000004C
-STATUS_INCOMPATIBLE_FILE_MAP                                      = 0xC000004D
-STATUS_SECTION_PROTECTION                                         = 0xC000004E
-STATUS_EAS_NOT_SUPPORTED                                          = 0xC000004F
-STATUS_EA_TOO_LARGE                                               = 0xC0000050
-STATUS_NONEXISTENT_EA_ENTRY                                       = 0xC0000051
-STATUS_NO_EAS_ON_FILE                                             = 0xC0000052
-STATUS_EA_CORRUPT_ERROR                                           = 0xC0000053
-STATUS_FILE_LOCK_CONFLICT                                         = 0xC0000054
-STATUS_LOCK_NOT_GRANTED                                           = 0xC0000055
-STATUS_DELETE_PENDING                                             = 0xC0000056
-STATUS_CTL_FILE_NOT_SUPPORTED                                     = 0xC0000057
-STATUS_UNKNOWN_REVISION                                           = 0xC0000058
-STATUS_REVISION_MISMATCH                                          = 0xC0000059
-STATUS_INVALID_OWNER                                              = 0xC000005A
-STATUS_INVALID_PRIMARY_GROUP                                      = 0xC000005B
-STATUS_NO_IMPERSONATION_TOKEN                                     = 0xC000005C
-STATUS_CANT_DISABLE_MANDATORY                                     = 0xC000005D
-STATUS_NO_LOGON_SERVERS                                           = 0xC000005E
-STATUS_NO_SUCH_LOGON_SESSION                                      = 0xC000005F
-STATUS_NO_SUCH_PRIVILEGE                                          = 0xC0000060
-STATUS_PRIVILEGE_NOT_HELD                                         = 0xC0000061
-STATUS_INVALID_ACCOUNT_NAME                                       = 0xC0000062
-STATUS_USER_EXISTS                                                = 0xC0000063
-STATUS_NO_SUCH_USER                                               = 0xC0000064
-STATUS_GROUP_EXISTS                                               = 0xC0000065
-STATUS_NO_SUCH_GROUP                                              = 0xC0000066
-STATUS_MEMBER_IN_GROUP                                            = 0xC0000067
-STATUS_MEMBER_NOT_IN_GROUP                                        = 0xC0000068
-STATUS_LAST_ADMIN                                                 = 0xC0000069
-STATUS_WRONG_PASSWORD                                             = 0xC000006A
-STATUS_ILL_FORMED_PASSWORD                                        = 0xC000006B
-STATUS_PASSWORD_RESTRICTION                                       = 0xC000006C
-STATUS_LOGON_FAILURE                                              = 0xC000006D
-STATUS_ACCOUNT_RESTRICTION                                        = 0xC000006E
-STATUS_INVALID_LOGON_HOURS                                        = 0xC000006F
-STATUS_INVALID_WORKSTATION                                        = 0xC0000070
-STATUS_PASSWORD_EXPIRED                                           = 0xC0000071
-STATUS_ACCOUNT_DISABLED                                           = 0xC0000072
-STATUS_NONE_MAPPED                                                = 0xC0000073
-STATUS_TOO_MANY_LUIDS_REQUESTED                                   = 0xC0000074
-STATUS_LUIDS_EXHAUSTED                                            = 0xC0000075
-STATUS_INVALID_SUB_AUTHORITY                                      = 0xC0000076
-STATUS_INVALID_ACL                                                = 0xC0000077
-STATUS_INVALID_SID                                                = 0xC0000078
-STATUS_INVALID_SECURITY_DESCR                                     = 0xC0000079
-STATUS_PROCEDURE_NOT_FOUND                                        = 0xC000007A
-STATUS_INVALID_IMAGE_FORMAT                                       = 0xC000007B
-STATUS_NO_TOKEN                                                   = 0xC000007C
-STATUS_BAD_INHERITANCE_ACL                                        = 0xC000007D
-STATUS_RANGE_NOT_LOCKED                                           = 0xC000007E
-STATUS_DISK_FULL                                                  = 0xC000007F
-STATUS_SERVER_DISABLED                                            = 0xC0000080
-STATUS_SERVER_NOT_DISABLED                                        = 0xC0000081
-STATUS_TOO_MANY_GUIDS_REQUESTED                                   = 0xC0000082
-STATUS_GUIDS_EXHAUSTED                                            = 0xC0000083
-STATUS_INVALID_ID_AUTHORITY                                       = 0xC0000084
-STATUS_AGENTS_EXHAUSTED                                           = 0xC0000085
-STATUS_INVALID_VOLUME_LABEL                                       = 0xC0000086
-STATUS_SECTION_NOT_EXTENDED                                       = 0xC0000087
-STATUS_NOT_MAPPED_DATA                                            = 0xC0000088
-STATUS_RESOURCE_DATA_NOT_FOUND                                    = 0xC0000089
-STATUS_RESOURCE_TYPE_NOT_FOUND                                    = 0xC000008A
-STATUS_RESOURCE_NAME_NOT_FOUND                                    = 0xC000008B
-STATUS_ARRAY_BOUNDS_EXCEEDED                                      = 0xC000008C
-STATUS_FLOAT_DENORMAL_OPERAND                                     = 0xC000008D
-STATUS_FLOAT_DIVIDE_BY_ZERO                                       = 0xC000008E
-STATUS_FLOAT_INEXACT_RESULT                                       = 0xC000008F
-STATUS_FLOAT_INVALID_OPERATION                                    = 0xC0000090
-STATUS_FLOAT_OVERFLOW                                             = 0xC0000091
-STATUS_FLOAT_STACK_CHECK                                          = 0xC0000092
-STATUS_FLOAT_UNDERFLOW                                            = 0xC0000093
-STATUS_INTEGER_DIVIDE_BY_ZERO                                     = 0xC0000094
-STATUS_INTEGER_OVERFLOW                                           = 0xC0000095
-STATUS_PRIVILEGED_INSTRUCTION                                     = 0xC0000096
-STATUS_TOO_MANY_PAGING_FILES                                      = 0xC0000097
-STATUS_FILE_INVALID                                               = 0xC0000098
-STATUS_ALLOTTED_SPACE_EXCEEDED                                    = 0xC0000099
-STATUS_INSUFFICIENT_RESOURCES                                     = 0xC000009A
-STATUS_DFS_EXIT_PATH_FOUND                                        = 0xC000009B
-STATUS_DEVICE_DATA_ERROR                                          = 0xC000009C
-STATUS_DEVICE_NOT_CONNECTED                                       = 0xC000009D
-STATUS_FREE_VM_NOT_AT_BASE                                        = 0xC000009F
-STATUS_MEMORY_NOT_ALLOCATED                                       = 0xC00000A0
-STATUS_WORKING_SET_QUOTA                                          = 0xC00000A1
-STATUS_MEDIA_WRITE_PROTECTED                                      = 0xC00000A2
-STATUS_DEVICE_NOT_READY                                           = 0xC00000A3
-STATUS_INVALID_GROUP_ATTRIBUTES                                   = 0xC00000A4
-STATUS_BAD_IMPERSONATION_LEVEL                                    = 0xC00000A5
-STATUS_CANT_OPEN_ANONYMOUS                                        = 0xC00000A6
-STATUS_BAD_VALIDATION_CLASS                                       = 0xC00000A7
-STATUS_BAD_TOKEN_TYPE                                             = 0xC00000A8
-STATUS_BAD_MASTER_BOOT_RECORD                                     = 0xC00000A9
-STATUS_INSTRUCTION_MISALIGNMENT                                   = 0xC00000AA
-STATUS_INSTANCE_NOT_AVAILABLE                                     = 0xC00000AB
-STATUS_PIPE_NOT_AVAILABLE                                         = 0xC00000AC
-STATUS_INVALID_PIPE_STATE                                         = 0xC00000AD
-STATUS_PIPE_BUSY                                                  = 0xC00000AE
-STATUS_ILLEGAL_FUNCTION                                           = 0xC00000AF
-STATUS_PIPE_DISCONNECTED                                          = 0xC00000B0
-STATUS_PIPE_CLOSING                                               = 0xC00000B1
-STATUS_PIPE_CONNECTED                                             = 0xC00000B2
-STATUS_PIPE_LISTENING                                             = 0xC00000B3
-STATUS_INVALID_READ_MODE                                          = 0xC00000B4
-STATUS_IO_TIMEOUT                                                 = 0xC00000B5
-STATUS_FILE_FORCED_CLOSED                                         = 0xC00000B6
-STATUS_PROFILING_NOT_STARTED                                      = 0xC00000B7
-STATUS_PROFILING_NOT_STOPPED                                      = 0xC00000B8
-STATUS_COULD_NOT_INTERPRET                                        = 0xC00000B9
-STATUS_FILE_IS_A_DIRECTORY                                        = 0xC00000BA
-STATUS_NOT_SUPPORTED                                              = 0xC00000BB
-STATUS_REMOTE_NOT_LISTENING                                       = 0xC00000BC
-STATUS_DUPLICATE_NAME                                             = 0xC00000BD
-STATUS_BAD_NETWORK_PATH                                           = 0xC00000BE
-STATUS_NETWORK_BUSY                                               = 0xC00000BF
-STATUS_DEVICE_DOES_NOT_EXIST                                      = 0xC00000C0
-STATUS_TOO_MANY_COMMANDS                                          = 0xC00000C1
-STATUS_ADAPTER_HARDWARE_ERROR                                     = 0xC00000C2
-STATUS_INVALID_NETWORK_RESPONSE                                   = 0xC00000C3
-STATUS_UNEXPECTED_NETWORK_ERROR                                   = 0xC00000C4
-STATUS_BAD_REMOTE_ADAPTER                                         = 0xC00000C5
-STATUS_PRINT_QUEUE_FULL                                           = 0xC00000C6
-STATUS_NO_SPOOL_SPACE                                             = 0xC00000C7
-STATUS_PRINT_CANCELLED                                            = 0xC00000C8
-STATUS_NETWORK_NAME_DELETED                                       = 0xC00000C9
-STATUS_NETWORK_ACCESS_DENIED                                      = 0xC00000CA
-STATUS_BAD_DEVICE_TYPE                                            = 0xC00000CB
-STATUS_BAD_NETWORK_NAME                                           = 0xC00000CC
-STATUS_TOO_MANY_NAMES                                             = 0xC00000CD
-STATUS_TOO_MANY_SESSIONS                                          = 0xC00000CE
-STATUS_SHARING_PAUSED                                             = 0xC00000CF
-STATUS_REQUEST_NOT_ACCEPTED                                       = 0xC00000D0
-STATUS_REDIRECTOR_PAUSED                                          = 0xC00000D1
-STATUS_NET_WRITE_FAULT                                            = 0xC00000D2
-STATUS_PROFILING_AT_LIMIT                                         = 0xC00000D3
-STATUS_NOT_SAME_DEVICE                                            = 0xC00000D4
-STATUS_FILE_RENAMED                                               = 0xC00000D5
-STATUS_VIRTUAL_CIRCUIT_CLOSED                                     = 0xC00000D6
-STATUS_NO_SECURITY_ON_OBJECT                                      = 0xC00000D7
-STATUS_CANT_WAIT                                                  = 0xC00000D8
-STATUS_PIPE_EMPTY                                                 = 0xC00000D9
-STATUS_CANT_ACCESS_DOMAIN_INFO                                    = 0xC00000DA
-STATUS_CANT_TERMINATE_SELF                                        = 0xC00000DB
-STATUS_INVALID_SERVER_STATE                                       = 0xC00000DC
-STATUS_INVALID_DOMAIN_STATE                                       = 0xC00000DD
-STATUS_INVALID_DOMAIN_ROLE                                        = 0xC00000DE
-STATUS_NO_SUCH_DOMAIN                                             = 0xC00000DF
-STATUS_DOMAIN_EXISTS                                              = 0xC00000E0
-STATUS_DOMAIN_LIMIT_EXCEEDED                                      = 0xC00000E1
-STATUS_OPLOCK_NOT_GRANTED                                         = 0xC00000E2
-STATUS_INVALID_OPLOCK_PROTOCOL                                    = 0xC00000E3
-STATUS_INTERNAL_DB_CORRUPTION                                     = 0xC00000E4
-STATUS_INTERNAL_ERROR                                             = 0xC00000E5
-STATUS_GENERIC_NOT_MAPPED                                         = 0xC00000E6
-STATUS_BAD_DESCRIPTOR_FORMAT                                      = 0xC00000E7
-STATUS_INVALID_USER_BUFFER                                        = 0xC00000E8
-STATUS_UNEXPECTED_IO_ERROR                                        = 0xC00000E9
-STATUS_UNEXPECTED_MM_CREATE_ERR                                   = 0xC00000EA
-STATUS_UNEXPECTED_MM_MAP_ERROR                                    = 0xC00000EB
-STATUS_UNEXPECTED_MM_EXTEND_ERR                                   = 0xC00000EC
-STATUS_NOT_LOGON_PROCESS                                          = 0xC00000ED
-STATUS_LOGON_SESSION_EXISTS                                       = 0xC00000EE
-STATUS_INVALID_PARAMETER_1                                        = 0xC00000EF
-STATUS_INVALID_PARAMETER_2                                        = 0xC00000F0
-STATUS_INVALID_PARAMETER_3                                        = 0xC00000F1
-STATUS_INVALID_PARAMETER_4                                        = 0xC00000F2
-STATUS_INVALID_PARAMETER_5                                        = 0xC00000F3
-STATUS_INVALID_PARAMETER_6                                        = 0xC00000F4
-STATUS_INVALID_PARAMETER_7                                        = 0xC00000F5
-STATUS_INVALID_PARAMETER_8                                        = 0xC00000F6
-STATUS_INVALID_PARAMETER_9                                        = 0xC00000F7
-STATUS_INVALID_PARAMETER_10                                       = 0xC00000F8
-STATUS_INVALID_PARAMETER_11                                       = 0xC00000F9
-STATUS_INVALID_PARAMETER_12                                       = 0xC00000FA
-STATUS_REDIRECTOR_NOT_STARTED                                     = 0xC00000FB
-STATUS_REDIRECTOR_STARTED                                         = 0xC00000FC
-STATUS_STACK_OVERFLOW                                             = 0xC00000FD
-STATUS_NO_SUCH_PACKAGE                                            = 0xC00000FE
-STATUS_BAD_FUNCTION_TABLE                                         = 0xC00000FF
-STATUS_VARIABLE_NOT_FOUND                                         = 0xC0000100
-STATUS_DIRECTORY_NOT_EMPTY                                        = 0xC0000101
-STATUS_FILE_CORRUPT_ERROR                                         = 0xC0000102
-STATUS_NOT_A_DIRECTORY                                            = 0xC0000103
-STATUS_BAD_LOGON_SESSION_STATE                                    = 0xC0000104
-STATUS_LOGON_SESSION_COLLISION                                    = 0xC0000105
-STATUS_NAME_TOO_LONG                                              = 0xC0000106
-STATUS_FILES_OPEN                                                 = 0xC0000107
-STATUS_CONNECTION_IN_USE                                          = 0xC0000108
-STATUS_MESSAGE_NOT_FOUND                                          = 0xC0000109
-STATUS_PROCESS_IS_TERMINATING                                     = 0xC000010A
-STATUS_INVALID_LOGON_TYPE                                         = 0xC000010B
-STATUS_NO_GUID_TRANSLATION                                        = 0xC000010C
-STATUS_CANNOT_IMPERSONATE                                         = 0xC000010D
-STATUS_IMAGE_ALREADY_LOADED                                       = 0xC000010E
-STATUS_NO_LDT                                                     = 0xC0000117
-STATUS_INVALID_LDT_SIZE                                           = 0xC0000118
-STATUS_INVALID_LDT_OFFSET                                         = 0xC0000119
-STATUS_INVALID_LDT_DESCRIPTOR                                     = 0xC000011A
-STATUS_INVALID_IMAGE_NE_FORMAT                                    = 0xC000011B
-STATUS_RXACT_INVALID_STATE                                        = 0xC000011C
-STATUS_RXACT_COMMIT_FAILURE                                       = 0xC000011D
-STATUS_MAPPED_FILE_SIZE_ZERO                                      = 0xC000011E
-STATUS_TOO_MANY_OPENED_FILES                                      = 0xC000011F
-STATUS_CANCELLED                                                  = 0xC0000120
-STATUS_CANNOT_DELETE                                              = 0xC0000121
-STATUS_INVALID_COMPUTER_NAME                                      = 0xC0000122
-STATUS_FILE_DELETED                                               = 0xC0000123
-STATUS_SPECIAL_ACCOUNT                                            = 0xC0000124
-STATUS_SPECIAL_GROUP                                              = 0xC0000125
-STATUS_SPECIAL_USER                                               = 0xC0000126
-STATUS_MEMBERS_PRIMARY_GROUP                                      = 0xC0000127
-STATUS_FILE_CLOSED                                                = 0xC0000128
-STATUS_TOO_MANY_THREADS                                           = 0xC0000129
-STATUS_THREAD_NOT_IN_PROCESS                                      = 0xC000012A
-STATUS_TOKEN_ALREADY_IN_USE                                       = 0xC000012B
-STATUS_PAGEFILE_QUOTA_EXCEEDED                                    = 0xC000012C
-STATUS_COMMITMENT_LIMIT                                           = 0xC000012D
-STATUS_INVALID_IMAGE_LE_FORMAT                                    = 0xC000012E
-STATUS_INVALID_IMAGE_NOT_MZ                                       = 0xC000012F
-STATUS_INVALID_IMAGE_PROTECT                                      = 0xC0000130
-STATUS_INVALID_IMAGE_WIN_16                                       = 0xC0000131
-STATUS_LOGON_SERVER_CONFLICT                                      = 0xC0000132
-STATUS_TIME_DIFFERENCE_AT_DC                                      = 0xC0000133
-STATUS_SYNCHRONIZATION_REQUIRED                                   = 0xC0000134
-STATUS_DLL_NOT_FOUND                                              = 0xC0000135
-STATUS_OPEN_FAILED                                                = 0xC0000136
-STATUS_IO_PRIVILEGE_FAILED                                        = 0xC0000137
-STATUS_ORDINAL_NOT_FOUND                                          = 0xC0000138
-STATUS_ENTRYPOINT_NOT_FOUND                                       = 0xC0000139
-STATUS_CONTROL_C_EXIT                                             = 0xC000013A
-STATUS_LOCAL_DISCONNECT                                           = 0xC000013B
-STATUS_REMOTE_DISCONNECT                                          = 0xC000013C
-STATUS_REMOTE_RESOURCES                                           = 0xC000013D
-STATUS_LINK_FAILED                                                = 0xC000013E
-STATUS_LINK_TIMEOUT                                               = 0xC000013F
-STATUS_INVALID_CONNECTION                                         = 0xC0000140
-STATUS_INVALID_ADDRESS                                            = 0xC0000141
-STATUS_DLL_INIT_FAILED                                            = 0xC0000142
-STATUS_MISSING_SYSTEMFILE                                         = 0xC0000143
-STATUS_UNHANDLED_EXCEPTION                                        = 0xC0000144
-STATUS_APP_INIT_FAILURE                                           = 0xC0000145
-STATUS_PAGEFILE_CREATE_FAILED                                     = 0xC0000146
-STATUS_NO_PAGEFILE                                                = 0xC0000147
-STATUS_INVALID_LEVEL                                              = 0xC0000148
-STATUS_WRONG_PASSWORD_CORE                                        = 0xC0000149
-STATUS_ILLEGAL_FLOAT_CONTEXT                                      = 0xC000014A
-STATUS_PIPE_BROKEN                                                = 0xC000014B
-STATUS_REGISTRY_CORRUPT                                           = 0xC000014C
-STATUS_REGISTRY_IO_FAILED                                         = 0xC000014D
-STATUS_NO_EVENT_PAIR                                              = 0xC000014E
-STATUS_UNRECOGNIZED_VOLUME                                        = 0xC000014F
-STATUS_SERIAL_NO_DEVICE_INITED                                    = 0xC0000150
-STATUS_NO_SUCH_ALIAS                                              = 0xC0000151
-STATUS_MEMBER_NOT_IN_ALIAS                                        = 0xC0000152
-STATUS_MEMBER_IN_ALIAS                                            = 0xC0000153
-STATUS_ALIAS_EXISTS                                               = 0xC0000154
-STATUS_LOGON_NOT_GRANTED                                          = 0xC0000155
-STATUS_TOO_MANY_SECRETS                                           = 0xC0000156
-STATUS_SECRET_TOO_LONG                                            = 0xC0000157
-STATUS_INTERNAL_DB_ERROR                                          = 0xC0000158
-STATUS_FULLSCREEN_MODE                                            = 0xC0000159
-STATUS_TOO_MANY_CONTEXT_IDS                                       = 0xC000015A
-STATUS_LOGON_TYPE_NOT_GRANTED                                     = 0xC000015B
-STATUS_NOT_REGISTRY_FILE                                          = 0xC000015C
-STATUS_NT_CROSS_ENCRYPTION_REQUIRED                               = 0xC000015D
-STATUS_DOMAIN_CTRLR_CONFIG_ERROR                                  = 0xC000015E
-STATUS_FT_MISSING_MEMBER                                          = 0xC000015F
-STATUS_ILL_FORMED_SERVICE_ENTRY                                   = 0xC0000160
-STATUS_ILLEGAL_CHARACTER                                          = 0xC0000161
-STATUS_UNMAPPABLE_CHARACTER                                       = 0xC0000162
-STATUS_UNDEFINED_CHARACTER                                        = 0xC0000163
-STATUS_FLOPPY_VOLUME                                              = 0xC0000164
-STATUS_FLOPPY_ID_MARK_NOT_FOUND                                   = 0xC0000165
-STATUS_FLOPPY_WRONG_CYLINDER                                      = 0xC0000166
-STATUS_FLOPPY_UNKNOWN_ERROR                                       = 0xC0000167
-STATUS_FLOPPY_BAD_REGISTERS                                       = 0xC0000168
-STATUS_DISK_RECALIBRATE_FAILED                                    = 0xC0000169
-STATUS_DISK_OPERATION_FAILED                                      = 0xC000016A
-STATUS_DISK_RESET_FAILED                                          = 0xC000016B
-STATUS_SHARED_IRQ_BUSY                                            = 0xC000016C
-STATUS_FT_ORPHANING                                               = 0xC000016D
-STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT                           = 0xC000016E
-STATUS_PARTITION_FAILURE                                          = 0xC0000172
-STATUS_INVALID_BLOCK_LENGTH                                       = 0xC0000173
-STATUS_DEVICE_NOT_PARTITIONED                                     = 0xC0000174
-STATUS_UNABLE_TO_LOCK_MEDIA                                       = 0xC0000175
-STATUS_UNABLE_TO_UNLOAD_MEDIA                                     = 0xC0000176
-STATUS_EOM_OVERFLOW                                               = 0xC0000177
-STATUS_NO_MEDIA                                                   = 0xC0000178
-STATUS_NO_SUCH_MEMBER                                             = 0xC000017A
-STATUS_INVALID_MEMBER                                             = 0xC000017B
-STATUS_KEY_DELETED                                                = 0xC000017C
-STATUS_NO_LOG_SPACE                                               = 0xC000017D
-STATUS_TOO_MANY_SIDS                                              = 0xC000017E
-STATUS_LM_CROSS_ENCRYPTION_REQUIRED                               = 0xC000017F
-STATUS_KEY_HAS_CHILDREN                                           = 0xC0000180
-STATUS_CHILD_MUST_BE_VOLATILE                                     = 0xC0000181
-STATUS_DEVICE_CONFIGURATION_ERROR                                 = 0xC0000182
-STATUS_DRIVER_INTERNAL_ERROR                                      = 0xC0000183
-STATUS_INVALID_DEVICE_STATE                                       = 0xC0000184
-STATUS_IO_DEVICE_ERROR                                            = 0xC0000185
-STATUS_DEVICE_PROTOCOL_ERROR                                      = 0xC0000186
-STATUS_BACKUP_CONTROLLER                                          = 0xC0000187
-STATUS_LOG_FILE_FULL                                              = 0xC0000188
-STATUS_TOO_LATE                                                   = 0xC0000189
-STATUS_NO_TRUST_LSA_SECRET                                        = 0xC000018A
-STATUS_NO_TRUST_SAM_ACCOUNT                                       = 0xC000018B
-STATUS_TRUSTED_DOMAIN_FAILURE                                     = 0xC000018C
-STATUS_TRUSTED_RELATIONSHIP_FAILURE                               = 0xC000018D
-STATUS_EVENTLOG_FILE_CORRUPT                                      = 0xC000018E
-STATUS_EVENTLOG_CANT_START                                        = 0xC000018F
-STATUS_TRUST_FAILURE                                              = 0xC0000190
-STATUS_MUTANT_LIMIT_EXCEEDED                                      = 0xC0000191
-STATUS_NETLOGON_NOT_STARTED                                       = 0xC0000192
-STATUS_ACCOUNT_EXPIRED                                            = 0xC0000193
-STATUS_POSSIBLE_DEADLOCK                                          = 0xC0000194
-STATUS_NETWORK_CREDENTIAL_CONFLICT                                = 0xC0000195
-STATUS_REMOTE_SESSION_LIMIT                                       = 0xC0000196
-STATUS_EVENTLOG_FILE_CHANGED                                      = 0xC0000197
-STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT                          = 0xC0000198
-STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT                          = 0xC0000199
-STATUS_NOLOGON_SERVER_TRUST_ACCOUNT                               = 0xC000019A
-STATUS_DOMAIN_TRUST_INCONSISTENT                                  = 0xC000019B
-STATUS_FS_DRIVER_REQUIRED                                         = 0xC000019C
-STATUS_IMAGE_ALREADY_LOADED_AS_DLL                                = 0xC000019D
-STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING       = 0xC000019E
-STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME                          = 0xC000019F
-STATUS_SECURITY_STREAM_IS_INCONSISTENT                            = 0xC00001A0
-STATUS_INVALID_LOCK_RANGE                                         = 0xC00001A1
-STATUS_INVALID_ACE_CONDITION                                      = 0xC00001A2
-STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT                                = 0xC00001A3
-STATUS_NOTIFICATION_GUID_ALREADY_DEFINED                          = 0xC00001A4
-STATUS_NETWORK_OPEN_RESTRICTION                                   = 0xC0000201
-STATUS_NO_USER_SESSION_KEY                                        = 0xC0000202
-STATUS_USER_SESSION_DELETED                                       = 0xC0000203
-STATUS_RESOURCE_LANG_NOT_FOUND                                    = 0xC0000204
-STATUS_INSUFF_SERVER_RESOURCES                                    = 0xC0000205
-STATUS_INVALID_BUFFER_SIZE                                        = 0xC0000206
-STATUS_INVALID_ADDRESS_COMPONENT                                  = 0xC0000207
-STATUS_INVALID_ADDRESS_WILDCARD                                   = 0xC0000208
-STATUS_TOO_MANY_ADDRESSES                                         = 0xC0000209
-STATUS_ADDRESS_ALREADY_EXISTS                                     = 0xC000020A
-STATUS_ADDRESS_CLOSED                                             = 0xC000020B
-STATUS_CONNECTION_DISCONNECTED                                    = 0xC000020C
-STATUS_CONNECTION_RESET                                           = 0xC000020D
-STATUS_TOO_MANY_NODES                                             = 0xC000020E
-STATUS_TRANSACTION_ABORTED                                        = 0xC000020F
-STATUS_TRANSACTION_TIMED_OUT                                      = 0xC0000210
-STATUS_TRANSACTION_NO_RELEASE                                     = 0xC0000211
-STATUS_TRANSACTION_NO_MATCH                                       = 0xC0000212
-STATUS_TRANSACTION_RESPONDED                                      = 0xC0000213
-STATUS_TRANSACTION_INVALID_ID                                     = 0xC0000214
-STATUS_TRANSACTION_INVALID_TYPE                                   = 0xC0000215
-STATUS_NOT_SERVER_SESSION                                         = 0xC0000216
-STATUS_NOT_CLIENT_SESSION                                         = 0xC0000217
-STATUS_CANNOT_LOAD_REGISTRY_FILE                                  = 0xC0000218
-STATUS_DEBUG_ATTACH_FAILED                                        = 0xC0000219
-STATUS_SYSTEM_PROCESS_TERMINATED                                  = 0xC000021A
-STATUS_DATA_NOT_ACCEPTED                                          = 0xC000021B
-STATUS_NO_BROWSER_SERVERS_FOUND                                   = 0xC000021C
-STATUS_VDM_HARD_ERROR                                             = 0xC000021D
-STATUS_DRIVER_CANCEL_TIMEOUT                                      = 0xC000021E
-STATUS_REPLY_MESSAGE_MISMATCH                                     = 0xC000021F
-STATUS_MAPPED_ALIGNMENT                                           = 0xC0000220
-STATUS_IMAGE_CHECKSUM_MISMATCH                                    = 0xC0000221
-STATUS_LOST_WRITEBEHIND_DATA                                      = 0xC0000222
-STATUS_CLIENT_SERVER_PARAMETERS_INVALID                           = 0xC0000223
-STATUS_PASSWORD_MUST_CHANGE                                       = 0xC0000224
-STATUS_NOT_FOUND                                                  = 0xC0000225
-STATUS_NOT_TINY_STREAM                                            = 0xC0000226
-STATUS_RECOVERY_FAILURE                                           = 0xC0000227
-STATUS_STACK_OVERFLOW_READ                                        = 0xC0000228
-STATUS_FAIL_CHECK                                                 = 0xC0000229
-STATUS_DUPLICATE_OBJECTID                                         = 0xC000022A
-STATUS_OBJECTID_EXISTS                                            = 0xC000022B
-STATUS_CONVERT_TO_LARGE                                           = 0xC000022C
-STATUS_RETRY                                                      = 0xC000022D
-STATUS_FOUND_OUT_OF_SCOPE                                         = 0xC000022E
-STATUS_ALLOCATE_BUCKET                                            = 0xC000022F
-STATUS_PROPSET_NOT_FOUND                                          = 0xC0000230
-STATUS_MARSHALL_OVERFLOW                                          = 0xC0000231
-STATUS_INVALID_VARIANT                                            = 0xC0000232
-STATUS_DOMAIN_CONTROLLER_NOT_FOUND                                = 0xC0000233
-STATUS_ACCOUNT_LOCKED_OUT                                         = 0xC0000234
-STATUS_HANDLE_NOT_CLOSABLE                                        = 0xC0000235
-STATUS_CONNECTION_REFUSED                                         = 0xC0000236
-STATUS_GRACEFUL_DISCONNECT                                        = 0xC0000237
-STATUS_ADDRESS_ALREADY_ASSOCIATED                                 = 0xC0000238
-STATUS_ADDRESS_NOT_ASSOCIATED                                     = 0xC0000239
-STATUS_CONNECTION_INVALID                                         = 0xC000023A
-STATUS_CONNECTION_ACTIVE                                          = 0xC000023B
-STATUS_NETWORK_UNREACHABLE                                        = 0xC000023C
-STATUS_HOST_UNREACHABLE                                           = 0xC000023D
-STATUS_PROTOCOL_UNREACHABLE                                       = 0xC000023E
-STATUS_PORT_UNREACHABLE                                           = 0xC000023F
-STATUS_REQUEST_ABORTED                                            = 0xC0000240
-STATUS_CONNECTION_ABORTED                                         = 0xC0000241
-STATUS_BAD_COMPRESSION_BUFFER                                     = 0xC0000242
-STATUS_USER_MAPPED_FILE                                           = 0xC0000243
-STATUS_AUDIT_FAILED                                               = 0xC0000244
-STATUS_TIMER_RESOLUTION_NOT_SET                                   = 0xC0000245
-STATUS_CONNECTION_COUNT_LIMIT                                     = 0xC0000246
-STATUS_LOGIN_TIME_RESTRICTION                                     = 0xC0000247
-STATUS_LOGIN_WKSTA_RESTRICTION                                    = 0xC0000248
-STATUS_IMAGE_MP_UP_MISMATCH                                       = 0xC0000249
-STATUS_INSUFFICIENT_LOGON_INFO                                    = 0xC0000250
-STATUS_BAD_DLL_ENTRYPOINT                                         = 0xC0000251
-STATUS_BAD_SERVICE_ENTRYPOINT                                     = 0xC0000252
-STATUS_LPC_REPLY_LOST                                             = 0xC0000253
-STATUS_IP_ADDRESS_CONFLICT1                                       = 0xC0000254
-STATUS_IP_ADDRESS_CONFLICT2                                       = 0xC0000255
-STATUS_REGISTRY_QUOTA_LIMIT                                       = 0xC0000256
-STATUS_PATH_NOT_COVERED                                           = 0xC0000257
-STATUS_NO_CALLBACK_ACTIVE                                         = 0xC0000258
-STATUS_LICENSE_QUOTA_EXCEEDED                                     = 0xC0000259
-STATUS_PWD_TOO_SHORT                                              = 0xC000025A
-STATUS_PWD_TOO_RECENT                                             = 0xC000025B
-STATUS_PWD_HISTORY_CONFLICT                                       = 0xC000025C
-STATUS_PLUGPLAY_NO_DEVICE                                         = 0xC000025E
-STATUS_UNSUPPORTED_COMPRESSION                                    = 0xC000025F
-STATUS_INVALID_HW_PROFILE                                         = 0xC0000260
-STATUS_INVALID_PLUGPLAY_DEVICE_PATH                               = 0xC0000261
-STATUS_DRIVER_ORDINAL_NOT_FOUND                                   = 0xC0000262
-STATUS_DRIVER_ENTRYPOINT_NOT_FOUND                                = 0xC0000263
-STATUS_RESOURCE_NOT_OWNED                                         = 0xC0000264
-STATUS_TOO_MANY_LINKS                                             = 0xC0000265
-STATUS_QUOTA_LIST_INCONSISTENT                                    = 0xC0000266
-STATUS_FILE_IS_OFFLINE                                            = 0xC0000267
-STATUS_EVALUATION_EXPIRATION                                      = 0xC0000268
-STATUS_ILLEGAL_DLL_RELOCATION                                     = 0xC0000269
-STATUS_LICENSE_VIOLATION                                          = 0xC000026A
-STATUS_DLL_INIT_FAILED_LOGOFF                                     = 0xC000026B
-STATUS_DRIVER_UNABLE_TO_LOAD                                      = 0xC000026C
-STATUS_DFS_UNAVAILABLE                                            = 0xC000026D
-STATUS_VOLUME_DISMOUNTED                                          = 0xC000026E
-STATUS_WX86_INTERNAL_ERROR                                        = 0xC000026F
-STATUS_WX86_FLOAT_STACK_CHECK                                     = 0xC0000270
-STATUS_VALIDATE_CONTINUE                                          = 0xC0000271
-STATUS_NO_MATCH                                                   = 0xC0000272
-STATUS_NO_MORE_MATCHES                                            = 0xC0000273
-STATUS_NOT_A_REPARSE_POINT                                        = 0xC0000275
-STATUS_IO_REPARSE_TAG_INVALID                                     = 0xC0000276
-STATUS_IO_REPARSE_TAG_MISMATCH                                    = 0xC0000277
-STATUS_IO_REPARSE_DATA_INVALID                                    = 0xC0000278
-STATUS_IO_REPARSE_TAG_NOT_HANDLED                                 = 0xC0000279
-STATUS_REPARSE_POINT_NOT_RESOLVED                                 = 0xC0000280
-STATUS_DIRECTORY_IS_A_REPARSE_POINT                               = 0xC0000281
-STATUS_RANGE_LIST_CONFLICT                                        = 0xC0000282
-STATUS_SOURCE_ELEMENT_EMPTY                                       = 0xC0000283
-STATUS_DESTINATION_ELEMENT_FULL                                   = 0xC0000284
-STATUS_ILLEGAL_ELEMENT_ADDRESS                                    = 0xC0000285
-STATUS_MAGAZINE_NOT_PRESENT                                       = 0xC0000286
-STATUS_REINITIALIZATION_NEEDED                                    = 0xC0000287
-STATUS_ENCRYPTION_FAILED                                          = 0xC000028A
-STATUS_DECRYPTION_FAILED                                          = 0xC000028B
-STATUS_RANGE_NOT_FOUND                                            = 0xC000028C
-STATUS_NO_RECOVERY_POLICY                                         = 0xC000028D
-STATUS_NO_EFS                                                     = 0xC000028E
-STATUS_WRONG_EFS                                                  = 0xC000028F
-STATUS_NO_USER_KEYS                                               = 0xC0000290
-STATUS_FILE_NOT_ENCRYPTED                                         = 0xC0000291
-STATUS_NOT_EXPORT_FORMAT                                          = 0xC0000292
-STATUS_FILE_ENCRYPTED                                             = 0xC0000293
-STATUS_WMI_GUID_NOT_FOUND                                         = 0xC0000295
-STATUS_WMI_INSTANCE_NOT_FOUND                                     = 0xC0000296
-STATUS_WMI_ITEMID_NOT_FOUND                                       = 0xC0000297
-STATUS_WMI_TRY_AGAIN                                              = 0xC0000298
-STATUS_SHARED_POLICY                                              = 0xC0000299
-STATUS_POLICY_OBJECT_NOT_FOUND                                    = 0xC000029A
-STATUS_POLICY_ONLY_IN_DS                                          = 0xC000029B
-STATUS_VOLUME_NOT_UPGRADED                                        = 0xC000029C
-STATUS_REMOTE_STORAGE_NOT_ACTIVE                                  = 0xC000029D
-STATUS_REMOTE_STORAGE_MEDIA_ERROR                                 = 0xC000029E
-STATUS_NO_TRACKING_SERVICE                                        = 0xC000029F
-STATUS_SERVER_SID_MISMATCH                                        = 0xC00002A0
-STATUS_DS_NO_ATTRIBUTE_OR_VALUE                                   = 0xC00002A1
-STATUS_DS_INVALID_ATTRIBUTE_SYNTAX                                = 0xC00002A2
-STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED                                = 0xC00002A3
-STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS                               = 0xC00002A4
-STATUS_DS_BUSY                                                    = 0xC00002A5
-STATUS_DS_UNAVAILABLE                                             = 0xC00002A6
-STATUS_DS_NO_RIDS_ALLOCATED                                       = 0xC00002A7
-STATUS_DS_NO_MORE_RIDS                                            = 0xC00002A8
-STATUS_DS_INCORRECT_ROLE_OWNER                                    = 0xC00002A9
-STATUS_DS_RIDMGR_INIT_ERROR                                       = 0xC00002AA
-STATUS_DS_OBJ_CLASS_VIOLATION                                     = 0xC00002AB
-STATUS_DS_CANT_ON_NON_LEAF                                        = 0xC00002AC
-STATUS_DS_CANT_ON_RDN                                             = 0xC00002AD
-STATUS_DS_CANT_MOD_OBJ_CLASS                                      = 0xC00002AE
-STATUS_DS_CROSS_DOM_MOVE_FAILED                                   = 0xC00002AF
-STATUS_DS_GC_NOT_AVAILABLE                                        = 0xC00002B0
-STATUS_DIRECTORY_SERVICE_REQUIRED                                 = 0xC00002B1
-STATUS_REPARSE_ATTRIBUTE_CONFLICT                                 = 0xC00002B2
-STATUS_CANT_ENABLE_DENY_ONLY                                      = 0xC00002B3
-STATUS_FLOAT_MULTIPLE_FAULTS                                      = 0xC00002B4
-STATUS_FLOAT_MULTIPLE_TRAPS                                       = 0xC00002B5
-STATUS_DEVICE_REMOVED                                             = 0xC00002B6
-STATUS_JOURNAL_DELETE_IN_PROGRESS                                 = 0xC00002B7
-STATUS_JOURNAL_NOT_ACTIVE                                         = 0xC00002B8
-STATUS_NOINTERFACE                                                = 0xC00002B9
-STATUS_DS_ADMIN_LIMIT_EXCEEDED                                    = 0xC00002C1
-STATUS_DRIVER_FAILED_SLEEP                                        = 0xC00002C2
-STATUS_MUTUAL_AUTHENTICATION_FAILED                               = 0xC00002C3
-STATUS_CORRUPT_SYSTEM_FILE                                        = 0xC00002C4
-STATUS_DATATYPE_MISALIGNMENT_ERROR                                = 0xC00002C5
-STATUS_WMI_READ_ONLY                                              = 0xC00002C6
-STATUS_WMI_SET_FAILURE                                            = 0xC00002C7
-STATUS_COMMITMENT_MINIMUM                                         = 0xC00002C8
-STATUS_REG_NAT_CONSUMPTION                                        = 0xC00002C9
-STATUS_TRANSPORT_FULL                                             = 0xC00002CA
-STATUS_DS_SAM_INIT_FAILURE                                        = 0xC00002CB
-STATUS_ONLY_IF_CONNECTED                                          = 0xC00002CC
-STATUS_DS_SENSITIVE_GROUP_VIOLATION                               = 0xC00002CD
-STATUS_PNP_RESTART_ENUMERATION                                    = 0xC00002CE
-STATUS_JOURNAL_ENTRY_DELETED                                      = 0xC00002CF
-STATUS_DS_CANT_MOD_PRIMARYGROUPID                                 = 0xC00002D0
-STATUS_SYSTEM_IMAGE_BAD_SIGNATURE                                 = 0xC00002D1
-STATUS_PNP_REBOOT_REQUIRED                                        = 0xC00002D2
-STATUS_POWER_STATE_INVALID                                        = 0xC00002D3
-STATUS_DS_INVALID_GROUP_TYPE                                      = 0xC00002D4
-STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN                      = 0xC00002D5
-STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN                       = 0xC00002D6
-STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER                           = 0xC00002D7
-STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER                       = 0xC00002D8
-STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER                        = 0xC00002D9
-STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER                     = 0xC00002DA
-STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER                = 0xC00002DB
-STATUS_DS_HAVE_PRIMARY_MEMBERS                                    = 0xC00002DC
-STATUS_WMI_NOT_SUPPORTED                                          = 0xC00002DD
-STATUS_INSUFFICIENT_POWER                                         = 0xC00002DE
-STATUS_SAM_NEED_BOOTKEY_PASSWORD                                  = 0xC00002DF
-STATUS_SAM_NEED_BOOTKEY_FLOPPY                                    = 0xC00002E0
-STATUS_DS_CANT_START                                              = 0xC00002E1
-STATUS_DS_INIT_FAILURE                                            = 0xC00002E2
-STATUS_SAM_INIT_FAILURE                                           = 0xC00002E3
-STATUS_DS_GC_REQUIRED                                             = 0xC00002E4
-STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY                              = 0xC00002E5
-STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS                              = 0xC00002E6
-STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED                          = 0xC00002E7
-STATUS_CURRENT_DOMAIN_NOT_ALLOWED                                 = 0xC00002E9
-STATUS_CANNOT_MAKE                                                = 0xC00002EA
-STATUS_SYSTEM_SHUTDOWN                                            = 0xC00002EB
-STATUS_DS_INIT_FAILURE_CONSOLE                                    = 0xC00002EC
-STATUS_DS_SAM_INIT_FAILURE_CONSOLE                                = 0xC00002ED
-STATUS_UNFINISHED_CONTEXT_DELETED                                 = 0xC00002EE
-STATUS_NO_TGT_REPLY                                               = 0xC00002EF
-STATUS_OBJECTID_NOT_FOUND                                         = 0xC00002F0
-STATUS_NO_IP_ADDRESSES                                            = 0xC00002F1
-STATUS_WRONG_CREDENTIAL_HANDLE                                    = 0xC00002F2
-STATUS_CRYPTO_SYSTEM_INVALID                                      = 0xC00002F3
-STATUS_MAX_REFERRALS_EXCEEDED                                     = 0xC00002F4
-STATUS_MUST_BE_KDC                                                = 0xC00002F5
-STATUS_STRONG_CRYPTO_NOT_SUPPORTED                                = 0xC00002F6
-STATUS_TOO_MANY_PRINCIPALS                                        = 0xC00002F7
-STATUS_NO_PA_DATA                                                 = 0xC00002F8
-STATUS_PKINIT_NAME_MISMATCH                                       = 0xC00002F9
-STATUS_SMARTCARD_LOGON_REQUIRED                                   = 0xC00002FA
-STATUS_KDC_INVALID_REQUEST                                        = 0xC00002FB
-STATUS_KDC_UNABLE_TO_REFER                                        = 0xC00002FC
-STATUS_KDC_UNKNOWN_ETYPE                                          = 0xC00002FD
-STATUS_SHUTDOWN_IN_PROGRESS                                       = 0xC00002FE
-STATUS_SERVER_SHUTDOWN_IN_PROGRESS                                = 0xC00002FF
-STATUS_NOT_SUPPORTED_ON_SBS                                       = 0xC0000300
-STATUS_WMI_GUID_DISCONNECTED                                      = 0xC0000301
-STATUS_WMI_ALREADY_DISABLED                                       = 0xC0000302
-STATUS_WMI_ALREADY_ENABLED                                        = 0xC0000303
-STATUS_MFT_TOO_FRAGMENTED                                         = 0xC0000304
-STATUS_COPY_PROTECTION_FAILURE                                    = 0xC0000305
-STATUS_CSS_AUTHENTICATION_FAILURE                                 = 0xC0000306
-STATUS_CSS_KEY_NOT_PRESENT                                        = 0xC0000307
-STATUS_CSS_KEY_NOT_ESTABLISHED                                    = 0xC0000308
-STATUS_CSS_SCRAMBLED_SECTOR                                       = 0xC0000309
-STATUS_CSS_REGION_MISMATCH                                        = 0xC000030A
-STATUS_CSS_RESETS_EXHAUSTED                                       = 0xC000030B
-STATUS_PKINIT_FAILURE                                             = 0xC0000320
-STATUS_SMARTCARD_SUBSYSTEM_FAILURE                                = 0xC0000321
-STATUS_NO_KERB_KEY                                                = 0xC0000322
-STATUS_HOST_DOWN                                                  = 0xC0000350
-STATUS_UNSUPPORTED_PREAUTH                                        = 0xC0000351
-STATUS_EFS_ALG_BLOB_TOO_BIG                                       = 0xC0000352
-STATUS_PORT_NOT_SET                                               = 0xC0000353
-STATUS_DEBUGGER_INACTIVE                                          = 0xC0000354
-STATUS_DS_VERSION_CHECK_FAILURE                                   = 0xC0000355
-STATUS_AUDITING_DISABLED                                          = 0xC0000356
-STATUS_PRENT4_MACHINE_ACCOUNT                                     = 0xC0000357
-STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER                           = 0xC0000358
-STATUS_INVALID_IMAGE_WIN_32                                       = 0xC0000359
-STATUS_INVALID_IMAGE_WIN_64                                       = 0xC000035A
-STATUS_BAD_BINDINGS                                               = 0xC000035B
-STATUS_NETWORK_SESSION_EXPIRED                                    = 0xC000035C
-STATUS_APPHELP_BLOCK                                              = 0xC000035D
-STATUS_ALL_SIDS_FILTERED                                          = 0xC000035E
-STATUS_NOT_SAFE_MODE_DRIVER                                       = 0xC000035F
-STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT                          = 0xC0000361
-STATUS_ACCESS_DISABLED_BY_POLICY_PATH                             = 0xC0000362
-STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER                        = 0xC0000363
-STATUS_ACCESS_DISABLED_BY_POLICY_OTHER                            = 0xC0000364
-STATUS_FAILED_DRIVER_ENTRY                                        = 0xC0000365
-STATUS_DEVICE_ENUMERATION_ERROR                                   = 0xC0000366
-STATUS_MOUNT_POINT_NOT_RESOLVED                                   = 0xC0000368
-STATUS_INVALID_DEVICE_OBJECT_PARAMETER                            = 0xC0000369
-STATUS_MCA_OCCURED                                                = 0xC000036A
-STATUS_DRIVER_BLOCKED_CRITICAL                                    = 0xC000036B
-STATUS_DRIVER_BLOCKED                                             = 0xC000036C
-STATUS_DRIVER_DATABASE_ERROR                                      = 0xC000036D
-STATUS_SYSTEM_HIVE_TOO_LARGE                                      = 0xC000036E
-STATUS_INVALID_IMPORT_OF_NON_DLL                                  = 0xC000036F
-STATUS_NO_SECRETS                                                 = 0xC0000371
-STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY                      = 0xC0000372
-STATUS_FAILED_STACK_SWITCH                                        = 0xC0000373
-STATUS_HEAP_CORRUPTION                                            = 0xC0000374
-STATUS_SMARTCARD_WRONG_PIN                                        = 0xC0000380
-STATUS_SMARTCARD_CARD_BLOCKED                                     = 0xC0000381
-STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED                           = 0xC0000382
-STATUS_SMARTCARD_NO_CARD                                          = 0xC0000383
-STATUS_SMARTCARD_NO_KEY_CONTAINER                                 = 0xC0000384
-STATUS_SMARTCARD_NO_CERTIFICATE                                   = 0xC0000385
-STATUS_SMARTCARD_NO_KEYSET                                        = 0xC0000386
-STATUS_SMARTCARD_IO_ERROR                                         = 0xC0000387
-STATUS_DOWNGRADE_DETECTED                                         = 0xC0000388
-STATUS_SMARTCARD_CERT_REVOKED                                     = 0xC0000389
-STATUS_ISSUING_CA_UNTRUSTED                                       = 0xC000038A
-STATUS_REVOCATION_OFFLINE_C                                       = 0xC000038B
-STATUS_PKINIT_CLIENT_FAILURE                                      = 0xC000038C
-STATUS_SMARTCARD_CERT_EXPIRED                                     = 0xC000038D
-STATUS_DRIVER_FAILED_PRIOR_UNLOAD                                 = 0xC000038E
-STATUS_SMARTCARD_SILENT_CONTEXT                                   = 0xC000038F
-STATUS_PER_USER_TRUST_QUOTA_EXCEEDED                              = 0xC0000401
-STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED                              = 0xC0000402
-STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED                           = 0xC0000403
-STATUS_DS_NAME_NOT_UNIQUE                                         = 0xC0000404
-STATUS_DS_DUPLICATE_ID_FOUND                                      = 0xC0000405
-STATUS_DS_GROUP_CONVERSION_ERROR                                  = 0xC0000406
-STATUS_VOLSNAP_PREPARE_HIBERNATE                                  = 0xC0000407
-STATUS_USER2USER_REQUIRED                                         = 0xC0000408
-STATUS_STACK_BUFFER_OVERRUN                                       = 0xC0000409
-STATUS_NO_S4U_PROT_SUPPORT                                        = 0xC000040A
-STATUS_CROSSREALM_DELEGATION_FAILURE                              = 0xC000040B
-STATUS_REVOCATION_OFFLINE_KDC                                     = 0xC000040C
-STATUS_ISSUING_CA_UNTRUSTED_KDC                                   = 0xC000040D
-STATUS_KDC_CERT_EXPIRED                                           = 0xC000040E
-STATUS_KDC_CERT_REVOKED                                           = 0xC000040F
-STATUS_PARAMETER_QUOTA_EXCEEDED                                   = 0xC0000410
-STATUS_HIBERNATION_FAILURE                                        = 0xC0000411
-STATUS_DELAY_LOAD_FAILED                                          = 0xC0000412
-STATUS_AUTHENTICATION_FIREWALL_FAILED                             = 0xC0000413
-STATUS_VDM_DISALLOWED                                             = 0xC0000414
-STATUS_HUNG_DISPLAY_DRIVER_THREAD                                 = 0xC0000415
-STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE    = 0xC0000416
-STATUS_INVALID_CRUNTIME_PARAMETER                                 = 0xC0000417
-STATUS_NTLM_BLOCKED                                               = 0xC0000418
-STATUS_DS_SRC_SID_EXISTS_IN_FOREST                                = 0xC0000419
-STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST                            = 0xC000041A
-STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST                              = 0xC000041B
-STATUS_INVALID_USER_PRINCIPAL_NAME                                = 0xC000041C
-STATUS_ASSERTION_FAILURE                                          = 0xC0000420
-STATUS_VERIFIER_STOP                                              = 0xC0000421
-STATUS_CALLBACK_POP_STACK                                         = 0xC0000423
-STATUS_INCOMPATIBLE_DRIVER_BLOCKED                                = 0xC0000424
-STATUS_HIVE_UNLOADED                                              = 0xC0000425
-STATUS_COMPRESSION_DISABLED                                       = 0xC0000426
-STATUS_FILE_SYSTEM_LIMITATION                                     = 0xC0000427
-STATUS_INVALID_IMAGE_HASH                                         = 0xC0000428
-STATUS_NOT_CAPABLE                                                = 0xC0000429
-STATUS_REQUEST_OUT_OF_SEQUENCE                                    = 0xC000042A
-STATUS_IMPLEMENTATION_LIMIT                                       = 0xC000042B
-STATUS_ELEVATION_REQUIRED                                         = 0xC000042C
-STATUS_NO_SECURITY_CONTEXT                                        = 0xC000042D
-STATUS_PKU2U_CERT_FAILURE                                         = 0xC000042E
-STATUS_BEYOND_VDL                                                 = 0xC0000432
-STATUS_ENCOUNTERED_WRITE_IN_PROGRESS                              = 0xC0000433
-STATUS_PTE_CHANGED                                                = 0xC0000434
-STATUS_PURGE_FAILED                                               = 0xC0000435
-STATUS_CRED_REQUIRES_CONFIRMATION                                 = 0xC0000440
-STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE                      = 0xC0000441
-STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER                           = 0xC0000442
-STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE                      = 0xC0000443
-STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE                           = 0xC0000444
-STATUS_CS_ENCRYPTION_FILE_NOT_CSE                                 = 0xC0000445
-STATUS_INVALID_LABEL                                              = 0xC0000446
-STATUS_DRIVER_PROCESS_TERMINATED                                  = 0xC0000450
-STATUS_AMBIGUOUS_SYSTEM_DEVICE                                    = 0xC0000451
-STATUS_SYSTEM_DEVICE_NOT_FOUND                                    = 0xC0000452
-STATUS_RESTART_BOOT_APPLICATION                                   = 0xC0000453
-STATUS_INSUFFICIENT_NVRAM_RESOURCES                               = 0xC0000454
-STATUS_INVALID_TASK_NAME                                          = 0xC0000500
-STATUS_INVALID_TASK_INDEX                                         = 0xC0000501
-STATUS_THREAD_ALREADY_IN_TASK                                     = 0xC0000502
-STATUS_CALLBACK_BYPASS                                            = 0xC0000503
-STATUS_FAIL_FAST_EXCEPTION                                        = 0xC0000602
-STATUS_IMAGE_CERT_REVOKED                                         = 0xC0000603
-STATUS_PORT_CLOSED                                                = 0xC0000700
-STATUS_MESSAGE_LOST                                               = 0xC0000701
-STATUS_INVALID_MESSAGE                                            = 0xC0000702
-STATUS_REQUEST_CANCELED                                           = 0xC0000703
-STATUS_RECURSIVE_DISPATCH                                         = 0xC0000704
-STATUS_LPC_RECEIVE_BUFFER_EXPECTED                                = 0xC0000705
-STATUS_LPC_INVALID_CONNECTION_USAGE                               = 0xC0000706
-STATUS_LPC_REQUESTS_NOT_ALLOWED                                   = 0xC0000707
-STATUS_RESOURCE_IN_USE                                            = 0xC0000708
-STATUS_HARDWARE_MEMORY_ERROR                                      = 0xC0000709
-STATUS_THREADPOOL_HANDLE_EXCEPTION                                = 0xC000070A
-STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED                  = 0xC000070B
-STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED          = 0xC000070C
-STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED              = 0xC000070D
-STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED               = 0xC000070E
-STATUS_THREADPOOL_RELEASED_DURING_OPERATION                       = 0xC000070F
-STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING                      = 0xC0000710
-STATUS_APC_RETURNED_WHILE_IMPERSONATING                           = 0xC0000711
-STATUS_PROCESS_IS_PROTECTED                                       = 0xC0000712
-STATUS_MCA_EXCEPTION                                              = 0xC0000713
-STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE                             = 0xC0000714
-STATUS_SYMLINK_CLASS_DISABLED                                     = 0xC0000715
-STATUS_INVALID_IDN_NORMALIZATION                                  = 0xC0000716
-STATUS_NO_UNICODE_TRANSLATION                                     = 0xC0000717
-STATUS_ALREADY_REGISTERED                                         = 0xC0000718
-STATUS_CONTEXT_MISMATCH                                           = 0xC0000719
-STATUS_PORT_ALREADY_HAS_COMPLETION_LIST                           = 0xC000071A
-STATUS_CALLBACK_RETURNED_THREAD_PRIORITY                          = 0xC000071B
-STATUS_INVALID_THREAD                                             = 0xC000071C
-STATUS_CALLBACK_RETURNED_TRANSACTION                              = 0xC000071D
-STATUS_CALLBACK_RETURNED_LDR_LOCK                                 = 0xC000071E
-STATUS_CALLBACK_RETURNED_LANG                                     = 0xC000071F
-STATUS_CALLBACK_RETURNED_PRI_BACK                                 = 0xC0000720
-STATUS_DISK_REPAIR_DISABLED                                       = 0xC0000800
-STATUS_DS_DOMAIN_RENAME_IN_PROGRESS                               = 0xC0000801
-STATUS_DISK_QUOTA_EXCEEDED                                        = 0xC0000802
-STATUS_CONTENT_BLOCKED                                            = 0xC0000804
-STATUS_BAD_CLUSTERS                                               = 0xC0000805
-STATUS_VOLUME_DIRTY                                               = 0xC0000806
-STATUS_FILE_CHECKED_OUT                                           = 0xC0000901
-STATUS_CHECKOUT_REQUIRED                                          = 0xC0000902
-STATUS_BAD_FILE_TYPE                                              = 0xC0000903
-STATUS_FILE_TOO_LARGE                                             = 0xC0000904
-STATUS_FORMS_AUTH_REQUIRED                                        = 0xC0000905
-STATUS_VIRUS_INFECTED                                             = 0xC0000906
-STATUS_VIRUS_DELETED                                              = 0xC0000907
-STATUS_BAD_MCFG_TABLE                                             = 0xC0000908
-STATUS_CANNOT_BREAK_OPLOCK                                        = 0xC0000909
-STATUS_WOW_ASSERTION                                              = 0xC0009898
-STATUS_INVALID_SIGNATURE                                          = 0xC000A000
-STATUS_HMAC_NOT_SUPPORTED                                         = 0xC000A001
-STATUS_IPSEC_QUEUE_OVERFLOW                                       = 0xC000A010
-STATUS_ND_QUEUE_OVERFLOW                                          = 0xC000A011
-STATUS_HOPLIMIT_EXCEEDED                                          = 0xC000A012
-STATUS_PROTOCOL_NOT_SUPPORTED                                     = 0xC000A013
-STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED                 = 0xC000A080
-STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR                 = 0xC000A081
-STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR                     = 0xC000A082
-STATUS_XML_PARSE_ERROR                                            = 0xC000A083
-STATUS_XMLDSIG_ERROR                                              = 0xC000A084
-STATUS_WRONG_COMPARTMENT                                          = 0xC000A085
-STATUS_AUTHIP_FAILURE                                             = 0xC000A086
-STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS                      = 0xC000A087
-STATUS_DS_OID_NOT_FOUND                                           = 0xC000A088
-STATUS_HASH_NOT_SUPPORTED                                         = 0xC000A100
-STATUS_HASH_NOT_PRESENT                                           = 0xC000A101
-DBG_NO_STATE_CHANGE                                               = 0xC0010001
-DBG_APP_NOT_IDLE                                                  = 0xC0010002
-RPC_NT_INVALID_STRING_BINDING                                     = 0xC0020001
-RPC_NT_WRONG_KIND_OF_BINDING                                      = 0xC0020002
-RPC_NT_INVALID_BINDING                                            = 0xC0020003
-RPC_NT_PROTSEQ_NOT_SUPPORTED                                      = 0xC0020004
-RPC_NT_INVALID_RPC_PROTSEQ                                        = 0xC0020005
-RPC_NT_INVALID_STRING_UUID                                        = 0xC0020006
-RPC_NT_INVALID_ENDPOINT_FORMAT                                    = 0xC0020007
-RPC_NT_INVALID_NET_ADDR                                           = 0xC0020008
-RPC_NT_NO_ENDPOINT_FOUND                                          = 0xC0020009
-RPC_NT_INVALID_TIMEOUT                                            = 0xC002000A
-RPC_NT_OBJECT_NOT_FOUND                                           = 0xC002000B
-RPC_NT_ALREADY_REGISTERED                                         = 0xC002000C
-RPC_NT_TYPE_ALREADY_REGISTERED                                    = 0xC002000D
-RPC_NT_ALREADY_LISTENING                                          = 0xC002000E
-RPC_NT_NO_PROTSEQS_REGISTERED                                     = 0xC002000F
-RPC_NT_NOT_LISTENING                                              = 0xC0020010
-RPC_NT_UNKNOWN_MGR_TYPE                                           = 0xC0020011
-RPC_NT_UNKNOWN_IF                                                 = 0xC0020012
-RPC_NT_NO_BINDINGS                                                = 0xC0020013
-RPC_NT_NO_PROTSEQS                                                = 0xC0020014
-RPC_NT_CANT_CREATE_ENDPOINT                                       = 0xC0020015
-RPC_NT_OUT_OF_RESOURCES                                           = 0xC0020016
-RPC_NT_SERVER_UNAVAILABLE                                         = 0xC0020017
-RPC_NT_SERVER_TOO_BUSY                                            = 0xC0020018
-RPC_NT_INVALID_NETWORK_OPTIONS                                    = 0xC0020019
-RPC_NT_NO_CALL_ACTIVE                                             = 0xC002001A
-RPC_NT_CALL_FAILED                                                = 0xC002001B
-RPC_NT_CALL_FAILED_DNE                                            = 0xC002001C
-RPC_NT_PROTOCOL_ERROR                                             = 0xC002001D
-RPC_NT_UNSUPPORTED_TRANS_SYN                                      = 0xC002001F
-RPC_NT_UNSUPPORTED_TYPE                                           = 0xC0020021
-RPC_NT_INVALID_TAG                                                = 0xC0020022
-RPC_NT_INVALID_BOUND                                              = 0xC0020023
-RPC_NT_NO_ENTRY_NAME                                              = 0xC0020024
-RPC_NT_INVALID_NAME_SYNTAX                                        = 0xC0020025
-RPC_NT_UNSUPPORTED_NAME_SYNTAX                                    = 0xC0020026
-RPC_NT_UUID_NO_ADDRESS                                            = 0xC0020028
-RPC_NT_DUPLICATE_ENDPOINT                                         = 0xC0020029
-RPC_NT_UNKNOWN_AUTHN_TYPE                                         = 0xC002002A
-RPC_NT_MAX_CALLS_TOO_SMALL                                        = 0xC002002B
-RPC_NT_STRING_TOO_LONG                                            = 0xC002002C
-RPC_NT_PROTSEQ_NOT_FOUND                                          = 0xC002002D
-RPC_NT_PROCNUM_OUT_OF_RANGE                                       = 0xC002002E
-RPC_NT_BINDING_HAS_NO_AUTH                                        = 0xC002002F
-RPC_NT_UNKNOWN_AUTHN_SERVICE                                      = 0xC0020030
-RPC_NT_UNKNOWN_AUTHN_LEVEL                                        = 0xC0020031
-RPC_NT_INVALID_AUTH_IDENTITY                                      = 0xC0020032
-RPC_NT_UNKNOWN_AUTHZ_SERVICE                                      = 0xC0020033
-EPT_NT_INVALID_ENTRY                                              = 0xC0020034
-EPT_NT_CANT_PERFORM_OP                                            = 0xC0020035
-EPT_NT_NOT_REGISTERED                                             = 0xC0020036
-RPC_NT_NOTHING_TO_EXPORT                                          = 0xC0020037
-RPC_NT_INCOMPLETE_NAME                                            = 0xC0020038
-RPC_NT_INVALID_VERS_OPTION                                        = 0xC0020039
-RPC_NT_NO_MORE_MEMBERS                                            = 0xC002003A
-RPC_NT_NOT_ALL_OBJS_UNEXPORTED                                    = 0xC002003B
-RPC_NT_INTERFACE_NOT_FOUND                                        = 0xC002003C
-RPC_NT_ENTRY_ALREADY_EXISTS                                       = 0xC002003D
-RPC_NT_ENTRY_NOT_FOUND                                            = 0xC002003E
-RPC_NT_NAME_SERVICE_UNAVAILABLE                                   = 0xC002003F
-RPC_NT_INVALID_NAF_ID                                             = 0xC0020040
-RPC_NT_CANNOT_SUPPORT                                             = 0xC0020041
-RPC_NT_NO_CONTEXT_AVAILABLE                                       = 0xC0020042
-RPC_NT_INTERNAL_ERROR                                             = 0xC0020043
-RPC_NT_ZERO_DIVIDE                                                = 0xC0020044
-RPC_NT_ADDRESS_ERROR                                              = 0xC0020045
-RPC_NT_FP_DIV_ZERO                                                = 0xC0020046
-RPC_NT_FP_UNDERFLOW                                               = 0xC0020047
-RPC_NT_FP_OVERFLOW                                                = 0xC0020048
-RPC_NT_CALL_IN_PROGRESS                                           = 0xC0020049
-RPC_NT_NO_MORE_BINDINGS                                           = 0xC002004A
-RPC_NT_GROUP_MEMBER_NOT_FOUND                                     = 0xC002004B
-EPT_NT_CANT_CREATE                                                = 0xC002004C
-RPC_NT_INVALID_OBJECT                                             = 0xC002004D
-RPC_NT_NO_INTERFACES                                              = 0xC002004F
-RPC_NT_CALL_CANCELLED                                             = 0xC0020050
-RPC_NT_BINDING_INCOMPLETE                                         = 0xC0020051
-RPC_NT_COMM_FAILURE                                               = 0xC0020052
-RPC_NT_UNSUPPORTED_AUTHN_LEVEL                                    = 0xC0020053
-RPC_NT_NO_PRINC_NAME                                              = 0xC0020054
-RPC_NT_NOT_RPC_ERROR                                              = 0xC0020055
-RPC_NT_SEC_PKG_ERROR                                              = 0xC0020057
-RPC_NT_NOT_CANCELLED                                              = 0xC0020058
-RPC_NT_INVALID_ASYNC_HANDLE                                       = 0xC0020062
-RPC_NT_INVALID_ASYNC_CALL                                         = 0xC0020063
-RPC_NT_PROXY_ACCESS_DENIED                                        = 0xC0020064
-RPC_NT_NO_MORE_ENTRIES                                            = 0xC0030001
-RPC_NT_SS_CHAR_TRANS_OPEN_FAIL                                    = 0xC0030002
-RPC_NT_SS_CHAR_TRANS_SHORT_FILE                                   = 0xC0030003
-RPC_NT_SS_IN_NULL_CONTEXT                                         = 0xC0030004
-RPC_NT_SS_CONTEXT_MISMATCH                                        = 0xC0030005
-RPC_NT_SS_CONTEXT_DAMAGED                                         = 0xC0030006
-RPC_NT_SS_HANDLES_MISMATCH                                        = 0xC0030007
-RPC_NT_SS_CANNOT_GET_CALL_HANDLE                                  = 0xC0030008
-RPC_NT_NULL_REF_POINTER                                           = 0xC0030009
-RPC_NT_ENUM_VALUE_OUT_OF_RANGE                                    = 0xC003000A
-RPC_NT_BYTE_COUNT_TOO_SMALL                                       = 0xC003000B
-RPC_NT_BAD_STUB_DATA                                              = 0xC003000C
-RPC_NT_INVALID_ES_ACTION                                          = 0xC0030059
-RPC_NT_WRONG_ES_VERSION                                           = 0xC003005A
-RPC_NT_WRONG_STUB_VERSION                                         = 0xC003005B
-RPC_NT_INVALID_PIPE_OBJECT                                        = 0xC003005C
-RPC_NT_INVALID_PIPE_OPERATION                                     = 0xC003005D
-RPC_NT_WRONG_PIPE_VERSION                                         = 0xC003005E
-RPC_NT_PIPE_CLOSED                                                = 0xC003005F
-RPC_NT_PIPE_DISCIPLINE_ERROR                                      = 0xC0030060
-RPC_NT_PIPE_EMPTY                                                 = 0xC0030061
-STATUS_PNP_BAD_MPS_TABLE                                          = 0xC0040035
-STATUS_PNP_TRANSLATION_FAILED                                     = 0xC0040036
-STATUS_PNP_IRQ_TRANSLATION_FAILED                                 = 0xC0040037
-STATUS_PNP_INVALID_ID                                             = 0xC0040038
-STATUS_IO_REISSUE_AS_CACHED                                       = 0xC0040039
-STATUS_CTX_WINSTATION_NAME_INVALID                                = 0xC00A0001
-STATUS_CTX_INVALID_PD                                             = 0xC00A0002
-STATUS_CTX_PD_NOT_FOUND                                           = 0xC00A0003
-STATUS_CTX_CLOSE_PENDING                                          = 0xC00A0006
-STATUS_CTX_NO_OUTBUF                                              = 0xC00A0007
-STATUS_CTX_MODEM_INF_NOT_FOUND                                    = 0xC00A0008
-STATUS_CTX_INVALID_MODEMNAME                                      = 0xC00A0009
-STATUS_CTX_RESPONSE_ERROR                                         = 0xC00A000A
-STATUS_CTX_MODEM_RESPONSE_TIMEOUT                                 = 0xC00A000B
-STATUS_CTX_MODEM_RESPONSE_NO_CARRIER                              = 0xC00A000C
-STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE                             = 0xC00A000D
-STATUS_CTX_MODEM_RESPONSE_BUSY                                    = 0xC00A000E
-STATUS_CTX_MODEM_RESPONSE_VOICE                                   = 0xC00A000F
-STATUS_CTX_TD_ERROR                                               = 0xC00A0010
-STATUS_CTX_LICENSE_CLIENT_INVALID                                 = 0xC00A0012
-STATUS_CTX_LICENSE_NOT_AVAILABLE                                  = 0xC00A0013
-STATUS_CTX_LICENSE_EXPIRED                                        = 0xC00A0014
-STATUS_CTX_WINSTATION_NOT_FOUND                                   = 0xC00A0015
-STATUS_CTX_WINSTATION_NAME_COLLISION                              = 0xC00A0016
-STATUS_CTX_WINSTATION_BUSY                                        = 0xC00A0017
-STATUS_CTX_BAD_VIDEO_MODE                                         = 0xC00A0018
-STATUS_CTX_GRAPHICS_INVALID                                       = 0xC00A0022
-STATUS_CTX_NOT_CONSOLE                                            = 0xC00A0024
-STATUS_CTX_CLIENT_QUERY_TIMEOUT                                   = 0xC00A0026
-STATUS_CTX_CONSOLE_DISCONNECT                                     = 0xC00A0027
-STATUS_CTX_CONSOLE_CONNECT                                        = 0xC00A0028
-STATUS_CTX_SHADOW_DENIED                                          = 0xC00A002A
-STATUS_CTX_WINSTATION_ACCESS_DENIED                               = 0xC00A002B
-STATUS_CTX_INVALID_WD                                             = 0xC00A002E
-STATUS_CTX_WD_NOT_FOUND                                           = 0xC00A002F
-STATUS_CTX_SHADOW_INVALID                                         = 0xC00A0030
-STATUS_CTX_SHADOW_DISABLED                                        = 0xC00A0031
-STATUS_RDP_PROTOCOL_ERROR                                         = 0xC00A0032
-STATUS_CTX_CLIENT_LICENSE_NOT_SET                                 = 0xC00A0033
-STATUS_CTX_CLIENT_LICENSE_IN_USE                                  = 0xC00A0034
-STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE                            = 0xC00A0035
-STATUS_CTX_SHADOW_NOT_RUNNING                                     = 0xC00A0036
-STATUS_CTX_LOGON_DISABLED                                         = 0xC00A0037
-STATUS_CTX_SECURITY_LAYER_ERROR                                   = 0xC00A0038
-STATUS_TS_INCOMPATIBLE_SESSIONS                                   = 0xC00A0039
-STATUS_MUI_FILE_NOT_FOUND                                         = 0xC00B0001
-STATUS_MUI_INVALID_FILE                                           = 0xC00B0002
-STATUS_MUI_INVALID_RC_CONFIG                                      = 0xC00B0003
-STATUS_MUI_INVALID_LOCALE_NAME                                    = 0xC00B0004
-STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME                          = 0xC00B0005
-STATUS_MUI_FILE_NOT_LOADED                                        = 0xC00B0006
-STATUS_RESOURCE_ENUM_USER_STOP                                    = 0xC00B0007
-STATUS_CLUSTER_INVALID_NODE                                       = 0xC0130001
-STATUS_CLUSTER_NODE_EXISTS                                        = 0xC0130002
-STATUS_CLUSTER_JOIN_IN_PROGRESS                                   = 0xC0130003
-STATUS_CLUSTER_NODE_NOT_FOUND                                     = 0xC0130004
-STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND                               = 0xC0130005
-STATUS_CLUSTER_NETWORK_EXISTS                                     = 0xC0130006
-STATUS_CLUSTER_NETWORK_NOT_FOUND                                  = 0xC0130007
-STATUS_CLUSTER_NETINTERFACE_EXISTS                                = 0xC0130008
-STATUS_CLUSTER_NETINTERFACE_NOT_FOUND                             = 0xC0130009
-STATUS_CLUSTER_INVALID_REQUEST                                    = 0xC013000A
-STATUS_CLUSTER_INVALID_NETWORK_PROVIDER                           = 0xC013000B
-STATUS_CLUSTER_NODE_DOWN                                          = 0xC013000C
-STATUS_CLUSTER_NODE_UNREACHABLE                                   = 0xC013000D
-STATUS_CLUSTER_NODE_NOT_MEMBER                                    = 0xC013000E
-STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS                               = 0xC013000F
-STATUS_CLUSTER_INVALID_NETWORK                                    = 0xC0130010
-STATUS_CLUSTER_NO_NET_ADAPTERS                                    = 0xC0130011
-STATUS_CLUSTER_NODE_UP                                            = 0xC0130012
-STATUS_CLUSTER_NODE_PAUSED                                        = 0xC0130013
-STATUS_CLUSTER_NODE_NOT_PAUSED                                    = 0xC0130014
-STATUS_CLUSTER_NO_SECURITY_CONTEXT                                = 0xC0130015
-STATUS_CLUSTER_NETWORK_NOT_INTERNAL                               = 0xC0130016
-STATUS_CLUSTER_POISONED                                           = 0xC0130017
-STATUS_ACPI_INVALID_OPCODE                                        = 0xC0140001
-STATUS_ACPI_STACK_OVERFLOW                                        = 0xC0140002
-STATUS_ACPI_ASSERT_FAILED                                         = 0xC0140003
-STATUS_ACPI_INVALID_INDEX                                         = 0xC0140004
-STATUS_ACPI_INVALID_ARGUMENT                                      = 0xC0140005
-STATUS_ACPI_FATAL                                                 = 0xC0140006
-STATUS_ACPI_INVALID_SUPERNAME                                     = 0xC0140007
-STATUS_ACPI_INVALID_ARGTYPE                                       = 0xC0140008
-STATUS_ACPI_INVALID_OBJTYPE                                       = 0xC0140009
-STATUS_ACPI_INVALID_TARGETTYPE                                    = 0xC014000A
-STATUS_ACPI_INCORRECT_ARGUMENT_COUNT                              = 0xC014000B
-STATUS_ACPI_ADDRESS_NOT_MAPPED                                    = 0xC014000C
-STATUS_ACPI_INVALID_EVENTTYPE                                     = 0xC014000D
-STATUS_ACPI_HANDLER_COLLISION                                     = 0xC014000E
-STATUS_ACPI_INVALID_DATA                                          = 0xC014000F
-STATUS_ACPI_INVALID_REGION                                        = 0xC0140010
-STATUS_ACPI_INVALID_ACCESS_SIZE                                   = 0xC0140011
-STATUS_ACPI_ACQUIRE_GLOBAL_LOCK                                   = 0xC0140012
-STATUS_ACPI_ALREADY_INITIALIZED                                   = 0xC0140013
-STATUS_ACPI_NOT_INITIALIZED                                       = 0xC0140014
-STATUS_ACPI_INVALID_MUTEX_LEVEL                                   = 0xC0140015
-STATUS_ACPI_MUTEX_NOT_OWNED                                       = 0xC0140016
-STATUS_ACPI_MUTEX_NOT_OWNER                                       = 0xC0140017
-STATUS_ACPI_RS_ACCESS                                             = 0xC0140018
-STATUS_ACPI_INVALID_TABLE                                         = 0xC0140019
-STATUS_ACPI_REG_HANDLER_FAILED                                    = 0xC0140020
-STATUS_ACPI_POWER_REQUEST_FAILED                                  = 0xC0140021
-STATUS_SXS_SECTION_NOT_FOUND                                      = 0xC0150001
-STATUS_SXS_CANT_GEN_ACTCTX                                        = 0xC0150002
-STATUS_SXS_INVALID_ACTCTXDATA_FORMAT                              = 0xC0150003
-STATUS_SXS_ASSEMBLY_NOT_FOUND                                     = 0xC0150004
-STATUS_SXS_MANIFEST_FORMAT_ERROR                                  = 0xC0150005
-STATUS_SXS_MANIFEST_PARSE_ERROR                                   = 0xC0150006
-STATUS_SXS_ACTIVATION_CONTEXT_DISABLED                            = 0xC0150007
-STATUS_SXS_KEY_NOT_FOUND                                          = 0xC0150008
-STATUS_SXS_VERSION_CONFLICT                                       = 0xC0150009
-STATUS_SXS_WRONG_SECTION_TYPE                                     = 0xC015000A
-STATUS_SXS_THREAD_QUERIES_DISABLED                                = 0xC015000B
-STATUS_SXS_ASSEMBLY_MISSING                                       = 0xC015000C
-STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET                            = 0xC015000E
-STATUS_SXS_EARLY_DEACTIVATION                                     = 0xC015000F
-STATUS_SXS_INVALID_DEACTIVATION                                   = 0xC0150010
-STATUS_SXS_MULTIPLE_DEACTIVATION                                  = 0xC0150011
-STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY                = 0xC0150012
-STATUS_SXS_PROCESS_TERMINATION_REQUESTED                          = 0xC0150013
-STATUS_SXS_CORRUPT_ACTIVATION_STACK                               = 0xC0150014
-STATUS_SXS_CORRUPTION                                             = 0xC0150015
-STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE                       = 0xC0150016
-STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME                        = 0xC0150017
-STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE                           = 0xC0150018
-STATUS_SXS_IDENTITY_PARSE_ERROR                                   = 0xC0150019
-STATUS_SXS_COMPONENT_STORE_CORRUPT                                = 0xC015001A
-STATUS_SXS_FILE_HASH_MISMATCH                                     = 0xC015001B
-STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT          = 0xC015001C
-STATUS_SXS_IDENTITIES_DIFFERENT                                   = 0xC015001D
-STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT                           = 0xC015001E
-STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY                              = 0xC015001F
-STATUS_ADVANCED_INSTALLER_FAILED                                  = 0xC0150020
-STATUS_XML_ENCODING_MISMATCH                                      = 0xC0150021
-STATUS_SXS_MANIFEST_TOO_BIG                                       = 0xC0150022
-STATUS_SXS_SETTING_NOT_REGISTERED                                 = 0xC0150023
-STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE                         = 0xC0150024
-STATUS_SMI_PRIMITIVE_INSTALLER_FAILED                             = 0xC0150025
-STATUS_GENERIC_COMMAND_FAILED                                     = 0xC0150026
-STATUS_SXS_FILE_HASH_MISSING                                      = 0xC0150027
-STATUS_TRANSACTIONAL_CONFLICT                                     = 0xC0190001
-STATUS_INVALID_TRANSACTION                                        = 0xC0190002
-STATUS_TRANSACTION_NOT_ACTIVE                                     = 0xC0190003
-STATUS_TM_INITIALIZATION_FAILED                                   = 0xC0190004
-STATUS_RM_NOT_ACTIVE                                              = 0xC0190005
-STATUS_RM_METADATA_CORRUPT                                        = 0xC0190006
-STATUS_TRANSACTION_NOT_JOINED                                     = 0xC0190007
-STATUS_DIRECTORY_NOT_RM                                           = 0xC0190008
-STATUS_TRANSACTIONS_UNSUPPORTED_REMOTE                            = 0xC019000A
-STATUS_LOG_RESIZE_INVALID_SIZE                                    = 0xC019000B
-STATUS_REMOTE_FILE_VERSION_MISMATCH                               = 0xC019000C
-STATUS_CRM_PROTOCOL_ALREADY_EXISTS                                = 0xC019000F
-STATUS_TRANSACTION_PROPAGATION_FAILED                             = 0xC0190010
-STATUS_CRM_PROTOCOL_NOT_FOUND                                     = 0xC0190011
-STATUS_TRANSACTION_SUPERIOR_EXISTS                                = 0xC0190012
-STATUS_TRANSACTION_REQUEST_NOT_VALID                              = 0xC0190013
-STATUS_TRANSACTION_NOT_REQUESTED                                  = 0xC0190014
-STATUS_TRANSACTION_ALREADY_ABORTED                                = 0xC0190015
-STATUS_TRANSACTION_ALREADY_COMMITTED                              = 0xC0190016
-STATUS_TRANSACTION_INVALID_MARSHALL_BUFFER                        = 0xC0190017
-STATUS_CURRENT_TRANSACTION_NOT_VALID                              = 0xC0190018
-STATUS_LOG_GROWTH_FAILED                                          = 0xC0190019
-STATUS_OBJECT_NO_LONGER_EXISTS                                    = 0xC0190021
-STATUS_STREAM_MINIVERSION_NOT_FOUND                               = 0xC0190022
-STATUS_STREAM_MINIVERSION_NOT_VALID                               = 0xC0190023
-STATUS_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION        = 0xC0190024
-STATUS_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT                   = 0xC0190025
-STATUS_CANT_CREATE_MORE_STREAM_MINIVERSIONS                       = 0xC0190026
-STATUS_HANDLE_NO_LONGER_VALID                                     = 0xC0190028
-STATUS_LOG_CORRUPTION_DETECTED                                    = 0xC0190030
-STATUS_RM_DISCONNECTED                                            = 0xC0190032
-STATUS_ENLISTMENT_NOT_SUPERIOR                                    = 0xC0190033
-STATUS_FILE_IDENTITY_NOT_PERSISTENT                               = 0xC0190036
-STATUS_CANT_BREAK_TRANSACTIONAL_DEPENDENCY                        = 0xC0190037
-STATUS_CANT_CROSS_RM_BOUNDARY                                     = 0xC0190038
-STATUS_TXF_DIR_NOT_EMPTY                                          = 0xC0190039
-STATUS_INDOUBT_TRANSACTIONS_EXIST                                 = 0xC019003A
-STATUS_TM_VOLATILE                                                = 0xC019003B
-STATUS_ROLLBACK_TIMER_EXPIRED                                     = 0xC019003C
-STATUS_TXF_ATTRIBUTE_CORRUPT                                      = 0xC019003D
-STATUS_EFS_NOT_ALLOWED_IN_TRANSACTION                             = 0xC019003E
-STATUS_TRANSACTIONAL_OPEN_NOT_ALLOWED                             = 0xC019003F
-STATUS_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE                      = 0xC0190040
-STATUS_TRANSACTION_REQUIRED_PROMOTION                             = 0xC0190043
-STATUS_CANNOT_EXECUTE_FILE_IN_TRANSACTION                         = 0xC0190044
-STATUS_TRANSACTIONS_NOT_FROZEN                                    = 0xC0190045
-STATUS_TRANSACTION_FREEZE_IN_PROGRESS                             = 0xC0190046
-STATUS_NOT_SNAPSHOT_VOLUME                                        = 0xC0190047
-STATUS_NO_SAVEPOINT_WITH_OPEN_FILES                               = 0xC0190048
-STATUS_SPARSE_NOT_ALLOWED_IN_TRANSACTION                          = 0xC0190049
-STATUS_TM_IDENTITY_MISMATCH                                       = 0xC019004A
-STATUS_FLOATED_SECTION                                            = 0xC019004B
-STATUS_CANNOT_ACCEPT_TRANSACTED_WORK                              = 0xC019004C
-STATUS_CANNOT_ABORT_TRANSACTIONS                                  = 0xC019004D
-STATUS_TRANSACTION_NOT_FOUND                                      = 0xC019004E
-STATUS_RESOURCEMANAGER_NOT_FOUND                                  = 0xC019004F
-STATUS_ENLISTMENT_NOT_FOUND                                       = 0xC0190050
-STATUS_TRANSACTIONMANAGER_NOT_FOUND                               = 0xC0190051
-STATUS_TRANSACTIONMANAGER_NOT_ONLINE                              = 0xC0190052
-STATUS_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION                 = 0xC0190053
-STATUS_TRANSACTION_NOT_ROOT                                       = 0xC0190054
-STATUS_TRANSACTION_OBJECT_EXPIRED                                 = 0xC0190055
-STATUS_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION                     = 0xC0190056
-STATUS_TRANSACTION_RESPONSE_NOT_ENLISTED                          = 0xC0190057
-STATUS_TRANSACTION_RECORD_TOO_LONG                                = 0xC0190058
-STATUS_NO_LINK_TRACKING_IN_TRANSACTION                            = 0xC0190059
-STATUS_OPERATION_NOT_SUPPORTED_IN_TRANSACTION                     = 0xC019005A
-STATUS_TRANSACTION_INTEGRITY_VIOLATED                             = 0xC019005B
-STATUS_EXPIRED_HANDLE                                             = 0xC0190060
-STATUS_TRANSACTION_NOT_ENLISTED                                   = 0xC0190061
-STATUS_LOG_SECTOR_INVALID                                         = 0xC01A0001
-STATUS_LOG_SECTOR_PARITY_INVALID                                  = 0xC01A0002
-STATUS_LOG_SECTOR_REMAPPED                                        = 0xC01A0003
-STATUS_LOG_BLOCK_INCOMPLETE                                       = 0xC01A0004
-STATUS_LOG_INVALID_RANGE                                          = 0xC01A0005
-STATUS_LOG_BLOCKS_EXHAUSTED                                       = 0xC01A0006
-STATUS_LOG_READ_CONTEXT_INVALID                                   = 0xC01A0007
-STATUS_LOG_RESTART_INVALID                                        = 0xC01A0008
-STATUS_LOG_BLOCK_VERSION                                          = 0xC01A0009
-STATUS_LOG_BLOCK_INVALID                                          = 0xC01A000A
-STATUS_LOG_READ_MODE_INVALID                                      = 0xC01A000B
-STATUS_LOG_METADATA_CORRUPT                                       = 0xC01A000D
-STATUS_LOG_METADATA_INVALID                                       = 0xC01A000E
-STATUS_LOG_METADATA_INCONSISTENT                                  = 0xC01A000F
-STATUS_LOG_RESERVATION_INVALID                                    = 0xC01A0010
-STATUS_LOG_CANT_DELETE                                            = 0xC01A0011
-STATUS_LOG_CONTAINER_LIMIT_EXCEEDED                               = 0xC01A0012
-STATUS_LOG_START_OF_LOG                                           = 0xC01A0013
-STATUS_LOG_POLICY_ALREADY_INSTALLED                               = 0xC01A0014
-STATUS_LOG_POLICY_NOT_INSTALLED                                   = 0xC01A0015
-STATUS_LOG_POLICY_INVALID                                         = 0xC01A0016
-STATUS_LOG_POLICY_CONFLICT                                        = 0xC01A0017
-STATUS_LOG_PINNED_ARCHIVE_TAIL                                    = 0xC01A0018
-STATUS_LOG_RECORD_NONEXISTENT                                     = 0xC01A0019
-STATUS_LOG_RECORDS_RESERVED_INVALID                               = 0xC01A001A
-STATUS_LOG_SPACE_RESERVED_INVALID                                 = 0xC01A001B
-STATUS_LOG_TAIL_INVALID                                           = 0xC01A001C
-STATUS_LOG_FULL                                                   = 0xC01A001D
-STATUS_LOG_MULTIPLEXED                                            = 0xC01A001E
-STATUS_LOG_DEDICATED                                              = 0xC01A001F
-STATUS_LOG_ARCHIVE_NOT_IN_PROGRESS                                = 0xC01A0020
-STATUS_LOG_ARCHIVE_IN_PROGRESS                                    = 0xC01A0021
-STATUS_LOG_EPHEMERAL                                              = 0xC01A0022
-STATUS_LOG_NOT_ENOUGH_CONTAINERS                                  = 0xC01A0023
-STATUS_LOG_CLIENT_ALREADY_REGISTERED                              = 0xC01A0024
-STATUS_LOG_CLIENT_NOT_REGISTERED                                  = 0xC01A0025
-STATUS_LOG_FULL_HANDLER_IN_PROGRESS                               = 0xC01A0026
-STATUS_LOG_CONTAINER_READ_FAILED                                  = 0xC01A0027
-STATUS_LOG_CONTAINER_WRITE_FAILED                                 = 0xC01A0028
-STATUS_LOG_CONTAINER_OPEN_FAILED                                  = 0xC01A0029
-STATUS_LOG_CONTAINER_STATE_INVALID                                = 0xC01A002A
-STATUS_LOG_STATE_INVALID                                          = 0xC01A002B
-STATUS_LOG_PINNED                                                 = 0xC01A002C
-STATUS_LOG_METADATA_FLUSH_FAILED                                  = 0xC01A002D
-STATUS_LOG_INCONSISTENT_SECURITY                                  = 0xC01A002E
-STATUS_LOG_APPENDED_FLUSH_FAILED                                  = 0xC01A002F
-STATUS_LOG_PINNED_RESERVATION                                     = 0xC01A0030
-STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD                           = 0xC01B00EA
-STATUS_FLT_NO_HANDLER_DEFINED                                     = 0xC01C0001
-STATUS_FLT_CONTEXT_ALREADY_DEFINED                                = 0xC01C0002
-STATUS_FLT_INVALID_ASYNCHRONOUS_REQUEST                           = 0xC01C0003
-STATUS_FLT_DISALLOW_FAST_IO                                       = 0xC01C0004
-STATUS_FLT_INVALID_NAME_REQUEST                                   = 0xC01C0005
-STATUS_FLT_NOT_SAFE_TO_POST_OPERATION                             = 0xC01C0006
-STATUS_FLT_NOT_INITIALIZED                                        = 0xC01C0007
-STATUS_FLT_FILTER_NOT_READY                                       = 0xC01C0008
-STATUS_FLT_POST_OPERATION_CLEANUP                                 = 0xC01C0009
-STATUS_FLT_INTERNAL_ERROR                                         = 0xC01C000A
-STATUS_FLT_DELETING_OBJECT                                        = 0xC01C000B
-STATUS_FLT_MUST_BE_NONPAGED_POOL                                  = 0xC01C000C
-STATUS_FLT_DUPLICATE_ENTRY                                        = 0xC01C000D
-STATUS_FLT_CBDQ_DISABLED                                          = 0xC01C000E
-STATUS_FLT_DO_NOT_ATTACH                                          = 0xC01C000F
-STATUS_FLT_DO_NOT_DETACH                                          = 0xC01C0010
-STATUS_FLT_INSTANCE_ALTITUDE_COLLISION                            = 0xC01C0011
-STATUS_FLT_INSTANCE_NAME_COLLISION                                = 0xC01C0012
-STATUS_FLT_FILTER_NOT_FOUND                                       = 0xC01C0013
-STATUS_FLT_VOLUME_NOT_FOUND                                       = 0xC01C0014
-STATUS_FLT_INSTANCE_NOT_FOUND                                     = 0xC01C0015
-STATUS_FLT_CONTEXT_ALLOCATION_NOT_FOUND                           = 0xC01C0016
-STATUS_FLT_INVALID_CONTEXT_REGISTRATION                           = 0xC01C0017
-STATUS_FLT_NAME_CACHE_MISS                                        = 0xC01C0018
-STATUS_FLT_NO_DEVICE_OBJECT                                       = 0xC01C0019
-STATUS_FLT_VOLUME_ALREADY_MOUNTED                                 = 0xC01C001A
-STATUS_FLT_ALREADY_ENLISTED                                       = 0xC01C001B
-STATUS_FLT_CONTEXT_ALREADY_LINKED                                 = 0xC01C001C
-STATUS_FLT_NO_WAITER_FOR_REPLY                                    = 0xC01C0020
-STATUS_MONITOR_NO_DESCRIPTOR                                      = 0xC01D0001
-STATUS_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT                          = 0xC01D0002
-STATUS_MONITOR_INVALID_DESCRIPTOR_CHECKSUM                        = 0xC01D0003
-STATUS_MONITOR_INVALID_STANDARD_TIMING_BLOCK                      = 0xC01D0004
-STATUS_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED                  = 0xC01D0005
-STATUS_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK                 = 0xC01D0006
-STATUS_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK                 = 0xC01D0007
-STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA                            = 0xC01D0008
-STATUS_MONITOR_INVALID_DETAILED_TIMING_BLOCK                      = 0xC01D0009
-STATUS_MONITOR_INVALID_MANUFACTURE_DATE                           = 0xC01D000A
-STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER                          = 0xC01E0000
-STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER                           = 0xC01E0001
-STATUS_GRAPHICS_INVALID_DISPLAY_ADAPTER                           = 0xC01E0002
-STATUS_GRAPHICS_ADAPTER_WAS_RESET                                 = 0xC01E0003
-STATUS_GRAPHICS_INVALID_DRIVER_MODEL                              = 0xC01E0004
-STATUS_GRAPHICS_PRESENT_MODE_CHANGED                              = 0xC01E0005
-STATUS_GRAPHICS_PRESENT_OCCLUDED                                  = 0xC01E0006
-STATUS_GRAPHICS_PRESENT_DENIED                                    = 0xC01E0007
-STATUS_GRAPHICS_CANNOTCOLORCONVERT                                = 0xC01E0008
-STATUS_GRAPHICS_PRESENT_REDIRECTION_DISABLED                      = 0xC01E000B
-STATUS_GRAPHICS_PRESENT_UNOCCLUDED                                = 0xC01E000C
-STATUS_GRAPHICS_NO_VIDEO_MEMORY                                   = 0xC01E0100
-STATUS_GRAPHICS_CANT_LOCK_MEMORY                                  = 0xC01E0101
-STATUS_GRAPHICS_ALLOCATION_BUSY                                   = 0xC01E0102
-STATUS_GRAPHICS_TOO_MANY_REFERENCES                               = 0xC01E0103
-STATUS_GRAPHICS_TRY_AGAIN_LATER                                   = 0xC01E0104
-STATUS_GRAPHICS_TRY_AGAIN_NOW                                     = 0xC01E0105
-STATUS_GRAPHICS_ALLOCATION_INVALID                                = 0xC01E0106
-STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE                  = 0xC01E0107
-STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED                  = 0xC01E0108
-STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION                      = 0xC01E0109
-STATUS_GRAPHICS_INVALID_ALLOCATION_USAGE                          = 0xC01E0110
-STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION                     = 0xC01E0111
-STATUS_GRAPHICS_ALLOCATION_CLOSED                                 = 0xC01E0112
-STATUS_GRAPHICS_INVALID_ALLOCATION_INSTANCE                       = 0xC01E0113
-STATUS_GRAPHICS_INVALID_ALLOCATION_HANDLE                         = 0xC01E0114
-STATUS_GRAPHICS_WRONG_ALLOCATION_DEVICE                           = 0xC01E0115
-STATUS_GRAPHICS_ALLOCATION_CONTENT_LOST                           = 0xC01E0116
-STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE                           = 0xC01E0200
-STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY                            = 0xC01E0300
-STATUS_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED                      = 0xC01E0301
-STATUS_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED            = 0xC01E0302
-STATUS_GRAPHICS_INVALID_VIDPN                                     = 0xC01E0303
-STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE                      = 0xC01E0304
-STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET                      = 0xC01E0305
-STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED                      = 0xC01E0306
-STATUS_GRAPHICS_INVALID_VIDPN_SOURCEMODESET                       = 0xC01E0308
-STATUS_GRAPHICS_INVALID_VIDPN_TARGETMODESET                       = 0xC01E0309
-STATUS_GRAPHICS_INVALID_FREQUENCY                                 = 0xC01E030A
-STATUS_GRAPHICS_INVALID_ACTIVE_REGION                             = 0xC01E030B
-STATUS_GRAPHICS_INVALID_TOTAL_REGION                              = 0xC01E030C
-STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE                 = 0xC01E0310
-STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE                 = 0xC01E0311
-STATUS_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET                    = 0xC01E0312
-STATUS_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY                          = 0xC01E0313
-STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET                           = 0xC01E0314
-STATUS_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET                     = 0xC01E0315
-STATUS_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET                     = 0xC01E0316
-STATUS_GRAPHICS_SOURCE_ALREADY_IN_SET                             = 0xC01E0317
-STATUS_GRAPHICS_TARGET_ALREADY_IN_SET                             = 0xC01E0318
-STATUS_GRAPHICS_INVALID_VIDPN_PRESENT_PATH                        = 0xC01E0319
-STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY                     = 0xC01E031A
-STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET                 = 0xC01E031B
-STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE                    = 0xC01E031C
-STATUS_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET                         = 0xC01E031D
-STATUS_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET                     = 0xC01E031F
-STATUS_GRAPHICS_STALE_MODESET                                     = 0xC01E0320
-STATUS_GRAPHICS_INVALID_MONITOR_SOURCEMODESET                     = 0xC01E0321
-STATUS_GRAPHICS_INVALID_MONITOR_SOURCE_MODE                       = 0xC01E0322
-STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN                   = 0xC01E0323
-STATUS_GRAPHICS_MODE_ID_MUST_BE_UNIQUE                            = 0xC01E0324
-STATUS_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION   = 0xC01E0325
-STATUS_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES           = 0xC01E0326
-STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY                              = 0xC01E0327
-STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE             = 0xC01E0328
-STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET             = 0xC01E0329
-STATUS_GRAPHICS_INVALID_MONITORDESCRIPTORSET                      = 0xC01E032A
-STATUS_GRAPHICS_INVALID_MONITORDESCRIPTOR                         = 0xC01E032B
-STATUS_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET                      = 0xC01E032C
-STATUS_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET                  = 0xC01E032D
-STATUS_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE               = 0xC01E032E
-STATUS_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE                  = 0xC01E032F
-STATUS_GRAPHICS_RESOURCES_NOT_RELATED                             = 0xC01E0330
-STATUS_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE                          = 0xC01E0331
-STATUS_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE                          = 0xC01E0332
-STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET                         = 0xC01E0333
-STATUS_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER      = 0xC01E0334
-STATUS_GRAPHICS_NO_VIDPNMGR                                       = 0xC01E0335
-STATUS_GRAPHICS_NO_ACTIVE_VIDPN                                   = 0xC01E0336
-STATUS_GRAPHICS_STALE_VIDPN_TOPOLOGY                              = 0xC01E0337
-STATUS_GRAPHICS_MONITOR_NOT_CONNECTED                             = 0xC01E0338
-STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY                            = 0xC01E0339
-STATUS_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE                       = 0xC01E033A
-STATUS_GRAPHICS_INVALID_VISIBLEREGION_SIZE                        = 0xC01E033B
-STATUS_GRAPHICS_INVALID_STRIDE                                    = 0xC01E033C
-STATUS_GRAPHICS_INVALID_PIXELFORMAT                               = 0xC01E033D
-STATUS_GRAPHICS_INVALID_COLORBASIS                                = 0xC01E033E
-STATUS_GRAPHICS_INVALID_PIXELVALUEACCESSMODE                      = 0xC01E033F
-STATUS_GRAPHICS_TARGET_NOT_IN_TOPOLOGY                            = 0xC01E0340
-STATUS_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT                = 0xC01E0341
-STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE                               = 0xC01E0342
-STATUS_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN                          = 0xC01E0343
-STATUS_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL                   = 0xC01E0344
-STATUS_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION      = 0xC01E0345
-STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED = 0xC01E0346
-STATUS_GRAPHICS_INVALID_GAMMA_RAMP                                = 0xC01E0347
-STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED                          = 0xC01E0348
-STATUS_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED                       = 0xC01E0349
-STATUS_GRAPHICS_MODE_NOT_IN_MODESET                               = 0xC01E034A
-STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON      = 0xC01E034D
-STATUS_GRAPHICS_INVALID_PATH_CONTENT_TYPE                         = 0xC01E034E
-STATUS_GRAPHICS_INVALID_COPYPROTECTION_TYPE                       = 0xC01E034F
-STATUS_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS                 = 0xC01E0350
-STATUS_GRAPHICS_INVALID_SCANLINE_ORDERING                         = 0xC01E0352
-STATUS_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED                      = 0xC01E0353
-STATUS_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS                  = 0xC01E0354
-STATUS_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT                       = 0xC01E0355
-STATUS_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM                    = 0xC01E0356
-STATUS_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN                 = 0xC01E0357
-STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT         = 0xC01E0358
-STATUS_GRAPHICS_MAX_NUM_PATHS_REACHED                             = 0xC01E0359
-STATUS_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION                = 0xC01E035A
-STATUS_GRAPHICS_INVALID_CLIENT_TYPE                               = 0xC01E035B
-STATUS_GRAPHICS_CLIENTVIDPN_NOT_SET                               = 0xC01E035C
-STATUS_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED                 = 0xC01E0400
-STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED                    = 0xC01E0401
-STATUS_GRAPHICS_NOT_A_LINKED_ADAPTER                              = 0xC01E0430
-STATUS_GRAPHICS_LEADLINK_NOT_ENUMERATED                           = 0xC01E0431
-STATUS_GRAPHICS_CHAINLINKS_NOT_ENUMERATED                         = 0xC01E0432
-STATUS_GRAPHICS_ADAPTER_CHAIN_NOT_READY                           = 0xC01E0433
-STATUS_GRAPHICS_CHAINLINKS_NOT_STARTED                            = 0xC01E0434
-STATUS_GRAPHICS_CHAINLINKS_NOT_POWERED_ON                         = 0xC01E0435
-STATUS_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE                    = 0xC01E0436
-STATUS_GRAPHICS_NOT_POST_DEVICE_DRIVER                            = 0xC01E0438
-STATUS_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED                       = 0xC01E043B
-STATUS_GRAPHICS_OPM_NOT_SUPPORTED                                 = 0xC01E0500
-STATUS_GRAPHICS_COPP_NOT_SUPPORTED                                = 0xC01E0501
-STATUS_GRAPHICS_UAB_NOT_SUPPORTED                                 = 0xC01E0502
-STATUS_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS                  = 0xC01E0503
-STATUS_GRAPHICS_OPM_PARAMETER_ARRAY_TOO_SMALL                     = 0xC01E0504
-STATUS_GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST                    = 0xC01E0505
-STATUS_GRAPHICS_PVP_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME         = 0xC01E0506
-STATUS_GRAPHICS_PVP_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP        = 0xC01E0507
-STATUS_GRAPHICS_PVP_MIRRORING_DEVICES_NOT_SUPPORTED               = 0xC01E0508
-STATUS_GRAPHICS_OPM_INVALID_POINTER                               = 0xC01E050A
-STATUS_GRAPHICS_OPM_INTERNAL_ERROR                                = 0xC01E050B
-STATUS_GRAPHICS_OPM_INVALID_HANDLE                                = 0xC01E050C
-STATUS_GRAPHICS_PVP_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE      = 0xC01E050D
-STATUS_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH                    = 0xC01E050E
-STATUS_GRAPHICS_OPM_SPANNING_MODE_ENABLED                         = 0xC01E050F
-STATUS_GRAPHICS_OPM_THEATER_MODE_ENABLED                          = 0xC01E0510
-STATUS_GRAPHICS_PVP_HFS_FAILED                                    = 0xC01E0511
-STATUS_GRAPHICS_OPM_INVALID_SRM                                   = 0xC01E0512
-STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP                  = 0xC01E0513
-STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP                   = 0xC01E0514
-STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA                 = 0xC01E0515
-STATUS_GRAPHICS_OPM_HDCP_SRM_NEVER_SET                            = 0xC01E0516
-STATUS_GRAPHICS_OPM_RESOLUTION_TOO_HIGH                           = 0xC01E0517
-STATUS_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE              = 0xC01E0518
-STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS             = 0xC01E051A
-STATUS_GRAPHICS_OPM_SESSION_TYPE_CHANGE_IN_PROGRESS               = 0xC01E051B
-STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS = 0xC01E051C
-STATUS_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST                   = 0xC01E051D
-STATUS_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR                         = 0xC01E051E
-STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS  = 0xC01E051F
-STATUS_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED                       = 0xC01E0520
-STATUS_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST                 = 0xC01E0521
-STATUS_GRAPHICS_I2C_NOT_SUPPORTED                                 = 0xC01E0580
-STATUS_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST                         = 0xC01E0581
-STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA                       = 0xC01E0582
-STATUS_GRAPHICS_I2C_ERROR_RECEIVING_DATA                          = 0xC01E0583
-STATUS_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED                           = 0xC01E0584
-STATUS_GRAPHICS_DDCCI_INVALID_DATA                                = 0xC01E0585
-STATUS_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE = 0xC01E0586
-STATUS_GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING                 = 0xC01E0587
-STATUS_GRAPHICS_MCA_INTERNAL_ERROR                                = 0xC01E0588
-STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND                     = 0xC01E0589
-STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH                      = 0xC01E058A
-STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM                    = 0xC01E058B
-STATUS_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE                   = 0xC01E058C
-STATUS_GRAPHICS_MONITOR_NO_LONGER_EXISTS                          = 0xC01E058D
-STATUS_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED                    = 0xC01E05E0
-STATUS_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME             = 0xC01E05E1
-STATUS_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP            = 0xC01E05E2
-STATUS_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED                   = 0xC01E05E3
-STATUS_GRAPHICS_INVALID_POINTER                                   = 0xC01E05E4
-STATUS_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE          = 0xC01E05E5
-STATUS_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL                         = 0xC01E05E6
-STATUS_GRAPHICS_INTERNAL_ERROR                                    = 0xC01E05E7
-STATUS_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS                   = 0xC01E05E8
-STATUS_FVE_LOCKED_VOLUME                                          = 0xC0210000
-STATUS_FVE_NOT_ENCRYPTED                                          = 0xC0210001
-STATUS_FVE_BAD_INFORMATION                                        = 0xC0210002
-STATUS_FVE_TOO_SMALL                                              = 0xC0210003
-STATUS_FVE_FAILED_WRONG_FS                                        = 0xC0210004
-STATUS_FVE_FAILED_BAD_FS                                          = 0xC0210005
-STATUS_FVE_FS_NOT_EXTENDED                                        = 0xC0210006
-STATUS_FVE_FS_MOUNTED                                             = 0xC0210007
-STATUS_FVE_NO_LICENSE                                             = 0xC0210008
-STATUS_FVE_ACTION_NOT_ALLOWED                                     = 0xC0210009
-STATUS_FVE_BAD_DATA                                               = 0xC021000A
-STATUS_FVE_VOLUME_NOT_BOUND                                       = 0xC021000B
-STATUS_FVE_NOT_DATA_VOLUME                                        = 0xC021000C
-STATUS_FVE_CONV_READ_ERROR                                        = 0xC021000D
-STATUS_FVE_CONV_WRITE_ERROR                                       = 0xC021000E
-STATUS_FVE_OVERLAPPED_UPDATE                                      = 0xC021000F
-STATUS_FVE_FAILED_SECTOR_SIZE                                     = 0xC0210010
-STATUS_FVE_FAILED_AUTHENTICATION                                  = 0xC0210011
-STATUS_FVE_NOT_OS_VOLUME                                          = 0xC0210012
-STATUS_FVE_KEYFILE_NOT_FOUND                                      = 0xC0210013
-STATUS_FVE_KEYFILE_INVALID                                        = 0xC0210014
-STATUS_FVE_KEYFILE_NO_VMK                                         = 0xC0210015
-STATUS_FVE_TPM_DISABLED                                           = 0xC0210016
-STATUS_FVE_TPM_SRK_AUTH_NOT_ZERO                                  = 0xC0210017
-STATUS_FVE_TPM_INVALID_PCR                                        = 0xC0210018
-STATUS_FVE_TPM_NO_VMK                                             = 0xC0210019
-STATUS_FVE_PIN_INVALID                                            = 0xC021001A
-STATUS_FVE_AUTH_INVALID_APPLICATION                               = 0xC021001B
-STATUS_FVE_AUTH_INVALID_CONFIG                                    = 0xC021001C
-STATUS_FVE_DEBUGGER_ENABLED                                       = 0xC021001D
-STATUS_FVE_DRY_RUN_FAILED                                         = 0xC021001E
-STATUS_FVE_BAD_METADATA_POINTER                                   = 0xC021001F
-STATUS_FVE_OLD_METADATA_COPY                                      = 0xC0210020
-STATUS_FVE_REBOOT_REQUIRED                                        = 0xC0210021
-STATUS_FVE_RAW_ACCESS                                             = 0xC0210022
-STATUS_FVE_RAW_BLOCKED                                            = 0xC0210023
-STATUS_FVE_NO_FEATURE_LICENSE                                     = 0xC0210026
-STATUS_FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED                    = 0xC0210027
-STATUS_FVE_CONV_RECOVERY_FAILED                                   = 0xC0210028
-STATUS_FVE_VIRTUALIZED_SPACE_TOO_BIG                              = 0xC0210029
-STATUS_FVE_VOLUME_TOO_SMALL                                       = 0xC0210030
-STATUS_FWP_CALLOUT_NOT_FOUND                                      = 0xC0220001
-STATUS_FWP_CONDITION_NOT_FOUND                                    = 0xC0220002
-STATUS_FWP_FILTER_NOT_FOUND                                       = 0xC0220003
-STATUS_FWP_LAYER_NOT_FOUND                                        = 0xC0220004
-STATUS_FWP_PROVIDER_NOT_FOUND                                     = 0xC0220005
-STATUS_FWP_PROVIDER_CONTEXT_NOT_FOUND                             = 0xC0220006
-STATUS_FWP_SUBLAYER_NOT_FOUND                                     = 0xC0220007
-STATUS_FWP_NOT_FOUND                                              = 0xC0220008
-STATUS_FWP_ALREADY_EXISTS                                         = 0xC0220009
-STATUS_FWP_IN_USE                                                 = 0xC022000A
-STATUS_FWP_DYNAMIC_SESSION_IN_PROGRESS                            = 0xC022000B
-STATUS_FWP_WRONG_SESSION                                          = 0xC022000C
-STATUS_FWP_NO_TXN_IN_PROGRESS                                     = 0xC022000D
-STATUS_FWP_TXN_IN_PROGRESS                                        = 0xC022000E
-STATUS_FWP_TXN_ABORTED                                            = 0xC022000F
-STATUS_FWP_SESSION_ABORTED                                        = 0xC0220010
-STATUS_FWP_INCOMPATIBLE_TXN                                       = 0xC0220011
-STATUS_FWP_TIMEOUT                                                = 0xC0220012
-STATUS_FWP_NET_EVENTS_DISABLED                                    = 0xC0220013
-STATUS_FWP_INCOMPATIBLE_LAYER                                     = 0xC0220014
-STATUS_FWP_KM_CLIENTS_ONLY                                        = 0xC0220015
-STATUS_FWP_LIFETIME_MISMATCH                                      = 0xC0220016
-STATUS_FWP_BUILTIN_OBJECT                                         = 0xC0220017
-STATUS_FWP_TOO_MANY_BOOTTIME_FILTERS                              = 0xC0220018
-STATUS_FWP_TOO_MANY_CALLOUTS                                      = 0xC0220018
-STATUS_FWP_NOTIFICATION_DROPPED                                   = 0xC0220019
-STATUS_FWP_TRAFFIC_MISMATCH                                       = 0xC022001A
-STATUS_FWP_INCOMPATIBLE_SA_STATE                                  = 0xC022001B
-STATUS_FWP_NULL_POINTER                                           = 0xC022001C
-STATUS_FWP_INVALID_ENUMERATOR                                     = 0xC022001D
-STATUS_FWP_INVALID_FLAGS                                          = 0xC022001E
-STATUS_FWP_INVALID_NET_MASK                                       = 0xC022001F
-STATUS_FWP_INVALID_RANGE                                          = 0xC0220020
-STATUS_FWP_INVALID_INTERVAL                                       = 0xC0220021
-STATUS_FWP_ZERO_LENGTH_ARRAY                                      = 0xC0220022
-STATUS_FWP_NULL_DISPLAY_NAME                                      = 0xC0220023
-STATUS_FWP_INVALID_ACTION_TYPE                                    = 0xC0220024
-STATUS_FWP_INVALID_WEIGHT                                         = 0xC0220025
-STATUS_FWP_MATCH_TYPE_MISMATCH                                    = 0xC0220026
-STATUS_FWP_TYPE_MISMATCH                                          = 0xC0220027
-STATUS_FWP_OUT_OF_BOUNDS                                          = 0xC0220028
-STATUS_FWP_RESERVED                                               = 0xC0220029
-STATUS_FWP_DUPLICATE_CONDITION                                    = 0xC022002A
-STATUS_FWP_DUPLICATE_KEYMOD                                       = 0xC022002B
-STATUS_FWP_ACTION_INCOMPATIBLE_WITH_LAYER                         = 0xC022002C
-STATUS_FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER                      = 0xC022002D
-STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER                        = 0xC022002E
-STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT                      = 0xC022002F
-STATUS_FWP_INCOMPATIBLE_AUTH_METHOD                               = 0xC0220030
-STATUS_FWP_INCOMPATIBLE_DH_GROUP                                  = 0xC0220031
-STATUS_FWP_EM_NOT_SUPPORTED                                       = 0xC0220032
-STATUS_FWP_NEVER_MATCH                                            = 0xC0220033
-STATUS_FWP_PROVIDER_CONTEXT_MISMATCH                              = 0xC0220034
-STATUS_FWP_INVALID_PARAMETER                                      = 0xC0220035
-STATUS_FWP_TOO_MANY_SUBLAYERS                                     = 0xC0220036
-STATUS_FWP_CALLOUT_NOTIFICATION_FAILED                            = 0xC0220037
-STATUS_FWP_INCOMPATIBLE_AUTH_CONFIG                               = 0xC0220038
-STATUS_FWP_INCOMPATIBLE_CIPHER_CONFIG                             = 0xC0220039
-STATUS_FWP_DUPLICATE_AUTH_METHOD                                  = 0xC022003C
-STATUS_FWP_TCPIP_NOT_READY                                        = 0xC0220100
-STATUS_FWP_INJECT_HANDLE_CLOSING                                  = 0xC0220101
-STATUS_FWP_INJECT_HANDLE_STALE                                    = 0xC0220102
-STATUS_FWP_CANNOT_PEND                                            = 0xC0220103
-STATUS_NDIS_CLOSING                                               = 0xC0230002
-STATUS_NDIS_BAD_VERSION                                           = 0xC0230004
-STATUS_NDIS_BAD_CHARACTERISTICS                                   = 0xC0230005
-STATUS_NDIS_ADAPTER_NOT_FOUND                                     = 0xC0230006
-STATUS_NDIS_OPEN_FAILED                                           = 0xC0230007
-STATUS_NDIS_DEVICE_FAILED                                         = 0xC0230008
-STATUS_NDIS_MULTICAST_FULL                                        = 0xC0230009
-STATUS_NDIS_MULTICAST_EXISTS                                      = 0xC023000A
-STATUS_NDIS_MULTICAST_NOT_FOUND                                   = 0xC023000B
-STATUS_NDIS_REQUEST_ABORTED                                       = 0xC023000C
-STATUS_NDIS_RESET_IN_PROGRESS                                     = 0xC023000D
-STATUS_NDIS_INVALID_PACKET                                        = 0xC023000F
-STATUS_NDIS_INVALID_DEVICE_REQUEST                                = 0xC0230010
-STATUS_NDIS_ADAPTER_NOT_READY                                     = 0xC0230011
-STATUS_NDIS_INVALID_LENGTH                                        = 0xC0230014
-STATUS_NDIS_INVALID_DATA                                          = 0xC0230015
-STATUS_NDIS_BUFFER_TOO_SHORT                                      = 0xC0230016
-STATUS_NDIS_INVALID_OID                                           = 0xC0230017
-STATUS_NDIS_ADAPTER_REMOVED                                       = 0xC0230018
-STATUS_NDIS_UNSUPPORTED_MEDIA                                     = 0xC0230019
-STATUS_NDIS_GROUP_ADDRESS_IN_USE                                  = 0xC023001A
-STATUS_NDIS_FILE_NOT_FOUND                                        = 0xC023001B
-STATUS_NDIS_ERROR_READING_FILE                                    = 0xC023001C
-STATUS_NDIS_ALREADY_MAPPED                                        = 0xC023001D
-STATUS_NDIS_RESOURCE_CONFLICT                                     = 0xC023001E
-STATUS_NDIS_MEDIA_DISCONNECTED                                    = 0xC023001F
-STATUS_NDIS_INVALID_ADDRESS                                       = 0xC0230022
-STATUS_NDIS_PAUSED                                                = 0xC023002A
-STATUS_NDIS_INTERFACE_NOT_FOUND                                   = 0xC023002B
-STATUS_NDIS_UNSUPPORTED_REVISION                                  = 0xC023002C
-STATUS_NDIS_INVALID_PORT                                          = 0xC023002D
-STATUS_NDIS_INVALID_PORT_STATE                                    = 0xC023002E
-STATUS_NDIS_LOW_POWER_STATE                                       = 0xC023002F
-STATUS_NDIS_NOT_SUPPORTED                                         = 0xC02300BB
-STATUS_NDIS_OFFLOAD_POLICY                                        = 0xC023100F
-STATUS_NDIS_OFFLOAD_CONNECTION_REJECTED                           = 0xC0231012
-STATUS_NDIS_OFFLOAD_PATH_REJECTED                                 = 0xC0231013
-STATUS_NDIS_DOT11_AUTO_CONFIG_ENABLED                             = 0xC0232000
-STATUS_NDIS_DOT11_MEDIA_IN_USE                                    = 0xC0232001
-STATUS_NDIS_DOT11_POWER_STATE_INVALID                             = 0xC0232002
-STATUS_NDIS_PM_WOL_PATTERN_LIST_FULL                              = 0xC0232003
-STATUS_NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL                         = 0xC0232004
-STATUS_IPSEC_BAD_SPI                                              = 0xC0360001
-STATUS_IPSEC_SA_LIFETIME_EXPIRED                                  = 0xC0360002
-STATUS_IPSEC_WRONG_SA                                             = 0xC0360003
-STATUS_IPSEC_REPLAY_CHECK_FAILED                                  = 0xC0360004
-STATUS_IPSEC_INVALID_PACKET                                       = 0xC0360005
-STATUS_IPSEC_INTEGRITY_CHECK_FAILED                               = 0xC0360006
-STATUS_IPSEC_CLEAR_TEXT_DROP                                      = 0xC0360007
-STATUS_IPSEC_AUTH_FIREWALL_DROP                                   = 0xC0360008
-STATUS_IPSEC_THROTTLE_DROP                                        = 0xC0360009
-STATUS_IPSEC_DOSP_BLOCK                                           = 0xC0368000
-STATUS_IPSEC_DOSP_RECEIVED_MULTICAST                              = 0xC0368001
-STATUS_IPSEC_DOSP_INVALID_PACKET                                  = 0xC0368002
-STATUS_IPSEC_DOSP_STATE_LOOKUP_FAILED                             = 0xC0368003
-STATUS_IPSEC_DOSP_MAX_ENTRIES                                     = 0xC0368004
-STATUS_IPSEC_DOSP_KEYMOD_NOT_ALLOWED                              = 0xC0368005
-STATUS_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES                     = 0xC0368006
-STATUS_VOLMGR_MIRROR_NOT_SUPPORTED                                = 0xC038005B
-STATUS_VOLMGR_RAID5_NOT_SUPPORTED                                 = 0xC038005C
-STATUS_VIRTDISK_PROVIDER_NOT_FOUND                                = 0xC03A0014
-STATUS_VIRTDISK_NOT_VIRTUAL_DISK                                  = 0xC03A0015
-STATUS_VHD_PARENT_VHD_ACCESS_DENIED                               = 0xC03A0016
-STATUS_VHD_CHILD_PARENT_SIZE_MISMATCH                             = 0xC03A0017
-STATUS_VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED                      = 0xC03A0018
-STATUS_VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT                     = 0xC03A0019
diff --git a/tests/python_dependencies/impacket/ntlm.py 
b/tests/python_dependencies/impacket/ntlm.py
deleted file mode 100644
index 8845e9d50..000000000
--- a/tests/python_dependencies/impacket/ntlm.py
+++ /dev/null
@@ -1,973 +0,0 @@
-from __future__ import print_function
-# Copyright (c) 2003-2016 CORE Security Technologies:
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-import base64
-import struct
-import calendar
-import time
-import hashlib
-import random
-import string
-import binascii
-
-from impacket.structure import Structure
-from impacket import LOG
-
-
-# This is important. NTLMv2 is not negotiated by the client or server.
-# It is used if set locally on both sides. Change this item if you don't want 
to use
-# NTLMv2 by default and fall back to NTLMv1 (with EXTENDED_SESSION_SECURITY or 
not)
-# Check the following links:
-# http://davenport.sourceforge.net/ntlm.html
-# 
http://blogs.msdn.com/b/openspecification/archive/2010/04/20/ntlm-keys-and-sundry-stuff.aspx
-# 
http://social.msdn.microsoft.com/Forums/en-US/os_interopscenarios/thread/c8f488ed-1b96-4e06-bd65-390aa41138d1/
-# So I'm setting a global variable to control this, this can also be set 
programmatically
-
-USE_NTLMv2 = True # if false will fall back to NTLMv1 (or NTLMv1 with ESS 
a.k.a NTLM2)
-
-
-def computeResponse(flags, serverChallenge, clientChallenge, serverName, 
domain, user, password, lmhash='', nthash='',
-                    use_ntlmv2=USE_NTLMv2):
-    if use_ntlmv2:
-        return computeResponseNTLMv2(flags, serverChallenge, clientChallenge, 
serverName, domain, user, password,
-                                     lmhash, nthash, use_ntlmv2=use_ntlmv2)
-    else:
-        return computeResponseNTLMv1(flags, serverChallenge, clientChallenge, 
serverName, domain, user, password,
-                                     lmhash, nthash, use_ntlmv2=use_ntlmv2)
-try:
-    POW = None
-    from Crypto.Cipher import ARC4
-    from Crypto.Cipher import DES
-    from Crypto.Hash import MD4
-except Exception:
-    try:
-        import POW
-    except Exception:
-        LOG.critical("Warning: You don't have any crypto installed. You need 
PyCrypto")
-        LOG.critical("See http://www.pycrypto.org/";)
-
-NTLM_AUTH_NONE          = 1
-NTLM_AUTH_CONNECT       = 2
-NTLM_AUTH_CALL          = 3
-NTLM_AUTH_PKT           = 4
-NTLM_AUTH_PKT_INTEGRITY = 5
-NTLM_AUTH_PKT_PRIVACY   = 6
-
-# If set, requests 56-bit encryption. If the client sends 
NTLMSSP_NEGOTIATE_SEAL or NTLMSSP_NEGOTIATE_SIGN
-# with NTLMSSP_NEGOTIATE_56 to the server in the NEGOTIATE_MESSAGE, the server 
MUST return NTLMSSP_NEGOTIATE_56 to
-# the client in the CHALLENGE_MESSAGE. Otherwise it is ignored. If both 
NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128
-# are requested and supported by the client and server, NTLMSSP_NEGOTIATE_56 
and NTLMSSP_NEGOTIATE_128 will both be
-# returned to the client. Clients and servers that set NTLMSSP_NEGOTIATE_SEAL 
SHOULD set NTLMSSP_NEGOTIATE_56 if it is
-# supported. An alternate name for this field is NTLMSSP_NEGOTIATE_56.
-NTLMSSP_NEGOTIATE_56                       = 0x80000000
-
-# If set, requests an explicit key exchange. This capability SHOULD be used 
because it improves security for message
-# integrity or confidentiality. See sections 3.2.5.1.2, 3.2.5.2.1, and 
3.2.5.2.2 for details. An alternate name for
-# this field is NTLMSSP_NEGOTIATE_KEY_EXCH.
-NTLMSSP_NEGOTIATE_KEY_EXCH                 = 0x40000000
-
-# If set, requests 128-bit session key negotiation. An alternate name for this 
field is NTLMSSP_NEGOTIATE_128.
-# If the client sends NTLMSSP_NEGOTIATE_128 to the server in the 
NEGOTIATE_MESSAGE, the server MUST return
-# NTLMSSP_NEGOTIATE_128 to the client in the CHALLENGE_MESSAGE only if the 
client sets NTLMSSP_NEGOTIATE_SEAL or
-# NTLMSSP_NEGOTIATE_SIGN. Otherwise it is ignored. If both 
NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128 are
-# requested and supported by the client and server, NTLMSSP_NEGOTIATE_56 and 
NTLMSSP_NEGOTIATE_128 will both be
-# returned to the client. Clients and servers that set NTLMSSP_NEGOTIATE_SEAL 
SHOULD set NTLMSSP_NEGOTIATE_128 if it
-# is supported. An alternate name for this field is NTLMSSP_NEGOTIATE_128
-NTLMSSP_NEGOTIATE_128                      = 0x20000000
-
-NTLMSSP_RESERVED_1                         = 0x10000000
-NTLMSSP_RESERVED_2                         = 0x08000000
-NTLMSSP_RESERVED_3                         = 0x04000000
-
-# If set, requests the protocol version number. The data corresponding to this 
flag is provided in the Version field
-# of the NEGOTIATE_MESSAGE, the CHALLENGE_MESSAGE, and the 
AUTHENTICATE_MESSAGE.<22> An alternate name for this field
-# is NTLMSSP_NEGOTIATE_VERSION
-NTLMSSP_NEGOTIATE_VERSION                  = 0x02000000
-NTLMSSP_RESERVED_4                         = 0x01000000
-
-# If set, indicates that the TargetInfo fields in the CHALLENGE_MESSAGE 
(section 2.2.1.2) are populated.
-# An alternate name for this field is NTLMSSP_NEGOTIATE_TARGET_INFO.
-NTLMSSP_NEGOTIATE_TARGET_INFO              = 0x00800000
-
-# If set, requests the usage of the LMOWF (section 3.3). An alternate name for 
this field is
-# NTLMSSP_REQUEST_NON_NT_SESSION_KEY.
-NTLMSSP_REQUEST_NON_NT_SESSION_KEY         = 0x00400000
-NTLMSSP_RESERVED_5                         = 0x00200000
-
-# If set, requests an identify level token. An alternate name for this field 
is NTLMSSP_NEGOTIATE_IDENTIFY
-NTLMSSP_NEGOTIATE_IDENTIFY                 = 0x00100000
-
-# If set, requests usage of the NTLM v2 session security. NTLM v2 session 
security is a misnomer because it is not
-# NTLM v2. It is NTLM v1 using the extended session security that is also in 
NTLM v2. NTLMSSP_NEGOTIATE_LM_KEY and
-# NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are mutually exclusive. If both 
NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
-# and NTLMSSP_NEGOTIATE_LM_KEY are requested, 
NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY alone MUST be returned to the
-# client. NTLM v2 authentication session key generation MUST be supported by 
both the client and the DC in order to be
-# used, and extended session security signing and sealing requires support 
from the client and the server in order to
-# be used.<23> An alternate name for this field is 
NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
-NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY = 0x00080000
-NTLMSSP_NEGOTIATE_NTLM2                    = 0x00080000
-NTLMSSP_TARGET_TYPE_SHARE                  = 0x00040000
-
-# If set, TargetName MUST be a server name. The data corresponding to this 
flag is provided by the server in the
-# TargetName field of the CHALLENGE_MESSAGE. If this bit is set, then 
NTLMSSP_TARGET_TYPE_DOMAIN MUST NOT be set.
-# This flag MUST be ignored in the NEGOTIATE_MESSAGE and the 
AUTHENTICATE_MESSAGE. An alternate name for this field
-# is NTLMSSP_TARGET_TYPE_SERVER
-NTLMSSP_TARGET_TYPE_SERVER                 = 0x00020000
-
-# If set, TargetName MUST be a domain name. The data corresponding to this 
flag is provided by the server in the
-# TargetName field of the CHALLENGE_MESSAGE. If set, then 
NTLMSSP_TARGET_TYPE_SERVER MUST NOT be set. This flag MUST
-# be ignored in the NEGOTIATE_MESSAGE and the AUTHENTICATE_MESSAGE. An 
alternate name for this field is
-# NTLMSSP_TARGET_TYPE_DOMAIN.
-NTLMSSP_TARGET_TYPE_DOMAIN                 = 0x00010000
-
-# If set, requests the presence of a signature block on all messages. 
NTLMSSP_NEGOTIATE_ALWAYS_SIGN MUST be set in the
-# NEGOTIATE_MESSAGE to the server and the CHALLENGE_MESSAGE to the client. 
NTLMSSP_NEGOTIATE_ALWAYS_SIGN is overridden
-# by NTLMSSP_NEGOTIATE_SIGN and NTLMSSP_NEGOTIATE_SEAL, if they are supported. 
An alternate name for this field is
-# NTLMSSP_NEGOTIATE_ALWAYS_SIGN.
-NTLMSSP_NEGOTIATE_ALWAYS_SIGN              = 0x00008000       # forces the 
other end to sign packets
-NTLMSSP_RESERVED_6                         = 0x00004000
-
-# This flag indicates whether the Workstation field is present. If this flag 
is not set, the Workstation field MUST be
-# ignored. If this flag is set, the length field of the Workstation field 
specifies whether the workstation name is
-# nonempty or not.<24> An alternate name for this field is 
NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED.
-NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 0x00002000
-
-# If set, the domain name is provided (section 2.2.1.1).<25> An alternate name 
for this field is
-# NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED
-NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED      = 0x00001000
-NTLMSSP_RESERVED_7                         = 0x00000800
-
-
-# If set, LM authentication is not allowed and only NT authentication is used.
-NTLMSSP_NEGOTIATE_NT_ONLY                  = 0x00000400
-
-# If set, requests usage of the NTLM v1 session security protocol. 
NTLMSSP_NEGOTIATE_NTLM MUST be set in the
-# NEGOTIATE_MESSAGE to the server and the CHALLENGE_MESSAGE to the client. An 
alternate name for this field is
-# NTLMSSP_NEGOTIATE_NTLM
-NTLMSSP_NEGOTIATE_NTLM                     = 0x00000200
-NTLMSSP_RESERVED_8                         = 0x00000100
-
-# If set, requests LAN Manager (LM) session key computation. 
NTLMSSP_NEGOTIATE_LM_KEY and
-# NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are mutually exclusive. If both 
NTLMSSP_NEGOTIATE_LM_KEY and
-# NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are requested, 
NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY alone MUST be
-# returned to the client. NTLM v2 authentication session key generation MUST 
be supported by both the client and the
-# DC in order to be used, and extended session security signing and sealing 
requires support from the client and the
-# server to be used. An alternate name for this field is 
NTLMSSP_NEGOTIATE_LM_KEY.
-NTLMSSP_NEGOTIATE_LM_KEY                   = 0x00000080
-
-# If set, requests connectionless authentication. If 
NTLMSSP_NEGOTIATE_DATAGRAM is set, then NTLMSSP_NEGOTIATE_KEY_EXCH
-# MUST always be set in the AUTHENTICATE_MESSAGE to the server and the 
CHALLENGE_MESSAGE to the client. An alternate
-# name for this field is NTLMSSP_NEGOTIATE_DATAGRAM.
-NTLMSSP_NEGOTIATE_DATAGRAM                 = 0x00000040
-
-# If set, requests session key negotiation for message confidentiality. If the 
client sends NTLMSSP_NEGOTIATE_SEAL to
-# the server in the NEGOTIATE_MESSAGE, the server MUST return 
NTLMSSP_NEGOTIATE_SEAL to the client in the
-# CHALLENGE_MESSAGE. Clients and servers that set NTLMSSP_NEGOTIATE_SEAL 
SHOULD always set NTLMSSP_NEGOTIATE_56 and
-# NTLMSSP_NEGOTIATE_128, if they are supported. An alternate name for this 
field is NTLMSSP_NEGOTIATE_SEAL.
-NTLMSSP_NEGOTIATE_SEAL                     = 0x00000020
-
-# If set, requests session key negotiation for message signatures. If the 
client sends NTLMSSP_NEGOTIATE_SIGN to the
-# server in the NEGOTIATE_MESSAGE, the server MUST return 
NTLMSSP_NEGOTIATE_SIGN to the client in the CHALLENGE_MESSAGE.
-# An alternate name for this field is NTLMSSP_NEGOTIATE_SIGN.
-NTLMSSP_NEGOTIATE_SIGN                     = 0x00000010       # means packet 
is signed, if verifier is wrong it fails
-NTLMSSP_RESERVED_9                         = 0x00000008
-
-# If set, a TargetName field of the CHALLENGE_MESSAGE (section 2.2.1.2) MUST 
be supplied. An alternate name for this
-# field is NTLMSSP_REQUEST_TARGET.
-NTLMSSP_REQUEST_TARGET                     = 0x00000004
-
-# If set, requests OEM character set encoding. An alternate name for this 
field is NTLM_NEGOTIATE_OEM. See bit A for
-# details.
-NTLM_NEGOTIATE_OEM                         = 0x00000002
-
-# If set, requests Unicode character set encoding. An alternate name for this 
field is NTLMSSP_NEGOTIATE_UNICODE.
-NTLMSSP_NEGOTIATE_UNICODE                  = 0x00000001
-
-# AV_PAIR constants
-NTLMSSP_AV_EOL              = 0x00
-NTLMSSP_AV_HOSTNAME         = 0x01
-NTLMSSP_AV_DOMAINNAME       = 0x02
-NTLMSSP_AV_DNS_HOSTNAME     = 0x03
-NTLMSSP_AV_DNS_DOMAINNAME   = 0x04
-NTLMSSP_AV_DNS_TREENAME     = 0x05
-NTLMSSP_AV_FLAGS            = 0x06
-NTLMSSP_AV_TIME             = 0x07
-NTLMSSP_AV_RESTRICTIONS     = 0x08
-NTLMSSP_AV_TARGET_NAME      = 0x09
-NTLMSSP_AV_CHANNEL_BINDINGS = 0x0a
-
-class AV_PAIRS():
-    def __init__(self, data = None):
-        self.fields = {}
-        if data is not None:
-            self.fromString(data)
-
-    def __setitem__(self,key,value):
-        self.fields[key] = (len(value),value)
-
-    def __getitem__(self, key):
-        if key in self.fields:
-           return self.fields[key]
-        return None
-
-    def __delitem__(self, key):
-        del self.fields[key]
-
-    def __len__(self):
-        return len(self.getData())
-
-    def __str__(self):
-        return len(self.getData())
-
-    def fromString(self, data):
-        tInfo = data
-        fType = 0xff
-        while fType is not NTLMSSP_AV_EOL:
-            fType = struct.unpack('<H',tInfo[:struct.calcsize('<H')])[0]
-            tInfo = tInfo[struct.calcsize('<H'):]
-            length = struct.unpack('<H',tInfo[:struct.calcsize('<H')])[0]
-            tInfo = tInfo[struct.calcsize('<H'):]
-            content = tInfo[:length]
-            self.fields[fType]=(length,content)
-            tInfo = tInfo[length:]
-
-    def dump(self):
-        for i in self.fields.keys():
-            print("%s: {%r}" % (i,self[i]))
-
-    def getData(self):
-        if NTLMSSP_AV_EOL in self.fields:
-            del self.fields[NTLMSSP_AV_EOL]
-        ans = ''
-        for i in self.fields.keys():
-            ans+= struct.pack('<HH', i, self[i][0])
-            ans+= self[i][1]
-
-        # end with a NTLMSSP_AV_EOL
-        ans += struct.pack('<HH', NTLMSSP_AV_EOL, 0)
-
-        return ans
-
-class NTLMAuthMixin:
-    def get_os_version(self):
-        if self['os_version'] == '':
-            return None
-        else:
-            mayor_v = struct.unpack('B',self['os_version'][0])[0]
-            minor_v = struct.unpack('B',self['os_version'][1])[0]
-            build_v = struct.unpack('H',self['os_version'][2:4])
-            return (mayor_v,minor_v,build_v)
-
-class NTLMAuthNegotiate(Structure, NTLMAuthMixin):
-
-    structure = (
-        ('','"NTLMSSP\x00'),
-        ('message_type','<L=1'),
-        ('flags','<L'),
-        ('domain_len','<H-domain_name'),
-        ('domain_max_len','<H-domain_name'),
-        ('domain_offset','<L=0'),
-        ('host_len','<H-host_name'),
-        ('host_maxlen','<H-host_name'),
-        ('host_offset','<L=0'),
-        ('os_version',':'),
-        ('host_name',':'),
-        ('domain_name',':'))
-
-    def __init__(self):
-        Structure.__init__(self)
-        self['flags']= (
-               NTLMSSP_NEGOTIATE_128     |
-               NTLMSSP_NEGOTIATE_KEY_EXCH|
-               # NTLMSSP_LM_KEY      |
-               NTLMSSP_NEGOTIATE_NTLM    |
-               NTLMSSP_NEGOTIATE_UNICODE     |
-               # NTLMSSP_ALWAYS_SIGN |
-               NTLMSSP_NEGOTIATE_SIGN        |
-               NTLMSSP_NEGOTIATE_SEAL        |
-               # NTLMSSP_TARGET      |
-               0)
-        self['host_name']=''
-        self['domain_name']=''
-        self['os_version']=''
-
-    def getData(self):
-        if len(self.fields['host_name']) > 0:
-            self['flags'] |= NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED
-        if len(self.fields['domain_name']) > 0:
-            self['flags'] |= NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED
-        if len(self.fields['os_version']) > 0:
-            self['flags'] |= NTLMSSP_NEGOTIATE_VERSION
-        if (self['flags'] & NTLMSSP_NEGOTIATE_VERSION) == 
NTLMSSP_NEGOTIATE_VERSION:
-            version_len = 8
-        else:
-            version_len = 0
-        if (self['flags'] & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED) == 
NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED:
-            self['host_offset']=32 + version_len
-        if (self['flags'] & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED) == 
NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED:
-            self['domain_offset']=32+len(self['host_name']) + version_len
-        return Structure.getData(self)
-
-    def fromString(self,data):
-        Structure.fromString(self,data)
-
-        domain_offset = self['domain_offset']
-        domain_end    = self['domain_len'] + domain_offset
-        self['domain_name'] = data[ domain_offset : domain_end ]
-
-        host_offset = self['host_offset']
-        host_end    = self['host_len'] + host_offset
-        self['host_name'] = data[ host_offset : host_end ]
-
-        hasOsInfo = self['flags'] & NTLMSSP_NEGOTIATE_VERSION
-        if len(data) >= 36 and hasOsInfo:
-            self['os_version'] = data[32:40]
-        else:
-            self['os_version'] = ''
-
-class NTLMAuthChallenge(Structure):
-
-    structure = (
-        ('','"NTLMSSP\x00'),
-        ('message_type','<L=2'),
-        ('domain_len','<H-domain_name'),
-        ('domain_max_len','<H-domain_name'),
-        ('domain_offset','<L=40'),
-        ('flags','<L=0'),
-        ('challenge','8s'),
-        ('reserved','8s=""'),
-        ('TargetInfoFields_len','<H-TargetInfoFields'),
-        ('TargetInfoFields_max_len','<H-TargetInfoFields'),
-        ('TargetInfoFields_offset','<L'),
-        ('VersionLen','_-Version','self.checkVersion(self["flags"])'),
-        ('Version',':'),
-        ('domain_name',':'),
-        ('TargetInfoFields',':'))
-
-    def checkVersion(self, flags):
-        if flags is not None:
-           if flags & NTLMSSP_NEGOTIATE_VERSION == 0:
-              return 0
-        return 8
-
-    def getData(self):
-        if self['TargetInfoFields'] is not None and 
type(self['TargetInfoFields']) is not str:
-            raw_av_fields = self['TargetInfoFields'].getData()
-            self['TargetInfoFields'] = raw_av_fields
-        return Structure.getData(self)
-
-    def fromString(self,data):
-        Structure.fromString(self,data)
-        # Just in case there's more data after the TargetInfoFields
-        self['TargetInfoFields'] = 
self['TargetInfoFields'][:self['TargetInfoFields_len']]
-        # We gotta process the TargetInfoFields
-        #if self['TargetInfoFields_len'] > 0:
-        #    av_pairs = 
AV_PAIRS(self['TargetInfoFields'][:self['TargetInfoFields_len']])
-        #    self['TargetInfoFields'] = av_pairs
-
-        return self
-
-class NTLMAuthChallengeResponse(Structure, NTLMAuthMixin):
-
-    structure = (
-        ('','"NTLMSSP\x00'),
-        ('message_type','<L=3'),
-        ('lanman_len','<H-lanman'),
-        ('lanman_max_len','<H-lanman'),
-        ('lanman_offset','<L'),
-        ('ntlm_len','<H-ntlm'),
-        ('ntlm_max_len','<H-ntlm'),
-        ('ntlm_offset','<L'),
-        ('domain_len','<H-domain_name'),
-        ('domain_max_len','<H-domain_name'),
-        ('domain_offset','<L'),
-        ('user_len','<H-user_name'),
-        ('user_max_len','<H-user_name'),
-        ('user_offset','<L'),
-        ('host_len','<H-host_name'),
-        ('host_max_len','<H-host_name'),
-        ('host_offset','<L'),
-        ('session_key_len','<H-session_key'),
-        ('session_key_max_len','<H-session_key'),
-        ('session_key_offset','<L'),
-        ('flags','<L'),
-        ('VersionLen','_-Version','self.checkVersion(self["flags"])'),
-        ('Version',':=""'),
-        ('MICLen','_-MIC','self.checkMIC(self["flags"])'),
-        ('MIC',':=""'),
-        ('domain_name',':'),
-        ('user_name',':'),
-        ('host_name',':'),
-        ('lanman',':'),
-        ('ntlm',':'),
-        ('session_key',':'))
-
-    def __init__(self, username = '', password = '', challenge = '', lmhash = 
'', nthash = '', flags = 0):
-        Structure.__init__(self)
-        self['session_key']=''
-        self['user_name']=username.encode('utf-16le')
-        self['domain_name']='' #"CLON".encode('utf-16le')
-        self['host_name']='' #"BETS".encode('utf-16le')
-        self['flags'] = (   #authResp['flags']
-                # we think (beto & gera) that his flags force a memory conten 
leakage when a windows 2000 answers using uninitializaed verifiers
-           NTLMSSP_NEGOTIATE_128     |
-           NTLMSSP_NEGOTIATE_KEY_EXCH|
-           # NTLMSSP_LM_KEY      |
-           NTLMSSP_NEGOTIATE_NTLM    |
-           NTLMSSP_NEGOTIATE_UNICODE     |
-           # NTLMSSP_ALWAYS_SIGN |
-           NTLMSSP_NEGOTIATE_SIGN        |
-           NTLMSSP_NEGOTIATE_SEAL        |
-           # NTLMSSP_TARGET      |
-           0)
-        # Here we do the stuff
-        if username and ( lmhash != '' or nthash != ''):
-            self['lanman'] = get_ntlmv1_response(lmhash, challenge)
-            self['ntlm'] = get_ntlmv1_response(nthash, challenge)
-        elif (username and password):
-            lmhash = compute_lmhash(password)
-            nthash = compute_nthash(password)
-            self['lanman']=get_ntlmv1_response(lmhash, challenge)
-            self['ntlm']=get_ntlmv1_response(nthash, challenge)    # This is 
not used for LM_KEY nor NTLM_KEY
-        else:
-            self['lanman'] = ''
-            self['ntlm'] = ''
-            if not self['host_name']:
-                self['host_name'] = 'NULL'.encode('utf-16le')      # for NULL 
session there must be a hostname
-
-    def checkVersion(self, flags):
-        if flags is not None:
-           if flags & NTLMSSP_NEGOTIATE_VERSION == 0:
-              return 0
-        return 8
-
-    def checkMIC(self, flags):
-        # TODO: Find a proper way to check the MIC is in there
-        if flags is not None:
-           if flags & NTLMSSP_NEGOTIATE_VERSION == 0:
-              return 0
-        return 16
-
-    def getData(self):
-        
self['domain_offset']=64+self.checkMIC(self["flags"])+self.checkVersion(self["flags"])
-        
self['user_offset']=64+self.checkMIC(self["flags"])+self.checkVersion(self["flags"])+len(self['domain_name'])
-        self['host_offset']=self['user_offset']+len(self['user_name'])
-        self['lanman_offset']=self['host_offset']+len(self['host_name'])
-        self['ntlm_offset']=self['lanman_offset']+len(self['lanman'])
-        self['session_key_offset']=self['ntlm_offset']+len(self['ntlm'])
-        return Structure.getData(self)
-
-    def fromString(self,data):
-        Structure.fromString(self,data)
-        # [MS-NLMP] page 27
-        # Payload data can be present in any order within the Payload field,
-        # with variable-length padding before or after the data
-
-        domain_offset = self['domain_offset']
-        domain_end = self['domain_len'] + domain_offset
-        self['domain_name'] = data[ domain_offset : domain_end ]
-
-        host_offset = self['host_offset']
-        host_end    = self['host_len'] + host_offset
-        self['host_name'] = data[ host_offset: host_end ]
-
-        user_offset = self['user_offset']
-        user_end    = self['user_len'] + user_offset
-        self['user_name'] = data[ user_offset: user_end ]
-
-        ntlm_offset = self['ntlm_offset']
-        ntlm_end    = self['ntlm_len'] + ntlm_offset
-        self['ntlm'] = data[ ntlm_offset : ntlm_end ]
-
-        lanman_offset = self['lanman_offset']
-        lanman_end    = self['lanman_len'] + lanman_offset
-        self['lanman'] = data[ lanman_offset : lanman_end]
-
-        #if len(data) >= 36:
-        #    self['os_version'] = data[32:36]
-        #else:
-        #    self['os_version'] = ''
-
-class ImpacketStructure(Structure):
-    def set_parent(self, other):
-        self.parent = other
-
-    def get_packet(self):
-        return str(self)
-
-    def get_size(self):
-        return len(self)
-
-class ExtendedOrNotMessageSignature(Structure):
-    def __init__(self, flags = 0, **kargs):
-        if flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
-            self.structure = self.extendedMessageSignature
-        else:
-            self.structure = self.MessageSignature
-        return Structure.__init__(self, **kargs)
-
-class NTLMMessageSignature(ExtendedOrNotMessageSignature):
-      extendedMessageSignature = (
-          ('Version','<L=1'),
-          ('Checksum','<q'),
-          ('SeqNum','<i'),
-      )
-
-      MessageSignature = (
-          ('Version','<L=1'),
-          ('RandomPad','<i=0'),
-          ('Checksum','<i'),
-          ('SeqNum','<i'),
-      )
-
-KNOWN_DES_INPUT = "KGS!@#$%"
-
-def __expand_DES_key( key):
-    # Expand the key from a 7-byte password key into a 8-byte DES key
-    key  = key[:7]
-    key += '\x00'*(7-len(key))
-    s = chr(((ord(key[0]) >> 1) & 0x7f) << 1)
-    s = s + chr(((ord(key[0]) & 0x01) << 6 | ((ord(key[1]) >> 2) & 0x3f)) << 1)
-    s = s + chr(((ord(key[1]) & 0x03) << 5 | ((ord(key[2]) >> 3) & 0x1f)) << 1)
-    s = s + chr(((ord(key[2]) & 0x07) << 4 | ((ord(key[3]) >> 4) & 0x0f)) << 1)
-    s = s + chr(((ord(key[3]) & 0x0f) << 3 | ((ord(key[4]) >> 5) & 0x07)) << 1)
-    s = s + chr(((ord(key[4]) & 0x1f) << 2 | ((ord(key[5]) >> 6) & 0x03)) << 1)
-    s = s + chr(((ord(key[5]) & 0x3f) << 1 | ((ord(key[6]) >> 7) & 0x01)) << 1)
-    s = s + chr((ord(key[6]) & 0x7f) << 1)
-    return s
-
-def __DES_block(key, msg):
-    if POW:
-        cipher = POW.Symmetric(POW.DES_ECB)
-        cipher.encryptInit(__expand_DES_key(key))
-        return cipher.update(msg)
-    else:
-        cipher = DES.new(__expand_DES_key(key),DES.MODE_ECB)
-        return cipher.encrypt(msg)
-
-def ntlmssp_DES_encrypt(key, challenge):
-    answer  = __DES_block(key[:7], challenge)
-    answer += __DES_block(key[7:14], challenge)
-    answer += __DES_block(key[14:], challenge)
-    return answer
-
-# High level functions to use NTLMSSP
-
-def getNTLMSSPType1(workstation='', domain='', signingRequired = False, 
use_ntlmv2 = USE_NTLMv2):
-    # Let's do some encoding checks before moving on. Kind of dirty, but found 
effective when dealing with
-    # international characters.
-    import sys
-    encoding = sys.getfilesystemencoding()
-    if encoding is not None:
-        try:
-            workstation.encode('utf-16le')
-        except:
-            workstation = workstation.decode(encoding)
-        try:
-            domain.encode('utf-16le')
-        except:
-            domain = domain.decode(encoding)
-
-    # Let's prepare a Type 1 NTLMSSP Message
-    auth = NTLMAuthNegotiate()
-    auth['flags']=0
-    if signingRequired:
-       auth['flags'] = NTLMSSP_NEGOTIATE_KEY_EXCH | NTLMSSP_NEGOTIATE_SIGN | 
NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_SEAL
-    if use_ntlmv2:
-       auth['flags'] |= NTLMSSP_NEGOTIATE_TARGET_INFO
-    auth['flags'] |= NTLMSSP_NEGOTIATE_NTLM | 
NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY | NTLMSSP_NEGOTIATE_UNICODE | 
NTLMSSP_REQUEST_TARGET |  NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_56
-    auth['domain_name'] = domain.encode('utf-16le')
-    return auth
-
-def getNTLMSSPType3(type1, type2, user, password, domain, lmhash = '', nthash 
= '', use_ntlmv2 = USE_NTLMv2):
-
-    # Let's do some encoding checks before moving on. Kind of dirty, but found 
effective when dealing with
-    # international characters.
-    import sys
-    encoding = sys.getfilesystemencoding()
-    if encoding is not None:
-        try:
-            user.encode('utf-16le')
-        except:
-            user = user.decode(encoding)
-        try:
-            password.encode('utf-16le')
-        except:
-            password = password.decode(encoding)
-        try:
-            domain.encode('utf-16le')
-        except:
-            domain = user.decode(encoding)
-
-    ntlmChallenge = NTLMAuthChallenge(type2)
-
-    # Let's start with the original flags sent in the type1 message
-    responseFlags = type1['flags']
-
-    # Token received and parsed. Depending on the authentication
-    # method we will create a valid ChallengeResponse
-    ntlmChallengeResponse = NTLMAuthChallengeResponse(user, password, 
ntlmChallenge['challenge'])
-
-    clientChallenge = "".join([random.choice(string.digits+string.letters) for 
i in range(8)])
-
-    serverName = ntlmChallenge['TargetInfoFields']
-
-    ntResponse, lmResponse, sessionBaseKey = 
computeResponse(ntlmChallenge['flags'], ntlmChallenge['challenge'], 
clientChallenge, serverName, domain, user, password, lmhash, nthash, use_ntlmv2 
)
-
-    # Let's check the return flags
-    if (ntlmChallenge['flags'] & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY) 
== 0:
-        # No extended session security, taking it out
-        responseFlags &= 0xffffffff ^ 
NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
-    if (ntlmChallenge['flags'] & NTLMSSP_NEGOTIATE_128 ) == 0:
-        # No support for 128 key len, taking it out
-        responseFlags &= 0xffffffff ^ NTLMSSP_NEGOTIATE_128
-    if (ntlmChallenge['flags'] & NTLMSSP_NEGOTIATE_KEY_EXCH) == 0:
-        # No key exchange supported, taking it out
-        responseFlags &= 0xffffffff ^ NTLMSSP_NEGOTIATE_KEY_EXCH
-    if (ntlmChallenge['flags'] & NTLMSSP_NEGOTIATE_SEAL) == 0:
-        # No sign available, taking it out
-        responseFlags &= 0xffffffff ^ NTLMSSP_NEGOTIATE_SEAL
-    if (ntlmChallenge['flags'] & NTLMSSP_NEGOTIATE_SIGN) == 0:
-        # No sign available, taking it out
-        responseFlags &= 0xffffffff ^ NTLMSSP_NEGOTIATE_SIGN
-    if (ntlmChallenge['flags'] & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) == 0:
-        # No sign available, taking it out
-        responseFlags &= 0xffffffff ^ NTLMSSP_NEGOTIATE_ALWAYS_SIGN
-
-    keyExchangeKey = KXKEY(ntlmChallenge['flags'],sessionBaseKey, lmResponse, 
ntlmChallenge['challenge'], password, lmhash, nthash,use_ntlmv2)
-
-    # Special case for anonymous login
-    if user == '' and password == '' and lmhash == '' and nthash == '':
-      keyExchangeKey = '\x00'*16
-
-    # If we set up key exchange, let's fill the right variables
-    if ntlmChallenge['flags'] & NTLMSSP_NEGOTIATE_KEY_EXCH:
-       # not exactly what I call random tho :\
-       # exportedSessionKey = this is the key we should use to sign
-       exportedSessionKey = 
"".join([random.choice(string.digits+string.letters) for i in range(16)])
-       #exportedSessionKey = "A"*16
-       #print "keyExchangeKey %r" % keyExchangeKey
-       # Let's generate the right session key based on the challenge flags
-       #if responseFlags & NTLMSSP_NTLM2_KEY:
-           # Extended session security enabled
-       #    if responseFlags & NTLMSSP_KEY_128:
-               # Full key
-       #        exportedSessionKey = exportedSessionKey
-       #    elif responseFlags & NTLMSSP_KEY_56:
-               # Only 56-bit key
-       #        exportedSessionKey = exportedSessionKey[:7]
-       #    else:
-       #        exportedSessionKey = exportedSessionKey[:5]
-       #elif responseFlags & NTLMSSP_KEY_56:
-           # No extended session security, just 56 bits key
-       #    exportedSessionKey = exportedSessionKey[:7] + '\xa0'
-       #else:
-       #    exportedSessionKey = exportedSessionKey[:5] + '\xe5\x38\xb0'
-
-       encryptedRandomSessionKey = generateEncryptedSessionKey(keyExchangeKey, 
exportedSessionKey)
-    else:
-       encryptedRandomSessionKey = None
-       # [MS-NLMP] page 46
-       exportedSessionKey        = keyExchangeKey
-
-    ntlmChallengeResponse['flags'] = responseFlags
-    ntlmChallengeResponse['domain_name'] = domain.encode('utf-16le')
-    ntlmChallengeResponse['lanman'] = lmResponse
-    ntlmChallengeResponse['ntlm'] = ntResponse
-    if encryptedRandomSessionKey is not None:
-        ntlmChallengeResponse['session_key'] = encryptedRandomSessionKey
-
-    return ntlmChallengeResponse, exportedSessionKey
-
-
-# NTLMv1 Algorithm
-
-def generateSessionKeyV1(password, lmhash, nthash):
-    if POW:
-        hash = POW.Digest(POW.MD4_DIGEST)
-    else:
-        hash = MD4.new()
-    hash.update(NTOWFv1(password, lmhash, nthash))
-    return hash.digest()
-
-def computeResponseNTLMv1(flags, serverChallenge, clientChallenge, serverName, 
domain, user, password, lmhash='', nthash='', use_ntlmv2 = USE_NTLMv2):
-    if (user == '' and password == ''):
-        # Special case for anonymous authentication
-        lmResponse = ''
-        ntResponse = ''
-    else:
-        lmhash = LMOWFv1(password, lmhash, nthash)
-        nthash = NTOWFv1(password, lmhash, nthash)
-        if flags & NTLMSSP_NEGOTIATE_LM_KEY:
-           ntResponse = ''
-           lmResponse = get_ntlmv1_response(lmhash, serverChallenge)
-        elif flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
-           md5 = hashlib.new('md5')
-           chall = (serverChallenge + clientChallenge)
-           md5.update(chall)
-           ntResponse = ntlmssp_DES_encrypt(nthash, md5.digest()[:8])
-           lmResponse = clientChallenge + '\x00'*16
-        else:
-           ntResponse = get_ntlmv1_response(nthash,serverChallenge)
-           lmResponse = get_ntlmv1_response(lmhash, serverChallenge)
-
-    sessionBaseKey = generateSessionKeyV1(password, lmhash, nthash)
-    return ntResponse, lmResponse, sessionBaseKey
-
-def compute_lmhash(password):
-    # This is done according to Samba's encryption specification 
(docs/html/ENCRYPTION.html)
-    password = password.upper()
-    lmhash  = __DES_block(password[:7], KNOWN_DES_INPUT)
-    lmhash += __DES_block(password[7:14], KNOWN_DES_INPUT)
-    return lmhash
-
-def NTOWFv1(password, lmhash = '', nthash=''):
-    if nthash != '':
-       return nthash
-    return compute_nthash(password)
-
-def LMOWFv1(password, lmhash = '', nthash=''):
-    if lmhash != '':
-       return lmhash
-    return compute_lmhash(password)
-
-def compute_nthash(password):
-    # This is done according to Samba's encryption specification 
(docs/html/ENCRYPTION.html)
-    try:
-        password = unicode(password).encode('utf_16le')
-    except NameError:  # unicode() was removed in Python 3
-        password = str(password).encode('utf_16le')
-    except UnicodeDecodeError:
-        import sys
-        password = 
password.decode(sys.getfilesystemencoding()).encode('utf_16le')
-
-    if POW:
-        hash = POW.Digest(POW.MD4_DIGEST)
-    else:
-        hash = MD4.new()
-    hash.update(password)
-    return hash.digest()
-
-def get_ntlmv1_response(key, challenge):
-    return ntlmssp_DES_encrypt(key, challenge)
-
-# NTLMv2 Algorithm - as described in MS-NLMP Section 3.3.2
-
-# Crypto Stuff
-
-def MAC(flags, handle, signingKey, seqNum, message):
-   # [MS-NLMP] Section 3.4.4
-   # Returns the right messageSignature depending on the flags
-   messageSignature = NTLMMessageSignature(flags)
-   if flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
-       if flags & NTLMSSP_NEGOTIATE_KEY_EXCH:
-           messageSignature['Version'] = 1
-           messageSignature['Checksum'] = 
struct.unpack('<q',handle(hmac_md5(signingKey, 
struct.pack('<i',seqNum)+message)[:8]))[0]
-           messageSignature['SeqNum'] = seqNum
-           seqNum += 1
-       else:
-           messageSignature['Version'] = 1
-           messageSignature['Checksum'] = 
struct.unpack('<q',hmac_md5(signingKey, 
struct.pack('<i',seqNum)+message)[:8])[0]
-           messageSignature['SeqNum'] = seqNum
-           seqNum += 1
-   else:
-       messageSignature['Version'] = 1
-       messageSignature['Checksum'] = struct.pack('<i',binascii.crc32(message))
-       messageSignature['RandomPad'] = 0
-       messageSignature['RandomPad'] = 
handle(struct.pack('<i',messageSignature['RandomPad']))
-       messageSignature['Checksum'] = 
struct.unpack('<i',handle(messageSignature['Checksum']))[0]
-       messageSignature['SeqNum'] = handle('\x00\x00\x00\x00')
-       messageSignature['SeqNum'] = 
struct.unpack('<i',messageSignature['SeqNum'])[0] ^ seqNum
-       messageSignature['RandomPad'] = 0
-
-   return messageSignature
-
-def SEAL(flags, signingKey, sealingKey, messageToSign, messageToEncrypt, 
seqNum, handle):
-   sealedMessage = handle(messageToEncrypt)
-   signature = MAC(flags, handle, signingKey, seqNum, messageToSign)
-   return sealedMessage, signature
-
-def SIGN(flags, signingKey, message, seqNum, handle):
-   return MAC(flags, handle, signingKey, seqNum, message)
-
-def SIGNKEY(flags, randomSessionKey, mode = 'Client'):
-   if flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
-       if mode == 'Client':
-           md5 = hashlib.new('md5')
-           md5.update(randomSessionKey + "session key to client-to-server 
signing key magic constant\x00")
-           signKey = md5.digest()
-       else:
-           md5 = hashlib.new('md5')
-           md5.update(randomSessionKey + "session key to server-to-client 
signing key magic constant\x00")
-           signKey = md5.digest()
-   else:
-       signKey = None
-   return signKey
-
-def SEALKEY(flags, randomSessionKey, mode = 'Client'):
-   if flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
-       if flags & NTLMSSP_NEGOTIATE_128:
-           sealKey = randomSessionKey
-       elif flags & NTLMSSP_NEGOTIATE_56:
-           sealKey = randomSessionKey[:7]
-       else:
-           sealKey = randomSessionKey[:5]
-
-       if mode == 'Client':
-               md5 = hashlib.new('md5')
-               md5.update(sealKey + 'session key to client-to-server sealing 
key magic constant\x00')
-               sealKey = md5.digest()
-       else:
-               md5 = hashlib.new('md5')
-               md5.update(sealKey + 'session key to server-to-client sealing 
key magic constant\x00')
-               sealKey = md5.digest()
-
-   elif flags & NTLMSSP_NEGOTIATE_56:
-       sealKey = randomSessionKey[:7] + '\xa0'
-   else:
-       sealKey = randomSessionKey[:5] + '\xe5\x38\xb0'
-
-   return sealKey
-
-
-def generateEncryptedSessionKey(keyExchangeKey, exportedSessionKey):
-   if POW:
-       cipher = POW.Symmetric(POW.RC4)
-       cipher.encryptInit(keyExchangeKey)
-       cipher_encrypt = cipher.update
-   else:
-       cipher = ARC4.new(keyExchangeKey)
-       cipher_encrypt = cipher.encrypt
-
-   sessionKey = cipher_encrypt(exportedSessionKey)
-   return sessionKey
-
-def KXKEY(flags, sessionBaseKey, lmChallengeResponse, serverChallenge, 
password, lmhash, nthash, use_ntlmv2 = USE_NTLMv2):
-   if use_ntlmv2:
-       return sessionBaseKey
-
-   if flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
-       if flags & NTLMSSP_NEGOTIATE_NTLM:
-          keyExchangeKey = hmac_md5(sessionBaseKey, serverChallenge + 
lmChallengeResponse[:8])
-       else:
-          keyExchangeKey = sessionBaseKey
-   elif flags & NTLMSSP_NEGOTIATE_NTLM:
-       if flags & NTLMSSP_NEGOTIATE_LM_KEY:
-          keyExchangeKey = __DES_block(LMOWFv1(password,lmhash)[:7], 
lmChallengeResponse[:8]) + __DES_block(LMOWFv1(password,lmhash)[7] + 
'\xBD\xBD\xBD\xBD\xBD\xBD', lmChallengeResponse[:8])
-       elif flags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY:
-          keyExchangeKey = LMOWFv1(password,lmhash)[:8] + '\x00'*8
-       else:
-          keyExchangeKey = sessionBaseKey
-   else:
-       raise "Can't create a valid KXKEY!"
-
-   return keyExchangeKey
-
-def hmac_md5(key, data):
-    if POW:
-        h = POW.Hmac(POW.MD5_DIGEST, key)
-        h.update(data)
-        result = h.mac()
-    else:
-        import hmac
-        h = hmac.new(key)
-        h.update(data)
-        result = h.digest()
-    return result
-
-def NTOWFv2( user, password, domain, hash = ''):
-    if hash != '':
-       theHash = hash
-    else:
-       theHash = compute_nthash(password)
-    return hmac_md5(theHash, user.upper().encode('utf-16le') + 
domain.encode('utf-16le'))
-
-def LMOWFv2( user, password, domain, lmhash = ''):
-    return NTOWFv2( user, password, domain, lmhash)
-
-
-def computeResponseNTLMv2(flags, serverChallenge, clientChallenge,  
serverName, domain, user, password, lmhash = '', nthash = '', use_ntlmv2 = 
USE_NTLMv2):
-
-    responseServerVersion = '\x01'
-    hiResponseServerVersion = '\x01'
-    responseKeyNT = NTOWFv2(user, password, domain, nthash)
-    responseKeyLM = LMOWFv2(user, password, domain, lmhash)
-
-    # If you're running test-ntlm, comment the following lines and uncoment 
the ones that are commented. Don't forget to turn it back after the tests!
-    ######################
-    av_pairs = AV_PAIRS(serverName)
-    # In order to support SPN target name validation, we have to add this to 
the serverName av_pairs. Otherwise we will get access denied
-    # This is set at Local Security Policy -> Local Policies -> Security 
Options -> Server SPN target name validation level
-    av_pairs[NTLMSSP_AV_TARGET_NAME] = 'cifs/'.encode('utf-16le') + 
av_pairs[NTLMSSP_AV_HOSTNAME][1]
-    if av_pairs[NTLMSSP_AV_TIME] is not None:
-       aTime = av_pairs[NTLMSSP_AV_TIME][1]
-    else:
-       aTime = struct.pack('<q', (116444736000000000 + 
calendar.timegm(time.gmtime()) * 10000000) )
-       #aTime = '\x00'*8
-       av_pairs[NTLMSSP_AV_TIME] = aTime
-    serverName = av_pairs.getData()
-
-    ######################
-    #aTime = '\x00'*8
-    ######################
-    temp = responseServerVersion + hiResponseServerVersion + '\x00' * 6 + 
aTime + clientChallenge + '\x00' * 4 + serverName + '\x00' * 4
-
-    ntProofStr = hmac_md5(responseKeyNT, serverChallenge + temp)
-
-    ntChallengeResponse = ntProofStr + temp
-    lmChallengeResponse = hmac_md5(responseKeyNT, serverChallenge + 
clientChallenge) + clientChallenge
-    sessionBaseKey = hmac_md5(responseKeyNT, ntProofStr)
-
-    if (user == '' and password == ''):
-        # Special case for anonymous authentication
-        ntChallengeResponse = ''
-        lmChallengeResponse = ''
-
-    return ntChallengeResponse, lmChallengeResponse, sessionBaseKey
-
-class NTLM_HTTP(object):
-    '''Parent class for NTLM HTTP classes.'''
-    MSG_TYPE = None
-
-    @classmethod
-    def get_instace(cls,msg_64):
-        msg = None
-        msg_type = 0
-        if msg_64 != '':
-            msg = base64.b64decode(msg_64[5:]) # Remove the 'NTLM '
-            msg_type = ord(msg[8])
-
-        for _cls in NTLM_HTTP.__subclasses__():
-            if msg_type == _cls.MSG_TYPE:
-                instance = _cls()
-                instance.fromString(msg)
-                return instance
-
-
-class NTLM_HTTP_AuthRequired(NTLM_HTTP):
-    commonHdr = ()
-    # Message 0 means the first HTTP request e.g. 'GET /bla.png'
-    MSG_TYPE = 0
-
-    def fromString(self,data):
-        pass
-
-
-class NTLM_HTTP_AuthNegotiate(NTLM_HTTP, NTLMAuthNegotiate):
-    commonHdr = ()
-    MSG_TYPE = 1
-
-    def __init__(self):
-        NTLMAuthNegotiate.__init__(self)
-
-
-class NTLM_HTTP_AuthChallengeResponse(NTLM_HTTP, NTLMAuthChallengeResponse):
-    commonHdr = ()
-    MSG_TYPE = 3
-
-    def __init__(self):
-        NTLMAuthChallengeResponse.__init__(self)
diff --git a/tests/python_dependencies/impacket/smb.py 
b/tests/python_dependencies/impacket/smb.py
deleted file mode 100644
index c4ea6fc68..000000000
--- a/tests/python_dependencies/impacket/smb.py
+++ /dev/null
@@ -1,4099 +0,0 @@
-# Copyright (c) 2003-2016 CORE Security Technologies
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-# Copyright (C) 2001 Michael Teo <address@hidden>
-# smb.py - SMB/CIFS library
-#
-# This software is provided 'as-is', without any express or implied warranty. 
-# In no event will the author be held liable for any damages arising from the 
-# use of this software.
-#
-# Permission is granted to anyone to use this software for any purpose, 
-# including commercial applications, and to alter it and redistribute it 
-# freely, subject to the following restrictions:
-#
-# 1. The origin of this software must not be misrepresented; you must not 
-#    claim that you wrote the original software. If you use this software 
-#    in a product, an acknowledgment in the product documentation would be
-#    appreciated but is not required.
-#
-# 2. Altered source versions must be plainly marked as such, and must not be 
-#    misrepresented as being the original software.
-#
-# 3. This notice cannot be removed or altered from any source distribution.
-#
-# Altered source done by Alberto Solino (@agsolino)
-
-# Todo:
-# [ ] Try [SMB]transport fragmentation using Transact requests
-# [ ] Try other methods of doing write (write_raw, transact2, write, 
write_and_unlock, write_and_close, write_mpx)
-# [-] Try replacements for SMB_COM_NT_CREATE_ANDX  (CREATE, T_TRANSACT_CREATE, 
OPEN_ANDX works
-# [x] Fix forceWriteAndx, which needs to send a RecvRequest, because recv() 
will not send it
-# [x] Fix Recv() when using RecvAndx and the answer comes splet in several 
packets
-# [ ] Try [SMB]transport fragmentation with overlaping segments
-# [ ] Try [SMB]transport fragmentation with out of order segments
-# [x] Do chained AndX requests
-# [ ] Transform the rest of the calls to structure
-# [X] Implement TRANS/TRANS2 reassembly for list_path
-
-import os
-import socket
-import string
-from binascii import a2b_hex
-import datetime
-from struct import pack, unpack
-from contextlib import contextmanager
-
-from impacket import nmb, ntlm, nt_errors, LOG
-from impacket.structure import Structure
-from impacket.spnego import SPNEGO_NegTokenInit, TypesMech, SPNEGO_NegTokenResp
-
-# For signing
-import hashlib
-
-unicode_support = 0
-unicode_convert = 1
-
-try:
-    from cStringIO import StringIO
-except ImportError:
-    from StringIO import StringIO
-
-# Dialect for SMB1
-SMB_DIALECT = 'NT LM 0.12'
-
-# Shared Device Type
-SHARED_DISK                      = 0x00
-SHARED_DISK_HIDDEN               = 0x80000000
-SHARED_PRINT_QUEUE               = 0x01
-SHARED_DEVICE                    = 0x02
-SHARED_IPC                       = 0x03
-
-# Extended attributes mask
-ATTR_ARCHIVE                     = 0x020
-ATTR_COMPRESSED                  = 0x800
-ATTR_NORMAL                      = 0x080
-ATTR_HIDDEN                      = 0x002
-ATTR_READONLY                    = 0x001
-ATTR_TEMPORARY                   = 0x100
-ATTR_DIRECTORY                   = 0x010
-ATTR_SYSTEM                      = 0x004
-
-# Service Type
-SERVICE_DISK                     = 'A:'
-SERVICE_PRINTER                  = 'LPT1:'
-SERVICE_IPC                      = 'IPC'
-SERVICE_COMM                     = 'COMM'
-SERVICE_ANY                      = '?????'
-
-# Server Type (Can be used to mask with SMBMachine.get_type() or 
SMBDomain.get_type())
-SV_TYPE_WORKSTATION              = 0x00000001
-SV_TYPE_SERVER                   = 0x00000002
-SV_TYPE_SQLSERVER                = 0x00000004
-SV_TYPE_DOMAIN_CTRL              = 0x00000008
-SV_TYPE_DOMAIN_BAKCTRL           = 0x00000010
-SV_TYPE_TIME_SOURCE              = 0x00000020
-SV_TYPE_AFP                      = 0x00000040
-SV_TYPE_NOVELL                   = 0x00000080
-SV_TYPE_DOMAIN_MEMBER            = 0x00000100
-SV_TYPE_PRINTQ_SERVER            = 0x00000200
-SV_TYPE_DIALIN_SERVER            = 0x00000400
-SV_TYPE_XENIX_SERVER             = 0x00000800
-SV_TYPE_NT                       = 0x00001000
-SV_TYPE_WFW                      = 0x00002000
-SV_TYPE_SERVER_NT                = 0x00004000
-SV_TYPE_POTENTIAL_BROWSER        = 0x00010000
-SV_TYPE_BACKUP_BROWSER           = 0x00020000
-SV_TYPE_MASTER_BROWSER           = 0x00040000
-SV_TYPE_DOMAIN_MASTER            = 0x00080000
-SV_TYPE_LOCAL_LIST_ONLY          = 0x40000000
-SV_TYPE_DOMAIN_ENUM              = 0x80000000
-
-# Options values for SMB.stor_file and SMB.retr_file
-SMB_O_CREAT                      = 0x10   # Create the file if file does not 
exists. Otherwise, operation fails.
-SMB_O_EXCL                       = 0x00   # When used with SMB_O_CREAT, 
operation fails if file exists. Cannot be used with SMB_O_OPEN.
-SMB_O_OPEN                       = 0x01   # Open the file if the file exists
-SMB_O_TRUNC                      = 0x02   # Truncate the file if the file 
exists
-
-# Share Access Mode
-SMB_SHARE_COMPAT                 = 0x00
-SMB_SHARE_DENY_EXCL              = 0x10
-SMB_SHARE_DENY_WRITE             = 0x20
-SMB_SHARE_DENY_READEXEC          = 0x30
-SMB_SHARE_DENY_NONE              = 0x40
-SMB_ACCESS_READ                  = 0x00
-SMB_ACCESS_WRITE                 = 0x01
-SMB_ACCESS_READWRITE             = 0x02
-SMB_ACCESS_EXEC                  = 0x03
-
-TRANS_DISCONNECT_TID             = 1
-TRANS_NO_RESPONSE                = 2
-
-STATUS_SUCCESS                   = 0x00000000
-STATUS_LOGON_FAILURE             = 0xC000006D
-STATUS_LOGON_TYPE_NOT_GRANTED    = 0xC000015B
-MAX_TFRAG_SIZE                   = 5840
-EVASION_NONE                     = 0
-EVASION_LOW                      = 1
-EVASION_HIGH                     = 2
-EVASION_MAX                      = 3
-RPC_X_BAD_STUB_DATA              = 0x6F7
-
-# SMB_FILE_ATTRIBUTES
-
-SMB_FILE_ATTRIBUTE_NORMAL        = 0x0000
-SMB_FILE_ATTRIBUTE_READONLY      = 0x0001
-SMB_FILE_ATTRIBUTE_HIDDEN        = 0x0002
-SMB_FILE_ATTRIBUTE_SYSTEM        = 0x0004
-SMB_FILE_ATTRIBUTE_VOLUME        = 0x0008
-SMB_FILE_ATTRIBUTE_DIRECTORY     = 0x0010
-SMB_FILE_ATTRIBUTE_ARCHIVE       = 0x0020
-SMB_SEARCH_ATTRIBUTE_READONLY    = 0x0100
-SMB_SEARCH_ATTRIBUTE_HIDDEN      = 0x0200
-SMB_SEARCH_ATTRIBUTE_SYSTEM      = 0x0400
-SMB_SEARCH_ATTRIBUTE_DIRECTORY   = 0x1000
-SMB_SEARCH_ATTRIBUTE_ARCHIVE     = 0x2000
-
-# Session SetupAndX Action flags
-SMB_SETUP_GUEST                  = 0x01
-SMB_SETUP_USE_LANMAN_KEY         = 0x02
-
-# QUERY_INFORMATION levels
-SMB_INFO_ALLOCATION              = 0x0001
-SMB_INFO_VOLUME                  = 0x0002
-FILE_FS_SIZE_INFORMATION         = 0x0003
-SMB_QUERY_FS_VOLUME_INFO         = 0x0102
-SMB_QUERY_FS_SIZE_INFO           = 0x0103
-SMB_QUERY_FILE_EA_INFO           = 0x0103
-SMB_QUERY_FS_DEVICE_INFO         = 0x0104
-SMB_QUERY_FS_ATTRIBUTE_INFO      = 0x0105
-SMB_QUERY_FILE_BASIC_INFO        = 0x0101
-SMB_QUERY_FILE_STANDARD_INFO     = 0x0102
-SMB_QUERY_FILE_ALL_INFO          = 0x0107
-FILE_FS_FULL_SIZE_INFORMATION    = 0x03EF
-
-# SET_INFORMATION levels
-SMB_SET_FILE_DISPOSITION_INFO    = 0x0102
-SMB_SET_FILE_BASIC_INFO          = 0x0101
-SMB_SET_FILE_END_OF_FILE_INFO    = 0x0104
-
-
-# File System Attributes
-FILE_CASE_SENSITIVE_SEARCH       = 0x00000001
-FILE_CASE_PRESERVED_NAMES        = 0x00000002
-FILE_UNICODE_ON_DISK             = 0x00000004
-FILE_PERSISTENT_ACLS             = 0x00000008
-FILE_FILE_COMPRESSION            = 0x00000010
-FILE_VOLUME_IS_COMPRESSED        = 0x00008000
-
-# FIND_FIRST2 flags and levels
-SMB_FIND_CLOSE_AFTER_REQUEST     = 0x0001
-SMB_FIND_CLOSE_AT_EOS            = 0x0002
-SMB_FIND_RETURN_RESUME_KEYS      = 0x0004
-SMB_FIND_CONTINUE_FROM_LAST      = 0x0008
-SMB_FIND_WITH_BACKUP_INTENT      = 0x0010
-
-FILE_DIRECTORY_FILE              = 0x00000001
-FILE_DELETE_ON_CLOSE             = 0x00001000
-FILE_NON_DIRECTORY_FILE          = 0x00000040
-
-SMB_FIND_INFO_STANDARD           = 0x0001
-SMB_FIND_FILE_DIRECTORY_INFO     = 0x0101
-SMB_FIND_FILE_FULL_DIRECTORY_INFO= 0x0102
-SMB_FIND_FILE_NAMES_INFO         = 0x0103
-SMB_FIND_FILE_BOTH_DIRECTORY_INFO= 0x0104
-SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO = 0x105
-SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO = 0x106
-
-
-# DesiredAccess flags
-FILE_READ_DATA                   = 0x00000001
-FILE_WRITE_DATA                  = 0x00000002
-FILE_APPEND_DATA                 = 0x00000004
-FILE_EXECUTE                     = 0x00000020
-MAXIMUM_ALLOWED                  = 0x02000000
-GENERIC_ALL                      = 0x10000000
-GENERIC_EXECUTE                  = 0x20000000
-GENERIC_WRITE                    = 0x40000000
-GENERIC_READ                     = 0x80000000
-
-# ShareAccess flags
-FILE_SHARE_NONE                  = 0x00000000
-FILE_SHARE_READ                  = 0x00000001
-FILE_SHARE_WRITE                 = 0x00000002
-FILE_SHARE_DELETE                = 0x00000004
-
-# CreateDisposition flags
-FILE_SUPERSEDE                  = 0x00000000
-FILE_OPEN                       = 0x00000001
-FILE_CREATE                     = 0x00000002
-FILE_OPEN_IF                    = 0x00000003
-FILE_OVERWRITE                  = 0x00000004
-FILE_OVERWRITE_IF               = 0x00000005
-
-def strerror(errclass, errcode):
-    if errclass == 0x01:
-        return 'OS error', ERRDOS.get(errcode, 'Unknown error')
-    elif errclass == 0x02:
-        return 'Server error', ERRSRV.get(errcode, 'Unknown error')
-    elif errclass == 0x03:
-        return 'Hardware error', ERRHRD.get(errcode, 'Unknown error')
-    # This is not a standard error class for SMB
-    #elif errclass == 0x80:
-    #    return 'Browse error', ERRBROWSE.get(errcode, 'Unknown error')
-    elif errclass == 0xff:
-        return 'Bad command', 'Bad command. Please file bug report'
-    else:
-        return 'Unknown error', 'Unknown error'
-
-# Raised when an error has occured during a session
-class SessionError(Exception):
-    # SMB X/Open error codes for the ERRDOS error class
-    ERRsuccess                           = 0
-    ERRbadfunc                           = 1
-    ERRbadfile                           = 2
-    ERRbadpath                           = 3
-    ERRnofids                            = 4
-    ERRnoaccess                          = 5
-    ERRbadfid                            = 6
-    ERRbadmcb                            = 7
-    ERRnomem                             = 8
-    ERRbadmem                            = 9
-    ERRbadenv                            = 10
-    ERRbadaccess                         = 12
-    ERRbaddata                           = 13
-    ERRres                               = 14
-    ERRbaddrive                          = 15
-    ERRremcd                             = 16
-    ERRdiffdevice                        = 17
-    ERRnofiles                           = 18
-    ERRgeneral                           = 31
-    ERRbadshare                          = 32
-    ERRlock                              = 33
-    ERRunsup                             = 50
-    ERRnetnamedel                        = 64
-    ERRnosuchshare                       = 67
-    ERRfilexists                         = 80
-    ERRinvalidparam                      = 87
-    ERRcannotopen                        = 110
-    ERRinsufficientbuffer                = 122
-    ERRinvalidname                       = 123
-    ERRunknownlevel                      = 124
-    ERRnotlocked                         = 158
-    ERRrename                            = 183
-    ERRbadpipe                           = 230
-    ERRpipebusy                          = 231
-    ERRpipeclosing                       = 232
-    ERRnotconnected                      = 233
-    ERRmoredata                          = 234
-    ERRnomoreitems                       = 259
-    ERRbaddirectory                      = 267
-    ERReasnotsupported                   = 282
-    ERRlogonfailure                      = 1326
-    ERRbuftoosmall                       = 2123
-    ERRunknownipc                        = 2142
-    ERRnosuchprintjob                    = 2151
-    ERRinvgroup                          = 2455
-
-    # here's a special one from observing NT
-    ERRnoipc                             = 66
-
-    # These errors seem to be only returned by the NT printer driver system
-    ERRdriveralreadyinstalled            = 1795
-    ERRunknownprinterport                = 1796
-    ERRunknownprinterdriver              = 1797
-    ERRunknownprintprocessor             = 1798
-    ERRinvalidseparatorfile              = 1799
-    ERRinvalidjobpriority                = 1800
-    ERRinvalidprintername                = 1801
-    ERRprinteralreadyexists              = 1802
-    ERRinvalidprintercommand             = 1803
-    ERRinvaliddatatype                   = 1804
-    ERRinvalidenvironment                = 1805
-
-    ERRunknownprintmonitor               = 3000
-    ERRprinterdriverinuse                = 3001
-    ERRspoolfilenotfound                 = 3002
-    ERRnostartdoc                        = 3003
-    ERRnoaddjob                          = 3004
-    ERRprintprocessoralreadyinstalled    = 3005
-    ERRprintmonitoralreadyinstalled      = 3006
-    ERRinvalidprintmonitor               = 3007
-    ERRprintmonitorinuse                 = 3008
-    ERRprinterhasjobsqueued              = 3009
-
-    # Error codes for the ERRSRV class
-
-    ERRerror                             = 1
-    ERRbadpw                             = 2
-    ERRbadtype                           = 3
-    ERRaccess                            = 4
-    ERRinvnid                            = 5
-    ERRinvnetname                        = 6
-    ERRinvdevice                         = 7
-    ERRqfull                             = 49
-    ERRqtoobig                           = 50
-    ERRinvpfid                           = 52
-    ERRsmbcmd                            = 64
-    ERRsrverror                          = 65
-    ERRfilespecs                         = 67
-    ERRbadlink                           = 68
-    ERRbadpermits                        = 69
-    ERRbadpid                            = 70
-    ERRsetattrmode                       = 71
-    ERRpaused                            = 81
-    ERRmsgoff                            = 82
-    ERRnoroom                            = 83
-    ERRrmuns                             = 87
-    ERRtimeout                           = 88
-    ERRnoresource                        = 89
-    ERRtoomanyuids                       = 90
-    ERRbaduid                            = 91
-    ERRuseMPX                            = 250
-    ERRuseSTD                            = 251
-    ERRcontMPX                           = 252
-    ERRbadPW                             = None
-    ERRnosupport                         = 0
-    ERRunknownsmb                        = 22
-
-    # Error codes for the ERRHRD class
-
-    ERRnowrite                           = 19
-    ERRbadunit                           = 20
-    ERRnotready                          = 21
-    ERRbadcmd                            = 22
-    ERRdata                              = 23
-    ERRbadreq                            = 24
-    ERRseek                              = 25
-    ERRbadmedia                          = 26
-    ERRbadsector                         = 27
-    ERRnopaper                           = 28
-    ERRwrite                             = 29
-    ERRread                              = 30
-    ERRwrongdisk                         = 34
-    ERRFCBunavail                        = 35
-    ERRsharebufexc                       = 36
-    ERRdiskfull                          = 39
-
-
-    hard_msgs = {
-      19: ("ERRnowrite", "Attempt to write on write-protected diskette."),
-      20: ("ERRbadunit", "Unknown unit."),
-      21: ("ERRnotready", "Drive not ready."),
-      22: ("ERRbadcmd", "Unknown command."),
-      23: ("ERRdata", "Data error (CRC)."),
-      24: ("ERRbadreq", "Bad request structure length."),
-      25: ("ERRseek", "Seek error."),
-      26: ("ERRbadmedia", "Unknown media type."),
-      27: ("ERRbadsector", "Sector not found."),
-      28: ("ERRnopaper", "Printer out of paper."),
-      29: ("ERRwrite", "Write fault."),
-      30: ("ERRread", "Read fault."),
-      31: ("ERRgeneral", "General failure."),
-      32: ("ERRbadshare", "An open conflicts with an existing open."),
-      33: ("ERRlock", "A Lock request conflicted with an existing lock or 
specified an invalid mode, or an Unlock requested attempted to remove a lock 
held by another process."),
-      34: ("ERRwrongdisk", "The wrong disk was found in a drive."),
-      35: ("ERRFCBUnavail", "No FCBs are available to process request."),
-      36: ("ERRsharebufexc", "A sharing buffer has been exceeded.")
-      }
-
-    dos_msgs = {
-      ERRbadfunc: ("ERRbadfunc", "Invalid function."),
-      ERRbadfile: ("ERRbadfile", "File not found."),
-      ERRbadpath: ("ERRbadpath", "Directory invalid."),
-      ERRnofids: ("ERRnofids", "No file descriptors available"),
-      ERRnoaccess: ("ERRnoaccess", "Access denied."),
-      ERRbadfid: ("ERRbadfid", "Invalid file handle."),
-      ERRbadmcb: ("ERRbadmcb", "Memory control blocks destroyed."),
-      ERRnomem: ("ERRnomem", "Insufficient server memory to perform the 
requested function."),
-      ERRbadmem: ("ERRbadmem", "Invalid memory block address."),
-      ERRbadenv: ("ERRbadenv", "Invalid environment."),
-      11: ("ERRbadformat", "Invalid format."),
-      ERRbadaccess: ("ERRbadaccess", "Invalid open mode."),
-      ERRbaddata: ("ERRbaddata", "Invalid data."),
-      ERRres: ("ERRres", "reserved."),
-      ERRbaddrive: ("ERRbaddrive", "Invalid drive specified."),
-      ERRremcd: ("ERRremcd", "A Delete Directory request attempted  to  remove 
 the  server's  current directory."),
-      ERRdiffdevice: ("ERRdiffdevice", "Not same device."),
-      ERRnofiles: ("ERRnofiles", "A File Search command can find no more files 
matching the specified criteria."),
-      ERRbadshare: ("ERRbadshare", "The sharing mode specified for an Open 
conflicts with existing  FIDs  on the file."),
-      ERRlock: ("ERRlock", "A Lock request conflicted with an existing lock or 
specified an  invalid mode,  or an Unlock requested attempted to remove a lock 
held by another process."),
-      ERRunsup: ("ERRunsup",  "The operation is unsupported"),
-      ERRnosuchshare: ("ERRnosuchshare",  "You specified an invalid share 
name"),
-      ERRfilexists: ("ERRfilexists", "The file named in a Create Directory, 
Make  New  File  or  Link  request already exists."),
-      ERRinvalidname: ("ERRinvalidname",  "Invalid name"),
-      ERRbadpipe: ("ERRbadpipe", "Pipe invalid."),
-      ERRpipebusy: ("ERRpipebusy", "All instances of the requested pipe are 
busy."),
-      ERRpipeclosing: ("ERRpipeclosing", "Pipe close in progress."),
-      ERRnotconnected: ("ERRnotconnected", "No process on other end of pipe."),
-      ERRmoredata: ("ERRmoredata", "There is more data to be returned."),
-      ERRinvgroup: ("ERRinvgroup", "Invalid workgroup (try the -W option)"),
-      ERRlogonfailure: ("ERRlogonfailure", "Logon failure"),
-      ERRdiskfull: ("ERRdiskfull", "Disk full"),
-      ERRgeneral: ("ERRgeneral",  "General failure"),
-      ERRunknownlevel: ("ERRunknownlevel",  "Unknown info level")
-      }
-
-    server_msgs = {
-      1: ("ERRerror", "Non-specific error code."),
-      2: ("ERRbadpw", "Bad password - name/password pair in a Tree Connect or 
Session Setup are invalid."),
-      3: ("ERRbadtype", "reserved."),
-      4: ("ERRaccess", "The requester does not have  the  necessary  access  
rights  within  the specified  context for the requested function. The context 
is defined by the TID or the UID."),
-      5: ("ERRinvnid", "The tree ID (TID) specified in a command was 
invalid."),
-      6: ("ERRinvnetname", "Invalid network name in tree connect."),
-      7: ("ERRinvdevice", "Invalid device - printer request made to 
non-printer connection or  non-printer request made to printer connection."),
-      49: ("ERRqfull", "Print queue full (files) -- returned by open print 
file."),
-      50: ("ERRqtoobig", "Print queue full -- no space."),
-      51: ("ERRqeof", "EOF on print queue dump."),
-      52: ("ERRinvpfid", "Invalid print file FID."),
-      64: ("ERRsmbcmd", "The server did not recognize the command received."),
-      65: ("ERRsrverror","The server encountered an internal error, e.g., 
system file unavailable."),
-      67: ("ERRfilespecs", "The file handle (FID) and pathname parameters 
contained an invalid  combination of values."),
-      68: ("ERRreserved", "reserved."),
-      69: ("ERRbadpermits", "The access permissions specified for a file or 
directory are not a valid combination.  The server cannot set the requested 
attribute."),
-      70: ("ERRreserved", "reserved."),
-      71: ("ERRsetattrmode", "The attribute mode in the Set File Attribute 
request is invalid."),
-      81: ("ERRpaused", "Server is paused."),
-      82: ("ERRmsgoff", "Not receiving messages."),
-      83: ("ERRnoroom", "No room to buffer message."),
-      87: ("ERRrmuns", "Too many remote user names."),
-      88: ("ERRtimeout", "Operation timed out."),
-      89: ("ERRnoresource", "No resources currently available for request."),
-      90: ("ERRtoomanyuids", "Too many UIDs active on this session."),
-      91: ("ERRbaduid", "The UID is not known as a valid ID on this session."),
-      250: ("ERRusempx","Temp unable to support Raw, use MPX mode."),
-      251: ("ERRusestd","Temp unable to support Raw, use standard 
read/write."),
-      252: ("ERRcontmpx", "Continue in MPX mode."),
-      253: ("ERRreserved", "reserved."),
-      254: ("ERRreserved", "reserved."),
-  0xFFFF: ("ERRnosupport", "Function not supported.")
-  }
-    # Error clases
-
-    ERRDOS = 0x1
-    error_classes = { 0: ("SUCCESS", {}),
-                      ERRDOS: ("ERRDOS", dos_msgs),
-                      0x02: ("ERRSRV",server_msgs),
-                      0x03: ("ERRHRD",hard_msgs),
-                      0x04: ("ERRXOS", {} ),
-                      0xE1: ("ERRRMX1", {} ),
-                      0xE2: ("ERRRMX2", {} ),
-                      0xE3: ("ERRRMX3", {} ),
-                      0xFF: ("ERRCMD", {} ) }
-
-
-
-    def __init__( self, error_string, error_class, error_code, nt_status = 0):
-        Exception.__init__(self, error_string)
-        self.nt_status = nt_status
-        self._args = error_string
-        if nt_status:
-           self.error_class = 0
-           self.error_code  = (error_code << 16) + error_class
-        else:
-           self.error_class = error_class
-           self.error_code = error_code
-
-
-    def get_error_class( self ):
-        return self.error_class
-
-    def get_error_code( self ):
-        return self.error_code
-
-    def __str__( self ):
-        error_class = SessionError.error_classes.get( self.error_class, None )
-        if not error_class:
-            error_code_str = self.error_code
-            error_class_str = self.error_class
-        else:
-            error_class_str = error_class[0]
-            error_code = error_class[1].get( self.error_code, None )
-            if not error_code:
-                error_code_str = self.error_code
-            else:
-                error_code_str = '%s(%s)' % error_code
-
-        if self.nt_status:
-            return 'SMB SessionError: %s(%s)' % 
nt_errors.ERROR_MESSAGES[self.error_code]
-        else:
-            # Fall back to the old format
-            return 'SMB SessionError: class: %s, code: %s' % (error_class_str, 
error_code_str)
-
-
-# Raised when an supported feature is present/required in the protocol but is 
not
-# currently supported by pysmb
-class UnsupportedFeature(Exception): pass
-
-# Contains information about a SMB shared device/service
-class SharedDevice:
-    def __init__(self, name, share_type, comment):
-        self.__name = name
-        self.__type = share_type
-        self.__comment = comment
-
-    def get_name(self):
-        return self.__name
-
-    def get_type(self):
-        return self.__type
-
-    def get_comment(self):
-        return self.__comment
-
-    def __repr__(self):
-        return '<SharedDevice instance: name=' + self.__name + ', type=' + 
str(self.__type) + ', comment="' + self.__comment + '">'
-
-
-# Contains information about the shared file/directory
-class SharedFile:
-    def __init__(self, ctime, atime, mtime, filesize, allocsize, attribs, 
shortname, longname):
-        self.__ctime = ctime
-        self.__atime = atime
-        self.__mtime = mtime
-        self.__filesize = filesize
-        self.__allocsize = allocsize
-        self.__attribs = attribs
-        try:
-            self.__shortname = shortname[:string.index(shortname, '\0')]
-        except ValueError:
-            self.__shortname = shortname
-        try:
-            self.__longname = longname[:string.index(longname, '\0')]
-        except ValueError:
-            self.__longname = longname
-
-    def get_ctime(self):
-        return self.__ctime
-
-    def get_ctime_epoch(self):
-        return self.__convert_smbtime(self.__ctime)
-
-    def get_mtime(self):
-        return self.__mtime
-
-    def get_mtime_epoch(self):
-        return self.__convert_smbtime(self.__mtime)
-
-    def get_atime(self):
-        return self.__atime
-
-    def get_atime_epoch(self):
-        return self.__convert_smbtime(self.__atime)
-
-    def get_filesize(self):
-        return self.__filesize
-
-    def get_allocsize(self):
-        return self.__allocsize
-
-    def get_attributes(self):
-        return self.__attribs
-
-    def is_archive(self):
-        return self.__attribs & ATTR_ARCHIVE
-
-    def is_compressed(self):
-        return self.__attribs & ATTR_COMPRESSED
-
-    def is_normal(self):
-        return self.__attribs & ATTR_NORMAL
-
-    def is_hidden(self):
-        return self.__attribs & ATTR_HIDDEN
-
-    def is_readonly(self):
-        return self.__attribs & ATTR_READONLY
-
-    def is_temporary(self):
-        return self.__attribs & ATTR_TEMPORARY
-
-    def is_directory(self):
-        return self.__attribs & ATTR_DIRECTORY
-
-    def is_system(self):
-        return self.__attribs & ATTR_SYSTEM
-
-    def get_shortname(self):
-        return self.__shortname
-
-    def get_longname(self):
-        return self.__longname
-
-    def __repr__(self):
-        return '<SharedFile instance: shortname="' + self.__shortname + '", 
longname="' + self.__longname + '", filesize=' + str(self.__filesize) + '>'
-
-    @staticmethod
-    def __convert_smbtime(t):
-        x = t >> 32
-        y = t & 0xffffffff
-        geo_cal_offset = 11644473600.0  # = 369.0 * 365.25 * 24 * 60 * 60 - 
(3.0 * 24 * 60 * 60 + 6.0 * 60 * 60)
-        return (x * 4.0 * (1 << 30) + (y & 0xfff00000)) * 1.0e-7 - 
geo_cal_offset
-
-
-# Contain information about a SMB machine
-class SMBMachine:
-    def __init__(self, nbname, nbt_type, comment):
-        self.__nbname = nbname
-        self.__type = nbt_type
-        self.__comment = comment
-
-    def __repr__(self):
-        return '<SMBMachine instance: nbname="' + self.__nbname + '", type=' + 
hex(self.__type) + ', comment="' + self.__comment + '">'
-
-class SMBDomain:
-    def __init__(self, nbgroup, domain_type, master_browser):
-        self.__nbgroup = nbgroup
-        self.__type = domain_type
-        self.__master_browser = master_browser
-
-    def __repr__(self):
-        return '<SMBDomain instance: nbgroup="' + self.__nbgroup + '", type=' 
+ hex(self.__type) + ', master browser="' + self.__master_browser + '">'
-
-# Represents a SMB Packet
-class NewSMBPacket(Structure):
-    structure = (
-        ('Signature', '"\xffSMB'),
-        ('Command','B=0'),
-        ('ErrorClass','B=0'),
-        ('_reserved','B=0'),
-        ('ErrorCode','<H=0'),
-        ('Flags1','B=0'),
-        ('Flags2','<H=0'),
-        ('PIDHigh','<H=0'),
-        ('SecurityFeatures','8s=""'),
-        ('Reserved','<H=0'),
-        ('Tid','<H=0xffff'),
-        ('Pid','<H=0'),
-        ('Uid','<H=0'),
-        ('Mid','<H=0'),
-        ('Data','*:'),
-    )
-
-    def __init__(self, **kargs):
-        Structure.__init__(self, **kargs)
-
-        if ('Flags2' in self.fields) is False:
-             self['Flags2'] = 0
-        if ('Flags1' in self.fields) is False:
-             self['Flags1'] = 0
-
-        if 'data' not in kargs:
-            self['Data'] = []
-
-    def addCommand(self, command):
-        if len(self['Data']) == 0:
-            self['Command'] = command.command
-        else:
-            self['Data'][-1]['Parameters']['AndXCommand'] = command.command
-            self['Data'][-1]['Parameters']['AndXOffset'] = len(self)
-        self['Data'].append(command)
-
-    def isMoreData(self):
-        return (self['Command'] in [SMB.SMB_COM_TRANSACTION, 
SMB.SMB_COM_READ_ANDX, SMB.SMB_COM_READ_RAW] and
-                self['ErrorClass'] == 1 and self['ErrorCode'] == 
SessionError.ERRmoredata)
-
-    def isMoreProcessingRequired(self):
-        return self['ErrorClass'] == 0x16 and self['ErrorCode'] == 0xc000
-
-    def isValidAnswer(self, cmd):
-        # this was inside a loop reading more from the net (with 
recv_packet(None))
-        if self['Command'] == cmd:
-            if (self['ErrorClass'] == 0x00 and
-                self['ErrorCode']  == 0x00):
-                    return 1
-            elif self.isMoreData():
-                return 1
-            elif self.isMoreProcessingRequired():
-                return 1
-            raise SessionError("SMB Library Error", self['ErrorClass'] + 
(self['_reserved'] << 8), self['ErrorCode'], self['Flags2'] & 
SMB.FLAGS2_NT_STATUS)
-        else:
-            raise UnsupportedFeature("Unexpected answer from server: Got %d, 
Expected %d" % (self['Command'], cmd))
-
-
-class SMBCommand(Structure):
-    structure = (
-        ('WordCount', 'B=len(Parameters)/2'),
-        ('_ParametersLength','_-Parameters','WordCount*2'),
-        ('Parameters',':'),             # default set by constructor
-        ('ByteCount','<H-Data'),
-        ('Data',':'),                   # default set by constructor
-    )
-
-    def __init__(self, commandOrData = None, data = None, **kargs):
-        if type(commandOrData) == type(0):
-            self.command = commandOrData
-        else:
-            data = data or commandOrData
-
-        Structure.__init__(self, data = data, **kargs)
-
-        if data is None:
-            self['Parameters'] = ''
-            self['Data']       = ''
-
-class AsciiOrUnicodeStructure(Structure):
-    UnicodeStructure = ()
-    AsciiStructure   = ()
-    def __init__(self, flags = 0, **kargs):
-        if flags & SMB.FLAGS2_UNICODE:
-            self.structure = self.UnicodeStructure
-        else:
-            self.structure = self.AsciiStructure
-        Structure.__init__(self, **kargs)
-
-class SMBCommand_Parameters(Structure):
-    pass
-
-class SMBAndXCommand_Parameters(Structure):
-    commonHdr = (
-        ('AndXCommand','B=0xff'),
-        ('_reserved','B=0'),
-        ('AndXOffset','<H=0'),
-    )
-    structure = (       # default structure, overriden by subclasses
-        ('Data',':=""'),
-    )
-
-############# TRANSACTIONS RELATED
-# TRANS2_QUERY_FS_INFORMATION
-# QUERY_FS Information Levels
-# SMB_QUERY_FS_ATTRIBUTE_INFO
-class SMBQueryFsAttributeInfo(Structure):
-    structure = (
-        ('FileSystemAttributes','<L'),
-        ('MaxFilenNameLengthInBytes','<L'),
-        ('LengthOfFileSystemName','<L-FileSystemName'),
-        ('FileSystemName',':'),
-    )
-
-class SMBQueryFsInfoVolume(AsciiOrUnicodeStructure):
-    commonHdr = (
-        ('ulVolSerialNbr','<L=0xABCDEFAA'),
-        ('cCharCount','<B-VolumeLabel'),
-    )
-    AsciiStructure = (
-        ('VolumeLabel','z'),
-    )
-    UnicodeStructure = (
-        ('VolumeLabel','u'),
-    )
-
-# FILE_FS_SIZE_INFORMATION
-class FileFsSizeInformation(Structure):
-    structure = (
-        ('TotalAllocationUnits','<q=148529400'),
-        ('AvailableAllocationUnits','<q=14851044'),
-        ('SectorsPerAllocationUnit','<L=2'),
-        ('BytesPerSector','<L=512'),
-    )
-
-# SMB_QUERY_FS_SIZE_INFO
-class SMBQueryFsSizeInfo(Structure):
-    structure = (
-        ('TotalAllocationUnits','<q=148529400'),
-        ('TotalFreeAllocationUnits','<q=14851044'),
-        ('SectorsPerAllocationUnit','<L=2'),
-        ('BytesPerSector','<L=512'),
-    )
-# FILE_FS_FULL_SIZE_INFORMATION
-class SMBFileFsFullSizeInformation(Structure):
-    structure = (
-        ('TotalAllocationUnits','<q=148529400'),
-        ('CallerAvailableAllocationUnits','<q=148529400'),
-        ('ActualAvailableAllocationUnits','<q=148529400'),
-        ('SectorsPerAllocationUnit','<L=15'),
-        ('BytesPerSector','<L=512')
-    )
-# SMB_QUERY_FS_VOLUME_INFO
-class SMBQueryFsVolumeInfo(Structure):
-    structure = (
-        ('VolumeCreationTime','<q'),
-        ('SerialNumber','<L=0xABCDEFAA'),
-        ('VolumeLabelSize','<L=len(VolumeLabel)'),
-        ('Reserved','<H=0x10'),
-        ('VolumeLabel',':')
-    )
-# SMB_FIND_FILE_BOTH_DIRECTORY_INFO level
-class SMBFindFileBothDirectoryInfo(AsciiOrUnicodeStructure):
-    commonHdr = (
-        ('NextEntryOffset','<L=0'),
-        ('FileIndex','<L=0'),
-        ('CreationTime','<q'),
-        ('LastAccessTime','<q'),
-        ('LastWriteTime','<q'),
-        ('LastChangeTime','<q'),
-        ('EndOfFile','<q=0'),
-        ('AllocationSize','<q=0'),
-        ('ExtFileAttributes','<L=0'),
-    )
-    AsciiStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)'),
-        ('EaSize','<L=0'),
-        ('ShortNameLength','<B=0'),
-        ('Reserved','<B=0'),
-        ('ShortName','24s'),
-        ('FileName',':'),
-    )
-    UnicodeStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)*2'),
-        ('EaSize','<L=0'),
-        ('ShortNameLength','<B=0'),
-        ('Reserved','<B=0'),
-        ('ShortName','24s'),
-        ('FileName',':'),
-    )
-
-# SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO level
-class SMBFindFileIdFullDirectoryInfo(AsciiOrUnicodeStructure):
-    commonHdr = (
-        ('NextEntryOffset','<L=0'),
-        ('FileIndex','<L=0'),
-        ('CreationTime','<q'),
-        ('LastAccessTime','<q'),
-        ('LastWriteTime','<q'),
-        ('LastChangeTime','<q'),
-        ('EndOfFile','<q=0'),
-        ('AllocationSize','<q=0'),
-        ('ExtFileAttributes','<L=0'),
-    )
-    AsciiStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)'),
-        ('EaSize','<L=0'),
-        ('FileID','<q=0'),
-        ('FileName',':'),
-    )
-    UnicodeStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)*2'),
-        ('EaSize','<L=0'),
-        ('FileID','<q=0'),
-        ('FileName',':'),
-    )
-
-# SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO level
-class SMBFindFileIdBothDirectoryInfo(AsciiOrUnicodeStructure):
-    commonHdr = (
-        ('NextEntryOffset','<L=0'),
-        ('FileIndex','<L=0'),
-        ('CreationTime','<q'),
-        ('LastAccessTime','<q'),
-        ('LastWriteTime','<q'),
-        ('LastChangeTime','<q'),
-        ('EndOfFile','<q=0'),
-        ('AllocationSize','<q=0'),
-        ('ExtFileAttributes','<L=0'),
-    )
-    AsciiStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)'),
-        ('EaSize','<L=0'),
-        ('ShortNameLength','<B=0'),
-        ('Reserved','<B=0'),
-        ('ShortName','24s'),
-        ('Reserved','<H=0'),
-        ('FileID','<q=0'),
-        ('FileName','z'),
-    )
-    UnicodeStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)*2'),
-        ('EaSize','<L=0'),
-        ('ShortNameLength','<B=0'),
-        ('Reserved','<B=0'),
-        ('ShortName','24s'),
-        ('Reserved','<H=0'),
-        ('FileID','<q=0'),
-        ('FileName',':'),
-    )
-
-# SMB_FIND_FILE_DIRECTORY_INFO level
-class SMBFindFileDirectoryInfo(AsciiOrUnicodeStructure):
-    commonHdr = (
-        ('NextEntryOffset','<L=0'),
-        ('FileIndex','<L=0'),
-        ('CreationTime','<q'),
-        ('LastAccessTime','<q'),
-        ('LastWriteTime','<q'),
-        ('LastChangeTime','<q'),
-        ('EndOfFile','<q=0'),
-        ('AllocationSize','<q=1'),
-        ('ExtFileAttributes','<L=0'),
-    )
-    AsciiStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)'),
-        ('FileName','z'),
-    )
-    UnicodeStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)*2'),
-        ('FileName',':'),
-    )
-
-# SMB_FIND_FILE_NAMES_INFO level
-class SMBFindFileNamesInfo(AsciiOrUnicodeStructure):
-    commonHdr = (
-        ('NextEntryOffset','<L=0'),
-        ('FileIndex','<L=0'),
-    )
-    AsciiStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)'),
-        ('FileName','z'),
-    )
-    UnicodeStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)*2'),
-        ('FileName',':'),
-    )
-
-# SMB_FIND_FILE_FULL_DIRECTORY_INFO level
-class SMBFindFileFullDirectoryInfo(AsciiOrUnicodeStructure):
-    commonHdr = (
-        ('NextEntryOffset','<L=0'),
-        ('FileIndex','<L=0'),
-        ('CreationTime','<q'),
-        ('LastAccessTime','<q'),
-        ('LastWriteTime','<q'),
-        ('LastChangeTime','<q'),
-        ('EndOfFile','<q=0'),
-        ('AllocationSize','<q=1'),
-        ('ExtFileAttributes','<L=0'),
-    )
-    AsciiStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)'),
-        ('EaSize','<L'),
-        ('FileName','z'),
-    )
-    UnicodeStructure = (
-        ('FileNameLength','<L-FileName','len(FileName)*2'),
-        ('EaSize','<L'),
-        ('FileName',':'),
-    )
-
-# SMB_FIND_INFO_STANDARD level
-class SMBFindInfoStandard(AsciiOrUnicodeStructure):
-    commonHdr = (
-        ('ResumeKey','<L=0xff'),
-        ('CreationDate','<H=0'),
-        ('CreationTime','<H=0'),
-        ('LastAccessDate','<H=0'),
-        ('LastAccessTime','<H=0'),
-        ('LastWriteDate','<H=0'),
-        ('LastWriteTime','<H=0'),
-        ('EaSize','<L'),
-        ('AllocationSize','<L=1'),
-        ('ExtFileAttributes','<H=0'),
-    )
-    AsciiStructure = (
-        ('FileNameLength','<B-FileName','len(FileName)'),
-        ('FileName','z'),
-    )
-    UnicodeStructure = (
-        ('FileNameLength','<B-FileName','len(FileName)*2'),
-        ('FileName',':'),
-    )
-
-# SET_FILE_INFORMATION structures
-# SMB_SET_FILE_DISPOSITION_INFO
-class SMBSetFileDispositionInfo(Structure):
-    structure = (
-        ('DeletePending','<B'),
-    )
-
-# SMB_SET_FILE_BASIC_INFO
-class SMBSetFileBasicInfo(Structure):
-    structure = (
-        ('CreationTime','<q'),
-        ('LastAccessTime','<q'),
-        ('LastWriteTime','<q'),
-        ('ChangeTime','<q'),
-        ('ExtFileAttributes','<H'),
-        ('Reserved','<L'),
-    )
-
-# FILE_STREAM_INFORMATION
-class SMBFileStreamInformation(Structure):
-    commonHdr = (
-        ('NextEntryOffset','<L=0'),
-        ('StreamNameLength','<L=0'),
-        ('StreamSize','<q=0'),
-        ('StreamAllocationSize','<q=0'),
-        ('StreamName',':=""'),
-    )
-
-# FILE_NETWORK_OPEN_INFORMATION
-class SMBFileNetworkOpenInfo(Structure):
-    structure = (
-        ('CreationTime','<q=0'),
-        ('LastAccessTime','<q=0'),
-        ('LastWriteTime','<q=0'),
-        ('ChangeTime','<q=0'),
-        ('AllocationSize','<q=0'),
-        ('EndOfFile','<q=0'),
-        ('FileAttributes','<L=0'),
-        ('Reserved','<L=0'),
-    )
-
-# SMB_SET_FILE_END_OF_FILE_INFO
-class SMBSetFileEndOfFileInfo(Structure):
-    structure = (
-        ('EndOfFile','<q'),
-    )
-
-# TRANS2_FIND_NEXT2
-class SMBFindNext2_Parameters(AsciiOrUnicodeStructure):
-     commonHdr = (
-         ('SID','<H'),
-         ('SearchCount','<H'),
-         ('InformationLevel','<H'),
-         ('ResumeKey','<L'),
-         ('Flags','<H'),
-     )
-     AsciiStructure = (
-         ('FileName','z'),
-     )
-     UnicodeStructure = (
-         ('FileName','u'),
-     )
-
-class SMBFindNext2Response_Parameters(Structure):
-     structure = (
-         ('SearchCount','<H'),
-         ('EndOfSearch','<H=1'),
-         ('EaErrorOffset','<H=0'),
-         ('LastNameOffset','<H=0'),
-     )
-
-class SMBFindNext2_Data(Structure):
-     structure = (
-         ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 
'self["GetExtendedAttributesListLength"]'),
-         ('GetExtendedAttributesList',':'),
-     )
-
-
-# TRANS2_FIND_FIRST2 
-class SMBFindFirst2Response_Parameters(Structure):
-     structure = (
-         ('SID','<H'),
-         ('SearchCount','<H'),
-         ('EndOfSearch','<H=1'),
-         ('EaErrorOffset','<H=0'),
-         ('LastNameOffset','<H=0'),
-     )
-
-class SMBFindFirst2_Parameters(AsciiOrUnicodeStructure):
-     commonHdr = (
-         ('SearchAttributes','<H'),
-         ('SearchCount','<H'),
-         ('Flags','<H'),
-         ('InformationLevel','<H'),
-         ('SearchStorageType','<L'),
-     )
-     AsciiStructure = (
-         ('FileName','z'),
-     )
-     UnicodeStructure = (
-         ('FileName','u'),
-     )
-
-class SMBFindFirst2_Data(Structure):
-     structure = (
-         ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 
'self["GetExtendedAttributesListLength"]'),
-         ('GetExtendedAttributesList',':'),
-     )
-
-# TRANS2_SET_PATH_INFORMATION
-class SMBSetPathInformation_Parameters(AsciiOrUnicodeStructure):
-    commonHdr = (
-        ('InformationLevel','<H'),
-        ('Reserved','<L'),
-    )
-    AsciiStructure = (
-        ('FileName','z'),
-    )
-    UnicodeStructure = (
-        ('FileName','u'),
-    )
-
-class SMBSetPathInformationResponse_Parameters(Structure):
-    structure = (
-        ('EaErrorOffset','<H=0'),
-    )
-
-# TRANS2_SET_FILE_INFORMATION
-class SMBSetFileInformation_Parameters(Structure):
-    structure = (
-        ('FID','<H'),
-        ('InformationLevel','<H'),
-        ('Reserved','<H'),
-    )
-
-class SMBSetFileInformationResponse_Parameters(Structure):
-    structure = (
-        ('EaErrorOffset','<H=0'),
-    )
-
-# TRANS2_QUERY_FILE_INFORMATION
-class SMBQueryFileInformation_Parameters(Structure):
-    structure = (
-        ('FID','<H'),
-        ('InformationLevel','<H'),
-    )
-
-class SMBQueryFileInformationResponse_Parameters(Structure):
-    structure = (
-        ('EaErrorOffset','<H=0'),
-    )
-
-class SMBQueryFileInformation_Data(Structure):
-    structure = (
-        ('GetExtendedAttributeList',':'),
-    )
-
-# TRANS2_QUERY_PATH_INFORMATION
-class SMBQueryPathInformationResponse_Parameters(Structure):
-    structure = (
-        ('EaErrorOffset','<H=0'),
-    )
-
-class SMBQueryPathInformation_Parameters(AsciiOrUnicodeStructure):
-    commonHdr = (
-        ('InformationLevel','<H'),
-        ('Reserved','<L=0'),
-    )
-    AsciiStructure = (
-        ('FileName','z'),
-    )
-    UnicodeStructure = (
-        ('FileName','u'),
-    )
-
-class SMBQueryPathInformation_Data(Structure):
-    structure = (
-        ('GetExtendedAttributeList',':'),
-    )
-
-
-# SMB_QUERY_FILE_EA_INFO
-class SMBQueryFileEaInfo(Structure):
-    structure = (
-        ('EaSize','<L=0'),
-    )
-
-# SMB_QUERY_FILE_BASIC_INFO
-class SMBQueryFileBasicInfo(Structure):
-    structure = (
-        ('CreationTime','<q'),
-        ('LastAccessTime','<q'),
-        ('LastWriteTime','<q'),
-        ('LastChangeTime','<q'),
-        ('ExtFileAttributes','<L'),
-        #('Reserved','<L=0'),
-    )
-
-# SMB_QUERY_FILE_STANDARD_INFO
-class SMBQueryFileStandardInfo(Structure):
-    structure = (
-        ('AllocationSize','<q'),
-        ('EndOfFile','<q'),
-        ('NumberOfLinks','<L=0'),
-        ('DeletePending','<B=0'),
-        ('Directory','<B'),
-    )
-
-# SMB_QUERY_FILE_ALL_INFO
-class SMBQueryFileAllInfo(Structure):
-    structure = (
-        ('CreationTime','<q'),
-        ('LastAccessTime','<q'),
-        ('LastWriteTime','<q'),
-        ('LastChangeTime','<q'),
-        ('ExtFileAttributes','<L'),
-        ('Reserved','<L=0'),
-        ('AllocationSize','<q'),
-        ('EndOfFile','<q'),
-        ('NumberOfLinks','<L=0'),
-        ('DeletePending','<B=0'),
-        ('Directory','<B'),
-        ('Reserved','<H=0'),
-        ('EaSize','<L=0'),
-        ('FileNameLength','<L-FileName','len(FileName)'),
-        ('FileName',':'),
-    )
-
-# \PIPE\LANMAN NetShareEnum
-class SMBNetShareEnum(Structure):
-    structure = (
-        ('RAPOpcode','<H=0'),
-        ('ParamDesc','z'),
-        ('DataDesc','z'),
-        ('InfoLevel','<H'),
-        ('ReceiveBufferSize','<H'),
-    )
-
-class SMBNetShareEnumResponse(Structure):
-    structure = (
-        ('Status','<H=0'),
-        ('Convert','<H=0'),
-        ('EntriesReturned','<H'),
-        ('EntriesAvailable','<H'),
-    )
-
-class NetShareInfo1(Structure):
-    structure = (
-        ('NetworkName','13s'),
-        ('Pad','<B=0'),
-        ('Type','<H=0'),
-        ('RemarkOffsetLow','<H=0'),
-        ('RemarkOffsetHigh','<H=0'),
-    )
-
-# \PIPE\LANMAN NetServerGetInfo
-class SMBNetServerGetInfoResponse(Structure):
-    structure = (
-        ('Status','<H=0'),
-        ('Convert','<H=0'),
-        ('TotalBytesAvailable','<H'),
-    )
-
-class SMBNetServerInfo1(Structure):
-    # Level 1 Response
-    structure = (
-        ('ServerName','16s'),
-        ('MajorVersion','B=5'),
-        ('MinorVersion','B=0'),
-        ('ServerType','<L=3'),
-        ('ServerCommentLow','<H=0'),
-        ('ServerCommentHigh','<H=0'),
-    )
-
-# \PIPE\LANMAN NetShareGetInfo
-class SMBNetShareGetInfo(Structure):
-    structure = (
-        ('RAPOpcode','<H=0'),
-        ('ParamDesc','z'),
-        ('DataDesc','z'),
-        ('ShareName','z'),
-        ('InfoLevel','<H'),
-        ('ReceiveBufferSize','<H'),
-    )
-
-class SMBNetShareGetInfoResponse(Structure):
-    structure = (
-        ('Status','<H=0'),
-        ('Convert','<H=0'),
-        ('TotalBytesAvailable','<H'),
-    )
-
-############# Security Features
-class SecurityFeatures(Structure):
-    structure = (
-        ('Key','<L=0'),
-        ('CID','<H=0'),
-        ('SequenceNumber','<H=0'),
-    )
-
-############# SMB_COM_QUERY_INFORMATION2 (0x23)
-class SMBQueryInformation2_Parameters(Structure):
-    structure = (
-        ('Fid','<H'),
-    )
-
-class SMBQueryInformation2Response_Parameters(Structure):
-    structure = (
-        ('CreateDate','<H'),
-        ('CreationTime','<H'),
-        ('LastAccessDate','<H'),
-        ('LastAccessTime','<H'),
-        ('LastWriteDate','<H'),
-        ('LastWriteTime','<H'),
-        ('FileDataSize','<L'),
-        ('FileAllocationSize','<L'),
-        ('FileAttributes','<L'),
-    )
-
-
-
-############# SMB_COM_SESSION_SETUP_ANDX (0x73)
-class SMBSessionSetupAndX_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('MaxBuffer','<H'),
-        ('MaxMpxCount','<H'),
-        ('VCNumber','<H'),
-        ('SessionKey','<L'),
-        ('AnsiPwdLength','<H'),
-        ('UnicodePwdLength','<H'),
-        ('_reserved','<L=0'),
-        ('Capabilities','<L'),
-    )
-
-class SMBSessionSetupAndX_Extended_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('MaxBufferSize','<H'),
-        ('MaxMpxCount','<H'),
-        ('VcNumber','<H'),
-        ('SessionKey','<L'),
-        ('SecurityBlobLength','<H'),
-        ('Reserved','<L=0'),
-        ('Capabilities','<L'),
-    )
-
-class SMBSessionSetupAndX_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'),
-        ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'),
-        ('AnsiPwd',':=""'),
-        ('UnicodePwd',':=""'),
-        ('Account','z=""'),
-        ('PrimaryDomain','z=""'),
-        ('NativeOS','z=""'),
-        ('NativeLanMan','z=""'),
-    )
-
-    UnicodeStructure = (
-        ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'),
-        ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'),
-        ('AnsiPwd',':=""'),
-        ('UnicodePwd',':=""'),
-        ('Account','u=""'),
-        ('PrimaryDomain','u=""'),
-        ('NativeOS','u=""'),
-        ('NativeLanMan','u=""'),
-    )
-
-class SMBSessionSetupAndX_Extended_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
-        ('SecurityBlob',':'),
-        ('NativeOS','z=""'),
-        ('NativeLanMan','z=""'),
-    )
-
-    UnicodeStructure = (
-        ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
-        ('SecurityBlob',':'),
-        ('NativeOS','u=""'),
-        ('NativeLanMan','u=""'),
-    )
-
-class SMBSessionSetupAndXResponse_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('Action','<H'),
-    )
-
-class 
SMBSessionSetupAndX_Extended_Response_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('Action','<H=0'),
-        ('SecurityBlobLength','<H'),
-    )
-
-class SMBSessionSetupAndXResponse_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('NativeOS','z=""'),
-        ('NativeLanMan','z=""'),
-        ('PrimaryDomain','z=""'),
-    )
-
-    UnicodeStructure = (
-        ('NativeOS','u=""'),
-        ('NativeLanMan','u=""'),
-        ('PrimaryDomain','u=""'),
-    )
-
-class SMBSessionSetupAndX_Extended_Response_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
-        ('SecurityBlob',':'),
-        ('NativeOS','z=""'),
-        ('NativeLanMan','z=""'),
-    )
-
-    UnicodeStructure = (
-        ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
-        ('SecurityBlob',':'),
-        ('NativeOS','u=""'),
-        ('NativeLanMan','u=""'),
-    )
-
-############# SMB_COM_TREE_CONNECT (0x70)
-class SMBTreeConnect_Parameters(SMBCommand_Parameters):
-    structure = (
-    )
-
-class SMBTreeConnect_Data(SMBCommand_Parameters):
-    structure = (
-        ('PathFormat','"\x04'),
-        ('Path','z'),
-        ('PasswordFormat','"\x04'),
-        ('Password','z'),
-        ('ServiceFormat','"\x04'),
-        ('Service','z'),
-    )
-
-############# SMB_COM_TREE_CONNECT_ANDX (0x75)
-class SMBTreeConnectAndX_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('Flags','<H=0'),
-        ('PasswordLength','<H'),
-    )
-
-class SMBTreeConnectAndXResponse_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('OptionalSupport','<H=0'),
-    )
-
-class SMBTreeConnectAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('OptionalSupport','<H=1'),
-        ('MaximalShareAccessRights','<L=0x1fffff'),
-        ('GuestMaximalShareAccessRights','<L=0x1fffff'),
-    )
-
-class SMBTreeConnectAndX_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('_PasswordLength','_-Password','self["_PasswordLength"]'),
-        ('Password',':'),
-        ('Path','z'),
-        ('Service','z'),
-    )
-
-    UnicodeStructure = (
-        ('_PasswordLength','_-Password','self["_PasswordLength"] if 
self["_PasswordLength"] > 0 else 1'),
-        ('Password',':'),
-        ('Path','u'),
-        ('Service','z'),
-    )
-
-class SMBTreeConnectAndXResponse_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('Service','z'),
-        ('PadLen','_-Pad','self["PadLen"]'),
-        ('Pad',':=""'),
-        ('NativeFileSystem','z'),
-    )
-    UnicodeStructure = (
-        ('Service','z'),
-        ('PadLen','_-Pad','self["PadLen"]'),
-        ('Pad',':=""'),
-        ('NativeFileSystem','u'),
-    )
-
-############# SMB_COM_NT_CREATE_ANDX (0xA2)
-class SMBNtCreateAndX_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('_reserved', 'B=0'),
-        ('FileNameLength','<H'),     # NameLength
-        ('CreateFlags','<L'),        # Flags
-        ('RootFid','<L=0'),          # RootDirectoryFID
-        ('AccessMask','<L'),         # DesiredAccess
-        ('AllocationSizeLo','<L=0'), # AllocationSize
-        ('AllocationSizeHi','<L=0'),
-        ('FileAttributes','<L=0'),   # ExtFileAttributes
-        ('ShareAccess','<L=3'),      #
-        ('Disposition','<L=1'),      # CreateDisposition
-        ('CreateOptions','<L'),      # CreateOptions
-        ('Impersonation','<L=2'),
-        ('SecurityFlags','B=3'),
-    )
-
-class SMBNtCreateAndXResponse_Parameters(SMBAndXCommand_Parameters):
-    # XXX Is there a memory leak in the response for NTCreate (where the Data 
section would be) in Win 2000, Win XP, and Win 2003?
-    structure = (
-        ('OplockLevel', 'B=0'),
-        ('Fid','<H'),
-        ('CreateAction','<L'),
-        ('CreateTime','<q=0'),
-        ('LastAccessTime','<q=0'),
-        ('LastWriteTime','<q=0'),
-        ('LastChangeTime','<q=0'),
-        ('FileAttributes','<L=0x80'),
-        ('AllocationSize','<q=0'),
-        ('EndOfFile','<q=0'),
-        ('FileType','<H=0'),
-        ('IPCState','<H=0'),
-        ('IsDirectory','B'),
-    )
-
-class SMBNtCreateAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters):
-    # [MS-SMB] Extended response description
-    structure = (
-        ('OplockLevel', 'B=0'),
-        ('Fid','<H'),
-        ('CreateAction','<L'),
-        ('CreateTime','<q=0'),
-        ('LastAccessTime','<q=0'),
-        ('LastWriteTime','<q=0'),
-        ('LastChangeTime','<q=0'),
-        ('FileAttributes','<L=0x80'),
-        ('AllocationSize','<q=0'),
-        ('EndOfFile','<q=0'),
-        ('FileType','<H=0'),
-        ('IPCState','<H=0'),
-        ('IsDirectory','B'),
-        ('VolumeGUID','16s'),
-        ('FileIdLow','<L=0'),
-        ('FileIdHigh','<L=0'),
-        ('MaximalAccessRights','<L=0x12019b'),
-        ('GuestMaximalAccessRights','<L=0x120089'),
-    )
-
-class SMBNtCreateAndX_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('FileName','z'),
-    )
-    UnicodeStructure = (
-        ('Pad','B'),
-        ('FileName','u'),
-    )
-
-############# SMB_COM_OPEN_ANDX (0xD2)
-class SMBOpenAndX_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('Flags','<H=0'),
-        ('DesiredAccess','<H=0'),
-        ('SearchAttributes','<H=0'),
-        ('FileAttributes','<H=0'),
-        ('CreationTime','<L=0'),
-        ('OpenMode','<H=1'),        # SMB_O_OPEN = 1
-        ('AllocationSize','<L=0'),
-        ('Reserved','8s=""'),
-    )
-
-class SMBOpenAndX_Data(SMBNtCreateAndX_Data):
-    pass
-
-class SMBOpenAndXResponse_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('Fid','<H=0'),
-        ('FileAttributes','<H=0'),
-        ('LastWriten','<L=0'),
-        ('FileSize','<L=0'),
-        ('GrantedAccess','<H=0'),
-        ('FileType','<H=0'),
-        ('IPCState','<H=0'),
-        ('Action','<H=0'),
-        ('ServerFid','<L=0'),
-        ('_reserved','<H=0'),
-    )
-
-############# SMB_COM_WRITE (0x0B)
-class SMBWrite_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('Fid','<H'),
-        ('Count','<H'),
-        ('Offset','<L'),
-        ('Remaining','<H'),
-    )
-
-class SMBWriteResponse_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('Count','<H'),
-    )
-
-class SMBWrite_Data(Structure):
-    structure = (
-        ('BufferFormat','<B=1'),
-        ('DataLength','<H-Data'),
-        ('Data',':'),
-    )
-
-
-############# SMB_COM_WRITE_ANDX (0x2F)
-class SMBWriteAndX_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('Fid','<H=0'),
-        ('Offset','<L=0'),
-        ('_reserved','<L=0xff'),
-        ('WriteMode','<H=8'),
-        ('Remaining','<H=0'),
-        ('DataLength_Hi','<H=0'),
-        ('DataLength','<H=0'),
-        ('DataOffset','<H=0'),
-        ('HighOffset','<L=0'),
-    )
-
-class SMBWriteAndX_Data_Short(Structure):
-     structure = (
-         ('_PadLen','_-Pad','self["DataOffset"] - 59'),
-         ('Pad',':'),
-         #('Pad','<B=0'),
-         ('DataLength','_-Data','self["DataLength"]'),
-         ('Data',':'),
-     )
-
-class SMBWriteAndX_Data(Structure):
-     structure = (
-         ('_PadLen','_-Pad','self["DataOffset"] - 63'),
-         ('Pad',':'),
-         #('Pad','<B=0'),
-         ('DataLength','_-Data','self["DataLength"]'),
-         ('Data',':'),
-     )
-
-
-class SMBWriteAndX_Parameters_Short(SMBAndXCommand_Parameters):
-    structure = (
-        ('Fid','<H'),
-        ('Offset','<L'),
-        ('_reserved','<L=0xff'),
-        ('WriteMode','<H=8'),
-        ('Remaining','<H'),
-        ('DataLength_Hi','<H=0'),
-        ('DataLength','<H'),
-        ('DataOffset','<H=0'),
-    )
-
-class SMBWriteAndXResponse_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('Count','<H'),
-        ('Available','<H'),
-        ('Reserved','<L=0'),
-    )
-
-############# SMB_COM_WRITE_RAW (0x1D)
-class SMBWriteRaw_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('Fid','<H'),
-        ('Count','<H'),
-        ('_reserved','<H=0'),
-        ('Offset','<L'),
-        ('Timeout','<L=0'),
-        ('WriteMode','<H=0'),
-        ('_reserved2','<L=0'),
-        ('DataLength','<H'),
-        ('DataOffset','<H=0'),
-    )
-
-############# SMB_COM_READ (0x0A)
-class SMBRead_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('Fid','<H'),
-        ('Count','<H'),
-        ('Offset','<L'),
-        ('Remaining','<H=Count'),
-    )
-
-class SMBReadResponse_Parameters(Structure):
-    structure = (
-        ('Count','<H=0'),
-        ('_reserved','8s=""'),
-    )
-
-class SMBReadResponse_Data(Structure):
-    structure = (
-        ('BufferFormat','<B=0x1'),
-        ('DataLength','<H-Data'),
-        ('Data',':'),
-    )
-
-############# SMB_COM_READ_RAW (0x1A)
-class SMBReadRaw_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('Fid','<H'),
-        ('Offset','<L'),
-        ('MaxCount','<H'),
-        ('MinCount','<H=MaxCount'),
-        ('Timeout','<L=0'),
-        ('_reserved','<H=0'),
-    )
-
-############# SMB_COM_NT_TRANSACT  (0xA0)
-class SMBNTTransaction_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('MaxSetupCount','<B=0'),
-        ('Reserved1','<H=0'),
-        ('TotalParameterCount','<L'),
-        ('TotalDataCount','<L'),
-        ('MaxParameterCount','<L=1024'),
-        ('MaxDataCount','<L=65504'),
-        ('ParameterCount','<L'),
-        ('ParameterOffset','<L'),
-        ('DataCount','<L'),
-        ('DataOffset','<L'),
-        ('SetupCount','<B=len(Setup)/2'),
-        ('Function','<H=0'),
-        ('SetupLength','_-Setup','SetupCount*2'),
-        ('Setup',':'),
-    )
-
-class SMBNTTransactionResponse_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('Reserved1','3s=""'),
-        ('TotalParameterCount','<L'),
-        ('TotalDataCount','<L'),
-        ('ParameterCount','<L'),
-        ('ParameterOffset','<L'),
-        ('ParameterDisplacement','<L=0'),
-        ('DataCount','<L'),
-        ('DataOffset','<L'),
-        ('DataDisplacement','<L=0'),
-        ('SetupCount','<B=0'),
-        ('SetupLength','_-Setup','SetupCount*2'),
-        ('Setup',':'),
-    )
-
-class SMBNTTransaction_Data(Structure):
-    structure = (
-        ('Pad1Length','_-Pad1','self["Pad1Length"]'),
-        ('Pad1',':'),
-        
('NT_Trans_ParametersLength','_-NT_Trans_Parameters','self["NT_Trans_ParametersLength"]'),
-        ('NT_Trans_Parameters',':'),
-        ('Pad2Length','_-Pad2','self["Pad2Length"]'),
-        ('Pad2',':'),
-        
('NT_Trans_DataLength','_-NT_Trans_Data','self["NT_Trans_DataLength"]'),
-        ('NT_Trans_Data',':'),
-    )
-
-class SMBNTTransactionResponse_Data(Structure):
-    structure = (
-        ('Pad1Length','_-Pad1','self["Pad1Length"]'),
-        ('Pad1',':'),
-        
('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
-        ('Trans_Parameters',':'),
-        ('Pad2Length','_-Pad2','self["Pad2Length"]'),
-        ('Pad2',':'),
-        ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
-        ('Trans_Data',':'),
-    )
-
-
-############# SMB_COM_TRANSACTION2_SECONDARY (0x33)
-class SMBTransaction2Secondary_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('TotalParameterCount','<H'),
-        ('TotalDataCount','<H'),
-        ('ParameterCount','<H'),
-        ('ParameterOffset','<H'),
-        ('DataCount','<H'),
-        ('DataOffset','<H'),
-        ('DataDisplacement','<H=0'),
-        ('FID','<H'),
-    )
-
-class SMBTransaction2Secondary_Data(Structure):
-    structure = (
-        ('Pad1Length','_-Pad1','self["Pad1Length"]'),
-        ('Pad1',':'),
-        
('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
-        ('Trans_Parameters',':'),
-        ('Pad2Length','_-Pad2','self["Pad2Length"]'),
-        ('Pad2',':'),
-        ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
-        ('Trans_Data',':'),
-    )
-
-
-############# SMB_COM_TRANSACTION2 (0x32)
-
-class SMBTransaction2_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('TotalParameterCount','<H'),
-        ('TotalDataCount','<H'),
-        ('MaxParameterCount','<H=1024'),
-        ('MaxDataCount','<H=65504'),
-        ('MaxSetupCount','<B=0'),
-        ('Reserved1','<B=0'),
-        ('Flags','<H=0'),
-        ('Timeout','<L=0'),
-        ('Reserved2','<H=0'),
-        ('ParameterCount','<H'),
-        ('ParameterOffset','<H'),
-        ('DataCount','<H'),
-        ('DataOffset','<H'),
-        ('SetupCount','<B=len(Setup)/2'),
-        ('Reserved3','<B=0'),
-        ('SetupLength','_-Setup','SetupCount*2'),
-        ('Setup',':'),
-    )
-
-class SMBTransaction2Response_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('TotalParameterCount','<H'),
-        ('TotalDataCount','<H'),
-        ('Reserved1','<H=0'),
-        ('ParameterCount','<H'),
-        ('ParameterOffset','<H'),
-        ('ParameterDisplacement','<H=0'),
-        ('DataCount','<H'),
-        ('DataOffset','<H'),
-        ('DataDisplacement','<H=0'),
-        ('SetupCount','<B=0'),
-        ('Reserved2','<B=0'),
-        ('SetupLength','_-Setup','SetupCount*2'),
-        ('Setup',':'),
-    )
-
-class SMBTransaction2_Data(Structure):
-    structure = (
-#        ('NameLength','_-Name','1'),
-#        ('Name',':'),
-        ('Pad1Length','_-Pad1','self["Pad1Length"]'),
-        ('Pad1',':'),
-        
('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
-        ('Trans_Parameters',':'),
-        ('Pad2Length','_-Pad2','self["Pad2Length"]'),
-        ('Pad2',':'),
-        ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
-        ('Trans_Data',':'),
-    )
-
-class SMBTransaction2Response_Data(Structure):
-    structure = (
-        ('Pad1Length','_-Pad1','self["Pad1Length"]'),
-        ('Pad1',':'),
-        
('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
-        ('Trans_Parameters',':'),
-        ('Pad2Length','_-Pad2','self["Pad2Length"]'),
-        ('Pad2',':'),
-        ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
-        ('Trans_Data',':'),
-    )
-
-############# SMB_COM_QUERY_INFORMATION (0x08)
-
-class SMBQueryInformation_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('BufferFormat','B=4'),
-        ('FileName','z'),
-    )
-    UnicodeStructure = (
-        ('BufferFormat','B=4'),
-        ('FileName','u'),
-    )
-
-
-class SMBQueryInformationResponse_Parameters(Structure):
-    structure = (
-        ('FileAttributes','<H'),
-        ('LastWriteTime','<L'),
-        ('FileSize','<L'),
-        ('Reserved','"0123456789'),
-    )
-
-############# SMB_COM_TRANSACTION (0x25)
-class SMBTransaction_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('TotalParameterCount','<H'),
-        ('TotalDataCount','<H'),
-        ('MaxParameterCount','<H=1024'),
-        ('MaxDataCount','<H=65504'),
-        ('MaxSetupCount','<B=0'),
-        ('Reserved1','<B=0'),
-        ('Flags','<H=0'),
-        ('Timeout','<L=0'),
-        ('Reserved2','<H=0'),
-        ('ParameterCount','<H'),
-        ('ParameterOffset','<H'),
-        ('DataCount','<H'),
-        ('DataOffset','<H'),
-        ('SetupCount','<B=len(Setup)/2'),
-        ('Reserved3','<B=0'),
-        ('SetupLength','_-Setup','SetupCount*2'),
-        ('Setup',':'),
-    )
-
-class SMBTransactionResponse_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('TotalParameterCount','<H'),
-        ('TotalDataCount','<H'),
-        ('Reserved1','<H=0'),
-        ('ParameterCount','<H'),
-        ('ParameterOffset','<H'),
-        ('ParameterDisplacement','<H=0'),
-        ('DataCount','<H'),
-        ('DataOffset','<H'),
-        ('DataDisplacement','<H=0'),
-        ('SetupCount','<B'),
-        ('Reserved2','<B=0'),
-        ('SetupLength','_-Setup','SetupCount*2'),
-        ('Setup',':'),
-    )
-
-# TODO: We should merge these both. But this will require fixing
-# the instances where this structure is used on the client side
-class SMBTransaction_SData(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('Name','z'),
-        ('Trans_ParametersLength','_-Trans_Parameters'),
-        ('Trans_Parameters',':'),
-        ('Trans_DataLength','_-Trans_Data'),
-        ('Trans_Data',':'),
-    )
-    UnicodeStructure = (
-        ('Pad','B'),
-        ('Name','u'),
-        ('Trans_ParametersLength','_-Trans_Parameters'),
-        ('Trans_Parameters',':'),
-        ('Trans_DataLength','_-Trans_Data'),
-        ('Trans_Data',':'),
-    )
-
-class SMBTransaction_Data(Structure):
-    structure = (
-        ('NameLength','_-Name'),
-        ('Name',':'),
-        ('Trans_ParametersLength','_-Trans_Parameters'),
-        ('Trans_Parameters',':'),
-        ('Trans_DataLength','_-Trans_Data'),
-        ('Trans_Data',':'),
-    )
-
-class SMBTransactionResponse_Data(Structure):
-    structure = (
-        ('Trans_ParametersLength','_-Trans_Parameters'),
-        ('Trans_Parameters',':'),
-        ('Trans_DataLength','_-Trans_Data'),
-        ('Trans_Data',':'),
-    )
-
-############# SMB_COM_READ_ANDX (0x2E)
-class SMBReadAndX_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('Fid','<H'),
-        ('Offset','<L'),
-        ('MaxCount','<H'),
-        ('MinCount','<H=MaxCount'),
-        ('_reserved','<L=0x0'),
-        ('Remaining','<H=MaxCount'),
-        ('HighOffset','<L=0'),
-    )
-
-class SMBReadAndX_Parameters2(SMBAndXCommand_Parameters):
-    structure = (
-        ('Fid','<H'),
-        ('Offset','<L'),
-        ('MaxCount','<H'),
-        ('MinCount','<H=MaxCount'),
-        ('_reserved','<L=0xffffffff'),
-        ('Remaining','<H=MaxCount'),
-    )
-
-class SMBReadAndXResponse_Parameters(SMBAndXCommand_Parameters):
-    structure = (
-        ('Remaining','<H=0'),
-        ('DataMode','<H=0'),
-        ('_reserved','<H=0'),
-        ('DataCount','<H'),
-        ('DataOffset','<H'),
-        ('DataCount_Hi','<L'),
-        ('_reserved2','6s=""'),
-    )
-
-############# SMB_COM_ECHO (0x2B)
-class SMBEcho_Data(Structure):
-    structure = (
-        ('Data',':'),
-    )
-
-class SMBEcho_Parameters(Structure):
-    structure = (
-        ('EchoCount','<H'),
-    )
-
-class SMBEchoResponse_Data(Structure):
-    structure = (
-        ('Data',':'),
-    )
-
-class SMBEchoResponse_Parameters(Structure):
-    structure = (
-        ('SequenceNumber','<H=1'),
-    )
-
-############# SMB_COM_QUERY_INFORMATION_DISK (0x80)
-class SMBQueryInformationDiskResponse_Parameters(Structure):
-    structure = (
-        ('TotalUnits','<H'),
-        ('BlocksPerUnit','<H'),
-        ('BlockSize','<H'),
-        ('FreeUnits','<H'),
-        ('Reserved','<H=0'),
-    )
-
-
-############# SMB_COM_LOGOFF_ANDX (0x74)
-class SMBLogOffAndX(SMBAndXCommand_Parameters):
-    strucure = ()
-
-############# SMB_COM_CLOSE (0x04)
-class SMBClose_Parameters(SMBCommand_Parameters):
-   structure = (
-        ('FID','<H'),
-        ('Time','<L=0'),
-   )
-
-############# SMB_COM_FLUSH (0x05)
-class SMBFlush_Parameters(SMBCommand_Parameters):
-   structure = (
-        ('FID','<H'),
-   )
-
-############# SMB_COM_CREATE_DIRECTORY (0x00)
-class SMBCreateDirectory_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('BufferFormat','<B=4'),
-        ('DirectoryName','z'),
-    )
-    UnicodeStructure = (
-        ('BufferFormat','<B=4'),
-        ('DirectoryName','u'),
-    )
-
-############# SMB_COM_DELETE (0x06)
-class SMBDelete_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('BufferFormat','<B=4'),
-        ('FileName','z'),
-    )
-    UnicodeStructure = (
-        ('BufferFormat','<B=4'),
-        ('FileName','u'),
-    )
-
-class SMBDelete_Parameters(Structure):
-    structure = (
-        ('SearchAttributes','<H'),
-    )
-
-############# SMB_COM_DELETE_DIRECTORY (0x01)
-class SMBDeleteDirectory_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('BufferFormat','<B=4'),
-        ('DirectoryName','z'),
-    )
-    UnicodeStructure = (
-        ('BufferFormat','<B=4'),
-        ('DirectoryName','u'),
-    )
-
-############# SMB_COM_CHECK_DIRECTORY (0x10)
-class SMBCheckDirectory_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('BufferFormat','<B=4'),
-        ('DirectoryName','z'),
-    )
-    UnicodeStructure = (
-        ('BufferFormat','<B=4'),
-        ('DirectoryName','u'),
-    )
-
-############# SMB_COM_RENAME (0x07)
-class SMBRename_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('SearchAttributes','<H'),
-    )
-
-class SMBRename_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('BufferFormat1','<B=4'),
-        ('OldFileName','z'),
-        ('BufferFormat2','<B=4'),
-        ('NewFileName','z'),
-    )
-    UnicodeStructure = (
-        ('BufferFormat1','<B=4'),
-        ('OldFileName','u'),
-        ('BufferFormat2','<B=4'),
-        ('Pad','B=0'),
-        ('NewFileName','u'),
-    )
-
-
-############# SMB_COM_OPEN (0x02)
-class SMBOpen_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('DesiredAccess','<H=0'),
-        ('SearchAttributes','<H=0'),
-    )
-
-class SMBOpen_Data(AsciiOrUnicodeStructure):
-    AsciiStructure = (
-        ('FileNameFormat','"\x04'),
-        ('FileName','z'),
-    )
-    UnicodeStructure = (
-        ('FileNameFormat','"\x04'),
-        ('FileName','z'),
-    )
-
-class SMBOpenResponse_Parameters(SMBCommand_Parameters):
-    structure = (
-        ('Fid','<H=0'),
-        ('FileAttributes','<H=0'),
-        ('LastWriten','<L=0'),
-        ('FileSize','<L=0'),
-        ('GrantedAccess','<H=0'),
-    )
-
-############# EXTENDED SECURITY CLASSES
-class SMBExtended_Security_Parameters(Structure):
-    structure = (
-        ('DialectIndex','<H'),
-        ('SecurityMode','<B'),
-        ('MaxMpxCount','<H'),
-        ('MaxNumberVcs','<H'),
-        ('MaxBufferSize','<L'),
-        ('MaxRawSize','<L'),
-        ('SessionKey','<L'),
-        ('Capabilities','<L'),
-        ('LowDateTime','<L'),
-        ('HighDateTime','<L'),
-        ('ServerTimeZone','<H'),
-        ('ChallengeLength','<B'),
-    )
-
-class SMBExtended_Security_Data(Structure):
-    structure = (
-        ('ServerGUID','16s'),
-        ('SecurityBlob',':'),
-    )
-
-class SMBNTLMDialect_Parameters(Structure):
-    structure = (
-        ('DialectIndex','<H'),
-        ('SecurityMode','<B'),
-        ('MaxMpxCount','<H'),
-        ('MaxNumberVcs','<H'),
-        ('MaxBufferSize','<L'),
-        ('MaxRawSize','<L'),
-        ('SessionKey','<L'),
-        ('Capabilities','<L'),
-        ('LowDateTime','<L'),
-        ('HighDateTime','<L'),
-        ('ServerTimeZone','<H'),
-        ('ChallengeLength','<B'),
-    )
-
-class SMBNTLMDialect_Data(Structure):
-    structure = (
-        ('ChallengeLength','_-Challenge','self["ChallengeLength"]'),
-        ('Challenge',':'),
-        ('Payload',':'),
-# For some reason on an old Linux this field is not present, we have to check 
this out. There must be a flag stating this.
-        ('DomainName','_'),
-        ('ServerName','_'),
-    )
-    def __init__(self,data = None, alignment = 0):
-         Structure.__init__(self,data,alignment)
-         #self['ChallengeLength']=8
-
-    def fromString(self,data):
-        Structure.fromString(self,data)
-        self['DomainName'] = ''
-        self['ServerName'] = ''
-
-class SMB:
-    # SMB Command Codes
-    SMB_COM_CREATE_DIRECTORY                = 0x00
-    SMB_COM_DELETE_DIRECTORY                = 0x01
-    SMB_COM_OPEN                            = 0x02
-    SMB_COM_CREATE                          = 0x03
-    SMB_COM_CLOSE                           = 0x04
-    SMB_COM_FLUSH                           = 0x05
-    SMB_COM_DELETE                          = 0x06
-    SMB_COM_RENAME                          = 0x07
-    SMB_COM_QUERY_INFORMATION               = 0x08
-    SMB_COM_SET_INFORMATION                 = 0x09
-    SMB_COM_READ                            = 0x0A
-    SMB_COM_WRITE                           = 0x0B
-    SMB_COM_LOCK_BYTE_RANGE                 = 0x0C
-    SMB_COM_UNLOCK_BYTE_RANGE               = 0x0D
-    SMB_COM_CREATE_TEMPORARY                = 0x0E
-    SMB_COM_CREATE_NEW                      = 0x0F
-    SMB_COM_CHECK_DIRECTORY                 = 0x10
-    SMB_COM_PROCESS_EXIT                    = 0x11
-    SMB_COM_SEEK                            = 0x12
-    SMB_COM_LOCK_AND_READ                   = 0x13
-    SMB_COM_WRITE_AND_UNLOCK                = 0x14
-    SMB_COM_READ_RAW                        = 0x1A
-    SMB_COM_READ_MPX                        = 0x1B
-    SMB_COM_READ_MPX_SECONDARY              = 0x1C
-    SMB_COM_WRITE_RAW                       = 0x1D
-    SMB_COM_WRITE_MPX                       = 0x1E
-    SMB_COM_WRITE_MPX_SECONDARY             = 0x1F
-    SMB_COM_WRITE_COMPLETE                  = 0x20
-    SMB_COM_QUERY_SERVER                    = 0x21
-    SMB_COM_SET_INFORMATION2                = 0x22
-    SMB_COM_QUERY_INFORMATION2              = 0x23
-    SMB_COM_LOCKING_ANDX                    = 0x24
-    SMB_COM_TRANSACTION                     = 0x25
-    SMB_COM_TRANSACTION_SECONDARY           = 0x26
-    SMB_COM_IOCTL                           = 0x27
-    SMB_COM_IOCTL_SECONDARY                 = 0x28
-    SMB_COM_COPY                            = 0x29
-    SMB_COM_MOVE                            = 0x2A
-    SMB_COM_ECHO                            = 0x2B
-    SMB_COM_WRITE_AND_CLOSE                 = 0x2C
-    SMB_COM_OPEN_ANDX                       = 0x2D
-    SMB_COM_READ_ANDX                       = 0x2E
-    SMB_COM_WRITE_ANDX                      = 0x2F
-    SMB_COM_NEW_FILE_SIZE                   = 0x30
-    SMB_COM_CLOSE_AND_TREE_DISC             = 0x31
-    SMB_COM_TRANSACTION2                    = 0x32
-    SMB_COM_TRANSACTION2_SECONDARY          = 0x33
-    SMB_COM_FIND_CLOSE2                     = 0x34
-    SMB_COM_FIND_NOTIFY_CLOSE               = 0x35
-    # Used by Xenix/Unix 0x60 - 0x6E 
-    SMB_COM_TREE_CONNECT                    = 0x70
-    SMB_COM_TREE_DISCONNECT                 = 0x71
-    SMB_COM_NEGOTIATE                       = 0x72
-    SMB_COM_SESSION_SETUP_ANDX              = 0x73
-    SMB_COM_LOGOFF_ANDX                     = 0x74
-    SMB_COM_TREE_CONNECT_ANDX               = 0x75
-    SMB_COM_QUERY_INFORMATION_DISK          = 0x80
-    SMB_COM_SEARCH                          = 0x81
-    SMB_COM_FIND                            = 0x82
-    SMB_COM_FIND_UNIQUE                     = 0x83
-    SMB_COM_FIND_CLOSE                      = 0x84
-    SMB_COM_NT_TRANSACT                     = 0xA0
-    SMB_COM_NT_TRANSACT_SECONDARY           = 0xA1
-    SMB_COM_NT_CREATE_ANDX                  = 0xA2
-    SMB_COM_NT_CANCEL                       = 0xA4
-    SMB_COM_NT_RENAME                       = 0xA5
-    SMB_COM_OPEN_PRINT_FILE                 = 0xC0
-    SMB_COM_WRITE_PRINT_FILE                = 0xC1
-    SMB_COM_CLOSE_PRINT_FILE                = 0xC2
-    SMB_COM_GET_PRINT_QUEUE                 = 0xC3
-    SMB_COM_READ_BULK                       = 0xD8
-    SMB_COM_WRITE_BULK                      = 0xD9
-    SMB_COM_WRITE_BULK_DATA                 = 0xDA
-
-    # TRANSACT codes
-    TRANS_TRANSACT_NMPIPE                   = 0x26
-
-    # TRANSACT2 codes
-    TRANS2_FIND_FIRST2                      = 0x0001
-    TRANS2_FIND_NEXT2                       = 0x0002
-    TRANS2_QUERY_FS_INFORMATION             = 0x0003
-    TRANS2_QUERY_PATH_INFORMATION           = 0x0005
-    TRANS2_QUERY_FILE_INFORMATION           = 0x0007
-    TRANS2_SET_FILE_INFORMATION             = 0x0008
-    TRANS2_SET_PATH_INFORMATION             = 0x0006
-
-    # Security Share Mode (Used internally by SMB class)
-    SECURITY_SHARE_MASK                     = 0x01
-    SECURITY_SHARE_SHARE                    = 0x00
-    SECURITY_SHARE_USER                     = 0x01
-    SECURITY_SIGNATURES_ENABLED             = 0X04
-    SECURITY_SIGNATURES_REQUIRED            = 0X08
-
-    # Security Auth Mode (Used internally by SMB class)
-    SECURITY_AUTH_MASK                      = 0x02
-    SECURITY_AUTH_ENCRYPTED                 = 0x02
-    SECURITY_AUTH_PLAINTEXT                 = 0x00
-
-    # Raw Mode Mask (Used internally by SMB class. Good for dialect up to and 
including LANMAN2.1)
-    RAW_READ_MASK                           = 0x01
-    RAW_WRITE_MASK                          = 0x02
-
-    # Capabilities Mask (Used internally by SMB class. Good for dialect NT LM 
0.12)
-    CAP_RAW_MODE                            = 0x00000001
-    CAP_MPX_MODE                            = 0x0002
-    CAP_UNICODE                             = 0x0004
-    CAP_LARGE_FILES                         = 0x0008
-    CAP_EXTENDED_SECURITY                   = 0x80000000
-    CAP_USE_NT_ERRORS                       = 0x40
-    CAP_NT_SMBS                             = 0x10
-    CAP_LARGE_READX                         = 0x00004000
-    CAP_LARGE_WRITEX                        = 0x00008000
-    CAP_RPC_REMOTE_APIS                     = 0x20
-
-    # Flags1 Mask
-    FLAGS1_LOCK_AND_READ_OK                 = 0x01
-    FLAGS1_PATHCASELESS                     = 0x08
-    FLAGS1_CANONICALIZED_PATHS              = 0x10
-    FLAGS1_REPLY                            = 0x80
-
-    # Flags2 Mask
-    FLAGS2_LONG_NAMES                       = 0x0001
-    FLAGS2_EAS                              = 0x0002
-    FLAGS2_SMB_SECURITY_SIGNATURE           = 0x0004
-    FLAGS2_IS_LONG_NAME                     = 0x0040
-    FLAGS2_DFS                              = 0x1000
-    FLAGS2_PAGING_IO                        = 0x2000
-    FLAGS2_NT_STATUS                        = 0x4000
-    FLAGS2_UNICODE                          = 0x8000
-    FLAGS2_COMPRESSED                       = 0x0008
-    FLAGS2_SMB_SECURITY_SIGNATURE_REQUIRED  = 0x0010
-    FLAGS2_EXTENDED_SECURITY                = 0x0800
-
-    # Dialect's Security Mode flags
-    NEGOTIATE_USER_SECURITY                 = 0x01
-    NEGOTIATE_ENCRYPT_PASSWORDS             = 0x02
-    NEGOTIATE_SECURITY_SIGNATURE_ENABLE     = 0x04
-    NEGOTIATE_SECURITY_SIGNATURE_REQUIRED   = 0x08
-
-    # Tree Connect AndX Response optionalSuppor flags
-    SMB_SUPPORT_SEARCH_BITS                 = 0x01
-    SMB_SHARE_IS_IN_DFS                     = 0x02
-
-    def __init__(self, remote_name, remote_host, my_name = None, host_type = 
nmb.TYPE_SERVER, sess_port = 445, timeout=None, UDP = 0, session = None, 
negPacket = None):
-        # The uid attribute will be set when the client calls the login() 
method
-        self._uid = 0
-        self.__server_name = ''
-        self.__server_os = ''
-        self.__server_os_major = None
-        self.__server_os_minor = None
-        self.__server_os_build = None
-        self.__server_lanman = ''
-        self.__server_domain = ''
-        self.__server_dns_domain_name = ''
-        self.__remote_name = string.upper(remote_name)
-        self.__remote_host = remote_host
-        self.__isNTLMv2 = True
-        self._dialects_parameters = None
-        self._dialects_data = None
-        # Credentials
-        self.__userName = ''
-        self.__password = ''
-        self.__domain   = ''
-        self.__lmhash   = ''
-        self.__nthash   = ''
-        self.__aesKey   = ''
-        self.__kdc      = ''
-        self.__TGT      = None
-        self.__TGS      = None
-
-        # Negotiate Protocol Result, used everywhere
-        # Could be extended or not, flags should be checked before 
-        self._dialect_data = 0
-        self._dialect_parameters = 0
-        self._action = 0
-        self._sess = None
-        self.encrypt_passwords = True
-        self.tid = 0
-        self.fid = 0
-
-        # Signing stuff
-        self._SignSequenceNumber = 0
-        self._SigningSessionKey = ''
-        self._SigningChallengeResponse = ''
-        self._SignatureEnabled = False
-        self._SignatureVerificationEnabled = False
-        self._SignatureRequired = False
-
-        # Base flags (default flags, can be overriden using set_flags())
-        self.__flags1 = SMB.FLAGS1_PATHCASELESS | 
SMB.FLAGS1_CANONICALIZED_PATHS
-        self.__flags2 = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | 
SMB.FLAGS2_LONG_NAMES
-
-        if timeout is None:
-            self.__timeout = 60
-        else:
-            self.__timeout = timeout
-
-        # If port 445 and the name sent is *SMBSERVER we're setting the name 
to the IP. 
-        # This is to help some old applications still believing 
-        # *SMSBSERVER will work against modern OSes. If port is 
NETBIOS_SESSION_PORT the user better 
-        # know about *SMBSERVER's limitations
-        if sess_port == 445 and remote_name == '*SMBSERVER':
-           self.__remote_name = remote_host
-
-        if session is None:
-            if not my_name:
-                my_name = socket.gethostname()
-                i = string.find(my_name, '.')
-                if i > -1:
-                    my_name = my_name[:i]
-
-            if UDP:
-                self._sess = nmb.NetBIOSUDPSession(my_name, remote_name, 
remote_host, host_type, sess_port, self.__timeout)
-            else:
-                self._sess = nmb.NetBIOSTCPSession(my_name, remote_name, 
remote_host, host_type, sess_port, self.__timeout)
-
-                # Initialize session values (_dialect_data and 
_dialect_parameters)
-                self.neg_session()
-
-                # Call login() without any authentication information to 
-                # setup a session if the remote server
-                # is in share mode.
-                if (self._dialects_parameters['SecurityMode'] & 
SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE:
-                    self.login('', '')
-        else:
-            self._sess = session
-            self.neg_session(negPacket = negPacket)
-            # Call login() without any authentication information to 
-            # setup a session if the remote server
-            # is in share mode.
-            if (self._dialects_parameters['SecurityMode'] & 
SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE:
-                self.login('', '')
-
-    @staticmethod
-    def ntlm_supported():
-        return False
-
-    def get_remote_name(self):
-        return self.__remote_name
-
-    def get_remote_host(self):
-        return self.__remote_host
-
-    def get_flags(self):
-        return self.__flags1, self.__flags2
-
-    def set_flags(self, flags1=None, flags2=None):
-        if flags1 is not None:
-           self.__flags1 = flags1
-        if flags2 is not None:
-           self.__flags2 = flags2
-
-    def set_timeout(self, timeout):
-        prev_timeout = self.__timeout
-        self.__timeout = timeout
-        return prev_timeout
-
-    def get_timeout(self):
-        return self.__timeout
-
-    @contextmanager
-    def use_timeout(self, timeout):
-        prev_timeout = self.set_timeout(timeout)
-        try:
-            yield
-        finally:
-            self.set_timeout(prev_timeout)
-
-    def get_session(self):
-        return self._sess
-
-    def get_tid(self):
-        return self.tid
-
-    def get_fid(self):
-        return self.fid
-
-    def isGuestSession(self):
-        return self._action & SMB_SETUP_GUEST
-
-    def doesSupportNTLMv2(self):
-        return self.__isNTLMv2
-
-    def __del__(self):
-        if self._sess:
-            self._sess.close()
-
-    def recvSMB(self):
-        r = self._sess.recv_packet(self.__timeout)
-        return NewSMBPacket(data = r.get_trailer())
-
-    @staticmethod
-    def __decode_trans(params, data):
-        totparamcnt, totdatacnt, _, paramcnt, paramoffset, paramds, datacnt, 
dataoffset, datads, setupcnt = unpack('<HHHHHHHHHB', params[:19])
-        if paramcnt + paramds < totparamcnt or datacnt + datads < totdatacnt:
-            has_more = 1
-        else:
-            has_more = 0
-        paramoffset = paramoffset - 55 - setupcnt * 2
-        dataoffset = dataoffset - 55 - setupcnt * 2
-        return has_more, params[20:20 + setupcnt * 2], 
data[paramoffset:paramoffset + paramcnt], data[dataoffset:dataoffset + datacnt]
-
-    # TODO: Move this to NewSMBPacket, it belongs there
-    def signSMB(self, packet, signingSessionKey, signingChallengeResponse):
-        # This logic MUST be applied for messages sent in response to any of 
the higher-layer actions and in
-        # compliance with the message sequencing rules.
-        #  * The client or server that sends the message MUST provide the 
32-bit sequence number for this
-        #    message, as specified in sections 3.2.4.1 and 3.3.4.1.
-        #  * The SMB_FLAGS2_SMB_SECURITY_SIGNATURE flag in the header MUST be 
set.
-        #  * To generate the signature, a 32-bit sequence number is copied 
into the 
-        #    least significant 32 bits of the SecuritySignature field and the 
remaining 
-        #    4 bytes are set to 0x00.
-        #  * The MD5 algorithm, as specified in [RFC1321], MUST be used to 
generate a hash of the SMB
-        #    message from the start of the SMB Header, which is defined as 
follows.
-        #    CALL MD5Init( md5context )
-        #    CALL MD5Update( md5context, Connection.SigningSessionKey )
-        #    CALL MD5Update( md5context, Connection.SigningChallengeResponse )
-        #    CALL MD5Update( md5context, SMB message )
-        #    CALL MD5Final( digest, md5context )
-        #    SET signature TO the first 8 bytes of the digest
-        # The resulting 8-byte signature MUST be copied into the 
SecuritySignature field of the SMB Header,
-        # after which the message can be transmitted.
-
-        #print "seq(%d) signingSessionKey %r, signingChallengeResponse %r" % 
(self._SignSequenceNumber, signingSessionKey, signingChallengeResponse)
-        packet['SecurityFeatures'] = pack('<q',self._SignSequenceNumber)
-        # Sign with the sequence
-        m = hashlib.md5()
-        m.update( signingSessionKey )
-        m.update( signingChallengeResponse )
-        m.update( str(packet) )
-        # Replace sequence with acual hash
-        packet['SecurityFeatures'] = m.digest()[:8]
-        if self._SignatureVerificationEnabled:
-           self._SignSequenceNumber +=1
-        else:
-           self._SignSequenceNumber +=2
-
-    def checkSignSMB(self, packet, signingSessionKey, 
signingChallengeResponse):
-        # Let's check
-        signature = packet['SecurityFeatures']
-        #print "Signature received: %r " % signature
-        self.signSMB(packet, signingSessionKey, signingChallengeResponse)
-        #print "Signature calculated: %r" % packet['SecurityFeatures']
-        if self._SignatureVerificationEnabled is not True:
-           self._SignSequenceNumber -= 1
-        return packet['SecurityFeatures'] == signature
-
-    def sendSMB(self,smb):
-        smb['Uid'] = self._uid
-        #At least on AIX, PIDs can exceed 16 bits, so we mask them out
-        smb['Pid'] = (os.getpid() & 0xFFFF)
-        # set flags
-        smb['Flags1'] |= self.__flags1
-        smb['Flags2'] |= self.__flags2
-        if self._SignatureEnabled:
-            smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
-            self.signSMB(smb, self._SigningSessionKey, 
self._SigningChallengeResponse)
-
-        self._sess.send_packet(str(smb))
-
-    @staticmethod
-    def isValidAnswer(s, cmd):
-        while 1:
-            if s.rawData():
-                if s.get_command() == cmd:
-                    if s.get_error_class() == 0x00 and s.get_error_code() == 
0x00:
-                        return 1
-                    else:
-                        raise SessionError( "SMB Library Error", 
s.get_error_class()+ (s.get_reserved() << 8), s.get_error_code() , 
s.get_flags2() & SMB.FLAGS2_NT_STATUS)
-                else:
-                    break
-        return 0
-
-    def neg_session(self, extended_security = True, negPacket = None):
-        def parsePacket(smb):
-            if smb.isValidAnswer(SMB.SMB_COM_NEGOTIATE):
-                sessionResponse = SMBCommand(smb['Data'][0])
-                self._dialects_parameters = 
SMBNTLMDialect_Parameters(sessionResponse['Parameters'])
-                self._dialects_data = SMBNTLMDialect_Data()
-                self._dialects_data['ChallengeLength'] = 
self._dialects_parameters['ChallengeLength']
-                self._dialects_data.fromString(sessionResponse['Data'])
-                if self._dialects_parameters['Capabilities'] & 
SMB.CAP_EXTENDED_SECURITY:
-                    # Whether we choose it or it is enforced by the server, we 
go for extended security
-                    self._dialects_parameters = 
SMBExtended_Security_Parameters(sessionResponse['Parameters'])
-                    self._dialects_data = 
SMBExtended_Security_Data(sessionResponse['Data'])
-                    # Let's setup some variable for later use
-                    if self._dialects_parameters['SecurityMode'] & 
SMB.SECURITY_SIGNATURES_REQUIRED:
-                         self._SignatureRequired = True
-
-                    # Interestingly, the security Blob might be missing 
sometimes.
-                    #spnego = 
SPNEGO_NegTokenInit(self._dialects_data['SecurityBlob'])
-                    #for i in spnego['MechTypes']:
-                    #      print "Mech Found: %s" % MechTypes[i]
-                    return 1
-
-                # If not, let's try the old way
-                else:
-                    if self._dialects_data['ServerName'] is not None:
-                        self.__server_name = self._dialects_data['ServerName']
-
-                    if self._dialects_parameters['DialectIndex'] == 0xffff:
-                        raise UnsupportedFeature("Remote server does not know 
NT LM 0.12")
-                    return 1
-            else:
-                return 0
-
-        if negPacket is None:
-            smb = NewSMBPacket()
-            negSession = SMBCommand(SMB.SMB_COM_NEGOTIATE)
-            flags2 = self.get_flags()[1]
-            if extended_security is True:
-                self.set_flags(flags2=flags2|SMB.FLAGS2_EXTENDED_SECURITY)
-            else:
-                self.set_flags(flags2=flags2 & (~SMB.FLAGS2_EXTENDED_SECURITY))
-
-            negSession['Data'] = '\x02NT LM 0.12\x00'
-            smb.addCommand(negSession)
-            self.sendSMB(smb)
-
-            while 1:
-                smb = self.recvSMB()
-                return parsePacket(smb)
-        else:
-
-            return parsePacket( NewSMBPacket( data = negPacket))
-
-    def tree_connect(self, path, password = '', service = SERVICE_ANY):
-        LOG.warning("[MS-CIFS] This is an original Core Protocol command.This 
command has been deprecated.Client Implementations SHOULD use 
SMB_COM_TREE_CONNECT_ANDX")
-
-        # return 0x800
-        if password:
-            # Password is only encrypted if the server passed us an 
"encryption" during protocol dialect
-            if self._dialects_parameters['ChallengeLength'] > 0:
-                # this code is untested
-                password = 
self.get_ntlmv1_response(ntlm.compute_lmhash(password))
-
-        if not unicode_support:
-            if unicode_convert:
-                path = str(path)
-            else:
-                raise Exception('SMB: Can\t conver path from unicode!')
-
-        smb = NewSMBPacket()
-        treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT)
-        treeConnect['Parameters'] = SMBTreeConnect_Parameters()
-        treeConnect['Data']       = SMBTreeConnect_Data()
-        treeConnect['Data']['Path'] = path.upper()
-        treeConnect['Data']['Password'] = password
-        treeConnect['Data']['Service'] = service
-        smb.addCommand(treeConnect)
-        self.sendSMB(smb)
-
-        while 1:
-            smb = self.recvSMB()
-            if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT):
-                # XXX Here we are ignoring the rest of the response
-                return smb['Tid']
-            return smb['Tid']
-
-    def get_uid(self):
-        return self._uid
-
-    def set_uid(self, uid):
-        self._uid = uid
-
-    def tree_connect_andx(self, path, password = None, service = SERVICE_ANY, 
smb_packet=None):
-        if password:
-            # Password is only encrypted if the server passed us an 
"encryption" during protocol dialect
-            if self._dialects_parameters['ChallengeLength'] > 0:
-                # this code is untested
-                password = 
self.get_ntlmv1_response(ntlm.compute_lmhash(password))
-        else:
-            password = '\x00'
-
-        if not unicode_support:
-            if unicode_convert:
-                path = str(path)
-            else:
-                raise Exception('SMB: Can\t convert path from unicode!')
-
-        if smb_packet is None:
-            smb = NewSMBPacket()
-        else:
-            smb = smb_packet
-
-        # Just in case this came with the full path ,let's just leave 
-        # the sharename, we'll take care of the rest
-
-        share = path.split('\\')[-1]
-        try:
-            _, _, _, _, sockaddr = socket.getaddrinfo(self.get_remote_host(), 
80, 0, 0, socket.IPPROTO_TCP)[0]
-            remote_host = sockaddr[0]
-        except Exception:
-            remote_host =  self.get_remote_host()
-
-        path = '\\\\' + remote_host + '\\' +share
-        path = path.upper().encode('utf-16le') if self.__flags2 & 
SMB.FLAGS2_UNICODE else path
-
-        treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT_ANDX)
-        treeConnect['Parameters'] = SMBTreeConnectAndX_Parameters()
-        treeConnect['Data']       = 
SMBTreeConnectAndX_Data(flags=self.__flags2)
-        treeConnect['Parameters']['PasswordLength'] = len(password)
-        treeConnect['Data']['Password'] = password
-        treeConnect['Data']['Path'] = path
-        treeConnect['Data']['Service'] = service
-
-        if self.__flags2 & SMB.FLAGS2_UNICODE:
-            treeConnect['Data']['Pad'] = 0x0
-
-        smb.addCommand(treeConnect)
-
-        # filename = "\PIPE\epmapper"
-
-        # ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX)
-        # ntCreate['Parameters'] = SMBNtCreateAndX_Parameters()
-        # ntCreate['Data']       = SMBNtCreateAndX_Data()
-        # ntCreate['Parameters']['FileNameLength'] = len(filename)
-        # ntCreate['Parameters']['CreateFlags'] = 0
-        # ntCreate['Parameters']['AccessMask'] = 0x3
-        # ntCreate['Parameters']['CreateOptions'] = 0x0
-        # ntCreate['Data']['FileName'] = filename
-
-        # smb.addCommand(ntCreate)
-        self.sendSMB(smb)
-
-        while 1:
-            smb = self.recvSMB()
-            if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT_ANDX):
-                # XXX Here we are ignoring the rest of the response
-                self.tid = smb['Tid']
-                return self.tid
-            self.tid = smb['Tid']
-            return self.tid
-
-    # backwars compatibility
-    connect_tree = tree_connect_andx
-
-    @staticmethod
-    def getDialect():
-        return SMB_DIALECT
-
-    def get_server_name(self):
-        #return self._dialects_data['ServerName']
-        return self.__server_name
-
-    def get_session_key(self):
-        return self._SigningSessionKey
-
-    def set_session_key(self, key):
-        self._SigningSessionKey = key
-
-    def get_encryption_key(self):
-        if 'Challenge' in self._dialects_data.fields:
-            return self._dialects_data['Challenge']
-        else:
-            return None
-
-    def get_server_time(self):
-        timestamp = self._dialects_parameters['HighDateTime']
-        timestamp <<= 32
-        timestamp |= self._dialects_parameters['LowDateTime']
-        timestamp -= 116444736000000000
-        timestamp /= 10000000
-        d = datetime.datetime.utcfromtimestamp(timestamp)
-        return d.strftime("%a, %d %b %Y %H:%M:%S GMT")
-
-    def disconnect_tree(self, tid):
-        smb = NewSMBPacket()
-        smb['Tid']  = tid
-
-        smb.addCommand(SMBCommand(SMB.SMB_COM_TREE_DISCONNECT))
-
-        self.sendSMB(smb)
-        self.recvSMB()
-
-    def open(self, tid, filename, open_mode, desired_access):
-        filename = string.replace(filename,'/', '\\')
-        filename = filename.encode('utf-16le') if self.__flags2 & 
SMB.FLAGS2_UNICODE else filename
-
-        smb = NewSMBPacket()
-        smb['Tid']    = tid
-
-        openFile = SMBCommand(SMB.SMB_COM_OPEN)
-        openFile['Parameters'] = SMBOpen_Parameters()
-        openFile['Parameters']['DesiredAccess']    = desired_access
-        openFile['Parameters']['OpenMode']         = open_mode
-        openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | 
ATTR_HIDDEN | ATTR_ARCHIVE
-        openFile['Data']       = SMBOpen_Data(flags=self.__flags2)
-        openFile['Data']['FileName'] = filename
-
-        if self.__flags2 & SMB.FLAGS2_UNICODE:
-            openFile['Data']['Pad'] = 0x0
-
-        smb.addCommand(openFile)
-
-        self.sendSMB(smb)
-
-        smb = self.recvSMB()
-        if smb.isValidAnswer(SMB.SMB_COM_OPEN):
-            # XXX Here we are ignoring the rest of the response
-            openFileResponse   = SMBCommand(smb['Data'][0])
-            openFileParameters = 
SMBOpenResponse_Parameters(openFileResponse['Parameters'])
-
-            return (
-                openFileParameters['Fid'],
-                openFileParameters['FileAttributes'],
-                openFileParameters['LastWriten'],
-                openFileParameters['FileSize'],
-                openFileParameters['GrantedAccess'],
-            )
-
-    def open_andx(self, tid, filename, open_mode, desired_access):
-        filename = string.replace(filename,'/', '\\')
-        filename = filename.encode('utf-16le') if self.__flags2 & 
SMB.FLAGS2_UNICODE else filename
-
-        smb = NewSMBPacket()
-        smb['Tid']    = tid
-
-        openFile = SMBCommand(SMB.SMB_COM_OPEN_ANDX)
-        openFile['Parameters'] = SMBOpenAndX_Parameters()
-        openFile['Parameters']['DesiredAccess']    = desired_access
-        openFile['Parameters']['OpenMode']         = open_mode
-        openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | 
ATTR_HIDDEN | ATTR_ARCHIVE
-        openFile['Data']       = SMBOpenAndX_Data(flags=self.__flags2)
-        openFile['Data']['FileName'] = filename
-
-        if self.__flags2 & SMB.FLAGS2_UNICODE:
-            openFile['Data']['Pad'] = 0x0
-
-        smb.addCommand(openFile)
-
-        self.sendSMB(smb)
-
-        smb = self.recvSMB()
-        if smb.isValidAnswer(SMB.SMB_COM_OPEN_ANDX):
-            # XXX Here we are ignoring the rest of the response
-            openFileResponse   = SMBCommand(smb['Data'][0])
-            openFileParameters = 
SMBOpenAndXResponse_Parameters(openFileResponse['Parameters'])
-
-            return (
-                openFileParameters['Fid'],
-                openFileParameters['FileAttributes'],
-                openFileParameters['LastWriten'],
-                openFileParameters['FileSize'],
-                openFileParameters['GrantedAccess'],
-                openFileParameters['FileType'],
-                openFileParameters['IPCState'],
-                openFileParameters['Action'],
-                openFileParameters['ServerFid'],
-            )
-
-    def close(self, tid, fid):
-        smb = NewSMBPacket()
-        smb['Tid']    = tid
-
-        closeFile = SMBCommand(SMB.SMB_COM_CLOSE)
-        closeFile['Parameters'] = SMBClose_Parameters()
-        closeFile['Parameters']['FID']    = fid
-        smb.addCommand(closeFile)
-
-        self.sendSMB(smb)
-        smb = self.recvSMB()
-        if smb.isValidAnswer(SMB.SMB_COM_CLOSE):
-           return 1
-        return 0
-
-    def send_trans(self, tid, setup, name, param, data, noAnswer = 0):
-        smb = NewSMBPacket()
-        smb['Tid']    = tid
-
-        transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION)
-        transCommand['Parameters'] = SMBTransaction_Parameters()
-        transCommand['Data'] = SMBTransaction_Data()
-
-        transCommand['Parameters']['Setup'] = setup
-        transCommand['Parameters']['TotalParameterCount'] = len(param)
-        transCommand['Parameters']['TotalDataCount'] = len(data)
-
-        transCommand['Parameters']['ParameterCount'] = len(param)
-        transCommand['Parameters']['ParameterOffset'] = 
32+3+28+len(setup)+len(name)
-
-        transCommand['Parameters']['DataCount'] = len(data)
-        transCommand['Parameters']['DataOffset'] = 
transCommand['Parameters']['ParameterOffset'] + len(param)
-
-        transCommand['Data']['Name'] = name
-        transCommand['Data']['Trans_Parameters'] = param
-        transCommand['Data']['Trans_Data'] = data
-
-        if noAnswer:
-           transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE
-
-        smb.addCommand(transCommand)
-
-        self.sendSMB(smb)
-
-    def send_trans2(self, tid, setup, name, param, data):
-        smb = NewSMBPacket()
-        smb['Tid']    = tid
-
-        command = pack('<H', setup)
-
-        transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION2)
-        transCommand['Parameters'] = SMBTransaction2_Parameters()
-        transCommand['Parameters']['MaxDataCount'] = 
self._dialects_parameters['MaxBufferSize']
-        transCommand['Data'] = SMBTransaction2_Data()
-
-        transCommand['Parameters']['Setup'] = command
-        transCommand['Parameters']['TotalParameterCount'] = len(param)
-        transCommand['Parameters']['TotalDataCount'] = len(data)
-
-        if len(param) > 0:
-            padLen = (4 - (32+2+28 + len(command)) % 4 ) % 4
-            padBytes = '\xFF' * padLen
-            transCommand['Data']['Pad1'] = padBytes
-        else:
-            transCommand['Data']['Pad1'] = ''
-            padLen = 0
-
-        transCommand['Parameters']['ParameterCount'] = len(param)
-        transCommand['Parameters']['ParameterOffset'] = 
32+2+28+len(command)+len(name) + padLen
-
-        if len(data) > 0:
-            pad2Len = (4 - (32+2+28 + len(command) + padLen + len(param)) % 4) 
% 4
-            transCommand['Data']['Pad2'] = '\xFF' * pad2Len
-        else:
-            transCommand['Data']['Pad2'] = ''
-            pad2Len = 0
-
-        transCommand['Parameters']['DataCount'] = len(data)
-        transCommand['Parameters']['DataOffset'] = 
transCommand['Parameters']['ParameterOffset'] + len(param) + pad2Len
-
-        transCommand['Data']['Name'] = name
-        transCommand['Data']['Trans_Parameters'] = param
-        transCommand['Data']['Trans_Data'] = data
-        smb.addCommand(transCommand)
-
-        self.sendSMB(smb)
-
-    def query_file_info(self, tid, fid, fileInfoClass = 
SMB_QUERY_FILE_STANDARD_INFO):
-        self.send_trans2(tid, SMB.TRANS2_QUERY_FILE_INFORMATION, '\x00', 
pack('<HH', fid, fileInfoClass), '')
-
-        resp = self.recvSMB()
-        if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2):
-            trans2Response = SMBCommand(resp['Data'][0])
-            trans2Parameters = 
SMBTransaction2Response_Parameters(trans2Response['Parameters'])
-            # Remove Potential Prefix Padding
-            return trans2Response['Data'][-trans2Parameters['TotalDataCount']:]
-
-    def __nonraw_retr_file(self, tid, fid, offset, datasize, callback):
-        if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) 
and self._SignatureEnabled is False:
-            max_buf_size = 65000
-        else:
-            max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff 
 # Read in multiple KB blocks
-
-        read_offset = offset
-        while read_offset < datasize:
-            data = self.read_andx(tid, fid, read_offset, max_buf_size)
-
-            callback(data)
-            read_offset += len(data)
-
-    def __nonraw_stor_file(self, tid, fid, offset, datasize, callback):
-        if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) 
and self._SignatureEnabled is False:
-            max_buf_size = 65000
-        else:
-            max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff 
 # Write in multiple KB blocks
-
-        write_offset = offset
-        while 1:
-            data = callback(max_buf_size)
-            if not data:
-                break
-
-            smb = self.write_andx(tid,fid,data, write_offset)
-            writeResponse   = SMBCommand(smb['Data'][0])
-            writeResponseParameters = 
SMBWriteAndXResponse_Parameters(writeResponse['Parameters'])
-            write_offset += writeResponseParameters['Count']
-
-    def get_server_domain(self):
-        return self.__server_domain
-
-    def get_server_dns_domain_name(self):
-        return self.__server_dns_domain_name
-
-    def get_server_os(self):
-        return self.__server_os
-
-    def get_server_os_major(self):
-        return self.__server_os_major
-
-    def get_server_os_minor(self):
-        return self.__server_os_minor
-
-    def get_server_os_build(self):
-        return self.__server_os_build
-
-    def set_server_os(self, os):
-        self.__server_os = os
-
-    def get_server_lanman(self):
-        return self.__server_lanman
-
-    def is_login_required(self):
-        # Login is required if share mode is user. 
-        # Otherwise only public services or services in share mode
-        # are allowed.
-        return (self._dialects_parameters['SecurityMode'] & 
SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_USER
-
-    def is_signing_required(self):
-        return self._SignatureRequired
-
-    def get_ntlmv1_response(self, key):
-        challenge = self._dialects_data['Challenge']
-        return ntlm.get_ntlmv1_response(key, challenge)
-
-    def kerberos_login(self, user, password, domain = '', lmhash = '', nthash 
= '', aesKey = '', kdcHost = '', TGT=None, TGS=None):
-        # Importing down here so pyasn1 is not required if kerberos is not 
used.
-        from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set
-        from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS
-        from impacket.krb5 import constants
-        from impacket.krb5.types import Principal, KerberosTime, Ticket
-        from pyasn1.codec.der import decoder, encoder
-        import datetime
-
-        # login feature does not support unicode
-        # disable it if enabled
-        flags2 = self.__flags2
-        if flags2 & SMB.FLAGS2_UNICODE:
-            self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE)
-
-        # If TGT or TGS are specified, they are in the form of:
-        # TGS['KDC_REP'] = the response from the server
-        # TGS['cipher'] = the cipher used
-        # TGS['sessionKey'] = the sessionKey
-        # If we have hashes, normalize them
-        if lmhash != '' or nthash != '':
-            if len(lmhash) % 2:     lmhash = '0%s' % lmhash
-            if len(nthash) % 2:     nthash = '0%s' % nthash
-            try: # just in case they were converted already
-                lmhash = a2b_hex(lmhash)
-                nthash = a2b_hex(nthash)
-            except:
-                pass
-
-        self.__userName = user
-        self.__password = password
-        self.__domain   = domain
-        self.__lmhash   = lmhash
-        self.__nthash   = nthash
-        self.__aesKey   = aesKey
-        self.__kdc      = kdcHost
-        self.__TGT      = TGT
-        self.__TGS      = TGS
-
-        # First of all, we need to get a TGT for the user
-        userName = Principal(user, 
type=constants.PrincipalNameType.NT_PRINCIPAL.value)
-        if TGT is None:
-            if TGS is None:
-                tgt, cipher, oldSessionKey, sessionKey = 
getKerberosTGT(userName, password, domain, lmhash, nthash, aesKey, kdcHost)
-        else:
-            tgt = TGT['KDC_REP']
-            cipher = TGT['cipher']
-            sessionKey = TGT['sessionKey']
-
-        # Now that we have the TGT, we should ask for a TGS for cifs
-
-        if TGS is None:
-            serverName = Principal('cifs/%s' % self.__remote_name, 
type=constants.PrincipalNameType.NT_SRV_INST.value)
-            tgs, cipher, oldSessionKey, sessionKey = 
getKerberosTGS(serverName, domain, kdcHost, tgt, cipher, sessionKey)
-        else:
-            tgs = TGS['KDC_REP']
-            cipher = TGS['cipher']
-            sessionKey = TGS['sessionKey']
-
-        smb = NewSMBPacket()
-
-        # Are we required to sign SMB? If so we do it, if not we skip it
-        if self._SignatureRequired:
-           smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
-
-
-        sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
-        sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
-        sessionSetup['Data']       = SMBSessionSetupAndX_Extended_Data()
-
-        sessionSetup['Parameters']['MaxBufferSize']        = 61440
-        sessionSetup['Parameters']['MaxMpxCount']          = 2
-        sessionSetup['Parameters']['VcNumber']             = 1
-        sessionSetup['Parameters']['SessionKey']           = 0
-        sessionSetup['Parameters']['Capabilities']         = 
SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | 
SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX
-
-
-        # Let's build a NegTokenInit with the NTLMSSP
-        # TODO: In the future we should be able to choose different providers
-
-        blob = SPNEGO_NegTokenInit()
-
-        # Kerberos v5 mech
-        blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]
-
-        # Let's extract the ticket from the TGS
-        tgs = decoder.decode(tgs, asn1Spec = TGS_REP())[0]
-        ticket = Ticket()
-        ticket.from_asn1(tgs['ticket'])
-
-        # Now let's build the AP_REQ
-        apReq = AP_REQ()
-        apReq['pvno'] = 5
-        apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)
-
-        opts = list()
-        apReq['ap-options'] = constants.encodeFlags(opts)
-        seq_set(apReq,'ticket', ticket.to_asn1)
-
-        authenticator = Authenticator()
-        authenticator['authenticator-vno'] = 5
-        authenticator['crealm'] = domain
-        seq_set(authenticator, 'cname', userName.components_to_asn1)
-        now = datetime.datetime.utcnow()
-
-        authenticator['cusec'] = now.microsecond
-        authenticator['ctime'] = KerberosTime.to_asn1(now)
-
-        encodedAuthenticator = encoder.encode(authenticator)
-
-        # Key Usage 11
-        # AP-REQ Authenticator (includes application authenticator
-        # subkey), encrypted with the application session key
-        # (Section 5.5.1)
-        encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, 
encodedAuthenticator, None)
-
-        apReq['authenticator'] = None
-        apReq['authenticator']['etype'] = cipher.enctype
-        apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator
-
-        blob['MechToken'] = encoder.encode(apReq)
-
-        sessionSetup['Parameters']['SecurityBlobLength']  = len(blob)
-        sessionSetup['Parameters'].getData()
-        sessionSetup['Data']['SecurityBlob']       = blob.getData()
-
-        # Fake Data here, don't want to get us fingerprinted
-        sessionSetup['Data']['NativeOS']      = 'Unix'
-        sessionSetup['Data']['NativeLanMan']  = 'Samba'
-
-        smb.addCommand(sessionSetup)
-        self.sendSMB(smb)
-
-        smb = self.recvSMB()
-        if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
-            # We will need to use this uid field for all future 
requests/responses
-            self._uid = smb['Uid']
-
-            # Now we have to extract the blob to continue the auth process
-            sessionResponse   = SMBCommand(smb['Data'][0])
-            sessionParameters = 
SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters'])
-            sessionData       = 
SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2'])
-            sessionData['SecurityBlobLength'] = 
sessionParameters['SecurityBlobLength']
-            sessionData.fromString(sessionResponse['Data'])
-
-            self._action = sessionParameters['Action']
-            # If smb sign required, let's enable it for the rest of the 
connection
-            if self._dialects_parameters['SecurityMode'] & 
SMB.SECURITY_SIGNATURES_REQUIRED:
-               self._SigningSessionKey = sessionKey.contents
-               self._SignSequenceNumber = 2
-               self._SignatureEnabled = True
-
-            # restore unicode flag if needed
-            if flags2 & SMB.FLAGS2_UNICODE:
-                self.__flags2 |= SMB.FLAGS2_UNICODE
-
-            return 1
-        else:
-            raise Exception('Error: Could not login successfully')
-
-    def login_extended(self, user, password, domain = '', lmhash = '', nthash 
= '', use_ntlmv2 = True ):
-
-        # login feature does not support unicode
-        # disable it if enabled
-        flags2 = self.__flags2
-        if flags2 & SMB.FLAGS2_UNICODE:
-            self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE)
-
-        # Once everything's working we should join login methods into a single 
one
-        smb = NewSMBPacket()
-        # Are we required to sign SMB? If so we do it, if not we skip it
-        if self._SignatureRequired:
-           smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
-
-        sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
-        sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
-        sessionSetup['Data']       = SMBSessionSetupAndX_Extended_Data()
-
-        sessionSetup['Parameters']['MaxBufferSize']        = 61440
-        sessionSetup['Parameters']['MaxMpxCount']          = 2
-        sessionSetup['Parameters']['VcNumber']             = 1
-        sessionSetup['Parameters']['SessionKey']           = 0
-        sessionSetup['Parameters']['Capabilities']         = 
SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | 
SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX
-
-
-        # Let's build a NegTokenInit with the NTLMSSP
-        # TODO: In the future we should be able to choose different providers
-
-        blob = SPNEGO_NegTokenInit()
-
-        # NTLMSSP
-        blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security 
Support Provider']]
-        auth = ntlm.getNTLMSSPType1('','',self._SignatureRequired, use_ntlmv2 
= use_ntlmv2)
-        blob['MechToken'] = str(auth)
-
-        sessionSetup['Parameters']['SecurityBlobLength']  = len(blob)
-        sessionSetup['Parameters'].getData()
-        sessionSetup['Data']['SecurityBlob']       = blob.getData()
-
-        # Fake Data here, don't want to get us fingerprinted
-        sessionSetup['Data']['NativeOS']      = 'Unix'
-        sessionSetup['Data']['NativeLanMan']  = 'Samba'
-
-        smb.addCommand(sessionSetup)
-        self.sendSMB(smb)
-
-        smb = self.recvSMB()
-        if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
-            # We will need to use this uid field for all future 
requests/responses
-            self._uid = smb['Uid']
-
-            # Now we have to extract the blob to continue the auth process
-            sessionResponse   = SMBCommand(smb['Data'][0])
-            sessionParameters = 
SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters'])
-            sessionData       = 
SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2'])
-            sessionData['SecurityBlobLength'] = 
sessionParameters['SecurityBlobLength']
-            sessionData.fromString(sessionResponse['Data'])
-            respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob'])
-
-            # Let's parse some data and keep it to ourselves in case it is 
asked
-            ntlmChallenge = ntlm.NTLMAuthChallenge(respToken['ResponseToken'])
-            if ntlmChallenge['TargetInfoFields_len'] > 0:
-                av_pairs = 
ntlm.AV_PAIRS(ntlmChallenge['TargetInfoFields'][:ntlmChallenge['TargetInfoFields_len']])
-                if av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] is not None:
-                   try:
-                       self.__server_name = 
av_pairs[ntlm.NTLMSSP_AV_HOSTNAME][1].decode('utf-16le')
-                   except:
-                       # For some reason, we couldn't decode Unicode here.. 
silently discard the operation
-                       pass
-                if av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME] is not None:
-                   try:
-                       if self.__server_name != 
av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le'):
-                           self.__server_domain = 
av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le')
-                   except:
-                       # For some reason, we couldn't decode Unicode here.. 
silently discard the operation
-                       pass
-                if av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME] is not None:
-                   try:
-                       self.__server_dns_domain_name = 
av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME][1].decode('utf-16le')
-                   except:
-                       # For some reason, we couldn't decode Unicode here.. 
silently discard the operation
-                       pass
-
-            # Parse Version to know the target Operating system name. Not 
provided elsewhere anymore
-            if 'Version' in ntlmChallenge.fields:
-                version = ntlmChallenge['Version']
-
-                if len(version) >= 4:
-                   self.__server_os_major, self.__server_os_minor, 
self.__server_os_build = unpack('<BBH',version[:4])
-
-            type3, exportedSessionKey = ntlm.getNTLMSSPType3(auth, 
respToken['ResponseToken'], user, password, domain, lmhash, nthash, use_ntlmv2 
= use_ntlmv2)
-
-            if exportedSessionKey is not None:
-                self._SigningSessionKey = exportedSessionKey
-
-            smb = NewSMBPacket()
-
-            # Are we required to sign SMB? If so we do it, if not we skip it
-            if self._SignatureRequired:
-               smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
-
-            respToken2 = SPNEGO_NegTokenResp()
-            respToken2['ResponseToken'] = str(type3)
-
-            # Reusing the previous structure
-            sessionSetup['Parameters']['SecurityBlobLength'] = len(respToken2)
-            sessionSetup['Data']['SecurityBlob'] = respToken2.getData()
-
-            # Storing some info for later use
-            self.__server_os     = sessionData['NativeOS']
-            self.__server_lanman = sessionData['NativeLanMan']
-
-            smb.addCommand(sessionSetup)
-            self.sendSMB(smb)
-
-            smb = self.recvSMB()
-            self._uid = 0
-            if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
-                self._uid = smb['Uid']
-                sessionResponse   = SMBCommand(smb['Data'][0])
-                sessionParameters = 
SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters'])
-
-                self._action = sessionParameters['Action']
-                # If smb sign required, let's enable it for the rest of the 
connection
-                if self._dialects_parameters['SecurityMode'] & 
SMB.SECURITY_SIGNATURES_REQUIRED:
-                   self._SignSequenceNumber = 2
-                   self._SignatureEnabled = True
-
-                # restore unicode flag if needed
-                if flags2 & SMB.FLAGS2_UNICODE:
-                    self.__flags2 |= SMB.FLAGS2_UNICODE
-
-                return 1
-        else:
-            raise Exception('Error: Could not login successfully')
-
-    def getCredentials(self):
-        return (
-            self.__userName,
-            self.__password,
-            self.__domain,
-            self.__lmhash,
-            self.__nthash,
-            self.__aesKey,
-            self.__TGT,
-            self.__TGS)
-
-    def getIOCapabilities(self):
-        res = dict()
-        if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) 
and self._SignatureEnabled is False:
-            max_size = 65000
-        else:
-            max_size = self._dialects_parameters['MaxBufferSize'] # Read in 
multiple KB blocks
-        res['MaxReadSize'] = max_size
-        res['MaxWriteSize'] = max_size
-        return res
-
-    def login(self, user, password, domain = '', lmhash = '', nthash = '', 
ntlm_fallback = True):
-
-        # If we have hashes, normalize them
-        if lmhash != '' or nthash != '':
-            if len(lmhash) % 2:     lmhash = '0%s' % lmhash
-            if len(nthash) % 2:     nthash = '0%s' % nthash
-            try: # just in case they were converted already
-                lmhash = a2b_hex(lmhash)
-                nthash = a2b_hex(nthash)
-            except:
-                pass
-
-        self.__userName = user
-        self.__password = password
-        self.__domain   = domain
-        self.__lmhash   = lmhash
-        self.__nthash   = nthash
-        self.__aesKey   = ''
-        self.__TGT      = None
-        self.__TGS      = None
-
-        if self._dialects_parameters['Capabilities'] & 
SMB.CAP_EXTENDED_SECURITY:
-            try:
-                self.login_extended(user, password, domain, lmhash, nthash, 
use_ntlmv2 = True)
-            except:
-                # If the target OS is Windows 5.0 or Samba, let's try using 
NTLMv1
-                if ntlm_fallback and ((self.get_server_lanman().find('Windows 
2000') != -1) or (self.get_server_lanman().find('Samba') != -1)):
-                    self.login_extended(user, password, domain, lmhash, 
nthash, use_ntlmv2 = False)
-                    self.__isNTLMv2 = False
-                else:
-                    raise
-        elif ntlm_fallback:
-            self.login_standard(user, password, domain, lmhash, nthash)
-            self.__isNTLMv2 = False
-        else:
-            raise SessionError('Cannot authenticate against target, enable 
ntlm_fallback')
-
-    def login_standard(self, user, password, domain = '', lmhash = '', nthash 
= ''):
-
-        # login feature does not support unicode
-        # disable it if enabled
-        flags2 = self.__flags2
-        if flags2 & SMB.FLAGS2_UNICODE:
-            self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE)
-
-        # Only supports NTLMv1
-        # Password is only encrypted if the server passed us an "encryption 
key" during protocol dialect negotiation
-        if self._dialects_parameters['ChallengeLength'] > 0:
-            if lmhash != '' or nthash != '':
-               pwd_ansi = self.get_ntlmv1_response(lmhash)
-               pwd_unicode = self.get_ntlmv1_response(nthash)
-            elif password:
-               lmhash = ntlm.compute_lmhash(password)
-               nthash = ntlm.compute_nthash(password)
-               pwd_ansi = self.get_ntlmv1_response(lmhash)
-               pwd_unicode = self.get_ntlmv1_response(nthash)
-            else: # NULL SESSION
-               pwd_ansi = ''
-               pwd_unicode = ''
-        else:
-            pwd_ansi = password
-            pwd_unicode = ''
-
-        smb = NewSMBPacket()
-
-        sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
-        sessionSetup['Parameters'] = SMBSessionSetupAndX_Parameters()
-        sessionSetup['Data']       = SMBSessionSetupAndX_Data()
-
-        sessionSetup['Parameters']['MaxBuffer']        = 61440
-        sessionSetup['Parameters']['MaxMpxCount']      = 2
-        sessionSetup['Parameters']['VCNumber']         = os.getpid()
-        sessionSetup['Parameters']['SessionKey']       = 
self._dialects_parameters['SessionKey']
-        sessionSetup['Parameters']['AnsiPwdLength']    = len(pwd_ansi)
-        sessionSetup['Parameters']['UnicodePwdLength'] = len(pwd_unicode)
-        sessionSetup['Parameters']['Capabilities']     = SMB.CAP_RAW_MODE | 
SMB.CAP_USE_NT_ERRORS | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX
-
-        sessionSetup['Data']['AnsiPwd']       = pwd_ansi
-        sessionSetup['Data']['UnicodePwd']    = pwd_unicode
-        sessionSetup['Data']['Account']       = str(user)
-        sessionSetup['Data']['PrimaryDomain'] = str(domain)
-        sessionSetup['Data']['NativeOS']      = str(os.name)
-        sessionSetup['Data']['NativeLanMan']  = 'pysmb'
-        smb.addCommand(sessionSetup)
-
-        self.sendSMB(smb)
-
-        smb = self.recvSMB()
-        if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
-            # We will need to use this uid field for all future 
requests/responses
-            self._uid = smb['Uid']
-            sessionResponse   = SMBCommand(smb['Data'][0])
-            sessionParameters = 
SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters'])
-            sessionData       = SMBSessionSetupAndXResponse_Data(flags = 
smb['Flags2'], data = sessionResponse['Data'])
-
-            self._action = sessionParameters['Action']
-
-            # Still gotta figure out how to do this with no EXTENDED_SECURITY
-            if sessionParameters['Action'] & SMB_SETUP_USE_LANMAN_KEY == 0:
-                 self._SigningChallengeResponse = 
sessionSetup['Data']['UnicodePwd']
-                 self._SigningSessionKey = nthash
-            else:
-                 self._SigningChallengeResponse = 
sessionSetup['Data']['AnsiPwd']
-                 self._SigningSessionKey = lmhash
-
-            #self._SignSequenceNumber = 1
-            #self.checkSignSMB(smb, self._SigningSessionKey 
,self._SigningChallengeResponse)
-            #self._SignatureEnabled = True
-            self.__server_os     = sessionData['NativeOS']
-            self.__server_lanman = sessionData['NativeLanMan']
-            self.__server_domain = sessionData['PrimaryDomain']
-
-            # restore unicode flag if needed
-            if flags2 & SMB.FLAGS2_UNICODE:
-                self.__flags2 |= SMB.FLAGS2_UNICODE
-
-            return 1
-        else: raise Exception('Error: Could not login successfully')
-
-    def waitNamedPipe(self, tid, pipe, timeout = 5, noAnswer = 0):
-        smb = NewSMBPacket()
-        smb['Tid']    = tid
-
-        transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION)
-        transCommand['Parameters'] = SMBTransaction_Parameters()
-        transCommand['Data'] = SMBTransaction_Data()
-
-        setup = '\x53\x00\x00\x00'
-        name = '\\PIPE%s\x00' % pipe
-        transCommand['Parameters']['Setup'] = setup
-        transCommand['Parameters']['TotalParameterCount'] = 0
-        transCommand['Parameters']['TotalDataCount'] = 0
-        transCommand['Parameters']['MaxParameterCount'] = 0
-        transCommand['Parameters']['MaxDataCount'] = 0
-        transCommand['Parameters']['Timeout'] = timeout * 1000
-
-        transCommand['Parameters']['ParameterCount'] = 0
-        transCommand['Parameters']['ParameterOffset'] = 
32+3+28+len(setup)+len(name)
-
-        transCommand['Parameters']['DataCount'] = 0
-        transCommand['Parameters']['DataOffset'] = 0
-
-        transCommand['Data']['Name'] = name
-        transCommand['Data']['Trans_Parameters'] = ''
-        transCommand['Data']['Trans_Data'] = ''
-
-        if noAnswer:
-           transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE
-
-        smb.addCommand(transCommand)
-        self.sendSMB(smb)
-
-        smb = self.recvSMB()
-        if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION):
-           return 1
-        return 0
-
-    def read(self, tid, fid, offset=0, max_size = None, wait_answer=1):
-        if not max_size:
-            max_size = self._dialects_parameters['MaxBufferSize'] # Read in 
multiple KB blocks
-
-        # max_size is not working, because although it would, the server 
returns an error (More data avail)
-
-        smb = NewSMBPacket()
-        smb['Tid']    = tid
-
-        read = SMBCommand(SMB.SMB_COM_READ)
-        read['Parameters'] = SMBRead_Parameters()
-        read['Parameters']['Fid'] = fid
-        read['Parameters']['Offset'] = offset
-        read['Parameters']['Count'] = max_size
-        smb.addCommand(read)
-
-        if wait_answer:
-            while 1:
-                self.sendSMB(smb)
-                ans = self.recvSMB()
-
-                if ans.isValidAnswer(SMB.SMB_COM_READ):
-                    readResponse   = SMBCommand(ans['Data'][0])
-                    readData       = SMBReadResponse_Data(readResponse['Data'])
-
-                    return readData['Data']
-
-        return None
-
-    def read_andx(self, tid, fid, offset=0, max_size = None, wait_answer=1, 
smb_packet=None):
-        if not max_size:
-            if (self._dialects_parameters['Capabilities'] & 
SMB.CAP_LARGE_READX) and self._SignatureEnabled is False:
-                max_size = 65000
-            else:
-                max_size = self._dialects_parameters['MaxBufferSize'] # Read 
in multiple KB blocks
-
-        # max_size is not working, because although it would, the server 
returns an error (More data avail)
-
-        if smb_packet is None:
-            smb = NewSMBPacket()
-            smb['Tid']    = tid
-
-            readAndX = SMBCommand(SMB.SMB_COM_READ_ANDX)
-            readAndX['Parameters'] = SMBReadAndX_Parameters()
-            readAndX['Parameters']['Fid'] = fid
-            readAndX['Parameters']['Offset'] = offset
-            readAndX['Parameters']['MaxCount'] = max_size
-            smb.addCommand(readAndX)
-        else:
-            smb = smb_packet
-
-        if wait_answer:
-            answer = ''
-            while 1:
-                self.sendSMB(smb)
-                ans = self.recvSMB()
-
-                if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX):
-                    # XXX Here we are only using a few fields from the response
-                    readAndXResponse   = SMBCommand(ans['Data'][0])
-                    readAndXParameters = 
SMBReadAndXResponse_Parameters(readAndXResponse['Parameters'])
-
-                    offset = readAndXParameters['DataOffset']
-                    count = 
readAndXParameters['DataCount']+0x10000*readAndXParameters['DataCount_Hi']
-                    answer += str(ans)[offset:offset+count]
-                    if not ans.isMoreData():
-                        return answer
-                    max_size = min(max_size, readAndXParameters['Remaining'])
-                    readAndX['Parameters']['Offset'] += count                  
    # XXX Offset is not important (apparently)
-        else:
-            self.sendSMB(smb)
-            ans = self.recvSMB()
-
-            try:
-                if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX):
-                    return ans
-                else:
-                    return None
-            except:
-                return ans
-
-        return None
-
-    def read_raw(self, tid, fid, offset=0, max_size = None, wait_answer=1):
-        if not max_size:
-            max_size = self._dialects_parameters['MaxBufferSize'] # Read in 
multiple KB blocks
-
-        # max_size is not working, because although it would, the server 
returns an error (More data avail)
-        smb = NewSMBPacket()
-        smb['Tid']    = tid
-
-        readRaw = SMBCommand(SMB.SMB_COM_READ_RAW)
-        readRaw['Parameters'] = SMBReadRaw_Parameters()
-        readRaw['Parameters']['Fid'] = fid
-        readRaw['Parameters']['Offset'] = offset
-        readRaw['Parameters']['MaxCount'] = max_size
-        smb.addCommand(readRaw)
-
-        self.sendSMB(smb)
-        if wait_answer:
-            data = self._sess.recv_packet(self.__timeout).get_trailer()
-            if not data:
-                # If there is no data it means there was an error
-                data = self.read_andx(tid, fid, offset, max_size)
-            return data
-
-        return None
-
-    def write(self,tid,fid,data, offset = 0, wait_answer=1):
-        smb = NewSMBPacket()
-        smb['Tid']    = tid
-
-        write = SMBCommand(SMB.SMB_COM_WRITE)
-        write['Parameters'] = SMBWrite_Parameters()
-        write['Data'] = SMBWrite_Data()
-        write['Parameters']['Fid'] = fid
-        write['Parameters']['Count'] = len(data)
-        write['Parameters']['Offset'] = offset
-        write['Parameters']['Remaining'] = len(data)
-        write['Data']['Data'] = data
-        smb.addCommand(write)
-
-        self.sendSMB(smb)
-
-        if wait_answer:
-            smb = self.recvSMB()
-            if smb.isValidAnswer(SMB.SMB_COM_WRITE):
-                return smb
-        return None
-
-    def write_andx(self,tid,fid,data, offset = 0, wait_answer=1, 
write_pipe_mode = False, smb_packet=None):
-        if smb_packet is None:
-            smb = NewSMBPacket()
-            smb['Tid']    = tid
-
-            writeAndX = SMBCommand(SMB.SMB_COM_WRITE_ANDX)
-            smb.addCommand(writeAndX)
-
-            writeAndX['Parameters'] = SMBWriteAndX_Parameters()
-            writeAndX['Parameters']['Fid'] = fid
-            writeAndX['Parameters']['Offset'] = offset
-            writeAndX['Parameters']['WriteMode'] = 8
-            writeAndX['Parameters']['Remaining'] = len(data)
-            writeAndX['Parameters']['DataLength'] = len(data)
-            writeAndX['Parameters']['DataOffset'] = len(smb)    # this length 
already includes the parameter
-            writeAndX['Data'] = data
-
-            if write_pipe_mode is True:
-                # First of all we gotta know what the MaxBuffSize is
-                maxBuffSize = self._dialects_parameters['MaxBufferSize']
-                if len(data) > maxBuffSize:
-                    chunks_size = maxBuffSize - 60
-                    writeAndX['Parameters']['WriteMode'] = 0x0c
-                    sendData = '\xff\xff' + data
-                    totalLen = len(sendData)
-                    writeAndX['Parameters']['DataLength'] = chunks_size
-                    writeAndX['Parameters']['Remaining'] = totalLen-2
-                    writeAndX['Data'] = sendData[:chunks_size]
-
-                    self.sendSMB(smb)
-                    if wait_answer:
-                        smbResp = self.recvSMB()
-                        smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX)
-
-                    alreadySent = chunks_size
-                    sendData = sendData[chunks_size:]
-
-                    while alreadySent < totalLen:
-                        writeAndX['Parameters']['WriteMode'] = 0x04
-                        writeAndX['Parameters']['DataLength'] = 
len(sendData[:chunks_size])
-                        writeAndX['Data'] = sendData[:chunks_size]
-                        self.sendSMB(smb)
-                        if wait_answer:
-                            smbResp = self.recvSMB()
-                            smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX)
-                        alreadySent += writeAndX['Parameters']['DataLength']
-                        sendData = sendData[chunks_size:]
-
-                    return smbResp
-
-        else:
-            smb = smb_packet
-
-        self.sendSMB(smb)
-
-        if wait_answer:
-            smb = self.recvSMB()
-            if smb.isValidAnswer(SMB.SMB_COM_WRITE_ANDX):
-                return smb
-        return None
-
-    def write_raw(self,tid,fid,data, offset = 0, wait_answer=1):
-        LOG.warning("[MS-CIFS] This command was introduced in the CorePlus 
dialect, but is often listed as part of the LAN Manager 1.0 dialect.This 
command has been deprecated.Clients SHOULD use SMB_COM_WRITE_ANDX")
-        smb = NewSMBPacket()
-        smb['Tid']    = tid
-
-        writeRaw = SMBCommand(SMB.SMB_COM_WRITE_RAW)
-        writeRaw['Parameters'] = SMBWriteRaw_Parameters()
-        writeRaw['Parameters']['Fid'] = fid
-        writeRaw['Parameters']['Offset'] = offset
-        writeRaw['Parameters']['Count'] = len(data)
-        writeRaw['Parameters']['DataLength'] = 0
-        writeRaw['Parameters']['DataOffset'] = 0
-        smb.addCommand(writeRaw)
-
-        self.sendSMB(smb)
-        self._sess.send_packet(data)
-
-        if wait_answer:
-            smb = self.recvSMB()
-            if smb.isValidAnswer(SMB.SMB_COM_WRITE_RAW):
-                return smb
-        return None
-
-    def TransactNamedPipe(self, tid, fid, data = '', noAnswer = 0, waitAnswer 
= 1, offset = 0):
-        self.send_trans(tid,pack('<HH', 0x26, fid),'\\PIPE\\\x00','',data, 
noAnswer = noAnswer)
-
-        if noAnswer or not waitAnswer:
-            return
-        smb = self.recvSMB()
-        if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION):
-           transResponse = SMBCommand(smb['Data'][0])
-           transParameters = 
SMBTransactionResponse_Parameters(transResponse['Parameters'])
-           return transResponse['Data'][-transParameters['TotalDataCount']:] # 
Remove Potential Prefix Padding
-        return None
-
-    def TransactNamedPipeRecv(self):
-        s = self.recvSMB()
-        if s.isValidAnswer(SMB.SMB_COM_TRANSACTION):
-           transResponse = SMBCommand(s['Data'][0])
-           transParameters = 
SMBTransactionResponse_Parameters(transResponse['Parameters'])
-           return transResponse['Data'][-transParameters['TotalDataCount']:] # 
Remove Potential Prefix Padding
-        return None
-
-    def nt_create_andx(self,tid,filename, smb_packet=None, cmd = None, 
shareAccessMode = FILE_SHARE_READ | FILE_SHARE_WRITE, disposition = FILE_OPEN, 
accessMask = 0x2019f):
-        filename = filename.replace('/', '\\')
-        filename = filename.encode('utf-16le') if self.__flags2 & 
SMB.FLAGS2_UNICODE else filename
-
-        if smb_packet is None:
-            smb = NewSMBPacket()
-            smb['Tid']    = tid
-        else:
-            smb = smb_packet
-
-        if cmd is None:
-            ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX)
-            ntCreate['Parameters'] = SMBNtCreateAndX_Parameters()
-            ntCreate['Data']       = SMBNtCreateAndX_Data(flags=self.__flags2)
-            ntCreate['Parameters']['FileNameLength'] = len(filename)
-            ntCreate['Parameters']['CreateFlags'] = 0x16
-            ntCreate['Parameters']['AccessMask'] = accessMask
-            ntCreate['Parameters']['CreateOptions'] = 0x40
-            ntCreate['Parameters']['ShareAccess'] = shareAccessMode
-            ntCreate['Parameters']['Disposition'] = disposition
-            ntCreate['Data']['FileName'] = filename
-
-            if self.__flags2 & SMB.FLAGS2_UNICODE:
-                ntCreate['Data']['Pad'] = 0x0
-        else:
-            ntCreate = cmd
-
-        smb.addCommand(ntCreate)
-
-        self.sendSMB(smb)
-
-        while 1:
-            smb = self.recvSMB()
-            if smb.isValidAnswer(SMB.SMB_COM_NT_CREATE_ANDX):
-                # XXX Here we are ignoring the rest of the response
-                ntCreateResponse   = SMBCommand(smb['Data'][0])
-                ntCreateParameters = 
SMBNtCreateAndXResponse_Parameters(ntCreateResponse['Parameters'])
-
-                self.fid = ntCreateParameters['Fid']
-                return ntCreateParameters['Fid']
-
-    def logoff(self):
-        smb = NewSMBPacket()
-
-        logOff = SMBCommand(SMB.SMB_COM_LOGOFF_ANDX)
-        logOff['Parameters'] = SMBLogOffAndX()
-        smb.addCommand(logOff)
-
-        self.sendSMB(smb)
-        self.recvSMB()
-        # Let's clear some fields so you can login again under the same session
-        self._uid = 0
-
-    def list_path(self, service, path = '*', password = None):
-        path = path.replace('/', '\\')
-        path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE 
else path
-
-        tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + 
service, password)
-        try:
-            findFirstParameter = SMBFindFirst2_Parameters()
-            findFirstParameter['SearchAttributes'] = 
SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_HIDDEN | \
-                                                     SMB_FILE_ATTRIBUTE_SYSTEM 
| SMB_FILE_ATTRIBUTE_READONLY | \
-                                                     SMB_FILE_ATTRIBUTE_ARCHIVE
-            findFirstParameter['SearchCount'] = 512
-            findFirstParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | 
SMB_FIND_CLOSE_AT_EOS
-            findFirstParameter['InformationLevel'] = 
SMB_FIND_FILE_BOTH_DIRECTORY_INFO
-            findFirstParameter['SearchStorageType'] = 0
-            findFirstParameter['FileName'] = path + ('\x00\x00' if 
self.__flags2 & SMB.FLAGS2_UNICODE else '\x00')
-            self.send_trans2(tid, SMB.TRANS2_FIND_FIRST2, '\x00', 
findFirstParameter, '')
-            files = [ ]
-
-            totalDataCount = 1
-            findData = ''
-            findFirst2ParameterBlock = ''
-            while len(findData) < totalDataCount:
-                resp = self.recvSMB()
-
-                if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2):
-                    trans2Response = SMBCommand(resp['Data'][0])
-                    trans2Parameters = 
SMBTransaction2Response_Parameters(trans2Response['Parameters'])
-                    totalDataCount = trans2Parameters['TotalDataCount']
-                    findFirst2ParameterBlock += 
trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']]
-                    findData += 
trans2Response['Data'][trans2Parameters['DataOffset']-55:]
-
-            findParameterBlock = 
SMBFindFirst2Response_Parameters(findFirst2ParameterBlock)
-            # Save the SID for resume operations
-            sid = findParameterBlock['SID']
-
-            while True:
-                record = SMBFindFileBothDirectoryInfo(data = findData)
-
-                shortname = record['ShortName'].decode('utf-16le') if 
self.__flags2 & SMB.FLAGS2_UNICODE else record['ShortName']
-                filename = record['FileName'].decode('utf-16le') if 
self.__flags2 & SMB.FLAGS2_UNICODE else record['FileName']
-
-                fileRecord = SharedFile(record['CreationTime'], 
record['LastAccessTime'], record['LastChangeTime'],
-                                  record['EndOfFile'], 
record['AllocationSize'], record['ExtFileAttributes'],
-                                  shortname, filename)
-                files.append(fileRecord)
-                if record['NextEntryOffset'] > 0 and 
len(findData[record['NextEntryOffset']:]) > 0:
-                    findData = findData[record['NextEntryOffset']:]
-                else:
-                    # More data to search?
-                    if findParameterBlock['EndOfSearch'] == 0:
-                        resume_filename = record['FileName']
-                        findNextParameter = SMBFindNext2_Parameters()
-                        findNextParameter['SID'] = sid
-                        findNextParameter['SearchCount'] = 1024
-                        findNextParameter['InformationLevel'] = 
SMB_FIND_FILE_BOTH_DIRECTORY_INFO
-                        findNextParameter['ResumeKey'] = 0
-                        findNextParameter['Flags'] = 
SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS
-                        findNextParameter['FileName'] = resume_filename + 
('\x00\x00' if self.__flags2 & SMB.FLAGS2_UNICODE else '\x00')
-                        self.send_trans2(tid, SMB.TRANS2_FIND_NEXT2, '\x00', 
findNextParameter, '')
-                        findData = ''
-                        findNext2ParameterBlock = ''
-                        totalDataCount = 1
-                        while len(findData) < totalDataCount:
-                            resp = self.recvSMB()
-
-                            if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2):
-                                trans2Response = SMBCommand(resp['Data'][0])
-                                trans2Parameters = 
SMBTransaction2Response_Parameters(trans2Response['Parameters'])
-                                totalDataCount = 
trans2Parameters['TotalDataCount']
-                                findNext2ParameterBlock += 
trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']]
-                                findData += 
trans2Response['Data'][trans2Parameters['DataOffset']-55:]
-                                findParameterBlock = 
SMBFindNext2Response_Parameters(findNext2ParameterBlock)
-                    else:
-                       break
-        finally:
-            self.disconnect_tree(tid)
-
-        return files
-
-    def retr_file(self, service, filename, callback, mode = FILE_OPEN, offset 
= 0, password = None, shareAccessMode = SMB_ACCESS_READ):
-        filename = string.replace(filename, '/', '\\')
-
-        fid = -1
-        tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + 
service, password)
-        try:
-            fid = self.nt_create_andx(tid, filename, shareAccessMode = 
shareAccessMode, accessMask = 0x20089)
-
-            res = self.query_file_info(tid, fid)
-            datasize = SMBQueryFileStandardInfo(res)['EndOfFile']
-
-            self.__nonraw_retr_file(tid, fid, offset, datasize, callback)
-        finally:
-            if fid >= 0:
-                self.close(tid, fid)
-            self.disconnect_tree(tid)
-
-    def stor_file(self, service, filename, callback, mode = FILE_OVERWRITE_IF, 
offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE):
-        filename = string.replace(filename, '/', '\\')
-
-        fid = -1
-        tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + 
service, password)
-        try:
-            fid = self.nt_create_andx(tid, filename, shareAccessMode = 
shareAccessMode, disposition = mode )
-
-            self.__nonraw_stor_file(tid, fid, offset, 0, callback)
-        finally:
-            if fid >= 0:
-                self.close(tid, fid)
-            self.disconnect_tree(tid)
-
-    def stor_file_nonraw(self, service, filename, callback, mode = 
FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = 
SMB_ACCESS_WRITE ):
-        filename = string.replace(filename, '/', '\\')
-
-        fid = -1
-        tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + 
service, password)
-        try:
-            fid = self.nt_create_andx(tid, filename, shareAccessMode = 
shareAccessMode, disposition = mode)
-            self.__nonraw_stor_file(tid, fid, offset, 0, callback)
-        finally:
-            if fid >= 0:
-                self.close(tid, fid)
-            self.disconnect_tree(tid)
-
-    def check_dir(self, service, path, password = None):
-        path = string.replace(path,'/', '\\')
-        tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + 
service, password)
-        try:
-            smb = NewSMBPacket()
-            smb['Tid'] = tid
-            smb['Mid'] = 0
-
-            cmd = SMBCommand(SMB.SMB_COM_CHECK_DIRECTORY)
-            cmd['Parameters'] = ''
-            cmd['Data'] = SMBCheckDirectory_Data(flags = self.__flags2)
-            cmd['Data']['DirectoryName'] = path.encode('utf-16le') if 
self.__flags2 & SMB.FLAGS2_UNICODE else path
-            smb.addCommand(cmd)
-
-            self.sendSMB(smb)
-
-            while 1:
-                s = self.recvSMB()
-                if s.isValidAnswer(SMB.SMB_COM_CHECK_DIRECTORY):
-                    return
-        finally:
-            self.disconnect_tree(tid)
-
-    def remove(self, service, path, password = None):
-        path = string.replace(path,'/', '\\')
-        # Perform a list to ensure the path exists
-        self.list_path(service, path, password)
-
-        tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + 
service, password)
-        try:
-            smb = NewSMBPacket()
-            smb['Tid'] = tid
-            smb['Mid'] = 0
-
-            cmd = SMBCommand(SMB.SMB_COM_DELETE)
-            cmd['Parameters'] = SMBDelete_Parameters()
-            cmd['Parameters']['SearchAttributes'] = ATTR_HIDDEN | ATTR_SYSTEM 
| ATTR_ARCHIVE
-            cmd['Data'] = SMBDelete_Data(flags = self.__flags2)
-            cmd['Data']['FileName'] = (path + '\x00').encode('utf-16le') if 
self.__flags2 & SMB.FLAGS2_UNICODE else (path + '\x00')
-            smb.addCommand(cmd)
-
-            self.sendSMB(smb)
-
-            while 1:
-                s = self.recvSMB()
-                if s.isValidAnswer(SMB.SMB_COM_DELETE):
-                    return
-        finally:
-            self.disconnect_tree(tid)
-
-    def rmdir(self, service, path, password = None):
-        path = string.replace(path,'/', '\\')
-        # Check that the directory exists
-        self.check_dir(service, path, password)
-
-        tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + 
service, password)
-        try:
-            path = path.encode('utf-16le') if self.__flags2 & 
SMB.FLAGS2_UNICODE else path
-
-            smb = NewSMBPacket()
-            smb['Tid'] = tid
-            createDir = SMBCommand(SMB.SMB_COM_DELETE_DIRECTORY)
-            createDir['Data'] = SMBDeleteDirectory_Data(flags=self.__flags2)
-            createDir['Data']['DirectoryName'] = path
-            smb.addCommand(createDir)
-
-            self.sendSMB(smb)
-
-            while 1:
-                s = self.recvSMB()
-                if s.isValidAnswer(SMB.SMB_COM_DELETE_DIRECTORY):
-                    return
-        finally:
-            self.disconnect_tree(tid)
-
-    def mkdir(self, service, path, password = None):
-        path = string.replace(path,'/', '\\')
-        tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + 
service, password)
-        try:
-            path = path.encode('utf-16le') if self.__flags2 & 
SMB.FLAGS2_UNICODE else path
-
-            smb = NewSMBPacket()
-            smb['Tid'] = tid
-            smb['Mid'] = 0
-
-            createDir = SMBCommand(SMB.SMB_COM_CREATE_DIRECTORY)
-            createDir['Data'] = SMBCreateDirectory_Data(flags=self.__flags2)
-            createDir['Data']['DirectoryName'] = path
-            smb.addCommand(createDir)
-
-            self.sendSMB(smb)
-
-            smb = self.recvSMB()
-            if smb.isValidAnswer(SMB.SMB_COM_CREATE_DIRECTORY):
-                return 1
-            return 0
-        finally:
-            self.disconnect_tree(tid)
-
-    def rename(self, service, old_path, new_path, password = None):
-        old_path = string.replace(old_path,'/', '\\')
-        new_path = string.replace(new_path,'/', '\\')
-        tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + 
service, password)
-        try:
-            smb = NewSMBPacket()
-            smb['Tid'] = tid
-            smb['Mid'] = 0
-
-            renameCmd = SMBCommand(SMB.SMB_COM_RENAME)
-            renameCmd['Parameters'] = SMBRename_Parameters()
-            renameCmd['Parameters']['SearchAttributes'] = ATTR_SYSTEM | 
ATTR_HIDDEN | ATTR_DIRECTORY
-            renameCmd['Data'] = SMBRename_Data(flags = self.__flags2)
-            renameCmd['Data']['OldFileName'] = old_path.encode('utf-16le') if 
self.__flags2 & SMB.FLAGS2_UNICODE else old_path
-            renameCmd['Data']['NewFileName'] = new_path.encode('utf-16le') if 
self.__flags2 & SMB.FLAGS2_UNICODE else new_path
-            smb.addCommand(renameCmd)
-
-            self.sendSMB(smb)
-
-            smb = self.recvSMB()
-            if smb.isValidAnswer(SMB.SMB_COM_RENAME):
-               return 1
-            return 0
-        finally:
-            self.disconnect_tree(tid)
-
-    def writeFile(self, treeId, fileId, data, offset = 0):
-        if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) 
and self._SignatureEnabled is False:
-            max_buf_size = 65000
-        else:
-            max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff 
 # Write in multiple KB blocks
-
-        write_offset = offset
-        while 1:
-            if len(data) == 0:
-                break
-            writeData = data[:max_buf_size]
-            data = data[max_buf_size:]
-
-            smb = self.write_andx(treeId,fileId,writeData, write_offset)
-            writeResponse   = SMBCommand(smb['Data'][0])
-            writeResponseParameters = 
SMBWriteAndXResponse_Parameters(writeResponse['Parameters'])
-            write_offset += writeResponseParameters['Count']
-
-    def get_socket(self):
-        return self._sess.get_socket()
-
-ERRDOS = { 1: 'Invalid function',
-           2: 'File not found',
-           3: 'Invalid directory',
-           4: 'Too many open files',
-           5: 'Access denied',
-           6: 'Invalid file handle. Please file a bug report.',
-           7: 'Memory control blocks destroyed',
-           8: 'Out of memory',
-           9: 'Invalid memory block address',
-           10: 'Invalid environment',
-           11: 'Invalid format',
-           12: 'Invalid open mode',
-           13: 'Invalid data',
-           15: 'Invalid drive',
-           16: 'Attempt to remove server\'s current directory',
-           17: 'Not the same device',
-           18: 'No files found',
-           32: 'Sharing mode conflicts detected',
-           33: 'Lock request conflicts detected',
-           80: 'File already exists'
-           }
-
-ERRSRV = { 1: 'Non-specific error',
-           2: 'Bad password',
-           4: 'Access denied',
-           5: 'Invalid tid. Please file a bug report.',
-           6: 'Invalid network name',
-           7: 'Invalid device',
-           49: 'Print queue full',
-           50: 'Print queue full',
-           51: 'EOF on print queue dump',
-           52: 'Invalid print file handle',
-           64: 'Command not recognized. Please file a bug report.',
-           65: 'Internal server error',
-           67: 'Invalid path',
-           69: 'Invalid access permissions',
-           71: 'Invalid attribute mode',
-           81: 'Server is paused',
-           82: 'Not receiving messages',
-           83: 'No room to buffer messages',
-           87: 'Too many remote user names',
-           88: 'Operation timeout',
-           89: 'Out of resources',
-           91: 'Invalid user handle. Please file a bug report.',
-           250: 'Temporarily unable to support raw mode for transfer',
-           251: 'Temporarily unable to support raw mode for transfer',
-           252: 'Continue in MPX mode',
-           65535: 'Unsupported function'
-           }
-
-ERRHRD = { 19: 'Media is write-protected',
-           20: 'Unknown unit',
-           21: 'Drive not ready',
-           22: 'Unknown command',
-           23: 'CRC error',
-           24: 'Bad request',
-           25: 'Seek error',
-           26: 'Unknown media type',
-           27: 'Sector not found',
-           28: 'Printer out of paper',
-           29: 'Write fault',
-           30: 'Read fault',
-           31: 'General failure',
-           32: 'Open conflicts with an existing open',
-           33: 'Invalid lock request',
-           34: 'Wrong disk in drive',
-           35: 'FCBs not available',
-           36: 'Sharing buffer exceeded'
-           }
-
diff --git a/tests/python_dependencies/impacket/smb3.py 
b/tests/python_dependencies/impacket/smb3.py
deleted file mode 100644
index d81c7e117..000000000
--- a/tests/python_dependencies/impacket/smb3.py
+++ /dev/null
@@ -1,1630 +0,0 @@
-from __future__ import print_function
-# Copyright (c) 2003-2016 CORE Security Technologies
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-# Author: Alberto Solino (@agsolino)
-#
-# Description:
-#   [MS-SMB2] Protocol Implementation (SMB2 and SMB3)
-#   As you might see in the code, it's implemented strictly following 
-#   the structures defined in the protocol specification. This may
-#   not be the most efficient way (e.g. self._Connection is the
-#   same to self._Session in the context of this library ) but
-#   it certainly helps following the document way easier.
-#
-# ToDo: 
-# [X] Implement SMB2_CHANGE_NOTIFY
-# [X] Implement SMB2_QUERY_INFO
-# [X] Implement SMB2_SET_INFO
-# [ ] Implement SMB2_OPLOCK_BREAK
-# [X] Implement SMB3 signing 
-# [ ] Implement SMB3 encryption
-# [ ] Add more backward compatible commands from the smb.py code
-# [ ] Fix up all the 'ToDo' comments inside the code
-#
-
-import socket
-import ntpath
-import random
-import string
-import struct
-from binascii import a2b_hex
-from contextlib import contextmanager
-
-from impacket import nmb, ntlm, uuid, crypto, LOG
-from impacket.smb3structs import *
-from impacket.nt_errors import STATUS_SUCCESS, 
STATUS_MORE_PROCESSING_REQUIRED, STATUS_INVALID_PARAMETER, \
-    STATUS_NO_MORE_FILES, STATUS_PENDING, STATUS_NOT_IMPLEMENTED, 
ERROR_MESSAGES
-from impacket.spnego import SPNEGO_NegTokenInit, TypesMech, SPNEGO_NegTokenResp
-
-
-# For signing
-import hashlib, hmac, copy
-
-# Structs to be used
-TREE_CONNECT = {
-    'ShareName'       : '',
-    'TreeConnectId'   : 0,
-    'Session'         : 0,
-    'IsDfsShare'      : False,
-    # If the client implements the SMB 3.0 dialect, 
-    # the client MUST also implement the following
-    'IsCAShare'       : False,
-    'EncryptData'     : False,
-    'IsScaleoutShare' : False,
-    # Outside the protocol
-    'NumberOfUses'    : 0,
-}
-
-FILE = {
-    'OpenTable'       : [],
-    'LeaseKey'        : '',
-    'LeaseState'      : 0,
-    'LeaseEpoch'      : 0,
-}
-
-OPEN = {
-    'FileID'             : '',
-    'TreeConnect'        : 0,
-    'Connection'         : 0, # Not Used
-    'Oplocklevel'        : 0,
-    'Durable'            : False,
-    'FileName'           : '',
-    'ResilientHandle'    : False,
-    'LastDisconnectTime' : 0,
-    'ResilientTimeout'   : 0,
-    'OperationBuckets'   : [],
-    # If the client implements the SMB 3.0 dialect, 
-    # the client MUST implement the following
-    'CreateGuid'         : '',
-    'IsPersistent'       : False,
-    'DesiredAccess'      : '',
-    'ShareMode'          : 0,
-    'CreateOption'       : '',
-    'FileAttributes'     : '',
-    'CreateDisposition'  : '',
-}
-
-REQUEST = {
-    'CancelID'     : '',
-    'Message'      : '',
-    'Timestamp'    : 0,
-}
-
-CHANNEL = {
-    'SigningKey' : '',
-    'Connection' : 0,
-}
-
-
-class SessionError(Exception):
-    def __init__( self, error = 0, packet=0):
-        Exception.__init__(self)
-        self.error = error
-        self.packet = packet
-       
-    def get_error_code( self ):
-        return self.error
-
-    def get_error_packet( self ):
-        return self.packet
-
-    def __str__( self ):
-        return 'SMB SessionError: %s(%s)' % (ERROR_MESSAGES[self.error])
-
-
-class SMB3:
-    def __init__(self, remote_name, remote_host, my_name = None, host_type = 
nmb.TYPE_SERVER, sess_port = 445, timeout=60, UDP = 0, preferredDialect = None, 
session = None):
-
-        # [MS-SMB2] Section 3
-        self.RequireMessageSigning = False    #
-        self.ConnectionTable = {}
-        self.GlobalFileTable = {}
-        self.ClientGuid = ''.join([random.choice(string.letters) for i in 
range(16)])
-        # Only for SMB 3.0
-        self.EncryptionAlgorithmList = ['AES-CCM']
-        self.MaxDialect = []
-        self.RequireSecureNegotiate = False
-
-        # Per Transport Connection Data
-        self._Connection = {
-            # Indexed by SessionID
-            #'SessionTable'             : {},    
-            # Indexed by MessageID
-            'OutstandingRequests'      : {},
-            'OutstandingResponses'     : {},    #
-            'SequenceWindow'           : 0,     #
-            'GSSNegotiateToken'        : '',    #
-            'MaxTransactSize'          : 0,     #
-            'MaxReadSize'              : 0,     #
-            'MaxWriteSize'             : 0,     #
-            'ServerGuid'               : '',    #
-            'RequireSigning'           : False, #
-            'ServerName'               : '',    #
-            # If the client implements the SMB 2.1 or SMB 3.0 dialects, it 
MUST 
-            # also implement the following
-            'Dialect'                  : '',    #
-            'SupportsFileLeasing'      : False, #
-            'SupportsMultiCredit'      : False, #
-            # If the client implements the SMB 3.0 dialect, 
-            # it MUST also implement the following
-            'SupportsDirectoryLeasing' : False, #
-            'SupportsMultiChannel'     : False, #
-            'SupportsPersistentHandles': False, #
-            'SupportsEncryption'       : False, #
-            'ClientCapabilities'       : 0,
-            'ServerCapabilities'       : 0,    #
-            'ClientSecurityMode'       : 0,    #
-            'ServerSecurityMode'       : 0,    #
-            # Outside the protocol
-            'ServerIP'                 : '',    #
-        }
-   
-        self._Session = {
-            'SessionID'                : 0,   #
-            'TreeConnectTable'         : {},    #
-            'SessionKey'               : '',    #
-            'SigningRequired'          : False, #
-            'Connection'               : 0,     # 
-            'UserCredentials'          : '',    #
-            'OpenTable'                : {},    #
-            # If the client implements the SMB 3.0 dialect, 
-            # it MUST also implement the following
-            'ChannelList'              : [],
-            'ChannelSequence'          : 0,
-            #'EncryptData'              : False,
-            'EncryptData'              : True,
-            'EncryptionKey'            : '',
-            'DecryptionKey'            : '',
-            'SigningKey'               : '',  
-            'ApplicationKey'           : '',
-            # Outside the protocol
-            'SessionFlags'             : 0,     # 
-            'ServerName'               : '',    #
-            'ServerDomain'             : '',    #
-            'ServerDNSDomainName'      : '',    #
-            'ServerOS'                 : '',    #
-            'SigningActivated'         : False, #
-        }
-
-        self.SMB_PACKET = SMB2Packet
-        
-        self._timeout = timeout
-        self._Connection['ServerIP'] = remote_host
-        self._NetBIOSSession = None
-
-        self.__userName = ''
-        self.__password = ''
-        self.__domain   = ''
-        self.__lmhash   = ''
-        self.__nthash   = ''
-        self.__kdc      = ''
-        self.__aesKey   = ''
-        self.__TGT      = None
-        self.__TGS      = None
-
-        if sess_port == 445 and remote_name == '*SMBSERVER':
-           self._Connection['ServerName'] = remote_host
-        else:
-           self._Connection['ServerName'] = remote_name
-
-        if session is None:
-            if not my_name:
-                my_name = socket.gethostname()
-                i = string.find(my_name, '.')
-                if i > -1:
-                    my_name = my_name[:i]
-
-            if UDP:
-                self._NetBIOSSession = nmb.NetBIOSUDPSession(my_name, 
self._Connection['ServerName'], remote_host, host_type, sess_port, 
self._timeout)
-            else:
-                self._NetBIOSSession = nmb.NetBIOSTCPSession(my_name, 
self._Connection['ServerName'], remote_host, host_type, sess_port, 
self._timeout)
-
-                self.negotiateSession(preferredDialect)
-        else:
-            self._NetBIOSSession = session
-            # We should increase the SequenceWindow since a packet was already 
received.
-            self._Connection['SequenceWindow'] += 1
-            # Let's negotiate again using the same connection
-            self.negotiateSession(preferredDialect)
-
-    def printStatus(self):
-        print("CONNECTION")
-        for i in self._Connection.items():
-            print("%-40s : %s" % i)
-        print()
-        print("SESSION")
-        for i in self._Session.items():
-            print("%-40s : %s" % i)
-
-    def getServerName(self):
-        return self._Session['ServerName']
-
-    def getServerIP(self):
-        return self._Connection['ServerIP']
-
-    def getServerDomain(self):
-        return self._Session['ServerDomain']
-
-    def getServerDNSDomainName(self):
-        return self._Session['ServerDNSDomainName']
-
-    def getServerOS(self):
-        return self._Session['ServerOS']
-
-    def getServerOSMajor(self):
-        return self._Session['ServerOSMajor']
-
-    def getServerOSMinor(self):
-        return self._Session['ServerOSMinor']
-
-    def getServerOSBuild(self):
-        return self._Session['ServerOSBuild']
-
-    def isGuestSession(self):
-        return self._Session['SessionFlags'] & SMB2_SESSION_FLAG_IS_GUEST 
-
-    def setTimeout(self, timeout):
-        self._timeout = timeout
-
-    @contextmanager
-    def useTimeout(self, timeout):
-        prev_timeout = self.getTimeout(timeout)
-        try:
-            yield
-        finally:
-            self.setTimeout(prev_timeout)
-
-    def getDialect(self):
-        return self._Connection['Dialect']
-
-
-    def signSMB(self, packet):
-        packet['Signature'] = '\x00'*16
-        if self._Connection['Dialect'] == SMB2_DIALECT_21 or 
self._Connection['Dialect'] == SMB2_DIALECT_002:
-            if len(self._Session['SessionKey']) > 0:
-                signature = hmac.new(self._Session['SessionKey'], str(packet), 
hashlib.sha256).digest()
-                packet['Signature'] = signature[:16]
-        else:
-            if len(self._Session['SessionKey']) > 0:
-                p = str(packet)
-                signature = crypto.AES_CMAC(self._Session['SigningKey'], p, 
len(p))
-                packet['Signature'] = signature
-     
-    def sendSMB(self, packet):
-        # The idea here is to receive multiple/single commands and create a 
compound request, and send it
-        # Should return the MessageID for later retrieval. Implement 
compounded related requests.
-
-        # If Connection.Dialect is equal to "3.000" and if 
Connection.SupportsMultiChannel or
-        # Connection.SupportsPersistentHandles is TRUE, the client MUST set 
ChannelSequence in the
-        # SMB2 header to Session.ChannelSequence
-
-        # Check this is not a CANCEL request. If so, don't consume sequece 
numbers
-        if packet['Command'] is not SMB2_CANCEL:
-            packet['MessageID'] = self._Connection['SequenceWindow']
-            self._Connection['SequenceWindow'] += 1
-        packet['SessionID'] = self._Session['SessionID']
-
-        # Default the credit charge to 1 unless set by the caller
-        if ('CreditCharge' in packet.fields) is False:
-            packet['CreditCharge'] = 1
-
-        # Standard credit request after negotiating protocol
-        if self._Connection['SequenceWindow'] > 3:
-            packet['CreditRequestResponse'] = 127
-
-        messageId = packet['MessageID']
-
-        if self._Session['SigningActivated'] is True and 
self._Connection['SequenceWindow'] > 2:
-            if packet['TreeID'] > 0 and (packet['TreeID'] in 
self._Session['TreeConnectTable']) is True:
-                if 
self._Session['TreeConnectTable'][packet['TreeID']]['EncryptData'] is False:
-                    packet['Flags'] = SMB2_FLAGS_SIGNED
-                    self.signSMB(packet)
-            elif packet['TreeID'] == 0:
-                packet['Flags'] = SMB2_FLAGS_SIGNED
-                self.signSMB(packet)
-
-        if (self._Session['SessionFlags'] & SMB2_SESSION_FLAG_ENCRYPT_DATA) or 
( packet['TreeID'] != 0 and 
self._Session['TreeConnectTable'][packet['TreeID']]['EncryptData'] is True):
-            plainText = str(packet)
-            transformHeader = SMB2_TRANSFORM_HEADER()
-            transformHeader['Nonce'] = ''.join([random.choice(string.letters) 
for i in range(11)])
-            transformHeader['OriginalMessageSize'] = len(plainText)
-            transformHeader['EncryptionAlgorithm'] = SMB2_ENCRYPTION_AES128_CCM
-            transformHeader['SessionID'] = self._Session['SessionID'] 
-            from Crypto.Cipher import AES
-            try: 
-                AES.MODE_CCM
-            except:
-                LOG.critical("Your pycrypto doesn't support AES.MODE_CCM. 
Currently only pycrypto experimental supports this mode.\nDownload it from 
https://www.dlitz.net/software/pycrypto ")
-                raise 
-            cipher = AES.new(self._Session['EncryptionKey'], AES.MODE_CCM,  
transformHeader['Nonce'])
-            cipher.update(str(transformHeader)[20:])
-            cipherText = cipher.encrypt(plainText)
-            transformHeader['Signature'] = cipher.digest()
-            packet = str(transformHeader) + cipherText
-
-        self._NetBIOSSession.send_packet(str(packet))
-        return messageId
-
-    def recvSMB(self, packetID = None):
-        # First, verify we don't have the packet already
-        if packetID in self._Connection['OutstandingResponses']:
-            return self._Connection['OutstandingResponses'].pop(packetID) 
-
-        data = self._NetBIOSSession.recv_packet(self._timeout) 
-
-        if data.get_trailer().startswith('\xfdSMB'):
-            # Packet is encrypted
-            transformHeader = SMB2_TRANSFORM_HEADER(data.get_trailer())
-            from Crypto.Cipher import AES
-            try: 
-                AES.MODE_CCM
-            except:
-                LOG.critical("Your pycrypto doesn't support AES.MODE_CCM. 
Currently only pycrypto experimental supports this mode.\nDownload it from 
https://www.dlitz.net/software/pycrypto ")
-                raise 
-            cipher = AES.new(self._Session['DecryptionKey'], AES.MODE_CCM,  
transformHeader['Nonce'][:11])
-            cipher.update(str(transformHeader)[20:])
-            plainText = 
cipher.decrypt(data.get_trailer()[len(SMB2_TRANSFORM_HEADER()):])
-            #cipher.verify(transformHeader['Signature'])
-            packet = SMB2Packet(plainText)
-        else:
-            # In all SMB dialects for a response this field is interpreted as 
the Status field. 
-            # This field can be set to any value. For a list of valid status 
codes, 
-            # see [MS-ERREF] section 2.3.
-            packet = SMB2Packet(data.get_trailer())
-
-        # Loop while we receive pending requests
-        if packet['Status'] == STATUS_PENDING:
-            status = STATUS_PENDING
-            while status == STATUS_PENDING:
-                data = self._NetBIOSSession.recv_packet(self._timeout) 
-                if data.get_trailer().startswith('\xfeSMB'):
-                    packet = SMB2Packet(data.get_trailer())
-                else:
-                    # Packet is encrypted
-                    transformHeader = SMB2_TRANSFORM_HEADER(data.get_trailer())
-                    from Crypto.Cipher import AES
-                    try: 
-                        AES.MODE_CCM
-                    except:
-                        LOG.critical("Your pycrypto doesn't support 
AES.MODE_CCM. Currently only pycrypto experimental supports this 
mode.\nDownload it from https://www.dlitz.net/software/pycrypto ")
-                        raise 
-                    cipher = AES.new(self._Session['DecryptionKey'], 
AES.MODE_CCM,  transformHeader['Nonce'][:11])
-                    cipher.update(str(transformHeader)[20:])
-                    plainText = 
cipher.decrypt(data.get_trailer()[len(SMB2_TRANSFORM_HEADER()):])
-                    #cipher.verify(transformHeader['Signature'])
-                    packet = SMB2Packet(plainText)
-                status = packet['Status']
-
-        if packet['MessageID'] == packetID or packetID is None:
-        #    if self._Session['SigningRequired'] is True:
-        #        self.signSMB(packet)
-            # Let's update the sequenceWindow based on the CreditsCharged
-            self._Connection['SequenceWindow'] += (packet['CreditCharge'] - 1)
-            return packet
-        else:
-            self._Connection['OutstandingResponses'][packet['MessageID']] = 
packet
-            return self.recvSMB(packetID) 
-
-    def negotiateSession(self, preferredDialect = None):
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_NEGOTIATE
-        negSession = SMB2Negotiate()
-
-        negSession['SecurityMode'] = SMB2_NEGOTIATE_SIGNING_ENABLED 
-        if self.RequireMessageSigning is True:
-            negSession['SecurityMode'] |= SMB2_NEGOTIATE_SIGNING_REQUIRED
-        negSession['Capabilities'] = SMB2_GLOBAL_CAP_ENCRYPTION
-        negSession['ClientGuid'] = self.ClientGuid
-        if preferredDialect is not None:
-            negSession['Dialects'] = [preferredDialect]
-        else:
-            negSession['Dialects'] = [SMB2_DIALECT_002, SMB2_DIALECT_21, 
SMB2_DIALECT_30]
-        negSession['DialectCount'] = len(negSession['Dialects'])
-        packet['Data'] = negSession
-
-        # Storing this data for later use
-        self._Connection['ClientSecurityMode'] = negSession['SecurityMode']
-        self._Connection['Capabilities']       = negSession['Capabilities']
-
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-        if ans.isValidAnswer(STATUS_SUCCESS):
-             # ToDo this:
-             # If the DialectRevision in the SMB2 NEGOTIATE Response is 
0x02FF, the client MUST issue a new
-             # SMB2 NEGOTIATE request as described in section 3.2.4.2.2.2 with 
the only exception 
-             # that the client MUST allocate sequence number 1 from 
Connection.SequenceWindow, and MUST set
-             # MessageId field of the SMB2 header to 1. Otherwise, the client 
MUST proceed as follows.
-            negResp = SMB2Negotiate_Response(ans['Data'])
-            self._Connection['MaxTransactSize']   = 
min(0x100000,negResp['MaxTransactSize'])
-            self._Connection['MaxReadSize']       = 
min(0x100000,negResp['MaxReadSize'])
-            self._Connection['MaxWriteSize']      = 
min(0x100000,negResp['MaxWriteSize'])
-            self._Connection['ServerGuid']        = negResp['ServerGuid']
-            self._Connection['GSSNegotiateToken'] = negResp['Buffer']
-            self._Connection['Dialect']           = negResp['DialectRevision']
-            if (negResp['SecurityMode'] & SMB2_NEGOTIATE_SIGNING_REQUIRED) == 
SMB2_NEGOTIATE_SIGNING_REQUIRED:
-                self._Connection['RequireSigning'] = True
-            if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_LEASING) == 
SMB2_GLOBAL_CAP_LEASING: 
-                self._Connection['SupportsFileLeasing'] = True
-            if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_LARGE_MTU) == 
SMB2_GLOBAL_CAP_LARGE_MTU:
-                self._Connection['SupportsMultiCredit'] = True
-
-            if self._Connection['Dialect'] == SMB2_DIALECT_30:
-                # Switching to the right packet format
-                self.SMB_PACKET = SMB3Packet
-                if (negResp['Capabilities'] & 
SMB2_GLOBAL_CAP_DIRECTORY_LEASING) == SMB2_GLOBAL_CAP_DIRECTORY_LEASING:
-                    self._Connection['SupportsDirectoryLeasing'] = True
-                if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_MULTI_CHANNEL) 
== SMB2_GLOBAL_CAP_MULTI_CHANNEL:
-                    self._Connection['SupportsMultiChannel'] = True
-                if (negResp['Capabilities'] & 
SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) == SMB2_GLOBAL_CAP_PERSISTENT_HANDLES:
-                    self._Connection['SupportsPersistentHandles'] = True
-                if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_ENCRYPTION) == 
SMB2_GLOBAL_CAP_ENCRYPTION:
-                    self._Connection['SupportsEncryption'] = True
-
-                self._Connection['ServerCapabilities'] = 
negResp['Capabilities']
-                self._Connection['ServerSecurityMode'] = 
negResp['SecurityMode']
-
-    def getCredentials(self):
-        return (
-            self.__userName,
-            self.__password,
-            self.__domain,
-            self.__lmhash,
-            self.__nthash,
-            self.__aesKey, 
-            self.__TGT, 
-            self.__TGS)
-
-    def kerberosLogin(self, user, password, domain = '', lmhash = '', nthash = 
'', aesKey='', kdcHost = '', TGT=None, TGS=None):
-        # If TGT or TGS are specified, they are in the form of:
-        # TGS['KDC_REP'] = the response from the server
-        # TGS['cipher'] = the cipher used
-        # TGS['sessionKey'] = the sessionKey
-        # If we have hashes, normalize them
-        if lmhash != '' or nthash != '':
-            if len(lmhash) % 2:     lmhash = '0%s' % lmhash
-            if len(nthash) % 2:     nthash = '0%s' % nthash
-            try: # just in case they were converted already
-                lmhash = a2b_hex(lmhash)
-                nthash = a2b_hex(nthash)
-            except:
-                pass
-
-        self.__userName = user
-        self.__password = password
-        self.__domain   = domain
-        self.__lmhash   = lmhash
-        self.__nthash   = nthash
-        self.__kdc      = kdcHost
-        self.__aesKey   = aesKey
-        self.__TGT      = TGT
-        self.__TGS      = TGS
-       
-        sessionSetup = SMB2SessionSetup()
-        if self.RequireMessageSigning is True:
-           sessionSetup['SecurityMode'] = SMB2_NEGOTIATE_SIGNING_REQUIRED
-        else:
-           sessionSetup['SecurityMode'] = SMB2_NEGOTIATE_SIGNING_ENABLED
-
-        sessionSetup['Flags'] = 0
-        #sessionSetup['Capabilities'] = SMB2_GLOBAL_CAP_LARGE_MTU | 
SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_DFS
-
-        # Importing down here so pyasn1 is not required if kerberos is not 
used.
-        from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set
-        from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS
-        from impacket.krb5 import constants
-        from impacket.krb5.types import Principal, KerberosTime, Ticket
-        from pyasn1.codec.der import decoder, encoder
-        import datetime
-
-        # First of all, we need to get a TGT for the user
-        userName = Principal(user, 
type=constants.PrincipalNameType.NT_PRINCIPAL.value)
-        if TGT is None:
-            if TGS is None:
-                tgt, cipher, oldSessionKey, sessionKey = 
getKerberosTGT(userName, password, domain, lmhash, nthash, aesKey, kdcHost)
-        else:
-            tgt = TGT['KDC_REP']
-            cipher = TGT['cipher']
-            sessionKey = TGT['sessionKey'] 
-
-        # Save the ticket
-        # If you want, for debugging purposes
-#        from impacket.krb5.ccache import CCache
-#        ccache = CCache()
-#        try:
-#            if TGS is None:
-#                ccache.fromTGT(tgt, oldSessionKey, sessionKey)
-#            else:
-#                ccache.fromTGS(TGS['KDC_REP'], TGS['oldSessionKey'], 
TGS['sessionKey'] )
-#            ccache.saveFile('/tmp/ticket.bin')
-#        except Exception, e:
-#            print e
-#            pass
-
-        # Now that we have the TGT, we should ask for a TGS for cifs
-
-        if TGS is None:
-            serverName = Principal('cifs/%s' % 
(self._Connection['ServerName']), 
type=constants.PrincipalNameType.NT_SRV_INST.value)
-            tgs, cipher, oldSessionKey, sessionKey = 
getKerberosTGS(serverName, domain, kdcHost, tgt, cipher, sessionKey)
-        else:
-            tgs = TGS['KDC_REP']
-            cipher = TGS['cipher']
-            sessionKey = TGS['sessionKey'] 
-
-        # Let's build a NegTokenInit with a Kerberos REQ_AP
-
-        blob = SPNEGO_NegTokenInit() 
-
-        # Kerberos
-        blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]
-
-        # Let's extract the ticket from the TGS
-        tgs = decoder.decode(tgs, asn1Spec = TGS_REP())[0]
-        ticket = Ticket()
-        ticket.from_asn1(tgs['ticket'])
-        
-        # Now let's build the AP_REQ
-        apReq = AP_REQ()
-        apReq['pvno'] = 5
-        apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)
-
-        opts = list()
-        apReq['ap-options'] = constants.encodeFlags(opts)
-        seq_set(apReq,'ticket', ticket.to_asn1)
-
-        authenticator = Authenticator()
-        authenticator['authenticator-vno'] = 5
-        authenticator['crealm'] = domain
-        seq_set(authenticator, 'cname', userName.components_to_asn1)
-        now = datetime.datetime.utcnow()
-
-        authenticator['cusec'] = now.microsecond
-        authenticator['ctime'] = KerberosTime.to_asn1(now)
-
-        encodedAuthenticator = encoder.encode(authenticator)
-
-        # Key Usage 11
-        # AP-REQ Authenticator (includes application authenticator
-        # subkey), encrypted with the application session key
-        # (Section 5.5.1)
-        encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, 
encodedAuthenticator, None)
-
-        apReq['authenticator'] = None
-        apReq['authenticator']['etype'] = cipher.enctype
-        apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator
-
-        blob['MechToken'] = encoder.encode(apReq)
-
-        sessionSetup['SecurityBufferLength'] = len(blob)
-        sessionSetup['Buffer']               = blob.getData()
-
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_SESSION_SETUP
-        packet['Data']    = sessionSetup
-
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            self._Session['SessionID']       = ans['SessionID']
-            self._Session['SigningRequired'] = 
self._Connection['RequireSigning']
-            self._Session['UserCredentials'] = (user, password, domain, 
lmhash, nthash)
-            self._Session['Connection']      = 
self._NetBIOSSession.get_socket()
-
-            self._Session['SessionKey']  = sessionKey.contents[:16]
-            if self._Session['SigningRequired'] is True and 
self._Connection['Dialect'] == SMB2_DIALECT_30:
-                self._Session['SigningKey']  = 
crypto.KDF_CounterMode(self._Session['SessionKey'], "SMB2AESCMAC\x00", 
"SmbSign\x00", 128)
-
-            # Calculate the key derivations for dialect 3.0
-            if self._Session['SigningRequired'] is True:
-                self._Session['SigningActivated'] = True
-            if self._Connection['Dialect'] == SMB2_DIALECT_30:
-                self._Session['ApplicationKey']  = 
crypto.KDF_CounterMode(self._Session['SessionKey'], "SMB2APP\x00", 
"SmbRpc\x00", 128)
-                self._Session['EncryptionKey']   = 
crypto.KDF_CounterMode(self._Session['SessionKey'], "SMB2AESCCM\x00", "ServerIn 
\x00", 128)
-                self._Session['DecryptionKey']   = 
crypto.KDF_CounterMode(self._Session['SessionKey'], "SMB2AESCCM\x00", 
"ServerOut\x00", 128)
-       
-            return True
-        else:
-            # We clean the stuff we used in case we want to authenticate again
-            # within the same connection
-            self._Session['UserCredentials']   = ''
-            self._Session['Connection']        = 0
-            self._Session['SessionID']         = 0
-            self._Session['SigningRequired']   = False
-            self._Session['SigningKey']        = ''
-            self._Session['SessionKey']        = ''
-            self._Session['SigningActivated']  = False
-            raise
-
-
-    def login(self, user, password, domain = '', lmhash = '', nthash = ''):
-        # If we have hashes, normalize them
-        if lmhash != '' or nthash != '':
-            if len(lmhash) % 2:     lmhash = '0%s' % lmhash
-            if len(nthash) % 2:     nthash = '0%s' % nthash
-            try: # just in case they were converted already
-                lmhash = a2b_hex(lmhash)
-                nthash = a2b_hex(nthash)
-            except:
-                pass
-
-        self.__userName = user
-        self.__password = password
-        self.__domain   = domain
-        self.__lmhash   = lmhash
-        self.__nthash   = nthash
-        self.__aesKey   = ''
-        self.__TGT      = None
-        self.__TGS      = None
-       
-        sessionSetup = SMB2SessionSetup()
-        if self.RequireMessageSigning is True:
-           sessionSetup['SecurityMode'] = SMB2_NEGOTIATE_SIGNING_REQUIRED
-        else:
-           sessionSetup['SecurityMode'] = SMB2_NEGOTIATE_SIGNING_ENABLED
-
-        sessionSetup['Flags'] = 0
-        #sessionSetup['Capabilities'] = SMB2_GLOBAL_CAP_LARGE_MTU | 
SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_DFS
-
-        # Let's build a NegTokenInit with the NTLMSSP
-        # TODO: In the future we should be able to choose different providers
-
-        blob = SPNEGO_NegTokenInit() 
-
-        # NTLMSSP
-        blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security 
Support Provider']]
-        auth = ntlm.getNTLMSSPType1('','', self._Connection['RequireSigning'])
-        blob['MechToken'] = str(auth)
-
-        sessionSetup['SecurityBufferLength'] = len(blob)
-        sessionSetup['Buffer']               = blob.getData()
-
-        # ToDo:
-        # If this authentication is for establishing an alternative channel 
for an existing Session, as specified
-        # in section 3.2.4.1.7, the client MUST also set the following values:
-        # The SessionId field in the SMB2 header MUST be set to the 
Session.SessionId for the new
-        # channel being established.
-        # The SMB2_SESSION_FLAG_BINDING bit MUST be set in the Flags field.
-        # The PreviousSessionId field MUST be set to zero.
-
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_SESSION_SETUP
-        packet['Data']    = sessionSetup
-
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-        if ans.isValidAnswer(STATUS_MORE_PROCESSING_REQUIRED):
-            self._Session['SessionID']       = ans['SessionID']
-            self._Session['SigningRequired'] = 
self._Connection['RequireSigning']
-            self._Session['UserCredentials'] = (user, password, domain, 
lmhash, nthash)
-            self._Session['Connection']      = 
self._NetBIOSSession.get_socket()
-            sessionSetupResponse = SMB2SessionSetup_Response(ans['Data'])
-            respToken = SPNEGO_NegTokenResp(sessionSetupResponse['Buffer'])
-
-            # Let's parse some data and keep it to ourselves in case it is 
asked
-            ntlmChallenge = ntlm.NTLMAuthChallenge(respToken['ResponseToken'])
-            if ntlmChallenge['TargetInfoFields_len'] > 0:
-                av_pairs = 
ntlm.AV_PAIRS(ntlmChallenge['TargetInfoFields'][:ntlmChallenge['TargetInfoFields_len']])
-                if av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] is not None:
-                   try:
-                       self._Session['ServerName'] = 
av_pairs[ntlm.NTLMSSP_AV_HOSTNAME][1].decode('utf-16le')
-                   except:
-                       # For some reason, we couldn't decode Unicode here.. 
silently discard the operation
-                       pass 
-                if av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME] is not None:
-                   try:
-                       if self._Session['ServerName'] != 
av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le'): 
-                           self._Session['ServerDomain'] = 
av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le')
-                   except:
-                       # For some reason, we couldn't decode Unicode here.. 
silently discard the operation
-                       pass 
-                if av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME] is not None:
-                   try:
-                       self._Session['ServerDNSDomainName'] = 
av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME][1].decode('utf-16le')
-                   except:
-                       # For some reason, we couldn't decode Unicode here.. 
silently discard the operation
-                       pass 
-
-                # Parse Version to know the target Operating system name. Not 
provided elsewhere anymore
-                if 'Version' in ntlmChallenge.fields:
-                    version = ntlmChallenge['Version']
-
-                    if len(version) >= 4:
-                        self._Session['ServerOS'] = "Windows %d.%d Build %d" % 
(ord(version[0]), ord(version[1]), struct.unpack('<H',version[2:4])[0])
-                        self._Session["ServerOSMajor"] = ord(version[0])
-                        self._Session["ServerOSMinor"] = ord(version[1])
-                        self._Session["ServerOSBuild"] = 
struct.unpack('<H',version[2:4])[0]
-
-            type3, exportedSessionKey = ntlm.getNTLMSSPType3(auth, 
respToken['ResponseToken'], user, password, domain, lmhash, nthash)
-   
-            if exportedSessionKey is not None: 
-                self._Session['SessionKey']  = exportedSessionKey
-                if self._Session['SigningRequired'] is True and 
self._Connection['Dialect'] == SMB2_DIALECT_30:
-                    self._Session['SigningKey']  = 
crypto.KDF_CounterMode(exportedSessionKey, "SMB2AESCMAC\x00", "SmbSign\x00", 
128)
-
-            respToken2 = SPNEGO_NegTokenResp()
-            respToken2['ResponseToken'] = str(type3)
-
-            # Reusing the previous structure
-            sessionSetup['SecurityBufferLength'] = len(respToken2)
-            sessionSetup['Buffer']               = respToken2.getData()
-
-            packetID = self.sendSMB(packet)
-            packet = self.recvSMB(packetID)
-            try:
-                if packet.isValidAnswer(STATUS_SUCCESS):
-                    sessionSetupResponse = 
SMB2SessionSetup_Response(packet['Data'])
-                    self._Session['SessionFlags'] = 
sessionSetupResponse['SessionFlags']
-
-                    # Calculate the key derivations for dialect 3.0
-                    if self._Session['SigningRequired'] is True:
-                        self._Session['SigningActivated'] = True
-                    if self._Connection['Dialect'] == SMB2_DIALECT_30:
-                        self._Session['ApplicationKey']  = 
crypto.KDF_CounterMode(exportedSessionKey, "SMB2APP\x00", "SmbRpc\x00", 128)
-                        self._Session['EncryptionKey']   = 
crypto.KDF_CounterMode(exportedSessionKey, "SMB2AESCCM\x00", "ServerIn \x00", 
128)
-                        self._Session['DecryptionKey']   = 
crypto.KDF_CounterMode(exportedSessionKey, "SMB2AESCCM\x00", "ServerOut\x00", 
128)
- 
-                    return True
-            except:
-                # We clean the stuff we used in case we want to authenticate 
again
-                # within the same connection
-                self._Session['UserCredentials']   = ''
-                self._Session['Connection']        = 0
-                self._Session['SessionID']         = 0
-                self._Session['SigningRequired']   = False
-                self._Session['SigningKey']        = ''
-                self._Session['SessionKey']        = ''
-                self._Session['SigningActivated']  = False
-                raise
-
-    def connectTree(self, share):
-
-        # Just in case this came with the full path (maybe an SMB1 client), 
let's just leave 
-        # the sharename, we'll take care of the rest
-
-        #print self._Session['TreeConnectTable']
-        share = share.split('\\')[-1]
-        if share in self._Session['TreeConnectTable']:
-            # Already connected, no need to reconnect
-            treeEntry =  self._Session['TreeConnectTable'][share]
-            treeEntry['NumberOfUses'] += 1
-            
self._Session['TreeConnectTable'][treeEntry['TreeConnectId']]['NumberOfUses'] 
+= 1
-            return treeEntry['TreeConnectId']
-
-        #path = share
-        try:
-            _, _, _, _, sockaddr = 
socket.getaddrinfo(self._Connection['ServerIP'], 80, 0, 0, 
socket.IPPROTO_TCP)[0]
-            remoteHost = sockaddr[0]
-        except:
-            remoteHost = self._Connection['ServerIP']
-        path = '\\\\' + remoteHost + '\\' +share
-
-        treeConnect = SMB2TreeConnect()
-        treeConnect['Buffer']     = path.encode('utf-16le')
-        treeConnect['PathLength'] = len(path)*2
-         
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_TREE_CONNECT
-        packet['Data'] = treeConnect
-        packetID = self.sendSMB(packet)
-        packet = self.recvSMB(packetID)
-        if packet.isValidAnswer(STATUS_SUCCESS):
-           treeConnectResponse = SMB2TreeConnect_Response(packet['Data'])
-           treeEntry = copy.deepcopy(TREE_CONNECT)
-           treeEntry['ShareName']     = share
-           treeEntry['TreeConnectId'] = packet['TreeID']
-           treeEntry['Session']       = packet['SessionID']
-           treeEntry['NumberOfUses'] += 1
-           if (treeConnectResponse['Capabilities'] & SMB2_SHARE_CAP_DFS) == 
SMB2_SHARE_CAP_DFS:
-               treeEntry['IsDfsShare'] = True
-           if (treeConnectResponse['Capabilities'] & 
SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY) == 
SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY:
-               treeEntry['IsCAShare'] = True
-
-           if self._Connection['Dialect'] == SMB2_DIALECT_30:
-               if (self._Connection['SupportsEncryption'] is True) and 
((treeConnectResponse['ShareFlags'] & SMB2_SHAREFLAG_ENCRYPT_DATA) == 
SMB2_SHAREFLAG_ENCRYPT_DATA):
-                   treeEntry['EncryptData'] = True
-                   # ToDo: This and what follows
-                   # If Session.EncryptData is FALSE, the client MUST then 
generate an encryption key, a
-                   # decryption key as specified in section 3.1.4.2, by 
providing the following inputs and store
-                   # them in Session.EncryptionKey and Session.DecryptionKey:
-               if (treeConnectResponse['Capabilities'] & 
SMB2_SHARE_CAP_SCALEOUT) == SMB2_SHARE_CAP_SCALEOUT:
-                   treeEntry['IsScaleoutShare'] = True
-
-           self._Session['TreeConnectTable'][packet['TreeID']] = treeEntry
-           self._Session['TreeConnectTable'][share]            = treeEntry
-
-           return packet['TreeID'] 
-
-    def disconnectTree(self, treeId):
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-
-        if treeId in self._Session['TreeConnectTable']:
-            # More than 1 use? descrease it and return, if not, send the packet
-            if self._Session['TreeConnectTable'][treeId]['NumberOfUses'] > 1:
-                treeEntry =  self._Session['TreeConnectTable'][treeId]
-                treeEntry['NumberOfUses'] -= 1
-                
self._Session['TreeConnectTable'][treeEntry['ShareName']]['NumberOfUses'] -= 1
-                return True
-
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_TREE_DISCONNECT
-        packet['TreeID'] = treeId
-        treeDisconnect = SMB2TreeDisconnect()
-        packet['Data'] = treeDisconnect
-        packetID = self.sendSMB(packet)
-        packet = self.recvSMB(packetID)
-        if packet.isValidAnswer(STATUS_SUCCESS):
-            shareName = self._Session['TreeConnectTable'][treeId]['ShareName']
-            del(self._Session['TreeConnectTable'][shareName])
-            del(self._Session['TreeConnectTable'][treeId])
-            return True
-
-    def create(self, treeId, fileName, desiredAccess, shareMode, 
creationOptions, creationDisposition, fileAttributes, impersonationLevel = 
SMB2_IL_IMPERSONATION, securityFlags = 0, oplockLevel = SMB2_OPLOCK_LEVEL_NONE, 
createContexts = None):
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-
-        fileName = string.replace(fileName, '/', '\\')
-        if len(fileName) > 0:
-            fileName = ntpath.normpath(fileName)
-            if fileName[0] == '\\':
-                fileName = fileName[1:]
-
-        if self._Session['TreeConnectTable'][treeId]['IsDfsShare'] is True:
-            pathName = fileName
-        else:
-            pathName = '\\\\' + self._Connection['ServerName'] + '\\' + 
fileName
-
-        fileEntry = copy.deepcopy(FILE)
-        fileEntry['LeaseKey']   = uuid.generate()
-        fileEntry['LeaseState'] = SMB2_LEASE_NONE
-        self.GlobalFileTable[pathName] = fileEntry 
-
-        if self._Connection['Dialect'] == SMB2_DIALECT_30 and 
self._Connection['SupportsDirectoryLeasing'] is True:
-           # Is this file NOT on the root directory?
-           if len(fileName.split('\\')) > 2:
-               parentDir = ntpath.dirname(pathName)
-           if parentDir in self.GlobalFileTable:
-               LOG.critical("Don't know what to do now! :-o")
-               raise
-           else:
-               parentEntry = copy.deepcopy(FILE)
-               parentEntry['LeaseKey']   = uuid.generate()
-               parentEntry['LeaseState'] = SMB2_LEASE_NONE 
-               self.GlobalFileTable[parentDir] = parentEntry 
-               
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_CREATE
-        packet['TreeID']  = treeId
-        if self._Session['TreeConnectTable'][treeId]['IsDfsShare'] is True:
-            packet['Flags'] = SMB2_FLAGS_DFS_OPERATIONS
-
-        smb2Create = SMB2Create()
-        smb2Create['SecurityFlags']        = 0
-        smb2Create['RequestedOplockLevel'] = oplockLevel
-        smb2Create['ImpersonationLevel']   = impersonationLevel
-        smb2Create['DesiredAccess']        = desiredAccess
-        smb2Create['FileAttributes']       = fileAttributes
-        smb2Create['ShareAccess']          = shareMode
-        smb2Create['CreateDisposition']    = creationDisposition
-        smb2Create['CreateOptions']        = creationOptions
-       
-        smb2Create['NameLength']           = len(fileName)*2
-        if fileName != '':
-            smb2Create['Buffer']               = fileName.encode('utf-16le')
-        else:
-            smb2Create['Buffer']               = '\x00'
-
-        if createContexts is not None:
-            smb2Create['Buffer'] += createContexts
-            smb2Create['CreateContextsOffset'] = len(SMB2Packet()) + 
SMB2Create.SIZE + smb2Create['NameLength']
-            smb2Create['CreateContextsLength'] = len(createContexts)
-        else:
-            smb2Create['CreateContextsOffset'] = 0
-            smb2Create['CreateContextsLength'] = 0
-
-        packet['Data'] = smb2Create
-
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            createResponse = SMB2Create_Response(ans['Data'])
-
-            openFile = copy.deepcopy(OPEN)
-            openFile['FileID']      = createResponse['FileID']
-            openFile['TreeConnect'] = treeId
-            openFile['Oplocklevel'] = oplockLevel
-            openFile['Durable']     = False
-            openFile['ResilientHandle']    = False
-            openFile['LastDisconnectTime'] = 0
-            openFile['FileName'] = pathName
-
-            # ToDo: Complete the OperationBuckets
-            if self._Connection['Dialect'] == SMB2_DIALECT_30:
-                openFile['DesiredAccess']     = oplockLevel
-                openFile['ShareMode']         = oplockLevel
-                openFile['CreateOptions']     = oplockLevel
-                openFile['FileAttributes']    = oplockLevel
-                openFile['CreateDisposition'] = oplockLevel
-
-            # ToDo: Process the contexts            
-            self._Session['OpenTable'][str(createResponse['FileID'])] = 
openFile
-
-            # The client MUST generate a handle for the Open, and it MUST 
-            # return success and the generated handle to the calling 
application.
-            # In our case, str(FileID)
-            return str(createResponse['FileID'])
-
-    def close(self, treeId, fileId):
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-        if (fileId in self._Session['OpenTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_CLOSE
-        packet['TreeID']  = treeId
-
-        smbClose = SMB2Close()
-        smbClose['Flags']  = 0
-        smbClose['FileID'] = fileId
-        
-        packet['Data'] = smbClose
-
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            
del(self.GlobalFileTable[self._Session['OpenTable'][fileId]['FileName']])
-            del(self._Session['OpenTable'][fileId])
-             
-            # ToDo Remove stuff from GlobalFileTable
-            return True
-
-    def read(self, treeId, fileId, offset = 0, bytesToRead = 0, waitAnswer = 
True):
-        # IMPORTANT NOTE: As you can see, this was coded as a recursive 
function
-        # Hence, you can exhaust the memory pretty easy ( large bytesToRead )
-        # This function should NOT be used for reading files directly, but 
another higher
-        # level function should be used that will break the read into smaller 
pieces
-
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-        if (fileId in self._Session['OpenTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_READ
-        packet['TreeID']  = treeId
-
-        if self._Connection['MaxReadSize'] < bytesToRead:
-            maxBytesToRead = self._Connection['MaxReadSize']
-        else: 
-            maxBytesToRead = bytesToRead
-
-        if self._Connection['Dialect'] != SMB2_DIALECT_002 and 
self._Connection['SupportsMultiCredit'] is True:
-            packet['CreditCharge'] = ( 1 + (maxBytesToRead - 1) / 65536)
-        else: 
-            maxBytesToRead = min(65536,bytesToRead)
-
-        smbRead = SMB2Read()
-        smbRead['Padding']  = 0x50
-        smbRead['FileID']   = fileId
-        smbRead['Length']   = maxBytesToRead
-        smbRead['Offset']   = offset
-        packet['Data'] = smbRead
-
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            readResponse = SMB2Read_Response(ans['Data'])
-            retData = readResponse['Buffer']
-            if readResponse['DataRemaining'] > 0:
-                retData += self.read(treeId, fileId, offset+len(retData), 
readResponse['DataRemaining'], waitAnswer)
-            return retData
-       
-    def write(self, treeId, fileId, data, offset = 0, bytesToWrite = 0, 
waitAnswer = True):
-        # IMPORTANT NOTE: As you can see, this was coded as a recursive 
function
-        # Hence, you can exhaust the memory pretty easy ( large bytesToWrite )
-        # This function should NOT be used for writing directly to files, but 
another higher
-        # level function should be used that will break the writes into 
smaller pieces
-
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-        if (fileId in self._Session['OpenTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_WRITE
-        packet['TreeID']  = treeId
-
-        if self._Connection['MaxWriteSize'] < bytesToWrite:
-            maxBytesToWrite = self._Connection['MaxWriteSize']
-        else: 
-            maxBytesToWrite = bytesToWrite
-
-        if self._Connection['Dialect'] != SMB2_DIALECT_002 and 
self._Connection['SupportsMultiCredit'] is True:
-            packet['CreditCharge'] = ( 1 + (maxBytesToWrite - 1) / 65536)
-        else: 
-            maxBytesToWrite = min(65536,bytesToWrite)
-
-        smbWrite = SMB2Write()
-        smbWrite['FileID'] = fileId
-        smbWrite['Length'] = maxBytesToWrite
-        smbWrite['Offset'] = offset
-        smbWrite['WriteChannelInfoOffset'] = 0
-        smbWrite['Buffer'] = data[:maxBytesToWrite]
-        packet['Data'] = smbWrite
-
-        packetID = self.sendSMB(packet)
-        if waitAnswer is True:
-            ans = self.recvSMB(packetID)
-        else:
-            return maxBytesToWrite
-
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            writeResponse = SMB2Write_Response(ans['Data'])
-            bytesWritten = writeResponse['Count']
-            if bytesWritten < bytesToWrite:
-                bytesWritten += self.write(treeId, fileId, 
data[bytesWritten:], offset+bytesWritten, bytesToWrite-bytesWritten, waitAnswer)
-            return bytesWritten
-
-    def queryDirectory(self, treeId, fileId, searchString = '*', resumeIndex = 
0, informationClass = FILENAMES_INFORMATION, maxBufferSize = None, enumRestart 
= False, singleEntry = False):
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-        if (fileId in self._Session['OpenTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_QUERY_DIRECTORY
-        packet['TreeID']  = treeId
-
-        queryDirectory = SMB2QueryDirectory()
-        queryDirectory['FileInformationClass'] = informationClass
-        if resumeIndex != 0 :
-            queryDirectory['Flags'] = SMB2_INDEX_SPECIFIED
-        queryDirectory['FileIndex'] = resumeIndex
-        queryDirectory['FileID']    = fileId
-        if maxBufferSize is None:
-            maxBufferSize = self._Connection['MaxReadSize']
-        queryDirectory['OutputBufferLength'] = maxBufferSize
-        queryDirectory['FileNameLength']     = len(searchString)*2
-        queryDirectory['Buffer']             = searchString.encode('utf-16le')
-
-        packet['Data'] = queryDirectory
-
-        if self._Connection['Dialect'] != SMB2_DIALECT_002 and 
self._Connection['SupportsMultiCredit'] is True:
-            packet['CreditCharge'] = ( 1 + (maxBufferSize - 1) / 65536)
-
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            queryDirectoryResponse = SMB2QueryDirectory_Response(ans['Data'])
-            return queryDirectoryResponse['Buffer']
-
-    def echo(self):
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_ECHO
-        smbEcho = SMB2Echo()
-        packet['Data'] = smbEcho
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            return True
-
-    def cancel(self, packetID):
-        packet = self.SMB_PACKET()
-        packet['Command']   = SMB2_CANCEL
-        packet['MessageID'] = packetID
-
-        smbCancel = SMB2Cancel()
-
-        packet['Data']      = smbCancel
-        self.sendSMB(packet)
-
-    def ioctl(self, treeId, fileId = None, ctlCode = -1, flags = 0, inputBlob 
= '',  maxInputResponse = None, maxOutputResponse = None, waitAnswer = 1):
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-        if fileId is None:
-            fileId = '\xff'*16
-        else:
-            if (fileId in self._Session['OpenTable']) is False:
-                raise SessionError(STATUS_INVALID_PARAMETER)
-
-        packet = self.SMB_PACKET()
-        packet['Command']            = SMB2_IOCTL
-        packet['TreeID']             = treeId
-       
-        smbIoctl = SMB2Ioctl()
-        smbIoctl['FileID']             = fileId
-        smbIoctl['CtlCode']            = ctlCode
-        smbIoctl['MaxInputResponse']   = maxInputResponse
-        smbIoctl['MaxOutputResponse']  = maxOutputResponse
-        smbIoctl['InputCount']         = len(inputBlob)
-        if len(inputBlob) == 0:
-            smbIoctl['InputOffset'] = 0
-            smbIoctl['Buffer']      = '\x00'
-        else:
-            smbIoctl['Buffer']             = inputBlob
-        smbIoctl['OutputOffset']       = 0
-        smbIoctl['MaxOutputResponse']  = maxOutputResponse
-        smbIoctl['Flags']              = flags
-
-        packet['Data'] = smbIoctl
- 
-        packetID = self.sendSMB(packet)
-
-        if waitAnswer == 0:
-            return True
-
-        ans = self.recvSMB(packetID)
-
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            smbIoctlResponse = SMB2Ioctl_Response(ans['Data'])
-            return smbIoctlResponse['Buffer']
-
-    def flush(self,treeId, fileId):
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-        if (fileId in self._Session['OpenTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_FLUSH
-        packet['TreeID']  = treeId
-
-        smbFlush = SMB2Flush()
-        smbFlush['FileID'] = fileId
-
-        packet['Data'] = smbFlush
-
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            return True
-
-    def lock(self, treeId, fileId, locks, lockSequence = 0):
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-        if (fileId in self._Session['OpenTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_LOCK
-        packet['TreeID']  = treeId
-
-        smbLock = SMB2Lock()
-        smbLock['FileID']       = fileId
-        smbLock['LockCount']    = len(locks)
-        smbLock['LockSequence'] = lockSequence
-        smbLock['Locks']        = ''.join(str(x) for x in locks)
-
-        packet['Data'] = smbLock
-
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            smbFlushResponse = SMB2Lock_Response(ans['Data'])
-            return True
-
-        # ToDo:
-        # If Open.ResilientHandle is TRUE or Connection.SupportsMultiChannel 
is TRUE, the client MUST
-        # do the following:
-        # The client MUST scan through Open.OperationBuckets and find an 
element with its Free field
-        # set to TRUE. If no such element could be found, an 
implementation-specific error MUST be
-        # returned to the application.
-        # Let the zero-based array index of the element chosen above be 
referred to as BucketIndex, and
-        # let BucketNumber = BucketIndex +1.
-        # Set Open.OperationBuckets[BucketIndex].Free = FALSE
-        # Let the SequenceNumber of the element chosen above be referred to as 
BucketSequence.
-        # The LockSequence field of the SMB2 lock request MUST be set to 
(BucketNumber<< 4) +
-        # BucketSequence.
-        # Increment the SequenceNumber of the element chosen above using MOD 
16 arithmetic.
-
-    def logoff(self):
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_LOGOFF
-
-        smbLogoff = SMB2Logoff()
-
-        packet['Data'] = smbLogoff
-
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            # We clean the stuff we used in case we want to authenticate again
-            # within the same connection
-            self._Session['UserCredentials']   = ''
-            self._Session['Connection']        = 0
-            self._Session['SessionID']         = 0
-            self._Session['SigningRequired']   = False
-            self._Session['SigningKey']        = ''
-            self._Session['SessionKey']        = ''
-            self._Session['SigningActivated']  = False
-            return True
-
-    def queryInfo(self, treeId, fileId, inputBlob = '', infoType = 
SMB2_0_INFO_FILE, fileInfoClass = SMB2_FILE_STANDARD_INFO, 
additionalInformation = 0, flags = 0 ):
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-        if (fileId in self._Session['OpenTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_QUERY_INFO
-        packet['TreeID']  = treeId
-
-        queryInfo = SMB2QueryInfo()
-        queryInfo['FileID']                = fileId
-        queryInfo['InfoType']              = SMB2_0_INFO_FILE 
-        queryInfo['FileInfoClass']         = fileInfoClass 
-        queryInfo['OutputBufferLength']    = 65535
-        queryInfo['AdditionalInformation'] = additionalInformation
-        if len(inputBlob) == 0:
-            queryInfo['InputBufferOffset'] = 0
-            queryInfo['Buffer']            = '\x00'
-        else:
-            queryInfo['InputBufferLength'] = len(inputBlob)
-            queryInfo['Buffer']            = inputBlob
-        queryInfo['Flags']                 = flags
-
-        packet['Data'] = queryInfo
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            queryResponse = SMB2QueryInfo_Response(ans['Data'])
-            return queryResponse['Buffer']
-
-    def setInfo(self, treeId, fileId, inputBlob = '', infoType = 
SMB2_0_INFO_FILE, fileInfoClass = SMB2_FILE_STANDARD_INFO, 
additionalInformation = 0 ):
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-        if (fileId in self._Session['OpenTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-
-        packet = self.SMB_PACKET()
-        packet['Command'] = SMB2_SET_INFO
-        packet['TreeID']  = treeId
-
-        setInfo = SMB2SetInfo()
-        setInfo['InfoType']              = SMB2_0_INFO_FILE 
-        setInfo['FileInfoClass']         = fileInfoClass 
-        setInfo['BufferLength']          = len(inputBlob)
-        setInfo['AdditionalInformation'] = additionalInformation
-        setInfo['FileID']                = fileId
-        setInfo['Buffer']                = inputBlob
-
-        packet['Data'] = setInfo
-        packetID = self.sendSMB(packet)
-        ans = self.recvSMB(packetID)
-
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            return True
-
-    def getSessionKey(self):
-        if self.getDialect() == SMB2_DIALECT_30: 
-           return self._Session['ApplicationKey']
-        else:
-           return self._Session['SessionKey']
-
-    def setSessionKey(self, key):
-        if self.getDialect() == SMB2_DIALECT_30:
-           self._Session['ApplicationKey'] = key
-        else:
-           self._Session['SessionKey'] = key
-
-    ######################################################################
-    # Higher level functions
-
-    def rename(self, shareName, oldPath, newPath):
-        oldPath = string.replace(oldPath,'/', '\\')
-        oldPath = ntpath.normpath(oldPath)
-        if len(oldPath) > 0 and oldPath[0] == '\\':
-            oldPath = oldPath[1:]
-
-        newPath = string.replace(newPath,'/', '\\')
-        newPath = ntpath.normpath(newPath)
-        if len(newPath) > 0 and newPath[0] == '\\':
-            newPath = newPath[1:]
-
-        treeId = self.connectTree(shareName)
-        fileId = None
-        try:
-            fileId = self.create(treeId, oldPath, MAXIMUM_ALLOWED 
,FILE_SHARE_READ | FILE_SHARE_WRITE |FILE_SHARE_DELETE, 0x200020, FILE_OPEN, 0) 
-            renameReq = FILE_RENAME_INFORMATION_TYPE_2()
-            renameReq['ReplaceIfExists'] = 1
-            renameReq['RootDirectory']   = '\x00'*8
-            renameReq['FileNameLength']  = len(newPath)*2
-            renameReq['FileName']        = newPath.encode('utf-16le')
-            self.setInfo(treeId, fileId, renameReq, infoType = 
SMB2_0_INFO_FILE, fileInfoClass = SMB2_FILE_RENAME_INFO)
-        finally:
-            if fileId is not None:
-                self.close(treeId, fileId)
-            self.disconnectTree(treeId) 
-
-        return True
-
-    def writeFile(self, treeId, fileId, data, offset = 0):
-        finished = False
-        writeOffset = offset
-        while not finished:
-            if len(data) == 0:
-                break
-            writeData = data[:self._Connection['MaxWriteSize']]
-            data = data[self._Connection['MaxWriteSize']:]
-            written = self.write(treeId, fileId, writeData, writeOffset, 
len(writeData))
-            writeOffset += written
-        return writeOffset - offset
-
-    def listPath(self, shareName, path, password = None):
-        # ToDo: Handle situations where share is password protected
-        path = string.replace(path,'/', '\\')
-        path = ntpath.normpath(path)
-        if len(path) > 0 and path[0] == '\\':
-            path = path[1:]
-
-        treeId = self.connectTree(shareName)
-
-        fileId = None
-        try:
-            # ToDo, we're assuming it's a directory, we should check what the 
file type is
-            fileId = self.create(treeId, ntpath.dirname(path), 
FILE_READ_ATTRIBUTES | FILE_READ_DATA ,FILE_SHARE_READ | FILE_SHARE_WRITE 
|FILE_SHARE_DELETE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, 
FILE_OPEN, 0) 
-            res = ''
-            files = []
-            from impacket import smb
-            while True:
-                try:
-                    res = self.queryDirectory( treeId, fileId, 
ntpath.basename(path), maxBufferSize = 65535, informationClass = 
FILE_FULL_DIRECTORY_INFORMATION )
-                    nextOffset = 1
-                    while nextOffset != 0:
-                        fileInfo = 
smb.SMBFindFileFullDirectoryInfo(smb.SMB.FLAGS2_UNICODE)
-                        fileInfo.fromString(res)
-                        
files.append(smb.SharedFile(fileInfo['CreationTime'],fileInfo['LastAccessTime'],fileInfo['LastChangeTime'],fileInfo['EndOfFile'],fileInfo['AllocationSize'],fileInfo['ExtFileAttributes'],fileInfo['FileName'].decode('utf-16le'),
 fileInfo['FileName'].decode('utf-16le')))
-                        nextOffset = fileInfo['NextEntryOffset']
-                        res = res[nextOffset:]
-                except SessionError as e:
-                    if (e.get_error_code()) != STATUS_NO_MORE_FILES:
-                        raise
-                    break 
-        finally:
-            if fileId is not None:
-                self.close(treeId, fileId)
-            self.disconnectTree(treeId) 
-
-        return files
-
-    def mkdir(self, shareName, pathName, password = None):
-        # ToDo: Handle situations where share is password protected
-        pathName = string.replace(pathName,'/', '\\')
-        pathName = ntpath.normpath(pathName)
-        if len(pathName) > 0 and pathName[0] == '\\':
-            pathName = pathName[1:]
-
-        treeId = self.connectTree(shareName)
-
-        fileId = None
-        try:
-            fileId = self.create(treeId, pathName,GENERIC_ALL ,FILE_SHARE_READ 
| FILE_SHARE_WRITE |FILE_SHARE_DELETE, FILE_DIRECTORY_FILE | 
FILE_SYNCHRONOUS_IO_NONALERT, FILE_CREATE, 0)          
-        finally:
-            if fileId is not None:
-                self.close(treeId, fileId)            
-            self.disconnectTree(treeId) 
-
-        return True
-
-    def rmdir(self, shareName, pathName, password = None):
-        # ToDo: Handle situations where share is password protected
-        pathName = string.replace(pathName,'/', '\\')
-        pathName = ntpath.normpath(pathName)
-        if len(pathName) > 0 and pathName[0] == '\\':
-            pathName = pathName[1:]
-
-        treeId = self.connectTree(shareName)
-
-        fileId = None
-        try:
-            fileId = self.create(treeId, pathName, DELETE, FILE_SHARE_DELETE, 
FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, FILE_OPEN, 0)
-        finally:
-            if fileId is not None:
-                self.close(treeId, fileId)
-            self.disconnectTree(treeId) 
-
-        return True
-
-    def remove(self, shareName, pathName, password = None):
-        # ToDo: Handle situations where share is password protected
-        pathName = string.replace(pathName,'/', '\\')
-        pathName = ntpath.normpath(pathName)
-        if len(pathName) > 0 and pathName[0] == '\\':
-            pathName = pathName[1:]
-
-        treeId = self.connectTree(shareName)
-
-        fileId = None
-        try:
-            fileId = self.create(treeId, pathName,DELETE | 
FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE | 
FILE_DELETE_ON_CLOSE, FILE_OPEN, 0)
-        finally:
-            if fileId is not None:
-                self.close(treeId, fileId)
-            self.disconnectTree(treeId) 
-
-        return True
-
-    def retrieveFile(self, shareName, path, callback, mode = FILE_OPEN, offset 
= 0, password = None, shareAccessMode = FILE_SHARE_READ):
-        # ToDo: Handle situations where share is password protected
-        path = string.replace(path,'/', '\\')
-        path = ntpath.normpath(path)
-        if len(path) > 0 and path[0] == '\\':
-            path = path[1:]
-
-        treeId = self.connectTree(shareName)
-        fileId = None
-        from impacket import smb
-        try:
-            fileId = self.create(treeId, path, FILE_READ_DATA, 
shareAccessMode, FILE_NON_DIRECTORY_FILE, mode, 0)
-            res = self.queryInfo(treeId, fileId)
-            fileInfo = smb.SMBQueryFileStandardInfo(res)
-            fileSize = fileInfo['EndOfFile']
-            if (fileSize-offset) < self._Connection['MaxReadSize']:
-                # Skip reading 0 bytes files. 
-                if (fileSize-offset) > 0:
-                    data = self.read(treeId, fileId, offset, fileSize-offset)
-                    callback(data)
-            else:
-                written = 0
-                toBeRead = fileSize-offset
-                while written < toBeRead:
-                    data = self.read(treeId, fileId, offset, 
self._Connection['MaxReadSize'])
-                    written += len(data)
-                    offset  += len(data)
-                    callback(data)
-        finally:
-            if fileId is not None:
-                self.close(treeId, fileId)
-            self.disconnectTree(treeId) 
-
-    def storeFile(self, shareName, path, callback, mode = FILE_OVERWRITE_IF, 
offset = 0, password = None, shareAccessMode = FILE_SHARE_WRITE):
-        # ToDo: Handle situations where share is password protected
-        path = string.replace(path,'/', '\\')
-        path = ntpath.normpath(path)
-        if len(path) > 0 and path[0] == '\\':
-            path = path[1:]
-
-        treeId = self.connectTree(shareName)
-        fileId = None
-        try:
-            fileId = self.create(treeId, path, FILE_WRITE_DATA, 
shareAccessMode, FILE_NON_DIRECTORY_FILE, mode, 0)
-            finished = False
-            writeOffset = offset
-            while not finished:
-                data = callback(self._Connection['MaxWriteSize'])
-                if len(data) == 0:
-                    break
-                written = self.write(treeId, fileId, data, writeOffset, 
len(data))
-                writeOffset += written
-        finally:
-            if fileId is not None:
-                self.close(treeId, fileId)
-            self.disconnectTree(treeId)
-
-    def waitNamedPipe(self, treeId, pipename, timeout = 5):
-        pipename = ntpath.basename(pipename)
-        if (treeId in self._Session['TreeConnectTable']) is False:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-        if len(pipename) > 0xffff:
-            raise SessionError(STATUS_INVALID_PARAMETER)
-
-        pipeWait = FSCTL_PIPE_WAIT_STRUCTURE()
-        pipeWait['Timeout']          = timeout*100000
-        pipeWait['NameLength']       = len(pipename)*2
-        pipeWait['TimeoutSpecified'] = 1
-        pipeWait['Name']             = pipename.encode('utf-16le')
-
-        return self.ioctl(treeId, None, 
FSCTL_PIPE_WAIT,flags=SMB2_0_IOCTL_IS_FSCTL, inputBlob=pipeWait, 
maxInputResponse = 0, maxOutputResponse=0)
-        
-    def getIOCapabilities(self):
-        res = dict()
-
-        res['MaxReadSize'] = self._Connection['MaxReadSize']
-        res['MaxWriteSize'] = self._Connection['MaxWriteSize']
-        return res
-        
-
-    ######################################################################
-    # Backward compatibility functions and alias for SMB1 and DCE Transports
-    # NOTE: It is strongly recommended not to use these commands
-    # when implementing new client calls.
-    get_server_name            = getServerName
-    get_server_domain          = getServerDomain
-    get_server_dns_domain_name = getServerDNSDomainName
-    get_remote_name            = getServerName
-    get_remote_host            = getServerIP
-    get_server_os              = getServerOS
-    get_server_os_major        = getServerOSMajor
-    get_server_os_minor        = getServerOSMinor
-    get_server_os_build        = getServerOSBuild
-    tree_connect_andx          = connectTree
-    tree_connect               = connectTree
-    connect_tree               = connectTree
-    disconnect_tree            = disconnectTree 
-    set_timeout                = setTimeout
-    use_timeout                = useTimeout
-    stor_file                  = storeFile
-    retr_file                  = retrieveFile
-    list_path                  = listPath
-
-    def __del__(self):
-        if self._NetBIOSSession:
-            self._NetBIOSSession.close()
-
-
-    def doesSupportNTLMv2(self):
-        # Always true :P 
-        return True
-    
-    def is_login_required(self):
-        # Always true :P 
-        return True
-
-    def is_signing_required(self):
-        return self._Session["SigningRequired"] 
-
-    def nt_create_andx(self, treeId, fileName, smb_packet=None, cmd = None):
-        if len(fileName) > 0 and fileName[0] == '\\':
-            fileName = fileName[1:]
- 
-        if cmd is not None:
-            from impacket import smb
-            ntCreate = smb.SMBCommand(data = str(cmd))
-            params = smb.SMBNtCreateAndX_Parameters(ntCreate['Parameters'])
-            return self.create(treeId, fileName, params['AccessMask'], 
params['ShareAccess'],
-                               params['CreateOptions'], params['Disposition'], 
params['FileAttributes'],
-                               params['Impersonation'], 
params['SecurityFlags'])
-                               
-        else:
-            return self.create(treeId, fileName, 
-                    FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | 
FILE_READ_EA |
-                    FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES | 
FILE_READ_ATTRIBUTES | READ_CONTROL,
-                    FILE_SHARE_READ | FILE_SHARE_WRITE, 
FILE_NON_DIRECTORY_FILE, FILE_OPEN, 0 )
-                    
-    def get_socket(self):
-        return self._NetBIOSSession.get_socket()
-
-
-    def write_andx(self,tid,fid,data, offset = 0, wait_answer=1, 
write_pipe_mode = False, smb_packet=None):
-        # ToDo: Handle the custom smb_packet situation
-        return self.write(tid, fid, data, offset, len(data))
-
-    def TransactNamedPipe(self, tid, fid, data, noAnswer = 0, waitAnswer = 1, 
offset = 0):
-        return self.ioctl(tid, fid, FSCTL_PIPE_TRANSCEIVE, 
SMB2_0_IOCTL_IS_FSCTL, data, maxOutputResponse = 65535, waitAnswer = noAnswer | 
waitAnswer)
-
-    def TransactNamedPipeRecv(self):
-        ans = self.recvSMB()
-
-        if ans.isValidAnswer(STATUS_SUCCESS):
-            smbIoctlResponse = SMB2Ioctl_Response(ans['Data'])
-            return smbIoctlResponse['Buffer']
-
-
-    def read_andx(self, tid, fid, offset=0, max_size = None, wait_answer=1, 
smb_packet=None):
-        # ToDo: Handle the custom smb_packet situation
-        if max_size is None:
-            max_size = self._Connection['MaxReadSize']
-        return self.read(tid, fid, offset, max_size, wait_answer)
-
-    def list_shared(self):
-        # In the context of SMB2/3, forget about the old LANMAN, throw NOT 
IMPLEMENTED
-        raise SessionError(STATUS_NOT_IMPLEMENTED)
-
-    def open_andx(self, tid, fileName, open_mode, desired_access):
-        # ToDo Return all the attributes of the file
-        if len(fileName) > 0 and fileName[0] == '\\':
-            fileName = fileName[1:]
-
-        fileId = self.create(tid,fileName,desired_access, open_mode, 
FILE_NON_DIRECTORY_FILE, open_mode, 0)
-        return fileId, 0, 0, 0, 0, 0, 0, 0, 0
-
diff --git a/tests/python_dependencies/impacket/smb3structs.py 
b/tests/python_dependencies/impacket/smb3structs.py
deleted file mode 100644
index ddc8a9084..000000000
--- a/tests/python_dependencies/impacket/smb3structs.py
+++ /dev/null
@@ -1,1363 +0,0 @@
-# Copyright (c) 2003-2016 CORE Security Technologies
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-# Author: Alberto Solino (@agsolino)
-#
-# Description:
-#   SMB 2 and 3 Protocol Structures and constants [MS-SMB2]
-#
-
-from impacket.structure import Structure
-
-# Constants
-
-# SMB Packet
-SMB2_PACKET_SIZE     = 64
-
-# SMB Commands
-SMB2_NEGOTIATE       = 0x0000 #
-SMB2_SESSION_SETUP   = 0x0001 #
-SMB2_LOGOFF          = 0x0002 #
-SMB2_TREE_CONNECT    = 0x0003 #
-SMB2_TREE_DISCONNECT = 0x0004 #
-SMB2_CREATE          = 0x0005 #
-SMB2_CLOSE           = 0x0006 #
-SMB2_FLUSH           = 0x0007 #
-SMB2_READ            = 0x0008 #
-SMB2_WRITE           = 0x0009 #
-SMB2_LOCK            = 0x000A #
-SMB2_IOCTL           = 0x000B #
-SMB2_CANCEL          = 0x000C #
-SMB2_ECHO            = 0x000D #
-SMB2_QUERY_DIRECTORY = 0x000E #
-SMB2_CHANGE_NOTIFY   = 0x000F
-SMB2_QUERY_INFO      = 0x0010 #
-SMB2_SET_INFO        = 0x0011
-SMB2_OPLOCK_BREAK    = 0x0012
-
-# SMB Flags
-SMB2_FLAGS_SERVER_TO_REDIR    = 0x00000001
-SMB2_FLAGS_ASYNC_COMMAND      = 0x00000002
-SMB2_FLAGS_RELATED_OPERATIONS = 0x00000004
-SMB2_FLAGS_SIGNED             = 0x00000008
-SMB2_FLAGS_DFS_OPERATIONS     = 0x10000000
-SMB2_FLAGS_REPLAY_OPERATION   = 0x80000000
-
-# SMB Error SymLink Flags
-SYMLINK_FLAG_ABSOLUTE         = 0x0
-SYMLINK_FLAG_RELATIVE         = 0x1
-
-# SMB2_NEGOTIATE
-# Security Modes
-SMB2_NEGOTIATE_SIGNING_ENABLED  = 0x1
-SMB2_NEGOTIATE_SIGNING_REQUIRED = 0x2
-
-# Capabilities
-SMB2_GLOBAL_CAP_DFS                = 0x01
-SMB2_GLOBAL_CAP_LEASING            = 0x02
-SMB2_GLOBAL_CAP_LARGE_MTU          = 0x04
-SMB2_GLOBAL_CAP_MULTI_CHANNEL      = 0x08
-SMB2_GLOBAL_CAP_PERSISTENT_HANDLES = 0x10
-SMB2_GLOBAL_CAP_DIRECTORY_LEASING  = 0x20
-SMB2_GLOBAL_CAP_ENCRYPTION         = 0x40
-
-# Dialects
-SMB2_DIALECT_002      = 0x0202 
-SMB2_DIALECT_21       = 0x0210 
-SMB2_DIALECT_30       = 0x0300 
-SMB2_DIALECT_WILDCARD = 0x02FF 
-
-# SMB2_SESSION_SETUP
-# Flags
-SMB2_SESSION_FLAG_BINDING        = 0x01
-SMB2_SESSION_FLAG_IS_GUEST       = 0x01
-SMB2_SESSION_FLAG_IS_NULL        = 0x02
-SMB2_SESSION_FLAG_ENCRYPT_DATA   = 0x04
-
-# SMB2_TREE_CONNECT 
-# Types
-SMB2_SHARE_TYPE_DISK   = 0x1
-SMB2_SHARE_TYPE_PIPE   = 0x2
-SMB2_SHARE_TYPE_PRINT  = 0x3
-
-# Share Flags
-SMB2_SHAREFLAG_MANUAL_CACHING              = 0x00000000
-SMB2_SHAREFLAG_AUTO_CACHING                = 0x00000010
-SMB2_SHAREFLAG_VDO_CACHING                 = 0x00000020
-SMB2_SHAREFLAG_NO_CACHING                  = 0x00000030
-SMB2_SHAREFLAG_DFS                         = 0x00000001
-SMB2_SHAREFLAG_DFS_ROOT                    = 0x00000002
-SMB2_SHAREFLAG_RESTRICT_EXCLUSIVE_OPENS    = 0x00000100
-SMB2_SHAREFLAG_FORCE_SHARED_DELETE         = 0x00000200
-SMB2_SHAREFLAG_ALLOW_NAMESPACE_CACHING     = 0x00000400
-SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM = 0x00000800
-SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK        = 0x00001000
-SMB2_SHAREFLAG_ENABLE_HASH_V1              = 0x00002000
-SMB2_SHAREFLAG_ENABLE_HASH_V2              = 0x00004000
-SMB2_SHAREFLAG_ENCRYPT_DATA                = 0x00008000
-
-# Capabilities
-SMB2_SHARE_CAP_DFS                         = 0x00000008
-SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY     = 0x00000010
-SMB2_SHARE_CAP_SCALEOUT                    = 0x00000020
-SMB2_SHARE_CAP_CLUSTER                     = 0x00000040
-
-# SMB_CREATE 
-# Oplocks
-SMB2_OPLOCK_LEVEL_NONE       = 0x00
-SMB2_OPLOCK_LEVEL_II         = 0x01
-SMB2_OPLOCK_LEVEL_EXCLUSIVE  = 0x08
-SMB2_OPLOCK_LEVEL_BATCH      = 0x09
-SMB2_OPLOCK_LEVEL_LEASE      = 0xFF
-
-# Impersonation Level
-SMB2_IL_ANONYMOUS       = 0x00000000
-SMB2_IL_IDENTIFICATION  = 0x00000001
-SMB2_IL_IMPERSONATION   = 0x00000002
-SMB2_IL_DELEGATE        = 0x00000003
-
-# File Attributes
-FILE_ATTRIBUTE_ARCHIVE             = 0x00000020
-FILE_ATTRIBUTE_COMPRESSED          = 0x00000800
-FILE_ATTRIBUTE_DIRECTORY           = 0x00000010
-FILE_ATTRIBUTE_ENCRYPTED           = 0x00004000
-FILE_ATTRIBUTE_HIDDEN              = 0x00000002
-FILE_ATTRIBUTE_NORMAL              = 0x00000080
-FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000
-FILE_ATTRIBUTE_OFFLINE             = 0x00001000
-FILE_ATTRIBUTE_READONLY            = 0x00000001
-FILE_ATTRIBUTE_REPARSE_POINT       = 0x00000400
-FILE_ATTRIBUTE_SPARSE_FILE         = 0x00000200
-FILE_ATTRIBUTE_SYSTEM              = 0x00000004
-FILE_ATTRIBUTE_TEMPORARY           = 0x00000100
-FILE_ATTRIBUTE_INTEGRITY_STREAM    = 0x00000800
-FILE_ATTRIBUTE_NO_SCRUB_DATA       = 0x00020000
-
-# Share Access
-FILE_SHARE_READ         = 0x00000001
-FILE_SHARE_WRITE        = 0x00000002
-FILE_SHARE_DELETE       = 0x00000004
-
-# Create Disposition
-FILE_SUPERSEDE          = 0x00000000 
-FILE_OPEN               = 0x00000001
-FILE_CREATE             = 0x00000002
-FILE_OPEN_IF            = 0x00000003
-FILE_OVERWRITE          = 0x00000004
-FILE_OVERWRITE_IF       = 0x00000005
-
-# Create Options
-FILE_DIRECTORY_FILE            = 0x00000001
-FILE_WRITE_THROUGH             = 0x00000002
-FILE_SEQUENTIAL_ONLY           = 0x00000004
-FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008
-FILE_SYNCHRONOUS_IO_ALERT      = 0x00000010
-FILE_SYNCHRONOUS_IO_NONALERT   = 0x00000020
-FILE_NON_DIRECTORY_FILE        = 0x00000040
-FILE_COMPLETE_IF_OPLOCKED      = 0x00000100
-FILE_NO_EA_KNOWLEDGE           = 0x00000200
-FILE_RANDOM_ACCESS             = 0x00000800
-FILE_DELETE_ON_CLOSE           = 0x00001000
-FILE_OPEN_BY_FILE_ID           = 0x00002000
-FILE_OPEN_FOR_BACKUP_INTENT    = 0x00004000
-FILE_NO_COMPRESSION            = 0x00008000
-FILE_RESERVE_OPFILTER          = 0x00100000
-FILE_OPEN_REPARSE_POINT        = 0x00200000 
-FILE_OPEN_NO_RECALL            = 0x00400000
-FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000
-
-# File Access Mask / Desired Access
-FILE_READ_DATA         = 0x00000001
-FILE_WRITE_DATA        = 0x00000002
-FILE_APPEND_DATA       = 0x00000004
-FILE_READ_EA           = 0x00000008
-FILE_WRITE_EA          = 0x00000010
-FILE_EXECUTE           = 0x00000020
-FILE_READ_ATTRIBUTES   = 0x00000080
-FILE_WRITE_ATTRIBUTES  = 0x00000100
-DELETE                 = 0x00010000
-READ_CONTROL           = 0x00020000
-WRITE_DAC              = 0x00040000
-WRITE_OWNER            = 0x00080000
-SYNCHRONIZE            = 0x00100000
-ACCESS_SYSTEM_SECURITY = 0x01000000
-MAXIMUM_ALLOWED        = 0x02000000
-GENERIC_ALL            = 0x10000000
-GENERIC_EXECUTE        = 0x20000000
-GENERIC_WRITE          = 0x40000000
-GENERIC_READ           = 0x80000000
-
-# Directory Access Mask 
-FILE_LIST_DIRECTORY    = 0x00000001
-FILE_ADD_FILE          = 0x00000002
-FILE_ADD_SUBDIRECTORY  = 0x00000004
-FILE_TRAVERSE          = 0x00000020
-FILE_DELETE_CHILD      = 0x00000040
-
-# Create Contexts
-SMB2_CREATE_EA_BUFFER                     = 0x45787441 
-SMB2_CREATE_SD_BUFFER                     = 0x53656344
-SMB2_CREATE_DURABLE_HANDLE_REQUEST        = 0x44486e51 
-SMB2_CREATE_DURABLE_HANDLE_RECONNECT      = 0x44486e43 
-SMB2_CREATE_ALLOCATION_SIZE               = 0x416c5369 
-SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST  = 0x4d784163 
-SMB2_CREATE_TIMEWARP_TOKEN                = 0x54577270 
-SMB2_CREATE_QUERY_ON_DISK_ID              = 0x51466964 
-SMB2_CREATE_REQUEST                       = 0x52714c73 
-SMB2_CREATE_REQUEST_LEASE_V2              = 0x52714c73 
-SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2     = 0x44483251 
-SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2   = 0x44483243 
-SMB2_CREATE_APP_INSTANCE_ID               = 0x45BCA66AEFA7F74A9008FA462E144D74 
-
-# Flags
-SMB2_CREATE_FLAG_REPARSEPOINT  = 0x1
-FILE_NEED_EA                   = 0x80
-
-# CreateAction
-FILE_SUPERSEDED    = 0x00000000
-FILE_OPENED        = 0x00000001
-FILE_CREATED       = 0x00000002
-FILE_OVERWRITTEN   = 0x00000003
-
-# SMB2_CREATE_REQUEST_LEASE states
-SMB2_LEASE_NONE            = 0x00
-SMB2_LEASE_READ_CACHING    = 0x01
-SMB2_LEASE_HANDLE_CACHING  = 0x02
-SMB2_LEASE_WRITE_CACHING   = 0x04
-
-# SMB2_CREATE_REQUEST_LEASE_V2 Flags
-SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET = 0x4
-
-# SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 Flags
-SMB2_DHANDLE_FLAG_PERSISTENT = 0x02
- 
-# SMB2_CLOSE
-# Flags
-SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB  = 0x0001
-
-# SMB2_READ
-# Channel
-SMB2_CHANNEL_NONE     = 0x00
-SMB2_CHANNEL_RDMA_V1  = 0x01
-
-# SMB2_WRITE
-# Flags
-SMB2_WRITEFLAG_WRITE_THROUGH = 0x01
-
-# Lease Break Notification
-SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED  = 0x01
-
-# SMB_LOCK
-# Flags
-SMB2_LOCKFLAG_SHARED_LOCK       = 0x01
-SMB2_LOCKFLAG_EXCLUSIVE_LOCK    = 0x02
-SMB2_LOCKFLAG_UNLOCK            = 0x04
-SMB2_LOCKFLAG_FAIL_IMMEDIATELY  = 0x10
-
-# SMB IOCTL
-# Control Codes
-FSCTL_DFS_GET_REFERRALS              = 0x00060194
-FSCTL_PIPE_PEEK                      = 0x0011400C
-FSCTL_PIPE_WAIT                      = 0x00110018
-FSCTL_PIPE_TRANSCEIVE                = 0x0011C017
-FSCTL_SRV_COPYCHUNK                  = 0x001440F2
-FSCTL_SRV_ENUMERATE_SNAPSHOTS        = 0x00144064
-FSCTL_SRV_REQUEST_RESUME_KEY         = 0x00140078
-FSCTL_SRV_READ_HASH                  = 0x001441bb
-FSCTL_SRV_COPYCHUNK_WRITE            = 0x001480F2
-FSCTL_LMR_REQUEST_RESILIENCY         = 0x001401D4
-FSCTL_QUERY_NETWORK_INTERFACE_INFO   = 0x001401FC
-FSCTL_SET_REPARSE_POINT              = 0x000900A4
-FSCTL_DFS_GET_REFERRALS_EX           = 0x000601B0
-FSCTL_FILE_LEVEL_TRIM                = 0x00098208
-FSCTL_VALIDATE_NEGOTIATE_INFO        = 0x00140204
-
-# Flags
-SMB2_0_IOCTL_IS_FSCTL  = 0x1
-
-# SRV_READ_HASH
-# Type
-SRV_HASH_TYPE_PEER_DIST  = 0x01
-
-# Version
-SRV_HASH_VER_1  = 0x1
-SRV_HASH_VER_2  = 0x2
-
-# Retrieval Type
-SRV_HASH_RETRIEVE_HASH_BASED  = 0x01
-SRV_HASH_RETRIEVE_FILE_BASED  = 0x02
-
-# NETWORK_INTERFACE_INFO
-# Capabilities
-RSS_CAPABLE  = 0x01
-RDMA_CAPABLE = 0x02
-
-# SMB2_QUERY_DIRECTORIES
-# Information Class 
-FILE_DIRECTORY_INFORMATION         = 0x01
-FILE_FULL_DIRECTORY_INFORMATION    = 0x02
-FILEID_FULL_DIRECTORY_INFORMATION  = 0x26
-FILE_BOTH_DIRECTORY_INFORMATION    = 0x03
-FILEID_BOTH_DIRECTORY_INFORMATION  = 0x25
-FILENAMES_INFORMATION              = 0x0C
-
-# Flags
-SMB2_RESTART_SCANS        = 0x01
-SMB2_RETURN_SINGLE_ENTRY  = 0x02
-SMB2_INDEX_SPECIFIED      = 0x04
-SMB2_REOPEN               = 0x10
-
-# SMB2_CHANGE_NOTIFY
-# Flags
-SMB2_WATCH_TREE  = 0x01
-
-# Filters
-FILE_NOTIFY_CHANGE_FILE_NAME     = 0x00000001
-FILE_NOTIFY_CHANGE_DIR_NAME      = 0x00000002
-FILE_NOTIFY_CHANGE_ATTRIBUTES    = 0x00000004
-FILE_NOTIFY_CHANGE_SIZE          = 0x00000008
-FILE_NOTIFY_CHANGE_LAST_WRITE    = 0x00000010
-FILE_NOTIFY_CHANGE_LAST_ACCESS   = 0x00000020
-FILE_NOTIFY_CHANGE_CREATION      = 0x00000040
-FILE_NOTIFY_CHANGE_EA            = 0x00000080
-FILE_NOTIFY_CHANGE_SECURITY      = 0x00000100
-FILE_NOTIFY_CHANGE_STREAM_NAME   = 0x00000200
-FILE_NOTIFY_CHANGE_STREAM_SIZE   = 0x00000400
-FILE_NOTIFY_CHANGE_STREAM_WRITE  = 0x00000800
-
-# FILE_NOTIFY_INFORMATION
-# Actions
-FILE_ACTION_ADDED            = 0x00000001
-FILE_ACTION_REMOVED          = 0x00000002
-FILE_ACTION_MODIFIED         = 0x00000003
-FILE_ACTION_RENAMED_OLD_NAME = 0x00000004 
-FILE_ACTION_RENAMED_NEW_NAME = 0x00000005
-
-# SMB2_QUERY_INFO
-# InfoTypes
-SMB2_0_INFO_FILE        = 0x01
-SMB2_0_INFO_FILESYSTEM  = 0x02
-SMB2_0_INFO_SECURITY    = 0x03
-SMB2_0_INFO_QUOTA       = 0x04
-
-# File Information Classes
-SMB2_FILE_ACCESS_INFO                 = 8
-SMB2_FILE_ALIGNMENT_INFO              = 17
-SMB2_FILE_ALL_INFO                    = 18
-SMB2_FILE_ALLOCATION_INFO             = 19
-SMB2_FILE_ALTERNATE_NAME_INFO         = 21
-SMB2_ATTRIBUTE_TAG_INFO               = 35
-SMB2_FILE_BASIC_INFO                  = 4
-SMB2_FILE_BOTH_DIRECTORY_INFO         = 3
-SMB2_FILE_COMPRESSION_INFO            = 28
-SMB2_FILE_DIRECTORY_INFO              = 1
-SMB2_FILE_DISPOSITION_INFO            = 13
-SMB2_FILE_EA_INFO                     = 7
-SMB2_FILE_END_OF_FILE_INFO            = 20
-SMB2_FULL_DIRECTORY_INFO              = 2
-SMB2_FULL_EA_INFO                     = 15
-SMB2_FILE_HARDLINK_INFO               = 46
-SMB2_FILE_ID_BOTH_DIRECTORY_INFO      = 37
-SMB2_FILE_ID_FULL_DIRECTORY_INFO      = 38
-SMB2_FILE_ID_GLOBAL_TX_DIRECTORY_INFO = 50
-SMB2_FILE_INTERNAL_INFO               = 6
-SMB2_FILE_LINK_INFO                   = 11
-SMB2_FILE_MAILSLOT_QUERY_INFO         = 26
-SMB2_FILE_MAILSLOT_SET_INFO           = 27
-SMB2_FILE_MODE_INFO                   = 16
-SMB2_FILE_MOVE_CLUSTER_INFO           = 31
-SMB2_FILE_NAME_INFO                   = 9
-SMB2_FILE_NAMES_INFO                  = 12
-SMB2_FILE_NETWORK_OPEN_INFO           = 34
-SMB2_FILE_NORMALIZED_NAME_INFO        = 48
-SMB2_FILE_OBJECT_ID_INFO              = 29
-SMB2_FILE_PIPE_INFO                   = 23
-SMB2_FILE_PIPE_LOCAL_INFO             = 24
-SMB2_FILE_PIPE_REMOTE_INFO            = 25
-SMB2_FILE_POSITION_INFO               = 14
-SMB2_FILE_QUOTA_INFO                  = 32
-SMB2_FILE_RENAME_INFO                 = 10
-SMB2_FILE_REPARSE_POINT_INFO          = 33
-SMB2_FILE_SFIO_RESERVE_INFO           = 44
-SMB2_FILE_SHORT_NAME_INFO             = 45
-SMB2_FILE_STANDARD_INFO               = 5
-SMB2_FILE_STANDARD_LINK_INFO          = 54
-SMB2_FILE_STREAM_INFO                 = 22
-SMB2_FILE_TRACKING_INFO               = 36
-SMB2_FILE_VALID_DATA_LENGTH_INFO      = 39
-
-# File System Information Classes
-SMB2_FILESYSTEM_VOLUME_INFO           = 1
-SMB2_FILESYSTEM_LABEL_INFO            = 2
-SMB2_FILESYSTEM_SIZE_INFO             = 3
-SMB2_FILESYSTEM_DEVICE_INFO           = 4
-SMB2_FILESYSTEM_ATTRIBUTE_INFO        = 5
-SMB2_FILESYSTEM_CONTROL_INFO          = 6
-SMB2_FILESYSTEM_FULL_SIZE_INFO        = 7
-SMB2_FILESYSTEM_OBJECT_ID_INFO        = 8
-SMB2_FILESYSTEM_DRIVER_PATH_INFO      = 9
-SMB2_FILESYSTEM_SECTOR_SIZE_INFO      = 11
-
-# Additional information
-OWNER_SECURITY_INFORMATION  = 0x00000001
-GROUP_SECURITY_INFORMATION  = 0x00000002
-DACL_SECURITY_INFORMATION   = 0x00000004
-SACL_SECURITY_INFORMATION   = 0x00000008
-LABEL_SECURITY_INFORMATION  = 0x00000010
-
-# Flags
-SL_RESTART_SCAN         = 0x00000001
-SL_RETURN_SINGLE_ENTRY  = 0x00000002
-SL_INDEX_SPECIFIED      = 0x00000004
-
-# TRANSFORM_HEADER
-SMB2_ENCRYPTION_AES128_CCM = 0x0001
-
-
-# STRUCtures
-# Represents a SMB2/3 Packet
-class SMBPacketBase(Structure):
-    def addCommand(self,command):
-        # Pad to 8 bytes and put the offset of another SMBPacket
-        raise 'Implement This!' 
-
-    def isValidAnswer(self, status):
-        if self['Status'] != status:
-            import smb3
-            raise smb3.SessionError(self['Status'], self)
-        return True
-
-    def __init__(self, data = None):
-        Structure.__init__(self,data)
-        if data is None:
-            self['TreeID'] = 0
-
-
-class SMB2PacketAsync(SMBPacketBase):
-    structure = (
-        ('ProtocolID','"\xfeSMB'),
-        ('StructureSize','<H=64'),
-        ('CreditCharge','<H=0'),
-        ('Status','<L=0'),
-        ('Command','<H=0'),
-        ('CreditRequestResponse','<H=0'),
-        ('Flags','<L=0'),
-        ('NextCommand','<L=0'),
-        ('MessageID','<Q=0'),
-        ('AsyncID','<Q=0'),
-        ('SessionID','<Q=0'),
-        ('Signature','16s=""'),
-        ('Data',':=""'),
-    )
-
-class SMB3PacketAsync(SMBPacketBase):
-    structure = (
-        ('ProtocolID','"\xfeSMB'),
-        ('StructureSize','<H=64'),
-        ('CreditCharge','<H=0'),
-        ('ChannelSequence','<H=0'),
-        ('Reserved','<H=0'),
-        ('Command','<H=0'),
-        ('CreditRequestResponse','<H=0'),
-        ('Flags','<L=0'),
-        ('NextCommand','<L=0'),
-        ('MessageID','<Q=0'),
-        ('AsyncID','<Q=0'),
-        ('SessionID','<Q=0'),
-        ('Signature','16s=""'),
-        ('Data',':=""'),
-    )
-
-class SMB2Packet(SMBPacketBase):
-    structure = (
-        ('ProtocolID','"\xfeSMB'),
-        ('StructureSize','<H=64'),
-        ('CreditCharge','<H=0'),
-        ('Status','<L=0'),
-        ('Command','<H=0'),
-        ('CreditRequestResponse','<H=0'),
-        ('Flags','<L=0'),
-        ('NextCommand','<L=0'),
-        ('MessageID','<Q=0'),
-        ('Reserved','<L=0'),
-        ('TreeID','<L=0'),
-        ('SessionID','<Q=0'),
-        ('Signature','16s=""'),
-        ('Data',':=""'),
-    )
-
-class SMB3Packet(SMBPacketBase):
-    structure = (
-        ('ProtocolID','"\xfeSMB'),
-        ('StructureSize','<H=64'),
-        ('CreditCharge','<H=0'),
-        ('ChannelSequence','<H=0'),
-        ('Reserved','<H=0'),
-        ('Command','<H=0'),
-        ('CreditRequestResponse','<H=0'),
-        ('Flags','<L=0'),
-        ('NextCommand','<L=0'),
-        ('MessageID','<Q=0'),
-        ('Reserved','<L=0'),
-        ('TreeID','<L=0'),
-        ('SessionID','<Q=0'),
-        ('Signature','16s=""'),
-        ('Data',':=""'),
-    )
-
-class SMB2Error(Structure):
-    structure = (
-        ('StructureSize','<H=9'),
-        ('Reserved','<H=0'),
-        ('ByteCount','<L=0'),
-        ('_ErrorData','_-ErrorData','self["ByteCount"]'),
-        ('ErrorData','"\xff'),
-    )
-
-class SMB2ErrorSymbolicLink(Structure):
-    structure = (
-        ('SymLinkLength','<L=0'),
-        ('SymLinkErrorTag','<L=0'),
-        ('ReparseTag','<L=0'),
-        ('ReparseDataLenght','<H=0'),
-        ('UnparsedPathLength','<H=0'),
-        ('SubstituteNameOffset','<H=0'),
-        ('SubstituteNameLength','<H=0'),
-        ('PrintNameOffset','<H=0'),
-        ('PrintNameLength','<H=0'),
-        ('Flags','<L=0'),
-        ('PathBuffer',':'),
-    )
-
-# SMB2_NEGOTIATE
-class SMB2Negotiate(Structure):
-    structure = (
-        ('StructureSize','<H=36'),
-        ('DialectCount','<H=0'),
-        ('SecurityMode','<H=0'),
-        ('Reserved','<H=0'),
-        ('Capabilities','<L=0'),
-        ('ClientGuid','16s=""'),
-        ('ClientStartTime','<Q=0'),
-        ('Dialects','*<H'),
-    )
-
-class SMB2Negotiate_Response(Structure):
-    structure = (
-        ('StructureSize','<H=65'),
-        ('SecurityMode','<H=0'),
-        ('DialectRevision','<H=0'),
-        ('Reserved','<H=0'),
-        ('ServerGuid','16s=""'),
-        ('Capabilities','<L=0'),
-        ('MaxTransactSize','<L=0'),
-        ('MaxReadSize','<L=0'),
-        ('MaxWriteSize','<L=0'),
-        ('SystemTime','<Q=0'),
-        ('ServerStartTime','<Q=0'),
-        ('SecurityBufferOffset','<H=0'),
-        ('SecurityBufferLength','<H=0'),
-        ('Reserved2','<L=0'),
-        ('_AlignPad','_-AlignPad','self["SecurityBufferOffset"] - (64 + 
self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["SecurityBufferLength"]'),
-        ('Buffer',':'),
-    )
-
-# SMB2_SESSION_SETUP 
-class SMB2SessionSetup(Structure):
-    SIZE = 24
-    structure = (
-        ('StructureSize','<H=25'),
-        ('Flags','<B=0'),
-        ('SecurityMode','<B=0'),
-        ('Capabilities','<L=0'),
-        ('Channel','<L=0'),
-        ('SecurityBufferOffset','<H=(self.SIZE + 64 + len(self["AlignPad"]))'),
-        ('SecurityBufferLength','<H=0'),
-        ('PreviousSessionId','<Q=0'),
-        ('_AlignPad','_-AlignPad','self["SecurityBufferOffset"] - (64 + 
self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["SecurityBufferLength"]'),
-        ('Buffer',':'),
-    )
-
-    def __init__(self, data = None):
-        Structure.__init__(self,data)
-        if data is None:
-            self['AlignPad'] = ''
-
-    def getData(self):
-        #self['AlignPad'] = '\x00' * ((8 - ((24 + SMB2_PACKET_SIZE) & 7)) & 7)
-        #self['SecurityBufferOffset'] = 24 + SMB2_PACKET_SIZE 
+len(self['AlignPad']) 
-        #self['SecurityBufferLength'] += len(self['AlignPad'])
-        return Structure.getData(self)
-        
-
-class SMB2SessionSetup_Response(Structure):
-    structure = (
-        ('StructureSize','<H=9'),
-        ('SessionFlags','<H=0'),
-        ('SecurityBufferOffset','<H=0'),
-        ('SecurityBufferLength','<H=0'),
-        ('_AlignPad','_-AlignPad','self["SecurityBufferOffset"] - (64 + 
self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["SecurityBufferLength"]'),
-        ('Buffer',':'),
-    )
-
-# SMB2_LOGOFF
-class SMB2Logoff(Structure):
-    structure = (
-        ('StructureSize','<H=4'),
-        ('Reserved','<H=0'),
-    ) 
-
-
-class SMB2Logoff_Response(Structure):
-    structure = (
-        ('StructureSize','<H=4'),
-        ('Reserved','<H=0'),
-    )
-
-# SMB2_TREE_CONNECT
-class SMB2TreeConnect(Structure):
-    SIZE = 8
-    structure = (
-        ('StructureSize','<H=9'),
-        ('Reserved','<H=0'),
-        ('PathOffset','<H=(self.SIZE + 64 + len(self["AlignPad"]))'),
-        ('PathLength','<H=0'),
-        ('_AlignPad','_-AlignPad','self["PathOffset"] - (64 + self.SIZE - 1)'),
-        ('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["PathLength"]'),
-        ('Buffer',':'),
-    )
-    def __init__(self, data = None):
-        Structure.__init__(self,data)
-        if data is None:
-            self['AlignPad'] = ''
-
-class SMB2TreeConnect_Response(Structure):
-    structure = (
-        ('StructureSize','<H=16'),
-        ('ShareType','<B=0'),
-        ('Reserved','<B=0'),
-        ('ShareFlags','<L=0'),
-        ('Capabilities','<L=0'),
-        ('MaximalAccess','<L=0'),
-    )
-
-# SMB2_TREE_DISCONNECT
-class SMB2TreeDisconnect(Structure):
-    structure = (
-        ('StructureSize','<H=4'),
-        ('Reserved','<H=0'),
-    )
-
-class SMB2TreeDisconnect_Response(Structure):
-    structure = (
-        ('StructureSize','<H=4'),
-        ('Reserved','<H=0'),
-    )
-
-# SMB2_CREATE
-class SMB2Create(Structure):
-    SIZE = 56
-    structure = (
-        ('StructureSize','<H=57'),
-        ('SecurityFlags','<B=0'),
-        ('RequestedOplockLevel','<B=0'),
-        ('ImpersonationLevel','<L=0'),
-        ('SmbCreateFlags','<Q=0'),
-        ('Reserved','<Q=0'),
-        ('DesiredAccess','<L=0'),
-        ('FileAttributes','<L=0'),
-        ('ShareAccess','<L=0'),
-        ('CreateDisposition','<L=0'),
-        ('CreateOptions','<L=0'),
-        ('NameOffset','<H=(self.SIZE + 64 + len(self["AlignPad"]))'),
-        ('NameLength','<H=0'),
-        ('CreateContextsOffset','<L=0'),
-        ('CreateContextsLength','<L=0'),
-        ('_AlignPad','_-AlignPad','self["NameOffset"] - (64 + 
self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        
('_Buffer','_-Buffer','self["CreateContextsLength"]+self["NameLength"]'),
-        ('Buffer',':'),
-    )
-    def __init__(self, data = None):
-        Structure.__init__(self,data)
-        if data is None:
-            self['AlignPad'] = ''
-
-class SMB2CreateContext(Structure):
-     structure = (
-         ('Next','<L=0'),
-         ('NameOffset','<H=0'),
-         ('NameLength','<H=0'),
-         ('Reserved','<H=0'),
-         ('DataOffset','<H=0'),
-         ('DataLength','<L=0'),
-         ('_Buffer','_-Buffer','self["DataLength"]+self["NameLength"]'),
-         ('Buffer',':'),
-     )
-
-class SMB2_FILEID(Structure):
-    structure = (
-        ('Persistent','<Q=0'),
-        ('Volatile','<Q=0'),
-    )
-
-class SMB2Create_Response(Structure):
-    structure = (
-        ('StructureSize','<H=89'),
-        ('OplockLevel','<B=0'),
-        ('Flags','<B=0'),
-        ('CreateAction','<L=0'),
-        ('CreationTime','<Q=0'),
-        ('LastAccessTime','<Q=0'),
-        ('LastWriteTime','<Q=0'),
-        ('ChangeTime','<Q=0'),
-        ('AllocationSize','<Q=0'),
-        ('EndOfFile','<Q=0'),
-        ('FileAttributes','<L=0'),
-        ('Reserved2','<L=0'),
-        ('FileID',':',SMB2_FILEID),
-        ('CreateContextsOffset','<L=0'),
-        ('CreateContextsLength','<L=0'),
-        ('_AlignPad','_-AlignPad','self["CreateContextsOffset"] - (64 + 
self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["CreateContextsLength"]'),
-        ('Buffer',':'),
-    )
-
-class FILE_FULL_EA_INFORMATION(Structure):
-    structure = (
-        ('NextEntryOffset','<L=0'),
-        ('Flags','<B=0'),
-        ('EaNameLength','<B=0'),
-        ('EaValueLength','<H=0'),
-        ('_EaName','_-EaName','self["EaNameLength"]'),
-        ('EaName',':'),
-        ('_EaValue','_-EaValue','self["EaValue"]'),
-        ('EaValue',':'),
-    )
-
-
-class SMB2_CREATE_DURABLE_HANDLE_RECONNECT(Structure):
-    structure = (
-        ('Data',':',SMB2_FILEID),
-    )
-
-class SMB2_CREATE_DURABLE_HANDLE_REQUEST(Structure):
-    structure = (
-        ('DurableRequest','16s=""'),
-    )
-
-class SMB2_CREATE_DURABLE_HANDLE_RESPONSE(Structure):
-    structure = (
-        ('Reserved','<Q=0'),
-    )
-
-class SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST(Structure):
-    structure = (
-        ('Timestamp','<Q=0'),
-    )
-
-class SMB2_CREATE_QUERY_MAXIMAL_ACCESS_RESPONSE(Structure):
-    structure = (
-        ('QueryStatus','<L=0'),
-        ('MaximalAccess','<L=0'),
-    )
-
-class SMB2_CREATE_ALLOCATION_SIZE(Structure):
-    structure = (
-        ('AllocationSize','<Q=0'),
-    )
-
-class SMB2_CREATE_TIMEWARP_TOKEN(Structure):
-    structure = (
-        ('AllocationSize','<Q=0'),
-    )
-
-class SMB2_CREATE_REQUEST_LEASE(Structure):
-    structure = (
-        ('LeaseKey','16s=""'),
-        ('LeaseState','<L=0'),
-        ('LeaseFlags','<L=0'),
-        ('LeaseDuration','<Q=0'),
-    )
-
-SMB2_CREATE_RESPONSE_LEASE = SMB2_CREATE_REQUEST_LEASE
-
-class SMB2_CREATE_REQUEST_LEASE_V2(Structure):
-    structure = (
-        ('LeaseKey','16s=""'),
-        ('LeaseState','<L=0'),
-        ('Flags','<L=0'),
-        ('LeaseDuration','<Q=0'),
-        ('ParentLeaseKey','16s=""'),
-        ('Epoch','<H=0'),
-        ('Reserved','<H=0'),
-    )
-
-SMB2_CREATE_RESPONSE_LEASE_V2 = SMB2_CREATE_REQUEST_LEASE_V2
-
-class SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2(Structure):
-    structure = (
-        ('Timeout','<L=0'),
-        ('Flags','<L=0'),
-        ('Reserved','8s=""'),
-        ('CreateGuid','16s=""'),
-    )
-
-class SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2(Structure):
-    structure = (
-        ('Timeout','<L=0'),
-        ('Flags','<L=0'),
-    )
-
-class SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2(Structure):
-    structure = (
-        ('FileID',':', SMB2_FILEID),
-        ('CreateGuid','16s=""'),
-        ('Flags','<L=0'),
-    )
-
-class SMB2_CREATE_APP_INSTANCE_ID(Structure):
-    structure = (
-        ('StructureSize','<H=0'),
-        ('Reserved','<H=0'),
-        ('AppInstanceId','16s=""'),
-    )
-
-class SMB2_CREATE_QUERY_ON_DISK_ID(Structure):
-    structure = (
-        ('DiskIDBuffer','32s=""'),
-    )
-
-# Todo: Add Classes for
-#SMB2_CREATE_SD_BUFFER                    
-
-# SMB2_CLOSE
-class SMB2Close(Structure):
-    structure = (
-        ('StructureSize','<H=24'),
-        ('Flags','<H=0'),
-        ('Reserved','<L=0'),
-        ('FileID',':', SMB2_FILEID),
-    )
-
-class SMB2Close_Response(Structure):
-    structure = (
-        ('StructureSize','<H=60'),
-        ('Flags','<H=0'),
-        ('Reserved','<L=0'),
-        ('CreationTime','<Q=0'),
-        ('LastAccessTime','<Q=0'),
-        ('LastWriteTime','<Q=0'),
-        ('ChangeTime','<Q=0'),
-        ('AllocationSize','<Q=0'),
-        ('EndofFile','<Q=0'),
-        ('FileAttributes','<L=0'),
-    )
-
-# SMB2_FLUSH
-class SMB2Flush(Structure):
-    structure = (
-        ('StructureSize','<H=24'),
-        ('Reserved1','<H=0'),
-        ('Reserved2','<L=0'),
-        ('FileID',':',SMB2_FILEID),
-    )
-
-class SMB2Flush_Response(Structure):
-    structure = (
-        ('StructureSize','<H=4'),
-        ('Reserved','<H=0'),
-    )
-
-# SMB2_READ
-class SMB2Read(Structure):
-    SIZE = 48
-    structure = (
-        ('StructureSize','<H=49'),
-        ('Padding','<B=0'),
-        ('Reserved','<B=0'),
-        ('Length','<L=0'),
-        ('Offset','<Q=0'),
-        ('FileID',':',SMB2_FILEID),
-        ('MinimumCount','<L=0'),
-        ('Channel','<L=0'),
-        ('RemainingBytes','<L=0'),
-        ('ReadChannelInfoOffset','<H=0'),
-        ('ReadChannelInfoLength','<H=0'),
-        ('_AlignPad','_-AlignPad','self["ReadChannelInfoOffset"] - (64 + 
self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["ReadChannelInfoLength"]'),
-        ('Buffer',':=0'),
-    )
-    def __init__(self, data = None):
-        Structure.__init__(self,data)
-        if data is None:
-            self['AlignPad'] = ''
-
-
-class SMB2Read_Response(Structure):
-    structure = (
-        ('StructureSize','<H=17'),
-        ('DataOffset','<B=0'),
-        ('Reserved','<B=0'),
-        ('DataLength','<L=0'),
-        ('DataRemaining','<L=0'),
-        ('Reserved2','<L=0'),
-        ('_AlignPad','_-AlignPad','self["DataOffset"] - (64 + 
self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["DataLength"]'),
-        ('Buffer',':'),
-    )
-
-# SMB2_WRITE
-class SMB2Write(Structure):
-    SIZE = 48
-    structure = (
-        ('StructureSize','<H=49'),
-        ('DataOffset','<H=(self.SIZE + 64 + len(self["AlignPad"]))'),
-        ('Length','<L=0'),
-        ('Offset','<Q=0'),
-        ('FileID',':',SMB2_FILEID),
-        ('Channel','<L=0'),
-        ('RemainingBytes','<L=0'),
-        ('WriteChannelInfoOffset','<H=0'),
-        ('WriteChannelInfoLength','<H=0'),
-        ('_AlignPad','_-AlignPad','self["DataOffset"] + 
self["WriteChannelInfoOffset"] - (64 + self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        ('Flags','<L=0'),
-        ('_Buffer','_-Buffer','self["Length"]+self["WriteChannelInfoLength"]'),
-        ('Buffer',':'),
-    )
-    def __init__(self, data = None):
-        Structure.__init__(self,data)
-        if data is None:
-            self['AlignPad'] = ''
-
-
-class SMB2Write_Response(Structure):
-    structure = (
-        ('StructureSize','<H=17'),
-        ('Reserved','<H=0'),
-        ('Count','<L=0'),
-        ('Remaining','<L=0'),
-        ('WriteChannelInfoOffset','<H=0'),
-        ('WriteChannelInfoLength','<H=0'),
-    )
-
-class SMB2OplockBreakNotification(Structure):
-    structure = (
-        ('StructureSize','<H=24'),
-        ('OplockLevel','<B=0'),
-        ('Reserved','<B=0'),
-        ('Reserved2','<L=0'),
-        ('FileID',':',SMB2_FILEID),
-    )
-
-SMB2OplockBreakAcknowledgment = SMB2OplockBreakNotification
-SMB2OplockBreakResponse       = SMB2OplockBreakNotification
-
-class SMB2LeaseBreakNotification(Structure):
-    structure = (
-        ('StructureSize','<H=44'),
-        ('NewEpoch','<H=0'),
-        ('Flags','<L=0'),
-        ('LeaseKey','16s=""'),
-        ('CurrentLeaseState','<L=0'),
-        ('NewLeaseState','<L=0'),
-        ('BreakReason','<L=0'),
-        ('AccessMaskHint','<L=0'),
-        ('ShareMaskHint','<L=0'),
-    )
-
-class SMB2LeaseBreakAcknowledgement(Structure):
-    structure = (
-        ('StructureSize','<H=36'),
-        ('Reserved','<H=0'),
-        ('Flags','<L=0'),
-        ('LeaseKey','16s=""'),
-        ('LeaseState','<L=0'),
-        ('LeaseDuration','<Q=0'),
-    )
-
-SMB2LeaseBreakResponse = SMB2LeaseBreakAcknowledgement
-
-# SMB2_LOCK
-class SMB2_LOCK_ELEMENT(Structure):
-    structure = (
-        ('Offset','<Q=0'),
-        ('Length','<Q=0'),
-        ('Flags','<L=0'),
-        ('Reserved','<L=0'),
-    )
-
-class SMB2Lock(Structure):
-    structure = (
-        ('StructureSize','<H=48'),
-        ('LockCount','<H=0'),
-        ('LockSequence','<L=0'),
-        ('FileID',':',SMB2_FILEID),
-        ('_Locks','_-Locks','self["LockCount"]*24'),
-        ('Locks',':'),
-    )
-
-class SMB2Lock_Response(Structure):
-    structure = (
-        ('StructureSize','<H=4'),
-        ('Reserved','<H=0'),
-    )
-
-
-# SMB2_ECHO
-class SMB2Echo(Structure):
-    structure = (
-        ('StructureSize','<H=4'),
-        ('Reserved','<H=0'),
-    )
-
-SMB2Echo_Response = SMB2Echo
-
-# SMB2_CANCEL`
-class SMB2Cancel(Structure):
-    structure = (
-        ('StructureSize','<H=4'),
-        ('Reserved','<H=0'),
-    )
-
-# SMB2_IOCTL
-class SMB2Ioctl(Structure):
-    SIZE = 56
-    structure = (
-        ('StructureSize','<H=57'),
-        ('Reserved','<H=0'),
-        ('CtlCode','<L=0'),
-        ('FileID',':',SMB2_FILEID),
-        ('InputOffset','<L=(self.SIZE + 64 + len(self["AlignPad"]))'),
-        ('InputCount','<L=0'),
-        ('MaxInputResponse','<L=0'),
-        ('OutputOffset','<L=(self.SIZE + 64 + len(self["AlignPad"]) + 
self["InputCount"])'),
-        ('OutputCount','<L=0'),
-        ('MaxOutputResponse','<L=0'),
-        ('Flags','<L=0'),
-        ('Reserved2','<L=0'),
-        #('_AlignPad','_-AlignPad','self["InputOffset"] + self["OutputOffset"] 
- (64 + self["StructureSize"] - 1)'),
-        #('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["InputCount"]+self["OutputCount"]'),
-        ('Buffer',':'),
-    )
-    def __init__(self, data = None):
-        Structure.__init__(self,data)
-        if data is None:
-            self['AlignPad'] = ''
-
-class FSCTL_PIPE_WAIT_STRUCTURE(Structure):
-    structure = (
-        ('Timeout','<q=0'),
-        ('NameLength','<L=0'),
-        ('TimeoutSpecified','<B=0'),
-        ('Padding','<B=0'),
-        ('_Name','_-Name','self["NameLength"]'),
-        ('Name',':'),
-    )
-
-class SRV_COPYCHUNK_COPY(Structure):
-    structure = (
-        ('SourceKey','24s=""'),
-        ('ChunkCount','<L=0'),
-        ('Reserved','<L=0'),
-        ('_Chunks','_-Chunks', 'self["ChunkCount"]*len(SRV_COPYCHUNK)'),
-        ('Chunks',':'),
-    )
-
-class SRV_COPYCHUNK(Structure):
-    structure = (
-        ('SourceOffset','<Q=0'),
-        ('TargetOffset','<Q=0'),
-        ('Length','<L=0'),
-        ('Reserved','<L=0'),
-    )
-
-class SRV_COPYCHUNK_RESPONSE(Structure):
-    structure = (
-        ('ChunksWritten','<L=0'),
-        ('ChunkBytesWritten','<L=0'),
-        ('TotalBytesWritten','<L=0'),
-    )
-
-class SRV_READ_HASH(Structure):
-    structure = (
-        ('HashType','<L=0'),
-        ('HashVersion','<L=0'),
-        ('HashRetrievalType','<L=0'),
-        ('Length','<L=0'),
-        ('Offset','<Q=0'),
-    )
-
-class NETWORK_RESILIENCY_REQUEST(Structure):
-    structure = (
-        ('Timeout','<L=0'),
-        ('Reserved','<L=0'),
-    ) 
-
-class VALIDATE_NEGOTIATE_INFO(Structure):
-    structure = (
-        ('Capabilities','<L=0'),
-        ('Guid','16s=""'),
-        ('SecurityMode','<H=0'),
-        #('DialectCount','<H=0'),
-        ('Dialects','<H*<H'),
-    )
-
-class SRV_SNAPSHOT_ARRAY(Structure):
-    structure = (
-        ('NumberOfSnapShots','<L=0'),
-        ('NumberOfSnapShotsReturned','<L=0'),
-        ('SnapShotArraySize','<L=0'),
-        ('_SnapShots','_-SnapShots','self["SnapShotArraySize"]'),
-        ('SnapShots',':'),
-    )
-
-class SRV_REQUEST_RESUME_KEY(Structure):
-    structure = (
-        ('ResumeKey','24s=""'),
-        ('ContextLength','<L=0'),
-        ('_Context','_-Context','self["ContextLength"]'),
-        ('Context',':'),
-    )
-
-class HASH_HEADER(Structure):
-    structure = (
-        ('HashType','<L=0'),
-        ('HashVersion','<L=0'),
-        ('SourceFileChangeTime','<Q=0'),
-        ('SourceFileSize','<Q=0'),
-        ('HashBlobLength','<L=0'),
-        ('HashBlobOffset','<L=0'),
-        ('Dirty','<H=0'),
-        ('SourceFileNameLength','<L=0'),
-        ('_SourceFileName','_-SourceFileName','self["SourceFileNameLength"]',),
-        ('SourceFileName',':'),
-    )
-
-class SRV_HASH_RETRIEVE_HASH_BASED(Structure):
-    structure = (
-        ('Offset','<Q=0'),
-        ('BufferLength','<L=0'),
-        ('Reserved','<L=0'),
-        ('_Buffer','_-Buffer','self["BufferLength"]'),
-        ('Buffer',':'),
-    )
-
-class SRV_HASH_RETRIEVE_FILE_BASED(Structure):
-    structure = (
-        ('FileDataOffset','<Q=0'),
-        ('FileDataLength','<Q=0'),
-        ('BufferLength','<L=0'),
-        ('Reserved','<L=0'),
-        ('_Buffer','_-Buffer','self["BufferLength"]'),
-        ('Buffer',':'),
-    )
-
-class NETWORK_INTERFACE_INFO(Structure):
-    structure = (
-        ('Next','<L=0'),
-        ('IfIndex','<L=0'),
-        ('Capability','<L=0'),
-        ('Reserved','<L=0'),
-        ('LinkSpeed','<Q=0'),
-        ('SockAddr_Storage','128s=""'),
-    )
-
-class SMB2Ioctl_Response(Structure):
-    structure = (
-        ('StructureSize','<H=49'),
-        ('Reserved','<H=0'),
-        ('CtlCode','<L=0'),
-        ('FileID',':',SMB2_FILEID),
-        ('InputOffset','<L=0'),
-        ('InputCount','<L=0'),
-        ('OutputOffset','<L=0'),
-        ('OutputCount','<L=0'),
-        ('Flags','<L=0'),
-        ('Reserved2','<L=0'),
-        ('_AlignPad','_-AlignPad','self["OutputOffset"] - (64 + 
self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["InputCount"]+self["OutputCount"]'),
-        ('Buffer',':'),
-    )
-
-# SMB2_QUERY_DIRECTORY
-class SMB2QueryDirectory(Structure):
-    SIZE = 32
-    structure = (
-        ('StructureSize','<H=33'),
-        ('FileInformationClass','<B=0'),
-        ('Flags','<B=0'),
-        ('FileIndex','<L=0'),
-        ('FileID',':',SMB2_FILEID),
-        ('FileNameOffset','<H=(self.SIZE + 64 + len(self["AlignPad"]))'),
-        ('FileNameLength','<H=0'),
-        ('OutputBufferLength','<L=0'),
-        ('_AlignPad','_-AlignPad','self["FileNameOffset"] - (64 + 
self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["FileNameLength"]'),
-        ('Buffer',':'),
-    )
-    def __init__(self, data = None):
-        Structure.__init__(self,data)
-        if data is None:
-            self['AlignPad'] = ''
-
-class SMB2QueryDirectory_Response(Structure):
-    structure = (
-        ('StructureSize','<H=9'),
-        ('OutputBufferOffset','<H=0'),
-        ('OutputBufferLength','<L=0'),
-        ('_AlignPad','_-AlignPad','self["OutputBufferOffset"] - (64 + 
self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["OutputBufferLength"]'),
-        ('Buffer',':'),
-    )
-
-# SMB2_CHANGE_NOTIFY
-class SMB2ChangeNotify(Structure):
-    structure = (
-        ('StructureSize','<H=32'),
-        ('Flags','<H=0'),
-        ('OutputBufferLength','<L=0'),
-        ('FileID',':',SMB2_FILEID),
-        ('CompletionFilter','<L=0'),
-        ('Reserved','<L=0'),
-    )
-
-class SMB2ChangeNotify_Response(Structure):
-    structure = (
-        ('StructureSize','<H=9'),
-        ('OutputBufferOffset','<H=0'),
-        ('OutputBufferLength','<L=0'),
-        ('_AlignPad','_-AlignPad','self["OutputBufferOffset"] - (64 + 
self["StructureSize"] - 1)'),
-        ('AlignPad',':=""'),
-        ('_Buffer','_-Buffer','self["OutputBufferLength"]'),
-        ('Buffer',':'),
-    )
-
-class FILE_NOTIFY_INFORMATION(Structure):
-    structure = (
-        ('NextEntryOffset','<L=0'),
-        ('Action','<L=0'),
-        ('FileNameLength','<L=0'),
-        ('_FileName','_-FileName','self["FileNameLength"]',),
-        ('FileName',':'),
-    )
-
-# SMB2_QUERY_INFO
-class SMB2QueryInfo(Structure):
-    SIZE = 40
-    structure = (
-       ('StructureSize','<H=41'),
-       ('InfoType','<B=0'),
-       ('FileInfoClass','<B=0'),
-       ('OutputBufferLength','<L=0'),
-       ('InputBufferOffset','<H=(self.SIZE + 64 + len(self["AlignPad"]))'),
-       ('Reserved','<H=0'),
-       ('InputBufferLength','<L=0'),
-       ('AdditionalInformation','<L=0'),
-       ('Flags','<L=0'),
-       ('FileID',':',SMB2_FILEID),
-       ('_AlignPad','_-AlignPad','self["InputBufferOffset"] - (64 + 
self["StructureSize"] - 1)'),
-       ('AlignPad',':=""'),
-       ('_Buffer','_-Buffer','self["InputBufferLength"]'),
-       ('Buffer',':'),
-    )
-    def __init__(self, data = None):
-        Structure.__init__(self,data)
-        if data is None:
-            self['AlignPad'] = ''
-
-
-class SMB2_QUERY_QUOTA_INFO(Structure):
-    structure = (
-        ('ReturnSingle','<B=0'),
-        ('RestartScan','<B=0'),
-        ('Reserved','<H=0'),
-        ('SidListLength','<L=0'),
-        ('StartSidLength','<L=0'),
-        ('StartSidOffset','<L=0'),
-        # ToDo: Check 2.2.37.1 here
-        ('SidBuffer',':'),
-    )
-
-class SMB2QueryInfo_Response(Structure):
-   structure = (
-       ('StructureSize','<H=9'),
-       ('OutputBufferOffset','<H=0'),
-       ('OutputBufferLength','<L=0'),
-       ('_AlignPad','_-AlignPad','self["OutputBufferOffset"] - (64 + 
self["StructureSize"] - 1)'),
-       ('AlignPad',':=""'),
-       ('_Buffer','_-Buffer','self["OutputBufferLength"]'),
-       ('Buffer',':'),
-   )
-
-# SMB2_SET_INFO
-class SMB2SetInfo(Structure):
-    SIZE = 32
-    structure = (
-       ('StructureSize','<H=33'),
-       ('InfoType','<B=0'),
-       ('FileInfoClass','<B=0'),
-       ('BufferLength','<L=0'),
-       ('BufferOffset','<H=(self.SIZE + 64 + len(self["AlignPad"]))'),
-       ('Reserved','<H=0'),
-       ('AdditionalInformation','<L=0'),
-       ('FileID',':',SMB2_FILEID),
-       ('_AlignPad','_-AlignPad','self["BufferOffset"] - (64 + 
self["StructureSize"] - 1)'),
-       ('AlignPad',':=""'),
-       ('_Buffer','_-Buffer','self["BufferLength"]'),
-       ('Buffer',':'),
-    )
-    def __init__(self, data = None):
-        Structure.__init__(self,data)
-        if data is None:
-            self['AlignPad'] = ''
-
-class SMB2SetInfo_Response(Structure):
-    structure = (
-       ('StructureSize','<H=2'),
-    )
-
-class FILE_RENAME_INFORMATION_TYPE_2(Structure):
-    structure = (
-        ('ReplaceIfExists','<B=0'),
-        ('Reserved','7s=""'),
-        ('RootDirectory','<Q=0'),
-        ('FileNameLength','<L=0'),
-        ('_FileName','_-FileName','self["FileNameLength"]'),
-        ('FileName',':'),
-    )
-
-class SMB2_TRANSFORM_HEADER(Structure):
-    structure = (
-        ('ProtocolID','"\xfdSMB'),
-        ('Signature','16s=""'),
-        ('Nonce','16s=""'),
-        ('OriginalMessageSize','<L=0'),
-        ('Reserved','<H=0'),
-        ('EncryptionAlgorithm','<H=0'),
-        ('SessionID','<Q=0'),
-    )
-
-# SMB2_FILE_INTERNAL_INFO
-class FileInternalInformation(Structure):
-    structure = (
-        ('IndexNumber','<q=0'),
-    )
diff --git a/tests/python_dependencies/impacket/smbserver.py 
b/tests/python_dependencies/impacket/smbserver.py
deleted file mode 100644
index c481b27ba..000000000
--- a/tests/python_dependencies/impacket/smbserver.py
+++ /dev/null
@@ -1,4177 +0,0 @@
-# Copyright (c) 2003-2016 CORE Security Technologies
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-# Author: Alberto Solino (@agsolino)
-#
-# TODO:
-# [-] Functions should return NT error codes
-# [-] Handling errors in all situations, right now it's just raising 
exceptions.
-# [*] Standard authentication support
-# [ ] Organize the connectionData stuff
-# [*] Add capability to send a bad user ID if the user is not authenticated,
-#     right now you can ask for any command without actually being 
authenticated
-# [ ] PATH TRAVERSALS EVERYWHERE.. BE WARNED!
-# [ ] Check the credentials.. now we're just letting everybody to log in.
-# [ ] Check error situation (now many places assume the right data is coming)
-# [ ] Implement IPC to the main process so the connectionData is on a single 
place
-# [ ] Hence.. implement locking
-# estamos en la B
-
-from __future__ import with_statement
-import calendar
-import socket
-import time
-import datetime
-import struct
-try: # Python 3
-    import configparser
-except ImportError: # Python 2
-    import ConfigParser as configparser
-import SocketServer
-import threading
-import logging
-import logging.config
-import ntpath
-import os
-import fnmatch
-import errno
-import sys
-import random
-import shutil
-from binascii import hexlify
-
-# For signing
-from impacket import smb, nmb, ntlm, uuid, LOG
-from impacket import smb3structs as smb2
-from impacket.spnego import SPNEGO_NegTokenInit, TypesMech, MechTypes, 
SPNEGO_NegTokenResp, ASN1_AID, ASN1_SUPPORTED_MECH
-from impacket.nt_errors import STATUS_NO_MORE_FILES, 
STATUS_NETWORK_NAME_DELETED, STATUS_INVALID_PARAMETER, \
-    STATUS_FILE_CLOSED, STATUS_MORE_PROCESSING_REQUIRED, 
STATUS_OBJECT_PATH_NOT_FOUND, STATUS_DIRECTORY_NOT_EMPTY, \
-    STATUS_FILE_IS_A_DIRECTORY, STATUS_NOT_IMPLEMENTED, STATUS_INVALID_HANDLE, 
STATUS_OBJECT_NAME_COLLISION, \
-    STATUS_NO_SUCH_FILE, STATUS_CANCELLED, STATUS_OBJECT_NAME_NOT_FOUND, 
STATUS_SUCCESS, STATUS_ACCESS_DENIED, \
-    STATUS_NOT_SUPPORTED, STATUS_INVALID_DEVICE_REQUEST, 
STATUS_FS_DRIVER_REQUIRED, STATUS_INVALID_INFO_CLASS
-
-# These ones not defined in nt_errors
-STATUS_SMB_BAD_UID = 0x005B0002
-STATUS_SMB_BAD_TID = 0x00050002
-
-try:
-    unicode        # Python 2
-except NameError:
-    unicode = str  # Python 3
-
-
-# Utility functions
-# and general functions.
-# There are some common functions that can be accessed from more than one SMB
-# command (or either TRANSACTION). That's why I'm putting them here
-# TODO: Return NT ERROR Codes
-
-def outputToJohnFormat(challenge, username, domain, lmresponse, ntresponse):
-# We don't want to add a possible failure here, since this is an
-# extra bonus. We try, if it fails, returns nothing
-    ret_value = ''
-    try:
-        if len(ntresponse) > 24:
-            # Extended Security - NTLMv2
-            ret_value = {'hash_string':'%s::%s:%s:%s:%s' % 
(username.decode('utf-16le'), domain.decode('utf-16le'), hexlify(challenge), 
hexlify(ntresponse)[:32], hexlify(ntresponse)[32:]), 'hash_version':'ntlmv2'}
-        else:
-            # NTLMv1
-            ret_value = {'hash_string':'%s::%s:%s:%s:%s' % 
(username.decode('utf-16le'), domain.decode('utf-16le'), hexlify(lmresponse), 
hexlify(ntresponse), hexlify(challenge)), 'hash_version':'ntlm'}
-    except:
-        # Let's try w/o decoding Unicode
-        try:
-            if len(ntresponse) > 24:
-                # Extended Security - NTLMv2
-                ret_value = {'hash_string':'%s::%s:%s:%s:%s' % (username, 
domain, hexlify(challenge), hexlify(ntresponse)[:32], 
hexlify(ntresponse)[32:]), 'hash_version':'ntlmv2'}
-            else:
-                # NTLMv1
-                ret_value = {'hash_string':'%s::%s:%s:%s:%s' % (username, 
domain, hexlify(lmresponse), hexlify(ntresponse), hexlify(challenge)), 
'hash_version':'ntlm'}
-        except Exception as e:
-            LOG.error("outputToJohnFormat: %s" % e)
-            pass
-
-    return ret_value
-
-def writeJohnOutputToFile(hash_string, hash_version, file_name):
-    fn_data = os.path.splitext(file_name)
-    if hash_version == "ntlmv2":
-        output_filename = fn_data[0] + "_ntlmv2" + fn_data[1]
-    else:
-        output_filename = fn_data[0] + "_ntlm" + fn_data[1]
-
-    with open(output_filename,"a") as f:
-            f.write(hash_string)
-            f.write('\n')
-
-
-def decodeSMBString( flags, text ):
-    if flags & smb.SMB.FLAGS2_UNICODE:
-        return text.decode('utf-16le')
-    else:
-        return text
-
-def encodeSMBString( flags, text ):
-    if flags & smb.SMB.FLAGS2_UNICODE:
-        return (text).encode('utf-16le')
-    else:
-        return text
-
-def getFileTime(t):
-    t *= 10000000
-    t += 116444736000000000
-    return t
-
-def getUnixTime(t):
-    t -= 116444736000000000
-    t /= 10000000
-    return t
-
-def getSMBDate(t):
-    # TODO: Fix this :P
-    d = datetime.date.fromtimestamp(t)
-    year = d.year - 1980
-    ret = (year << 8) + (d.month << 4) + d.day
-    return ret
-
-def getSMBTime(t):
-    # TODO: Fix this :P
-    d = datetime.datetime.fromtimestamp(t)
-    return (d.hour << 8) + (d.minute << 4) + d.second
-
-def getShares(connId, smbServer):
-    config = smbServer.getServerConfig()
-    sections = config.sections()
-    # Remove the global one
-    del(sections[sections.index('global')])
-    shares = {}
-    for i in sections:
-        shares[i] = dict(config.items(i))
-    return shares
-
-def searchShare(connId, share, smbServer):
-    config = smbServer.getServerConfig()
-    if config.has_section(share):
-       return dict(config.items(share))
-    else:
-       return None
-
-def openFile(path,fileName, accessMode, fileAttributes, openMode):
-    fileName = os.path.normpath(fileName.replace('\\','/'))
-    errorCode = 0
-    if len(fileName) > 0 and (fileName[0] == '/' or fileName[0] == '\\'):
-       # strip leading '/'
-       fileName = fileName[1:]
-    pathName = os.path.join(path,fileName)
-    mode = 0
-    # Check the Open Mode
-    if openMode & 0x10:
-        # If the file does not exist, create it.
-        mode = os.O_CREAT
-    else:
-        # If file does not exist, return an error
-        if os.path.exists(pathName) is not True:
-            errorCode = STATUS_NO_SUCH_FILE
-            return 0,mode, pathName, errorCode
-
-    if os.path.isdir(pathName) and (fileAttributes & smb.ATTR_DIRECTORY) == 0:
-        # Request to open a normal file and this is actually a directory
-            errorCode = STATUS_FILE_IS_A_DIRECTORY
-            return 0, mode, pathName, errorCode
-    # Check the Access Mode
-    if accessMode & 0x7 == 1:
-       mode |= os.O_WRONLY
-    elif accessMode & 0x7 == 2:
-       mode |= os.O_RDWR
-    else:
-       mode = os.O_RDONLY
-
-    try:
-        if sys.platform == 'win32':
-            mode |= os.O_BINARY
-        fid = os.open(pathName, mode)
-    except Exception as e:
-        LOG.error("openFile: %s,%s" % (pathName, mode) ,e)
-        fid = 0
-        errorCode = STATUS_ACCESS_DENIED
-
-    return fid, mode, pathName, errorCode
-
-def queryFsInformation(path, filename, level=0):
-
-    if isinstance(filename,unicode):
-         encoding = 'utf-16le'
-         flags    = smb.SMB.FLAGS2_UNICODE
-    else:
-         encoding = 'ascii'
-         flags    = 0
-
-    fileName = os.path.normpath(filename.replace('\\','/'))
-    if len(fileName) > 0 and (fileName[0] == '/' or fileName[0] == '\\'):
-       # strip leading '/'
-       fileName = fileName[1:]
-    pathName = os.path.join(path,fileName)
-    fileSize = os.path.getsize(pathName)
-    (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = 
os.stat(pathName)
-    if level == smb.SMB_QUERY_FS_ATTRIBUTE_INFO or level == 
smb2.SMB2_FILESYSTEM_ATTRIBUTE_INFO:
-        data = smb.SMBQueryFsAttributeInfo()
-        data['FileSystemAttributes']      = smb.FILE_CASE_SENSITIVE_SEARCH | 
smb.FILE_CASE_PRESERVED_NAMES
-        data['MaxFilenNameLengthInBytes'] = 255
-        data['LengthOfFileSystemName']    = len('XTFS')*2
-        data['FileSystemName']            = 'XTFS'.encode('utf-16le')
-        return data.getData()
-    elif level == smb.SMB_INFO_VOLUME:
-        data = smb.SMBQueryFsInfoVolume( flags = flags )
-        data['VolumeLabel']               = 'SHARE'.encode(encoding)
-        return data.getData()
-    elif level == smb.SMB_QUERY_FS_VOLUME_INFO or level == 
smb2.SMB2_FILESYSTEM_VOLUME_INFO:
-        data = smb.SMBQueryFsVolumeInfo()
-        data['VolumeLabel']               = ''
-        data['VolumeCreationTime']        = getFileTime(ctime)
-        return data.getData()
-    elif level == smb.SMB_QUERY_FS_SIZE_INFO:
-        data = smb.SMBQueryFsSizeInfo()
-        return data.getData()
-    elif level == smb.FILE_FS_FULL_SIZE_INFORMATION:
-        data = smb.SMBFileFsFullSizeInformation()
-        return data.getData()
-    elif level == smb.FILE_FS_SIZE_INFORMATION:
-        data = smb.FileFsSizeInformation()
-        return data.getData()
-    else:
-        lastWriteTime = mtime
-        attribs = 0
-        if os.path.isdir(pathName):
-            attribs |= smb.SMB_FILE_ATTRIBUTE_DIRECTORY
-        if os.path.isfile(pathName):
-            attribs |= smb.SMB_FILE_ATTRIBUTE_NORMAL
-        fileAttributes = attribs
-        return fileSize, lastWriteTime, fileAttributes
-
-def findFirst2(path, fileName, level, searchAttributes, isSMB2 = False):
-     # TODO: Depending on the level, this could be done much simpler
-
-     #print "FindFirs2 path:%s, filename:%s" % (path, fileName)
-     fileName = os.path.normpath(fileName.replace('\\','/'))
-     # Let's choose the right encoding depending on the request
-     if isinstance(fileName,unicode):
-         encoding = 'utf-16le'
-         flags    = smb.SMB.FLAGS2_UNICODE
-     else:
-         encoding = 'ascii'
-         flags    = 0
-
-     if len(fileName) > 0 and (fileName[0] == '/' or fileName[0] == '\\'):
-        # strip leading '/'
-        fileName = fileName[1:]
-
-     pathName = os.path.join(path,fileName)
-     files = []
-
-     if pathName.find('*') == -1 and pathName.find('?') == -1:
-         # No search patterns
-         pattern = ''
-     else:
-         pattern = os.path.basename(pathName)
-         dirName = os.path.dirname(pathName)
-
-     # Always add . and .. Not that important for Windows, but Samba whines if
-     # not present (for * search only)
-     if pattern == '*':
-         files.append(os.path.join(dirName,'.'))
-         files.append(os.path.join(dirName,'..'))
-
-     if pattern != '':
-         for file in os.listdir(dirName):
-             if fnmatch.fnmatch(file.lower(),pattern.lower()):
-                entry = os.path.join(dirName, file)
-                if os.path.isdir(entry):
-                    if searchAttributes & smb.ATTR_DIRECTORY:
-                        files.append(entry)
-                else:
-                    files.append(entry)
-     else:
-         if os.path.exists(pathName):
-             files.append(pathName)
-
-     searchResult = []
-     searchCount = len(files)
-     errorCode = STATUS_SUCCESS
-
-     for i in files:
-        if level == smb.SMB_FIND_FILE_BOTH_DIRECTORY_INFO or level == 
smb2.SMB2_FILE_BOTH_DIRECTORY_INFO:
-            item = smb.SMBFindFileBothDirectoryInfo( flags = flags )
-        elif level == smb.SMB_FIND_FILE_DIRECTORY_INFO or level == 
smb2.SMB2_FILE_DIRECTORY_INFO:
-            item = smb.SMBFindFileDirectoryInfo( flags = flags )
-        elif level == smb.SMB_FIND_FILE_FULL_DIRECTORY_INFO or level == 
smb2.SMB2_FULL_DIRECTORY_INFO:
-            item = smb.SMBFindFileFullDirectoryInfo( flags = flags )
-        elif level == smb.SMB_FIND_INFO_STANDARD:
-            item = smb.SMBFindInfoStandard( flags = flags )
-        elif level == smb.SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO or level == 
smb2.SMB2_FILE_ID_FULL_DIRECTORY_INFO:
-            item = smb.SMBFindFileIdFullDirectoryInfo( flags = flags )
-        elif level == smb.SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO or level == 
smb2.SMB2_FILE_ID_BOTH_DIRECTORY_INFO:
-            item = smb.SMBFindFileIdBothDirectoryInfo( flags = flags )
-        elif level == smb.SMB_FIND_FILE_NAMES_INFO or level == 
smb2.SMB2_FILE_NAMES_INFO:
-            item = smb.SMBFindFileNamesInfo( flags = flags )
-        else:
-            LOG.error("Wrong level %d!" % level)
-            return  searchResult, searchCount, STATUS_NOT_SUPPORTED
-
-        (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = 
os.stat(i)
-        if os.path.isdir(i):
-           item['ExtFileAttributes'] = smb.ATTR_DIRECTORY
-        else:
-           item['ExtFileAttributes'] = smb.ATTR_NORMAL | smb.ATTR_ARCHIVE
-
-        item['FileName'] = os.path.basename(i).encode(encoding)
-
-        if level == smb.SMB_FIND_FILE_BOTH_DIRECTORY_INFO or level == 
smb.SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO or level == 
smb2.SMB2_FILE_ID_BOTH_DIRECTORY_INFO or level == 
smb2.SMB2_FILE_BOTH_DIRECTORY_INFO:
-           item['EaSize']            = 0
-           item['EndOfFile']         = size
-           item['AllocationSize']    = size
-           item['CreationTime']      = getFileTime(ctime)
-           item['LastAccessTime']    = getFileTime(atime)
-           item['LastWriteTime']     = getFileTime(mtime)
-           item['LastChangeTime']    = getFileTime(mtime)
-           item['ShortName']         = '\x00'*24
-           item['FileName']          = os.path.basename(i).encode(encoding)
-           padLen = (8-(len(item) % 8)) % 8
-           item['NextEntryOffset']   = len(item) + padLen
-        elif level == smb.SMB_FIND_FILE_DIRECTORY_INFO:
-           item['EndOfFile']         = size
-           item['AllocationSize']    = size
-           item['CreationTime']      = getFileTime(ctime)
-           item['LastAccessTime']    = getFileTime(atime)
-           item['LastWriteTime']     = getFileTime(mtime)
-           item['LastChangeTime']    = getFileTime(mtime)
-           item['FileName']          = os.path.basename(i).encode(encoding)
-           padLen = (8-(len(item) % 8)) % 8
-           item['NextEntryOffset']   = len(item) + padLen
-        elif level == smb.SMB_FIND_FILE_FULL_DIRECTORY_INFO or level == 
smb.SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO or level == 
smb2.SMB2_FULL_DIRECTORY_INFO:
-           item['EaSize']            = 0
-           item['EndOfFile']         = size
-           item['AllocationSize']    = size
-           item['CreationTime']      = getFileTime(ctime)
-           item['LastAccessTime']    = getFileTime(atime)
-           item['LastWriteTime']     = getFileTime(mtime)
-           item['LastChangeTime']    = getFileTime(mtime)
-           padLen = (8-(len(item) % 8)) % 8
-           item['NextEntryOffset']   = len(item) + padLen
-        elif level == smb.SMB_FIND_INFO_STANDARD:
-           item['EaSize']            = size
-           item['CreationDate']      = getSMBDate(ctime)
-           item['CreationTime']      = getSMBTime(ctime)
-           item['LastAccessDate']    = getSMBDate(atime)
-           item['LastAccessTime']    = getSMBTime(atime)
-           item['LastWriteDate']     = getSMBDate(mtime)
-           item['LastWriteTime']     = getSMBTime(mtime)
-        searchResult.append(item)
-
-     # No more files
-     if (level >= smb.SMB_FIND_FILE_DIRECTORY_INFO or isSMB2 == True) and 
searchCount > 0:
-         searchResult[-1]['NextEntryOffset'] = 0
-
-     return searchResult, searchCount, errorCode
-
-def queryFileInformation(path, filename, level):
-    #print "queryFileInfo path: %s, filename: %s, level:0x%x" % 
(path,filename,level)
-    return queryPathInformation(path,filename, level)
-
-def queryPathInformation(path, filename, level):
-    # TODO: Depending on the level, this could be done much simpler
-  #print "queryPathInfo path: %s, filename: %s, level:0x%x" % 
(path,filename,level)
-  try:
-    errorCode = 0
-    fileName = os.path.normpath(filename.replace('\\','/'))
-    if len(fileName) > 0 and (fileName[0] == '/' or fileName[0] == '\\') and 
path != '':
-       # strip leading '/'
-       fileName = fileName[1:]
-    pathName = os.path.join(path,fileName)
-    if os.path.exists(pathName):
-        (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = 
os.stat(pathName)
-        if level == smb.SMB_QUERY_FILE_BASIC_INFO:
-            infoRecord = smb.SMBQueryFileBasicInfo()
-            infoRecord['CreationTime']         = getFileTime(ctime)
-            infoRecord['LastAccessTime']       = getFileTime(atime)
-            infoRecord['LastWriteTime']        = getFileTime(mtime)
-            infoRecord['LastChangeTime']       = getFileTime(mtime)
-            if os.path.isdir(pathName):
-               infoRecord['ExtFileAttributes'] = smb.ATTR_DIRECTORY
-            else:
-               infoRecord['ExtFileAttributes'] = smb.ATTR_NORMAL | 
smb.ATTR_ARCHIVE
-        elif level == smb.SMB_QUERY_FILE_STANDARD_INFO:
-            infoRecord = smb.SMBQueryFileStandardInfo()
-            infoRecord['AllocationSize']       = size
-            infoRecord['EndOfFile']            = size
-            if os.path.isdir(pathName):
-               infoRecord['Directory']         = 1
-            else:
-               infoRecord['Directory']         = 0
-        elif level == smb.SMB_QUERY_FILE_ALL_INFO or level == 
smb2.SMB2_FILE_ALL_INFO:
-            infoRecord = smb.SMBQueryFileAllInfo()
-            infoRecord['CreationTime']         = getFileTime(ctime)
-            infoRecord['LastAccessTime']       = getFileTime(atime)
-            infoRecord['LastWriteTime']        = getFileTime(mtime)
-            infoRecord['LastChangeTime']       = getFileTime(mtime)
-            if os.path.isdir(pathName):
-               infoRecord['ExtFileAttributes'] = smb.ATTR_DIRECTORY
-            else:
-               infoRecord['ExtFileAttributes'] = smb.ATTR_NORMAL | 
smb.ATTR_ARCHIVE
-            infoRecord['AllocationSize']       = size
-            infoRecord['EndOfFile']            = size
-            if os.path.isdir(pathName):
-               infoRecord['Directory']         = 1
-            else:
-               infoRecord['Directory']         = 0
-            infoRecord['FileName']             = filename.encode('utf-16le')
-        elif level == smb2.SMB2_FILE_NETWORK_OPEN_INFO:
-            infoRecord = smb.SMBFileNetworkOpenInfo()
-            infoRecord['CreationTime']         = getFileTime(ctime)
-            infoRecord['LastAccessTime']       = getFileTime(atime)
-            infoRecord['LastWriteTime']        = getFileTime(mtime)
-            infoRecord['ChangeTime']           = getFileTime(mtime)
-            infoRecord['AllocationSize']       = size
-            infoRecord['EndOfFile']            = size
-            if os.path.isdir(pathName):
-               infoRecord['FileAttributes'] = smb.ATTR_DIRECTORY
-            else:
-               infoRecord['FileAttributes'] = smb.ATTR_NORMAL | 
smb.ATTR_ARCHIVE
-        elif level == smb.SMB_QUERY_FILE_EA_INFO or level == 
smb2.SMB2_FILE_EA_INFO:
-            infoRecord = smb.SMBQueryFileEaInfo()
-        elif level == smb2.SMB2_FILE_STREAM_INFO:
-            infoRecord = smb.SMBFileStreamInformation()
-        else:
-            LOG.error('Unknown level for query path info! 0x%x' % level)
-            # UNSUPPORTED
-            return None, STATUS_NOT_SUPPORTED
-
-        return infoRecord, errorCode
-    else:
-        # NOT FOUND
-        return None, STATUS_OBJECT_NAME_NOT_FOUND
-  except Exception as e:
-      LOG.error('queryPathInfo: %s' % e)
-      raise
-
-def queryDiskInformation(path):
-# TODO: Do something useful here :)
-# For now we just return fake values
-   totalUnits = 65535
-   freeUnits = 65535
-   return totalUnits, freeUnits
-
-# Here we implement the NT transaction handlers
-class NTTRANSCommands:
-    def default(self, connId, smbServer, recvPacket, parameters, data, 
maxDataCount = 0):
-        pass
-
-# Here we implement the NT transaction handlers
-class TRANSCommands:
-    @staticmethod
-    def lanMan(connId, smbServer, recvPacket, parameters, data, maxDataCount = 
0):
-        # Minimal [MS-RAP] implementation, just to return the shares
-        connData = smbServer.getConnectionData(connId)
-
-        respSetup = ''
-        respParameters = ''
-        respData = ''
-        errorCode = STATUS_SUCCESS
-        if struct.unpack('<H',parameters[:2])[0] == 0:
-            # NetShareEnum Request
-            netShareEnum = smb.SMBNetShareEnum(parameters)
-            if netShareEnum['InfoLevel'] == 1:
-                shares = getShares(connId, smbServer)
-                respParameters = smb.SMBNetShareEnumResponse()
-                respParameters['EntriesReturned']  = len(shares)
-                respParameters['EntriesAvailable'] = len(shares)
-                tailData = ''
-                for i in shares:
-                    # NetShareInfo1 len == 20
-                    entry = smb.NetShareInfo1()
-                    entry['NetworkName'] = i + '\x00'*(13-len(i))
-                    entry['Type']        = int(shares[i]['share type'])
-                    # (beto) If offset == 0 it crashes explorer.exe on windows 
7
-                    entry['RemarkOffsetLow'] = 20 * len(shares) + len(tailData)
-                    respData += entry.getData()
-                    if 'comment' in shares[i]:
-                        tailData += shares[i]['comment'] + '\x00'
-                    else:
-                        tailData += '\x00'
-                respData += tailData
-            else:
-                # We don't support other info levels
-                errorCode = STATUS_NOT_SUPPORTED
-        elif struct.unpack('<H',parameters[:2])[0] == 13:
-            # NetrServerGetInfo Request
-            respParameters = smb.SMBNetServerGetInfoResponse()
-            netServerInfo = smb.SMBNetServerInfo1()
-            netServerInfo['ServerName'] = smbServer.getServerName()
-            respData = str(netServerInfo)
-            respParameters['TotalBytesAvailable'] = len(respData)
-        elif struct.unpack('<H',parameters[:2])[0] == 1:
-            # NetrShareGetInfo Request
-            request = smb.SMBNetShareGetInfo(parameters)
-            respParameters = smb.SMBNetShareGetInfoResponse()
-            shares = getShares(connId, smbServer)
-            share = shares[request['ShareName'].upper()]
-            shareInfo = smb.NetShareInfo1()
-            shareInfo['NetworkName'] = request['ShareName'].upper() + '\x00'
-            shareInfo['Type']        = int(share['share type'])
-            respData = shareInfo.getData()
-            if 'comment' in share:
-                shareInfo['RemarkOffsetLow'] = len(respData)
-                respData += share['comment'] + '\x00'
-            respParameters['TotalBytesAvailable'] = len(respData)
-
-        else:
-            # We don't know how to handle anything else
-            errorCode = STATUS_NOT_SUPPORTED
-
-        smbServer.setConnectionData(connId, connData)
-
-        return respSetup, respParameters, respData, errorCode
-
-    @staticmethod
-    def transactNamedPipe(connId, smbServer, recvPacket, parameters, data, 
maxDataCount = 0):
-        connData = smbServer.getConnectionData(connId)
-
-        respSetup = ''
-        respParameters = ''
-        respData = ''
-        errorCode = STATUS_SUCCESS
-        SMBCommand  = smb.SMBCommand(recvPacket['Data'][0])
-        transParameters= 
smb.SMBTransaction_Parameters(SMBCommand['Parameters'])
-
-        # Extract the FID
-        fid = struct.unpack('<H', transParameters['Setup'][2:])[0]
-
-        if fid in connData['OpenedFiles']:
-            fileHandle = connData['OpenedFiles'][fid]['FileHandle']
-            if fileHandle != PIPE_FILE_DESCRIPTOR:
-                os.write(fileHandle,data)
-                respData = os.read(fileHandle,data)
-            else:
-                sock = connData['OpenedFiles'][fid]['Socket']
-                sock.send(data)
-                respData = sock.recv(maxDataCount)
-        else:
-            errorCode = STATUS_INVALID_HANDLE
-
-        smbServer.setConnectionData(connId, connData)
-
-        return respSetup, respParameters, respData, errorCode
-
-# Here we implement the transaction2 handlers
-class TRANS2Commands:
-    # All these commands return setup, parameters, data, errorCode
-    @staticmethod
-    def setPathInformation(connId, smbServer, recvPacket, parameters, data, 
maxDataCount = 0):
-        connData = smbServer.getConnectionData(connId)
-
-        respSetup = ''
-        respParameters = ''
-        respData = ''
-        errorCode = STATUS_SUCCESS
-        setPathInfoParameters = smb.SMBSetPathInformation_Parameters(flags = 
recvPacket['Flags2'], data = parameters)
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-            path     = connData['ConnectedShares'][recvPacket['Tid']]['path']
-            fileName = decodeSMBString(recvPacket['Flags2'], 
setPathInfoParameters['FileName'])
-            fileName = os.path.normpath(fileName.replace('\\','/'))
-            if len(fileName) > 0 and (fileName[0] == '/' or fileName[0] == 
'\\') and path != '':
-               # strip leading '/'
-               fileName = fileName[1:]
-            pathName = os.path.join(path,fileName)
-            if os.path.exists(pathName):
-                informationLevel = setPathInfoParameters['InformationLevel']
-                if informationLevel == smb.SMB_SET_FILE_BASIC_INFO:
-                    infoRecord = smb.SMBSetFileBasicInfo(data)
-                    # Creation time won't be set,  the other ones we play with.
-                    atime = infoRecord['LastAccessTime']
-                    if atime == 0:
-                        atime = -1
-                    else:
-                        atime = getUnixTime(atime)
-                    mtime = infoRecord['LastWriteTime']
-                    if mtime == 0:
-                        mtime = -1
-                    else:
-                        mtime = getUnixTime(mtime)
-                    if mtime != -1 or atime != -1:
-                        os.utime(pathName,(atime,mtime))
-                else:
-                    smbServer.log('Unknown level for set path info! 0x%x' % 
setPathInfoParameters['InformationLevel'], logging.ERROR)
-                    # UNSUPPORTED
-                    errorCode =  STATUS_NOT_SUPPORTED
-            else:
-                errorCode = STATUS_OBJECT_NAME_NOT_FOUND
-
-            if errorCode == STATUS_SUCCESS:
-                respParameters = smb.SMBSetPathInformationResponse_Parameters()
-
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-        smbServer.setConnectionData(connId, connData)
-
-        return respSetup, respParameters, respData, errorCode
-
-
-    @staticmethod
-    def setFileInformation(connId, smbServer, recvPacket, parameters, data, 
maxDataCount = 0):
-        connData = smbServer.getConnectionData(connId)
-
-        respSetup = ''
-        respParameters = ''
-        respData = ''
-        errorCode = STATUS_SUCCESS
-        setFileInfoParameters = 
smb.SMBSetFileInformation_Parameters(parameters)
-
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-            if setFileInfoParameters['FID'] in connData['OpenedFiles']:
-                fileName = 
connData['OpenedFiles'][setFileInfoParameters['FID']]['FileName']
-                informationLevel = setFileInfoParameters['InformationLevel']
-                if informationLevel == smb.SMB_SET_FILE_DISPOSITION_INFO:
-                    infoRecord = smb.SMBSetFileDispositionInfo(parameters)
-                    if infoRecord['DeletePending'] > 0:
-                       # Mark this file for removal after closed
-                       
connData['OpenedFiles'][setFileInfoParameters['FID']]['DeleteOnClose'] = True
-                       respParameters = 
smb.SMBSetFileInformationResponse_Parameters()
-                elif informationLevel == smb.SMB_SET_FILE_BASIC_INFO:
-                    infoRecord = smb.SMBSetFileBasicInfo(data)
-                    # Creation time won't be set,  the other ones we play with.
-                    atime = infoRecord['LastAccessTime']
-                    if atime == 0:
-                        atime = -1
-                    else:
-                        atime = getUnixTime(atime)
-                    mtime = infoRecord['LastWriteTime']
-                    if mtime == 0:
-                        mtime = -1
-                    else:
-                        mtime = getUnixTime(mtime)
-                    os.utime(fileName,(atime,mtime))
-                elif informationLevel == smb.SMB_SET_FILE_END_OF_FILE_INFO:
-                    fileHandle = 
connData['OpenedFiles'][setFileInfoParameters['FID']]['FileHandle']
-                    infoRecord = smb.SMBSetFileEndOfFileInfo(data)
-                    if infoRecord['EndOfFile'] > 0:
-                        os.lseek(fileHandle, infoRecord['EndOfFile']-1, 0)
-                        os.write(fileHandle, '\x00')
-                else:
-                    smbServer.log('Unknown level for set file info! 0x%x' % 
setFileInfoParameters['InformationLevel'], logging.ERROR)
-                    # UNSUPPORTED
-                    errorCode =  STATUS_NOT_SUPPORTED
-            else:
-                errorCode = STATUS_NO_SUCH_FILE
-
-            if errorCode == STATUS_SUCCESS:
-                respParameters = smb.SMBSetFileInformationResponse_Parameters()
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-        smbServer.setConnectionData(connId, connData)
-
-        return respSetup, respParameters, respData, errorCode
-
-    @staticmethod
-    def queryFileInformation(connId, smbServer, recvPacket, parameters, data, 
maxDataCount = 0):
-        connData = smbServer.getConnectionData(connId)
-
-        respSetup = ''
-        respParameters = ''
-        respData = ''
-
-        queryFileInfoParameters = 
smb.SMBQueryFileInformation_Parameters(parameters)
-
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-            if queryFileInfoParameters['FID'] in connData['OpenedFiles']:
-                fileName = 
connData['OpenedFiles'][queryFileInfoParameters['FID']]['FileName']
-
-                infoRecord, errorCode = queryFileInformation('', fileName, 
queryFileInfoParameters['InformationLevel'])
-
-                if infoRecord is not None:
-                    respParameters = 
smb.SMBQueryFileInformationResponse_Parameters()
-                    respData = infoRecord
-            else:
-                errorCode = STATUS_INVALID_HANDLE
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-        smbServer.setConnectionData(connId, connData)
-
-        return respSetup, respParameters, respData, errorCode
-
-    @staticmethod
-    def queryPathInformation(connId, smbServer, recvPacket, parameters, data, 
maxDataCount = 0):
-        connData = smbServer.getConnectionData(connId)
-
-        respSetup = ''
-        respParameters = ''
-        respData = ''
-        errorCode = 0
-
-        queryPathInfoParameters = smb.SMBQueryPathInformation_Parameters(flags 
= recvPacket['Flags2'], data = parameters)
-
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-            path = connData['ConnectedShares'][recvPacket['Tid']]['path']
-            try:
-               infoRecord, errorCode = queryPathInformation(path, 
decodeSMBString(recvPacket['Flags2'], queryPathInfoParameters['FileName']), 
queryPathInfoParameters['InformationLevel'])
-            except Exception as e:
-               smbServer.log("queryPathInformation: %s" % e,logging.ERROR)
-
-            if infoRecord is not None:
-                respParameters = 
smb.SMBQueryPathInformationResponse_Parameters()
-                respData = infoRecord
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-        smbServer.setConnectionData(connId, connData)
-
-        return respSetup, respParameters, respData, errorCode
-
-    @staticmethod
-    def queryFsInformation(connId, smbServer, recvPacket, parameters, data, 
maxDataCount = 0):
-        connData = smbServer.getConnectionData(connId)
-        errorCode = 0
-        # Get the Tid associated
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-            data = 
queryFsInformation(connData['ConnectedShares'][recvPacket['Tid']]['path'], '', 
struct.unpack('<H',parameters)[0])
-
-        smbServer.setConnectionData(connId, connData)
-
-        return '','', data, errorCode
-
-    @staticmethod
-    def findNext2(connId, smbServer, recvPacket, parameters, data, 
maxDataCount):
-        connData = smbServer.getConnectionData(connId)
-
-        respSetup = ''
-        respParameters = ''
-        respData = ''
-        errorCode = STATUS_SUCCESS
-        findNext2Parameters = smb.SMBFindNext2_Parameters(flags = 
recvPacket['Flags2'], data = parameters)
-
-        sid = findNext2Parameters['SID']
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-            if sid in connData['SIDs']:
-                searchResult = connData['SIDs'][sid]
-                respParameters = smb.SMBFindNext2Response_Parameters()
-                endOfSearch = 1
-                searchCount = 1
-                totalData = 0
-                for i in enumerate(searchResult):
-                    data = i[1].getData()
-                    lenData = len(data)
-                    if (totalData+lenData) >= maxDataCount or (i[0]+1) >= 
findNext2Parameters['SearchCount']:
-                        # We gotta stop here and continue on a find_next2
-                        endOfSearch = 0
-                        connData['SIDs'][sid] = searchResult[i[0]:]
-                        respParameters['LastNameOffset'] = totalData
-                        break
-                    else:
-                        searchCount +=1
-                        respData += data
-                        totalData += lenData
-
-                # Have we reached the end of the search or still stuff to send?
-                if endOfSearch > 0:
-                    # Let's remove the SID from our ConnData
-                    del(connData['SIDs'][sid])
-
-                respParameters['EndOfSearch'] = endOfSearch
-                respParameters['SearchCount'] = searchCount
-            else:
-                errorCode = STATUS_INVALID_HANDLE
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-        smbServer.setConnectionData(connId, connData)
-
-        return respSetup, respParameters, respData, errorCode
-
-    @staticmethod
-    def findFirst2(connId, smbServer, recvPacket, parameters, data, 
maxDataCount):
-        connData = smbServer.getConnectionData(connId)
-
-        respSetup = ''
-        respParameters = ''
-        respData = ''
-        findFirst2Parameters = smb.SMBFindFirst2_Parameters( 
recvPacket['Flags2'], data = parameters)
-
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-            path = connData['ConnectedShares'][recvPacket['Tid']]['path']
-
-            searchResult, searchCount, errorCode = findFirst2(path,
-                          decodeSMBString( recvPacket['Flags2'], 
findFirst2Parameters['FileName'] ),
-                          findFirst2Parameters['InformationLevel'],
-                          findFirst2Parameters['SearchAttributes'] )
-
-            respParameters = smb.SMBFindFirst2Response_Parameters()
-            endOfSearch = 1
-            sid = 0x80 # default SID
-            searchCount = 0
-            totalData = 0
-            for i in enumerate(searchResult):
-                #i[1].dump()
-                data = i[1].getData()
-                lenData = len(data)
-                if (totalData+lenData) >= maxDataCount or (i[0]+1) > 
findFirst2Parameters['SearchCount']:
-                    # We gotta stop here and continue on a find_next2
-                    endOfSearch = 0
-                    # Simple way to generate a fid
-                    if len(connData['SIDs']) == 0:
-                       sid = 1
-                    else:
-                       sid = connData['SIDs'].keys()[-1] + 1
-                    # Store the remaining search results in the ConnData SID
-                    connData['SIDs'][sid] = searchResult[i[0]:]
-                    respParameters['LastNameOffset'] = totalData
-                    break
-                else:
-                    searchCount +=1
-                    respData += data
-
-                    padLen = (8-(lenData % 8)) %8
-                    respData += '\xaa'*padLen
-                    totalData += lenData + padLen
-
-            respParameters['SID'] = sid
-            respParameters['EndOfSearch'] = endOfSearch
-            respParameters['SearchCount'] = searchCount
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-        smbServer.setConnectionData(connId, connData)
-
-        return respSetup, respParameters, respData, errorCode
-
-# Here we implement the commands handlers
-class SMBCommands:
-
-    @staticmethod
-    def smbTransaction(connId, smbServer, SMBCommand, recvPacket, 
transCommands):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb.SMBCommand(recvPacket['Command'])
-
-        transParameters= 
smb.SMBTransaction_Parameters(SMBCommand['Parameters'])
-
-        # Do the stuff
-        if transParameters['ParameterCount'] != 
transParameters['TotalParameterCount']:
-            # TODO: Handle partial parameters
-            raise Exception("Unsupported partial parameters in TRANSACT2!")
-        else:
-            transData = smb.SMBTransaction_SData(flags = recvPacket['Flags2'])
-            # Standard says servers shouldn't trust Parameters and Data comes
-            # in order, so we have to parse the offsets, ugly
-
-            paramCount = transParameters['ParameterCount']
-            transData['Trans_ParametersLength'] = paramCount
-            dataCount = transParameters['DataCount']
-            transData['Trans_DataLength'] = dataCount
-            transData.fromString(SMBCommand['Data'])
-            if transParameters['ParameterOffset'] > 0:
-                paramOffset = transParameters['ParameterOffset'] - 63 - 
transParameters['SetupLength']
-                transData['Trans_Parameters'] = 
SMBCommand['Data'][paramOffset:paramOffset+paramCount]
-            else:
-                transData['Trans_Parameters'] = ''
-
-            if transParameters['DataOffset'] > 0:
-                dataOffset = transParameters['DataOffset'] - 63 - 
transParameters['SetupLength']
-                transData['Trans_Data'] = 
SMBCommand['Data'][dataOffset:dataOffset + dataCount]
-            else:
-                transData['Trans_Data'] = ''
-
-            # Call the handler for this TRANSACTION
-            if transParameters['SetupCount'] == 0:
-                # No subcommand, let's play with the Name
-                command = 
decodeSMBString(recvPacket['Flags2'],transData['Name'])
-            else:
-                command = struct.unpack('<H', transParameters['Setup'][:2])[0]
-
-            if command in transCommands:
-               # Call the TRANS subcommand
-               setup = ''
-               parameters = ''
-               data = ''
-               try:
-                   setup, parameters, data, errorCode = 
transCommands[command](connId,
-                                smbServer,
-                                recvPacket,
-                                transData['Trans_Parameters'],
-                                transData['Trans_Data'],
-                                transParameters['MaxDataCount'])
-               except Exception as e:
-                   #print 'Transaction: %s' % e,e
-                   smbServer.log('Transaction: (%r,%s)' % (command, e), 
logging.ERROR)
-                   errorCode = STATUS_ACCESS_DENIED
-                   #raise
-
-               if setup == '' and parameters == '' and data == '':
-                   # Something wen't wrong
-                   respParameters = ''
-                   respData = ''
-               else:
-                   # Build the answer
-                   data = str(data)
-                   remainingData = len(data)
-                   parameters = str(parameters)
-                   remainingParameters = len(parameters)
-                   commands = []
-                   dataDisplacement = 0
-                   while remainingData > 0 or remainingParameters > 0:
-                       respSMBCommand = smb.SMBCommand(recvPacket['Command'])
-                       respParameters = smb.SMBTransactionResponse_Parameters()
-                       respData       = smb.SMBTransaction2Response_Data()
-
-                       respParameters['TotalParameterCount'] = len(parameters)
-                       respParameters['ParameterCount']      = len(parameters)
-                       respData['Trans_ParametersLength']    = len(parameters)
-                       respParameters['TotalDataCount']      = len(data)
-                       respParameters['DataDisplacement']    = dataDisplacement
-
-                       # TODO: Do the same for parameters
-                       if len(data) >  transParameters['MaxDataCount']:
-                           # Answer doesn't fit in this packet
-                           LOG.debug("Lowering answer from %d to %d" % 
(len(data),transParameters['MaxDataCount']) )
-                           respParameters['DataCount'] = 
transParameters['MaxDataCount']
-                       else:
-                           respParameters['DataCount'] = len(data)
-
-                       respData['Trans_DataLength']          = 
respParameters['DataCount']
-                       respParameters['SetupCount']          = len(setup)
-                       respParameters['Setup']               = setup
-                       # TODO: Make sure we're calculating the pad right
-                       if len(parameters) > 0:
-                           #padLen = 4 - (55 + len(setup)) % 4
-                           padLen = (4 - (55 + len(setup)) % 4 ) % 4
-                           padBytes = '\xFF' * padLen
-                           respData['Pad1'] = padBytes
-                           respParameters['ParameterOffset'] = 55 + len(setup) 
+ padLen
-                       else:
-                           padLen = 0
-                           respParameters['ParameterOffset'] = 0
-                           respData['Pad1']                  = ''
-
-                       if len(data) > 0:
-                           #pad2Len = 4 - (55 + len(setup) + padLen + 
len(parameters)) % 4
-                           pad2Len = (4 - (55 + len(setup) + padLen + 
len(parameters)) % 4) % 4
-                           respData['Pad2'] = '\xFF' * pad2Len
-                           respParameters['DataOffset'] = 55 + len(setup) + 
padLen + len(parameters) + pad2Len
-                       else:
-                           respParameters['DataOffset'] = 0
-                           respData['Pad2']             = ''
-
-                       respData['Trans_Parameters'] = 
parameters[:respParameters['ParameterCount']]
-                       respData['Trans_Data']       = 
data[:respParameters['DataCount']]
-                       respSMBCommand['Parameters'] = respParameters
-                       respSMBCommand['Data']       = respData
-
-                       data = data[respParameters['DataCount']:]
-                       remainingData -= respParameters['DataCount']
-                       dataDisplacement += respParameters['DataCount'] + 1
-
-                       parameters = 
parameters[respParameters['ParameterCount']:]
-                       remainingParameters -= respParameters['ParameterCount']
-                       commands.append(respSMBCommand)
-
-                   smbServer.setConnectionData(connId, connData)
-                   return commands, None, errorCode
-
-            else:
-               smbServer.log("Unsupported Transact command %r" % command, 
logging.ERROR)
-               respParameters = ''
-               respData = ''
-               errorCode = STATUS_NOT_IMPLEMENTED
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-
-    @staticmethod
-    def smbNTTransact(connId, smbServer, SMBCommand, recvPacket, 
transCommands):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb.SMBCommand(recvPacket['Command'])
-
-        NTTransParameters= 
smb.SMBNTTransaction_Parameters(SMBCommand['Parameters'])
-        # Do the stuff
-        if NTTransParameters['ParameterCount'] != 
NTTransParameters['TotalParameterCount']:
-            # TODO: Handle partial parameters
-            raise Exception("Unsupported partial parameters in NTTrans!")
-        else:
-            NTTransData = smb.SMBNTTransaction_Data()
-            # Standard says servers shouldn't trust Parameters and Data comes
-            # in order, so we have to parse the offsets, ugly
-
-            paramCount = NTTransParameters['ParameterCount']
-            NTTransData['NT_Trans_ParametersLength'] = paramCount
-            dataCount = NTTransParameters['DataCount']
-            NTTransData['NT_Trans_DataLength'] = dataCount
-
-            if NTTransParameters['ParameterOffset'] > 0:
-                paramOffset = NTTransParameters['ParameterOffset'] - 73 - 
NTTransParameters['SetupLength']
-                NTTransData['NT_Trans_Parameters'] = 
SMBCommand['Data'][paramOffset:paramOffset+paramCount]
-            else:
-                NTTransData['NT_Trans_Parameters'] = ''
-
-            if NTTransParameters['DataOffset'] > 0:
-                dataOffset = NTTransParameters['DataOffset'] - 73 - 
NTTransParameters['SetupLength']
-                NTTransData['NT_Trans_Data'] = 
SMBCommand['Data'][dataOffset:dataOffset + dataCount]
-            else:
-                NTTransData['NT_Trans_Data'] = ''
-
-            # Call the handler for this TRANSACTION
-            command = NTTransParameters['Function']
-            if command in transCommands:
-               # Call the NT TRANS subcommand
-               setup = ''
-               parameters = ''
-               data = ''
-               try:
-                   setup, parameters, data, errorCode = 
transCommands[command](connId,
-                                smbServer,
-                                recvPacket,
-                                NTTransData['NT_Trans_Parameters'],
-                                NTTransData['NT_Trans_Data'],
-                                NTTransParameters['MaxDataCount'])
-               except Exception as e:
-                   smbServer.log('NTTransaction: (0x%x,%s)' % (command, e), 
logging.ERROR)
-                   errorCode = STATUS_ACCESS_DENIED
-                   #raise
-
-               if setup == '' and parameters == '' and data == '':
-                   # Something wen't wrong
-                   respParameters = ''
-                   respData = ''
-                   if errorCode == STATUS_SUCCESS:
-                       errorCode = STATUS_ACCESS_DENIED
-               else:
-                   # Build the answer
-                   data = str(data)
-                   remainingData = len(data)
-                   parameters = str(parameters)
-                   remainingParameters = len(parameters)
-                   commands = []
-                   dataDisplacement = 0
-                   while remainingData > 0 or remainingParameters > 0:
-                       respSMBCommand = smb.SMBCommand(recvPacket['Command'])
-                       respParameters = 
smb.SMBNTTransactionResponse_Parameters()
-                       respData       = smb.SMBNTTransactionResponse_Data()
-
-                       respParameters['TotalParameterCount'] = len(parameters)
-                       respParameters['ParameterCount']      = len(parameters)
-                       respData['Trans_ParametersLength']    = len(parameters)
-                       respParameters['TotalDataCount']      = len(data)
-                       respParameters['DataDisplacement']    = dataDisplacement
-                       # TODO: Do the same for parameters
-                       if len(data) >  NTTransParameters['MaxDataCount']:
-                           # Answer doesn't fit in this packet
-                           LOG.debug("Lowering answer from %d to %d" % 
(len(data),NTTransParameters['MaxDataCount']) )
-                           respParameters['DataCount'] = 
NTTransParameters['MaxDataCount']
-                       else:
-                           respParameters['DataCount'] = len(data)
-
-                       respData['NT_Trans_DataLength']          = 
respParameters['DataCount']
-                       respParameters['SetupCount']          = len(setup)
-                       respParameters['Setup']               = setup
-                       # TODO: Make sure we're calculating the pad right
-                       if len(parameters) > 0:
-                           #padLen = 4 - (71 + len(setup)) % 4
-                           padLen = (4 - (73 + len(setup)) % 4 ) % 4
-                           padBytes = '\xFF' * padLen
-                           respData['Pad1'] = padBytes
-                           respParameters['ParameterOffset'] = 73 + len(setup) 
+ padLen
-                       else:
-                           padLen = 0
-                           respParameters['ParameterOffset'] = 0
-                           respData['Pad1']                  = ''
-
-                       if len(data) > 0:
-                           #pad2Len = 4 - (71 + len(setup) + padLen + 
len(parameters)) % 4
-                           pad2Len = (4 - (73 + len(setup) + padLen + 
len(parameters)) % 4) % 4
-                           respData['Pad2'] = '\xFF' * pad2Len
-                           respParameters['DataOffset'] = 73 + len(setup) + 
padLen + len(parameters) + pad2Len
-                       else:
-                           respParameters['DataOffset'] = 0
-                           respData['Pad2']             = ''
-
-                       respData['NT_Trans_Parameters'] = 
parameters[:respParameters['ParameterCount']]
-                       respData['NT_Trans_Data']       = 
data[:respParameters['DataCount']]
-                       respSMBCommand['Parameters'] = respParameters
-                       respSMBCommand['Data']       = respData
-
-                       data = data[respParameters['DataCount']:]
-                       remainingData -= respParameters['DataCount']
-                       dataDisplacement += respParameters['DataCount'] + 1
-
-                       parameters = 
parameters[respParameters['ParameterCount']:]
-                       remainingParameters -= respParameters['ParameterCount']
-                       commands.append(respSMBCommand)
-
-                   smbServer.setConnectionData(connId, connData)
-                   return commands, None, errorCode
-
-            else:
-               #smbServer.log("Unsupported NTTransact command 0x%x" % command, 
logging.ERROR)
-               respParameters = ''
-               respData = ''
-               errorCode = STATUS_NOT_IMPLEMENTED
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-
-    @staticmethod
-    def smbTransaction2(connId, smbServer, SMBCommand, recvPacket, 
transCommands):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb.SMBCommand(recvPacket['Command'])
-
-        trans2Parameters= 
smb.SMBTransaction2_Parameters(SMBCommand['Parameters'])
-
-        # Do the stuff
-        if trans2Parameters['ParameterCount'] != 
trans2Parameters['TotalParameterCount']:
-            # TODO: Handle partial parameters
-            #print "Unsupported partial parameters in TRANSACT2!"
-            raise Exception("Unsupported partial parameters in TRANSACT2!")
-        else:
-            trans2Data = smb.SMBTransaction2_Data()
-            # Standard says servers shouldn't trust Parameters and Data comes
-            # in order, so we have to parse the offsets, ugly
-
-            paramCount = trans2Parameters['ParameterCount']
-            trans2Data['Trans_ParametersLength'] = paramCount
-            dataCount = trans2Parameters['DataCount']
-            trans2Data['Trans_DataLength'] = dataCount
-
-            if trans2Parameters['ParameterOffset'] > 0:
-                paramOffset = trans2Parameters['ParameterOffset'] - 63 - 
trans2Parameters['SetupLength']
-                trans2Data['Trans_Parameters'] = 
SMBCommand['Data'][paramOffset:paramOffset+paramCount]
-            else:
-                trans2Data['Trans_Parameters'] = ''
-
-            if trans2Parameters['DataOffset'] > 0:
-                dataOffset = trans2Parameters['DataOffset'] - 63 - 
trans2Parameters['SetupLength']
-                trans2Data['Trans_Data'] = 
SMBCommand['Data'][dataOffset:dataOffset + dataCount]
-            else:
-                trans2Data['Trans_Data'] = ''
-
-            # Call the handler for this TRANSACTION
-            command = struct.unpack('<H', trans2Parameters['Setup'])[0]
-            if command in transCommands:
-               # Call the TRANS2 subcommand
-               try:
-                   setup, parameters, data, errorCode = 
transCommands[command](connId,
-                                smbServer,
-                                recvPacket,
-                                trans2Data['Trans_Parameters'],
-                                trans2Data['Trans_Data'],
-                                trans2Parameters['MaxDataCount'])
-               except Exception as e:
-                   smbServer.log('Transaction2: (0x%x,%s)' % (command, e), 
logging.ERROR)
-                   #import traceback
-                   #traceback.print_exc()
-                   raise
-
-               if setup == '' and parameters == '' and data == '':
-                   # Something wen't wrong
-                   respParameters = ''
-                   respData = ''
-               else:
-                   # Build the answer
-                   data = str(data)
-                   remainingData = len(data)
-                   parameters = str(parameters)
-                   remainingParameters = len(parameters)
-                   commands = []
-                   dataDisplacement = 0
-                   while remainingData > 0 or remainingParameters > 0:
-                       respSMBCommand = smb.SMBCommand(recvPacket['Command'])
-                       respParameters = 
smb.SMBTransaction2Response_Parameters()
-                       respData       = smb.SMBTransaction2Response_Data()
-
-                       respParameters['TotalParameterCount'] = len(parameters)
-                       respParameters['ParameterCount']      = len(parameters)
-                       respData['Trans_ParametersLength']    = len(parameters)
-                       respParameters['TotalDataCount']      = len(data)
-                       respParameters['DataDisplacement']    = dataDisplacement
-                       # TODO: Do the same for parameters
-                       if len(data) >  trans2Parameters['MaxDataCount']:
-                           # Answer doesn't fit in this packet
-                           LOG.debug("Lowering answer from %d to %d" % 
(len(data),trans2Parameters['MaxDataCount']) )
-                           respParameters['DataCount'] = 
trans2Parameters['MaxDataCount']
-                       else:
-                           respParameters['DataCount'] = len(data)
-
-                       respData['Trans_DataLength']          = 
respParameters['DataCount']
-                       respParameters['SetupCount']          = len(setup)
-                       respParameters['Setup']               = setup
-                       # TODO: Make sure we're calculating the pad right
-                       if len(parameters) > 0:
-                           #padLen = 4 - (55 + len(setup)) % 4
-                           padLen = (4 - (55 + len(setup)) % 4 ) % 4
-                           padBytes = '\xFF' * padLen
-                           respData['Pad1'] = padBytes
-                           respParameters['ParameterOffset'] = 55 + len(setup) 
+ padLen
-                       else:
-                           padLen = 0
-                           respParameters['ParameterOffset'] = 0
-                           respData['Pad1']                  = ''
-
-                       if len(data) > 0:
-                           #pad2Len = 4 - (55 + len(setup) + padLen + 
len(parameters)) % 4
-                           pad2Len = (4 - (55 + len(setup) + padLen + 
len(parameters)) % 4) % 4
-                           respData['Pad2'] = '\xFF' * pad2Len
-                           respParameters['DataOffset'] = 55 + len(setup) + 
padLen + len(parameters) + pad2Len
-                       else:
-                           respParameters['DataOffset'] = 0
-                           respData['Pad2']             = ''
-
-                       respData['Trans_Parameters'] = 
parameters[:respParameters['ParameterCount']]
-                       respData['Trans_Data']       = 
data[:respParameters['DataCount']]
-                       respSMBCommand['Parameters'] = respParameters
-                       respSMBCommand['Data']       = respData
-
-                       data = data[respParameters['DataCount']:]
-                       remainingData -= respParameters['DataCount']
-                       dataDisplacement += respParameters['DataCount'] + 1
-
-                       parameters = 
parameters[respParameters['ParameterCount']:]
-                       remainingParameters -= respParameters['ParameterCount']
-                       commands.append(respSMBCommand)
-
-                   smbServer.setConnectionData(connId, connData)
-                   return commands, None, errorCode
-
-            else:
-               smbServer.log("Unsupported Transact/2 command 0x%x" % command, 
logging.ERROR)
-               respParameters = ''
-               respData = ''
-               errorCode = STATUS_NOT_IMPLEMENTED
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComLockingAndX(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_LOCKING_ANDX)
-        respParameters        = ''
-        respData              = ''
-
-        # I'm actually doing nothing.. just make MacOS happy ;)
-        errorCode = STATUS_SUCCESS
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-
-    @staticmethod
-    def smbComClose(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_CLOSE)
-        respParameters        = ''
-        respData              = ''
-
-        comClose =  smb.SMBClose_Parameters(SMBCommand['Parameters'])
-
-        if comClose['FID'] in connData['OpenedFiles']:
-             errorCode = STATUS_SUCCESS
-             fileHandle = 
connData['OpenedFiles'][comClose['FID']]['FileHandle']
-             try:
-                 if fileHandle == PIPE_FILE_DESCRIPTOR:
-                     connData['OpenedFiles'][comClose['FID']]['Socket'].close()
-                 elif fileHandle != VOID_FILE_DESCRIPTOR:
-                     os.close(fileHandle)
-             except Exception as e:
-                 smbServer.log("comClose %s" % e, logging.ERROR)
-                 errorCode = STATUS_ACCESS_DENIED
-             else:
-                 # Check if the file was marked for removal
-                 if connData['OpenedFiles'][comClose['FID']]['DeleteOnClose'] 
is True:
-                     try:
-                         
os.remove(connData['OpenedFiles'][comClose['FID']]['FileName'])
-                     except Exception as e:
-                         smbServer.log("comClose %s" % e, logging.ERROR)
-                         errorCode = STATUS_ACCESS_DENIED
-                 del(connData['OpenedFiles'][comClose['FID']])
-        else:
-            errorCode = STATUS_INVALID_HANDLE
-
-        if errorCode > 0:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComWrite(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_WRITE)
-        respParameters        = smb.SMBWriteResponse_Parameters()
-        respData              = ''
-
-        comWriteParameters =  smb.SMBWrite_Parameters(SMBCommand['Parameters'])
-        comWriteData = smb.SMBWrite_Data(SMBCommand['Data'])
-
-        if comWriteParameters['Fid'] in connData['OpenedFiles']:
-             fileHandle = 
connData['OpenedFiles'][comWriteParameters['Fid']]['FileHandle']
-             errorCode = STATUS_SUCCESS
-             try:
-                 if fileHandle != PIPE_FILE_DESCRIPTOR:
-                     # TODO: Handle big size files
-                     # If we're trying to write past the file end we just skip 
the write call (Vista does this)
-                     if os.lseek(fileHandle, 0, 2) >= 
comWriteParameters['Offset']:
-                         os.lseek(fileHandle,comWriteParameters['Offset'],0)
-                         os.write(fileHandle,comWriteData['Data'])
-                 else:
-                     sock = 
connData['OpenedFiles'][comWriteParameters['Fid']]['Socket']
-                     sock.send(comWriteData['Data'])
-                 respParameters['Count']    = comWriteParameters['Count']
-             except Exception as e:
-                 smbServer.log('smbComWrite: %s' % e, logging.ERROR)
-                 errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_INVALID_HANDLE
-
-
-        if errorCode > 0:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComFlush(connId, smbServer, SMBCommand,recvPacket ):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_FLUSH)
-        respParameters        = ''
-        respData              = ''
-
-        comFlush =  smb.SMBFlush_Parameters(SMBCommand['Parameters'])
-
-        if comFlush['FID'] in connData['OpenedFiles']:
-             errorCode = STATUS_SUCCESS
-             fileHandle = 
connData['OpenedFiles'][comFlush['FID']]['FileHandle']
-             try:
-                 os.fsync(fileHandle)
-             except Exception as e:
-                 smbServer.log("comFlush %s" % e, logging.ERROR)
-                 errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_INVALID_HANDLE
-
-        if errorCode > 0:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-
-    @staticmethod
-    def smbComCreateDirectory(connId, smbServer, SMBCommand,recvPacket ):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = 
smb.SMBCommand(smb.SMB.SMB_COM_CREATE_DIRECTORY)
-        respParameters        = ''
-        respData              = ''
-
-        comCreateDirectoryData=  smb.SMBCreateDirectory_Data(flags = 
recvPacket['Flags2'], data = SMBCommand['Data'])
-
-        # Get the Tid associated
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-             errorCode = STATUS_SUCCESS
-             path = connData['ConnectedShares'][recvPacket['Tid']]['path']
-             fileName = 
os.path.normpath(decodeSMBString(recvPacket['Flags2'],comCreateDirectoryData['DirectoryName']).replace('\\','/'))
-             if len(fileName) > 0:
-                if fileName[0] == '/' or fileName[0] == '\\':
-                    # strip leading '/'
-                    fileName = fileName[1:]
-             pathName = os.path.join(path,fileName)
-             if os.path.exists(pathName):
-                errorCode = STATUS_OBJECT_NAME_COLLISION
-
-             # TODO: More checks here in the future.. Specially when we support
-             # user access
-             else:
-                 try:
-                     os.mkdir(pathName)
-                 except Exception as e:
-                     smbServer.log("smbComCreateDirectory: %s" % e, 
logging.ERROR)
-                     errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-
-        if errorCode > 0:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComRename(connId, smbServer, SMBCommand, recvPacket ):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_RENAME)
-        respParameters        = ''
-        respData              = ''
-
-        comRenameData      =  smb.SMBRename_Data(flags = recvPacket['Flags2'], 
data = SMBCommand['Data'])
-        # Get the Tid associated
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-             errorCode = STATUS_SUCCESS
-             path = connData['ConnectedShares'][recvPacket['Tid']]['path']
-             oldFileName = 
os.path.normpath(decodeSMBString(recvPacket['Flags2'],comRenameData['OldFileName']).replace('\\','/'))
-             newFileName = 
os.path.normpath(decodeSMBString(recvPacket['Flags2'],comRenameData['NewFileName']).replace('\\','/'))
-             if len(oldFileName) > 0 and (oldFileName[0] == '/' or 
oldFileName[0] == '\\'):
-                # strip leading '/'
-                oldFileName = oldFileName[1:]
-             oldPathName = os.path.join(path,oldFileName)
-             if len(newFileName) > 0 and (newFileName[0] == '/' or 
newFileName[0] == '\\'):
-                # strip leading '/'
-                newFileName = newFileName[1:]
-             newPathName = os.path.join(path,newFileName)
-
-             if os.path.exists(oldPathName) is not True:
-                errorCode = STATUS_NO_SUCH_FILE
-
-             # TODO: More checks here in the future.. Specially when we support
-             # user access
-             else:
-                 try:
-                     os.rename(oldPathName,newPathName)
-                 except OSError as e:
-                     smbServer.log("smbComRename: %s" % e, logging.ERROR)
-                     errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-
-        if errorCode > 0:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComDelete(connId, smbServer, SMBCommand, recvPacket ):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_DELETE)
-        respParameters        = ''
-        respData              = ''
-
-        comDeleteData         =  smb.SMBDelete_Data(flags = 
recvPacket['Flags2'], data = SMBCommand['Data'])
-
-        # Get the Tid associated
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-             errorCode = STATUS_SUCCESS
-             path = connData['ConnectedShares'][recvPacket['Tid']]['path']
-             fileName = 
os.path.normpath(decodeSMBString(recvPacket['Flags2'],comDeleteData['FileName']).replace('\\','/'))
-             if len(fileName) > 0 and (fileName[0] == '/' or fileName[0] == 
'\\'):
-                # strip leading '/'
-                fileName = fileName[1:]
-             pathName = os.path.join(path,fileName)
-             if os.path.exists(pathName) is not True:
-                errorCode = STATUS_NO_SUCH_FILE
-
-             # TODO: More checks here in the future.. Specially when we support
-             # user access
-             else:
-                 try:
-                     os.remove(pathName)
-                 except OSError as e:
-                     smbServer.log("smbComDelete: %s" % e, logging.ERROR)
-                     errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-        if errorCode > 0:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-
-    @staticmethod
-    def smbComDeleteDirectory(connId, smbServer, SMBCommand, recvPacket ):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = 
smb.SMBCommand(smb.SMB.SMB_COM_DELETE_DIRECTORY)
-        respParameters        = ''
-        respData              = ''
-
-        comDeleteDirectoryData=  smb.SMBDeleteDirectory_Data(flags = 
recvPacket['Flags2'], data = SMBCommand['Data'])
-
-        # Get the Tid associated
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-             errorCode = STATUS_SUCCESS
-             path = connData['ConnectedShares'][recvPacket['Tid']]['path']
-             fileName = 
os.path.normpath(decodeSMBString(recvPacket['Flags2'],comDeleteDirectoryData['DirectoryName']).replace('\\','/'))
-             if len(fileName) > 0 and (fileName[0] == '/' or fileName[0] == 
'\\'):
-                # strip leading '/'
-                fileName = fileName[1:]
-             pathName = os.path.join(path,fileName)
-             if os.path.exists(pathName) is not True:
-                errorCode = STATUS_NO_SUCH_FILE
-
-             # TODO: More checks here in the future.. Specially when we support
-             # user access
-             else:
-                 try:
-                     os.rmdir(pathName)
-                 except OSError as e:
-                     smbServer.log("smbComDeleteDirectory: %s" % 
e,logging.ERROR)
-                     if e.errno == errno.ENOTEMPTY:
-                         errorCode = STATUS_DIRECTORY_NOT_EMPTY
-                     else:
-                         errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-        if errorCode > 0:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-
-    @staticmethod
-    def smbComWriteAndX(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_WRITE_ANDX)
-        respParameters        = smb.SMBWriteAndXResponse_Parameters()
-        respData              = ''
-
-        if SMBCommand['WordCount'] == 0x0C:
-            writeAndX =  
smb.SMBWriteAndX_Parameters_Short(SMBCommand['Parameters'])
-            writeAndXData = smb.SMBWriteAndX_Data_Short()
-        else:
-            writeAndX =  smb.SMBWriteAndX_Parameters(SMBCommand['Parameters'])
-            writeAndXData = smb.SMBWriteAndX_Data()
-        writeAndXData['DataLength'] = writeAndX['DataLength']
-        writeAndXData['DataOffset'] = writeAndX['DataOffset']
-        writeAndXData.fromString(SMBCommand['Data'])
-
-
-        if writeAndX['Fid'] in connData['OpenedFiles']:
-             fileHandle = 
connData['OpenedFiles'][writeAndX['Fid']]['FileHandle']
-             errorCode = STATUS_SUCCESS
-             try:
-                 if fileHandle != PIPE_FILE_DESCRIPTOR:
-                     offset = writeAndX['Offset']
-                     if 'HighOffset' in writeAndX.fields:
-                         offset += (writeAndX['HighOffset'] << 32)
-                     # If we're trying to write past the file end we just skip 
the write call (Vista does this)
-                     if os.lseek(fileHandle, 0, 2) >= offset:
-                         os.lseek(fileHandle,offset,0)
-                         os.write(fileHandle,writeAndXData['Data'])
-                 else:
-                     sock = connData['OpenedFiles'][writeAndX['Fid']]['Socket']
-                     sock.send(writeAndXData['Data'])
-
-                 respParameters['Count']    = writeAndX['DataLength']
-                 respParameters['Available']= 0xff
-             except Exception as e:
-                 smbServer.log('smbComWriteAndx: %s' % e, logging.ERROR)
-                 errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_INVALID_HANDLE
-
-        if errorCode > 0:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComRead(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_READ)
-        respParameters        = smb.SMBReadResponse_Parameters()
-        respData              = smb.SMBReadResponse_Data()
-
-        comReadParameters =  smb.SMBRead_Parameters(SMBCommand['Parameters'])
-
-        if comReadParameters['Fid'] in connData['OpenedFiles']:
-             fileHandle = 
connData['OpenedFiles'][comReadParameters['Fid']]['FileHandle']
-             errorCode = STATUS_SUCCESS
-             try:
-                 if fileHandle != PIPE_FILE_DESCRIPTOR:
-                     # TODO: Handle big size files
-                     os.lseek(fileHandle,comReadParameters['Offset'],0)
-                     content = os.read(fileHandle,comReadParameters['Count'])
-                 else:
-                     sock = 
connData['OpenedFiles'][comReadParameters['Fid']]['Socket']
-                     content = sock.recv(comReadParameters['Count'])
-                 respParameters['Count']    = len(content)
-                 respData['DataLength']     = len(content)
-                 respData['Data']           = content
-             except Exception as e:
-                 smbServer.log('smbComRead: %s ' % e, logging.ERROR)
-                 errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_INVALID_HANDLE
-
-        if errorCode > 0:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComReadAndX(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_READ_ANDX)
-        respParameters        = smb.SMBReadAndXResponse_Parameters()
-        respData              = ''
-
-        if SMBCommand['WordCount'] == 0x0A:
-            readAndX =  smb.SMBReadAndX_Parameters2(SMBCommand['Parameters'])
-        else:
-            readAndX =  smb.SMBReadAndX_Parameters(SMBCommand['Parameters'])
-
-        if readAndX['Fid'] in connData['OpenedFiles']:
-             fileHandle = 
connData['OpenedFiles'][readAndX['Fid']]['FileHandle']
-             errorCode = 0
-             try:
-                 if fileHandle != PIPE_FILE_DESCRIPTOR:
-                     offset = readAndX['Offset']
-                     if 'HighOffset' in readAndX.fields:
-                         offset += (readAndX['HighOffset'] << 32)
-                     os.lseek(fileHandle,offset,0)
-                     content = os.read(fileHandle,readAndX['MaxCount'])
-                 else:
-                     sock = connData['OpenedFiles'][readAndX['Fid']]['Socket']
-                     content = sock.recv(readAndX['MaxCount'])
-                 respParameters['Remaining']    = 0xffff
-                 respParameters['DataCount']    = len(content)
-                 respParameters['DataOffset']   = 59
-                 respParameters['DataCount_Hi'] = 0
-                 respData = content
-             except Exception as e:
-                 smbServer.log('smbComReadAndX: %s ' % e, logging.ERROR)
-                 errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_INVALID_HANDLE
-
-        if errorCode > 0:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbQueryInformation(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_QUERY_INFORMATION)
-        respParameters = smb.SMBQueryInformationResponse_Parameters()
-        respData       = ''
-
-        queryInformation= smb.SMBQueryInformation_Data(flags = 
recvPacket['Flags2'], data = SMBCommand['Data'])
-
-        # Get the Tid associated
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-            fileSize, lastWriteTime, fileAttributes = queryFsInformation(
-                connData['ConnectedShares'][recvPacket['Tid']]['path'],
-                
decodeSMBString(recvPacket['Flags2'],queryInformation['FileName']))
-
-            respParameters['FileSize']       = fileSize
-            respParameters['LastWriteTime']  = lastWriteTime
-            respParameters['FileAttributes'] = fileAttributes
-            errorCode = STATUS_SUCCESS
-        else:
-            # STATUS_SMB_BAD_TID
-            errorCode = STATUS_SMB_BAD_TID
-            respParameters  = ''
-            respData        = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbQueryInformationDisk(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_QUERY_INFORMATION_DISK)
-        respParameters = smb.SMBQueryInformationDiskResponse_Parameters()
-        respData       = ''
-
-        # Get the Tid associated
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-            totalUnits, freeUnits = queryDiskInformation(
-                        connData['ConnectedShares'][recvPacket['Tid']]['path'])
-
-            respParameters['TotalUnits']    = totalUnits
-            respParameters['BlocksPerUnit'] = 1
-            respParameters['BlockSize']     = 1
-            respParameters['FreeUnits']     = freeUnits
-            errorCode = STATUS_SUCCESS
-        else:
-            # STATUS_SMB_BAD_TID
-            respData  = ''
-            respParameters = ''
-            errorCode = STATUS_SMB_BAD_TID
-
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComEcho(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_ECHO)
-        respParameters = smb.SMBEchoResponse_Parameters()
-        respData       = smb.SMBEchoResponse_Data()
-
-        echoData       = smb.SMBEcho_Data(SMBCommand['Data'])
-
-        respParameters['SequenceNumber'] = 1
-        respData['Data']                 = echoData['Data']
-
-        respSMBCommand['Parameters']     = respParameters
-        respSMBCommand['Data']           = respData
-
-        errorCode = STATUS_SUCCESS
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComTreeDisconnect(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_TREE_DISCONNECT)
-
-        # Check if the Tid matches the Tid trying to disconnect
-        respParameters = ''
-        respData = ''
-
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-            smbServer.log("Disconnecting Share(%d:%s)" % 
(recvPacket['Tid'],connData['ConnectedShares'][recvPacket['Tid']]['shareName']))
-            del(connData['ConnectedShares'][recvPacket['Tid']])
-            errorCode = STATUS_SUCCESS
-        else:
-            # STATUS_SMB_BAD_TID
-            errorCode = STATUS_SMB_BAD_TID
-
-        respSMBCommand['Parameters'] = respParameters
-        respSMBCommand['Data']       = respData
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComLogOffAndX(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_LOGOFF_ANDX)
-
-        # Check if the Uid matches the user trying to logoff
-        respParameters = ''
-        respData = ''
-        if recvPacket['Uid'] != connData['Uid']:
-            # STATUS_SMB_BAD_UID
-            errorCode = STATUS_SMB_BAD_UID
-        else:
-            errorCode = STATUS_SUCCESS
-
-        respSMBCommand['Parameters']   = respParameters
-        respSMBCommand['Data']         = respData
-        connData['Uid'] = 0
-
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComQueryInformation2(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = 
smb.SMBCommand(smb.SMB.SMB_COM_QUERY_INFORMATION2)
-        respParameters        = smb.SMBQueryInformation2Response_Parameters()
-        respData              = ''
-
-        queryInformation2 = 
smb.SMBQueryInformation2_Parameters(SMBCommand['Parameters'])
-        errorCode = 0xFF
-        if queryInformation2['Fid'] in connData['OpenedFiles']:
-             errorCode = STATUS_SUCCESS
-             pathName = 
connData['OpenedFiles'][queryInformation2['Fid']]['FileName']
-             try:
-                 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) 
= os.stat(pathName)
-                 respParameters['CreateDate']         = getSMBDate(ctime)
-                 respParameters['CreationTime']       = getSMBTime(ctime)
-                 respParameters['LastAccessDate']     = getSMBDate(atime)
-                 respParameters['LastAccessTime']     = getSMBTime(atime)
-                 respParameters['LastWriteDate']      = getSMBDate(mtime)
-                 respParameters['LastWriteTime']      = getSMBTime(mtime)
-                 respParameters['FileDataSize']       = size
-                 respParameters['FileAllocationSize'] = size
-                 attribs = 0
-                 if os.path.isdir(pathName):
-                     attribs = smb.SMB_FILE_ATTRIBUTE_DIRECTORY
-                 if os.path.isfile(pathName):
-                     attribs = smb.SMB_FILE_ATTRIBUTE_NORMAL
-                 respParameters['FileAttributes'] = attribs
-             except Exception as e:
-                 smbServer.log('smbComQueryInformation2 %s' % e,logging.ERROR)
-                 errorCode = STATUS_ACCESS_DENIED
-
-        if errorCode > 0:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComNtCreateAndX(connId, smbServer, SMBCommand, recvPacket):
-        # TODO: Fully implement this
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_NT_CREATE_ANDX)
-        respParameters        = smb.SMBNtCreateAndXResponse_Parameters()
-        respData              = ''
-
-        ntCreateAndXParameters = 
smb.SMBNtCreateAndX_Parameters(SMBCommand['Parameters'])
-        ntCreateAndXData       = smb.SMBNtCreateAndX_Data( flags = 
recvPacket['Flags2'], data = SMBCommand['Data'])
-
-        #if ntCreateAndXParameters['CreateFlags'] & 0x10:  # 
NT_CREATE_REQUEST_EXTENDED_RESPONSE
-        #    respParameters        = 
smb.SMBNtCreateAndXExtendedResponse_Parameters()
-        #    respParameters['VolumeGUID'] = '\x00'
-
-        # Get the Tid associated
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-             # If we have a rootFid, the path is relative to that fid
-             errorCode = STATUS_SUCCESS
-             if ntCreateAndXParameters['RootFid'] > 0:
-                 path = 
connData['OpenedFiles'][ntCreateAndXParameters['RootFid']]['FileName']
-                 LOG.debug("RootFid present %s!" % path)
-             else:
-                 if 'path' in connData['ConnectedShares'][recvPacket['Tid']]:
-                     path = 
connData['ConnectedShares'][recvPacket['Tid']]['path']
-                 else:
-                     path = 'NONE'
-                     errorCode = STATUS_ACCESS_DENIED
-
-             deleteOnClose = False
-
-             fileName = 
os.path.normpath(decodeSMBString(recvPacket['Flags2'],ntCreateAndXData['FileName']).replace('\\','/'))
-             if len(fileName) > 0 and (fileName[0] == '/' or fileName[0] == 
'\\'):
-                # strip leading '/'
-                fileName = fileName[1:]
-             pathName = os.path.join(path,fileName)
-             createDisposition = ntCreateAndXParameters['Disposition']
-             mode = 0
-
-             if createDisposition == smb.FILE_SUPERSEDE:
-                 mode |= os.O_TRUNC | os.O_CREAT
-             elif createDisposition & smb.FILE_OVERWRITE_IF == 
smb.FILE_OVERWRITE_IF:
-                 mode |= os.O_TRUNC | os.O_CREAT
-             elif createDisposition & smb.FILE_OVERWRITE == smb.FILE_OVERWRITE:
-                 if os.path.exists(pathName) is True:
-                     mode |= os.O_TRUNC
-                 else:
-                     errorCode = STATUS_NO_SUCH_FILE
-             elif createDisposition & smb.FILE_OPEN_IF == smb.FILE_OPEN_IF:
-                 if os.path.exists(pathName) is True:
-                     mode |= os.O_TRUNC
-                 else:
-                     mode |= os.O_TRUNC | os.O_CREAT
-             elif createDisposition & smb.FILE_CREATE == smb.FILE_CREATE:
-                 if os.path.exists(pathName) is True:
-                     errorCode = STATUS_OBJECT_NAME_COLLISION
-                 else:
-                     mode |= os.O_CREAT
-             elif createDisposition & smb.FILE_OPEN == smb.FILE_OPEN:
-                 if os.path.exists(pathName) is not True and 
(unicode(pathName) in smbServer.getRegisteredNamedPipes()) is not True:
-                     errorCode = STATUS_NO_SUCH_FILE
-
-             if errorCode == STATUS_SUCCESS:
-                 desiredAccess = ntCreateAndXParameters['AccessMask']
-                 if (desiredAccess & smb.FILE_READ_DATA) or (desiredAccess & 
smb.GENERIC_READ):
-                     mode |= os.O_RDONLY
-                 if (desiredAccess & smb.FILE_WRITE_DATA) or (desiredAccess & 
smb.GENERIC_WRITE):
-                     if (desiredAccess & smb.FILE_READ_DATA) or (desiredAccess 
& smb.GENERIC_READ):
-                         mode |= os.O_RDWR #| os.O_APPEND
-                     else:
-                         mode |= os.O_WRONLY #| os.O_APPEND
-                 if desiredAccess & smb.GENERIC_ALL:
-                     mode |= os.O_RDWR #| os.O_APPEND
-
-                 createOptions =  ntCreateAndXParameters['CreateOptions']
-                 if mode & os.O_CREAT == os.O_CREAT:
-                     if createOptions & smb.FILE_DIRECTORY_FILE == 
smb.FILE_DIRECTORY_FILE:
-                         try:
-                             # Let's create the directory
-                             os.mkdir(pathName)
-                             mode = os.O_RDONLY
-                         except Exception as e:
-                             smbServer.log("NTCreateAndX: %s,%s,%s" % 
(pathName,mode,e),logging.ERROR)
-                             errorCode = STATUS_ACCESS_DENIED
-                 if createOptions & smb.FILE_NON_DIRECTORY_FILE == 
smb.FILE_NON_DIRECTORY_FILE:
-                     # If the file being opened is a directory, the server 
MUST fail the request with
-                     # STATUS_FILE_IS_A_DIRECTORY in the Status field of the 
SMB Header in the server
-                     # response.
-                     if os.path.isdir(pathName) is True:
-                        errorCode = STATUS_FILE_IS_A_DIRECTORY
-
-                 if createOptions & smb.FILE_DELETE_ON_CLOSE == 
smb.FILE_DELETE_ON_CLOSE:
-                     deleteOnClose = True
-
-                 if errorCode == STATUS_SUCCESS:
-                     try:
-                         if os.path.isdir(pathName) and sys.platform == 
'win32':
-                            fid = VOID_FILE_DESCRIPTOR
-                         else:
-                            if sys.platform == 'win32':
-                               mode |= os.O_BINARY
-                            if unicode(pathName) in 
smbServer.getRegisteredNamedPipes():
-                                fid = PIPE_FILE_DESCRIPTOR
-                                sock = socket.socket()
-                                
sock.connect(smbServer.getRegisteredNamedPipes()[unicode(pathName)])
-                            else:
-                                fid = os.open(pathName, mode)
-                     except Exception as e:
-                         smbServer.log("NTCreateAndX: %s,%s,%s" % 
(pathName,mode,e),logging.ERROR)
-                         #print e
-                         fid = 0
-                         errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-        if errorCode == STATUS_SUCCESS:
-            # Simple way to generate a fid
-            if len(connData['OpenedFiles']) == 0:
-               fakefid = 1
-            else:
-               fakefid = connData['OpenedFiles'].keys()[-1] + 1
-            respParameters['Fid'] = fakefid
-            respParameters['CreateAction'] = createDisposition
-            if fid == PIPE_FILE_DESCRIPTOR:
-                respParameters['FileAttributes'] = 0x80
-                respParameters['IsDirectory'] = 0
-                respParameters['CreateTime']     = 0
-                respParameters['LastAccessTime'] = 0
-                respParameters['LastWriteTime']  = 0
-                respParameters['LastChangeTime'] = 0
-                respParameters['AllocationSize'] = 4096
-                respParameters['EndOfFile']      = 0
-                respParameters['FileType']       = 2
-                respParameters['IPCState']       = 0x5ff
-            else:
-                if os.path.isdir(pathName):
-                    respParameters['FileAttributes'] = 
smb.SMB_FILE_ATTRIBUTE_DIRECTORY
-                    respParameters['IsDirectory'] = 1
-                else:
-                    respParameters['IsDirectory'] = 0
-                    respParameters['FileAttributes'] = 
ntCreateAndXParameters['FileAttributes']
-                # Let's get this file's information
-                respInfo, errorCode = queryPathInformation('',pathName,level= 
smb.SMB_QUERY_FILE_ALL_INFO)
-                if errorCode == STATUS_SUCCESS:
-                    respParameters['CreateTime']     = respInfo['CreationTime']
-                    respParameters['LastAccessTime'] = 
respInfo['LastAccessTime']
-                    respParameters['LastWriteTime']  = 
respInfo['LastWriteTime']
-                    respParameters['LastChangeTime'] = 
respInfo['LastChangeTime']
-                    respParameters['FileAttributes'] = 
respInfo['ExtFileAttributes']
-                    respParameters['AllocationSize'] = 
respInfo['AllocationSize']
-                    respParameters['EndOfFile']      = respInfo['EndOfFile']
-                else:
-                    respParameters = ''
-                    respData       = ''
-
-            if errorCode == STATUS_SUCCESS:
-                # Let's store the fid for the connection
-                # smbServer.log('Create file %s, mode:0x%x' % (pathName, mode))
-                connData['OpenedFiles'][fakefid] = {}
-                connData['OpenedFiles'][fakefid]['FileHandle'] = fid
-                connData['OpenedFiles'][fakefid]['FileName'] = pathName
-                connData['OpenedFiles'][fakefid]['DeleteOnClose']  = 
deleteOnClose
-                if fid == PIPE_FILE_DESCRIPTOR:
-                    connData['OpenedFiles'][fakefid]['Socket'] = sock
-        else:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComOpenAndX(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb.SMBCommand(smb.SMB.SMB_COM_OPEN_ANDX)
-        respParameters        = smb.SMBOpenAndXResponse_Parameters()
-        respData              = ''
-
-        openAndXParameters = 
smb.SMBOpenAndX_Parameters(SMBCommand['Parameters'])
-        openAndXData       = smb.SMBOpenAndX_Data( flags = 
recvPacket['Flags2'], data = SMBCommand['Data'])
-
-        # Get the Tid associated
-        if recvPacket['Tid'] in connData['ConnectedShares']:
-             path = connData['ConnectedShares'][recvPacket['Tid']]['path']
-             openedFile, mode, pathName, errorCode = openFile(path,
-                     
decodeSMBString(recvPacket['Flags2'],openAndXData['FileName']),
-                     openAndXParameters['DesiredAccess'],
-                     openAndXParameters['FileAttributes'],
-                     openAndXParameters['OpenMode'])
-        else:
-           errorCode = STATUS_SMB_BAD_TID
-
-        if errorCode == STATUS_SUCCESS:
-            # Simple way to generate a fid
-            fid = len(connData['OpenedFiles']) + 1
-            if len(connData['OpenedFiles']) == 0:
-               fid = 1
-            else:
-               fid = connData['OpenedFiles'].keys()[-1] + 1
-            respParameters['Fid'] = fid
-            if mode & os.O_CREAT:
-                # File did not exist and was created
-                respParameters['Action'] = 0x2
-            elif mode & os.O_RDONLY:
-                # File existed and was opened
-                respParameters['Action'] = 0x1
-            elif mode & os.O_APPEND:
-                # File existed and was opened
-                respParameters['Action'] = 0x1
-            else:
-                # File existed and was truncated
-                respParameters['Action'] = 0x3
-
-            # Let's store the fid for the connection
-            #smbServer.log('Opening file %s' % pathName)
-            connData['OpenedFiles'][fid] = {}
-            connData['OpenedFiles'][fid]['FileHandle'] = openedFile
-            connData['OpenedFiles'][fid]['FileName'] = pathName
-            connData['OpenedFiles'][fid]['DeleteOnClose']  = False
-        else:
-            respParameters = ''
-            respData       = ''
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComTreeConnectAndX(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        resp = smb.NewSMBPacket()
-        resp['Flags1'] = smb.SMB.FLAGS1_REPLY
-        resp['Flags2'] = smb.SMB.FLAGS2_EXTENDED_SECURITY | 
smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_LONG_NAMES | recvPacket['Flags2'] & 
smb.SMB.FLAGS2_UNICODE
-
-        resp['Tid'] = recvPacket['Tid']
-        resp['Mid'] = recvPacket['Mid']
-        resp['Pid'] = connData['Pid']
-
-        respSMBCommand        = 
smb.SMBCommand(smb.SMB.SMB_COM_TREE_CONNECT_ANDX)
-        respParameters        = smb.SMBTreeConnectAndXResponse_Parameters()
-        respData              = smb.SMBTreeConnectAndXResponse_Data()
-
-        treeConnectAndXParameters = 
smb.SMBTreeConnectAndX_Parameters(SMBCommand['Parameters'])
-
-        if treeConnectAndXParameters['Flags'] & 0x8:
-            respParameters        = 
smb.SMBTreeConnectAndXExtendedResponse_Parameters()
-
-        treeConnectAndXData                    = smb.SMBTreeConnectAndX_Data( 
flags = recvPacket['Flags2'] )
-        treeConnectAndXData['_PasswordLength'] = 
treeConnectAndXParameters['PasswordLength']
-        treeConnectAndXData.fromString(SMBCommand['Data'])
-
-        errorCode = STATUS_SUCCESS
-
-        ## Process here the request, does the share exist?
-        UNCOrShare = decodeSMBString(recvPacket['Flags2'], 
treeConnectAndXData['Path'])
-
-        # Is this a UNC?
-        if ntpath.ismount(UNCOrShare):
-            path = UNCOrShare.split('\\')[3]
-        else:
-            path = ntpath.basename(UNCOrShare)
-
-        share = searchShare(connId, path, smbServer)
-        if share is not None:
-            # Simple way to generate a Tid
-            if len(connData['ConnectedShares']) == 0:
-               tid = 1
-            else:
-               tid = connData['ConnectedShares'].keys()[-1] + 1
-            connData['ConnectedShares'][tid] = share
-            connData['ConnectedShares'][tid]['shareName'] = path
-            resp['Tid'] = tid
-            #smbServer.log("Connecting Share(%d:%s)" % (tid,path))
-        else:
-            smbServer.log("TreeConnectAndX not found %s" % path, logging.ERROR)
-            errorCode = STATUS_OBJECT_PATH_NOT_FOUND
-            resp['ErrorCode']   = errorCode >> 16
-            resp['ErrorClass']  = errorCode & 0xff
-        ##
-        respParameters['OptionalSupport'] = smb.SMB.SMB_SUPPORT_SEARCH_BITS
-
-        if path == 'IPC$':
-            respData['Service']               = 'IPC'
-        else:
-            respData['Service']               = path
-        respData['PadLen']                = 0
-        respData['NativeFileSystem']      = 
encodeSMBString(recvPacket['Flags2'], 'NTFS' )
-
-        respSMBCommand['Parameters']             = respParameters
-        respSMBCommand['Data']                   = respData
-
-        resp['Uid'] = connData['Uid']
-        resp.addCommand(respSMBCommand)
-        smbServer.setConnectionData(connId, connData)
-
-        return None, [resp], errorCode
-
-    @staticmethod
-    def smbComSessionSetupAndX(connId, smbServer, SMBCommand, recvPacket):
-        connData = smbServer.getConnectionData(connId, checkStatus = False)
-
-        respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
-
-        # From [MS-SMB]
-        # When extended security is being used (see section 3.2.4.2.4), the
-        # request MUST take the following form
-        # [..]
-        # WordCount (1 byte): The value of this field MUST be 0x0C.
-        if SMBCommand['WordCount'] == 12:
-            # Extended security. Here we deal with all SPNEGO stuff
-            respParameters = 
smb.SMBSessionSetupAndX_Extended_Response_Parameters()
-            respData       = 
smb.SMBSessionSetupAndX_Extended_Response_Data(flags = recvPacket['Flags2'])
-            sessionSetupParameters = 
smb.SMBSessionSetupAndX_Extended_Parameters(SMBCommand['Parameters'])
-            sessionSetupData = smb.SMBSessionSetupAndX_Extended_Data()
-            sessionSetupData['SecurityBlobLength'] = 
sessionSetupParameters['SecurityBlobLength']
-            sessionSetupData.fromString(SMBCommand['Data'])
-            connData['Capabilities'] = sessionSetupParameters['Capabilities']
-
-            rawNTLM = False
-            if struct.unpack('B',sessionSetupData['SecurityBlob'][0])[0] == 
ASN1_AID:
-               # NEGOTIATE packet
-               blob =  SPNEGO_NegTokenInit(sessionSetupData['SecurityBlob'])
-               token = blob['MechToken']
-               if len(blob['MechTypes'][0]) > 0:
-                   # Is this GSSAPI NTLM or something else we don't support?
-                   mechType = blob['MechTypes'][0]
-                   if mechType != TypesMech['NTLMSSP - Microsoft NTLM Security 
Support Provider']:
-                       # Nope, do we know it?
-                       if mechType in MechTypes:
-                           mechStr = MechTypes[mechType]
-                       else:
-                           mechStr = hexlify(mechType)
-                       smbServer.log("Unsupported MechType '%s'" % mechStr, 
logging.CRITICAL)
-                       # We don't know the token, we answer back again saying
-                       # we just support NTLM.
-                       # ToDo: Build this into a SPNEGO_NegTokenResp()
-                       respToken = 
'\xa1\x15\x30\x13\xa0\x03\x0a\x01\x03\xa1\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a'
-                       respParameters['SecurityBlobLength'] = len(respToken)
-                       respData['SecurityBlobLength'] = 
respParameters['SecurityBlobLength']
-                       respData['SecurityBlob']       = respToken
-                       respData['NativeOS']     = 
encodeSMBString(recvPacket['Flags2'], smbServer.getServerOS())
-                       respData['NativeLanMan'] = 
encodeSMBString(recvPacket['Flags2'], smbServer.getServerOS())
-                       respSMBCommand['Parameters'] = respParameters
-                       respSMBCommand['Data']       = respData
-                       return [respSMBCommand], None, 
STATUS_MORE_PROCESSING_REQUIRED
-
-            elif struct.unpack('B',sessionSetupData['SecurityBlob'][0])[0] == 
ASN1_SUPPORTED_MECH:
-               # AUTH packet
-               blob = SPNEGO_NegTokenResp(sessionSetupData['SecurityBlob'])
-               token = blob['ResponseToken']
-            else:
-               # No GSSAPI stuff, raw NTLMSSP
-               rawNTLM = True
-               token = sessionSetupData['SecurityBlob']
-
-            # Here we only handle NTLMSSP, depending on what stage of the
-            # authentication we are, we act on it
-            messageType = 
struct.unpack('<L',token[len('NTLMSSP\x00'):len('NTLMSSP\x00')+4])[0]
-
-            if messageType == 0x01:
-                # NEGOTIATE_MESSAGE
-                negotiateMessage = ntlm.NTLMAuthNegotiate()
-                negotiateMessage.fromString(token)
-                # Let's store it in the connection data
-                connData['NEGOTIATE_MESSAGE'] = negotiateMessage
-                # Let's build the answer flags
-                # TODO: Parse all the flags. With this we're leaving some 
clients out
-
-                ansFlags = 0
-
-                if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_56:
-                   ansFlags |= ntlm.NTLMSSP_NEGOTIATE_56
-                if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_128:
-                   ansFlags |= ntlm.NTLMSSP_NEGOTIATE_128
-                if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_KEY_EXCH:
-                   ansFlags |= ntlm.NTLMSSP_NEGOTIATE_KEY_EXCH
-                if negotiateMessage['flags'] & 
ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
-                   ansFlags |= ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
-                if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_UNICODE:
-                   ansFlags |= ntlm.NTLMSSP_NEGOTIATE_UNICODE
-                if negotiateMessage['flags'] & ntlm.NTLM_NEGOTIATE_OEM:
-                   ansFlags |= ntlm.NTLM_NEGOTIATE_OEM
-
-                ansFlags |= ntlm.NTLMSSP_NEGOTIATE_VERSION | 
ntlm.NTLMSSP_NEGOTIATE_TARGET_INFO | ntlm.NTLMSSP_TARGET_TYPE_SERVER | 
ntlm.NTLMSSP_NEGOTIATE_NTLM | ntlm.NTLMSSP_REQUEST_TARGET
-
-                # Generate the AV_PAIRS
-                av_pairs = ntlm.AV_PAIRS()
-                # TODO: Put the proper data from SMBSERVER config
-                av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] = 
av_pairs[ntlm.NTLMSSP_AV_DNS_HOSTNAME] = 
smbServer.getServerName().encode('utf-16le')
-                av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME] = 
av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME] = 
smbServer.getServerDomain().encode('utf-16le')
-                av_pairs[ntlm.NTLMSSP_AV_TIME] = struct.pack('<q', 
(116444736000000000 + calendar.timegm(time.gmtime()) * 10000000) )
-
-                challengeMessage = ntlm.NTLMAuthChallenge()
-                challengeMessage['flags']            = ansFlags
-                challengeMessage['domain_len']       = 
len(smbServer.getServerDomain().encode('utf-16le'))
-                challengeMessage['domain_max_len']   = 
challengeMessage['domain_len']
-                challengeMessage['domain_offset']    = 40 + 16
-                challengeMessage['challenge']        = 
smbServer.getSMBChallenge()
-                challengeMessage['domain_name']      = 
smbServer.getServerDomain().encode('utf-16le')
-                challengeMessage['TargetInfoFields_len']     = len(av_pairs)
-                challengeMessage['TargetInfoFields_max_len'] = len(av_pairs)
-                challengeMessage['TargetInfoFields'] = av_pairs
-                challengeMessage['TargetInfoFields_offset']  = 40 + 16 + 
len(challengeMessage['domain_name'])
-                challengeMessage['Version']          = '\xff'*8
-                challengeMessage['VersionLen']       = 8
-
-                if rawNTLM is False:
-                    respToken = SPNEGO_NegTokenResp()
-                    # accept-incomplete. We want more data
-                    respToken['NegResult'] = '\x01'
-                    respToken['SupportedMech'] = TypesMech['NTLMSSP - 
Microsoft NTLM Security Support Provider']
-
-                    respToken['ResponseToken'] = challengeMessage.getData()
-                else:
-                    respToken = challengeMessage
-
-                # Setting the packet to STATUS_MORE_PROCESSING
-                errorCode = STATUS_MORE_PROCESSING_REQUIRED
-                # Let's set up an UID for this connection and store it
-                # in the connection's data
-                # Picking a fixed value
-                # TODO: Manage more UIDs for the same session
-                connData['Uid'] = 10
-                # Let's store it in the connection data
-                connData['CHALLENGE_MESSAGE'] = challengeMessage
-
-            elif messageType == 0x02:
-                # CHALLENGE_MESSAGE
-                raise Exception('Challenge Message raise, not implemented!')
-            elif messageType == 0x03:
-                # AUTHENTICATE_MESSAGE, here we deal with authentication
-                authenticateMessage = ntlm.NTLMAuthChallengeResponse()
-                authenticateMessage.fromString(token)
-                smbServer.log("AUTHENTICATE_MESSAGE (%s\\%s,%s)" % 
(authenticateMessage['domain_name'], authenticateMessage['user_name'], 
authenticateMessage['host_name']))
-                # TODO: Check the credentials! Now granting permissions
-
-                respToken = SPNEGO_NegTokenResp()
-                # accept-completed
-                respToken['NegResult'] = '\x00'
-
-                # Status SUCCESS
-                errorCode = STATUS_SUCCESS
-                smbServer.log('User %s\\%s authenticated successfully' % 
(authenticateMessage['user_name'], authenticateMessage['host_name']))
-                # Let's store it in the connection data
-                connData['AUTHENTICATE_MESSAGE'] = authenticateMessage
-                try:
-                    jtr_dump_path = smbServer.getJTRdumpPath()
-                    ntlm_hash_data = outputToJohnFormat( 
connData['CHALLENGE_MESSAGE']['challenge'], authenticateMessage['user_name'], 
authenticateMessage['domain_name'], authenticateMessage['lanman'], 
authenticateMessage['ntlm'] )
-                    smbServer.log(ntlm_hash_data['hash_string'])
-                    if jtr_dump_path is not '':
-                        writeJohnOutputToFile(ntlm_hash_data['hash_string'], 
ntlm_hash_data['hash_version'], jtr_dump_path)
-                except:
-                    smbServer.log("Could not write NTLM Hashes to the 
specified JTR_Dump_Path %s" % jtr_dump_path)
-            else:
-                raise Exception("Unknown NTLMSSP MessageType %d" % messageType)
-
-            respParameters['SecurityBlobLength'] = len(respToken)
-            respData['SecurityBlobLength'] = 
respParameters['SecurityBlobLength']
-            respData['SecurityBlob']       = respToken.getData()
-
-        else:
-            # Process Standard Security
-            respParameters = smb.SMBSessionSetupAndXResponse_Parameters()
-            respData       = smb.SMBSessionSetupAndXResponse_Data()
-            sessionSetupParameters = 
smb.SMBSessionSetupAndX_Parameters(SMBCommand['Parameters'])
-            sessionSetupData = smb.SMBSessionSetupAndX_Data()
-            sessionSetupData['AnsiPwdLength'] = 
sessionSetupParameters['AnsiPwdLength']
-            sessionSetupData['UnicodePwdLength'] = 
sessionSetupParameters['UnicodePwdLength']
-            sessionSetupData.fromString(SMBCommand['Data'])
-            connData['Capabilities'] = sessionSetupParameters['Capabilities']
-            # Do the verification here, for just now we grant access
-            # TODO: Manage more UIDs for the same session
-            errorCode = STATUS_SUCCESS
-            connData['Uid'] = 10
-            respParameters['Action'] = 0
-            smbServer.log('User %s\\%s authenticated successfully (basic)' % 
(sessionSetupData['PrimaryDomain'], sessionSetupData['Account']))
-            try:
-                jtr_dump_path = smbServer.getJTRdumpPath()
-                ntlm_hash_data = outputToJohnFormat( '', 
sessionSetupData['Account'], sessionSetupData['PrimaryDomain'], 
sessionSetupData['AnsiPwd'], sessionSetupData['UnicodePwd'] )
-                smbServer.log(ntlm_hash_data['hash_string'])
-                if jtr_dump_path is not '':
-                    writeJohnOutputToFile(ntlm_hash_data['hash_string'], 
ntlm_hash_data['hash_version'], jtr_dump_path)
-            except:
-                smbServer.log("Could not write NTLM Hashes to the specified 
JTR_Dump_Path %s" % jtr_dump_path)
-
-        respData['NativeOS']     = encodeSMBString(recvPacket['Flags2'], 
smbServer.getServerOS())
-        respData['NativeLanMan'] = encodeSMBString(recvPacket['Flags2'], 
smbServer.getServerOS())
-        respSMBCommand['Parameters'] = respParameters
-        respSMBCommand['Data']       = respData
-
-        # From now on, the client can ask for other commands
-        connData['Authenticated'] = True
-        # For now, just switching to nobody
-        #os.setregid(65534,65534)
-        #os.setreuid(65534,65534)
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smbComNegotiate(connId, smbServer, SMBCommand, recvPacket ):
-        connData = smbServer.getConnectionData(connId, checkStatus = False)
-        connData['Pid'] = recvPacket['Pid']
-
-        SMBCommand = smb.SMBCommand(recvPacket['Data'][0])
-        respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_NEGOTIATE)
-
-        resp = smb.NewSMBPacket()
-        resp['Flags1'] = smb.SMB.FLAGS1_REPLY
-        resp['Pid'] = connData['Pid']
-        resp['Tid'] = recvPacket['Tid']
-        resp['Mid'] = recvPacket['Mid']
-
-        # TODO: We support more dialects, and parse them accordingly
-        dialects = SMBCommand['Data'].split('\x02')
-        try:
-           index = dialects.index('NT LM 0.12\x00') - 1
-           # Let's fill the data for NTLM
-           if recvPacket['Flags2'] & smb.SMB.FLAGS2_EXTENDED_SECURITY:
-                    resp['Flags2'] = smb.SMB.FLAGS2_EXTENDED_SECURITY | 
smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_UNICODE
-                    #resp['Flags2'] = smb.SMB.FLAGS2_EXTENDED_SECURITY | 
smb.SMB.FLAGS2_NT_STATUS
-                    _dialects_data = smb.SMBExtended_Security_Data()
-                    _dialects_data['ServerGUID'] = 'A'*16
-                    blob = SPNEGO_NegTokenInit()
-                    blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM 
Security Support Provider']]
-                    _dialects_data['SecurityBlob'] = blob.getData()
-
-                    _dialects_parameters = 
smb.SMBExtended_Security_Parameters()
-                    _dialects_parameters['Capabilities']    = 
smb.SMB.CAP_EXTENDED_SECURITY | smb.SMB.CAP_USE_NT_ERRORS | smb.SMB.CAP_NT_SMBS 
| smb.SMB.CAP_UNICODE
-                    _dialects_parameters['ChallengeLength'] = 0
-
-           else:
-                    resp['Flags2'] = smb.SMB.FLAGS2_NT_STATUS | 
smb.SMB.FLAGS2_UNICODE
-                    _dialects_parameters = smb.SMBNTLMDialect_Parameters()
-                    _dialects_data= smb.SMBNTLMDialect_Data()
-                    _dialects_data['Payload'] = ''
-                    if 'EncryptionKey' in connData:
-                        _dialects_data['Challenge'] = connData['EncryptionKey']
-                        _dialects_parameters['ChallengeLength'] = 
len(str(_dialects_data))
-                    else:
-                        # TODO: Handle random challenges, now one that can be 
used with rainbow tables
-                        _dialects_data['Challenge'] = 
'\x11\x22\x33\x44\x55\x66\x77\x88'
-                        _dialects_parameters['ChallengeLength'] = 8
-                    _dialects_parameters['Capabilities']    = 
smb.SMB.CAP_USE_NT_ERRORS | smb.SMB.CAP_NT_SMBS
-
-           # Let's see if we need to support RPC_REMOTE_APIS
-           config = smbServer.getServerConfig()
-           if config.has_option('global','rpc_apis'):
-               if config.getboolean('global', 'rpc_apis') is True:
-                  _dialects_parameters['Capabilities'] |= 
smb.SMB.CAP_RPC_REMOTE_APIS
-
-           _dialects_parameters['DialectIndex']    = index
-           _dialects_parameters['SecurityMode']    = 
smb.SMB.SECURITY_AUTH_ENCRYPTED | smb.SMB.SECURITY_SHARE_USER
-           _dialects_parameters['MaxMpxCount']     = 1
-           _dialects_parameters['MaxNumberVcs']    = 1
-           _dialects_parameters['MaxBufferSize']   = 64000
-           _dialects_parameters['MaxRawSize']      = 65536
-           _dialects_parameters['SessionKey']      = 0
-           _dialects_parameters['LowDateTime']     = 0
-           _dialects_parameters['HighDateTime']    = 0
-           _dialects_parameters['ServerTimeZone']  = 0
-
-
-           respSMBCommand['Data']           = _dialects_data
-           respSMBCommand['Parameters']     = _dialects_parameters
-           connData['_dialects_data']       = _dialects_data
-           connData['_dialects_parameters'] = _dialects_parameters
-
-        except Exception as e:
-           # No NTLM throw an error
-           smbServer.log('smbComNegotiate: %s' % e, logging.ERROR)
-           respSMBCommand['Data'] = struct.pack('<H',0xffff)
-
-
-        smbServer.setConnectionData(connId, connData)
-
-        resp.addCommand(respSMBCommand)
-
-        return None, [resp], STATUS_SUCCESS
-
-    @staticmethod
-    def default(connId, smbServer, SMBCommand, recvPacket):
-        # By default we return an SMB Packet with error not implemented
-        smbServer.log("Not implemented command: 0x%x" % 
recvPacket['Command'],logging.DEBUG)
-        packet = smb.NewSMBPacket()
-        packet['Flags1']  = smb.SMB.FLAGS1_REPLY
-        packet['Flags2']  = smb.SMB.FLAGS2_NT_STATUS
-        packet['Command'] = recvPacket['Command']
-        packet['Pid']     = recvPacket['Pid']
-        packet['Tid']     = recvPacket['Tid']
-        packet['Mid']     = recvPacket['Mid']
-        packet['Uid']     = recvPacket['Uid']
-        packet['Data']    = '\x00\x00\x00'
-        errorCode = STATUS_NOT_IMPLEMENTED
-        packet['ErrorCode']   = errorCode >> 16
-        packet['ErrorClass']  = errorCode & 0xff
-
-        return None, [packet], errorCode
-
-class SMB2Commands:
-    @staticmethod
-    def smb2Negotiate(connId, smbServer, recvPacket, isSMB1 = False):
-        connData = smbServer.getConnectionData(connId, checkStatus = False)
-
-        respPacket = smb2.SMB2Packet()
-        respPacket['Flags']     = smb2.SMB2_FLAGS_SERVER_TO_REDIR
-        respPacket['Status']    = STATUS_SUCCESS
-        respPacket['CreditRequestResponse'] = 1
-        respPacket['Command']   = smb2.SMB2_NEGOTIATE
-        respPacket['SessionID'] = 0
-        if isSMB1 is False:
-            respPacket['MessageID'] = recvPacket['MessageID']
-        else:
-            respPacket['MessageID'] = 0
-        respPacket['TreeID']    = 0
-
-
-        respSMBCommand = smb2.SMB2Negotiate_Response()
-
-        respSMBCommand['SecurityMode'] = 1
-        if isSMB1 is True:
-            # Let's first parse the packet to see if the client supports SMB2
-            SMBCommand = smb.SMBCommand(recvPacket['Data'][0])
-
-            dialects = SMBCommand['Data'].split('\x02')
-            if 'SMB 2.002\x00' in dialects or 'SMB 2.???\x00' in dialects:
-                respSMBCommand['DialectRevision'] = smb2.SMB2_DIALECT_002
-            else:
-                # Client does not support SMB2 fallbacking
-                raise Exception('SMB2 not supported, fallbacking')
-        else:
-            respSMBCommand['DialectRevision'] = smb2.SMB2_DIALECT_002
-        respSMBCommand['ServerGuid'] = 'A'*16
-        respSMBCommand['Capabilities'] = 0
-        respSMBCommand['MaxTransactSize'] = 65536
-        respSMBCommand['MaxReadSize'] = 65536
-        respSMBCommand['MaxWriteSize'] = 65536
-        respSMBCommand['SystemTime'] = 
getFileTime(calendar.timegm(time.gmtime()))
-        respSMBCommand['ServerStartTime'] = 
getFileTime(calendar.timegm(time.gmtime()))
-        respSMBCommand['SecurityBufferOffset'] = 0x80
-
-        blob = SPNEGO_NegTokenInit()
-        blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security 
Support Provider']]
-
-        respSMBCommand['Buffer'] = blob.getData()
-        respSMBCommand['SecurityBufferLength'] = len(respSMBCommand['Buffer'])
-
-        respPacket['Data']      = respSMBCommand
-
-        smbServer.setConnectionData(connId, connData)
-
-        return None, [respPacket], STATUS_SUCCESS
-
-    @staticmethod
-    def smb2SessionSetup(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId, checkStatus = False)
-
-        respSMBCommand = smb2.SMB2SessionSetup_Response()
-
-        sessionSetupData = smb2.SMB2SessionSetup(recvPacket['Data'])
-
-        connData['Capabilities'] = sessionSetupData['Capabilities']
-
-        securityBlob = sessionSetupData['Buffer']
-
-        rawNTLM = False
-        if struct.unpack('B',securityBlob[0])[0] == ASN1_AID:
-           # NEGOTIATE packet
-           blob =  SPNEGO_NegTokenInit(securityBlob)
-           token = blob['MechToken']
-           if len(blob['MechTypes'][0]) > 0:
-               # Is this GSSAPI NTLM or something else we don't support?
-               mechType = blob['MechTypes'][0]
-               if mechType != TypesMech['NTLMSSP - Microsoft NTLM Security 
Support Provider']:
-                   # Nope, do we know it?
-                   if mechType in MechTypes:
-                       mechStr = MechTypes[mechType]
-                   else:
-                       mechStr = hexlify(mechType)
-                   smbServer.log("Unsupported MechType '%s'" % mechStr, 
logging.CRITICAL)
-                   # We don't know the token, we answer back again saying
-                   # we just support NTLM.
-                   # ToDo: Build this into a SPNEGO_NegTokenResp()
-                   respToken = 
'\xa1\x15\x30\x13\xa0\x03\x0a\x01\x03\xa1\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a'
-                   respSMBCommand['SecurityBufferOffset'] = 0x48
-                   respSMBCommand['SecurityBufferLength'] = len(respToken)
-                   respSMBCommand['Buffer'] = respToken
-
-                   return [respSMBCommand], None, 
STATUS_MORE_PROCESSING_REQUIRED
-        elif struct.unpack('B',securityBlob[0])[0] == ASN1_SUPPORTED_MECH:
-           # AUTH packet
-           blob = SPNEGO_NegTokenResp(securityBlob)
-           token = blob['ResponseToken']
-        else:
-           # No GSSAPI stuff, raw NTLMSSP
-           rawNTLM = True
-           token = securityBlob
-
-        # Here we only handle NTLMSSP, depending on what stage of the
-        # authentication we are, we act on it
-        messageType = 
struct.unpack('<L',token[len('NTLMSSP\x00'):len('NTLMSSP\x00')+4])[0]
-
-        if messageType == 0x01:
-            # NEGOTIATE_MESSAGE
-            negotiateMessage = ntlm.NTLMAuthNegotiate()
-            negotiateMessage.fromString(token)
-            # Let's store it in the connection data
-            connData['NEGOTIATE_MESSAGE'] = negotiateMessage
-            # Let's build the answer flags
-            # TODO: Parse all the flags. With this we're leaving some clients 
out
-
-            ansFlags = 0
-
-            if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_56:
-               ansFlags |= ntlm.NTLMSSP_NEGOTIATE_56
-            if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_128:
-               ansFlags |= ntlm.NTLMSSP_NEGOTIATE_128
-            if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_KEY_EXCH:
-               ansFlags |= ntlm.NTLMSSP_NEGOTIATE_KEY_EXCH
-            if negotiateMessage['flags'] & 
ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
-               ansFlags |= ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
-            if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_UNICODE:
-               ansFlags |= ntlm.NTLMSSP_NEGOTIATE_UNICODE
-            if negotiateMessage['flags'] & ntlm.NTLM_NEGOTIATE_OEM:
-               ansFlags |= ntlm.NTLM_NEGOTIATE_OEM
-
-            ansFlags |= ntlm.NTLMSSP_NEGOTIATE_VERSION | 
ntlm.NTLMSSP_NEGOTIATE_TARGET_INFO | ntlm.NTLMSSP_TARGET_TYPE_SERVER | 
ntlm.NTLMSSP_NEGOTIATE_NTLM | ntlm.NTLMSSP_REQUEST_TARGET
-
-            # Generate the AV_PAIRS
-            av_pairs = ntlm.AV_PAIRS()
-            # TODO: Put the proper data from SMBSERVER config
-            av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] = 
av_pairs[ntlm.NTLMSSP_AV_DNS_HOSTNAME] = 
smbServer.getServerName().encode('utf-16le')
-            av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME] = 
av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME] = 
smbServer.getServerDomain().encode('utf-16le')
-            av_pairs[ntlm.NTLMSSP_AV_TIME] = struct.pack('<q', 
(116444736000000000 + calendar.timegm(time.gmtime()) * 10000000) )
-
-            challengeMessage = ntlm.NTLMAuthChallenge()
-            challengeMessage['flags']            = ansFlags
-            challengeMessage['domain_len']       = 
len(smbServer.getServerDomain().encode('utf-16le'))
-            challengeMessage['domain_max_len']   = 
challengeMessage['domain_len']
-            challengeMessage['domain_offset']    = 40 + 16
-            challengeMessage['challenge']        = smbServer.getSMBChallenge()
-            challengeMessage['domain_name']      = 
smbServer.getServerDomain().encode('utf-16le')
-            challengeMessage['TargetInfoFields_len']     = len(av_pairs)
-            challengeMessage['TargetInfoFields_max_len'] = len(av_pairs)
-            challengeMessage['TargetInfoFields'] = av_pairs
-            challengeMessage['TargetInfoFields_offset']  = 40 + 16 + 
len(challengeMessage['domain_name'])
-            challengeMessage['Version']          = '\xff'*8
-            challengeMessage['VersionLen']       = 8
-
-            if rawNTLM is False:
-                respToken = SPNEGO_NegTokenResp()
-                # accept-incomplete. We want more data
-                respToken['NegResult'] = '\x01'
-                respToken['SupportedMech'] = TypesMech['NTLMSSP - Microsoft 
NTLM Security Support Provider']
-
-                respToken['ResponseToken'] = challengeMessage.getData()
-            else:
-                respToken = challengeMessage
-
-            # Setting the packet to STATUS_MORE_PROCESSING
-            errorCode = STATUS_MORE_PROCESSING_REQUIRED
-            # Let's set up an UID for this connection and store it
-            # in the connection's data
-            # Picking a fixed value
-            # TODO: Manage more UIDs for the same session
-            connData['Uid'] = random.randint(1,0xffffffff)
-            # Let's store it in the connection data
-            connData['CHALLENGE_MESSAGE'] = challengeMessage
-
-        elif messageType == 0x02:
-            # CHALLENGE_MESSAGE
-            raise Exception('Challenge Message raise, not implemented!')
-        elif messageType == 0x03:
-            # AUTHENTICATE_MESSAGE, here we deal with authentication
-            authenticateMessage = ntlm.NTLMAuthChallengeResponse()
-            authenticateMessage.fromString(token)
-            smbServer.log("AUTHENTICATE_MESSAGE (%s\\%s,%s)" % 
(authenticateMessage['domain_name'], authenticateMessage['user_name'], 
authenticateMessage['host_name']))
-            # TODO: Check the credentials! Now granting permissions
-
-            respToken = SPNEGO_NegTokenResp()
-            # accept-completed
-            respToken['NegResult'] = '\x00'
-
-            # Status SUCCESS
-            errorCode = STATUS_SUCCESS
-            smbServer.log('User %s\\%s authenticated successfully' % 
(authenticateMessage['user_name'], authenticateMessage['host_name']))
-            # Let's store it in the connection data
-            connData['AUTHENTICATE_MESSAGE'] = authenticateMessage
-            try:
-                jtr_dump_path = smbServer.getJTRdumpPath()
-                ntlm_hash_data = outputToJohnFormat( 
connData['CHALLENGE_MESSAGE']['challenge'], authenticateMessage['user_name'], 
authenticateMessage['domain_name'], authenticateMessage['lanman'], 
authenticateMessage['ntlm'] )
-                smbServer.log(ntlm_hash_data['hash_string'])
-                if jtr_dump_path is not '':
-                    writeJohnOutputToFile(ntlm_hash_data['hash_string'], 
ntlm_hash_data['hash_version'], jtr_dump_path)
-            except:
-                smbServer.log("Could not write NTLM Hashes to the specified 
JTR_Dump_Path %s" % jtr_dump_path)
-            respSMBCommand['SessionFlags'] = 1
-        else:
-            raise Exception("Unknown NTLMSSP MessageType %d" % messageType)
-
-        respSMBCommand['SecurityBufferOffset'] = 0x48
-        respSMBCommand['SecurityBufferLength'] = len(respToken)
-        respSMBCommand['Buffer'] = respToken.getData()
-
-        # From now on, the client can ask for other commands
-        connData['Authenticated'] = True
-        # For now, just switching to nobody
-        #os.setregid(65534,65534)
-        #os.setreuid(65534,65534)
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2TreeConnect(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respPacket = smb2.SMB2Packet()
-        respPacket['Flags']     = smb2.SMB2_FLAGS_SERVER_TO_REDIR
-        respPacket['Status']    = STATUS_SUCCESS
-        respPacket['CreditRequestResponse'] = 1
-        respPacket['Command']   = recvPacket['Command']
-        respPacket['SessionID'] = connData['Uid']
-        respPacket['Reserved']  = recvPacket['Reserved']
-        respPacket['MessageID'] = recvPacket['MessageID']
-        respPacket['TreeID']    = recvPacket['TreeID']
-
-        respSMBCommand        = smb2.SMB2TreeConnect_Response()
-
-        treeConnectRequest = smb2.SMB2TreeConnect(recvPacket['Data'])
-
-        errorCode = STATUS_SUCCESS
-
-        ## Process here the request, does the share exist?
-        path = 
str(recvPacket)[treeConnectRequest['PathOffset']:][:treeConnectRequest['PathLength']]
-        UNCOrShare = path.decode('utf-16le')
-
-        # Is this a UNC?
-        if ntpath.ismount(UNCOrShare):
-            path = UNCOrShare.split('\\')[3]
-        else:
-            path = ntpath.basename(UNCOrShare)
-
-        share = searchShare(connId, path.upper(), smbServer)
-        if share is not None:
-            # Simple way to generate a Tid
-            if len(connData['ConnectedShares']) == 0:
-               tid = 1
-            else:
-               tid = connData['ConnectedShares'].keys()[-1] + 1
-            connData['ConnectedShares'][tid] = share
-            connData['ConnectedShares'][tid]['shareName'] = path
-            respPacket['TreeID']    = tid
-            smbServer.log("Connecting Share(%d:%s)" % (tid,path))
-        else:
-            smbServer.log("SMB2_TREE_CONNECT not found %s" % path, 
logging.ERROR)
-            errorCode = STATUS_OBJECT_PATH_NOT_FOUND
-            respPacket['Status'] = errorCode
-        ##
-
-        if path == 'IPC$':
-            respSMBCommand['ShareType'] = smb2.SMB2_SHARE_TYPE_PIPE
-            respSMBCommand['ShareFlags'] = 0x30
-        else:
-            respSMBCommand['ShareType'] = smb2.SMB2_SHARE_TYPE_DISK
-            respSMBCommand['ShareFlags'] = 0x0
-
-        respSMBCommand['Capabilities'] = 0
-        respSMBCommand['MaximalAccess'] = 0x000f01ff
-
-        respPacket['Data'] = respSMBCommand
-
-        smbServer.setConnectionData(connId, connData)
-
-        return None, [respPacket], errorCode
-
-    @staticmethod
-    def smb2Create(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb2.SMB2Create_Response()
-
-        ntCreateRequest       = smb2.SMB2Create(recvPacket['Data'])
-
-        respSMBCommand['Buffer'] = '\x00'
-        # Get the Tid associated
-        if recvPacket['TreeID'] in connData['ConnectedShares']:
-             # If we have a rootFid, the path is relative to that fid
-             errorCode = STATUS_SUCCESS
-             if 'path' in connData['ConnectedShares'][recvPacket['TreeID']]:
-                 path = 
connData['ConnectedShares'][recvPacket['TreeID']]['path']
-             else:
-                 path = 'NONE'
-                 errorCode = STATUS_ACCESS_DENIED
-
-             deleteOnClose = False
-
-             fileName = 
os.path.normpath(ntCreateRequest['Buffer'][:ntCreateRequest['NameLength']].decode('utf-16le').replace('\\','/'))
-             if len(fileName) > 0 and (fileName[0] == '/' or fileName[0] == 
'\\'):
-                # strip leading '/'
-                fileName = fileName[1:]
-             pathName = os.path.join(path,fileName)
-             createDisposition = ntCreateRequest['CreateDisposition']
-             mode = 0
-
-             if createDisposition == smb2.FILE_SUPERSEDE:
-                 mode |= os.O_TRUNC | os.O_CREAT
-             elif createDisposition & smb2.FILE_OVERWRITE_IF == 
smb2.FILE_OVERWRITE_IF:
-                 mode |= os.O_TRUNC | os.O_CREAT
-             elif createDisposition & smb2.FILE_OVERWRITE == 
smb2.FILE_OVERWRITE:
-                 if os.path.exists(pathName) is True:
-                     mode |= os.O_TRUNC
-                 else:
-                     errorCode = STATUS_NO_SUCH_FILE
-             elif createDisposition & smb2.FILE_OPEN_IF == smb2.FILE_OPEN_IF:
-                 if os.path.exists(pathName) is True:
-                     mode |= os.O_TRUNC
-                 else:
-                     mode |= os.O_TRUNC | os.O_CREAT
-             elif createDisposition & smb2.FILE_CREATE == smb2.FILE_CREATE:
-                 if os.path.exists(pathName) is True:
-                     errorCode = STATUS_OBJECT_NAME_COLLISION
-                 else:
-                     mode |= os.O_CREAT
-             elif createDisposition & smb2.FILE_OPEN == smb2.FILE_OPEN:
-                 if os.path.exists(pathName) is not True and 
(unicode(pathName) in smbServer.getRegisteredNamedPipes()) is not True:
-                     errorCode = STATUS_NO_SUCH_FILE
-
-             if errorCode == STATUS_SUCCESS:
-                 desiredAccess = ntCreateRequest['DesiredAccess']
-                 if (desiredAccess & smb2.FILE_READ_DATA) or (desiredAccess & 
smb2.GENERIC_READ):
-                     mode |= os.O_RDONLY
-                 if (desiredAccess & smb2.FILE_WRITE_DATA) or (desiredAccess & 
smb2.GENERIC_WRITE):
-                     if (desiredAccess & smb2.FILE_READ_DATA) or 
(desiredAccess & smb2.GENERIC_READ):
-                         mode |= os.O_RDWR #| os.O_APPEND
-                     else:
-                         mode |= os.O_WRONLY #| os.O_APPEND
-                 if desiredAccess & smb2.GENERIC_ALL:
-                     mode |= os.O_RDWR #| os.O_APPEND
-
-                 createOptions =  ntCreateRequest['CreateOptions']
-                 if mode & os.O_CREAT == os.O_CREAT:
-                     if createOptions & smb2.FILE_DIRECTORY_FILE == 
smb2.FILE_DIRECTORY_FILE:
-                         try:
-                             # Let's create the directory
-                             os.mkdir(pathName)
-                             mode = os.O_RDONLY
-                         except Exception as e:
-                             smbServer.log("SMB2_CREATE: %s,%s,%s" % 
(pathName,mode,e),logging.ERROR)
-                             errorCode = STATUS_ACCESS_DENIED
-                 if createOptions & smb2.FILE_NON_DIRECTORY_FILE == 
smb2.FILE_NON_DIRECTORY_FILE:
-                     # If the file being opened is a directory, the server 
MUST fail the request with
-                     # STATUS_FILE_IS_A_DIRECTORY in the Status field of the 
SMB Header in the server
-                     # response.
-                     if os.path.isdir(pathName) is True:
-                        errorCode = STATUS_FILE_IS_A_DIRECTORY
-
-                 if createOptions & smb2.FILE_DELETE_ON_CLOSE == 
smb2.FILE_DELETE_ON_CLOSE:
-                     deleteOnClose = True
-
-                 if errorCode == STATUS_SUCCESS:
-                     try:
-                         if os.path.isdir(pathName) and sys.platform == 
'win32':
-                            fid = VOID_FILE_DESCRIPTOR
-                         else:
-                            if sys.platform == 'win32':
-                               mode |= os.O_BINARY
-                            if unicode(pathName) in 
smbServer.getRegisteredNamedPipes():
-                                fid = PIPE_FILE_DESCRIPTOR
-                                sock = socket.socket()
-                                
sock.connect(smbServer.getRegisteredNamedPipes()[unicode(pathName)])
-                            else:
-                                fid = os.open(pathName, mode)
-                     except Exception as e:
-                         smbServer.log("SMB2_CREATE: %s,%s,%s" % 
(pathName,mode,e),logging.ERROR)
-                         #print e
-                         fid = 0
-                         errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-        if errorCode == STATUS_SUCCESS:
-            # Simple way to generate a fid
-            fakefid = uuid.generate()
-
-            respSMBCommand['FileID'] = fakefid
-            respSMBCommand['CreateAction'] = createDisposition
-
-            if fid == PIPE_FILE_DESCRIPTOR:
-                respSMBCommand['CreationTime']   = 0
-                respSMBCommand['LastAccessTime'] = 0
-                respSMBCommand['LastWriteTime']  = 0
-                respSMBCommand['ChangeTime']     = 0
-                respSMBCommand['AllocationSize'] = 4096
-                respSMBCommand['EndOfFile']      = 0
-                respSMBCommand['FileAttributes'] = 0x80
-
-            else:
-                if os.path.isdir(pathName):
-                    respSMBCommand['FileAttributes'] = 
smb.SMB_FILE_ATTRIBUTE_DIRECTORY
-                else:
-                    respSMBCommand['FileAttributes'] = 
ntCreateRequest['FileAttributes']
-                # Let's get this file's information
-                respInfo, errorCode = queryPathInformation('',pathName,level= 
smb.SMB_QUERY_FILE_ALL_INFO)
-                if errorCode == STATUS_SUCCESS:
-                    respSMBCommand['CreationTime']   = respInfo['CreationTime']
-                    respSMBCommand['LastAccessTime'] = 
respInfo['LastAccessTime']
-                    respSMBCommand['LastWriteTime']  = 
respInfo['LastWriteTime']
-                    respSMBCommand['LastChangeTime'] = 
respInfo['LastChangeTime']
-                    respSMBCommand['FileAttributes'] = 
respInfo['ExtFileAttributes']
-                    respSMBCommand['AllocationSize'] = 
respInfo['AllocationSize']
-                    respSMBCommand['EndOfFile']      = respInfo['EndOfFile']
-
-            if errorCode == STATUS_SUCCESS:
-                # Let's store the fid for the connection
-                # smbServer.log('Create file %s, mode:0x%x' % (pathName, mode))
-                connData['OpenedFiles'][fakefid] = {}
-                connData['OpenedFiles'][fakefid]['FileHandle'] = fid
-                connData['OpenedFiles'][fakefid]['FileName'] = pathName
-                connData['OpenedFiles'][fakefid]['DeleteOnClose']  = 
deleteOnClose
-                connData['OpenedFiles'][fakefid]['Open']  = {}
-                
connData['OpenedFiles'][fakefid]['Open']['EnumerationLocation'] = 0
-                
connData['OpenedFiles'][fakefid]['Open']['EnumerationSearchPattern'] = ''
-                if fid == PIPE_FILE_DESCRIPTOR:
-                    connData['OpenedFiles'][fakefid]['Socket'] = sock
-        else:
-            respSMBCommand = smb2.SMB2Error()
-
-        if errorCode == STATUS_SUCCESS:
-            connData['LastRequest']['SMB2_CREATE'] = respSMBCommand
-        smbServer.setConnectionData(connId, connData)
-
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2Close(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb2.SMB2Close_Response()
-
-        closeRequest = smb2.SMB2Close(recvPacket['Data'])
-
-        if str(closeRequest['FileID']) == '\xff'*16:
-            # Let's take the data from the lastRequest
-            if  'SMB2_CREATE' in connData['LastRequest']:
-                fileID = connData['LastRequest']['SMB2_CREATE']['FileID']
-            else:
-                fileID = str(closeRequest['FileID'])
-        else:
-            fileID = str(closeRequest['FileID'])
-
-        if fileID in connData['OpenedFiles']:
-             errorCode = STATUS_SUCCESS
-             fileHandle = connData['OpenedFiles'][fileID]['FileHandle']
-             pathName = connData['OpenedFiles'][fileID]['FileName']
-             infoRecord = None
-             try:
-                 if fileHandle == PIPE_FILE_DESCRIPTOR:
-                     connData['OpenedFiles'][fileID]['Socket'].close()
-                 elif fileHandle != VOID_FILE_DESCRIPTOR:
-                     os.close(fileHandle)
-                     infoRecord, errorCode = 
queryFileInformation(os.path.dirname(pathName), os.path.basename(pathName), 
smb2.SMB2_FILE_NETWORK_OPEN_INFO)
-             except Exception as e:
-                 smbServer.log("SMB2_CLOSE %s" % e, logging.ERROR)
-                 errorCode = STATUS_INVALID_HANDLE
-             else:
-                 # Check if the file was marked for removal
-                 if connData['OpenedFiles'][fileID]['DeleteOnClose'] is True:
-                     try:
-                         if os.path.isdir(pathName):
-                             
shutil.rmtree(connData['OpenedFiles'][fileID]['FileName'])
-                         else:
-                             
os.remove(connData['OpenedFiles'][fileID]['FileName'])
-                     except Exception as e:
-                         smbServer.log("SMB2_CLOSE %s" % e, logging.ERROR)
-                         errorCode = STATUS_ACCESS_DENIED
-
-                 # Now fill out the response
-                 if infoRecord is not None:
-                     respSMBCommand['CreationTime']   = 
infoRecord['CreationTime']
-                     respSMBCommand['LastAccessTime'] = 
infoRecord['LastAccessTime']
-                     respSMBCommand['LastWriteTime']  = 
infoRecord['LastWriteTime']
-                     respSMBCommand['ChangeTime']     = 
infoRecord['ChangeTime']
-                     respSMBCommand['AllocationSize'] = 
infoRecord['AllocationSize']
-                     respSMBCommand['EndofFile']      = infoRecord['EndOfFile']
-                     respSMBCommand['FileAttributes'] = 
infoRecord['FileAttributes']
-                 if errorCode == STATUS_SUCCESS:
-                     del(connData['OpenedFiles'][fileID])
-        else:
-            errorCode = STATUS_INVALID_HANDLE
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2QueryInfo(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb2.SMB2QueryInfo_Response()
-
-        queryInfo = smb2.SMB2QueryInfo(recvPacket['Data'])
-
-        errorCode = STATUS_SUCCESS
-
-        respSMBCommand['OutputBufferOffset'] = 0x48
-        respSMBCommand['Buffer'] = '\x00'
-
-        if str(queryInfo['FileID']) == '\xff'*16:
-            # Let's take the data from the lastRequest
-            if  'SMB2_CREATE' in connData['LastRequest']:
-                fileID = connData['LastRequest']['SMB2_CREATE']['FileID']
-            else:
-                fileID = str(queryInfo['FileID'])
-        else:
-            fileID = str(queryInfo['FileID'])
-
-        if recvPacket['TreeID'] in connData['ConnectedShares']:
-            if fileID in connData['OpenedFiles']:
-                fileName = connData['OpenedFiles'][fileID]['FileName']
-
-                if queryInfo['InfoType'] == smb2.SMB2_0_INFO_FILE:
-                    if queryInfo['FileInfoClass'] == 
smb2.SMB2_FILE_INTERNAL_INFO:
-                        # No need to call queryFileInformation, we have the 
data here
-                        infoRecord = smb2.FileInternalInformation()
-                        infoRecord['IndexNumber'] = fileID
-                    else:
-                        infoRecord, errorCode = 
queryFileInformation(os.path.dirname(fileName), os.path.basename(fileName), 
queryInfo['FileInfoClass'])
-                elif queryInfo['InfoType'] == smb2.SMB2_0_INFO_FILESYSTEM:
-                    infoRecord = queryFsInformation(os.path.dirname(fileName), 
os.path.basename(fileName), queryInfo['FileInfoClass'])
-                elif queryInfo['InfoType'] == smb2.SMB2_0_INFO_SECURITY:
-                    # Failing for now, until we support it
-                    infoRecord = None
-                    errorCode = STATUS_ACCESS_DENIED
-                else:
-                    smbServer.log("queryInfo not supported (%x)" %  
queryInfo['InfoType'], logging.ERROR)
-
-                if infoRecord is not None:
-                    respSMBCommand['OutputBufferLength'] = len(infoRecord)
-                    respSMBCommand['Buffer'] = infoRecord
-            else:
-                errorCode = STATUS_INVALID_HANDLE
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2SetInfo(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand        = smb2.SMB2SetInfo_Response()
-
-        setInfo = smb2.SMB2SetInfo(recvPacket['Data'])
-
-        errorCode = STATUS_SUCCESS
-
-        if str(setInfo['FileID']) == '\xff'*16:
-            # Let's take the data from the lastRequest
-            if  'SMB2_CREATE' in connData['LastRequest']:
-                fileID = connData['LastRequest']['SMB2_CREATE']['FileID']
-            else:
-                fileID = str(setInfo['FileID'])
-        else:
-            fileID = str(setInfo['FileID'])
-
-        if recvPacket['TreeID'] in connData['ConnectedShares']:
-            path     = 
connData['ConnectedShares'][recvPacket['TreeID']]['path']
-            if fileID in connData['OpenedFiles']:
-                pathName = connData['OpenedFiles'][fileID]['FileName']
-
-                if setInfo['InfoType'] == smb2.SMB2_0_INFO_FILE:
-                    # The file information is being set
-                    informationLevel = setInfo['FileInfoClass']
-                    if informationLevel == smb2.SMB2_FILE_DISPOSITION_INFO:
-                        infoRecord = 
smb.SMBSetFileDispositionInfo(setInfo['Buffer'])
-                        if infoRecord['DeletePending'] > 0:
-                           # Mark this file for removal after closed
-                           connData['OpenedFiles'][fileID]['DeleteOnClose'] = 
True
-                    elif informationLevel == smb2.SMB2_FILE_BASIC_INFO:
-                        infoRecord = smb.SMBSetFileBasicInfo(setInfo['Buffer'])
-                        # Creation time won't be set,  the other ones we play 
with.
-                        atime = infoRecord['LastWriteTime']
-                        if atime == 0:
-                            atime = -1
-                        else:
-                            atime = getUnixTime(atime)
-                        mtime = infoRecord['ChangeTime']
-                        if mtime == 0:
-                            mtime = -1
-                        else:
-                            mtime = getUnixTime(mtime)
-                        if atime > 0 and mtime > 0:
-                            os.utime(pathName,(atime,mtime))
-                    elif informationLevel == smb2.SMB2_FILE_END_OF_FILE_INFO:
-                        fileHandle = 
connData['OpenedFiles'][fileID]['FileHandle']
-                        infoRecord = 
smb.SMBSetFileEndOfFileInfo(setInfo['Buffer'])
-                        if infoRecord['EndOfFile'] > 0:
-                            os.lseek(fileHandle, infoRecord['EndOfFile']-1, 0)
-                            os.write(fileHandle, '\x00')
-                    elif informationLevel == smb2.SMB2_FILE_RENAME_INFO:
-                        renameInfo = 
smb2.FILE_RENAME_INFORMATION_TYPE_2(setInfo['Buffer'])
-                        newPathName = 
os.path.join(path,renameInfo['FileName'].decode('utf-16le').replace('\\', '/'))
-                        if renameInfo['ReplaceIfExists'] == 0 and 
os.path.exists(newPathName):
-                            return [smb2.SMB2Error()], None, 
STATUS_OBJECT_NAME_COLLISION
-                        try:
-                             os.rename(pathName,newPathName)
-                             connData['OpenedFiles'][fileID]['FileName'] = 
newPathName
-                        except Exception as e:
-                             smbServer.log("smb2SetInfo: %s" % e, 
logging.ERROR)
-                             errorCode = STATUS_ACCESS_DENIED
-                    else:
-                        smbServer.log('Unknown level for set file info! 0x%x' 
% informationLevel, logging.ERROR)
-                        # UNSUPPORTED
-                        errorCode =  STATUS_NOT_SUPPORTED
-                #elif setInfo['InfoType'] == smb2.SMB2_0_INFO_FILESYSTEM:
-                #    # The underlying object store information is being set.
-                #    setInfo = queryFsInformation('/', fileName, 
queryInfo['FileInfoClass'])
-                #elif setInfo['InfoType'] == smb2.SMB2_0_INFO_SECURITY:
-                #    # The security information is being set.
-                #    # Failing for now, until we support it
-                #    infoRecord = None
-                #    errorCode = STATUS_ACCESS_DENIED
-                #elif setInfo['InfoType'] == smb2.SMB2_0_INFO_QUOTA:
-                #    # The underlying object store quota information is being 
set.
-                #    setInfo = queryFsInformation('/', fileName, 
queryInfo['FileInfoClass'])
-                else:
-                    smbServer.log("setInfo not supported (%x)" %  
setInfo['InfoType'], logging.ERROR)
-
-            else:
-                errorCode = STATUS_INVALID_HANDLE
-        else:
-            errorCode = STATUS_SMB_BAD_TID
-
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2Write(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb2.SMB2Write_Response()
-        writeRequest   = smb2.SMB2Write(recvPacket['Data'])
-
-        respSMBCommand['Buffer'] = '\x00'
-
-        if str(writeRequest['FileID']) == '\xff'*16:
-            # Let's take the data from the lastRequest
-            if  'SMB2_CREATE' in connData['LastRequest']:
-                fileID = connData['LastRequest']['SMB2_CREATE']['FileID']
-            else:
-                fileID = str(writeRequest['FileID'])
-        else:
-            fileID = str(writeRequest['FileID'])
-
-        if fileID in connData['OpenedFiles']:
-             fileHandle = connData['OpenedFiles'][fileID]['FileHandle']
-             errorCode = STATUS_SUCCESS
-             try:
-                 if fileHandle != PIPE_FILE_DESCRIPTOR:
-                     offset = writeRequest['Offset']
-                     # If we're trying to write past the file end we just skip 
the write call (Vista does this)
-                     if os.lseek(fileHandle, 0, 2) >= offset:
-                         os.lseek(fileHandle,offset,0)
-                         os.write(fileHandle,writeRequest['Buffer'])
-                 else:
-                     sock = connData['OpenedFiles'][fileID]['Socket']
-                     sock.send(writeRequest['Buffer'])
-
-                 respSMBCommand['Count']    = writeRequest['Length']
-                 respSMBCommand['Remaining']= 0xff
-             except Exception as e:
-                 smbServer.log('SMB2_WRITE: %s' % e, logging.ERROR)
-                 errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_INVALID_HANDLE
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2Read(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb2.SMB2Read_Response()
-        readRequest   = smb2.SMB2Read(recvPacket['Data'])
-
-        respSMBCommand['Buffer'] = '\x00'
-
-        if str(readRequest['FileID']) == '\xff'*16:
-            # Let's take the data from the lastRequest
-            if  'SMB2_CREATE' in connData['LastRequest']:
-                fileID = connData['LastRequest']['SMB2_CREATE']['FileID']
-            else:
-                fileID = str(readRequest['FileID'])
-        else:
-            fileID = str(readRequest['FileID'])
-
-        if fileID in connData['OpenedFiles']:
-             fileHandle = connData['OpenedFiles'][fileID]['FileHandle']
-             errorCode = 0
-             try:
-                 if fileHandle != PIPE_FILE_DESCRIPTOR:
-                     offset = readRequest['Offset']
-                     os.lseek(fileHandle,offset,0)
-                     content = os.read(fileHandle,readRequest['Length'])
-                 else:
-                     sock = connData['OpenedFiles'][fileID]['Socket']
-                     content = sock.recv(readRequest['Length'])
-
-                 respSMBCommand['DataOffset']   = 0x50
-                 respSMBCommand['DataLength']   = len(content)
-                 respSMBCommand['DataRemaining']= 0
-                 respSMBCommand['Buffer']       = content
-             except Exception as e:
-                 smbServer.log('SMB2_READ: %s ' % e, logging.ERROR)
-                 errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_INVALID_HANDLE
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2Flush(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb2.SMB2Flush_Response()
-        flushRequest   = smb2.SMB2Flush(recvPacket['Data'])
-
-        if str(flushRequest['FileID']) in connData['OpenedFiles']:
-             fileHandle = 
connData['OpenedFiles'][str(flushRequest['FileID'])]['FileHandle']
-             errorCode = STATUS_SUCCESS
-             try:
-                 os.fsync(fileHandle)
-             except Exception as e:
-                 smbServer.log("SMB2_FLUSH %s" % e, logging.ERROR)
-                 errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_INVALID_HANDLE
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-
-    @staticmethod
-    def smb2QueryDirectory(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-        respSMBCommand = smb2.SMB2QueryDirectory_Response()
-        queryDirectoryRequest   = smb2.SMB2QueryDirectory(recvPacket['Data'])
-
-        respSMBCommand['Buffer'] = '\x00'
-
-        # The server MUST locate the tree connection, as specified in section 
3.3.5.2.11.
-        if (recvPacket['TreeID'] in connData['ConnectedShares']) is False:
-            return [smb2.SMB2Error()], None, STATUS_NETWORK_NAME_DELETED
-
-        # Next, the server MUST locate the open for the directory to be queried
-        # If no open is found, the server MUST fail the request with 
STATUS_FILE_CLOSED
-        if str(queryDirectoryRequest['FileID']) == '\xff'*16:
-            # Let's take the data from the lastRequest
-            if  'SMB2_CREATE' in connData['LastRequest']:
-                fileID = connData['LastRequest']['SMB2_CREATE']['FileID']
-            else:
-                fileID = str(queryDirectoryRequest['FileID'])
-        else:
-            fileID = str(queryDirectoryRequest['FileID'])
-
-        if (fileID in connData['OpenedFiles']) is False:
-            return [smb2.SMB2Error()], None, STATUS_FILE_CLOSED
-
-        # If the open is not an open to a directory, the request MUST be failed
-        # with STATUS_INVALID_PARAMETER.
-        if os.path.isdir(connData['OpenedFiles'][fileID]['FileName']) is False:
-            return [smb2.SMB2Error()], None, STATUS_INVALID_PARAMETER
-
-        # If any other information class is specified in the 
FileInformationClass
-        # field of the SMB2 QUERY_DIRECTORY Request, the server MUST fail the
-        # operation with STATUS_INVALID_INFO_CLASS.
-        if queryDirectoryRequest['FileInformationClass'] not in (
-        smb2.FILE_DIRECTORY_INFORMATION, smb2.FILE_FULL_DIRECTORY_INFORMATION, 
smb2.FILEID_FULL_DIRECTORY_INFORMATION,
-        smb2.FILE_BOTH_DIRECTORY_INFORMATION, 
smb2.FILEID_BOTH_DIRECTORY_INFORMATION, smb2.FILENAMES_INFORMATION):
-            return [smb2.SMB2Error()], None, STATUS_INVALID_INFO_CLASS
-
-        # If SMB2_REOPEN is set in the Flags field of the SMB2 QUERY_DIRECTORY
-        # Request, the server SHOULD<326> set Open.EnumerationLocation to 0
-        # and Open.EnumerationSearchPattern to an empty string.
-        if queryDirectoryRequest['Flags'] & smb2.SMB2_REOPEN:
-            connData['OpenedFiles'][fileID]['Open']['EnumerationLocation'] = 0
-            
connData['OpenedFiles'][fileID]['Open']['EnumerationSearchPattern'] = ''
-
-        # If SMB2_RESTART_SCANS is set in the Flags field of the SMB2
-        # QUERY_DIRECTORY Request, the server MUST set
-        # Open.EnumerationLocation to 0.
-        if queryDirectoryRequest['Flags'] & smb2.SMB2_RESTART_SCANS:
-            connData['OpenedFiles'][fileID]['Open']['EnumerationLocation'] = 0
-
-        # If Open.EnumerationLocation is 0 and Open.EnumerationSearchPattern
-        # is an empty string, then Open.EnumerationSearchPattern MUST be set
-        # to the search pattern specified in the SMB2 QUERY_DIRECTORY by
-        # FileNameOffset and FileNameLength. If FileNameLength is 0, the server
-        # SHOULD<327> set Open.EnumerationSearchPattern as "*" to search all 
entries.
-
-        pattern = queryDirectoryRequest['Buffer'].decode('utf-16le')
-        if  connData['OpenedFiles'][fileID]['Open']['EnumerationLocation'] == 
0 and \
-            
connData['OpenedFiles'][fileID]['Open']['EnumerationSearchPattern'] == '':
-            if pattern == '':
-                pattern = '*'
-            
connData['OpenedFiles'][fileID]['Open']['EnumerationSearchPattern'] = pattern
-
-        # If SMB2_INDEX_SPECIFIED is set and FileNameLength is not zero,
-        # the server MUST set Open.EnumerationSearchPattern to the search 
pattern
-        # specified in the request by FileNameOffset and FileNameLength.
-        if queryDirectoryRequest['Flags'] & smb2.SMB2_INDEX_SPECIFIED and \
-           queryDirectoryRequest['FileNameLength'] > 0:
-            
connData['OpenedFiles'][fileID]['Open']['EnumerationSearchPattern'] = pattern
-
-        pathName = 
os.path.join(os.path.normpath(connData['OpenedFiles'][fileID]['FileName']),pattern)
-        searchResult, searchCount, errorCode = 
findFirst2(os.path.dirname(pathName),
-                  os.path.basename(pathName),
-                  queryDirectoryRequest['FileInformationClass'],
-                  smb.ATTR_DIRECTORY, isSMB2 = True )
-
-        if errorCode != STATUS_SUCCESS:
-            return [smb2.SMB2Error()], None, errorCode
-
-        if searchCount > 2 and pattern == '*':
-            # strip . and ..
-            searchCount -= 2
-            searchResult = searchResult[2:]
-
-        if searchCount == 0 and 
connData['OpenedFiles'][fileID]['Open']['EnumerationLocation'] == 0:
-            return [smb2.SMB2Error()], None, STATUS_NO_SUCH_FILE
-
-        if  connData['OpenedFiles'][fileID]['Open']['EnumerationLocation'] < 0:
-            return [smb2.SMB2Error()], None, STATUS_NO_MORE_FILES
-
-        totalData = 0
-        respData = ''
-        for nItem in 
range(connData['OpenedFiles'][fileID]['Open']['EnumerationLocation'], 
searchCount):
-            connData['OpenedFiles'][fileID]['Open']['EnumerationLocation'] += 1
-            if queryDirectoryRequest['Flags'] & smb2.SL_RETURN_SINGLE_ENTRY:
-                # If single entry is requested we must clear the 
NextEntryOffset
-                searchResult[nItem]['NextEntryOffset'] = 0
-            data = searchResult[nItem].getData()
-            lenData = len(data)
-            padLen = (8-(lenData % 8)) %8
-
-            if (totalData+lenData) >= 
queryDirectoryRequest['OutputBufferLength']:
-                connData['OpenedFiles'][fileID]['Open']['EnumerationLocation'] 
-= 1
-                break
-            else:
-                respData += data + '\x00'*padLen
-                totalData += lenData + padLen
-
-            if queryDirectoryRequest['Flags'] & smb2.SL_RETURN_SINGLE_ENTRY:
-                break
-
-        if connData['OpenedFiles'][fileID]['Open']['EnumerationLocation'] >= 
searchCount:
-             connData['OpenedFiles'][fileID]['Open']['EnumerationLocation'] = 
-1
-
-        respSMBCommand['OutputBufferOffset'] = 0x48
-        respSMBCommand['OutputBufferLength'] = totalData
-        respSMBCommand['Buffer'] = respData
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2ChangeNotify(connId, smbServer, recvPacket):
-
-        return [smb2.SMB2Error()], None, STATUS_NOT_SUPPORTED
-
-    @staticmethod
-    def smb2Echo(connId, smbServer, recvPacket):
-
-        respSMBCommand = smb2.SMB2Echo_Response()
-
-        return [respSMBCommand], None, STATUS_SUCCESS
-
-    @staticmethod
-    def smb2TreeDisconnect(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb2.SMB2TreeDisconnect_Response()
-
-        if recvPacket['TreeID'] in connData['ConnectedShares']:
-            smbServer.log("Disconnecting Share(%d:%s)" % 
(recvPacket['TreeID'],connData['ConnectedShares'][recvPacket['TreeID']]['shareName']))
-            del(connData['ConnectedShares'][recvPacket['TreeID']])
-            errorCode = STATUS_SUCCESS
-        else:
-            # STATUS_SMB_BAD_TID
-            errorCode = STATUS_SMB_BAD_TID
-
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2Logoff(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb2.SMB2Logoff_Response()
-
-        if recvPacket['SessionID'] != connData['Uid']:
-            # STATUS_SMB_BAD_UID
-            errorCode = STATUS_SMB_BAD_UID
-        else:
-            errorCode = STATUS_SUCCESS
-
-        connData['Uid'] = 0
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2Ioctl(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb2.SMB2Ioctl_Response()
-        ioctlRequest   = smb2.SMB2Ioctl(recvPacket['Data'])
-
-        ioctls = smbServer.getIoctls()
-        if ioctlRequest['CtlCode'] in ioctls:
-            outputData, errorCode = ioctls[ioctlRequest['CtlCode']](connId, 
smbServer, ioctlRequest)
-            if errorCode == STATUS_SUCCESS:
-                respSMBCommand['CtlCode']      = ioctlRequest['CtlCode']
-                respSMBCommand['FileID']       = ioctlRequest['FileID']
-                respSMBCommand['InputOffset']  = 0
-                respSMBCommand['InputCount']   = 0
-                respSMBCommand['OutputOffset'] = 0x70
-                respSMBCommand['OutputCount']  = len(outputData)
-                respSMBCommand['Flags']        = 0
-                respSMBCommand['Buffer']       = outputData
-            else:
-                respSMBCommand = outputData
-        else:
-            smbServer.log("Ioctl not implemented command: 0x%x" % 
ioctlRequest['CtlCode'],logging.DEBUG)
-            errorCode = STATUS_INVALID_DEVICE_REQUEST
-            respSMBCommand = smb2.SMB2Error()
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2Lock(connId, smbServer, recvPacket):
-        connData = smbServer.getConnectionData(connId)
-
-        respSMBCommand = smb2.SMB2Lock_Response()
-
-        # I'm actually doing nothing.. just make MacOS happy ;)
-        errorCode = STATUS_SUCCESS
-
-        smbServer.setConnectionData(connId, connData)
-        return [respSMBCommand], None, errorCode
-
-    @staticmethod
-    def smb2Cancel(connId, smbServer, recvPacket):
-        # I'm actually doing nothing
-        return [smb2.SMB2Error()], None, STATUS_CANCELLED
-
-    @staticmethod
-    def default(connId, smbServer, recvPacket):
-        # By default we return an SMB Packet with error not implemented
-        smbServer.log("Not implemented command: 0x%x" % 
recvPacket['Command'],logging.DEBUG)
-        return [smb2.SMB2Error()], None, STATUS_NOT_SUPPORTED
-
-class Ioctls:
-   @staticmethod
-   def fsctlDfsGetReferrals(connId, smbServer, ioctlRequest):
-        return smb2.SMB2Error(), STATUS_FS_DRIVER_REQUIRED
-
-   @staticmethod
-   def fsctlPipeTransceive(connId, smbServer, ioctlRequest):
-        connData = smbServer.getConnectionData(connId)
-
-        ioctlResponse = ''
-
-        if str(ioctlRequest['FileID']) in connData['OpenedFiles']:
-             fileHandle = 
connData['OpenedFiles'][str(ioctlRequest['FileID'])]['FileHandle']
-             errorCode = STATUS_SUCCESS
-             try:
-                 if fileHandle != PIPE_FILE_DESCRIPTOR:
-                     errorCode = STATUS_INVALID_DEVICE_REQUEST
-                 else:
-                     sock = 
connData['OpenedFiles'][str(ioctlRequest['FileID'])]['Socket']
-                     sock.sendall(ioctlRequest['Buffer'])
-                     ioctlResponse = 
sock.recv(ioctlRequest['MaxOutputResponse'])
-             except Exception as e:
-                 smbServer.log('fsctlPipeTransceive: %s ' % e, logging.ERROR)
-                 errorCode = STATUS_ACCESS_DENIED
-        else:
-            errorCode = STATUS_INVALID_DEVICE_REQUEST
-
-        smbServer.setConnectionData(connId, connData)
-        return ioctlResponse, errorCode
-
-   @staticmethod
-   def fsctlValidateNegotiateInfo(connId, smbServer, ioctlRequest):
-        connData = smbServer.getConnectionData(connId)
-
-        errorCode = STATUS_SUCCESS
-
-        validateNegotiateInfo = 
smb2.VALIDATE_NEGOTIATE_INFO(ioctlRequest['Buffer'])
-        validateNegotiateInfo['Capabilities'] = 0
-        validateNegotiateInfo['Guid'] = 'A'*16
-        validateNegotiateInfo['SecurityMode'] = 1
-        validateNegotiateInfo['Dialects'] = (smb2.SMB2_DIALECT_002,)
-
-        smbServer.setConnectionData(connId, connData)
-        return validateNegotiateInfo.getData(), errorCode
-
-
-class SMBSERVERHandler(SocketServer.BaseRequestHandler):
-    def __init__(self, request, client_address, server, select_poll = False):
-        self.__SMB = server
-        self.__ip, self.__port = client_address
-        self.__request = request
-        self.__connId = threading.currentThread().getName()
-        self.__timeOut = 60*5
-        self.__select_poll = select_poll
-        #self.__connId = os.getpid()
-        SocketServer.BaseRequestHandler.__init__(self, request, 
client_address, server)
-
-    def handle(self):
-        self.__SMB.log("Incoming connection (%s,%d)" % (self.__ip, 
self.__port))
-        self.__SMB.addConnection(self.__connId, self.__ip, self.__port)
-        while True:
-            try:
-                # Firt of all let's get the NETBIOS packet
-                session = 
nmb.NetBIOSTCPSession(self.__SMB.getServerName(),'HOST', self.__ip, sess_port = 
self.__port, sock = self.__request, select_poll = self.__select_poll)
-                try:
-                    p = session.recv_packet(self.__timeOut)
-                except nmb.NetBIOSTimeout:
-                    raise
-                except nmb.NetBIOSError:
-                    break
-
-                if p.get_type() == nmb.NETBIOS_SESSION_REQUEST:
-                   # Someone is requesting a session, we're gonna accept them 
all :)
-                   _, rn, my = p.get_trailer().split(' ')
-                   remote_name = nmb.decode_name('\x20'+rn)
-                   myname = nmb.decode_name('\x20'+my)
-                   self.__SMB.log("NetBIOS Session request (%s,%s,%s)" % 
(self.__ip, remote_name[1].strip(), myname[1]))
-                   r = nmb.NetBIOSSessionPacket()
-                   r.set_type(nmb.NETBIOS_SESSION_POSITIVE_RESPONSE)
-                   r.set_trailer(p.get_trailer())
-                   self.__request.send(r.rawData())
-                else:
-                   resp = self.__SMB.processRequest(self.__connId, 
p.get_trailer())
-                   # Send all the packets recevied. Except for big 
transactions this should be
-                   # a single packet
-                   for i in resp:
-                       session.send_packet(str(i))
-            except Exception as e:
-                self.__SMB.log("Handle: %s" % e)
-                #import traceback
-                #traceback.print_exc()
-                break
-
-    def finish(self):
-        # Thread/process is dying, we should tell the main SMB thread to 
remove all this thread data
-        self.__SMB.log("Closing down connection (%s,%d)" % (self.__ip, 
self.__port))
-        self.__SMB.removeConnection(self.__connId)
-        return SocketServer.BaseRequestHandler.finish(self)
-
-class SMBSERVER(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
-#class SMBSERVER(SocketServer.ForkingMixIn, SocketServer.TCPServer):
-    def __init__(self, server_address, handler_class=SMBSERVERHandler, 
config_parser = None):
-        SocketServer.TCPServer.allow_reuse_address = True
-        SocketServer.TCPServer.__init__(self, server_address, handler_class)
-
-        # Server name and OS to be presented whenever is necessary
-        self.__serverName   = ''
-        self.__serverOS     = ''
-        self.__serverDomain = ''
-        self.__challenge    = ''
-        self.__log          = None
-
-        # Our ConfigParser data
-        self.__serverConfig = config_parser
-
-        # Our credentials to be used during the server's lifetime
-        self.__credentials = {}
-
-        # Our log file
-        self.__logFile = ''
-
-        # Registered Named Pipes, format is PipeName,Socket
-        self.__registeredNamedPipes = {}
-
-        # JTR dump path
-        self.__jtr_dump_path = ''
-
-        # SMB2 Support flag = default not active
-        self.__SMB2Support = False
-
-        # Our list of commands we will answer, by default the NOT IMPLEMENTED 
one
-        self.__smbCommandsHandler = SMBCommands()
-        self.__smbTrans2Handler   = TRANS2Commands()
-        self.__smbTransHandler    = TRANSCommands()
-        self.__smbNTTransHandler  = NTTRANSCommands()
-        self.__smb2CommandsHandler = SMB2Commands()
-        self.__IoctlHandler       = Ioctls()
-
-        self.__smbNTTransCommands = {
-        # NT IOCTL, can't find doc for this
-        0xff                               :self.__smbNTTransHandler.default
-        }
-
-        self.__smbTransCommands  = {
-'\\PIPE\\LANMAN'                       :self.__smbTransHandler.lanMan,
-smb.SMB.TRANS_TRANSACT_NMPIPE          
:self.__smbTransHandler.transactNamedPipe,
-        }
-        self.__smbTrans2Commands = {
- smb.SMB.TRANS2_FIND_FIRST2            :self.__smbTrans2Handler.findFirst2,
- smb.SMB.TRANS2_FIND_NEXT2             :self.__smbTrans2Handler.findNext2,
- smb.SMB.TRANS2_QUERY_FS_INFORMATION   
:self.__smbTrans2Handler.queryFsInformation,
- smb.SMB.TRANS2_QUERY_PATH_INFORMATION 
:self.__smbTrans2Handler.queryPathInformation,
- smb.SMB.TRANS2_QUERY_FILE_INFORMATION 
:self.__smbTrans2Handler.queryFileInformation,
- smb.SMB.TRANS2_SET_FILE_INFORMATION   
:self.__smbTrans2Handler.setFileInformation,
- smb.SMB.TRANS2_SET_PATH_INFORMATION   
:self.__smbTrans2Handler.setPathInformation
-        }
-
-        self.__smbCommands = {
- #smb.SMB.SMB_COM_FLUSH:              self.__smbCommandsHandler.smbComFlush,
- smb.SMB.SMB_COM_CREATE_DIRECTORY:   
self.__smbCommandsHandler.smbComCreateDirectory,
- smb.SMB.SMB_COM_DELETE_DIRECTORY:   
self.__smbCommandsHandler.smbComDeleteDirectory,
- smb.SMB.SMB_COM_RENAME:             self.__smbCommandsHandler.smbComRename,
- smb.SMB.SMB_COM_DELETE:             self.__smbCommandsHandler.smbComDelete,
- smb.SMB.SMB_COM_NEGOTIATE:          self.__smbCommandsHandler.smbComNegotiate,
- smb.SMB.SMB_COM_SESSION_SETUP_ANDX: 
self.__smbCommandsHandler.smbComSessionSetupAndX,
- smb.SMB.SMB_COM_LOGOFF_ANDX:        
self.__smbCommandsHandler.smbComLogOffAndX,
- smb.SMB.SMB_COM_TREE_CONNECT_ANDX:  
self.__smbCommandsHandler.smbComTreeConnectAndX,
- smb.SMB.SMB_COM_TREE_DISCONNECT:    
self.__smbCommandsHandler.smbComTreeDisconnect,
- smb.SMB.SMB_COM_ECHO:               self.__smbCommandsHandler.smbComEcho,
- smb.SMB.SMB_COM_QUERY_INFORMATION:  
self.__smbCommandsHandler.smbQueryInformation,
- smb.SMB.SMB_COM_TRANSACTION2:       self.__smbCommandsHandler.smbTransaction2,
- smb.SMB.SMB_COM_TRANSACTION:        self.__smbCommandsHandler.smbTransaction,
- # Not needed for now
- smb.SMB.SMB_COM_NT_TRANSACT:        self.__smbCommandsHandler.smbNTTransact,
- smb.SMB.SMB_COM_QUERY_INFORMATION_DISK: 
self.__smbCommandsHandler.smbQueryInformationDisk,
- smb.SMB.SMB_COM_OPEN_ANDX:          self.__smbCommandsHandler.smbComOpenAndX,
- smb.SMB.SMB_COM_QUERY_INFORMATION2: 
self.__smbCommandsHandler.smbComQueryInformation2,
- smb.SMB.SMB_COM_READ_ANDX:          self.__smbCommandsHandler.smbComReadAndX,
- smb.SMB.SMB_COM_READ:               self.__smbCommandsHandler.smbComRead,
- smb.SMB.SMB_COM_WRITE_ANDX:         self.__smbCommandsHandler.smbComWriteAndX,
- smb.SMB.SMB_COM_WRITE:              self.__smbCommandsHandler.smbComWrite,
- smb.SMB.SMB_COM_CLOSE:              self.__smbCommandsHandler.smbComClose,
- smb.SMB.SMB_COM_LOCKING_ANDX:       
self.__smbCommandsHandler.smbComLockingAndX,
- smb.SMB.SMB_COM_NT_CREATE_ANDX:     
self.__smbCommandsHandler.smbComNtCreateAndX,
- 0xFF:                               self.__smbCommandsHandler.default
-}
-
-        self.__smb2Ioctls = {
- smb2.FSCTL_DFS_GET_REFERRALS:            
self.__IoctlHandler.fsctlDfsGetReferrals,
-# smb2.FSCTL_PIPE_PEEK:                    self.__IoctlHandler.fsctlPipePeek,
-# smb2.FSCTL_PIPE_WAIT:                    self.__IoctlHandler.fsctlPipeWait,
- smb2.FSCTL_PIPE_TRANSCEIVE:              
self.__IoctlHandler.fsctlPipeTransceive,
-# smb2.FSCTL_SRV_COPYCHUNK:                
self.__IoctlHandler.fsctlSrvCopyChunk,
-# smb2.FSCTL_SRV_ENUMERATE_SNAPSHOTS:      
self.__IoctlHandler.fsctlSrvEnumerateSnapshots,
-# smb2.FSCTL_SRV_REQUEST_RESUME_KEY:       
self.__IoctlHandler.fsctlSrvRequestResumeKey,
-# smb2.FSCTL_SRV_READ_HASH:                
self.__IoctlHandler.fsctlSrvReadHash,
-# smb2.FSCTL_SRV_COPYCHUNK_WRITE:          
self.__IoctlHandler.fsctlSrvCopyChunkWrite,
-# smb2.FSCTL_LMR_REQUEST_RESILIENCY:       
self.__IoctlHandler.fsctlLmrRequestResiliency,
-# smb2.FSCTL_QUERY_NETWORK_INTERFACE_INFO: 
self.__IoctlHandler.fsctlQueryNetworkInterfaceInfo,
-# smb2.FSCTL_SET_REPARSE_POINT:            
self.__IoctlHandler.fsctlSetReparsePoint,
-# smb2.FSCTL_DFS_GET_REFERRALS_EX:         
self.__IoctlHandler.fsctlDfsGetReferralsEx,
-# smb2.FSCTL_FILE_LEVEL_TRIM:              
self.__IoctlHandler.fsctlFileLevelTrim,
- smb2.FSCTL_VALIDATE_NEGOTIATE_INFO:      
self.__IoctlHandler.fsctlValidateNegotiateInfo,
-}
-
-        self.__smb2Commands = {
- smb2.SMB2_NEGOTIATE:       self.__smb2CommandsHandler.smb2Negotiate,
- smb2.SMB2_SESSION_SETUP:   self.__smb2CommandsHandler.smb2SessionSetup,
- smb2.SMB2_LOGOFF:          self.__smb2CommandsHandler.smb2Logoff,
- smb2.SMB2_TREE_CONNECT:    self.__smb2CommandsHandler.smb2TreeConnect,
- smb2.SMB2_TREE_DISCONNECT: self.__smb2CommandsHandler.smb2TreeDisconnect,
- smb2.SMB2_CREATE:          self.__smb2CommandsHandler.smb2Create,
- smb2.SMB2_CLOSE:           self.__smb2CommandsHandler.smb2Close,
- smb2.SMB2_FLUSH:           self.__smb2CommandsHandler.smb2Flush,
- smb2.SMB2_READ:            self.__smb2CommandsHandler.smb2Read,
- smb2.SMB2_WRITE:           self.__smb2CommandsHandler.smb2Write,
- smb2.SMB2_LOCK:            self.__smb2CommandsHandler.smb2Lock,
- smb2.SMB2_IOCTL:           self.__smb2CommandsHandler.smb2Ioctl,
- smb2.SMB2_CANCEL:          self.__smb2CommandsHandler.smb2Cancel,
- smb2.SMB2_ECHO:            self.__smb2CommandsHandler.smb2Echo,
- smb2.SMB2_QUERY_DIRECTORY: self.__smb2CommandsHandler.smb2QueryDirectory,
- smb2.SMB2_CHANGE_NOTIFY:   self.__smb2CommandsHandler.smb2ChangeNotify,
- smb2.SMB2_QUERY_INFO:      self.__smb2CommandsHandler.smb2QueryInfo,
- smb2.SMB2_SET_INFO:        self.__smb2CommandsHandler.smb2SetInfo,
-# smb2.SMB2_OPLOCK_BREAK:    self.__smb2CommandsHandler.smb2SessionSetup,
- 0xFF:                      self.__smb2CommandsHandler.default
-}
-
-        # List of active connections
-        self.__activeConnections = {}
-
-    def getIoctls(self):
-        return self.__smb2Ioctls
-
-    def getCredentials(self):
-        return self.__credentials
-
-    def removeConnection(self, name):
-        try:
-           del(self.__activeConnections[name])
-        except:
-           pass
-        self.log("Remaining connections %s" % self.__activeConnections.keys())
-
-    def addConnection(self, name, ip, port):
-        self.__activeConnections[name] = {}
-        # Let's init with some know stuff we will need to have
-        # TODO: Document what's in there
-        #print "Current Connections", self.__activeConnections.keys()
-        self.__activeConnections[name]['PacketNum']       = 0
-        self.__activeConnections[name]['ClientIP']        = ip
-        self.__activeConnections[name]['ClientPort']      = port
-        self.__activeConnections[name]['Uid']             = 0
-        self.__activeConnections[name]['ConnectedShares'] = {}
-        self.__activeConnections[name]['OpenedFiles']     = {}
-        # SID results for findfirst2
-        self.__activeConnections[name]['SIDs']            = {}
-        self.__activeConnections[name]['LastRequest']     = {}
-
-    def getActiveConnections(self):
-        return self.__activeConnections
-
-    def setConnectionData(self, connId, data):
-        self.__activeConnections[connId] = data
-        #print "setConnectionData"
-        #print self.__activeConnections
-
-    def getConnectionData(self, connId, checkStatus = True):
-        conn = self.__activeConnections[connId]
-        if checkStatus is True:
-            if ('Authenticated' in conn) is not True:
-                # Can't keep going further
-                raise Exception("User not Authenticated!")
-        return conn
-
-    def getRegisteredNamedPipes(self):
-        return self.__registeredNamedPipes
-
-    def registerNamedPipe(self, pipeName, address):
-        self.__registeredNamedPipes[unicode(pipeName)] = address
-        return True
-
-    def unregisterNamedPipe(self, pipeName):
-        if pipeName in self.__registeredNamedPipes:
-            del(self.__registeredNamedPipes[unicode(pipeName)])
-            return True
-        return False
-
-    def unregisterTransaction(self, transCommand):
-        if transCommand in self.__smbTransCommands:
-           del(self.__smbTransCommands[transCommand])
-
-    def hookTransaction(self, transCommand, callback):
-        # If you call this function, callback will replace
-        # the current Transaction sub command.
-        # (don't get confused with the Transaction smbCommand)
-        # If the transaction sub command doesn't not exist, it is added
-        # If the transaction sub command exists, it returns the original 
function         # replaced
-        #
-        # callback MUST be declared as:
-        # callback(connId, smbServer, recvPacket, parameters, data, 
maxDataCount=0)
-        #
-        # WHERE:
-        #
-        # connId      : the connection Id, used to grab/update information 
about
-        #               the current connection
-        # smbServer   : the SMBServer instance available for you to ask
-        #               configuration data
-        # recvPacket  : the full SMBPacket that triggered this command
-        # parameters  : the transaction parameters
-        # data        : the transaction data
-        # maxDataCount: the max amount of data that can be transfered agreed
-        #               with the client
-        #
-        # and MUST return:
-        # respSetup, respParameters, respData, errorCode
-        #
-        # WHERE:
-        #
-        # respSetup: the setup response of the transaction
-        # respParameters: the parameters response of the transaction
-        # respData: the data reponse of the transaction
-        # errorCode: the NT error code
-
-        if transCommand in self.__smbTransCommands:
-           originalCommand = self.__smbTransCommands[transCommand]
-        else:
-           originalCommand = None
-
-        self.__smbTransCommands[transCommand] = callback
-        return originalCommand
-
-    def unregisterTransaction2(self, transCommand):
-        if transCommand in self.__smbTrans2Commands:
-           del(self.__smbTrans2Commands[transCommand])
-
-    def hookTransaction2(self, transCommand, callback):
-        # Here we should add to __smbTrans2Commands
-        # Same description as Transaction
-        if transCommand in self.__smbTrans2Commands:
-           originalCommand = self.__smbTrans2Commands[transCommand]
-        else:
-           originalCommand = None
-
-        self.__smbTrans2Commands[transCommand] = callback
-        return originalCommand
-
-    def unregisterNTTransaction(self, transCommand):
-        if transCommand in self.__smbNTTransCommands:
-           del(self.__smbNTTransCommands[transCommand])
-
-    def hookNTTransaction(self, transCommand, callback):
-        # Here we should add to __smbNTTransCommands
-        # Same description as Transaction
-        if transCommand in self.__smbNTTransCommands:
-           originalCommand = self.__smbNTTransCommands[transCommand]
-        else:
-           originalCommand = None
-
-        self.__smbNTTransCommands[transCommand] = callback
-        return originalCommand
-
-    def unregisterSmbCommand(self, smbCommand):
-        if smbCommand in self.__smbCommands:
-           del(self.__smbCommands[smbCommand])
-
-    def hookSmbCommand(self, smbCommand, callback):
-        # Here we should add to self.__smbCommands
-        # If you call this function, callback will replace
-        # the current smbCommand.
-        # If smbCommand doesn't not exist, it is added
-        # If SMB command exists, it returns the original function replaced
-        #
-        # callback MUST be declared as:
-        # callback(connId, smbServer, SMBCommand, recvPacket)
-        #
-        # WHERE:
-        #
-        # connId    : the connection Id, used to grab/update information about
-        #             the current connection
-        # smbServer : the SMBServer instance available for you to ask
-        #             configuration data
-        # SMBCommand: the SMBCommand itself, with its data and parameters.
-        #             Check smb.py:SMBCommand() for a reference
-        # recvPacket: the full SMBPacket that triggered this command
-        #
-        # and MUST return:
-        # <list of respSMBCommands>, <list of packets>, errorCode
-        # <list of packets> has higher preference over commands, in case you
-        # want to change the whole packet
-        # errorCode: the NT error code
-        #
-        # For SMB_COM_TRANSACTION2, SMB_COM_TRANSACTION and SMB_COM_NT_TRANSACT
-        # the callback function is slightly different:
-        #
-        # callback(connId, smbServer, SMBCommand, recvPacket, transCommands)
-        #
-        # WHERE:
-        #
-        # transCommands: a list of transaction subcommands already registered
-        #
-
-        if smbCommand in self.__smbCommands:
-           originalCommand = self.__smbCommands[smbCommand]
-        else:
-           originalCommand = None
-
-        self.__smbCommands[smbCommand] = callback
-        return originalCommand
-
-    def unregisterSmb2Command(self, smb2Command):
-        if smb2Command in self.__smb2Commands:
-           del(self.__smb2Commands[smb2Command])
-
-    def hookSmb2Command(self, smb2Command, callback):
-        if smb2Command in self.__smb2Commands:
-           originalCommand = self.__smb2Commands[smb2Command]
-        else:
-           originalCommand = None
-
-        self.__smb2Commands[smb2Command] = callback
-        return originalCommand
-
-    def log(self, msg, level=logging.INFO):
-        self.__log.log(level,msg)
-
-    def getServerName(self):
-        return self.__serverName
-
-    def getServerOS(self):
-        return self.__serverOS
-
-    def getServerDomain(self):
-        return self.__serverDomain
-
-    def getSMBChallenge(self):
-        return self.__challenge
-
-    def getServerConfig(self):
-        return self.__serverConfig
-
-    def setServerConfig(self, config):
-        self.__serverConfig = config
-
-    def getJTRdumpPath(self):
-        return self.__jtr_dump_path
-
-    def verify_request(self, request, client_address):
-        # TODO: Control here the max amount of processes we want to launch
-        # returning False, closes the connection
-        return True
-
-    def processRequest(self, connId, data):
-
-        # TODO: Process batched commands.
-        isSMB2      = False
-        SMBCommand  = None
-        try:
-            packet = smb.NewSMBPacket(data = data)
-            SMBCommand  = smb.SMBCommand(packet['Data'][0])
-        except:
-            # Maybe a SMB2 packet?
-            packet = smb2.SMB2Packet(data = data)
-            isSMB2 = True
-
-        # We might have compound requests
-        compoundedPacketsResponse = []
-        compoundedPackets         = []
-        try:
-            # Search out list of implemented commands
-            # We provide them with:
-            # connId      : representing the data for this specific connection
-            # self        : the SMBSERVER if they want to ask data to it
-            # SMBCommand  : the SMBCommand they are expecting to process
-            # packet      : the received packet itself, in case they need more 
data than the actual command
-            # Only for Transactions
-            # transCommand: a list of transaction subcommands
-            # We expect to get:
-            # respCommands: a list of answers for the commands processed
-            # respPacket  : if the commands chose to directly craft packet/s, 
we use this and not the previous
-            #               this MUST be a list
-            # errorCode   : self explanatory
-            if isSMB2 is False:
-                if packet['Command'] == smb.SMB.SMB_COM_TRANSACTION2:
-                    respCommands, respPackets, errorCode = 
self.__smbCommands[packet['Command']](
-                                  connId,
-                                  self,
-                                  SMBCommand,
-                                  packet,
-                                  self.__smbTrans2Commands)
-                elif packet['Command'] == smb.SMB.SMB_COM_NT_TRANSACT:
-                    respCommands, respPackets, errorCode = 
self.__smbCommands[packet['Command']](
-                                  connId,
-                                  self,
-                                  SMBCommand,
-                                  packet,
-                                  self.__smbNTTransCommands)
-                elif packet['Command'] == smb.SMB.SMB_COM_TRANSACTION:
-                    respCommands, respPackets, errorCode = 
self.__smbCommands[packet['Command']](
-                                  connId,
-                                  self,
-                                  SMBCommand,
-                                  packet,
-                                  self.__smbTransCommands)
-                else:
-                    if packet['Command'] in self.__smbCommands:
-                       if self.__SMB2Support is True:
-                           if packet['Command'] == smb.SMB.SMB_COM_NEGOTIATE:
-                               try:
-                                   respCommands, respPackets, errorCode = 
self.__smb2Commands[smb2.SMB2_NEGOTIATE](connId, self, packet, True)
-                                   isSMB2 = True
-                               except Exception as e:
-                                   self.log('SMB2_NEGOTIATE: %s' % e, 
logging.ERROR)
-                                   # If something went wrong, let's fallback 
to SMB1
-                                   respCommands, respPackets, errorCode = 
self.__smbCommands[packet['Command']](
-                                       connId,
-                                       self,
-                                       SMBCommand,
-                                       packet)
-                                   #self.__SMB2Support = False
-                                   pass
-                           else:
-                               respCommands, respPackets, errorCode = 
self.__smbCommands[packet['Command']](
-                                       connId,
-                                       self,
-                                       SMBCommand,
-                                       packet)
-                       else:
-                           respCommands, respPackets, errorCode = 
self.__smbCommands[packet['Command']](
-                                       connId,
-                                       self,
-                                       SMBCommand,
-                                       packet)
-                    else:
-                       respCommands, respPackets, errorCode = 
self.__smbCommands[255](connId, self, SMBCommand, packet)
-
-                compoundedPacketsResponse.append((respCommands, respPackets, 
errorCode))
-                compoundedPackets.append(packet)
-
-            else:
-                done = False
-                while not done:
-                    if packet['Command'] in self.__smb2Commands:
-                       if self.__SMB2Support is True:
-                           respCommands, respPackets, errorCode = 
self.__smb2Commands[packet['Command']](
-                                   connId,
-                                   self,
-                                   packet)
-                       else:
-                           respCommands, respPackets, errorCode = 
self.__smb2Commands[255](connId, self, packet)
-                    else:
-                       respCommands, respPackets, errorCode = 
self.__smb2Commands[255](connId, self, packet)
-                    # Let's store the result for this compounded packet
-                    compoundedPacketsResponse.append((respCommands, 
respPackets, errorCode))
-                    compoundedPackets.append(packet)
-                    if packet['NextCommand'] != 0:
-                        data = data[packet['NextCommand']:]
-                        packet = smb2.SMB2Packet(data = data)
-                    else:
-                        done = True
-
-        except Exception as e:
-            #import traceback
-            #traceback.print_exc()
-            # Something wen't wrong, defaulting to Bad user ID
-            self.log('processRequest (0x%x,%s)' % (packet['Command'],e), 
logging.ERROR)
-            raise
-
-        # We prepare the response packet to commands don't need to bother 
about that.
-        connData    = self.getConnectionData(connId, False)
-
-        # Force reconnection loop.. This is just a test.. client will send me 
back credentials :)
-        #connData['PacketNum'] += 1
-        #if connData['PacketNum'] == 15:
-        #    connData['PacketNum'] = 0
-        #    # Something wen't wrong, defaulting to Bad user ID
-        #    self.log('Sending BAD USER ID!', logging.ERROR)
-        #    #raise
-        #    packet['Flags1'] |= smb.SMB.FLAGS1_REPLY
-        #    packet['Flags2'] = 0
-        #    errorCode = STATUS_SMB_BAD_UID
-        #    packet['ErrorCode']   = errorCode >> 16
-        #    packet['ErrorClass']  = errorCode & 0xff
-        #    return [packet]
-
-        self.setConnectionData(connId, connData)
-
-        packetsToSend = []
-        for packetNum in range(len(compoundedPacketsResponse)):
-            respCommands, respPackets, errorCode = 
compoundedPacketsResponse[packetNum]
-            packet = compoundedPackets[packetNum]
-            if respPackets is None:
-                for respCommand in respCommands:
-                    if isSMB2 is False:
-                        respPacket           = smb.NewSMBPacket()
-                        respPacket['Flags1'] = smb.SMB.FLAGS1_REPLY
-
-                        # TODO this should come from a per session 
configuration
-                        respPacket['Flags2'] = 
smb.SMB.FLAGS2_EXTENDED_SECURITY | smb.SMB.FLAGS2_NT_STATUS | 
smb.SMB.FLAGS2_LONG_NAMES | packet['Flags2'] & smb.SMB.FLAGS2_UNICODE
-                        #respPacket['Flags2'] = 
smb.SMB.FLAGS2_EXTENDED_SECURITY | smb.SMB.FLAGS2_NT_STATUS | 
smb.SMB.FLAGS2_LONG_NAMES
-                        #respPacket['Flags1'] = 0x98
-                        #respPacket['Flags2'] = 0xc807
-
-
-                        respPacket['Tid']    = packet['Tid']
-                        respPacket['Mid']    = packet['Mid']
-                        respPacket['Pid']    = packet['Pid']
-                        respPacket['Uid']    = connData['Uid']
-
-                        respPacket['ErrorCode']   = errorCode >> 16
-                        respPacket['_reserved']   = errorCode >> 8 & 0xff
-                        respPacket['ErrorClass']  = errorCode & 0xff
-                        respPacket.addCommand(respCommand)
-
-                        packetsToSend.append(respPacket)
-                    else:
-                        respPacket = smb2.SMB2Packet()
-                        respPacket['Flags']     = 
smb2.SMB2_FLAGS_SERVER_TO_REDIR
-                        if packetNum > 0:
-                            respPacket['Flags'] |= 
smb2.SMB2_FLAGS_RELATED_OPERATIONS
-                        respPacket['Status']    = errorCode
-                        respPacket['CreditRequestResponse'] = 
packet['CreditRequestResponse']
-                        respPacket['Command']   = packet['Command']
-                        respPacket['CreditCharge'] = packet['CreditCharge']
-                        #respPacket['CreditCharge'] = 0
-                        respPacket['Reserved']  = packet['Reserved']
-                        respPacket['SessionID'] = connData['Uid']
-                        respPacket['MessageID'] = packet['MessageID']
-                        respPacket['TreeID']    = packet['TreeID']
-                        respPacket['Data']      = str(respCommand)
-                        packetsToSend.append(respPacket)
-            else:
-                # The SMBCommand took care of building the packet
-                packetsToSend = respPackets
-
-        if isSMB2 is True:
-            # Let's build a compound answer
-            finalData = ''
-            i = 0
-            for i in range(len(packetsToSend)-1):
-                packet = packetsToSend[i]
-                # Align to 8-bytes
-                padLen = (8 - (len(packet) % 8) ) % 8
-                packet['NextCommand'] = len(packet) + padLen
-                finalData += str(packet) + padLen*'\x00'
-
-            # Last one
-            finalData += str(packetsToSend[len(packetsToSend)-1])
-            packetsToSend = [finalData]
-
-        # We clear the compound requests
-        connData['LastRequest'] = {}
-
-        return packetsToSend
-
-    def processConfigFile(self, configFile = None):
-        # TODO: Do a real config parser
-        if self.__serverConfig is None:
-            if configFile is None:
-                configFile = 'smb.conf'
-            self.__serverConfig = configparser.ConfigParser()
-            self.__serverConfig.read(configFile)
-
-        self.__serverName   = self.__serverConfig.get('global','server_name')
-        self.__serverOS     = self.__serverConfig.get('global','server_os')
-        self.__serverDomain = self.__serverConfig.get('global','server_domain')
-        self.__logFile      = self.__serverConfig.get('global','log_file')
-        if self.__serverConfig.has_option('global', 'challenge'):
-            self.__challenge    = self.__serverConfig.get('global', 
'challenge')
-        else:
-            self.__challenge    = 'A'*8
-
-        if self.__serverConfig.has_option("global", "jtr_dump_path"):
-            self.__jtr_dump_path = self.__serverConfig.get("global", 
"jtr_dump_path")
-
-        if self.__serverConfig.has_option("global", "SMB2Support"):
-            self.__SMB2Support = 
self.__serverConfig.getboolean("global","SMB2Support")
-        else:
-            self.__SMB2Support = False
-
-        if self.__logFile != 'None':
-            logging.basicConfig(filename = self.__logFile,
-                             level = logging.DEBUG,
-                             format="%(asctime)s: %(levelname)s: %(message)s",
-                             datefmt = '%m/%d/%Y %I:%M:%S %p')
-        self.__log        = LOG
-
-        # Process the credentials
-        credentials_fname = 
self.__serverConfig.get('global','credentials_file')
-        if credentials_fname is not "":
-            cred = open(credentials_fname)
-            line = cred.readline()
-            while line:
-                name, domain, lmhash, nthash = line.split(':')
-                self.__credentials[name] = (domain, lmhash, 
nthash.strip('\r\n'))
-                line = cred.readline()
-            cred.close()
-        self.log('Config file parsed')
-
-# For windows platforms, opening a directory is not an option, so we set a 
void FD
-VOID_FILE_DESCRIPTOR = -1
-PIPE_FILE_DESCRIPTOR = -2
diff --git a/tests/python_dependencies/impacket/spnego.py 
b/tests/python_dependencies/impacket/spnego.py
deleted file mode 100644
index 98069f579..000000000
--- a/tests/python_dependencies/impacket/spnego.py
+++ /dev/null
@@ -1,372 +0,0 @@
-from __future__ import print_function
-# Copyright (c) 2003-2016 CORE Security Technologies
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-# Author: Alberto Solino (address@hidden)
-#
-# Description:
-#   SPNEGO functions used by SMB, SMB2/3 and DCERPC
-#
-
-from struct import pack, unpack, calcsize
-
-############### GSS Stuff ################
-GSS_API_SPNEGO_UUID              = '\x2b\x06\x01\x05\x05\x02'
-ASN1_SEQUENCE                    = 0x30
-ASN1_AID                         = 0x60
-ASN1_OID                         = 0x06
-ASN1_OCTET_STRING                = 0x04
-ASN1_MECH_TYPE                   = 0xa0
-ASN1_MECH_TOKEN                  = 0xa2
-ASN1_SUPPORTED_MECH              = 0xa1
-ASN1_RESPONSE_TOKEN              = 0xa2
-ASN1_ENUMERATED                  = 0x0a
-MechTypes = {
-'+\x06\x01\x04\x01\x827\x02\x02\x1e': 'SNMPv2-SMI::enterprises.311.2.2.30',
-'+\x06\x01\x04\x01\x827\x02\x02\n': 'NTLMSSP - Microsoft NTLM Security Support 
Provider',
-'*\x86H\x82\xf7\x12\x01\x02\x02': 'MS KRB5 - Microsoft Kerberos 5',
-'*\x86H\x86\xf7\x12\x01\x02\x02': 'KRB5 - Kerberos 5',
-'*\x86H\x86\xf7\x12\x01\x02\x02\x03': 'KRB5 - Kerberos 5 - User to User'
-}
-TypesMech = dict((v,k) for k, v in MechTypes.iteritems())
-
-def asn1encode(data = ''):
-    #res = asn1.SEQUENCE(str).encode()
-    #import binascii
-    #print '\nalex asn1encode str: %s\n' % binascii.hexlify(str)
-    if 0 <= len(data) <= 0x7F:
-        res = pack('B', len(data)) + data
-    elif 0x80 <= len(data) <= 0xFF:
-        res = pack('BB', 0x81, len(data)) + data
-    elif 0x100 <= len(data) <= 0xFFFF:
-        res = pack('!BH', 0x82, len(data)) + data
-    elif 0x10000 <= len(data) <= 0xffffff:
-        res = pack('!BBH', 0x83, len(data) >> 16, len(data) & 0xFFFF) + data
-    elif 0x1000000 <= len(data) <= 0xffffffff:
-        res = pack('!BL', 0x84, len(data)) + data
-    else:
-        raise Exception('Error in asn1encode')
-    return str(res)
-
-def asn1decode(data = ''):
-    len1 = unpack('B', data[:1])[0]
-    data = data[1:]
-    if len1 == 0x81:
-        pad = calcsize('B')
-        len2 = unpack('B',data[:pad])[0]
-        data = data[pad:]
-        ans = data[:len2]
-    elif len1 == 0x82:
-        pad = calcsize('H')
-        len2 = unpack('!H', data[:pad])[0]
-        data = data[pad:]
-        ans = data[:len2]
-    elif len1 == 0x83:
-        pad = calcsize('B') + calcsize('!H')
-        len2, len3 = unpack('!BH', data[:pad])
-        data = data[pad:]
-        ans = data[:len2 << 16 + len3]
-    elif len1 == 0x84:
-        pad = calcsize('!L')
-        len2 = unpack('!L', data[:pad])[0]
-        data = data[pad:]
-        ans = data[:len2]
-    # 1 byte length, string <= 0x7F
-    else:
-        pad = 0
-        ans = data[:len1]
-    return ans, len(ans)+pad+1
-
-class GSSAPI:
-# Generic GSSAPI Header Format
-    def __init__(self, data = None):
-        self.fields = {}
-        self['UUID'] = GSS_API_SPNEGO_UUID
-        if data:
-            self.fromString(data)
-        pass
-
-    def __setitem__(self,key,value):
-        self.fields[key] = value
-
-    def __getitem__(self, key):
-        return self.fields[key]
-
-    def __delitem__(self, key):
-        del self.fields[key]
-
-    def __len__(self):
-        return len(self.getData())
-
-    def __str__(self):
-        return len(self.getData())
-
-    def fromString(self, data = None):
-        # Manual parse of the GSSAPI Header Format
-        # It should be something like
-        # AID = 0x60 TAG, BER Length
-        # OID = 0x06 TAG
-        # GSSAPI OID
-        # UUID data (BER Encoded)
-        # Payload
-        next_byte = unpack('B',data[:1])[0]
-        if next_byte != ASN1_AID:
-            raise Exception('Unknown AID=%x' % next_byte)
-        data = data[1:]
-        decode_data, total_bytes = asn1decode(data)
-        # Now we should have a OID tag
-        next_byte = unpack('B',decode_data[:1])[0]
-        if next_byte !=  ASN1_OID:
-            raise Exception('OID tag not found %x' % next_byte)
-        decode_data = decode_data[1:]
-        # Now the OID contents, should be SPNEGO UUID
-        uuid, total_bytes = asn1decode(decode_data)
-        self['OID'] = uuid
-        # the rest should be the data
-        self['Payload'] = decode_data[total_bytes:]
-        #pass
-
-    def dump(self):
-        for i in self.fields.keys():
-            print("%s: {%r}" % (i,self[i]))
-
-    def getData(self):
-        ans = pack('B',ASN1_AID)
-        ans += asn1encode(
-               pack('B',ASN1_OID) +
-               asn1encode(self['UUID']) +
-               self['Payload'] )
-        return ans
-
-class SPNEGO_NegTokenResp:
-    # http://tools.ietf.org/html/rfc4178#page-9
-    # NegTokenResp ::= SEQUENCE {
-    #     negState       [0] ENUMERATED {
-    #         accept-completed    (0),
-    #         accept-incomplete   (1),
-    #         reject              (2),
-    #         request-mic         (3)
-    #     }                                 OPTIONAL,
-    #       -- REQUIRED in the first reply from the target
-    #     supportedMech   [1] MechType      OPTIONAL,
-    #       -- present only in the first reply from the target
-    #     responseToken   [2] OCTET STRING  OPTIONAL,
-    #     mechListMIC     [3] OCTET STRING  OPTIONAL,
-    #     ...
-    # }
-    # This structure is not prepended by a GSS generic header!
-    SPNEGO_NEG_TOKEN_RESP = 0xa1
-    SPNEGO_NEG_TOKEN_TARG = 0xa0
-
-    def __init__(self, data = None):
-        self.fields = {}
-        if data:
-            self.fromString(data)
-        pass
-
-    def __setitem__(self,key,value):
-        self.fields[key] = value
-
-    def __getitem__(self, key):
-        return self.fields[key]
-
-    def __delitem__(self, key):
-        del self.fields[key]
-
-    def __len__(self):
-        return len(self.getData())
-
-    def __str__(self):
-        return len(self.getData())
-
-    def fromString(self, data = 0):
-        payload = data
-        next_byte = unpack('B', payload[:1])[0]
-        if next_byte != SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
-            raise Exception('NegTokenResp not found %x' % next_byte)
-        payload = payload[1:]
-        decode_data, total_bytes = asn1decode(payload)
-        next_byte = unpack('B', decode_data[:1])[0]
-        if next_byte != ASN1_SEQUENCE:
-            raise Exception('SEQUENCE tag not found %x' % next_byte)
-        decode_data = decode_data[1:]
-        decode_data, total_bytes = asn1decode(decode_data)
-        next_byte = unpack('B',decode_data[:1])[0]
-
-        if next_byte != ASN1_MECH_TYPE:
-            # MechType not found, could be an AUTH answer
-            if next_byte != ASN1_RESPONSE_TOKEN:
-                raise Exception('MechType/ResponseToken tag not found %x' % 
next_byte)
-        else:
-            decode_data2 = decode_data[1:]
-            decode_data2, total_bytes = asn1decode(decode_data2)
-            next_byte = unpack('B', decode_data2[:1])[0]
-            if next_byte != ASN1_ENUMERATED:
-                raise Exception('Enumerated tag not found %x' % next_byte)
-            item, total_bytes2 = asn1decode(decode_data)
-            self['NegResult'] = item
-            decode_data = decode_data[1:]
-            decode_data = decode_data[total_bytes:]
-
-            # Do we have more data?
-            if len(decode_data) == 0:
-                return
-
-            next_byte = unpack('B', decode_data[:1])[0]
-            if next_byte != ASN1_SUPPORTED_MECH:
-                if next_byte != ASN1_RESPONSE_TOKEN:
-                    raise Exception('Supported Mech/ResponseToken tag not 
found %x' % next_byte)
-            else:
-                decode_data2 = decode_data[1:]
-                decode_data2, total_bytes = asn1decode(decode_data2)
-                next_byte = unpack('B', decode_data2[:1])[0]
-                if next_byte != ASN1_OID:
-                    raise Exception('OID tag not found %x' % next_byte)
-                decode_data2 = decode_data2[1:]
-                item, total_bytes2 = asn1decode(decode_data2)
-                self['SupportedMech'] = item
-
-                decode_data = decode_data[1:]
-                decode_data = decode_data[total_bytes:]
-                next_byte = unpack('B', decode_data[:1])[0]
-                if next_byte != ASN1_RESPONSE_TOKEN:
-                    raise Exception('Response token tag not found %x' % 
next_byte)
-
-        decode_data = decode_data[1:]
-        decode_data, total_bytes = asn1decode(decode_data)
-        next_byte = unpack('B', decode_data[:1])[0]
-        if next_byte != ASN1_OCTET_STRING:
-            raise Exception('Octet string token tag not found %x' % next_byte)
-        decode_data = decode_data[1:]
-        decode_data, total_bytes = asn1decode(decode_data)
-        self['ResponseToken'] = decode_data
-
-    def dump(self):
-        for i in self.fields.keys():
-            print("%s: {%r}" % (i,self[i]))
-
-    def getData(self):
-        ans = pack('B',SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP)
-        if 'NegResult' in self.fields and 'SupportedMech' in self.fields:
-            # Server resp
-            ans += asn1encode(
-               pack('B', ASN1_SEQUENCE) +
-               asn1encode(
-               pack('B',SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_TARG) +
-               asn1encode(
-               pack('B',ASN1_ENUMERATED) +
-               asn1encode( self['NegResult'] )) +
-               pack('B',ASN1_SUPPORTED_MECH) +
-               asn1encode(
-               pack('B',ASN1_OID) +
-               asn1encode(self['SupportedMech'])) +
-               pack('B',ASN1_RESPONSE_TOKEN ) +
-               asn1encode(
-               pack('B', ASN1_OCTET_STRING) + 
asn1encode(self['ResponseToken']))))
-        elif 'NegResult' in self.fields:
-            # Server resp
-            ans += asn1encode(
-               pack('B', ASN1_SEQUENCE) +
-               asn1encode(
-               pack('B', SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_TARG) +
-               asn1encode(
-               pack('B',ASN1_ENUMERATED) +
-               asn1encode( self['NegResult'] ))))
-        else:
-            # Client resp
-            ans += asn1encode(
-               pack('B', ASN1_SEQUENCE) +
-               asn1encode(
-               pack('B', ASN1_RESPONSE_TOKEN) +
-               asn1encode(
-               pack('B', ASN1_OCTET_STRING) + 
asn1encode(self['ResponseToken']))))
-        return ans
-
-class SPNEGO_NegTokenInit(GSSAPI):
-    # http://tools.ietf.org/html/rfc4178#page-8
-    # NegTokeInit :: = SEQUENCE {
-    #   mechTypes       [0] MechTypeList,
-    #   reqFlags        [1] ContextFlags OPTIONAL,
-    #   mechToken       [2] OCTET STRING OPTIONAL,
-    #   mechListMIC     [3] OCTET STRING OPTIONAL,
-    # }
-    SPNEGO_NEG_TOKEN_INIT = 0xa0
-    def fromString(self, data = 0):
-        GSSAPI.fromString(self, data)
-        payload = self['Payload']
-        next_byte = unpack('B', payload[:1])[0]
-        if next_byte != SPNEGO_NegTokenInit.SPNEGO_NEG_TOKEN_INIT:
-            raise Exception('NegTokenInit not found %x' % next_byte)
-        payload = payload[1:]
-        decode_data, total_bytes = asn1decode(payload)
-        # Now we should have a SEQUENCE Tag
-        next_byte = unpack('B', decode_data[:1])[0]
-        if next_byte != ASN1_SEQUENCE:
-            raise Exception('SEQUENCE tag not found %x' % next_byte)
-        decode_data = decode_data[1:]
-        decode_data, total_bytes2 = asn1decode(decode_data)
-        next_byte = unpack('B',decode_data[:1])[0]
-        if next_byte != ASN1_MECH_TYPE:
-            raise Exception('MechType tag not found %x' % next_byte)
-        decode_data = decode_data[1:]
-        remaining_data = decode_data
-        decode_data, total_bytes3 = asn1decode(decode_data)
-        next_byte = unpack('B', decode_data[:1])[0]
-        if next_byte != ASN1_SEQUENCE:
-            raise Exception('SEQUENCE tag not found %x' % next_byte)
-        decode_data = decode_data[1:]
-        decode_data, total_bytes4 = asn1decode(decode_data)
-        # And finally we should have the MechTypes
-        self['MechTypes'] = []
-        while decode_data:
-            next_byte = unpack('B', decode_data[:1])[0]
-            if next_byte != ASN1_OID:
-            # Not a valid OID, there must be something else we won't unpack
-                break
-            decode_data = decode_data[1:]
-            item, total_bytes = asn1decode(decode_data)
-            self['MechTypes'].append(item)
-            decode_data = decode_data[total_bytes:]
-
-        # Do we have MechTokens as well?
-        decode_data = remaining_data[total_bytes3:]
-        if len(decode_data) > 0:
-            next_byte = unpack('B', decode_data[:1])[0]
-            if next_byte == ASN1_MECH_TOKEN:
-                # We have tokens in here!
-                decode_data = decode_data[1:]
-                decode_data, total_bytes = asn1decode(decode_data)
-                next_byte = unpack('B', decode_data[:1])[0]
-                if next_byte ==  ASN1_OCTET_STRING:
-                    decode_data = decode_data[1:]
-                    decode_data, total_bytes = asn1decode(decode_data)
-                    self['MechToken'] =  decode_data
-
-    def getData(self):
-        mechTypes = ''
-        for i in self['MechTypes']:
-            mechTypes += pack('B', ASN1_OID)
-            mechTypes += asn1encode(i)
-
-        mechToken = ''
-        # Do we have tokens to send?
-        if 'MechToken' in self.fields:
-            mechToken = pack('B', ASN1_MECH_TOKEN) + asn1encode(
-                pack('B', ASN1_OCTET_STRING) + asn1encode(
-                    self['MechToken']))
-
-        ans = pack('B',SPNEGO_NegTokenInit.SPNEGO_NEG_TOKEN_INIT)
-        ans += asn1encode(
-               pack('B', ASN1_SEQUENCE) +
-               asn1encode(
-               pack('B', ASN1_MECH_TYPE) +
-               asn1encode(
-               pack('B', ASN1_SEQUENCE) +
-               asn1encode(mechTypes)) + mechToken ))
-
-
-        self['Payload'] = ans
-        return GSSAPI.getData(self)
diff --git a/tests/python_dependencies/impacket/structure.py 
b/tests/python_dependencies/impacket/structure.py
deleted file mode 100644
index 68066a61f..000000000
--- a/tests/python_dependencies/impacket/structure.py
+++ /dev/null
@@ -1,744 +0,0 @@
-from __future__ import print_function
-# Copyright (c) 2003-2016 CORE Security Technologies
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-
-from struct import pack, unpack, calcsize
-
-class Structure:
-    """ sublcasses can define commonHdr and/or structure.
-        each of them is an tuple of either two: (fieldName, format) or three: 
(fieldName, ':', class) fields.
-        [it can't be a dictionary, because order is important]
-        
-        where format specifies how the data in the field will be converted 
to/from bytes (string)
-        class is the class to use when unpacking ':' fields.
-
-        each field can only contain one value (or an array of values for *)
-           i.e. struct.pack('Hl',1,2) is valid, but format specifier 'Hl' is 
not (you must use 2 dfferent fields)
-
-        format specifiers:
-          specifiers from module pack can be used with the same format 
-          see struct.__doc__ (pack/unpack is finally called)
-            x       [padding byte]
-            c       [character]
-            b       [signed byte]
-            B       [unsigned byte]
-            h       [signed short]
-            H       [unsigned short]
-            l       [signed long]
-            L       [unsigned long]
-            i       [signed integer]
-            I       [unsigned integer]
-            q       [signed long long (quad)]
-            Q       [unsigned long long (quad)]
-            s       [string (array of chars), must be preceded with length in 
format specifier, padded with zeros]
-            p       [pascal string (includes byte count), must be preceded 
with length in format specifier, padded with zeros]
-            f       [float]
-            d       [double]
-            =       [native byte ordering, size and alignment]
-            @       [native byte ordering, standard size and alignment]
-            !       [network byte ordering]
-            <       [little endian]
-            >       [big endian]
-
-          usual printf like specifiers can be used (if started with %) 
-          [not recommeneded, there is no why to unpack this]
-
-            %08x    will output an 8 bytes hex
-            %s      will output a string
-            %s\\x00  will output a NUL terminated string
-            %d%d    will output 2 decimal digits (against the very same 
specification of Structure)
-            ...
-
-          some additional format specifiers:
-            :       just copy the bytes from the field into the output string 
(input may be string, other structure, or anything responding to __str__()) 
(for unpacking, all what's left is returned)
-            z       same as :, but adds a NUL byte at the end (asciiz) (for 
unpacking the first NUL byte is used as terminator)  [asciiz string]
-            u       same as z, but adds two NUL bytes at the end (after 
padding to an even size with NULs). (same for unpacking) [unicode string]
-            w       DCE-RPC/NDR string (it's a macro for [  
'<L=(len(field)+1)/2','"\\x00\\x00\\x00\\x00','<L=(len(field)+1)/2',':' ]
-            ?-field length of field named 'field', formated as specified with 
? ('?' may be '!H' for example). The input value overrides the real length
-            ?1*?2   array of elements. Each formated as '?2', the number of 
elements in the array is stored as specified by '?1' (?1 is optional, or can 
also be a constant (number), for unpacking)
-            'xxxx   literal xxxx (field's value doesn't change the output. 
quotes must not be closed or escaped)
-            "xxxx   literal xxxx (field's value doesn't change the output. 
quotes must not be closed or escaped)
-            _       will not pack the field. Accepts a third argument, which 
is an unpack code. See _Test_UnpackCode for an example
-            ?=packcode  will evaluate packcode in the context of the 
structure, and pack the result as specified by ?. Unpacking is made plain
-            ?&fieldname "Address of field fieldname".
-                        For packing it will simply pack the id() of fieldname. 
Or use 0 if fieldname doesn't exists.
-                        For unpacking, it's used to know weather fieldname has 
to be unpacked or not, i.e. by adding a & field you turn another field 
(fieldname) in an optional field.
-            
-    """
-    commonHdr = ()
-    structure = ()
-    debug = 0
-
-    def __init__(self, data = None, alignment = 0):
-        if not hasattr(self, 'alignment'):
-            self.alignment = alignment
-
-        self.fields    = {}
-        self.rawData   = data
-        if data is not None:
-            self.fromString(data)
-        else:
-            self.data = None
-
-    @classmethod
-    def fromFile(self, file):
-        answer = self()
-        answer.fromString(file.read(len(answer)))
-        return answer
-
-    def setAlignment(self, alignment):
-        self.alignment = alignment
-
-    def setData(self, data):
-        self.data = data
-
-    def packField(self, fieldName, format = None):
-        if self.debug:
-            print("packField( %s | %s )" % (fieldName, format))
-
-        if format is None:
-            format = self.formatForField(fieldName)
-
-        if fieldName in self.fields:
-            ans = self.pack(format, self.fields[fieldName], field = fieldName)
-        else:
-            ans = self.pack(format, None, field = fieldName)
-
-        if self.debug:
-            print("\tanswer %r" % ans)
-
-        return ans
-
-    def getData(self):
-        if self.data is not None:
-            return self.data
-        data = ''
-        for field in self.commonHdr+self.structure:
-            try:
-                data += self.packField(field[0], field[1])
-            except Exception as e:
-                if field[0] in self.fields:
-                    e.args += ("When packing field '%s | %s | %r' in %s" % 
(field[0], field[1], self[field[0]], self.__class__),)
-                else:
-                    e.args += ("When packing field '%s | %s' in %s" % 
(field[0], field[1], self.__class__),)
-                raise
-            if self.alignment:
-                if len(data) % self.alignment:
-                    data += ('\x00'*self.alignment)[:-(len(data) % 
self.alignment)]
-            
-        #if len(data) % self.alignment: data += 
('\x00'*self.alignment)[:-(len(data) % self.alignment)]
-        return data
-
-    def fromString(self, data):
-        self.rawData = data
-        for field in self.commonHdr+self.structure:
-            if self.debug:
-                print("fromString( %s | %s | %r )" % (field[0], field[1], 
data))
-            size = self.calcUnpackSize(field[1], data, field[0])
-            if self.debug:
-                print("  size = %d" % size)
-            dataClassOrCode = str
-            if len(field) > 2:
-                dataClassOrCode = field[2]
-            try:
-                self[field[0]] = self.unpack(field[1], data[:size], 
dataClassOrCode = dataClassOrCode, field = field[0])
-            except Exception as e:
-                e.args += ("When unpacking field '%s | %s | %r[:%d]'" % 
(field[0], field[1], data, size),)
-                raise
-
-            size = self.calcPackSize(field[1], self[field[0]], field[0])
-            if self.alignment and size % self.alignment:
-                size += self.alignment - (size % self.alignment)
-            data = data[size:]
-
-        return self
-        
-    def __setitem__(self, key, value):
-        self.fields[key] = value
-        self.data = None        # force recompute
-
-    def __getitem__(self, key):
-        return self.fields[key]
-
-    def __delitem__(self, key):
-        del self.fields[key]
-        
-    def __str__(self):
-        return self.getData()
-
-    def __len__(self):
-        # XXX: improve
-        return len(self.getData())
-
-    def pack(self, format, data, field = None):
-        if self.debug:
-            print("  pack( %s | %r | %s)" %  (format, data, field))
-
-        if field:
-            addressField = self.findAddressFieldFor(field)
-            if (addressField is not None) and (data is None):
-                return ''
-
-        # void specifier
-        if format[:1] == '_':
-            return ''
-
-        # quote specifier
-        if format[:1] == "'" or format[:1] == '"':
-            return format[1:]
-
-        # code specifier
-        two = format.split('=')
-        if len(two) >= 2:
-            try:
-                return self.pack(two[0], data)
-            except:
-                fields = {'self':self}
-                fields.update(self.fields)
-                return self.pack(two[0], eval(two[1], {}, fields))
-
-        # address specifier
-        two = format.split('&')
-        if len(two) == 2:
-            try:
-                return self.pack(two[0], data)
-            except:
-                if (two[1] in self.fields) and (self[two[1]] is not None):
-                    return self.pack(two[0], id(self[two[1]]) & 
((1<<(calcsize(two[0])*8))-1) )
-                else:
-                    return self.pack(two[0], 0)
-
-        # length specifier
-        two = format.split('-')
-        if len(two) == 2:
-            try:
-                return self.pack(two[0],data)
-            except:
-                return self.pack(two[0], self.calcPackFieldSize(two[1]))
-
-        # array specifier
-        two = format.split('*')
-        if len(two) == 2:
-            answer = ''
-            for each in data:
-                answer += self.pack(two[1], each)
-            if two[0]:
-                if two[0].isdigit():
-                    if int(two[0]) != len(data):
-                        raise Exception("Array field has a constant size, and 
it doesn't match the actual value")
-                else:
-                    return self.pack(two[0], len(data))+answer
-            return answer
-
-        # "printf" string specifier
-        if format[:1] == '%':
-            # format string like specifier
-            return format % data
-
-        # asciiz specifier
-        if format[:1] == 'z':
-            return str(data)+'\0'
-
-        # unicode specifier
-        if format[:1] == 'u':
-            return str(data)+'\0\0' + (len(data) & 1 and '\0' or '')
-
-        # DCE-RPC/NDR string specifier
-        if format[:1] == 'w':
-            if len(data) == 0:
-                data = '\0\0'
-            elif len(data) % 2:
-                data += '\0'
-            l = pack('<L', len(data)/2)
-            return '%s\0\0\0\0%s%s' % (l,l,data)
-                    
-        if data is None:
-            raise Exception("Trying to pack None")
-        
-        # literal specifier
-        if format[:1] == ':':
-            return str(data)
-
-        # struct like specifier
-        return pack(format, data)
-
-    def unpack(self, format, data, dataClassOrCode = str, field = None):
-        if self.debug:
-            print("  unpack( %s | %r )" %  (format, data))
-
-        if field:
-            addressField = self.findAddressFieldFor(field)
-            if addressField is not None:
-                if not self[addressField]:
-                    return
-
-        # void specifier
-        if format[:1] == '_':
-            if dataClassOrCode != str:
-                fields = {'self':self, 'inputDataLeft':data}
-                fields.update(self.fields)
-                return eval(dataClassOrCode, {}, fields)
-            else:
-                return None
-
-        # quote specifier
-        if format[:1] == "'" or format[:1] == '"':
-            answer = format[1:]
-            if answer != data:
-                raise Exception("Unpacked data doesn't match constant value 
'%r' should be '%r'" % (data, answer))
-            return answer
-
-        # address specifier
-        two = format.split('&')
-        if len(two) == 2:
-            return self.unpack(two[0],data)
-
-        # code specifier
-        two = format.split('=')
-        if len(two) >= 2:
-            return self.unpack(two[0],data)
-
-        # length specifier
-        two = format.split('-')
-        if len(two) == 2:
-            return self.unpack(two[0],data)
-
-        # array specifier
-        two = format.split('*')
-        if len(two) == 2:
-            answer = []
-            sofar = 0
-            if two[0].isdigit():
-                number = int(two[0])
-            elif two[0]:
-                sofar += self.calcUnpackSize(two[0], data)
-                number = self.unpack(two[0], data[:sofar])
-            else:
-                number = -1
-
-            while number and sofar < len(data):
-                nsofar = sofar + self.calcUnpackSize(two[1],data[sofar:])
-                answer.append(self.unpack(two[1], data[sofar:nsofar], 
dataClassOrCode))
-                number -= 1
-                sofar = nsofar
-            return answer
-
-        # "printf" string specifier
-        if format[:1] == '%':
-            # format string like specifier
-            return format % data
-
-        # asciiz specifier
-        if format == 'z':
-            if data[-1] != '\x00':
-                raise Exception("%s 'z' field is not NUL terminated: %r" % 
(field, data))
-            return data[:-1] # remove trailing NUL
-
-        # unicode specifier
-        if format == 'u':
-            if data[-2:] != '\x00\x00':
-                raise Exception("%s 'u' field is not NUL-NUL terminated: %r" % 
(field, data))
-            return data[:-2] # remove trailing NUL
-
-        # DCE-RPC/NDR string specifier
-        if format == 'w':
-            l = unpack('<L', data[:4])[0]
-            return data[12:12+l*2]
-
-        # literal specifier
-        if format == ':':
-            return dataClassOrCode(data)
-
-        # struct like specifier
-        return unpack(format, data)[0]
-
-    def calcPackSize(self, format, data, field = None):
-#        # print "  calcPackSize  %s:%r" %  (format, data)
-        if field:
-            addressField = self.findAddressFieldFor(field)
-            if addressField is not None:
-                if not self[addressField]:
-                    return 0
-
-        # void specifier
-        if format[:1] == '_':
-            return 0
-
-        # quote specifier
-        if format[:1] == "'" or format[:1] == '"':
-            return len(format)-1
-
-        # address specifier
-        two = format.split('&')
-        if len(two) == 2:
-            return self.calcPackSize(two[0], data)
-
-        # code specifier
-        two = format.split('=')
-        if len(two) >= 2:
-            return self.calcPackSize(two[0], data)
-
-        # length specifier
-        two = format.split('-')
-        if len(two) == 2:
-            return self.calcPackSize(two[0], data)
-
-        # array specifier
-        two = format.split('*')
-        if len(two) == 2:
-            answer = 0
-            if two[0].isdigit():
-                    if int(two[0]) != len(data):
-                        raise Exception("Array field has a constant size, and 
it doesn't match the actual value")
-            elif two[0]:
-                answer += self.calcPackSize(two[0], len(data))
-
-            for each in data:
-                answer += self.calcPackSize(two[1], each)
-            return answer
-
-        # "printf" string specifier
-        if format[:1] == '%':
-            # format string like specifier
-            return len(format % data)
-
-        # asciiz specifier
-        if format[:1] == 'z':
-            return len(data)+1
-
-        # asciiz specifier
-        if format[:1] == 'u':
-            l = len(data)
-            return l + (l & 1 and 3 or 2)
-
-        # DCE-RPC/NDR string specifier
-        if format[:1] == 'w':
-            l = len(data)
-            return 12+l+l % 2
-
-        # literal specifier
-        if format[:1] == ':':
-            return len(data)
-
-        # struct like specifier
-        return calcsize(format)
-
-    def calcUnpackSize(self, format, data, field = None):
-        if self.debug:
-            print("  calcUnpackSize( %s | %s | %r)" %  (field, format, data))
-
-        # void specifier
-        if format[:1] == '_':
-            return 0
-
-        addressField = self.findAddressFieldFor(field)
-        if addressField is not None:
-            if not self[addressField]:
-                return 0
-
-        try:
-            lengthField = self.findLengthFieldFor(field)
-            return self[lengthField]
-        except:
-            pass
-
-        # XXX: Try to match to actual values, raise if no match
-        
-        # quote specifier
-        if format[:1] == "'" or format[:1] == '"':
-            return len(format)-1
-
-        # address specifier
-        two = format.split('&')
-        if len(two) == 2:
-            return self.calcUnpackSize(two[0], data)
-
-        # code specifier
-        two = format.split('=')
-        if len(two) >= 2:
-            return self.calcUnpackSize(two[0], data)
-
-        # length specifier
-        two = format.split('-')
-        if len(two) == 2:
-            return self.calcUnpackSize(two[0], data)
-
-        # array specifier
-        two = format.split('*')
-        if len(two) == 2:
-            answer = 0
-            if two[0]:
-                if two[0].isdigit():
-                    number = int(two[0])
-                else:
-                    answer += self.calcUnpackSize(two[0], data)
-                    number = self.unpack(two[0], data[:answer])
-
-                while number:
-                    number -= 1
-                    answer += self.calcUnpackSize(two[1], data[answer:])
-            else:
-                while answer < len(data):
-                    answer += self.calcUnpackSize(two[1], data[answer:])
-            return answer
-
-        # "printf" string specifier
-        if format[:1] == '%':
-            raise Exception("Can't guess the size of a printf like specifier 
for unpacking")
-
-        # asciiz specifier
-        if format[:1] == 'z':
-            return data.index('\x00')+1
-
-        # asciiz specifier
-        if format[:1] == 'u':
-            l = data.index('\x00\x00')
-            return l + (l & 1 and 3 or 2)
-
-        # DCE-RPC/NDR string specifier
-        if format[:1] == 'w':
-            l = unpack('<L', data[:4])[0]
-            return 12+l*2
-
-        # literal specifier
-        if format[:1] == ':':
-            return len(data)
-
-        # struct like specifier
-        return calcsize(format)
-
-    def calcPackFieldSize(self, fieldName, format = None):
-        if format is None:
-            format = self.formatForField(fieldName)
-
-        return self.calcPackSize(format, self[fieldName])
-
-    def formatForField(self, fieldName):
-        for field in self.commonHdr+self.structure:
-            if field[0] == fieldName:
-                return field[1]
-        raise Exception("Field %s not found" % fieldName)
-
-    def findAddressFieldFor(self, fieldName):
-        descriptor = '&%s' % fieldName
-        l = len(descriptor)
-        for field in self.commonHdr+self.structure:
-            if field[1][-l:] == descriptor:
-                return field[0]
-        return None
-        
-    def findLengthFieldFor(self, fieldName):
-        descriptor = '-%s' % fieldName
-        l = len(descriptor)
-        for field in self.commonHdr+self.structure:
-            if field[1][-l:] == descriptor:
-                return field[0]
-        return None
-        
-    def zeroValue(self, format):
-        two = format.split('*')
-        if len(two) == 2:
-            if two[0].isdigit():
-                return (self.zeroValue(two[1]),)*int(two[0])
-                        
-        if not format.find('*') == -1: return ()
-        if 's' in format: return ''
-        if format in ['z',':','u']: return ''
-        if format == 'w': return '\x00\x00'
-
-        return 0
-
-    def clear(self):
-        for field in self.commonHdr + self.structure:
-            self[field[0]] = self.zeroValue(field[1])
-
-    def dump(self, msg = None, indent = 0):
-        if msg is None: msg = self.__class__.__name__
-        ind = ' '*indent
-        print("\n%s" % msg)
-        fixedFields = []
-        for field in self.commonHdr+self.structure:
-            i = field[0] 
-            if i in self.fields:
-                fixedFields.append(i)
-                if isinstance(self[i], Structure):
-                    self[i].dump('%s%s:{' % (ind,i), indent = indent + 4)
-                    print("%s}" % ind)
-                else:
-                    print("%s%s: {%r}" % (ind,i,self[i]))
-        # Do we have remaining fields not defined in the structures? let's 
-        # print them
-        remainingFields = list(set(self.fields) - set(fixedFields))
-        for i in remainingFields:
-            if isinstance(self[i], Structure):
-                self[i].dump('%s%s:{' % (ind,i), indent = indent + 4)
-                print("%s}" % ind)
-            else:
-                print("%s%s: {%r}" % (ind,i,self[i]))
-
-
-class _StructureTest:
-    alignment = 0
-    def create(self,data = None):
-        if data is not None:
-            return self.theClass(data, alignment = self.alignment)
-        else:
-            return self.theClass(alignment = self.alignment)
-
-    def run(self):
-        print()
-        print("-"*70)
-        testName = self.__class__.__name__
-        print("starting test: %s....." % testName)
-        a = self.create()
-        self.populate(a)
-        a.dump("packing.....")
-        a_str = str(a)
-        print("packed: %r" % a_str)
-        print("unpacking.....")
-        b = self.create(a_str)
-        b.dump("unpacked.....")
-        print("repacking.....")
-        b_str = str(b)
-        if b_str != a_str:
-            print("ERROR: original packed and repacked don't match")
-            print("packed: %r" % b_str)
-
-class _Test_simple(_StructureTest):
-    class theClass(Structure):
-        commonHdr = ()
-        structure = (
-                ('int1', '!L'),
-                ('len1','!L-z1'),
-                ('arr1','B*<L'),
-                ('z1', 'z'),
-                ('u1','u'),
-                ('', '"COCA'),
-                ('len2','!H-:1'),
-                ('', '"COCA'),
-                (':1', ':'),
-                ('int3','>L'),
-                ('code1','>L=len(arr1)*2+0x1000'),
-                )
-
-    def populate(self, a):
-        a['default'] = 'hola'
-        a['int1'] = 0x3131
-        a['int3'] = 0x45444342
-        a['z1']   = 'hola'
-        a['u1']   = 'hola'.encode('utf_16_le')
-        a[':1']   = ':1234:'
-        a['arr1'] = (0x12341234,0x88990077,0x41414141)
-        # a['len1'] = 0x42424242
-
-class _Test_fixedLength(_Test_simple):
-    def populate(self, a):
-        _Test_simple.populate(self, a)
-        a['len1'] = 0x42424242
-
-class _Test_simple_aligned4(_Test_simple):
-    alignment = 4
-
-class _Test_nested(_StructureTest):
-    class theClass(Structure):
-        class _Inner(Structure):
-            structure = (('data', 'z'),)
-
-        structure = (
-            ('nest1', ':', _Inner),
-            ('nest2', ':', _Inner),
-            ('int', '<L'),
-        )
-
-    def populate(self, a):
-        a['nest1'] = _Test_nested.theClass._Inner()
-        a['nest2'] = _Test_nested.theClass._Inner()
-        a['nest1']['data'] = 'hola manola'
-        a['nest2']['data'] = 'chau loco'
-        a['int'] = 0x12345678
-    
-class _Test_Optional(_StructureTest):
-    class theClass(Structure):
-        structure = (
-                ('pName','<L&Name'),
-                ('pList','<L&List'),
-                ('Name','w'),
-                ('List','<H*<L'),
-            )
-            
-    def populate(self, a):
-        a['Name'] = 'Optional test'
-        a['List'] = (1,2,3,4)
-        
-class _Test_Optional_sparse(_Test_Optional):
-    def populate(self, a):
-        _Test_Optional.populate(self, a)
-        del a['Name']
-
-class _Test_AsciiZArray(_StructureTest):
-    class theClass(Structure):
-        structure = (
-            ('head','<L'),
-            ('array','B*z'),
-            ('tail','<L'),
-        )
-
-    def populate(self, a):
-        a['head'] = 0x1234
-        a['tail'] = 0xabcd
-        a['array'] = ('hola','manola','te traje')
-        
-class _Test_UnpackCode(_StructureTest):
-    class theClass(Structure):
-        structure = (
-            ('leni','<L=len(uno)*2'),
-            ('cuchi','_-uno','leni/2'),
-            ('uno',':'),
-            ('dos',':'),
-        )
-
-    def populate(self, a):
-        a['uno'] = 'soy un loco!'
-        a['dos'] = 'que haces fiera'
-
-class _Test_AAA(_StructureTest):
-    class theClass(Structure):
-        commonHdr = ()
-        structure = (
-          ('iv', '!L=((init_vector & 0xFFFFFF) << 8) | ((pad & 0x3f) << 2) | 
(keyid & 3)'),
-          ('init_vector',   '_','(iv >> 8)'),
-          ('pad',           '_','((iv >>2) & 0x3F)'),
-          ('keyid',         '_','( iv & 0x03 )'),
-          ('dataLen',       '_-data', 'len(inputDataLeft)-4'),
-          ('data',':'),
-          ('icv','>L'),
-        )
-
-    def populate(self, a):
-        a['init_vector']=0x01020304
-        #a['pad']=int('01010101',2)
-        a['pad']=int('010101',2)
-        a['keyid']=0x07
-        a['data']="\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9"
-        a['icv'] = 0x05060708
-        #a['iv'] = 0x01020304
-        
-if __name__ == '__main__':
-    _Test_simple().run()
-
-    try:
-        _Test_fixedLength().run()
-    except:
-        print("cannot repack because length is bogus")
-
-    _Test_simple_aligned4().run()
-    _Test_nested().run()
-    _Test_Optional().run()
-    _Test_Optional_sparse().run()
-    _Test_AsciiZArray().run()
-    _Test_UnpackCode().run()
-    _Test_AAA().run()
diff --git a/tests/python_dependencies/impacket/uuid.py 
b/tests/python_dependencies/impacket/uuid.py
deleted file mode 100644
index 750eba459..000000000
--- a/tests/python_dependencies/impacket/uuid.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (c) 2003-2016 CORE Security Technologies
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-# Description:
-#   Generate UUID compliant with 
http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt.
-#   A different, much simpler (not necessarily better) algorithm is used.
-#
-# Author:
-#   Javier Kohen (jkohen)
-#
-
-import re
-
-from random import randrange
-from struct import pack, unpack
-
-try:
-    long        # Python 2
-except NameError:
-    long = int  # Python 3
-
-def generate():
-    # UHm... crappy Python has an maximum integer of 2**31-1.
-    top = (1<<31)-1
-    return pack("IIII", randrange(top), randrange(top), randrange(top), 
randrange(top))
-
-def bin_to_string(uuid):
-    uuid1, uuid2, uuid3 = unpack('<LHH', uuid[:8])
-    uuid4, uuid5, uuid6 = unpack('>HHL', uuid[8:16])
-    return '%08X-%04X-%04X-%04X-%04X%08X' % (uuid1, uuid2, uuid3, uuid4, 
uuid5, uuid6)
-
-def string_to_bin(uuid):
-    matches = 
re.match('([\dA-Fa-f]{8})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})([\dA-Fa-f]{8})',
 uuid)
-    (uuid1, uuid2, uuid3, uuid4, uuid5, uuid6) = map(lambda x: long(x, 16), 
matches.groups())
-    uuid = pack('<LHH', uuid1, uuid2, uuid3)
-    uuid += pack('>HHL', uuid4, uuid5, uuid6)
-    return uuid
-
-def stringver_to_bin(s):
-    (maj,min) = s.split('.')
-    return pack('<H',int(maj)) + pack('<H',int(min))
-
-def uuidtup_to_bin(tup):
-    if len(tup) != 2: return
-    return string_to_bin(tup[0]) + stringver_to_bin(tup[1])
-
-def bin_to_uuidtup(bin):
-    assert len(bin) == 20
-    uuidstr = bin_to_string(bin[:16])
-    maj, min = unpack("<HH", bin[16:])
-    return uuidstr, "%d.%d" % (maj, min)
-
-#input: string
-#output: tuple (uuid,version)
-#if version is not found in the input string "1.0"  is returned
-#example:
-#           "00000000-0000-0000-0000-000000000000 3.0" returns 
('00000000-0000-0000-0000-000000000000','3.0')
-#           "10000000-2000-3000-4000-500000000000 version 3.0" returns 
('00000000-0000-0000-0000-000000000000','3.0')
-#           "10000000-2000-3000-4000-500000000000 v 3.0" returns 
('00000000-0000-0000-0000-000000000000','3.0')
-#           "10000000-2000-3000-4000-500000000000" returns 
('00000000-0000-0000-0000-000000000000','1.0')
-def string_to_uuidtup(s):
-    g =  
re.search("([A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}).*?([0-9]{1,5}\.[0-9]{1,5})",s+"
 1.0")
-    if g:
-        (u,v) = g.groups()
-        return (u,v)
-    return
-
-def uuidtup_to_string(tup):
-    uuid, (maj, min) = tup
-    return "%s v%d.%d" % (uuid, maj, min)
diff --git a/tests/python_dependencies/impacket/version.py 
b/tests/python_dependencies/impacket/version.py
deleted file mode 100644
index badd4a8a4..000000000
--- a/tests/python_dependencies/impacket/version.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2003-2016 CORE Security Technologies
-#
-# This software is provided under under a slightly modified version
-# of the Apache Software License. See the accompanying LICENSE file
-# for more information.
-#
-
-VER_MAJOR = "0"
-VER_MINOR = "9.15"
-
-BANNER = "Impacket v%s.%s - Copyright 2002-2016 Core Security Technologies\n" 
% (VER_MAJOR,VER_MINOR)
-
diff --git a/tests/rtspserver.pl b/tests/rtspserver.pl
index 026a81950..315526a93 100755
--- a/tests/rtspserver.pl
+++ b/tests/rtspserver.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -44,6 +44,7 @@ my $ipvnum = 4;      # default IP version of rtsp server
 my $idnum = 1;       # default rtsp server instance number
 my $proto = 'rtsp';  # protocol the rtsp server speaks
 my $pidfile;         # rtsp server pid file
+my $portfile;
 my $logfile;         # rtsp server log file
 my $srcdir;
 
@@ -58,6 +59,12 @@ while(@ARGV) {
             shift @ARGV;
         }
     }
+    elsif($ARGV[0] eq '--portfile') {
+        if($ARGV[1]) {
+            $portfile = $ARGV[1];
+            shift @ARGV;
+        }
+    }
     elsif($ARGV[0] eq '--logfile') {
         if($ARGV[1]) {
             $logfile = $ARGV[1];
@@ -107,7 +114,9 @@ if(!$logfile) {
     $logfile = server_logfilename($logdir, $proto, $ipvnum, $idnum);
 }
 
-$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
+$flags .= "--pidfile \"$pidfile\" ".
+    "--portfile \"$portfile\" ".
+    "--logfile \"$logfile\" ";
 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
 
 exec("server/rtspd".exe_ext('SRV')." $flags");
diff --git a/tests/runtests.pl b/tests/runtests.pl
index 47c3931af..f37e157f4 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -78,6 +78,7 @@ use serverhelp qw(
     servername_str
     servername_canon
     server_pidfilename
+    server_portfilename
     server_logfilename
     );
 
@@ -123,38 +124,42 @@ my $base = 8990; # base port number
 my $minport;     # minimum used port number
 my $maxport;     # maximum used port number
 
-my $HTTPPORT;            # HTTP server port
-my $HTTP6PORT;           # HTTP IPv6 server port
-my $HTTPSPORT;           # HTTPS (stunnel) server port
-my $FTPPORT;             # FTP server port
-my $FTP2PORT;            # FTP server 2 port
-my $FTPSPORT;            # FTPS (stunnel) server port
-my $FTP6PORT;            # FTP IPv6 server port
-my $TFTPPORT;            # TFTP
-my $TFTP6PORT;           # TFTP
-my $SSHPORT;             # SCP/SFTP
-my $SOCKSPORT;           # SOCKS4/5 port
-my $POP3PORT;            # POP3
-my $POP36PORT;           # POP3 IPv6 server port
-my $IMAPPORT;            # IMAP
-my $IMAP6PORT;           # IMAP IPv6 server port
-my $SMTPPORT;            # SMTP
-my $SMTP6PORT;           # SMTP IPv6 server port
-my $RTSPPORT;            # RTSP
-my $RTSP6PORT;           # RTSP IPv6 server port
-my $GOPHERPORT;          # Gopher
-my $GOPHER6PORT;         # Gopher IPv6 server port
-my $HTTPTLSPORT;         # HTTP TLS (non-stunnel) server port
-my $HTTPTLS6PORT;        # HTTP TLS (non-stunnel) IPv6 server port
-my $HTTPPROXYPORT;       # HTTP proxy port, when using CONNECT
+my $noport="[not running]";
+
+my $NOLISTENPORT=47;     # port number we use for a local non-listening service
+my $MQTTPORT=$noport;    # MQTT server port
+my $HTTPPORT=$noport;    # HTTP server port
+my $HTTP6PORT=$noport;   # HTTP IPv6 server port
+my $HTTPSPORT=$noport;   # HTTPS (stunnel) server port
+my $FTPPORT=$noport;     # FTP server port
+my $FTP2PORT=$noport;    # FTP server 2 port
+my $FTPSPORT=$noport;    # FTPS (stunnel) server port
+my $FTP6PORT=$noport;    # FTP IPv6 server port
+my $TFTPPORT=$noport;    # TFTP
+my $TFTP6PORT=$noport;   # TFTP
+my $SSHPORT=$noport;     # SCP/SFTP
+my $SOCKSPORT=$noport;   # SOCKS4/5 port
+my $POP3PORT=$noport;    # POP3
+my $POP36PORT=$noport;   # POP3 IPv6 server port
+my $IMAPPORT=$noport;    # IMAP
+my $IMAP6PORT=$noport;   # IMAP IPv6 server port
+my $SMTPPORT=$noport;    # SMTP
+my $SMTP6PORT=$noport;   # SMTP IPv6 server port
+my $RTSPPORT=$noport;    # RTSP
+my $RTSP6PORT=$noport;   # RTSP IPv6 server port
+my $GOPHERPORT=$noport;  # Gopher
+my $GOPHER6PORT=$noport; # Gopher IPv6 server port
+my $HTTPTLSPORT=$noport; # HTTP TLS (non-stunnel) server port
+my $HTTPTLS6PORT=$noport; # HTTP TLS (non-stunnel) IPv6 server port
+my $HTTPPROXYPORT=$noport; # HTTP proxy port, when using CONNECT
+my $HTTP2PORT=$noport;   # HTTP/2 server port
+my $DICTPORT=$noport;    # DICT server port
+my $SMBPORT=$noport;     # SMB server port
+my $SMBSPORT=$noport;    # SMBS server port
+my $NEGTELNETPORT=$noport; # TELNET server port with negotiation
 my $HTTPUNIXPATH;        # HTTP server Unix domain socket path
-my $HTTP2PORT;           # HTTP/2 server port
-my $DICTPORT;            # DICT server port
-my $SMBPORT;             # SMB server port
-my $SMBSPORT;            # SMBS server port
-my $NEGTELNETPORT;       # TELNET server port with negotiation
 
-my $SSHSRVMD5;           # MD5 of ssh server public key
+my $SSHSRVMD5 = "[uninitialized]"; # MD5 of ssh server public key
 
 my $srcdir = $ENV{'srcdir'} || '.';
 my $CURL="../src/gnurl".exe_ext('TOOL'); # what curl executable to run on the 
tests
@@ -171,7 +176,7 @@ my $SERVERIN="$LOGDIR/server.input"; # what curl sent the 
server
 my $SERVER2IN="$LOGDIR/server2.input"; # what curl sent the second server
 my $PROXYIN="$LOGDIR/proxy.input"; # what curl sent the proxy
 my $CURLLOG="commands.log"; # all command lines run
-my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy ftp server instructions here
+my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy server instructions here
 my $SERVERLOGS_LOCK="$LOGDIR/serverlogs.lock"; # server logs advisor read lock
 my $CURLCONFIG="../gnurl-config"; # curl-config from current build
 
@@ -249,6 +254,7 @@ my $has_ldpreload;  # set if curl is built for systems 
supporting LD_PRELOAD
 my $has_multissl;   # set if curl is build with MultiSSL support
 my $has_manual;     # set if curl is built with built-in manual
 my $has_win32;      # set if curl is built for Windows
+my $has_mingw;      # set if curl is built with MinGW (as opposed to MinGW-w64)
 
 # this version is decided by the particular nghttp2 library that is being used
 my $h2cver = "h2c";
@@ -272,7 +278,6 @@ my $resolver;       # name of the resolver backend (for 
human presentation)
 
 my $has_textaware;  # set if running on a system that has a text mode concept
                     # on files. Windows for example
-
 my @protocols;   # array of lowercase supported protocol servers
 
 my $skipped=0;  # number of tests skipped; reported in main loop
@@ -326,6 +331,7 @@ my $run_event_based; # run curl with --test-event to test 
the event API
 my %run;          # running server
 my %doesntrun;    # servers that don't work, identified by pidfile
 my %serverpidfile;# all server pid file names, identified by server id
+my %serverportfile;# all server port file names, identified by server id
 my %runcert;      # cert file currently in use by an ssl running server
 
 # torture test variables
@@ -399,7 +405,8 @@ delete $ENV{'SSL_CERT_PATH'} if($ENV{'SSL_CERT_PATH'});
 delete $ENV{'CURL_CA_BUNDLE'} if($ENV{'CURL_CA_BUNDLE'});
 
 #######################################################################
-# Load serverpidfile hash with pidfile names for all possible servers.
+# Load serverpidfile and serverportfile hashes with file names for all
+# possible servers.
 #
 sub init_serverpidfile_hash {
   for my $proto (('ftp', 'http', 'imap', 'pop3', 'smtp', 'http/2')) {
@@ -409,17 +416,21 @@ sub init_serverpidfile_hash {
           my $serv = servername_id("$proto$ssl", $ipvnum, $idnum);
           my $pidf = server_pidfilename("$proto$ssl", $ipvnum, $idnum);
           $serverpidfile{$serv} = $pidf;
+          my $portf = server_portfilename("$proto$ssl", $ipvnum, $idnum);
+          $serverportfile{$serv} = $portf;
         }
       }
     }
   }
   for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp', 'gopher', 'httptls',
-                  'dict', 'smb', 'smbs', 'telnet')) {
+                  'dict', 'smb', 'smbs', 'telnet', 'mqtt')) {
     for my $ipvnum ((4, 6)) {
       for my $idnum ((1, 2)) {
         my $serv = servername_id($proto, $ipvnum, $idnum);
         my $pidf = server_pidfilename($proto, $ipvnum, $idnum);
         $serverpidfile{$serv} = $pidf;
+        my $portf = server_portfilename($proto, $ipvnum, $idnum);
+        $serverportfile{$serv} = $portf;
       }
     }
   }
@@ -428,6 +439,8 @@ sub init_serverpidfile_hash {
       my $serv = servername_id("$proto$ssl", "unix", 1);
       my $pidf = server_pidfilename("$proto$ssl", "unix", 1);
       $serverpidfile{$serv} = $pidf;
+      my $portf = server_portfilename("$proto$ssl", "unix", 1);
+      $serverportfile{$serv} = $portf;
     }
   }
 }
@@ -441,7 +454,7 @@ sub checkdied {
     if((not defined $pid) || $pid <= 0) {
         return 0;
     }
-    my $rc = waitpid($pid, &WNOHANG);
+    my $rc = pidwait($pid, &WNOHANG);
     return ($rc == $pid)?1:0;
 }
 
@@ -750,6 +763,7 @@ sub torture {
 #
 sub stopserver {
     my ($server, $pidlist) = @_;
+
     #
     # kill sockfilter processes for pingpong relative server
     #
@@ -779,6 +793,12 @@ sub stopserver {
         # given a ssh server, also kill socks piggybacking one
         push @killservers, "socks${2}";
     }
+    if($server eq "http") {
+        # since the http2 server is a proxy that needs to know about the
+        # dynamic http port it too needs to get restarted when the http server
+        # is killed
+        push @killservers, "http/2";
+    }
     push @killservers, $server;
     #
     # kill given pids and server relative ones clearing them in %run hash
@@ -1488,6 +1508,7 @@ sub runhttpserver {
     $server = servername_id($proto, $ipvnum, $idnum);
 
     $pidfile = $serverpidfile{$server};
+    my $portfile = $serverportfile{$server};
 
     # don't retry if the server doesn't work
     if ($doesntrun{$pidfile}) {
@@ -1508,11 +1529,12 @@ sub runhttpserver {
     $flags .= "--connect $HOSTIP " if($alt eq "proxy");
     $flags .= $verbose_flag if($debugprotocol);
     $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
+    $flags .= "--portfile $portfile ";
     $flags .= "--id $idnum " if($idnum > 1);
     if($ipvnum eq "unix") {
         $flags .= "--unix-socket '$port_or_path' ";
     } else {
-        $flags .= "--ipv$ipvnum --port $port_or_path ";
+        $flags .= "--ipv$ipvnum --port 0 ";
     }
     $flags .= "--srcdir \"$srcdir\"";
 
@@ -1528,6 +1550,12 @@ sub runhttpserver {
         return (0,0);
     }
 
+    # where is it?
+    my $port;
+    if(!$port_or_path) {
+        $port = $port_or_path = pidfromfile($portfile);
+    }
+
     # Server is up. Verify that we can speak to it.
     my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
     if(!$pid3) {
@@ -1541,12 +1569,12 @@ sub runhttpserver {
     $pid2 = $pid3;
 
     if($verbose) {
-        logmsg "RUN: $srvrname server is now running PID $httppid\n";
+        logmsg "RUN: $srvrname server is on PID $httppid port $port\n";
     }
 
     sleep(1);
 
-    return ($httppid, $pid2);
+    return ($httppid, $pid2, $port);
 }
 
 #######################################################################
@@ -1726,31 +1754,10 @@ sub runpingpongserver {
     my $logfile;
     my $flags = "";
 
-    if($proto eq "ftp") {
-        $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
-
-        if($ipvnum==6) {
-            # if IPv6, use a different setup
-            $port = $FTP6PORT;
-        }
-    }
-    elsif($proto eq "pop3") {
-        $port = ($ipvnum==6) ? $POP36PORT : $POP3PORT;
-    }
-    elsif($proto eq "imap") {
-        $port = ($ipvnum==6) ? $IMAP6PORT : $IMAPPORT;
-    }
-    elsif($proto eq "smtp") {
-        $port = ($ipvnum==6) ? $SMTP6PORT : $SMTPPORT;
-    }
-    else {
-        print STDERR "Unsupported protocol $proto!!\n";
-        return 0;
-    }
-
     $server = servername_id($proto, $ipvnum, $idnum);
 
     $pidfile = $serverpidfile{$server};
+    my $portfile = $serverportfile{$server};
 
     # don't retry if the server doesn't work
     if ($doesntrun{$pidfile}) {
@@ -1769,9 +1776,10 @@ sub runpingpongserver {
 
     $flags .= "--verbose " if($debugprotocol);
     $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
+    $flags .= "--portfile \"$portfile\" ";
     $flags .= "--srcdir \"$srcdir\" --proto $proto ";
     $flags .= "--id $idnum " if($idnum > 1);
-    $flags .= "--ipv$ipvnum --port $port --addr \"$ip\"";
+    $flags .= "--ipv$ipvnum --port 0 --addr \"$ip\"";
 
     my $cmd = "$perl $srcdir/ftpserver.pl $flags";
     my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
@@ -1785,6 +1793,11 @@ sub runpingpongserver {
         return (0,0);
     }
 
+    # where is it?
+    $port = pidfromfile($portfile);
+
+    logmsg "PINGPONG runs on port $port ($portfile)\n" if($verbose);
+
     # Server is up. Verify that we can speak to it.
     my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
     if(!$pid3) {
@@ -1798,8 +1811,48 @@ sub runpingpongserver {
 
     $pid2 = $pid3;
 
-    if($verbose) {
-        logmsg "RUN: $srvrname server is now running PID $ftppid\n";
+    logmsg "RUN: $srvrname server is PID $ftppid port $port\n" if($verbose);
+
+    # Assign the correct port variable!
+    if($proto eq "ftp") {
+        if($ipvnum == 6) {
+            # if IPv6, use a different setup
+            $FTP6PORT = $port;
+        }
+        elsif($idnum>1) {
+            $FTP2PORT = $port;
+        }
+        else {
+            $FTPPORT = $port;
+        }
+    }
+    elsif($proto eq "pop3") {
+        if($ipvnum == 6) {
+            $POP36PORT = $port;
+        }
+        else {
+            $POP3PORT = $port;
+        }
+    }
+    elsif($proto eq "imap") {
+        if($ipvnum == 6) {
+            $IMAP6PORT  = $port;
+        }
+        else {
+            $IMAPPORT = $port;
+        }
+    }
+    elsif($proto eq "smtp") {
+        if($ipvnum == 6) {
+            $SMTP6PORT = $port;
+        }
+        else {
+            $SMTPPORT = $port;
+        }
+    }
+    else {
+        print STDERR "Unsupported protocol $proto!!\n";
+        return 0;
     }
 
     sleep(1);
@@ -1895,7 +1948,6 @@ sub runftpsserver {
 #
 sub runtftpserver {
     my ($id, $verbose, $ipv6) = @_;
-    my $port = $TFTPPORT;
     my $ip = $HOSTIP;
     my $proto = 'tftp';
     my $ipvnum = 4;
@@ -1909,13 +1961,13 @@ sub runtftpserver {
     if($ipv6) {
         # if IPv6, use a different setup
         $ipvnum = 6;
-        $port = $TFTP6PORT;
         $ip = $HOST6IP;
     }
 
     $server = servername_id($proto, $ipvnum, $idnum);
 
     $pidfile = $serverpidfile{$server};
+    my $portfile = $serverportfile{$server};
 
     # don't retry if the server doesn't work
     if ($doesntrun{$pidfile}) {
@@ -1933,9 +1985,11 @@ sub runtftpserver {
     $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
 
     $flags .= "--verbose " if($debugprotocol);
-    $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
+    $flags .= "--pidfile \"$pidfile\" ".
+        "--portfile \"$portfile\" ".
+        "--logfile \"$logfile\" ";
     $flags .= "--id $idnum " if($idnum > 1);
-    $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
+    $flags .= "--ipv$ipvnum --port 0 --srcdir \"$srcdir\"";
 
     my $cmd = "$perl $srcdir/tftpserver.pl $flags";
     my ($tftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
@@ -1949,6 +2003,8 @@ sub runtftpserver {
         return (0,0);
     }
 
+    my $port = pidfromfile($portfile);
+
     # Server is up. Verify that we can speak to it.
     my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
     if(!$pid3) {
@@ -1962,12 +2018,12 @@ sub runtftpserver {
     $pid2 = $pid3;
 
     if($verbose) {
-        logmsg "RUN: $srvrname server is now running PID $tftppid\n";
+        logmsg "RUN: $srvrname server on PID $tftppid port $port\n";
     }
 
     sleep(1);
 
-    return ($pid2, $tftppid);
+    return ($pid2, $tftppid, $port);
 }
 
 
@@ -1976,7 +2032,6 @@ sub runtftpserver {
 #
 sub runrtspserver {
     my ($verbose, $ipv6) = @_;
-    my $port = $RTSPPORT;
     my $ip = $HOSTIP;
     my $proto = 'rtsp';
     my $ipvnum = 4;
@@ -1990,13 +2045,13 @@ sub runrtspserver {
     if($ipv6) {
         # if IPv6, use a different setup
         $ipvnum = 6;
-        $port = $RTSP6PORT;
         $ip = $HOST6IP;
     }
 
     $server = servername_id($proto, $ipvnum, $idnum);
 
     $pidfile = $serverpidfile{$server};
+    my $portfile = $serverportfile{$server};
 
     # don't retry if the server doesn't work
     if ($doesntrun{$pidfile}) {
@@ -2014,9 +2069,11 @@ sub runrtspserver {
     $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
 
     $flags .= "--verbose " if($debugprotocol);
-    $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
+    $flags .= "--pidfile \"$pidfile\" ".
+         "--portfile \"$portfile\" ".
+        "--logfile \"$logfile\" ";
     $flags .= "--id $idnum " if($idnum > 1);
-    $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
+    $flags .= "--ipv$ipvnum --port 0 --srcdir \"$srcdir\"";
 
     my $cmd = "$perl $srcdir/rtspserver.pl $flags";
     my ($rtsppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
@@ -2030,6 +2087,8 @@ sub runrtspserver {
         return (0,0);
     }
 
+    my $port = pidfromfile($portfile);
+
     # Server is up. Verify that we can speak to it.
     my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
     if(!$pid3) {
@@ -2043,12 +2102,12 @@ sub runrtspserver {
     $pid2 = $pid3;
 
     if($verbose) {
-        logmsg "RUN: $srvrname server is now running PID $rtsppid\n";
+        logmsg "RUN: $srvrname server PID $rtsppid port $port\n";
     }
 
     sleep(1);
 
-    return ($rtsppid, $pid2);
+    return ($rtsppid, $pid2, $port);
 }
 
 
@@ -2162,13 +2221,73 @@ sub runsshserver {
     return ($pid2, $sshpid);
 }
 
+#######################################################################
+# Start the socks server
+#
+sub runmqttserver {
+    my ($id, $verbose, $ipv6) = @_;
+    my $ip=$HOSTIP;
+    my $port = $MQTTPORT;
+    my $proto = 'mqtt';
+    my $ipvnum = 4;
+    my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
+    my $server;
+    my $srvrname;
+    my $pidfile;
+    my $portfile;
+    my $logfile;
+    my $flags = "";
+
+    $server = servername_id($proto, $ipvnum, $idnum);
+    $pidfile = $serverpidfile{$server};
+    $portfile = $serverportfile{$server};
+
+    # don't retry if the server doesn't work
+    if ($doesntrun{$pidfile}) {
+        return (0,0);
+    }
+
+    my $pid = processexists($pidfile);
+    if($pid > 0) {
+        stopserver($server, "$pid");
+    }
+    unlink($pidfile) if(-f $pidfile);
+
+    $srvrname = servername_str($proto, $ipvnum, $idnum);
+
+    $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
+
+    # start our MQTT server - on a random port!
+    my $cmd="server/mqttd".exe_ext('SRV').
+        " --port 0 ".
+        " --pidfile $pidfile".
+        " --portfile $portfile".
+        " --config $FTPDCMD";
+    my ($sockspid, $pid2) = startnew($cmd, $pidfile, 30, 0);
+
+    if($sockspid <= 0 || !pidexists($sockspid)) {
+        # it is NOT alive
+        logmsg "RUN: failed to start the $srvrname server\n";
+        stopserver($server, "$pid2");
+        $doesntrun{$pidfile} = 1;
+        return (0,0);
+    }
+
+    $MQTTPORT = pidfromfile($portfile);
+
+    if($verbose) {
+        logmsg "RUN: $srvrname server is now running PID $pid2 on PORT 
$MQTTPORT\n";
+    }
+
+    return ($pid2, $sockspid);
+}
+
 #######################################################################
 # Start the socks server
 #
 sub runsocksserver {
     my ($id, $verbose, $ipv6) = @_;
     my $ip=$HOSTIP;
-    my $port = $SOCKSPORT;
     my $proto = 'socks';
     my $ipvnum = 4;
     my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
@@ -2181,6 +2300,7 @@ sub runsocksserver {
     $server = servername_id($proto, $ipvnum, $idnum);
 
     $pidfile = $serverpidfile{$server};
+    my $portfile = $serverportfile{$server};
 
     # don't retry if the server doesn't work
     if ($doesntrun{$pidfile}) {
@@ -2199,8 +2319,9 @@ sub runsocksserver {
 
     # start our socks server, get commands from the FTP cmd file
     my $cmd="server/socksd".exe_ext('SRV').
-        " --port $port ".
+        " --port 0 ".
         " --pidfile $pidfile".
+        " --portfile $portfile".
         " --backend $HOSTIP".
         " --config $FTPDCMD";
     my ($sockspid, $pid2) = startnew($cmd, $pidfile, 30, 0);
@@ -2213,11 +2334,13 @@ sub runsocksserver {
         return (0,0);
     }
 
+    my $port = pidfromfile($portfile);
+
     if($verbose) {
         logmsg "RUN: $srvrname server is now running PID $pid2\n";
     }
 
-    return ($pid2, $sockspid);
+    return ($pid2, $sockspid, $port);
 }
 
 #######################################################################
@@ -2659,6 +2782,7 @@ sub setupfeatures {
     $feature{"manual"} = $has_manual;
     $feature{"unix-sockets"} = $has_unix;
     $feature{"win32"} = $has_win32;
+    $feature{"MinGW"} = $has_mingw;
 
     # make each protocol an enabled "feature"
     for my $p (@protocols) {
@@ -2739,6 +2863,7 @@ sub checksystem {
                 $pwd = pathhelp::sys_native_current_path();
                 $has_textaware = 1;
                 $has_win32 = 1;
+                $has_mingw = 1 if ($curl =~ /-pc-mingw32/);
             }
            if ($libcurl =~ /(winssl|schannel)/i) {
                $has_winssl=1;
@@ -3008,6 +3133,7 @@ sub checksystem {
 
     my $hostname=join(' ', runclientoutput("hostname"));
     my $hosttype=join(' ', runclientoutput("uname -a"));
+    my $hostos=$^O;
 
     logmsg ("********* System characteristics ******** \n",
             "* $curl\n",
@@ -3015,7 +3141,8 @@ sub checksystem {
             "* Features: $feat\n",
             "* Disabled: $dis\n",
             "* Host: $hostname",
-            "* System: $hosttype");
+            "* System: $hosttype",
+            "* OS: $hostos\n");
 
     if($has_memory_tracking && $has_threadedres) {
         $has_memory_tracking = 0;
@@ -3036,43 +3163,14 @@ sub checksystem {
     logmsg ("* Port range: $minport-$maxport\n");
 
     if($verbose) {
-        logmsg "* Ports:\n";
-
-        logmsg sprintf("*   HTTP/%d ", $HTTPPORT);
-        logmsg sprintf("FTP/%d ", $FTPPORT);
-        logmsg sprintf("FTP2/%d ", $FTP2PORT);
-        logmsg sprintf("RTSP/%d ", $RTSPPORT);
+        logmsg "* Ports: ";
         if($stunnel) {
             logmsg sprintf("FTPS/%d ", $FTPSPORT);
             logmsg sprintf("HTTPS/%d ", $HTTPSPORT);
         }
-        logmsg sprintf("\n*   TFTP/%d ", $TFTPPORT);
-        if($http_ipv6) {
-            logmsg sprintf("HTTP-IPv6/%d ", $HTTP6PORT);
-            logmsg sprintf("RTSP-IPv6/%d ", $RTSP6PORT);
-        }
-        if($ftp_ipv6) {
-            logmsg sprintf("FTP-IPv6/%d ", $FTP6PORT);
-        }
-        if($tftp_ipv6) {
-            logmsg sprintf("TFTP-IPv6/%d ", $TFTP6PORT);
-        }
-        logmsg sprintf("\n*   GOPHER/%d ", $GOPHERPORT);
-        if($gopher_ipv6) {
-            logmsg sprintf("GOPHER-IPv6/%d", $GOPHER6PORT);
-        }
         logmsg sprintf("\n*   SSH/%d ", $SSHPORT);
-        logmsg sprintf("SOCKS/%d ", $SOCKSPORT);
-        logmsg sprintf("POP3/%d ", $POP3PORT);
-        logmsg sprintf("IMAP/%d ", $IMAPPORT);
-        logmsg sprintf("SMTP/%d\n", $SMTPPORT);
-        if($ftp_ipv6) {
-            logmsg sprintf("*   POP3-IPv6/%d ", $POP36PORT);
-            logmsg sprintf("IMAP-IPv6/%d ", $IMAP6PORT);
-            logmsg sprintf("SMTP-IPv6/%d\n", $SMTP6PORT);
-        }
         if($httptlssrv) {
-            logmsg sprintf("*   HTTPTLS/%d ", $HTTPTLSPORT);
+            logmsg sprintf("HTTPTLS/%d ", $HTTPTLSPORT);
             if($has_ipv6) {
                 logmsg sprintf("HTTPTLS-IPv6/%d ", $HTTPTLS6PORT);
             }
@@ -3101,104 +3199,84 @@ sub checksystem {
 # a command, in either case passed by reference
 #
 sub subVariables {
-  my ($thing) = @_;
-
-  # ports
-
-  $$thing =~ s/%FTP6PORT/$FTP6PORT/g;
-  $$thing =~ s/%FTP2PORT/$FTP2PORT/g;
-  $$thing =~ s/%FTPSPORT/$FTPSPORT/g;
-  $$thing =~ s/%FTPPORT/$FTPPORT/g;
-
-  $$thing =~ s/%GOPHER6PORT/$GOPHER6PORT/g;
-  $$thing =~ s/%GOPHERPORT/$GOPHERPORT/g;
-
-  $$thing =~ s/%HTTPTLS6PORT/$HTTPTLS6PORT/g;
-  $$thing =~ s/%HTTPTLSPORT/$HTTPTLSPORT/g;
-  $$thing =~ s/%HTTP6PORT/$HTTP6PORT/g;
-  $$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
-  $$thing =~ s/%HTTP2PORT/$HTTP2PORT/g;
-  $$thing =~ s/%HTTPPORT/$HTTPPORT/g;
-  $$thing =~ s/%PROXYPORT/$HTTPPROXYPORT/g;
-
-  $$thing =~ s/%IMAP6PORT/$IMAP6PORT/g;
-  $$thing =~ s/%IMAPPORT/$IMAPPORT/g;
-
-  $$thing =~ s/%POP36PORT/$POP36PORT/g;
-  $$thing =~ s/%POP3PORT/$POP3PORT/g;
-
-  $$thing =~ s/%RTSP6PORT/$RTSP6PORT/g;
-  $$thing =~ s/%RTSPPORT/$RTSPPORT/g;
-
-  $$thing =~ s/%SMTP6PORT/$SMTP6PORT/g;
-  $$thing =~ s/%SMTPPORT/$SMTPPORT/g;
-
-  $$thing =~ s/%SOCKSPORT/$SOCKSPORT/g;
-  $$thing =~ s/%SSHPORT/$SSHPORT/g;
-
-  $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
-  $$thing =~ s/%TFTPPORT/$TFTPPORT/g;
-
-  $$thing =~ s/%DICTPORT/$DICTPORT/g;
-
-  $$thing =~ s/%SMBPORT/$SMBPORT/g;
-  $$thing =~ s/%SMBSPORT/$SMBSPORT/g;
-
-  $$thing =~ s/%NEGTELNETPORT/$NEGTELNETPORT/g;
-
-  # server Unix domain socket paths
-
-  $$thing =~ s/%HTTPUNIXPATH/$HTTPUNIXPATH/g;
-
-  # client IP addresses
-
-  $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
-  $$thing =~ s/%CLIENTIP/$CLIENTIP/g;
-
-  # server IP addresses
-
-  $$thing =~ s/%HOST6IP/$HOST6IP/g;
-  $$thing =~ s/%HOSTIP/$HOSTIP/g;
-
-  # misc
-
-  $$thing =~ s/%CURL/$CURL/g;
-  $$thing =~ s/%PWD/$pwd/g;
-  $$thing =~ s/%POSIX_PWD/$posix_pwd/g;
-
-  my $file_pwd = $pwd;
-  if($file_pwd !~ /^\//) {
-      $file_pwd = "/$file_pwd";
-  }
-
-  $$thing =~ s/%FILE_PWD/$file_pwd/g;
-  $$thing =~ s/%SRCDIR/$srcdir/g;
-  $$thing =~ s/%USER/$USER/g;
-
-  if($$thing =~ /%SSHSRVMD5/) {
-      if(!$SSHSRVMD5) {
-          my $msg = "Fatal: Missing SSH server pubkey MD5. Is server running?";
-          logmsg "$msg\n";
-          stopservers($verbose);
-          die $msg;
-      }
-      $$thing =~ s/%SSHSRVMD5/$SSHSRVMD5/g;
-  }
-
-  # The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
-  # used for time-out tests and that would work on most hosts as these
-  # adjust for the startup/check time for this particular host. We needed
-  # to do this to make the test suite run better on very slow hosts.
-
-  my $ftp2 = $ftpchecktime * 2;
-  my $ftp3 = $ftpchecktime * 3;
-
-  $$thing =~ s/%FTPTIME2/$ftp2/g;
-  $$thing =~ s/%FTPTIME3/$ftp3/g;
-
-  # HTTP2
-
-  $$thing =~ s/%H2CVER/$h2cver/g;
+    my ($thing, $prefix) = @_;
+
+    if(!$prefix) {
+        $prefix = "%";
+    }
+
+    # test server ports
+    $$thing =~ s/${prefix}FTP6PORT/$FTP6PORT/g;
+    $$thing =~ s/${prefix}FTP2PORT/$FTP2PORT/g;
+    $$thing =~ s/${prefix}FTPSPORT/$FTPSPORT/g;
+    $$thing =~ s/${prefix}FTPPORT/$FTPPORT/g;
+    $$thing =~ s/${prefix}GOPHER6PORT/$GOPHER6PORT/g;
+    $$thing =~ s/${prefix}GOPHERPORT/$GOPHERPORT/g;
+    $$thing =~ s/${prefix}HTTPTLS6PORT/$HTTPTLS6PORT/g;
+    $$thing =~ s/${prefix}HTTPTLSPORT/$HTTPTLSPORT/g;
+    $$thing =~ s/${prefix}HTTP6PORT/$HTTP6PORT/g;
+    $$thing =~ s/${prefix}HTTPSPORT/$HTTPSPORT/g;
+    $$thing =~ s/${prefix}HTTP2PORT/$HTTP2PORT/g;
+    $$thing =~ s/${prefix}HTTPPORT/$HTTPPORT/g;
+    $$thing =~ s/${prefix}PROXYPORT/$HTTPPROXYPORT/g;
+    $$thing =~ s/${prefix}MQTTPORT/$MQTTPORT/g;
+    $$thing =~ s/${prefix}IMAP6PORT/$IMAP6PORT/g;
+    $$thing =~ s/${prefix}IMAPPORT/$IMAPPORT/g;
+    $$thing =~ s/${prefix}POP36PORT/$POP36PORT/g;
+    $$thing =~ s/${prefix}POP3PORT/$POP3PORT/g;
+    $$thing =~ s/${prefix}RTSP6PORT/$RTSP6PORT/g;
+    $$thing =~ s/${prefix}RTSPPORT/$RTSPPORT/g;
+    $$thing =~ s/${prefix}SMTP6PORT/$SMTP6PORT/g;
+    $$thing =~ s/${prefix}SMTPPORT/$SMTPPORT/g;
+    $$thing =~ s/${prefix}SOCKSPORT/$SOCKSPORT/g;
+    $$thing =~ s/${prefix}SSHPORT/$SSHPORT/g;
+    $$thing =~ s/${prefix}TFTP6PORT/$TFTP6PORT/g;
+    $$thing =~ s/${prefix}TFTPPORT/$TFTPPORT/g;
+    $$thing =~ s/${prefix}DICTPORT/$DICTPORT/g;
+    $$thing =~ s/${prefix}SMBPORT/$SMBPORT/g;
+    $$thing =~ s/${prefix}SMBSPORT/$SMBSPORT/g;
+    $$thing =~ s/${prefix}NEGTELNETPORT/$NEGTELNETPORT/g;
+    $$thing =~ s/${prefix}NOLISTENPORT/$NOLISTENPORT/g;
+
+    # server Unix domain socket paths
+    $$thing =~ s/${prefix}HTTPUNIXPATH/$HTTPUNIXPATH/g;
+
+    # client IP addresses
+    $$thing =~ s/${prefix}CLIENT6IP/$CLIENT6IP/g;
+    $$thing =~ s/${prefix}CLIENTIP/$CLIENTIP/g;
+
+    # server IP addresses
+    $$thing =~ s/${prefix}HOST6IP/$HOST6IP/g;
+    $$thing =~ s/${prefix}HOSTIP/$HOSTIP/g;
+
+    # misc
+    $$thing =~ s/${prefix}CURL/$CURL/g;
+    $$thing =~ s/${prefix}PWD/$pwd/g;
+    $$thing =~ s/${prefix}POSIX_PWD/$posix_pwd/g;
+
+    my $file_pwd = $pwd;
+    if($file_pwd !~ /^\//) {
+        $file_pwd = "/$file_pwd";
+    }
+
+    $$thing =~ s/${prefix}FILE_PWD/$file_pwd/g;
+    $$thing =~ s/${prefix}SRCDIR/$srcdir/g;
+    $$thing =~ s/${prefix}USER/$USER/g;
+
+    $$thing =~ s/${prefix}SSHSRVMD5/$SSHSRVMD5/g;
+
+    # The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
+    # used for time-out tests and that would work on most hosts as these
+    # adjust for the startup/check time for this particular host. We needed to
+    # do this to make the test suite run better on very slow hosts.
+    my $ftp2 = $ftpchecktime * 2;
+    my $ftp3 = $ftpchecktime * 3;
+
+    $$thing =~ s/${prefix}FTPTIME2/$ftp2/g;
+    $$thing =~ s/${prefix}FTPTIME3/$ftp3/g;
+
+    # HTTP2
+    $$thing =~ s/${prefix}H2CVER/$h2cver/g;
 }
 
 sub fixarray {
@@ -3414,6 +3492,25 @@ sub singletest {
         $why = serverfortest($testnum);
     }
 
+    # Save a preprocessed version of the entire test file. This allows more
+    # "basic" test case readers to enjoy variable replacements.
+    my @entiretest = fulltest();
+    my $otest = "log/test$testnum";
+    open(D, ">$otest");
+    my $diff;
+    for my $s (@entiretest) {
+        my $f = $s;
+        subVariables(\$s, "%");
+        if($f ne $s) {
+            $diff++;
+        }
+        print D $s;
+    }
+    close(D);
+    # remove the separate test file again if nothing was updated to keep
+    # things simpler
+    unlink($otest) if(!$diff);
+
     # timestamp required servers verification end
     $timesrvrend{$testnum} = Time::HiRes::time();
 
@@ -3453,7 +3550,7 @@ sub singletest {
         if(@precheck) {
             $cmd = $precheck[0];
             chomp $cmd;
-            subVariables \$cmd;
+            subVariables(\$cmd);
             if($cmd) {
                 my @p = split(/ /, $cmd);
                 if($p[0] !~ /\//) {
@@ -3532,6 +3629,9 @@ sub singletest {
             map s/\n/\r\n/g, @reply;
         }
     }
+    for my $r (@reply) {
+        subVariables(\$r);
+    }
 
     # this is the valid protocol blurb curl should generate
     my @protocol= fixarray ( getpart("verify", "protocol") );
@@ -3584,10 +3684,9 @@ sub singletest {
     unlink($SERVER2IN);
     unlink($PROXYIN);
 
-    if(@ftpservercmd) {
-        # write the instructions to file
-        writearray($FTPDCMD, \@ftpservercmd);
-    }
+    push @ftpservercmd, "Testnum $testnum\n";
+    # write the instructions to file
+    writearray($FTPDCMD, \@ftpservercmd);
 
     # get the command line options to use
     my @blaha;
@@ -3597,7 +3696,7 @@ sub singletest {
         # make some nice replace operations
         $cmd =~ s/\n//g; # no newlines please
         # substitute variables in the command line
-        subVariables \$cmd;
+        subVariables(\$cmd);
     }
     else {
         # there was no command given, use something silly
@@ -3680,9 +3779,14 @@ sub singletest {
         if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-include/)) {
             $inc = " --include";
         }
-
         $cmdargs = "$out$inc ";
-        $cmdargs .= "--trace-ascii log/trace$testnum ";
+
+        if($cmdhash{'option'} && ($cmdhash{'option'} =~ /binary-trace/)) {
+            $cmdargs .= "--trace log/trace$testnum ";
+        }
+        else {
+            $cmdargs .= "--trace-ascii log/trace$testnum ";
+        }
         $cmdargs .= "--trace-time ";
         if($evbased) {
             $cmdargs .= "--test-event ";
@@ -3872,70 +3976,12 @@ sub singletest {
 
     my @killtestservers = getpart("client", "killserver");
     if(@killtestservers) {
-        #
-        # All servers relative to the given one must be stopped also
-        #
-        my @killservers;
         foreach my $server (@killtestservers) {
             chomp $server;
-            if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) 
{
-                # given a stunnel ssl server, also kill non-ssl underlying one
-                push @killservers, "${1}${2}";
-            }
-            elsif($server =~ 
/^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|-unix|))$/) {
-                # given a non-ssl server, also kill stunnel piggybacking one
-                push @killservers, "${1}s${2}";
-            }
-            elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
-                # given a socks server, also kill ssh underlying one
-                push @killservers, "ssh${2}";
-            }
-            elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
-                # given a ssh server, also kill socks piggybacking one
-                push @killservers, "socks${2}";
-            }
-            push @killservers, $server;
-        }
-        #
-        # kill sockfilter processes for pingpong relative servers
-        #
-        foreach my $server (@killservers) {
-            if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
-                my $proto  = $1;
-                my $idnum  = ($2 && ($2 > 1)) ? $2 : 1;
-                my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
-                killsockfilters($proto, $ipvnum, $idnum, $verbose);
-            }
-        }
-        #
-        # kill server relative pids clearing them in %run hash
-        #
-        my $pidlist;
-        foreach my $server (@killservers) {
-            if($run{$server}) {
-                $pidlist .= "$run{$server} ";
-                $run{$server} = 0;
-            }
-            $runcert{$server} = 0 if($runcert{$server});
-        }
-        killpid($verbose, $pidlist);
-        #
-        # cleanup server pid files
-        #
-        foreach my $server (@killservers) {
-            my $pidfile = $serverpidfile{$server};
-            my $pid = processexists($pidfile);
-            if($pid > 0) {
-                logmsg "Warning: $server server unexpectedly alive\n";
-                killpid($verbose, $pid);
-            }
-            unlink($pidfile) if(-f $pidfile);
+            stopserver($server);
         }
     }
 
-    # remove the test server commands file after each test
-    unlink($FTPDCMD) if(-f $FTPDCMD);
-
     # run the postcheck command
     my @postcheck= getpart("client", "postcheck");
     if(@postcheck) {
@@ -4118,6 +4164,13 @@ sub singletest {
             }
         }
 
+        if((!$out[0] || ($out[0] eq "")) && $protstrip[0]) {
+            logmsg "\n $testnum: protocol FAILED!\n".
+                " There was no content at all in the file $SERVERIN.\n".
+                " Server glitch? Total curl failure? Returned: $cmdres\n";
+            return $errorreturncode;
+        }
+
         $res = compare($testnum, $testname, "protocol", \@out, \@protstrip);
         if($res) {
             return $errorreturncode;
@@ -4366,7 +4419,7 @@ sub singletest {
             $ok .= "v";
         }
         else {
-            if(!$short && !$disablevalgrind) {
+            if($verbose && !$disablevalgrind) {
                 logmsg " valgrind SKIPPED\n";
             }
             $ok .= "-"; # skipped
@@ -4523,8 +4576,8 @@ sub startservers {
                 stopserver('gopher');
             }
             if(!$run{'gopher'}) {
-                ($pid, $pid2) = runhttpserver("gopher", $verbose, 0,
-                                              $GOPHERPORT);
+                ($pid, $pid2, $GOPHERPORT) =
+                    runhttpserver("gopher", $verbose, 0);
                 if($pid <= 0) {
                     return "failed starting GOPHER server";
                 }
@@ -4540,8 +4593,8 @@ sub startservers {
                 stopserver('gopher-ipv6');
             }
             if(!$run{'gopher-ipv6'}) {
-                ($pid, $pid2) = runhttpserver("gopher", $verbose, "ipv6",
-                                              $GOPHER6PORT);
+                ($pid, $pid2, $GOPHER6PORT) =
+                    runhttpserver("gopher", $verbose, "ipv6");
                 if($pid <= 0) {
                     return "failed starting GOPHER-IPv6 server";
                 }
@@ -4567,8 +4620,8 @@ sub startservers {
                 stopserver('http');
             }
             if(!$run{'http'}) {
-                ($pid, $pid2) = runhttpserver("http", $verbose, 0,
-                                              $HTTPPORT);
+                ($pid, $pid2, $HTTPPORT) =
+                    runhttpserver("http", $verbose, 0);
                 if($pid <= 0) {
                     return "failed starting HTTP server";
                 }
@@ -4584,8 +4637,8 @@ sub startservers {
                 stopserver('http-proxy');
             }
             if(!$run{'http-proxy'}) {
-                ($pid, $pid2) = runhttpserver("http", $verbose, "proxy",
-                                              $HTTPPROXYPORT);
+                ($pid, $pid2, $HTTPPROXYPORT) =
+                    runhttpserver("http", $verbose, "proxy");
                 if($pid <= 0) {
                     return "failed starting HTTP-proxy server";
                 }
@@ -4600,8 +4653,8 @@ sub startservers {
                 stopserver('http-ipv6');
             }
             if(!$run{'http-ipv6'}) {
-                ($pid, $pid2) = runhttpserver("http", $verbose, "ipv6",
-                                              $HTTP6PORT);
+                ($pid, $pid2, $HTTP6PORT) =
+                    runhttpserver("http", $verbose, "ipv6");
                 if($pid <= 0) {
                     return "failed starting HTTP-IPv6 server";
                 }
@@ -4616,7 +4669,7 @@ sub startservers {
                 stopserver('rtsp');
             }
             if(!$run{'rtsp'}) {
-                ($pid, $pid2) = runrtspserver($verbose);
+                ($pid, $pid2, $RTSPPORT) = runrtspserver($verbose);
                 if($pid <= 0) {
                     return "failed starting RTSP server";
                 }
@@ -4630,7 +4683,7 @@ sub startservers {
                 stopserver('rtsp-ipv6');
             }
             if(!$run{'rtsp-ipv6'}) {
-                ($pid, $pid2) = runrtspserver($verbose, "ipv6");
+                ($pid, $pid2, $RTSP6PORT) = runrtspserver($verbose, "ipv6");
                 if($pid <= 0) {
                     return "failed starting RTSP-IPv6 server";
                 }
@@ -4687,8 +4740,8 @@ sub startservers {
                 stopserver('http');
             }
             if(!$run{'http'}) {
-                ($pid, $pid2) = runhttpserver("http", $verbose, 0,
-                                              $HTTPPORT);
+                ($pid, $pid2, $HTTPPORT) =
+                    runhttpserver("http", $verbose, 0);
                 if($pid <= 0) {
                     return "failed starting HTTP server";
                 }
@@ -4749,7 +4802,8 @@ sub startservers {
                 stopserver('tftp');
             }
             if(!$run{'tftp'}) {
-                ($pid, $pid2) = runtftpserver("", $verbose);
+                ($pid, $pid2, $TFTPPORT) =
+                    runtftpserver("", $verbose);
                 if($pid <= 0) {
                     return "failed starting TFTP server";
                 }
@@ -4763,7 +4817,8 @@ sub startservers {
                 stopserver('tftp-ipv6');
             }
             if(!$run{'tftp-ipv6'}) {
-                ($pid, $pid2) = runtftpserver("", $verbose, "ipv6");
+                ($pid, $pid2, $TFTP6PORT) =
+                    runtftpserver("", $verbose, "ipv6");
                 if($pid <= 0) {
                     return "failed starting TFTP-IPv6 server";
                 }
@@ -4783,7 +4838,7 @@ sub startservers {
         }
         elsif($what eq "socks4" || $what eq "socks5" ) {
             if(!$run{'socks'}) {
-                ($pid, $pid2) = runsocksserver("", $verbose);
+                ($pid, $pid2, $SOCKSPORT) = runsocksserver("", $verbose);
                 if($pid <= 0) {
                     return "failed starting socks server";
                 }
@@ -4791,14 +4846,25 @@ sub startservers {
                 $run{'socks'}="$pid $pid2";
             }
         }
+        elsif($what eq "mqtt" ) {
+            if(!$run{'mqtt'}) {
+                ($pid, $pid2) = runmqttserver("", $verbose);
+                if($pid <= 0) {
+                    return "failed starting mqtt server";
+                }
+                printf ("* pid mqtt => %d %d\n", $pid, $pid2) if($verbose);
+                $run{'mqtt'}="$pid $pid2";
+            }
+        }
         elsif($what eq "http-unix") {
             if($torture && $run{'http-unix'} &&
                !responsive_http_server("http", $verbose, "unix", 
$HTTPUNIXPATH)) {
                 stopserver('http-unix');
             }
             if(!$run{'http-unix'}) {
-                ($pid, $pid2) = runhttpserver("http", $verbose, "unix",
-                                              $HTTPUNIXPATH);
+                my $unused;
+                ($pid, $pid2, $unused) =
+                    runhttpserver("http", $verbose, "unix", $HTTPUNIXPATH);
                 if($pid <= 0) {
                     return "failed starting HTTP-unix server";
                 }
@@ -5328,37 +5394,17 @@ if ($gdbthis) {
 }
 
 $minport         = $base; # original base port number
-
-$HTTPPORT        = $base++; # HTTP server port
 $HTTPSPORT       = $base++; # HTTPS (stunnel) server port
-$FTPPORT         = $base++; # FTP server port
 $FTPSPORT        = $base++; # FTPS (stunnel) server port
-$HTTP6PORT       = $base++; # HTTP IPv6 server port
-$FTP2PORT        = $base++; # FTP server 2 port
-$FTP6PORT        = $base++; # FTP IPv6 port
-$TFTPPORT        = $base++; # TFTP (UDP) port
-$TFTP6PORT       = $base++; # TFTP IPv6 (UDP) port
 $SSHPORT         = $base++; # SSH (SCP/SFTP) port
-$SOCKSPORT       = $base++; # SOCKS port
-$POP3PORT        = $base++; # POP3 server port
-$POP36PORT       = $base++; # POP3 IPv6 server port
-$IMAPPORT        = $base++; # IMAP server port
-$IMAP6PORT       = $base++; # IMAP IPv6 server port
-$SMTPPORT        = $base++; # SMTP server port
-$SMTP6PORT       = $base++; # SMTP IPv6 server port
-$RTSPPORT        = $base++; # RTSP server port
-$RTSP6PORT       = $base++; # RTSP IPv6 server port
-$GOPHERPORT      = $base++; # Gopher IPv4 server port
-$GOPHER6PORT     = $base++; # Gopher IPv6 server port
 $HTTPTLSPORT     = $base++; # HTTP TLS (non-stunnel) server port
 $HTTPTLS6PORT    = $base++; # HTTP TLS (non-stunnel) IPv6 server port
-$HTTPPROXYPORT   = $base++; # HTTP proxy port, when using CONNECT
 $HTTP2PORT       = $base++; # HTTP/2 port
 $DICTPORT        = $base++; # DICT port
 $SMBPORT         = $base++; # SMB port
 $SMBSPORT        = $base++; # SMBS port
 $NEGTELNETPORT   = $base++; # TELNET port with negotiation
-$HTTPUNIXPATH    = 'http.sock'; # HTTP server Unix domain socket path
+$HTTPUNIXPATH    = "http$$.sock"; # HTTP server Unix domain socket path
 
 $maxport         = $base-1; # updated base port number
 
@@ -5398,7 +5444,13 @@ sub disabledtests {
                 next;
             }
             if($_ =~ /(\d+)/) {
-                $disabled{$1}=$1; # disable this test number
+                my ($n) = $1;
+                $disabled{$n}=$n; # disable this test number
+                if(! -f "$srcdir/data/test$n") {
+                    print STDERR "WARNING! Non-exiting test $n in DISABLED!\n";
+                    # fail hard to make user notice
+                    exit 1;
+                }
             }
         }
         close(D);
@@ -5560,6 +5612,9 @@ sub displaylogs {
         if(($log =~ /^valgrind\d+/) && ($log !~ /^valgrind$testnum(\..*|)$/)) {
             next; # skip valgrindNnn of other tests
         }
+        if(($log =~ /^test$testnum$/)) {
+            next; # skip test$testnum since it can be very big
+        }
         logmsg "=== Start of file $log\n";
         displaylogcontent("$LOGDIR/$log");
         logmsg "=== End of file $log\n";
diff --git a/tests/secureserver.pl b/tests/secureserver.pl
index 969fb17b5..c525ef7d8 100755
--- a/tests/secureserver.pl
+++ b/tests/secureserver.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -329,6 +329,7 @@ if($stunnel_version >= 400) {
 # Set file permissions on certificate pem file.
 #
 chmod(0600, $certfile) if(-f $certfile);
+print STDERR "RUN: $cmd\n" if($verbose);
 
 #***************************************************************************
 # Run tstunnel on Windows.
@@ -341,8 +342,10 @@ if($tstunnel_windows) {
     }
 
     # Put an "exec" in front of the command so that the child process
-    # keeps this child's process ID.
+    # keeps this child's process ID by being tied to the spawned shell.
     exec("exec $cmd") || die "Can't exec() $cmd: $!";
+    # exec() will create a new process, but ties the existance of the
+    # new process to the parent waiting perl.exe and sh.exe processes.
 
     # exec() should never return back here to this process. We protect
     # ourselves by calling die() just in case something goes really bad.
diff --git a/tests/server/.gitignore b/tests/server/.gitignore
index 94329f7da..2c8d36895 100644
--- a/tests/server/.gitignore
+++ b/tests/server/.gitignore
@@ -7,3 +7,4 @@ sws
 tftpd
 socksd
 disabled
+mqttd
diff --git a/tests/server/CMakeLists.txt b/tests/server/CMakeLists.txt
index 3a15284e4..71054a462 100644
--- a/tests/server/CMakeLists.txt
+++ b/tests/server/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2009 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 set(TARGET_LABEL_PREFIX "Test server ")
 
 if(MSVC)
diff --git a/tests/server/Makefile.inc b/tests/server/Makefile.inc
index 6296af7cc..fb13d79cb 100644
--- a/tests/server/Makefile.inc
+++ b/tests/server/Makefile.inc
@@ -1,4 +1,27 @@
-noinst_PROGRAMS = getpart resolve rtspd sockfilt sws tftpd fake_ntlm socksd 
disabled
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2009 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+noinst_PROGRAMS = getpart resolve rtspd sockfilt sws tftpd fake_ntlm    \
+ socksd disabled mqttd
 
 CURLX_SRCS = \
  ../../lib/mprintf.c \
@@ -56,6 +79,12 @@ socksd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) 
$(UTIL) \
 socksd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
 socksd_CFLAGS = $(AM_CFLAGS)
 
+mqttd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
+ server_sockaddr.h mqttd.c \
+ ../../lib/inet_pton.c
+mqttd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
+mqttd_CFLAGS = $(AM_CFLAGS)
+
 sws_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
  server_sockaddr.h \
  sws.c \
diff --git a/tests/server/base64.pl b/tests/server/base64.pl
index 449c3103a..d00673ec9 100755
--- a/tests/server/base64.pl
+++ b/tests/server/base64.pl
@@ -1,4 +1,25 @@
 #!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2004 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
 use MIME::Base64 qw(encode_base64);
 
diff --git a/tests/server/fake_ntlm.c b/tests/server/fake_ntlm.c
index c6e36b6f6..c9211f7ea 100644
--- a/tests/server/fake_ntlm.c
+++ b/tests/server/fake_ntlm.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2010, Mandy Wu, <address@hidden>
- * Copyright (C) 2011 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2011 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -112,7 +112,6 @@ int main(int argc, char *argv[])
   char buf[1024];
   char logfilename[256];
   FILE *stream;
-  char *filename;
   int error;
   char *type1_input = NULL, *type3_input = NULL;
   char *type1_output = NULL, *type3_output = NULL;
@@ -186,12 +185,10 @@ int main(int argc, char *argv[])
     path = env;
   }
 
-  filename = test2file(testnum);
-  stream = fopen(filename, "rb");
+  stream = test2fopen(testnum);
   if(!stream) {
     error = errno;
     logmsg("fopen() failed with error: %d %s", error, strerror(error));
-    logmsg("Error opening file: %s", filename);
     logmsg("Couldn't open test file %ld", testnum);
     exit(1);
   }
@@ -205,13 +202,11 @@ int main(int argc, char *argv[])
     }
   }
 
-  stream = fopen(filename, "rb");
+  stream = test2fopen(testnum);
   if(!stream) {
     error = errno;
     logmsg("fopen() failed with error: %d %s", error, strerror(error));
-    logmsg("Error opening file: %s", filename);
     logmsg("Couldn't open test file %ld", testnum);
-    exit(1);
   }
   else {
     size = 0;
@@ -225,11 +220,10 @@ int main(int argc, char *argv[])
 
   while(fgets(buf, sizeof(buf), stdin)) {
     if(strcmp(buf, type1_input) == 0) {
-      stream = fopen(filename, "rb");
+      stream = test2fopen(testnum);
       if(!stream) {
         error = errno;
         logmsg("fopen() failed with error: %d %s", error, strerror(error));
-        logmsg("Error opening file: %s", filename);
         logmsg("Couldn't open test file %ld", testnum);
         exit(1);
       }
@@ -247,11 +241,10 @@ int main(int argc, char *argv[])
       fflush(stdout);
     }
     else if(strncmp(buf, type3_input, strlen(type3_input)) == 0) {
-      stream = fopen(filename, "rb");
+      stream = test2fopen(testnum);
       if(!stream) {
         error = errno;
         logmsg("fopen() failed with error: %d %s", error, strerror(error));
-        logmsg("Error opening file: %s", filename);
         logmsg("Couldn't open test file %ld", testnum);
         exit(1);
       }
diff --git a/tests/server/getpart.c b/tests/server/getpart.c
index 044705d06..664d81569 100644
--- a/tests/server/getpart.c
+++ b/tests/server/getpart.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/server/getpart.h b/tests/server/getpart.h
index 277368519..e8ddd22aa 100644
--- a/tests/server/getpart.h
+++ b/tests/server/getpart.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/server/mqttd.c b/tests/server/mqttd.c
new file mode 100644
index 000000000..6785b0014
--- /dev/null
+++ b/tests/server/mqttd.c
@@ -0,0 +1,1018 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "server_setup.h"
+#include <stdlib.h>
+#include <string.h>
+#include "util.h"
+
+/* Function
+ *
+ * Accepts a TCP connection on a custom port (IPv4 or IPv6).  Speaks MQTT.
+ *
+ * Read commands from FILE (set with --config). The commands control how to
+ * act and is reset to defaults each client TCP connect.
+ *
+ * Config file keywords:
+ *
+ * TODO
+ */
+
+/* based on sockfilt.c */
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#define ENABLE_CURLX_PRINTF
+/* make the curlx header define all printf() functions to use the curlx_*
+   versions instead */
+#include "curlx.h" /* from the private lib dir */
+#include "getpart.h"
+#include "inet_pton.h"
+#include "util.h"
+#include "server_sockaddr.h"
+#include "warnless.h"
+
+/* include memdebug.h last */
+#include "memdebug.h"
+
+#ifdef USE_WINSOCK
+#undef  EINTR
+#define EINTR    4 /* errno.h value */
+#undef  EAGAIN
+#define EAGAIN  11 /* errno.h value */
+#undef  ENOMEM
+#define ENOMEM  12 /* errno.h value */
+#undef  EINVAL
+#define EINVAL  22 /* errno.h value */
+#endif
+
+#define DEFAULT_PORT 1883 /* MQTT default port */
+
+#ifndef DEFAULT_LOGFILE
+#define DEFAULT_LOGFILE "log/mqttd.log"
+#endif
+
+#ifndef DEFAULT_CONFIG
+#define DEFAULT_CONFIG "mqttd.config"
+#endif
+
+#define MQTT_MSG_CONNECT    0x10
+#define MQTT_MSG_CONNACK    0x20
+#define MQTT_MSG_PUBLISH    0x30
+#define MQTT_MSG_PUBACK     0x40
+#define MQTT_MSG_SUBSCRIBE  0x82
+#define MQTT_MSG_SUBACK     0x90
+#define MQTT_MSG_DISCONNECT 0xe0
+
+#define MQTT_CONNACK_LEN 4
+#define MQTT_SUBACK_LEN 5
+#define MQTT_CLIENTID_LEN 12 /* "curl0123abcd" */
+#define MQTT_HEADER_LEN 5    /* max 5 bytes */
+
+struct configurable {
+  unsigned char version; /* initial version byte in the request must match
+                            this */
+  bool publish_before_suback;
+  bool short_publish;
+  unsigned char error_connack;
+  int testnum;
+};
+
+#define REQUEST_DUMP  "log/server.input"
+#define CONFIG_VERSION 5
+
+static struct configurable config;
+
+const char *serverlogfile = DEFAULT_LOGFILE;
+static const char *configfile = DEFAULT_CONFIG;
+
+#ifdef ENABLE_IPV6
+static bool use_ipv6 = FALSE;
+#endif
+static const char *ipv_inuse = "IPv4";
+static unsigned short port = DEFAULT_PORT;
+
+static void resetdefaults(void)
+{
+  logmsg("Reset to defaults");
+  config.version = CONFIG_VERSION;
+  config.publish_before_suback = FALSE;
+  config.short_publish = FALSE;
+  config.error_connack = 0;
+  config.testnum = 0;
+}
+
+static unsigned char byteval(char *value)
+{
+  unsigned long num = strtoul(value, NULL, 10);
+  return num & 0xff;
+}
+
+static void getconfig(void)
+{
+  FILE *fp = fopen(configfile, FOPEN_READTEXT);
+  resetdefaults();
+  if(fp) {
+    char buffer[512];
+    logmsg("parse config file");
+    while(fgets(buffer, sizeof(buffer), fp)) {
+      char key[32];
+      char value[32];
+      if(2 == sscanf(buffer, "%31s %31s", key, value)) {
+        if(!strcmp(key, "version")) {
+          config.version = byteval(value);
+          logmsg("version [%d] set", config.version);
+        }
+        else if(!strcmp(key, "PUBLISH-before-SUBACK")) {
+          logmsg("PUBLISH-before-SUBACK set");
+          config.publish_before_suback = TRUE;
+        }
+        else if(!strcmp(key, "short-PUBLISH")) {
+          logmsg("short-PUBLISH set");
+          config.short_publish = TRUE;
+        }
+        else if(!strcmp(key, "error-CONNACK")) {
+          config.error_connack = byteval(value);
+          logmsg("error-CONNACK = %d", config.error_connack);
+        }
+        else if(!strcmp(key, "Testnum")) {
+          config.testnum = atoi(value);
+          logmsg("testnum = %d", config.testnum);
+        }
+      }
+    }
+    fclose(fp);
+  }
+  else {
+    logmsg("No config file '%s' to read", configfile);
+  }
+}
+
+static void loghex(unsigned char *buffer, ssize_t len)
+{
+  char data[12000];
+  ssize_t i;
+  unsigned char *ptr = buffer;
+  char *optr = data;
+  ssize_t width = 0;
+  int left = sizeof(data);
+
+  for(i = 0; i<len && (left >= 0); i++) {
+    msnprintf(optr, left, "%02x", ptr[i]);
+    width += 2;
+    optr += 2;
+    left -= 2;
+  }
+  if(width)
+    logmsg("'%s'", data);
+}
+
+typedef enum {
+  FROM_CLIENT,
+  FROM_SERVER
+} mqttdir;
+
+static void logprotocol(mqttdir dir,
+                        const char *prefix, size_t remlen,
+                        FILE *output,
+                        unsigned char *buffer, ssize_t len)
+{
+  char data[12000] = "";
+  ssize_t i;
+  unsigned char *ptr = buffer;
+  char *optr = data;
+  ssize_t width = 0;
+  int left = sizeof(data);
+
+  for(i = 0; i<len && (left >= 0); i++) {
+    msnprintf(optr, left, "%02x", ptr[i]);
+    width += 2;
+    optr += 2;
+    left -= 2;
+  }
+  fprintf(output, "%s %s %zx %s\n",
+          dir == FROM_CLIENT? "client": "server",
+          prefix, remlen,
+          data);
+}
+
+
+/* return 0 on success */
+static int connack(FILE *dump, curl_socket_t fd)
+{
+  unsigned char packet[]={
+    MQTT_MSG_CONNACK, 0x02,
+    0x00, 0x00
+  };
+  ssize_t rc;
+
+  packet[3] = config.error_connack;
+
+  rc = swrite(fd, (char *)packet, sizeof(packet));
+  if(rc > 0) {
+    logmsg("WROTE %d bytes [CONNACK]", rc);
+    loghex(packet, rc);
+    logprotocol(FROM_SERVER, "CONNACK", 2, dump, packet, sizeof(packet));
+  }
+  if(rc == sizeof(packet)) {
+    return 0;
+  }
+  return 1;
+}
+
+/* return 0 on success */
+static int suback(FILE *dump, curl_socket_t fd, unsigned short packetid)
+{
+  unsigned char packet[]={
+    MQTT_MSG_SUBACK, 0x03,
+    0, 0, /* filled in below */
+    0x00
+  };
+  ssize_t rc;
+  packet[2] = (unsigned char)(packetid >> 8);
+  packet[3] = (unsigned char)(packetid & 0xff);
+
+  rc = swrite(fd, (char *)packet, sizeof(packet));
+  if(rc == sizeof(packet)) {
+    logmsg("WROTE %d bytes [SUBACK]", rc);
+    loghex(packet, rc);
+    logprotocol(FROM_SERVER, "SUBACK", 3, dump, packet, rc);
+    return 0;
+  }
+  return 1;
+}
+
+#ifdef QOS
+/* return 0 on success */
+static int puback(FILE *dump, curl_socket_t fd, unsigned short packetid)
+{
+  unsigned char packet[]={
+    MQTT_MSG_PUBACK, 0x00,
+    0, 0 /* filled in below */
+  };
+  ssize_t rc;
+  packet[2] = (unsigned char)(packetid >> 8);
+  packet[3] = (unsigned char)(packetid & 0xff);
+
+  rc = swrite(fd, (char *)packet, sizeof(packet));
+  if(rc == sizeof(packet)) {
+    logmsg("WROTE %d bytes [PUBACK]", rc);
+    loghex(packet, rc);
+    logprotocol(FROM_SERVER, dump, packet, rc);
+    return 0;
+  }
+  logmsg("Failed sending [PUBACK]");
+  return 1;
+}
+#endif
+
+/* return 0 on success */
+static int disconnect(FILE *dump, curl_socket_t fd)
+{
+  unsigned char packet[]={
+    MQTT_MSG_DISCONNECT, 0x00,
+  };
+  ssize_t rc = swrite(fd, (char *)packet, sizeof(packet));
+  if(rc == sizeof(packet)) {
+    logmsg("WROTE %d bytes [DISCONNECT]", rc);
+    loghex(packet, rc);
+    logprotocol(FROM_SERVER, "DISCONNECT", 0, dump, packet, rc);
+    return 0;
+  }
+  logmsg("Failed sending [DISCONNECT]");
+  return 1;
+}
+
+
+
+/*
+  do
+
+     encodedByte = X MOD 128
+
+     X = X DIV 128
+
+     // if there are more data to encode, set the top bit of this byte
+
+     if ( X > 0 )
+
+        encodedByte = encodedByte OR 128
+
+      endif
+
+    'output' encodedByte
+
+  while ( X > 0 )
+
+*/
+
+/* return number of bytes used */
+static int encode_length(size_t packetlen, char *remlength) /* 4 bytes */
+{
+  int bytes = 0;
+  unsigned char encode;
+
+  do {
+    encode = packetlen % 0x80;
+    packetlen /= 0x80;
+    if(packetlen)
+      encode |= 0x80;
+
+    remlength[bytes++] = encode;
+
+    if(bytes > 3) {
+      logmsg("too large packet!");
+      return 0;
+    }
+  } while(packetlen);
+
+  return bytes;
+}
+
+
+static size_t decode_length(unsigned char *buf,
+                            size_t buflen, size_t *lenbytes)
+{
+  size_t len = 0;
+  size_t mult = 1;
+  size_t i;
+  unsigned char encoded = 0x80;
+
+  for(i = 0; (i < buflen) && (encoded & 0x80); i++) {
+    encoded = buf[i];
+    len += (encoded & 0x7f) * mult;
+    mult *= 0x80;
+  }
+
+  if(lenbytes)
+    *lenbytes = i;
+
+  return len;
+}
+
+
+/* return 0 on success */
+static int publish(FILE *dump,
+                   curl_socket_t fd, unsigned short packetid,
+                   char *topic, char *payload, size_t payloadlen)
+{
+  size_t topiclen = strlen(topic);
+  unsigned char *packet;
+  size_t payloadindex;
+  ssize_t remaininglength = topiclen + 2 + payloadlen;
+  ssize_t packetlen;
+  ssize_t sendamount;
+  ssize_t rc;
+  char rembuffer[4];
+  int encodedlen;
+
+  encodedlen = encode_length(remaininglength, rembuffer);
+
+  /* one packet type byte (possibly two more for packetid) */
+  packetlen = remaininglength + encodedlen + 1;
+  packet = malloc(packetlen);
+  if(!packet)
+    return 1;
+
+  packet[0] = MQTT_MSG_PUBLISH; /* TODO: set QoS? */
+  memcpy(&packet[1], rembuffer, encodedlen);
+
+  (void)packetid;
+  /* packet_id if QoS is set */
+
+  packet[1 + encodedlen] = (unsigned char)(topiclen >> 8);
+  packet[2 + encodedlen] = (unsigned char)(topiclen & 0xff);
+  memcpy(&packet[3 + encodedlen], topic, topiclen);
+
+  payloadindex = 3 + topiclen + encodedlen;
+  memcpy(&packet[payloadindex], payload, payloadlen);
+
+  sendamount = packetlen;
+  if(config.short_publish)
+    sendamount -= 2;
+
+  rc = swrite(fd, (char *)packet, sendamount);
+  if(rc > 0) {
+    logmsg("WROTE %d bytes [PUBLISH]", rc);
+    loghex(packet, rc);
+    logprotocol(FROM_SERVER, "PUBLISH", remaininglength, dump, packet, rc);
+  }
+  if(rc == packetlen)
+    return 0;
+  return 1;
+}
+
+#define MAX_TOPIC_LENGTH 65535
+#define MAX_CLIENT_ID_LENGTH 32
+
+static char topic[MAX_TOPIC_LENGTH + 1];
+
+static int fixedheader(curl_socket_t fd,
+                       unsigned char *bytep,
+                       size_t *remaining_lengthp,
+                       size_t *remaining_length_bytesp)
+{
+  /* get the fixed header */
+  unsigned char buffer[10];
+
+  /* get the first two bytes */
+  ssize_t rc = sread(fd, (char *)buffer, 2);
+  int i;
+  if(rc < 2) {
+    logmsg("READ %d bytes [SHORT!]", rc);
+    return 1; /* fail */
+  }
+  logmsg("READ %d bytes", rc);
+  loghex(buffer, rc);
+  *bytep = buffer[0];
+
+  /* if the length byte has the top bit set, get the next one too */
+  i = 1;
+  while(buffer[i] & 0x80) {
+    i++;
+    rc = sread(fd, (char *)&buffer[i], 1);
+    if(rc != 1) {
+      logmsg("Remaining Length broken");
+      return 1;
+    }
+  }
+  *remaining_lengthp = decode_length(&buffer[1], i, remaining_length_bytesp);
+  logmsg("Remaining Length: %ld [%d bytes]", (long) *remaining_lengthp,
+         *remaining_length_bytesp);
+  return 0;
+}
+
+static curl_socket_t mqttit(curl_socket_t fd)
+{
+  unsigned char buffer[10*1024];
+  ssize_t rc;
+  unsigned char byte;
+  unsigned short packet_id;
+  size_t payload_len;
+  unsigned int topic_len;
+  size_t remaining_length = 0;
+  size_t bytes = 0; /* remaining length field size in bytes */
+  char client_id[MAX_CLIENT_ID_LENGTH];
+  long testno;
+
+  static const char protocol[7] = {
+    0x00, 0x04,       /* protocol length */
+    'M','Q','T','T',  /* protocol name */
+    0x04              /* protocol level */
+  };
+  FILE *dump = fopen(REQUEST_DUMP, "ab");
+  if(!dump)
+    goto end;
+
+  getconfig();
+
+  testno = config.testnum;
+
+  if(testno)
+    logmsg("Found test number %ld", testno);
+
+  do {
+    /* get the fixed header */
+    rc = fixedheader(fd, &byte, &remaining_length, &bytes);
+    if(rc)
+      break;
+    if(remaining_length) {
+      rc = sread(fd, (char *)buffer, remaining_length);
+      if(rc > 0) {
+        logmsg("READ %d bytes", rc);
+        loghex(buffer, rc);
+      }
+    }
+
+    if(byte == MQTT_MSG_CONNECT) {
+      logprotocol(FROM_CLIENT, "CONNECT", remaining_length,
+                  dump, buffer, rc);
+
+      if(memcmp(protocol, buffer, sizeof(protocol))) {
+        logmsg("Protocol preamble mismatch");
+        goto end;
+      }
+      /* ignore the connect flag byte and two keepalive bytes */
+
+      payload_len = (buffer[10] << 8) | buffer[11];
+      if((ssize_t)payload_len != (rc - 12)) {
+        logmsg("Payload length mismatch, expected %x got %x",
+               rc - 12, payload_len);
+        goto end;
+      }
+      else if((payload_len + 1) > MAX_CLIENT_ID_LENGTH) {
+        logmsg("Too large client id");
+        goto end;
+      }
+      memcpy(client_id, &buffer[14], payload_len);
+      client_id[payload_len] = 0;
+
+      logmsg("MQTT client connect accepted: %s", client_id);
+
+      /* The first packet sent from the Server to the Client MUST be a
+         CONNACK Packet */
+
+      if(connack(dump, fd)) {
+        logmsg("failed sending CONNACK");
+        goto end;
+      }
+    }
+    else if(byte == MQTT_MSG_SUBSCRIBE) {
+      FILE *stream;
+      int error;
+      char *data;
+      size_t datalen;
+      logprotocol(FROM_CLIENT, "SUBSCRIBE", remaining_length,
+                  dump, buffer, rc);
+      logmsg("Incoming SUBSCRIBE");
+
+      if(rc < 6) {
+        logmsg("Too small SUBSCRIBE");
+        goto end;
+      }
+
+      /* two bytes packet id */
+      packet_id = (unsigned short)((buffer[0] << 8) | buffer[1]);
+
+      /* two bytes topic length */
+      topic_len = (buffer[2] << 8) | buffer[3];
+      if(topic_len != (remaining_length - 5)) {
+        logmsg("Wrong topic length, got %d expected %d",
+               topic_len, remaining_length - 5);
+        goto end;
+      }
+      memcpy(topic, &buffer[4], topic_len);
+      topic[topic_len] = 0;
+
+      /* there's a QoS byte (two bits) after the topic */
+
+      logmsg("SUBSCRIBE to '%s' [%d]", topic, packet_id);
+      stream = test2fopen(testno);
+      error = getpart(&data, &datalen, "reply", "data", stream);
+      if(!error) {
+        if(!config.publish_before_suback) {
+          if(suback(dump, fd, packet_id)) {
+            logmsg("failed sending SUBACK");
+            goto end;
+          }
+        }
+        if(publish(dump, fd, packet_id, topic, data, datalen)) {
+          logmsg("PUBLISH failed");
+          goto end;
+        }
+        if(config.publish_before_suback) {
+          if(suback(dump, fd, packet_id)) {
+            logmsg("failed sending SUBACK");
+            goto end;
+          }
+        }
+      }
+      else {
+        char *def = (char *)"this is random payload yes yes it is";
+        publish(dump, fd, packet_id, topic, def, strlen(def));
+      }
+      disconnect(dump, fd);
+    }
+    else if((byte & 0xf0) == (MQTT_MSG_PUBLISH & 0xf0)) {
+      size_t topiclen;
+
+      logmsg("Incoming PUBLISH");
+      logprotocol(FROM_CLIENT, "PUBLISH", remaining_length,
+                  dump, buffer, rc);
+
+      topiclen = (buffer[1 + bytes] << 8) | buffer[2 + bytes];
+      logmsg("Got %d bytes topic", topiclen);
+      /* TODO: verify topiclen */
+
+#ifdef QOS
+      /* TODO: handle packetid if there is one. Send puback if QoS > 0 */
+      puback(dump, fd, 0);
+#endif
+      /* expect a disconnect here */
+      /* get the request */
+      rc = sread(fd, (char *)&buffer[0], 2);
+
+      logmsg("READ %d bytes [DISCONNECT]", rc);
+      loghex(buffer, rc);
+      logprotocol(FROM_CLIENT, "DISCONNECT", 0, dump, buffer, rc);
+      goto end;
+    }
+    else {
+      /* not supported (yet) */
+      goto end;
+    }
+  } while(1);
+
+  end:
+  fclose(dump);
+  return CURL_SOCKET_BAD;
+}
+
+/*
+  sockfdp is a pointer to an established stream or CURL_SOCKET_BAD
+
+  if sockfd is CURL_SOCKET_BAD, listendfd is a listening socket we must
+  accept()
+*/
+static bool incoming(curl_socket_t listenfd)
+{
+  fd_set fds_read;
+  fd_set fds_write;
+  fd_set fds_err;
+  int clients = 0; /* connected clients */
+
+  if(got_exit_signal) {
+    logmsg("signalled to die, exiting...");
+    return FALSE;
+  }
+
+#ifdef HAVE_GETPPID
+  /* As a last resort, quit if socks5 process becomes orphan. */
+  if(getppid() <= 1) {
+    logmsg("process becomes orphan, exiting");
+    return FALSE;
+  }
+#endif
+
+  do {
+    ssize_t rc;
+    int error = 0;
+    curl_socket_t sockfd = listenfd;
+    int maxfd = (int)sockfd;
+
+    FD_ZERO(&fds_read);
+    FD_ZERO(&fds_write);
+    FD_ZERO(&fds_err);
+
+    /* there's always a socket to wait for */
+    FD_SET(sockfd, &fds_read);
+
+    do {
+      /* select() blocking behavior call on blocking descriptors please */
+      rc = select(maxfd + 1, &fds_read, &fds_write, &fds_err, NULL);
+      if(got_exit_signal) {
+        logmsg("signalled to die, exiting...");
+        return FALSE;
+      }
+    } while((rc == -1) && ((error = SOCKERRNO) == EINTR));
+
+    if(rc < 0) {
+      logmsg("select() failed with error: (%d) %s",
+             error, strerror(error));
+      return FALSE;
+    }
+
+    if(FD_ISSET(sockfd, &fds_read)) {
+      curl_socket_t newfd = accept(sockfd, NULL, NULL);
+      if(CURL_SOCKET_BAD == newfd) {
+        error = SOCKERRNO;
+        logmsg("accept(%d, NULL, NULL) failed with error: (%d) %s",
+               sockfd, error, strerror(error));
+      }
+      else {
+        logmsg("====> Client connect, fd %d. Read config from %s",
+               newfd, configfile);
+        set_advisor_read_lock(SERVERLOGS_LOCK);
+        (void)mqttit(newfd); /* until done */
+        clear_advisor_read_lock(SERVERLOGS_LOCK);
+
+        logmsg("====> Client disconnect");
+        sclose(newfd);
+      }
+    }
+  } while(clients);
+
+  return TRUE;
+}
+
+static curl_socket_t sockdaemon(curl_socket_t sock,
+                                unsigned short *listenport)
+{
+  /* passive daemon style */
+  srvr_sockaddr_union_t listener;
+  int flag;
+  int rc;
+  int totdelay = 0;
+  int maxretr = 10;
+  int delay = 20;
+  int attempt = 0;
+  int error = 0;
+
+  do {
+    attempt++;
+    flag = 1;
+    rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+         (void *)&flag, sizeof(flag));
+    if(rc) {
+      error = SOCKERRNO;
+      logmsg("setsockopt(SO_REUSEADDR) failed with error: (%d) %s",
+             error, strerror(error));
+      if(maxretr) {
+        rc = wait_ms(delay);
+        if(rc) {
+          /* should not happen */
+          logmsg("wait_ms() failed with error: %d", rc);
+          sclose(sock);
+          return CURL_SOCKET_BAD;
+        }
+        if(got_exit_signal) {
+          logmsg("signalled to die, exiting...");
+          sclose(sock);
+          return CURL_SOCKET_BAD;
+        }
+        totdelay += delay;
+        delay *= 2; /* double the sleep for next attempt */
+      }
+    }
+  } while(rc && maxretr--);
+
+  if(rc) {
+    logmsg("setsockopt(SO_REUSEADDR) failed %d times in %d ms. Error: (%d) %s",
+           attempt, totdelay, error, strerror(error));
+    logmsg("Continuing anyway...");
+  }
+
+  /* When the specified listener port is zero, it is actually a
+     request to let the system choose a non-zero available port. */
+
+#ifdef ENABLE_IPV6
+  if(!use_ipv6) {
+#endif
+    memset(&listener.sa4, 0, sizeof(listener.sa4));
+    listener.sa4.sin_family = AF_INET;
+    listener.sa4.sin_addr.s_addr = INADDR_ANY;
+    listener.sa4.sin_port = htons(*listenport);
+    rc = bind(sock, &listener.sa, sizeof(listener.sa4));
+#ifdef ENABLE_IPV6
+  }
+  else {
+    memset(&listener.sa6, 0, sizeof(listener.sa6));
+    listener.sa6.sin6_family = AF_INET6;
+    listener.sa6.sin6_addr = in6addr_any;
+    listener.sa6.sin6_port = htons(*listenport);
+    rc = bind(sock, &listener.sa, sizeof(listener.sa6));
+  }
+#endif /* ENABLE_IPV6 */
+  if(rc) {
+    error = SOCKERRNO;
+    logmsg("Error binding socket on port %hu: (%d) %s",
+           *listenport, error, strerror(error));
+    sclose(sock);
+    return CURL_SOCKET_BAD;
+  }
+
+  if(!*listenport) {
+    /* The system was supposed to choose a port number, figure out which
+       port we actually got and update the listener port value with it. */
+    curl_socklen_t la_size;
+    srvr_sockaddr_union_t localaddr;
+#ifdef ENABLE_IPV6
+    if(!use_ipv6)
+#endif
+      la_size = sizeof(localaddr.sa4);
+#ifdef ENABLE_IPV6
+    else
+      la_size = sizeof(localaddr.sa6);
+#endif
+    memset(&localaddr.sa, 0, (size_t)la_size);
+    if(getsockname(sock, &localaddr.sa, &la_size) < 0) {
+      error = SOCKERRNO;
+      logmsg("getsockname() failed with error: (%d) %s",
+             error, strerror(error));
+      sclose(sock);
+      return CURL_SOCKET_BAD;
+    }
+    switch(localaddr.sa.sa_family) {
+    case AF_INET:
+      *listenport = ntohs(localaddr.sa4.sin_port);
+      break;
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      *listenport = ntohs(localaddr.sa6.sin6_port);
+      break;
+#endif
+    default:
+      break;
+    }
+    if(!*listenport) {
+      /* Real failure, listener port shall not be zero beyond this point. */
+      logmsg("Apparently getsockname() succeeded, with listener port zero.");
+      logmsg("A valid reason for this failure is a binary built without");
+      logmsg("proper network library linkage. This might not be the only");
+      logmsg("reason, but double check it before anything else.");
+      sclose(sock);
+      return CURL_SOCKET_BAD;
+    }
+  }
+
+  /* start accepting connections */
+  rc = listen(sock, 5);
+  if(0 != rc) {
+    error = SOCKERRNO;
+    logmsg("listen(%d, 5) failed with error: (%d) %s",
+           sock, error, strerror(error));
+    sclose(sock);
+    return CURL_SOCKET_BAD;
+  }
+
+  return sock;
+}
+
+
+int main(int argc, char *argv[])
+{
+  curl_socket_t sock = CURL_SOCKET_BAD;
+  curl_socket_t msgsock = CURL_SOCKET_BAD;
+  int wrotepidfile = 0;
+  int wroteportfile = 0;
+  const char *pidname = ".mqttd.pid";
+  const char *portname = ".mqttd.port";
+  bool juggle_again;
+  int error;
+  int arg = 1;
+
+  while(argc>arg) {
+    if(!strcmp("--version", argv[arg])) {
+      printf("mqttd IPv4%s\n",
+#ifdef ENABLE_IPV6
+             "/IPv6"
+#else
+             ""
+#endif
+             );
+      return 0;
+    }
+    else if(!strcmp("--pidfile", argv[arg])) {
+      arg++;
+      if(argc>arg)
+        pidname = argv[arg++];
+    }
+    else if(!strcmp("--portfile", argv[arg])) {
+      arg++;
+      if(argc>arg)
+        portname = argv[arg++];
+    }
+    else if(!strcmp("--config", argv[arg])) {
+      arg++;
+      if(argc>arg)
+        configfile = argv[arg++];
+    }
+    else if(!strcmp("--logfile", argv[arg])) {
+      arg++;
+      if(argc>arg)
+        serverlogfile = argv[arg++];
+    }
+    else if(!strcmp("--ipv6", argv[arg])) {
+#ifdef ENABLE_IPV6
+      ipv_inuse = "IPv6";
+      use_ipv6 = TRUE;
+#endif
+      arg++;
+    }
+    else if(!strcmp("--ipv4", argv[arg])) {
+      /* for completeness, we support this option as well */
+#ifdef ENABLE_IPV6
+      ipv_inuse = "IPv4";
+      use_ipv6 = FALSE;
+#endif
+      arg++;
+    }
+    else if(!strcmp("--port", argv[arg])) {
+      arg++;
+      if(argc>arg) {
+        char *endptr;
+        unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
+        if((endptr != argv[arg] + strlen(argv[arg])) ||
+           ((ulnum != 0UL) && ((ulnum < 1025UL) || (ulnum > 65535UL)))) {
+          fprintf(stderr, "mqttd: invalid --port argument (%s)\n",
+                  argv[arg]);
+          return 0;
+        }
+        port = curlx_ultous(ulnum);
+        arg++;
+      }
+    }
+    else {
+      puts("Usage: mqttd [option]\n"
+           " --config [file]\n"
+           " --version\n"
+           " --logfile [file]\n"
+           " --pidfile [file]\n"
+           " --ipv4\n"
+           " --ipv6\n"
+           " --port [port]\n");
+      return 0;
+    }
+  }
+
+#ifdef WIN32
+  win32_init();
+  atexit(win32_cleanup);
+
+  setmode(fileno(stdin), O_BINARY);
+  setmode(fileno(stdout), O_BINARY);
+  setmode(fileno(stderr), O_BINARY);
+#endif
+
+  install_signal_handlers(FALSE);
+
+#ifdef ENABLE_IPV6
+  if(!use_ipv6)
+#endif
+    sock = socket(AF_INET, SOCK_STREAM, 0);
+#ifdef ENABLE_IPV6
+  else
+    sock = socket(AF_INET6, SOCK_STREAM, 0);
+#endif
+
+  if(CURL_SOCKET_BAD == sock) {
+    error = SOCKERRNO;
+    logmsg("Error creating socket: (%d) %s",
+           error, strerror(error));
+    goto mqttd_cleanup;
+  }
+
+  {
+    /* passive daemon style */
+    sock = sockdaemon(sock, &port);
+    if(CURL_SOCKET_BAD == sock) {
+      goto mqttd_cleanup;
+    }
+    msgsock = CURL_SOCKET_BAD; /* no stream socket yet */
+  }
+
+  logmsg("Running %s version", ipv_inuse);
+  logmsg("Listening on port %hu", port);
+
+  wrotepidfile = write_pidfile(pidname);
+  if(!wrotepidfile) {
+    goto mqttd_cleanup;
+  }
+
+  wroteportfile = write_portfile(portname, (int)port);
+  if(!wroteportfile) {
+    goto mqttd_cleanup;
+  }
+
+  do {
+    juggle_again = incoming(sock);
+  } while(juggle_again);
+
+mqttd_cleanup:
+
+  if((msgsock != sock) && (msgsock != CURL_SOCKET_BAD))
+    sclose(msgsock);
+
+  if(sock != CURL_SOCKET_BAD)
+    sclose(sock);
+
+  if(wrotepidfile)
+    unlink(pidname);
+
+  restore_signal_handlers(FALSE);
+
+  if(got_exit_signal) {
+    logmsg("============> mqttd exits with signal (%d)", exit_signal);
+    /*
+     * To properly set the return status of the process we
+     * must raise the same signal SIGINT or SIGTERM that we
+     * caught and let the old handler take care of it.
+     */
+    raise(exit_signal);
+  }
+
+  logmsg("============> mqttd quits");
+  return 0;
+}
diff --git a/tests/server/resolve.c b/tests/server/resolve.c
index 993e03125..f72561879 100644
--- a/tests/server/resolve.c
+++ b/tests/server/resolve.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -127,7 +127,7 @@ int main(int argc, char *argv[])
     memset(&hints, 0, sizeof(hints));
     hints.ai_family = use_ipv6 ? PF_INET6 : PF_INET;
     hints.ai_socktype = SOCK_STREAM;
-    hints.ai_flags = AI_CANONNAME;
+    hints.ai_flags = 0;
     /* Use parenthesis around functions to stop them from being replaced by
        the macro in memdebug.h */
     rc = (getaddrinfo)(host, "80", &hints, &ai);
diff --git a/tests/server/rtspd.c b/tests/server/rtspd.c
index 7563fd22a..6ee7787b1 100644
--- a/tests/server/rtspd.c
+++ b/tests/server/rtspd.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -201,138 +201,6 @@ static const char *doc404_RTSP = "RTSP/1.0 404 Not 
Found\r\n"
 #define RTP_DATA_SIZE 12
 static const char *RTP_DATA = "$_1234\n\0asdf";
 
-/* do-nothing macro replacement for systems which lack siginterrupt() */
-
-#ifndef HAVE_SIGINTERRUPT
-#define siginterrupt(x,y) do {} while(0)
-#endif
-
-/* vars used to keep around previous signal handlers */
-
-typedef RETSIGTYPE (*SIGHANDLER_T)(int);
-
-#ifdef SIGHUP
-static SIGHANDLER_T old_sighup_handler  = SIG_ERR;
-#endif
-
-#ifdef SIGPIPE
-static SIGHANDLER_T old_sigpipe_handler = SIG_ERR;
-#endif
-
-#ifdef SIGALRM
-static SIGHANDLER_T old_sigalrm_handler = SIG_ERR;
-#endif
-
-#ifdef SIGINT
-static SIGHANDLER_T old_sigint_handler  = SIG_ERR;
-#endif
-
-#ifdef SIGTERM
-static SIGHANDLER_T old_sigterm_handler = SIG_ERR;
-#endif
-
-#if defined(SIGBREAK) && defined(WIN32)
-static SIGHANDLER_T old_sigbreak_handler = SIG_ERR;
-#endif
-
-/* var which if set indicates that the program should finish execution */
-
-SIG_ATOMIC_T got_exit_signal = 0;
-
-/* if next is set indicates the first signal handled in exit_signal_handler */
-
-static volatile int exit_signal = 0;
-
-/* signal handler that will be triggered to indicate that the program
-  should finish its execution in a controlled manner as soon as possible.
-  The first time this is called it will set got_exit_signal to one and
-  store in exit_signal the signal that triggered its execution. */
-
-static RETSIGTYPE exit_signal_handler(int signum)
-{
-  int old_errno = errno;
-  if(got_exit_signal == 0) {
-    got_exit_signal = 1;
-    exit_signal = signum;
-  }
-  (void)signal(signum, exit_signal_handler);
-  errno = old_errno;
-}
-
-static void install_signal_handlers(void)
-{
-#ifdef SIGHUP
-  /* ignore SIGHUP signal */
-  old_sighup_handler = signal(SIGHUP, SIG_IGN);
-  if(old_sighup_handler == SIG_ERR)
-    logmsg("cannot install SIGHUP handler: %s", strerror(errno));
-#endif
-#ifdef SIGPIPE
-  /* ignore SIGPIPE signal */
-  old_sigpipe_handler = signal(SIGPIPE, SIG_IGN);
-  if(old_sigpipe_handler == SIG_ERR)
-    logmsg("cannot install SIGPIPE handler: %s", strerror(errno));
-#endif
-#ifdef SIGALRM
-  /* ignore SIGALRM signal */
-  old_sigalrm_handler = signal(SIGALRM, SIG_IGN);
-  if(old_sigalrm_handler == SIG_ERR)
-    logmsg("cannot install SIGALRM handler: %s", strerror(errno));
-#endif
-#ifdef SIGINT
-  /* handle SIGINT signal with our exit_signal_handler */
-  old_sigint_handler = signal(SIGINT, exit_signal_handler);
-  if(old_sigint_handler == SIG_ERR)
-    logmsg("cannot install SIGINT handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGINT, 1);
-#endif
-#ifdef SIGTERM
-  /* handle SIGTERM signal with our exit_signal_handler */
-  old_sigterm_handler = signal(SIGTERM, exit_signal_handler);
-  if(old_sigterm_handler == SIG_ERR)
-    logmsg("cannot install SIGTERM handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGTERM, 1);
-#endif
-#if defined(SIGBREAK) && defined(WIN32)
-  /* handle SIGBREAK signal with our exit_signal_handler */
-  old_sigbreak_handler = signal(SIGBREAK, exit_signal_handler);
-  if(old_sigbreak_handler == SIG_ERR)
-    logmsg("cannot install SIGBREAK handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGBREAK, 1);
-#endif
-}
-
-static void restore_signal_handlers(void)
-{
-#ifdef SIGHUP
-  if(SIG_ERR != old_sighup_handler)
-    (void)signal(SIGHUP, old_sighup_handler);
-#endif
-#ifdef SIGPIPE
-  if(SIG_ERR != old_sigpipe_handler)
-    (void)signal(SIGPIPE, old_sigpipe_handler);
-#endif
-#ifdef SIGALRM
-  if(SIG_ERR != old_sigalrm_handler)
-    (void)signal(SIGALRM, old_sigalrm_handler);
-#endif
-#ifdef SIGINT
-  if(SIG_ERR != old_sigint_handler)
-    (void)signal(SIGINT, old_sigint_handler);
-#endif
-#ifdef SIGTERM
-  if(SIG_ERR != old_sigterm_handler)
-    (void)signal(SIGTERM, old_sigterm_handler);
-#endif
-#if defined(SIGBREAK) && defined(WIN32)
-  if(SIG_ERR != old_sigbreak_handler)
-    (void)signal(SIGBREAK, old_sigbreak_handler);
-#endif
-}
-
 static int ProcessRequest(struct httprequest *req)
 {
   char *line = &req->reqbuf[req->checkindex];
@@ -379,8 +247,6 @@ static int ProcessRequest(struct httprequest *req)
     /* get the number after it */
     if(ptr) {
       FILE *stream;
-      char *filename;
-
       if((strlen(doc) + strlen(request)) < 200)
         msnprintf(logbuf, sizeof(logbuf), "Got request: %s %s %s/%d.%d",
                   request, doc, prot_str, prot_major, prot_minor);
@@ -420,13 +286,11 @@ static int ProcessRequest(struct httprequest *req)
                 req->testno, req->partno);
       logmsg("%s", logbuf);
 
-      filename = test2file(req->testno);
+      stream = test2fopen(req->testno);
 
-      stream = fopen(filename, "rb");
       if(!stream) {
         int error = errno;
         logmsg("fopen() failed with error: %d %s", error, strerror(error));
-        logmsg("Error opening file: %s", filename);
         logmsg("Couldn't open test file %ld", req->testno);
         req->open = FALSE; /* closes connection */
         return 1; /* done */
@@ -981,17 +845,13 @@ static int send_doc(curl_socket_t sock, struct 
httprequest *req)
     count = strlen(buffer);
   }
   else {
-    char *filename = test2file(req->testno);
+    FILE *stream = test2fopen(req->testno);
     char partbuf[80]="data";
-    FILE *stream;
     if(0 != req->partno)
       msnprintf(partbuf, sizeof(partbuf), "data%ld", req->partno);
-
-    stream = fopen(filename, "rb");
     if(!stream) {
       error = errno;
       logmsg("fopen() failed with error: %d %s", error, strerror(error));
-      logmsg("Error opening file: %s", filename);
       logmsg("Couldn't open test file");
       return 0;
     }
@@ -1011,11 +871,10 @@ static int send_doc(curl_socket_t sock, struct 
httprequest *req)
     }
 
     /* re-open the same file again */
-    stream = fopen(filename, "rb");
+    stream = test2fopen(req->testno);
     if(!stream) {
       error = errno;
       logmsg("fopen() failed with error: %d %s", error, strerror(error));
-      logmsg("Error opening file: %s", filename);
       logmsg("Couldn't open test file");
       free(ptr);
       return 0;
@@ -1190,6 +1049,7 @@ int main(int argc, char *argv[])
   int flag;
   unsigned short port = DEFAULT_PORT;
   const char *pidname = ".rtsp.pid";
+  const char *portfile = NULL;
   struct httprequest req;
   int rc;
   int error;
@@ -1216,6 +1076,11 @@ int main(int argc, char *argv[])
       if(argc>arg)
         pidname = argv[arg++];
     }
+    else if(!strcmp("--portfile", argv[arg])) {
+      arg++;
+      if(argc>arg)
+        portfile = argv[arg++];
+    }
     else if(!strcmp("--logfile", argv[arg])) {
       arg++;
       if(argc>arg)
@@ -1240,12 +1105,6 @@ int main(int argc, char *argv[])
       if(argc>arg) {
         char *endptr;
         unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
-        if((endptr != argv[arg] + strlen(argv[arg])) ||
-           (ulnum < 1025UL) || (ulnum > 65535UL)) {
-          fprintf(stderr, "rtspd: invalid --port argument (%s)\n",
-                  argv[arg]);
-          return 0;
-        }
         port = curlx_ultous(ulnum);
         arg++;
       }
@@ -1262,6 +1121,7 @@ int main(int argc, char *argv[])
            " --version\n"
            " --logfile [file]\n"
            " --pidfile [file]\n"
+           " --portfile [file]\n"
            " --ipv4\n"
            " --ipv6\n"
            " --port [port]\n"
@@ -1275,7 +1135,7 @@ int main(int argc, char *argv[])
   atexit(win32_cleanup);
 #endif
 
-  install_signal_handlers();
+  install_signal_handlers(false);
 
   pid = (long)getpid();
 
@@ -1329,6 +1189,49 @@ int main(int argc, char *argv[])
     goto server_cleanup;
   }
 
+  if(!port) {
+    /* The system was supposed to choose a port number, figure out which
+       port we actually got and update the listener port value with it. */
+    curl_socklen_t la_size;
+    srvr_sockaddr_union_t localaddr;
+#ifdef ENABLE_IPV6
+    if(!use_ipv6)
+#endif
+      la_size = sizeof(localaddr.sa4);
+#ifdef ENABLE_IPV6
+    else
+      la_size = sizeof(localaddr.sa6);
+#endif
+    memset(&localaddr.sa, 0, (size_t)la_size);
+    if(getsockname(sock, &localaddr.sa, &la_size) < 0) {
+      error = SOCKERRNO;
+      logmsg("getsockname() failed with error: (%d) %s",
+             error, strerror(error));
+      sclose(sock);
+      goto server_cleanup;
+    }
+    switch(localaddr.sa.sa_family) {
+    case AF_INET:
+      port = ntohs(localaddr.sa4.sin_port);
+      break;
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      port = ntohs(localaddr.sa6.sin6_port);
+      break;
+#endif
+    default:
+      break;
+    }
+    if(!port) {
+      /* Real failure, listener port shall not be zero beyond this point. */
+      logmsg("Apparently getsockname() succeeded, with listener port zero.");
+      logmsg("A valid reason for this failure is a binary built without");
+      logmsg("proper network library linkage. This might not be the only");
+      logmsg("reason, but double check it before anything else.");
+      sclose(sock);
+      goto server_cleanup;
+    }
+  }
   logmsg("Running %s version on port %d", ipv_inuse, (int)port);
 
   /* start accepting connections */
@@ -1349,6 +1252,12 @@ int main(int argc, char *argv[])
   if(!wrotepidfile)
     goto server_cleanup;
 
+  if(portfile) {
+    wrotepidfile = write_portfile(portfile, port);
+    if(!wrotepidfile)
+      goto server_cleanup;
+  }
+
   for(;;) {
     msgsock = accept(sock, NULL, NULL);
 
@@ -1465,7 +1374,7 @@ server_cleanup:
     clear_advisor_read_lock(SERVERLOGS_LOCK);
   }
 
-  restore_signal_handlers();
+  restore_signal_handlers(false);
 
   if(got_exit_signal) {
     logmsg("========> %s rtspd (port: %d pid: %ld) exits with signal (%d)",
diff --git a/tests/server/server_setup.h b/tests/server/server_setup.h
index 76c462369..1f2cef10c 100644
--- a/tests/server/server_setup.h
+++ b/tests/server/server_setup.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/server/server_sockaddr.h b/tests/server/server_sockaddr.h
index bbcab8346..c3602e1cf 100644
--- a/tests/server/server_sockaddr.h
+++ b/tests/server/server_sockaddr.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/server/sockfilt.c b/tests/server/sockfilt.c
index 569be6f6c..84c72f960 100644
--- a/tests/server/sockfilt.c
+++ b/tests/server/sockfilt.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -147,138 +147,6 @@ enum sockmode {
   ACTIVE_DISCONNECT  /* as a client, disconnected from server */
 };
 
-/* do-nothing macro replacement for systems which lack siginterrupt() */
-
-#ifndef HAVE_SIGINTERRUPT
-#define siginterrupt(x,y) do {} while(0)
-#endif
-
-/* vars used to keep around previous signal handlers */
-
-typedef RETSIGTYPE (*SIGHANDLER_T)(int);
-
-#ifdef SIGHUP
-static SIGHANDLER_T old_sighup_handler  = SIG_ERR;
-#endif
-
-#ifdef SIGPIPE
-static SIGHANDLER_T old_sigpipe_handler = SIG_ERR;
-#endif
-
-#ifdef SIGALRM
-static SIGHANDLER_T old_sigalrm_handler = SIG_ERR;
-#endif
-
-#ifdef SIGINT
-static SIGHANDLER_T old_sigint_handler  = SIG_ERR;
-#endif
-
-#ifdef SIGTERM
-static SIGHANDLER_T old_sigterm_handler = SIG_ERR;
-#endif
-
-#if defined(SIGBREAK) && defined(WIN32)
-static SIGHANDLER_T old_sigbreak_handler = SIG_ERR;
-#endif
-
-/* var which if set indicates that the program should finish execution */
-
-SIG_ATOMIC_T got_exit_signal = 0;
-
-/* if next is set indicates the first signal handled in exit_signal_handler */
-
-static volatile int exit_signal = 0;
-
-/* signal handler that will be triggered to indicate that the program
-  should finish its execution in a controlled manner as soon as possible.
-  The first time this is called it will set got_exit_signal to one and
-  store in exit_signal the signal that triggered its execution. */
-
-static RETSIGTYPE exit_signal_handler(int signum)
-{
-  int old_errno = errno;
-  if(got_exit_signal == 0) {
-    got_exit_signal = 1;
-    exit_signal = signum;
-  }
-  (void)signal(signum, exit_signal_handler);
-  errno = old_errno;
-}
-
-static void install_signal_handlers(void)
-{
-#ifdef SIGHUP
-  /* ignore SIGHUP signal */
-  old_sighup_handler = signal(SIGHUP, SIG_IGN);
-  if(old_sighup_handler == SIG_ERR)
-    logmsg("cannot install SIGHUP handler: %s", strerror(errno));
-#endif
-#ifdef SIGPIPE
-  /* ignore SIGPIPE signal */
-  old_sigpipe_handler = signal(SIGPIPE, SIG_IGN);
-  if(old_sigpipe_handler == SIG_ERR)
-    logmsg("cannot install SIGPIPE handler: %s", strerror(errno));
-#endif
-#ifdef SIGALRM
-  /* ignore SIGALRM signal */
-  old_sigalrm_handler = signal(SIGALRM, SIG_IGN);
-  if(old_sigalrm_handler == SIG_ERR)
-    logmsg("cannot install SIGALRM handler: %s", strerror(errno));
-#endif
-#ifdef SIGINT
-  /* handle SIGINT signal with our exit_signal_handler */
-  old_sigint_handler = signal(SIGINT, exit_signal_handler);
-  if(old_sigint_handler == SIG_ERR)
-    logmsg("cannot install SIGINT handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGINT, 1);
-#endif
-#ifdef SIGTERM
-  /* handle SIGTERM signal with our exit_signal_handler */
-  old_sigterm_handler = signal(SIGTERM, exit_signal_handler);
-  if(old_sigterm_handler == SIG_ERR)
-    logmsg("cannot install SIGTERM handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGTERM, 1);
-#endif
-#if defined(SIGBREAK) && defined(WIN32)
-  /* handle SIGBREAK signal with our exit_signal_handler */
-  old_sigbreak_handler = signal(SIGBREAK, exit_signal_handler);
-  if(old_sigbreak_handler == SIG_ERR)
-    logmsg("cannot install SIGBREAK handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGBREAK, 1);
-#endif
-}
-
-static void restore_signal_handlers(void)
-{
-#ifdef SIGHUP
-  if(SIG_ERR != old_sighup_handler)
-    (void)signal(SIGHUP, old_sighup_handler);
-#endif
-#ifdef SIGPIPE
-  if(SIG_ERR != old_sigpipe_handler)
-    (void)signal(SIGPIPE, old_sigpipe_handler);
-#endif
-#ifdef SIGALRM
-  if(SIG_ERR != old_sigalrm_handler)
-    (void)signal(SIGALRM, old_sigalrm_handler);
-#endif
-#ifdef SIGINT
-  if(SIG_ERR != old_sigint_handler)
-    (void)signal(SIGINT, old_sigint_handler);
-#endif
-#ifdef SIGTERM
-  if(SIG_ERR != old_sigterm_handler)
-    (void)signal(SIGTERM, old_sigterm_handler);
-#endif
-#if defined(SIGBREAK) && defined(WIN32)
-  if(SIG_ERR != old_sigbreak_handler)
-    (void)signal(SIGBREAK, old_sigbreak_handler);
-#endif
-}
-
 #ifdef WIN32
 /*
  * read-wrapper to support reading from stdin on Windows.
@@ -532,22 +400,26 @@ static void lograw(unsigned char *buffer, ssize_t len)
  */
 struct select_ws_wait_data {
   HANDLE handle; /* actual handle to wait for during select */
-  HANDLE event;  /* internal event to abort waiting thread */
+  HANDLE signal; /* internal event to signal handle trigger */
+  HANDLE abort;  /* internal event to abort waiting thread */
+  HANDLE mutex;  /* mutex to prevent event race-condition */
 };
 static DWORD WINAPI select_ws_wait_thread(LPVOID lpParameter)
 {
   struct select_ws_wait_data *data;
-  HANDLE handle, handles[2];
+  HANDLE mutex, signal, handle, handles[2];
   INPUT_RECORD inputrecord;
   LARGE_INTEGER size, pos;
-  DWORD type, length;
+  DWORD type, length, ret;
 
   /* retrieve handles from internal structure */
   data = (struct select_ws_wait_data *) lpParameter;
   if(data) {
     handle = data->handle;
-    handles[0] = data->event;
+    handles[0] = data->abort;
     handles[1] = handle;
+    signal = data->signal;
+    mutex = data->mutex;
     free(data);
   }
   else
@@ -567,29 +439,41 @@ static DWORD WINAPI select_ws_wait_thread(LPVOID 
lpParameter)
         */
       while(WaitForMultipleObjectsEx(1, handles, FALSE, 0, FALSE)
             == WAIT_TIMEOUT) {
-        /* get total size of file */
-        length = 0;
-        size.QuadPart = 0;
-        size.LowPart = GetFileSize(handle, &length);
-        if((size.LowPart != INVALID_FILE_SIZE) ||
-           (GetLastError() == NO_ERROR)) {
-          size.HighPart = length;
-          /* get the current position within the file */
-          pos.QuadPart = 0;
-          pos.LowPart = SetFilePointer(handle, 0, &pos.HighPart,
-                                       FILE_CURRENT);
-          if((pos.LowPart != INVALID_SET_FILE_POINTER) ||
+        ret = WaitForSingleObjectEx(mutex, 0, FALSE);
+        if(ret == WAIT_OBJECT_0) {
+          /* get total size of file */
+          length = 0;
+          size.QuadPart = 0;
+          size.LowPart = GetFileSize(handle, &length);
+          if((size.LowPart != INVALID_FILE_SIZE) ||
              (GetLastError() == NO_ERROR)) {
-            /* compare position with size, abort if not equal */
-            if(size.QuadPart == pos.QuadPart) {
-              /* sleep and continue waiting */
-              SleepEx(0, FALSE);
-              continue;
+            size.HighPart = length;
+            /* get the current position within the file */
+            pos.QuadPart = 0;
+            pos.LowPart = SetFilePointer(handle, 0, &pos.HighPart,
+                                        FILE_CURRENT);
+            if((pos.LowPart != INVALID_SET_FILE_POINTER) ||
+               (GetLastError() == NO_ERROR)) {
+              /* compare position with size, abort if not equal */
+              if(size.QuadPart == pos.QuadPart) {
+                /* sleep and continue waiting */
+                SleepEx(0, FALSE);
+                ReleaseMutex(mutex);
+                continue;
+              }
             }
           }
+          /* there is some data available, stop waiting */
+          logmsg("[select_ws_wait_thread] data available, DISK: %p", handle);
+          SetEvent(signal);
+          ReleaseMutex(mutex);
+          break;
+        }
+        else if(ret == WAIT_ABANDONED) {
+          /* we are not allowed to process this event, because select_ws
+             is post-processing the signalled events and we must exit. */
+          break;
         }
-        /* there is some data available, stop waiting */
-        break;
       }
       break;
 
@@ -603,22 +487,33 @@ static DWORD WINAPI select_ws_wait_thread(LPVOID 
lpParameter)
         */
       while(WaitForMultipleObjectsEx(2, handles, FALSE, INFINITE, FALSE)
             == WAIT_OBJECT_0 + 1) {
-        /* check if this is an actual console handle */
-        length = 0;
-        if(GetConsoleMode(handle, &length)) {
-          /* retrieve an event from the console buffer */
-          length = 0;
-          if(PeekConsoleInput(handle, &inputrecord, 1, &length)) {
-            /* check if the event is not an actual key-event */
-            if(length == 1 && inputrecord.EventType != KEY_EVENT) {
-              /* purge the non-key-event and continue waiting */
-              ReadConsoleInput(handle, &inputrecord, 1, &length);
-              continue;
+        ret = WaitForSingleObjectEx(mutex, 0, FALSE);
+        if(ret == WAIT_OBJECT_0) {
+          /* check if this is an actual console handle */
+          if(GetConsoleMode(handle, &ret)) {
+            /* retrieve an event from the console buffer */
+            length = 0;
+            if(PeekConsoleInput(handle, &inputrecord, 1, &length)) {
+              /* check if the event is not an actual key-event */
+              if(length == 1 && inputrecord.EventType != KEY_EVENT) {
+                /* purge the non-key-event and continue waiting */
+                ReadConsoleInput(handle, &inputrecord, 1, &length);
+                ReleaseMutex(mutex);
+                continue;
+              }
             }
           }
+          /* there is some data available, stop waiting */
+          logmsg("[select_ws_wait_thread] data available, CHAR: %p", handle);
+          SetEvent(signal);
+          ReleaseMutex(mutex);
+          break;
+        }
+        else if(ret == WAIT_ABANDONED) {
+          /* we are not allowed to process this event, because select_ws
+             is post-processing the signalled events and we must exit. */
+          break;
         }
-        /* there is some data available, stop waiting */
-        break;
       }
       break;
 
@@ -632,36 +527,65 @@ static DWORD WINAPI select_ws_wait_thread(LPVOID 
lpParameter)
         */
       while(WaitForMultipleObjectsEx(1, handles, FALSE, 0, FALSE)
             == WAIT_TIMEOUT) {
-        /* peek into the pipe and retrieve the amount of data available */
-        length = 0;
-        if(PeekNamedPipe(handle, NULL, 0, NULL, &length, NULL)) {
-          /* if there is no data available, sleep and continue waiting */
-          if(length == 0) {
-            SleepEx(0, FALSE);
-            continue;
+        ret = WaitForSingleObjectEx(mutex, 0, FALSE);
+        if(ret == WAIT_OBJECT_0) {
+          /* peek into the pipe and retrieve the amount of data available */
+          length = 0;
+          if(PeekNamedPipe(handle, NULL, 0, NULL, &length, NULL)) {
+            /* if there is no data available, sleep and continue waiting */
+            if(length == 0) {
+              SleepEx(0, FALSE);
+              ReleaseMutex(mutex);
+              continue;
+            }
+            else {
+              logmsg("[select_ws_wait_thread] PeekNamedPipe len: %d", length);
+            }
           }
-        }
-        else {
-          /* if the pipe has been closed, sleep and continue waiting */
-          if(GetLastError() == ERROR_BROKEN_PIPE) {
-            SleepEx(0, FALSE);
-            continue;
+          else {
+            /* if the pipe has NOT been closed, sleep and continue waiting */
+            ret = GetLastError();
+            if(ret != ERROR_BROKEN_PIPE) {
+              logmsg("[select_ws_wait_thread] PeekNamedPipe error: %d", ret);
+              SleepEx(0, FALSE);
+              ReleaseMutex(mutex);
+              continue;
+            }
+            else {
+              logmsg("[select_ws_wait_thread] pipe closed, PIPE: %p", handle);
+            }
           }
+          /* there is some data available, stop waiting */
+          logmsg("[select_ws_wait_thread] data available, PIPE: %p", handle);
+          SetEvent(signal);
+          ReleaseMutex(mutex);
+          break;
+        }
+        else if(ret == WAIT_ABANDONED) {
+          /* we are not allowed to process this event, because select_ws
+             is post-processing the signalled events and we must exit. */
+          break;
         }
-        /* there is some data available, stop waiting */
-        break;
       }
       break;
 
     default:
       /* The handle has an unknown type, try to wait on it */
-      WaitForMultipleObjectsEx(2, handles, FALSE, INFINITE, FALSE);
+      if(WaitForMultipleObjectsEx(2, handles, FALSE, INFINITE, FALSE)
+         == WAIT_OBJECT_0 + 1) {
+        if(WaitForSingleObjectEx(mutex, 0, FALSE) == WAIT_OBJECT_0) {
+          logmsg("[select_ws_wait_thread] data available, HANDLE: %p", handle);
+          SetEvent(signal);
+          ReleaseMutex(mutex);
+        }
+      }
       break;
   }
 
   return 0;
 }
-static HANDLE select_ws_wait(HANDLE handle, HANDLE event)
+static HANDLE select_ws_wait(HANDLE handle, HANDLE signal,
+                             HANDLE abort, HANDLE mutex)
 {
   struct select_ws_wait_data *data;
   HANDLE thread = NULL;
@@ -670,7 +594,9 @@ static HANDLE select_ws_wait(HANDLE handle, HANDLE event)
   data = malloc(sizeof(struct select_ws_wait_data));
   if(data) {
     data->handle = handle;
-    data->event = event;
+    data->signal = signal;
+    data->abort = abort;
+    data->mutex = mutex;
 
     /* launch waiting thread */
     thread = CreateThread(NULL, 0,
@@ -686,23 +612,24 @@ static HANDLE select_ws_wait(HANDLE handle, HANDLE event)
   return thread;
 }
 struct select_ws_data {
-  curl_socket_t fd;      /* the original input handle   (indexed by fds) */
-  curl_socket_t wsasock; /* the internal socket handle  (indexed by wsa) */
-  WSAEVENT wsaevent;     /* the internal WINSOCK2 event (indexed by wsa) */
-  HANDLE thread;         /* the internal threads handle (indexed by thd) */
+  int fd;                /* provided file descriptor  (indexed by nfd) */
+  long wsastate;         /* internal pre-select state (indexed by nfd) */
+  curl_socket_t wsasock; /* internal socket handle    (indexed by nws) */
+  WSAEVENT wsaevent;     /* internal select event     (indexed by nws) */
+  HANDLE signal;         /* internal thread signal    (indexed by nth) */
+  HANDLE thread;         /* internal thread handle    (indexed by nth) */
 };
 static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
-                     fd_set *exceptfds, struct timeval *timeout)
+                     fd_set *exceptfds, struct timeval *tv)
 {
-  DWORD milliseconds, wait, idx;
-  WSANETWORKEVENTS wsanetevents;
+  HANDLE abort, mutex, signal, handle, *handles;
+  DWORD timeout_ms, wait, nfd, nth, nws, i;
+  fd_set readsock, writesock, exceptsock;
   struct select_ws_data *data;
-  HANDLE handle, *handles;
+  WSANETWORKEVENTS wsaevents;
+  curl_socket_t wsasock;
+  int error, ret, fd;
   WSAEVENT wsaevent;
-  int error, fds;
-  HANDLE waitevent = NULL;
-  DWORD nfd = 0, thd = 0, wsa = 0;
-  int ret = 0;
 
   /* check if the input value is valid */
   if(nfds < 0) {
@@ -710,15 +637,31 @@ static int select_ws(int nfds, fd_set *readfds, fd_set 
*writefds,
     return -1;
   }
 
+  /* convert struct timeval to milliseconds */
+  if(tv) {
+    timeout_ms = (tv->tv_sec*1000) + (DWORD)(((double)tv->tv_usec)/1000.0);
+  }
+  else {
+    timeout_ms = INFINITE;
+  }
+
   /* check if we got descriptors, sleep in case we got none */
   if(!nfds) {
-    Sleep((timeout->tv_sec*1000)+(DWORD)(((double)timeout->tv_usec)/1000.0));
+    SleepEx(timeout_ms, FALSE);
     return 0;
   }
 
-  /* create internal event to signal waiting threads */
-  waitevent = CreateEvent(NULL, TRUE, FALSE, NULL);
-  if(!waitevent) {
+  /* create internal event to abort waiting threads */
+  abort = CreateEvent(NULL, TRUE, FALSE, NULL);
+  if(!abort) {
+    errno = ENOMEM;
+    return -1;
+  }
+
+  /* create internal mutex to lock event handling in threads */
+  mutex = CreateMutex(NULL, FALSE, NULL);
+  if(!mutex) {
+    CloseHandle(abort);
     errno = ENOMEM;
     return -1;
   }
@@ -726,7 +669,8 @@ static int select_ws(int nfds, fd_set *readfds, fd_set 
*writefds,
   /* allocate internal array for the internal data */
   data = calloc(nfds, sizeof(struct select_ws_data));
   if(data == NULL) {
-    CloseHandle(waitevent);
+    CloseHandle(abort);
+    CloseHandle(mutex);
     errno = ENOMEM;
     return -1;
   }
@@ -734,61 +678,106 @@ static int select_ws(int nfds, fd_set *readfds, fd_set 
*writefds,
   /* allocate internal array for the internal event handles */
   handles = calloc(nfds, sizeof(HANDLE));
   if(handles == NULL) {
-    CloseHandle(waitevent);
+    CloseHandle(abort);
+    CloseHandle(mutex);
     free(data);
     errno = ENOMEM;
     return -1;
   }
 
   /* loop over the handles in the input descriptor sets */
-  for(fds = 0; fds < nfds; fds++) {
-    long networkevents = 0;
+  nfd = 0; /* number of handled file descriptors */
+  nth = 0; /* number of interal waiting threads */
+  nws = 0; /* number of handled WINSOCK sockets */
+  for(fd = 0; fd < nfds; fd++) {
+    wsasock = curlx_sitosk(fd);
+    wsaevents.lNetworkEvents = 0;
     handles[nfd] = 0;
 
-    if(FD_ISSET(fds, readfds))
-      networkevents |= FD_READ|FD_ACCEPT|FD_CLOSE;
+    FD_ZERO(&readsock);
+    FD_ZERO(&writesock);
+    FD_ZERO(&exceptsock);
 
-    if(FD_ISSET(fds, writefds))
-      networkevents |= FD_WRITE|FD_CONNECT;
+    if(FD_ISSET(wsasock, readfds)) {
+      FD_SET(wsasock, &readsock);
+      wsaevents.lNetworkEvents |= FD_READ|FD_ACCEPT|FD_CLOSE;
+    }
+
+    if(FD_ISSET(wsasock, writefds)) {
+      FD_SET(wsasock, &writesock);
+      wsaevents.lNetworkEvents |= FD_WRITE|FD_CONNECT;
+    }
 
-    if(FD_ISSET(fds, exceptfds))
-      networkevents |= FD_OOB|FD_CLOSE;
+    if(FD_ISSET(wsasock, exceptfds)) {
+      FD_SET(wsasock, &exceptsock);
+      wsaevents.lNetworkEvents |= FD_OOB;
+    }
 
     /* only wait for events for which we actually care */
-    if(networkevents) {
-      data[nfd].fd = curlx_sitosk(fds);
-      if(fds == fileno(stdin)) {
-        handle = GetStdHandle(STD_INPUT_HANDLE);
-        handle = select_ws_wait(handle, waitevent);
-        handles[nfd] = handle;
-        data[thd].thread = handle;
-        thd++;
+    if(wsaevents.lNetworkEvents) {
+      data[nfd].fd = fd;
+      if(fd == fileno(stdin)) {
+        signal = CreateEvent(NULL, TRUE, FALSE, NULL);
+        if(signal) {
+          handle = GetStdHandle(STD_INPUT_HANDLE);
+          handle = select_ws_wait(handle, signal, abort, mutex);
+          if(handle) {
+            handles[nfd] = signal;
+            data[nth].signal = signal;
+            data[nth].thread = handle;
+            nth++;
+          }
+          else {
+            CloseHandle(signal);
+          }
+        }
       }
-      else if(fds == fileno(stdout)) {
+      else if(fd == fileno(stdout)) {
         handles[nfd] = GetStdHandle(STD_OUTPUT_HANDLE);
       }
-      else if(fds == fileno(stderr)) {
+      else if(fd == fileno(stderr)) {
         handles[nfd] = GetStdHandle(STD_ERROR_HANDLE);
       }
       else {
         wsaevent = WSACreateEvent();
         if(wsaevent != WSA_INVALID_EVENT) {
-          error = WSAEventSelect(fds, wsaevent, networkevents);
+          error = WSAEventSelect(wsasock, wsaevent, wsaevents.lNetworkEvents);
           if(error != SOCKET_ERROR) {
-            handle = (HANDLE) wsaevent;
-            handles[nfd] = handle;
-            data[wsa].wsasock = curlx_sitosk(fds);
-            data[wsa].wsaevent = wsaevent;
-            wsa++;
+            handles[nfd] = (HANDLE)wsaevent;
+            data[nws].wsasock = wsasock;
+            data[nws].wsaevent = wsaevent;
+            data[nfd].wsastate = 0;
+            tv->tv_sec = 0;
+            tv->tv_usec = 0;
+            /* check if the socket is already ready */
+            if(select(fd + 1, &readsock, &writesock, &exceptsock, tv) == 1) {
+              logmsg("[select_ws] socket %d is ready", fd);
+              WSASetEvent(wsaevent);
+              if(FD_ISSET(wsasock, &readsock))
+                data[nfd].wsastate |= FD_READ;
+              if(FD_ISSET(wsasock, &writesock))
+                data[nfd].wsastate |= FD_WRITE;
+              if(FD_ISSET(wsasock, &exceptsock))
+                data[nfd].wsastate |= FD_OOB;
+            }
+            nws++;
           }
           else {
-            curl_socket_t socket = curlx_sitosk(fds);
             WSACloseEvent(wsaevent);
-            handle = (HANDLE) socket;
-            handle = select_ws_wait(handle, waitevent);
-            handles[nfd] = handle;
-            data[thd].thread = handle;
-            thd++;
+            signal = CreateEvent(NULL, TRUE, FALSE, NULL);
+            if(signal) {
+              handle = (HANDLE)wsasock;
+              handle = select_ws_wait(handle, signal, abort, mutex);
+              if(handle) {
+                handles[nfd] = signal;
+                data[nth].signal = signal;
+                data[nth].thread = handle;
+                nth++;
+              }
+              else {
+                CloseHandle(signal);
+              }
+            }
           }
         }
       }
@@ -796,104 +785,94 @@ static int select_ws(int nfds, fd_set *readfds, fd_set 
*writefds,
     }
   }
 
-  /* convert struct timeval to milliseconds */
-  if(timeout) {
-    milliseconds = ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000));
-  }
-  else {
-    milliseconds = INFINITE;
-  }
-
   /* wait for one of the internal handles to trigger */
-  wait = WaitForMultipleObjectsEx(nfd, handles, FALSE, milliseconds, FALSE);
+  wait = WaitForMultipleObjectsEx(nfd, handles, FALSE, timeout_ms, FALSE);
 
-  /* signal the event handle for the waiting threads */
-  SetEvent(waitevent);
+  /* wait for internal mutex to lock event handling in threads */
+  WaitForSingleObjectEx(mutex, INFINITE, FALSE);
 
   /* loop over the internal handles returned in the descriptors */
-  for(idx = 0; idx < nfd; idx++) {
-    curl_socket_t sock = data[idx].fd;
-    handle = handles[idx];
-    fds = curlx_sktosi(sock);
+  ret = 0; /* number of ready file descriptors */
+  for(i = 0; i < nfd; i++) {
+    fd = data[i].fd;
+    handle = handles[i];
+    wsasock = curlx_sitosk(fd);
 
     /* check if the current internal handle was triggered */
-    if(wait != WAIT_FAILED && (wait - WAIT_OBJECT_0) <= idx &&
+    if(wait != WAIT_FAILED && (wait - WAIT_OBJECT_0) <= i &&
        WaitForSingleObjectEx(handle, 0, FALSE) == WAIT_OBJECT_0) {
       /* first handle stdin, stdout and stderr */
-      if(fds == fileno(stdin)) {
+      if(fd == fileno(stdin)) {
         /* stdin is never ready for write or exceptional */
-        FD_CLR(sock, writefds);
-        FD_CLR(sock, exceptfds);
+        FD_CLR(wsasock, writefds);
+        FD_CLR(wsasock, exceptfds);
       }
-      else if(fds == fileno(stdout) || fds == fileno(stderr)) {
+      else if(fd == fileno(stdout) || fd == fileno(stderr)) {
         /* stdout and stderr are never ready for read or exceptional */
-        FD_CLR(sock, readfds);
-        FD_CLR(sock, exceptfds);
+        FD_CLR(wsasock, readfds);
+        FD_CLR(wsasock, exceptfds);
       }
       else {
         /* try to handle the event with the WINSOCK2 functions */
-        wsanetevents.lNetworkEvents = 0;
-        error = WSAEnumNetworkEvents(fds, handle, &wsanetevents);
+        wsaevents.lNetworkEvents = 0;
+        error = WSAEnumNetworkEvents(wsasock, handle, &wsaevents);
         if(error != SOCKET_ERROR) {
+          /* merge result from pre-check using select */
+          wsaevents.lNetworkEvents |= data[i].wsastate;
+
           /* remove from descriptor set if not ready for read/accept/close */
-          if(!(wsanetevents.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE)))
-            FD_CLR(sock, readfds);
+          if(!(wsaevents.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE)))
+            FD_CLR(wsasock, readfds);
 
           /* remove from descriptor set if not ready for write/connect */
-          if(!(wsanetevents.lNetworkEvents & (FD_WRITE|FD_CONNECT)))
-            FD_CLR(sock, writefds);
-
-          /* HACK:
-           * use exceptfds together with readfds to signal
-           * that the connection was closed by the client.
-           *
-           * Reason: FD_CLOSE is only signaled once, sometimes
-           * at the same time as FD_READ with data being available.
-           * This means that recv/sread is not reliable to detect
-           * that the connection is closed.
-           */
+          if(!(wsaevents.lNetworkEvents & (FD_WRITE|FD_CONNECT)))
+            FD_CLR(wsasock, writefds);
+
           /* remove from descriptor set if not exceptional */
-          if(!(wsanetevents.lNetworkEvents & (FD_OOB|FD_CLOSE)))
-            FD_CLR(sock, exceptfds);
+          if(!(wsaevents.lNetworkEvents & (FD_OOB)))
+            FD_CLR(wsasock, exceptfds);
         }
       }
 
       /* check if the event has not been filtered using specific tests */
-      if(FD_ISSET(sock, readfds) || FD_ISSET(sock, writefds) ||
-         FD_ISSET(sock, exceptfds)) {
+      if(FD_ISSET(wsasock, readfds) || FD_ISSET(wsasock, writefds) ||
+         FD_ISSET(wsasock, exceptfds)) {
         ret++;
       }
     }
     else {
       /* remove from all descriptor sets since this handle did not trigger */
-      FD_CLR(sock, readfds);
-      FD_CLR(sock, writefds);
-      FD_CLR(sock, exceptfds);
+      FD_CLR(wsasock, readfds);
+      FD_CLR(wsasock, writefds);
+      FD_CLR(wsasock, exceptfds);
     }
   }
 
-  for(fds = 0; fds < nfds; fds++) {
-    if(FD_ISSET(fds, readfds))
-      logmsg("select_ws: %d is readable", fds);
-
-    if(FD_ISSET(fds, writefds))
-      logmsg("select_ws: %d is writable", fds);
+  /* signal the event handle for the other waiting threads */
+  SetEvent(abort);
 
-    if(FD_ISSET(fds, exceptfds))
-      logmsg("select_ws: %d is excepted", fds);
+  for(fd = 0; fd < nfds; fd++) {
+    if(FD_ISSET(fd, readfds))
+      logmsg("[select_ws] %d is readable", fd);
+    if(FD_ISSET(fd, writefds))
+      logmsg("[select_ws] %d is writable", fd);
+    if(FD_ISSET(fd, exceptfds))
+      logmsg("[select_ws] %d is exceptional", fd);
   }
 
-  for(idx = 0; idx < wsa; idx++) {
-    WSAEventSelect(data[idx].wsasock, NULL, 0);
-    WSACloseEvent(data[idx].wsaevent);
+  for(i = 0; i < nws; i++) {
+    WSAEventSelect(data[i].wsasock, NULL, 0);
+    WSACloseEvent(data[i].wsaevent);
   }
 
-  for(idx = 0; idx < thd; idx++) {
-    WaitForSingleObject(data[idx].thread, INFINITE);
-    CloseHandle(data[idx].thread);
+  for(i = 0; i < nth; i++) {
+    WaitForSingleObjectEx(data[i].thread, INFINITE, FALSE);
+    CloseHandle(data[i].thread);
+    CloseHandle(data[i].signal);
   }
 
-  CloseHandle(waitevent);
+  CloseHandle(abort);
+  CloseHandle(mutex);
 
   free(handles);
   free(data);
@@ -972,9 +951,6 @@ static bool juggle(curl_socket_t *sockfdp,
     else {
       /* there's always a socket to wait for */
       FD_SET(sockfd, &fds_read);
-#ifdef USE_WINSOCK
-      FD_SET(sockfd, &fds_err);
-#endif
       maxfd = (int)sockfd;
     }
     break;
@@ -985,9 +961,6 @@ static bool juggle(curl_socket_t *sockfdp,
     /* sockfd turns CURL_SOCKET_BAD when our connection has been closed */
     if(CURL_SOCKET_BAD != sockfd) {
       FD_SET(sockfd, &fds_read);
-#ifdef USE_WINSOCK
-      FD_SET(sockfd, &fds_err);
-#endif
       maxfd = (int)sockfd;
     }
     else {
@@ -1165,11 +1138,7 @@ static bool juggle(curl_socket_t *sockfdp,
       lograw(buffer, nread_socket);
     }
 
-    if(nread_socket <= 0
-#ifdef USE_WINSOCK
-       || FD_ISSET(sockfd, &fds_err)
-#endif
-       ) {
+    if(nread_socket <= 0) {
       logmsg("====> Client disconnect");
       if(!write_stdout("DISC\n", 5))
         return FALSE;
@@ -1335,6 +1304,7 @@ int main(int argc, char *argv[])
   curl_socket_t msgsock = CURL_SOCKET_BAD;
   int wrotepidfile = 0;
   const char *pidname = ".sockfilt.pid";
+  const char *portfile = NULL; /* none by default */
   bool juggle_again;
   int rc;
   int error;
@@ -1362,6 +1332,11 @@ int main(int argc, char *argv[])
       if(argc>arg)
         pidname = argv[arg++];
     }
+    else if(!strcmp("--portfile", argv[arg])) {
+      arg++;
+      if(argc > arg)
+        portfile = argv[arg++];
+    }
     else if(!strcmp("--logfile", argv[arg])) {
       arg++;
       if(argc>arg)
@@ -1391,12 +1366,6 @@ int main(int argc, char *argv[])
       if(argc>arg) {
         char *endptr;
         unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
-        if((endptr != argv[arg] + strlen(argv[arg])) ||
-           ((ulnum != 0UL) && ((ulnum < 1025UL) || (ulnum > 65535UL)))) {
-          fprintf(stderr, "sockfilt: invalid --port argument (%s)\n",
-                  argv[arg]);
-          return 0;
-        }
         port = curlx_ultous(ulnum);
         arg++;
       }
@@ -1451,7 +1420,7 @@ int main(int argc, char *argv[])
   setmode(fileno(stderr), O_BINARY);
 #endif
 
-  install_signal_handlers();
+  install_signal_handlers(false);
 
 #ifdef ENABLE_IPV6
   if(!use_ipv6)
@@ -1532,6 +1501,13 @@ int main(int argc, char *argv[])
     write_stdout("FAIL\n", 5);
     goto sockfilt_cleanup;
   }
+  if(portfile) {
+    wrotepidfile = write_portfile(portfile, port);
+    if(!wrotepidfile) {
+      write_stdout("FAIL\n", 5);
+      goto sockfilt_cleanup;
+    }
+  }
 
   do {
     juggle_again = juggle(&msgsock, sock, &mode);
@@ -1548,7 +1524,7 @@ sockfilt_cleanup:
   if(wrotepidfile)
     unlink(pidname);
 
-  restore_signal_handlers();
+  restore_signal_handlers(false);
 
   if(got_exit_signal) {
     logmsg("============> sockfilt exits with signal (%d)", exit_signal);
diff --git a/tests/server/socksd.c b/tests/server/socksd.c
index 5e32bc904..e6e9c12b0 100644
--- a/tests/server/socksd.c
+++ b/tests/server/socksd.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -230,123 +230,6 @@ static void getconfig(void)
   }
 }
 
-
-/* do-nothing macro replacement for systems which lack siginterrupt() */
-
-#ifndef HAVE_SIGINTERRUPT
-#define siginterrupt(x,y) do {} while(0)
-#endif
-
-/* vars used to keep around previous signal handlers */
-
-typedef RETSIGTYPE (*SIGHANDLER_T)(int);
-
-#ifdef SIGHUP
-static SIGHANDLER_T old_sighup_handler  = SIG_ERR;
-#endif
-
-#ifdef SIGPIPE
-static SIGHANDLER_T old_sigpipe_handler = SIG_ERR;
-#endif
-
-#ifdef SIGALRM
-static SIGHANDLER_T old_sigalrm_handler = SIG_ERR;
-#endif
-
-#ifdef SIGINT
-static SIGHANDLER_T old_sigint_handler  = SIG_ERR;
-#endif
-
-#if defined(SIGBREAK) && defined(WIN32)
-static SIGHANDLER_T old_sigbreak_handler = SIG_ERR;
-#endif
-
-/* var which if set indicates that the program should finish execution */
-
-SIG_ATOMIC_T got_exit_signal = 0;
-
-/* if next is set indicates the first signal handled in exit_signal_handler */
-
-static volatile int exit_signal = 0;
-
-/* signal handler that will be triggered to indicate that the program
-  should finish its execution in a controlled manner as soon as possible.
-  The first time this is called it will set got_exit_signal to one and
-  store in exit_signal the signal that triggered its execution. */
-
-static RETSIGTYPE exit_signal_handler(int signum)
-{
-  int old_errno = errno;
-  if(got_exit_signal == 0) {
-    got_exit_signal = 1;
-    exit_signal = signum;
-  }
-  (void)signal(signum, exit_signal_handler);
-  errno = old_errno;
-}
-
-static void install_signal_handlers(void)
-{
-#ifdef SIGHUP
-  /* ignore SIGHUP signal */
-  old_sighup_handler = signal(SIGHUP, SIG_IGN);
-  if(old_sighup_handler == SIG_ERR)
-    logmsg("cannot install SIGHUP handler: %s", strerror(errno));
-#endif
-#ifdef SIGPIPE
-  /* ignore SIGPIPE signal */
-  old_sigpipe_handler = signal(SIGPIPE, SIG_IGN);
-  if(old_sigpipe_handler == SIG_ERR)
-    logmsg("cannot install SIGPIPE handler: %s", strerror(errno));
-#endif
-#ifdef SIGALRM
-  /* ignore SIGALRM signal */
-  old_sigalrm_handler = signal(SIGALRM, SIG_IGN);
-  if(old_sigalrm_handler == SIG_ERR)
-    logmsg("cannot install SIGALRM handler: %s", strerror(errno));
-#endif
-#ifdef SIGINT
-  /* handle SIGINT signal with our exit_signal_handler */
-  old_sigint_handler = signal(SIGINT, exit_signal_handler);
-  if(old_sigint_handler == SIG_ERR)
-    logmsg("cannot install SIGINT handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGINT, 1);
-#endif
-#if defined(SIGBREAK) && defined(WIN32)
-  /* handle SIGBREAK signal with our exit_signal_handler */
-  old_sigbreak_handler = signal(SIGBREAK, exit_signal_handler);
-  if(old_sigbreak_handler == SIG_ERR)
-    logmsg("cannot install SIGBREAK handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGBREAK, 1);
-#endif
-}
-
-static void restore_signal_handlers(void)
-{
-#ifdef SIGHUP
-  if(SIG_ERR != old_sighup_handler)
-    (void)signal(SIGHUP, old_sighup_handler);
-#endif
-#ifdef SIGPIPE
-  if(SIG_ERR != old_sigpipe_handler)
-    (void)signal(SIGPIPE, old_sigpipe_handler);
-#endif
-#ifdef SIGALRM
-  if(SIG_ERR != old_sigalrm_handler)
-    (void)signal(SIGALRM, old_sigalrm_handler);
-#endif
-#ifdef SIGINT
-  if(SIG_ERR != old_sigint_handler)
-    (void)signal(SIGINT, old_sigint_handler);
-#endif
-#if defined(SIGBREAK) && defined(WIN32)
-  if(SIG_ERR != old_sigbreak_handler)
-    (void)signal(SIGBREAK, old_sigbreak_handler);
-#endif
-}
-
 static void loghex(unsigned char *buffer, ssize_t len)
 {
   char data[1200];
@@ -1000,6 +883,7 @@ int main(int argc, char *argv[])
   curl_socket_t msgsock = CURL_SOCKET_BAD;
   int wrotepidfile = 0;
   const char *pidname = ".socksd.pid";
+  const char *portfile = NULL;
   bool juggle_again;
   int error;
   int arg = 1;
@@ -1020,6 +904,11 @@ int main(int argc, char *argv[])
       if(argc>arg)
         pidname = argv[arg++];
     }
+    else if(!strcmp("--portfile", argv[arg])) {
+      arg++;
+      if(argc>arg)
+        portfile = argv[arg++];
+    }
     else if(!strcmp("--config", argv[arg])) {
       arg++;
       if(argc>arg)
@@ -1060,12 +949,6 @@ int main(int argc, char *argv[])
       if(argc>arg) {
         char *endptr;
         unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
-        if((endptr != argv[arg] + strlen(argv[arg])) ||
-           ((ulnum != 0UL) && ((ulnum < 1025UL) || (ulnum > 65535UL)))) {
-          fprintf(stderr, "socksd: invalid --port argument (%s)\n",
-                  argv[arg]);
-          return 0;
-        }
         port = curlx_ultous(ulnum);
         arg++;
       }
@@ -1078,6 +961,7 @@ int main(int argc, char *argv[])
            " --version\n"
            " --logfile [file]\n"
            " --pidfile [file]\n"
+           " --portfile [file]\n"
            " --ipv4\n"
            " --ipv6\n"
            " --bindonly\n"
@@ -1095,7 +979,7 @@ int main(int argc, char *argv[])
   setmode(fileno(stderr), O_BINARY);
 #endif
 
-  install_signal_handlers();
+  install_signal_handlers(false);
 
 #ifdef ENABLE_IPV6
   if(!use_ipv6)
@@ -1130,6 +1014,13 @@ int main(int argc, char *argv[])
     goto socks5_cleanup;
   }
 
+  if(portfile) {
+    wrotepidfile = write_portfile(portfile, port);
+    if(!wrotepidfile) {
+      goto socks5_cleanup;
+    }
+  }
+
   do {
     juggle_again = incoming(sock);
   } while(juggle_again);
@@ -1145,7 +1036,7 @@ socks5_cleanup:
   if(wrotepidfile)
     unlink(pidname);
 
-  restore_signal_handlers();
+  restore_signal_handlers(false);
 
   if(got_exit_signal) {
     logmsg("============> socksd exits with signal (%d)", exit_signal);
diff --git a/tests/server/sws.c b/tests/server/sws.c
index b397ed19b..48ea26d5e 100644
--- a/tests/server/sws.c
+++ b/tests/server/sws.c
@@ -213,141 +213,9 @@ static const char *doc404 = "HTTP/1.1 404 Not Found\r\n"
     "The requested URL was not found on this server.\n"
     "<P><HR><ADDRESS>" SWSVERSION "</ADDRESS>\n" "</BODY></HTML>\n";
 
-/* do-nothing macro replacement for systems which lack siginterrupt() */
-
-#ifndef HAVE_SIGINTERRUPT
-#define siginterrupt(x,y) do {} while(0)
-#endif
-
-/* vars used to keep around previous signal handlers */
-
-typedef RETSIGTYPE (*SIGHANDLER_T)(int);
-
-#ifdef SIGHUP
-static SIGHANDLER_T old_sighup_handler  = SIG_ERR;
-#endif
-
-#ifdef SIGPIPE
-static SIGHANDLER_T old_sigpipe_handler = SIG_ERR;
-#endif
-
-#ifdef SIGALRM
-static SIGHANDLER_T old_sigalrm_handler = SIG_ERR;
-#endif
-
-#ifdef SIGINT
-static SIGHANDLER_T old_sigint_handler  = SIG_ERR;
-#endif
-
-#ifdef SIGTERM
-static SIGHANDLER_T old_sigterm_handler = SIG_ERR;
-#endif
-
-#if defined(SIGBREAK) && defined(WIN32)
-static SIGHANDLER_T old_sigbreak_handler = SIG_ERR;
-#endif
-
-/* var which if set indicates that the program should finish execution */
-
-SIG_ATOMIC_T got_exit_signal = 0;
-
-/* if next is set indicates the first signal handled in exit_signal_handler */
-
-static volatile int exit_signal = 0;
-
 /* work around for handling trailing headers */
 static int already_recv_zeroed_chunk = FALSE;
 
-/* signal handler that will be triggered to indicate that the program
-  should finish its execution in a controlled manner as soon as possible.
-  The first time this is called it will set got_exit_signal to one and
-  store in exit_signal the signal that triggered its execution. */
-
-static RETSIGTYPE exit_signal_handler(int signum)
-{
-  int old_errno = errno;
-  if(got_exit_signal == 0) {
-    got_exit_signal = 1;
-    exit_signal = signum;
-  }
-  (void)signal(signum, exit_signal_handler);
-  errno = old_errno;
-}
-
-static void install_signal_handlers(void)
-{
-#ifdef SIGHUP
-  /* ignore SIGHUP signal */
-  old_sighup_handler = signal(SIGHUP, SIG_IGN);
-  if(old_sighup_handler == SIG_ERR)
-    logmsg("cannot install SIGHUP handler: %s", strerror(errno));
-#endif
-#ifdef SIGPIPE
-  /* ignore SIGPIPE signal */
-  old_sigpipe_handler = signal(SIGPIPE, SIG_IGN);
-  if(old_sigpipe_handler == SIG_ERR)
-    logmsg("cannot install SIGPIPE handler: %s", strerror(errno));
-#endif
-#ifdef SIGALRM
-  /* ignore SIGALRM signal */
-  old_sigalrm_handler = signal(SIGALRM, SIG_IGN);
-  if(old_sigalrm_handler == SIG_ERR)
-    logmsg("cannot install SIGALRM handler: %s", strerror(errno));
-#endif
-#ifdef SIGINT
-  /* handle SIGINT signal with our exit_signal_handler */
-  old_sigint_handler = signal(SIGINT, exit_signal_handler);
-  if(old_sigint_handler == SIG_ERR)
-    logmsg("cannot install SIGINT handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGINT, 1);
-#endif
-#ifdef SIGTERM
-  /* handle SIGTERM signal with our exit_signal_handler */
-  old_sigterm_handler = signal(SIGTERM, exit_signal_handler);
-  if(old_sigterm_handler == SIG_ERR)
-    logmsg("cannot install SIGTERM handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGTERM, 1);
-#endif
-#if defined(SIGBREAK) && defined(WIN32)
-  /* handle SIGBREAK signal with our exit_signal_handler */
-  old_sigbreak_handler = signal(SIGBREAK, exit_signal_handler);
-  if(old_sigbreak_handler == SIG_ERR)
-    logmsg("cannot install SIGBREAK handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGBREAK, 1);
-#endif
-}
-
-static void restore_signal_handlers(void)
-{
-#ifdef SIGHUP
-  if(SIG_ERR != old_sighup_handler)
-    (void)signal(SIGHUP, old_sighup_handler);
-#endif
-#ifdef SIGPIPE
-  if(SIG_ERR != old_sigpipe_handler)
-    (void)signal(SIGPIPE, old_sigpipe_handler);
-#endif
-#ifdef SIGALRM
-  if(SIG_ERR != old_sigalrm_handler)
-    (void)signal(SIGALRM, old_sigalrm_handler);
-#endif
-#ifdef SIGINT
-  if(SIG_ERR != old_sigint_handler)
-    (void)signal(SIGINT, old_sigint_handler);
-#endif
-#ifdef SIGTERM
-  if(SIG_ERR != old_sigterm_handler)
-    (void)signal(SIGTERM, old_sigterm_handler);
-#endif
-#if defined(SIGBREAK) && defined(WIN32)
-  if(SIG_ERR != old_sigbreak_handler)
-    (void)signal(SIGBREAK, old_sigbreak_handler);
-#endif
-}
-
 /* returns true if the current socket is an IP one */
 static bool socket_domain_is_ip(void)
 {
@@ -367,18 +235,15 @@ static bool socket_domain_is_ip(void)
 static int parse_servercmd(struct httprequest *req)
 {
   FILE *stream;
-  char *filename;
   int error;
 
-  filename = test2file(req->testno);
+  stream = test2fopen(req->testno);
   req->close = FALSE;
   req->connmon = FALSE;
 
-  stream = fopen(filename, "rb");
   if(!stream) {
     error = errno;
     logmsg("fopen() failed with error: %d %s", error, strerror(error));
-    logmsg("  [1] Error opening file: %s", filename);
     logmsg("  Couldn't open test file %ld", req->testno);
     req->open = FALSE; /* closes connection */
     return 1; /* done */
@@ -1123,7 +988,6 @@ static int send_doc(curl_socket_t sock, struct httprequest 
*req)
   }
   else {
     char partbuf[80];
-    char *filename = test2file(req->testno);
 
     /* select the <data> tag for "normal" requests and the <connect> one
        for CONNECT requests (within the <reply> section) */
@@ -1136,11 +1000,10 @@ static int send_doc(curl_socket_t sock, struct 
httprequest *req)
 
     logmsg("Send response test%ld section <%s>", req->testno, partbuf);
 
-    stream = fopen(filename, "rb");
+    stream = test2fopen(req->testno);
     if(!stream) {
       error = errno;
       logmsg("fopen() failed with error: %d %s", error, strerror(error));
-      logmsg("  [3] Error opening file: %s", filename);
       return 0;
     }
     else {
@@ -1159,11 +1022,10 @@ static int send_doc(curl_socket_t sock, struct 
httprequest *req)
     }
 
     /* re-open the same file again */
-    stream = fopen(filename, "rb");
+    stream = test2fopen(req->testno);
     if(!stream) {
       error = errno;
       logmsg("fopen() failed with error: %d %s", error, strerror(error));
-      logmsg("  [4] Error opening file: %s", filename);
       free(ptr);
       return 0;
     }
@@ -1981,6 +1843,7 @@ int main(int argc, char *argv[])
   bool unlink_socket = false;
 #endif
   const char *pidname = ".http.pid";
+  const char *portname = ".http.port";
   struct httprequest req;
   int rc = 0;
   int error;
@@ -2013,6 +1876,11 @@ int main(int argc, char *argv[])
       if(argc>arg)
         pidname = argv[arg++];
     }
+    else if(!strcmp("--portfile", argv[arg])) {
+      arg++;
+      if(argc>arg)
+        portname = argv[arg++];
+    }
     else if(!strcmp("--logfile", argv[arg])) {
       arg++;
       if(argc>arg)
@@ -2060,7 +1928,7 @@ int main(int argc, char *argv[])
         char *endptr;
         unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
         if((endptr != argv[arg] + strlen(argv[arg])) ||
-           (ulnum < 1025UL) || (ulnum > 65535UL)) {
+           (ulnum && ((ulnum < 1025UL) || (ulnum > 65535UL)))) {
           fprintf(stderr, "sws: invalid --port argument (%s)\n",
                   argv[arg]);
           return 0;
@@ -2093,6 +1961,7 @@ int main(int argc, char *argv[])
            " --version\n"
            " --logfile [file]\n"
            " --pidfile [file]\n"
+           " --portfile [file]\n"
            " --ipv4\n"
            " --ipv6\n"
            " --unix-socket [file]\n"
@@ -2104,14 +1973,12 @@ int main(int argc, char *argv[])
     }
   }
 
-  msnprintf(port_str, sizeof(port_str), "port %hu", port);
-
 #ifdef WIN32
   win32_init();
   atexit(win32_cleanup);
 #endif
 
-  install_signal_handlers();
+  install_signal_handlers(false);
 
   pid = (long)getpid();
 
@@ -2212,11 +2079,58 @@ int main(int argc, char *argv[])
   }
   if(0 != rc) {
     error = SOCKERRNO;
-    logmsg("Error binding socket on %s: (%d) %s",
-           location_str, error, strerror(error));
+    logmsg("Error binding socket: (%d) %s", error, strerror(error));
     goto sws_cleanup;
   }
 
+  if(!port) {
+    /* The system was supposed to choose a port number, figure out which
+       port we actually got and update the listener port value with it. */
+    curl_socklen_t la_size;
+    srvr_sockaddr_union_t localaddr;
+#ifdef ENABLE_IPV6
+    if(socket_domain != AF_INET6)
+#endif
+      la_size = sizeof(localaddr.sa4);
+#ifdef ENABLE_IPV6
+    else
+      la_size = sizeof(localaddr.sa6);
+#endif
+    memset(&localaddr.sa, 0, (size_t)la_size);
+    if(getsockname(sock, &localaddr.sa, &la_size) < 0) {
+      error = SOCKERRNO;
+      logmsg("getsockname() failed with error: (%d) %s",
+             error, strerror(error));
+      sclose(sock);
+      goto sws_cleanup;
+    }
+    switch(localaddr.sa.sa_family) {
+    case AF_INET:
+      port = ntohs(localaddr.sa4.sin_port);
+      break;
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      port = ntohs(localaddr.sa6.sin6_port);
+      break;
+#endif
+    default:
+      break;
+    }
+    if(!port) {
+      /* Real failure, listener port shall not be zero beyond this point. */
+      logmsg("Apparently getsockname() succeeded, with listener port zero.");
+      logmsg("A valid reason for this failure is a binary built without");
+      logmsg("proper network library linkage. This might not be the only");
+      logmsg("reason, but double check it before anything else.");
+      sclose(sock);
+      goto sws_cleanup;
+    }
+  }
+#ifdef USE_UNIX_SOCKETS
+  if(socket_domain != AF_UNIX)
+#endif
+    msnprintf(port_str, sizeof(port_str), "port %hu", port);
+
   logmsg("Running %s %s version on %s",
          use_gopher?"GOPHER":"HTTP", socket_type, location_str);
 
@@ -2243,6 +2157,10 @@ int main(int argc, char *argv[])
   if(!wrotepidfile)
     goto sws_cleanup;
 
+  wrotepidfile = write_portfile(portname, port);
+  if(!wrotepidfile)
+    goto sws_cleanup;
+
   /* initialization of httprequest struct is done before get_request(), but
      the pipelining struct field must be initialized previously to FALSE
      every time a new connection arrives. */
@@ -2394,7 +2312,7 @@ sws_cleanup:
     clear_advisor_read_lock(SERVERLOGS_LOCK);
   }
 
-  restore_signal_handlers();
+  restore_signal_handlers(false);
 
   if(got_exit_signal) {
     logmsg("========> %s sws (%s pid: %ld) exits with signal (%d)",
diff --git a/tests/server/testpart.c b/tests/server/testpart.c
index 7d31e5183..9c295e0f5 100644
--- a/tests/server/testpart.c
+++ b/tests/server/testpart.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/server/tftp.h b/tests/server/tftp.h
index 3cdd6e6d0..62a0cc35e 100644
--- a/tests/server/tftp.h
+++ b/tests/server/tftp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/server/tftpd.c b/tests/server/tftpd.c
index 35419b0b9..0c0e9bedf 100644
--- a/tests/server/tftpd.c
+++ b/tests/server/tftpd.c
@@ -15,7 +15,8 @@
  */
 
 /*
- * Copyright (c) 1983 Regents of the University of California.
+ * Copyright (C) 2005 - 2020, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (c) 1983, Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -209,6 +210,7 @@ static const char *ipv_inuse = "IPv4";
 
 const  char *serverlogfile = DEFAULT_LOGFILE;
 static const char *pidname = ".tftpd.pid";
+static const char *portfile = NULL;
 static int serverlogslocked = 0;
 static int wrotepidfile = 0;
 
@@ -220,44 +222,6 @@ static sigjmp_buf timeoutbuf;
 static const unsigned int rexmtval = TIMEOUT;
 #endif
 
-/* do-nothing macro replacement for systems which lack siginterrupt() */
-
-#ifndef HAVE_SIGINTERRUPT
-#define siginterrupt(x,y) do {} while(0)
-#endif
-
-/* vars used to keep around previous signal handlers */
-
-typedef RETSIGTYPE (*SIGHANDLER_T)(int);
-
-#ifdef SIGHUP
-static SIGHANDLER_T old_sighup_handler  = SIG_ERR;
-#endif
-
-#ifdef SIGPIPE
-static SIGHANDLER_T old_sigpipe_handler = SIG_ERR;
-#endif
-
-#ifdef SIGINT
-static SIGHANDLER_T old_sigint_handler  = SIG_ERR;
-#endif
-
-#ifdef SIGTERM
-static SIGHANDLER_T old_sigterm_handler = SIG_ERR;
-#endif
-
-#if defined(SIGBREAK) && defined(WIN32)
-static SIGHANDLER_T old_sigbreak_handler = SIG_ERR;
-#endif
-
-/* var which if set indicates that the program should finish execution */
-
-SIG_ATOMIC_T got_exit_signal = 0;
-
-/* if next is set indicates the first signal handled in exit_signal_handler */
-
-static volatile int exit_signal = 0;
-
 /*****************************************************************************
 *                            FUNCTION PROTOTYPES                             *
 *****************************************************************************/
@@ -294,12 +258,6 @@ static void justtimeout(int signum);
 
 #endif /* HAVE_ALARM && SIGALRM */
 
-static RETSIGTYPE exit_signal_handler(int signum);
-
-static void install_signal_handlers(void);
-
-static void restore_signal_handlers(void);
-
 /*****************************************************************************
 *                          FUNCTION IMPLEMENTATIONS                          *
 *****************************************************************************/
@@ -347,86 +305,6 @@ static void justtimeout(int signum)
 
 #endif /* HAVE_ALARM && SIGALRM */
 
-/* signal handler that will be triggered to indicate that the program
-  should finish its execution in a controlled manner as soon as possible.
-  The first time this is called it will set got_exit_signal to one and
-  store in exit_signal the signal that triggered its execution. */
-
-static RETSIGTYPE exit_signal_handler(int signum)
-{
-  int old_errno = errno;
-  if(got_exit_signal == 0) {
-    got_exit_signal = 1;
-    exit_signal = signum;
-  }
-  (void)signal(signum, exit_signal_handler);
-  errno = old_errno;
-}
-
-static void install_signal_handlers(void)
-{
-#ifdef SIGHUP
-  /* ignore SIGHUP signal */
-  old_sighup_handler = signal(SIGHUP, SIG_IGN);
-  if(old_sighup_handler == SIG_ERR)
-    logmsg("cannot install SIGHUP handler: %s", strerror(errno));
-#endif
-#ifdef SIGPIPE
-  /* ignore SIGPIPE signal */
-  old_sigpipe_handler = signal(SIGPIPE, SIG_IGN);
-  if(old_sigpipe_handler == SIG_ERR)
-    logmsg("cannot install SIGPIPE handler: %s", strerror(errno));
-#endif
-#ifdef SIGINT
-  /* handle SIGINT signal with our exit_signal_handler */
-  old_sigint_handler = signal(SIGINT, exit_signal_handler);
-  if(old_sigint_handler == SIG_ERR)
-    logmsg("cannot install SIGINT handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGINT, 1);
-#endif
-#ifdef SIGTERM
-  /* handle SIGTERM signal with our exit_signal_handler */
-  old_sigterm_handler = signal(SIGTERM, exit_signal_handler);
-  if(old_sigterm_handler == SIG_ERR)
-    logmsg("cannot install SIGTERM handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGTERM, 1);
-#endif
-#if defined(SIGBREAK) && defined(WIN32)
-  /* handle SIGBREAK signal with our exit_signal_handler */
-  old_sigbreak_handler = signal(SIGBREAK, exit_signal_handler);
-  if(old_sigbreak_handler == SIG_ERR)
-    logmsg("cannot install SIGBREAK handler: %s", strerror(errno));
-  else
-    siginterrupt(SIGBREAK, 1);
-#endif
-}
-
-static void restore_signal_handlers(void)
-{
-#ifdef SIGHUP
-  if(SIG_ERR != old_sighup_handler)
-    (void)signal(SIGHUP, old_sighup_handler);
-#endif
-#ifdef SIGPIPE
-  if(SIG_ERR != old_sigpipe_handler)
-    (void)signal(SIGPIPE, old_sigpipe_handler);
-#endif
-#ifdef SIGINT
-  if(SIG_ERR != old_sigint_handler)
-    (void)signal(SIGINT, old_sigint_handler);
-#endif
-#ifdef SIGTERM
-  if(SIG_ERR != old_sigterm_handler)
-    (void)signal(SIGTERM, old_sigterm_handler);
-#endif
-#if defined(SIGBREAK) && defined(WIN32)
-  if(SIG_ERR != old_sigbreak_handler)
-    (void)signal(SIGBREAK, old_sigbreak_handler);
-#endif
-}
-
 /*
  * init for either read-ahead or write-behind.
  * zero for write-behind, one for read-head.
@@ -697,6 +575,11 @@ int main(int argc, char **argv)
       if(argc>arg)
         pidname = argv[arg++];
     }
+    else if(!strcmp("--portfile", argv[arg])) {
+      arg++;
+      if(argc>arg)
+        portfile = argv[arg++];
+    }
     else if(!strcmp("--logfile", argv[arg])) {
       arg++;
       if(argc>arg)
@@ -721,12 +604,6 @@ int main(int argc, char **argv)
       if(argc>arg) {
         char *endptr;
         unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
-        if((endptr != argv[arg] + strlen(argv[arg])) ||
-           (ulnum < 1025UL) || (ulnum > 65535UL)) {
-          fprintf(stderr, "tftpd: invalid --port argument (%s)\n",
-                  argv[arg]);
-          return 0;
-        }
         port = curlx_ultous(ulnum);
         arg++;
       }
@@ -756,7 +633,7 @@ int main(int argc, char **argv)
   atexit(win32_cleanup);
 #endif
 
-  install_signal_handlers();
+  install_signal_handlers(true);
 
   pid = (long)getpid();
 
@@ -813,12 +690,64 @@ int main(int argc, char **argv)
     goto tftpd_cleanup;
   }
 
+  if(!port) {
+    /* The system was supposed to choose a port number, figure out which
+       port we actually got and update the listener port value with it. */
+    curl_socklen_t la_size;
+    srvr_sockaddr_union_t localaddr;
+#ifdef ENABLE_IPV6
+    if(!use_ipv6)
+#endif
+      la_size = sizeof(localaddr.sa4);
+#ifdef ENABLE_IPV6
+    else
+      la_size = sizeof(localaddr.sa6);
+#endif
+    memset(&localaddr.sa, 0, (size_t)la_size);
+    if(getsockname(sock, &localaddr.sa, &la_size) < 0) {
+      error = SOCKERRNO;
+      logmsg("getsockname() failed with error: (%d) %s",
+             error, strerror(error));
+      sclose(sock);
+      goto tftpd_cleanup;
+    }
+    switch(localaddr.sa.sa_family) {
+    case AF_INET:
+      port = ntohs(localaddr.sa4.sin_port);
+      break;
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      port = ntohs(localaddr.sa6.sin6_port);
+      break;
+#endif
+    default:
+      break;
+    }
+    if(!port) {
+      /* Real failure, listener port shall not be zero beyond this point. */
+      logmsg("Apparently getsockname() succeeded, with listener port zero.");
+      logmsg("A valid reason for this failure is a binary built without");
+      logmsg("proper network library linkage. This might not be the only");
+      logmsg("reason, but double check it before anything else.");
+      result = 2;
+      goto tftpd_cleanup;
+    }
+  }
+
   wrotepidfile = write_pidfile(pidname);
   if(!wrotepidfile) {
     result = 1;
     goto tftpd_cleanup;
   }
 
+  if(portfile) {
+    wrotepidfile = write_portfile(portfile, port);
+    if(!wrotepidfile) {
+      result = 1;
+      goto tftpd_cleanup;
+    }
+  }
+
   logmsg("Running %s version on port UDP/%d", ipv_inuse, (int)port);
 
   for(;;) {
@@ -923,13 +852,15 @@ tftpd_cleanup:
 
   if(wrotepidfile)
     unlink(pidname);
+  if(portfile)
+    unlink(portfile);
 
   if(serverlogslocked) {
     serverlogslocked = 0;
     clear_advisor_read_lock(SERVERLOGS_LOCK);
   }
 
-  restore_signal_handlers();
+  restore_signal_handlers(true);
 
   if(got_exit_signal) {
     logmsg("========> %s tftpd (port: %d pid: %ld) exits with signal (%d)",
@@ -1067,16 +998,12 @@ static int do_tftp(struct testcase *test, struct tftphdr 
*tp, ssize_t size)
 static int parse_servercmd(struct testcase *req)
 {
   FILE *stream;
-  char *filename;
   int error;
 
-  filename = test2file(req->testno);
-
-  stream = fopen(filename, "rb");
+  stream = test2fopen(req->testno);
   if(!stream) {
     error = errno;
     logmsg("fopen() failed with error: %d %s", error, strerror(error));
-    logmsg("  [1] Error opening file: %s", filename);
     logmsg("  Couldn't open test file %ld", req->testno);
     return 1; /* done */
   }
@@ -1159,7 +1086,7 @@ static int validate_access(struct testcase *test,
     char partbuf[80]="data";
     long partno;
     long testno;
-    char *file;
+    FILE *stream;
 
     ptr++; /* skip the slash */
 
@@ -1184,40 +1111,33 @@ static int validate_access(struct testcase *test,
 
     (void)parse_servercmd(test);
 
-    file = test2file(testno);
+    stream = test2fopen(testno);
 
     if(0 != partno)
       msnprintf(partbuf, sizeof(partbuf), "data%ld", partno);
 
-    if(file) {
-      FILE *stream = fopen(file, "rb");
-      if(!stream) {
-        int error = errno;
-        logmsg("fopen() failed with error: %d %s", error, strerror(error));
-        logmsg("Error opening file: %s", file);
-        logmsg("Couldn't open test file: %s", file);
+    if(!stream) {
+      int error = errno;
+      logmsg("fopen() failed with error: %d %s", error, strerror(error));
+      logmsg("Couldn't open test file for test : %d", testno);
+      return EACCESS;
+    }
+    else {
+      size_t count;
+      int error = getpart(&test->buffer, &count, "reply", partbuf, stream);
+      fclose(stream);
+      if(error) {
+        logmsg("getpart() failed with error: %d", error);
         return EACCESS;
       }
-      else {
-        size_t count;
-        int error = getpart(&test->buffer, &count, "reply", partbuf, stream);
-        fclose(stream);
-        if(error) {
-          logmsg("getpart() failed with error: %d", error);
-          return EACCESS;
-        }
-        if(test->buffer) {
-          test->rptr = test->buffer; /* set read pointer */
-          test->bufsize = count;    /* set total count */
-          test->rcount = count;     /* set data left to read */
-        }
-        else
-          return EACCESS;
+      if(test->buffer) {
+        test->rptr = test->buffer; /* set read pointer */
+        test->bufsize = count;    /* set total count */
+        test->rcount = count;     /* set data left to read */
       }
-
+      else
+        return EACCESS;
     }
-    else
-      return EACCESS;
   }
   else {
     logmsg("no slash found in path");
diff --git a/tests/server/util.c b/tests/server/util.c
index 263f0cece..f576b9c23 100644
--- a/tests/server/util.c
+++ b/tests/server/util.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -194,11 +194,21 @@ void win32_cleanup(void)
 /* set by the main code to point to where the test dir is */
 const char *path = ".";
 
-char *test2file(long testno)
+FILE *test2fopen(long testno)
 {
-  static char filename[256];
+  FILE *stream;
+  char filename[256];
+  /* first try the alternative, preprocessed, file */
+  msnprintf(filename, sizeof(filename), ALTTEST_DATA_PATH, path, testno);
+  stream = fopen(filename, "rb");
+  if(stream)
+    return stream;
+
+  /* then try the source version */
   msnprintf(filename, sizeof(filename), TEST_DATA_PATH, path, testno);
-  return filename;
+  stream = fopen(filename, "rb");
+
+  return stream;
 }
 
 /*
@@ -261,20 +271,43 @@ int wait_ms(int timeout_ms)
 int write_pidfile(const char *filename)
 {
   FILE *pidfile;
-  long pid;
+  curl_off_t pid;
 
-  pid = (long)getpid();
+  pid = (curl_off_t)getpid();
   pidfile = fopen(filename, "wb");
   if(!pidfile) {
     logmsg("Couldn't write pid file: %s %s", filename, strerror(errno));
     return 0; /* fail */
   }
-  fprintf(pidfile, "%ld\n", pid);
+#if defined(WIN32) || defined(_WIN32)
+  /* store pid + 65536 to avoid conflict with Cygwin/msys PIDs, see also:
+   * - https://cygwin.com/git/?p=newlib-cygwin.git;a=commit; ↵
+   *   h=b5e1003722cb14235c4f166be72c09acdffc62ea
+   * - https://cygwin.com/git/?p=newlib-cygwin.git;a=commit; ↵
+   *   h=448cf5aa4b429d5a9cebf92a0da4ab4b5b6d23fe
+   */
+  pid += 65536;
+#endif
+  fprintf(pidfile, "%" CURL_FORMAT_CURL_OFF_T "\n", pid);
   fclose(pidfile);
   logmsg("Wrote pid %ld to %s", pid, filename);
   return 1; /* success */
 }
 
+/* store the used port number in a file */
+int write_portfile(const char *filename, int port)
+{
+  FILE *portfile = fopen(filename, "wb");
+  if(!portfile) {
+    logmsg("Couldn't write port file: %s %s", filename, strerror(errno));
+    return 0; /* fail */
+  }
+  fprintf(portfile, "%d\n", port);
+  fclose(portfile);
+  logmsg("Wrote port %d to %s", port, filename);
+  return 1; /* success */
+}
+
 void set_advisor_read_lock(const char *filename)
 {
   FILE *lockfile;
@@ -500,3 +533,278 @@ long timediff(struct timeval newer, struct timeval older)
   return (long)(newer.tv_sec-older.tv_sec)*1000+
     (long)(newer.tv_usec-older.tv_usec)/1000;
 }
+
+/* do-nothing macro replacement for systems which lack siginterrupt() */
+
+#ifndef HAVE_SIGINTERRUPT
+#define siginterrupt(x,y) do {} while(0)
+#endif
+
+/* vars used to keep around previous signal handlers */
+
+typedef RETSIGTYPE (*SIGHANDLER_T)(int);
+
+#ifdef SIGHUP
+static SIGHANDLER_T old_sighup_handler  = SIG_ERR;
+#endif
+
+#ifdef SIGPIPE
+static SIGHANDLER_T old_sigpipe_handler = SIG_ERR;
+#endif
+
+#ifdef SIGALRM
+static SIGHANDLER_T old_sigalrm_handler = SIG_ERR;
+#endif
+
+#ifdef SIGINT
+static SIGHANDLER_T old_sigint_handler  = SIG_ERR;
+#endif
+
+#ifdef SIGTERM
+static SIGHANDLER_T old_sigterm_handler = SIG_ERR;
+#endif
+
+#if defined(SIGBREAK) && defined(WIN32)
+static SIGHANDLER_T old_sigbreak_handler = SIG_ERR;
+#endif
+
+#ifdef WIN32
+static DWORD thread_main_id = 0;
+static HANDLE thread_main_window = NULL;
+static HWND hidden_main_window = NULL;
+#endif
+
+/* var which if set indicates that the program should finish execution */
+volatile int got_exit_signal = 0;
+
+/* if next is set indicates the first signal handled in exit_signal_handler */
+volatile int exit_signal = 0;
+
+/* signal handler that will be triggered to indicate that the program
+ * should finish its execution in a controlled manner as soon as possible.
+ * The first time this is called it will set got_exit_signal to one and
+ * store in exit_signal the signal that triggered its execution.
+ */
+static RETSIGTYPE exit_signal_handler(int signum)
+{
+  int old_errno = errno;
+  logmsg("exit_signal_handler: %d", signum);
+  if(got_exit_signal == 0) {
+    got_exit_signal = 1;
+    exit_signal = signum;
+  }
+  (void)signal(signum, exit_signal_handler);
+  errno = old_errno;
+}
+
+#ifdef WIN32
+/* CTRL event handler for Windows Console applications to simulate
+ * SIGINT, SIGTERM and SIGBREAK on CTRL events and trigger signal handler.
+ *
+ * Background information from MSDN:
+ * SIGINT is not supported for any Win32 application. When a CTRL+C
+ * interrupt occurs, Win32 operating systems generate a new thread
+ * to specifically handle that interrupt. This can cause a single-thread
+ * application, such as one in UNIX, to become multithreaded and cause
+ * unexpected behavior.
+ * [...]
+ * The SIGILL and SIGTERM signals are not generated under Windows.
+ * They are included for ANSI compatibility. Therefore, you can set
+ * signal handlers for these signals by using signal, and you can also
+ * explicitly generate these signals by calling raise. Source:
+ * https://docs.microsoft.com/de-de/cpp/c-runtime-library/reference/signal
+ */
+static BOOL WINAPI ctrl_event_handler(DWORD dwCtrlType)
+{
+  int signum = 0;
+  logmsg("ctrl_event_handler: %d", dwCtrlType);
+  switch(dwCtrlType) {
+#ifdef SIGINT
+    case CTRL_C_EVENT: signum = SIGINT; break;
+#endif
+#ifdef SIGTERM
+    case CTRL_CLOSE_EVENT: signum = SIGTERM; break;
+#endif
+#ifdef SIGBREAK
+    case CTRL_BREAK_EVENT: signum = SIGBREAK; break;
+#endif
+    default: return FALSE;
+  }
+  if(signum) {
+    logmsg("ctrl_event_handler: %d -> %d", dwCtrlType, signum);
+    exit_signal_handler(signum);
+  }
+  return TRUE;
+}
+/* Window message handler for Windows applications to add support
+ * for graceful process termination via taskkill (without /f) which
+ * sends WM_CLOSE to all Windows of a process (even hidden ones).
+ *
+ * Therefore we create and run a hidden Window in a separate thread
+ * to receive and handle the WM_CLOSE message as SIGTERM signal.
+ */
+static LRESULT CALLBACK main_window_proc(HWND hwnd, UINT uMsg,
+                                         WPARAM wParam, LPARAM lParam)
+{
+  int signum = 0;
+  if(hwnd == hidden_main_window) {
+    switch(uMsg) {
+#ifdef SIGTERM
+      case WM_CLOSE: signum = SIGTERM; break;
+#endif
+      case WM_DESTROY: PostQuitMessage(0); break;
+    }
+    if(signum) {
+      logmsg("main_window_proc: %d -> %d", uMsg, signum);
+      exit_signal_handler(signum);
+    }
+  }
+  return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+/* Window message queue loop for hidden main window, details see above.
+ */
+static DWORD WINAPI main_window_loop(LPVOID lpParameter)
+{
+  WNDCLASS wc;
+  BOOL ret;
+  MSG msg;
+
+  ZeroMemory(&wc, sizeof(wc));
+  wc.lpfnWndProc = (WNDPROC)main_window_proc;
+  wc.hInstance = (HINSTANCE)lpParameter;
+  wc.lpszClassName = "MainWClass";
+  if(!RegisterClass(&wc)) {
+    perror("RegisterClass failed");
+    return (DWORD)-1;
+  }
+
+  hidden_main_window = CreateWindowEx(0, "MainWClass", "Recv WM_CLOSE msg",
+                                      WS_OVERLAPPEDWINDOW,
+                                      CW_USEDEFAULT, CW_USEDEFAULT,
+                                      CW_USEDEFAULT, CW_USEDEFAULT,
+                                      (HWND)NULL, (HMENU)NULL,
+                                      wc.hInstance, (LPVOID)NULL);
+  if(!hidden_main_window) {
+    perror("CreateWindowEx failed");
+    return (DWORD)-1;
+  }
+
+  do {
+    ret = GetMessage(&msg, NULL, 0, 0);
+    if(ret == -1) {
+      perror("GetMessage failed");
+      return (DWORD)-1;
+    }
+    else if(ret) {
+      if(msg.message == WM_APP) {
+        DestroyWindow(hidden_main_window);
+      }
+      else if(msg.hwnd && !TranslateMessage(&msg)) {
+        DispatchMessage(&msg);
+      }
+    }
+  } while(ret);
+
+  hidden_main_window = NULL;
+  return (DWORD)msg.wParam;
+}
+#endif
+
+void install_signal_handlers(bool keep_sigalrm)
+{
+#ifdef SIGHUP
+  /* ignore SIGHUP signal */
+  old_sighup_handler = signal(SIGHUP, SIG_IGN);
+  if(old_sighup_handler == SIG_ERR)
+    logmsg("cannot install SIGHUP handler: %s", strerror(errno));
+#endif
+#ifdef SIGPIPE
+  /* ignore SIGPIPE signal */
+  old_sigpipe_handler = signal(SIGPIPE, SIG_IGN);
+  if(old_sigpipe_handler == SIG_ERR)
+    logmsg("cannot install SIGPIPE handler: %s", strerror(errno));
+#endif
+#ifdef SIGALRM
+  if(!keep_sigalrm) {
+    /* ignore SIGALRM signal */
+    old_sigalrm_handler = signal(SIGALRM, SIG_IGN);
+    if(old_sigalrm_handler == SIG_ERR)
+      logmsg("cannot install SIGALRM handler: %s", strerror(errno));
+  }
+#else
+  (void)keep_sigalrm;
+#endif
+#ifdef SIGINT
+  /* handle SIGINT signal with our exit_signal_handler */
+  old_sigint_handler = signal(SIGINT, exit_signal_handler);
+  if(old_sigint_handler == SIG_ERR)
+    logmsg("cannot install SIGINT handler: %s", strerror(errno));
+  else
+    siginterrupt(SIGINT, 1);
+#endif
+#ifdef SIGTERM
+  /* handle SIGTERM signal with our exit_signal_handler */
+  old_sigterm_handler = signal(SIGTERM, exit_signal_handler);
+  if(old_sigterm_handler == SIG_ERR)
+    logmsg("cannot install SIGTERM handler: %s", strerror(errno));
+  else
+    siginterrupt(SIGTERM, 1);
+#endif
+#if defined(SIGBREAK) && defined(WIN32)
+  /* handle SIGBREAK signal with our exit_signal_handler */
+  old_sigbreak_handler = signal(SIGBREAK, exit_signal_handler);
+  if(old_sigbreak_handler == SIG_ERR)
+    logmsg("cannot install SIGBREAK handler: %s", strerror(errno));
+  else
+    siginterrupt(SIGBREAK, 1);
+#endif
+#ifdef WIN32
+  if(!SetConsoleCtrlHandler(ctrl_event_handler, TRUE))
+    logmsg("cannot install CTRL event handler");
+  thread_main_window = CreateThread(NULL, 0,
+                                    &main_window_loop,
+                                    (LPVOID)GetModuleHandle(NULL),
+                                    0, &thread_main_id);
+  if(!thread_main_window || !thread_main_id)
+    logmsg("cannot start main window loop");
+#endif
+}
+
+void restore_signal_handlers(bool keep_sigalrm)
+{
+#ifdef SIGHUP
+  if(SIG_ERR != old_sighup_handler)
+    (void)signal(SIGHUP, old_sighup_handler);
+#endif
+#ifdef SIGPIPE
+  if(SIG_ERR != old_sigpipe_handler)
+    (void)signal(SIGPIPE, old_sigpipe_handler);
+#endif
+#ifdef SIGALRM
+  if(!keep_sigalrm) {
+    if(SIG_ERR != old_sigalrm_handler)
+      (void)signal(SIGALRM, old_sigalrm_handler);
+  }
+#else
+  (void)keep_sigalrm;
+#endif
+#ifdef SIGINT
+  if(SIG_ERR != old_sigint_handler)
+    (void)signal(SIGINT, old_sigint_handler);
+#endif
+#ifdef SIGTERM
+  if(SIG_ERR != old_sigterm_handler)
+    (void)signal(SIGTERM, old_sigterm_handler);
+#endif
+#if defined(SIGBREAK) && defined(WIN32)
+  if(SIG_ERR != old_sigbreak_handler)
+    (void)signal(SIGBREAK, old_sigbreak_handler);
+#endif
+#ifdef WIN32
+  (void)SetConsoleCtrlHandler(ctrl_event_handler, FALSE);
+  if(thread_main_window && thread_main_id) {
+    if(PostThreadMessage(thread_main_id, WM_APP, 0, 0))
+      (void)WaitForSingleObjectEx(thread_main_window, INFINITE, TRUE);
+  }
+#endif
+}
diff --git a/tests/server/util.h b/tests/server/util.h
index 236d4550e..73f5f45f6 100644
--- a/tests/server/util.h
+++ b/tests/server/util.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -28,6 +28,7 @@ void logmsg(const char *msg, ...);
 long timediff(struct timeval newer, struct timeval older);
 
 #define TEST_DATA_PATH "%s/data/test%ld"
+#define ALTTEST_DATA_PATH "%s/log/test%ld"
 
 #define SERVERLOGS_LOCK "log/serverlogs.lock"
 
@@ -53,17 +54,23 @@ void win32_init(void);
 void win32_cleanup(void);
 #endif  /* USE_WINSOCK */
 
-/* returns the path name to the test case file */
-char *test2file(long testno);
+/* fopens the test case file */
+FILE *test2fopen(long testno);
 
 int wait_ms(int timeout_ms);
-
 int write_pidfile(const char *filename);
-
+int write_portfile(const char *filename, int port);
 void set_advisor_read_lock(const char *filename);
-
 void clear_advisor_read_lock(const char *filename);
-
 int strncasecompare(const char *first, const char *second, size_t max);
 
+/* global variable which if set indicates that the program should finish */
+extern volatile int got_exit_signal;
+
+/* global variable which if set indicates the first signal handled */
+extern volatile int exit_signal;
+
+void install_signal_handlers(bool keep_sigalrm);
+void restore_signal_handlers(bool keep_sigalrm);
+
 #endif  /* HEADER_CURL_SERVER_UTIL_H */
diff --git a/tests/serverhelp.pm b/tests/serverhelp.pm
index 7c9808c82..466091fcc 100644
--- a/tests/serverhelp.pm
+++ b/tests/serverhelp.pm
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -51,6 +51,7 @@ use vars qw(
     servername_str
     servername_canon
     server_pidfilename
+    server_portfilename
     server_logfilename
     server_cmdfilename
     server_inputfilename
@@ -105,7 +106,7 @@ sub servername_str {
 
     $proto = uc($proto) if($proto);
     die "unsupported protocol: '$proto'" unless($proto &&
-        ($proto =~ 
/^(((FTP|HTTP|HTTP\/2|IMAP|POP3|SMTP|HTTP-PIPE)S?)|(TFTP|SFTP|SOCKS|SSH|RTSP|GOPHER|HTTPTLS|DICT|SMB|SMBS|TELNET))$/));
+        ($proto =~ 
/^(((FTP|HTTP|HTTP\/2|IMAP|POP3|SMTP|HTTP-PIPE)S?)|(TFTP|SFTP|SOCKS|SSH|RTSP|GOPHER|HTTPTLS|DICT|SMB|SMBS|TELNET|MQTT))$/));
 
     $ipver = (not $ipver) ? 'ipv4' : lc($ipver);
     die "unsupported IP version: '$ipver'" unless($ipver &&
@@ -151,6 +152,15 @@ sub server_pidfilename {
     return '.'. servername_canon($proto, $ipver, $idnum) ."$trailer";
 }
 
+#***************************************************************************
+# Return file name for server port file.
+#
+sub server_portfilename {
+    my ($proto, $ipver, $idnum) = @_;
+    my $trailer = '_server.port';
+    return '.'. servername_canon($proto, $ipver, $idnum) ."$trailer";
+}
+
 
 #***************************************************************************
 # Return file name for server log file.
diff --git a/tests/smbserver.py.in b/tests/smbserver.py.in
index 2677f0c46..f752c17a2 100755
--- a/tests/smbserver.py.in
+++ b/tests/smbserver.py.in
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2017 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -22,23 +22,27 @@
 """Server for testing SMB"""
 
 from __future__ import (absolute_import, division, print_function)
-# unicode_literals)
+# NOTE: the impacket configuration is not unicode_literals compatible!
 import argparse
 import os
 import sys
 import logging
 import tempfile
-try: # Python 3
+if sys.version_info.major >= 3:
     import configparser
-except ImportError: # Python 2
+else:
     import ConfigParser as configparser
 
 # Import our curl test data helper
 import curl_test_data
 
-# This saves us having to set up the PYTHONPATH explicitly
-deps_dir = os.path.join(os.path.dirname(__file__), "python_dependencies")
-sys.path.append(deps_dir)
+# impacket needs to be installed in the Python environment
+try:
+    import impacket
+except ImportError:
+    sys.stderr.write('Python package impacket needs to be installed!\n')
+    sys.stderr.write('Use pip or your package manager to install it.\n')
+    sys.exit(1)
 from impacket import smbserver as imp_smbserver
 from impacket import smb as imp_smb
 from impacket.nt_errors import (STATUS_ACCESS_DENIED, STATUS_SUCCESS,
@@ -48,7 +52,7 @@ log = logging.getLogger(__name__)
 SERVER_MAGIC = "SERVER_MAGIC"
 TESTS_MAGIC = "TESTS_MAGIC"
 VERIFIED_REQ = "verifiedserver"
-VERIFIED_RSP = b"WE ROOLZ: {pid}\n"
+VERIFIED_RSP = "WE ROOLZ: {pid}\n"
 
 
 def smbserver(options):
@@ -57,8 +61,11 @@ def smbserver(options):
     """
     if options.pidfile:
         pid = os.getpid()
+        # see tests/server/util.c function write_pidfile
+        if os.name == "nt":
+            pid += 65536
         with open(options.pidfile, "w") as f:
-            f.write("{0}".format(pid))
+            f.write(str(pid))
 
     # Here we write a mini config for the server
     smb_config = configparser.ConfigParser()
@@ -263,7 +270,11 @@ class TestSmbServer(imp_smbserver.SMBSERVER):
 
         if requested_filename == VERIFIED_REQ:
             log.debug("[SMB] Verifying server is alive")
-            contents = VERIFIED_RSP.format(pid=os.getpid())
+            pid = os.getpid()
+            # see tests/server/util.c function write_pidfile
+            if os.name == "nt":
+                pid += 65536
+            contents = VERIFIED_RSP.format(pid=pid).encode('utf-8')
 
         self.write_to_fid(fid, contents)
         return fid, filename
@@ -284,7 +295,7 @@ class TestSmbServer(imp_smbserver.SMBSERVER):
                   filename, fid, requested_filename)
 
         try:
-            contents = self.ctd.get_test_data(requested_filename)
+            contents = 
self.ctd.get_test_data(requested_filename).encode('utf-8')
             self.write_to_fid(fid, contents)
             return fid, filename
 
diff --git a/tests/sshhelp.pm b/tests/sshhelp.pm
index e43f86532..cd7f58fc1 100644
--- a/tests/sshhelp.pm
+++ b/tests/sshhelp.pm
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/sshserver.pl b/tests/sshserver.pl
index 4414ca51b..1874b9388 100644
--- a/tests/sshserver.pl
+++ b/tests/sshserver.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -405,7 +405,7 @@ my $hstprvkeyf_config = abs_path("$path/$hstprvkeyf");
 my $pidfile_config = $pidfile;
 my $sftpsrv_config = $sftpsrv;
 
-if ($^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys') {
+if (pathhelp::os_is_win()) {
     # Ensure to use MinGW/Cygwin paths
     $clipubkeyf_config = pathhelp::build_sys_abs_path($clipubkeyf_config);
     $hstprvkeyf_config = pathhelp::build_sys_abs_path($hstprvkeyf_config);
@@ -535,7 +535,9 @@ push @cfgarr, '#';
 push @cfgarr, "AuthorizedKeysFile $clipubkeyf_config";
 push @cfgarr, "AuthorizedKeysFile2 $clipubkeyf_config";
 push @cfgarr, "HostKey $hstprvkeyf_config";
-push @cfgarr, "PidFile $pidfile_config";
+if ($sshdid !~ /OpenSSH-Windows/) {
+    push @cfgarr, "PidFile $pidfile_config";
+}
 push @cfgarr, '#';
 push @cfgarr, "Port $port";
 push @cfgarr, "ListenAddress $listenaddr";
@@ -797,7 +799,7 @@ if((! -e $knownhosts) || (! -s $knownhosts)) {
 my $identity_config = abs_path("$path/$identity");
 my $knownhosts_config = abs_path("$path/$knownhosts");
 
-if ($^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys') {
+if (pathhelp::os_is_win()) {
     # Ensure to use MinGW/Cygwin paths
     $identity_config = pathhelp::build_sys_abs_path($identity_config);
     $knownhosts_config = pathhelp::build_sys_abs_path($knownhosts_config);
@@ -1098,12 +1100,38 @@ if($error) {
 }
 @cfgarr = ();
 
+#***************************************************************************
+# Prepare command line of ssh server daemon
+#
+my $cmd = "\"$sshd\" -e -D -f $sshdconfig > $sshdlog 2>&1";
+logmsg "SCP/SFTP server listening on port $port" if($verbose);
+logmsg "RUN: $cmd" if($verbose);
+
+#***************************************************************************
+# Start the ssh server daemon on Windows without forking it
+#
+if ($sshdid =~ /OpenSSH-Windows/) {
+    # Fake pidfile for ssh server on Windows.
+    if(open(OUT, ">$pidfile")) {
+        print OUT $$ . "\n";
+        close(OUT);
+    }
+
+    # Put an "exec" in front of the command so that the child process
+    # keeps this child's process ID by being tied to the spawned shell.
+    exec("exec $cmd") || die "Can't exec() $cmd: $!";
+    # exec() will create a new process, but ties the existance of the
+    # new process to the parent waiting perl.exe and sh.exe processes.
+
+    # exec() should never return back here to this process. We protect
+    # ourselves by calling die() just in case something goes really bad.
+    die "error: exec() has returned";
+}
 
 #***************************************************************************
 # Start the ssh server daemon without forking it
 #
-logmsg "SCP/SFTP server listening on port $port" if($verbose);
-my $rc = system "\"$sshd\" -e -D -f $sshdconfig > $sshdlog 2>&1";
+my $rc = system($cmd);
 if($rc == -1) {
     logmsg "\"$sshd\" failed with: $!";
 }
diff --git a/tests/symbol-scan.pl b/tests/symbol-scan.pl
index c8d68147a..45c662fac 100755
--- a/tests/symbol-scan.pl
+++ b/tests/symbol-scan.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2010-2018, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2010 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/testcurl.pl b/tests/testcurl.pl
index 48f154ec2..5f2b7b168 100755
--- a/tests/testcurl.pl
+++ b/tests/testcurl.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/tftpserver.pl b/tests/tftpserver.pl
index c16a9e140..a7b9b39df 100755
--- a/tests/tftpserver.pl
+++ b/tests/tftpserver.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -43,8 +43,9 @@ my $port = 8997;     # just a default
 my $ipvnum = 4;      # default IP version of tftp server
 my $idnum = 1;       # default tftp server instance number
 my $proto = 'tftp';  # protocol the tftp server speaks
-my $pidfile;         # tftp server pid file
-my $logfile;         # tftp server log file
+my $pidfile;
+my $portfile;
+my $logfile;
 my $srcdir;
 my $fork;
 
@@ -59,6 +60,12 @@ while(@ARGV) {
             shift @ARGV;
         }
     }
+    elsif($ARGV[0] eq '--portfile') {
+        if($ARGV[1]) {
+            $portfile = $ARGV[1];
+            shift @ARGV;
+        }
+    }
     elsif($ARGV[0] eq '--logfile') {
         if($ARGV[1]) {
             $logfile = $ARGV[1];
@@ -108,7 +115,9 @@ if(!$logfile) {
     $logfile = server_logfilename($logdir, $proto, $ipvnum, $idnum);
 }
 
-$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
+$flags .= "--pidfile \"$pidfile\" ".
+    "--portfile \"$portfile\" ".
+    "--logfile \"$logfile\" ";
 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
 
 exec("server/tftpd".exe_ext('SRV')." $flags");
diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt
index e4e10c236..51a642f39 100644
--- a/tests/unit/CMakeLists.txt
+++ b/tests/unit/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 
 set(UT_SRC
   unit1300.c
diff --git a/tests/unit/curlcheck.h b/tests/unit/curlcheck.h
index ecc556533..016119a39 100644
--- a/tests/unit/curlcheck.h
+++ b/tests/unit/curlcheck.h
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/unit/unit1300.c b/tests/unit/unit1300.c
index 5d8799779..3e4c33ccc 100644
--- a/tests/unit/unit1300.c
+++ b/tests/unit/unit1300.c
@@ -75,7 +75,7 @@ UNITTEST_START
   fail_unless(llist.head == NULL, "list head should initiate to NULL");
   fail_unless(llist.tail == NULL, "list tail should intiate to NULL");
   fail_unless(llist.dtor == test_curl_llist_dtor,
-               "list dtor shold initiate to test_curl_llist_dtor");
+               "list dtor should initiate to test_curl_llist_dtor");
 
   /**
    * testing Curl_llist_insert_next
diff --git a/tests/unit/unit1302.c b/tests/unit/unit1302.c
index e6f94b24e..bd240d52c 100644
--- a/tests/unit/unit1302.c
+++ b/tests/unit/unit1302.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/unit/unit1330.c b/tests/unit/unit1330.c
index e6431bbba..c9f19ccc5 100644
--- a/tests/unit/unit1330.c
+++ b/tests/unit/unit1330.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/unit/unit1394.c b/tests/unit/unit1394.c
index 010f052ec..d6644f8eb 100644
--- a/tests/unit/unit1394.c
+++ b/tests/unit/unit1394.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -122,8 +122,10 @@ UNITTEST_START
         fail("assertion failure");
       }
     }
-    if(certname) free(certname);
-    if(passphrase) free(passphrase);
+    if(certname)
+      free(certname);
+    if(passphrase)
+      free(passphrase);
   }
 
 UNITTEST_STOP
diff --git a/tests/unit/unit1395.c b/tests/unit/unit1395.c
index 78fdfa021..b8440b477 100644
--- a/tests/unit/unit1395.c
+++ b/tests/unit/unit1395.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/unit/unit1600.c b/tests/unit/unit1600.c
index 190cf0f0a..4e774aabb 100644
--- a/tests/unit/unit1600.c
+++ b/tests/unit/unit1600.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/unit/unit1605.c b/tests/unit/unit1605.c
index 57a9199c5..0ec726a72 100644
--- a/tests/unit/unit1605.c
+++ b/tests/unit/unit1605.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/tests/unit/unit1650.c b/tests/unit/unit1650.c
index 35ac12c81..e656c073a 100644
--- a/tests/unit/unit1650.c
+++ b/tests/unit/unit1650.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2018 - 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -185,7 +185,7 @@ UNITTEST_START
     size_t len;
     int u;
     memset(&d, 0, sizeof(d));
-    rc = doh_decode((unsigned char *)resp[i].packet, resp[i].size,
+    rc = doh_decode((const unsigned char *)resp[i].packet, resp[i].size,
                     resp[i].type, &d);
     if(rc != resp[i].rc) {
       fprintf(stderr, "resp %zu: Expected return code %d got %d\n", i,
@@ -241,7 +241,7 @@ UNITTEST_START
       struct dohentry d;
       int rc;
       memset(&d, 0, sizeof(d));
-      rc = doh_decode((unsigned char *)full49, i, DNS_TYPE_A, &d);
+      rc = doh_decode((const unsigned char *)full49, i, DNS_TYPE_A, &d);
       if(!rc) {
         /* none of them should work */
         fprintf(stderr, "%zu: %d\n", i, rc);
@@ -253,7 +253,7 @@ UNITTEST_START
       struct dohentry d;
       int rc;
       memset(&d, 0, sizeof(d));
-      rc = doh_decode((unsigned char *)&full49[i], sizeof(full49)-i-1,
+      rc = doh_decode((const unsigned char *)&full49[i], sizeof(full49)-i-1,
                       DNS_TYPE_A, &d);
       if(!rc) {
         /* none of them should work */
@@ -266,7 +266,7 @@ UNITTEST_START
       struct dohentry d;
       struct dohaddr *a;
       memset(&d, 0, sizeof(d));
-      rc = doh_decode((unsigned char *)full49, sizeof(full49)-1,
+      rc = doh_decode((const unsigned char *)full49, sizeof(full49)-1,
                       DNS_TYPE_A, &d);
       fail_if(d.numaddr != 1, "missing address");
       a = &d.addr[0];
diff --git a/tests/unit/unit1655.c b/tests/unit/unit1655.c
index a06b23a76..1b910ed9f 100644
--- a/tests/unit/unit1655.c
+++ b/tests/unit/unit1655.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -75,6 +75,7 @@ do {
     "this.is.an.otherwise-valid.hostname."
     "with-a-label-of-greater-length-than-the-sixty-three-characters-"
     "specified.in.the.RFCs.";
+  int i;
 
   struct test {
     const char *name;
@@ -96,7 +97,7 @@ do {
     { max, DOH_OK }                      /* expect buffer overwrite */
   };
 
-  for(int i = 0; i < (int)(sizeof(playlist)/sizeof(*playlist)); i++) {
+  for(i = 0; i < (int)(sizeof(playlist)/sizeof(*playlist)); i++) {
     const char *name = playlist[i].name;
     size_t olen = 100000;
     struct demo victim;
diff --git a/tests/valgrind.pm b/tests/valgrind.pm
index 8b3d717d4..43163bf01 100644
--- a/tests/valgrind.pm
+++ b/tests/valgrind.pm
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
diff --git a/tests/extern-scan.pl b/tests/version-scan.pl
similarity index 55%
copy from tests/extern-scan.pl
copy to tests/version-scan.pl
index 1b22410f5..788ba0fa3 100755
--- a/tests/extern-scan.pl
+++ b/tests/version-scan.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2010-2015, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2010 - 2020, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -21,42 +21,46 @@
 #
 ###########################################################################
 #
+# Verify that curl_version_info.3 documents all the CURL_VERSION_ bits
+# from the header.
 #
 
 use strict;
 use warnings;
 
-# we may get the dir root pointed out
-my $root=$ARGV[0] || ".";
+my $manpage=$ARGV[0];
+my $header=$ARGV[1];
+my %manversion;
+my %headerversion;
+my $error;
 
-my @incs = (
-    "$root/include/gnurl/curl.h",
-    "$root/include/gnurl/easy.h",
-    "$root/include/gnurl/mprintf.h",
-    "$root/include/gnurl/multi.h",
-    );
-
-my $verbose=0;
-my $summary=0;
-my $misses=0;
-
-my @syms;
-my %doc;
-my %rem;
+open(M, "<$manpage");
+while(<M>) {
+    if($_ =~ /^.ip (CURL_VERSION_[A-Z0-9_]+)/i) {
+        $manversion{$1}++;
+    }
+}
+close(M);
 
-sub scanheader {
-    my ($f)=@_;
-    open H, "<$f" || die;
-    while(<H>) {
-        if (/^(CURL_EXTERN.*)/) {
-            my $decl = $1;
-            $decl =~ s/\r$//;
-            print "$decl\n";
-        }
+open(H, "<$header");
+while(<H>) {
+    if($_ =~ /^\#define (CURL_VERSION_[A-Z0-9_]+)/i) {
+        $headerversion{$1}++;
     }
-    close H;
 }
+close(H);
 
-foreach my $i (@incs) {
-    scanheader($i);
+for my $h (keys %headerversion) {
+    if(!$manversion{$h}) {
+        print STDERR "$manpage: missing $h\n";
+        $error++;
+    }
+}
+for my $h (keys %manversion) {
+    if(!$headerversion{$h}) {
+        print STDERR "$manpage: $h is not in the header!\n";
+        $error++;
+    }
 }
+
+exit $error;

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]