Initial commit

This commit is contained in:
Tux 2021-02-26 11:43:14 +01:00
commit b345ece059
85 changed files with 24730 additions and 0 deletions

12
.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
VisualStudio/
bin/
build/
buildroot-configs/
floppy/
hotbird64-mass-build/
lib/
src/VisualStudio-Linux-Remote/
*.vcxproj*
*.html
*.pdf
*.txt

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "debian"]
path = debian
url = https://github.com/Wind4/vlmcsd-debian.git
[submodule "docker"]
path = docker
url = https://github.com/Wind4/vlmcsd-docker.git

233
GNUmakefile Normal file
View File

@ -0,0 +1,233 @@
.NOTPARALLEL:
MAX_THREADS ?= 16
PROGRAM_NAME ?= bin/vlmcsd
CLIENT_NAME ?= bin/vlmcs
MULTI_NAME ?= bin/vlmcsdmulti
OBJ_NAME ?= build/libkms-static.o
A_NAME ?= lib/libkms.a
BASE_PROGRAM_NAME=$(notdir $(PROGRAM_NAME))
BASE_CLIENT_NAME=$(notdir $(CLIENT_NAME))
BASE_MULTI_NAME=$(notdir $(MULTI_NAME))
BASE_DLL_NAME=$(notdir $(DLL_NAME))
BASE_A_NAME=$(notdir $(A_NAME))
TARGETPLATFORM := $(shell LANG=en_US.UTF-8 $(CC) -v 2>&1 | grep '^Target: ' | cut -f 2 -d ' ')
ifneq (,$(findstring darwin,$(TARGETPLATFORM)))
DARWIN := 1
UNIX := 1
endif
ifneq (,$(findstring android,$(TARGETPLATFORM)))
ANDROID := 1
UNIX := 1
ELF := 1
endif
ifneq (,$(findstring minix,$(TARGETPLATFORM)))
MINIX := 1
UNIX := 1
ELF := 1
endif
ifneq (,$(findstring mingw,$(TARGETPLATFORM)))
MINGW := 1
WIN := 1
PE := 1
endif
ifneq (,$(findstring cygwin,$(TARGETPLATFORM)))
CYGWIN := 1
WIN := 1
PE := 1
endif
ifneq (,$(findstring cygnus,$(TARGETPLATFORM)))
CYGWIN := 1
WIN := 1
PE := 1
endif
ifneq (,$(findstring freebsd,$(TARGETPLATFORM)))
FREEBSD := 1
UNIX := 1
BSD := 1
ELF := 1
endif
ifneq (,$(findstring netbsd,$(TARGETPLATFORM)))
NETBSD := 1
UNIX := 1
BSD := 1
ELF := 1
endif
ifneq (,$(findstring openbsd,$(TARGETPLATFORM)))
OPENBSD := 1
UNIX := 1
BSD := 1
ELF := 1
endif
ifneq (,$(findstring solaris,$(TARGETPLATFORM)))
SOLARIS := 1
UNIX := 1
ELF := 1
endif
ifneq (,$(findstring linux,$(TARGETPLATFORM)))
LINUX := 1
UNIX := 1
ELF := 1
endif
ifneq (,$(findstring gnu,$(TARGETPLATFORM)))
ifeq (,$(findstring linux,$(TARGETPLATFORM)))
UNIX := 1
HURD := 1
ELF := 1
endif
endif
ifeq ($(CYGWIN),1)
DLL_NAME ?= lib/cygkms.dll
else ifeq ($(WIN),1)
DLL_NAME ?= lib/libkms.dll
else ifeq ($(DARWIN),1)
DLL_NAME ?= lib/libkms.dylib
else
DLL_NAME ?= lib/libkms.so
endif
.DEFAULT:
+@(test -d bin || mkdir bin) & (test -d lib || mkdir lib) & (test -d build || mkdir build)
+@$(MAKE) -j$(MAX_THREADS) -C src $@ FROM_PARENT=1 PROGRAM_NAME=$(PROGRAM_NAME) CLIENT_NAME=$(CLIENT_NAME) MULTI_NAME=$(MULTI_NAME) DLL_NAME=$(DLL_NAME) A_NAME=$(A_NAME)
all:
+@(test -d bin || mkdir bin) & (test -d lib || mkdir lib) & (test -d build || mkdir build)
+@$(MAKE) -j$(MAX_THREADS) -C src $@ FROM_PARENT=1 PROGRAM_NAME=$(PROGRAM_NAME) CLIENT_NAME=$(CLIENT_NAME) MULTI_NAME=$(MULTI_NAME) DLL_NAME=$(DLL_NAME) A_NAME=$(A_NAME)
clean:
+@$(MAKE) -j$(MAX_THREADS) -C src $@ FROM_PARENT=1 PROGRAM_NAME=$(PROGRAM_NAME) CLIENT_NAME=$(CLIENT_NAME) MULTI_NAME=$(MULTI_NAME) DLL_NAME=$(DLL_NAME) A_NAME=$(A_NAME)
+@$(MAKE) -j$(MAX_THREADS) -C man $@
alldocs:
+@$(MAKE) -j$(MAX_THREADS) -C man $@
dosdocs:
+@$(MAKE) -j$(MAX_THREADS) -C man $@
unixdocs:
+@$(MAKE) -j$(MAX_THREADS) -C man $@
htmldocs:
+@$(MAKE) -j$(MAX_THREADS) -C man $@
pdfdocs:
+@$(MAKE) -j$(MAX_THREADS) -C man $@
GNUmakefile:
help:
@echo "Type"
@echo " ${MAKE} - to build $(BASE_PROGRAM_NAME) and $(BASE_CLIENT_NAME)"
@echo " ${MAKE} clean - to remove all targets and temporary files"
@echo " ${MAKE} pdfdocs - Create PDF versions of the documentation (Requires groff with PDF support)."
@echo " ${MAKE} htmldocs - Create HTML versions of the documentation."
@echo " ${MAKE} unixdocs - Create Unix TXT versions of the documentation."
@echo " ${MAKE} dosdocs - Create DOS/Windows TXT versions of the documentation."
@echo " ${MAKE} alldocs - Create all versions of the documentation."
@echo " ${MAKE} vlmcsd - to build KMS server $(PROGRAM_NAME)"
@echo " ${MAKE} vlmcs - to build KMS client $(CLIENT_NAME)"
@echo " ${MAKE} vlmcsdmulti - to build $(BASE_PROGRAM_NAME) and $(BASE_CLIENT_NAME) in a single multi-call binary $(MULTI_NAME)"
@echo " ${MAKE} libkms - to build the shared library $(DLL_NAME)"
@echo " ${MAKE} libkms-static - to build the static library $(A_NAME)"
@echo ""
@echo "Options"
@echo " CONFIG=<x> Compile <x> as instead of config.h."
@echo " INI=<x> Compile $(BASE_PROGRAM_NAME) with default ini file <x>"
@echo " DATA=<x> Compile $(BASE_PROGRAM_NAME) and $(BASE_CLIENT_NAME) with default KMS data file <x>"
@echo " PROGRAM_NAME=<x> Use <x> as output file name for the KMS server. Defaults to vlmcsd."
@echo " CLIENT_NAME=<x> Use <x> as output file name for the KMS client. Defaults to vlmcs."
@echo " MULTI_NAME=<x> Use <x> as output file name for the multi-call binary. Defaults to vlmcsdmulti."
@echo " DEPENDENCIES=1 Create dependency files."
@echo " CRYPTO=openssl Use openssl for SHA256/HMAC calculations."
@echo " CRYPTO=openssl_with_aes EXPERIMENTAL: Use openssl for SHA256/HMAC and AES calculations (hardware, e.g. AES-NI on x86)."
@echo " CRYPTO=openssl_with_aes_soft EXPERIMENTAL: Use openssl for SHA256/HMAC and AES calculations (software)."
@echo " CRYPTO=polarssl Use polarssl instead of internal crypto code for SHA256/HMAC calculations."
@echo " CRYPTO=windows Use Windows CryptoAPI instead of internal crypto code for SHA256/HMAC calculations."
@echo " MSRPC=1 Use Microsoft RPC instead of vlmcsd's internal RPC. Only works with Windows and Cygwin targets."
@echo " CC=<x> Use compiler <x>. Supported compilers are gcc, icc, tcc and clang. Others may or may not work."
@echo " AR=<x> Use <x> instead of ar to build $(BASE_A_NAME). Set to gcc-ar if you want to use gcc's LTO feature."
@echo " COMPILER_LANGUAGE=<x> May be c or c++."
@echo " TERMINAL_WIDTH=<x> Assume a fixed terminal width of <x> columns. Use in case of problems only."
@echo " VLMCSD_VERSION=<x> Sets <x> as your version identifier. Defaults to \"private build\"."
@echo " CFLAGS=<x> Pass <x> as additional arguments to the compiler."
@echo " LDFLAGS=<x> Pass <x> as additional arguments to the linker."
@echo " PLATFORMFLAGS=<x> Pass <x> as additional arguments to the compiler and the linker."
@echo " BASECFLAGS=<x> Pass only <x> as arguments to the compiler (advanced users only)."
@echo " BASELDFLAGS=<x> Pass only <x> as arguments to the linker (advanced users only)."
@echo " STRIP=0 Don't strip debug information from $(BASE_PROGRAM_NAME) and $(BASE_CLIENT_NAME) (for developers)."
@echo " VERBOSE=1 Be verbose when making targets."
@echo " VERBOSE=3 Show name of compiler."
@echo " THREADS=1 Use threads instead of fork(). Automatically set for native Windows. Recommended for Cygwin."
@echo " HWID=<x> Use <x> as the default HWID (when it can't be found in an ini file)."
@echo " FEATURES=full Compile $(BASE_PROGRAM_NAME) with all features (default)."
@echo " FEATURES=most Compile $(BASE_PROGRAM_NAME) without rarely used features."
@echo " FEATURES=embedded Compile $(BASE_PROGRAM_NAME) with typical features for embedded systems."
@echo " FEATURES=autostart Removes features typically not needed if you place $(BASE_PROGRAM_NAME) in an autostart script."
@echo " FEATURES=inetd Compile $(BASE_PROGRAM_NAME) for running through an internet superserver only."
@echo " FEATURES=minimum Compiles only basic features of $(BASE_PROGRAM_NAME)."
@echo " FEATURES=fixedepids $(BASE_PROGRAM_NAME) only uses bultin internal ePIDs."
@echo ""
@echo "Useful CFLAGS to save memory when running $(BASE_PROGRAM_NAME) on very small embedded devices (finer control than FEATURES=)"
@echo " -DNO_STRICT_MODES Don't support enhanced emulator detection prevention."
@echo " -DNO_CLIENT_LIST Don't support maintaining a client list (CMIDs)."
@echo " -DNO_VERBOSE_LOG Don't support verbose logging. Removes -v option."
@echo " -DNO_LOG Don't add support for logging. Implies -DNO_VERBOSE_LOG."
@echo " -DNO_RANDOM_EPID Don't support random ePIDs."
@echo " -DNO_INI_FILE Don't support reading ePIDs/HWIDs from a file."
@echo " -DNO_PID_FILE Don't support writing a PID file. Removes -p option."
@echo " -DNO_USER_SWITCH Don't support changing uid/gid after program start. Removes -u and -g options."
@echo " -DNO_HELP Don't support command line help."
@echo " -DNO_CUSTOM_INTERVALS Don't support custom intervals for retry and refresh activation. Removes -A and -R options."
@echo " -DNO_FREEBIND Don't support binding to foreign IP addresses. Removes -F0 and -F1 options. Only affects FreeBSD and Linux."
@echo " -DNO_SOCKETS Don't support standalone operation. Requires an internet superserver to start $(BASE_PROGRAM_NAME)."
@echo " -DSIMPLE_SOCKETS Compile $(BASE_PROGRAM_NAME) with basic socket support only. Removes -L option."
@echo " -DSIMPLE_RPC Don't support RPC with NDR64 and BTFN in $(BASE_PROGRAM_NAME) (but do in $(BASE_CLIENT_NAME)). Makes emulator detection easy."
@echo " -DNO_TAP Compile $(BASE_PROGRAM_NAME) without VPN support (Windows and Cygwin only)."
@echo " -DNO_CL_PIDS Don't support specifying ePIDs and HwId from the command line in $(BASE_PROGRAM_NAME)."
@echo " -DNO_LIMIT Don't support limiting concurrent clients in $(BASE_PROGRAM_NAME)."
@echo " -DNO_SIGHUP Don't support SIGHUP handling in $(BASE_PROGRAM_NAME)."
@echo " -DNO_VERSION_INFORMATION Don't support displaying version information in $(BASE_PROGRAM_NAME) and $(BASE_CLIENT_NAME). Removes -V option."
@echo " -DNO_PRIVATE_IP_DETECT Don't support protection against clients with public IP addresses in $(BASE_PROGRAM_NAME)"
@echo " -DSMALL_AES Use a smaller (saves about 200 bytes) but slower implementation of AES."
@echo " -DNO_EXTERNAL_DATA Don't support loading an external database. Mutually exclusive with -DNO_INTERNAL_DATA"
@echo " -DNO_INTERNAL_DATA Don't compile an internal database. Mutually exclusive with -DNO_EXTERNAL_DATA"
@echo " -DUNSAFE_DATA_LOAD Don't check the KMS data file for integrity. Saves some bytes but is dangerous."
@echo ""
@echo "Troubleshooting options"
@echo " CAT=1 Combine all sources in a single in-memory file and compile directly to target."
@echo " NOPROCFS=1 Don't rely on a properly mounted proc filesystem in /proc."
@echo " AUXV=1 Use /proc/self/auxv (requires Linux with glibc >= 2.16 or musl.)"
@echo " NOLPTHREAD=1 Disable detection if -lpthread is required (for use with Android NDK)."
@echo " NOLRESOLV=1 Disable detection if -lresolv is required (for use with Android NDK)."
@echo " NOLIBS=1 Do not attempt to autodetect any library dependencies."
@echo " OPENSSL_HMAC=0 Compile for openssl versions that don't have HMAC support (required on some embedded devices)."
@echo " NO_TIMEOUT=1 Do not set timeouts for sockets (for systems that don't support it)."
@echo " CHILD_HANDLER=1 Install a handler for SIGCHLD (for systems that don't support SA_NOCLDWAIT)."
@echo " NO_DNS=1 Compile $(BASE_CLIENT_NAME) without support for detecting KMS servers via DNS."
@echo " NO_GETIFADDRS=1 Compile $(BASE_PROGRAM_NAME) without using getifaddrs()."
@echo " GETIFADDRS=musl Compile $(BASE_PROGRAM_NAME) with its own implementation of getifaddrs() based on musl."
@echo " DNS_PARSER=internal Use $(BASE_CLIENT_NAME) internal DNS parsing routines. No effect on MingW (native Windows)."
@echo ""
@echo "Other useful CFLAGS"
@echo " -DNO_COMPILER_UAA Do not use compiler support for byte swapping and unaligned access"
@echo " -DFULL_INTERNAL_DATA Embed full internal KMS data in $(BASE_PROGRAM_NAME)."
@echo " -DSUPPORT_WINE Add code that the Windows version of $(BASE_PROGRAM_NAME) runs on Wine if MSRPC=1"
@echo " -D_PEDANTIC Report rare error/warning conditions instead of silently ignoring them."
@echo " -DFD_SETSIZE=<x> Allow <x> -L statements in $(BASE_PROGRAM_NAME) (default: 64 on Windows, 1024 on most Unixes)."

7
Makefile Normal file
View File

@ -0,0 +1,7 @@
# Let BSD make switch to GNU make
all ${.TARGETS}:
@echo "================================================================"
@echo " PLEASE USE THE GNU VERSION OF MAKE (gmake) INSTEAD OF ${MAKE} "
@echo "================================================================"
@echo ""
@gmake $@

14
README Normal file
View File

@ -0,0 +1,14 @@
To view the documentation cd to the directory containing the distribution
files and type
man man/vlmcsd.8
to see documentation for vlmcsd
man man/vlmcs.1
to see documentation for vlmcs
man man/vlmcsd.7
to see general documentation for kms
If you don't have man, you may also use the .txt, .html and .pdf files
in the man directory

View File

@ -0,0 +1,110 @@
Compilation and pre-built binaries FAQ
======================================
What is the best pre-built binary for my system or device?
----------------------------------------------------------
None. The best binary is compiled by yourself using a toolchain that is
optimized for your system or device in every respect.
How do I compile my own binary?
-------------------------------
On a full blown desktop system this is relativly easy. If not already done so,
install a C compiler (e.g. gcc or clang) through your packet manager, e.g.
"sudo apt-get install gcc" (Debian/Ubuntu) or "sudo yum install gcc"
(RedHat/Fedora).
Then cd to your vlmcsd directory and type "make". vlmcs and vlmcsd will
be built right away for your local system.
If you installed gcc and it is not the default compiler for your OS or
distribution, you may need to type "make CC=gcc" to explicitly select a
specific C compiller.
How do I compile a binary for my embedded device?
-------------------------------------------------
What you need is cross-compiling toolchain for your device. It consists of a
C compiler, libraries, header files and some tools (called binutils). The
toolchain must match the device in processor architecture, endianess, ABI,
library and header files version, library configuration, ...
If the endianess or ABI differs or the version of some library between
toolchain and device differs too much, the resulting binary does not run
on your device.
Once you have a proper toolchain (probably found on the Internet for download),
unpack it to any directory and type
"make CC=/path/to/toolchain/bindir/c-compiler-binary"
Building vlmcsd for using a cross-compiling toolchain is as easy as building
vlmcsd for your local machine. The only question is, whether this you have
a toolchain that actually matches your device.
Whenever you change any parameter of the make command line, you must "clean"
the source directory from intermediate files and output from previous runs
of make. You can do so by typeing "make clean" or force make to behave as if
the directory were clean by adding -B to the command line, e.g.
"make -B CC=/path/to/toolchain/bindir/c-compiler-binary"
I have downloaded several promising toolchains for my device but they all
don't work. Can I create my own toolchain?
-------------------------------------------------------------------------
You can use tools like buildroot or OpenWRT. Both are able to create toolchains
for many embedded devices. But this is out of the scope of this document.
If you are unable to walk through thousands of configuration options and make
the right choice, you may probably want to try the pre-built binaries.
How to choose a pre-built binary?
---------------------------------
The directory structure for the binaries is
binaries
+
+--<operating system>
+
+--<cpu arch>
+
+--<endianess> (omitted if CPU or OS does not allow multi-endianess)
+
+--<C-library>
<C-library> can also be "static". That means no special library is required.
Static binaries are much bigger and need more RAM than dynamic binaries but
are more likely to run on your system. Use a static binary only, if none of
the dynmic binaries run.
Don't get confused when a binary is named after an OS or a specific device,
e.g. the name contains "openwrt", "tomato" or "Fritzbox". This does not mean
that the binary will run only on that OS or on that device. It is a hint only
where I got or built the toolchain from.
How to determine the endianess of my system?
--------------------------------------------
- All Intel CPUs (x86, x32, x64) are little-endian only
- Windows is little-endian only even if the CPU support big-endian
- big-endian ARM is extremely uncommon. You can safely assume little-endian
- little-endian PowerPC virtually does not exist since only newer POWER7
and POWER8 CPUs support it. Always assume big-endian.
- For MIPS both little-endian and big-endian are common. Most Broadcomm and
TI chips run little-endian. Most Atheros and Ikanos CPUs run big-endian.
Try typing
echo -n I | od -o | awk 'FNR==1{ print substr($2,6,1)}'
This returns 1 for little-endian systems and 0 for big-endian systems. However
some devices do not have the od command and thus this method won't work.

55
README.openssl Normal file
View File

@ -0,0 +1,55 @@
IMPORTANT
=========
1. Do not use any of the OpenSSL binaries
2. Do not compile OpenSSL binaries yourself
(except for doing some research into the deep internals of OpenSSL)
REASONS
=======
All OpenSSL binaries included are highly experimental and are likely to fail
in many cases. To get some real benefit from OpenSSL (or PolarSSL) it should
handle all crypting/hashing.
However this is not possible because Microsoft has slightly altered AES
encryption in KMSv6 and uses a non-AES variant of the Rijndael CMAC in
KMSv4. OpenSSL is not able to handle this if you use it correctly.
This means OpenSSL can be used safely only for SHA256 and HMAC SHA256
calculations used in KMSv5 and KMSv6 but the code size benefit is only
100 to 300 bytes (depending on the architecture).
To benefit more from OpenSSL (getting it performing the AES stuff) I do
the first phase of AES encryption/decryption (called key expansion) with my
own code. I then poke the expanded key into internal OpenSSL structs to make
it behave in a way not intended by the OpenSSL developers but in a way to
perform non-standard AES crypting as required by KMSv4 and KMSv6. KMSv5 is
the only protocol that could use OpenSSL without hacking the OpenSSL internals.
That means vlmcsd still needs about 40% of the internal AES code plus some
OpenSSL hacking code to poke the expanded key into OpenSSL.
The entire OpenSSL hacking does not work in every case because the internal
OpenSSL structs differ depending on the OpenSSL version, OpenSSL configuration
at compile time (whether it is configured to use compiled C code or assembler
code), CPU architecture and CPU features (whether it can perform AES in
hardware).
SUMMARY
=======
If you use OpenSSL in a safe way (compile with CRYPTO=openssl), there is not
much benefit from it. The binary may become bigger or smaller and you
definitely need more RAM when you run vlmcsd or vlmcs.
If you use hacked OpenSSL (compile with CRYPTO=openssl_with_aes or
CRYPTO=openssl_with_aes_soft) you risk malfunction of vlmcs/vlmcsd even if it
performed correctly several times before.
Both vlmcs and vlmcsd do not have more features when compiled with OpenSSL
support. It may be faster (especially on CPUs with hardware assisted AES) but
uses more memory and may fail or perform unreliably.

149
etc/vlmcsd.ini Normal file
View File

@ -0,0 +1,149 @@
#
#
# Sample vlmcsd.ini
#
# An ini file for vlmcsd is normally not required. It is for advanced users only.
# vlmcsd uses an ini file only if specified using the -i option in the command line parameters.
# There is no default ini file because vlmcsd is designed to run on many platforms.
#
# Every line starting with a number sign (#) or semicolon (;) is treated as a comment.
# If a key word is used more than once, the last occurrence is used. The only exception
# to this is Listen. You can use Listen=<ip address>[:port] more than once.
#
# Set ePID/HwId for Windows explicitly
;Windows = 06401-00206-471-111111-03-1033-17763.0000-2822018 / 01 02 03 04 05 06 07 08
# Set ePID for Office 2010 (including Visio and Project) explicitly
;Office2010 = 06401-00096-199-222222-03-1033-17763.0000-2822018
# Set ePID/HwId for Office 2013 (including Visio and Project) explicitly
;Office2013 = 06401-00206-234-333333-03-1033-17763.0000-2822018 / 01 02 03 04 05 06 07 08
# Set ePID/HwId for Office 2016 (including Visio and Project) explicitly
;Office2016 = 06401-00206-437-444444-03-1033-17763.0000-2822018 / 01 02 03 04 05 06 07 08
# Set ePID/HwId for Office 2019 (including Visio and Project) explicitly
;Office2019 = 06401-00206-666-666666-03-1033-17763.0000-2822018 / 01 02 03 04 05 06 07 08
# Set ePID/HwId for Windows China Government (Enterprise G/GN) explicitly
;WinChinaGov = 06401-03858-000-555555-03-1033-17763.0000-2822018 / 01 02 03 04 05 06 07 08
# Use a compatible VPN device to create a hidden local IPv4 address
# Command line: -O
# VPN = <VPN adapter name>[=<IPv4 address>][/<CIDR mask>][:<DHCP lease duration>]
# Use VPN adapter "KMS Mirror" give it IP address 192.168.123.100 with a lease duration of one day and make entire 192.168.128.x a hidden local IPv4 address.
;VPN = KMS Mirror=192.168.123.100/24:1d
# Use custom TCP port
# Command line: -P
# ***The Port directive only works if vlmcsd was compiled to use MS RPC or simple sockets
# ***Use Listen otherwise
;Port = 1234
# Listen on all IPv4 addresses (default port 1688)
# Command line: -L
# Does not work with MS RPC or simple sockets, use Port=
;Listen = 0.0.0.0:1688
# Listen on all IPv6 addresses (default port 1688)
# Command line: -L
;Listen = [::]:1688
# Listen on all private IP addresses and reject incoming requests from public IP addresses
# Command line: -o
# PublicIPProtectionLevel = 3
# Allow binding to foreign IP addresses
# Command line: -F0 and -F1
;FreeBind = true
# Randomize ePIDs at program start up (only those that are not explicitly specified)
# Command line: -r
;RandomizationLevel = 1
# Use a specific host build in ePIDs even if the ePID is randomized
# Command line: -H
;HostBuild = 17763
# Use a specific culture (1033 = English US) in ePIDs even if the ePID is randomized
# Command line: -C
;LCID = 1033
# Set a maximum of 4 workers (forked processes or threads)
# Command line: -m
;MaxWorkers = 4
# Disconnect users after 30 seconds of inactivity
# Command line: -t
;ConnectionTimeout = 30
# Disconnect clients immediately after each request
# Command line: -d and -k
;DisconnectClientsImmediately = yes
# Write a pid file (a file containing the process id of vlmcsd)
# Command line: -p
;PidFile = /var/run/vlmcsd.pid
# Load a KMS data file
# Command line: -j
;KmsData = /etc/vlmcsd.kmd
# Write log to /var/log/vlmcsd.log
# Command line: -l (-e and -f also override this directive)
;LogFile = /var/log/vlmcsd.log
# Don't include date and time in logs (default is true)
# Command line: -T0 and -T1
;LogDateAndTime = false
# Create a verbose log
# Command line: -v and -q
;LogVerbose = true
# Whitelist known products
# Command line: -K0, -K1, -K2, -K3
;WhiteListingLevel = 0
# Check that the client time is within +/- 4 hours of the system time
# Command line: -c0, -c1
;CheckClientTime = false
# Maintain a list of CMIDs
# Command line: -M0, -M1
;MaintainClients = false
# Start with empty CMID list (Requires MaintainClients = true)
# Command line: -E0, -E1
;StartEmpty = false
# Set activation interval to 2 hours
# Command line: -A
;ActivationInterval = 2h
# Set renewal interval to 7 days
# Command line: -R
;RenewalInterval = 7d
# Exit vlmcsd if warning of certain level has been reached
# Command line: -x
# 0 = Never
# 1 = Exit, if any listening socket could not be established or TAP error occurs
;ExitLevel = 0
# Run program as user vlmcsduser
# Command line: -u
;user = vlmcsduser
# Run program as group vlmcsdgroup
# Command line: -g
;group = vlmcsdgroup
# Disable or enable the NDR64 transfer syntax in RPC (default enabled)
# Command line: -N0 and -N1
;UseNDR64 = true
# Disable or enable bind time feature negotiation in RPC (default enabled)
# Command line: -B0 and -B1
;UseBTFN = true

BIN
etc/vlmcsd.kmd Normal file

Binary file not shown.

44
man/GNUmakefile Normal file
View File

@ -0,0 +1,44 @@
################################################################################
.PHONY: clean
PDFDOCS = vlmcs.1.pdf vlmcsd.7.pdf vlmcsd.8.pdf vlmcsdmulti.1.pdf vlmcsd.ini.5.pdf vlmcsd-floppy.7.pdf
HTMLDOCS = $(PDFDOCS:.pdf=.html)
UNIXDOCS = $(PDFDOCS:.pdf=.unix.txt)
DOSDOCS = $(PDFDOCS:.pdf=.dos.txt)
%.pdf : %
ifeq ($(shell uname), Darwin)
groff -Tps -mandoc -c $< | pstopdf -i -o $@
else
groff -Tpdf -mandoc -c $< > $@
endif
%.html : %
groff -Thtml -mandoc -c $< > $@
%.unix.txt : %
groff -P -c -Tascii -mandoc -c $< | col -bx > $@
%.dos.txt : %.unix.txt
# unix2dos -n $< $@
# sed -e 's/$$/\r/' $< > $@
awk 'sub("$$", "\r")' $< > $@
alldocs : $(UNIXDOCS) $(HTMLDOCS) $(PDFDOCS) $(DOSDOCS)
pdfdocs : $(PDFDOCS)
dosdocs : $(DOSDOCS)
unixdocs : $(UNIXDOCS)
htmldocs : $(HTMLDOCS)
clean:
rm -f $(PDFDOCS) $(DOSDOCS) $(UNIXDOCS) $(HTMLDOCS)
help:
@echo "Help is available by typing 'make help' in directory $(shell realpath `pwd`/..). Use 'cd ..' to get there."

263
man/vlmcs.1 Normal file
View File

@ -0,0 +1,263 @@
.mso www.tmac
.TH VLMCS 1 "November 2016" "Hotbird64" "KMS Activation Manual"
.LO 1
.SH NAME
vlmcs \- a client for testing and/or charging KMS servers
.SH SYNOPSIS
\fBvlmcs\fR [ \fIoptions\fR ] [ \fItarget\fR ] [ \fIoptions\fR ]
.PP
\fItarget\fR can be one of the following:
.RS
.PP
\fIhostname\fR|\fIipaddress\fR[:\fItcp-port\fR] to query a specific KMS server (example: vlmcs kms.example.com:1688).
.br
\fR.\fIdomain\fR to automatically detect KMS servers via DNS for \fIdomain\fR (example: vlmcs .example.com). Please note the dot before \fIdomain\fR.
.br
\fI-\fR (a single dash) to detect KMS servers in your own domain.
.RE
If you use \fIipaddress\fR:\fIport\fR as the \fItarget\fR, the \fIipaddress\fR must be enclosed in brackets
if it contains colons, e.g. [2001:db8:dead:beef::1]:1688. If you use a link-local IPv6 address on Unix systems, you must append a percent sign and the
interface identifier of the source interface, for example fe80::dead:beef%eth0.
.PP
If you omit the \fItarget\fR, 127.0.0.1:1688 will be used except if you use \fB-i6\fR. In this case the default target is [::1]:1688.
.SH DESCRIPTION
\fBvlmcs\fR is a program that can be used to test a KMS server that provides activation for
several Microsoft products. The KMS server may also be an emulator. It supports
KMS protocol versions 4, 5 and 6.
.PP
.B vlmcs
generates one or more activation requests for a Microsoft KMS product and sends
it to a KMS server. It then analyzes and displays the responses of the KMS server.
.PP
.B vlcms
checks both the DCE-RPC protocol and the activation message for correctness and
reports any errors that it finds.
.PP
.B vlmcs
can also be used to "charge" a KMS server. A Microsoft KMS server sends correct activation messages only if it detects a certain minimum of clients (25 for Windows client OSses, 5 otherwise) on the network. This is Microsoft's futile attempt to prevent running a KMS server in a home environment.
.SH OPTIONS
.IP "\fB-h\fR or \fB-?"
Show help.
.IP "\fB-V\fR"
Displays extended version information. This includes the compiler used to build vlmcs, the intended platform and flags (compile time options) to build vlmcs. If you have the source code of vlmcsd, you can type \fBmake help\fR (or \fBgmake help\fR on systems that do not use the GNU version of \fBmake\fR(1) by default) to see the meaning of those flags.
.IP \fB-x
Show valid
.IR application s
that can be used with
.BR "-l" "."
.IP \fB-e
Show some examples how to use vlmcs correctly.
.IP \fB-v
Be verbose. Instead of just displaying the returned ePID and the HwId
(protocol v6 only) vlmcsd shows all details of the query and the response.
.IP "\fB-l\fR \fIapplication"
Request activation for a specific
.IR "application" "."
Valid applications can be displayed by using
.BR "-x" "."
The default
.IR application " is"
.IR "Windows Vista Business" "."
The list of available applications is not complete. You may
supply GUIDs with
.BR "-a" ", " "-k" " and " "-s"
to specify applications that are not listed with \fB-x\fR. The
.B -l
option is used as a shortcut for the most common applications.
.IP "\fB-K\fR \fIprotocol-version\fR"
Force a specific version of the KMS protocol. Valid versions are 4.0, 5.0 and 6.0. The default is to select a suitable version according to the \fIapplication\fR selected. You may use \fB-K\fR to send an incorrect protocol version to the KMS server and see how it behaves. Genuine KMS servers return HRESULT 0x8007000D if the KMS protocol is not 4.0, 5.0 or 6.0. Emulators should do the same. When sending a request with an incorrect protocol number, vlmcs ignores the minor protocol number (e.g. sends a v4 request for version 4.1). If the major version number is less then 4, it sends a v4 request. If the major version is greater then 6, it sends a v6 request. In any case the \fIprotocol-version\fR as specified by \fB-K\fR is put in the version fields of the request.
.IP "\fB-4\fR, \fB-5\fR and \fB-6"
Force version 4, 5 or 6 of the KMS protocol. These options are actually shortcuts of \fB-K 4.0\fR, \fB-K 5.0\fR and \fB-K 6.0\fR.
.IP "\fB-j\fR \fIfilename\fR"
Use KMS data file \fIfilename\fR. By default vlmcs contains product data that is recent when vlmcs was compiled. You may use a more recent KMS data file that contains additional products.
If vlmcsd has been compiled to use a default KMS data file, you may use \fB-j-\fR to ignore the default configuration file.
.IP "\fB-m"
Let the client pretend to be a virtual machine. Early versions of Microsoft's
KMS server did not increase the client count if the request came from a virtual
machine. Newer versions ignore this flag.
.IP "\fB-d"
Use NetBIOS names instead of DNS names. By default vlmcsd generates some random
DNS names for each request. If you prefer NetBIOS names, you may use
.IR "\fB-d" "."
A real Microsoft activation client uses DNS names or NetBIOS depending on the
client name configuration. KMS servers treat the workstation name as a comment
that affects logging only. Clients will be identified by a GUID that can
be specified using \fB-c\fR. \fB-d\fR has no effect if you also specify \fB-w\fR.
.IP "\fB-a\fR \fIapplication-guid"
Send requests with a specific
.IR "application-guid" "."
There are currently only three known valid
.IR "application-guid" "s:"
.IP
55c92734-d682-4d71-983e-d6ec3f16059f (Windows)
.br
59a52881-a989-479d-af46-f275c6370663 (Office 2010)
.br
0ff1ce15-a989-479d-af46-f275c6370663 (Office 2013)
.IP
A Microsoft KMS server uses these GUIDs to have seperate counters for the
already activated clients. A client that does not contact the KMS server
within 30 days will be deleted from the database. Emulated KMS servers
are always fully charged.
.IP "\fB-k\fR \fIkms-guid\fR"
Send requests with a specific
.IR "kms-guid" "."
A Microsoft KMS server uses these GUIDs as a product id to decide whether to
grant activation or not. A list of current \fIkms-guid\fRs can be found in
kms.c (table KmsIdList). Emulated KMS servers grant activation unconditionally
and do not check the \fIkms-guid\fR.
.IP "\fB-s\fR \fIactivation-guid\fR"
The \fIactivation-guid\fR defines the actual product, e.g. "Windows 8.1 Professional WMC KMSCLIENT edition". A \fIactivation-guid\fR maps 1:1 to a product key.
However, neither a Microsoft KMS server nor emulated servers check this id.
The \fIactivation-guid\fR is useful in logging to get a specific product description like
"Windows 8.1 Professional WMC". A list of current \fIactivation-guid\fRs can be found in
kms.c (table ExtendedProductList).
.IP "\fB-n\fR \fIrequests"
Send
.I requests
requests to the server. The default is to send at least one request and enough
subsequent requests that the server is fully charged afterwards for
the \fIapplication\-guid\fR you selected (explicitly with
.BR "-a" " or implicitly by using " "-l" ")."
.IP "\fB-T"
Causes to use a new TCP connection for each request if multiple requests
are sent with vlmcsd. This is useful when you want to test an emulated KMS
server whether it suffers from memory leaks. To test for memory leaks use
.B -n
with a large number of requests (> 100000) and then test twice (with and
without
.BR "-T" ")."
This option may become neccessary for future versions of Microsoft's KMS
server because multiple requests with different
.IR clients-guid s
for the same
.I kms-id-guid
are impossible in a real KMS szenario over the same TCP connection.
.IP "\fB-c\fR \fIclient-machine-guid\fR"
Normally vlmcs generates a random \fIclient-machine-guid\fR for each request. By using this option you can specify a fixed \fIclient-machine-guid\fR
This causes a Microsoft KMS not to increment its client count because it
receives multiple requests for the same client. Thus do not use
.BR "-c"
if you want to charge a real KMS server.
.IP "\fB-o\fR \fIprevious-client-machine-guid\fR"
If the \fIclient-machine-guid\fR changes for some reason, the real KMS client stores a \fIprevious-client-machine-guid\fR which is sent
to the KMS server. This happens rarely and usually 00000000-0000-0000-0000-000000000000 is used. You can use \fB-o\fR to specify a different
\fIprevious-client-machine-guid\fR.
.IP "\fB-G\fR \fIfilename\fR"
Grabs ePIDs and HWIDs from a KMS server and writes the information to \fIfilename\fR
in format suitable to be used as a configuration file (aka ini file) for \fBvlmcsd\fR(8).
This is especially useful if you have access to a genuine KMS server and want to use
the same data with \fBvlmcsd\fR(8).
If \fIfilename\fR does not exist, it will be created.
If you specify an existing \fIfilename\fR, it will be updated to use the information
received from the remote KMS server and a backup \fIfilename\fR~ will be created.
\fB-G\fR cannot be used with \fB-l\fR, \fB-4\fR, \fB-5\fR, \fB-6\fR, \fB-a\fR, \fB-s\fR, \fB-k\fR, \fB-r\fR and \fB-n\fR
.IP "\fB-w\fR \fIworkstation-name"
Send requests with a specific
.IR "workstation-name" "."
This disables the random generator for the workstation name. Since it is
a comment only, this option does not have much effect.
.IP "\fB-r\fR \fIrequired-client-count"
Also known as the "N count policy". Tells the KMS server that successful activation requires
\fIrequired-client-count\fR clients. The default is the
\fIrequired-client-count\fR that the product would need if the request
was a real activation. A Microsoft KMS server counts clients
up to the double amount what was specified with \fB-r\fR. This option
can be used to "overcharge" a Microsoft KMS server.
.IP "\fB\-t\ \fIstatus\fR"
Reports a specific license status to the KMS server. \fIstatus\fR is a number
that can be from 0 to 6. 0=unlicensed, 1=licensed, 2=OOB grace, 3=OOT grace,
4=Non-genuinue grace, 5=notification, 6=extended grace. Refer to
.URL "http://technet.microsoft.com/en-us/library/ff686879.aspx#_Toc257201371" "TechNet" ""
for more information. A Microsoft KMS server collects this information for
statistics only.
.IP "\fB-g\fR \fIbinding-expiration\fR"
This tells the KMS server how long a client will stay in its current license
status. This can be the remaining OOB time (the grace peroid that is granted between installation of a product and when activation is actuall required) or
the remaining time when KMS activation must be renewed.
\fIbinding-expiration\fR is specified in minutes. A Microsoft KMS server
apparantly does not use this information.
.IP "\fB-i \fIprotocol-version\fR"
Force the use of Internet protocol \fIprotocol-version\fR. Allowed values are 4 (IPv4) and 6 (IPv6). This option is useful only if you specfiy a \fIhostname\fR and not an
\fIip-address\fR on the command line.
.IP "\fB-p\fR"
Do not set the RPC_PF_MULTIPLEX flag in the RPC bind request. This can be used to test if the KMS server uses the same setting of this flag in the RPC bind respone. Some KMS
emulators don't set this correctly.
.IP "\fB-N0\fR and \fB-N1\fR"
Disables (\fB-N0\fR) or enables (\fB-N1\fR) the NDR64 transfer syntax in the RPC protocol. Disable NDR64 only in case of problems. If NDR64 is not used, vlmcs cannot detect many RPC protocol errors in KMS emulators. If you want to test whether a KMS emulator fully supports NDR64, you must use the \fB-n\fR option to send at least two requests. This is because Microsoft's client always sends the first request using NDR32 syntax and subsequent requests using NDR64 syntax.
.IP "\fB-B0\fR and \fB-B1\fR"
Disables (\fB-B0\fR) or enables (\fB-B1\fR) bind time feature negotiation (BTFN) in the RPC protocol. Disable BTFN only in case of problems. If BTFN is not used, vlmcs cannot detect many RPC protocol errors in KMS emulators.
.PP
Options that do not require an argument can be specified together with a single
dash, e.g. vlmcs -6mvT. If you specify an option more than once, the last occurence
will be in effect.
.SH FILES
.IP "\fBvlmcsd.ini\fR(5)"
.SH EXAMPLES
.IP "\fBvlmcs kms.example.com"
Request activation for Windows Vista using v4 protocol from kms.example.com.
Repeat activation requests until server is charged for all Windows products.
.IP "\fBvlmcs -"
Request activation for Windows Vista using v4 protocol from a KMS server that is published via DNS for the current domain.
.IP "\fBvlmcs .example.com"
Request activation for Windows Vista using v4 protocol from a KMS server that is published via DNS for domain example.com.
.IP "\fBvlmcs -6 -l Office2013 -v -n 1"
Request exactly one activation for Office2013 using v6 protocol from
localhost. Display verbose results.
.IP "\fBvlmcs kms.bigcompany.com -G /etc/vlmcsd.ini"
Get ePIDs and HWIDs from kms.bigcompany.com and create/update /etc/vlmcsd.ini accordingly.
.SH BUGS
Some platforms (e.g. Solaris) may have a \fBman\fR(7) system that does not handle URLs. URLs may be omitted in the documentation on those platforms. Cygwin, Linux, FreeBSD and Mac OS X are known to work correctly.
.SH AUTHOR
Written by Hotbird64
.SH CREDITS
Thanks to CODYQX4, crony12, deagles, DougQaid, eIcn, mikmik38, nosferati87, qad, Ratiborus, vityan666, ...
.SH SEE ALSO
\fBvlmcsd\fR(7), \fBvlmcsd\fR(8), \fBvlmcsdmulti\fR(1)

304
man/vlmcsd-floppy.7 Normal file
View File

@ -0,0 +1,304 @@
.mso www.tmac
.TH "VLMCSD-FLOPPY" 7 "February 2019" "Hotbird64" "KMS Activation Manual"
.LO 8
.SH NAME
floppy144.vfd \- a bootable floppy disk with Linux and \fBvlmcsd\fR(8)
.SH DESCRIPTION
\fBfloppy144.vfd\fR is an image of a bootable floppy that contains a minimal version of Linux and \fBvlmcsd\fR(8). It requires only 16 MB of RAM. Its primary purpose is to run \fBvlmcsd\fR(8) in a small virtual machine which makes it easy to use \fBvlmcsd\fR(8) to activate the virtual machine's host computer which is not possible in Windows 8.1 and up. The floppy image is a standard 3,5" floppy with 1.44 MB storage. It is formatted with a FAT12 filesystem. The floppy can be mounted to apply several customizations.
.SH SUPPORTED HYPERVISORS
The floppy image has been tested with the following hypervisors:
.IP
VMWare, VirtualBox, Hyper-V and QEMU
.RE
Others are likely to work.
.SH SETUP
Create a new virtual machine. Assign 16 MB of RAM. Add a floppy drive and attach \fBfloppy144.vfd\fR to this drive. Do not create a virtual hard disk. Setup the virtual machine to boot from a floppy drive (VirtualBox has floppy boot disabled by default). If possible, setup a virtual machine with plain old BIOS (not UEFI). If you created an UEFI virtual machine, enable the compatibility support mode (CSM) to allow a BIOS compatible boot. Set number of CPUs to 1. The Linux kernel is not capable of SMP. Remove IDE, SATA, SCSI and USB support if possible. The Linux kernel can't handle this and ignores any devices connected to these buses.
Setup an ethernet card. The following models are supported:
.IP
Intel PRO/1000
.br
AMD PCNET III
.br
AMD PCNET32
.br
VMWare vmxnet3 (paravirtualized driver used by VMWare)
.br
virtio (paravirtualized driver used by VirtualBox, QEMU, KVM and lguest)
.RE
Most hypervisors emulate an Intel PRO/1000 or AMD PCNET32 by default. Selecting a paravirtualized driver slightly improves performance. In VirtualBox you can simply select virtio in the network configuration dialog. VMWare requires that you add or change the VMX file. Use 'ethernet0.virtualDev\ =\ "vmxnet3"' in your VMWare config file.
If you are using QEMU, you must also setup a TAP adapter. Port redirection does not work to activate your own computer.
.SH CONFIGURATION
\fBfloppy144.vfd\fR can be customized to fit your needs. This is done by editing the file syslinux.cfg on the floppy image. The floppy image must be mounted. Under Linux you can simply attach \fBfloppy144.vfd\fR to a loop device which is mountable like any other block device. For Windows you must use some software that allows mounting a floppy image, e.g.
.URL http://www.osforensics.com/tools/mount-disk-images.html OSFMount ""
OSFMount works under all Windows versions beginning with Windows XP up to Windows 10 (32- and 64-bit).
The default syslinux.cfg file looks like this:
.IP
.br
.SM
prompt 0
.br
.SM
TIMEOUT 50
.br
.SM
default dhcp
.br
.SM
LABEL dhcp
.br
.SM
\0\0KERNEL bzImage
.br
.SM
\0\0APPEND vga=773 quiet initrd=initrd KBD=us LISTEN=[::]:1688,0.0.0.0:1688 TZ=UTC0 IPV4_CONFIG=DHCP NTP_SERVER=pool.ntp.org HOST_NAME=vlmcsd ROOT_PASSWORD=vlmcsd USER_NAME=user USER_PASSWORD=vlmcsd GUEST_PASSWORD=vlmcsd INETD=Y WINDOWS=06401-00206-271-395032-03-1033-9600.0000-1652016 OFFICE2010=06401-00096-199-204970-03-1033-9600.0000-1652016 OFFICE2013=06401-00206-234-921934-03-1033-9600.0000-1652016 HWID=36:4F:46:3A:88:63:D3:5F
.SM
LABEL static
.br
.SM
\0\0KERNEL bzImage
.br
.SM
\0\0APPEND vga=773 quiet initrd=initrd KBD=fr LISTEN=[::]:1688,0.0.0.0:1688 TZ=CET-1CEST,M3.5.0,M10.5.0/3 IPV4_CONFIG=STATIC IPV4_ADDRESS=192.168.20.123/24 IPV4_GATEWAY=192.168.20.2 IPV4_DNS1=192.168.20.2 IPV4_DNS2=NONE NTP_SERVER=pool.ntp.org HOST_NAME=vlmcsd ROOT_PASSWORD=vlmcsd USER_NAME=user USER_PASSWORD=vlmcsd GUEST_PASSWORD=vlmcsd INETD=Y
.PP
There are two configurations in this files: \fIdhcp\fR (for configuring the IPv4 network via DHCP) and \fIstatic\fR (for a static IPv4 configuration). The kernel always boots the \fIdhcp\fR configuration without asking (lines 'prompt 0' and 'default dhcp'). You can simply change the default configuration to \fIstatic\fR and then customize the APPEND line in the \fIstatic\fR configuration. For more details how to customize the syslinux.cfg file see \fBsyslinux\fR(1).
Each APPPEND line contains one or more items seperated by spaces. \fBAll items are case-sensitive\fR. The following parameters can be customized:
.IP \fBvga=\fIvesa-video-mode\fR
Sets the VESA display mode for the virtual machine. The parameter is not optional. If you ommit it, you will not see anything on the screen. 773 means 1024x768 with 256 colors. See
.URL https://en.wikipedia.org/wiki/VESA_BIOS_Extensions#Linux_video_mode_numbers Wikipedia ""
for more video modes. Note that all 16 color (4-bit) modes will not work. Use 8-bit (256 colors), 16-bit (65536 colors), 24-bit and 32-bit (> 16 Million colors) only. All modes above 1280x1024 are non-VESA-standard and vary for all (virtual) graphic cards.
.IP \fBquiet\fR
This causes the kernel not display the its log during boot. You may omit \fBquiet\fR but it doesn't make much sense. The boot log is actually very verbose and scrolls away from screen quickly. If any errors occur during boot, they will be displayed even if \fBquiet\fR is present in the APPEND line. You may evaluate the complete boot log later by using the dmesg command or the menu on /dev/tty8.
.IP "\fBinitrd=\fIinitial-ram-disk-file\fR"
This defines the initial ram disk that the kernel will read. There is only one initial ram disk on the floppy thus leave \fIinitrd=initrd\fR as it is.
.IP "\fBKBD=\fIkeyboard-layout-name\fR"
This allows you to select the keyboard layout. \fIkeyboard-layout-name\fR is usually the ISO 3166-1 (top level domain) code for a country. A list of valid \fIkeyboard-layout-name\fRs can be accessed via the menu system on /dev/tty8 (press ALT-F8). Note, that this is a keyboard driver only. There is no Unicode font support in \fBfloppy144.vfd\fR (due to the fact that the kernel uses a generic VESA framebuffer device only). Characters beyond ASCII work for Western European languages only but not Eastern European, Greek, Cyrillic, Arabic, Hebrew, CJK and other languages. There is no need in \fBfloppy144.vfd\fR to enter any characters outside ASCII. The purpose of the keyboard maps are that you will find characters like dash, backslash, brackets, braces, etc. at the usual place on your keyboard.
.IP "\fBLISTEN=\fRPRIVATE[:\fItcp-port\fR] | \fIip-address\fR[:\fItcp-port\fR][,\fIip-address\fR[:\fItcp-port\fR]][,...]"
One or more combinations of IP addresses and optional TCP port seperated by commas that \fBvlmcsd\fR(8) should listen on or PRIVATE to listen on all private IP addresses only. The default port is 1688. If you use an explicit port number, append it to the IP address seperated by a colon. If you use a port number and the IP address contains colons, you must enclose the IP address in brackets. For example \fI192.168.0.2,[fd00::dead:beef]:5678\fR causes \fBvlmcsd\fR(8) to listen on 192.168.0.2 port 1688 and fd00::dead:beef port 5678.
.IP "\fBWINDOWS=\fIepid\fR"
Defines the ePID that is used for Windows activations. If you ommit this parameter, vlmcsd generates a random ePID when it is started.
.IP "\fBOFFICE2010=\fIepid\fR"
Defines the ePID that is used for Office 2010 activations. If you ommit this parameter, \fBvlmcsd\fR(8) generates a random ePID when it is started.
.IP "\fBOFFICE2013=\fIepid\fR"
Defines the ePID that is used for Office 2016 activations. If you ommit this parameter, \fBvlmcsd\fR(8) generates a random ePID when it is started.
.IP "\fBOFFICE2016=\fIepid\fR"
Defines the ePID that is used for Office 2016 activations. If you ommit this parameter, \fBvlmcsd\fR(8) generates a random ePID when it is started.
.IP "\fBOFFICE2019=\fIepid\fR"
Defines the ePID that is used for Office 2019 activations. If you ommit this parameter, \fBvlmcsd\fR(8) generates a random ePID when it is started.
.IP "\fBWINCHINAGOV=\fIepid\fR"
Defines the ePID that is used for Windows China Government Edition activations (Enterprise G/GN). If you ommit this parameter, \fBvlmcsd\fR(8) generates a random ePID when it is started.
.IP "\fBHWID=\fIhwid\fR"
Defines the HwId that is sent to clients. \fIhwid\fR must be specified as 16 hex digits that are interpreted as a series of 8 bytes (big endian). Any character that is not a hex digit will be ignored. This is for better readability.
.IP "\fBTZ=\fIposix-time-zone-string\fR"
Set the time zone to \fIposix-time-zone-string\fR. It must conform to the
.URL http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html POSIX
specification. Simplified time zone strings like "Europe/London" or "America/Detroit" are not allowed. This has the very simple reason that there is no space on the floppy to store the time zone database.
The string \fICET-1CEST,M3.5.0,M10.5.0/3\fR (most countries in Europe) reads as follows:
.RS 7
.IP \fICET\fR 10
The standard (winter) time zone has the name CET.
.IP \fI-1\fR 10
The standard time zone is one hour east of UTC. Negative numbers are east of UTC. Positive numbers are west of UTC.
.IP \fICEST\fR 10
The daylight saving (summer) time zone has the name CEST.
.IP \fIM3.5.0\fR 10
Daylight saving time starts in the 3rd month (March) on the 5th (=last) occurence of weekday 0 (Sunday) at 2 o'clock (2 o'clock is a default value).
.IP \fIM10.5.0/3\fR 10
Daylight saving time ends in the 10th month (October) on the 5th (=last) occurence of weekday 0 (Sunday) at 3 o'clock.
.RE
.IP
If you don't have daylight saving time, things are easier. For Chinese Standard Time for example, just use \fICST-8\fR as the time zone string.
On a Linux desktop system, you can use a command like \fBstrings\ /usr/share/zoneinfo/America/New_York\ |\ tail\ -n1\fR. This should return \fIEST5EDT,M3.2.0,M11.1.0\fR. You can use the returned string for the \fBTZ=\fIposix-time-zone-string\fR parameter.
.IP "\fBIPV4_CONFIG=\fRDHCP | STATIC\fR"
This determines how you want to configure IPv4 networking. If you use \fBIPV4_CONFIG=\fRSTATIC, you must supply additional paramaters to the APPEND command line.
.IP "\fBIPV4_ADDRESS=\fIipv4-address\fR/\fICIDR-mask\fR"
Use \fIipv4-address\fR with netmask \fICIDR-mask\fR for static IPv4 configuration. The netmask must not be ommitted. For IPv4 address 192.168.12.17 with a netmask of 255.255.255.0 use \fI192.168.12.17/24\fR. For IPv4 address 10.4.0.8 with a netmask of 255.255.0.0 use 10.4.0.8/16. This paramater is ignored, if you used \fBIPV4_CONFIG=\fRDHCP.
.IP "\fBIPV4_GATEWAY=\fIipv4-address\fR | NONE"
Use \fIipv4-address\fR as the default gateway. This is usually the IPv4 address of your router. You may specify NONE explicitly for no gateway. In this case your virtual machine is only visible on its local LAN. This paramater is ignored, if you used \fBIPV4_CONFIG=\fRDHCP.
.IP "\fBIPV4_DNS1=\fIipv4-address\fR | NONE"
Use \fIipv4-address\fR as the primary name server. In home networks this is often the IPv4 address of your router. You may specify NONE explicitly. If you specified NONE for both \fBIPV4_DNS1=\fR and \fBIPV4_DNS2=\fR, your virtual machine cannot resolve host names to IP addresses. While \fBvlmcsd\fR(8) works perfectly without DNS servers, you must use IP addresses when referring to a host, e.g. for specifying an NTP server. This paramater is ignored, if you used \fBIPV4_CONFIG=\fRDHCP.
.IP "\fBIPV4_DNS2=\fIipv4-address\fR | NONE"
Use \fIipv4-address\fR as the secondary name server. It serves as a backup if the primary name server is not available. Home networks often don't have a secondary name server. In this case set this to NONE. This paramater is ignored, if you used \fBIPV4_CONFIG=\fRDHCP.
.IP "\fBNTP_SERVER=\fIhost-name\fR | \fIipv4-address\fR | NONE"
This sets the name of a time server using the NTP protocol. If your virtualization environment reliably provides time, you can set this to NONE. Don't use a public time service like pool.ntp.org or time.nist.gov if you have a (at least somewhat reliable) NTP server in your LAN.
.IP "\fBHOST_NAME=\fIhost-name\fR"
Sets the local host name for your virtual machine. It can be a single name or a fully-qualified domain name FQDN. If you used \fBIPV4_CONFIG=\fRDHCP and your DHCP server returns a domain name, the domain part of an FQDN will be replaced by that name. This host name or host part of an FQDN will not replaced by a host name returned via DHCP. The host name is not important for the operation of \fBfloppy144.vfd\fR.
.IP "\fBROOT_PASSWORD=\fIpassword\fR"
Sets the password of the root user.
.IP "\fBUSER_NAME=\fIusername\fR"
Sets the name of for a general user with no special privileges. This user can login but can't do much.
.IP "\fBUSER_PASSWORD=\fIpassword\fR"
Sets the password for the user defined by \fBUSER_NAME=\fIusername\fR.
.IP "\fBGUEST_PASSWORD=\fIpassword\fR"
Sets the password for the pre-defined guest user. This user has the same priviliges (none) as the user defined by \fBUSER_NAME=\fIusername\fR.
.IP "\fBINETD=\fRY | N"
\fBINETD=\fRY specifies that \fBinetd\fR(8) should automatically be started. That means you can telnet and ftp to your virtual machine.
.IP "\fBVLMCSD_EXTRA_ARGS=\fR\fIcomma-seperated-argument-list\fR"
Allows you to specify additional command line options that will be passed to \fBvlmcsd\fR(8). Instead of spaces you use commas between arguments. Example: \fBVLMCSD_EXTRA_ARGS=\fR\-c1,-K3,-M1
.SH OPERATION
.SS Diskless System
The \fBfloppy144.vfd\fR virtual machine is a diskless system that works entirely from RAM. The file system is actually a RAM disk that is created from the \fBinitrd\fR(4) file on the floppy image.
Anything you'll do from inside the virtual machine, for instance editing a config file, will be lost when you reboot the machine. So, if you ever asked yourself if \fBrm -fr /\fR (root privileges required) really deletes all files from all mounted partitions, the \fBfloppy144.vfd\fR VM is the right place to test it (Yes, it does).
The VM uses a RAM disk, because the Linux kernel had to be stripped down to essential features to fit on a 1.44 MB floppy. It has no floppy driver, no disk file system drivers and no block layer (cannot use disks of any type).
.SS System startup
The kernel boots up very quickly and the init script (/sbin/init) waits 5 seconds. In these 5 seconds you can:
.IP
Press 'm' to manually enter the time zone and the IPv4 parameters. These will be queried interactively.
.br
Press 't' to manually enter the time zone only.
.br
Press 's' to escape to a shell.
.RE
If you don't want to 5 seconds for continuing the init process, you can press any other key to speed things up. At the end of the init script you should see that\fBvlmcsd\fR(8) has started. You should also see the IP addresses and all user names and passwords.
.SS Logging into the system
There are 5 local logins provided on /dev/tty2 to /dev/tty6. To switch to these logins, simply press ALT\-F2 to ALT\-F6. To return to the console on /dev/tty1, press ALT\-F1. If \fBinetd\fR(8) is running you can also use \fBtelnet\fR(1). This allows you use a terminal program (e.g. putty) that can utilize your keyboard layout, can be resized and has full UTF-8 support. The local terminals support US keyboard layout only. Please be aware that \fBtelnet\fR(1) is unencrypted and everything including passwords is transmitted in clear text. There is not enough space for an ssh server like \fBsshd\fR(8) or \fBdropbear\fR(8).
The floppy image only provides basic Unix commands. Type \fIbusybox\fR or \fIll /bin\fR to get a list. The only editor available is \fBvi\fR(1). If you don't like vi, you may transfer config files via \fBftp\fR(1) edit them with the editor of your choice and transfer them back to the \fBfloppy144.vfd\fR VM.
.SS The menu system
You'll find a menu system on /dev/tty8 (press ALT\-F8 to see it). It allows you performing some administrative tasks and to view various system information. It is mainly for users that do not have much experience with Unix commands.
.IP "\fB1) (Re)start vlmcsd\fR"
Starts or restarts \fBvlmcsd\fR(8). This is useful if you changed \fB/etc/vlmcsd.ini\fR(5).
.IP "\fB2) Stop vlmcsd\fR"
Stops \fBvlmcsd\fR(8).
.IP "\fB3) (Re)start inetd\fR"
Starts or restarts \fBinetd\fR(8). If \fBinetd\fR(8) is restarted, current clients connected via \fBtelnet\fR(1) or \fBftp\fR(1) will \fBnot\fR be dropped. They can continue their sessions. This is useful if you changed \fB/etc/inetd.conf\fR(5).
.IP "\fB4) Stop inet\fR"
Stops \fBinetd\fR(8). All clients connected via \fBtelnet\fR(1) or \fBftp\fR(1) will be dropped immediately.
.IP "\fB5) Change the time zone\fR"
Just in case you missed pressing 't' during system startup. This also restarts \fBvlmcsd\fR(8) if it was running to notify it that the time zone has changed. Restarting \fBvlmcsd\fR(8) allows currently connected clients to finish their activation.
.IP "\fBk) Change keyboard layout\fR"
This allows you to select a different keyboard layout.
.IP "\fB6) Show all kernel boot parameters\fR"
Shows all parameters passed to the kernel via syslinux.cfg. If you experience any unexpected behavior, you can use this to check if your APPEND line in syslinux.cfg is correct. The output is piped through \fBless(1)\fR. So press 'q' to return to the menu.
.IP "\fB7) Show boot log (dmesg)\fR"
Shows the boot log of the kernel. The output is piped through \fBless(1)\fR. So press 'q' to return to the menu.
.IP "\fB8) Show TCP/IP configuration\fR"
Shows the TCP/IP configuration, listening sockets and current TCP and UDP connections. Useful, if you problems with net connectivity. The output is piped through \fBless(1)\fR. So press 'q' to return to the menu.
.IP "\fB9) Show running processes\fR"
Shows all processes including memory and CPU usage. Display will updated every second. Press 'q' or CTRL-C to return to the menu.
.IP "\fBs) Shutdown\fR"
Shuts down the \fBfloppy144.vfd\fR virtual machine. Proper shutdown is not required. It is ok to use a hard power off in your virtualization program.
.IP "\fBr) Reboot\fR"
Reboots the \fBfloppy144.vfd\fR virtual machine. Proper reboot is not required. It is ok to use a hard reset in your virtualization program.
.SH PERMANENT CHANGES OF INITRD
If you want to change any file or script of the file system (e.g. the init script /sbin/init or /etc/vlmcsd.ini), you'll need to mount the floppy image, unpack the \fBinitrd\fR(4) file, make any modfications you like, create a new \fBinitrd\fR(4) file and copy it to the mounted floppy.
To unpack the \fBinitrd\fR(4) file you'll need \fBxz\fR(1) (or \fBlzma\fR(1) on older unix-like OSses) and \fBcpio\fR(1). These can be installed using your package manager on all major distros. It is ok to use the BSD version of \fBcpio\fR(1). No need to get the GNU version for BSD users.
Provided the floppy is mounted in /mnt/floppy do the following:
.IP "Create an empty directory"
mkdir ~/vlmcsd-floppy-initrd
.IP "cd into that directory"
cd ~/vlmcsd-floppy-initrd
.IP "Unpack initrd"
cat /mnt/floppy/initrd | unlzma | cpio -i
.RE
After applying your changes build a new \fBinitrd\fR(4) file:
.IP "cd into your directory"
cd ~/vlmcsd-floppy-initrd
.IP "Create the packed file"
find . | cpio -o -H newc | lzma > /mnt/floppy/initrd
.RE
Do not try to use 'lzma -9' to achive better compression. The kernel can't read the resulting file. While customizing the \fBinitrd\fR(4) file works on almost any unix-like OS, it does not work on Windows even not with Cygwin. The reason is that the NTFS file system can't handle uids and gids. These cannot be preserved when unpacking the \fBcpio\fR(1) archive to NTFS. If you use the WSL subsystem of Windows 10 Redstone (Anniversary Update) and later, you must make sure to unpack the \fBinitrd\fR(4) file to a directory on VolFs (normally everything that is \fBnot\fR mounted under /mnt). The \fBinitrd\fR(4) file can be on a VolFs or DriveFs.
.SH FAQ
.SS On what distro is the floppy image based?
None. Besides the boot loader \fBldlinux.sys\fR, there are only three binaries: The Linux kernel \fBbzImage\fR, \fBbusybox\fR(1) and \fBvlmcsdmulti-x86-musl-static\fR. \fBbzImage\fR and \fBbusybox\fR(1) have been compiled with carefully selected configuration parameters not found in any distro. This was neccesary to fit everything on a 1.44 MB floppy.
.SS Why is a rather old Linux kernel (3.12) used?
Linux 3.12 is the last kernel that can be booted with 16 MB of RAM. Beginning with Linux 3.13 it requires much more memory (about 80 MB) to boot. The floppy image is regularly tested with newer kernels. Everything works except that you need to assign much more main memory to the virtual machine.
.SS Can the floppy be booted on bare metal?
Basically yes. However, only Intel Pro/1000 and AMD PCNET32 ethernet cards are supported by the kernel. In addition there is no USB support compiled into the kernel. That means you can only use an IBM AT or IBM PS/2 keyboard which are not available on newer hardware.
.SH FILES
\fBsyslinux.cfg\fR, \fBvlmcsd.ini\fR(5)
.SH BUGS
IPv6 cannot be configured with static or manual parameters.
.br
DHCPv6 is not supported.
.br
\'ip route add ...' does not work. Use 'route add ...' instead.
.SH AUTHOR
\fBfloppy144.vfd\fR has been created by Hotbird64
.SH CREDITS
Linus Torvalds et al. for the Linux kernel
.br
Erik Andersen et al. for the original uClibc
.br
Waldemar Brodkorb et al. for uClibc-ng
.br
Denys Vlasenko et al. for BusyBox
.br
H. Peter Anvin et al. for SYSLINUX
.SH SEE ALSO
\fBvlmcsd\fR(8), \fBvlmcsd.ini\fR(5), \fBinitrd\fR(4), \fBbusybox\fR(1), \fBsyslinux(1)\fR

145
man/vlmcsd.7 Normal file
View File

@ -0,0 +1,145 @@
.TH VLMCSD 7 "March 2016" "Hotbird64" "KMS Activation Manual"
.SH NAME
vlmcsd\ \-\ a guide to KMS activation using vlmcsd
.SH SYNOPSIS
.B vlmcsd
[
.IR "options" " ]
.SH DESCRIPTION
This manual describes the concepts of Microsoft KMS activation using \fBvlmcsd\fR. For detailed usage of \fBvlmcsd\fR see \fBvlmcsd\fR(8).
.SS What is KMS?
KMS is a way to activate Microsoft products that was designed for medium and large businesses. In a standard SOHO environment you enter a product key during installation and then activate your product over the Internet. This is done by sending a request to a server at microsoft.com which then either grants or refuses activation.
.PP
By entering a special key called General Volume License Key (\fBGVLK\fR), a.k.a "KMS client key", the product no longer asks the Microsoft server for activation but a user-defined server (called the KMS server) which usually resides in a company's intranet. \fBvlmcsd\fR is an independent open source implementation of a KMS server that is available for everyone while Microsoft gives their KMS server only to corporations that signed a so called "Select contract". In addition \fBvlmcsd\fR never refuses activation while the Microsoft KMS server only activates the products the customer has paid for.
.PP
Product activation using \fBvlmcsd\fR is performed in three easy steps:
.IP 1) 3
Run \fBvlmcsd\fR (or any other KMS emulator) on a computer in your network. This will be your KMS server. New users should simply run the program without any parameters. The defaults should fit the needs of most users.
.IP 2) 3
Install your product and enter the GVLK when you are asked for a key
.IP 3) 3
Configure your client (the machine where you installed your product) to use your KMS server.
.PP
However, when it comes to the details, some things turn out to be more difficult than you might think.
.PP
The most important thing to know is that KMS activation is not permanent. The computer remains activated for 180 days (30 or 45 days with consumer-only products). KMS activation however is not an evaluation license. You can repeat the activation anytime and as often as you like to extend activation to another 180 days. This normally happens automatically. For this to work, you have to ensure that a KMS server is always reachable for the clients on your network.
.PP
Beginning with Windows 8.1 the KMS server must be a different computer than the client. You cannot use \fBvlmcsd\fR on the same computer where you want to activate a product. If you have only one computer, you can run \fBvlmcsd\fR in a virtual machine. \fBvlmcsd\fR is also designed to run on "always-on devices", for example a router. The router becomes your KMS server then.
.SS How to get a GVLK?
That is relatively simple. The GVLKs are published on Microsoft's Technet web site.
.PP
Windows: http://technet.microsoft.com/en-us/library/jj612867.aspx
.br
Office 2010: http://technet.microsoft.com/en-us/library/ee624355(v=office.14).aspx#section2_3
.br
Office 2013: http://technet.microsoft.com/en-us/library/dn385360.aspx
.PP
These lists only include products that Microsoft sells to corporations via volume license contracts. For Windows there are inofficial GVLKs that work with consumer-only versions of Windows. Here is a list:
.PP
TX9XD\-98N7V\-6WMQ6\-BX7FG\-H8Q99 - Windows 10 Home
.br
3KHY7\-WNT83\-DGQKR\-F7HPR\-844BM - Windows 10 Home N
.br
7HNRX\-D7KGG\-3K4RQ\-4WPJ4\-YTDFH - Windows 10 Home Single Language
.br
PVMJN\-6DFY6\-9CCP6\-7BKTT\-D3WVR - Windows 10 Home Country Specific
.br
789NJ\-TQK6T\-6XTH8\-J39CJ\-J8D3P - Windows 8.1 Professional with Media Center
.br
M9Q9P\-WNJJT\-6PXPY\-DWX8H\-6XWKK - Windows 8.1 Core
.br
7B9N3\-D94CG\-YTVHR\-QBPX3\-RJP64 - Windows 8.1 Core N
.br
BB6NG\-PQ82V\-VRDPW\-8XVD2\-V8P66 - Windows 8.1 Core Single Language
.br
NCTT7\-2RGK8\-WMHRF\-RY7YQ\-JTXG3 - Windows 8.1 Core Country Specific
.br
GNBB8\-YVD74\-QJHX6\-27H4K\-8QHDG - Windows 8 Professional with Media Center
.br
BN3D2\-R7TKB\-3YPBD\-8DRP2\-27GG4 - Windows 8 Core
.br
8N2M2\-HWPGY\-7PGT9\-HGDD8\-GVGGY - Windows 8 Core N
.br
2WN2H\-YGCQR\-KFX6K\-CD6TF\-84YXQ - Windows 8 Core Single Language
.br
4K36P\-JN4VD\-GDC6V\-KDT89\-DYFKP - Windows 8 Core Country Specific
.PP
The above keys require activation renewal every 45 days (Win 8.1) or 30 days (Win 8). All GVLKs from the Microsoft Technet web site require renewal every 180 days.
.SS What are SLMGR and OSPP and how to use them?
You will need these utilities later. So please continue reading this section.
.PP
These are two Visual Basic script utilities that are used to control Microsoft's Software Protection system. To use them open a Windows Command Prompt. slmgr.vbs is for Windows. ospp.vbs is for Office 2010 and 2013. These utilities are installed with Windows and Office and you don't need to download them.
.PP
slmgr.vbs resides in the system32 directory. So you just have to type "slmgr" in the Windows Command prompt to use it. To use ospp.vbs you'll have to change the current directory to your Office installation. This is usually something like "C:\eProgram\ Files\eMicrosoft\ Office\eOffice14". You may type "slmgr" or "cscript ospp.vbs" without parameters to see help for these commands but this produces some rather confusing output for newbies.
.SS How to get the GVLK into the product?
Normally every product asks you to enter a key during installation. At this time simply enter the GVLK. If you skipped this step or entered some other key which later turned out to be non-working, you can use "slmgr\ /ipk\ \fIGVLK\fR" (Windows) or "cscript ospp.vbs\ /inpkey:\fIGVLK\fR" (Office) at any time.
.IP \fBExamples\fR
slmgr\ /ipk GCRJD\-8NW9H\-F2CDX\-CCM8D\-9D6T9
.br
cscript ospp.vbs\ /inpkey:YC7DK\-G2NP3\-2QQC3\-J6H88\-GVGXT
.SS Why doesn't Office accpet a GVLK?
You'll have to install a volume license (VL) version of Office. Office versions downloaded from MSDN and/or Technet are non-VL.
.SS How to configure a client to use a KMS server?
After you have installed a GVLK you can set your product to use your KMS server. \fBvlmcsd\fR or another KMS server must already be running on your server machine.
.IP "\fBWindows\fR" 5
.PP
Type "slmgr\ /skms\ \fIkms-server\fR[:\fItcp-port\fR]". Example: "slmgr\ /skms\ 192.168.1.17:1688"
.IP "\fBOffice\fR" 5
.IP 1) 3
Type "cscript ospp.vbs\ /sethst:\fIkms-server\fR". Example "cscript ospp.vbs\ /sethst:192.168.1.17"
.IP 2) 3
Type "cscript ospp.vbs\ /setprt:\fItcp-port\fR". Example: cscript ospp.vbs\ /setprt:1688
.PP
\fItcp-port\fR is usually 1688 unless you instructed \fBvlmcsd\fR to use a different port which is rarely necessary.
.SS How to activate my product?
If you have installed a product with GVLK and pointed it to working KMS server like \fBvlmcsd\fR, activation occurs automatically. This may take a while.
.IP "You may type"
slmgr\ /ato
.br
\-or\-
.br
cscript ospp.vbs\ /act
.PP
at any time to speed up that process. You may repeat these commands later to extend your activation for another 180 (45) days.
.SS Does vlmcsd work correctly?
If something does not work, it may have the cause that \fRvlmcsd\fR does not work correctly although this is unlikely. You can test this with the KMS client \fBvlmcs\fR(1). First type "vlmcs" on the same machine where you started \fBvlmcsd\fR. If things are ok, you should see something like this:
.IP
Connecting to 127.0.0.1:1688 ... successful
.br
Sending\ activation\ request\ (KMS\ V4)\ 1\ of\ 1\ \-> 06401\-00206\-296\-206344\-03\-5179\-9600.0000\-3432013
.PP
If anything goes wrong, you'll see an error message. Next try "vlmcs \fIkms-server\fR" from another machine where \fIkms-server\fR is the hostname or IP address of your KMS server. If that fails while it works locally, you'll most likely have to configure your firewall that it accepts incoming connections on TCP port 1688.
.SS Is there an easier way than using OSPP and SLMGR?
Yes and no. KMS activation was designed for large corporations. Thus Microsoft designed KMS in a way that corporations can configure their network infrastructure to fully automate KMS activation. Since this involves DHCP and DNS, it is not that easy to accomplish that for home users. However, if you are using an open source router firmware like OpenWRT or DD-WRT, it is easy to customize DHCP and DNS.
.IP 1) 3
Configure DHCP that it assigns a DNS domain name to your clients (if it doesn't already), e.g. my-home-net.local
.IP 2) 3
Create zone my-home-net.local in your DNS server (if it doesn't exist already).
.IP 3) 3
Add the following records to your DNS
_vlmcs._tcp.my-home-net.local. 10800 IN SRV 100 100 kms1.my-home-net.local.
.br
kms1.my-home-net.local. 10800 IN A 192.168.1.17
Replace 192.168.1.17 with the IP address of your KMS server. If you don't like a cache time of 10800 seconds (3 hours), replace it with another number.
.PP
This causes that clients will find the KMS server automatically.
.SH AUTHOR
This manual page was written by Hotbird64.
.SH SEE ALSO
\fBvlmcsd\fR(8), \fBvlmcs\fR(1)

346
man/vlmcsd.8 Normal file
View File

@ -0,0 +1,346 @@
.mso www.tmac
.TH VLMCSD 8 "February 2019" "Hotbird64" "KMS Activation Manual"
.LO 8
.SH NAME
vlmcsd \- a fully Microsoft compatible KMS server
.SH SYNOPSIS
.B vlmcsd
[
.IR "options" " ]
.SH DESCRIPTION
\fBvlmcsd\fR is a fully Microsoft compatible KMS server that provides product activation services to clients. It is meant as a drop-in replacement for a Microsoft KMS server (Windows computer with KMS key entered). It currently supports KMS protocol versions 4, 5 and 6.
.PP
\fBvlmcsd\fR is designed to run on POSIX compatible operating systens. It only requires a basic C library with a BSD-style sockets API and either \fBfork\fR(2) or \fBpthreads\fR(7). That allows it to run on most embedded systems like routers, NASes, mobile phones, tablets, TVs, settop boxes, etc. Some efforts have been made that it also runs on Windows.
.PP
Although \fBvlmcsd\fR does neither require an activation key nor a payment to anyone, it is not meant to run illegal copies of Windows. Its purpose is to ensure that owners of legal copies can use their software without restrictions, e.g. if you buy a new computer or motherboard and your key will be refused activation from Microsoft servers due to hardware changes.
.PP
\fBvlmcsd\fR may be started via an internet superserver like \fBinetd\fR(8) or \fBxinetd\fR(8) as well as an advanced init system like \fBsystemd\fR(8) or \fBlaunchd\fR(8) using socket based activation. If \fBvlmcsd\fR detects that \fBstdin\fR(3) is a socket, it assumes that there is already a connected client on stdin that wants to be activated.
All options that control setting up listening sockets will be ignored when in inetd mode. The sockets will be set up by your internet superserver. You also cannot limit the number of simultanous clients (option \fB-m\fR). You need to configure the limit in your internet superserver.
The followong features that require that vlmcsd is permanently loaded will not work if started from an internet superserver:
.IP
You cannot maintain a client list (option \fB-M1\fR)
.IP
EPID Randomization Level 1 (option \fB-r1\fR) works like Level 2 (\fB-r2\fR). You may want to use Level 0 (\fB-r0\fR) or custom EPIDs (options \fB-w\fR, \fB-G\fR, \fB-0\fR, \fB-3\fR and \fB-6\fR) instead.
.SH OPTIONS
Since vlmcsd can be configured at compile time, some options may not be available on your system.
.PP
All options that do no require an argument may be combined with a single dash, for instance "vlmcsd -D -e" is identical to "vlmcsd -De". For all options that require an argument a space between the option and the option argument is optional. Thus "vlmcsd -r 2" and "vlmcsd -r2" are identical too.
.IP "\fB-h\fR or \fB-?\fR"
Displays help.
.IP "\fB-V\fR"
Displays extended version information. This includes the compiler used to build vlmcsd, the intended platform and flags (compile time options) to build vlmcsd. If you have the source code of vlmcsd, you can type \fBmake help\fR (or \fBgmake help\fR on systems that do not use the GNU version of \fBmake\fR(1) by default) to see the meaning of those flags.
.IP "\fB-L\fR \fIipaddress\fR[:\fIport\fR]"
Instructs vlmcsd to listen on \fIipaddress\fR with optional \fIport\fR (default 1688). You can use this option more than once. If you do not specify \fB-L\fR at least once, IP addresses 0.0.0.0 (IPv4) and :: (IPv6) are used. If the IP address contains colons (IPv6) you must enclose the IP address in brackets if you specify the optional port, e.g. [2001:db8::dead:beef]:1688.
.PP
.IP
If no port is specified, vlmcsd uses the default port according to a preceding \fB-P\fR option. If you specify a port, it can be a number (1-65535) or a name (usually found in /etc/services if not provided via LDAP, NIS+ or another name service).
.PP
.IP
If you specify a link local IPv6 address (fe80::/10, usually starting with fe80::), it must be followed by a percent sign (%) and a scope id (=network interface name or number) on most unixoid OSses including Linux, Android, MacOS X and iOS, e.g. fe80::1234:56ff:fe78:9abc\fB%eth0\fR or [fe80::1234:56ff:fe78:9abc\fB%2\fR]:1688. Windows (including cygwin) does not require a scope id unless the same link local address is used on more than one network interface. Windows does not accept a name and the scope id must be a number.
.IP "\fB-o \fIlevel\fR"
Sets the \fIlevel\fR of protection against activations from public IP addresses. The default is \fB-o0\fR for no protection.
\fB-o1\fR causes vlmcsd not to listen on all IP addresses but on private IP addresses only. IPv4 addresses in the 100.64.0.0/10 range (see RFC6598) are not treated as private since they can be reached from other users of your ISP. Private IPv4 addresses are 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 and 127.0.0.0/8. vlmcsd treats all IPv6 addresses not within 2000::/3 as private addresses.
If \fB-o1\fR is combined with \fB-L\fR, it will listen on all private IP addresses plus the ones specified by one or more \fB-L\fR statements. If \fB-o1\fR is combined with \fB-P\fR, only the last \fB-P\fR statement will be used.
Using \fB-o1\fR does not protect you if you enable NAT port forwarding on your router to your vlmcsd machine. It is identical to using multiple -L statements with all of your private IP addresses. What \fB-o1\fR does for you, is automatically enumerating your private IP addresses.
\fB-o2\fR does not affect the interfaces, vlmcsd is listening on. When a clients connects, vlmcsd immediately drops the connection if the client has a public IP address. Unlike \fB-o1\fR clients will be able to establish a TCP connection but it will be closed without a single byte sent over the connection. This protects against clients with public IP addresses even if NAT port forwarding is used. While \fB-o2\fR offers a higher level of protection than \fB-o1\fR, the client sees that the KMS TCP port (1688 by default) is actually accepting connections.
If vlmcsd is compiled to use MS RPC, \fB-o2\fR can only offer very poor protection. Control is passed from MS RPC to vlmcsd after the KMS protocol has already been negotiated. Thus a client can always verify that the KMS protocol is available even though it receives an RPC_S_ACCESS_DENIED error message. vlmcsd will issue a warning if \fB-o2\fR is used with MS RPC. \fBFor adaequate protection do not use a MS RPC build of vlmcsd with -o2\fR.
\fB-o3\fR combines \fB-o1\fR and \fB-o2\fR. vlmcsd listens on private interfaces only and if a public client manages to connect anyway due to NAT port forwarding, it will be immediately dropped.
If you use any form of TCP level port forwarding (e.g. \fBnc\fR(1), \fBnetcat\fR(1), \fBssh\fR(1) port forwarding or similar) to redirect KMS requests to vlmcsd, there will be no protection even if you use \fB-o2\fR or \fB-o3\fR. This is due to the simple fact that vlmcsd sees the IP address of the redirector and not the IP address of the client.
\fB-o1\fR (and thus \fB-o3\fR) is not (yet) available in some scenarios:
.RS 12
FreeBSD: There is a longtime unfixed
.URL https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=178881 bug ""
in the 32-bit ABI of the 64-bit kernel. If you have a 64-bit FreeBSD kernel, you must run the 64-bit version of vlmcsd if you use \fB-o1\fR or \fB-o3\fR. The 32-bit version causes undefined behavior up to crashing vlmcsd. Other BSDs (NetBSD, OpenBSD, Dragonfly and Mac OS X) work correctly.
If vlmcsd was started by an internet superserver or was compiled to use Microsoft RPC (Windows only) or simple sockets, \fB-o1\fR and \fB-o3\fR are not available by design.
.RE
.IP "\fB-P\fR \fIport\fR"
Use TCP \fIport\fR for all subsequent \fB-L\fR statements that do not include an optional port. If you use \fB-P\fR and \fB-L\fR, \fB-P\fR must be specified before \fB-L\fR.
.IP "\fB-O\fR \fIvpn-adapter-name\fR[=\fIipv4-address\fR][/\fIcidr-mask\fR][:\fIdhcp-lease-duration\fR]"
Enables a compatible VPN adapter to create additional local IPv4 addresses (like 127.0.0.1) that appear as remote IPv4 addresses to the system. This allows product activation using a local instance of vlmcsd. This feature is only available in Windows and Cygwin builds of vlmcsd since it is not of any use on other operating systems. Compatible VPN adapters are Tap-windows version 8.2 or higher (from OpenVPN) and the TeamViewer VPN adapter. There are two special \fIvpn-adapter-name\fRs. A single period (.) instructs vlmcsd to use the first available compatible VPN adapter. A single dash (\-) disables the use of a VPN adapter if one has been configured in \fBvlmcsd.ini\fR(5). The \fIvpn-adapter-name\fR is \fBnot\fR case-sensitive. If the \fIvpn-adapter-name\fR contains spaces (e.g. Ethernet 3), you must enclose it in quotes.
The default \fIipv4-address\fR is 10.10.10.9 and the default \fIcidr-mask\fR is 30. If you are using the default values, your VPN adapter uses an IPv4 address of 10.10.10.9 and you can set your activation client to use the easy to remember address 10.10.10.10 (e.g. slmgr /skms 10.10.10.10 or cscript ospp.vbs /sethst:10.10.10.10).
The \fIdhcp-lease-duration\fR is a number optionally followed by s, m, h, d or w to indicate seconds, minutes, hours, days or weeks. The default \fIdhcp-lease-duration\fR is 1d (one day). It is normally not required to change this value.
It is advised not to manually configure your OpenVPN TAP or TeamViewer VPN adapter in "Network Connections". If you set the IPv4 configuration manually anyway, the IPv4 address and the subnet mask must match the \fB-O\fR parameter. It is safe leave the IPv4 configuration to automatic (DHCP). vlmcsd will wait up to four seconds for the DHCP configuration to complete before binding to and listenin on any interfaces.
You should be aware that only one program can use a VPN adapter at a time. If you use the TeamViewer VPN adapter for example, you will not be able to use the VPN feature of TeamViewer as long as vlmcsd is running. The same applies to OpenVPN TAP adapters that are in use by other programs (for example OpenVPN, QEMU, Ratiborus VM, aiccu, etc.). The best way to avoid conflicts is to install Tap-Windows from OpenVPN, cd to C:\\Program Files\\TAP-Windows\\bin and run addtap.bat to install an additional TAP adapter. Go to "Network Connections" and rename the new adapter to "vlmcsd" and specify \fB-O vlmcsd\fR to use it.
Example: \fB-O "Ethernet 7"=192.168.123.1/24\fR (uses VPN adapter Ethernet 7 with IPv4 address 192.168.123.1 and have 192.168.123.2 to 192.168.123.254 as additional local (but apparently remote) IPv4 addresses.
.IP "\fB-x0\fR and \fB-x1\fR"
Controls under what circumstances vlmcsd will exit. Using the default of \fB-x0\fR vlmcsd stays active as long as it can perform some useful operations. If vlmcsd is run by any form of a watchdog, e.g. NT service manager (Windows), systemd (Linux) or launchd (Mac OS / iOS), it may be desirable to end vlmcsd and let the watchdog restart it. This is especially true if some pre-requisites are not yet met but will be some time later, e.g. network is not yet fully setup.
By using \fB-x0\fR vlmcsd will
.RS 12
exit if none of the listening sockets specified with \fB-L\fR can be used. It continues if at least one socket can be setup for listening.
exit any TAP mirror thread (Windows version only) if there is an error condition while reading or writing from or to the VPN adapter but continue to work without utilizing a VPN adapter.
.RE
.IP
By using \fB-x1\fR vlmcsd will
.RS 12
exit if not all listening sockets specified with \fB-L\fR can be used.
exit completely if there is a problem with a VPN adapter it is using. This can happen for instance if the VPN adapter has been disabled using "Control Panel - Network - Adapter Settings" while vlmcsd is using it.
.RE
.IP
Please note that \fB-x1\fR is kind of a workaround option. While it may help under some circumstances, it is better to solve the problem at its origin, e.g. properly implementing dependencies in your startup script to ensure all network interfaces and the VPN adapter you will use are completely setup before you start vlmcsd.
.IP "\fB-F0\fR and \fB-F1\fR"
Allow (\fB-F1\fR) or disallow (\fB-F0\fR) binding to IP addresses that are currently not configured on your system. The default is \fB-F0\fR. \fB-F1\fR allows you to bind to an IP address that may be configured after you started \fBvlmcsd\fR. \fBvlmcsd\fR will listen on that address as soon as it becomes available. This feature is only available under Linux (IPv4 and IPv6) and FreeBSD (IPv4 only). FreeBSD allows this feature only for the root user (more correctly: processes that have the PRIV_NETINET_BINDANY privilege). Linux does not require a capability for this.
.IP "\fB-t\fR \fIseconds\fR"
Timeout the TCP connection with the client after \fIseconds\fR seconds. After sending an activation request. RPC keeps the TCP connection for a while. The default is 30 seconds. You may specify a shorter period to free ressources on your device faster. This is useful for devices with limited main memory or if you used \fB-m\fR to limit the concurrent clients that may request activation. Microsoft RPC clients disconnect after 30 seconds by default. Setting \fIseconds\fR to a greater value does not make much sense.
.IP "\fB-m\fR \fIconcurrent-clients\fR"
Limit the number of clients that will be handled concurrently. This is useful for devices with limited ressources or if you are experiencing DoS attacks that spawn thousands of threads or forked processes. If additional clients connect to vlmcsd, they need to wait until another client disconnects. If you set \fIconcurrent-clients\fR to a small value ( <10 ), you should also select a reasonable timeout of 2 or 3 seconds with \fB-t\fR. The default is no limit.
.IP "\fB-d\fR"
Disconnect each client after processing one activation request. This is a direct violation of DCE RPC but may help if you receive malicous fake RPC requests that block your threads or forked processes. Some other KMS emulators (e.g. py-kms) behave this way.
.IP "\fB-k\fR"
Do not disconnect clients after processing an activation request. This selects the default behavior. \fB-k\fR is useful only if you used an ini file (see \fBvlmcsd.ini\fR(5) and \fB-i\fR). If the ini file contains the line "DisconnectClientsImmediately = true", you can use this switch to restore the default behavior.
.IP "\fB-N0\fR and \fB-N1\fR
Disables (\fB-N0\fR) or enables (\fB-N1\fR) the use of the NDR64 transfer syntax in the RPC protocol. Unlike Microsoft vlmcsd supports NDR64 on 32-bit operating systems. Microsoft introduced NDR64 in Windows Vista but their KMS servers started using it with Windows 8. Thus if you choose random ePIDs, vlmcsd will select ePIDs with build numbers 9200 and 9600 if you enable NDR64 and build numbers 6002 and 7601 if you disable NDR64. The default is to enable NDR64.
.IP "\fB-B0\fR and \fB-B1\fR"
Disables (\fB-B0\fR) or enables (\fB-B1\fR) bind time feature negotiation (BTFN) in the RPC protocol. All Windows operating systems starting with Vista support BTFN and try to negotiate it when initiating an RPC connection. Thus consider turning it off as a debug / troubleshooting feature only. Some older firewalls that selectively block or redirect RPC traffic may get confused when they detect NDR64 or BTFN.
.IP "\fB-l\fR \fIfilename\fR
Use \fIfilename\fR as a log file. The log file records all activations with IP address, Windows workstation name (no reverse DNS lookup), activated product, KMS protocol, time and date. If you do not specify a log file, no log is created. For a live view of the log file
type tail -f \fIfile\fR.
.PP
.IP
If you use the special \fIfilename\fR "syslog", vlmcsd uses \fBsyslog\fR(3) for logging. If your system has no syslog service (/dev/log) installed, logging output will go to /dev/console. Syslog logging is not available in the native Windows version. The Cygwin version does support syslog logging.
.IP "\fB-T0\fR and \fB-T1\fR"
Disable (\fB-T0\fR) or enable (\fB-T1\fR) the inclusion of date and time in each line of the log. The default is \fB-T1\fR. \fB-T0\fR is useful if you log to \fBstdout\fR(3) which is redirected to another logging mechanism that already includes date and time in its output, for instance \fBsystemd-journald\fR(8). If you log to \fBsyslog\fR(3), \fB-T1\fR is ignored and date and time will never be included in the output sent to \fBsyslog\fR(3).
.IP "\fB-D\fR"
Normally vlmcsd daemonizes and runs in background (except the native Windows version). If \fB-D\fR is specified, vlmcsd does not daemonize and runs in foreground. This is useful for testing and allows you to simply press <Ctrl-C> to exit vlmcsd.
.PP
.IP
The native Windows version never daemonizes and always behaves as if \fB-D\fR had been specified. You may want to install vlmcsd as a service instead. See \fB-s\fR.
.IP "\fB-e\fR"
If specified, vlmcsd ignores \fB-l\fR and writes all logging output to \fBstdout\fR(3). This is mainly useful for testing and debugging and often combined with \fB-D\fR.
.IP "\fB-v\fR"
Use verbose logging. Logs every parameter of the base request and the base response. It also logs the HWID of the KMS server if KMS protocol version 6 is used. This option is mainly for debugging purposes. It only has an effect if some form of logging is used. Thus \fB-v\fR does not make sense if not used with \fB-l\fR, \fB-e\fR or \fB-f\fR.
.IP "\fB-q\fR"
Do not use verbose logging. This is actually the default behavior. It only makes sense if you use vlmcsd with an ini file (see \fB-i\fR and \fBvlmcsd.ini\fR(5)). If the ini file contains the line "LogVerbose = true" you can use \fB-q\fR to restore the default behavior.
.IP "\fB-p\fR \fIfilename\fR"
Create pid file \fIfilename\fR. This has nothing to do with KMS ePIDs. A pid file is a file where vlmcsd writes its own process id. This is used by standard init scripts (typically found in /etc/init.d). The default is not to write a pid file.
.IP "\fB-u\fR \fIuser\fR and \fB-g\fR \fIgroup\fR"
Causes vlmcsd to run in the specified \fIuser\fR and \fIgroup\fR security context. The main purpose for this is to drop root privileges after it has been started from the root account. To use this feature from cygwin you must run cyglsa-config and the account from which vlmcsd is started must have the rights "Act as part of the operating system" and "Replace a process
level token". The native Windows version does not support these options.
.PP
.IP
The actual security context switch is performed after the TCP sockets have been created. This allows you to use privileged ports (< 1024) when you start vlmcsd from the root account.
.PP
.IP
However if you use an ini, pid or log file, you must ensure that the unprivileged user has access to these files. You can always log to \fBsyslog\fR(3) from an unprivileged account on most platforms (see \fB-l\fR).
.IP "\fB-a\fR \fICSVLK\fR = \fIePID\fR [ / \fIHwId\fR ]"
Use \fIePID\fR and \fIHwId\fR for a specific \fICSVLK\fR. When you use it, \fB-r\fR is disregarded for this \fICSVLK\fR. If vlmcsd uses the default vlmcsd.kmd database, you can use the following \fICSVLK\fRs: Windows, WinChinaGov, Office2010, Office2013, Office2016 and Office2019. The \fB-a\fR option requires that database version 1.6 or later is used.
\fIHwId\fR must be specified as 16 hex digits that are interpreted as a series of 8 bytes (big endian). Any character that is not a hex digit will be ignored. This is for better readability.
.IP "\fB-i\fR \fIfilename\fR"
Use configuration file (aka ini file) \fIfilename\fR. Most configuration parameters can be set either via the command line or an ini file. The command line always has precedence over configuration items in the ini file. See \fBvlmcsd.ini\fR(5) for the format of the configuration file.
If vlmcsd has been compiled to use a default configuration file (often /etc/vlmcsd.ini), you may use \fB-i-\fR to ignore the default configuration file.
.IP "\fB-j\fR \fIfilename\fR"
Use KMS data file \fIfilename\fR. By default vlmcsd only contains the minimum product data that is required to perform all operations correctly. You may use a more complete KMS data file that contains all detailed product names. This is especially useful if you are logging KMS requests. If you don't log, there is no need to load an external KMS data file.
If vlmcsd has been compiled to use a default KMS data file, you may use \fB-j-\fR to ignore the default configuration file.
.IP "\fB-r0\fR, \fB-r1\fR (default) and \fB-r2\fR"
These options determine how ePIDs are generated if
- you did not sprecify an ePID in the command line and
.br
- you haven't used \fB-i\fR or
.br
- the file specified by \fB-i\fR cannot be opened or
.br
- the file specified by \fB-i\fR does not contain an ePID for the KMS request
\fB-r0\fR means there are no random ePIDs. vlmcsd simply issues default ePIDs that are built into the binary at compile time. \fBPro:\fR behaves like real KMS server that also always issues the same ePID. \fBCon:\fR Microsoft may start blacklisting again and the default ePID may not work any longer.
\fB-r1\fR instructs vlmcsd to generate random ePIDs when the program starts or receives a SIGHUP signal and uses these ePIDs until it is stopped or receives another SIGHUP. Most other KMS emulators generate a new ePID on every KMS request. This is easily detectable. Microsoft could just modify sppsvc.exe in a way that it always sends two identical KMS requests in two RPC requests but over the same TCP connection. If both KMS responses contain the different ePIDs, the KMS server is not genuine. \fB-r1\fR is the default mode. \fB-r1\fR also ensures that all three ePIDs (Windows, Office 2010 and Office 2013) use the same OS build number and LCID (language id).
If vlmcsd has been started by an internet superserver, \fB-r1\fR works almost identically to \fB-r2\fR. The only exception occurs if you send more than one activation request over the same TCP connection. This is simply due to the fact that vlmcsd is started upon a connection request and does not stay in memory after servicing a KMS request. Consider using \fB-r0\fR or \fB-w\fR, \fB-G\fR, \fB-0\fR, \fB-3\fR and \fB-6\fR when starting vlmcsd by an internet superserver.
\fB-r2\fR behaves like most other KMS server emulators with random support and generates a new random ePID on every request. \fB-r2\fR should be treated as debugging option only because it allows very easy emulator detection.
.IP "\fB-C\fR \fILCID\fR"
Do not randomize the locale id part of the ePID and use \fILCID\fR instead. The \fILCID\fR must be specified as a decimal number, e.g. 1049 for "Russian - Russia". This option has no effect if the ePID is not randomized at all, e.g. if it is selected from the command line or an ini file.
By default vlmcsd generates a valid locale id that is recognized by .NET Framework 4.0. This may lead to a locale id which is unlikely to occur in your country, for instance 2155 for "Quecha - Ecuador". You may want to select the locale id of your country instead. See
.URL "http://msdn.microsoft.com/en-us/goglobal/bb964664.aspx" "MSDN" ""
for a list of valid \fILCID\fRs. Please note that some of them are not recognized by .NET Framework 4.0.
Most other KMS emulators use a fixed \fILCID\fR of 1033 (English - US). To achive the same behavior in vlmcsd use \fB-C 1033\fR.
.IP "\fB-H\fR \fIHostBuild\fR"
Do not randomize the host build number in the ePID and use \fIHostBuild\fR instead, for instance 17763 for Windows Server 2019 / Windows 10 1809.
.IP "\fB-K0\fR, \fB-K1\fR, \fB-K2\fR and \fB-K3\fR"
Sets the whitelisting level to determine which products vlmcsd activates or refuses. The default is \fB-K0\fR.
.RS 12
\fB-K0\fR: activate all products with an unknown, retail or beta/preview KMS ID.
.br
\fB-K1\fR: activate products with a retail or beta/preview KMS ID but refuse to activate products with an unknown KMS ID.
.br
\fB-K2\fR: activate products with an unknown KMS ID but refuse products with a retail or beta/preview KMS ID.
.br
\fB-K3\fR: activate only products with a known volume license RTM KMS ID and refuse all others.
.RE
.IP ""
The SKU ID is not checked. Like a genuine KMS server vlmcsd activates a product that has a random or unknown SKU ID. If you select \fB-K1\fR or \fB-K3\fR, vlmcsd also checks the Application ID for correctness. If Microsoft introduces a new KMS ID for a new product, you cannot activate it if you used \fB-K1\fR or \fB-K3\fR until a new version of vlmcsd is available.
.IP "\fB-c0\fR and \fB-c1\fR"
\fB-c1\fR causes vlmcsd to check if the client time differs no more than four hours from the system time. \fB-c0\fR (the default) disables this check. \fB-c1\fR is useful to prevent emulator detection. A client that tries to detect an emulator could simply send two subsequent request with two time stamps that differ more than four hours from each other. If both requests succeed, the server is an emulator. If you specify \fB-c1\fR on a system with no reliable time source, activations will fail. It is ok to set the correct system time after you started vlmcsd.
.IP "\fB-M0\fR and \fB-M1\fR"
Disables (\fB-M0\fR) or enables (\fB-M1\fR) maintaining a list of client machine IDs (CMIDs). The default is \fB-M0\fR. \fB-M1\fR is useful to prevent emulator detection. By maintaing a CMID list, vlmcsd reports current active clients exactly like a genuine KMS emulator. This includes bug compatibility to the extent that you can permanently kill a genuine KMS emulator by sending an "overcharge request" with a required client count of 376 or more and then request activation for 671 clients. vlmcsd can be reset from this condition by restarting it. If \fB-M0\fR is used, vlmcsd reports current active clients as good as possible. If no client sends an "overcharge request", it is not possible to detect vlmcsd as an emulator with \fB-M0\fR. \fB-M1\fR requires the allocation of a buffer that is about 50 kB in size. On hardware with few memory resources use it only if you really need it.
If you start vlmcsd from an internet superserver, \fB-M1\fR cannot be used. Since vlmcsd exits after each activation, it cannot maintain any state in memory.
.IP "\fB-E0\fR and \fB-E1\fR"
These options are ignored if you do not also specify \fB-M1\fR. If you use \fB-E0\fR (the default), vlmcsd starts up as a fully "charged" KMS server. Clients activate immediately. \fB-E1\fR lets you start up vlmcsd with an empty CMID list. Activation will start when the required minimum clients (25 for Windows Client OSses, 5 for Windows Server OSses and Office) have registered with the KMS server. As long as the minimum client count has not been reached, clients end up in HRESULT 0xC004F038 "The count reported by your Key Management Service (KMS) is insufficient. Please contact your system administrator". You may use \fBvlmcs\fR(1) or another KMS client emulator to "charge" vlmcsd. \fB-E1\fR does not improve emulator detection prevention. It's primary purpose is to help developers of KMS clients to test "charging" a KMS server.
.IP "\fB-R\fR \fIrenewal-interval\fR"
Instructs clients to renew activation every \fIrenewal-interval\fR. The \fIrenewal-interval\fR is a number optionally immediately followed by a letter indicating the unit. Valid unit letters are s (seconds), m (minutes), h (hours), d (days) and w (weeks). If you do not specify a letter, minutes is assumed.
\fB-R3d\fR for instance instructs clients to renew activation every 3 days. The default \fIrenewal-interval\fR is 10080 (identical to 7d and 1w).
Due to poor implementation of Microsofts KMS Client it cannot be guaranteed that activation is renewed on time as specfied by the -R option. Don't care about that. Renewal will happen well before your activation expires (usually 180 days).
Even though you can specify seconds, the granularity of this option is 1 minute. Seconds are rounded down to the next multiple of 60.
.IP "\fB-A\fR \fIactivation-interval\fR"
Instructs clients to retry activation every \fIactivation-interval\fR if it was
unsuccessful, e.g. because it could not reach the server. The default is 120 (identical to 2h). \fIactivation-interval\fR follows the same syntax as \fIrenewal-interval\fR in the
\fB-R\fR option.
.IP "\fB-s\fR"
Installs vlmcsd as a Windows service. This option only works with the native Windows version and Cygwin. Combine \fB-s\fR with other command line options. These will be in effect when you start the service. The service automatically starts when you reboot your machine. To start it manually, type "net start vlmcsd".
If you use Cygwin, you must include your Cygwin system DLL directory (usually C:\eCygwin\ebin or C:\eCygwin64\ebin) into the PATH environment variable or the service will not start.
You can reinstall the service anytime using vlmcsd -s again, e.g. with a different command line. If the service is running, it will be restarted with the new command line.
When using \fB-s\fR the command line is checked for basic syntax errors only. For example "vlmcsd -s -L 1.2.3.4" reports no error but the service will not start if 1.2.3.4 is not an IP address on your system.
.IP "\fB-S\fR"
Uninstalls the vlmcsd service. Works only with the native Windows version and Cygwin. All other options will be ignored if you include -S in the command line.
.IP "\fB-U\fR [\fIdomain\fR\e]\fIusername\fR"
Can only be used together with \fB-s\fR. Starts the service as a different user than the local SYSTEM account. This is used to run the service under an account with low privileges. If you omit the domain, an account from the local computer will be used.
You may use "NT AUTHORITY\eNetworkService". This is a pseudo user with low privileges. You may also use "NT AUTHORITY\eLocalService" which has more privileges but these are of no use for running vlmcsd.
Make sure that the user you specify has at least execute permission for your executable. "NT AUTHORITY\eNetworkService" normally has no permission to run binaries from your home directory.
For your convenience you can use the special username "/l" as a shortcut for "NT AUTHORITY\eLocalService" and "/n" for "NT AUTHORITY\eNetworkService". "vlmcsd\ \-s\ \-U\ /n" installs the service to run as "NT AUTHORITY\eNetworkService".
.IP "\fB-W\fR \fIpassword\fR"
Can only be used together with \fB-s\fR. Specifies a \fIpassword\fR for the corresponding username you use with -U. SYSTEM, "NT AUTHORITY\eNetworkService", "NT AUTHORITY\eLocalService" do not require a password.
If you specify a user with even lower privileges than "NT AUTHORITY\eNetworkService", you must specify its password. You also have to grant the "Log on as a service" right to that user.
.SH SIGNALS
The following signals differ from the default behavior:
.IP "\fBSIGTERM\fR, \fBSIGINT\fR"
These signals cause vlmcsd to exit gracefully. All global semaphores and shared memory pages will be released, the pid file will be unlinked (deleted) and a shutdown message will be logged.
.IP "\fBSIGHUP\fR"
Causes vlmcsd to be restarted completely. This is useful if you started vlmcsd with an ini file. You can modify the ini file while vlmcsd is running and then sending \fBSIGHUP\fR, e.g. by typing "killall -SIGHUP vlmcsd" or "kill -SIGHUP `cat /var/run/vlmcsd.pid`".
The SIGHUP handler has been implemented relatively simple. It is virtually the same as stopping vlmcsd and starting it again immediately with the following exceptions:
.RS
.IP "\(em" 3
The new process does not get a new process id.
.IP "\(em" 3
If you used a pid file, it is not deleted and recreated because the process id stays the same.
.IP "\(em" 3
If you used the 'user' and/or 'group' directive in an ini file these are ignored. This is because once you switched to lower privileged users and groups, there is no way back. Anything else would be a severe security flaw in the OS.
.RE
Signaling is not available in the native Windows version and in the Cygwin version when vlmcsd runs as a Windows service.
.SH SUPPORTED OPERATING SYSTEMS
\fBvlmcsd\fR compiles and runs on Linux, Windows (no Cygwin required but explicitly supported), Mac OS X, FreeBSD, NetBSD, OpenBSD, Dragonfly BSD, Minix, Solaris, OpenIndiana, Android and iOS. Other POSIX or unixoid OSses may work with unmodified sources or may require minor porting efforts.
.SH SUPPORTED PRODUCTS
\fBvlmcsd\fR can answer activation requests for the following products: Windows Vista, Windows 7, Windows 8, Windows 8.1, Windows 10 (up to 1809), Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2, Windows Server 2016, Office 2010, Project 2010, Visio 2010, Office 2013, Project 2013, Visio 2013, Office 2016, Project 2016, Visio 2016, Office 2019, Project 2019, Visio 2019. Newer products may work as long as the KMS protocol does not change. A complete list of fully supported products can be obtained using the \fB-x\fR option of \fBvlmcs\fR(1).
.PP
Windows Vista, Windows 7, Office, Project and Visio must be volume license versions.
.SH FILES
.IP "\fBvlmcsd.ini\fR(5)"
.SH EXAMPLES
.IP "\fBvlmcsd -De\fR"
Starts \fBvlmcsd\fR in foreground. Useful if you use it for the first time and want to see what's happening when a client requests activation.
.IP "\fBvlmcsd -l /var/log/vlmcsd.log\fR"
Starts \fBvlmcsd\fR as a daemon and logs everything to /var/log/vlmcsd.log.
.IP "\fBvlmcsd -L 192.168.1.17"
Starts \fBvlmcsd\fR as a daemon and listens on IP address 192.168.1.17 only. This is useful for routers that have a public and a private IP address to prevent your KMS server from becoming public.
.IP "\fBvlmcsd -s -U /n -l C:\elogs\evlmcsd.log"
Installs \fBvlmcsd\fR as a Windows service with low privileges and logs everything to C:\elogs\evlmcsd.log when the service is started with "net start vlmcsd".
.SH BUGS
An ePID specified in an ini file must not contain spaces.
.SH AUTHOR
Written by crony12, Hotbird64 and vityan666.
With contributions from DougQaid.
.SH CREDITS
Thanks to abbodi1406, CODYQX4, deagles, eIcn, mikmik38, nosferati87, qad, Ratiborus, ...
.SH SEE ALSO
\fBvlmcsd.ini\fR(5), \fBvlmcsd\fR(7), \fBvlmcs\fR(1), \fBvlmcsdmulti\fR(1)

206
man/vlmcsd.ini.5 Normal file
View File

@ -0,0 +1,206 @@
.TH VLMCSD.INI 5 "October 2018" "Hotbird64" "KMS Activation Manual"
.LO 8
.SH NAME
\fBvlmcsd.ini\fR \- vlmcsd KMS emulator configuration file
.SH SYNOPSIS
.B vlmcsd.ini
.SH DESCRIPTION
\fBvlmcsd.ini\fR (or simply called the "ini file") is a configuration file for \fBvlmcsd\fR(8). By default vlmcsd does not use a configuration file. It is completely optional and for advanced users only. You must use the \fB-i\fR option on the vlmcsd command line to use an ini file. There is no default name or default location for the ini file.
.PP
Everything, that can be configured in the ini file, may also be specified on the command line. Any configuration option specified on the command line takes precedence over the respective configuration line in the ini file.
.PP
\fBBenefits of a configuration file\fR
.PP
While you can use the configuration file to simply modify the default behavior of vlmcsd, it can also be used to change the configuration of vlmcsd after you sent a HUP \fBsignal\fR(7). Whenever you send SIGHUP, the configuration file will be re-read. Any changes you made to the ini file will be reflected after vlmcsd received the hangup signal.
.PP
\fBDifferences between command line and configuration file\fR
.PP
If you specify an illegal option or option argument on the command line, vlmcsd displays help and exits. If you specify an incorrect \fIkeyword\fR or \fIargument\fR in the ini file, vlmcsd displays a warning with some information, ignores the respective line and continues. This is intentional and prevents vlmcsd from aborting after a SIGHUP if the configuration was modified incorrectly.
.SH SYNTAX
vlmcsd.ini is a UTF-8 encoded text file with each line being in the format \fIkeyword\fR = \fIargument\fR. The \fIkeyword\fR is not case-sensitive. The \fIargument\fR is treated literally. It is neither required nor allowed to enclose the \fIargument\fR in any form of quote characters except when quote characters are part of the argument itself. Whitespace characters are ignored only
- at the beginning of a line
.br
- between the \fIkeyword\fR and '='
.br
- between '=' and the \fIargument\fR
Lines, that start with '#' or ';' are treated as comments. Empty lines are ignored as well. If a \fIkeyword\fR is repeated in another line, vlmcsd will use the \fIargument\fR of the last occurence of the \fIkeyword\fR. An exception to this is the Listen \fIkeyword\fR which can be specified multiple times and causes vlmcsd to listen on more than one IP address and/or port.
.PP
Some \fIargument\fRs are binary arguments that need to be either TRUE or FALSE. You can use "Yes", "On" or "1" as an alias for TRUE and "No", "Off" or "0" as an alias for FALSE. Binary arguments are case-insensitive.
.SH KEYWORDS
The following \fIkeyword\fRs are defined (not all keywords may be available depending on the operating system and the options used when \fBvlmcsd\fR(8) was compiled):
.IP "\fBListen\fR"
This defines on what combinations of IP addresses and ports vlmcsd should listen. \fBListen\fR can be specified more than once. The \fIargument\fR has the form \fIipaddress\fR[:\fIport\fR]. If you omit the \fIport\fR, the default port of 1688 is used. If the \fIipaddress\fR contains colons and a \fIport\fR is used, you must enclose the \fIipaddress\fR in brackets. The default is to listen to 0.0.0.0:1688 and [::]:1688 which means listen to all IPv4 and all IPv6 addresses. See the \fB-L\fR option in \fBvlmcsd\fR(8) for more info about the syntax. If you use \fB-L\fR or \fB-P\fR on the command line, all \fBListen\fR keywords in the ini file will be ignored. The \fBListen\fR keyword cannot be used if vlmcsd has been compiled to use Microsoft RPC (Windows and Cygwin only) or simple sockets.
Examples:
Listen = 192.168.1.123:1688
.br
Listen = 0.0.0.0:1234
.br
Listen = [fe80::1721:12ff:fe81:d36b%eth0]:1688
.IP "\fBPort\fR"
Can only be used if vlmcsd has been compiled to use simple sockets or on Windows and Cygwin if \fBvlmcsd\fR(8) has been compiled to use Microsoft RPC. Otherwise you must use \fBListen\fR instead. Causes vlmcsd to listen on that port instead of 1688.
.IP "\fBFreeBind\fR"
Can be TRUE or FALSE. If TRUE, you can use the \fBListen\fR keyword with IP addresses that are currently not defined on your system. \fBvlmcsd\fR(8) will start listening on these IP addresses as soon as they become available. This keyword is only available under Linux and FreeBSD because no other OS currently supports that feature. FreeBSD supports this only for IPv4 and requires the PRIV_NETINET_BINDANY privilege which is normally assigned to proccesses of the root user.
.IP "\fBPublicIPProtectionLevel\fR"
Set the level of protection against KMS activations from public IP addresses.
0 = No protection (default)
.br
1\ =\ Listen on private IP addresses only (plus those specified by one or more \fBListen\fR statements)
.br
2\ =\ Disconnect clients with public IP addresses without activating
.br
3\ =\ Combines 1 and 2
For details on public IP protection levels see \fBvlmcsd\fR(8) command line option \fB-o\fR.
.IP "\fBVPN\fR"
Has to be in the form \fIvpn-adapter-name\fR[=\fIipv4-address\fR][/\fIcidr-mask\fR][:\fIdhcp-lease-duration\fR].
Enables a compatible VPN adapter to create additional local IPv4 addresses (like 127.0.0.1) that appear as remote IPv4 addresses to the system. This allows product activation using a local instance of vlmcsd. This feature is only available in Windows and Cygwin builds of vlmcsd since it is not of any use on other operating systems. Compatible VPN adapters are Tap-windows version 8.2 or higher (from OpenVPN) and the TeamViewer VPN adapter. There is a special \fIvpn-adapter-name\fR. A single period (.) instructs vlmcsd to use the first available compatible VPN adapter. The \fIvpn-adapter-name\fR is \fBnot\fR case-sensitive. If the \fIvpn-adapter-name\fR contains spaces (e.g. Ethernet 3), do \fBnot\fR enclose it in quotes.
The default \fIipv4-address\fR is 10.10.10.9 and the default \fIcidr-mask\fR is 30. If you are using the default values, your VPN adapter uses an IPv4 address of 10.10.10.9 and you can set your activation client to use the easy to remember address 10.10.10.10 (e.g. slmgr /skms 10.10.10.10 or cscript ospp.vbs /sethst:10.10.10.10).
The \fIdhcp-lease-duration\fR is a number optionally followed by s, m, h, d or w to indicate seconds, minutes, hours, days or weeks. The default \fIdhcp-lease-duration\fR is 1d (one day). It is normally not required to change this value.
It is advised not to manually configure your OpenVPN TAP or TeamViewer VPN adapter in "Network Connections". If you set the IPv4 configuration manually anyway, the IPv4 address and the subnet mask must match the \fBVPN=\fR directive. It is safe leave the IPv4 configuration to automatic (DHCP). vlmcsd will wait up to four seconds for the DHCP configuration to complete before binding to and listenin on any interfaces.
You should be aware that only one program can use a VPN adapter at a time. If you use the TeamViewer VPN adapter for example, you will not be able to use the VPN feature of TeamViewer as long as vlmcsd is running. The same applies to OpenVPN TAP adapters that are in use by other programs (for example OpenVPN, QEMU, Ratiborus VM, aiccu, etc.). The best way to avoid conflicts is to install Tap-Windows from OpenVPN, cd to C:\\Program Files\\TAP-Windows\\bin and run addtap.bat to install an additional TAP adapter. Go to "Network Connections" and rename the new adapter to "vlmcsd" and specify \fBVPN=vlmcsd\fR to use it.
.IP "\fBExitLevel"
Can be either 0 (the default) or 1. Controls under what circumstances vlmcsd will exit. Using the default of \fB0\fR vlmcsd stays active as long as it can perform some useful operations. If vlmcsd is run by any form of a watchdog, e.g. NT service manager (Windows), systemd (Linux) or launchd (Mac OS / iOS), it may be desirable to end vlmcsd and let the watchdog restart it. This is especially true if some pre-requisites are not yet met but will be some time later, e.g. network is not yet fully setup.
By using \fBExitLevel = 0\fR vlmcsd will
.RS 12
exit if none of the listening sockets specified with \fB-L\fR can be used. It continues if at least one socket can be setup for listening.
exit any TAP mirror thread (Windows version only) if there is an error condition while reading or writing from or to the VPN adapter but continue to work without utilizing a VPN adapter.
.RE
.IP
By using \fBExitLevel = 1\fR vlmcsd will
.RS 12
exit if not all listening sockets specified with \fB-L\fR can be used.
exit completely if there is a problem with a VPN adapter it is using. This may happen for instance if the VPN adapter has been disabled using "Control Panel - Network - Adapter Settings" while vlmcsd is using it.
.RE
.IP
Please note that \fBExitLevel = 1\fR is kind of a workaround option. While it may help under some circumstances, it is better to solve the problem at its origin, e.g. properly implementing dependencies in your startup script to ensure all network interfaces and the VPN adapter you will use are completely setup before you start vlmcsd.
.IP "\fBUseNDR64\fR"
Can be TRUE or FALSE. Specifies whether you want to use the NDR64 transfer syntax. See options \fB-n0\fR and \fB-n1\fR in \fBvlmcsd\fR(8). The default is TRUE.
.IP "\fBUseBTFN\fR"
Can be TRUE or FALSE. Specifies whether you want to use bind time feature negotiation in RPC. See options \fB-b0\fR and \fB-b1\fR in \fBvlmcsd\fR(8). The default is TRUE.
.IP "\fBRandomizationLevel\fR"
The \fIargument\fR must 0, 1 or 2. This specifies the ePID randomization level. See options \fB-r0\fR, \fB-r1\fR and \fB-r2\fR in \fBvlmcsd\fR(8). The default randomization level is 1. A \fBRandomizationLevel\fR of 2 is not recommended and should be treated as a debugging level.
.IP "\fBLCID\fR"
Use a specific culture id (LCID) even if the ePID is randomized. The \fIargument\fR must be a number between 1 and 32767. While any number in that range is valid, you should use an offcial LCID. A list of assigned LCIDs can be found at http://msdn.microsoft.com/en\-us/goglobal/bb964664.aspx. On the command line you control this setting with option \fB-C\fR.
.IP "\fBHostBuild\fR"
Use a specific host build number in the ePID even if it is randomized. The \fIargument\fR must be a number between 1 and 65535. While you can use any number you should only use build numbers that a released build numbers of Windows Servers, e.g. 17763 for Windows Server 2019.
.IP "\fBMaxWorkers\fR"
The \fIargument\fR specifies the maximum number of worker processes or threads that will be used to serve activation requests concurrently. This is the same as specifying \fB-m\fR on the command line. Minimum is 1. The maximum is platform specific and is at least 32767 but is likely to be greater on most systems. The default is no limit.
.IP "\fBConnectionTimeout\fR"
Used to control when the vlmcsd disconnects idle TPC connections. The default is 30 seconds. This is the same setting as \fB-t\fR on the command line.
.IP "\fBDisconnectClientsImmediately\fR"
Set this to TRUE to disconnect a client after it got an activation response regardless whether a timeout has occured or not. The default is FALSE. Setting this to TRUE is non-standard behavior. Use only if you are experiencing DoS or DDoS attacks. On the command line you control this behavior with options \fB-d\fR and \fB-k\fR.
.IP "\fBPidFile\fR"
Write a pid file. The \fIargument\fR is the full pathname of a pid file. The pid file contains is single line containing the process id of the vlmcsd process. It can be used to stop (SIGTERM) or restart (SIGHUP) vlmcsd. This directive can be overriden using \fB-p\fR on the command line.
.IP "\fBLogFile\fR"
Write a log file. The \fIargument\fR is the full pathname of a log file. On a unixoid OS and with Cygwin you can use the special filename 'syslog' to log to the syslog facility. This is the same as specifying \fB-l\fR on the command line.
.IP "\fBKmsData\fR"
Use a KMS data file. The \fIargument\fR is the full pathname of a KMS data file. By default vlmcsd only contains the minimum product data that is required to perform all operations correctly. You may use a more complete KMS data file that contains all detailed product names. This is especially useful if you are logging KMS requests. If you don't log, there is no need to load an external KMS data file.
You may use \fBKmsData\ =\ \-\fR to prevent the default KMS data file to be loaded.
.IP "\fBLogDateAndTime\fR"
Can be TRUE or FALSE. The default is TRUE. If set to FALSE, logging output does not include date and time. This is useful if you log to \fBstdout\fR(3) which is redirected to another logging mechanism that already includes date and time in its output, for instance \fBsystemd-journald\fR(8). If you log to \fBsyslog\fR(3), \fBLogDateAndTime\fR is ignored and date and time will never be included in the output sent to \fBsyslog\fR(3). Using the command line you control this setting with options \fB-T0\fR and \fB-T1\fR.
.IP "\fBLogVerbose\fR"
Set this to either TRUE or FALSE. The default is FALSE. If set to TRUE, more details of each activation will be logged. You use \fB-v\fR and \fB-q\fR in the command line to control this setting. \fBLogVerbose\fR has an effect only if you specify a log file or redirect logging to \fBstdout\fR(3).
.IP "\fBWhitelistingLevel\fR"
Can be 0, 1, 2 or 3. The default is 0. Sets the whitelisting level to determine which products vlmcsd activates or refuses.
.RS 12
\fB0\fR: activate all products with an unknown, retail or beta/preview KMS ID.
.br
\fB1\fR: activate products with a retail or beta/preview KMS ID but refuse to activate products with an unknown KMS ID.
.br
\fB2\fR: activate products with an unknown KMS ID but refuse products with a retail or beta/preview KMS ID.
.br
\fB3\fR: activate only products with a known volume license RTM KMS ID and refuse all others.
.RE
.IP ""
The SKU ID is not checked. Like a genuine KMS server vlmcsd activates a product that has a random or unknown SKU ID. If you select \fB1\fR or \fB3\fR, vlmcsd also checks the Application ID for correctness. If Microsoft introduces a new KMS ID for a new product, you cannot activate it if you used \fB1\fR or \fB3\fR until a new version of vlmcsd is available.
.IP "\fBCheckClientTime\fR"
Can be TRUE or FALSE. The default is FALSE. If you set this to TRUE \fBvlmcsd\fR(8) checks if the client time differs no more than four hours from the system time. This is useful to prevent emulator detection. A client that tries to detect an emulator could simply send two subsequent request with two time stamps that differ more than four hours from each other. If both requests succeed, the server is an emulator. If you set this to TRUE on a system with no reliable time source, activations will fail. It is ok to set the correct system time after you started \fBvlmcsd\fR(8).
.IP "\fBMaintainClients\fR"
Can be TRUE or FALSE (the default). Disables (FALSE) or enables (TRUE) maintaining a list of client machine IDs (CMIDs). TRUE is useful to prevent emulator detection. By maintaing a CMID list, \fBvlmcsd\fR(8) reports current active clients exactly like a genuine KMS emulator. This includes bug compatibility to the extent that you can permanently kill a genuine KMS emulator by sending an "overcharge request" with a required client count of 376 or more and then request activation for 671 clients. \fBvlmcsd\fR(8) can be reset from this condition by restarting it. If FALSE is used, \fBvlmcsd\fR(8) reports current active clients as good as possible. If no client sends an "overcharge request", it is not possible to detect \fBvlmcsd\fR(8) as an emulator with \fBMaintainClients\fR\~=\~FALSE. Maintaining clients requires the allocation of a buffer that is about 50 kB in size. On hardware with few memory resources use it only if you really need it.
If you start \fBvlmcsd\fR(8) from an internet superserver, this setting cannot be used. Since \fBvlmcsd\fR(8) exits after each activation, it cannot maintain any state in memory.
.IP "\fBStartEmpty\fR"
This setting is ignored if you do not also specify \fBMaintainClients\fR\~=\~TRUE. If you specify FALSE (the default), \fBvlmcsd\fR(8) starts up as a fully "charged" KMS server. Clients activate immediately. \fBStartEmpty\fR\~=\~TRUE lets you start up \fBvlmcsd\fR(8) with an empty CMID list. Activation will start when the required minimum clients (25 for Windows Client OSses, 5 for Windows Server OSses and Office) have registered with the KMS server. As long as the minimum client count has not been reached, clients end up in HRESULT 0xC004F038 "The count reported by your Key Management Service (KMS) is insufficient. Please contact your system administrator". You may use \fBvlmcs\fR(1) or another KMS client emulator to "charge" \fBvlmcsd\fR(8). Setting this parameter to TRUE does not improve emulator detection prevention. It's primary purpose is to help developers of KMS clients to test "charging" a KMS server.
.IP "\fBActivationInterval\fR"
This is the same as specifying \fB-A\fR on the command line. See \fBvlmcsd\fR(8) for details. The default is 2 hours. Example: ActivationInterval\~=\~1h
.IP "\fBRenewalInterval\fR"
This is the same as specifying \fB-R\fR on the command line. See \fBvlmcsd\fR(8) for details. The default is 7 days. Example: RenewalInterval = 3d. Please note that the KMS client decides itself when to renew activation. Even though vlmcsd sends the renewal interval you specify, it is no more than some kind of recommendation to the client. Older KMS clients did follow the recommendation from a KMS server or emulator. Newer clients do not.
.IP "\fBUser\fR"
Run vlmcsd as another, preferrably less privileged, user. The \fIargument\fR can be a user name or a numeric user id. You must have the required privileges (capabilities on Linux) to change the security context of a process without providing any credentials (a password in most cases). On most unixoid OSses 'root' is the only user who has these privileges in the default configuration. This setting is not available in the native Windows version of vlmcsd. See \fB-u\fR in \fBvlmcsd\fR(8). This setting cannot be changed on the fly by sending SIGHUP to vlmcsd.
.IP "\fBGroup\fR"
Run vlmcsd as another, preferrably less privileged, group. The \fIargument\fR can be a group name or a numeric group id. You must have the required privileges (capabilities on Linux) to change the security context of a process without providing any credentials (a password in most cases). On most unixoid OSses 'root' is the only user who has these privileges in the default configuration. This setting is not available in the native Windows version of vlmcsd. See \fB-g\fR in \fBvlmcsd\fR(8). This setting cannot be changed on the fly by sending SIGHUP to vlmcsd.
.IP "\fB<csvlk-name>\fR"
The \fIargument\fR has the form \fIePID\fR [ / \fIHwId\fR ]. Always use \fIePID\fR and \fIHwId\fR for activations with \fB<csvlk-name>\fR. If specified, \fBRandomizationLevel\fR for the \fB<csvlk-name>\fR will be ignored. With the default vlmcsd.kmd database you can use the following \fB<csvlk-name>\fRs: Windows, Office2010, Office2013, Office2016, Office2019 and WinChinaGov. While vlmcsd is compatible with older databases, you must use at least database version 1.6 for this feature to work.
.SH "VALID EPIDS"
The ePID is currently a comment only. You can specify any string up to 63 bytes. In Windows 7 Microsoft has blacklisted few ( < 10 ) ePIDs that were used in KMSv5 versions of the "Ratiborus Virtual Machine". Microsoft has given up on blacklisting when KMS emulators appeared in the wild.
Even if you can use "Activated by cool hacker guys" as an ePID, you may wish to use ePIDs that cannot be detected as non-MS ePIDs. If you don't know how these "valid" ePIDs look like exactly, do not use GUIDS in vlmcsd.ini. vlmcsd provides internal mechanisms to generate valid ePIDs.
If you use non-ASCII characters in your ePID (you shouldn't do anyway), these must be in UTF-8 format. This is especially important when you run vlmcsd on Windows or cygwin because UTF-8 is not the default encoding for most editors.
If you are specifying an optional HWID it follows the same syntax as in the \fB\-H\fR option in \fBvlmcsd\fR(8) ecxept that you must not enclose a HWID in quotes even if it contains spaces.
.SH FILES
.IP "\fBvlmcsd.ini\fR(5)"
.SH AUTHOR
\fBvlmcsd\fR(8) was written by crony12, Hotbird64 and vityan666. With contributions from DougQaid.
.SH CREDITS
Thanks to abbodi1406, CODYQX4, deagles, eIcn, mikmik38, nosferati87, qad, Ratiborus, ...
.SH SEE ALSO
\fBvlmcsd\fR(8), \fBvlmcsd\fR(7), \fBvlmcs\fR(1), \fBvlmcsdmulti\fR(1)

53
man/vlmcsdmulti.1 Normal file
View File

@ -0,0 +1,53 @@
.TH VLMCSDMULTI 1 "February 2015" "Hotbird64" "KMS Activation Manual"
.LO 1
.SH NAME
vlmcsdmulti \- a multi-call binary containing \fBvlmcs\fR(1) and \fBvlmcsd\fR(8)
.SH SYNOPSIS
\fBvlmcsdmulti\fR vlmcs [ \fIoptions\fR ] [ \fIhostname\fR|\fIip-address\fR[:\fIport\fR] ] [ \fIoptions\fR ] | vlmcsd [ \fIoptions\fR ]
.SH DESCRIPTION
\fBvlmcsdmulti\fR is a multi-call binary that contains \fBvlmcs\fR(1) and \fBvlmcsd\fR(8) in a single binary. Since both programs share a lot of code and data, the combined binary is significantly smaller than the sum of both files.
.PP
\fBvlmcsdmulti\fR should not be called directly. Instead you may want to create symbolic links named vlmcs and vlmcsd which point to \fBvlmcsdmulti\fR. You then use these links to call the respective program. You may however call \fBvlmcsdmulti\fR followed by a complete command line of either \fBvlmcs\fR(1) or \fBvlmcsd\fR(8).
.SS Creating symbolic links in unixoid operating systems
cd to the directory containing \fBvlmcsdmulti\fR and type
.PP
ln -s vlmcsdmulti vlmcsd
.br
ln -s vlmcsdmulti vlmcs
.PP
You may use a destination directory, e.g.
.PP
ln -s vlmcsdmulti /usr/local/sbin/vlmcsd
.br
ln -s vlmcsdmulti /usr/local/bin/vlmcs
.PP
Ensure that \fBvlmcsdmulti\fR has execute permissions. You can do that by typing "chmod 755 vlmcsdmulti". See \fBchmod\fR(1) for details.
.SS Creating symbolic links in Windows (Vista and higher only)
cd to the directory containing \fBvlmcsdmulti\fR and type
.PP
mklink vlmcsd.exe vlmcsdmulti.exe
.br
mklink vlmcs.exe vlmcsdmulti.exe
.PP
You may use a destination directory, e.g.
.PP
mklink C:\\tools\\vlmcsd.exe vlmcsdmulti.exe
.br
mklink C:\\tools\\vlmcs.exe vlmcsdmulti.exe
.SS Memory considerations
While you definitely save disk space by using \fBvlmcsdmulti\fR you will need more RAM when you run \fBvlmcsdmulti\fR as a daemon (KMS server) instead of vlmcsd. You should consider running \fBvlmcsdmulti\fR via an internet superserver like \fBinetd\fR(8) or \fBxinetd\fR(8).
.SH BUGS
\fBvlmcsdmulti\fR has the same bugs as \fBvlmcs\fR(1) and \fBvlmcsd\fR(8).
.SH AUTHOR
Written by Hotbird64
.SH CREDITS
Thanks to CODYQX4, crony12, deagles, DougQaid, eIcn, mikmik38, nosferati87, qad, vityan666, ...
.SH SEE ALSO
\fBvlmcs\fR(1)\fB, vlmcsd\fR(8)\fB, vlmcsd\fR(7)

653
src/GNUmakefile Normal file
View File

@ -0,0 +1,653 @@
################################################################################
.PHONY: clean
PROGRAM_NAME ?= ../bin/vlmcsd
CLIENT_NAME ?= ../bin/vlmcs
MULTI_NAME ?= ../bin/vlmcsdmulti
OBJ_NAME ?= ../build/libkms-static.o
A_NAME ?= ../lib/libkms.a
CONFIG ?= config.h
COMPILER_LANGUAGE ?= c
BASE_PROGRAM_NAME=$(notdir $(PROGRAM_NAME))
BASE_CLIENT_NAME=$(notdir $(CLIENT_NAME))
BASE_MULTI_NAME=$(notdir $(MULTI_NAME))
BASE_DLL_NAME=$(notdir $(DLL_NAME))
BASE_A_NAME=$(notdir $(A_NAME))
ifeq (1,$(FROM_PARENT))
CLIENT_NAME_TEST=$(patsubst /%,/,$(CLIENT_NAME))
MULTI_NAME_TEST=$(patsubst /%,/,$(MULTI_NAME))
DLL_NAME_TEST=$(patsubst /%,/,$(DLL_NAME))
A_NAME_TEST=$(patsubst /%,/,$(A_NAME))
PROGRAM_NAME_TEST=$(patsubst /%,/,$(PROGRAM_NAME))
ifneq (/,$(PROGRAM_NAME_TEST))
PROGRAM_PREFIX=../
endif
ifneq (/,$(CLIENT_NAME_TEST))
CLIENT_PREFIX=../
endif
ifneq (/,$(MULTI_NAME_TEST))
MULTI_PREFIX=../
endif
ifneq (/,$(DLL_NAME_TEST))
DLL_PREFIX=../
endif
ifneq (/,$(A_NAME_TEST))
A_PREFIX=../
endif
endif
REAL_PROGRAM_NAME=$(PROGRAM_PREFIX)$(PROGRAM_NAME)
REAL_CLIENT_NAME=$(CLIENT_PREFIX)$(CLIENT_NAME)
REAL_MULTI_NAME=$(MULTI_PREFIX)$(MULTI_NAME)
REAL_DLL_NAME=$(DLL_PREFIX)$(DLL_NAME)
REAL_A_NAME=$(A_PREFIX)$(A_NAME)
# crypto library to use for standard algos, could save ~1-2kb ;)
# can be either 'openssl', 'polarssl' or anything other for internal impl
CRYPTO ?= internal
# use DNS_PARSER=internal if your OS doesn't supply the DNS parser routines
DNS_PARSER ?= OS
# You should supply your own version string here
VLMCSD_VERSION ?= $(shell test -d ../.git && git describe)
FEATURES ?= full
VERBOSE ?= NO
################################################################################
CC ?= gcc
TARGETPLATFORM := $(shell LANG=en_US.UTF-8 $(CC) -v 2>&1 | grep '^Target: ' | cut -f 2 -d ' ')
ifneq (,$(findstring darwin,$(TARGETPLATFORM)))
DARWIN := 1
UNIX := 1
endif
ifneq (,$(findstring android,$(TARGETPLATFORM)))
ANDROID := 1
UNIX := 1
ELF := 1
endif
ifneq (,$(findstring minix,$(TARGETPLATFORM)))
MINIX := 1
UNIX := 1
ELF := 1
endif
ifneq (,$(findstring mingw,$(TARGETPLATFORM)))
MINGW := 1
WIN := 1
PE := 1
endif
ifneq (,$(findstring cygwin,$(TARGETPLATFORM)))
CYGWIN := 1
WIN := 1
PE := 1
endif
ifneq (,$(findstring cygnus,$(TARGETPLATFORM)))
CYGWIN := 1
WIN := 1
PE := 1
endif
ifneq (,$(findstring freebsd,$(TARGETPLATFORM)))
FREEBSD := 1
UNIX := 1
BSD := 1
ELF := 1
endif
ifneq (,$(findstring netbsd,$(TARGETPLATFORM)))
NETBSD := 1
UNIX := 1
BSD := 1
ELF := 1
endif
ifneq (,$(findstring openbsd,$(TARGETPLATFORM)))
OPENBSD := 1
UNIX := 1
BSD := 1
ELF := 1
endif
ifneq (,$(findstring solaris,$(TARGETPLATFORM)))
SOLARIS := 1
UNIX := 1
ELF := 1
endif
ifneq (,$(findstring linux,$(TARGETPLATFORM)))
LINUX := 1
UNIX := 1
ELF := 1
endif
ifneq (,$(findstring gnu,$(TARGETPLATFORM)))
ifeq (,$(findstring linux,$(TARGETPLATFORM)))
UNIX := 1
HURD := 1
ELF := 1
endif
endif
ifeq ($(CYGWIN),1)
DLL_NAME ?= ../lib/cygkms.dll
else ifeq ($(WIN),1)
DLL_NAME ?= ../lib/libkms.dll
else ifeq ($(DARWIN),1)
DLL_NAME ?= ../lib/libkms.dylib
else
DLL_NAME ?= ../lib/libkms.so
endif
BASECFLAGS = -DVLMCSD_COMPILER=\"$(notdir $(CC))\" -DVLMCSD_PLATFORM=\"$(TARGETPLATFORM)\" -DCONFIG=\"$(CONFIG)\" -DBUILD_TIME=$(shell date '+%s') -g -Os -fno-strict-aliasing -fomit-frame-pointer -ffunction-sections -fdata-sections
BASELDFLAGS =
STRIPFLAGS =
CLIENTLDFLAGS =
SERVERLDFLAGS =
ifndef SAFE_MODE
BASECFLAGS += -fvisibility=hidden -pipe -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants
ifeq ($(ELF),1)
BASELDFLAGS += -Wl,-z,norelro
endif
ifneq (,$(findstring gcc,$(notdir $(CC))))
BASECFLAGS += -flto
endif
endif
ifeq ($(ELF), 1)
PICFLAGS += -fPIC
endif
ifeq ($(NOLIBS),1)
NOLRESOLV=1
NOLPTHREAD=1
endif
ifneq ($(NOLIBS),1)
ifeq ($(MINGW),1)
BASELDFLAGS += -lws2_32 -liphlpapi -lshlwapi
endif
endif
ifneq ($(NOLIBS),1)
ifeq ($(CYGWIN),1)
BASELDFLAGS += -liphlpapi
endif
endif
ifneq ($(NO_DNS),1)
ifneq ($(ANDROID),1)
ifneq ($(NOLRESOLV),1)
ifeq ($(MINGW),1)
CLIENTLDFLAGS += -ldnsapi
endif
ifeq ($(LINUX),1)
CLIENTLDFLAGS += -lresolv
endif
ifeq ($(HURD),1)
CLIENTLDFLAGS += -lresolv
endif
ifeq ($(DARWIN),1)
CLIENTLDFLAGS += -lresolv
endif
ifeq ($(CYGWIN),1)
DNS_PARSER := internal
CLIENTLDFLAGS += -lresolv
endif
ifeq ($(OPENBSD),1)
DNS_PARSER := internal
endif
ifeq ($(SOLARIS),1)
CLIENTLDFLAGS += -lresolv
endif
endif
endif
else
BASECFLAGS += -DNO_DNS
endif
ifneq ($(CAT),2)
BASECFLAGS += "-Wall"
endif
ifeq ($(DARWIN), 1)
STRIPFLAGS += -Wl,-S -Wl,-x
BASECFLAGS += -Wno-deprecated-declarations
else ifeq ($(shell uname), SunOS)
STRIPFLAGS += -s
ifeq ($(notdir $(LD_ALTEXEC)),gld)
BASELDFLAGS += -Wl,--gc-sections
endif
BASELDFLAGS += -lsocket
else
ifneq ($(CC),tcc)
BASELDFLAGS += -Wl,--gc-sections
endif
STRIPFLAGS += -s
endif
LIBRARY_CFLAGS = -DSIMPLE_SOCKETS -DNO_TIMEOUT -DNO_SIGHUP -DNO_CL_PIDS -DNO_LOG -DNO_RANDOM_EPID -DNO_INI_FILE -DNO_HELP -DNO_CUSTOM_INTERVALS -DNO_PID_FILE -DNO_USER_SWITCH -DNO_VERBOSE_LOG -DNO_LIMIT -DNO_VERSION_INFORMATION -DNO_PRIVATE_IP_DETECT -DNO_STRICT_MODES -DNO_CLIENT_LIST -DNO_TAP -UNO_SOCKETS -USIMPLE_RPC
ifeq ($(FEATURES), embedded)
BASECFLAGS += -DNO_HELP -DNO_USER_SWITCH -DNO_CUSTOM_INTERVALS -DNO_PID_FILE -DNO_VERBOSE_LOG -DNO_VERSION_INFORMATION
else ifeq ($(FEATURES), autostart)
BASECFLAGS += -DNO_HELP -DNO_VERSION_INFORMATION
else ifeq ($(FEATURES), minimum)
BASECFLAGS += -DSIMPLE_RPC -DSIMPLE_SOCKETS -DNO_TIMEOUT -DNO_SIGHUP -DNO_CL_PIDS -DNO_LOG -DNO_RANDOM_EPID -DNO_INI_FILE -DNO_HELP -DNO_CUSTOM_INTERVALS -DNO_PID_FILE -DNO_USER_SWITCH -DNO_VERBOSE_LOG -DNO_LIMIT -DNO_VERSION_INFORMATION -DNO_PRIVATE_IP_DETECT -DSMALL_AES -DNO_STRICT_MODES -DNO_TAP -DNO_CLIENT_LIST -DUNSAFE_DATA_LOAD -DNO_EXTERNAL_DATA -UFULL_INTERNAL_DATA -U_PEDANTIC
else ifeq ($(FEATURES), most)
BASECFLAGS += -DNO_SIGHUP -DNO_PID_FILE -DNO_LIMIT
else ifeq ($(FEATURES), inetd)
BASECFLAGS += -DNO_SIGHUP -DNO_SOCKETS -DNO_PID_FILE -DNO_LIMIT -DNO_VERSION_INFORMATION
else ifeq ($(FEATURES), fixedepids)
BASECFLAGS += -DNO_SIGHUP -DNO_CL_PIDS -DNO_RANDOM_EPID -DNO_INI_FILE
endif
ifdef INI
BASECFLAGS += -DINI_FILE=\"$(INI)\"
endif
ifdef DATA
BASECFLAGS += -DDATA_FILE=\"$(DATA)\"
endif
ifeq ($(NO_GETIFADDRS), 1)
BASECFLAGS += -DNO_GETIFADDRS
endif
ifeq ($(THREADS), 1)
BASECFLAGS += -DUSE_THREADS
endif
ifeq ($(CHILD_HANDLER), 1)
BASECFLAGS += -DCHILD_HANDLER
endif
ifeq ($(NO_TIMEOUT), 1)
BASECFLAGS += -DNO_TIMEOUT
endif
ifdef WINDOWS
BASECFLAGS += -DEPID_WINDOWS=\"$(WINDOWS)\"
endif
ifdef OFFICE2010
BASECFLAGS += -DEPID_OFFICE2010=\"$(OFFICE2010)\"
endif
ifdef OFFICE2013
BASECFLAGS += -DEPID_OFFICE2013=\"$(OFFICE2013)\"
endif
ifdef OFFICE2016
BASECFLAGS += -DEPID_OFFICE2016=\"$(OFFICE2016)\"
endif
ifdef HWID
BASECFLAGS += -DHWID=$(HWID)
endif
ifdef TERMINAL_WIDTH
BASECFLAGS += -DTERMINAL_FIXED_WIDTH=$(TERMINAL_WIDTH) -DDISPLAY_WIDTH=\"$(TERMINAL_WIDTH)\"
endif
ifeq ($(NOPROCFS), 1)
BASECFLAGS += -DNO_PROCFS
endif
ifeq ($(AUXV), 1)
BASECFLAGS += -DUSE_AUXV
endif
ifneq ($(ANDROID), 1)
ifneq ($(MINIX), 1)
ifneq ($(NOLPTHREAD), 1)
ifneq ($(DARWIN), 1)
ifeq ($(THREADS), 1)
SERVERLDFLAGS += -lpthread
endif
ifeq (,$(findstring NO_LIMIT,$(CFLAGS) $(BASECFLAGS)))
SERVERLDFLAGS += -lpthread
endif
endif
endif
endif
endif
$(REAL_MULTI_NAME): BASECFLAGS += -DMULTI_CALL_BINARY=1
all: $(REAL_CLIENT_NAME) $(REAL_PROGRAM_NAME)
allmulti: $(REAL_CLIENT_NAME) $(REAL_PROGRAM_NAME) $(REAL_MULTI_NAME)
vlmcsd: $(REAL_PROGRAM_NAME)
+@true
vlmcs: $(REAL_CLIENT_NAME)
+@true
vlmcsdmulti: $(REAL_MULTI_NAME)
+@true
libkms: $(REAL_DLL_NAME)
+@true
libkms-static: $(REAL_A_NAME)
ifneq ($(strip $(VLMCSD_VERSION)),)
BASECFLAGS += -DVERSION=\"$(VLMCSD_VERSION),\ built\ $(shell date -u '+%Y-%m-%d %H:%M:%S' | sed -e 's/ /\\ /g')\ UTC\"
endif
ifdef CAT
BASECFLAGS += -DONE_FILE
endif
SRCS = crypto.c kms.c endian.c output.c shared_globals.c helpers.c
HEADERS = $(CONFIG) types.h rpc.h vlmcsd.h endian.h crypto.h kms.h network.h output.h shared_globals.h vlmcs.h helpers.h kmsdata.h
DEPS = $(patsubst %,../build/%,$(MULTI_SRCS:.c=.d))
VLMCSD_SRCS = vlmcsd.c kmsdata.c $(SRCS)
VLMCSD_OBJS = $(patsubst %,../build/%,$(VLMCSD_SRCS:.c=.o))
VLMCS_SRCS = vlmcs.c kmsdata-full.c $(SRCS)
VLMCS_OBJS = $(patsubst %,../build/%,$(VLMCS_SRCS:.c=.o))
MULTI_SRCS = vlmcsd.c vlmcs.c vlmcsdmulti.c kmsdata-full.c $(SRCS)
MULTI_OBJS = $(patsubst %,../build/%,$(SRCS:.c=.o)) ../build/kmsdata-full.o ../build/vlmcsd-m.o ../build/vlmcs-m.o ../build/vlmcsdmulti-m.o
DLL_SRCS = libkms.c vlmcs.c $(SRCS)
DLL_OBJS = $(patsubst %,../build/%,$(DLL_SRCS:.c=-l.o))
A_OBJS = $(patsubst %,../build/%,$(DLL_SRCS:.c=-a.o))
PDFDOCS = vlmcs.1.pdf vlmcsd.7.pdf vlmcsd.8.pdf vlmcsdmulti.1.pdf vlmcsd.ini.5.pdf vlmcsd-floppy.7.pdf
HTMLDOCS = $(PDFDOCS:.pdf=.html)
UNIXDOCS = $(PDFDOCS:.pdf=.unix.txt)
DOSDOCS = $(PDFDOCS:.pdf=.dos.txt)
ifneq ($(NO_DNS),1)
VLMCS_SRCS += dns_srv.c
MULTI_SRCS += dns_srv.c
MULTI_OBJS += ../build/dns_srv.o
ifeq ($(DNS_PARSER),internal)
ifneq ($(MINGW),1)
VLMCS_SRCS += ns_parse.c ns_name.c
MULTI_SRCS += ns_parse.c ns_name.c
MULTI_OBJS += ../build/ns_parse.o ../build/ns_name.o
BASECFLAGS += "-DDNS_PARSER_INTERNAL"
endif
endif
endif
ifeq ($(MSRPC),1)
VLMCSD_SRCS += msrpc-server.c
VLMCS_SRCS += msrpc-client.c
MULTI_SRCS += msrpc-server.c msrpc-client.c
MULTI_OBJS += ../build/msrpc-server-m.o ../build/msrpc-client-m.o
DLL_SRCS += msrpc-server.c
BASECFLAGS += -DUSE_MSRPC -Wno-unknown-pragmas
BASELDFLAGS += -lrpcrt4
else
SRCS += network.c rpc.c
endif
ifeq ($(GETIFADDRS),musl)
ifneq ($(NO_GETIFADDRS),1)
BASECFLAGS += -DGETIFADDRS_MUSL
VLMCSD_SRCS += getifaddrs-musl.c
MULTI_SRCS += getifaddrs-musl.c
VLMCS_SRCS += getifaddrs-musl.c
DLL_SRCS += getifaddrs-musl.c
MULTI_OBJS += ../build/getifaddrs-musl.o
endif
endif
ifeq ($(ANDROID),1)
ifneq ($(NO_GETIFADDRS),1)
VLMCSD_SRCS += ifaddrs-android.c
MULTI_SRCS += ifaddrs-android.c
DLL_SRCS += ifaddrs-android.c
MULTI_OBJS += ../build/ifaddrs-android.o
endif
endif
ifeq "$(WIN)" "1"
VLMCSD_SRCS += ntservice.c wintap.c
MULTI_SRCS += ntservice.c wintap.c
MULTI_OBJS += ../build/ntservice.o ../build/wintap.o
endif
ifeq ($(CRYPTO), openssl_with_aes)
BASECFLAGS += -D_CRYPTO_OPENSSL -D_USE_AES_FROM_OPENSSL
BASELDFLAGS += -lcrypto
SRCS += crypto_openssl.c
else ifeq ($(CRYPTO), openssl_with_aes_soft)
BASECFLAGS += -D_CRYPTO_OPENSSL -D_USE_AES_FROM_OPENSSL -D_OPENSSL_SOFTWARE
BASELDFLAGS += -lcrypto
SRCS += crypto_openssl.c
else ifeq ($(CRYPTO), openssl)
BASECFLAGS += -D_CRYPTO_OPENSSL
BASELDFLAGS += -lcrypto
SRCS += crypto_openssl.c
else ifeq ($(CRYPTO), polarssl)
BASECFLAGS += -D_CRYPTO_POLARSSL
BASELDFLAGS += -lpolarssl
else ifeq ($(CRYPTO), windows)
BASECFLAGS += -D_CRYPTO_WINDOWS
SRCS += crypto_windows.c
else
BASECFLAGS += -D_CRYPTO_INTERNAL
SRCS += crypto_internal.c
endif
ifneq ($(STRIP),0)
BASELDFLAGS += $(STRIPFLAGS)
endif
ifeq ($(OPENSSL_HMAC),0)
BASECFLAGS += -D_OPENSSL_NO_HMAC
endif
ifeq ($(DEPENDENCIES),2)
BASECFLAGS += -MMD
endif
ifeq ($(VERBOSE),3)
COMPILER := $(shell printf "%-40s" $(notdir $(CC)))
ARCHIVER := $(shell printf "%-40s" $(notdir $(AR)))
endif
ARCMD := AR
ifdef CAT
LDCMD := CC/LD
else
LDCMD := LD
endif
-include $(MULTI_SRCS:.c=.d)
../build/%.o: %.c
ifeq ($(VERBOSE),1)
+$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -c $< -o $@
ifeq ($(DEPENDENCIES),1)
+$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -MM -MF $*.d $< -MT $@
endif
else
+@echo "$(COMPILER) CC $(notdir $@) <- $<"
+@$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -c $< -o $@
ifeq ($(DEPENDENCIES),1)
+@echo "$(COMPILER) DEP $*.d <- $<"
+@$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -MM -MF $*.d $< -MT $@
endif
endif
../build/%-m.o: %.c
ifeq ($(VERBOSE),1)
+$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -o $@ -c $<
ifeq ($(DEPENDENCIES),1)
+$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -MM -MF $*.d $< -MT $@
endif
else
+@echo "$(COMPILER) CC $(notdir $@) <- $<"
+@$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -o $@ -c $<
ifeq ($(DEPENDENCIES),1)
+@echo "$(COMPILER) DEP $*.d <- $<"
+@$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -MM -MF $*.d $< -MT $@
endif
endif
../build/%-a.o: %.c
ifeq ($(VERBOSE),1)
+$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) $(SERVERLDFLAGS) -fvisibility=hidden -c -DIS_LIBRARY=1 $(LIBRARY_CFLAGS) -UNO_SOCKETS -UUSE_MSRPC -o $@ -c $<
ifeq ($(DEPENDENCIES),1)
+$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) $(SERVERLDFLAGS) -fvisibility=hidden -c -DIS_LIBRARY=1 $(LIBRARY_CFLAGS) -UNO_SOCKETS -UUSE_MSRPC -MM -MF $*.d $<
endif
else
+@echo "$(COMPILER) CC $(notdir $@) <- $<"
+@$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) $(SERVERLDFLAGS) -fvisibility=hidden -c -DIS_LIBRARY=1 $(LIBRARY_CFLAGS) -UNO_SOCKETS -UUSE_MSRPC -o $@ -c $<
ifeq ($(DEPENDENCIES),1)
+@echo "$(COMPILER) DEP $*.d <- $<"
+@$(CC) -x$(COMPILER_LANGUAGE) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) $(SERVERLDFLAGS) -fvisibility=hidden -c -DIS_LIBRARY=1 $(LIBRARY_CFLAGS) -UNO_SOCKETS -UUSE_MSRPC -MM -MF $*.d $<
endif
endif
../build/%-l.o: %.c
ifeq ($(VERBOSE),1)
+$(CC) -x$(COMPILER_LANGUAGE) $(PICFLAGS) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) $(SERVERLDFLAGS) -fvisibility=hidden -c -DIS_LIBRARY=1 $(LIBRARY_CFLAGS) -UNO_SOCKETS -UUSE_MSRPC -o $@ -c $<
ifeq ($(DEPENDENCIES),1)
+$(CC) -x$(COMPILER_LANGUAGE) $(PICFLAGS) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) $(SERVERLDFLAGS) -fvisibility=hidden -c -DIS_LIBRARY=1 $(LIBRARY_CFLAGS) -UNO_SOCKETS -UUSE_MSRPC -MM -MF $*.d $<
endif
else
+@echo "$(COMPILER) CC $(notdir $@) <- $<"
+@$(CC) -x$(COMPILER_LANGUAGE) $(PICFLAGS) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) $(SERVERLDFLAGS) -fvisibility=hidden -c -DIS_LIBRARY=1 $(LIBRARY_CFLAGS) -UNO_SOCKETS -UUSE_MSRPC -o $@ -c $<
ifeq ($(DEPENDENCIES),1)
+@echo "$(COMPILER) DEP $*.d <- $<"
+@$(CC) -x$(COMPILER_LANGUAGE) $(PICFLAGS) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) $(SERVERLDFLAGS) -fvisibility=hidden -c -DIS_LIBRARY=1 $(LIBRARY_CFLAGS) -UNO_SOCKETS -UUSE_MSRPC -MM -MF $*.d $<
endif
endif
ifdef CAT
BUILDCOMMAND = cat $^ | $(CC) -x$(COMPILER_LANGUAGE) -o $@ -
VLMCSD_PREREQUISITES = $(VLMCSD_SRCS)
VLMCS_PREREQUISITES = $(VLMCS_SRCS)
MULTI_PREREQUISITES = $(MULTI_SRCS)
DLL_PREREQUISITES = $(DLL_SRCS)
OBJ_PREREQUISITES = $(DLL_SRCS)
A_PREREQUISITES = $(DLL_SRCS)
else
BUILDCOMMAND = $(CC) -o $@ $^
VLMCSD_PREREQUISITES = $(VLMCSD_OBJS)
VLMCS_PREREQUISITES = $(VLMCS_OBJS)
MULTI_PREREQUISITES = $(MULTI_OBJS)
DLL_PREREQUISITES = $(DLL_OBJS)
OBJ_PREREQUISITES = $(A_OBJS)
A_PREREQUISITES = $(A_OBJS)
endif
ifeq ($(VERBOSE),1)
BUILDCOMMANDPREFIX = +
else
BUILDCOMMANDPREFIX = +@
endif
INFOCOMMAND = +@echo "$(COMPILER) $(LDCMD) $@ <- $(notdir $^)"
ARINFOCOMMAND = +@echo "$(ARCHIVER) $(ARCMD) $@ <. $(notdir $^)"
VLMCSD_COMMAND = $(BUILDCOMMANDPREFIX)$(BUILDCOMMAND) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS) $(SERVERLDFLAGS)
VLMCS_COMMAND = $(BUILDCOMMANDPREFIX)$(BUILDCOMMAND) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS) $(CLIENTLDFLAGS)
MULTI_COMMAND = $(BUILDCOMMANDPREFIX)$(BUILDCOMMAND) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS) $(CLIENTLDFLAGS) $(SERVERLDFLAGS)
DLL_COMMAND = $(BUILDCOMMANDPREFIX)$(BUILDCOMMAND) $(PICFLAGS) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS) $(SERVERLDFLAGS) -fvisibility=hidden -shared -DIS_LIBRARY=1 $(LIBRARY_CFLAGS) -UNO_SOCKETS -UUSE_MSRPC
OBJ_COMMAND = $(BUILDCOMMANDPREFIX)$(BUILDCOMMAND) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS) $(SERVERLDFLAGS) -fvisibility=hidden -c -DIS_LIBRARY=1 $(LIBRARY_CFLAGS) -UNO_SOCKETS -UUSE_MSRPC
$(REAL_PROGRAM_NAME): $(VLMCSD_PREREQUISITES)
ifneq ($(VERBOSE),1)
$(INFOCOMMAND)
endif
$(VLMCSD_COMMAND)
$(REAL_CLIENT_NAME): $(VLMCS_PREREQUISITES)
ifneq ($(VERBOSE),1)
$(INFOCOMMAND)
endif
$(VLMCS_COMMAND)
$(REAL_MULTI_NAME): $(MULTI_PREREQUISITES)
ifneq ($(VERBOSE),1)
$(INFOCOMMAND)
endif
$(MULTI_COMMAND)
$(REAL_DLL_NAME): $(DLL_PREREQUISITES)
ifneq ($(VERBOSE),1)
$(INFOCOMMAND)
endif
$(DLL_COMMAND)
ifndef CAT
$(OBJ_NAME):
+@echo Cannot make $@ without CAT defined. Please create $(A_NAME)
else
$(OBJ_NAME): $(OBJ_PREREQUISITES)
ifneq ($(VERBOSE),1)
$(INFOCOMMAND)
endif
$(OBJ_COMMAND)
endif
ifdef CAT
$(REAL_A_NAME): $(OBJ_NAME)
else
$(REAL_A_NAME): BASECFLAGS += -fvisibility=hidden -DIS_LIBRARY=1 $(LIBRARY_CFLAGS) -UNO_SOCKETS -UUSE_MSRPC
$(REAL_A_NAME): $(A_OBJS)
endif
ifneq ($(VERBOSE),1)
$(ARINFOCOMMAND)
endif
+@rm -f $@
$(BUILDCOMMANDPREFIX)$(AR) rcs $@ $^
clean:
rm -f $(REAL_PROGRAM_NAME) $(REAL_MULTI_NAME) $(REAL_DLL_NAME) $(REAL_CLIENT_NAME) $(OBJ_NAME) $(REAL_A_NAME) ../bin/* ../build/* *.d
dnsclean:
rm -f ../build/dns_srv.o
help:
@echo "Help is available by typing 'make help' in directory $(shell realpath `pwd`/..). Use 'cd ..' to get there."

14
src/KMSServer.idl Normal file
View File

@ -0,0 +1,14 @@
[
uuid(51C82175-844E-4750-B0D8-EC255555BC06),
version(1.0),
]
interface KMSServer
{
int RequestActivation
(
[in] int requestSize,
[in, size_is(requestSize)] unsigned char* request,
[out] int* responseSize,
[out, size_is( , *responseSize)] unsigned char** response
);
}

279
src/KMSServer_c_mingw_gcc.c Normal file
View File

@ -0,0 +1,279 @@
/* this ALWAYS GENERATED file contains the RPC client stubs */
/* File created by MIDL compiler version 8.00.0595 */
/* at Thu Oct 18 15:24:14 2012
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0595
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#pragma warning( disable: 4100 ) /* unreferenced arguments in x86 call */
#pragma optimize("", off )
#include <string.h>
#include "KMSServer_h.h"
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 59
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
#if !MULTI_CALL_BINARY
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
#endif // !MULTI_CALL_BINARY
#define GENERIC_BINDING_TABLE_SIZE 0
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
static const RPC_CLIENT_INTERFACE KMSServer___RpcClientInterface =
{
sizeof(RPC_CLIENT_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
0,
0,
0,
0,
0,
0x00000000
};
RPC_IF_HANDLE KMSServer_v1_0_c_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcClientInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
static RPC_BINDING_HANDLE KMSServer__MIDL_AutoBindHandle;
int RequestActivation(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response)
{
CLIENT_CALL_RETURN _RetVal;
_RetVal = NdrClientCall2(
( PMIDL_STUB_DESC )&KMSServer_StubDesc,
(PFORMAT_STRING) &KMSServer__MIDL_ProcFormatString.Format[0],
( unsigned char * )&IDL_handle);
return ( int )_RetVal.Simple;
}
#if !defined(__RPC_WIN32__)
#error Invalid build platform for this stub.
#endif
#if !(TARGET_IS_NT50_OR_LATER)
#error You need Windows 2000 or later to run this stub because it uses these features:
#error /robust command line switch.
#error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems.
#error This app will fail with the RPC_X_WRONG_STUB_VERSION error.
#endif
#if !MULTI_CALL_BINARY
/*static*/ const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure RequestActivation */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0x8, /* 8 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 28 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 30 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 32 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 34 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 36 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 38 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 40 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 42 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 44 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 46 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 48 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 50 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 52 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 54 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 56 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
/*static*/ const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
//typedef void *(__RPC_API midl_user_allocate_t)(size_t);
typedef void *(__RPC_API *midl_allocate_t)(size_t);
/*static*/ const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcClientInterface,
(midl_allocate_t)MIDL_user_allocate,
MIDL_user_free,
&KMSServer__MIDL_AutoBindHandle,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x50002, /* Ndr library version */
0,
0x8000253, /* MIDL Version 8.0.595 */
0,
0,
0, /* notify & notify_flag routine table */
0x1, /* MIDL flag */
0, /* cs routines */
0, /* proxy/server info */
0
};
#endif // !MULTI_CALL_BINARY
#pragma optimize("", on )
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif /* !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_) */

View File

@ -0,0 +1,735 @@
/* this ALWAYS GENERATED file contains the RPC client stubs */
/* File created by MIDL compiler version 8.00.0603 */
/* at Fri Feb 20 04:17:07 2015
* modified by Hotbird64 to work with MingW-w64 and gcc
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603
protocol : all , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if defined(_M_AMD64)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#include <string.h>
#include "KMSServer_h.h"
#if !MULTI_CALL_BINARY
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 61
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
static const RPC_SYNTAX_IDENTIFIER _NDR64_RpcTransferSyntax =
{{0x71710533,0xbeba,0x4937,{0x83,0x19,0xb5,0xdb,0xef,0x9c,0xcc,0x36}},{1,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
#endif // !MULTI_CALL_BINARY
#define GENERIC_BINDING_TABLE_SIZE 0
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
extern const MIDL_STUBLESS_PROXY_INFO KMSServer_ProxyInfo;
static const RPC_CLIENT_INTERFACE KMSServer___RpcClientInterface =
{
sizeof(RPC_CLIENT_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
0,
0,
0,
0,
&KMSServer_ProxyInfo,
0x02000000
};
RPC_IF_HANDLE KMSServer_v1_0_c_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcClientInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
static RPC_BINDING_HANDLE KMSServer__MIDL_AutoBindHandle;
int RequestActivation(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response)
{
CLIENT_CALL_RETURN _RetVal;
_RetVal = NdrClientCall3(
( PMIDL_STUBLESS_PROXY_INFO )&KMSServer_ProxyInfo,
0,
0,
IDL_handle,
requestSize,
request,
responseSize,
response);
return ( int )_RetVal.Simple;
}
#if !defined(__RPC_WIN64__)
#error Invalid build platform for this stub.
#endif
#if !MULTI_CALL_BINARY
/*static*/ const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure RequestActivation */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x30 ), /* X64 Stack size/offset = 48 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0xa, /* 10 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* 28 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 30 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 32 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 34 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 36 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 38 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
/* 40 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 42 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 44 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 46 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 48 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 50 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */
/* 52 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 54 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 56 */ NdrFcShort( 0x28 ), /* X64 Stack size/offset = 40 */
/* 58 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
/*static*/ const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
#endif //!MULTI_CALL_BINARY
#endif /* defined(_M_AMD64)*/
/* this ALWAYS GENERATED file contains the RPC client stubs */
/* File created by MIDL compiler version 8.00.0603 */
/* at Fri Feb 20 04:17:07 2015
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603
protocol : all , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if defined(_M_AMD64)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if !defined(__RPC_WIN64__)
#error Invalid build platform for this stub.
#endif
#include "ndr64types.h"
#include "pshpack8.h"
#if !MULTI_CALL_BINARY
typedef
struct
{
NDR64_FORMAT_UINT32 frag1;
struct _NDR64_EXPR_OPERATOR frag2;
struct _NDR64_EXPR_VAR frag3;
}
__midl_frag13_t;
extern const __midl_frag13_t __midl_frag13;
typedef
struct
{
struct _NDR64_CONF_ARRAY_HEADER_FORMAT frag1;
struct _NDR64_ARRAY_ELEMENT_INFO frag2;
}
__midl_frag12_t;
extern const __midl_frag12_t __midl_frag12;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag11_t;
extern const __midl_frag11_t __midl_frag11;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag10_t;
extern const __midl_frag10_t __midl_frag10;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag8_t;
extern const __midl_frag8_t __midl_frag8;
typedef
NDR64_FORMAT_CHAR
__midl_frag7_t;
extern const __midl_frag7_t __midl_frag7;
typedef
struct
{
NDR64_FORMAT_UINT32 frag1;
struct _NDR64_EXPR_VAR frag2;
}
__midl_frag6_t;
extern const __midl_frag6_t __midl_frag6;
typedef
struct
{
struct _NDR64_CONF_ARRAY_HEADER_FORMAT frag1;
struct _NDR64_ARRAY_ELEMENT_INFO frag2;
}
__midl_frag5_t;
extern const __midl_frag5_t __midl_frag5;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag4_t;
extern const __midl_frag4_t __midl_frag4;
typedef
NDR64_FORMAT_CHAR
__midl_frag3_t;
extern const __midl_frag3_t __midl_frag3;
typedef
struct
{
struct _NDR64_PROC_FORMAT frag1;
struct _NDR64_BIND_AND_NOTIFY_EXTENSION frag2;
struct _NDR64_PARAM_FORMAT frag3;
struct _NDR64_PARAM_FORMAT frag4;
struct _NDR64_PARAM_FORMAT frag5;
struct _NDR64_PARAM_FORMAT frag6;
struct _NDR64_PARAM_FORMAT frag7;
}
__midl_frag2_t;
extern const __midl_frag2_t __midl_frag2;
typedef
NDR64_FORMAT_UINT32
__midl_frag1_t;
extern const __midl_frag1_t __midl_frag1;
/*static*/ const __midl_frag13_t __midl_frag13 =
{
/* */
(NDR64_UINT32) 1 /* 0x1 */,
{
/* struct _NDR64_EXPR_OPERATOR */
0x4, /* FC_EXPR_OPER */
0x5, /* OP_UNARY_INDIRECTION */
0x5, /* FC64_INT32 */
(NDR64_UINT8) 0 /* 0x0 */
},
{
/* struct _NDR64_EXPR_VAR */
0x3, /* FC_EXPR_VAR */
0x7, /* FC64_INT64 */
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT32) 24 /* 0x18 */ /* Offset */
}
};
/*static*/ const __midl_frag12_t __midl_frag12 =
{
/* *char */
{
/* *char */
0x41, /* FC64_CONF_ARRAY */
(NDR64_UINT8) 0 /* 0x0 */,
{
/* *char */
0,
0,
0,
0,
0,
0,
0,
0
},
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag13
},
{
/* struct _NDR64_ARRAY_ELEMENT_INFO */
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag7
}
};
/*static*/ const __midl_frag11_t __midl_frag11 =
{
/* *char */
0x21, /* FC64_UP */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag12
};
/*static*/ const __midl_frag10_t __midl_frag10 =
{
/* **char */
0x20, /* FC64_RP */
(NDR64_UINT8) 20 /* 0x14 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag11
};
/*static*/ const __midl_frag8_t __midl_frag8 =
{
/* *int */
0x20, /* FC64_RP */
(NDR64_UINT8) 12 /* 0xc */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag3
};
/*static*/ const __midl_frag7_t __midl_frag7 =
0x10 /* FC64_CHAR */;
/*static*/ const __midl_frag6_t __midl_frag6 =
{
/* */
(NDR64_UINT32) 1 /* 0x1 */,
{
/* struct _NDR64_EXPR_VAR */
0x3, /* FC_EXPR_VAR */
0x5, /* FC64_INT32 */
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT32) 8 /* 0x8 */ /* Offset */
}
};
/*static*/ const __midl_frag5_t __midl_frag5 =
{
/* *char */
{
/* *char */
0x41, /* FC64_CONF_ARRAY */
(NDR64_UINT8) 0 /* 0x0 */,
{
/* *char */
0,
0,
0,
0,
0,
0,
0,
0
},
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag6
},
{
/* struct _NDR64_ARRAY_ELEMENT_INFO */
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag7
}
};
/*static*/ const __midl_frag4_t __midl_frag4 =
{
/* *char */
0x20, /* FC64_RP */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag5
};
/*static*/ const __midl_frag3_t __midl_frag3 =
0x5 /* FC64_INT32 */;
/*static*/ const __midl_frag2_t __midl_frag2 =
{
/* RequestActivation */
{
/* RequestActivation */ /* procedure RequestActivation */
(NDR64_UINT32) 23986240 /* 0x16e0040 */, /* explicit handle */ /* IsIntrepreted, ServerMustSize, ClientMustSize, HasReturn, ServerCorrelation, ClientCorrelation, HasExtensions */
(NDR64_UINT32) 48 /* 0x30 */ , /* Stack size */
(NDR64_UINT32) 8 /* 0x8 */,
(NDR64_UINT32) 40 /* 0x28 */,
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT16) 5 /* 0x5 */,
(NDR64_UINT16) 8 /* 0x8 */
},
{
/* struct _NDR64_BIND_AND_NOTIFY_EXTENSION */
{
/* struct _NDR64_BIND_AND_NOTIFY_EXTENSION */
0x72, /* FC64_BIND_PRIMITIVE */
(NDR64_UINT8) 0 /* 0x0 */,
0 /* 0x0 */, /* Stack offset */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT8) 0 /* 0x0 */
},
(NDR64_UINT16) 0 /* 0x0 */ /* Notify index */
},
{
/* requestSize */ /* parameter requestSize */
&__midl_frag3,
{
/* requestSize */
0,
0,
0,
1,
0,
0,
1,
1,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* [in], Basetype, ByValue */
(NDR64_UINT16) 0 /* 0x0 */,
8 /* 0x8 */, /* Stack offset */
},
{
/* request */ /* parameter request */
&__midl_frag5,
{
/* request */
1,
1,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* MustSize, MustFree, [in], SimpleRef */
(NDR64_UINT16) 0 /* 0x0 */,
16 /* 0x10 */, /* Stack offset */
},
{
/* responseSize */ /* parameter responseSize */
&__midl_frag3,
{
/* responseSize */
0,
0,
0,
0,
1,
0,
1,
0,
1,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
1
}, /* [out], Basetype, SimpleRef, UseCache */
(NDR64_UINT16) 0 /* 0x0 */,
24 /* 0x18 */, /* Stack offset */
},
{
/* response */ /* parameter response */
&__midl_frag10,
{
/* response */
1,
1,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
1
}, /* MustSize, MustFree, [out], UseCache */
(NDR64_UINT16) 0 /* 0x0 */,
32 /* 0x20 */, /* Stack offset */
},
{
/* int */ /* parameter int */
&__midl_frag3,
{
/* int */
0,
0,
0,
0,
1,
1,
1,
1,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* [out], IsReturn, Basetype, ByValue */
(NDR64_UINT16) 0 /* 0x0 */,
40 /* 0x28 */, /* Stack offset */
}
};
/*static*/ const __midl_frag1_t __midl_frag1 =
(NDR64_UINT32) 0 /* 0x0 */;
#endif // !MULTI_CALL_BINARY
#include "poppack.h"
#if !MULTI_CALL_BINARY
static const FormatInfoRef KMSServer_Ndr64ProcTable[] =
{
&__midl_frag2
};
//typedef void *__RPC_USER MIDL_user_allocate_t(SIZE_T)
typedef void *(__RPC_API *midl_allocate_t)(size_t);
/*static*/ const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcClientInterface,
(midl_allocate_t)MIDL_user_allocate,
MIDL_user_free,
&KMSServer__MIDL_AutoBindHandle,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x60000, /* Ndr library version */
0,
0x800025b, /* MIDL Version 8.0.603 */
0,
0,
0, /* notify & notify_flag routine table */
0x2000001, /* MIDL flag */
0, /* cs routines */
(void *)& KMSServer_ProxyInfo, /* proxy/server info */
0
};
static const MIDL_SYNTAX_INFO KMSServer_SyntaxInfo [ 2 ] =
{
{
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
0,
KMSServer__MIDL_ProcFormatString.Format,
KMSServer_FormatStringOffsetTable,
KMSServer__MIDL_TypeFormatString.Format,
0,
0,
0
}
,{
{{0x71710533,0xbeba,0x4937,{0x83,0x19,0xb5,0xdb,0xef,0x9c,0xcc,0x36}},{1,0}},
0,
0 ,
(unsigned short *) KMSServer_Ndr64ProcTable,
0,
0,
0,
0
}
};
#endif // !MULTI_CALL_BINARY
/*static*/ const MIDL_STUBLESS_PROXY_INFO KMSServer_ProxyInfo =
{
&KMSServer_StubDesc,
KMSServer__MIDL_ProcFormatString.Format,
KMSServer_FormatStringOffsetTable,
(RPC_SYNTAX_IDENTIFIER*)&_RpcTransferSyntax,
2,
(MIDL_SYNTAX_INFO*)KMSServer_SyntaxInfo
};
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif /* defined(_M_AMD64)*/

84
src/KMSServer_h.h Normal file
View File

@ -0,0 +1,84 @@
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
/* Modified by Hotbird64 for use with MingW and gcc */
/* File created by MIDL compiler version 8.00.0595 */
/* at Thu Oct 18 15:24:14 2012
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0595
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if _WIN32
#include "winsock2.h"
#endif
#pragma warning( disable: 4049 ) /* more than 64k source lines */
/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif
//#include "rpc.h"
#include "rpcndr.h"
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__
#ifndef __KMSServer_h_h__
#define __KMSServer_h_h__
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
/* Forward Declarations */
#ifdef __cplusplus
extern "C"{
#endif
#ifndef __KMSServer_INTERFACE_DEFINED__
#define __KMSServer_INTERFACE_DEFINED__
/* interface KMSServer */
/* [version][uuid] */
int RequestActivation(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response);
extern RPC_IF_HANDLE KMSServer_v1_0_c_ifspec;
extern RPC_IF_HANDLE KMSServer_v1_0_s_ifspec;
#endif /* __KMSServer_INTERFACE_DEFINED__ */
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,282 @@
/* this ALWAYS GENERATED file contains the RPC server stubs */
/* WARNING! manually edited by Hotbird64 to work with MingW */
/* File created by MIDL compiler version 8.00.0595 */
/* at Thu Oct 18 15:24:14 2012
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0595
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#pragma warning( disable: 4100 ) /* unreferenced arguments in x86 call */
#pragma optimize("", off )
#include <string.h>
#include "KMSServer_h.h"
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 59
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
extern const MIDL_SERVER_INFO KMSServer_ServerInfo;
extern const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable;
int ProcessActivationRequest(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response);
static const RPC_SERVER_INTERFACE KMSServer___RpcServerInterface =
{
sizeof(RPC_SERVER_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
(RPC_DISPATCH_TABLE*)&KMSServer_v1_0_DispatchTable,
0,
0,
0,
&KMSServer_ServerInfo,
0x04000000
};
RPC_IF_HANDLE KMSServer_v1_0_s_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcServerInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
#if !defined(__RPC_WIN32__)
#error Invalid build platform for this stub.
#endif
#if !(TARGET_IS_NT50_OR_LATER)
#error You need Windows 2000 or later to run this stub because it uses these features:
#error /robust command line switch.
#error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems.
#error This app will fail with the RPC_X_WRONG_STUB_VERSION error.
#endif
const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure RequestActivation */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0x8, /* 8 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 28 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 30 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 32 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 34 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 36 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 38 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 40 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 42 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 44 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 46 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 48 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 50 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 52 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 54 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 56 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
typedef void *(__RPC_API *midl_allocate_t)(size_t);
const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcServerInterface,
(midl_allocate_t)MIDL_user_allocate,
MIDL_user_free,
0,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x50002, /* Ndr library version */
0,
0x8000253, /* MIDL Version 8.0.595 */
0,
0,
0, /* notify & notify_flag routine table */
0x1, /* MIDL flag */
0, /* cs routines */
0, /* proxy/server info */
0
};
static const RPC_DISPATCH_FUNCTION KMSServer_table[] =
{
NdrServerCall2,
0
};
const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable =
{
1,
(RPC_DISPATCH_FUNCTION*)KMSServer_table
};
static const SERVER_ROUTINE KMSServer_ServerRoutineTable[] =
{
(SERVER_ROUTINE)ProcessActivationRequest
};
const MIDL_SERVER_INFO KMSServer_ServerInfo =
{
&KMSServer_StubDesc,
KMSServer_ServerRoutineTable,
KMSServer__MIDL_ProcFormatString.Format,
KMSServer_FormatStringOffsetTable,
0,
0,
0,
0};
#pragma optimize("", on )
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif /* !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_) */

View File

@ -0,0 +1,730 @@
/* this ALWAYS GENERATED file contains the RPC server stubs */
/* File created by MIDL compiler version 8.00.0603 */
/* at Fri Feb 20 04:17:07 2015
* Modified by Hotbird64 to work with gcc and MingW-w64
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603
protocol : all , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if defined(_M_AMD64)
int ProcessActivationRequest(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response);
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#include <string.h>
#include "KMSServer_h.h"
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 61
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
static const RPC_SYNTAX_IDENTIFIER _NDR64_RpcTransferSyntax =
{{0x71710533,0xbeba,0x4937,{0x83,0x19,0xb5,0xdb,0xef,0x9c,0xcc,0x36}},{1,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
extern const MIDL_SERVER_INFO KMSServer_ServerInfo;
extern const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable;
static const RPC_SERVER_INTERFACE KMSServer___RpcServerInterface =
{
sizeof(RPC_SERVER_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
(RPC_DISPATCH_TABLE*)&KMSServer_v1_0_DispatchTable,
0,
0,
0,
&KMSServer_ServerInfo,
0x06000000
};
RPC_IF_HANDLE KMSServer_v1_0_s_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcServerInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
#if !defined(__RPC_WIN64__)
#error Invalid build platform for this stub.
#endif
/*static*/ const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure RequestActivation */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x30 ), /* X64 Stack size/offset = 48 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0xa, /* 10 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* 28 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 30 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 32 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 34 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 36 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 38 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
/* 40 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 42 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 44 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 46 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 48 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 50 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */
/* 52 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 54 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 56 */ NdrFcShort( 0x28 ), /* X64 Stack size/offset = 40 */
/* 58 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
/*static*/ const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
static const RPC_DISPATCH_FUNCTION KMSServer_table[] =
{
NdrServerCall2,
0
};
/*static*/ const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable =
{
1,
(RPC_DISPATCH_FUNCTION*)KMSServer_table
};
#endif /* defined(_M_AMD64)*/
/* this ALWAYS GENERATED file contains the RPC server stubs */
/* File created by MIDL compiler version 8.00.0603 */
/* at Fri Feb 20 04:17:07 2015
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603
protocol : all , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if defined(_M_AMD64)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if !defined(__RPC_WIN64__)
#error Invalid build platform for this stub.
#endif
#include "ndr64types.h"
#include "pshpack8.h"
typedef
struct
{
NDR64_FORMAT_UINT32 frag1;
struct _NDR64_EXPR_OPERATOR frag2;
struct _NDR64_EXPR_VAR frag3;
}
__midl_frag13_t;
extern const __midl_frag13_t __midl_frag13;
typedef
struct
{
struct _NDR64_CONF_ARRAY_HEADER_FORMAT frag1;
struct _NDR64_ARRAY_ELEMENT_INFO frag2;
}
__midl_frag12_t;
extern const __midl_frag12_t __midl_frag12;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag11_t;
extern const __midl_frag11_t __midl_frag11;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag10_t;
extern const __midl_frag10_t __midl_frag10;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag8_t;
extern const __midl_frag8_t __midl_frag8;
typedef
NDR64_FORMAT_CHAR
__midl_frag7_t;
extern const __midl_frag7_t __midl_frag7;
typedef
struct
{
NDR64_FORMAT_UINT32 frag1;
struct _NDR64_EXPR_VAR frag2;
}
__midl_frag6_t;
extern const __midl_frag6_t __midl_frag6;
typedef
struct
{
struct _NDR64_CONF_ARRAY_HEADER_FORMAT frag1;
struct _NDR64_ARRAY_ELEMENT_INFO frag2;
}
__midl_frag5_t;
extern const __midl_frag5_t __midl_frag5;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag4_t;
extern const __midl_frag4_t __midl_frag4;
typedef
NDR64_FORMAT_CHAR
__midl_frag3_t;
extern const __midl_frag3_t __midl_frag3;
typedef
struct
{
struct _NDR64_PROC_FORMAT frag1;
struct _NDR64_BIND_AND_NOTIFY_EXTENSION frag2;
struct _NDR64_PARAM_FORMAT frag3;
struct _NDR64_PARAM_FORMAT frag4;
struct _NDR64_PARAM_FORMAT frag5;
struct _NDR64_PARAM_FORMAT frag6;
struct _NDR64_PARAM_FORMAT frag7;
}
__midl_frag2_t;
extern const __midl_frag2_t __midl_frag2;
typedef
NDR64_FORMAT_UINT32
__midl_frag1_t;
extern const __midl_frag1_t __midl_frag1;
/*static*/ const __midl_frag13_t __midl_frag13 =
{
/* */
(NDR64_UINT32) 1 /* 0x1 */,
{
/* struct _NDR64_EXPR_OPERATOR */
0x4, /* FC_EXPR_OPER */
0x5, /* OP_UNARY_INDIRECTION */
0x5, /* FC64_INT32 */
(NDR64_UINT8) 0 /* 0x0 */
},
{
/* struct _NDR64_EXPR_VAR */
0x3, /* FC_EXPR_VAR */
0x7, /* FC64_INT64 */
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT32) 24 /* 0x18 */ /* Offset */
}
};
/*static*/ const __midl_frag12_t __midl_frag12 =
{
/* *char */
{
/* *char */
0x41, /* FC64_CONF_ARRAY */
(NDR64_UINT8) 0 /* 0x0 */,
{
/* *char */
0,
0,
0,
0,
0,
0,
0,
0
},
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag13
},
{
/* struct _NDR64_ARRAY_ELEMENT_INFO */
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag7
}
};
/*static*/ const __midl_frag11_t __midl_frag11 =
{
/* *char */
0x21, /* FC64_UP */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag12
};
/*static*/ const __midl_frag10_t __midl_frag10 =
{
/* **char */
0x20, /* FC64_RP */
(NDR64_UINT8) 20 /* 0x14 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag11
};
/*static*/ const __midl_frag8_t __midl_frag8 =
{
/* *int */
0x20, /* FC64_RP */
(NDR64_UINT8) 12 /* 0xc */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag3
};
/*static*/ const __midl_frag7_t __midl_frag7 =
0x10 /* FC64_CHAR */;
/*static*/ const __midl_frag6_t __midl_frag6 =
{
/* */
(NDR64_UINT32) 1 /* 0x1 */,
{
/* struct _NDR64_EXPR_VAR */
0x3, /* FC_EXPR_VAR */
0x5, /* FC64_INT32 */
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT32) 8 /* 0x8 */ /* Offset */
}
};
/*static*/ const __midl_frag5_t __midl_frag5 =
{
/* *char */
{
/* *char */
0x41, /* FC64_CONF_ARRAY */
(NDR64_UINT8) 0 /* 0x0 */,
{
/* *char */
0,
0,
0,
0,
0,
0,
0,
0
},
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag6
},
{
/* struct _NDR64_ARRAY_ELEMENT_INFO */
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag7
}
};
/*static*/ const __midl_frag4_t __midl_frag4 =
{
/* *char */
0x20, /* FC64_RP */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag5
};
/*static*/ const __midl_frag3_t __midl_frag3 =
0x5 /* FC64_INT32 */;
/*static*/ const __midl_frag2_t __midl_frag2 =
{
/* RequestActivation */
{
/* RequestActivation */ /* procedure RequestActivation */
(NDR64_UINT32) 23986240 /* 0x16e0040 */, /* explicit handle */ /* IsIntrepreted, ServerMustSize, ClientMustSize, HasReturn, ServerCorrelation, ClientCorrelation, HasExtensions */
(NDR64_UINT32) 48 /* 0x30 */ , /* Stack size */
(NDR64_UINT32) 8 /* 0x8 */,
(NDR64_UINT32) 40 /* 0x28 */,
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT16) 5 /* 0x5 */,
(NDR64_UINT16) 8 /* 0x8 */
},
{
/* struct _NDR64_BIND_AND_NOTIFY_EXTENSION */
{
/* struct _NDR64_BIND_AND_NOTIFY_EXTENSION */
0x72, /* FC64_BIND_PRIMITIVE */
(NDR64_UINT8) 0 /* 0x0 */,
0 /* 0x0 */, /* Stack offset */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT8) 0 /* 0x0 */
},
(NDR64_UINT16) 0 /* 0x0 */ /* Notify index */
},
{
/* requestSize */ /* parameter requestSize */
&__midl_frag3,
{
/* requestSize */
0,
0,
0,
1,
0,
0,
1,
1,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* [in], Basetype, ByValue */
(NDR64_UINT16) 0 /* 0x0 */,
8 /* 0x8 */, /* Stack offset */
},
{
/* request */ /* parameter request */
&__midl_frag5,
{
/* request */
1,
1,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* MustSize, MustFree, [in], SimpleRef */
(NDR64_UINT16) 0 /* 0x0 */,
16 /* 0x10 */, /* Stack offset */
},
{
/* responseSize */ /* parameter responseSize */
&__midl_frag3,
{
/* responseSize */
0,
0,
0,
0,
1,
0,
1,
0,
1,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
1
}, /* [out], Basetype, SimpleRef, UseCache */
(NDR64_UINT16) 0 /* 0x0 */,
24 /* 0x18 */, /* Stack offset */
},
{
/* response */ /* parameter response */
&__midl_frag10,
{
/* response */
1,
1,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
1
}, /* MustSize, MustFree, [out], UseCache */
(NDR64_UINT16) 0 /* 0x0 */,
32 /* 0x20 */, /* Stack offset */
},
{
/* int */ /* parameter int */
&__midl_frag3,
{
/* int */
0,
0,
0,
0,
1,
1,
1,
1,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* [out], IsReturn, Basetype, ByValue */
(NDR64_UINT16) 0 /* 0x0 */,
40 /* 0x28 */, /* Stack offset */
}
};
/*static*/ const __midl_frag1_t __midl_frag1 =
(NDR64_UINT32) 0 /* 0x0 */;
#include "poppack.h"
static const FormatInfoRef KMSServer_Ndr64ProcTable[] =
{
&__midl_frag2
};
//typedef void *__RPC_USER MIDL_user_allocate_t(SIZE_T);
typedef void *(__RPC_API *midl_allocate_t)(size_t);
/*static*/ const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcServerInterface,
(midl_allocate_t)MIDL_user_allocate,
MIDL_user_free,
0,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x60000, /* Ndr library version */
0,
0x800025b, /* MIDL Version 8.0.603 */
0,
0,
0, /* notify & notify_flag routine table */
0x2000001, /* MIDL flag */
0, /* cs routines */
(void *)& KMSServer_ServerInfo, /* proxy/server info */
0
};
static const RPC_DISPATCH_FUNCTION KMSServer_NDR64__table[] =
{
NdrServerCallAll,
0
};
static const RPC_DISPATCH_TABLE KMSServer_NDR64__v1_0_DispatchTable =
{
1,
(RPC_DISPATCH_FUNCTION*)KMSServer_NDR64__table
};
static const MIDL_SYNTAX_INFO KMSServer_SyntaxInfo [ 2 ] =
{
{
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
(RPC_DISPATCH_TABLE*)&KMSServer_v1_0_DispatchTable,
KMSServer__MIDL_ProcFormatString.Format,
KMSServer_FormatStringOffsetTable,
KMSServer__MIDL_TypeFormatString.Format,
0,
0,
0
}
,{
{{0x71710533,0xbeba,0x4937,{0x83,0x19,0xb5,0xdb,0xef,0x9c,0xcc,0x36}},{1,0}},
(RPC_DISPATCH_TABLE*)&KMSServer_NDR64__v1_0_DispatchTable,
0 ,
(unsigned short *) KMSServer_Ndr64ProcTable,
0,
0,
0,
0
}
};
static const SERVER_ROUTINE KMSServer_ServerRoutineTable[] =
{
(SERVER_ROUTINE)ProcessActivationRequest
};
/*static*/ const MIDL_SERVER_INFO KMSServer_ServerInfo =
{
&KMSServer_StubDesc,
KMSServer_ServerRoutineTable,
KMSServer__MIDL_ProcFormatString.Format,
(unsigned short *) KMSServer_FormatStringOffsetTable,
0,
(RPC_SYNTAX_IDENTIFIER*)&_NDR64_RpcTransferSyntax,
2,
(MIDL_SYNTAX_INFO*)KMSServer_SyntaxInfo
};
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif /* defined(_M_AMD64)*/

674
src/config.h Normal file
View File

@ -0,0 +1,674 @@
#ifndef CONFIG_H_
#define CONFIG_H_
/* Don't change anything ABOVE this line */
/*
* As a best practice do not change the original config.h as distributed with vlmcsd.
* Instead make a copy, e.g. myconfig.h, customize it and type 'make CONFIG=myconfig.h'
* to build vlmcsd. This prevents your copy being overwritten when you upgrade to a
* new version.
*/
/*
* ----------------------------------------------------------------------------------------
* Useful customizations. These options are mandatory. You cannot comment them out.
* Feel free to change them to fit your needs.
* ----------------------------------------------------------------------------------------
*/
#ifndef VERSION
/*
* Define your own version identifier here, e.g. '#define VERSION "my vlmcsd based on 1103"'
*/
#define VERSION "private build"
#endif // VERSION
#ifndef HWID // HwId from the Ratiborus VM
#define HWID 0x3A, 0x1C, 0x04, 0x96, 0x00, 0xB6, 0x00, 0x76
#endif
/*
* Anything below this line is optional. If you want to use any of these options
* uncomment one or more lines starting with "//#define"
*/
/*
* -------------------------------
* Defaults
* -------------------------------
*/
#ifndef INI_FILE
/*
* Uncomment and customize the following line if you want vlmcsd to look for an ini file
* at a default location.
*/
//#define INI_FILE "/etc/vlmcsd.ini"
#endif // INI_FILE
#ifndef DATA_FILE
/*
* Uncomment and customize the following line if you want vlmcsd to look for a KMS data file
* at a custom default location.
*/
//#define DATA_FILE "/etc/vlmcsd.kmd"
#endif // DATA_FILE
/*
* ----------------------------------------------------------------------------------------
* Troubleshooting options. Please note that disabling features may also help troubleshooting.
* If you have an old OS that does not support features like pthreads, shared memory or
* semaphores, uncomment "#define NO_LIMIT" and "#define NO_SIGHUP" and leave "#define USE_THREADS"
* commented out.
* ----------------------------------------------------------------------------------------
*/
#ifndef CHILD_HANDLER
/*
* Uncomment the following #define if you are compiling for a platform that does
* not correctly handle the SA_NOCLDWAIT flag when ignoring SIGCHLD, i.e. forked
* processes remain as "zombies" after dying. This option will add a SIGCHLD handler that
* "waits" for a child that has terminated. This is only required for a few
* unixoid OSses.
*/
//#define CHILD_HANDLER
#endif // CHILD_HANDLER
#ifndef NO_TIMEOUT
/*
* Uncomment the following #define if you are compiling for a platform that does
* not support custom socket send or receive timeouts.
*/
//#define NO_TIMEOUT
#endif // NO_TIMEOUT
#ifndef NO_DNS
/*
* Uncomment the following #define if you have trouble with accessing routines
* from libresolv. If enabled, vlmcs will be compiled without support for
* detecting KMS servers via DNS.
*/
//#define NO_DNS
#endif // NO_DNS
#ifndef TERMINAL_FIXED_WIDTH
/*
* Uncomment the following #define and optionally change its value if you are compiling for
* a platform that cannot properly determine the width of a terminal/command prompt.
* This affects the output of "vlmcsd -x" only. It should be rarely necessary to use this.
*/
//#define TERMINAL_FIXED_WIDTH 80
#endif // TERMINAL_FIXED_WIDTH
#ifndef _PEDANTIC
/*
* Uncomment the following #define if you want to do vlmcs and vlmcsd more checks on the data
* it receives over the network. They are normally not necessary but may provide useful if
* you are testing any KMS server or client emulator that may send malformed KMS packets.
*/
//#define _PEDANTIC
#endif // _PEDANTIC
#ifndef NO_PROCFS
/*
* Cygwin, Linux, Android, NetBSD, DragonflyBSD:
* Do not rely on a properly mounted proc filesystem and use the less reliable
* argv[0] to determine the program's executable name.
* Use only if absolutely necessary (very old versions of these OSses).
*
* Minix, OpenBSD:
* This option has no effect since the OS always must use the less reliable argv[0].
*
* FreeBSD, Mac OS X, iOS, Solaris, Windows:
* This option is not neccessary (and has no effect) since these OSses provide
* a reliable way to determine the executable name.
*
*/
//#define NO_PROCFS
#endif // NO_PROCFS
#ifndef USE_AUXV
/*
* Linux only:
* Use the process' ELF aux vector to determine the executable name.
* This is actually the best method but is supported only with
*
* * the musl library
* * the glbic library 2.16 or newer
*
* It does NOT work with uclibc (most routers and other small devices) and glibc < 2.16.
* Use it only if your system supports it and you do not plan to use the binary on older systems.
* It won't work on debian 7 or Red Hat 6.x.
*
* It is safe to try this by yourself. vlmcsd won't compile if your system doesn't support it.
*/
//#define USE_AUXV
#endif // USE_AUXV
#ifndef _OPENSSL_NO_HMAC
/*
* If you configured vlmcsd to use OpenSSL (which you shouldn't) you may use this option
* to calculate the KMSv6 HMAC with internal code instead of using OpenSSL.
*
* This may be necessary for some embedded devices that have OpenSSL without HMAC support.
*/
//#define _OPENSSL_NO_HMAC
#endif // _OPENSSL_NO_HMAC
/*
* ----------------------------------------------------------------------------------------
* Modes of operation
* ----------------------------------------------------------------------------------------
*/
#ifndef USE_THREADS
/*
* Do not use fork() but threads to serve your clients.
*
* Unix-like operarting systems:
* You may use this or not. Entirely your choice. Threads do not require explicitly allocating
* a shared memory segment which might be a problem on some systems. Using fork() is more robust
* although the threaded version of vlmcsd is rock solid too.
*
* Some older unixoid OSses may not have pthreads. Do NOT use USE_THREADS and define NO_SIGHUP
* and NO_LIMIT instead to disable use of the pthreads, shared memory and semaphores.
*
* Cygwin:
* It is recommended to use threads since fork() is extremely slow (no copy on write) and somewhat
* unstable.
*
* Windows:
* This option has no effect since fork() is not supported.
*/
//#define USE_THREADS
#endif // USE_THREADS
#ifndef _CRYPTO_POLARSSL
/*
* Not available on native Windows. Can be used with Cygwin.
*
* Use PolarSSL for crypto routines if possible and if it is safe. There is not much benefit by using this
* options since it can be used for SHA256 and HMAC_SHA256 only. It cannot be used for AES calculations because
* KMSv6 uses a modified algorithm that PolarSSL does not support. KMSv4 CMAC is also unsupported since it uses
* a Rijndael keysize (160 bits) that is not part of the AES standard.
*
* It is strongly recommended not to use an external crypto library.
*
* Do not define both _CRYPTO_OPENSSL and _CRYPTO_POLARSSL
*/
//#define _CRYPTO_POLARSSL
#endif // _CRYPTO_POLARSSL
#ifndef _CRYPTO_OPENSSL
/*
* Not available on native Windows. Can be used with Cygwin.
*
* Use OpenSSL for crypto routines if possible and if it is safe. There is not much benefit by using this
* options since it can be used for SHA256 and HMAC_SHA256 only. It cannot be used for AES calculations because
* KMSv6 uses a modified algorithm that OpenSSL does not support. KMSv4 CMAC is also unsupported since it uses
* a Rijndael keysize (160 bits) that is not part of the AES standard.
*
* It is strongly recommended not to use an external crypto library.
*
* Do not define both _CRYPTO_OPENSSL and _CRYPTO_POLARSSL
*/
//#define _CRYPTO_OPENSSL
#endif // _CRYPTO_OPENSSL
#ifndef _USE_AES_FROM_OPENSSL
/*
* DANGEROUS: Tweak OpenSSL to perform KMSv4 CMAC and KMSv6 modified AES. This option creates the expanded
* AES key by itself and then applies modifications to it. OpenSSL will then perfom modified AES operations.
*
* This options tampers with internal structures of OpenSSL that are subject to change or may have a platform
* specific implementation. In this case your resulting binary can only perform KMSv5 operations.
*
* This option has no effect if _CRYPTO_OPENSSL is not defined.
*
* Don't use this except for your own research on the internals of OpenSSL.
*/
//#define _USE_AES_FROM_OPENSSL
#endif // _USE_AES_FROM_OPENSSL
#ifndef _OPENSSL_SOFTWARE
/*
* Use this only if you have defined _CRYPTO_OPENSSL and _USE_AES_FROM_OPENSSL. It has no effect otherwise.
*
* This options assumes a different internal AES expanded key in OpenSSL which is used mostly if OpenSSL is
* compiled without support for hardware accelerated AES. It's worth a try if _USE_AES_FROM_OPENSSL doesn't work.
*/
//#define _OPENSSL_SOFTWARE
#endif // _OPENSSL_SOFTWARE
#ifndef FULL_INTERNAL_DATA
/*
* Includes the full database in vlmcsd.
*/
//#define FULL_INTERNAL_DATA
#endif // FULL_INTERNAL_DATA
/*
* ----------------------------------------------------------------------------------------
* Removal of features. Allows you to remove features of vlmcsd you do not need or want.
* Use it to get smaller binaries. This is especially useful on very small embedded devices.
* ----------------------------------------------------------------------------------------
*/
#ifndef NO_FREEBIND
/*
* Do not compile support for FREEBIND (Linux) and IP_BINDANY (FreeBSD). This disables the -F1 command
* line option and you can bind only to (listen on) IP addresses that are currently up and running on
* your system.
*/
//#define NO_FREEBIND
#endif // NO_FREEBIND
#ifndef NO_TAP
/*
* Do not compile support for using a VPN adapter under Windows. Disables -O command line option.
*/
//#define NO_TAP
#endif // NO_TAP
#ifndef NO_VERSION_INFORMATION
/*
* Removes the -V option from vlmcsd and vlmcs that displays the version information
*/
//#define NO_VERSION_INFORMATION
#endif // NO_VERSION_INFORMATION
#ifndef NO_VERBOSE_LOG
/*
* Removes the ability to do verbose logging and disables -v and -q in vlmcsd. It does not remove the -v
* option in the vlmcs client. Disables ini file directive LogVerbose.
*/
//#define NO_VERBOSE_LOG
#endif // NO_VERBOSE_LOG
#ifndef NO_LOG
/*
* Disables logging completely. You can neither log to a file nor to the console. -D and -f will
* start vlmcsd in foreground. -e will not be available. Disables ini file directive LogFile.
* Implies NO_VERBOSE_LOG.
*/
//#define NO_LOG
#endif // NO_LOG
#ifndef NO_STRICT_MODES
/*
* Disables emulator detection protection. Removes -M0, -M1, -E0, -E1, -K0, -K1, -K2 and -K3 from
* vlmcsd command line options and WhitelistingLevel from INI file parameters. vlmcsd always behaves
* as if it was started with -K0, -M0.
*/
//#define NO_STRICT_MODES
#endif // NO_STRICT_MODES
#ifndef NO_CLIENT_LIST
/*
* Disables the ability to maintain a list of Client Machine IDs (CMIDs). Removes -M0, -M1, -E0 and -E1
* from vlmcsd command line options.
*/
//#define NO_CLIENT_LIST
#endif // !NO_CLIENT_LIST
#ifndef NO_RANDOM_EPID
/*
* Disables the ability to generate random ePIDs. Useful if you managed to grab ePID/HWID from a
* real KMS server and want to use these. Removes -r from the vlmcsd command line and the ini
* file directive RandomizationLevel (The randomization level will be harcoded to 0).
*/
//#define NO_RANDOM_EPID
#endif // NO_RANDOM_EPID
#ifndef NO_INI_FILE
/*
* Disables the ability to use a configuration file (aka ini file). Removes -i from the command line.
*/
//#define NO_INI_FILE
#endif // NO_INI_FILE
#ifndef NO_PID_FILE
/*
* Disables the abilty to write a pid file containing the process id of vlmcsd. If your init system
* does not need this feature, you can safely disables this but it won't save much space. Disables
* the use of -p from the command line and PidFile from the ini file.
*/
//#define NO_PID_FILE
#endif // NO_PID_FILE
#ifndef NO_EXTERNAL_DATA
/*
* Disables the abilty to load external KMS data from a file. Disables command line options -j
* and ini file parameter KmsData. Implies UNSAFE_DATA_LOAD.
*/
//#define NO_EXTERNAL_DATA
#endif // NO_EXTERNAL_DATA
#ifndef NO_INTERNAL_DATA
/*
* Compiles vlmcsd and vlmcs without an internal database. If no database is found at
* either the default location or the file specified with command line option -j.,
* the program exits with an error message.
*/
//#define NO_INTERNAL_DATA
#endif // NO_INTERNAL_DATA
#ifndef UNSAFE_DATA_LOAD
/*
* Does not check an external KMS data file for integrity.
* This save some bytes but it dangerous if you load a KMS data file from an unknown source.
*/
//#define UNSAFE_DATA_LOAD
#endif // UNSAFE_DATA_LOAD
#ifndef NO_USER_SWITCH
/*
* Disables switching to another uid and/or gid after starting the program and setting up the sockets.
* You cannot use -u anf -g on the command line as well as User and Group in the ini file. If your init system
* supports starting daemons as another uid/gid (user/group) you can disable this feature in vlmcsd as long as you
* do not need to run vlmcsd on a privileged port ( < 1024 on most systems).
*
* This setting has no effect on native Windows since -u and -g is not available anyway. It may be used with
* Cygwin.
*/
//#define NO_USER_SWITCH
#endif // NO_USER_SWITCH
#ifndef NO_HELP
/*
* Disables display of help in both vlmcsd and vlmcs. Saves some bytes but only makes sense if you have
* access to the man files vlmcsd.8 and vlmcs.1
*/
//#define NO_HELP
#endif // NO_HELP
#ifndef NO_CUSTOM_INTERVALS
/*
* Disables the ability to specify custom interval for renewing and retrying activation. Newer versions of the Microsoft's
* KMS activation client (as in Win 8.1) do not honor these parameters anyway. Disable them to save some bytes. Removes
* -A and -R from the command line as well as ActivationInterval and RenewalInterval in the ini file.
*/
//#define NO_CUSTOM_INTERVALS
#endif // NO_CUSTOM_INTERVALS
#ifndef NO_PRIVATE_IP_DETECT
/*
* Disables the ability to protect vlmcsd against KMS requests from public IP addresses.
* Removes -o from the command line.
*/
//#define NO_PRIVATE_IP_DETECT
#endif // NO_PRIVATE_IP_DETECT
#ifndef NO_SOCKETS
/*
* Disables standalone startup of vlmcsd. If you use this config directive, you must start vlmcsd from an internet
* superserver like inetd, xinetd, systemd or launchd. Disables -m, -t, -4, -6, -e, -f, -P and -L in the vlmcsd
* command line. Socket setup is the job of your superserver.
*/
//#define NO_SOCKETS
#endif // NO_SOCKETS
#ifndef NO_CL_PIDS
/*
* Disables the ability to specify ePIDs and HWID at the command line. You still may use them in the ini file.
* Removes -0, -3, -w and -H from the vlmcsd command line.
*/
//#define NO_CL_PIDS
#endif // NO_CL_PIDS
#ifndef NO_LIMIT
/*
* Disables the ability to limit the number of worker threads or processes that vlmcsd uses. While you should set a
* limit whenever possible, you may save some bytes by enabling that setting. If you do not use a limit, use vlmcsd
* in a "friendly" environment only, i.e. do not run it without a reasonable limit on the internet.
*
* Removes the ability to use -m in the vlmcsd command line and MaxWorkers in the ini file.
*
* Some older unixoid OSses may not have pthreads. Do NOT use USE_THREADS and define NO_SIGHUP
* and NO_LIMIT instead to disable use of the pthreads, shared memory and semaphores.
*/
//#define NO_LIMIT
#endif // NO_LIMIT
#ifndef NO_SIGHUP
/*
* Disables the ability to signal hangup (SIGHUP) to vlmcsd to restart it (rereading the ini file). The SIGHUP
* handler makes heavy use of OS specific code. It should not cause any trouble on Solaris, Mac OS X and iOS. On Linux
* use "#define USE_AUXV" (see troubleshooting options) if this is supported by your C runtime library.
*
* You may save some bytes by enabling this option. Use it also if the SIGHUP handler causes any trouble on your
* platform. Please note that with no SIGHUP handler at all. vlmcsd will simply terminate (uncleanly) if it receives
* the SIGHUP signal. This is the same behavior as with most other signals.
*
* This option has no effect on native Windows since Posix signaling is not supported. It can be used with Cygwin.
*/
//#define NO_SIGHUP
#endif // NO_SIGHUP
#ifndef SIMPLE_RPC
/*
* Uses a simple version of the RPC protocol which does not support NDR64 and BTFN.
* Supports RPC with the features present in Windows XP and earlier only. Using this creates
* smaller binaries but makes emulator detection easier.
*/
//#define SIMPLE_RPC
#endif // !SIMPLE_RPC
#ifndef SIMPLE_SOCKETS
/*
* Disables the ability to choose IP addresses using the -L option in vlmcsd. vlmcsd will listen on all IP addresses.
* It still supports IPv4 and IPv6.
*/
//#define SIMPLE_SOCKETS
#endif // SIMPLE_SOCKETS
/* Don't change anything BELOW this line */
#endif /* CONFIG_H_ */

338
src/crypto.c Normal file
View File

@ -0,0 +1,338 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "crypto.h"
#include "endian.h"
#include <stdint.h>
const BYTE AesKeyV4[] = {
0x05, 0x3D, 0x83, 0x07, 0xF9, 0xE5, 0xF0, 0x88, 0xEB, 0x5E, 0xA6, 0x68, 0x6C, 0xF0, 0x37, 0xC7, 0xE4, 0xEF, 0xD2, 0xD6};
const BYTE AesKeyV5[] = {
0xCD, 0x7E, 0x79, 0x6F, 0x2A, 0xB2, 0x5D, 0xCB, 0x55, 0xFF, 0xC8, 0xEF, 0x83, 0x64, 0xC4, 0x70 };
const BYTE AesKeyV6[] = {
0xA9, 0x4A, 0x41, 0x95, 0xE2, 0x01, 0x43, 0x2D, 0x9B, 0xCB, 0x46, 0x04, 0x05, 0xD8, 0x4A, 0x21 };
static const BYTE SBox[] = {
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};
void XorBlock(const BYTE *const in, const BYTE *out) // Ensure that this is always 32 bit aligned
{
/*UAA64( out, 0 ) ^= UAA64( in, 0 );
UAA64( out, 1 ) ^= UAA64( in, 1 );*/
uint_fast8_t i;
for (i = 0; i < AES_BLOCK_WORDS; i++)
{
((DWORD*)out)[i] ^= ((DWORD*)in)[i];
}
}
#define AddRoundKey(d, rk) XorBlock((const BYTE *)rk, (const BYTE *)d)
#define Mul2(word) (((word & 0x7f7f7f7f) << 1) ^ (((word & 0x80808080) >> 7) * 0x1b))
#define Mul3(word) (Mul2(word) ^ word)
#define Mul4(word) (Mul2(Mul2(word)))
#define Mul8(word) (Mul2(Mul2(Mul2(word))))
#define Mul9(word) (Mul8(word) ^ word)
#define MulB(word) (Mul8(word) ^ Mul3(word))
#define MulD(word) (Mul8(word) ^ Mul4(word) ^ word)
#define MulE(word) (Mul8(word) ^ Mul4(word) ^ Mul2(word))
//32 bit Galois Multiplication (generates bigger code than Macros)
/*static DWORD Mul(DWORD x, DWORD y)
{
DWORD result = x, yTemp = y, log2;
if (!y) return 0;
for (log2 = 0; yTemp >>= 1; log2++ )
{
result = Mul2(result);
}
return result ^ Mul(x, y - (1 << log2));
}*/
void MixColumnsR(BYTE *restrict state)
{
uint_fast8_t i = 0;
for (; i < AES_BLOCK_WORDS; i++)
{
#if defined(_CRYPTO_OPENSSL) && defined(_OPENSSL_SOFTWARE) && defined(_USE_AES_FROM_OPENSSL) //Always byte swap regardless of endianess
DWORD word = BS32(((DWORD *) state)[i]);
((DWORD *) state)[i] = BS32(MulE(word) ^ ROR32(MulB(word), 8) ^ ROR32(MulD(word), 16) ^ ROR32(Mul9(word), 24));
#else
DWORD word = LE32(((DWORD *) state)[i]);
((DWORD *) state)[i] = LE32(MulE(word) ^ ROR32(MulB(word), 8) ^ ROR32(MulD(word), 16) ^ ROR32(Mul9(word), 24));
#endif
}
}
static DWORD SubDword(DWORD v)
{
BYTE *b = (BYTE *)&v;
uint_fast8_t i = 0;
for (; i < sizeof(DWORD); i++) b[i] = SBox[b[i]];
return v;
}
void AesInitKey(AesCtx *Ctx, const BYTE *Key, int_fast8_t IsV6, int RijndaelKeyBytes)
{
int RijndaelKeyDwords = RijndaelKeyBytes / sizeof(DWORD);
Ctx->rounds = (uint_fast8_t)(RijndaelKeyDwords + 6);
static const DWORD RCon[] = {
0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 };
uint_fast8_t i;
DWORD temp;
memcpy(Ctx->Key, Key, RijndaelKeyBytes);
for ( i = (uint_fast8_t)RijndaelKeyDwords; i < ( Ctx->rounds + 1 ) << 2; i++ )
{
temp = Ctx->Key[ i - 1 ];
if ( ( i % RijndaelKeyDwords ) == 0 )
temp = BE32( SubDword( ROR32( BE32(temp), 24) ) ^ RCon[ i / RijndaelKeyDwords ] );
Ctx->Key[ i ] = Ctx->Key[ i - RijndaelKeyDwords ] ^ temp;
}
if ( IsV6 )
{
BYTE *_p = (BYTE *)Ctx->Key;
_p[ 4 * 16 ] ^= 0x73;
_p[ 6 * 16 ] ^= 0x09;
_p[ 8 * 16 ] ^= 0xE4;
}
}
#if !defined(_CRYPTO_OPENSSL) || !defined(_USE_AES_FROM_OPENSSL) || defined(_OPENSSL_SOFTWARE)
static void SubBytes(BYTE *block)
{
uint_fast8_t i;
for (i = 0; i < AES_BLOCK_BYTES; i++)
block[i] = SBox[ block[i] ];
}
static void ShiftRows(BYTE *state)
{
BYTE bIn[AES_BLOCK_BYTES];
uint_fast8_t i;
memcpy(bIn, state, AES_BLOCK_BYTES);
for (i = 0; i < AES_BLOCK_BYTES; i++)
{
state[i] = bIn[(i + ((i & 3) << 2)) & 0xf];
}
};
static void MixColumns(BYTE *state)
{
uint_fast8_t i = 0;
for (; i < AES_BLOCK_WORDS; i++)
{
DWORD word = LE32(((DWORD *) state)[i]);
((DWORD *) state)[i] = LE32(Mul2(word) ^ ROR32(Mul3(word), 8) ^ ROR32(word, 16) ^ ROR32(word, 24));
}
}
void AesEncryptBlock(const AesCtx *const Ctx, BYTE *block)
{
uint_fast8_t i;
for ( i = 0 ;; i += 4 )
{
AddRoundKey(block, &Ctx->Key[ i ]);
SubBytes(block);
ShiftRows(block);
if ( i >= ( Ctx->rounds - 1 ) << 2 ) break;
MixColumns(block);
}
AddRoundKey(block, &Ctx->Key[ Ctx->rounds << 2 ]);
}
void AesCmacV4(BYTE *Message, size_t MessageSize, BYTE *MacOut)
{
size_t i;
BYTE mac[AES_BLOCK_BYTES];
AesCtx Ctx;
AesInitKey(&Ctx, AesKeyV4, FALSE, V4_KEY_BYTES);
memset(mac, 0, sizeof(mac));
memset(Message + MessageSize, 0, AES_BLOCK_BYTES);
Message[MessageSize] = 0x80;
for (i = 0; i <= MessageSize; i += AES_BLOCK_BYTES)
{
XorBlock(Message + i, mac);
AesEncryptBlock(&Ctx, mac);
}
memcpy(MacOut, mac, AES_BLOCK_BYTES);
}
#endif
#if !defined(_CRYPTO_OPENSSL) || !defined(_USE_AES_FROM_OPENSSL)
#ifndef SMALL_AES
static const BYTE SBoxR[] = {
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};
#define GetSBoxR(x) SBoxR[x]
#else // SMALL_AES
static uint8_t SBoxR(uint8_t byte)
{
uint8_t i;
for (i = 0; TRUE; i++)
{
if (byte == SBox[i]) return i;
}
}
#define GetSBoxR(x) SBoxR(x)
#endif // SMALL_AES
static void ShiftRowsR(BYTE *state)
{
BYTE b[AES_BLOCK_BYTES];
uint_fast8_t i;
memcpy(b, state, AES_BLOCK_BYTES);
for (i = 0; i < AES_BLOCK_BYTES; i++)
state[i] = b[(i - ((i & 0x3) << 2)) & 0xf];
}
static void SubBytesR(BYTE *block)
{
uint_fast8_t i;
for (i = 0; i < AES_BLOCK_BYTES; i++)
{
block[i] = GetSBoxR( block[i] );
}
}
void AesEncryptCbc(const AesCtx *const Ctx, BYTE *restrict iv, BYTE *restrict data, size_t *restrict len)
{
// Pad up to blocksize inclusive
size_t i;
uint_fast8_t pad = (~*len & (AES_BLOCK_BYTES - 1)) + 1;
#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 8) // gcc 4.8 memset bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56977
for (i = 0; i < pad; i++) data[*len + i] = pad;
#else
memset(data + *len, pad, pad);
#endif
*len += pad;
if ( iv ) XorBlock(iv, data);
AesEncryptBlock(Ctx, data);
for (i = *len - AES_BLOCK_BYTES; i; i -= AES_BLOCK_BYTES)
{
XorBlock(data, data + AES_BLOCK_BYTES);
data += AES_BLOCK_BYTES;
AesEncryptBlock(Ctx, data);
}
}
void AesDecryptBlock(const AesCtx *const Ctx, BYTE *block)
{
uint_fast8_t i;
AddRoundKey(block, &Ctx->Key[ Ctx->rounds << 2 ]);
for ( i = ( Ctx->rounds - 1 ) << 2 ;; i -= 4 )
{
ShiftRowsR(block);
SubBytesR(block);
AddRoundKey(block, &Ctx->Key[ i ]);
if ( i == 0 ) break;
MixColumnsR(block);
}
}
void AesDecryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t len)
{
BYTE *cc;
for (cc = data + len - AES_BLOCK_BYTES; cc > data; cc -= AES_BLOCK_BYTES)
{
AesDecryptBlock(Ctx, cc);
XorBlock(cc - AES_BLOCK_BYTES, cc);
}
AesDecryptBlock(Ctx, cc);
if ( iv ) XorBlock(iv, cc);
}
#endif // _CRYPTO_OPENSSL || OPENSSL_VERSION_NUMBER < 0x10000000L

57
src/crypto.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef __crypto_h
#define __crypto_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "types.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "endian.h"
#include <stdint.h>
#define AES_KEY_BYTES (16) // 128 Bits
#define AES_BLOCK_BYTES (16)
#define AES_BLOCK_WORDS (AES_BLOCK_BYTES / sizeof(DWORD))
#define AES_KEY_DWORDS (AES_KEY_BYTES / sizeof(DWORD))
#define V4_KEY_BYTES (20) // 160 Bits
#define ROR32(v, n) ( (v) << (32 - n) | (v) >> n )
void XorBlock(const BYTE *const in, const BYTE *out);
void AesCmacV4(BYTE *data, size_t len, BYTE *hash);
extern const BYTE AesKeyV5[];
extern const BYTE AesKeyV6[];
typedef struct {
DWORD Key[48]; // Supports a maximum of 160 key bits!
uint_fast8_t rounds;
} AesCtx;
void AesInitKey(AesCtx *Ctx, const BYTE *Key, int_fast8_t IsV6, int AesKeyBytes);
void AesEncryptBlock(const AesCtx *const Ctx, BYTE *block);
void AesDecryptBlock(const AesCtx *const Ctx, BYTE *block);
void AesEncryptCbc(const AesCtx *const Ctx, BYTE *restrict iv, BYTE *restrict data, size_t *restrict len);
void AesDecryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t len);
void MixColumnsR(BYTE *restrict state);
#if defined(_CRYPTO_OPENSSL)
#include "crypto_openssl.h"
#elif defined(_CRYPTO_POLARSSL)
#include "crypto_polarssl.h"
#elif defined(_CRYPTO_WINDOWS)
#include "crypto_windows.h"
#else
#include "crypto_internal.h"
#endif
#endif // __crypto_h

212
src/crypto_internal.c Normal file
View File

@ -0,0 +1,212 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#if !defined(_CRYPTO_OPENSSL) && !defined(_CRYPTO_POLARSSL) && !defined(_CRYPTO_WINDOWS)
#include "crypto_internal.h"
#include "endian.h"
#define F0(x, y, z) ( ((x) & (y)) | (~(x) & (z)) )
#define F1(x, y, z) ( ((x) & (y)) | ((x) & (z)) | ((y) & (z)) )
#define SI1(x) ( ROR32(x, 2 ) ^ ROR32(x, 13) ^ ROR32(x, 22) )
#define SI2(x) ( ROR32(x, 6 ) ^ ROR32(x, 11) ^ ROR32(x, 25) )
#define SI3(x) ( ROR32(x, 7 ) ^ ROR32(x, 18) ^ ((x) >> 3 ) )
#define SI4(x) ( ROR32(x, 17) ^ ROR32(x, 19) ^ ((x) >> 10) )
static const DWORD k[] = {
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1,
0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786,
0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147,
0x06CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B,
0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A,
0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
};
static void Sha256Init(Sha256Ctx *Ctx)
{
Ctx->State[0] = 0x6A09E667;
Ctx->State[1] = 0xBB67AE85;
Ctx->State[2] = 0x3C6EF372;
Ctx->State[3] = 0xA54FF53A;
Ctx->State[4] = 0x510E527F;
Ctx->State[5] = 0x9B05688C;
Ctx->State[6] = 0x1F83D9AB;
Ctx->State[7] = 0x5BE0CD19;
Ctx->Len = 0;
}
static void Sha256ProcessBlock(Sha256Ctx *Ctx, BYTE *block)
{
unsigned int i;
DWORD w[64], temp1, temp2;
DWORD a = Ctx->State[0];
DWORD b = Ctx->State[1];
DWORD c = Ctx->State[2];
DWORD d = Ctx->State[3];
DWORD e = Ctx->State[4];
DWORD f = Ctx->State[5];
DWORD g = Ctx->State[6];
DWORD h = Ctx->State[7];
for (i = 0; i < 16; i++)
//w[ i ] = GET_UAA32BE(block, i);
w[i] = BE32(((DWORD*)block)[i]);
for (i = 16; i < 64; i++)
w[ i ] = SI4(w[ i - 2 ]) + w[ i - 7 ] + SI3(w[ i - 15 ]) + w[ i - 16 ];
for (i = 0; i < 64; i++)
{
temp1 = h + SI2(e) + F0(e, f, g) + k[ i ] + w[ i ];
temp2 = SI1(a) + F1(a, b, c);
h = g;
g = f;
f = e;
e = d + temp1;
d = c;
c = b;
b = a;
a = temp1 + temp2;
}
Ctx->State[0] += a;
Ctx->State[1] += b;
Ctx->State[2] += c;
Ctx->State[3] += d;
Ctx->State[4] += e;
Ctx->State[5] += f;
Ctx->State[6] += g;
Ctx->State[7] += h;
}
static void Sha256Update(Sha256Ctx *Ctx, BYTE *data, size_t len)
{
unsigned int b_len = Ctx->Len & 63,
r_len = (b_len ^ 63) + 1;
Ctx->Len += (unsigned int)len;
if ( len < r_len )
{
memcpy(Ctx->Buffer + b_len, data, len);
return;
}
if ( r_len < 64 )
{
memcpy(Ctx->Buffer + b_len, data, r_len);
len -= r_len;
data += r_len;
Sha256ProcessBlock(Ctx, Ctx->Buffer);
}
for (; len >= 64; len -= 64, data += 64)
Sha256ProcessBlock(Ctx, data);
if ( len ) memcpy(Ctx->Buffer, data, len);
}
static void Sha256Finish(Sha256Ctx *Ctx, BYTE *hash)
{
unsigned int i, b_len = Ctx->Len & 63;
Ctx->Buffer[ b_len ] = 0x80;
if ( b_len ^ 63 ) memset(Ctx->Buffer + b_len + 1, 0, b_len ^ 63);
if ( b_len >= 56 )
{
Sha256ProcessBlock(Ctx, Ctx->Buffer);
memset(Ctx->Buffer, 0, 56);
}
//PUT_UAA64BE(Ctx->Buffer, (unsigned long long)(Ctx->Len * 8), 7);
((uint64_t*)Ctx->Buffer)[7] = BE64((uint64_t)Ctx->Len << 3);
Sha256ProcessBlock(Ctx, Ctx->Buffer);
for (i = 0; i < 8; i++)
//PUT_UAA32BE(hash, Ctx->State[i], i);
((DWORD*)hash)[i] = BE32(Ctx->State[i]);
}
void Sha256(BYTE *data, size_t len, BYTE *hash)
{
Sha256Ctx Ctx;
Sha256Init(&Ctx);
Sha256Update(&Ctx, data, len);
Sha256Finish(&Ctx, hash);
}
static void _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen)
{
BYTE IPad[64];
unsigned int i;
memset(IPad, 0x36, sizeof(IPad));
memset(Ctx->OPad, 0x5C, sizeof(Ctx->OPad));
if ( klen > 64 )
{
BYTE *temp = (BYTE*)alloca(32);
Sha256(key, klen, temp);
klen = 32;
key = temp;
}
for (i = 0; i < klen; i++)
{
IPad[ i ] ^= key[ i ];
Ctx->OPad[ i ] ^= key[ i ];
}
Sha256Init(&Ctx->ShaCtx);
Sha256Update(&Ctx->ShaCtx, IPad, sizeof(IPad));
}
static void _Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, size_t len)
{
Sha256Update(&Ctx->ShaCtx, data, len);
}
static void _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac)
{
BYTE temp[32];
Sha256Finish(&Ctx->ShaCtx, temp);
Sha256Init(&Ctx->ShaCtx);
Sha256Update(&Ctx->ShaCtx, Ctx->OPad, sizeof(Ctx->OPad));
Sha256Update(&Ctx->ShaCtx, temp, sizeof(temp));
Sha256Finish(&Ctx->ShaCtx, hmac);
}
int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac)
{
Sha256HmacCtx Ctx;
_Sha256HmacInit(&Ctx, key, 16);
_Sha256HmacUpdate(&Ctx, data, len);
_Sha256HmacFinish(&Ctx, hmac);
return TRUE;
}
#endif // No external Crypto

38
src/crypto_internal.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef __crypto_internal_h
#define __crypto_internal_h
#if !defined(_CRYPTO_OPENSSL) && !defined(_CRYPTO_POLARSSL) && !defined(_CRYPTO_WINDOWS)
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "crypto.h"
typedef struct {
DWORD State[8];
BYTE Buffer[64];
unsigned int Len;
} Sha256Ctx;
typedef struct {
Sha256Ctx ShaCtx;
BYTE OPad[64];
} Sha256HmacCtx;
void Sha256(BYTE *data, size_t len, BYTE *hash);
int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac);
//void _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen);
//void _Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, size_t len);
//void _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac);
//#define Sha256HmacInit(c, k, l) ( _Sha256HmacInit(c, k, l), !0 )
//#define Sha256HmacUpdate(c, d, l) ( _Sha256HmacUpdate(c, d, l), !0 )
//#define Sha256HmacFinish(c, h) ( _Sha256HmacFinish(c, h), !0 )
#endif // !defined(_CRYPTO_OPENSSL) && !defined(_CRYPTO_POLARSSL) && !defined(_CRYPTO_WINDOWS)
#endif // __crypto_internal_h

269
src/crypto_openssl.c Normal file
View File

@ -0,0 +1,269 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#if defined(_CRYPTO_OPENSSL)
#include "crypto.h"
#include "crypto_openssl.h" // Required for Eclipse only
#include <stdint.h>
#include "endian.h"
#ifndef _OPENSSL_NO_HMAC
int Sha256HmacInit_OpenSSL(HMAC_CTX *c, const void *k, int l)
{
HMAC_CTX_init(c);
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
int result =
#else
int result = TRUE;
#endif
HMAC_Init_ex(c, k, l, EVP_sha256(), NULL);
return result;
}
int Sha256HmacFinish_OpenSSL(HMAC_CTX *c, unsigned char *h, unsigned int *l)
{
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
int result =
#else
int result = !0;
#endif
HMAC_Final(c, h, l);
HMAC_CTX_cleanup(c);
return result;
}
int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac)
{
HMAC_CTX Ctx;
# if OPENSSL_VERSION_NUMBER >= 0x10000000L
return
Sha256HmacInit_OpenSSL(&Ctx, key, 16) &&
HMAC_Update(&Ctx, data, len) &&
Sha256HmacFinish_OpenSSL(&Ctx, hmac, NULL);
# else // OpenSSL 0.9.x
Sha256HmacInit_OpenSSL(&Ctx, key, 16);
HMAC_Update(&Ctx, data, len);
Sha256HmacFinish_OpenSSL(&Ctx, hmac, NULL);
return TRUE;
# endif
}
#else // _OPENSSL_NO_HMAC (some routers have OpenSSL without support for HMAC)
int _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen)
{
BYTE IPad[64];
unsigned int i;
memset(IPad, 0x36, sizeof(IPad));
memset(Ctx->OPad, 0x5C, sizeof(Ctx->OPad));
if ( klen > 64 )
{
BYTE *temp = (BYTE*)alloca(32);
SHA256(key, klen, temp);
klen = 32;
key = temp;
}
for (i = 0; i < klen; i++)
{
IPad[ i ] ^= key[ i ];
Ctx->OPad[ i ] ^= key[ i ];
}
SHA256_Init(&Ctx->ShaCtx);
return SHA256_Update(&Ctx->ShaCtx, IPad, sizeof(IPad));
}
int _Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, size_t len)
{
int rc = SHA256_Update(&Ctx->ShaCtx, data, len);
return rc;
}
int _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac, void* dummy)
{
BYTE temp[32];
SHA256_Final(temp, &Ctx->ShaCtx);
SHA256_Init(&Ctx->ShaCtx);
SHA256_Update(&Ctx->ShaCtx, Ctx->OPad, sizeof(Ctx->OPad));
SHA256_Update(&Ctx->ShaCtx, temp, sizeof(temp));
return SHA256_Final(hmac, &Ctx->ShaCtx);
}
int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac)
{
Sha256HmacCtx Ctx;
_Sha256HmacInit(&Ctx, key, 16);
_Sha256HmacUpdate(&Ctx, data, len);
_Sha256HmacFinish(&Ctx, hmac, NULL);
return TRUE;
}
#endif
#if defined(_USE_AES_FROM_OPENSSL)
void TransformOpenSslEncryptKey(AES_KEY *k, const AesCtx *const Ctx)
{
uint32_t *rk_OpenSSL = k->rd_key, *rk_vlmcsd = (uint32_t*)Ctx->Key;
k->rounds = Ctx->rounds;
for (; rk_OpenSSL < k->rd_key + ((k->rounds + 1) << 2); rk_OpenSSL++, rk_vlmcsd++)
{
#ifdef _OPENSSL_SOFTWARE
*rk_OpenSSL = BE32(*rk_vlmcsd);
#else
*rk_OpenSSL = LE32(*rk_vlmcsd);
#endif
}
}
void TransformOpenSslDecryptKey(AES_KEY *k, const AesCtx *const Ctx)
{
uint_fast8_t i;
#ifdef _DEBUG_OPENSSL
AES_set_decrypt_key((BYTE*)Ctx->Key, 128, k);
errorout("Correct V5 round key:");
for (i = 0; i < (Ctx->rounds + 1) << 4; i++)
{
if (!(i % 16)) errorout("\n");
if (!(i % 4)) errorout(" ");
errorout("%02X", ((BYTE*)(k->rd_key))[i]);
}
errorout("\n");
#endif
k->rounds = Ctx->rounds;
/* invert the order of the round keys blockwise (1 Block = AES_BLOCK_SIZE = 16): */
for (i = 0; i < (Ctx->rounds + 1) << 2; i++)
{
#ifdef _OPENSSL_SOFTWARE
k->rd_key[((Ctx->rounds-(i >> 2)) << 2) + (i & 3)] = BE32(Ctx->Key[i]);
#else
k->rd_key[((Ctx->rounds-(i >> 2)) << 2) + (i & 3)] = LE32(Ctx->Key[i]);
#endif
}
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
uint32_t *rk = k->rd_key + 4;
for (i = 0; i < (Ctx->rounds - 1); i++)
{
MixColumnsR((BYTE*)(rk + (i << 2)));
}
#ifdef _DEBUG_OPENSSL
errorout("Real round key:");
for (i = 0; i < (Ctx->rounds + 1) << 4; i++)
{
if (!(i % 16)) errorout("\n");
if (!(i % 4)) errorout(" ");
errorout("%02X", ((BYTE*)(k->rd_key))[i]);
}
errorout("\n");
#endif
}
static BYTE NullIV[AES_BLOCK_SIZE + 8]; // OpenSSL may overwrite bytes behind IV
void AesEncryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t *len)
{
AES_KEY k;
// OpenSSL overwrites IV plus 4 bytes
BYTE localIV[24]; // 4 spare bytes for safety
if (iv) memcpy(localIV, iv, AES_BLOCK_SIZE);
// OpenSSL Low-Level APIs do not pad. Could use EVP API instead but needs more code to access the expanded key
uint_fast8_t pad = (~*len & (AES_BLOCK_SIZE - 1)) + 1;
#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 8) // gcc 4.8 memset bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56977
size_t i;
for (i = 0; i < pad; i++) data[*len + i] = pad;
#else
memset(data + *len, pad, pad);
#endif
*len += pad;
memset(NullIV, 0, sizeof(NullIV));
TransformOpenSslEncryptKey(&k, Ctx);
AES_cbc_encrypt(data, data, *len, &k, iv ? localIV : NullIV, AES_ENCRYPT);
}
void AesDecryptBlock(const AesCtx *const Ctx, BYTE *block)
{
AES_KEY k;
TransformOpenSslDecryptKey(&k, Ctx);
AES_decrypt(block, block, &k);
}
#if defined(_CRYPTO_OPENSSL) && defined(_USE_AES_FROM_OPENSSL) && !defined(_OPENSSL_SOFTWARE)
void AesEncryptBlock(const AesCtx *const Ctx, BYTE *block)
{
AES_KEY k;
TransformOpenSslEncryptKey(&k, Ctx);
AES_encrypt(block, block, &k);
}
#endif
void AesDecryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t len)
{
AES_KEY k;
memset(NullIV, 0, sizeof(NullIV));
TransformOpenSslDecryptKey(&k, Ctx);
AES_cbc_encrypt(data, data, len, &k, iv ? iv : NullIV, AES_DECRYPT);
}
#ifndef _OPENSSL_SOFTWARE
void AesCmacV4(BYTE *Message, size_t MessageSize, BYTE *HashOut)
{
size_t i;
BYTE hash[AES_BLOCK_BYTES];
AesCtx Ctx;
AES_KEY k;
AesInitKey(&Ctx, AesKeyV4, FALSE, V4_KEY_BYTES);
TransformOpenSslEncryptKey(&k, &Ctx);
memset(hash, 0, sizeof(hash));
memset(Message + MessageSize, 0, AES_BLOCK_BYTES);
Message[MessageSize] = 0x80;
for (i = 0; i <= MessageSize; i += AES_BLOCK_BYTES)
{
XorBlock(Message + i, hash);
AES_encrypt(hash, hash, &k);
}
memcpy(HashOut, hash, AES_BLOCK_BYTES);
}
#endif // !_OPENSSL_SOFTWARE
#endif // defined(_USE_AES_FROM_OPENSSL)
#endif // _CRYPTO_OPENSSL

53
src/crypto_openssl.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef __crypto_openssl_h
#define __crypto_openssl_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include <openssl/opensslv.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/aes.h>
#include "crypto.h"
#define Sha256(d, l, h) SHA256(d, l, h)
int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac);
#ifndef _OPENSSL_NO_HMAC
#define Sha256HmacCtx HMAC_CTX
#else
typedef struct {
SHA256_CTX ShaCtx;
BYTE OPad[64];
} Sha256HmacCtx;
#endif
#ifndef _OPENSSL_NO_HMAC
#define Sha256HmacInit(c, k, l) Sha256HmacInit_OpenSSL(c, k, l)
#define Sha256HmacFinish(c, h) Sha256HmacFinish_OpenSSL(c, h, NULL)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#define Sha256HmacUpdate(c, d, l) HMAC_Update(c, d, l)
#else // OPENSSL_VERSION_NUMBER < 0x10000000L
#define Sha256HmacUpdate(c, d, l) (HMAC_Update(c, d, l), !0)
#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
int Sha256HmacInit_OpenSSL(HMAC_CTX *c, const void *k, int l);
int Sha256HmacFinish_OpenSSL(HMAC_CTX *c, unsigned char *h, unsigned int *l);
#else // _OPENSSL_NO_HMAC
int _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen);
int _Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, size_t len);
int _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac, void* dummy);
#define Sha256HmacInit(c, k, l) _Sha256HmacInit(c, k, l)
#define Sha256HmacFinish(c, h) _Sha256HmacFinish(c, h, NULL)
#define Sha256HmacUpdate(c, d, l) _Sha256HmacUpdate(c, d, l)
#endif // _OPENSSL_NO_HMAC
extern const BYTE AesKeyV4[];
#endif // __crypto_openssl_h

39
src/crypto_polarssl.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef __crypto_polarssl_h
#define __crypto_polarssl_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include <polarssl/version.h>
#include "crypto.h"
#if POLARSSL_VERSION_NUMBER >= 0x01030000
#include <polarssl/sha256.h>
#define Sha256(d, l, h) sha256(d, l, h, 0)
#define Sha256HmacCtx sha256_context
#define Sha256HmacInit(c, k, l) ( sha256_hmac_starts(c, k, l, 0), !0 )
#define Sha256HmacUpdate(c, d, l) ( sha256_hmac_update(c, d, l), !0 )
#define Sha256HmacFinish(c, h) ( sha256_hmac_finish(c, h), !0 )
#define Sha256Hmac(k, d, l, h) ( sha256_hmac(k, 16, d, l, h, FALSE), !0 )
#else // POLARSSL_VERSION_NUMBER
#include <polarssl/sha2.h>
#define Sha256(d, l, h) sha2(d, l, h, 0)
#define Sha256HmacCtx sha2_context
#define Sha256HmacInit(c, k, l) ( sha2_hmac_starts(c, k, l, 0), !0 )
#define Sha256HmacUpdate(c, d, l) ( sha2_hmac_update(c, d, l), !0 )
#define Sha256HmacFinish(c, h) ( sha2_hmac_finish(c, h), !0 )
#define Sha256Hmac(k, d, l, h) ( sha2_hmac(k, 16, d, l, h, FALSE), !0 )
#endif // POLARSSL_VERSION_NUMBER
#endif // __crypto_polarssl_h

170
src/crypto_windows.c Normal file
View File

@ -0,0 +1,170 @@
/*
* crypto_windows.c
*/
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifdef _CRYPTO_WINDOWS
#if !_WIN32 && !__CYGWIN__
#error You cannot use Windows CryptoAPI on non-Windows platforms
#else // _WIN32 || __CYGWIN__
#include "crypto_windows.h"
typedef struct _HMAC_KEYBLOB
{
BLOBHEADER hdr;
DWORD dwKeySize;
BYTE KeyData[16];
} HMAC_KEYBLOB;
/*
* MingW and Cygwin define NULL as ((void*)0) (Posix standard) which you can't assign to
* non-pointer types without compiler warning. Thus we use the following
*/
#define NULLHANDLE 0
#define NULLFLAGS 0
static HCRYPTPROV hRsaAesProvider = 0; // Needs to be initialized just once per process
static int_fast8_t AcquireCryptContext()
{
if (!hRsaAesProvider)
{
return (int_fast8_t)CryptAcquireContextW
(
&hRsaAesProvider, // Provider handle
NULL, // No key container name
NULL, // Default provider
PROV_RSA_AES, // Provides SHA and AES
CRYPT_VERIFYCONTEXT // We don't need access to persistent keys
);
}
return TRUE;
}
int_fast8_t Sha256(BYTE* restrict data, DWORD DataSize, BYTE* restrict hash)
{
HCRYPTHASH hHash = 0;
DWORD HashSize = 32;
int_fast8_t success =
AcquireCryptContext() &&
CryptCreateHash
(
hRsaAesProvider,// Provider handle
CALG_SHA_256, // Algorithm
NULLHANDLE, // SHA256 requires no key
NULLFLAGS, // Use default flags
&hHash // Handle for hashing
) &&
CryptHashData
(
hHash, // Handle
data, // data to hash
DataSize, // size of data
NULLFLAGS // Use default flags
) &&
CryptGetHashParam
(
hHash, // Handle
HP_HASHVAL, // what you actually want to get (the resulting hash)
hash, // data to retrieve
&HashSize, // size of data
NULLFLAGS // currently reserved (as of this writing)
);
if (hHash) CryptDestroyHash(hHash);
return success;
}
int_fast8_t Sha256Hmac(const BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac)
{
# ifndef USE_THREADS // In fork() mode thread-safety is not required
static
# endif
HMAC_KEYBLOB hmackeyblob = {
// Type, Version, Algorithm
{ PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, CALG_RC2 },
// Key length
16
};
HCRYPTKEY hKey = NULLHANDLE;
HCRYPTHASH hHmacHash = NULLHANDLE;
HMAC_INFO HmacInfo = { 0 };
DWORD dwHmacSize = 32;
HmacInfo.HashAlgid = CALG_SHA_256;
memcpy(hmackeyblob.KeyData, key, sizeof(hmackeyblob.KeyData));
BOOL success =
AcquireCryptContext() &&
CryptImportKey
(
hRsaAesProvider, // provider handle
(PBYTE)&hmackeyblob, // the actual key MS blob format
sizeof(HMAC_KEYBLOB), // size of the entire blob
NULLHANDLE, // password/key for the key store (none required here)
NULLFLAGS, // default flags
&hKey // key handle to retrieve (must be kept until you finish hashing)
) &&
CryptCreateHash
(
hRsaAesProvider, // provider handle
CALG_HMAC, // the actual key MS blob format
hKey, // size of the entire blob
NULLFLAGS, // password/key for the key store (none required here)
&hHmacHash // default flags
) && // key handle to retrieve (must be kept until you finish hashing)
CryptSetHashParam
(
hHmacHash, // hash handle
HP_HMAC_INFO, // parameter you want to set
(PBYTE)&HmacInfo, // the HMAC parameters (SHA256 with default ipad and opad)
NULLFLAGS // flags are reserved up to Windows 8.1
) &&
CryptHashData
(
hHmacHash, // hash handle
data, // Pointer to data you want to hash
len, // data length
NULLFLAGS // default flags
) &&
CryptGetHashParam
(
hHmacHash, // hash handle
HP_HASHVAL, // what you actually want to get (the resulting HMAC)
hmac, // data to retrieve
&dwHmacSize, // size of data
NULLFLAGS // currently reserved (as of this writing)
);
if (hKey) CryptDestroyKey(hKey);
if (hHmacHash) CryptDestroyHash(hHmacHash);
return (int_fast8_t)success;
}
#endif // _WIN32 || __CYGWIN__
#endif // _CRYPTO_WINDOWS

34
src/crypto_windows.h Normal file
View File

@ -0,0 +1,34 @@
/*
* crypto_windows.h
*/
#ifdef _CRYPTO_WINDOWS
#ifndef CRYPTO_WINDOWS_H_
#define CRYPTO_WINDOWS_H_
#if !_WIN32 && !__CYGWIN__
#error You cannot use Windows CryptoAPI on non-Windows platforms
#else // _WIN32 || __CYGWIN__
#include "types.h"
#if _MSC_VER
#include "Wincrypt.h"
#endif
typedef struct _Sha2356HmacCtx
{
HCRYPTHASH hHmac;
HCRYPTKEY hKey;
} Sha256HmacCtx;
int_fast8_t Sha256(BYTE* restrict data, DWORD DataSize, BYTE* restrict hash);
int_fast8_t Sha256Hmac(const BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac);
/*int_fast8_t Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, uint8_t keySize);
int_fast8_t Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, DWORD len);
int_fast8_t Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac);*/
#endif // _WIN32 || __CYGWIN__
#endif /* CRYPTO_WINDOWS_H_ */
#endif // _CRYPTO_WINDOWS

330
src/dns_srv.c Normal file
View File

@ -0,0 +1,330 @@
/*
* dns_srv.c
*
* This file contains the code for KMS SRV record lookup in DNS (_vlmcs._tcp.example.com IN SRV 0 0 1688 mykms.example.com)
*
*/
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifndef NO_DNS
#include "dns_srv.h"
#include <string.h>
#include <stdio.h>
#ifndef _WIN32
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
//#ifndef DNS_PARSER_INTERNAL
#if __ANDROID__
#include <netinet/in.h>
#include "nameser.h"
#include "resolv.h"
#else // other Unix non-Android
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#endif // other Unix non-Android
//#endif // DNS_PARSER_INTERNAL
#else // WIN32
#include <windns.h>
#endif // WIN32
#include "helpers.h"
#include "output.h"
#include "endian.h"
#if defined(DNS_PARSER_INTERNAL) && !defined(_WIN32)
#include "ns_name.h"
#include "ns_parse.h"
// Define macros to redirect DNS parser functions to internal versions
#undef ns_msg
#undef ns_initparse
#undef ns_parserr
#undef ns_rr
#undef ns_name_uncompress
#undef ns_msg_base
#undef ns_msg_end
#undef ns_rr_rdata
#undef ns_rr_type
#undef ns_msg_count
#undef ns_rr_class
#undef ns_s_an
#define ns_msg ns_msg_vlmcsd
#define ns_initparse ns_initparse_vlmcsd
#define ns_parserr ns_parserr_vlmcsd
#define ns_rr ns_rr_vlmcsd
#define ns_name_uncompress ns_name_uncompress_vlmcsd
#define ns_msg_base ns_msg_base_vlmcsd
#define ns_msg_end ns_msg_end_vlmcsd
#define ns_rr_rdata ns_rr_rdata_vlmcsd
#define ns_rr_type ns_rr_type_vlmcsd
#define ns_msg_count ns_msg_count_vlmcsd
#define ns_rr_class ns_rr_class_vlmcsd
#define ns_s_an ns_s_an_vlmcsd
#ifndef NS_MAXLABEL
#define NS_MAXLABEL 63
#endif
#endif // defined(DNS_PARSER_INTERNAL) && !defined(_WIN32)
//TODO: maybe move to helpers.c
static unsigned int isqrt(unsigned int n)
{
unsigned int c = 0x8000;
unsigned int g = 0x8000;
for (;;)
{
if (g*g > n)
g ^= c;
c >>= 1;
if (c == 0) return g;
g |= c;
}
}
/*
* Compare function for qsort to sort SRV records by priority and weight
* random_weight must be product of weight from SRV record and square root of a random number
*/
static int kmsServerListCompareFunc1(const void* a, const void* b)
{
if (!a && !b) return 0;
if (a && !b) return -1;
if (!a && b) return 1;
int priority_order = (int)((*(kms_server_dns_ptr*)a)->priority) - ((int)(*(kms_server_dns_ptr*)b)->priority);
if (priority_order) return priority_order;
return (int)((*(kms_server_dns_ptr*)b)->random_weight) - ((int)(*(kms_server_dns_ptr*)a)->random_weight);
}
/* Sort resulting SRV records */
void sortSrvRecords(kms_server_dns_ptr* serverlist, const int answers)
{
int i;
for (i = 0; i < answers; i++)
{
serverlist[i]->random_weight = (rand32() % 256) * isqrt(serverlist[i]->weight * 1000);
}
qsort(serverlist, answers, sizeof(kms_server_dns_ptr), kmsServerListCompareFunc1);
}
#define RECEIVE_BUFFER_SIZE 2048
#ifndef _WIN32 // UNIX resolver
/*
* Retrieves a raw DNS answer (a buffer of what came over the net)
* Result must be parsed
*/
static int getDnsRawAnswer(const char *restrict query, unsigned char** receive_buffer)
{
if (res_init() < 0)
{
errorout("Cannot initialize resolver: %s", strerror(errno));
return 0;
}
//if(!(*receive_buffer = (unsigned char*)malloc(RECEIVE_BUFFER_SIZE))) OutOfMemory();
*receive_buffer = (unsigned char*)vlmcsd_malloc(RECEIVE_BUFFER_SIZE);
int bytes_received;
if (*query == '.')
{
# if __ANDROID__ || __GLIBC__ /* including __UCLIBC__*/ || __APPLE__ || __CYGWIN__ || __FreeBSD__ || __NetBSD__ || __DragonFly__ || __OpenBSD__ || __sun__
bytes_received = res_querydomain("_vlmcs._tcp", query + 1, ns_c_in, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
# else
char* querystring = (char*)alloca(strlen(query) + 12);
strcpy(querystring, "_vlmcs._tcp");
strcat(querystring, query);
bytes_received = res_query(querystring, ns_c_in, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
# endif
}
else
{
bytes_received = res_search("_vlmcs._tcp", ns_c_in, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
}
if (bytes_received < 0)
{
errorout("Fatal: DNS query to %s%s failed: %s\n", "_vlmcs._tcp", *query == '.' ? query : "", hstrerror(h_errno));
return 0;
}
return bytes_received;
}
/*
* Retrieves an unsorted array of SRV records (Unix / Posix)
*/
int getKmsServerList(kms_server_dns_ptr** serverlist, const char *restrict query)
{
unsigned char* receive_buffer;
*serverlist = NULL;
int bytes_received = getDnsRawAnswer(query, &receive_buffer);
if (bytes_received == 0) return 0;
ns_msg msg;
if (ns_initparse(receive_buffer, bytes_received, &msg) < 0)
{
errorout("Fatal: Incorrect DNS response: %s\n", strerror(errno));
free(receive_buffer);
return 0;
}
uint16_t i, answers = ns_msg_count(msg, ns_s_an);
//if(!(*serverlist = (kms_server_dns_ptr*)malloc(answers * sizeof(kms_server_dns_ptr)))) OutOfMemory();
*serverlist = (kms_server_dns_ptr*)malloc(answers * sizeof(kms_server_dns_ptr));
memset(*serverlist, 0, answers * sizeof(kms_server_dns_ptr));
for (i = 0; i < answers; i++)
{
ns_rr rr;
if (ns_parserr(&msg, ns_s_an, i, &rr) < 0)
{
errorout("Warning: Error in DNS resource record: %s\n", strerror(errno));
continue;
}
if (ns_rr_type(rr) != ns_t_srv)
{
errorout("Warning: DNS server returned non-SRV record\n");
continue;
}
if (ns_rr_class(rr) != ns_c_in)
{
errorout("Warning: DNS server returned non-IN class record\n");
continue;
}
dns_srv_record_ptr srvrecord = (dns_srv_record_ptr)ns_rr_rdata(rr);
kms_server_dns_ptr kms_server = (kms_server_dns_ptr)vlmcsd_malloc(sizeof(kms_server_dns_t));
(*serverlist)[i] = kms_server;
if (ns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg), srvrecord->name, kms_server->serverName, sizeof(kms_server->serverName)) < 0)
{
errorout("Warning: No valid DNS name returned in SRV record: %s\n", strerror(errno));
continue;
}
sprintf(kms_server->serverName + strlen(kms_server->serverName), ":%hu", GET_UA16BE(&srvrecord->port));
kms_server->priority = GET_UA16BE(&srvrecord->priority);
kms_server->weight = GET_UA16BE(&srvrecord->weight);
}
free(receive_buffer);
return answers;
}
#else // WIN32 (Windows Resolver)
/*
* Retrieves an unsorted array of SRV records (Windows)
*/
int getKmsServerList(kms_server_dns_ptr** serverlist, const char *const restrict query)
{
# define MAX_DNS_NAME_SIZE 254
* serverlist = NULL;
PDNS_RECORD receive_buffer;
char dnsDomain[MAX_DNS_NAME_SIZE];
char FqdnQuery[MAX_DNS_NAME_SIZE];
DWORD size = MAX_DNS_NAME_SIZE;
DNS_STATUS result;
int answers = 0;
PDNS_RECORD dns_iterator;
if (*query == '-')
{
if (!GetComputerNameExA(ComputerNamePhysicalDnsDomain, dnsDomain, &size))
{
errorout("Fatal: Could not determine computer's DNS name: %s\n", vlmcsd_strerror(GetLastError()));
return 0;
}
strcpy(FqdnQuery, "_vlmcs._tcp.");
strncat(FqdnQuery, dnsDomain, MAX_DNS_NAME_SIZE - 12);
}
else
{
strcpy(FqdnQuery, "_vlmcs._tcp");
strncat(FqdnQuery, query, MAX_DNS_NAME_SIZE - 11);
}
if ((result = DnsQuery_UTF8(FqdnQuery, DNS_TYPE_SRV, 0, NULL, &receive_buffer, NULL)) != 0)
{
errorout("Fatal: DNS query to %s failed: %s\n", FqdnQuery, vlmcsd_strerror(result));
return 0;
}
for (dns_iterator = receive_buffer; dns_iterator; dns_iterator = dns_iterator->pNext)
{
if (dns_iterator->Flags.S.Section != 1) continue;
if (dns_iterator->wType != DNS_TYPE_SRV)
{
errorout("Warning: DNS server returned non-SRV record\n");
continue;
}
answers++;
}
*serverlist = (kms_server_dns_ptr*)vlmcsd_malloc(answers * sizeof(kms_server_dns_ptr));
for (answers = 0, dns_iterator = receive_buffer; dns_iterator; dns_iterator = dns_iterator->pNext)
{
if (dns_iterator->wType != DNS_TYPE_SRV) continue;
kms_server_dns_ptr kms_server = (kms_server_dns_ptr)vlmcsd_malloc(sizeof(kms_server_dns_t));
memset(kms_server, 0, sizeof(kms_server_dns_t));
vlmcsd_snprintf(kms_server->serverName, sizeof(kms_server->serverName), "%s:%hu", dns_iterator->Data.SRV.pNameTarget, dns_iterator->Data.SRV.wPort);
kms_server->priority = dns_iterator->Data.SRV.wPriority;
kms_server->weight = dns_iterator->Data.SRV.wWeight;
(*serverlist)[answers++] = kms_server;
}
//sortSrvRecords(*serverlist, answers, NoSrvRecordPriority);
DnsRecordListFree(receive_buffer, DnsFreeRecordList);
return answers;
# undef MAX_DNS_NAME_SIZE
}
#endif // _WIN32
#undef RECEIVE_BUFFER_SIZE
#endif // NO_DNS

103
src/dns_srv.h Normal file
View File

@ -0,0 +1,103 @@
/*
* dns_srv.h
*
*/
#ifndef DNS_SRV_H_
#define DNS_SRV_H_
#ifndef NO_DNS
#include "types.h"
typedef struct
{
uint32_t random_weight;
uint16_t priority;
uint16_t weight;
char serverName[260];
} kms_server_dns_t, *kms_server_dns_ptr;
typedef struct
{
uint16_t priority;
uint16_t weight;
uint16_t port;
unsigned char name[1];
} dns_srv_record_t, *dns_srv_record_ptr;
#if __OpenBSD__
typedef enum __ns_type {
ns_t_invalid = 0, /*%< Cookie. */
ns_t_a = 1, /*%< Host address. */
ns_t_ns = 2, /*%< Authoritative server. */
ns_t_md = 3, /*%< Mail destination. */
ns_t_mf = 4, /*%< Mail forwarder. */
ns_t_cname = 5, /*%< Canonical name. */
ns_t_soa = 6, /*%< Start of authority zone. */
ns_t_mb = 7, /*%< Mailbox domain name. */
ns_t_mg = 8, /*%< Mail group member. */
ns_t_mr = 9, /*%< Mail rename name. */
ns_t_null = 10, /*%< Null resource record. */
ns_t_wks = 11, /*%< Well known service. */
ns_t_ptr = 12, /*%< Domain name pointer. */
ns_t_hinfo = 13, /*%< Host information. */
ns_t_minfo = 14, /*%< Mailbox information. */
ns_t_mx = 15, /*%< Mail routing information. */
ns_t_txt = 16, /*%< Text strings. */
ns_t_rp = 17, /*%< Responsible person. */
ns_t_afsdb = 18, /*%< AFS cell database. */
ns_t_x25 = 19, /*%< X_25 calling address. */
ns_t_isdn = 20, /*%< ISDN calling address. */
ns_t_rt = 21, /*%< Router. */
ns_t_nsap = 22, /*%< NSAP address. */
ns_t_nsap_ptr = 23, /*%< Reverse NSAP lookup (deprecated). */
ns_t_sig = 24, /*%< Security signature. */
ns_t_key = 25, /*%< Security key. */
ns_t_px = 26, /*%< X.400 mail mapping. */
ns_t_gpos = 27, /*%< Geographical position (withdrawn). */
ns_t_aaaa = 28, /*%< Ip6 Address. */
ns_t_loc = 29, /*%< Location Information. */
ns_t_nxt = 30, /*%< Next domain (security). */
ns_t_eid = 31, /*%< Endpoint identifier. */
ns_t_nimloc = 32, /*%< Nimrod Locator. */
ns_t_srv = 33, /*%< Server Selection. */
ns_t_atma = 34, /*%< ATM Address */
ns_t_naptr = 35, /*%< Naming Authority PoinTeR */
ns_t_kx = 36, /*%< Key Exchange */
ns_t_cert = 37, /*%< Certification record */
ns_t_a6 = 38, /*%< IPv6 address (deprecated, use ns_t_aaaa) */
ns_t_dname = 39, /*%< Non-terminal DNAME (for IPv6) */
ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */
ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */
ns_t_apl = 42, /*%< Address prefix list (RFC3123) */
ns_t_tkey = 249, /*%< Transaction key */
ns_t_tsig = 250, /*%< Transaction signature. */
ns_t_ixfr = 251, /*%< Incremental zone transfer. */
ns_t_axfr = 252, /*%< Transfer zone of authority. */
ns_t_mailb = 253, /*%< Transfer mailbox records. */
ns_t_maila = 254, /*%< Transfer mail agent records. */
ns_t_any = 255, /*%< Wildcard match. */
ns_t_zxfr = 256, /*%< BIND-specific, nonstandard. */
ns_t_max = 65536
} ns_type;
typedef enum __ns_class {
ns_c_invalid = 0, /*%< Cookie. */
ns_c_in = 1, /*%< Internet. */
ns_c_2 = 2, /*%< unallocated/unsupported. */
ns_c_chaos = 3, /*%< MIT Chaos-net. */
ns_c_hs = 4, /*%< MIT Hesiod. */
/* Query class values which do not appear in resource records */
ns_c_none = 254, /*%< for prereq. sections in update requests */
ns_c_any = 255, /*%< Wildcard match. */
ns_c_max = 65536
} ns_class;
#endif
int getKmsServerList(kms_server_dns_ptr** serverlist, const char *const restrict query);
void sortSrvRecords(kms_server_dns_ptr* serverlist, const int answers);
#endif // NO_DNS
#endif /* DNS_SRV_H_ */

175
src/endian.c Normal file
View File

@ -0,0 +1,175 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "endian.h"
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \
&& defined(BS16) && defined(BS32) && defined(BS64) && !defined(NO_COMPILER_UAA)
#else // ! defined(__BYTE_ORDER)
void PUT_UAA64BE(void *p, unsigned long long v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
_p[ 0 ] = (unsigned char)(v >> 56);
_p[ 1 ] = (unsigned char)(v >> 48);
_p[ 2 ] = (unsigned char)(v >> 40);
_p[ 3 ] = (unsigned char)(v >> 32);
_p[ 4 ] = (unsigned char)(v >> 24);
_p[ 5 ] = (unsigned char)(v >> 16);
_p[ 6 ] = (unsigned char)(v >> 8);
_p[ 7 ] = (unsigned char)(v);
}
void PUT_UAA32BE(void *p, unsigned int v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
_p[ 0 ] = (unsigned char)(v >> 24);
_p[ 1 ] = (unsigned char)(v >> 16);
_p[ 2 ] = (unsigned char)(v >> 8);
_p[ 3 ] = (unsigned char)(v);
}
void PUT_UAA16BE(void *p, unsigned short v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
_p[ 0 ] = (unsigned char)(v >> 8);
_p[ 1 ] = (unsigned char)(v);
}
void PUT_UAA64LE(void *p, unsigned long long v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
_p[ 0 ] = (unsigned char)(v);
_p[ 1 ] = (unsigned char)(v >> 8);
_p[ 2 ] = (unsigned char)(v >> 16);
_p[ 3 ] = (unsigned char)(v >> 24);
_p[ 4 ] = (unsigned char)(v >> 32);
_p[ 5 ] = (unsigned char)(v >> 40);
_p[ 6 ] = (unsigned char)(v >> 48);
_p[ 7 ] = (unsigned char)(v >> 56);
}
void PUT_UAA32LE(void *p, unsigned int v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
_p[ 0 ] = (unsigned char)(v);
_p[ 1 ] = (unsigned char)(v >> 8);
_p[ 2 ] = (unsigned char)(v >> 16);
_p[ 3 ] = (unsigned char)(v >> 24);
}
void PUT_UAA16LE(void *p, unsigned short v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
_p[ 0 ] = (unsigned char)(v);
_p[ 1 ] = (unsigned char)(v >> 8);
}
unsigned long long GET_UAA64BE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
return
(unsigned long long)_p[ 0 ] << 56 |
(unsigned long long)_p[ 1 ] << 48 |
(unsigned long long)_p[ 2 ] << 40 |
(unsigned long long)_p[ 3 ] << 32 |
(unsigned long long)_p[ 4 ] << 24 |
(unsigned long long)_p[ 5 ] << 16 |
(unsigned long long)_p[ 6 ] << 8 |
(unsigned long long)_p[ 7 ];
}
unsigned int GET_UAA32BE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
return
(unsigned int)_p[ 0 ] << 24 |
(unsigned int)_p[ 1 ] << 16 |
(unsigned int)_p[ 2 ] << 8 |
(unsigned int)_p[ 3 ];
}
unsigned short GET_UAA16BE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
return
(unsigned short)_p[ 0 ] << 8 |
(unsigned short)_p[ 1 ];
}
unsigned long long GET_UAA64LE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
return
(unsigned long long)_p[ 0 ] |
(unsigned long long)_p[ 1 ] << 8 |
(unsigned long long)_p[ 2 ] << 16 |
(unsigned long long)_p[ 3 ] << 24 |
(unsigned long long)_p[ 4 ] << 32 |
(unsigned long long)_p[ 5 ] << 40 |
(unsigned long long)_p[ 6 ] << 48 |
(unsigned long long)_p[ 7 ] << 56;
}
unsigned int GET_UAA32LE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
return
(unsigned int)_p[ 0 ] |
(unsigned int)_p[ 1 ] << 8 |
(unsigned int)_p[ 2 ] << 16 |
(unsigned int)_p[ 3 ] << 24;
}
unsigned short GET_UAA16LE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
return
(unsigned short)_p[ 0 ] |
(unsigned short)_p[ 1 ] << 8;
}
#endif
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \
&& defined(BS16) && defined(BS32) && defined(BS64)
#else
unsigned short BE16(unsigned short x)
{
return GET_UAA16BE(&x, 0);
}
unsigned short LE16(unsigned short x)
{
return GET_UAA16LE(&x, 0);
}
unsigned int BE32(unsigned int x)
{
return GET_UAA32BE(&x, 0);
}
unsigned int LE32(unsigned int x)
{
return GET_UAA32LE(&x, 0);
}
unsigned long long BE64(unsigned long long x)
{
return GET_UAA64BE(&x, 0);
}
unsigned long long LE64(unsigned long long x)
{
return GET_UAA64LE(&x, 0);
}
#endif // defined(__BYTE_ORDER)

312
src/endian.h Normal file
View File

@ -0,0 +1,312 @@
#ifndef __endian_h
#define __endian_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
//
// Unaligned access
//
#if !defined(NO_COMPILER_UAA)
#define UAA16(p, i) (((PACKED16*)p)->val[i])
#define UAA32(p, i) (((PACKED32*)p)->val[i])
#define UAA64(p, i) (((PACKED64*)p)->val[i])
#endif
//
//Byteswap: Use compiler support if available
//
#ifndef NO_COMPILER_UAA
#ifdef __has_builtin // Clang supports this
#if __has_builtin(__builtin_bswap16)
#define BS16(x) __builtin_bswap16(x)
#endif
#if __has_builtin(__builtin_bswap32)
#define BS32(x) __builtin_bswap32(x)
#endif
#if __has_builtin(__builtin_bswap64)
#define BS64(x) __builtin_bswap64(x)
#endif
#endif // has_builtin
#ifdef __GNUC__ // GNU C >= 4.3 has bswap32 and bswap64. GNU C >= 4.8 also has bswap16
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
#ifndef BS32
#define BS32(x) __builtin_bswap32(x)
#endif
#ifndef BS64
#define BS64(x) __builtin_bswap64(x)
#endif
#if (__GNUC__ > 4) || (__GNUC_MINOR__ > 7)
#ifndef BS16
#define BS16(x) __builtin_bswap16(x)
#endif
#endif // GNU C > 4.7
#endif // __GNUC__ > 4
#endif // __GNUC__
#endif // NO_COMPILER_UAA
//
// Byteorder
//
#if defined(__linux__) || defined(__GLIBC__) || defined(__CYGWIN__)
#include <endian.h>
#include <byteswap.h>
#ifndef BS16
#define BS16(x) bswap_16(x)
#endif
#ifndef BS32
#define BS32(x) bswap_32(x)
#endif
#ifndef BS64
#define BS64(x) bswap_64(x)
#endif
#elif defined(__sun__)
#include <sys/byteorder.h>
#ifndef BS16
#define BS16(x) BSWAP_16(x)
#endif
#ifndef BS32
#define BS32(x) BSWAP_32(x)
#endif
#ifndef BS64
#define BS64(x) BSWAP_64(x)
#endif
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#ifdef _LITTLE_ENDIAN
#define __BYTE_ORDER __LITTLE_ENDIAN
#else
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#elif __minix__ || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
#include <sys/types.h>
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#ifdef __OpenBSD__
#ifndef BS16
#define BS16 swap16
#endif
#ifndef BS32
#define BS32 swap32
#endif
#ifndef BS64
#define BS64 swap64
#endif
#else // !__OpenBSD__
#ifndef BS16
#define BS16 bswap16
#endif
#ifndef BS32
#define BS32 bswap32
#endif
#ifndef BS64
#define BS64 bswap64
#endif
#endif // !__OpenBSD__
#elif defined(__APPLE__)
#include <sys/types.h>
#include <machine/endian.h>
#include <libkern/OSByteOrder.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#ifndef BS16
#define BS16 OSSwapInt16
#endif
#ifndef BS32
#define BS32 OSSwapInt32
#endif
#ifndef BS64
#define BS64 OSSwapInt64
#endif
#elif defined(_WIN32)
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
#include <stdlib.h>
#ifndef BS16
#define BS16 _byteswap_ushort
#endif
#ifndef BS32
#define BS32 _byteswap_ulong
#endif
#ifndef BS64
#define BS64 _byteswap_uint64
#endif
#endif // Byteorder in different OS
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \
&& defined(BS16) && defined(BS32) && defined(BS64)
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define __BE16(x) BS16(x)
#define __LE16(x) (x)
#define __BE32(x) BS32(x)
#define __LE32(x) (x)
#define __BE64(x) BS64(x)
#define __LE64(x) (x)
#define PUT_UA16(p, v) PUT_UA16LE(p, v)
#define PUT_UA32(p, v) PUT_UA32LE(p, v)
#define PUT_UA64(p, v) PUT_UA64LE(p, v)
#else // __BYTE_ORDER == __BIG_ENDIAN
#define __BE16(x) (x)
#define __LE16(x) BS16(x)
#define __BE32(x) (x)
#define __LE32(x) BS32(x)
#define __BE64(x) (x)
#define __LE64(x) BS64(x)
#define PUT_UA16(p, v) PUT_UA16BE(p, v)
#define PUT_UA32(p, v) PUT_UA32BE(p, v)
#define PUT_UA64(p, v) PUT_UA64BE(p, v)
#endif // __BYTE_ORDER
#define BE16(x) __BE16(x)
#define LE16(x) __LE16(x)
#define BE32(x) __BE32(x)
#define LE32(x) __LE32(x)
#define BE64(x) __BE64(x)
#define LE64(x) __LE64(x)
#else
extern unsigned short BE16(unsigned short x);
extern unsigned short LE16(unsigned short x);
extern unsigned int BE32(unsigned int x);
extern unsigned int LE32(unsigned int x);
extern unsigned long long BE64(unsigned long long x);
extern unsigned long long LE64(unsigned long long x);
#endif // defined(__BYTE_ORDER)
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \
&& defined(BS16) && defined(BS32) && defined(BS64) &&!defined(NO_COMPILER_UAA)
#define PUT_UAA64BE(p, v, i) ( UAA64(p, i) = __BE64(v) )
#define PUT_UAA32BE(p, v, i) ( UAA32(p, i) = __BE32(v) )
#define PUT_UAA16BE(p, v, i) ( UAA16(p, i) = __BE16(v) )
#define PUT_UAA64LE(p, v, i) ( UAA64(p, i) = __LE64(v) )
#define PUT_UAA32LE(p, v, i) ( UAA32(p, i) = __LE32(v) )
#define PUT_UAA16LE(p, v, i) ( UAA16(p, i) = __LE16(v) )
#define GET_UAA64BE(p, i) __BE64(UAA64(p, i))
#define GET_UAA32BE(p, i) __BE32(UAA32(p, i))
#define GET_UAA16BE(p, i) __BE16(UAA16(p, i))
#define GET_UAA64LE(p, i) __LE64(UAA64(p, i))
#define GET_UAA32LE(p, i) __LE32(UAA32(p, i))
#define GET_UAA16LE(p, i) __LE16(UAA16(p, i))
#else // ! defined(__BYTE_ORDER)
extern void PUT_UAA64BE(void* p, unsigned long long v, unsigned int i);
extern void PUT_UAA32BE(void* p, unsigned int v, unsigned int i);
extern void PUT_UAA16BE(void* p, unsigned short v, unsigned int i);
extern void PUT_UAA64LE(void* p, unsigned long long v, unsigned int i);
extern void PUT_UAA32LE(void* p, unsigned int v, unsigned int i);
extern void PUT_UAA16LE(void* p, unsigned short v, unsigned int i);
extern unsigned long long GET_UAA64BE(void* p, unsigned int i);
extern unsigned int GET_UAA32BE(void* p, unsigned int i);
extern unsigned short GET_UAA16BE(void* p, unsigned int i);
extern unsigned long long GET_UAA64LE(void* p, unsigned int i);
extern unsigned int GET_UAA32LE(void* p, unsigned int i);
extern unsigned short GET_UAA16LE(void* p, unsigned int i);
#endif
#define PUT_UA64BE(p, v) PUT_UAA64BE(p, v, 0)
#define PUT_UA32BE(p, v) PUT_UAA32BE(p, v, 0)
#define PUT_UA16BE(p, v) PUT_UAA16BE(p, v, 0)
#define PUT_UA64LE(p, v) PUT_UAA64LE(p, v, 0)
#define PUT_UA32LE(p, v) PUT_UAA32LE(p, v, 0)
#define PUT_UA16LE(p, v) PUT_UAA16LE(p, v, 0)
#define GET_UA64BE(p) GET_UAA64BE(p, 0)
#define GET_UA32BE(p) GET_UAA32BE(p, 0)
#define GET_UA16BE(p) GET_UAA16BE(p, 0)
#define GET_UA64LE(p) GET_UAA64LE(p, 0)
#define GET_UA32LE(p) GET_UAA32LE(p, 0)
#define GET_UA16LE(p) GET_UAA16LE(p, 0)
#endif // __endian_h

263
src/getifaddrs-musl.c Normal file
View File

@ -0,0 +1,263 @@
#define _GNU_SOURCE
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "ifaddrs-musl.h"
//#include <syscall.h>
#include <net/if.h>
#include <netinet/in.h>
#include "netlink-musl.h"
#define IFADDRS_HASH_SIZE 64
/* getifaddrs() reports hardware addresses with PF_PACKET that implies
* struct sockaddr_ll. But e.g. Infiniband socket address length is
* longer than sockaddr_ll.ssl_addr[8] can hold. Use this hack struct
* to extend ssl_addr - callers should be able to still use it. */
struct sockaddr_ll_hack {
unsigned short sll_family, sll_protocol;
int sll_ifindex;
unsigned short sll_hatype;
unsigned char sll_pkttype, sll_halen;
unsigned char sll_addr[24];
};
union sockany {
struct sockaddr sa;
struct sockaddr_ll_hack ll;
struct sockaddr_in v4;
struct sockaddr_in6 v6;
};
struct ifaddrs_storage {
struct ifaddrs ifa;
struct ifaddrs_storage *hash_next;
union sockany addr, netmask, ifu;
unsigned int index;
char name[IFNAMSIZ+1];
};
struct ifaddrs_ctx {
struct ifaddrs_storage *first;
struct ifaddrs_storage *last;
struct ifaddrs_storage *hash[IFADDRS_HASH_SIZE];
};
void freeifaddrs(struct ifaddrs *ifp)
{
struct ifaddrs *n;
while (ifp) {
n = ifp->ifa_next;
free(ifp);
ifp = n;
}
}
static int __netlink_enumerate(int fd, unsigned int seq, int type, int af,
int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
{
struct nlmsghdr *h;
union {
uint8_t buf[8192];
struct {
struct nlmsghdr nlh;
struct rtgenmsg g;
} req;
struct nlmsghdr reply;
} u;
int r, ret;
memset(&u.req, 0, sizeof(u.req));
u.req.nlh.nlmsg_len = sizeof(u.req);
u.req.nlh.nlmsg_type = type;
u.req.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
u.req.nlh.nlmsg_seq = seq;
u.req.g.rtgen_family = af;
r = send(fd, &u.req, sizeof(u.req), 0);
if (r < 0) return r;
while (1) {
r = recv(fd, u.buf, sizeof(u.buf), MSG_DONTWAIT);
if (r <= 0) return -1;
for (h = &u.reply; NLMSG_OK(h, (void*)&u.buf[r]); h = NLMSG_NEXT(h)) {
if (h->nlmsg_type == NLMSG_DONE) return 0;
if (h->nlmsg_type == NLMSG_ERROR) return -1;
ret = cb(ctx, h);
if (ret) return ret;
}
}
}
int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
{
int fd, r;
fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (fd < 0) return -1;
r = __netlink_enumerate(fd, 1, RTM_GETLINK, link_af, cb, ctx);
if (!r) r = __netlink_enumerate(fd, 2, RTM_GETADDR, addr_af, cb, ctx);
close(fd);
return r;
}
static void copy_addr(struct sockaddr **r, int af, union sockany *sa, void *addr, size_t addrlen, int ifindex)
{
uint8_t *dst;
int len;
switch (af) {
case AF_INET:
dst = (uint8_t*) &sa->v4.sin_addr;
len = 4;
break;
case AF_INET6:
dst = (uint8_t*) &sa->v6.sin6_addr;
len = 16;
if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MC_LINKLOCAL(addr))
sa->v6.sin6_scope_id = ifindex;
break;
default:
return;
}
if (addrlen < len) return;
sa->sa.sa_family = af;
memcpy(dst, addr, len);
*r = &sa->sa;
}
static void gen_netmask(struct sockaddr **r, int af, union sockany *sa, int prefixlen)
{
uint8_t addr[16] = {0};
int i;
if (prefixlen > 8*sizeof(addr)) prefixlen = 8*sizeof(addr);
i = prefixlen / 8;
memset(addr, 0xff, i);
if (i < sizeof(addr)) addr[i++] = 0xff << (8 - (prefixlen % 8));
copy_addr(r, af, sa, addr, sizeof(addr), 0);
}
static void copy_lladdr(struct sockaddr **r, union sockany *sa, void *addr, size_t addrlen, int ifindex, unsigned short hatype)
{
if (addrlen > sizeof(sa->ll.sll_addr)) return;
sa->ll.sll_family = AF_PACKET;
sa->ll.sll_ifindex = ifindex;
sa->ll.sll_hatype = hatype;
sa->ll.sll_halen = addrlen;
memcpy(sa->ll.sll_addr, addr, addrlen);
*r = &sa->sa;
}
static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h)
{
struct ifaddrs_ctx *ctx = pctx;
struct ifaddrs_storage *ifs, *ifs0 = NULL;
struct ifinfomsg *ifi = NLMSG_DATA(h);
struct ifaddrmsg *ifa = NLMSG_DATA(h);
struct rtattr *rta;
int stats_len = 0;
if (h->nlmsg_type == RTM_NEWLINK) {
for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
if (rta->rta_type != IFLA_STATS) continue;
stats_len = RTA_DATALEN(rta);
break;
}
} else {
for (ifs0 = ctx->hash[ifa->ifa_index % IFADDRS_HASH_SIZE]; ifs0; ifs0 = ifs0->hash_next)
if (ifs0->index == ifa->ifa_index)
break;
if (!ifs0) return 0;
}
ifs = calloc(1, sizeof(struct ifaddrs_storage) + stats_len);
if (ifs == 0) return -1;
if (h->nlmsg_type == RTM_NEWLINK) {
ifs->index = ifi->ifi_index;
ifs->ifa.ifa_flags = ifi->ifi_flags;
for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
switch (rta->rta_type) {
case IFLA_IFNAME:
if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
ifs->ifa.ifa_name = ifs->name;
}
break;
case IFLA_ADDRESS:
copy_lladdr(&ifs->ifa.ifa_addr, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
break;
case IFLA_BROADCAST:
copy_lladdr(&ifs->ifa.ifa_broadaddr, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
break;
case IFLA_STATS:
ifs->ifa.ifa_data = (void*)(ifs+1);
memcpy(ifs->ifa.ifa_data, RTA_DATA(rta), RTA_DATALEN(rta));
break;
}
}
if (ifs->ifa.ifa_name) {
unsigned int bucket = ifs->index % IFADDRS_HASH_SIZE;
ifs->hash_next = ctx->hash[bucket];
ctx->hash[bucket] = ifs;
}
} else {
ifs->ifa.ifa_name = ifs0->ifa.ifa_name;
ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags;
for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
switch (rta->rta_type) {
case IFA_ADDRESS:
/* If ifa_addr is already set we, received an IFA_LOCAL before
* so treat this as destination address */
if (ifs->ifa.ifa_addr)
copy_addr(&ifs->ifa.ifa_dstaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
else
copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
break;
case IFA_BROADCAST:
copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
break;
case IFA_LOCAL:
/* If ifa_addr is set and we get IFA_LOCAL, assume we have
* a point-to-point network. Move address to correct field. */
if (ifs->ifa.ifa_addr) {
ifs->ifu = ifs->addr;
ifs->ifa.ifa_dstaddr = &ifs->ifu.sa;
memset(&ifs->addr, 0, sizeof(ifs->addr));
}
copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
break;
case IFA_LABEL:
if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
ifs->ifa.ifa_name = ifs->name;
}
break;
}
}
if (ifs->ifa.ifa_addr)
gen_netmask(&ifs->ifa.ifa_netmask, ifa->ifa_family, &ifs->netmask, ifa->ifa_prefixlen);
}
if (ifs->ifa.ifa_name) {
if (!ctx->first) ctx->first = ifs;
if (ctx->last) ctx->last->ifa.ifa_next = &ifs->ifa;
ctx->last = ifs;
} else {
free(ifs);
}
return 0;
}
int getifaddrs(struct ifaddrs **ifap)
{
struct ifaddrs_ctx _ctx, *ctx = &_ctx;
int r;
memset(ctx, 0, sizeof *ctx);
r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, ctx);
if (r == 0) *ifap = &ctx->first->ifa;
else freeifaddrs(&ctx->first->ifa);
return r;
}

734
src/helpers.c Normal file
View File

@ -0,0 +1,734 @@
/*
* Helper functions used by other modules
*/
//#ifndef _GNU_SOURCE
//#define _GNU_SOURCE
//#endif
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifndef _WIN32
#include <errno.h>
#include <libgen.h>
#endif // _WIN32
#ifndef _MSC_VER
#include <getopt.h>
#else
#include "wingetopt.h"
#endif
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "helpers.h"
#include "output.h"
#include "endian.h"
#include "shared_globals.h"
#ifndef NO_INTERNAL_DATA
#include "kmsdata.h"
#endif // NO_INTERNAL_DATA
#ifdef _WIN32
#include <shlwapi.h>
#endif // _WIN32
#if __APPLE__
#include <mach-o/dyld.h>
#endif // __APPLE__
#if (__GLIBC__ || __linux__) && defined(USE_AUXV)
#include <sys/auxv.h>
#endif
#if __FreeBSD__ || __FreeBSD_kernel__
#include <sys/sysctl.h>
#endif
/*
* UCS2 <-> UTF-8 functions
* All functions use little endian UCS2 since we only need it to communicate with Windows via RPC
*/
// Convert one character from UTF-8 to UCS2
// Returns 0xffff, if utf-8 evaluates to > 0xfffe (outside basic multilingual pane)
WCHAR utf8_to_ucs2_char(const unsigned char *input, const unsigned char **end_ptr)
{
*end_ptr = input;
if (input[0] == 0)
return (WCHAR)~0;
if (input[0] < 0x80) {
*end_ptr = input + 1;
return LE16(input[0]);
}
if ((input[0] & 0xE0) == 0xE0) {
if (input[1] == 0 || input[2] == 0)
return (WCHAR)~0;
*end_ptr = input + 3;
return
LE16((input[0] & 0x0F) << 12 |
(input[1] & 0x3F) << 6 |
(input[2] & 0x3F));
}
if ((input[0] & 0xC0) == 0xC0) {
if (input[1] == 0)
return (WCHAR)~0;
*end_ptr = input + 2;
return
LE16((input[0] & 0x1F) << 6 |
(input[1] & 0x3F));
}
return (WCHAR)~0;
}
// Convert one character from UCS2 to UTF-8
// Returns length of UTF-8 char (1, 2 or 3) or -1 on error (UTF-16 outside UCS2)
// char *utf8 must be large enough to hold 3 bytes
int ucs2_to_utf8_char(const WCHAR ucs2_le, char *utf8)
{
const WCHAR ucs2 = LE16(ucs2_le);
if (ucs2 < 0x80) {
utf8[0] = (char)ucs2;
utf8[1] = '\0';
return 1;
}
if (ucs2 >= 0x80 && ucs2 < 0x800) {
utf8[0] = (char)((ucs2 >> 6) | 0xC0);
utf8[1] = (char)((ucs2 & 0x3F) | 0x80);
utf8[2] = '\0';
return 2;
}
if (ucs2 >= 0x800 && ucs2 < 0xFFFF) {
if (ucs2 >= 0xD800 && ucs2 <= 0xDFFF) {
/* Ill-formed (UTF-16 ouside of BMP) */
return -1;
}
utf8[0] = ((ucs2 >> 12)) | 0xE0;
utf8[1] = ((ucs2 >> 6) & 0x3F) | 0x80;
utf8[2] = ((ucs2) & 0x3F) | 0x80;
utf8[3] = '\0';
return 3;
}
return -1;
}
// Converts UTF8 to UCS2. Returns size in bytes of the converted string or -1 on error
size_t utf8_to_ucs2(WCHAR* const ucs2_le, const char* const utf8, const size_t maxucs2, const size_t maxutf8)
{
const unsigned char* current_utf8 = (unsigned char*)utf8;
WCHAR* current_ucs2_le = ucs2_le;
for (; *current_utf8; current_ucs2_le++)
{
size_t size = (char*)current_utf8 - utf8;
if (size >= maxutf8) return (size_t)-1;
if (((*current_utf8 & 0xc0) == 0xc0) && (size >= maxutf8 - 1)) return (size_t)-1;
if (((*current_utf8 & 0xe0) == 0xe0) && (size >= maxutf8 - 2)) return (size_t)-1;
if (current_ucs2_le - ucs2_le >= (intptr_t)maxucs2 - 1) return (size_t)-1;
*current_ucs2_le = utf8_to_ucs2_char(current_utf8, &current_utf8);
current_ucs2_le[1] = 0;
if (*current_ucs2_le == (WCHAR)-1) return (size_t)-1;
}
return current_ucs2_le - ucs2_le;
}
// Converts UCS2 to UTF-8. Returns TRUE or FALSE
BOOL ucs2_to_utf8(const WCHAR* const ucs2_le, char* utf8, size_t maxucs2, size_t maxutf8)
{
char utf8_char[4];
const WCHAR* current_ucs2 = ucs2_le;
unsigned int index_utf8 = 0;
for (*utf8 = 0; *current_ucs2; current_ucs2++)
{
if (current_ucs2 - ucs2_le > (intptr_t)maxucs2) return FALSE;
int len = ucs2_to_utf8_char(*current_ucs2, utf8_char);
if (index_utf8 + len > maxutf8) return FALSE;
strncat(utf8, utf8_char, len);
index_utf8 += len;
}
return TRUE;
}
/* End of UTF-8 <-> UCS2 conversion */
// Checks, whether a string is a valid integer number between min and max. Returns TRUE or FALSE. Puts int value in *value
BOOL stringToInt(const char *const szValue, const unsigned int min, const unsigned int max, unsigned int *const value)
{
char *nextchar;
errno = 0;
long long result = vlmcsd_strtoll(szValue, &nextchar, 10);
if (errno || result < (long long)min || result >(long long)max || *nextchar)
{
return FALSE;
}
*value = (unsigned int)result;
return TRUE;
}
//Converts a String Guid to a host binary guid in host endianess
int_fast8_t string2UuidLE(const char *const restrict input, GUID *const restrict guid)
{
int i;
if (strlen(input) < GUID_STRING_LENGTH) return FALSE;
if (input[8] != '-' || input[13] != '-' || input[18] != '-' || input[23] != '-') return FALSE;
for (i = 0; i < GUID_STRING_LENGTH; i++)
{
if (i == 8 || i == 13 || i == 18 || i == 23) continue;
const char c = (char)toupper((int)input[i]);
if (c < '0' || c > 'F' || (c > '9' && c < 'A')) return FALSE;
}
char inputCopy[GUID_STRING_LENGTH + 1];
strncpy(inputCopy, input, GUID_STRING_LENGTH + 1);
inputCopy[8] = inputCopy[13] = inputCopy[18] = 0;
hex2bin((BYTE*)&guid->Data1, inputCopy, 8);
hex2bin((BYTE*)&guid->Data2, inputCopy + 9, 4);
hex2bin((BYTE*)&guid->Data3, inputCopy + 14, 4);
hex2bin(guid->Data4, input + 19, 16);
guid->Data1 = BS32(guid->Data1);
guid->Data2 = BS16(guid->Data2);
guid->Data3 = BS16(guid->Data3);
return TRUE;
}
__pure DWORD timeSpanString2Seconds(const char *const restrict argument)
{
char *unitId;
long long val = vlmcsd_strtoll(argument, &unitId, 10);
switch (toupper((int)*unitId))
{
case 'W':
val *= 7;
case 'D':
val *= 24;
case 'H':
val *= 60;
case 0:
case 'M':
val *= 60;
case 'S':
break;
default:
return 0;
}
if (*unitId && unitId[1]) return 0;
if (val < 1) val = 1;
return (DWORD)(val & UINT_MAX);
}
#if !IS_LIBRARY
//Checks a command line argument if it is numeric and between min and max. Returns the numeric value or exits on error
__pure unsigned int getOptionArgumentInt(const char o, const unsigned int min, const unsigned int max)
{
unsigned int result;
if (!stringToInt(optarg, min, max, &result))
{
printerrorf("Fatal: Option \"-%c\" must be numeric between %u and %u.\n", o, min, max);
exit(VLMCSD_EINVAL);
}
return result;
}
// Resets getopt() to start parsing from the beginning
void optReset(void)
{
#if __minix__ || defined(__BSD__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
optind = 1;
optreset = 1; // Makes newer BSD getopt happy
#elif defined(__UCLIBC__) // uClibc headers also define __GLIBC__ so be careful here
optind = 0; // uClibc seeks compatibility with GLIBC
#elif defined(__GLIBC__)
optind = 0; // Makes GLIBC getopt happy
#else // Standard for most systems
optind = 1;
#endif
}
#endif // !IS_LIBRARY
#if _WIN32 || __CYGWIN__
// Returns a static message buffer containing text for a given Win32 error. Not thread safe (same as strerror)
char* win_strerror(const int message)
{
#define STRERROR_BUFFER_SIZE 256
static char buffer[STRERROR_BUFFER_SIZE];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, message, 0, buffer, STRERROR_BUFFER_SIZE, NULL);
return buffer;
}
#endif // _WIN32 || __CYGWIN__
/*
* parses an address in the form host:[port] in addr
* returns host and port in seperate strings
*/
void parseAddress(char *const addr, char** szHost, char** szPort)
{
*szHost = addr;
# ifndef NO_SOCKETS
*szPort = (char*)defaultport;
# else // NO_SOCKETS
*szPort = "1688";
# endif // NO_SOCKETS
char *lastcolon = strrchr(addr, ':');
char *firstcolon = strchr(addr, ':');
char *closingbracket = strrchr(addr, ']');
if (*addr == '[' && closingbracket) //Address in brackets
{
*closingbracket = 0;
(*szHost)++;
if (closingbracket[1] == ':')
*szPort = closingbracket + 2;
}
else if (firstcolon && firstcolon == lastcolon) //IPv4 address or hostname with port
{
*firstcolon = 0;
*szPort = firstcolon + 1;
}
}
// Initialize random generator (needs to be done in each thread)
void randomNumberInit()
{
# if _MSC_VER
srand(GetTickCount());
# else
struct timeval tv;
gettimeofday(&tv, NULL);
srand((unsigned int)(tv.tv_sec ^ tv.tv_usec));
# endif
}
// We always exit immediately if any OOM condition occurs
__noreturn void OutOfMemory(void)
{
errorout("Fatal: Out of memory");
exit(VLMCSD_ENOMEM);
}
void* vlmcsd_malloc(size_t len)
{
void* buf = malloc(len);
if (!buf) OutOfMemory();
return buf;
}
char* vlmcsd_strdup(const char* src)
{
# if _MSC_VER
char* dst = _strdup(src);
# else // !_MSC_VER
char* dst = strdup(src);
# endif
if (!dst) OutOfMemory();
return dst;
}
/*
* Converts hex digits to bytes in big-endian order.
* Ignores any non-hex characters
*/
void hex2bin(BYTE *const bin, const char *hex, const size_t maxbin)
{
static const char *const hexdigits = "0123456789ABCDEF";
char* nextchar;
size_t i;
for (i = 0; (i < 16) && utf8_to_ucs2_char((const unsigned char*)hex, (const unsigned char**)&nextchar) != (WCHAR)-1; hex = nextchar)
{
const char* pos = strchr(hexdigits, toupper((int)*hex));
if (!pos) continue;
if (!(i & 1)) bin[i >> 1] = 0;
bin[i >> 1] |= (char)(pos - hexdigits);
if (!(i & 1)) bin[i >> 1] <<= 4;
i++;
if (i >> 1 > maxbin) break;
}
}
__pure BOOL getArgumentBool(int_fast8_t *result, const char *const argument)
{
if (
!strncasecmp(argument, "true", 4) ||
!strncasecmp(argument, "on", 2) ||
!strncasecmp(argument, "yes", 3) ||
!strncasecmp(argument, "1", 1)
)
{
*result = TRUE;
return TRUE;
}
else if (
!strncasecmp(argument, "false", 5) ||
!strncasecmp(argument, "off", 3) ||
!strncasecmp(argument, "no", 2) ||
!strncasecmp(argument, "0", 1)
)
{
*result = FALSE;
return TRUE;
}
return FALSE;
}
#ifndef IS_LIBRARY
#ifndef NO_EXTERNAL_DATA
__noreturn static void dataFileReadError()
{
const int error = errno;
errorout("Fatal: Could not read %s: %s\n", fn_data, strerror(error));
exit(error);
}
__noreturn static void dataFileFormatError()
{
errorout("Fatal: %s is not a KMS data file version 2.x\n", fn_data);
exit(VLMCSD_EINVAL);
}
#endif // NO_EXTERNAL_DATA
#if !defined(DATA_FILE) || !defined(NO_SIGHUP)
void getExeName()
{
if (fn_exe != NULL) return;
# if (__GLIBC__ || __linux__) && defined(USE_AUXV)
fn_exe = (char*)getauxval(AT_EXECFN);
# elif (__ANDROID__ && __ANDROID_API__ < 16) || (__UCLIBC__ && __UCLIBC_MAJOR__ < 1 && !defined(NO_PROCFS)) // Workaround for older uclibc
char temp[PATH_MAX + 1];
if (realpath("/proc/self/exe", temp) == temp)
{
fn_exe = vlmcsd_strdup(temp);
}
# elif (__linux__ || __CYGWIN__) && !defined(NO_PROCFS)
fn_exe = realpath("/proc/self/exe", NULL);
# elif (__FreeBSD__ || __FreeBSD_kernel__)
int mib[4];
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
char path[PATH_MAX + 1];
size_t cb = sizeof(path);
if (!sysctl(mib, 4, path, &cb, NULL, 0))
{
fn_exe = vlmcsd_strdup(path);
}
# elif (__DragonFly__) && !defined(NO_PROCFS)
fn_exe = realpath("/proc/curproc/file", NULL);
# elif __NetBSD__ && !defined(NO_PROCFS)
fn_exe = realpath("/proc/curproc/exe", NULL);
# elif __sun__
fn_exe = getexecname();
# elif __APPLE__
char path[PATH_MAX + 1];
uint32_t size = sizeof(path);
if (_NSGetExecutablePath(path, &size) == 0)
{
fn_exe = vlmcsd_strdup(path);
}
# elif _WIN32
char path[512];
GetModuleFileName(GetModuleHandle(NULL), path, 512);
path[511] = 0;
fn_exe = vlmcsd_strdup(path);
# else
// Sorry no exe detection
# endif
}
#endif // defined(DATA_FILE) && defined(NO_SIGHUP)
#if !defined(DATA_FILE) && !defined(NO_EXTERNAL_DATA)
#ifdef _WIN32
static void getDefaultDataFile()
{
char fileName[MAX_PATH];
getExeName();
strncpy(fileName, fn_exe, MAX_PATH);
PathRemoveFileSpec(fileName);
strncat(fileName, "\\vlmcsd.kmd", MAX_PATH - 11);
fn_data = vlmcsd_strdup(fileName);
}
#else // !_WIN32
static void getDefaultDataFile()
{
char fileName[512];
getExeName();
if (!fn_exe)
{
fn_data = (char*)"/etc/vlmcsd.kmd";
return;
}
char* fn_exe_copy = vlmcsd_strdup(fn_exe);
strncpy(fileName, dirname(fn_exe_copy), 512);
free(fn_exe_copy);
strncat(fileName, "/vlmcsd.kmd", 500);
fn_data = vlmcsd_strdup(fileName);
}
#endif // !_WIN32
#endif // !defined(DATA_FILE) && !defined(NO_EXTERNAL_DATA)
void loadKmsData()
{
# ifndef NO_INTERNAL_DATA
KmsData = (PVlmcsdHeader_t)DefaultKmsData;
# endif // NO_INTERNAL_DATA
# ifndef NO_EXTERNAL_DATA
long size;
# ifndef NO_INTERNAL_DATA
size = (long)getDefaultKmsDataSize();
# endif // NO_INTERNAL_DATA
# ifndef DATA_FILE
if (!fn_data) getDefaultDataFile();
# endif // DATA_FILE
if (strcmp(fn_data, "-"))
{
FILE *file = fopen(fn_data, "rb");
if (!file)
{
# ifndef NO_INTERNAL_DATA
if (ExplicitDataLoad)
# endif // NO_INTERNAL_DATA
{
dataFileReadError();
}
}
else
{
if (fseek(file, 0, SEEK_END)) dataFileReadError();
size = ftell(file);
if (size == -1L) dataFileReadError();
KmsData = (PVlmcsdHeader_t)vlmcsd_malloc(size);
if (fseek(file, 0, SEEK_SET)) dataFileReadError();
const size_t bytesRead = fread(KmsData, 1, size, file);
if ((long)bytesRead != size) dataFileReadError();
fclose(file);
# if !defined(NO_LOG) && !defined(NO_SOCKETS)
if (!InetdMode) logger("Read KMS data file version %u.%u %s\n", (unsigned int)LE16(KmsData->MajorVer), (unsigned int)LE16(KmsData->MinorVer), fn_data);
# endif // NO_LOG
}
}
# endif // NO_EXTERNAL_DATA
# ifndef UNSAFE_DATA_LOAD
if (((BYTE*)KmsData)[size - 1] != 0) dataFileFormatError();
# endif // UNSAFE_DATA_LOAD
KmsData->MajorVer = LE16(KmsData->MajorVer);
KmsData->MinorVer = LE16(KmsData->MinorVer);
KmsData->AppItemCount = LE32(KmsData->AppItemCount);
KmsData->KmsItemCount = LE32(KmsData->KmsItemCount);
KmsData->SkuItemCount = LE32(KmsData->SkuItemCount);
KmsData->HostBuildCount = LE32(KmsData->HostBuildCount);
uint32_t i;
for (i = 0; i < vlmcsd_countof(KmsData->Datapointers); i++)
{
KmsData->Datapointers[i].Pointer = (BYTE*)KmsData + LE64(KmsData->Datapointers[i].Offset);
# ifndef UNSAFE_DATA_LOAD
if ((BYTE*)KmsData->Datapointers[i].Pointer > (BYTE*)KmsData + size) dataFileFormatError();
# endif // UNSAFE_DATA_LOAD
}
for (i = 0; i < KmsData->CsvlkCount; i++)
{
PCsvlkData_t csvlkData = &KmsData->CsvlkData[i];
csvlkData->EPid = (char*)KmsData + LE64(csvlkData->EPidOffset);
csvlkData->ReleaseDate = LE64(csvlkData->ReleaseDate);
# ifndef UNSAFE_DATA_LOAD
if (csvlkData->EPid > (char*)KmsData + size) dataFileFormatError();
# endif // UNSAFE_DATA_LOAD
# ifndef NO_RANDOM_EPID
csvlkData->GroupId = LE32(csvlkData->GroupId);
csvlkData->MinKeyId = LE32(csvlkData->MinKeyId);
csvlkData->MaxKeyId = LE32(csvlkData->MaxKeyId);
# endif // NO_RANDOM_EPID
}
for (i = 0; i < (uint32_t)KmsData->HostBuildCount; i++)
{
PHostBuild_t hostBuild = &KmsData->HostBuildList[i];
hostBuild->BuildNumber = LE32(hostBuild->BuildNumber);
hostBuild->Flags = LE32(hostBuild->Flags);
hostBuild->PlatformId = LE32(hostBuild->PlatformId);
hostBuild->ReleaseDate = LE64(hostBuild->ReleaseDate);
hostBuild->DisplayName = (char*)KmsData + LE64(hostBuild->DisplayNameOffset);
# ifndef UNSAFE_DATA_LOAD
if (hostBuild->DisplayName > (char*)KmsData + size) dataFileFormatError();
# endif // UNSAFE_DATA_LOAD
}
const uint32_t totalItemCount = KmsData->AppItemCount + KmsData->KmsItemCount + KmsData->SkuItemCount;
# ifndef NO_EXTERNAL_DATA
if (
memcmp(KmsData->Magic, "KMD", sizeof(KmsData->Magic)) ||
KmsData->MajorVer != 2
# ifndef UNSAFE_DATA_LOAD
||
sizeof(VlmcsdHeader_t) + totalItemCount * sizeof(VlmcsdData_t) >= ((uint64_t)size)
# endif //UNSAFE_DATA_LOAD
)
{
dataFileFormatError();
}
# endif // NO_EXTERNAL_DATA
for (i = 0; i < totalItemCount; i++)
{
PVlmcsdData_t item = &KmsData->AppItemList[i];
item->Name = (char*)KmsData + LE64(item->NameOffset);
# ifndef UNSAFE_DATA_LOAD
if (
item->Name >= (char*)KmsData + (uint64_t)size ||
(KmsData->AppItemCount && item->AppIndex >= KmsData->AppItemCount) ||
item->KmsIndex >= KmsData->KmsItemCount
)
{
dataFileFormatError();
}
# endif // UNSAFE_DATA_LOAD
}
}
#ifndef NO_SOCKETS
void exitOnWarningLevel(const int_fast8_t level)
{
if (ExitLevel >= level)
{
printerrorf("Fatal: Exiting on warning level %i or greater\n", (int)ExitLevel);
exit(-1);
}
}
#endif // !NO_SOCKETS
#endif // IS_LIBRARY
#if __ANDROID__ && !defined(USE_THREADS) // Bionic does not wrap these syscalls (intentionally because Google fears, developers don't know how to use it)
#ifdef __NR_shmget
int shmget(key_t key, size_t size, int shmflg)
{
return syscall(__NR_shmget, key, size, shmflg);
}
#endif // __NR_shmget
#ifdef __NR_shmat
void *shmat(int shmid, const void *shmaddr, int shmflg)
{
return (void *)syscall(__NR_shmat, shmid, shmaddr, shmflg);
}
#endif // __NR_shmat
#ifdef __NR_shmdt
int shmdt(const void *shmaddr)
{
return syscall(__NR_shmdt, shmaddr);
}
#endif // __NR_shmdt
#ifdef __NR_shmctl
int shmctl(int shmid, int cmd, /*struct shmid_ds*/void *buf)
{
return syscall(__NR_shmctl, shmid, cmd, buf);
}
#endif // __NR_shmctl
#endif // __ANDROID__ && !defined(USE_THREADS)

57
src/helpers.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef HELPERS_H
#define HELPERS_H
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include <stdint.h>
#include "types.h"
#if __ANDROID__
#include <sys/syscall.h>
#endif // __ANDROID__
#define GUID_LE 0
#define GUID_BE 1
#define GUID_SWAP 2
BOOL stringToInt(const char *const szValue, const unsigned int min, const unsigned int max, unsigned int *const value);
unsigned int getOptionArgumentInt(const char o, const unsigned int min, const unsigned int max);
void optReset(void);
__pure DWORD timeSpanString2Seconds(const char *const restrict argument);
#define timeSpanString2Minutes(x) (timeSpanString2Seconds(x) / 60)
char* win_strerror(const int message);
int ucs2_to_utf8_char (const WCHAR ucs2_le, char *utf8);
size_t utf8_to_ucs2(WCHAR* const ucs2_le, const char* const utf8, const size_t maxucs2, const size_t maxutf8);
WCHAR utf8_to_ucs2_char (const unsigned char * input, const unsigned char ** end_ptr);
BOOL ucs2_to_utf8(const WCHAR* const ucs2_le, char* utf8, size_t maxucs2, size_t maxutf8);
int_fast8_t string2UuidLE(const char *const restrict input, GUID *const restrict guid);
void randomNumberInit();
void parseAddress(char *const addr, char** szHost, char** szPort);
__noreturn void OutOfMemory(void);
void* vlmcsd_malloc(size_t len);
void hex2bin(BYTE *const bin, const char *hex, const size_t maxbin);
void loadKmsData();
#if !defined(DATA_FILE) || !defined(NO_SIGHUP)
void getExeName();
#endif // !defined(DATA_FILE) || !defined(NO_SIGHUP)
__pure BOOL getArgumentBool(int_fast8_t *result, const char *const argument);
char* vlmcsd_strdup(const char* src);
#if defined(NO_SOCKETS) || IS_LIBRARY
#define exitOnWarningLevel(x)
#else // !NO_SOCKETS
void exitOnWarningLevel(const int_fast8_t level);
#endif // !NO_SOCKETS
#if __ANDROID__ && !defined(USE_THREADS) // Bionic does not wrap these syscalls (intentionally because Google fears, developers don't know how to use it)
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, /*struct shmid_ds*/void *buf);
#endif // __ANDROID__ && !defined(USE_THREADS)
#endif // HELPERS_H

600
src/ifaddrs-android.c Normal file
View File

@ -0,0 +1,600 @@
/*
Copyright (c) 2013, Kenneth MacKay
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* 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.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ifaddrs-android.h"
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
typedef struct NetlinkList
{
struct NetlinkList *m_next;
struct nlmsghdr *m_data;
unsigned int m_size;
} NetlinkList;
static int netlink_socket(void)
{
int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if(l_socket < 0)
{
return -1;
}
struct sockaddr_nl l_addr;
memset(&l_addr, 0, sizeof(l_addr));
l_addr.nl_family = AF_NETLINK;
if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0)
{
close(l_socket);
return -1;
}
return l_socket;
}
static int netlink_send(int p_socket, int p_request)
{
char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))];
memset(l_buffer, 0, sizeof(l_buffer));
struct nlmsghdr *l_hdr = (struct nlmsghdr *)l_buffer;
struct rtgenmsg *l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
l_hdr->nlmsg_type = p_request;
l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
l_hdr->nlmsg_pid = 0;
l_hdr->nlmsg_seq = p_socket;
l_msg->rtgen_family = AF_UNSPEC;
struct sockaddr_nl l_addr;
memset(&l_addr, 0, sizeof(l_addr));
l_addr.nl_family = AF_NETLINK;
return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr)));
}
static int netlink_recv(int p_socket, void *p_buffer, size_t p_len)
{
struct msghdr l_msg;
struct iovec l_iov = { p_buffer, p_len };
struct sockaddr_nl l_addr;
//int l_result;
for(;;)
{
l_msg.msg_name = (void *)&l_addr;
l_msg.msg_namelen = sizeof(l_addr);
l_msg.msg_iov = &l_iov;
l_msg.msg_iovlen = 1;
l_msg.msg_control = NULL;
l_msg.msg_controllen = 0;
l_msg.msg_flags = 0;
int l_result = recvmsg(p_socket, &l_msg, 0);
if(l_result < 0)
{
if(errno == EINTR)
{
continue;
}
return -2;
}
if(l_msg.msg_flags & MSG_TRUNC)
{ // buffer was too small
return -1;
}
return l_result;
}
}
static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done)
{
size_t l_size = 4096;
void *l_buffer = NULL;
for(;;)
{
free(l_buffer);
l_buffer = malloc(l_size);
int l_read = netlink_recv(p_socket, l_buffer, l_size);
*p_size = l_read;
if(l_read == -2)
{
free(l_buffer);
return NULL;
}
if(l_read >= 0)
{
pid_t l_pid = getpid();
struct nlmsghdr *l_hdr;
for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read))
{
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
{
continue;
}
if(l_hdr->nlmsg_type == NLMSG_DONE)
{
*p_done = 1;
break;
}
if(l_hdr->nlmsg_type == NLMSG_ERROR)
{
free(l_buffer);
return NULL;
}
}
return l_buffer;
}
l_size *= 2;
}
}
static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size)
{
NetlinkList *l_item = malloc(sizeof(NetlinkList));
l_item->m_next = NULL;
l_item->m_data = p_data;
l_item->m_size = p_size;
return l_item;
}
static void freeResultList(NetlinkList *p_list)
{
NetlinkList *l_cur;
while(p_list)
{
l_cur = p_list;
p_list = p_list->m_next;
free(l_cur->m_data);
free(l_cur);
}
}
static NetlinkList *getResultList(int p_socket, int p_request)
{
if(netlink_send(p_socket, p_request) < 0)
{
return NULL;
}
NetlinkList *l_list = NULL;
NetlinkList *l_end = NULL;
int l_size;
int l_done = 0;
while(!l_done)
{
struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done);
if(!l_hdr)
{ // error
freeResultList(l_list);
return NULL;
}
NetlinkList *l_item = newListItem(l_hdr, l_size);
if(!l_list)
{
l_list = l_item;
}
else
{
l_end->m_next = l_item;
}
l_end = l_item;
}
return l_list;
}
static size_t maxSize(size_t a, size_t b)
{
return (a > b ? a : b);
}
static size_t calcAddrLen(sa_family_t p_family, int p_dataSize)
{
switch(p_family)
{
case AF_INET:
return sizeof(struct sockaddr_in);
case AF_INET6:
return sizeof(struct sockaddr_in6);
case AF_PACKET:
return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize);
default:
return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize);
}
}
static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size)
{
switch(p_family)
{
case AF_INET:
memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size);
break;
case AF_INET6:
memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size);
break;
case AF_PACKET:
memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size);
((struct sockaddr_ll*)p_dest)->sll_halen = p_size;
break;
default:
memcpy(p_dest->sa_data, p_data, p_size);
break;
}
p_dest->sa_family = p_family;
}
static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry)
{
if(!*p_resultList)
{
*p_resultList = p_entry;
}
else
{
struct ifaddrs *l_cur = *p_resultList;
while(l_cur->ifa_next)
{
l_cur = l_cur->ifa_next;
}
l_cur->ifa_next = p_entry;
}
}
static void interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
{
struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr);
size_t l_nameSize = 0;
size_t l_addrSize = 0;
size_t l_dataSize = 0;
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
struct rtattr *l_rta;
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
{
//void *l_rtaData = RTA_DATA(l_rta);
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
switch(l_rta->rta_type)
{
case IFLA_ADDRESS:
case IFLA_BROADCAST:
l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize));
break;
case IFLA_IFNAME:
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
break;
case IFLA_STATS:
l_dataSize += NLMSG_ALIGN(l_rtaSize);
break;
default:
break;
}
}
struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize + l_dataSize);
memset(l_entry, 0, sizeof(struct ifaddrs));
l_entry->ifa_name = "";
char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
char *l_addr = l_name + l_nameSize;
char *l_data = l_addr + l_addrSize;
l_entry->ifa_flags = l_info->ifi_flags;
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
{
void *l_rtaData = RTA_DATA(l_rta);
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
switch(l_rta->rta_type)
{
case IFLA_ADDRESS:
case IFLA_BROADCAST:
{
size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index;
((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type;
if(l_rta->rta_type == IFLA_ADDRESS)
{
l_entry->ifa_addr = (struct sockaddr *)l_addr;
}
else
{
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
}
l_addr += NLMSG_ALIGN(l_addrLen);
break;
}
case IFLA_IFNAME:
strncpy(l_name, l_rtaData, l_rtaDataSize);
l_name[l_rtaDataSize] = '\0';
l_entry->ifa_name = l_name;
break;
case IFLA_STATS:
memcpy(l_data, l_rtaData, l_rtaDataSize);
l_entry->ifa_data = l_data;
break;
default:
break;
}
}
addToEnd(p_resultList, l_entry);
p_links[l_info->ifi_index - 1] = l_entry;
}
static void interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
{
struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr);
size_t l_nameSize = 0;
size_t l_addrSize = 0;
int l_addedNetmask = 0;
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
struct rtattr *l_rta;
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
{
//void *l_rtaData = RTA_DATA(l_rta);
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
if(l_info->ifa_family == AF_PACKET)
{
continue;
}
switch(l_rta->rta_type)
{
case IFA_ADDRESS:
case IFA_LOCAL:
if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
{ // make room for netmask
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
l_addedNetmask = 1;
}
case IFA_BROADCAST:
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
break;
case IFA_LABEL:
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
break;
default:
break;
}
}
struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
memset(l_entry, 0, sizeof(struct ifaddrs));
l_entry->ifa_name = p_links[l_info->ifa_index - 1]->ifa_name;
char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
char *l_addr = l_name + l_nameSize;
l_entry->ifa_flags = l_info->ifa_flags | p_links[l_info->ifa_index - 1]->ifa_flags;
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
{
void *l_rtaData = RTA_DATA(l_rta);
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
switch(l_rta->rta_type)
{
case IFA_ADDRESS:
case IFA_BROADCAST:
case IFA_LOCAL:
{
size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize);
makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
if(l_info->ifa_family == AF_INET6)
{
if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData))
{
((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index;
}
}
if(l_rta->rta_type == IFA_ADDRESS)
{ // apparently in a point-to-point network IFA_ADDRESS contains the dest address and IFA_LOCAL contains the local address
if(l_entry->ifa_addr)
{
l_entry->ifa_dstaddr = (struct sockaddr *)l_addr;
}
else
{
l_entry->ifa_addr = (struct sockaddr *)l_addr;
}
}
else if(l_rta->rta_type == IFA_LOCAL)
{
if(l_entry->ifa_addr)
{
l_entry->ifa_dstaddr = l_entry->ifa_addr;
}
l_entry->ifa_addr = (struct sockaddr *)l_addr;
}
else
{
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
}
l_addr += NLMSG_ALIGN(l_addrLen);
break;
}
case IFA_LABEL:
strncpy(l_name, l_rtaData, l_rtaDataSize);
l_name[l_rtaDataSize] = '\0';
l_entry->ifa_name = l_name;
break;
default:
break;
}
}
if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6))
{
unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128);
unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen);
char l_mask[16] = {0};
unsigned i;
for(i=0; i<(l_prefix/8); ++i)
{
l_mask[i] = 0xff;
}
l_mask[i] = 0xff << (8 - (l_prefix % 8));
makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8);
l_entry->ifa_netmask = (struct sockaddr *)l_addr;
}
addToEnd(p_resultList, l_entry);
}
static void interpret(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
{
pid_t l_pid = getpid();
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
{
unsigned int l_nlsize = p_netlinkList->m_size;
struct nlmsghdr *l_hdr;
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
{
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
{
continue;
}
if(l_hdr->nlmsg_type == NLMSG_DONE)
{
break;
}
if(l_hdr->nlmsg_type == RTM_NEWLINK)
{
interpretLink(l_hdr, p_links, p_resultList);
}
else if(l_hdr->nlmsg_type == RTM_NEWADDR)
{
interpretAddr(l_hdr, p_links, p_resultList);
}
}
}
}
static unsigned countLinks(int p_socket, NetlinkList *p_netlinkList)
{
unsigned l_links = 0;
pid_t l_pid = getpid();
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
{
unsigned int l_nlsize = p_netlinkList->m_size;
struct nlmsghdr *l_hdr;
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
{
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
{
continue;
}
if(l_hdr->nlmsg_type == NLMSG_DONE)
{
break;
}
if(l_hdr->nlmsg_type == RTM_NEWLINK)
{
++l_links;
}
}
}
return l_links;
}
int getifaddrs(struct ifaddrs **ifap)
{
if(!ifap)
{
return -1;
}
*ifap = NULL;
int l_socket = netlink_socket();
if(l_socket < 0)
{
return -1;
}
NetlinkList *l_linkResults = getResultList(l_socket, RTM_GETLINK);
if(!l_linkResults)
{
close(l_socket);
return -1;
}
NetlinkList *l_addrResults = getResultList(l_socket, RTM_GETADDR);
if(!l_addrResults)
{
close(l_socket);
freeResultList(l_linkResults);
return -1;
}
unsigned l_numLinks = countLinks(l_socket, l_linkResults) + countLinks(l_socket, l_addrResults);
struct ifaddrs *l_links[l_numLinks];
memset(l_links, 0, l_numLinks * sizeof(struct ifaddrs *));
interpret(l_socket, l_linkResults, l_links, ifap);
interpret(l_socket, l_addrResults, l_links, ifap);
freeResultList(l_linkResults);
freeResultList(l_addrResults);
close(l_socket);
return 0;
}
void freeifaddrs(struct ifaddrs *ifa)
{
struct ifaddrs *l_cur;
while(ifa)
{
l_cur = ifa;
ifa = ifa->ifa_next;
free(l_cur);
}
}

58
src/ifaddrs-android.h Normal file
View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 1995, 1999
* Berkeley Software Design, Inc. 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.
*
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. 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.
*
* BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
*/
#if !__ANDROID__
#error ifaddrs-android only works with Android
#endif
#ifndef _IFADDRS_H_
#define _IFADDRS_H_
struct ifaddrs {
struct ifaddrs *ifa_next;
char *ifa_name;
unsigned int ifa_flags;
struct sockaddr *ifa_addr;
struct sockaddr *ifa_netmask;
struct sockaddr *ifa_dstaddr;
void *ifa_data;
};
/*
* This may have been defined in <net/if.h>. Note that if <net/if.h> is
* to be included it must be included before this header file.
*/
#ifndef ifa_broadaddr
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
#endif
#include <sys/cdefs.h>
__BEGIN_DECLS
extern int getifaddrs(struct ifaddrs **ifap);
extern void freeifaddrs(struct ifaddrs *ifa);
__END_DECLS
#endif

43
src/ifaddrs-musl.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef _IFADDRS_H
#define _IFADDRS_H
#ifdef __cplusplus
extern "C" {
#endif
#if !__linux__
#error ifaddrs-musl.h only works with a Linux kernel
#endif
#if __ANDROID__
#error ifaddrs-musl.h does not work with Android
#endif
#include <features.h>
#include <netinet/in.h>
#include <sys/socket.h>
struct ifaddrs {
struct ifaddrs *ifa_next;
char *ifa_name;
unsigned ifa_flags;
struct sockaddr *ifa_addr;
struct sockaddr *ifa_netmask;
union {
struct sockaddr *ifu_broadaddr;
struct sockaddr *ifu_dstaddr;
} ifa_ifu;
void *ifa_data;
};
#define ifa_broadaddr ifa_ifu.ifu_broadaddr
#define ifa_dstaddr ifa_ifu.ifu_dstaddr
void freeifaddrs(struct ifaddrs *ifp);
int getifaddrs(struct ifaddrs **ifap);
#ifdef __cplusplus
}
#endif
#endif

1202
src/kms.c Normal file

File diff suppressed because it is too large Load Diff

410
src/kms.h Normal file
View File

@ -0,0 +1,410 @@
#ifndef __kms_h
#define __kms_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#if _MSC_VER
//#include <time.h>
#else
#include <sys/time.h>
#endif // _MSC_VER
//#include <stdlib.h>
#include "types.h"
//
// REQUEST... types are actually fixed size
// RESPONSE... size may vary, defined here is max possible size
//
#define MAX_RESPONSE_SIZE 384
#define PID_BUFFER_SIZE 64
#define MAX_REQUEST_SIZE sizeof(REQUEST_V6)
#define WORKSTATION_NAME_BUFFER 64
// Constants for V6 time stamp interval
#define TIME_C1 0x00000022816889BDULL
#define TIME_C2 0x000000208CBAB5EDULL
#define TIME_C3 0x3156CD5AC628477AULL
#define VERSION_INFO union \
{ \
DWORD Version;\
struct { \
WORD MinorVer; \
WORD MajorVer; \
} /*__packed*/; \
} /*__packed*/
// Aliases for various KMS struct members
#define IsClientVM VMInfo
#define GraceTime BindingExpiration
#define MinutesRemaingInCurrentStatus BindingExpiration
#define ID ActID
#define ApplicationID AppID
#define SkuId ActID
#define KmsId KMSID
#define ClientMachineId CMID
#define MinimumClients N_Policy
#define TimeStamp ClientTime
#define PreviousCLientMachineId CMID_prev
#define Salt IV
#define XorSalt XoredIVs
#define ActivationInterval VLActivationInterval
#define RenewalInterval VLRenewalInterval
#define MAX_CLIENTS 671
typedef struct
{
GUID Guid[MAX_CLIENTS];
int_fast16_t CurrentCount;
int_fast16_t MaxCount;
int_fast16_t CurrentPosition;
} ClientList_t, *PClientList_t;
typedef struct {
VERSION_INFO;
DWORD VMInfo; // 0 = client is bare metal / 1 = client is VM
DWORD LicenseStatus; // 0 = Unlicensed, 1 = Licensed (Activated), 2 = OOB grace, 3 = OOT grace, 4 = NonGenuineGrace, 5 = Notification, 6 = extended grace
DWORD BindingExpiration; // Expiration of the current status in minutes (e.g. when KMS activation or OOB grace expires).
GUID AppID; // Can currently be Windows, Office2010 or Office2013 (see kms.c, table AppList).
GUID ActID; // Most detailed product list. One product key per ActID (see kms.c, table ExtendedProductList). Is ignored by KMS server.
GUID KMSID; // This is actually what the KMS server uses to grant or refuse activation (see kms.c, table BasicProductList).
GUID CMID; // Client machine id. Used by the KMS server for counting minimum clients.
DWORD N_Policy; // Minimum clients required for activation.
FILETIME ClientTime; // Current client time.
GUID CMID_prev; // previous client machine id. All zeros, if it never changed.
WCHAR WorkstationName[64]; // Workstation name. FQDN if available, NetBIOS otherwise.
} /*__packed*/ REQUEST;
typedef struct {
VERSION_INFO;
DWORD PIDSize; // Size of PIDData in bytes.
WCHAR KmsPID[PID_BUFFER_SIZE]; // ePID (must include terminating zero)
GUID CMID; // Client machine id. Must be the same as in request.
FILETIME ClientTime; // Current client time. Must be the same as in request.
DWORD Count; // Current activated machines. KMS server counts up to N_Policy << 1 then stops
DWORD VLActivationInterval; // Time in minutes when clients should retry activation if it was unsuccessful (default 2 hours)
DWORD VLRenewalInterval; // Time in minutes when clients should renew KMS activation (default 7 days)
} /*__packed*/ RESPONSE;
#ifdef _DEBUG
typedef struct {
VERSION_INFO;
DWORD PIDSize;
WCHAR KmsPID[49]; // Set this to the ePID length you want to debug
GUID CMID;
FILETIME ClientTime;
DWORD Count;
DWORD VLActivationInterval;
DWORD VLRenewalInterval;
} __packed RESPONSE_DEBUG;
#endif
typedef struct {
REQUEST RequestBase; // Base request
BYTE MAC[16]; // Aes 160 bit CMAC
} /*__packed*/ REQUEST_V4;
typedef struct {
RESPONSE ResponseBase; // Base response
BYTE MAC[16]; // Aes 160 bit CMAC
} /*__packed*/ RESPONSE_V4;
typedef struct {
VERSION_INFO; // unencrypted version info
BYTE IV[16]; // IV
REQUEST RequestBase; // Base Request
BYTE Pad[4]; // since this struct is fixed, we use fixed PKCS pad bytes
} /*__packed*/ REQUEST_V5;
typedef REQUEST_V5 REQUEST_V6; // v5 and v6 requests are identical
typedef struct {
VERSION_INFO;
BYTE IV[16];
RESPONSE ResponseBase;
BYTE RandomXoredIVs[16]; // If RequestIV was used for decryption: Random ^ decrypted Request IV ^ ResponseIV. If NULL IV was used for decryption: Random ^ decrypted Request IV
BYTE Hash[32]; // SHA256 of Random used in RandomXoredIVs
BYTE HwId[8]; // HwId from the KMS server
BYTE XoredIVs[16]; // If RequestIV was used for decryption: decrypted Request IV ^ ResponseIV. If NULL IV was used for decryption: decrypted Request IV.
BYTE HMAC[16]; // V6 Hmac (low 16 bytes only), see kms.c CreateV6Hmac
//BYTE Pad[10]; // Pad is variable sized. So do not include in struct
} /*__packed*/ RESPONSE_V6;
typedef struct { // not used except for sizeof(). Fields are the same as RESPONSE_V6
VERSION_INFO;
BYTE IV[16];
RESPONSE ResponseBase;
BYTE RandomXoredIVs[16];
BYTE Hash[32];
} /*__packed*/ RESPONSE_V5;
#ifdef _DEBUG
typedef struct { // Debug structure for direct casting of RPC data in debugger
VERSION_INFO;
BYTE IV[16];
RESPONSE_DEBUG ResponseBase;
BYTE RandomXoredIVs[16];
BYTE MAC[32];
BYTE Unknown[8];
BYTE XorSalts[16];
BYTE HMAC[16];
BYTE Pad[16];
} __packed RESPONSE_V6_DEBUG;
#endif
#define V4_PRE_EPID_SIZE ( \
sizeof(((RESPONSE*)0)->Version) + \
sizeof(((RESPONSE*)0)->PIDSize) \
)
#define V4_POST_EPID_SIZE ( \
sizeof(((RESPONSE*)0)->CMID) + \
sizeof(((RESPONSE*)0)->ClientTime) + \
sizeof(((RESPONSE*)0)->Count) + \
sizeof(((RESPONSE*)0)->VLActivationInterval) + \
sizeof(((RESPONSE*)0)->VLRenewalInterval) \
)
#define V6_DECRYPT_SIZE ( \
sizeof(((REQUEST_V6*)0)->IV) + \
sizeof(((REQUEST_V6*)0)->RequestBase) + \
sizeof(((REQUEST_V6*)0)->Pad) \
)
#define V6_UNENCRYPTED_SIZE ( \
sizeof(((RESPONSE_V6*)0)->Version) + \
sizeof(((RESPONSE_V6*)0)->IV) \
)
#define V6_PRE_EPID_SIZE ( \
V6_UNENCRYPTED_SIZE + \
sizeof(((RESPONSE*)0)->Version) + \
sizeof(((RESPONSE*)0)->PIDSize) \
)
#define V5_POST_EPID_SIZE ( \
V4_POST_EPID_SIZE + \
sizeof(((RESPONSE_V6*)0)->RandomXoredIVs) + \
sizeof(((RESPONSE_V6*)0)->Hash) \
)
#define V6_POST_EPID_SIZE ( \
V5_POST_EPID_SIZE + \
sizeof(((RESPONSE_V6*)0)->HwId) + \
sizeof(((RESPONSE_V6*)0)->XoredIVs) + \
sizeof(((RESPONSE_V6*)0)->HMAC) \
)
#define RESPONSE_RESULT_OK ((1 << 10) - 1) //(9 bits)
typedef union
{
DWORD mask;
struct
{
BOOL HashOK : 1;
BOOL TimeStampOK : 1;
BOOL ClientMachineIDOK : 1;
BOOL VersionOK : 1;
BOOL IVsOK : 1;
BOOL DecryptSuccess : 1;
BOOL HmacSha256OK : 1;
BOOL PidLengthOK : 1;
BOOL RpcOK : 1;
BOOL IVnotSuspicious : 1;
BOOL reserved3 : 1;
BOOL reserved4 : 1;
BOOL reserved5 : 1;
BOOL reserved6 : 1;
uint32_t effectiveResponseSize : 9;
uint32_t correctResponseSize : 9;
};
} RESPONSE_RESULT;
typedef BYTE hwid_t[8];
typedef enum
{
None = 0,
UseNdr64 = 1 << 0,
UseForEpid = 1 << 1,
MayBeServer = 1 << 2,
} HostBuildFlag;
typedef struct CsvlkData
{
union
{
uint64_t EPidOffset;
char* EPid;
};
int64_t ReleaseDate;
uint32_t GroupId;
uint32_t MinKeyId;
uint32_t MaxKeyId;
uint8_t MinActiveClients;
uint8_t Reserved[3];
} CsvlkData_t, *PCsvlkData_t;
typedef struct VlmcsdData
{
union
{
GUID Guid;
uint8_t GuidBytes[16];
};
union
{
uint64_t NameOffset;
char* Name;
};
uint8_t AppIndex;
uint8_t KmsIndex;
uint8_t ProtocolVersion;
uint8_t NCountPolicy;
uint8_t IsRetail;
uint8_t IsPreview;
uint8_t EPidIndex;
uint8_t reserved;
} VlmcsdData_t, *PVlmcsdData_t;
typedef struct
{
union
{
uint64_t Offset;
void* Pointer;
};
} DataPointer_t;
#define KMS_OPTIONS_USENDR64 1 << 0
typedef struct HostBuild
{
union
{
uint64_t DisplayNameOffset;
char* DisplayName;
};
int64_t ReleaseDate;
int32_t BuildNumber;
int32_t PlatformId;
HostBuildFlag Flags;
uint8_t reserved[4];
} HostBuild_t, *PHostBuild_t;
typedef struct VlmcsdHeader
{
BYTE Magic[4];
VERSION_INFO;
uint8_t CsvlkCount;
uint8_t Flags;
uint8_t Reserved[2];
union
{
int32_t Counts[5];
struct
{
int32_t AppItemCount;
int32_t KmsItemCount;
int32_t SkuItemCount;
int32_t HostBuildCount;
int32_t reserved2Counts;
};
};
union
{
DataPointer_t Datapointers[5];
struct
{
union
{
uint64_t AppItemOffset;
PVlmcsdData_t AppItemList;
};
union
{
uint64_t KmsItemOffset;
PVlmcsdData_t KmsItemList;
};
union
{
uint64_t SkuItemOffset;
PVlmcsdData_t SkuItemList;
};
union
{
uint64_t HostBuildOffset;
PHostBuild_t HostBuildList;
};
union
{
uint64_t Reserved2Offset;
void* Reserved2List;
};
CsvlkData_t CsvlkData[1];
};
};
} VlmcsdHeader_t, *PVlmcsdHeader_t;
//#define EPID_INDEX_WINDOWS 0
//#define EPID_INDEX_OFFICE2010 1
//#define EPID_INDEX_OFFICE2013 2
//#define EPID_INDEX_OFFICE2016 3
//#define EPID_INDEX_WINCHINAGOV 4
typedef HRESULT(__stdcall *RequestCallback_t)(REQUEST* baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr);
size_t CreateResponseV4(REQUEST_V4 *const Request, BYTE *const response_data, const char* const ipstr);
size_t CreateResponseV6(REQUEST_V6 *restrict Request, BYTE *const response_data, const char* const ipstr);
BYTE *CreateRequestV4(size_t *size, const REQUEST* requestBase);
BYTE *CreateRequestV6(size_t *size, const REQUEST* requestBase);
void randomPidInit();
void get16RandomBytes(void* ptr);
RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BYTE* const response, const BYTE* const rawRequest, BYTE* hwid);
RESPONSE_RESULT DecryptResponseV4(RESPONSE_V4* response_v4, const int responseSize, BYTE* const rawResponse, const BYTE* const rawRequest);
void getUnixTimeAsFileTime(FILETIME* ts);
__pure int64_t fileTimeToUnixTime(FILETIME* ts);
#ifndef IS_LIBRARY
int32_t getProductIndex(const GUID* guid, const PVlmcsdData_t list, const int32_t count, char** name, char** ePid);
#if !defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG)
const char* getNextString(const char* s);
#endif // !defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG)
#endif // IS_LIBRARY
#ifndef NO_STRICT_MODES
void InitializeClientLists();
void CleanUpClientLists();
#endif // !NO_STRICT_MODES
extern RequestCallback_t CreateResponseBase;
#ifdef _PEDANTIC
uint16_t IsValidLcid(const uint16_t lcid);
uint32_t IsValidHostBuild(const int32_t hostBuild);
#endif // _PEDANTIC
#endif // __kms_h

963
src/kmsdata-full.c Normal file
View File

@ -0,0 +1,963 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifndef NO_INTERNAL_DATA
#include "kmsdata.h"
uint8_t DefaultKmsData[] =
{
/* 0000 */ 0x4B, 0x4D, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // KMD.............
/* 0010 */ 0x1D, 0x00, 0x00, 0x00, 0xCA, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....Ê...........
/* 0020 */ 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........h.......
/* 0030 */ 0x08, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........H.......
/* 0040 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
/* 0050 */ 0x00, 0xB5, 0xB2, 0x5B, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0xC0, 0x97, 0xD7, 0x20, // .µ²[....Î...À.×
/* 0060 */ 0xBF, 0xC4, 0x08, 0x22, 0x00, 0x00, 0x00, 0x00, 0x56, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¿Ä."....V.......
/* 0070 */ 0x80, 0x4F, 0x3E, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x7F, 0xDC, 0x0B, // .O>L....`...À.Ü.
/* 0080 */ 0x7F, 0x6A, 0xFE, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x9F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .jþ.............
/* 0090 */ 0x00, 0x11, 0x07, 0x51, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0x80, 0x8E, 0xF2, 0x0D, // ...Q....Î.....ò.
/* 00A0 */ 0xFF, 0x3F, 0x42, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ÿ?B.....è.......
/* 00B0 */ 0x00, 0x9A, 0x00, 0x56, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0x40, 0x17, 0x0C, 0x1A, // ...V....Î...@...
/* 00C0 */ 0xBF, 0xC8, 0x5B, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¿È[.....1 ......
/* 00D0 */ 0x80, 0x33, 0xE4, 0x58, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0F, 0x00, 0x00, 0xC0, 0xE1, 0xE4, 0x00, // .3äX........Àáä.
/* 00E0 */ 0xFF, 0xC9, 0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ÿÉ.;..... ......
/* 00F0 */ 0x00, 0x29, 0xA8, 0x5B, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0x80, 0x5A, 0xB2, 0x27, // .)¨[....Î....Z²'
/* 0100 */ 0x7F, 0x87, 0xE3, 0x28, 0x00, 0x00, 0x00, 0x00, 0x34, 0x27, 0xC9, 0x55, 0x82, 0xD6, 0x71, 0x4D, // ..ã(....4'ÉU.ÖqM
/* 0110 */ 0x98, 0x3E, 0xD6, 0xEC, 0x3F, 0x16, 0x05, 0x9F, 0x84, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .>Öì?....!......
/* 0120 */ 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x81, 0x28, 0xA5, 0x59, 0x89, 0xA9, 0x9D, 0x47, // ...2.....(¥Y.©.G
/* 0130 */ 0xAF, 0x46, 0xF2, 0x75, 0xC6, 0x37, 0x06, 0x63, 0x8C, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¯FòuÆ7.c.!......
/* 0140 */ 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x15, 0xCE, 0xF1, 0x0F, 0x89, 0xA9, 0x9D, 0x47, // .........Îñ..©.G
/* 0150 */ 0xAF, 0x46, 0xF2, 0x75, 0xC6, 0x37, 0x06, 0x63, 0x97, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¯FòuÆ7.c.!......
/* 0160 */ 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x05, 0x00, 0xFB, 0xB1, 0x49, 0x84, 0xEA, 0xF0, 0x7A, 0x49, // ........û±I.êðzI
/* 0170 */ 0x99, 0xAB, 0x66, 0xCA, 0x96, 0xE9, 0xA0, 0xF5, 0xA3, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .«fÊ.é.õ£!......
/* 0180 */ 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x59, 0x56, 0xB1, 0x11, 0x03, 0xE6, 0xF1, 0x4C, // ........YV±..æñL
/* 0190 */ 0x9C, 0x1F, 0xF0, 0xEC, 0x01, 0xB8, 0x18, 0x88, 0xB7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..ðì.¸..·!......
/* 01A0 */ 0x00, 0x00, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x36, 0xD6, 0x7C, 0xD2, 0x62, 0x19, 0xE9, 0x44, // ........6Ö|Òb.éD
/* 01B0 */ 0x8B, 0x4F, 0x27, 0xB6, 0xC2, 0x3E, 0xFB, 0x85, 0xD0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .O'¶Â>û.Ð!......
/* 01C0 */ 0x00, 0x00, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x23, 0xBF, 0xA0, 0x7B, 0xF5, 0xD0, 0x72, 0x40, // ........#¿.{õÐr@
/* 01D0 */ 0x91, 0xD9, 0xD5, 0x5A, 0xF5, 0xA4, 0x81, 0xB6, 0xEC, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ÙÕZõ¤.¶ì!......
/* 01E0 */ 0x00, 0x00, 0x06, 0x19, 0x00, 0x00, 0x04, 0x00, 0xC0, 0xE3, 0x9F, 0x96, 0xEC, 0xA3, 0x1A, 0x49, // ........Àã..ì£.I
/* 01F0 */ 0x9F, 0x25, 0x42, 0x36, 0x05, 0xDE, 0xB3, 0x65, 0x08, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .%B6.Þ³e."......
/* 0200 */ 0x00, 0x00, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x58, 0x13, 0xC5, 0xE1, 0x3E, 0xFE, 0x03, 0x42, // ........X.Åá>þ.B
/* 0210 */ 0xA4, 0xA2, 0x3B, 0x6B, 0x20, 0xC9, 0x73, 0x4E, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¤¢;k ÉsN!"......
/* 0220 */ 0x00, 0x00, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x4F, 0x13, 0xE2, 0x58, 0x11, 0x8E, 0x17, 0x4D, // ........O.âX...M
/* 0230 */ 0x9C, 0xB2, 0x91, 0x06, 0x9C, 0x15, 0x11, 0x48, 0x35, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .².....H5"......
/* 0240 */ 0x00, 0x00, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x19, 0x52, 0xDE, 0x7F, 0xFA, 0xFB, 0x4A, 0x48, // .........RÞ.úûJH
/* 0250 */ 0x82, 0xC9, 0x34, 0xD1, 0xAD, 0x53, 0xE8, 0x56, 0x4E, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .É4Ñ­SèVN"......
/* 0260 */ 0x00, 0x00, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x3B, 0x7B, 0xB9, 0xBB, 0xA4, 0x8C, 0x28, 0x4A, // ........;{¹»¤.(J
/* 0270 */ 0x97, 0x17, 0x89, 0xFA, 0xBD, 0x42, 0xC4, 0xAC, 0x58, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...ú½BĬX"......
/* 0280 */ 0x00, 0x00, 0x05, 0x19, 0x01, 0x00, 0x00, 0x00, 0x58, 0xB3, 0x40, 0x3C, 0x48, 0x59, 0xAF, 0x45, // ........X³@<HY¯E
/* 0290 */ 0x92, 0x3B, 0x53, 0xD2, 0x1F, 0xCC, 0x7E, 0x79, 0x6B, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .;SÒ.Ì~yk"......
/* 02A0 */ 0x00, 0x00, 0x05, 0x19, 0x00, 0x00, 0x00, 0x00, 0x90, 0x68, 0x64, 0x6D, 0x06, 0x36, 0x1A, 0x46, // .........hdm.6.F
/* 02B0 */ 0x86, 0xAB, 0x59, 0x8B, 0xB8, 0x4A, 0xCE, 0x82, 0x7E, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .«Y.¸JÎ.~"......
/* 02C0 */ 0x00, 0x00, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x80, 0xC7, 0x8F, 0xCB, 0x05, 0x2C, 0x5A, 0x49, // .........Ç.Ë.,ZI
/* 02D0 */ 0x97, 0x10, 0x85, 0xAF, 0xFF, 0xC9, 0x04, 0xD7, 0x93, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...¯ÿÉ.×."......
/* 02E0 */ 0x00, 0x00, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xA0, 0x94, 0x5F, 0xA0, 0xD5, 0x81, 0x40, // ........».._.Õ.@
/* 02F0 */ 0xA6, 0x85, 0x58, 0x19, 0x41, 0x8B, 0x2F, 0xE0, 0xA8, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¦.X.A./à¨"......
/* 0300 */ 0x00, 0x00, 0x05, 0x19, 0x00, 0x01, 0x00, 0x00, 0xE4, 0x56, 0xE1, 0x33, 0x6F, 0xB7, 0x52, 0x4A, // ........äVá3o·RJ
/* 0310 */ 0x9F, 0x91, 0xF6, 0x41, 0xDD, 0x95, 0xAC, 0x48, 0xB8, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..öAÝ.¬H¸"......
/* 0320 */ 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x87, 0x33, 0xE5, 0x8F, 0x87, 0x30, 0x47, 0x44, // .........3å..0GD
/* 0330 */ 0x89, 0x85, 0xF7, 0x51, 0x32, 0x21, 0x5A, 0xC9, 0xDC, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..÷Q2!ZÉÜ"......
/* 0340 */ 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xFD, 0x21, 0x8A, 0xC5, 0xCB, 0xEB, 0x44, // ........óý!.ÅËëD
/* 0350 */ 0x83, 0xF3, 0xFE, 0x28, 0x4E, 0x66, 0x80, 0xA7, 0x0C, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .óþ(Nf.§.#......
/* 0360 */ 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0xAF, 0xCC, 0xC6, 0x0F, 0x0E, 0xFF, 0xAE, 0x4F, // ........¯ÌÆ..ÿ®O
/* 0370 */ 0x9D, 0x08, 0x43, 0x70, 0x78, 0x5B, 0xF7, 0xED, 0x2F, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..Cpx[֒/#......
/* 0380 */ 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0xB6, 0xF5, 0x87, 0xCA, 0x46, 0xCD, 0xC0, 0x40, // ........¶õ.ÊFÍÀ@
/* 0390 */ 0xB0, 0x6D, 0x8E, 0xCD, 0x57, 0xA4, 0x37, 0x3F, 0x56, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // °m.ÍW¤7?V#......
/* 03A0 */ 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x89, 0x26, 0xCA, 0xB2, 0xA8, 0xA9, 0xD7, 0x42, // .........&ʲ¨©×B
/* 03B0 */ 0x93, 0x8D, 0xCF, 0x8E, 0x9F, 0x20, 0x19, 0x58, 0x89, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..Ï.. .X.#......
/* 03C0 */ 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x71, 0xCB, 0x65, 0x86, 0x8C, 0x46, 0xA3, 0x4A, // ........qËe..F£J
/* 03D0 */ 0xA3, 0x37, 0xCB, 0x9B, 0xC9, 0xD5, 0xEA, 0xAC, 0xAF, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // £7Ë.ÉÕ꬯#......
/* 03E0 */ 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0xD3, 0xEF, 0x56, 0x84, 0x04, 0x0C, 0x89, 0x40, // ........ÓïV....@
/* 03F0 */ 0x87, 0x40, 0x5B, 0x72, 0x38, 0x53, 0x5A, 0x65, 0xC3, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .@[r8SZeÃ#......
/* 0400 */ 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x69, 0xC0, 0x9F, 0x6E, 0x7D, 0x25, 0xC4, 0x4B, // ........iÀ.n}%ÄK
/* 0410 */ 0xB4, 0xA7, 0x75, 0x05, 0x14, 0xD3, 0x27, 0x43, 0xDA, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ´§u..Ó'CÚ#......
/* 0420 */ 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x70, 0x52, 0x5F, 0x6D, 0xAC, 0x31, 0x3E, 0x43, // ........pR_m¬1>C
/* 0430 */ 0xB9, 0x0A, 0x39, 0x89, 0x29, 0x23, 0xC6, 0x57, 0xEE, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¹.9.)#ÆWî#......
/* 0440 */ 0x00, 0x00, 0x06, 0x05, 0x00, 0x01, 0x00, 0x00, 0xDC, 0x64, 0x2A, 0x21, 0xB1, 0x43, 0x3D, 0x4D, // ........Üd*!±C=M
/* 0450 */ 0xA3, 0x0C, 0x2F, 0xC6, 0x9D, 0x20, 0x95, 0xC6, 0x05, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // £./Æ. .Æ.$......
/* 0460 */ 0x00, 0x00, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x46, 0xF9, 0x5A, 0xE8, 0x25, 0x2E, 0xB7, 0x47, // ........FùZè%.·G
/* 0470 */ 0x83, 0xE1, 0xBE, 0xBC, 0xEB, 0xEA, 0xC6, 0x11, 0x13, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .á¾¼ëêÆ..$......
/* 0480 */ 0x01, 0x00, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0xBF, 0xF1, 0xA6, 0xE6, 0x40, 0x9D, 0xC3, 0x40, // ........¿ñ¦æ@.Ã@
/* 0490 */ 0xAA, 0x9F, 0xC7, 0x7B, 0xA2, 0x15, 0x78, 0xC0, 0x1F, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ª.Ç{¢.xÀ.$......
/* 04A0 */ 0x02, 0x00, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0x68, 0x79, 0x4C, 0xAA, 0xDA, 0xB9, 0x80, 0x46, // ........hyLªÚ¹.F
/* 04B0 */ 0x92, 0xB6, 0xAC, 0xB2, 0x5E, 0x2F, 0x86, 0x6C, 0x2B, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .¶¬²^/.l+$......
/* 04C0 */ 0x02, 0x00, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x1B, 0xF6, 0xB5, 0x85, 0x0B, 0x32, 0xE3, 0x4B, // .........öµ..2ãK
/* 04D0 */ 0x81, 0x4A, 0xB7, 0x6B, 0x2B, 0xFA, 0xFC, 0x82, 0x45, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .J·k+úü.E$......
/* 04E0 */ 0x02, 0x00, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0xB1, 0x9E, 0x7D, 0x61, 0x36, 0xEF, 0x82, 0x4F, // ........±.}a6ï.O
/* 04F0 */ 0x86, 0xE0, 0xA6, 0x5A, 0xE0, 0x7B, 0x96, 0xC6, 0x51, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .à¦Zà{.ÆQ$......
/* 0500 */ 0x02, 0x00, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0x62, 0xEB, 0xE8, 0x8D, 0xE0, 0xBB, 0xAC, 0x40, // ........bëè.໬@
/* 0510 */ 0xAC, 0x17, 0xF7, 0x55, 0x95, 0x07, 0x1E, 0xA3, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¬.÷U...£]$......
/* 0520 */ 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xC1, 0x9C, 0xA9, 0x19, 0x77, 0x06, 0x43, // ........ðÁ.©.w.C
/* 0530 */ 0x96, 0x45, 0x29, 0x41, 0x02, 0xFB, 0xFF, 0x95, 0x77, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .E)A.ûÿ.w$......
/* 0540 */ 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAE, 0xE1, 0x34, 0xF8, 0x27, 0x50, 0x49, // ........U®á4ø'PI
/* 0550 */ 0x88, 0x77, 0x7A, 0x03, 0xBE, 0x5F, 0xB1, 0x81, 0x96, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .wz.¾_±..$......
/* 0560 */ 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x3C, 0x4D, 0x03, 0x4B, 0x5D, 0x45, 0x42, // ........»<M.K]EB
/* 0570 */ 0xB3, 0xF8, 0xF8, 0x45, 0x71, 0x31, 0x40, 0x78, 0xB5, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ³øøEq1@xµ$......
/* 0580 */ 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xEA, 0x32, 0xDE, 0xEE, 0xAA, 0x62, 0x46, // ........ýê2ÞîªbF
/* 0590 */ 0x94, 0x44, 0xC1, 0xBE, 0xFB, 0x41, 0xBD, 0xE2, 0xD4, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .DÁ¾ûA½âÔ$......
/* 05A0 */ 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0xE5, 0x62, 0xC3, 0x90, 0xA1, 0x0D, 0xFD, 0x4B, // ........åbÃ.¡.ýK
/* 05B0 */ 0xB5, 0x3B, 0xB8, 0x7D, 0x30, 0x9A, 0xDE, 0x43, 0xF1, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // µ;¸}0.ÞCñ$......
/* 05C0 */ 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x95, 0xE3, 0x73, 0x0C, 0xFC, 0x0D, 0x40, // ........|.ãs.ü.@
/* 05D0 */ 0x91, 0x84, 0x5F, 0x7B, 0x6F, 0x2E, 0xB4, 0x09, 0x26, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .._{o.´.&%......
/* 05E0 */ 0x00, 0x00, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0xB3, 0xFA, 0xD2, 0x32, 0xA8, 0xE4, 0xC2, 0x42, // ........³úÒ2¨äÂB
/* 05F0 */ 0x92, 0x3B, 0x4B, 0xF4, 0xFD, 0x13, 0xE6, 0xEE, 0x59, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .;Kôý.æîY%......
/* 0600 */ 0x00, 0x01, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x33, 0xA3, 0x03, 0x71, 0xC8, 0xB8, 0xCC, 0x49, // ........3£.qȸÌI
/* 0610 */ 0x93, 0xCE, 0xD3, 0x7C, 0x09, 0x68, 0x7F, 0x92, 0x79, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ÎÓ|.h..y%......
/* 0620 */ 0x00, 0x01, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x83, 0xD3, 0xB2, 0xE0, 0x12, 0xD1, 0x3F, 0x41, // .........Ó²à.Ñ?A
/* 0630 */ 0x8A, 0x80, 0x97, 0xF3, 0x73, 0xA5, 0x82, 0x0C, 0x9B, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...ós¥...%......
/* 0640 */ 0x00, 0x03, 0x06, 0x19, 0x00, 0x00, 0x04, 0x00, 0xFB, 0x54, 0x84, 0xE3, 0xA4, 0x41, 0x59, 0x4F, // ........ûT.ã¤AYO
/* 0650 */ 0xA5, 0xDC, 0x25, 0x08, 0x0E, 0x35, 0x47, 0x30, 0xB3, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¥Ü%..5G0³%......
/* 0660 */ 0x00, 0x03, 0x06, 0x19, 0x00, 0x00, 0x04, 0x00, 0x60, 0x5A, 0x5A, 0x2D, 0x40, 0x30, 0xBF, 0x48, // ........`ZZ-@0¿H
/* 0670 */ 0xBE, 0xB0, 0xFC, 0xD7, 0x70, 0xC2, 0x0C, 0xE0, 0xCC, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¾°ü×pÂ.àÌ%......
/* 0680 */ 0x00, 0x04, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x83, 0x6D, 0x77, 0x9F, 0x56, 0x71, 0xB2, 0x45, // .........mw.Vq²E
/* 0690 */ 0x8A, 0x5C, 0x35, 0x9B, 0x9C, 0x9F, 0x22, 0xA3, 0xEC, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .\5..."£ì%......
/* 06A0 */ 0x00, 0x04, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x99, 0x7C, 0xE9, 0x58, 0x77, 0xF3, 0xF1, 0x4E, // .........|éXwóñN
/* 06B0 */ 0x81, 0xD5, 0x4A, 0xD5, 0x52, 0x2B, 0x5F, 0xD8, 0x0E, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ÕJÕR+_Ø.&......
/* 06C0 */ 0x00, 0x05, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x44, 0x75, 0x10, 0xA9, 0xA0, 0xF4, 0x53, 0x40, // ........Du.©.ôS@
/* 06D0 */ 0xA9, 0x6A, 0x14, 0x79, 0xAB, 0xDE, 0xF9, 0x12, 0x1E, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ©j.y«Þù..&......
/* 06E0 */ 0x00, 0x05, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x51, 0x17, 0x9E, 0x7B, 0xDA, 0xA8, 0x75, 0x4F, // ........Q..{Ú¨uO
/* 06F0 */ 0x95, 0x60, 0x5F, 0xAD, 0xFE, 0x3D, 0x8E, 0x38, 0x3F, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .`_­þ=.8?&......
/* 0700 */ 0x00, 0x05, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x57, 0x8A, 0x91, 0xCD, 0x1B, 0xA4, 0x82, 0x4C, // ........W..Í.¤.L
/* 0710 */ 0x8D, 0xCE, 0x1A, 0x53, 0x8E, 0x22, 0x1A, 0x83, 0x51, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Î.S."..Q&......
/* 0720 */ 0x00, 0x05, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x88, 0x22, 0xC4, 0xE0, 0x0C, 0x98, 0x88, 0x47, // ........."Äà...G
/* 0730 */ 0xA0, 0x14, 0xC0, 0x80, 0xD2, 0xE1, 0x92, 0x6E, 0x71, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..À.Òá.nq&......
/* 0740 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x55, 0x23, 0x10, 0x3C, 0x27, 0xD0, 0xC6, 0x42, // ........U#.<'ÐÆB
/* 0750 */ 0xAD, 0x23, 0x2E, 0x7E, 0xF8, 0xA0, 0x25, 0x85, 0x86, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ­#.~ø.%..&......
/* 0760 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x21, 0x11, 0x11, 0x73, 0x38, 0x56, 0xF6, 0x40, // ........!..s8Vö@
/* 0770 */ 0xBC, 0x11, 0xF1, 0xD7, 0xB0, 0xD6, 0x43, 0x00, 0x9D, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¼.ñ×°ÖC..&......
/* 0780 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xA4, 0x51, 0x7B, 0x04, 0x0C, 0x8F, 0x4E, // ........l¤Q{...N
/* 0790 */ 0x9A, 0xF4, 0x84, 0x96, 0xCC, 0xA9, 0x0D, 0x5E, 0xB3, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ô..Ì©.^³&......
/* 07A0 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0xB7, 0x38, 0xB8, 0x87, 0xB6, 0x41, 0x90, 0x45, // ........·8¸.¶A.E
/* 07B0 */ 0x83, 0x18, 0x57, 0x97, 0x95, 0x1D, 0x85, 0x29, 0xD3, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..W....)Ó&......
/* 07C0 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xE3, 0x72, 0xE2, 0x2F, 0x73, 0x65, 0x4C, // ........âãrâ/seL
/* 07D0 */ 0xA8, 0xF0, 0x48, 0x47, 0x47, 0xD0, 0xD9, 0x47, 0xF5, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¨ðHGGÐÙGõ&......
/* 07E0 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x92, 0xC0, 0xBB, 0x82, 0x50, 0xBC, 0x16, 0x4E, // .........À».P¼.N
/* 07F0 */ 0x8E, 0x18, 0xB7, 0x4F, 0xC4, 0x86, 0xAE, 0xC3, 0x0D, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..·OÄ.®Ã.'......
/* 0800 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x71, 0x15, 0x4B, 0xFB, 0xBA, 0x40, 0x4B, // ........Óq.Kûº@K
/* 0810 */ 0x80, 0x87, 0xA9, 0x61, 0xBE, 0x2C, 0xAF, 0x65, 0x31, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..©a¾,¯e1'......
/* 0820 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x92, 0x73, 0xE6, 0x2D, 0xA7, 0xB7, 0x2A, 0x46, // .........sæ-§·*F
/* 0830 */ 0xB1, 0xCA, 0x10, 0x8D, 0xD1, 0x89, 0xF5, 0x88, 0x57, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ±Ê..Ñ.õ.W'......
/* 0840 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x82, 0xFC, 0x1A, 0x3F, 0xAC, 0xF8, 0x6C, 0x4F, // .........ü.?¬ølO
/* 0850 */ 0x80, 0x05, 0x1D, 0x23, 0x3E, 0x60, 0x6E, 0xEE, 0x6F, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...#>`nîo'......
/* 0860 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x8C, 0xB1, 0x00, 0x53, 0x33, 0x2E, 0xC2, 0x4D, // .........±.S3.ÂM
/* 0870 */ 0x82, 0x91, 0x47, 0xFF, 0xCE, 0xC7, 0x46, 0xDD, 0x91, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..GÿÎÇFÝ.'......
/* 0880 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x5A, 0x0B, 0xA8, 0xAD, 0x76, 0x8B, 0x42, // ........¿Z.¨­v.B
/* 0890 */ 0xB0, 0x5D, 0xA4, 0x7D, 0x2D, 0xFF, 0xEE, 0xBF, 0xB5, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // °]¤}-ÿ'......
/* 08A0 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x01, 0x82, 0x80, 0xFF, 0xC6, 0xFE, 0xD4, 0x4F, // ...........ÿÆþÔO
/* 08B0 */ 0xAE, 0x16, 0xAB, 0xBD, 0xDA, 0xDE, 0x57, 0x06, 0xCF, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ®.«½ÚÞW.Ï'......
/* 08C0 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x05, 0xAB, 0xF2, 0x43, 0x87, 0x7C, 0x56, 0x4D, // .........«òC.|VM
/* 08D0 */ 0xB2, 0x7C, 0x44, 0xD0, 0xF9, 0xA3, 0xDA, 0xBD, 0xEF, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ²|DÐù£Ú½ï'......
/* 08E0 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x65, 0x8E, 0x86, 0xEC, 0xDF, 0xFA, 0x59, 0x47, // ........e..ìßúYG
/* 08F0 */ 0xB2, 0x3E, 0x93, 0xFE, 0x37, 0xF2, 0xCC, 0x29, 0x0D, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ²>.þ7òÌ).(......
/* 0900 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0xEA, 0x50, 0xDB, 0xE4, 0xA1, 0xBD, 0x66, 0x45, // ........êPÛ䡽fE
/* 0910 */ 0xB0, 0x47, 0x0C, 0xA5, 0x0A, 0xBC, 0x6F, 0x07, 0x38, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // °G.¥.¼o.8(......
/* 0920 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x14, 0xF8, 0xF4, 0x0D, 0x57, 0x3F, 0x8B, 0x4B, // .........øô.W?.K
/* 0930 */ 0x9A, 0x9D, 0xFD, 0xDA, 0xDC, 0xD6, 0x9F, 0xAC, 0x51, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..ýÚÜÖ.¬Q(......
/* 0940 */ 0x00, 0x06, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x09, 0xE5, 0x2E, 0xAE, 0x34, 0x1B, 0xC0, 0x41, // .........å.®4.ÀA
/* 0950 */ 0xAC, 0xB7, 0x6D, 0x46, 0x50, 0x16, 0x89, 0x15, 0x65, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¬·mFP...e(......
/* 0960 */ 0x00, 0x07, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x08, 0xED, 0xBB, 0x46, 0x7B, 0x9C, 0xFC, 0x48, // .........í»F{.üH
/* 0970 */ 0xA6, 0x14, 0x95, 0x25, 0x05, 0x73, 0xF4, 0xEA, 0x7A, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¦..%.sôêz(......
/* 0980 */ 0x00, 0x07, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x05, 0xD6, 0xB6, 0x1C, 0xB3, 0x11, 0x14, 0x4E, // .........Ö¶.³..N
/* 0990 */ 0xBB, 0x30, 0xDA, 0x91, 0xC8, 0xE3, 0x98, 0x3A, 0x91, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // »0Ú.Èã.:.(......
/* 09A0 */ 0x00, 0x07, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x80, 0x99, 0x2E, 0xB9, 0xD5, 0xB9, 0x21, 0x48, // ...........¹Õ¹!H
/* 09B0 */ 0x9C, 0x94, 0x14, 0x0F, 0x63, 0x2F, 0x63, 0x12, 0xA8, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....c/c.¨(......
/* 09C0 */ 0x00, 0x07, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x29, 0x15, 0x04, 0x5A, 0xF8, 0xFE, 0x07, 0x4D, // ........)..Zøþ.M
/* 09D0 */ 0xB0, 0x6F, 0xB5, 0x9B, 0x57, 0x3B, 0x32, 0xD2, 0xBF, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // °oµ.W;2Ò¿(......
/* 09E0 */ 0x00, 0x07, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x9A, 0xA0, 0x54, 0x7B, 0xD5, 0x10, 0x4C, // ...........T{Õ.L
/* 09F0 */ 0x8B, 0x69, 0xA8, 0x42, 0xD6, 0x59, 0x0A, 0xD5, 0xD8, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .i¨BÖY.ÕØ(......
/* 0A00 */ 0x00, 0x07, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x96, 0x78, 0x53, 0xDB, 0x6F, 0x37, 0xAE, 0x48, // .........xSÛo7®H
/* 0A10 */ 0xA4, 0x92, 0x53, 0xD0, 0x54, 0x77, 0x73, 0xD0, 0xF1, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¤.SÐTwsÐñ(......
/* 0A20 */ 0x00, 0x07, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x29, 0xA8, 0xE1, 0x37, 0xDB, 0xD1, 0x44, // ........j)¨á7ÛÑD
/* 0A30 */ 0x8C, 0xCE, 0x7B, 0xC9, 0x61, 0xD5, 0x9C, 0x54, 0x0D, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Î{ÉaÕ.T.)......
/* 0A40 */ 0x00, 0x07, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xD3, 0x6D, 0xAA, 0xB4, 0xC2, 0xE2, 0x40, // ........ªÓmª´Ââ@
/* 0A50 */ 0xA5, 0x44, 0xA6, 0xBB, 0xB3, 0xF5, 0xC3, 0x95, 0x29, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¥D¦»³õÃ.))......
/* 0A60 */ 0x00, 0x07, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xD6, 0x4E, 0xC0, 0xC8, 0x55, 0x47, 0x4B, // ........¿ÖNÀÈUGK
/* 0A70 */ 0x9F, 0x8E, 0x5A, 0x1F, 0x31, 0xCE, 0xEE, 0x60, 0x3A, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..Z.1Îî`:)......
/* 0A80 */ 0x00, 0x08, 0x05, 0x19, 0x01, 0x00, 0x00, 0x00, 0xA2, 0x84, 0x55, 0x9D, 0x85, 0x2D, 0x9A, 0x41, // ........¢.U..-.A
/* 0A90 */ 0x98, 0x2C, 0xA0, 0x08, 0x88, 0xBB, 0x9D, 0xDF, 0x49, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .,...».ßI)......
/* 0AA0 */ 0x00, 0x08, 0x05, 0x19, 0x01, 0x00, 0x00, 0x00, 0xA0, 0x90, 0x73, 0x19, 0xF6, 0x65, 0x95, 0x4A, // ..........s.öe.J
/* 0AB0 */ 0xBD, 0xC4, 0x55, 0xD5, 0x8A, 0x3B, 0x02, 0x53, 0x69, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ½ÄUÕ.;.Si)......
/* 0AC0 */ 0x00, 0x08, 0x05, 0x19, 0x01, 0x00, 0x00, 0x00, 0xD4, 0xFC, 0x60, 0x88, 0x7B, 0xA7, 0x20, 0x4A, // ........Ôü`.{§ J
/* 0AD0 */ 0x90, 0x45, 0xA1, 0x50, 0xFF, 0x11, 0xD6, 0x09, 0x7A, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .E¡Pÿ.Ö.z)......
/* 0AE0 */ 0x00, 0x08, 0x05, 0x19, 0x01, 0x00, 0x00, 0x00, 0xA3, 0x18, 0x00, 0xA0, 0x0F, 0xF2, 0x32, 0x46, // ........£....ò2F
/* 0AF0 */ 0xBF, 0x7C, 0x8D, 0xAA, 0x53, 0x51, 0xC9, 0x14, 0x99, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¿|.ªSQÉ..)......
/* 0B00 */ 0x00, 0x08, 0x05, 0x19, 0x01, 0x00, 0x00, 0x00, 0xAF, 0x8B, 0x01, 0x10, 0x21, 0xCE, 0x60, 0x40, // ........¯...!Î`@
/* 0B10 */ 0x80, 0xBD, 0x47, 0xFE, 0x74, 0xED, 0x4D, 0xAB, 0xB4, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .½GþtíM«´)......
/* 0B20 */ 0x00, 0x09, 0x05, 0x19, 0x00, 0x00, 0x00, 0x00, 0x48, 0x18, 0xDB, 0x18, 0xE0, 0x12, 0x67, 0x41, // ........H.Û.à.gA
/* 0B30 */ 0xB9, 0xD7, 0xDA, 0x7F, 0xCD, 0xA5, 0x07, 0xDB, 0xDD, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¹×Ú.Í¥.ÛÝ)......
/* 0B40 */ 0x00, 0x09, 0x05, 0x19, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x1B, 0x8E, 0x45, 0x7A, 0x83, 0xF6, 0x45, // ........ì..Ez.öE
/* 0B50 */ 0xB9, 0xD5, 0x92, 0x5E, 0xD5, 0xD2, 0x99, 0xDE, 0x04, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¹Õ.^ÕÒ.Þ.*......
/* 0B60 */ 0x00, 0x09, 0x05, 0x19, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x97, 0x49, 0xE1, 0x0A, 0x80, 0xF7, 0x4C, // ........ç.Iá..÷L
/* 0B70 */ 0xAD, 0x10, 0xDE, 0x4B, 0x45, 0xB5, 0x78, 0xDB, 0x19, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ­.ÞKEµxÛ.*......
/* 0B80 */ 0x00, 0x09, 0x05, 0x19, 0x00, 0x00, 0x00, 0x00, 0x6D, 0xCD, 0x8B, 0xA9, 0x43, 0x53, 0x03, 0x46, // ........mÍ.©CS.F
/* 0B90 */ 0x8A, 0xFE, 0x59, 0x08, 0xE4, 0x61, 0x11, 0x12, 0x30, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .þY.äa..0*......
/* 0BA0 */ 0x00, 0x09, 0x05, 0x19, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x45, 0xF2, 0xEB, 0xA8, 0x29, 0xAF, 0x4D, // ........ÁEòë¨)¯M
/* 0BB0 */ 0x9C, 0xB1, 0x38, 0xDF, 0xC6, 0x08, 0xA8, 0xC8, 0x47, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .±8ßÆ.¨ÈG*......
/* 0BC0 */ 0x00, 0x09, 0x05, 0x19, 0x00, 0x00, 0x00, 0x00, 0x38, 0x32, 0x1C, 0xFE, 0x2A, 0x43, 0xA1, 0x43, // ........82.þ*C¡C
/* 0BD0 */ 0x8E, 0x25, 0x97, 0xE7, 0xD1, 0xEF, 0x10, 0xF3, 0x60, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .%.çÑï.ó`*......
/* 0BE0 */ 0x00, 0x0A, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x6A, 0x45, 0xEE, 0xFF, 0x87, 0xCD, 0x90, 0x43, // ........jEîÿ.Í.C
/* 0BF0 */ 0x8E, 0x07, 0x16, 0x14, 0x6C, 0x67, 0x2F, 0xD0, 0x71, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....lg/Ðq*......
/* 0C00 */ 0x00, 0x0A, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x4F, 0xB7, 0x78, 0xDB, 0x1C, 0xEF, 0x92, 0x48, // ........O·xÛ.ï.H
/* 0C10 */ 0xAB, 0xFE, 0x1E, 0x66, 0xB8, 0x23, 0x1D, 0xF6, 0x86, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // «þ.f¸#.ö.*......
/* 0C20 */ 0x00, 0x0A, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x64, 0x8A, 0x55, 0x78, 0x19, 0xDC, 0xFE, 0x43, // ........d.Ux.ÜþC
/* 0C30 */ 0xA0, 0xD0, 0x80, 0x75, 0xB2, 0xA3, 0x70, 0xA3, 0xA8, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Ð.u²£p£¨*......
/* 0C40 */ 0x00, 0x0A, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x1D, 0x6A, 0x2C, 0xC7, 0x52, 0xF2, 0x7E, 0x4E, // .........j,ÇRò~N
/* 0C50 */ 0xBD, 0xD1, 0x3F, 0xCA, 0x34, 0x2A, 0xCB, 0x35, 0xBB, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ½Ñ?Ê4*Ë5»*......
/* 0C60 */ 0x00, 0x0A, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0xB5, 0x87, 0x8D, 0xE5, 0x26, 0x81, 0x80, 0x45, // ........µ..å&..E
/* 0C70 */ 0x80, 0xFB, 0x86, 0x1B, 0x22, 0xF7, 0x92, 0x96, 0xDC, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .û.."÷..Ü*......
/* 0C80 */ 0x00, 0x0A, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0xC7, 0x91, 0xB4, 0xCA, 0x18, 0xA9, 0x60, 0x4F, // ........Ç.´Ê.©`O
/* 0C90 */ 0xB5, 0x02, 0xDA, 0xB7, 0x5E, 0x33, 0x4F, 0x40, 0xFD, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // µ.Ú·^3O@ý*......
/* 0CA0 */ 0x00, 0x0A, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x3D, 0xE6, 0x6C, 0x09, 0xAC, 0x4F, 0xA9, 0x48, // ........=æl.¬O©H
/* 0CB0 */ 0x82, 0xA9, 0x61, 0xAE, 0x9E, 0x80, 0x0E, 0x5F, 0x20, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .©a®..._ +......
/* 0CC0 */ 0x00, 0x0A, 0x06, 0x19, 0x01, 0x00, 0x00, 0x00, 0x32, 0x2B, 0x94, 0xE9, 0x55, 0x2E, 0x97, 0x41, // ........2+.éU..A
/* 0CD0 */ 0xB0, 0xBD, 0x5F, 0xF5, 0x8C, 0xBA, 0x88, 0x60, 0x3D, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // °½_õ.º.`=+......
/* 0CE0 */ 0x00, 0x0B, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x12, 0x82, 0x99, 0xBA, 0x0A, 0x46, 0xDB, 0x44, // ...........º.FÛD
/* 0CF0 */ 0xBF, 0xB5, 0x71, 0xBF, 0x09, 0xD1, 0xC6, 0x8B, 0x58, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¿µq¿.ÑÆ.X+......
/* 0D00 */ 0x00, 0x0B, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xEC, 0xDD, 0xC6, 0x54, 0x23, 0x19, 0x4C, // ........ÖìÝÆT#.L
/* 0D10 */ 0x90, 0x9B, 0x30, 0x6A, 0x30, 0x58, 0x48, 0x4E, 0x84, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..0j0XHN.+......
/* 0D20 */ 0x00, 0x0B, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0xA3, 0xE3, 0xF5, 0xB8, 0x33, 0xED, 0x08, 0x46, // ........£ãõ¸3í.F
/* 0D30 */ 0x81, 0xE1, 0x37, 0xD6, 0xC9, 0xDC, 0xFD, 0x9C, 0xA1, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .á7ÖÉÜý.¡+......
/* 0D40 */ 0x00, 0x0B, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x1A, 0x67, 0x81, 0xD1, 0x79, 0xB1, 0x4E, // ........¯.g.Ñy±N
/* 0D50 */ 0xB0, 0x04, 0x8C, 0xBB, 0xE1, 0x73, 0xAF, 0xEA, 0xCC, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // °..»ás¯êÌ+......
/* 0D60 */ 0x00, 0x0B, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x70, 0x3E, 0x11, 0x49, 0xFA, 0xA4, 0x48, // ........\p>.Iú¤H
/* 0D70 */ 0xBE, 0xEA, 0x7D, 0xD8, 0x79, 0xB4, 0x6B, 0x14, 0xE3, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¾ê}Øy´k.ã+......
/* 0D80 */ 0x00, 0x0B, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x81, 0x69, 0x6B, 0xC0, 0xFD, 0xD7, 0x35, 0x4A, // .........ikÀý×5J
/* 0D90 */ 0xB7, 0xB4, 0x05, 0x47, 0x42, 0xB7, 0xAF, 0x67, 0xFC, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ·´.GB·¯gü+......
/* 0DA0 */ 0x00, 0x0B, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xD7, 0x76, 0x74, 0x48, 0x8E, 0xB4, 0x49, // .........×vtH.´I
/* 0DB0 */ 0xAB, 0x63, 0x4D, 0x0B, 0x81, 0x3A, 0x16, 0xE4, 0x15, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // «cM..:.ä.,......
/* 0DC0 */ 0x00, 0x0B, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x54, 0x2D, 0xB8, 0x0A, 0xF4, 0x47, 0xCB, 0x4A, // ........T-¸.ôGËJ
/* 0DD0 */ 0x81, 0x8C, 0xCC, 0x5B, 0xF0, 0xEC, 0xB6, 0x49, 0x30, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..Ì[ðì¶I0,......
/* 0DE0 */ 0x00, 0x0B, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x90, 0x85, 0xE8, 0xF7, 0xC7, 0xDF, 0x78, 0x4C, // ..........è÷ÇßxL
/* 0DF0 */ 0xBC, 0xCB, 0x6F, 0x38, 0x65, 0xB9, 0x9D, 0x1A, 0x5B, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¼Ëo8e¹..[,......
/* 0E00 */ 0x00, 0x0B, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0x9F, 0x2D, 0x4E, 0xCD, 0x59, 0x50, 0x50, 0x4A, // .........-NÍYPPJ
/* 0E10 */ 0xA9, 0x2D, 0x05, 0xD5, 0xBB, 0x12, 0x67, 0xC7, 0x84, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ©-.Õ».gÇ.,......
/* 0E20 */ 0x00, 0x0B, 0x06, 0x19, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x52, 0xE9, 0xCD, 0x96, 0x2F, 0x9D, 0x4D, // ........ÇRéÍ./.M
/* 0E30 */ 0x8F, 0x2B, 0x2D, 0x34, 0x9F, 0x64, 0xFC, 0x51, 0xAD, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .+-4.düQ­,......
/* 0E40 */ 0x00, 0x0C, 0x05, 0x19, 0x00, 0x01, 0x00, 0x00, 0x6B, 0x3E, 0x38, 0xA4, 0xDA, 0xDA, 0x3D, 0x42, // ........k>8¤ÚÚ=B
/* 0E50 */ 0xA4, 0x3D, 0xF2, 0x56, 0x78, 0x42, 0x96, 0x76, 0xCB, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¤=òVxB.vË,......
/* 0E60 */ 0x00, 0x0C, 0x05, 0x19, 0x00, 0x01, 0x00, 0x00, 0x7B, 0xA0, 0x59, 0xCF, 0x2A, 0x1A, 0xE0, 0x4B, // ........{.YÏ*.àK
/* 0E70 */ 0xBF, 0xE0, 0x42, 0x3B, 0x58, 0x23, 0xE6, 0x63, 0xEB, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¿àB;X#æcë,......
/* 0E80 */ 0x00, 0x0C, 0x05, 0x19, 0x00, 0x01, 0x00, 0x00, 0x7F, 0x33, 0x9C, 0x2B, 0x1D, 0x7A, 0x71, 0x42, // .........3.+.zqB
/* 0E90 */ 0x90, 0xA3, 0xC6, 0x85, 0x5A, 0x2B, 0x8A, 0x1C, 0x0F, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .£Æ.Z+...-......
/* 0EA0 */ 0x00, 0x0C, 0x05, 0x19, 0x00, 0x01, 0x00, 0x00, 0x72, 0xAD, 0x1E, 0x63, 0xAB, 0xA8, 0xF8, 0x4D, // ........r­.c«¨øM
/* 0EB0 */ 0xBB, 0xDF, 0x37, 0x20, 0x29, 0x98, 0x9B, 0xDD, 0x23, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // »ß7 )..Ý#-......
/* 0EC0 */ 0x00, 0x0C, 0x05, 0x19, 0x00, 0x01, 0x00, 0x00, 0x7C, 0x9F, 0xFA, 0xDD, 0x9E, 0xF0, 0xB9, 0x40, // ........|.úÝ.ð¹@
/* 0ED0 */ 0x8C, 0x1A, 0xBE, 0x87, 0x7A, 0x9A, 0x7F, 0x4B, 0x3B, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..¾.z..K;-......
/* 0EE0 */ 0x00, 0x0D, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x56, 0x11, 0xFB, 0x7A, 0x1D, 0x2C, 0xFC, 0x40, // ........V.ûz.,ü@
/* 0EF0 */ 0xB2, 0x60, 0xAA, 0xB7, 0x44, 0x2B, 0x62, 0xFE, 0x53, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ²`ª·D+bþS-......
/* 0F00 */ 0x00, 0x0D, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x42, 0x25, 0xAD, 0x54, 0x91, 0x6D, 0x4C, // ........ÔB%­T.mL
/* 0F10 */ 0x8A, 0x44, 0x30, 0xF1, 0x1E, 0xE9, 0x69, 0x89, 0x77, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .D0ñ.éi.w-......
/* 0F20 */ 0x00, 0x0E, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xE3, 0x01, 0x24, 0x0A, 0xC5, 0x58, 0x4B, // ........Ðã.$.ÅXK
/* 0F30 */ 0x87, 0xB2, 0x7E, 0x79, 0x4B, 0x7D, 0x26, 0x07, 0x94, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .²~yK}&..-......
/* 0F40 */ 0x00, 0x0E, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x90, 0x4D, 0xAF, 0xC1, 0xBC, 0xD1, 0xCA, 0x44, // .........M¯Á¼ÑÊD
/* 0F50 */ 0x85, 0xD4, 0x00, 0x3B, 0xA3, 0x3D, 0xB3, 0xB9, 0xC1, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Ô.;£=³¹Á-......
/* 0F60 */ 0x00, 0x0E, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x49, 0x98, 0x81, 0xD0, 0xAD, 0xB2, 0x47, // .........I..Э²G
/* 0F70 */ 0xB3, 0xBA, 0x31, 0x6B, 0x12, 0xD6, 0x47, 0xB4, 0xE0, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ³º1k.ÖG´à-......
/* 0F80 */ 0x00, 0x0E, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xE2, 0xB6, 0x68, 0x09, 0xCF, 0x6B, 0x46, // ........ â¶h.ÏkF
/* 0F90 */ 0x92, 0xD3, 0x45, 0xCD, 0x96, 0x4B, 0x95, 0x09, 0x0F, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ÓEÍ.K..........
/* 0FA0 */ 0x00, 0x0F, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x77, 0xEF, 0x09, 0xFD, 0x47, 0x56, 0xFF, 0x4E, // ........wï.ýGVÿN
/* 0FB0 */ 0x80, 0x9C, 0xAF, 0x2B, 0x64, 0x65, 0x9A, 0x45, 0x2E, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..¯+de.E........
/* 0FC0 */ 0x00, 0x0F, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x17, 0xEF, 0x01, 0x0D, 0x3E, 0x2A, 0x42, // ........k.ï..>*B
/* 0FD0 */ 0xB4, 0xF8, 0x4E, 0xA8, 0x80, 0x03, 0x5E, 0x8F, 0x5D, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ´øN¨..^.].......
/* 0FE0 */ 0x00, 0x0F, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x51, 0x72, 0xF7, 0x87, 0x0E, 0xD5, 0x48, // ........\Qr÷..ÕH
/* 0FF0 */ 0xA6, 0x76, 0xE6, 0x96, 0x2C, 0x3E, 0x11, 0x95, 0x7D, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¦væ.,>..}.......
/* 1000 */ 0x00, 0x10, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x8B, 0x8B, 0xA7, 0x17, 0x80, 0xF5, 0x4D, // ........Ù..§..õM
/* 1010 */ 0xB8, 0x6A, 0x09, 0xF7, 0x56, 0xAF, 0xFA, 0x7C, 0x9C, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¸j.÷V¯ú|........
/* 1020 */ 0x00, 0x10, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x8C, 0xA1, 0xCD, 0x96, 0xC1, 0xAD, 0x46, // ........ó.¡Í.Á­F
/* 1030 */ 0xB2, 0x89, 0x60, 0xC0, 0x72, 0x86, 0x99, 0x94, 0xB7, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ².`Àr...·.......
/* 1040 */ 0x00, 0x10, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0xB9, 0x1F, 0x53, 0x68, 0x11, 0x55, 0x89, 0x49, // ........¹.Sh.U.I
/* 1050 */ 0x97, 0xBE, 0xD1, 0x1A, 0x0F, 0x55, 0x63, 0x3F, 0xDA, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .¾Ñ..Uc?Ú.......
/* 1060 */ 0x00, 0x11, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x2B, 0x0E, 0x62, 0xE7, 0x09, 0xFD, 0x42, // ........=+.bç.ýB
/* 1070 */ 0x80, 0x2A, 0x17, 0xA1, 0x36, 0x52, 0xFE, 0x7A, 0xFA, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .*.¡6Rþzú.......
/* 1080 */ 0x00, 0x11, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xE6, 0x82, 0x74, 0x89, 0xC5, 0x7F, 0x4B, // .........æ.t.Å.K
/* 1090 */ 0x8E, 0xCC, 0x46, 0xD4, 0x55, 0xAC, 0x3B, 0x87, 0x1C, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ÌFÔU¬;../......
/* 10A0 */ 0x00, 0x12, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x85, 0x26, 0x8A, 0x7E, 0x1C, 0xD3, 0x48, // ..........&.~.ÓH
/* 10B0 */ 0xA6, 0x87, 0xFB, 0xCA, 0x9B, 0x9A, 0xC1, 0x6B, 0x3E, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¦.ûÊ..Ák>/......
/* 10C0 */ 0x00, 0x12, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x60, 0x3D, 0x64, 0xD3, 0x42, 0x0C, 0x2D, 0x41, // ........`=dÓB.-A
/* 10D0 */ 0xA7, 0xD6, 0x52, 0xE6, 0x63, 0x53, 0x27, 0xF6, 0x6C, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // §ÖRæcS'öl/......
/* 10E0 */ 0x00, 0x13, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x83, 0x1C, 0xFD, 0x95, 0xF5, 0x7D, 0x4A, 0x49, // ..........ý.õ}JI
/* 10F0 */ 0xBE, 0x8B, 0x13, 0x00, 0xE1, 0xC9, 0xD1, 0xCD, 0x8B, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¾...áÉÑÍ./......
/* 1100 */ 0x00, 0x13, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x86, 0x54, 0x7D, 0x20, 0xE1, 0x71, 0x47, // ........Ç.T} áqG
/* 1110 */ 0xB7, 0xF1, 0x7B, 0x56, 0xC6, 0xD3, 0x17, 0x0C, 0xB2, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ·ñ{VÆÓ..²/......
/* 1120 */ 0x00, 0x13, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x41, 0xEC, 0xF5, 0xF0, 0x55, 0x0D, 0x32, 0x47, // ........AìõðU.2G
/* 1130 */ 0xAF, 0x02, 0x44, 0x0A, 0x44, 0xA3, 0xCF, 0x0F, 0xDA, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¯.D.D£Ï.Ú/......
/* 1140 */ 0x00, 0x13, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xA2, 0x43, 0xB7, 0xD4, 0x68, 0xD3, 0x4D, // ........¾¢C·ÔhÓM
/* 1150 */ 0xAF, 0x32, 0x92, 0x42, 0x5B, 0x7B, 0xB6, 0x23, 0xF7, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¯2.B[{¶#÷/......
/* 1160 */ 0x00, 0x14, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x44, 0x13, 0x09, 0x00, 0xA4, 0x1E, 0x37, 0x4F, // ........D...¤.7O
/* 1170 */ 0xB7, 0x89, 0x01, 0x75, 0x0B, 0xA6, 0x98, 0x8C, 0x1C, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ·..u.¦...0......
/* 1180 */ 0x00, 0x14, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x6B, 0xDB, 0x21, 0x7B, 0x9A, 0x14, 0x4A, // ........¤kÛ!{..J
/* 1190 */ 0x9E, 0x29, 0x64, 0xA6, 0x0C, 0x59, 0x30, 0x1D, 0x3E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .)d¦.Y0.>0......
/* 11A0 */ 0x00, 0x14, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x04, 0xCA, 0xB3, 0x58, 0xA3, 0x68, 0x4D, // ........N.ʳX£hM
/* 11B0 */ 0x98, 0x83, 0xAA, 0xA2, 0x94, 0x1A, 0xCA, 0x99, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..ª¢..Ê.`0......
/* 11C0 */ 0x00, 0x14, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x34, 0xBF, 0x3D, 0x6C, 0x5F, 0xA7, 0x4F, // .........4¿=l_§O
/* 11D0 */ 0xB9, 0x36, 0x69, 0x9D, 0xCE, 0x9E, 0x26, 0x3F, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¹6i.Î.&?.0......
/* 11E0 */ 0x00, 0x15, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x33, 0x44, 0x7B, 0xE7, 0xB1, 0x88, 0x47, // ........ô3D{ç±.G
/* 11F0 */ 0x89, 0x5A, 0xC4, 0x53, 0x78, 0xD3, 0x82, 0x53, 0x9F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ZÄSxÓ.S.0......
/* 1200 */ 0x00, 0x15, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x79, 0x67, 0xC5, 0x21, 0x49, 0xB4, 0x20, 0x4D, // ........ygÅ!I´ M
/* 1210 */ 0xAD, 0xFC, 0xEE, 0xCE, 0x0E, 0x1A, 0xD7, 0x4B, 0xC1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ­üîÎ..×KÁ0......
/* 1220 */ 0x00, 0x15, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1B, 0x5A, 0x2B, 0xAB, 0xA5, 0x54, 0x4C, // ..........Z+«¥TL
/* 1230 */ 0xAC, 0x2F, 0xA6, 0xD9, 0x48, 0x24, 0xA2, 0x83, 0xE0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¬/¦ÙH$¢.à0......
/* 1240 */ 0x00, 0x15, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10, 0x54, 0x1C, 0x8C, 0x39, 0x9F, 0x05, 0x48, // .........T..9..H
/* 1250 */ 0x8C, 0x9D, 0x63, 0xA0, 0x77, 0x06, 0x35, 0x8F, 0xFF, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..c.w.5.ÿ0......
/* 1260 */ 0x00, 0x15, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x6E, 0xAF, 0xD9, 0x43, 0x86, 0x5E, 0xE8, 0x4B, // ........n¯ÙC.^èK
/* 1270 */ 0xA7, 0x97, 0xD0, 0x72, 0xA0, 0x46, 0x89, 0x6C, 0x1C, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // §.Ðr.F.l.1......
/* 1280 */ 0x00, 0x15, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x08, 0x9C, 0xE4, 0x82, 0xDA, 0xF8, 0x42, // ........ç..ä.ÚøB
/* 1290 */ 0xBD, 0xE2, 0xB5, 0x70, 0xFB, 0xCA, 0xE7, 0x6C, 0x36, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ½âµpûÊçl61......
/* 12A0 */ 0x00, 0x15, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x22, 0xEF, 0xC5, 0x61, 0x4F, 0xF1, 0x53, 0x45, // ........"ïÅaOñSE
/* 12B0 */ 0xA8, 0x24, 0xC4, 0xB3, 0x1E, 0x84, 0xB1, 0x00, 0x6B, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¨$ij..±.k1......
/* 12C0 */ 0x00, 0x15, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00, 0x44, 0x7C, 0x94, 0xBA, 0x9D, 0xD1, 0x86, 0x47, // ........D|.º.Ñ.G
/* 12D0 */ 0xB6, 0xAE, 0x22, 0x77, 0x0B, 0xC9, 0x4C, 0x54, 0x9E, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¶®"w.ÉLT.1......
/* 12E0 */ 0x00, 0x16, 0x06, 0x05, 0x00, 0x01, 0x00, 0x00, 0x06, 0x16, 0x3D, 0x4F, 0xEA, 0x3F, 0x01, 0x4C, // ..........=Oê?.L
/* 12F0 */ 0xBE, 0x3C, 0x8D, 0x67, 0x1C, 0x40, 0x1E, 0x3B, 0xC5, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¾<.g.@.;Å1......
/* 1300 */ 0x00, 0x17, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0xC2, 0x2D, 0x68, 0x2C, 0x68, 0x8B, 0x63, 0x4F, // ........Â-h,h.cO
/* 1310 */ 0xA1, 0x65, 0xAE, 0x29, 0x1D, 0x4C, 0xF1, 0x38, 0xDC, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¡e®).Lñ8Ü1......
/* 1320 */ 0x00, 0x17, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xD8, 0xCF, 0xD7, 0xC0, 0x2B, 0x45, // .........ÿØÏ×À+E
/* 1330 */ 0x9F, 0x60, 0xEF, 0x5C, 0x70, 0xC3, 0x20, 0x94, 0xF5, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .`ï\pà .õ1......
/* 1340 */ 0x00, 0x17, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x50, 0x49, 0xF5, 0xD4, 0xF2, 0x26, 0xB4, 0x4F, // ........PIõÔò&´O
/* 1350 */ 0xBA, 0x21, 0xFF, 0xAB, 0x16, 0xAF, 0xCA, 0xDE, 0x0E, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // º!ÿ«.¯ÊÞ.2......
/* 1360 */ 0x00, 0x17, 0x04, 0x19, 0x00, 0x00, 0x00, 0x00, 0x72, 0xE8, 0xE7, 0x8C, 0x8C, 0x18, 0x98, 0x4B, // ........rèç....K
/* 1370 */ 0x9D, 0x90, 0xF8, 0xF9, 0x0B, 0x7A, 0xAD, 0x02, 0x29, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..øù.z­.)2......
/* 1380 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x70, 0xD4, 0xE5, 0xCE, 0x3B, 0x6E, 0xCC, 0x4F, // ........pÔåÎ;nÌO
/* 1390 */ 0x8C, 0x2B, 0xD1, 0x74, 0x28, 0x56, 0x8A, 0x9F, 0x3C, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .+Ñt(V..<2......
/* 13A0 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0xB8, 0xD0, 0x47, 0x89, 0x3B, 0xC3, 0xE1, 0x43, // ........¸ÐG.;ÃáC
/* 13B0 */ 0x8C, 0x56, 0x9B, 0x67, 0x4C, 0x05, 0x28, 0x32, 0x4E, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .V.gL.(2N2......
/* 13C0 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x39, 0x66, 0x6B, 0xCA, 0xD6, 0x4A, 0xAE, 0x40, // ........9fkÊÖJ®@
/* 13D0 */ 0xA5, 0x75, 0x14, 0xDE, 0xE0, 0x7F, 0x64, 0x30, 0x61, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¥u.Þà.d0a2......
/* 13E0 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x40, 0x96, 0xED, 0x09, 0x20, 0xF0, 0x0A, 0x40, // ........@.í. ð.@
/* 13F0 */ 0xAC, 0xD8, 0xD7, 0xD8, 0x67, 0xDF, 0xD9, 0xC2, 0x76, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¬Ø×ØgßÙÂv2......
/* 1400 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x49, 0x4E, 0x3D, 0xEF, 0x3D, 0xA5, 0x81, 0x4D, // ........IN=ï=¥.M
/* 1410 */ 0xA2, 0xB1, 0x2C, 0xA6, 0xC2, 0x55, 0x6B, 0x2C, 0x8A, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¢±,¦ÂUk,.2......
/* 1420 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x6F, 0x58, 0xAB, 0x56, 0x52, 0x32, 0x46, // ........\oX«VR2F
/* 1430 */ 0x96, 0x2F, 0xFE, 0xFD, 0x8B, 0x49, 0xE6, 0xF4, 0x9E, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ./þý.Iæô.2......
/* 1440 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x92, 0xC1, 0xB7, 0xEC, 0xAB, 0x73, 0xED, 0x4D, // .........Á·ì«síM
/* 1450 */ 0xAC, 0xF4, 0x23, 0x99, 0xB0, 0x95, 0xD0, 0xCC, 0xB2, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¬ô#.°.Ð̲2......
/* 1460 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x1D, 0x3B, 0x59, 0x45, 0xB1, 0xDF, 0x91, 0x4E, // .........;YE±ß.N
/* 1470 */ 0xBB, 0xFB, 0x2D, 0x5D, 0x0C, 0xE2, 0x22, 0x7A, 0xC6, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // »û-].â"zÆ2......
/* 1480 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x60, 0x77, 0x32, 0x6F, 0x5C, 0x8C, 0x7C, 0x41, // ........`w2o\.|A
/* 1490 */ 0x9B, 0x61, 0x83, 0x6A, 0x98, 0x28, 0x7E, 0x0C, 0xDD, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .a.j.(~.Ý2......
/* 14A0 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0xF7, 0x3F, 0x13, 0xDF, 0x14, 0xBF, 0x95, 0x4F, // ........÷?.ß.¿.O
/* 14B0 */ 0xAF, 0xE3, 0x7B, 0x48, 0xE7, 0xE3, 0x31, 0xEF, 0xFB, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¯ã{Hçã1ïû2......
/* 14C0 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x61, 0xBF, 0xC7, 0x5D, 0xC9, 0x5E, 0x96, 0x49, // ........a¿Ç]É^.I
/* 14D0 */ 0x9C, 0xCB, 0xDF, 0x80, 0x6A, 0x2D, 0x0E, 0xFE, 0x13, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Ëß.j-.þ.3......
/* 14E0 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x75, 0x4F, 0x0C, 0xB5, 0x9B, 0x59, 0xE8, 0x43, // ........uO.µ.YèC
/* 14F0 */ 0x8D, 0xCD, 0x10, 0x81, 0xA7, 0x96, 0x72, 0x41, 0x30, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Í..§.rA03......
/* 1500 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x87, 0x9E, 0x50, 0xEA, 0xA1, 0x07, 0x45, 0x4A, // ..........Pê¡.EJ
/* 1510 */ 0x9E, 0xDC, 0xEB, 0xA5, 0xA3, 0x9F, 0x36, 0xAF, 0x46, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Ü륣.6¯F3......
/* 1520 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x78, 0xA6, 0xA2, 0x9D, 0x6B, 0xFB, 0x67, 0x4E, // ........x¦¢.kûgN
/* 1530 */ 0xAB, 0x84, 0x60, 0xDD, 0x6A, 0x9C, 0x81, 0x9A, 0x68, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // «.`Ýj...h3......
/* 1540 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x05, 0x61, 0x23, 0x92, 0x67, 0xBB, 0x4F, 0x49, // .........a#.g»OI
/* 1550 */ 0x94, 0xC7, 0x7F, 0x7A, 0x60, 0x79, 0x29, 0xBD, 0x7D, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Ç.z`y)½}3......
/* 1560 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x9C, 0x38, 0x58, 0xE5, 0xC3, 0x83, 0x29, 0x4B, // .........8XåÃ.)K
/* 1570 */ 0xAD, 0xFE, 0x5E, 0x4D, 0x7F, 0x46, 0xC3, 0x58, 0x97, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ­þ^M.FÃX.3......
/* 1580 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0xFF, 0x33, 0xD8, 0x9E, 0x92, 0x4F, 0x36, 0x4F, // ........ÿ3Ø..O6O
/* 1590 */ 0xB3, 0x70, 0x86, 0x83, 0xA4, 0xF1, 0x32, 0x75, 0xAD, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ³p..¤ñ2u­3......
/* 15A0 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0xE7, 0x82, 0x08, 0x2D, 0xE7, 0xA4, 0x3B, 0x42, // ........ç..-ç¤;B
/* 15B0 */ 0x8C, 0xCC, 0x70, 0xD9, 0x1E, 0x01, 0x58, 0xB1, 0xC8, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ÌpÙ..X±È3......
/* 15C0 */ 0x01, 0x18, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x2C, 0x62, 0xE7, 0x6E, 0xD8, 0x18, 0x05, 0x40, // ........,bçnØ..@
/* 15D0 */ 0x9F, 0xB7, 0x92, 0xDB, 0x64, 0x4A, 0x27, 0x9B, 0xD9, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .·.ÛdJ'.Ù3......
/* 15E0 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0x52, 0x1D, 0x46, 0xF7, 0x2B, 0x7C, 0xB2, 0x43, // ........R.F÷+|²C
/* 15F0 */ 0x87, 0x44, 0xEA, 0x95, 0x8E, 0x0B, 0xD0, 0x9A, 0xEC, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Dê...Ð.ì3......
/* 1600 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0x40, 0x80, 0x0B, 0xA3, 0x8A, 0xD6, 0x3F, 0x42, // ........@..£.Ö?B
/* 1610 */ 0xB0, 0xB5, 0x9C, 0xE2, 0x92, 0xEA, 0x5A, 0x8F, 0xFE, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // °µ.â.êZ.þ3......
/* 1620 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0xE3, 0x11, 0x9F, 0x1B, 0x5C, 0xC8, 0x1B, 0x4E, // ........ã...\È.N
/* 1630 */ 0xBB, 0x29, 0x87, 0x9A, 0xD2, 0xC9, 0x09, 0xE3, 0x13, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // »)..ÒÉ.ã.4......
/* 1640 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0x6B, 0x1C, 0x98, 0xDC, 0x8E, 0xFC, 0x0F, 0x42, // ........k..Ü.ü.B
/* 1650 */ 0xAA, 0x43, 0xF8, 0xF3, 0x3E, 0x5C, 0x09, 0x23, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ªCøó>\.#$4......
/* 1660 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0xE6, 0xF3, 0xE1, 0xEF, 0xA2, 0xAE, 0x44, 0x41, // ........æóáDA
/* 1670 */ 0xA2, 0x08, 0x32, 0xAA, 0x87, 0x2B, 0x65, 0x45, 0x36, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¢.2ª.+eE64......
/* 1680 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0xFA, 0x3A, 0x1C, 0x77, 0xC5, 0x50, 0x3F, 0x44, // ........ú:.wÅP?D
/* 1690 */ 0xB1, 0x51, 0xFF, 0x25, 0x46, 0xD8, 0x63, 0xA0, 0x4A, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ±Qÿ%FØc.J4......
/* 16A0 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0x49, 0x26, 0x76, 0x8C, 0xD1, 0x97, 0x53, 0x49, // ........I&v.Ñ.SI
/* 16B0 */ 0xAD, 0x27, 0xB7, 0xE2, 0xC2, 0x5B, 0x97, 0x2E, 0x5E, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ­'·âÂ[..^4......
/* 16C0 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0x9C, 0xDA, 0x22, 0xB3, 0xE2, 0xA2, 0x58, 0x40, // .........Ú"³â¢X@
/* 16D0 */ 0x9E, 0x4E, 0xF5, 0x9A, 0x69, 0x70, 0xBD, 0x69, 0x75, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Nõ.ip½iu4......
/* 16E0 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0x4A, 0x12, 0x5D, 0x4A, 0x20, 0xE6, 0xBA, 0x44, // ........J.]J æºD
/* 16F0 */ 0xB6, 0xFF, 0x65, 0x89, 0x61, 0xB3, 0x3B, 0x9A, 0x93, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¶ÿe.a³;..4......
/* 1700 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0xD1, 0x28, 0x7A, 0x42, 0x7C, 0xD1, 0xBF, 0x4A, // ........Ñ(zB|Ñ¿J
/* 1710 */ 0xB7, 0x17, 0x32, 0xC7, 0x80, 0xBA, 0x6F, 0x07, 0xAB, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ·.2Ç.ºo.«4......
/* 1720 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0xF1, 0x9F, 0xC7, 0x00, 0x50, 0x68, 0x3D, 0x44, // ........ñ.Ç.Ph=D
/* 1730 */ 0xBF, 0x61, 0x71, 0xCD, 0xE0, 0xDE, 0x30, 0x5F, 0xC8, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¿aqÍàÞ0_È4......
/* 1740 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0x38, 0xFB, 0x3A, 0xB1, 0x79, 0xCD, 0xE5, 0x4A, // ........8û:±yÍåJ
/* 1750 */ 0x9F, 0x7F, 0xEE, 0xD0, 0x58, 0xD7, 0x50, 0xCA, 0xDE, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..îÐX×PÊÞ4......
/* 1760 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0x0E, 0xC1, 0x3A, 0xE1, 0xD0, 0x75, 0xFF, 0x4A, // .........Á:áÐuÿJ
/* 1770 */ 0xA0, 0xCD, 0x76, 0x49, 0x82, 0xCF, 0x54, 0x1C, 0xF3, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ÍvI.ÏT.ó4......
/* 1780 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0xF0, 0xFA, 0x4E, 0xAC, 0x1F, 0xF8, 0x61, 0x4F, // ........ðúN¬.øaO
/* 1790 */ 0xBD, 0xF7, 0xEA, 0x32, 0xB0, 0x2A, 0xB1, 0x17, 0x09, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ½÷ê2°*±..5......
/* 17A0 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0xC6, 0xB1, 0xF5, 0xD9, 0x86, 0x53, 0x5A, 0x49, // ........ƱõÙ.SZI
/* 17B0 */ 0x88, 0xF9, 0x9A, 0xD6, 0xB4, 0x1A, 0xC9, 0xB3, 0x24, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ù.Ö´.ɳ$5......
/* 17C0 */ 0x02, 0x19, 0x05, 0x05, 0x00, 0x00, 0x02, 0x00, 0xE2, 0x38, 0xB5, 0x44, 0x34, 0xFB, 0x32, 0x47, // ........â8µD4û2G
/* 17D0 */ 0x81, 0xE4, 0x64, 0x4C, 0x17, 0xD2, 0xE7, 0x46, 0x35, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ädL.ÒçF55......
/* 17E0 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0xA0, 0xBF, 0x73, 0x93, 0xB3, 0x97, 0x87, 0x45, // .........¿s.³..E
/* 17F0 */ 0xAB, 0x73, 0x30, 0x93, 0x44, 0x61, 0xD5, 0x5C, 0x56, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // «s0.DaÕ\V5......
/* 1800 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0xB4, 0x6E, 0x28, 0xAA, 0x6F, 0x55, 0xEB, 0x4E, // ........´n(ªoUëN
/* 1810 */ 0x96, 0x7C, 0xC1, 0xB7, 0x71, 0xB7, 0x67, 0x3E, 0x76, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .|Á·q·g>v5......
/* 1820 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x56, 0x82, 0xCC, 0x7C, 0xAA, 0xFB, 0xC6, 0x49, // ........V.Ì|ªûÆI
/* 1830 */ 0xB2, 0xA9, 0xF5, 0xAF, 0xB4, 0x25, 0x7C, 0xD2, 0x97, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ²©õ¯´%|Ò.5......
/* 1840 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x17, 0xFE, 0x3D, 0xC5, 0x00, 0xCC, 0x67, 0x49, // .........þ=Å.ÌgI
/* 1850 */ 0xB1, 0x88, 0xA0, 0x88, 0xA9, 0x65, 0x49, 0x4D, 0xBA, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ±...©eIMº5......
/* 1860 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x7D, 0xA8, 0x16, 0x28, 0xED, 0xE1, 0x97, 0x40, // ........}¨.(íá.@
/* 1870 */ 0xB3, 0x11, 0xE2, 0x34, 0x1C, 0x57, 0xB1, 0x79, 0xD9, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ³.â4.W±yÙ5......
/* 1880 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x08, 0xF9, 0xC0, 0x67, 0x4F, 0x18, 0x64, 0x4F, // .........ùÀgO.dO
/* 1890 */ 0x82, 0x50, 0x12, 0xDB, 0x79, 0x7A, 0xB3, 0xC3, 0xF9, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .P.Ûyz³Ãù5......
/* 18A0 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x7A, 0x4E, 0xCE, 0x7B, 0x80, 0xDD, 0x82, 0x46, // ........zNÎ{.Ý.F
/* 18B0 */ 0x98, 0xFA, 0xF9, 0x93, 0x72, 0x58, 0x03, 0xD2, 0x1B, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .úù.rX.Ò.6......
/* 18C0 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x0A, 0x0C, 0xC1, 0x1E, 0xF6, 0x54, 0x3E, 0x45, // ..........Á.öT>E
/* 18D0 */ 0xB8, 0x5A, 0x6F, 0xA1, 0xBB, 0xFE, 0xA9, 0xB7, 0x3D, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¸Zo¡»þ©·=6......
/* 18E0 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0xBF, 0xB5, 0xD2, 0x87, 0x7B, 0xD4, 0xFB, 0x41, // ........¿µÒ.{ÔûA
/* 18F0 */ 0xAF, 0x62, 0x71, 0xC3, 0x82, 0xF5, 0xCC, 0x85, 0x62, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¯bqÃ.õÌ.b6......
/* 1900 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0xA9, 0x50, 0xFE, 0x3C, 0x03, 0x0E, 0x29, 0x4B, // ........©Pþ<..)K
/* 1910 */ 0x97, 0x54, 0x9F, 0x19, 0x3F, 0x07, 0xB7, 0x1F, 0x8E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .T..?.·..6......
/* 1920 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x57, 0x9E, 0xE4, 0x39, 0x68, 0xAE, 0xE3, 0x4E, // ........W.ä9h®ãN
/* 1930 */ 0xB0, 0x98, 0x26, 0x48, 0x0D, 0xF3, 0xDA, 0x96, 0xB4, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // °.&H.óÚ.´6......
/* 1940 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x17, 0x21, 0xAA, 0x15, 0x79, 0x8F, 0xA8, 0x49, // .........!ª.y.¨I
/* 1950 */ 0x83, 0x17, 0x75, 0x30, 0x26, 0xD6, 0xA0, 0x54, 0xDF, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..u0&Ö.Tß6......
/* 1960 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x0E, 0xD6, 0xBF, 0xCF, 0x5F, 0x0B, 0x7D, 0x42, // .........Ö¿Ï_.}B
/* 1970 */ 0x91, 0x7C, 0xA4, 0xDF, 0x42, 0xA8, 0x0E, 0x44, 0x03, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .|¤ßB¨.D.7......
/* 1980 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x81, 0xCC, 0x12, 0x70, 0x87, 0x88, 0xE9, 0x42, // .........Ì.p..éB
/* 1990 */ 0xB1, 0x7D, 0x4E, 0x5E, 0x42, 0x76, 0x0F, 0x0D, 0x27, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ±}N^Bv..'7......
/* 19A0 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0xB6, 0x7E, 0x9C, 0xDE, 0x85, 0x5A, 0x0D, 0x42, // ........¶~.Þ.Z.B
/* 19B0 */ 0x97, 0x03, 0xFF, 0xF1, 0x1B, 0xDD, 0x4D, 0x43, 0x50, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..ÿñ.ÝMCP7......
/* 19C0 */ 0x02, 0x1A, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x0C, 0xFC, 0xC0, 0x67, 0xBA, 0xDE, 0x1B, 0x40, // .........üÀgºÞ.@
/* 19D0 */ 0xBF, 0x8B, 0x9C, 0x8A, 0xD8, 0x39, 0x58, 0x04, 0x6F, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¿...Ø9X.o7......
/* 19E0 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x36, 0x5D, 0xE6, 0xC3, 0x1F, 0x14, 0x2F, 0x4D, // ........6]æÃ../M
/* 19F0 */ 0xA3, 0x03, 0xA8, 0x42, 0xEE, 0x75, 0x6A, 0x29, 0x82, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // £.¨Bîuj).7......
/* 1A00 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0xCB, 0xBC, 0xAA, 0x9C, 0xB1, 0x61, 0x4B, 0x4B, // ........˼ª.±aKK
/* 1A10 */ 0x8B, 0xEC, 0xD1, 0x0A, 0x3C, 0x3A, 0xC2, 0xCE, 0x94, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ìÑ.<:ÂÎ.7......
/* 1A20 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x6E, 0xEA, 0x14, 0xE9, 0xFA, 0xA5, 0x39, 0x44, // ........nê.éú¥9D
/* 1A30 */ 0xA3, 0x94, 0xA9, 0xBB, 0x32, 0x93, 0xCA, 0x09, 0xA6, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // £.©»2.Ê.¦7......
/* 1A40 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x59, 0xCE, 0xCA, 0xD8, 0xD2, 0x33, 0xC7, 0x4A, // ........YÎÊØÒ3ÇJ
/* 1A50 */ 0x9B, 0x1B, 0x9B, 0x72, 0x33, 0x9C, 0x51, 0xC8, 0xBA, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...r3.QȺ7......
/* 1A60 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x65, 0x92, 0x9D, 0xEC, 0x1E, 0x9D, 0xD0, 0x4E, // ........e..ì..ÐN
/* 1A70 */ 0x83, 0x8A, 0xCD, 0xC2, 0x0F, 0x25, 0x51, 0xA1, 0xCE, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..ÍÂ.%Q¡Î7......
/* 1A80 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0xBA, 0x1B, 0x0B, 0xD7, 0x93, 0xB8, 0x44, 0x45, // ........º..×.¸DE
/* 1A90 */ 0x96, 0xE2, 0xB7, 0xA3, 0x18, 0x09, 0x1C, 0x33, 0xE2, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .â·£...3â7......
/* 1AA0 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x6F, 0x59, 0x50, 0xD4, 0x4D, 0x89, 0xE0, 0x49, // ........oYPÔM.àI
/* 1AB0 */ 0x96, 0x6A, 0xFD, 0x39, 0xED, 0x4C, 0x4C, 0x64, 0xF9, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .jý9íLLdù7......
/* 1AC0 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x97, 0x41, 0x41, 0x4F, 0xC2, 0x0F, 0x01, 0x4C, // .........AAOÂ..L
/* 1AD0 */ 0xB6, 0x8A, 0x86, 0xCB, 0xB9, 0xAC, 0x25, 0x4C, 0x17, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¶..˹¬%L.8......
/* 1AE0 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x10, 0x81, 0x9B, 0x82, 0x6F, 0x0E, 0x49, 0x43, // ............o.IC
/* 1AF0 */ 0xBC, 0xA4, 0x42, 0x80, 0x35, 0x77, 0x78, 0x8D, 0x2F, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¼¤B.5wx./8......
/* 1B00 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0xBC, 0xDA, 0x7D, 0xDA, 0xBE, 0x3F, 0x47, 0x44, // ........¼Ú}Ú¾?GD
/* 1B10 */ 0x9E, 0x01, 0x6A, 0xB7, 0x44, 0x0B, 0x4C, 0xD4, 0x4B, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..j·D.LÔK8......
/* 1B20 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x45, 0xCA, 0xBA, 0xCB, 0x6A, 0x55, 0x16, 0x44, // ........EʺËjU.D
/* 1B30 */ 0xAD, 0x03, 0xBD, 0xA5, 0x98, 0xEA, 0xA7, 0xC8, 0x68, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ­.½¥.ê§Èh8......
/* 1B40 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0xCB, 0x06, 0x1A, 0x04, 0xB8, 0xC5, 0x72, 0x47, // ........Ë...¸ÅrG
/* 1B50 */ 0x80, 0x9F, 0x41, 0x6D, 0x03, 0xD1, 0x66, 0x54, 0x89, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..Am.ÑfT.8......
/* 1B60 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0xE1, 0x4E, 0xE0, 0x83, 0x8D, 0xFA, 0x6D, 0x43, // ........áNà..úmC
/* 1B70 */ 0x89, 0x94, 0xD3, 0x1A, 0x86, 0x2C, 0xAB, 0x77, 0x9F, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..Ó..,«w.8......
/* 1B80 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x3D, 0xA2, 0xDF, 0xDE, 0xD1, 0x6E, 0xA6, 0x45, // ........=¢ßÞÑn¦E
/* 1B90 */ 0x85, 0xDC, 0x63, 0xCA, 0xE0, 0x54, 0x6D, 0xE6, 0xBE, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ÜcÊàTmæ¾8......
/* 1BA0 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0xC1, 0x01, 0xF3, 0x6B, 0x4A, 0xB9, 0xE9, 0x43, // ........Á.ókJ¹éC
/* 1BB0 */ 0xBA, 0x31, 0xD4, 0x94, 0x59, 0x8C, 0x47, 0xFB, 0xD3, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // º1Ô.Y.GûÓ8......
/* 1BC0 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0xE3, 0xAB, 0x34, 0xB2, 0x57, 0x08, 0x9C, 0x4F, // ........ã«4²W..O
/* 1BD0 */ 0xB0, 0x5A, 0x4D, 0xC3, 0x14, 0xF8, 0x55, 0x57, 0xE9, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // °ZMÃ.øUWé8......
/* 1BE0 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x21, 0x78, 0x2A, 0xAA, 0x27, 0x18, 0x2C, 0x4C, // ........!x*ª'.,L
/* 1BF0 */ 0x8F, 0x1D, 0x45, 0x13, 0xA3, 0x4D, 0xDA, 0x97, 0x03, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..E.£MÚ..9......
/* 1C00 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x20, 0xE6, 0x1F, 0x36, 0xF4, 0x64, 0xB5, 0x41, // ........ æ.6ôdµA
/* 1C10 */ 0xBA, 0x77, 0x84, 0xF8, 0xE0, 0x79, 0xB1, 0xF7, 0x1E, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ºw.øày±÷.9......
/* 1C20 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0xDF, 0xBA, 0x11, 0xBB, 0xAA, 0xD8, 0x0E, 0x47, // ........ߺ.»ªØ.G
/* 1C30 */ 0x93, 0x11, 0x20, 0xEA, 0xF8, 0x0F, 0xE5, 0xCC, 0x3D, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .. êø.åÌ=9......
/* 1C40 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x85, 0x88, 0xC8, 0x0B, 0x8C, 0x71, 0x1D, 0x49, // ..........È..q.I
/* 1C50 */ 0x92, 0x1F, 0x6F, 0x21, 0x43, 0x49, 0xE7, 0x9C, 0x4E, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..o!CIç.N9......
/* 1C60 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x4D, 0x7C, 0xFC, 0x85, 0x2E, 0xB9, 0x4B, // .........M|ü..¹K
/* 1C70 */ 0xAF, 0xD4, 0x01, 0xED, 0x14, 0x76, 0xB5, 0xE9, 0x78, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¯Ô.í.vµéx9......
/* 1C80 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0x19, 0x66, 0x0F, 0x50, 0x93, 0xEF, 0x75, 0x4B, // .........f.P.ïuK
/* 1C90 */ 0xBC, 0xB4, 0x82, 0x81, 0x99, 0x98, 0xA3, 0xCA, 0x9C, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¼´....£Ê.9......
/* 1CA0 */ 0x02, 0x1B, 0x06, 0x05, 0x00, 0x00, 0x03, 0x00, 0xEB, 0xCE, 0x9B, 0x9E, 0x36, 0xE7, 0x26, 0x4F, // ........ëÎ..6ç&O
/* 1CB0 */ 0x88, 0xDE, 0x76, 0x3F, 0x87, 0xDC, 0xC4, 0x85, 0xBE, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Þv?.ÜÄ.¾9......
/* 1CC0 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0xE9, 0x54, 0x78, 0x23, 0xFC, 0x79, 0x97, 0x44, // ........éTx#üy.D
/* 1CD0 */ 0xA0, 0xC1, 0xA7, 0x09, 0x69, 0x69, 0x1C, 0x6B, 0xD1, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Á§.ii.kÑ9......
/* 1CE0 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0x01, 0xA3, 0xF8, 0xC8, 0xF5, 0x19, 0x32, 0x41, // .........£øÈõ.2A
/* 1CF0 */ 0x96, 0xCE, 0x2D, 0xE9, 0xD4, 0xAD, 0xBD, 0x33, 0xE3, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .Î-éÔ­½3ã9......
/* 1D00 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0x61, 0xFD, 0x31, 0x31, 0x4F, 0x5E, 0x08, 0x43, // ........aý11O^.C
/* 1D10 */ 0x8D, 0x6D, 0x62, 0xBE, 0x19, 0x87, 0xC9, 0x2C, 0xF7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .mb¾..É,÷9......
/* 1D20 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0x5F, 0x8B, 0xDD, 0x85, 0xA4, 0xEA, 0xF3, 0x4A, // ........_.Ý.¤êóJ
/* 1D30 */ 0xA6, 0x28, 0xCC, 0xE9, 0xE7, 0x7C, 0x9A, 0x03, 0x0E, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¦(Ìéç|...:......
/* 1D40 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0x3F, 0xBF, 0xA2, 0x2C, 0x9E, 0x94, 0x6A, 0x44, // ........?¿¢,..jD
/* 1D50 */ 0x82, 0xC7, 0xE2, 0x5A, 0x15, 0xEC, 0x78, 0xC4, 0x2C, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ÇâZ.ìxÄ,:......
/* 1D60 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0xE3, 0xF0, 0x77, 0x17, 0x92, 0x73, 0x98, 0x41, // ........ãðw..s.A
/* 1D70 */ 0x97, 0xEA, 0x8A, 0xE4, 0xDE, 0x6F, 0x63, 0x81, 0x44, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ê.äÞoc.D:......
/* 1D80 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0xCA, 0x4C, 0x3E, 0x9D, 0x72, 0xE1, 0xF1, 0x46, // ........ÊL>.ráñF
/* 1D90 */ 0xA2, 0xF4, 0x1D, 0x21, 0x07, 0x05, 0x14, 0x44, 0x61, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¢ô.!...Da:......
/* 1DA0 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0x6E, 0x6C, 0x4C, 0x73, 0xBA, 0xB0, 0x98, 0x42, // ........nlLsº°.B
/* 1DB0 */ 0xA8, 0x91, 0x67, 0x17, 0x72, 0xB2, 0xBD, 0x1B, 0x77, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¨.g.r²½.w:......
/* 1DC0 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0x4B, 0xA7, 0x12, 0x69, 0xFB, 0xA5, 0x1A, 0x40, // ........K§.iû¥.@
/* 1DD0 */ 0xBF, 0xDB, 0x2E, 0x3A, 0xB4, 0x6F, 0x4B, 0x02, 0x96, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¿Û.:´oK..:......
/* 1DE0 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0x8F, 0xF0, 0x5C, 0x5B, 0x1A, 0xB8, 0x1D, 0x43, // .........ð\[.¸.C
/* 1DF0 */ 0xB0, 0x80, 0x34, 0x50, 0xD8, 0x62, 0x05, 0x65, 0xAB, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // °.4PØb.e«:......
/* 1E00 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0xF3, 0x7D, 0x6D, 0xE0, 0xD0, 0xAA, 0x9D, 0x41, // ........ó}màЪ.A
/* 1E10 */ 0x8D, 0xFB, 0x0A, 0xC3, 0x7E, 0x2B, 0xDF, 0x39, 0xC1, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .û.Ã~+ß9Á:......
/* 1E20 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0xFE, 0x34, 0x98, 0x05, 0xEA, 0xA8, 0xFF, 0x4B, // ........þ4..ê¨ÿK
/* 1E30 */ 0xB6, 0x7B, 0x4D, 0x00, 0x6B, 0x54, 0x47, 0xD3, 0xDC, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ¶{M.kTGÓÜ:......
/* 1E40 */ 0x02, 0x1C, 0x06, 0x05, 0x00, 0x00, 0x05, 0x00, 0xD4, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........Ô ......
/* 1E50 */ 0x00, 0xB5, 0xB2, 0x5B, 0x00, 0x00, 0x00, 0x00, 0x63, 0x45, 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x00, // .µ²[....cE......
/* 1E60 */ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ò ......
/* 1E70 */ 0x80, 0xE2, 0x9F, 0x57, 0x00, 0x00, 0x00, 0x00, 0x39, 0x38, 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x00, // .â.W....98......
/* 1E80 */ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .........!......
/* 1E90 */ 0x00, 0x7A, 0x60, 0x52, 0x00, 0x00, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x01, 0x19, 0x00, 0x00, // .z`R.....%......
/* 1EA0 */ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........-!......
/* 1EB0 */ 0x80, 0xD2, 0x89, 0x50, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x23, 0x00, 0x00, 0x32, 0x15, 0x00, 0x00, // .Ò.P....ð#..2...
/* 1EC0 */ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........E!......
/* 1ED0 */ 0x80, 0xFC, 0x62, 0x4D, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x1D, 0x00, 0x00, 0x01, 0xD7, 0x00, 0x00, // .übM....±....×..
/* 1EE0 */ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........d!......
/* 1EF0 */ 0x00, 0x31, 0x1B, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x72, 0x17, 0x00, 0x00, 0x01, 0xD7, 0x00, 0x00, // .1.J....r....×..
/* 1F00 */ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, // ........03612-00
/* 1F10 */ 0x32, 0x30, 0x36, 0x2D, 0x35, 0x35, 0x36, 0x2D, 0x31, 0x32, 0x33, 0x37, 0x32, 0x37, 0x2D, 0x30, // 206-556-123727-0
/* 1F20 */ 0x33, 0x2D, 0x31, 0x30, 0x33, 0x33, 0x2D, 0x31, 0x37, 0x37, 0x36, 0x33, 0x2E, 0x30, 0x30, 0x30, // 3-1033-17763.000
/* 1F30 */ 0x30, 0x2D, 0x32, 0x39, 0x37, 0x32, 0x30, 0x31, 0x38, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, // 0-2972018.Window
/* 1F40 */ 0x73, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, // s.Windows Server
/* 1F50 */ 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, 0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, 0x30, 0x39, // 2019.03612-0009
/* 1F60 */ 0x36, 0x2D, 0x31, 0x39, 0x39, 0x2D, 0x37, 0x39, 0x39, 0x31, 0x38, 0x38, 0x2D, 0x30, 0x33, 0x2D, // 6-199-799188-03-
/* 1F70 */ 0x31, 0x30, 0x33, 0x33, 0x2D, 0x31, 0x37, 0x37, 0x36, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x2D, // 1033-17763.0000-
/* 1F80 */ 0x32, 0x39, 0x37, 0x32, 0x30, 0x31, 0x38, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x32, 0x30, // 2972018.Office20
/* 1F90 */ 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x30, // 10.Office 2010.0
/* 1FA0 */ 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, 0x32, 0x30, 0x36, 0x2D, 0x32, 0x34, 0x30, 0x2D, 0x37, // 3612-00206-240-7
/* 1FB0 */ 0x31, 0x39, 0x36, 0x33, 0x39, 0x2D, 0x30, 0x33, 0x2D, 0x31, 0x30, 0x33, 0x33, 0x2D, 0x31, 0x37, // 19639-03-1033-17
/* 1FC0 */ 0x37, 0x36, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x32, 0x39, 0x37, 0x32, 0x30, 0x31, 0x38, // 763.0000-2972018
/* 1FD0 */ 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, // .Office2013.Offi
/* 1FE0 */ 0x63, 0x65, 0x20, 0x32, 0x30, 0x31, 0x33, 0x00, 0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x30, // ce 2013.03612-00
/* 1FF0 */ 0x32, 0x30, 0x36, 0x2D, 0x34, 0x33, 0x38, 0x2D, 0x30, 0x30, 0x34, 0x35, 0x33, 0x32, 0x2D, 0x30, // 206-438-004532-0
/* 2000 */ 0x33, 0x2D, 0x31, 0x30, 0x33, 0x33, 0x2D, 0x31, 0x37, 0x37, 0x36, 0x33, 0x2E, 0x30, 0x30, 0x30, // 3-1033-17763.000
/* 2010 */ 0x30, 0x2D, 0x32, 0x39, 0x37, 0x32, 0x30, 0x31, 0x38, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, // 0-2972018.Office
/* 2020 */ 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x32, 0x30, 0x31, 0x36, // 2016.Office 2016
/* 2030 */ 0x00, 0x30, 0x33, 0x36, 0x31, 0x32, 0x2D, 0x30, 0x33, 0x38, 0x35, 0x38, 0x2D, 0x30, 0x35, 0x33, // .03612-03858-053
/* 2040 */ 0x2D, 0x30, 0x38, 0x39, 0x35, 0x31, 0x36, 0x2D, 0x30, 0x33, 0x2D, 0x31, 0x30, 0x33, 0x33, 0x2D, // -089516-03-1033-
/* 2050 */ 0x31, 0x37, 0x37, 0x36, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x32, 0x39, 0x37, 0x32, 0x30, // 17763.0000-29720
/* 2060 */ 0x31, 0x38, 0x00, 0x57, 0x69, 0x6E, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x47, 0x6F, 0x76, 0x00, 0x57, // 18.WinChinaGov.W
/* 2070 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, // indows 10 China
/* 2080 */ 0x47, 0x6F, 0x76, 0x65, 0x72, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x00, 0x30, 0x33, 0x36, 0x31, 0x32, // Government.03612
/* 2090 */ 0x2D, 0x30, 0x30, 0x32, 0x30, 0x36, 0x2D, 0x36, 0x38, 0x34, 0x2D, 0x31, 0x33, 0x37, 0x36, 0x36, // -00206-684-13766
/* 20A0 */ 0x39, 0x2D, 0x30, 0x33, 0x2D, 0x31, 0x30, 0x33, 0x33, 0x2D, 0x31, 0x37, 0x37, 0x36, 0x33, 0x2E, // 9-03-1033-17763.
/* 20B0 */ 0x30, 0x30, 0x30, 0x30, 0x2D, 0x32, 0x39, 0x37, 0x32, 0x30, 0x31, 0x38, 0x00, 0x4F, 0x66, 0x66, // 0000-2972018.Off
/* 20C0 */ 0x69, 0x63, 0x65, 0x32, 0x30, 0x31, 0x39, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x32, // ice2019.Office 2
/* 20D0 */ 0x30, 0x31, 0x39, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x31, // 019.Windows 10 1
/* 20E0 */ 0x38, 0x30, 0x39, 0x20, 0x2F, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, // 809 / Server 201
/* 20F0 */ 0x39, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x31, 0x36, 0x30, // 9.Windows 10 160
/* 2100 */ 0x37, 0x20, 0x2F, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, // 7 / Server 2016.
/* 2110 */ 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x2F, 0x20, 0x53, 0x65, // Windows 8.1 / Se
/* 2120 */ 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x52, 0x32, 0x00, 0x57, 0x69, 0x6E, // rver 2012 R2.Win
/* 2130 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x20, 0x2F, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, // dows 8 / Server
/* 2140 */ 0x32, 0x30, 0x31, 0x32, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x37, 0x20, 0x2F, // 2012.Windows 7 /
/* 2150 */ 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x52, 0x32, 0x20, // Server 2008 R2
/* 2160 */ 0x53, 0x50, 0x31, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x56, 0x69, 0x73, 0x74, // SP1.Windows Vist
/* 2170 */ 0x61, 0x20, 0x2F, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, // a / Server 2008
/* 2180 */ 0x53, 0x50, 0x32, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x00, 0x4F, 0x66, 0x66, 0x69, // SP2.Windows.Offi
/* 2190 */ 0x63, 0x65, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x32, 0x30, 0x31, // ce2010.Office201
/* 21A0 */ 0x33, 0x2B, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, // 3+.Windows Serve
/* 21B0 */ 0x72, 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, // r 2019.Windows 1
/* 21C0 */ 0x30, 0x20, 0x32, 0x30, 0x31, 0x39, 0x20, 0x28, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x29, 0x00, // 0 2019 (Volume).
/* 21D0 */ 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x55, 0x6E, 0x6B, 0x6E, 0x6F, // Windows 10 Unkno
/* 21E0 */ 0x77, 0x6E, 0x20, 0x28, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, // wn (Volume).Wind
/* 21F0 */ 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x47, 0x6F, 0x76, // ows 10 China Gov
/* 2200 */ 0x65, 0x72, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, // ernment.Windows
/* 2210 */ 0x31, 0x30, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x28, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x29, // 10 2016 (Volume)
/* 2220 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x28, 0x52, 0x65, 0x74, // .Windows 10 (Ret
/* 2230 */ 0x61, 0x69, 0x6C, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, // ail).Windows 10
/* 2240 */ 0x32, 0x30, 0x31, 0x35, 0x20, 0x28, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x29, 0x00, 0x57, 0x69, // 2015 (Volume).Wi
/* 2250 */ 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x37, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, // ndows 7.Windows
/* 2260 */ 0x38, 0x20, 0x28, 0x52, 0x65, 0x74, 0x61, 0x69, 0x6C, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, // 8 (Retail).Windo
/* 2270 */ 0x77, 0x73, 0x20, 0x38, 0x20, 0x28, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x29, 0x00, 0x57, 0x69, // ws 8 (Volume).Wi
/* 2280 */ 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x28, 0x52, 0x65, 0x74, 0x61, 0x69, // ndows 8.1 (Retai
/* 2290 */ 0x6C, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x28, // l).Windows 8.1 (
/* 22A0 */ 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, // Volume).Windows
/* 22B0 */ 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, // Preview.Windows
/* 22C0 */ 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x41, 0x20, 0x28, 0x57, // Server 2008 A (W
/* 22D0 */ 0x65, 0x62, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x48, 0x50, 0x43, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, // eb and HPC).Wind
/* 22E0 */ 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, // ows Server 2008
/* 22F0 */ 0x42, 0x20, 0x28, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x61, 0x6E, 0x64, 0x20, // B (Standard and
/* 2300 */ 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, // Enterprise).Wind
/* 2310 */ 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, // ows Server 2008
/* 2320 */ 0x43, 0x20, 0x28, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x29, 0x00, 0x57, // C (Datacenter).W
/* 2330 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, // indows Server 20
/* 2340 */ 0x30, 0x38, 0x20, 0x52, 0x32, 0x20, 0x41, 0x20, 0x28, 0x57, 0x65, 0x62, 0x20, 0x61, 0x6E, 0x64, // 08 R2 A (Web and
/* 2350 */ 0x20, 0x48, 0x50, 0x43, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, // HPC).Windows Se
/* 2360 */ 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x52, 0x32, 0x20, 0x42, 0x20, 0x28, // rver 2008 R2 B (
/* 2370 */ 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x45, 0x6E, 0x74, // Standard and Ent
/* 2380 */ 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, // erprise).Windows
/* 2390 */ 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x52, 0x32, 0x20, // Server 2008 R2
/* 23A0 */ 0x43, 0x20, 0x28, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x29, 0x00, 0x57, // C (Datacenter).W
/* 23B0 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, // indows Server 20
/* 23C0 */ 0x31, 0x32, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, // 12.Windows Serve
/* 23D0 */ 0x72, 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x52, 0x32, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, // r 2012 R2.Window
/* 23E0 */ 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x57, 0x69, // s Server 2016.Wi
/* 23F0 */ 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x50, 0x72, 0x65, // ndows Server Pre
/* 2400 */ 0x76, 0x69, 0x65, 0x77, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x56, 0x69, 0x73, // view.Windows Vis
/* 2410 */ 0x74, 0x61, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, // ta.Office 2010.O
/* 2420 */ 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, // ffice 2013.Offic
/* 2430 */ 0x65, 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, 0x6C, 0x65, // e 2013 (Pre-Rele
/* 2440 */ 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x32, 0x30, 0x31, 0x36, // ase).Office 2016
/* 2450 */ 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, 0x57, 0x69, 0x6E, // .Office 2019.Win
/* 2460 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x39, // dows Server 2019
/* 2470 */ 0x20, 0x41, 0x52, 0x4D, 0x36, 0x34, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, // ARM64.Windows S
/* 2480 */ 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x39, 0x20, 0x41, 0x7A, 0x75, 0x72, 0x65, // erver 2019 Azure
/* 2490 */ 0x20, 0x43, 0x6F, 0x72, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, // Core.Windows Se
/* 24A0 */ 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x39, 0x20, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, // rver 2019 Datace
/* 24B0 */ 0x6E, 0x74, 0x65, 0x72, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, // nter.Windows Ser
/* 24C0 */ 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x39, 0x20, 0x45, 0x73, 0x73, 0x65, 0x6E, 0x74, 0x69, // ver 2019 Essenti
/* 24D0 */ 0x61, 0x6C, 0x73, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, // als.Windows Serv
/* 24E0 */ 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x39, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, // er 2019 Standard
/* 24F0 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, // .Windows Server
/* 2500 */ 0x32, 0x30, 0x31, 0x39, 0x20, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, // 2019 Datacenter
/* 2510 */ 0x28, 0x53, 0x65, 0x6D, 0x69, 0x2D, 0x41, 0x6E, 0x6E, 0x75, 0x61, 0x6C, 0x20, 0x43, 0x68, 0x61, // (Semi-Annual Cha
/* 2520 */ 0x6E, 0x6E, 0x65, 0x6C, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, // nnel).Windows Se
/* 2530 */ 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x39, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, // rver 2019 Standa
/* 2540 */ 0x72, 0x64, 0x20, 0x28, 0x53, 0x65, 0x6D, 0x69, 0x2D, 0x41, 0x6E, 0x6E, 0x75, 0x61, 0x6C, 0x20, // rd (Semi-Annual
/* 2550 */ 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, // Channel).Windows
/* 2560 */ 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x4C, // 10 Enterprise L
/* 2570 */ 0x54, 0x53, 0x43, 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, // TSC 2019.Windows
/* 2580 */ 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x4C, // 10 Enterprise L
/* 2590 */ 0x54, 0x53, 0x43, 0x20, 0x32, 0x30, 0x31, 0x39, 0x20, 0x4E, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, // TSC 2019 N.Windo
/* 25A0 */ 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, // ws 10 Enterprise
/* 25B0 */ 0x20, 0x47, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, // G.Windows 10 En
/* 25C0 */ 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x47, 0x4E, 0x00, 0x57, 0x69, 0x6E, 0x64, // terprise GN.Wind
/* 25D0 */ 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, // ows 10 Enterpris
/* 25E0 */ 0x65, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x4C, 0x54, 0x53, 0x42, 0x00, 0x57, 0x69, 0x6E, 0x64, // e 2016 LTSB.Wind
/* 25F0 */ 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, // ows 10 Enterpris
/* 2600 */ 0x65, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x4C, 0x54, 0x53, 0x42, 0x20, 0x4E, 0x00, 0x57, 0x69, // e 2016 LTSB N.Wi
/* 2610 */ 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x48, 0x6F, 0x6D, 0x65, 0x00, 0x57, 0x69, // ndows 10 Home.Wi
/* 2620 */ 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x48, 0x6F, 0x6D, 0x65, 0x20, 0x43, 0x6F, // ndows 10 Home Co
/* 2630 */ 0x75, 0x6E, 0x74, 0x72, 0x79, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x00, 0x57, // untry Specific.W
/* 2640 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x48, 0x6F, 0x6D, 0x65, 0x20, 0x4E, // indows 10 Home N
/* 2650 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x48, 0x6F, 0x6D, 0x65, // .Windows 10 Home
/* 2660 */ 0x20, 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x4C, 0x61, 0x6E, 0x67, 0x75, 0x61, 0x67, 0x65, // Single Language
/* 2670 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x45, 0x64, 0x75, 0x63, // .Windows 10 Educ
/* 2680 */ 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, // ation.Windows 10
/* 2690 */ 0x20, 0x45, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x4E, 0x00, 0x57, 0x69, 0x6E, // Education N.Win
/* 26A0 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, // dows 10 Enterpri
/* 26B0 */ 0x73, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, // se.Windows 10 En
/* 26C0 */ 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x32, 0x30, 0x31, 0x35, 0x20, 0x4C, 0x54, // terprise 2015 LT
/* 26D0 */ 0x53, 0x42, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, // SB.Windows 10 En
/* 26E0 */ 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x32, 0x30, 0x31, 0x35, 0x20, 0x4C, 0x54, // terprise 2015 LT
/* 26F0 */ 0x53, 0x42, 0x20, 0x4E, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, // SB N.Windows 10
/* 2700 */ 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x4E, 0x00, 0x57, 0x69, 0x6E, // Enterprise N.Win
/* 2710 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, // dows 10 Professi
/* 2720 */ 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x57, 0x6F, 0x72, 0x6B, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, // onal Workstation
/* 2730 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x50, 0x72, 0x6F, 0x66, // .Windows 10 Prof
/* 2740 */ 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x57, 0x6F, 0x72, 0x6B, 0x73, 0x74, 0x61, // essional Worksta
/* 2750 */ 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x4E, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, // tion N.Windows 1
/* 2760 */ 0x30, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x00, 0x57, // 0 Professional.W
/* 2770 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, // indows 10 Profes
/* 2780 */ 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x45, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, // sional Education
/* 2790 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x50, 0x72, 0x6F, 0x66, // .Windows 10 Prof
/* 27A0 */ 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x45, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, // essional Educati
/* 27B0 */ 0x6F, 0x6E, 0x20, 0x4E, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, // on N.Windows 10
/* 27C0 */ 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x4E, 0x00, 0x57, // Professional N.W
/* 27D0 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, // indows 10 Profes
/* 27E0 */ 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x00, 0x57, // sional Preview.W
/* 27F0 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, // indows 10 Enterp
/* 2800 */ 0x72, 0x69, 0x73, 0x65, 0x20, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x00, 0x57, 0x69, 0x6E, // rise Preview.Win
/* 2810 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, // dows 10 Enterpri
/* 2820 */ 0x73, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6C, 0x20, 0x44, // se for Virtual D
/* 2830 */ 0x65, 0x73, 0x6B, 0x74, 0x6F, 0x70, 0x73, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, // esktops.Windows
/* 2840 */ 0x31, 0x30, 0x20, 0x52, 0x65, 0x6D, 0x6F, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, // 10 Remote Server
/* 2850 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x53, 0x20, 0x28, 0x4C, // .Windows 10 S (L
/* 2860 */ 0x65, 0x61, 0x6E, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x37, 0x20, 0x45, // ean).Windows 7 E
/* 2870 */ 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, // nterprise.Window
/* 2880 */ 0x73, 0x20, 0x37, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x45, // s 7 Enterprise E
/* 2890 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x37, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, // .Windows 7 Enter
/* 28A0 */ 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x4E, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, // prise N.Windows
/* 28B0 */ 0x37, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x00, 0x57, // 7 Professional.W
/* 28C0 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x37, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, // indows 7 Profess
/* 28D0 */ 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x45, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, // ional E.Windows
/* 28E0 */ 0x37, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x4E, // 7 Professional N
/* 28F0 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x37, 0x20, 0x45, 0x6D, 0x62, 0x65, 0x64, // .Windows 7 Embed
/* 2900 */ 0x64, 0x65, 0x64, 0x20, 0x50, 0x4F, 0x53, 0x52, 0x65, 0x61, 0x64, 0x79, 0x00, 0x57, 0x69, 0x6E, // ded POSReady.Win
/* 2910 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x37, 0x20, 0x45, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, // dows 7 Embedded
/* 2920 */ 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, // Standard.Windows
/* 2930 */ 0x20, 0x37, 0x20, 0x54, 0x68, 0x69, 0x6E, 0x50, 0x43, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, // 7 ThinPC.Window
/* 2940 */ 0x73, 0x20, 0x38, 0x20, 0x43, 0x6F, 0x72, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, // s 8 Core.Windows
/* 2950 */ 0x20, 0x38, 0x20, 0x43, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x72, 0x79, 0x20, // 8 Core Country
/* 2960 */ 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, // Specific.Windows
/* 2970 */ 0x20, 0x38, 0x20, 0x43, 0x6F, 0x72, 0x65, 0x20, 0x4E, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, // 8 Core N.Window
/* 2980 */ 0x73, 0x20, 0x38, 0x20, 0x43, 0x6F, 0x72, 0x65, 0x20, 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, // s 8 Core Single
/* 2990 */ 0x4C, 0x61, 0x6E, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, // Language.Windows
/* 29A0 */ 0x20, 0x38, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, // 8 Professional
/* 29B0 */ 0x57, 0x4D, 0x43, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x20, 0x45, 0x6D, // WMC.Windows 8 Em
/* 29C0 */ 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x49, 0x6E, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79, 0x20, // bedded Industry
/* 29D0 */ 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x00, 0x57, 0x69, 0x6E, // Professional.Win
/* 29E0 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x20, 0x45, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, // dows 8 Embedded
/* 29F0 */ 0x49, 0x6E, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, // Industry Enterpr
/* 2A00 */ 0x69, 0x73, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x20, 0x45, 0x6E, // ise.Windows 8 En
/* 2A10 */ 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, // terprise.Windows
/* 2A20 */ 0x20, 0x38, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x4E, 0x00, // 8 Enterprise N.
/* 2A30 */ 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, // Windows 8 Profes
/* 2A40 */ 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, // sional.Windows 8
/* 2A50 */ 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x4E, 0x00, // Professional N.
/* 2A60 */ 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x43, 0x6F, 0x72, 0x65, // Windows 8.1 Core
/* 2A70 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x43, 0x6F, 0x72, // .Windows 8.1 Cor
/* 2A80 */ 0x65, 0x20, 0x41, 0x52, 0x4D, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, // e ARM.Windows 8.
/* 2A90 */ 0x31, 0x20, 0x43, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x72, 0x79, 0x20, 0x53, // 1 Core Country S
/* 2AA0 */ 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, // pecific.Windows
/* 2AB0 */ 0x38, 0x2E, 0x31, 0x20, 0x43, 0x6F, 0x72, 0x65, 0x20, 0x4E, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, // 8.1 Core N.Windo
/* 2AC0 */ 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x43, 0x6F, 0x72, 0x65, 0x20, 0x53, 0x69, 0x6E, 0x67, // ws 8.1 Core Sing
/* 2AD0 */ 0x6C, 0x65, 0x20, 0x4C, 0x61, 0x6E, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, // le Language.Wind
/* 2AE0 */ 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, // ows 8.1 Professi
/* 2AF0 */ 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x74, 0x75, 0x64, 0x65, 0x6E, 0x74, 0x00, 0x57, 0x69, 0x6E, // onal Student.Win
/* 2B00 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, // dows 8.1 Profess
/* 2B10 */ 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x74, 0x75, 0x64, 0x65, 0x6E, 0x74, 0x20, 0x4E, 0x00, // ional Student N.
/* 2B20 */ 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x50, 0x72, 0x6F, 0x66, // Windows 8.1 Prof
/* 2B30 */ 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x57, 0x4D, 0x43, 0x00, 0x57, 0x69, 0x6E, // essional WMC.Win
/* 2B40 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x43, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x6F, // dows 8.1 Core Co
/* 2B50 */ 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, // nnected.Windows
/* 2B60 */ 0x38, 0x2E, 0x31, 0x20, 0x43, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, // 8.1 Core Connect
/* 2B70 */ 0x65, 0x64, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x72, 0x79, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, // ed Country Speci
/* 2B80 */ 0x66, 0x69, 0x63, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, // fic.Windows 8.1
/* 2B90 */ 0x43, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x4E, // Core Connected N
/* 2BA0 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x43, 0x6F, 0x72, // .Windows 8.1 Cor
/* 2BB0 */ 0x65, 0x20, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x53, 0x69, 0x6E, 0x67, // e Connected Sing
/* 2BC0 */ 0x6C, 0x65, 0x20, 0x4C, 0x61, 0x6E, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, // le Language.Wind
/* 2BD0 */ 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, // ows 8.1 Enterpri
/* 2BE0 */ 0x73, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x45, // se.Windows 8.1 E
/* 2BF0 */ 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x4E, 0x00, 0x57, 0x69, 0x6E, 0x64, // nterprise N.Wind
/* 2C00 */ 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, // ows 8.1 Professi
/* 2C10 */ 0x6F, 0x6E, 0x61, 0x6C, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, // onal.Windows 8.1
/* 2C20 */ 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x4E, 0x00, // Professional N.
/* 2C30 */ 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x45, 0x6D, 0x62, 0x65, // Windows 8.1 Embe
/* 2C40 */ 0x64, 0x64, 0x65, 0x64, 0x20, 0x49, 0x6E, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79, 0x20, 0x50, 0x72, // dded Industry Pr
/* 2C50 */ 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, // ofessional.Windo
/* 2C60 */ 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, 0x45, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, // ws 8.1 Embedded
/* 2C70 */ 0x49, 0x6E, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79, 0x20, 0x41, 0x75, 0x74, 0x6F, 0x6D, 0x6F, 0x74, // Industry Automot
/* 2C80 */ 0x69, 0x76, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x31, 0x20, // ive.Windows 8.1
/* 2C90 */ 0x45, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x49, 0x6E, 0x64, 0x75, 0x73, 0x74, 0x72, // Embedded Industr
/* 2CA0 */ 0x79, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x00, 0x57, 0x69, 0x6E, // y Enterprise.Win
/* 2CB0 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, // dows 10 Enterpri
/* 2CC0 */ 0x73, 0x65, 0x20, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, // se Preview.Windo
/* 2CD0 */ 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, // ws 10 Profession
/* 2CE0 */ 0x61, 0x6C, 0x20, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, // al Preview.Windo
/* 2CF0 */ 0x77, 0x73, 0x20, 0x31, 0x30, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, // ws 10 Profession
/* 2D00 */ 0x61, 0x6C, 0x20, 0x57, 0x4D, 0x43, 0x20, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x00, 0x57, // al WMC Preview.W
/* 2D10 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x78, 0x20, 0x50, 0x72, 0x65, 0x76, 0x69, // indows 8.x Previ
/* 2D20 */ 0x65, 0x77, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x38, 0x2E, 0x78, 0x20, 0x50, // ew.Windows 8.x P
/* 2D30 */ 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x20, 0x41, 0x52, 0x4D, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, // review ARM.Windo
/* 2D40 */ 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x57, // ws Server 2008 W
/* 2D50 */ 0x65, 0x62, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, // eb.Windows Serve
/* 2D60 */ 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x43, 0x6F, 0x6D, 0x70, 0x75, 0x74, 0x65, 0x20, 0x43, // r 2008 Compute C
/* 2D70 */ 0x6C, 0x75, 0x73, 0x74, 0x65, 0x72, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, // luster.Windows S
/* 2D80 */ 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, // erver 2008 Stand
/* 2D90 */ 0x61, 0x72, 0x64, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, // ard.Windows Serv
/* 2DA0 */ 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, // er 2008 Standard
/* 2DB0 */ 0x20, 0x77, 0x69, 0x74, 0x68, 0x6F, 0x75, 0x74, 0x20, 0x48, 0x79, 0x70, 0x65, 0x72, 0x2D, 0x56, // without Hyper-V
/* 2DC0 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, // .Windows Server
/* 2DD0 */ 0x32, 0x30, 0x30, 0x38, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x00, // 2008 Enterprise.
/* 2DE0 */ 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, // Windows Server 2
/* 2DF0 */ 0x30, 0x30, 0x38, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x77, // 008 Enterprise w
/* 2E00 */ 0x69, 0x74, 0x68, 0x6F, 0x75, 0x74, 0x20, 0x48, 0x79, 0x70, 0x65, 0x72, 0x2D, 0x56, 0x00, 0x57, // ithout Hyper-V.W
/* 2E10 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, // indows Server 20
/* 2E20 */ 0x30, 0x38, 0x20, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x00, 0x57, 0x69, // 08 Datacenter.Wi
/* 2E30 */ 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, // ndows Server 200
/* 2E40 */ 0x38, 0x20, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, // 8 Datacenter wit
/* 2E50 */ 0x68, 0x6F, 0x75, 0x74, 0x20, 0x48, 0x79, 0x70, 0x65, 0x72, 0x2D, 0x56, 0x00, 0x57, 0x69, 0x6E, // hout Hyper-V.Win
/* 2E60 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, // dows Server 2008
/* 2E70 */ 0x20, 0x66, 0x6F, 0x72, 0x20, 0x49, 0x74, 0x61, 0x6E, 0x69, 0x75, 0x6D, 0x00, 0x57, 0x69, 0x6E, // for Itanium.Win
/* 2E80 */ 0x64, 0x6F, 0x77, 0x73, 0x20, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x20, // dows MultiPoint
/* 2E90 */ 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x57, 0x69, 0x6E, 0x64, // Server 2010.Wind
/* 2EA0 */ 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, // ows Server 2008
/* 2EB0 */ 0x52, 0x32, 0x20, 0x57, 0x65, 0x62, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, // R2 Web.Windows S
/* 2EC0 */ 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x52, 0x32, 0x20, 0x48, 0x50, // erver 2008 R2 HP
/* 2ED0 */ 0x43, 0x20, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, // C Edition.Window
/* 2EE0 */ 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x52, 0x32, // s Server 2008 R2
/* 2EF0 */ 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, // Standard.Window
/* 2F00 */ 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x52, 0x32, // s Server 2008 R2
/* 2F10 */ 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, // Enterprise.Wind
/* 2F20 */ 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, // ows Server 2008
/* 2F30 */ 0x52, 0x32, 0x20, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x00, 0x57, 0x69, // R2 Datacenter.Wi
/* 2F40 */ 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x30, // ndows Server 200
/* 2F50 */ 0x38, 0x20, 0x52, 0x32, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x49, 0x74, 0x61, 0x6E, 0x69, 0x75, 0x6D, // 8 R2 for Itanium
/* 2F60 */ 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, // Enterprise.Wind
/* 2F70 */ 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, // ows Server 2012
/* 2F80 */ 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, // Datacenter.Windo
/* 2F90 */ 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x4D, // ws Server 2012 M
/* 2FA0 */ 0x75, 0x6C, 0x74, 0x69, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, // ultiPoint Premiu
/* 2FB0 */ 0x6D, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, // m.Windows Server
/* 2FC0 */ 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x50, 0x6F, 0x69, 0x6E, 0x74, // 2012 MultiPoint
/* 2FD0 */ 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, // Standard.Window
/* 2FE0 */ 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x53, 0x74, // s Server 2012 St
/* 2FF0 */ 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, // andard.Windows S
/* 3000 */ 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x52, 0x32, 0x20, 0x43, 0x6C, // erver 2012 R2 Cl
/* 3010 */ 0x6F, 0x75, 0x64, 0x20, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x00, 0x57, 0x69, 0x6E, 0x64, // oud Storage.Wind
/* 3020 */ 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, // ows Server 2012
/* 3030 */ 0x52, 0x32, 0x20, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x00, 0x57, 0x69, // R2 Datacenter.Wi
/* 3040 */ 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, // ndows Server 201
/* 3050 */ 0x32, 0x20, 0x52, 0x32, 0x20, 0x45, 0x73, 0x73, 0x65, 0x6E, 0x74, 0x69, 0x61, 0x6C, 0x73, 0x00, // 2 R2 Essentials.
/* 3060 */ 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, // Windows Server 2
/* 3070 */ 0x30, 0x31, 0x32, 0x20, 0x52, 0x32, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x00, // 012 R2 Standard.
/* 3080 */ 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, // Windows Server 2
/* 3090 */ 0x30, 0x31, 0x36, 0x20, 0x41, 0x7A, 0x75, 0x72, 0x65, 0x20, 0x43, 0x6F, 0x72, 0x65, 0x00, 0x57, // 016 Azure Core.W
/* 30A0 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, // indows Server 20
/* 30B0 */ 0x31, 0x36, 0x20, 0x43, 0x6C, 0x6F, 0x75, 0x64, 0x20, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, // 16 Cloud Storage
/* 30C0 */ 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, // .Windows Server
/* 30D0 */ 0x32, 0x30, 0x31, 0x36, 0x20, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x00, // 2016 Datacenter.
/* 30E0 */ 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, // Windows Server 2
/* 30F0 */ 0x30, 0x31, 0x36, 0x20, 0x45, 0x73, 0x73, 0x65, 0x6E, 0x74, 0x69, 0x61, 0x6C, 0x73, 0x00, 0x57, // 016 Essentials.W
/* 3100 */ 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, // indows Server 20
/* 3110 */ 0x31, 0x36, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x00, 0x57, 0x69, 0x6E, 0x64, // 16 Standard.Wind
/* 3120 */ 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, // ows Server 2016
/* 3130 */ 0x41, 0x52, 0x4D, 0x36, 0x34, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, // ARM64.Windows Se
/* 3140 */ 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, // rver 2016 Datace
/* 3150 */ 0x6E, 0x74, 0x65, 0x72, 0x20, 0x28, 0x53, 0x65, 0x6D, 0x69, 0x2D, 0x41, 0x6E, 0x6E, 0x75, 0x61, // nter (Semi-Annua
/* 3160 */ 0x6C, 0x20, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x29, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, // l Channel).Windo
/* 3170 */ 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x53, // ws Server 2016 S
/* 3180 */ 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x28, 0x53, 0x65, 0x6D, 0x69, 0x2D, 0x41, 0x6E, // tandard (Semi-An
/* 3190 */ 0x6E, 0x75, 0x61, 0x6C, 0x20, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x29, 0x00, 0x57, 0x69, // nual Channel).Wi
/* 31A0 */ 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, // ndows Server 201
/* 31B0 */ 0x36, 0x20, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x50, 0x72, 0x65, // 6 Datacenter Pre
/* 31C0 */ 0x76, 0x69, 0x65, 0x77, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x56, 0x69, 0x73, // view.Windows Vis
/* 31D0 */ 0x74, 0x61, 0x20, 0x42, 0x75, 0x73, 0x69, 0x6E, 0x65, 0x73, 0x73, 0x00, 0x57, 0x69, 0x6E, 0x64, // ta Business.Wind
/* 31E0 */ 0x6F, 0x77, 0x73, 0x20, 0x56, 0x69, 0x73, 0x74, 0x61, 0x20, 0x42, 0x75, 0x73, 0x69, 0x6E, 0x65, // ows Vista Busine
/* 31F0 */ 0x73, 0x73, 0x20, 0x4E, 0x00, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x56, 0x69, 0x73, // ss N.Windows Vis
/* 3200 */ 0x74, 0x61, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x00, 0x57, 0x69, // ta Enterprise.Wi
/* 3210 */ 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x56, 0x69, 0x73, 0x74, 0x61, 0x20, 0x45, 0x6E, 0x74, 0x65, // ndows Vista Ente
/* 3220 */ 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x4E, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, // rprise N.Office
/* 3230 */ 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, // Access 2010.Offi
/* 3240 */ 0x63, 0x65, 0x20, 0x45, 0x78, 0x63, 0x65, 0x6C, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, // ce Excel 2010.Of
/* 3250 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x47, 0x72, 0x6F, 0x6F, 0x76, 0x65, 0x20, 0x32, 0x30, 0x31, 0x30, // fice Groove 2010
/* 3260 */ 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x49, 0x6E, 0x66, 0x6F, 0x50, 0x61, 0x74, 0x68, // .Office InfoPath
/* 3270 */ 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x4D, 0x6F, 0x6E, // 2010.Office Mon
/* 3280 */ 0x64, 0x6F, 0x20, 0x31, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, // do 1 2010.Office
/* 3290 */ 0x20, 0x4D, 0x6F, 0x6E, 0x64, 0x6F, 0x20, 0x32, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, // Mondo 2 2010.Of
/* 32A0 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x4F, 0x6E, 0x65, 0x4E, 0x6F, 0x74, 0x65, 0x20, 0x32, 0x30, 0x31, // fice OneNote 201
/* 32B0 */ 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x4F, 0x75, 0x74, 0x4C, 0x6F, 0x6F, 0x6B, // 0.Office OutLook
/* 32C0 */ 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x6F, 0x77, // 2010.Office Pow
/* 32D0 */ 0x65, 0x72, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, // erPoint 2010.Off
/* 32E0 */ 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, // ice Professional
/* 32F0 */ 0x20, 0x50, 0x6C, 0x75, 0x73, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, // Plus 2010.Offic
/* 3300 */ 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x32, 0x30, // e Project Pro 20
/* 3310 */ 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, // 10.Office Projec
/* 3320 */ 0x74, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, // t Standard 2010.
/* 3330 */ 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x73, 0x68, 0x65, 0x72, // Office Publisher
/* 3340 */ 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x53, 0x6D, 0x61, // 2010.Office Sma
/* 3350 */ 0x6C, 0x6C, 0x20, 0x42, 0x75, 0x73, 0x69, 0x6E, 0x65, 0x73, 0x73, 0x20, 0x42, 0x61, 0x73, 0x69, // ll Business Basi
/* 3360 */ 0x63, 0x73, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x53, // cs 2010.Office S
/* 3370 */ 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, // tandard 2010.Off
/* 3380 */ 0x69, 0x63, 0x65, 0x20, 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, // ice Visio Premiu
/* 3390 */ 0x6D, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x56, 0x69, // m 2010.Office Vi
/* 33A0 */ 0x73, 0x69, 0x6F, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, // sio Pro 2010.Off
/* 33B0 */ 0x69, 0x63, 0x65, 0x20, 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, // ice Visio Standa
/* 33C0 */ 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x57, // rd 2010.Office W
/* 33D0 */ 0x6F, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x30, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, // ord 2010.Office
/* 33E0 */ 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, // Access 2013.Offi
/* 33F0 */ 0x63, 0x65, 0x20, 0x45, 0x78, 0x63, 0x65, 0x6C, 0x20, 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, // ce Excel 2013.Of
/* 3400 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x49, 0x6E, 0x66, 0x6F, 0x50, 0x61, 0x74, 0x68, 0x20, 0x32, 0x30, // fice InfoPath 20
/* 3410 */ 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x4C, 0x79, 0x6E, 0x63, 0x20, 0x32, // 13.Office Lync 2
/* 3420 */ 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x4D, 0x6F, 0x6E, 0x64, 0x6F, // 013.Office Mondo
/* 3430 */ 0x20, 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x4F, 0x6E, 0x65, // 2013.Office One
/* 3440 */ 0x4E, 0x6F, 0x74, 0x65, 0x20, 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, // Note 2013.Office
/* 3450 */ 0x20, 0x4F, 0x75, 0x74, 0x4C, 0x6F, 0x6F, 0x6B, 0x20, 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, // OutLook 2013.Of
/* 3460 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x6F, 0x77, 0x65, 0x72, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x20, // fice PowerPoint
/* 3470 */ 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x66, // 2013.Office Prof
/* 3480 */ 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x50, 0x6C, 0x75, 0x73, 0x20, 0x32, 0x30, // essional Plus 20
/* 3490 */ 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, // 13.Office Projec
/* 34A0 */ 0x74, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, // t Pro 2013.Offic
/* 34B0 */ 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, // e Project Standa
/* 34C0 */ 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, // rd 2013.Office P
/* 34D0 */ 0x75, 0x62, 0x6C, 0x69, 0x73, 0x68, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, // ublisher 2013.Of
/* 34E0 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x32, 0x30, // fice Standard 20
/* 34F0 */ 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, // 13.Office Visio
/* 3500 */ 0x50, 0x72, 0x6F, 0x20, 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, // Pro 2013.Office
/* 3510 */ 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x32, // Visio Standard 2
/* 3520 */ 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x20, // 013.Office Word
/* 3530 */ 0x32, 0x30, 0x31, 0x33, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x41, 0x63, 0x63, 0x65, // 2013.Office Acce
/* 3540 */ 0x73, 0x73, 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, 0x6C, // ss 2013 (Pre-Rel
/* 3550 */ 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x45, 0x78, 0x63, // ease).Office Exc
/* 3560 */ 0x65, 0x6C, 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, 0x6C, // el 2013 (Pre-Rel
/* 3570 */ 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x47, 0x72, 0x6F, // ease).Office Gro
/* 3580 */ 0x6F, 0x76, 0x65, 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, // ove 2013 (Pre-Re
/* 3590 */ 0x6C, 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x49, 0x6E, // lease).Office In
/* 35A0 */ 0x66, 0x6F, 0x50, 0x61, 0x74, 0x68, 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, // foPath 2013 (Pre
/* 35B0 */ 0x2D, 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, // -Release).Office
/* 35C0 */ 0x20, 0x4C, 0x79, 0x6E, 0x63, 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, // Lync 2013 (Pre-
/* 35D0 */ 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, // Release).Office
/* 35E0 */ 0x4D, 0x6F, 0x6E, 0x64, 0x6F, 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, // Mondo 2013 (Pre-
/* 35F0 */ 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, // Release).Office
/* 3600 */ 0x4F, 0x6E, 0x65, 0x4E, 0x6F, 0x74, 0x65, 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, // OneNote 2013 (Pr
/* 3610 */ 0x65, 0x2D, 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, // e-Release).Offic
/* 3620 */ 0x65, 0x20, 0x4F, 0x75, 0x74, 0x6C, 0x6F, 0x6F, 0x6B, 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, // e Outlook 2013 (
/* 3630 */ 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, // Pre-Release).Off
/* 3640 */ 0x69, 0x63, 0x65, 0x20, 0x50, 0x6F, 0x77, 0x65, 0x72, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x32, // ice PowerPoint 2
/* 3650 */ 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, // 013 (Pre-Release
/* 3660 */ 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, // ).Office Profess
/* 3670 */ 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x50, 0x6C, 0x75, 0x73, 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, // ional Plus 2013
/* 3680 */ 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, // (Pre-Release).Of
/* 3690 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x50, 0x72, 0x6F, // fice Project Pro
/* 36A0 */ 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, 0x6C, 0x65, 0x61, // 2013 (Pre-Relea
/* 36B0 */ 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, // se).Office Proje
/* 36C0 */ 0x63, 0x74, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x33, // ct Standard 2013
/* 36D0 */ 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, // (Pre-Release).O
/* 36E0 */ 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x73, 0x68, 0x65, 0x72, 0x20, // ffice Publisher
/* 36F0 */ 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, // 2013 (Pre-Releas
/* 3700 */ 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, // e).Office Visio
/* 3710 */ 0x50, 0x72, 0x6F, 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, // Pro 2013 (Pre-Re
/* 3720 */ 0x6C, 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x56, 0x69, // lease).Office Vi
/* 3730 */ 0x73, 0x69, 0x6F, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, // sio Standard 201
/* 3740 */ 0x33, 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, // 3 (Pre-Release).
/* 3750 */ 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x33, // Office Word 2013
/* 3760 */ 0x20, 0x28, 0x50, 0x72, 0x65, 0x2D, 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x29, 0x00, 0x4F, // (Pre-Release).O
/* 3770 */ 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x32, 0x30, 0x31, // ffice Access 201
/* 3780 */ 0x36, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x45, 0x78, 0x63, 0x65, 0x6C, 0x20, 0x32, // 6.Office Excel 2
/* 3790 */ 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x4D, 0x6F, 0x6E, 0x64, 0x6F, // 016.Office Mondo
/* 37A0 */ 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x4D, 0x6F, 0x6E, // 2016.Office Mon
/* 37B0 */ 0x64, 0x6F, 0x20, 0x52, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, // do R 2016.Office
/* 37C0 */ 0x20, 0x4F, 0x6E, 0x65, 0x4E, 0x6F, 0x74, 0x65, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, // OneNote 2016.Of
/* 37D0 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x4F, 0x75, 0x74, 0x6C, 0x6F, 0x6F, 0x6B, 0x20, 0x32, 0x30, 0x31, // fice Outlook 201
/* 37E0 */ 0x36, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x6F, 0x77, 0x65, 0x72, 0x70, 0x6F, // 6.Office Powerpo
/* 37F0 */ 0x69, 0x6E, 0x74, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, // int 2016.Office
/* 3800 */ 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x50, 0x6C, 0x75, // Professional Plu
/* 3810 */ 0x73, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, // s 2016.Office Pr
/* 3820 */ 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, // oject Pro 2016.O
/* 3830 */ 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x50, 0x72, // ffice Project Pr
/* 3840 */ 0x6F, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x43, 0x32, 0x52, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, // o 2016 C2R.Offic
/* 3850 */ 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, // e Project Standa
/* 3860 */ 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, // rd 2016.Office P
/* 3870 */ 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, // roject Standard
/* 3880 */ 0x32, 0x30, 0x31, 0x36, 0x20, 0x43, 0x32, 0x52, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, // 2016 C2R.Office
/* 3890 */ 0x50, 0x75, 0x62, 0x6C, 0x69, 0x73, 0x68, 0x65, 0x72, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, // Publisher 2016.O
/* 38A0 */ 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x53, 0x6B, 0x79, 0x70, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, // ffice Skype for
/* 38B0 */ 0x42, 0x75, 0x73, 0x69, 0x6E, 0x65, 0x73, 0x73, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, // Business 2016.Of
/* 38C0 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x32, 0x30, // fice Standard 20
/* 38D0 */ 0x31, 0x36, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, // 16.Office Visio
/* 38E0 */ 0x50, 0x72, 0x6F, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, // Pro 2016.Office
/* 38F0 */ 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x43, // Visio Pro 2016 C
/* 3900 */ 0x32, 0x52, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, // 2R.Office Visio
/* 3910 */ 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, // Standard 2016.Of
/* 3920 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, // fice Visio Stand
/* 3930 */ 0x61, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x43, 0x32, 0x52, 0x00, 0x4F, 0x66, 0x66, // ard 2016 C2R.Off
/* 3940 */ 0x69, 0x63, 0x65, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x36, 0x00, 0x4F, 0x66, // ice Word 2016.Of
/* 3950 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, // fice Professiona
/* 3960 */ 0x6C, 0x20, 0x50, 0x6C, 0x75, 0x73, 0x20, 0x32, 0x30, 0x31, 0x39, 0x20, 0x43, 0x32, 0x52, 0x20, // l Plus 2019 C2R
/* 3970 */ 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, // Preview.Office P
/* 3980 */ 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x32, 0x30, 0x31, 0x39, 0x20, // roject Pro 2019
/* 3990 */ 0x43, 0x32, 0x52, 0x20, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x00, 0x4F, 0x66, 0x66, 0x69, // C2R Preview.Offi
/* 39A0 */ 0x63, 0x65, 0x20, 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x32, 0x30, 0x31, // ce Visio Pro 201
/* 39B0 */ 0x39, 0x20, 0x43, 0x32, 0x52, 0x20, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x00, 0x4F, 0x66, // 9 C2R Preview.Of
/* 39C0 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x32, 0x30, 0x31, 0x39, // fice Access 2019
/* 39D0 */ 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x45, 0x78, 0x63, 0x65, 0x6C, 0x20, 0x32, 0x30, // .Office Excel 20
/* 39E0 */ 0x31, 0x39, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x4F, 0x75, 0x74, 0x6C, 0x6F, 0x6F, // 19.Office Outloo
/* 39F0 */ 0x6B, 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x6F, // k 2019.Office Po
/* 3A00 */ 0x77, 0x65, 0x72, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, 0x4F, 0x66, // werpoint 2019.Of
/* 3A10 */ 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x66, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x61, // fice Professiona
/* 3A20 */ 0x6C, 0x20, 0x50, 0x6C, 0x75, 0x73, 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, 0x4F, 0x66, 0x66, 0x69, // l Plus 2019.Offi
/* 3A30 */ 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x32, // ce Project Pro 2
/* 3A40 */ 0x30, 0x31, 0x39, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, // 019.Office Proje
/* 3A50 */ 0x63, 0x74, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x39, // ct Standard 2019
/* 3A60 */ 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x73, 0x68, 0x65, // .Office Publishe
/* 3A70 */ 0x72, 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x53, 0x6B, // r 2019.Office Sk
/* 3A80 */ 0x79, 0x70, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x42, 0x75, 0x73, 0x69, 0x6E, 0x65, 0x73, 0x73, // ype for Business
/* 3A90 */ 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x53, 0x74, 0x61, // 2019.Office Sta
/* 3AA0 */ 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, // ndard 2019.Offic
/* 3AB0 */ 0x65, 0x20, 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x32, 0x30, 0x31, 0x39, // e Visio Pro 2019
/* 3AC0 */ 0x00, 0x4F, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x56, 0x69, 0x73, 0x69, 0x6F, 0x20, 0x53, 0x74, // .Office Visio St
/* 3AD0 */ 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, 0x4F, 0x66, 0x66, 0x69, // andard 2019.Offi
/* 3AE0 */ 0x63, 0x65, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x20, 0x32, 0x30, 0x31, 0x39, 0x00, // ce Word 2019.
};
__pure size_t getDefaultKmsDataSize()
{
return sizeof(DefaultKmsData);
}
#endif // NO_INTERNAL_DATA

1167
src/kmsdata.c Normal file

File diff suppressed because it is too large Load Diff

19
src/kmsdata.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef KMSDATA_SERVER_H
#define KMSDATA_SERVER_H
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifndef NO_INTERNAL_DATA
#include "types.h"
extern uint8_t DefaultKmsData[];
__pure size_t getDefaultKmsDataSize();
#endif // NO_INTERNAL_DATA
#endif // KMSDATA_SERVER_H

42
src/libkms-test.c Normal file
View File

@ -0,0 +1,42 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libkms.h"
#include "kms.h"
#include "endian.h"
static const char ePID[] = { 'T', 0, 'E', 0, 'S', 0, 'T', 0, 0, 0 };
__stdcall BOOL KmsCallBack(const REQUEST *const baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr)
{
printf("libvlmcs-test.c: Entered KmsCallBack for client %s\n", ipstr);
memcpy(&baseResponse->CMID, &baseRequest->CMID, sizeof(GUID));
memcpy(&baseResponse->ClientTime, &baseRequest->ClientTime, sizeof(FILETIME));
memcpy(&baseResponse->KmsPID, ePID, sizeof(ePID));
baseResponse->Version = baseRequest->Version;
baseResponse->Count = LE32(LE32(baseRequest->N_Policy) << 1);
baseResponse->PIDSize = sizeof(ePID);
baseResponse->VLActivationInterval = LE32(120);
baseResponse->VLRenewalInterval = LE32(10080);
if (hwId && baseResponse->MajorVer > 5) memcpy(hwId, "\x01\x02\x03\x04\x05\x06\x07\x08", 8);
return TRUE;
}
int main(int argc, char** argv)
{
int version = GetLibKmsVersion();
if (version < 0x30001)
{
fprintf(stderr, "KMS library version %u.%u or greater required\n", (unsigned int)(version >> 16), (unsigned int)(version & 0xffff));
}
printf("%s: Program start\n", GetEmulatorVersion());
StartKmsServer(1688, KmsCallBack);
return 0;
}

208
src/libkms.c Normal file
View File

@ -0,0 +1,208 @@
/*
* libkms.c
*/
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifdef EXTERNAL
#undef EXTERNAL
#endif
#define EXTERNAL dllexport
#define DLLVERSION 0x40000
#include "libkms.h"
#include "shared_globals.h"
#include "network.h"
#include "helpers.h"
#ifndef _WIN32
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <netinet/in.h>
#endif // WIN32
static int_fast8_t IsServerStarted = FALSE;
#ifdef _WIN32
#ifndef USE_MSRPC
static int_fast8_t SocketsInitialized = FALSE;
WSADATA wsadata;
static int initializeWinSockets()
{
if (SocketsInitialized) return 0;
SocketsInitialized = TRUE;
return WSAStartup(0x0202, &wsadata);
}
#endif // USE_MSRPC
#endif // _WIN32
EXTERNC __declspec(EXTERNAL) char* __cdecl GetErrorMessage()
{
return ErrorMessage;
}
EXTERNC __declspec(EXTERNAL)SOCKET __cdecl ConnectToServer(const char* host, const char* port, const int addressFamily)
{
SOCKET sock;
*ErrorMessage = 0;
# if defined(_WIN32) && !defined(USE_MSRPC)
initializeWinSockets();
# endif // defined(_WIN32) && !defined(USE_MSRPC)
size_t adrlen = strlen(host) + 16;
char* RemoteAddr = (char*)alloca(adrlen);
vlmcsd_snprintf(RemoteAddr, adrlen, "[%s]:%s", host, port);
sock = connectToAddress(RemoteAddr, addressFamily, FALSE);
if (sock == INVALID_RPCCTX)
{
printerrorf("Fatal: Could not connect to %s\n", RemoteAddr);
return sock;
}
return sock;
}
EXTERNC __declspec(EXTERNAL)RpcStatus __cdecl BindRpc(const SOCKET sock, const int_fast8_t useMultiplexedRpc, const int_fast8_t useRpcNDR64, const int_fast8_t useRpcBTFN, PRpcDiag_t rpcDiag)
{
*ErrorMessage = 0;
UseMultiplexedRpc = useMultiplexedRpc;
UseClientRpcNDR64 = useRpcNDR64;
UseClientRpcBTFN = useRpcBTFN;
return rpcBindClient(sock, FALSE, rpcDiag);
}
EXTERNC __declspec(EXTERNAL) void __cdecl CloseConnection(const SOCKET sock)
{
socketclose(sock);
}
EXTERNC __declspec(EXTERNAL)DWORD __cdecl SendKMSRequest(const SOCKET sock, RESPONSE* baseResponse, REQUEST* baseRequest, RESPONSE_RESULT* result, BYTE *hwid)
{
*ErrorMessage = 0;
return SendActivationRequest(sock, baseResponse, baseRequest, result, hwid);
}
EXTERNC __declspec(EXTERNAL)int_fast8_t __cdecl IsDisconnected(const SOCKET sock)
{
return isDisconnected(sock);
}
EXTERNC __declspec(EXTERNAL)DWORD __cdecl StartKmsServer(const int port, RequestCallback_t requestCallback)
{
#ifndef SIMPLE_SOCKETS
char listenAddress[64];
if (IsServerStarted) return SOCKET_EALREADY;
# ifdef _WIN32
int error = initializeWinSockets();
if (error) return error;
# endif // _WIN32
CreateResponseBase = requestCallback;
int maxsockets = 0;
int_fast8_t haveIPv4 = FALSE;
int_fast8_t haveIPv6 = FALSE;
if (checkProtocolStack(AF_INET)) { haveIPv4 = TRUE; maxsockets++; }
if (checkProtocolStack(AF_INET6)) { haveIPv6 = TRUE; maxsockets++; }
if (!maxsockets) return SOCKET_EAFNOSUPPORT;
SocketList = (SOCKET*)vlmcsd_malloc(sizeof(SOCKET) * (size_t)maxsockets);
numsockets = 0;
if (haveIPv4)
{
snprintf(listenAddress, 64, "0.0.0.0:%u", (unsigned int)port);
addListeningSocket(listenAddress);
}
if (haveIPv6)
{
snprintf(listenAddress, 64, "[::]:%u", (unsigned int)port);
addListeningSocket(listenAddress);
}
if (!numsockets)
{
free(SocketList);
return SOCKET_EADDRNOTAVAIL;
}
IsServerStarted = TRUE;
runServer();
IsServerStarted = FALSE;
return 0;
# else // SIMPLE_SOCKETS
if (IsServerStarted) return SOCKET_EALREADY;
int error;
# ifdef _WIN32
error = initializeWinSockets();
if (error) return error;
# endif // _WIN32
defaultport = vlmcsd_malloc(16);
vlmcsd_snprintf((char*)defaultport, (size_t)16, "%i", port);
CreateResponseBase = requestCallback;
error = listenOnAllAddresses();
free(defaultport);
if (error) return error;
IsServerStarted = TRUE;
runServer();
IsServerStarted = FALSE;
return 0;
# endif // SIMPLE_SOCKETS
}
EXTERNC __declspec(EXTERNAL)DWORD __cdecl StopKmsServer()
{
if (!IsServerStarted) return VLMCSD_EPERM;
closeAllListeningSockets();
# ifndef SIMPLE_SOCKETS
if (SocketList) free(SocketList);
# endif
return 0;
}
EXTERNC __declspec(EXTERNAL) int __cdecl GetLibKmsVersion()
{
return DLLVERSION;
}
EXTERNC __declspec(EXTERNAL) const char* const __cdecl GetEmulatorVersion()
{
return VERSION;
}

34
src/libkms.h Normal file
View File

@ -0,0 +1,34 @@
/*
* libkms.h
*/
#ifndef LIBKMS_H_
#define LIBKMS_H_
#include "types.h"
#include "kms.h"
#include "rpc.h"
#include "vlmcs.h"
#ifndef EXTERNC
#ifdef __cplusplus
#define EXTERNC EXTERN "C"
#else
#define EXTERNC
#endif
#endif
EXTERNC __declspec(EXTERNAL) DWORD __cdecl SendKMSRequest(const SOCKET sock, RESPONSE* baseResponse, REQUEST* baseRequest, RESPONSE_RESULT* result, BYTE *hwid);
EXTERNC __declspec(EXTERNAL) DWORD __cdecl StartKmsServer(const int port, RequestCallback_t requestCallback);
EXTERNC __declspec(EXTERNAL) DWORD __cdecl StopKmsServer();
EXTERNC __declspec(EXTERNAL) int __cdecl GetLibKmsVersion();
EXTERNC __declspec(EXTERNAL) const char* const __cdecl GetEmulatorVersion();
EXTERNC __declspec(EXTERNAL) SOCKET __cdecl ConnectToServer(const char* host, const char* port, const int addressFamily);
EXTERNC __declspec(EXTERNAL) char* __cdecl GetErrorMessage();
EXTERNC __declspec(EXTERNAL) void __cdecl CloseConnection(const SOCKET sock);
EXTERNC __declspec(EXTERNAL) RpcStatus __cdecl BindRpc(const SOCKET sock, const int_fast8_t useMultiplexedRpc, const int_fast8_t useRpcNDR64, const int_fast8_t useRpcBTFN, PRpcDiag_t rpcDiag);
EXTERNC __declspec(EXTERNAL) int_fast8_t __cdecl IsDisconnected(const SOCKET sock);
//EXTERN_C __declspec(EXTERNAL) unsigned int __cdecl GetRandom32();
#endif /* LIBKMS_H_ */

192
src/msrpc-client.c Normal file
View File

@ -0,0 +1,192 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifdef USE_MSRPC
#if !defined(_WIN32) && !defined(__CYGWIN__)
#error MSRPC is only available with native Windows or Cygwin
#endif
#include "msrpc-client.h"
#include <stdio.h>
#include "output.h"
#include "helpers.h"
#if __amd64 || defined(_M_AMD64) // 64-bit
#ifndef _M_AMD64
#define _M_AMD64
#endif // _M_AMD64
#include "KMSServer_c_x64_mingw_gcc.c"
#else // 32-bit
#include "KMSServer_c_mingw_gcc.c"
#endif // 32-bit
static RPC_CSTR stringBinding;
jmp_buf jmp;
RPC_STATUS PreviousRpcCallFailed = RPC_S_OK;
/*
* Creates an RPC string binding that is used to connect to the server.
* Input is host:port, e.g. "[::1]:1688" or "127.0.0.1:1688"
* Output is for example "ncacn_ip_tcp:127.0.0.1[endpoint=1688]"
*/
#if !__amd64
#pragma GCC optimize("O0") ////TODO: Find out why gcc needs -O0 for RPC handling
#endif
static RPC_STATUS createStringBinding(char *const addr, RPC_CSTR* stringBinding)
{
char *szHost, *szPort;
parseAddress(addr, &szHost, &szPort);
return RpcStringBindingComposeA
(
NULL, /* UUID */
(RPC_CSTR)"ncacn_ip_tcp", /* use TCP */
(RPC_CSTR)szHost, /* host name or IP address */
(RPC_CSTR)szPort, /* endpoint (TCP port here) */
NULL, /* options */
stringBinding /* resulting string binding */
);
}
/*
* This does not actually connect to a TCP port because MS RPC doesn't connect
* before the actual RPC call is made. So this a stub
*/
RpcCtx connectToAddress(char *const addr, const int AddressFamily_unused, int_fast8_t showHostName_unused)
{
RPC_STATUS status;
printf("Connecting to %s ... ", addr);
if ((status = createStringBinding(addr, &stringBinding)) != RPC_S_OK)
{
printerrorf("%s\n", win_strerror(status));
return !0;
}
if (PreviousRpcCallFailed)
{
printerrorf("%s\n", win_strerror(PreviousRpcCallFailed));
return !0;
}
printf("successful\n");
return 0;
}
/*
* Does not do RPC binding on the wire. Just initializes the interface
*/
RpcStatus rpcBindClient(const RpcCtx handle, const int_fast8_t verbose, PRpcDiag_t rpcDiag)
{
RPC_STATUS status;
if ((status = RpcBindingFromStringBindingA(stringBinding, &KMSServer_v1_0_c_ifspec)) != RPC_S_OK)
{
errorout("\n%s\n", win_strerror(status));
}
rpcDiag->HasRpcDiag = FALSE;
return status;
}
/*
* You never know if you have a TCP connection or not
* This returns true if the previous RPC call failed
*/
int_fast8_t isDisconnected(const RpcCtx handle)
{
return PreviousRpcCallFailed;
}
/*
* This is the exception handler because the RPC call may
* throw an SEH exception and gcc does not support
* __try / __except as MSVC does.
*/
static LONG WINAPI rpcException (LPEXCEPTION_POINTERS exception_pointers)
{
DWORD exception = exception_pointers->ExceptionRecord->ExceptionCode;
if (!exception) exception = (DWORD)~0;
longjmp(jmp, exception_pointers->ExceptionRecord->ExceptionCode);
return EXCEPTION_EXECUTE_HANDLER;
}
/*
* This actually calls the RPC server
*/
#define try SetUnhandledExceptionFilter(rpcException); RPC_STATUS exception = setjmp(jmp); if (!exception)
#define catch else
RpcStatus rpcSendRequest(const RpcCtx handle, BYTE* KmsRequest, const size_t requestSize, BYTE **KmsResponse, size_t* responseSize)
{
*KmsResponse = NULL; // Let midl_user_allocate do the job
try
{
exception = RequestActivation(KMSServer_v1_0_c_ifspec, (int)requestSize, KmsRequest, (int*)responseSize, KmsResponse);
}
catch
{
errorout("\n%s", win_strerror(exception));
}
PreviousRpcCallFailed = exception;
SetUnhandledExceptionFilter(NULL);
return exception;
}
#undef catch
#undef try
/*
* Only frees local handles. Cannot close the TCP connection
*/
RpcStatus closeRpc(const RpcCtx handle)
{
RPC_STATUS status;
if ((status = RpcBindingFree(&KMSServer_v1_0_c_ifspec)) != RPC_S_OK) return status;
status = RpcStringFreeA(&stringBinding);
//Ctx = INVALID_RPCCTX;
return status;
}
#if !MULTI_CALL_BINARY
// Memory allocation function for RPC.
void *__RPC_USER midl_user_allocate(size_t len)
{
return vlmcsd_malloc(len);
}
// Memory deallocation function for RPC.
void __RPC_USER midl_user_free(void __RPC_FAR *ptr)
{
if (ptr) free(ptr);
ptr = NULL;
}
#endif // !MULTI_CALL_BINARY
#endif // USE_MSRPC

26
src/msrpc-client.h Normal file
View File

@ -0,0 +1,26 @@
/*
* msrpc-client.h
*/
#ifdef USE_MSRPC
#ifndef MSRPC_CLIENT_H_
#define MSRPC_CLIENT_H_
#include "types.h"
#include "shared_globals.h"
#include <setjmp.h>
#include "output.h"
typedef int_fast8_t RpcCtx;
typedef RPC_STATUS RpcStatus;
RpcCtx connectToAddress(char *const addr, const int AddressFamily_unused, int_fast8_t showHostName);
int_fast8_t isDisconnected(const RpcCtx handle);
RpcStatus rpcBindClient(const RpcCtx handle, const int_fast8_t verbose, PRpcDiag_t rpcDiag);
RpcStatus rpcSendRequest(const RpcCtx handle, BYTE* KmsRequest, size_t requestSize, BYTE **KmsResponse, size_t *responseSize);
RpcStatus closeRpc(RpcCtx s);
#define INVALID_RPCCTX ((RpcCtx)~0)
#endif // USE_MSRPC
#endif /* MSRPC_CLIENT_H_ */

311
src/msrpc-server.c Normal file
View File

@ -0,0 +1,311 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifdef USE_MSRPC
#if !defined(_WIN32) && !defined(__CYGWIN__)
#error MSRPC is only available with native Windows or Cygwin
#endif
#if _WIN32 && !defined(NO_PRIVATE_IP_DETECT)
#include <winsock2.h>
#endif
#include "msrpc-server.h"
#include "output.h"
#include "kms.h"
#include "helpers.h"
#include "shared_globals.h"
#include "ntservice.h"
#include "endian.h"
#include "types.h"
#if __amd64 || defined(_M_AMD64) // 64-bit
#ifndef _M_AMD64
#define _M_AMD64
#endif // _M_AMD64
#include "KMSServer_s2_x64_mingw_gcc.c"
#else // 32-bit
#include "KMSServer_s2_mingw_gcc.c"
#endif // 32-bit
#if !defined(NO_LIMIT)
#define MAXCALLS MaxTasks
#else // defined(NO_LIMIT)
#define MAXCALLS RPC_C_LISTEN_MAX_CALLS_DEFAULT
#endif
/*
* This is the main run loop for the KMS server
* We actually just setup things (must be after Cygwin fork) and then sleep
*/
int runServer()
{
# if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
// The RPC setup survives a Cygwin exec without problems but no daemonizing
// SIGHUP is currently disabled for Cygwin. So this code should never compile
if (IsRestarted)
{
# ifndef NO_LOG
logger("vlmcsd %s started successfully\n", Version);
# endif // NO_LOG
}
else
# endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
{
RPC_STATUS status;
// Endpoint is actually a TCP port for "ncacn_ip_tcp"
status = RpcServerUseProtseqEpA
(
(RPC_CSTR)"ncacn_ip_tcp",
RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
(RPC_CSTR)defaultport,
NULL
);
if (status)
{
printerrorf("Fatal: Cannot bind to port %s: %s\n", defaultport, win_strerror(status));
return status;
}
# ifndef NO_LOG
logger("Listening on port %s\n", defaultport);
# endif // NO_LOG
// Registers the KMSServer interface.
status = RpcServerRegisterIf2
(
KMSServer_v1_0_s_ifspec,
NULL,
NULL,
RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH | RPC_IF_AUTOLISTEN,
MAXCALLS,
MAX_RESPONSE_SIZE, // currently set to sizeof(RESPONSE_V6)
NULL
);
if (status)
{
printerrorf("Fatal: Cannot register RPC interface: %s\n", win_strerror(status));
return status;
}
# ifndef NO_LOG
logger("vlmcsd %s started successfully\n", Version);
# endif // NO_LOG
if (IsNTService) ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 200);
}
// We could run RpcServerListen here but we need something
// that can be signaled from Cygwin. So we just sleep 24h (POSIX sleep, no Windows Sleep),
// wake up for some nanoseconds and sleep again.
while(TRUE) sleep(86400); // Sleep one day
}
/*
* Get's the IP address from an RPC_BINDING_HANDLE. Caller must call RpcStringFreeA to
* release memory allocated in *ipAddress
*/
#ifndef NO_LOG
RPC_STATUS getClientIp(const RPC_BINDING_HANDLE clientBinding, RPC_CSTR *ipAddress)
{
RPC_STATUS result;
RPC_CSTR stringBinding;
RPC_BINDING_HANDLE serverBinding;
// Fix for wine (disabled by default, because vlmcsd runs natively on all platforms where wine runs)
// Feel free to #define SUPPORT_WINE if you really want to run the Windows version with MS RPC (Wine RPC in this case)
#ifdef SUPPORT_WINE
HMODULE h = GetModuleHandleA("kernel32.dll");
if (h)
{
// Since wine simply terminates the thread when RpcBindingServerFromClient is called, we exit with an error
if (GetProcAddress(h, "wine_get_unix_file_name")) return RPC_S_CANNOT_SUPPORT;
}
#endif // SUPPORT_WINE
if ((result = RpcBindingServerFromClient(clientBinding, &serverBinding)) != RPC_S_OK) return result;
if ((result = RpcBindingToStringBindingA(serverBinding, &stringBinding)) != RPC_S_OK)
{
RpcBindingFree(&serverBinding);
return result;
}
result = RpcStringBindingParseA(stringBinding, NULL, NULL, ipAddress, NULL, NULL);
RpcStringFreeA(&stringBinding);
RpcBindingFree(&serverBinding);
return result;
}
#endif // NO_LOG
#ifndef NO_PRIVATE_IP_DETECT
static int_fast8_t IsPrivateIPAddress(char* ipAddress)
{
int family = strchr(ipAddress,'.') ? AF_INET : AF_INET6;
switch(family)
{
case AF_INET:
{
int i;
char* current;
char* next;
uint32_t ip;
for (ip = 0, i = 0, current = ipAddress; i < 4; i++, current = next + 1)
{
ip = (ip << 8) | strtoul(current, &next, 10);
if (*next != '.') break;
}
if
(
(ip & 0xff000000) == 0x7f000000 || // 127.x.x.x localhost
(ip & 0xffff0000) == 0xc0a80000 || // 192.168.x.x private routeable
(ip & 0xffff0000) == 0xa9fe0000 || // 169.254.x.x link local
(ip & 0xff000000) == 0x0a000000 || // 10.x.x.x private routeable
(ip & 0xfff00000) == 0xac100000 // 172.16-31.x.x private routeable
)
{
return TRUE;
}
break;
}
case AF_INET6:
{
if (!strcmp(ipAddress, "::1")) return TRUE;
if (strchr(ipAddress, ':') - ipAddress != 4) break;
int16_t firstWord;
hex2bin((BYTE*)&firstWord, ipAddress, 2);
if ((BE16(firstWord) & 0xe000) != 0x2000) return TRUE;
}
}
return FALSE;
}
#endif // NO_PRIVATE_IP_DETECT
/*
* This is the callback function for the RPC request as defined in KMSServer.idl
* Output from the MIDL compiler has been modified manually to support gcc (and compatible compilers)
* as well as Cygwin and MingW-w64 toolchains.
*/
int ProcessActivationRequest(handle_t IDL_handle, int requestSize, unsigned char *request, int *responseSize, unsigned char **response)
{
RPC_CSTR clientIpAddress;
RPC_STATUS result;
int status = 0;
result = getClientIp(IDL_handle, &clientIpAddress);
# ifndef NO_LOG
logger("RPC connection accepted: %s\n", !result ? (const char*)clientIpAddress : "Unknown IP");
# endif // NO_LOG
# ifndef NO_PRIVATE_IP_DETECT
if (result && (PublicIPProtectionLevel & 2))
{
# ifndef NO_LOG
logger ("Cannot verify that client has a private IP address\n");
# endif
return 0x80070000 | RPC_S_ACCESS_DENIED;
}
if (!result && (PublicIPProtectionLevel & 2) && !IsPrivateIPAddress((char*)clientIpAddress))
{
# ifndef NO_LOG
logger("Client with public IP address rejected\n");
# endif
RpcStringFreeA(&clientIpAddress);
return 0x80070000 | RPC_S_ACCESS_DENIED;
}
# endif // NO_PRIVATE_IP_DETECT
// Discard any packet smaller than a v4 request
if (requestSize < (int)sizeof(REQUEST_V4))
{
if (!result) RpcStringFreeA(&clientIpAddress);
return 0x8007000D;
}
*response = (uint8_t *)midl_user_allocate(MAX_RESPONSE_SIZE);
int kmsStatus = 0x8007000D;
int version = LE32(((REQUEST*)(request))->Version);
switch(version)
{
case 0x40000:
kmsStatus = CreateResponseV4((REQUEST_V4 *)request, *response, (char*)clientIpAddress);
break;
case 0x50000:
case 0x60000:
kmsStatus = CreateResponseV6((REQUEST_V6 *) request, *response, (char*)clientIpAddress);
break;
default:
# ifndef NO_LOG
logger("Fatal: KMSv%u.%u unsupported\n", version >> 16, version & 0xffff);
# endif // NO_LOG
break;
}
if (kmsStatus < 0)
{
status = kmsStatus;
}
else
{
*responseSize = kmsStatus;
}
if (!result) RpcStringFreeA(&clientIpAddress);
return status;
}
// Memory allocation function for RPC.
void *__RPC_USER midl_user_allocate(size_t len)
{
return vlmcsd_malloc(len);
}
// Memory deallocation function for RPC.
void __RPC_USER midl_user_free(void __RPC_FAR *ptr)
{
if (ptr) free(ptr);
ptr = NULL;
}
#endif // USE_MSRPC

10
src/msrpc-server.h Normal file
View File

@ -0,0 +1,10 @@
/*
* msrpc-server.h
*/
#ifndef MSRPC_SERVER_H_
#define MSRPC_SERVER_H_
int runServer();
#endif /* MSRPC_SERVER_H_ */

569
src/nameser.h Normal file
View File

@ -0,0 +1,569 @@
/* $NetBSD: nameser.h,v 1.19 2005/12/26 19:01:47 perry Exp $ */
/*
* Copyright (c) 1983, 1989, 1993
* The Regents of the University of California. 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. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Id: nameser.h,v 1.2.2.4.4.1 2004/03/09 08:33:30 marka Exp
*/
#ifndef _ARPA_NAMESER_H_
#define _ARPA_NAMESER_H_
#define BIND_4_COMPAT
#include <sys/types.h>
#include <sys/cdefs.h>
/*
* Revision information. This is the release date in YYYYMMDD format.
* It can change every day so the right thing to do with it is use it
* in preprocessor commands such as "#if (__NAMESER > 19931104)". Do not
* compare for equality; rather, use it to determine whether your libbind.a
* contains a new enough lib/nameser/ to support the feature you need.
*/
#define __NAMESER 19991006 /* New interface version stamp. */
/*
* Define constants based on RFC 883, RFC 1034, RFC 1035
*/
#define NS_PACKETSZ 512 /* default UDP packet size */
#define NS_MAXDNAME 1025 /* maximum domain name */
#define NS_MAXMSG 65535 /* maximum message size */
#define NS_MAXCDNAME 255 /* maximum compressed domain name */
#define NS_MAXLABEL 63 /* maximum length of domain label */
#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
#define NS_INT32SZ 4 /* #/bytes of data in a uint32_t */
#define NS_INT16SZ 2 /* #/bytes of data in a uint16_t */
#define NS_INT8SZ 1 /* #/bytes of data in a uint8_t */
#define NS_INADDRSZ 4 /* IPv4 T_A */
#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
/*
* These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()
* in synch with it.
*/
typedef enum __ns_sect {
ns_s_qd = 0, /* Query: Question. */
ns_s_zn = 0, /* Update: Zone. */
ns_s_an = 1, /* Query: Answer. */
ns_s_pr = 1, /* Update: Prerequisites. */
ns_s_ns = 2, /* Query: Name servers. */
ns_s_ud = 2, /* Update: Update. */
ns_s_ar = 3, /* Query|Update: Additional records. */
ns_s_max = 4
} ns_sect;
/*
* This is a message handle. It is caller allocated and has no dynamic data.
* This structure is intended to be opaque to all but ns_parse.c, thus the
* leading _'s on the member names. Use the accessor functions, not the _'s.
*/
typedef struct __ns_msg {
const u_char *_msg, *_eom;
uint16_t _id, _flags, _counts[ns_s_max];
const u_char *_sections[ns_s_max];
ns_sect _sect;
int _rrnum;
const u_char *_msg_ptr;
} ns_msg;
/* Private data structure - do not use from outside library. */
struct _ns_flagdata { int mask, shift; };
extern const struct _ns_flagdata _ns_flagdata[];
/* Accessor macros - this is part of the public interface. */
#define ns_msg_id(handle) ((handle)._id + 0)
#define ns_msg_base(handle) ((handle)._msg + 0)
#define ns_msg_end(handle) ((handle)._eom + 0)
#define ns_msg_size(handle) ((size_t)((handle)._eom - (handle)._msg))
#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
/*
* This is a parsed record. It is caller allocated and has no dynamic data.
*/
typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const u_char * rdata;
} ns_rr;
/* Accessor macros - this is part of the public interface. */
#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
#define ns_rr_ttl(rr) ((u_long)(rr).ttl + 0)
#define ns_rr_rdlen(rr) ((size_t)(rr).rdlength + 0)
#define ns_rr_rdata(rr) ((rr).rdata + 0)
/*
* These don't have to be in the same order as in the packet flags word,
* and they can even overlap in some cases, but they will need to be kept
* in synch with ns_parse.c:ns_flagdata[].
*/
typedef enum __ns_flag {
ns_f_qr, /* Question/Response. */
ns_f_opcode, /* Operation code. */
ns_f_aa, /* Authoritative Answer. */
ns_f_tc, /* Truncation occurred. */
ns_f_rd, /* Recursion Desired. */
ns_f_ra, /* Recursion Available. */
ns_f_z, /* MBZ. */
ns_f_ad, /* Authentic Data (DNSSEC). */
ns_f_cd, /* Checking Disabled (DNSSEC). */
ns_f_rcode, /* Response code. */
ns_f_max
} ns_flag;
/*
* Currently defined opcodes.
*/
typedef enum __ns_opcode {
ns_o_query = 0, /* Standard query. */
ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */
ns_o_status = 2, /* Name server status query (unsupported). */
/* Opcode 3 is undefined/reserved. */
ns_o_notify = 4, /* Zone change notification. */
ns_o_update = 5, /* Zone update message. */
ns_o_max = 6
} ns_opcode;
/*
* Currently defined response codes.
*/
typedef enum __ns_rcode {
ns_r_noerror = 0, /* No error occurred. */
ns_r_formerr = 1, /* Format error. */
ns_r_servfail = 2, /* Server failure. */
ns_r_nxdomain = 3, /* Name error. */
ns_r_notimpl = 4, /* Unimplemented. */
ns_r_refused = 5, /* Operation refused. */
/* these are for BIND_UPDATE */
ns_r_yxdomain = 6, /* Name exists */
ns_r_yxrrset = 7, /* RRset exists */
ns_r_nxrrset = 8, /* RRset does not exist */
ns_r_notauth = 9, /* Not authoritative for zone */
ns_r_notzone = 10, /* Zone of record different from zone section */
ns_r_max = 11,
/* The following are EDNS extended rcodes */
ns_r_badvers = 16,
/* The following are TSIG errors */
ns_r_badsig = 16,
ns_r_badkey = 17,
ns_r_badtime = 18
} ns_rcode;
/* BIND_UPDATE */
typedef enum __ns_update_operation {
ns_uop_delete = 0,
ns_uop_add = 1,
ns_uop_max = 2
} ns_update_operation;
/*
* This structure is used for TSIG authenticated messages
*/
struct ns_tsig_key {
char name[NS_MAXDNAME], alg[NS_MAXDNAME];
unsigned char *data;
int len;
};
typedef struct ns_tsig_key ns_tsig_key;
/*
* This structure is used for TSIG authenticated TCP messages
*/
struct ns_tcp_tsig_state {
int counter;
struct dst_key *key;
void *ctx;
unsigned char sig[NS_PACKETSZ];
int siglen;
};
typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
#define NS_TSIG_FUDGE 300
#define NS_TSIG_TCP_COUNT 100
#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
#define NS_TSIG_ERROR_NO_TSIG -10
#define NS_TSIG_ERROR_NO_SPACE -11
#define NS_TSIG_ERROR_FORMERR -12
/*
* Currently defined type values for resources and queries.
*/
typedef enum __ns_type {
ns_t_invalid = 0, /* Cookie. */
ns_t_a = 1, /* Host address. */
ns_t_ns = 2, /* Authoritative server. */
ns_t_md = 3, /* Mail destination. */
ns_t_mf = 4, /* Mail forwarder. */
ns_t_cname = 5, /* Canonical name. */
ns_t_soa = 6, /* Start of authority zone. */
ns_t_mb = 7, /* Mailbox domain name. */
ns_t_mg = 8, /* Mail group member. */
ns_t_mr = 9, /* Mail rename name. */
ns_t_null = 10, /* Null resource record. */
ns_t_wks = 11, /* Well known service. */
ns_t_ptr = 12, /* Domain name pointer. */
ns_t_hinfo = 13, /* Host information. */
ns_t_minfo = 14, /* Mailbox information. */
ns_t_mx = 15, /* Mail routing information. */
ns_t_txt = 16, /* Text strings. */
ns_t_rp = 17, /* Responsible person. */
ns_t_afsdb = 18, /* AFS cell database. */
ns_t_x25 = 19, /* X_25 calling address. */
ns_t_isdn = 20, /* ISDN calling address. */
ns_t_rt = 21, /* Router. */
ns_t_nsap = 22, /* NSAP address. */
ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
ns_t_sig = 24, /* Security signature. */
ns_t_key = 25, /* Security key. */
ns_t_px = 26, /* X.400 mail mapping. */
ns_t_gpos = 27, /* Geographical position (withdrawn). */
ns_t_aaaa = 28, /* Ip6 Address. */
ns_t_loc = 29, /* Location Information. */
ns_t_nxt = 30, /* Next domain (security). */
ns_t_eid = 31, /* Endpoint identifier. */
ns_t_nimloc = 32, /* Nimrod Locator. */
ns_t_srv = 33, /* Server Selection. */
ns_t_atma = 34, /* ATM Address */
ns_t_naptr = 35, /* Naming Authority PoinTeR */
ns_t_kx = 36, /* Key Exchange */
ns_t_cert = 37, /* Certification record */
ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */
ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */
ns_t_sink = 40, /* Kitchen sink (experimentatl) */
ns_t_opt = 41, /* EDNS0 option (meta-RR) */
ns_t_apl = 42, /* Address prefix list (RFC 3123) */
ns_t_tkey = 249, /* Transaction key */
ns_t_tsig = 250, /* Transaction signature. */
ns_t_ixfr = 251, /* Incremental zone transfer. */
ns_t_axfr = 252, /* Transfer zone of authority. */
ns_t_mailb = 253, /* Transfer mailbox records. */
ns_t_maila = 254, /* Transfer mail agent records. */
ns_t_any = 255, /* Wildcard match. */
ns_t_zxfr = 256, /* BIND-specific, nonstandard. */
ns_t_max = 65536
} ns_type;
/* Exclusively a QTYPE? (not also an RTYPE) */
#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
(t) == ns_t_mailb || (t) == ns_t_maila)
/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */
#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */
#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
(t) == ns_t_zxfr)
/*
* Values for class field
*/
typedef enum __ns_class {
ns_c_invalid = 0, /* Cookie. */
ns_c_in = 1, /* Internet. */
ns_c_2 = 2, /* unallocated/unsupported. */
ns_c_chaos = 3, /* MIT Chaos-net. */
ns_c_hs = 4, /* MIT Hesiod. */
/* Query class values which do not appear in resource records */
ns_c_none = 254, /* for prereq. sections in update requests */
ns_c_any = 255, /* Wildcard match. */
ns_c_max = 65536
} ns_class;
/* DNSSEC constants. */
typedef enum __ns_key_types {
ns_kt_rsa = 1, /* key type RSA/MD5 */
ns_kt_dh = 2, /* Diffie Hellman */
ns_kt_dsa = 3, /* Digital Signature Standard (MANDATORY) */
ns_kt_private = 254 /* Private key type starts with OID */
} ns_key_types;
typedef enum __ns_cert_types {
cert_t_pkix = 1, /* PKIX (X.509v3) */
cert_t_spki = 2, /* SPKI */
cert_t_pgp = 3, /* PGP */
cert_t_url = 253, /* URL private type */
cert_t_oid = 254 /* OID private type */
} ns_cert_types;
/* Flags field of the KEY RR rdata. */
#define NS_KEY_TYPEMASK 0xC000 /* Mask for "type" bits */
#define NS_KEY_TYPE_AUTH_CONF 0x0000 /* Key usable for both */
#define NS_KEY_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */
#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */
#define NS_KEY_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */
/* The type bits can also be interpreted independently, as single bits: */
#define NS_KEY_NO_AUTH 0x8000 /* Key unusable for authentication */
#define NS_KEY_NO_CONF 0x4000 /* Key unusable for confidentiality */
#define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */
#define NS_KEY_EXTENDED_FLAGS 0x1000 /* reserved - must be zero */
#define NS_KEY_RESERVED4 0x0800 /* reserved - must be zero */
#define NS_KEY_RESERVED5 0x0400 /* reserved - must be zero */
#define NS_KEY_NAME_TYPE 0x0300 /* these bits determine the type */
#define NS_KEY_NAME_USER 0x0000 /* key is assoc. with user */
#define NS_KEY_NAME_ENTITY 0x0200 /* key is assoc. with entity eg host */
#define NS_KEY_NAME_ZONE 0x0100 /* key is zone key */
#define NS_KEY_NAME_RESERVED 0x0300 /* reserved meaning */
#define NS_KEY_RESERVED8 0x0080 /* reserved - must be zero */
#define NS_KEY_RESERVED9 0x0040 /* reserved - must be zero */
#define NS_KEY_RESERVED10 0x0020 /* reserved - must be zero */
#define NS_KEY_RESERVED11 0x0010 /* reserved - must be zero */
#define NS_KEY_SIGNATORYMASK 0x000F /* key can sign RR's of same name */
#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
NS_KEY_RESERVED4 | \
NS_KEY_RESERVED5 | \
NS_KEY_RESERVED8 | \
NS_KEY_RESERVED9 | \
NS_KEY_RESERVED10 | \
NS_KEY_RESERVED11 )
#define NS_KEY_RESERVED_BITMASK2 0xFFFF /* no bits defined here */
/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
#define NS_ALG_MD5RSA 1 /* MD5 with RSA */
#define NS_ALG_DH 2 /* Diffie Hellman KEY */
#define NS_ALG_DSA 3 /* DSA KEY */
#define NS_ALG_DSS NS_ALG_DSA
#define NS_ALG_EXPIRE_ONLY 253 /* No alg, no security */
#define NS_ALG_PRIVATE_OID 254 /* Key begins with OID giving alg */
/* Protocol values */
/* value 0 is reserved */
#define NS_KEY_PROT_TLS 1
#define NS_KEY_PROT_EMAIL 2
#define NS_KEY_PROT_DNSSEC 3
#define NS_KEY_PROT_IPSEC 4
#define NS_KEY_PROT_ANY 255
/* Signatures */
#define NS_MD5RSA_MIN_BITS 512 /* Size of a mod or exp in bits */
#define NS_MD5RSA_MAX_BITS 4096
/* Total of binary mod and exp */
#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3)
/* Max length of text sig block */
#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4)
#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8)
#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8)
#define NS_DSA_SIG_SIZE 41
#define NS_DSA_MIN_SIZE 213
#define NS_DSA_MAX_BYTES 405
/* Offsets into SIG record rdata to find various values */
#define NS_SIG_TYPE 0 /* Type flags */
#define NS_SIG_ALG 2 /* Algorithm */
#define NS_SIG_LABELS 3 /* How many labels in name */
#define NS_SIG_OTTL 4 /* Original TTL */
#define NS_SIG_EXPIR 8 /* Expiration time */
#define NS_SIG_SIGNED 12 /* Signature time */
#define NS_SIG_FOOT 16 /* Key footprint */
#define NS_SIG_SIGNER 18 /* Domain name of who signed it */
/* How RR types are represented as bit-flags in NXT records */
#define NS_NXT_BITS 8
#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_MAX 127
/*
* EDNS0 extended flags, host order.
*/
#define NS_OPT_DNSSEC_OK 0x8000U
/*
* Inline versions of get/put short/long. Pointer is advanced.
*/
#define NS_GET16(s, cp) do { \
const u_char *t_cp = (const u_char *)(cp); \
(s) = ((uint16_t)t_cp[0] << 8) \
| ((uint16_t)t_cp[1]) \
; \
(cp) += NS_INT16SZ; \
} while (/*CONSTCOND*/0)
#define NS_GET32(l, cp) do { \
const u_char *t_cp = (const u_char *)(cp); \
(l) = ((uint32_t)t_cp[0] << 24) \
| ((uint32_t)t_cp[1] << 16) \
| ((uint32_t)t_cp[2] << 8) \
| ((uint32_t)t_cp[3]) \
; \
(cp) += NS_INT32SZ; \
} while (/*CONSTCOND*/0)
#define NS_PUT16(s, cp) do { \
uint32_t t_s = (uint32_t)(s); \
u_char *t_cp = (u_char *)(cp); \
*t_cp++ = t_s >> 8; \
*t_cp = t_s; \
(cp) += NS_INT16SZ; \
} while (/*CONSTCOND*/0)
#define NS_PUT32(l, cp) do { \
uint32_t t_l = (uint32_t)(l); \
u_char *t_cp = (u_char *)(cp); \
*t_cp++ = t_l >> 24; \
*t_cp++ = t_l >> 16; \
*t_cp++ = t_l >> 8; \
*t_cp = t_l; \
(cp) += NS_INT32SZ; \
} while (/*CONSTCOND*/0)
/*
* ANSI C identifier hiding for bind's lib/nameser.
*/
#define ns_msg_getflag __ns_msg_getflag
#define ns_get16 __ns_get16
#define ns_get32 __ns_get32
#define ns_put16 __ns_put16
#define ns_put32 __ns_put32
#define ns_initparse __ns_initparse
#define ns_skiprr __ns_skiprr
#define ns_parserr __ns_parserr
#define ns_sprintrr __ns_sprintrr
#define ns_sprintrrf __ns_sprintrrf
#define ns_format_ttl __ns_format_ttl
#define ns_parse_ttl __ns_parse_ttl
#define ns_datetosecs __ns_datetosecs
#define ns_name_ntol __ns_name_ntol
#define ns_name_ntop __ns_name_ntop
#define ns_name_pton __ns_name_pton
#define ns_name_unpack __ns_name_unpack
#define ns_name_pack __ns_name_pack
#define ns_name_compress __ns_name_compress
#define ns_name_uncompress __ns_name_uncompress
#define ns_name_skip __ns_name_skip
#define ns_name_rollback __ns_name_rollback
#define ns_sign __ns_sign
#define ns_sign2 __ns_sign2
#define ns_sign_tcp __ns_sign_tcp
#define ns_sign_tcp2 __ns_sign_tcp2
#define ns_sign_tcp_init __ns_sign_tcp_init
#define ns_find_tsig __ns_find_tsig
#define ns_verify __ns_verify
#define ns_verify_tcp __ns_verify_tcp
#define ns_verify_tcp_init __ns_verify_tcp_init
#define ns_samedomain __ns_samedomain
#define ns_subdomain __ns_subdomain
#define ns_makecanon __ns_makecanon
#define ns_samename __ns_samename
__BEGIN_DECLS
int ns_msg_getflag(ns_msg, int);
uint16_t ns_get16(const u_char *);
uint32_t ns_get32(const u_char *);
void ns_put16(uint16_t, u_char *);
void ns_put32(uint32_t, u_char *);
int ns_initparse(const u_char *, int, ns_msg *);
int ns_skiprr(const u_char *, const u_char *, ns_sect, int);
int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
int ns_sprintrr(const ns_msg *, const ns_rr *,
const char *, const char *, char *, size_t);
int ns_sprintrrf(const u_char *, size_t, const char *,
ns_class, ns_type, u_long, const u_char *,
size_t, const char *, const char *,
char *, size_t);
int ns_format_ttl(u_long, char *, size_t);
int ns_parse_ttl(const char *, u_long *);
uint32_t ns_datetosecs(const char *cp, int *errp);
int ns_name_ntol(const u_char *, u_char *, size_t);
int ns_name_ntop(const u_char *, char *, size_t);
int ns_name_pton(const char *, u_char *, size_t);
int ns_name_unpack(const u_char *, const u_char *,
const u_char *, u_char *, size_t);
int ns_name_pack(const u_char *, u_char *, int,
const u_char **, const u_char **);
int ns_name_uncompress(const u_char *, const u_char *,
const u_char *, char *, size_t);
int ns_name_compress(const char *, u_char *, size_t,
const u_char **, const u_char **);
int ns_name_skip(const u_char **, const u_char *);
void ns_name_rollback(const u_char *, const u_char **,
const u_char **);
int ns_sign(u_char *, int *, int, int, void *,
const u_char *, int, u_char *, int *, time_t);
int ns_sign2(u_char *, int *, int, int, void *,
const u_char *, int, u_char *, int *, time_t,
u_char **, u_char **);
int ns_sign_tcp(u_char *, int *, int, int,
ns_tcp_tsig_state *, int);
int ns_sign_tcp2(u_char *, int *, int, int,
ns_tcp_tsig_state *, int,
u_char **, u_char **);
int ns_sign_tcp_init(void *, const u_char *, int,
ns_tcp_tsig_state *);
u_char *ns_find_tsig(u_char *, u_char *);
int ns_verify(u_char *, int *, void *,
const u_char *, int, u_char *, int *,
time_t *, int);
int ns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int);
int ns_verify_tcp_init(void *, const u_char *, int,
ns_tcp_tsig_state *);
int ns_samedomain(const char *, const char *);
int ns_subdomain(const char *, const char *);
int ns_makecanon(const char *, char *, size_t);
int ns_samename(const char *, const char *);
__END_DECLS
#ifdef BIND_4_COMPAT
#include "nameser_compat.h"
#endif
#endif /* !_ARPA_NAMESER_H_ */

236
src/nameser_compat.h Normal file
View File

@ -0,0 +1,236 @@
/* $NetBSD: nameser_compat.h,v 1.1.1.2 2004/11/07 01:28:27 christos Exp $ */
/* Copyright (c) 1983, 1989
* The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* from nameser.h 8.1 (Berkeley) 6/2/93
* Id: nameser_compat.h,v 1.1.2.3.4.2 2004/07/01 04:43:41 marka Exp
*/
#ifndef _ARPA_NAMESER_COMPAT_
#define _ARPA_NAMESER_COMPAT_
#define __BIND 19950621 /* (DEAD) interface version stamp. */
#include <endian.h>
#ifndef BYTE_ORDER
#if (BSD >= 199103)
# include <machine/endian.h>
#else
#ifdef __linux
# include <endian.h>
#else
#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */
#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/
#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
defined(__alpha__) || defined(__alpha) || \
(defined(__Lynx__) && defined(__x86__))
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
defined(apollo) || defined(__convex__) || defined(_CRAY) || \
defined(__hppa) || defined(__hp9000) || \
defined(__hp9000s300) || defined(__hp9000s700) || \
defined(__hp3000s900) || defined(__hpux) || defined(MPE) || \
defined (BIT_ZERO_ON_LEFT) || defined(m68k) || defined(__sparc) || \
(defined(__Lynx__) && \
(defined(__68k__) || defined(__sparc__) || defined(__powerpc__)))
#define BYTE_ORDER BIG_ENDIAN
#endif
#endif /* __linux */
#endif /* BSD */
#endif /* BYTE_ORDER */
#if !defined(BYTE_ORDER) || \
(BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \
BYTE_ORDER != PDP_ENDIAN)
/* you must determine what the correct bit order is for
* your compiler - the next line is an intentional error
* which will force your compiles to bomb until you fix
* the above macros.
*/
#error "Undefined or invalid BYTE_ORDER";
#endif
/*
* Structure for query header. The order of the fields is machine- and
* compiler-dependent, depending on the byte/bit order and the layout
* of bit fields. We use bit fields only in int variables, as this
* is all ANSI requires. This requires a somewhat confusing rearrangement.
*/
typedef struct {
unsigned id :16; /* query identification number */
#if BYTE_ORDER == BIG_ENDIAN
/* fields in third byte */
unsigned qr: 1; /* response flag */
unsigned opcode: 4; /* purpose of message */
unsigned aa: 1; /* authoritive answer */
unsigned tc: 1; /* truncated message */
unsigned rd: 1; /* recursion desired */
/* fields in fourth byte */
unsigned ra: 1; /* recursion available */
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
unsigned ad: 1; /* authentic data from named */
unsigned cd: 1; /* checking disabled by resolver */
unsigned rcode :4; /* response code */
#endif
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
/* fields in third byte */
unsigned rd :1; /* recursion desired */
unsigned tc :1; /* truncated message */
unsigned aa :1; /* authoritive answer */
unsigned opcode :4; /* purpose of message */
unsigned qr :1; /* response flag */
/* fields in fourth byte */
unsigned rcode :4; /* response code */
unsigned cd: 1; /* checking disabled by resolver */
unsigned ad: 1; /* authentic data from named */
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
unsigned ra :1; /* recursion available */
#endif
/* remaining bytes */
unsigned qdcount :16; /* number of question entries */
unsigned ancount :16; /* number of answer entries */
unsigned nscount :16; /* number of authority entries */
unsigned arcount :16; /* number of resource entries */
} HEADER;
#define PACKETSZ NS_PACKETSZ
#define MAXDNAME NS_MAXDNAME
#define MAXCDNAME NS_MAXCDNAME
#define MAXLABEL NS_MAXLABEL
#define HFIXEDSZ NS_HFIXEDSZ
#define QFIXEDSZ NS_QFIXEDSZ
#define RRFIXEDSZ NS_RRFIXEDSZ
#define INT32SZ NS_INT32SZ
#define INT16SZ NS_INT16SZ
#define INT8SZ NS_INT8SZ
#define INADDRSZ NS_INADDRSZ
#define IN6ADDRSZ NS_IN6ADDRSZ
#define INDIR_MASK NS_CMPRSFLGS
#define NAMESERVER_PORT NS_DEFAULTPORT
#define S_ZONE ns_s_zn
#define S_PREREQ ns_s_pr
#define S_UPDATE ns_s_ud
#define S_ADDT ns_s_ar
#define QUERY ns_o_query
#define IQUERY ns_o_iquery
#define STATUS ns_o_status
#define NS_NOTIFY_OP ns_o_notify
#define NS_UPDATE_OP ns_o_update
#define NOERROR ns_r_noerror
#define FORMERR ns_r_formerr
#define SERVFAIL ns_r_servfail
#define NXDOMAIN ns_r_nxdomain
#define NOTIMP ns_r_notimpl
#define REFUSED ns_r_refused
#define YXDOMAIN ns_r_yxdomain
#define YXRRSET ns_r_yxrrset
#define NXRRSET ns_r_nxrrset
#define NOTAUTH ns_r_notauth
#define NOTZONE ns_r_notzone
/*#define BADSIG ns_r_badsig*/
/*#define BADKEY ns_r_badkey*/
/*#define BADTIME ns_r_badtime*/
#define DELETE ns_uop_delete
#define ADD ns_uop_add
#define T_A ns_t_a
#define T_NS ns_t_ns
#define T_MD ns_t_md
#define T_MF ns_t_mf
#define T_CNAME ns_t_cname
#define T_SOA ns_t_soa
#define T_MB ns_t_mb
#define T_MG ns_t_mg
#define T_MR ns_t_mr
#define T_NULL ns_t_null
#define T_WKS ns_t_wks
#define T_PTR ns_t_ptr
#define T_HINFO ns_t_hinfo
#define T_MINFO ns_t_minfo
#define T_MX ns_t_mx
#define T_TXT ns_t_txt
#define T_RP ns_t_rp
#define T_AFSDB ns_t_afsdb
#define T_X25 ns_t_x25
#define T_ISDN ns_t_isdn
#define T_RT ns_t_rt
#define T_NSAP ns_t_nsap
#define T_NSAP_PTR ns_t_nsap_ptr
#define T_SIG ns_t_sig
#define T_KEY ns_t_key
#define T_PX ns_t_px
#define T_GPOS ns_t_gpos
#define T_AAAA ns_t_aaaa
#define T_LOC ns_t_loc
#define T_NXT ns_t_nxt
#define T_EID ns_t_eid
#define T_NIMLOC ns_t_nimloc
#define T_SRV ns_t_srv
#define T_ATMA ns_t_atma
#define T_NAPTR ns_t_naptr
#define T_A6 ns_t_a6
#define T_TSIG ns_t_tsig
#define T_IXFR ns_t_ixfr
#define T_AXFR ns_t_axfr
#define T_MAILB ns_t_mailb
#define T_MAILA ns_t_maila
#define T_ANY ns_t_any
#define C_IN ns_c_in
#define C_CHAOS ns_c_chaos
#define C_HS ns_c_hs
/* BIND_UPDATE */
#define C_NONE ns_c_none
#define C_ANY ns_c_any
#define GETSHORT NS_GET16
#define GETLONG NS_GET32
#define PUTSHORT NS_PUT16
#define PUTLONG NS_PUT32
#endif /* _ARPA_NAMESER_COMPAT_ */

107
src/netlink-musl.h Normal file
View File

@ -0,0 +1,107 @@
#ifndef NETLINK_MUSL_H
#define NETLINK_MUSL_H
#if !__linux__
#error netlink-musl.h only works with a linux kernel
#endif
#if __ANDROID__
#error netlink-musl.h does not work with Android
#endif
#include <stdint.h>
/* linux/netlink.h */
#define NETLINK_ROUTE 0
struct nlmsghdr {
uint32_t nlmsg_len;
uint16_t nlmsg_type;
uint16_t nlmsg_flags;
uint32_t nlmsg_seq;
uint32_t nlmsg_pid;
};
#define NLM_F_REQUEST 1
#define NLM_F_MULTI 2
#define NLM_F_ACK 4
#define NLM_F_ROOT 0x100
#define NLM_F_MATCH 0x200
#define NLM_F_ATOMIC 0x400
#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)
#define NLMSG_NOOP 0x1
#define NLMSG_ERROR 0x2
#define NLMSG_DONE 0x3
#define NLMSG_OVERRUN 0x4
/* linux/rtnetlink.h */
#define RTM_NEWLINK 16
#define RTM_GETLINK 18
#define RTM_NEWADDR 20
#define RTM_GETADDR 22
struct rtattr {
unsigned short rta_len;
unsigned short rta_type;
};
struct rtgenmsg {
unsigned char rtgen_family;
};
struct ifinfomsg {
unsigned char ifi_family;
unsigned char __ifi_pad;
unsigned short ifi_type;
int ifi_index;
unsigned ifi_flags;
unsigned ifi_change;
};
/* linux/if_link.h */
#define IFLA_ADDRESS 1
#define IFLA_BROADCAST 2
#define IFLA_IFNAME 3
#define IFLA_STATS 7
/* linux/if_addr.h */
struct ifaddrmsg {
uint8_t ifa_family;
uint8_t ifa_prefixlen;
uint8_t ifa_flags;
uint8_t ifa_scope;
uint32_t ifa_index;
};
#define IFA_ADDRESS 1
#define IFA_LOCAL 2
#define IFA_LABEL 3
#define IFA_BROADCAST 4
/* musl */
#define NETLINK_ALIGN(len) (((len)+3) & ~3)
#define NLMSG_DATA(nlh) ((void*)((char*)(nlh)+sizeof(struct nlmsghdr)))
#define NLMSG_DATALEN(nlh) ((nlh)->nlmsg_len-sizeof(struct nlmsghdr))
#define NLMSG_DATAEND(nlh) ((char*)(nlh)+(nlh)->nlmsg_len)
#define NLMSG_NEXT(nlh) (struct nlmsghdr*)((char*)(nlh)+NETLINK_ALIGN((nlh)->nlmsg_len))
#define NLMSG_OK(nlh,end) ((char*)(end)-(char*)(nlh) >= sizeof(struct nlmsghdr))
#define RTA_DATA(rta) ((void*)((char*)(rta)+sizeof(struct rtattr)))
#define RTA_DATALEN(rta) ((rta)->rta_len-sizeof(struct rtattr))
#define RTA_DATAEND(rta) ((char*)(rta)+(rta)->rta_len)
#define RTA_NEXT(rta) (struct rtattr*)((char*)(rta)+NETLINK_ALIGN((rta)->rta_len))
#define RTA_OK(nlh,end) ((char*)(end)-(char*)(rta) >= sizeof(struct rtattr))
#define NLMSG_RTA(nlh,len) ((void*)((char*)(nlh)+sizeof(struct nlmsghdr)+NETLINK_ALIGN(len)))
#define NLMSG_RTAOK(rta,nlh) RTA_OK(rta,NLMSG_DATAEND(nlh))
int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx);
#endif // NETLINK_MUSL_H

1071
src/network.c Normal file

File diff suppressed because it is too large Load Diff

48
src/network.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef INCLUDED_NETWORK_H
#define INCLUDED_NETWORK_H
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "types.h"
#include "output.h"
#if _MSC_VER
//typedef signed char int_fast8_t;
//typedef unsigned char BYTE;
//typedef UINT_PTR size_t;
//typedef unsigned long DWORD;
#define STDIN_FILENO 0
#endif
int_fast8_t sendrecv(SOCKET sock, BYTE *data, int len, int_fast8_t do_send);
#define _recv(s, d, l) sendrecv(s, (BYTE *)d, l, 0)
#define _send(s, d, l) sendrecv(s, (BYTE *)d, l, !0)
#ifndef NO_SOCKETS
void closeAllListeningSockets();
#ifdef SIMPLE_SOCKETS
int listenOnAllAddresses();
#endif // SIMPLE_SOCKETS
BOOL addListeningSocket(const char *const addr);
__pure int_fast8_t checkProtocolStack(const int addressfamily);
#if HAVE_GETIFADDR
void getPrivateIPAddresses(int* numAddresses, char*** ipAddresses);
#endif // HAVE_GETIFADDR
#endif // NO_SOCKETS
int runServer();
SOCKET connectToAddress(const char *const addr, const int AddressFamily, int_fast8_t showHostName);
int_fast8_t isDisconnected(const SOCKET s);
#endif // INCLUDED_NETWORK_H

355
src/ns_name.c Normal file
View File

@ -0,0 +1,355 @@
/*
* Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Modified by Hotbird64 for use with vlmcs.
*/
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifdef DNS_PARSER_INTERNAL
#ifndef NO_DNS
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include "types.h"
#include "ns_name.h"
#ifdef SPRINTF_CHAR
# define SPRINTF(x) strlen(sprintf/**/x)
#else
# define SPRINTF(x) ((size_t)sprintf x)
#endif
#define NS_TYPE_ELT 0x40 /* EDNS0 extended label type */
#define DNS_LABELTYPE_BITSTRING 0x41
#define NS_MAXCDNAME 255
#define NS_CMPRSFLGS 0xc0
/* Data. */
static char digits[] = "0123456789";
/* Forward. */
static int special_vlmcsd(int);
static int printable_vlmcsd(int);
static int labellen_vlmcsd(const uint8_t *);
static int decode_bitstring_vlmcsd(const char **, char *, const char *);
/*
* ns_name_ntop(src, dst, dstsiz)
* Convert an encoded domain name to printable ascii as per RFC1035.
* return:
* Number of bytes written to buffer, or -1 (with errno set)
* notes:
* The root is returned as "."
* All other domains are returned in non absolute form
*/
static int
ns_name_ntop_vlmcsd(const uint8_t *src, char *dst, size_t dstsiz)
{
const uint8_t *cp;
char *dn, *eom;
uint8_t c;
uint32_t n;
int l;
cp = src;
dn = dst;
eom = dst + dstsiz;
while ((n = *cp++) != 0) {
if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
/* Some kind of compression pointer. */
errno = EMSGSIZE;
return (-1);
}
if (dn != dst) {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '.';
}
if ((l = labellen_vlmcsd(cp - 1)) < 0) {
errno = EMSGSIZE; /* XXX */
return(-1);
}
if (dn + l >= eom) {
errno = EMSGSIZE;
return (-1);
}
if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) {
int m;
if (n != DNS_LABELTYPE_BITSTRING) {
/* XXX: labellen should reject this case */
errno = EINVAL;
return(-1);
}
if ((m = decode_bitstring_vlmcsd((const char **)&cp, dn, eom)) < 0)
{
errno = EMSGSIZE;
return(-1);
}
dn += m;
continue;
}
for ((void)NULL; l > 0; l--) {
c = *cp++;
if (special_vlmcsd(c)) {
if (dn + 1 >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\\';
*dn++ = (char)c;
} else if (!printable_vlmcsd(c)) {
if (dn + 3 >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\\';
*dn++ = digits[c / 100];
*dn++ = digits[(c % 100) / 10];
*dn++ = digits[c % 10];
} else {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = (char)c;
}
}
}
if (dn == dst) {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '.';
}
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\0';
return (dn - dst);
}
static int
ns_name_unpack_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src,
uint8_t *dst, size_t dstsiz)
{
const uint8_t *srcp, *dstlim;
uint8_t *dstp;
int n, len, checked, l;
len = -1;
checked = 0;
dstp = dst;
srcp = src;
dstlim = dst + dstsiz;
if (srcp < msg || srcp >= eom) {
errno = EMSGSIZE;
return (-1);
}
/* Fetch next label in domain name. */
while ((n = *srcp++) != 0) {
/* Check for indirection. */
switch (n & NS_CMPRSFLGS) {
case 0:
case NS_TYPE_ELT:
/* Limit checks. */
if ((l = labellen_vlmcsd(srcp - 1)) < 0) {
errno = EMSGSIZE;
return(-1);
}
if (dstp + l + 1 >= dstlim || srcp + l >= eom) {
errno = EMSGSIZE;
return (-1);
}
checked += l + 1;
*dstp++ = n;
memcpy(dstp, srcp, l);
dstp += l;
srcp += l;
break;
case NS_CMPRSFLGS:
if (srcp >= eom) {
errno = EMSGSIZE;
return (-1);
}
if (len < 0)
len = srcp - src + 1;
srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
if (srcp < msg || srcp >= eom) { /* Out of range. */
errno = EMSGSIZE;
return (-1);
}
checked += 2;
/*
* Check for loops in the compressed name;
* if we've looked at the whole message,
* there must be a loop.
*/
if (checked >= eom - msg) {
errno = EMSGSIZE;
return (-1);
}
break;
default:
errno = EMSGSIZE;
return (-1); /* flag error */
}
}
*dstp = '\0';
if (len < 0)
len = srcp - src;
return (len);
}
/*
* ns_name_uncompress_vlmcsd(msg, eom, src, dst, dstsiz)
* Expand compressed domain name to presentation format.
* return:
* Number of bytes read out of `src', or -1 (with errno set).
* note:
* Root domain returns as "." not "".
*/
int
ns_name_uncompress_vlmcsd(uint8_t *msg, uint8_t *eom, uint8_t *src,
char *dst, size_t dstsiz)
{
uint8_t tmp[NS_MAXCDNAME];
int n;
if ((n = ns_name_unpack_vlmcsd(msg, eom, src, tmp, sizeof tmp)) == -1)
return (-1);
if (ns_name_ntop_vlmcsd(tmp, dst, dstsiz) == -1)
return (-1);
return (n);
}
/*
* special(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this characted special ("in need of quoting") ?
* return:
* boolean.
*/
static int
special_vlmcsd(int ch) {
switch (ch) {
case 0x22: /* '"' */
case 0x2E: /* '.' */
case 0x3B: /* ';' */
case 0x5C: /* '\\' */
case 0x28: /* '(' */
case 0x29: /* ')' */
/* Special modifiers in zone files. */
case 0x40: /* '@' */
case 0x24: /* '$' */
return (1);
default:
return (0);
}
}
/*
* printable(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this character visible and not a space when printed ?
* return:
* boolean.
*/
static int
printable_vlmcsd(int ch) {
return (ch > 0x20 && ch < 0x7f);
}
static int
decode_bitstring_vlmcsd(const char **cpp, char *dn, const char *eom)
{
const char *cp = *cpp;
char *beg = dn, tc;
int b, blen, plen;
if ((blen = (*cp & 0xff)) == 0)
blen = 256;
plen = (blen + 3) / 4;
plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
if (dn + plen >= eom)
return(-1);
cp++;
dn += SPRINTF((dn, "\\[x"));
for (b = blen; b > 7; b -= 8, cp++)
dn += SPRINTF((dn, "%02x", *cp & 0xff));
if (b > 4) {
tc = *cp++;
dn += SPRINTF((dn, "%02x", tc & (0xff << (8 - b))));
} else if (b > 0) {
tc = *cp++;
dn += SPRINTF((dn, "%1x",
((tc >> 4) & 0x0f) & (0x0f << (4 - b))));
}
dn += SPRINTF((dn, "/%d]", blen));
*cpp = cp;
return(dn - beg);
}
static int
labellen_vlmcsd(const uint8_t *lp)
{
int bitlen;
uint8_t l = *lp;
if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
/* should be avoided by the caller */
return(-1);
}
if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) {
if (l == DNS_LABELTYPE_BITSTRING) {
if ((bitlen = *(lp + 1)) == 0)
bitlen = 256;
return((bitlen + 7 ) / 8 + 1);
}
return(-1); /* unknwon ELT */
}
return(l);
}
#endif // !NO_DNS
#endif // DNS_PARSER_INTERNAL

9
src/ns_name.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef NS_NAME_H_
#define NS_NAME_H_
int
ns_name_uncompress_vlmcsd(uint8_t *msg, uint8_t *eom, uint8_t *src,
char *dst, size_t dstsiz);
#endif /* NS_NAME_H_ */

206
src/ns_parse.c Normal file
View File

@ -0,0 +1,206 @@
/*
* Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Modified by Hotbird64 for use with vlmcs.
*/
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifdef DNS_PARSER_INTERNAL
#ifndef NO_DNS
/* Import. */
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include "types.h"
#include "endian.h"
#include "ns_name.h"
#include "ns_parse.h"
/* Macros. */
#define NS_GET16_VLMCSD(s, cp) do { \
(s) = GET_UA16BE(cp); \
(cp) += NS_INT16SZ; \
} while (0)
#define NS_GET32_VLMCSD(l, cp) do { \
(l) = GET_UA32BE(cp); \
(cp) += NS_INT32SZ; \
} while (0)
#define RETERR(err) do { errno = (err); return (-1); } while (0)
/* Forward. */
static void setsection_vlmcsd(ns_msg_vlmcsd *msg, ns_sect_vlmcsd sect);
static int dn_skipname_vlmcsd(unsigned char *s, unsigned char *end)
{
unsigned char *p;
for (p=s; p<end; p++)
if (!*p) return p-s+1;
else if (*p>=192)
{if (p+1<end) return p-s+2;
else break;}
return -1;
}
static int
ns_skiprr_vlmcsd(uint8_t *ptr, uint8_t *eom, ns_sect_vlmcsd section, int count) {
uint8_t *optr = ptr;
for ((void)NULL; count > 0; count--) {
int b, rdlength;
b = dn_skipname_vlmcsd(ptr, eom);
if (b < 0)
RETERR(EMSGSIZE);
ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
if (section != ns_s_qd_vlmcsd) {
if (ptr + NS_INT32SZ + NS_INT16SZ > eom)
RETERR(EMSGSIZE);
ptr += NS_INT32SZ/*TTL*/;
NS_GET16_VLMCSD(rdlength, ptr);
ptr += rdlength/*RData*/;
}
}
if (ptr > eom)
RETERR(EMSGSIZE);
return (ptr - optr);
}
int
ns_initparse_vlmcsd(uint8_t *msg, int msglen, ns_msg_vlmcsd *handle) {
uint8_t *eom = msg + msglen;
int i;
memset(handle, 0x5e, sizeof *handle);
handle->_msg = msg;
handle->_eom = eom;
if (msg + NS_INT16SZ > eom)
RETERR(EMSGSIZE);
NS_GET16_VLMCSD(handle->_id, msg);
if (msg + NS_INT16SZ > eom)
RETERR(EMSGSIZE);
NS_GET16_VLMCSD(handle->_flags, msg);
for (i = 0; i < ns_s_max_vlmcsd; i++) {
if (msg + NS_INT16SZ > eom)
RETERR(EMSGSIZE);
NS_GET16_VLMCSD(handle->_counts[i], msg);
}
for (i = 0; i < ns_s_max_vlmcsd; i++)
if (handle->_counts[i] == 0)
handle->_sections[i] = NULL;
else {
int b = ns_skiprr_vlmcsd(msg, eom, (ns_sect_vlmcsd)i,
handle->_counts[i]);
if (b < 0)
return (-1);
handle->_sections[i] = msg;
msg += b;
}
if (msg > eom)
RETERR(EMSGSIZE);
handle->_eom = msg;
setsection_vlmcsd(handle, ns_s_max_vlmcsd);
return (0);
}
int
ns_parserr_vlmcsd(ns_msg_vlmcsd *handle, ns_sect_vlmcsd section, int rrnum, ns_rr_vlmcsd *rr) {
int b;
/* Make section right. */
if (section >= ns_s_max_vlmcsd)
RETERR(ENODEV);
if (section != handle->_sect)
setsection_vlmcsd(handle, section);
/* Make rrnum right. */
if (rrnum == -1)
rrnum = handle->_rrnum;
if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
RETERR(ENODEV);
if (rrnum < handle->_rrnum)
setsection_vlmcsd(handle, section);
if (rrnum > handle->_rrnum) {
b = ns_skiprr_vlmcsd(handle->_msg_ptr, handle->_eom, section,
rrnum - handle->_rrnum);
if (b < 0)
return (-1);
handle->_msg_ptr += b;
handle->_rrnum = rrnum;
}
/* Do the parse. */
b = ns_name_uncompress_vlmcsd(handle->_msg, handle->_eom,
handle->_msg_ptr, rr->name, NS_MAXDNAME);
if (b < 0)
return (-1);
handle->_msg_ptr += b;
if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom)
RETERR(EMSGSIZE);
NS_GET16_VLMCSD(rr->type, handle->_msg_ptr);
NS_GET16_VLMCSD(rr->rr_class, handle->_msg_ptr);
if (section == ns_s_qd_vlmcsd) {
rr->ttl = 0;
rr->rdlength = 0;
rr->rdata = NULL;
} else {
if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
RETERR(EMSGSIZE);
NS_GET32_VLMCSD(rr->ttl, handle->_msg_ptr);
NS_GET16_VLMCSD(rr->rdlength, handle->_msg_ptr);
if (handle->_msg_ptr + rr->rdlength > handle->_eom)
RETERR(EMSGSIZE);
rr->rdata = handle->_msg_ptr;
handle->_msg_ptr += rr->rdlength;
}
if (++handle->_rrnum > handle->_counts[(int)section])
setsection_vlmcsd(handle, (ns_sect_vlmcsd)((int)section + 1));
/* All done. */
return (0);
}
/* Private. */
static void
setsection_vlmcsd(ns_msg_vlmcsd *msg, ns_sect_vlmcsd sect) {
msg->_sect = sect;
if (sect == ns_s_max_vlmcsd) {
msg->_rrnum = -1;
msg->_msg_ptr = NULL;
} else {
msg->_rrnum = 0;
msg->_msg_ptr = msg->_sections[(int)sect];
}
}
#endif // !NO_DNS
#endif // DNS_PARSER_INTERNAL

73
src/ns_parse.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef NS_PARSE_H_
#define NS_PARSE_H_
#ifndef NS_INT16SZ
#define NS_INT16SZ (sizeof(uint16_t))
#endif // NS_INT16SZ
#ifndef NS_INT32SZ
#define NS_INT32SZ (sizeof(uint32_t))
#endif // NS_INT32SZ
#ifndef NS_MAXDNAME
#define NS_MAXDNAME 1025
#endif
#define ns_msg_id_vlmcsd(handle) ((handle)._id + 0)
#define ns_msg_base_vlmcsd(handle) ((handle)._msg + 0)
#define ns_msg_end_vlmcsd(handle) ((handle)._eom + 0)
#define ns_msg_size_vlmcsd(handle) ((handle)._eom - (handle)._msg)
#define ns_msg_count_vlmcsd(handle, section) ((handle)._counts[section] + 0)
#define ns_rr_name_vlmcsd(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
#define ns_rr_type_vlmcsd(rr) ((ns_type)((rr).type + 0))
#define ns_rr_class_vlmcsd(rr) ((ns_class)((rr).rr_class + 0))
#define ns_rr_ttl_vlmcsd(rr) ((rr).ttl + 0)
#define ns_rr_rdlen_vlmcsd(rr) ((rr).rdlength + 0)
#define ns_rr_rdata_vlmcsd(rr) ((rr).rdata + 0)
#define ns_msg_id_vlmcsd(handle) ((handle)._id + 0)
#define ns_msg_base_vlmcsd(handle) ((handle)._msg + 0)
#define ns_msg_end_vlmcsd(handle) ((handle)._eom + 0)
#define ns_msg_size_vlmcsd(handle) ((handle)._eom - (handle)._msg)
#define ns_msg_count_vlmcsd(handle, section) ((handle)._counts[section] + 0)
typedef enum __ns_sect_vlmcsd {
ns_s_qd_vlmcsd = 0, /*%< Query: Question. */
ns_s_zn_vlmcsd = 0, /*%< Update: Zone. */
ns_s_an_vlmcsd = 1, /*%< Query: Answer. */
ns_s_pr_vlmcsd = 1, /*%< Update: Prerequisites. */
ns_s_ns_vlmcsd = 2, /*%< Query: Name servers. */
ns_s_ud_vlmcsd = 2, /*%< Update: Update. */
ns_s_ar_vlmcsd = 3, /*%< Query|Update: Additional records. */
ns_s_max_vlmcsd = 4
} ns_sect_vlmcsd;
typedef struct __ns_msg_vlmcsd {
uint8_t *_msg, *_eom;
uint16_t _id, _flags, _counts[ns_s_max_vlmcsd];
uint8_t *_sections[ns_s_max_vlmcsd];
ns_sect_vlmcsd _sect;
int _rrnum;
uint8_t *_msg_ptr;
} ns_msg_vlmcsd;
typedef struct __ns_rr_vlmcsd {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
uint8_t * rdata;
} ns_rr_vlmcsd;
int ns_initparse_vlmcsd(uint8_t *msg, int msglen, ns_msg_vlmcsd *handle);
int ns_parserr_vlmcsd(ns_msg_vlmcsd *handle, ns_sect_vlmcsd section, int rrnum, ns_rr_vlmcsd *rr);
#endif /* NS_PARSE_H_ */

335
src/ntservice.c Normal file
View File

@ -0,0 +1,335 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "ntservice.h"
#include "shared_globals.h"
#include "vlmcsd.h"
#include "output.h"
#include "helpers.h"
#ifdef _NTSERVICE
SERVICE_STATUS gSvcStatus;
SERVICE_STATUS_HANDLE gSvcStatusHandle;
VOID WINAPI ServiceCtrlHandler(DWORD dwCtrl)
{
// Handle the requested control code.
switch (dwCtrl)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
ServiceShutdown = TRUE;
ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
// Remove PID file and free ressources
cleanup();
# if __CYGWIN__ || defined(USE_MSRPC)
ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
# endif // __CYGWIN__
default:
break;
}
}
static VOID WINAPI ServiceMain(const int argc_unused, CARGV argv_unused)
{
// Register the handler function for the service
if (!((gSvcStatusHandle = RegisterServiceCtrlHandler(NT_SERVICE_NAME, ServiceCtrlHandler))))
{
return;
}
// These SERVICE_STATUS members remain as set here
gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
gSvcStatus.dwServiceSpecificExitCode = 0;
// Run the actual program
ReportServiceStatus(SERVICE_STOPPED, newmain(), 3000);
}
SERVICE_TABLE_ENTRY NTServiceDispatchTable[] = {
{
(LPSTR)NT_SERVICE_NAME,
(LPSERVICE_MAIN_FUNCTION)ServiceMain
},
{
NULL,
NULL
}
};
VOID ReportServiceStatus(const DWORD dwCurrentState, const DWORD dwWin32ExitCode, const DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
// Fill in the SERVICE_STATUS structure.
gSvcStatus.dwCurrentState = dwCurrentState;
gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
gSvcStatus.dwWaitHint = dwWaitHint;
if (dwCurrentState == SERVICE_START_PENDING)
gSvcStatus.dwControlsAccepted = 0;
else
gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
if ((dwCurrentState == SERVICE_RUNNING) ||
(dwCurrentState == SERVICE_STOPPED))
gSvcStatus.dwCheckPoint = 0;
else
gSvcStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the SCM.
SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
}
/*VOID ServiceReportEvent(char *szFunction)
{
HANDLE hEventSource;
const char *eventStrings[2];
TCHAR Buffer[80];
hEventSource = RegisterEventSource(NULL, NT_SERVICE_NAME);
if (hEventSource)
{
snprintf(Buffer, 80, "%s failed with %d", szFunction, GetLastError());
eventStrings[0] = NT_SERVICE_NAME;
eventStrings[1] = Buffer;
ReportEvent(hEventSource, // event log handle
EVENTLOG_ERROR_TYPE, // event type
0, // event category
00, // event identifier
NULL, // no security identifier
2, // size of lpszStrings array
0, // no binary data
eventStrings, // array of strings
NULL); // no binary data
DeregisterEventSource(hEventSource);
}
}*/
//Returns 0=Error, 1=Success, 2=Doesn't exist
static uint_fast8_t OpenAndRemoveService(DWORD *dwPreviousState, SC_HANDLE *schSCManager)
{
SERVICE_STATUS status;
uint_fast8_t i;
SC_HANDLE installedService;
uint_fast8_t result = 1;
BOOL closeManager = FALSE;
// Allow NULL for both Arguments
if (!dwPreviousState) dwPreviousState = (DWORD*)alloca(sizeof(*dwPreviousState));
if (!schSCManager)
{
schSCManager = (SC_HANDLE*)alloca(sizeof(*schSCManager));
closeManager = TRUE;
}
*schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (!*schSCManager) return 0;
if (!((installedService = OpenService(*schSCManager, NT_SERVICE_NAME, SERVICE_ALL_ACCESS))))
{
result = 2;
}
else
{
*dwPreviousState = SERVICE_STOPPED;
if (QueryServiceStatus(installedService, &status)) *dwPreviousState = status.dwCurrentState;
ControlService(installedService, SERVICE_CONTROL_STOP, &status);
for (i = 0; i < 10; i++)
{
QueryServiceStatus(installedService, &status);
// Give it 100 ms after it reported SERVICE_STOPPED. Subsequent CreateService will fail otherwise
Sleep(100);
if (status.dwCurrentState == SERVICE_STOPPED) break;
}
if (!DeleteService(installedService)) result = 0;
CloseServiceHandle(installedService);
}
if (closeManager) CloseServiceHandle(*schSCManager);
return result;
}
static VOID ServiceInstaller(const char *restrict ServiceUser, const char *const ServicePassword)
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
char szPath[MAX_PATH] = "\"";
if (!GetModuleFileName(NULL, szPath + sizeof(char), MAX_PATH - 1))
{
errorout("Cannot install service (%d)\n", (uint32_t)GetLastError());
return;
}
strcat(szPath, "\"");
int i;
for (i = 1; i < global_argc; i++)
{
// Strip unneccessary parameters, especially the password
if (!strcmp(global_argv[i], "-s")) continue;
if (!strcmp(global_argv[i], "-W") ||
!strcmp(global_argv[i], "-U"))
{
i++;
continue;
}
strcat(szPath, " ");
if (strchr(global_argv[i], ' '))
{
strcat(szPath, "\"");
strcat(szPath, global_argv[i]);
strcat(szPath, "\"");
}
else
strcat(szPath, global_argv[i]);
}
// Get a handle to the SCM database.
SERVICE_STATUS status;
DWORD dwPreviousState;
if (!OpenAndRemoveService(&dwPreviousState, &schSCManager))
{
errorout("Service removal failed (%d)\n", (uint32_t)GetLastError());
return;
}
char *tempUser = NULL;
if (ServiceUser)
{
// Shortcuts for some well known users
if (!strcasecmp(ServiceUser, "/l")) ServiceUser = "NT AUTHORITY\\LocalService";
if (!strcasecmp(ServiceUser, "/n")) ServiceUser = "NT AUTHORITY\\NetworkService";
// Allow Local Users without .\ , e.g. "johndoe" instead of ".\johndoe"
if (!strchr(ServiceUser, '\\'))
{
tempUser = (char*)vlmcsd_malloc(strlen(ServiceUser) + 3);
strcpy(tempUser, ".\\");
strcat(tempUser, ServiceUser);
ServiceUser = tempUser;
}
}
schService = CreateService(
schSCManager, // SCM database
NT_SERVICE_NAME, // name of service
NT_SERVICE_DISPLAY_NAME, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // path to service's binary
NULL, // no load ordering group
NULL, // no tag identifier
"tcpip\0", // depends on TCP/IP
ServiceUser, // LocalSystem account
ServicePassword); // no password
# if __clang__ && (__CYGWIN__ || __MINGW64__ )
// Workaround for clang not understanding some GCC asm syntax used in <w32api/psdk_inc/intrin-impl.h>
ZeroMemory((char*)ServicePassword, strlen(ServicePassword));
# else
SecureZeroMemory((char*)ServicePassword, strlen(ServicePassword));
# endif
if (tempUser) free(tempUser);
if (schService == NULL)
{
errorout("CreateService failed (%u)\n", (uint32_t)GetLastError());
CloseServiceHandle(schSCManager);
return;
}
else
{
errorout("Service installed successfully\n");
if (dwPreviousState == SERVICE_RUNNING)
{
printf("Restarting " NT_SERVICE_NAME " service => ");
status.dwCurrentState = SERVICE_STOPPED;
if (StartService(schService, 0, NULL))
{
for (i = 0; i < 10; i++)
{
if (!QueryServiceStatus(schService, &status) || status.dwCurrentState != SERVICE_START_PENDING) break;
Sleep(100);
}
if (status.dwCurrentState == SERVICE_RUNNING)
printf("Success\n");
else if (status.dwCurrentState == SERVICE_START_PENDING)
printf("Not ready within a second\n");
else
errorout("Error\n");
}
else
errorout("Error %u\n", (uint32_t)GetLastError());
}
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
int NtServiceInstallation(const int_fast8_t installService, const char *restrict ServiceUser, const char *const ServicePassword)
{
if (IsNTService) return 0;
if (installService == 1) // Install
{
ServiceInstaller(ServiceUser, ServicePassword);
return(0);
}
if (installService == 2) // Remove
{
switch (OpenAndRemoveService(NULL, NULL))
{
case 0:
errorout("Error removing service %s\n", NT_SERVICE_NAME);
return(!0);
case 1:
printf("Service %s removed successfully\n", NT_SERVICE_NAME);
return(0);
default:
errorout("Service %s does not exist.\n", NT_SERVICE_NAME);
return(!0);
}
}
// Do nothing
return(0);
}
#endif // _NTSERVICE

28
src/ntservice.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef INCLUDED_NTSERVICE_H
#define INCLUDED_NTSERVICE_H
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "types.h"
#ifdef _NTSERVICE
//#include <strsafe.h>
#define NT_SERVICE_NAME "vlmcsd"
#define NT_SERVICE_DISPLAY_NAME "Key Management Server"
extern SERVICE_TABLE_ENTRY NTServiceDispatchTable[];
VOID ReportServiceStatus(const DWORD, const DWORD, const DWORD);
int NtServiceInstallation(const int_fast8_t installService, const char *restrict ServiceUser, const char *const ServicePassword);
#else // !_NTSERVICE
#define ReportServiceStatus(x,y,z)
#endif // _NTSERVICE
#endif // INCLUDED_NTSERVICE_H

667
src/output.c Normal file
View File

@ -0,0 +1,667 @@
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE
#endif // _DEFAULT_SOURCE
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "output.h"
#include "shared_globals.h"
#include "endian.h"
#include "helpers.h"
// ReSharper disable All
#ifndef NO_LOG
static void vlogger(const char *message, va_list args)
{
FILE *log;
# ifdef _NTSERVICE
if (!IsNTService && logstdout) log = stdout;
# else
if (logstdout) log = stdout;
# endif
else
{
if (fn_log == NULL) return;
# ifndef _WIN32
if (!strcmp(fn_log, "syslog"))
{
openlog("vlmcsd", LOG_CONS | LOG_PID, LOG_USER);
////PORTABILITY: vsyslog is not in Posix but virtually all Unixes have it
vsyslog(LOG_INFO, message, args);
closelog();
return;
}
# endif // _WIN32
log = fopen(fn_log, "a");
if (!log) return;
}
time_t now = time(0);
# ifdef USE_THREADS
char mbstr[2048];
# else
char mbstr[24];
# endif
if (LogDateAndTime)
strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X: ", localtime(&now));
else
*mbstr = 0;
# ifndef USE_THREADS
fprintf(log, "%s", mbstr);
vfprintf(log, message, args);
fflush(log);
# else // USE_THREADS
// We write everything to a string before we really log inside the critical section
// so formatting the output can be concurrent
int len = (int)strlen(mbstr);
//# if !_MSC_VER
vlmcsd_vsnprintf(mbstr + len, sizeof(mbstr) - len, message, args);
//# else
// wvsprintf(mbstr + len, message, args);
//# endif
lock_mutex(&logmutex);
fprintf(log, "%s", mbstr);
fflush(log);
unlock_mutex(&logmutex);
# endif // USE_THREADS
if (log != stdout) fclose(log);
}
// Always sends to log output
int logger(const char *const fmt, ...)
{
va_list args;
va_start(args, fmt);
vlogger(fmt, args);
va_end(args);
return 0;
}
#endif //NO_LOG
// Output to stderr if it is available or to log otherwise (e.g. if running as daemon/service)
int printerrorf(const char *const fmt, ...)
{
int error = errno;
va_list arglist;
va_start(arglist, fmt);
# ifdef IS_LIBRARY
size_t len = strlen(ErrorMessage);
vlmcsd_vsnprintf(ErrorMessage + len, MESSAGE_BUFFER_SIZE - len - 1, fmt, arglist);
# else // !IS_LIBRARY
# ifndef NO_LOG
# ifdef _NTSERVICE
if (InetdMode || IsNTService)
# else // !_NTSERVICE
if (InetdMode)
# endif // NTSERVIICE
vlogger(fmt, arglist);
else
# endif //NO_LOG
# endif // IS_LIBRARY
{
vfprintf(stderr, fmt, arglist);
fflush(stderr);
}
va_end(arglist);
errno = error;
return 0;
}
// Always output to stderr
int errorout(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
int i = vfprintf(stderr, fmt, args);
va_end(args);
fflush(stderr);
return i;
}
#if !defined(NO_VERBOSE_LOG) && !defined(NO_LOG)
static const char *LicenseStatusText[] =
{
"Unlicensed", "Licensed", "OOB grace", "OOT grace", "Non-Genuine", "Notification", "Extended grace"
};
#endif // !defined(NO_VERBOSE_LOG) && !defined(NO_LOG)
void uuid2StringLE(const GUID *const guid, char *const string)
{
sprintf(string,
# ifdef _WIN32
"%08x-%04x-%04x-%04x-%012I64x",
# else
"%08x-%04x-%04x-%04x-%012llx",
# endif
(unsigned int)LE32(guid->Data1),
(unsigned int)LE16(guid->Data2),
(unsigned int)LE16(guid->Data3),
(unsigned int)BE16(*(uint16_t*)guid->Data4),
(unsigned long long)BE64(*(uint64_t*)(guid->Data4)) & 0xffffffffffffLL
);
}
#if !defined(NO_VERBOSE_LOG) && !defined(NO_LOG)
void logRequestVerbose(REQUEST* Request, const PRINTFUNC p)
{
char guidBuffer[GUID_STRING_LENGTH + 1];
char WorkstationBuffer[3 * WORKSTATION_NAME_BUFFER];
char* productName;
p("Protocol version : %u.%u\n", LE16(Request->MajorVer), LE16(Request->MinorVer));
p("Client is a virtual machine : %s\n", LE32(Request->VMInfo) ? "Yes" : "No");
p("Licensing status : %u (%s)\n", (uint32_t)LE32(Request->LicenseStatus), LE32(Request->LicenseStatus) < vlmcsd_countof(LicenseStatusText) ? LicenseStatusText[LE32(Request->LicenseStatus)] : "Unknown");
p("Remaining time (0 = forever) : %i minutes\n", (uint32_t)LE32(Request->BindingExpiration));
uuid2StringLE(&Request->AppID, guidBuffer);
getProductIndex(&Request->AppID, KmsData->AppItemList, KmsData->AppItemCount, &productName, NULL);
p("Application ID : %s (%s)\n", guidBuffer, productName);
uuid2StringLE(&Request->ActID, guidBuffer);
getProductIndex(&Request->ActID, KmsData->SkuItemList, KmsData->SkuItemCount, &productName, NULL);
p("SKU ID (aka Activation ID) : %s (%s)\n", guidBuffer, productName);
uuid2StringLE(&Request->KMSID, guidBuffer);
getProductIndex(&Request->KMSID, KmsData->KmsItemList, KmsData->KmsItemCount, &productName, NULL);
p("KMS ID (aka KMS counted ID) : %s (%s)\n", guidBuffer, productName);
uuid2StringLE(&Request->CMID, guidBuffer);
p("Client machine ID : %s\n", guidBuffer);
uuid2StringLE(&Request->CMID_prev, guidBuffer);
p("Previous client machine ID : %s\n", guidBuffer);
char mbstr[64];
time_t st;
st = fileTimeToUnixTime(&Request->ClientTime);
strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", gmtime(&st));
p("Client request timestamp (UTC) : %s\n", mbstr);
ucs2_to_utf8(Request->WorkstationName, WorkstationBuffer, WORKSTATION_NAME_BUFFER, sizeof(WorkstationBuffer));
p("Workstation name : %s\n", WorkstationBuffer);
p("N count policy (minimum clients): %u\n", (uint32_t)LE32(Request->N_Policy));
}
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, RESPONSE* response, const PRINTFUNC p)
{
char guidBuffer[GUID_STRING_LENGTH + 1];
p("Protocol version : %u.%u\n", (uint32_t)LE16(response->MajorVer), (uint32_t)LE16(response->MinorVer));
p("KMS host extended PID : %s\n", ePID);
if (LE16(response->MajorVer) > 5)
# ifndef _WIN32
p("KMS host Hardware ID : %016llX\n", (unsigned long long)BE64(*(uint64_t*)hwid));
# else // _WIN32
p("KMS host Hardware ID : %016I64X\n", (unsigned long long)BE64(*(uint64_t*)hwid));
# endif // WIN32
uuid2StringLE(&response->CMID, guidBuffer);
p("Client machine ID : %s\n", guidBuffer);
char mbstr[64];
time_t st;
st = fileTimeToUnixTime(&response->ClientTime);
strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", gmtime(&st));
p("Client request timestamp (UTC) : %s\n", mbstr);
p("KMS host current active clients : %u\n", (uint32_t)LE32(response->Count));
p("Renewal interval policy : %u\n", (uint32_t)LE32(response->VLRenewalInterval));
p("Activation interval policy : %u\n", (uint32_t)LE32(response->VLActivationInterval));
}
#endif // !defined(NO_VERBOSE_LOG) && !defined(NO_LOG)
#ifndef NO_VERSION_INFORMATION
void printPlatform()
{
int testNumber = 0x1234;
# if _MSC_VER
printf("Compiler: VC++ %02i.%02i build %i\n", _MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000);
# elif defined(VLMCSD_COMPILER)
printf
(
"Compiler: %s\n", VLMCSD_COMPILER
# ifdef __VERSION__
" " __VERSION__
# endif // __VERSION__
);
# endif // VLMCSD_COMPILER
printf
(
"Intended platform:%s %s\n", ""
# if __i386__ || _M_IX86
" Intel x86"
# endif
# if __x86_64__ || __amd64__ || _M_X64 || _M_AMD64
" Intel x86_64"
# endif
# if _M_ARM || __arm__
" ARM"
# endif
# if __thumb__
" thumb"
# endif
# if __aarch64__
" ARM64"
# endif
# if __hppa__
" HP/PA RISC"
# endif
# if __ia64__
" Intel Itanium"
# endif
# if __mips__
" MIPS"
# endif
# if defined(_MIPS_ARCH)
" " _MIPS_ARCH
# endif
# if __mips16
" mips16"
# endif
# if __mips_micromips
" micromips"
# endif
# if __ppc__ || __powerpc__
" PowerPC"
# endif
# if __powerpc64__ || __ppc64__
" PowerPC64"
# endif
# if __sparc__
" SPARC"
# endif
# if defined(__s390__) && !defined(__zarch__) && !defined(__s390x__)
" IBM S/390"
# endif
# if __zarch__ || __s390x__
" IBM z/Arch (S/390x)"
# endif
# if __m68k__
" Motorola 68k"
# endif
# if __ANDROID__
" Android"
# endif
# if __ANDROID_API__
" (API level " ANDROID_API_LEVEL ")"
# endif
# if __FreeBSD__ || __FreeBSD_kernel__
" FreeBSD"
# endif
# if __NetBSD__
" NetBSD"
# endif
# if __OpenBSD__
" OpenBSD"
# endif
# if __DragonFly__
" DragonFly BSD"
# endif
# if defined(__CYGWIN__) && !defined(_WIN64)
" Cygwin32"
# endif
# if defined(__CYGWIN__) && defined(_WIN64)
" Cygwin64"
# endif
# if __GNU__
" GNU"
# endif
# if __gnu_hurd__
" Hurd"
# endif
# if __MACH__
" Mach"
# endif
# if __linux__
" Linux"
# endif
# if __APPLE__ && __MACH__
" Darwin"
# endif
# if __minix__
" Minix"
# endif
# if __QNX__
" QNX"
# endif
# if __svr4__ || __SVR4
" SYSV R4"
# endif
# if (defined(__sun__) || defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__))
" Solaris"
# endif
# if (defined(__sun__) || defined(sun) || defined(__sun)) && !defined(__SVR4) && !defined(__svr4__)
" SunOS"
# endif
# if defined(_WIN32) && !defined(_WIN64)
" Windows32"
# endif
# if defined(_WIN32) && defined(_WIN64)
" Windows64"
# endif
# if __MVS__ || __TOS_MVS__
" z/OS"
# endif
# if defined(__GLIBC__) && !defined(__UCLIBC__)
" glibc"
# endif
# if __UCLIBC__
" uclibc"
# endif
# if defined(__linux__) && !defined(__GLIBC__) && !defined(__UCLIBC__) && !defined(__ANDROID__) && !defined(__BIONIC__)
" musl"
# endif
//# if _MIPSEL || __MIPSEL__ || __ARMEL__ || __THUMBEL__
// " little-endian"
//# endif
//
//# if _MIPSEB || __MIPSEB__ || __ARMEB__ || __THUMBEB__
// " big-endian"
//# endif
# if __PIE__ || __pie__
" PIE"
# endif
,
*((uint8_t*)&testNumber) == 0x34 ? "little-endian" : "big-endian"
);
}
void printCommonFlags()
{
printf
(
"Common flags:%s\n", ""
# ifdef NO_EXTERNAL_DATA
" NO_EXTERNAL_DATA"
# endif // NO_EXTERNAL_DATA
# ifdef NO_INTERNAL_DATA
" NO_INTERNAL_DATA"
# endif // NO_INTERNAL_DATA
# if !defined(NO_EXTERNAL_DATA)
# ifdef DATA_FILE
" DATA=" DATA_FILE
# endif // DATA_FILE
# ifdef UNSAFE_DATA_LOAD
" UNSAFE_DATA_LOAD"
# endif // UNSAFE_DATA_LOAD
# endif // !defined(NO_EXTERNAL_DATA)
# ifdef USE_MSRPC
" USE_MSRPC"
# endif // USE_MSRPC
# ifdef _CRYPTO_OPENSSL
" _CRYPTO_OPENSSL"
# endif // _CRYPTO_OPENSSL
# ifdef _CRYPTO_POLARSSL
" _CRYPTO_POLARSSL"
# endif // _CRYPTO_POLARSSL
# ifdef _CRYPTO_WINDOWS
" _CRYPTO_WINDOWS"
# endif // _CRYPTO_WINDOWS
# if defined(_OPENSSL_SOFTWARE) && defined(_CRYPTO_OPENSSL)
" _OPENSSL_SOFTWARE"
# endif // _OPENSSL_SOFTWARE
# if defined(_USE_AES_FROM_OPENSSL) && defined(_CRYPTO_OPENSSL)
" _USE_AES_FROM_OPENSSL"
# endif // _USE_AES_FROM_OPENSSL
# if defined(_OPENSSL_NO_HMAC) && defined(_CRYPTO_OPENSSL)
" OPENSSL_HMAC=0"
# endif // _OPENSSL_NO_HMAC
# ifdef _PEDANTIC
" _PEDANTIC"
# endif // _PEDANTIC
# ifdef INCLUDE_BETAS
" INCLUDE_BETAS"
# endif // INCLUDE_BETAS
# if __minix__ || defined(NO_TIMEOUT)
" NO_TIMEOUT=1"
# endif // __minix__ || defined(NO_TIMEOUT)
);
}
void printClientFlags()
{
printf
(
"vlmcs flags:%s\n", ""
# ifdef NO_DNS
" NO_DNS=1"
# endif
# if !defined(NO_DNS)
# if defined(DNS_PARSER_INTERNAL) && !defined(_WIN32)
" DNS_PARSER=internal"
# else // !defined(DNS_PARSER_INTERNAL) || defined(_WIN32)
" DNS_PARSER=OS"
# endif // !defined(DNS_PARSER_INTERNAL) || defined(_WIN32)
# endif // !defined(NO_DNS)
# if defined(DISPLAY_WIDTH)
" TERMINAL_WIDTH=" DISPLAY_WIDTH
# endif
);
}
void printServerFlags()
{
printf
(
"vlmcsd flags:%s\n", ""
# ifdef NO_LOG
" NO_LOG"
# endif // NO_LOG
# ifdef NO_RANDOM_EPID
" NO_RANDOM_EPID"
# endif // NO_RANDOM_EPID
# ifdef NO_INI_FILE
" NO_INI_FILE"
# endif // NO_INI_FILE
# if !defined(NO_INI_FILE) && defined(INI_FILE)
" INI=" INI_FILE
# endif // !defined(NO_INI_FILE)
# ifdef NO_PID_FILE
" NO_PID_FILE"
# endif // NO_PID_FILE
# ifdef NO_USER_SWITCH
" NO_USER_SWITCH"
# endif // NO_USER_SWITCH
# ifdef NO_HELP
" NO_HELP"
# endif // NO_HELP
# ifdef NO_STRICT_MODES
" NO_STRICT_MODES"
# endif // NO_STRICT_MODES
# ifdef NO_CUSTOM_INTERVALS
" NO_CUSTOM_INTERVALS"
# endif // NO_CUSTOM_INTERVALS
# ifdef NO_SOCKETS
" NO_SOCKETS"
# endif // NO_SOCKETS
# ifdef NO_CL_PIDS
" NO_CL_PIDS"
# endif // NO_CL_PIDS
# ifdef NO_LIMIT
" NO_LIMIT"
# endif // NO_LIMIT
# ifdef NO_SIGHUP
" NO_SIGHUP"
# endif // NO_SIGHUP
# ifdef NO_PROCFS
" NOPROCFS=1"
# endif // NO_PROCFS
# ifdef USE_THREADS
" THREADS=1"
# endif // USE_THREADS
# ifdef USE_AUXV
" AUXV=1"
# endif // USE_AUXV
# if defined(CHILD_HANDLER) || __minix__
" CHILD_HANDLER=1"
# endif // defined(CHILD_HANDLER) || __minix__
# if !defined(NO_SOCKETS) && defined(SIMPLE_SOCKETS)
" SIMPLE_SOCKETS"
# endif // !defined(NO_SOCKETS) && defined(SIMPLE_SOCKETS)
# ifdef SIMPLE_RPC
" SIMPLE_RPC"
# endif // SIMPLE_RPC
# ifdef NO_STRICT_MODES
" NO_STRICT_MODES"
# endif // NO_STRICT_MODES
# ifdef NO_CLIENT_LIST
" NO_CLIENT_LIST"
# endif // NO_CLIENT_LIST
# if (_WIN32 || __CYGWIN__) && (!defined(USE_MSRPC) || defined(SUPPORT_WINE))
" SUPPORT_WINE"
# endif // (_WIN32 || __CYGWIN__) && (!defined(USE_MSRPC) || defined(SUPPORT_WINE))
# if (_WIN32 || __CYGWIN__) && defined(NO_TAP)
" NO_TAP"
# endif // (_WIN32 || __CYGWIN__) && defined(NO_TAP)
# if !HAVE_FREEBIND
" NO_FREEBIND"
# endif //!HAVE_FREEBIND
# if !HAVE_GETIFADDR
" !HAVE_GETIFADDR"
# endif // !HAVE_GETIFADDR
# if HAVE_GETIFADDR && defined(GETIFADDRS_MUSL)
" GETIFADDRS=musl"
# endif // HAVE_GETIFADDR && defined(GETIFADDRS_MUSL)
# if defined(NO_PRIVATE_IP_DETECT)
" NO_PRIVATE_IP_DETECT"
# endif // defined(NO_PRIVATE_IP_DETECT)
);
}
#endif // NO_VERSION_INFORMATION

36
src/output.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef INCLUDED_OUTPUT_H
#define INCLUDED_OUTPUT_H
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include <errno.h>
#include "types.h"
#include "kms.h"
typedef int (*PRINTFUNC)(const char *const fmt, ...);
int printerrorf(const char *const fmt, ...);
int errorout(const char* fmt, ...);
void logRequestVerbose(REQUEST* Request, const PRINTFUNC p);
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, RESPONSE* response, const PRINTFUNC p);
#ifndef NO_VERSION_INFORMATION
void printPlatform();
void printCommonFlags();
void printServerFlags();
void printClientFlags();
#endif // NO_VERSION_INFORMATION
#ifndef NO_LOG
int logger(const char *const fmt, ...);
#endif //NO_LOG
void uuid2StringLE(const GUID *const guid, char *const string);
//void copy_arguments(int argc, char **argv, char ***new_argv);
//void destroy_arguments(int argc, char **argv);
#endif // INCLUDED_OUTPUT_H

499
src/resolv.h Normal file
View File

@ -0,0 +1,499 @@
/* $NetBSD: resolv.h,v 1.31 2005/12/26 19:01:47 perry Exp $ */
/*
* Copyright (c) 1983, 1987, 1989
* The Regents of the University of California. 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. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* @(#)resolv.h 8.1 (Berkeley) 6/2/93
* Id: resolv.h,v 1.7.2.11.4.2 2004/06/25 00:41:05 marka Exp
*/
#ifndef _RESOLV_PRIVATE_H_
#define _RESOLV_PRIVATE_H_
#include <resolv.h>
#include "resolv_static.h"
/*
* Revision information. This is the release date in YYYYMMDD format.
* It can change every day so the right thing to do with it is use it
* in preprocessor commands such as "#if (__RES > 19931104)". Do not
* compare for equality; rather, use it to determine whether your resolver
* is new enough to contain a certain feature.
*/
#define __RES 20030124
/*
* This used to be defined in res_query.c, now it's in herror.c.
* [XXX no it's not. It's in irs/irs_data.c]
* It was
* never extern'd by any *.h file before it was placed here. For thread
* aware programs, the last h_errno value set is stored in res->h_errno.
*
* XXX: There doesn't seem to be a good reason for exposing RES_SET_H_ERRNO
* (and __h_errno_set) to the public via <resolv.h>.
* XXX: __h_errno_set is really part of IRS, not part of the resolver.
* If somebody wants to build and use a resolver that doesn't use IRS,
* what do they do? Perhaps something like
* #ifdef WANT_IRS
* # define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x)
* #else
* # define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x))
* #endif
*/
#define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x))
struct __res_state; /* forward */
/*
* Resolver configuration file.
* Normally not present, but may contain the address of the
* initial name server(s) to query and the domain search list.
*/
#ifndef _PATH_RESCONF
#ifdef ANDROID_CHANGES
#define _PATH_RESCONF "/etc/ppp/resolv.conf"
#else
#define _PATH_RESCONF "/etc/resolv.conf"
#endif
#endif
typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
res_sendhookact;
typedef res_sendhookact (*res_send_qhook)(struct sockaddr * const *,
const u_char **, int *,
u_char *, int, int *);
typedef res_sendhookact (*res_send_rhook)(const struct sockaddr *,
const u_char *, int, u_char *,
int, int *);
struct res_sym {
int number; /* Identifying number, like T_MX */
const char * name; /* Its symbolic name, like "MX" */
const char * humanname; /* Its fun name, like "mail exchanger" */
};
/*
* Global defines and variables for resolver stub.
*/
#define MAXNS 3 /* max # name servers we'll track */
#define MAXDFLSRCH 3 /* # default domain levels to try */
#define MAXDNSRCH 6 /* max # domains in search path */
#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
#define RES_TIMEOUT 5 /* min. seconds between retries */
#define MAXRESOLVSORT 10 /* number of net to sort on */
#define RES_MAXNDOTS 15 /* should reflect bit field size */
#define RES_MAXRETRANS 30 /* only for resolv.conf/RES_OPTIONS */
#define RES_MAXRETRY 5 /* only for resolv.conf/RES_OPTIONS */
#define RES_DFLRETRY 2 /* Default #/tries. */
#define RES_MAXTIME 65535 /* Infinity, in milliseconds. */
struct __res_state_ext;
struct __res_state {
int retrans; /* retransmission time interval */
int retry; /* number of times to retransmit */
#ifdef sun
u_int options; /* option flags - see below. */
#else
u_long options; /* option flags - see below. */
#endif
int nscount; /* number of name servers */
struct sockaddr_in
nsaddr_list[MAXNS]; /* address of name server */
#define nsaddr nsaddr_list[0] /* for backward compatibility */
u_short id; /* current message id */
char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
char defdname[256]; /* default domain (deprecated) */
#ifdef sun
u_int pfcode; /* RES_PRF_ flags - see below. */
#else
u_long pfcode; /* RES_PRF_ flags - see below. */
#endif
unsigned ndots:4; /* threshold for initial abs. query */
unsigned nsort:4; /* number of elements in sort_list[] */
char unused[3];
struct {
struct in_addr addr;
uint32_t mask;
} sort_list[MAXRESOLVSORT];
#ifdef __OLD_RES_STATE
char lookups[4];
#else
res_send_qhook qhook; /* query hook */
res_send_rhook rhook; /* response hook */
int res_h_errno; /* last one set for this context */
int _vcsock; /* PRIVATE: for res_send VC i/o */
u_int _flags; /* PRIVATE: see below */
u_int _pad; /* make _u 64 bit aligned */
union {
/* On an 32-bit arch this means 512b total. */
char pad[72 - 4*sizeof (int) - 2*sizeof (void *)];
struct {
uint16_t nscount;
uint16_t nstimes[MAXNS]; /* ms. */
int nssocks[MAXNS];
struct __res_state_ext *ext; /* extention for IPv6 */
} _ext;
} _u;
#endif
struct res_static rstatic[1];
};
typedef struct __res_state *res_state;
union res_sockaddr_union {
struct sockaddr_in sin;
#ifdef IN6ADDR_ANY_INIT
struct sockaddr_in6 sin6;
#endif
#ifdef ISC_ALIGN64
int64_t __align64; /* 64bit alignment */
#else
int32_t __align32; /* 32bit alignment */
#endif
char __space[128]; /* max size */
};
/*
* Resolver flags (used to be discrete per-module statics ints).
*/
#define RES_F_VC 0x00000001 /* socket is TCP */
#define RES_F_CONN 0x00000002 /* socket is connected */
#define RES_F_EDNS0ERR 0x00000004 /* EDNS0 caused errors */
#define RES_F__UNUSED 0x00000008 /* (unused) */
#define RES_F_LASTMASK 0x000000F0 /* ordinal server of last res_nsend */
#define RES_F_LASTSHIFT 4 /* bit position of LASTMASK "flag" */
#define RES_GETLAST(res) (((res)._flags & RES_F_LASTMASK) >> RES_F_LASTSHIFT)
/* res_findzonecut2() options */
#define RES_EXHAUSTIVE 0x00000001 /* always do all queries */
#define RES_IPV4ONLY 0x00000002 /* IPv4 only */
#define RES_IPV6ONLY 0x00000004 /* IPv6 only */
/*
* Resolver options (keep these in synch with res_debug.c, please)
*/
#define RES_INIT 0x00000001 /* address initialized */
#define RES_DEBUG 0x00000002 /* print debug messages */
#define RES_AAONLY 0x00000004 /* authoritative answers only (!IMPL)*/
#define RES_USEVC 0x00000008 /* use virtual circuit */
#define RES_PRIMARY 0x00000010 /* query primary server only (!IMPL) */
#define RES_IGNTC 0x00000020 /* ignore trucation errors */
#define RES_RECURSE 0x00000040 /* recursion desired */
#define RES_DEFNAMES 0x00000080 /* use default domain name */
#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */
#define RES_DNSRCH 0x00000200 /* search up local domain tree */
#define RES_INSECURE1 0x00000400 /* type 1 security disabled */
#define RES_INSECURE2 0x00000800 /* type 2 security disabled */
#define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */
#define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */
#define RES_ROTATE 0x00004000 /* rotate ns list after each query */
#define RES_NOCHECKNAME 0x00008000 /* do not check names for sanity. */
#define RES_KEEPTSIG 0x00010000 /* do not strip TSIG records */
#define RES_BLAST 0x00020000 /* blast all recursive servers */
#define RES_NOTLDQUERY 0x00100000 /* don't unqualified name as a tld */
#define RES_USE_DNSSEC 0x00200000 /* use DNSSEC using OK bit in OPT */
/* #define RES_DEBUG2 0x00400000 */ /* nslookup internal */
/* KAME extensions: use higher bit to avoid conflict with ISC use */
#define RES_USE_DNAME 0x10000000 /* use DNAME */
#define RES_USE_EDNS0 0x40000000 /* use EDNS0 if configured */
#define RES_NO_NIBBLE2 0x80000000 /* disable alternate nibble lookup */
#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | \
RES_DNSRCH | RES_NO_NIBBLE2)
/*
* Resolver "pfcode" values. Used by dig.
*/
#define RES_PRF_STATS 0x00000001
#define RES_PRF_UPDATE 0x00000002
#define RES_PRF_CLASS 0x00000004
#define RES_PRF_CMD 0x00000008
#define RES_PRF_QUES 0x00000010
#define RES_PRF_ANS 0x00000020
#define RES_PRF_AUTH 0x00000040
#define RES_PRF_ADD 0x00000080
#define RES_PRF_HEAD1 0x00000100
#define RES_PRF_HEAD2 0x00000200
#define RES_PRF_TTLID 0x00000400
#define RES_PRF_HEADX 0x00000800
#define RES_PRF_QUERY 0x00001000
#define RES_PRF_REPLY 0x00002000
#define RES_PRF_INIT 0x00004000
#define RES_PRF_TRUNC 0x00008000
/* 0x00010000 */
/* Things involving an internal (static) resolver context. */
__BEGIN_DECLS
extern struct __res_state *__res_get_state(void);
extern void __res_put_state(struct __res_state *);
#ifndef ANDROID_CHANGES
/*
* Source and Binary compatibility; _res will not work properly
* with multi-threaded programs.
*/
extern struct __res_state *__res_state(void);
#define _res (*__res_state())
#endif
__END_DECLS
#ifndef __BIND_NOSTATIC
#define fp_nquery __fp_nquery
#define fp_query __fp_query
#define hostalias __hostalias
#define p_query __p_query
#define res_close __res_close
#define res_opt __res_opt
#define res_isourserver __res_isourserver
#define res_querydomain __res_querydomain
#define res_send __res_send
#define res_sendsigned __res_sendsigned
#ifdef BIND_RES_POSIX3
#define dn_expand __dn_expand
#define res_init __res_init
#define res_query __res_query
#define res_search __res_search
#define res_mkquery __res_mkquery
#endif
__BEGIN_DECLS
void fp_nquery(const u_char *, int, FILE *);
void fp_query(const u_char *, FILE *);
const char * hostalias(const char *);
void p_query(const u_char *);
void res_close(void);
int res_init(void);
int res_opt(int, u_char *, int, int);
int res_isourserver(const struct sockaddr_in *);
int res_mkquery(int, const char *, int, int, const u_char *, int, const u_char *, u_char *, int);
int res_query(const char *, int, int, u_char *, int);
int res_querydomain(const char *, const char *, int, int, u_char *, int);
int res_search(const char *, int, int, u_char *, int);
int res_send(const u_char *, int, u_char *, int);
int res_sendsigned(const u_char *, int, ns_tsig_key *, u_char *, int);
__END_DECLS
#endif
#if !defined(SHARED_LIBBIND) || defined(LIB)
/*
* If libbind is a shared object (well, DLL anyway)
* these externs break the linker when resolv.h is
* included by a lib client (like named)
* Make them go away if a client is including this
*
*/
extern const struct res_sym __p_key_syms[];
extern const struct res_sym __p_cert_syms[];
extern const struct res_sym __p_class_syms[];
extern const struct res_sym __p_type_syms[];
extern const struct res_sym __p_rcode_syms[];
#endif /* SHARED_LIBBIND */
#ifndef ADNROID_CHANGES
#define b64_ntop __b64_ntop
#define b64_pton __b64_pton
#endif
#define dn_comp __dn_comp
#define dn_count_labels __dn_count_labels
#define dn_skipname __dn_skipname
#define fp_resstat __fp_resstat
#define loc_aton __loc_aton
#define loc_ntoa __loc_ntoa
#define p_cdname __p_cdname
#define p_cdnname __p_cdnname
#define p_class __p_class
#define p_fqname __p_fqname
#define p_fqnname __p_fqnname
#define p_option __p_option
#define p_secstodate __p_secstodate
#define p_section __p_section
#define p_time __p_time
#define p_type __p_type
#define p_rcode __p_rcode
#define p_sockun __p_sockun
#define putlong __putlong
#define putshort __putshort
#define res_dnok __res_dnok
#define res_findzonecut __res_findzonecut
#define res_findzonecut2 __res_findzonecut2
#define res_hnok __res_hnok
#define res_hostalias __res_hostalias
#define res_mailok __res_mailok
#define res_nameinquery __res_nameinquery
#define res_nclose __res_nclose
#define res_ninit __res_ninit
#define res_nmkquery __res_nmkquery
#define res_pquery __res_pquery
#define res_nquery __res_nquery
#define res_nquerydomain __res_nquerydomain
#define res_nsearch __res_nsearch
#define res_nsend __res_nsend
#define res_nsendsigned __res_nsendsigned
#define res_nisourserver __res_nisourserver
#define res_ownok __res_ownok
#define res_queriesmatch __res_queriesmatch
#define res_randomid __res_randomid
#define sym_ntop __sym_ntop
#define sym_ntos __sym_ntos
#define sym_ston __sym_ston
#define res_nopt __res_nopt
#define res_ndestroy __res_ndestroy
#define res_nametoclass __res_nametoclass
#define res_nametotype __res_nametotype
#define res_setservers __res_setservers
#define res_getservers __res_getservers
#define res_buildprotolist __res_buildprotolist
#define res_destroyprotolist __res_destroyprotolist
#define res_destroyservicelist __res_destroyservicelist
#define res_get_nibblesuffix __res_get_nibblesuffix
#define res_get_nibblesuffix2 __res_get_nibblesuffix2
#define res_ourserver_p __res_ourserver_p
#define res_protocolname __res_protocolname
#define res_protocolnumber __res_protocolnumber
#define res_send_setqhook __res_send_setqhook
#define res_send_setrhook __res_send_setrhook
#define res_servicename __res_servicename
#define res_servicenumber __res_servicenumber
__BEGIN_DECLS
int res_hnok(const char *);
int res_ownok(const char *);
int res_mailok(const char *);
int res_dnok(const char *);
int sym_ston(const struct res_sym *, const char *, int *);
const char * sym_ntos(const struct res_sym *, int, int *);
const char * sym_ntop(const struct res_sym *, int, int *);
#ifndef ANDROID_CHANGES
int b64_ntop(u_char const *, size_t, char *, size_t);
int b64_pton(char const *, u_char *, size_t);
#endif
int loc_aton(const char *, u_char *);
const char * loc_ntoa(const u_char *, char *);
int dn_skipname(const u_char *, const u_char *);
void putlong(uint32_t, u_char *);
void putshort(uint16_t, u_char *);
#ifndef __ultrix__
uint16_t _getshort(const u_char *);
uint32_t _getlong(const u_char *);
#endif
const char * p_class(int);
const char * p_time(uint32_t);
const char * p_type(int);
const char * p_rcode(int);
const char * p_sockun(union res_sockaddr_union, char *, size_t);
const u_char * p_cdnname(const u_char *, const u_char *, int, FILE *);
const u_char * p_cdname(const u_char *, const u_char *, FILE *);
const u_char * p_fqnname(const u_char *, const u_char *,
int, char *, int);
const u_char * p_fqname(const u_char *, const u_char *, FILE *);
const char * p_option(u_long);
char * p_secstodate(u_long);
int dn_count_labels(const char *);
int dn_comp(const char *, u_char *, int, u_char **, u_char **);
int dn_expand(const u_char *, const u_char *, const u_char *,
char *, int);
u_int res_randomid(void);
int res_nameinquery(const char *, int, int, const u_char *,
const u_char *);
int res_queriesmatch(const u_char *, const u_char *,
const u_char *, const u_char *);
const char * p_section(int, int);
/* Things involving a resolver context. */
int res_ninit(res_state);
int res_nisourserver(const res_state, const struct sockaddr_in *);
void fp_resstat(const res_state, FILE *);
void res_pquery(const res_state, const u_char *, int, FILE *);
const char * res_hostalias(const res_state, const char *, char *, size_t);
int res_nquery(res_state, const char *, int, int, u_char *, int);
int res_nsearch(res_state, const char *, int, int, u_char *, int);
int res_nquerydomain(res_state, const char *, const char *,
int, int, u_char *, int);
int res_nmkquery(res_state, int, const char *, int, int,
const u_char *, int, const u_char *,
u_char *, int);
int res_nsend(res_state, const u_char *, int, u_char *, int);
int res_nsendsigned(res_state, const u_char *, int,
ns_tsig_key *, u_char *, int);
int res_findzonecut(res_state, const char *, ns_class, int,
char *, size_t, struct in_addr *, int);
int res_findzonecut2(res_state, const char *, ns_class, int,
char *, size_t,
union res_sockaddr_union *, int);
void res_nclose(res_state);
int res_nopt(res_state, int, u_char *, int, int);
void res_send_setqhook(res_send_qhook);
void res_send_setrhook(res_send_rhook);
int __res_vinit(res_state, int);
void res_destroyservicelist(void);
const char * res_servicename(uint16_t, const char *);
const char * res_protocolname(int);
void res_destroyprotolist(void);
void res_buildprotolist(void);
const char * res_get_nibblesuffix(res_state);
const char * res_get_nibblesuffix2(res_state);
void res_ndestroy(res_state);
uint16_t res_nametoclass(const char *, int *);
uint16_t res_nametotype(const char *, int *);
void res_setservers(res_state,
const union res_sockaddr_union *, int);
int res_getservers(res_state,
union res_sockaddr_union *, int);
int res_get_dns_changed();
u_int res_randomid(void);
__END_DECLS
#endif /* !_RESOLV_PRIVATE_H_ */

32
src/resolv_static.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef _RESOLV_STATIC_H
#define _RESOLV_STATIC_H
#include <netdb.h>
/* this structure contains all the variables that were declared
* 'static' in the original NetBSD resolver code.
*
* this caused vast amounts of crashes and memory corruptions
* when the resolver was being used by multiple threads.
*
* (note: the OpenBSD/FreeBSD resolver has similar 'issues')
*/
#define MAXALIASES 35
#define MAXADDRS 35
typedef struct res_static {
char* h_addr_ptrs[MAXADDRS + 1];
char* host_aliases[MAXALIASES];
char hostbuf[8*1024];
u_int32_t host_addr[16 / sizeof(u_int32_t)]; /* IPv4 or IPv6 */
FILE* hostf;
int stayopen;
const char* servent_ptr;
struct servent servent;
struct hostent host;
} *res_static;
extern res_static __res_get_static(void);
#endif /* _RESOLV_STATIC_H */

1255
src/rpc.c Normal file

File diff suppressed because it is too large Load Diff

323
src/rpc.h Normal file
View File

@ -0,0 +1,323 @@
#ifndef __rpc_h
#define __rpc_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "types.h"
#include "shared_globals.h"
#if !defined(_WIN32) && !defined(__CYGWIN__)
#define RPC_S_OK 0
#define RPC_S_INVALID_ARG 87
#define RPC_S_OUT_OF_MEMORY 14
#define RPC_S_OUT_OF_THREADS 164
#define RPC_S_INVALID_LEVEL RPC_S_INVALID_ARG
#define RPC_S_BUFFER_TOO_SMALL 122
#define RPC_S_INVALID_SECURITY_DESC 1338
#define RPC_S_ACCESS_DENIED 5
#define RPC_S_SERVER_OUT_OF_MEMORY 1130
#define RPC_S_ASYNC_CALL_PENDING 997
#define RPC_S_UNKNOWN_PRINCIPAL 1332
#define RPC_S_TIMEOUT 1460
#define RPC_S_INVALID_STRING_BINDING 1700
#define RPC_S_WRONG_KIND_OF_BINDING 1701
#define RPC_S_INVALID_BINDING 1702
#define RPC_S_PROTSEQ_NOT_SUPPORTED 1703
#define RPC_S_INVALID_RPC_PROTSEQ 1704
#define RPC_S_INVALID_STRING_UUID 1705
#define RPC_S_INVALID_ENDPOINT_FORMAT 1706
#define RPC_S_INVALID_NET_ADDR 1707
#define RPC_S_NO_ENDPOINT_FOUND 1708
#define RPC_S_INVALID_TIMEOUT 1709
#define RPC_S_OBJECT_NOT_FOUND 1710
#define RPC_S_ALREADY_REGISTERED 1711
#define RPC_S_TYPE_ALREADY_REGISTERED 1712
#define RPC_S_ALREADY_LISTENING 1713
#define RPC_S_NO_PROTSEQS_REGISTERED 1714
#define RPC_S_NOT_LISTENING 1715
#define RPC_S_UNKNOWN_MGR_TYPE 1716
#define RPC_S_UNKNOWN_IF 1717
#define RPC_S_NO_BINDINGS 1718
#define RPC_S_NO_PROTSEQS 1719
#define RPC_S_CANT_CREATE_ENDPOINT 1720
#define RPC_S_OUT_OF_RESOURCES 1721
#define RPC_S_SERVER_UNAVAILABLE 1722
#define RPC_S_SERVER_TOO_BUSY 1723
#define RPC_S_INVALID_NETWORK_OPTIONS 1724
#define RPC_S_NO_CALL_ACTIVE 1725
#define RPC_S_CALL_FAILED 1726
#define RPC_S_CALL_FAILED_DNE 1727
#define RPC_S_PROTOCOL_ERROR 1728
#define RPC_S_PROXY_ACCESS_DENIED 1729
#define RPC_S_UNSUPPORTED_TRANS_SYN 1730
#define RPC_S_UNSUPPORTED_TYPE 1732
#define RPC_S_INVALID_TAG 1733
#define RPC_S_INVALID_BOUND 1734
#define RPC_S_NO_ENTRY_NAME 1735
#define RPC_S_INVALID_NAME_SYNTAX 1736
#define RPC_S_UNSUPPORTED_NAME_SYNTAX 1737
#define RPC_S_UUID_NO_ADDRESS 1739
#define RPC_S_DUPLICATE_ENDPOINT 1740
#define RPC_S_UNKNOWN_AUTHN_TYPE 1741
#define RPC_S_MAX_CALLS_TOO_SMALL 1742
#define RPC_S_STRING_TOO_LONG 1743
#define RPC_S_PROTSEQ_NOT_FOUND 1744
#define RPC_S_PROCNUM_OUT_OF_RANGE 1745
#define RPC_S_BINDING_HAS_NO_AUTH 1746
#define RPC_S_UNKNOWN_AUTHN_SERVICE 1747
#define RPC_S_UNKNOWN_AUTHN_LEVEL 1748
#define RPC_S_INVALID_AUTH_IDENTITY 1749
#define RPC_S_UNKNOWN_AUTHZ_SERVICE 1750
#define EPT_S_INVALID_ENTRY 1751
#define EPT_S_CANT_PERFORM_OP 1752
#define EPT_S_NOT_REGISTERED 1753
#define RPC_S_NOTHING_TO_EXPORT 1754
#define RPC_S_INCOMPLETE_NAME 1755
#define RPC_S_INVALID_VERS_OPTION 1756
#define RPC_S_NO_MORE_MEMBERS 1757
#define RPC_S_NOT_ALL_OBJS_UNEXPORTED 1758
#define RPC_S_INTERFACE_NOT_FOUND 1759
#define RPC_S_ENTRY_ALREADY_EXISTS 1760
#define RPC_S_ENTRY_NOT_FOUND 1761
#define RPC_S_NAME_SERVICE_UNAVAILABLE 1762
#define RPC_S_INVALID_NAF_ID 1763
#define RPC_S_CANNOT_SUPPORT 1764
#define RPC_S_NO_CONTEXT_AVAILABLE 1765
#define RPC_S_INTERNAL_ERROR 1766
#define RPC_S_ZERO_DIVIDE 1767
#define RPC_S_ADDRESS_ERROR 1768
#define RPC_S_FP_DIV_ZERO 1769
#define RPC_S_FP_UNDERFLOW 1770
#define RPC_S_FP_OVERFLOW 1771
#define RPC_X_NO_MORE_ENTRIES 1772
#define RPC_X_SS_CHAR_TRANS_OPEN_FAIL 1773
#define RPC_X_SS_CHAR_TRANS_SHORT_FILE 1774
#define RPC_X_SS_IN_NULL_CONTEXT 1775
#define RPC_X_SS_CONTEXT_DAMAGED 1777
#define RPC_X_SS_HANDLES_MISMATCH 1778
#define RPC_X_SS_CANNOT_GET_CALL_HANDLE 1779
#define RPC_X_NULL_REF_POINTER 1780
#define RPC_X_ENUM_VALUE_OUT_OF_RANGE 1781
#define RPC_X_BYTE_COUNT_TOO_SMALL 1782
#define RPC_X_BAD_STUB_DATA 1783
#define RPC_S_CALL_IN_PROGRESS 1791
#define RPC_S_NO_MORE_BINDINGS 1806
#define RPC_S_NO_INTERFACES 1817
#define RPC_S_CALL_CANCELLED 1818
#define RPC_S_BINDING_INCOMPLETE 1819
#define RPC_S_COMM_FAILURE 1820
#define RPC_S_UNSUPPORTED_AUTHN_LEVEL 1821
#define RPC_S_NO_PRINC_NAME 1822
#define RPC_S_NOT_RPC_ERROR 1823
#define RPC_S_UUID_LOCAL_ONLY 1824
#define RPC_S_SEC_PKG_ERROR 1825
#define RPC_S_NOT_CANCELLED 1826
#define RPC_X_INVALID_ES_ACTION 1827
#define RPC_X_WRONG_ES_VERSION 1828
#define RPC_X_WRONG_STUB_VERSION 1829
#define RPC_X_INVALID_PIPE_OBJECT 1830
#define RPC_X_WRONG_PIPE_ORDER 1831
#define RPC_X_WRONG_PIPE_VERSION 1832
#define RPC_S_COOKIE_AUTH_FAILED 1833
#define RPC_S_GROUP_MEMBER_NOT_FOUND 1898
#define EPT_S_CANT_CREATE 1899
#define RPC_S_INVALID_OBJECT 1900
#define RPC_S_SEND_INCOMPLETE 1913
#define RPC_S_INVALID_ASYNC_HANDLE 1914
#define RPC_S_INVALID_ASYNC_CALL 1915
#define RPC_X_PIPE_CLOSED 1916
#define RPC_X_PIPE_DISCIPLINE_ERROR 1917
#define RPC_X_PIPE_EMPTY 1918
#define RPC_S_ENTRY_TYPE_MISMATCH 1922
#define RPC_S_NOT_ALL_OBJS_EXPORTED 1923
#define RPC_S_INTERFACE_NOT_EXPORTED 1924
#define RPC_S_PROFILE_NOT_ADDED 1925
#define RPC_S_PRF_ELT_NOT_ADDED 1926
#define RPC_S_PRF_ELT_NOT_REMOVED 1927
#define RPC_S_GRP_ELT_NOT_ADDED 1928
#define RPC_S_GRP_ELT_NOT_REMOVED 1929
#endif // !defined(_WIN32) && !_defined(__CYGWIN__)
typedef struct {
BYTE VersionMajor;
BYTE VersionMinor;
BYTE PacketType;
BYTE PacketFlags;
DWORD DataRepresentation;
WORD FragLength;
WORD AuthLength;
DWORD CallId;
} /*__packed*/ RPC_HEADER;
typedef struct {
WORD MaxXmitFrag;
WORD MaxRecvFrag;
DWORD AssocGroup;
DWORD NumCtxItems;
struct CtxItem {
WORD ContextId;
WORD NumTransItems;
GUID InterfaceUUID;
WORD InterfaceVerMajor;
WORD InterfaceVerMinor;
GUID TransferSyntax;
DWORD SyntaxVersion;
} CtxItems[1];
} /*__packed*/ RPC_BIND_REQUEST;
typedef struct {
WORD MaxXmitFrag;
WORD MaxRecvFrag;
DWORD AssocGroup;
WORD SecondaryAddressLength;
BYTE SecondaryAddress[6];
DWORD NumResults;
struct CtxResults {
WORD AckResult;
WORD AckReason;
GUID TransferSyntax;
DWORD SyntaxVersion;
} Results[0];
} /*__packed*/ RPC_BIND_RESPONSE;
typedef struct {
DWORD AllocHint;
WORD ContextId;
WORD Opnum;
struct {
DWORD DataLength;
DWORD DataSizeIs;
} Ndr;
BYTE Data[0];
} /*__packed*/ RPC_REQUEST;
typedef struct {
DWORD AllocHint;
WORD ContextId;
BYTE CancelCount;
BYTE Pad1;
struct {
DWORD DataLength;
DWORD DataSizeIs1;
DWORD DataSizeIs2;
} Ndr;
BYTE Data[0];
} /*__packed*/ RPC_RESPONSE;
typedef struct {
DWORD AllocHint;
WORD ContextId;
WORD Opnum;
union {
struct {
DWORD DataLength;
DWORD DataSizeIs;
BYTE Data[0];
} Ndr;
struct {
uint64_t DataLength;
uint64_t DataSizeIs;
BYTE Data[0];
} Ndr64;
};
} /*__packed*/ RPC_REQUEST64;
typedef struct {
DWORD AllocHint;
WORD ContextId;
BYTE CancelCount;
BYTE Pad1;
union {
struct {
DWORD DataLength;
DWORD DataSizeMax;
union
{
DWORD DataSizeIs;
DWORD status;
};
BYTE Data[0];
} Ndr;
struct {
uint64_t DataLength;
uint64_t DataSizeMax;
union
{
uint64_t DataSizeIs;
DWORD status;
};
BYTE Data[0];
} Ndr64;
struct
{
DWORD Code;
DWORD Padding;
} Error;
};
} /*__packed*/ RPC_RESPONSE64;
//#define RpcCtx SOCKET
typedef SOCKET RpcCtx;
typedef int RpcStatus;
#define RPC_INVALID_CTX ((WORD)~0)
#define RPC_BIND_ACCEPT (0)
#define RPC_BIND_NACK (LE16(2))
#define RPC_BIND_ACK (LE16(3))
#define RPC_SYNTAX_UNSUPPORTED (LE16(2))
#define RPC_ABSTRACTSYNTAX_UNSUPPORTED (LE16(1))
#define RPC_NCA_UNK_IF (LE32(0x1c010003))
#define RPC_NCA_PROTO_ERROR (LE32(0x1c01000b))
#define RPC_BTFN_SEC_CONTEXT_MULTIPLEX (LE16(1))
#define RPC_BTFN_KEEP_ORPHAN (LE16(2))
#define INVALID_RPCCTX INVALID_SOCKET
#define closeRpc socketclose
#define RPC_PT_REQUEST 0
#define RPC_PT_RESPONSE 2
#define RPC_PT_FAULT 3
#define RPC_PT_BIND_REQ 11
#define RPC_PT_BIND_ACK 12
#define RPC_PT_ALTERCONTEXT_REQ 14
#define RPC_PT_ALTERCONTEXT_ACK 15
#define RPC_PF_FIRST 1
#define RPC_PF_LAST 2
#define RPC_PF_CANCEL_PENDING 4
#define RPC_PF_RESERVED 8
#define RPC_PF_MULTIPLEX 16
#define RPC_PF_NOT_EXEC 32
#define RPC_PF_MAYBE 64
#define RPC_PF_OBJECT 128
typedef union _RPC_FLAGS
{
DWORD mask;
struct {
uint32_t FlagsBTFN : 16;
BOOL HasNDR32 : 1;
BOOL HasNDR64 : 1;
BOOL HasBTFN : 1;
};
} RPC_FLAGS, *PRPC_FLAGS;
extern RPC_FLAGS RpcFlags;
void rpcServer(const SOCKET sock, const DWORD rpcAssocGroup, const char* const ipstr);
RpcStatus rpcBindClient(const RpcCtx sock, const int_fast8_t verbose, PRpcDiag_t rpcDiag);
RpcStatus rpcSendRequest(const RpcCtx socket, const BYTE *const kmsRequest, const size_t requestSize, BYTE **kmsResponse, size_t *const responseSize);
#endif // __rpc_h

155
src/shared_globals.c Normal file
View File

@ -0,0 +1,155 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "shared_globals.h"
int global_argc, multi_argc = 0;
CARGV global_argv, multi_argv = NULL;
const char *const Version = VERSION;
DWORD VLActivationInterval = 60 * 2; // 2 hours
DWORD VLRenewalInterval = 60 * 24 * 7; // 7 days
int_fast8_t DisconnectImmediately = FALSE;
const char *const cIPv4 = "IPv4";
const char *const cIPv6 = "IPv6";
#ifdef IS_LIBRARY
char ErrorMessage[MESSAGE_BUFFER_SIZE];
#endif // IS_LIBRARY
#ifndef NO_STRICT_MODES
uint32_t WhitelistingLevel = 0;
int_fast8_t CheckClientTime = FALSE;
#ifndef NO_CLIENT_LIST
int_fast8_t MaintainClients = FALSE;
int_fast8_t StartEmpty = FALSE;
#endif // NO_CLIENT_LIST
#endif // !NO_STRICT_MODES
#ifndef USE_MSRPC
int_fast8_t UseMultiplexedRpc = TRUE;
#ifndef SIMPLE_RPC
int_fast8_t UseServerRpcNDR64 = TRUE;
int_fast8_t UseServerRpcBTFN = TRUE;
#endif // !SIMPLE_RPC
int_fast8_t UseClientRpcNDR64 = TRUE;
int_fast8_t UseClientRpcBTFN = TRUE;
#endif // USE_MSRPC
#ifndef NO_SOCKETS
char *defaultport = (char*)"1688";
#endif // NO_SOCKETS
#if !defined(NO_PRIVATE_IP_DETECT)
uint32_t PublicIPProtectionLevel = 0;
#endif
#if !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
KmsResponseParam_t* KmsResponseParameters;
#endif // !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
#if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
int_fast8_t IsRestarted = FALSE;
#endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
#if !defined(NO_TIMEOUT) && !__minix__
DWORD ServerTimeout = 30;
#endif // !defined(NO_TIMEOUT) && !__minix__
#if !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
#ifdef USE_MSRPC
uint32_t MaxTasks = RPC_C_LISTEN_MAX_CALLS_DEFAULT;
#else // !USE_MSRPC
uint32_t MaxTasks = SEM_VALUE_MAX;
#endif // !USE_MSRPC
#endif // !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
#ifndef NO_LOG
int_fast8_t LogDateAndTime = TRUE;
char *fn_log = NULL;
int_fast8_t logstdout = 0;
#ifndef NO_VERBOSE_LOG
int_fast8_t logverbose = 0;
#endif // NO_VERBOSE_LOG
#endif // NO_LOG
#ifndef NO_SOCKETS
int_fast8_t ExitLevel = 0;
#ifndef _WIN32
int_fast8_t nodaemon = 0;
#endif // _WIN32
int_fast8_t InetdMode = 0;
#else
#ifndef _WIN32
int_fast8_t nodaemon = 1;
#endif // _WIN32
int_fast8_t InetdMode = 1;
#endif // NO_SOCKETS
PVlmcsdHeader_t KmsData = NULL;
#ifndef NO_EXTERNAL_DATA
#ifndef DATA_FILE
char *fn_data = NULL;
#else // DATA_FILE
char *fn_data = DATA_FILE;
#endif // DATA_FILE
#ifndef NO_INTERNAL_DATA
int_fast8_t ExplicitDataLoad = FALSE;
#endif // NO_INTERNAL_DATA
#endif // NO_EXTERNAL_DATA
const char *fn_exe = NULL;
#ifndef NO_RANDOM_EPID
int_fast8_t RandomizationLevel = 1;
uint16_t Lcid = 0;
uint16_t HostBuild = 0;
#endif
#if !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
uint8_t IsNDR64Defined = FALSE;
#endif // !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
#if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
#ifdef SIMPLE_SOCKETS
SOCKET s_server;
#else
SOCKET *SocketList;
int numsockets = 0;
#endif
#if !defined(NO_LIMIT) && !__minix__
#ifndef _WIN32 // Posix
sem_t *MaxTaskSemaphore;
#else // _WIN32
HANDLE MaxTaskSemaphore;
#endif // _WIN32
#endif // !defined(NO_LIMIT) && !__minix__
#endif // !defined(NO_SOCKETS) && !defined(USE_MSRPC)
#ifdef _NTSERVICE
int_fast8_t IsNTService = TRUE;
int_fast8_t ServiceShutdown = FALSE;
#endif // _NTSERVICE
#ifndef NO_LOG
#ifdef USE_THREADS
#if !defined(_WIN32) && !defined(__CYGWIN__)
pthread_mutex_t logmutex = PTHREAD_MUTEX_INITIALIZER;
#else
CRITICAL_SECTION logmutex;
#endif // !defined(_WIN32) && !defined(__CYGWIN__)
#endif // USE_THREADS
#endif // NO_LOG
#if HAVE_FREEBIND
int_fast8_t freebind = FALSE;
#endif // HAVE_FREEBIND

216
src/shared_globals.h Normal file
View File

@ -0,0 +1,216 @@
#ifndef INCLUDED_SHARED_GLOBALS_H
#define INCLUDED_SHARED_GLOBALS_H
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include <sys/types.h>
#ifndef _WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pwd.h>
#include <grp.h>
#include <syslog.h>
#if !__minix__
#include <pthread.h>
#endif // !__minix__
#include <fcntl.h>
#include <sys/stat.h>
#if !defined(NO_LIMIT) && !__minix__
#include <semaphore.h>
#endif // !defined(NO_LIMIT) && !__minix__
#else
//#ifndef USE_MSRPC
#include <winsock2.h>
#include <ws2tcpip.h>
//#endif // USE_MSRPC
#include <windows.h>
#endif
#include <signal.h>
#if !_MSC_VER
#include <unistd.h>
#endif
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>
#include <ctype.h>
#include <stdarg.h>
//#include <semaphore.h>
#include "types.h"
#include "kms.h"
//#define MIN_CSVLK 6
typedef struct
{
const char* Epid;
const BYTE* HwId;
#ifndef NO_LOG
const char* EpidSource;
uint8_t IsRandom;
#endif // NO_LOG
} KmsResponseParam_t, *PKmsResponseParam_t;
typedef struct
{
int8_t HasRpcDiag;
int8_t HasBTFN;
int8_t HasNDR64;
} RpcDiag_t, *PRpcDiag_t;
#if !defined(NO_LIMIT) && !__minix__
#ifndef SEM_VALUE_MAX // Android does not define this
#ifdef __ANDROID__
#define SEM_VALUE_MAX 0x3fffffff
#elif defined(_WIN32)
#define SEM_VALUE_MAX 0x7fffffff
#else
#define SEM_VALUE_MAX 0x7fff // Be cautious if unknown
#endif // __ANDROID__
#endif // !defined(SEM_VALUE_MAX)
#endif // !defined(NO_LIMIT) && !__minix__
extern const char *const Version;
//Fix for stupid eclipse parser
#ifndef UINT_MAX
#define UINT_MAX 4294967295
#endif
#define MESSAGE_BUFFER_SIZE 4096
#ifdef IS_LIBRARY
extern char ErrorMessage[MESSAGE_BUFFER_SIZE];
#endif // IS_LIBRARY
extern int global_argc, multi_argc;
extern CARGV global_argv, multi_argv;
#ifndef _WIN32
extern int_fast8_t nodaemon;
#endif // _WIN32
extern DWORD VLActivationInterval;
extern DWORD VLRenewalInterval;
extern int_fast8_t DisconnectImmediately;
#if !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
extern KmsResponseParam_t* KmsResponseParameters;
#endif // !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
extern const char *const cIPv4;
extern const char *const cIPv6;
extern int_fast8_t InetdMode;
extern PVlmcsdHeader_t KmsData;
#ifndef NO_EXTERNAL_DATA
extern char* fn_data;
#ifndef NO_INTERNAL_DATA
extern int_fast8_t ExplicitDataLoad;
#endif // NO_INTERNAL_DATA
#endif // NO_EXTERNAL_DATA
extern const char* fn_exe;
#ifndef NO_STRICT_MODES
extern uint32_t WhitelistingLevel;
extern int_fast8_t CheckClientTime;
#ifndef NO_CLIENT_LIST
extern int_fast8_t MaintainClients;
extern int_fast8_t StartEmpty;
#endif // NO_CLIENT_LIST
#endif // !NO_STRICT_MODES
#ifndef USE_MSRPC
extern int_fast8_t UseMultiplexedRpc;
#ifndef SIMPLE_RPC
extern int_fast8_t UseServerRpcNDR64;
extern int_fast8_t UseServerRpcBTFN;
#endif // !SIMPLE_RPC
extern int_fast8_t UseClientRpcNDR64;
extern int_fast8_t UseClientRpcBTFN;
#endif // USE_MSRPC
#ifndef NO_SOCKETS
extern int_fast8_t ExitLevel;
extern char *defaultport;
#endif // NO_SOCKETS
#if !defined(NO_PRIVATE_IP_DETECT)
extern uint32_t PublicIPProtectionLevel;
#endif
#if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
extern int_fast8_t IsRestarted;
#endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
#if !defined(NO_TIMEOUT) && !__minix__
extern DWORD ServerTimeout;
#endif // !defined(NO_TIMEOUT) && !__minix__
#if !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
extern uint32_t MaxTasks;
#endif // !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
#ifndef NO_LOG
extern int_fast8_t LogDateAndTime;
extern char *fn_log;
extern int_fast8_t logstdout;
#ifndef NO_VERBOSE_LOG
extern int_fast8_t logverbose;
#endif
#endif
#if !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
extern uint8_t IsNDR64Defined;
#endif
#ifndef NO_RANDOM_EPID
extern int_fast8_t RandomizationLevel;
extern uint16_t Lcid;
extern uint16_t HostBuild;
#endif
#if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
#if defined(SIMPLE_SOCKETS)
extern SOCKET s_server;
#else // !defined(SIMPLE_SOCKETS)
extern SOCKET *SocketList;
extern int numsockets;
#endif // !defined(SIMPLE_SOCKETS)
#if !defined(NO_LIMIT) && !__minix__
#ifndef _WIN32
extern sem_t *MaxTaskSemaphore;
#else // _WIN32
extern HANDLE MaxTaskSemaphore;
#endif // _WIN32
#endif // !defined(NO_LIMIT) && !__minix__
#endif // !defined(NO_SOCKETS) && !defined(USE_MSRPC)
#ifdef _NTSERVICE
extern int_fast8_t IsNTService;
extern int_fast8_t ServiceShutdown;
#endif
#ifndef NO_LOG
#ifdef USE_THREADS
#if !defined(_WIN32) && !defined(__CYGWIN__)
extern pthread_mutex_t logmutex;
#else
extern CRITICAL_SECTION logmutex;
#endif // _WIN32
#endif // USE_THREADS
#endif // NO_LOG
#if HAVE_FREEBIND
extern int_fast8_t freebind;
#endif // HAVE_FREEBIND
#endif // INCLUDED_SHARED_GLOBALS_H

77
src/tap-windows.h Normal file
View File

@ -0,0 +1,77 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2014 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below). This particular file
* (tap-windows.h) is also licensed using the MIT license (see COPYRIGHT.MIT).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __TAP_WIN_H
#define __TAP_WIN_H
/*
* =============
* TAP IOCTLs
* =============
*/
#define TAP_WIN_CONTROL_CODE(request,method) \
CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
/* Present in 8.1 */
#define TAP_WIN_IOCTL_GET_MAC TAP_WIN_CONTROL_CODE (1, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_GET_VERSION TAP_WIN_CONTROL_CODE (2, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_GET_MTU TAP_WIN_CONTROL_CODE (3, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_GET_INFO TAP_WIN_CONTROL_CODE (4, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT TAP_WIN_CONTROL_CODE (5, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_SET_MEDIA_STATUS TAP_WIN_CONTROL_CODE (6, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_CONFIG_DHCP_MASQ TAP_WIN_CONTROL_CODE (7, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_GET_LOG_LINE TAP_WIN_CONTROL_CODE (8, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT TAP_WIN_CONTROL_CODE (9, METHOD_BUFFERED)
/* Added in 8.2 */
/* obsoletes TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT */
#define TAP_WIN_IOCTL_CONFIG_TUN TAP_WIN_CONTROL_CODE (10, METHOD_BUFFERED)
/*
* =================
* Registry keys
* =================
*/
#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
/*
* ======================
* Filesystem prefixes
* ======================
*/
#define USERMODEDEVICEDIR "\\\\.\\Global\\"
#define SYSDEVICEDIR "\\Device\\"
#define USERDEVICEDIR "\\DosDevices\\Global\\"
#define TAP_WIN_SUFFIX ".tap"
#endif // __TAP_WIN_H

395
src/types.h Normal file
View File

@ -0,0 +1,395 @@
#ifndef __types_h
#define __types_h
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#if defined(NO_INTERNAL_DATA) && defined(NO_EXTERNAL_DATA)
#error NO_INTERAL_DATA and NO_EXTERNAL_DATA cannot be used together
#endif
#if defined(_WIN32)
//#ifndef USE_MSRPC
#include <winsock2.h>
//#include <ws2tcpip.h>
//#endif // USE_MSRPC
#endif // defined(_WIN32)
#define ANDROID_API_LEVEL ANDROID_HELPER1(__ANDROID_API__)
#define ANDROID_HELPER1(s) ANDROID_HELPER2(s)
#define ANDROID_HELPER2(s) #s
#if !_WIN32 && !__CYGWIN__
#if !__minix__
#include <pthread.h>
#endif // !__minix__
#define __declspec(x) __attribute__((__visibility__("default")))
#endif
#if !defined(EXTERNAL)
#define EXTERNAL dllimport
#endif
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
#include <stdlib.h>
//#include <limits.h>
#include <stdint.h>
#ifdef __ANDROID__
#include <android/api-level.h>
#endif // __ANDROID__
#ifndef _WIN32
#include <unistd.h>
#include <netinet/in.h>
#endif // _WIN32
#if __linux__ // Some versions of uclibc do not define IP_FREEBIND in the correct header file
#ifndef IP_FREEBIND
#define IP_FREEBIND 15
#endif // IP_FREEBIND
#endif // __linux__
#ifdef NO_EXTERNAL_DATA
#ifndef UNSAFE_DATA_LOAD
#define UNSAFE_DATA_LOAD
#endif // UNSAFE_DATA_LOAD
#endif // NO_EXTERNAL_DATA
#if (IP_BINDANY || IP_FREEBIND || IPV6_BINDANY || IP_NONLOCALOK) && !defined(NO_FREEBIND) && !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
#define HAVE_FREEBIND 1
#endif
#if !defined(NO_GETIFADDRS) && !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS) && !defined(NO_SOCKETS) && !defined(NO_PRIVATE_IP_DETECT)
#define HAVE_GETIFADDR 1
#endif
//#if (__minix__ || defined(NO_SOCKETS)) && !defined(NO_STRICT_MODES)
//#define NO_STRICT_MODES
//#endif // __minix__ && !defined(NO_STRICT_MODES)
#if (defined(NO_STRICT_MODES) || defined(NO_SOCKETS)) && !defined(NO_CLIENT_LIST)
#define NO_CLIENT_LIST
#endif // defined(NO_STRICT_MODES) || defined(NO_SOCKETS) && !defined(NO_CLIENT_LIST)
#if !_WIN32 && !__CYGWIN__
#if !defined(_POSIX_THREADS) || (!defined(_POSIX_THREAD_PROCESS_SHARED) && !defined(USE_THREADS) && !__ANDROID__)
#ifndef NO_CLIENT_LIST
#define NO_CLIENT_LIST
#endif // !NO_CLIENT_LIST
#endif // !defined(_POSIX_THREADS) || (!defined(_POSIX_THREAD_PROCESS_SHARED) && !defined(USE_THREADS))
#if !defined(_POSIX_THREADS) && !defined(NO_LIMIT)
#define NO_LIMIT
#endif // !defined(POSIX_THREADS) && !defined(NO_LIMIT)
#endif // !_WIN32 && !__CYGWIN__
#ifndef alloca
#ifdef __GNUC__
#define alloca(x) __builtin_alloca(x)
#endif // __GNUC__
#endif // alloca
#ifndef alloca
#ifdef __has_builtin // clang feature test
#if __has_builtin(__builtin_alloca)
#define alloca(x) __builtin_alloca(x)
#endif // __has_builtin(__builtin_alloca)
#endif // __has_builtin
#endif // alloca
#ifndef alloca
#if !_MSC_VER
#include <alloca.h>
#else
#include <malloc.h>
//#define alloca _malloca
#endif
//#define alloca _malloca
//#endif // _MSC_VER
#endif // alloca
#ifndef __packed
#if _MSC_VER
#define __packed
#else // !_MSC_VER
#define __packed __attribute__((packed))
#endif // !_MSC_VER
#endif
#ifndef __pure
#if _MSC_VER
#define __pure
#else
#define __pure __attribute__((pure))
#endif
#endif
#ifndef __noreturn
#if _MSC_VER
#define __noreturn __declspec(noreturn)
#else
#define __noreturn __attribute__((noreturn))
#endif
#endif
#define restrict __restrict
typedef struct __packed
{
uint16_t val[0];
} PACKED16;
typedef struct __packed
{
uint32_t val[0];
} PACKED32;
typedef struct __packed
{
uint64_t val[0];
} PACKED64;
// Deal with Mingw32-w64 C++ header which defines a _countof that is incompatible with vlmcsd
#define vlmcsd_countof(x) ( sizeof(x) / sizeof(x[0]) )
// PATH_MAX is optional in Posix. We use a default of 260 here
#ifndef PATH_MAX
#ifdef _WIN32
#define PATH_MAX MAX_PATH
#else
#define PATH_MAX 260
#endif // _WIN32
#endif // !PATH_MAX
#if PATH_MAX > 260
#define VLMCSD_PATH_MAX 260
#else
#define VLMCSD_PATH_MAX PATH_MAX
#endif
// Synchronization Objects
// Mutexes
#ifdef USE_THREADS
#if !defined(_WIN32) && !defined(__CYGWIN__)
#define lock_mutex(x) pthread_mutex_lock(x)
#define unlock_mutex(x) pthread_mutex_unlock(x)
#else
#define lock_mutex(x) EnterCriticalSection(x)
#define unlock_mutex(x) LeaveCriticalSection(x)
#endif
#else // !USE_THREADS
//defines to nothing
#define lock_mutex(x)
#define unlock_mutex(x)
#endif // !USE_THREADS
// Semaphores
#ifndef _WIN32
#define semaphore_wait(x) sem_wait(x)
#define semaphore_post(x) sem_post(x)
#else // _WIN32
#define semaphore_wait(x) WaitForSingleObject(x, INFINITE)
#define semaphore_post(x) ReleaseSemaphore(x, 1, NULL)
#endif // _WIN32
// Stupid MingW just uses rand() from msvcrt.dll which uses RAND_MAX of 0x7fff
#if RAND_MAX < 0x7fffffff
#define rand32() ((uint32_t)((rand() << 17) | (rand() << 2) | (rand() & 3)))
#elif RAND_MAX < 0xffffffff
#define rand32(x) ((uint32_t)((rand(x) << 1) | (rand(x) & 1)))
#else
#define rand32(x) (uint32_t)rand(x)
#endif
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(NO_SOCKETS)
#define _NTSERVICE
#else
#ifndef NO_TAP
#define NO_TAP
#endif
#endif
#if (defined(__CYGWIN__) || defined(_WIN32) || defined(NO_SOCKETS)) && !defined(NO_SIGHUP)
#define NO_SIGHUP
#endif // (defined(__CYGWIN__) || defined(_WIN32) || defined(NO_SOCKETS)) && !defined(NO_SIGHUP)
#ifdef _WIN32
#ifndef USE_THREADS
#define USE_THREADS
#endif
#endif
#if defined(USE_THREADS)
#define _TLS __thread
#else
#define _TLS
#endif
#define GUID_STRING_LENGTH 36
#if defined(_WIN32)
#include <windows.h>
//#include <VersionHelpers.h>
typedef char* sockopt_t;
/* Unknown Winsock error codes */
#define WSAENODEV -1
// Map VLMCSD error codes to WSAGetLastError() and GetLastError() codes
// Add more if you need them
#define SOCKET_EADDRINUSE WSAEADDRINUSE
#define SOCKET_ENODEV WSAENODEV
#define SOCKET_EADDRNOTAVAIL WSAEADDRNOTAVAIL
#define SOCKET_EACCES WSAEACCES
#define SOCKET_EINVAL WSAEINVAL
#define SOCKET_ENOTSOCK WSAENOTSOCK
#define SOCKET_EINTR WSAEINTR
#define SOCKET_EINPROGRESS WSAEINPROGRESS
#define SOCKET_ECONNABORTED WSAECONNABORTED
#define SOCKET_EALREADY WSAEALREADY
#define VLMCSD_EACCES ERROR_ACCESS_DENIED
#define VLMCSD_EINVAL ERROR_INVALID_PARAMETER
#define VLMCSD_ENOMEM ERROR_OUTOFMEMORY
#define VLMCSD_EPERM ERROR_CAN_NOT_COMPLETE
#define socket_errno WSAGetLastError()
#define socketclose(x) (closesocket(x))
#define vlmcsd_strerror(x) win_strerror(x)
#define VLMCSD_SHUT_RD SD_RECEIVE
#define VLMCSD_SHUT_WR SD_SEND
#define VLMCSD_SHUT_RDWR SD_BOTH
#elif defined(__CYGWIN__)
#include <windows.h>
// Resolve conflicts between OpenSSL and MS Crypto API
#ifdef _CRYPTO_OPENSSL
#undef OCSP_RESPONSE
#undef X509_NAME
#endif
#else
typedef uint32_t DWORD;
typedef uint16_t WORD;
typedef uint8_t BYTE;
typedef uint16_t WCHAR;
typedef int32_t BOOL;
typedef int32_t HRESULT;
#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
#define FAILED(hr) (((HRESULT)(hr)) < 0)
#define S_OK ((HRESULT)0)
#define FALSE 0
#define TRUE !0
typedef struct {
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
} /*__packed*/ GUID;
typedef struct {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} /*__packed*/ FILETIME;
#endif // defined(__CYGWIN__)
#ifndef _WIN32
// Map VLMCSD error codes to POSIX codes
// Add more if you need them
#define SOCKET_EADDRINUSE EADDRINUSE
#define SOCKET_ENODEV ENODEV
#define SOCKET_EADDRNOTAVAIL EADDRNOTAVAIL
#define SOCKET_EACCES EACCES
#define SOCKET_EINVAL EINVAL
#define SOCKET_ENOTSOCK ENOTSOCK
#define SOCKET_EINTR EINTR
#define SOCKET_EINPROGRESS EINPROGRESS
#define SOCKET_ECONNABORTED ECONNABORTED
#define SOCKET_EALREADY EALREADY
#define VLMCSD_EACCES EACCES
#define VLMCSD_EINVAL EINVAL
#define VLMCSD_EINTR EINTR
#define VLMCSD_ENOMEM ENOMEM
#define VLMCSD_EPERM EPERM
typedef void* sockopt_t;
#define _countof(x) ( sizeof(x) / sizeof(x[0]) )
#define SOCKET int
#define INVALID_SOCKET -1
#define socket_errno errno
#define socketclose(x) (close(x))
#define vlmcsd_strerror strerror
#define VLMCSD_SHUT_RD SHUT_RD
#define VLMCSD_SHUT_WR SHUT_WR
#define VLMCSD_SHUT_RDWR SHUT_RDWR
#endif // __MINGW__
#define INVALID_UID ((uid_t)~0)
#define INVALID_GID ((gid_t)~0)
#undef IsEqualGUID
#define IsEqualGUID(a, b) ( !memcmp(a, b, sizeof(GUID)) )
#if !defined(__stdcall) && !_MSC_VER
#define __stdcall
#endif
#if !defined(__cdecl) && !_MSC_VER
#define __cdecl
#endif
typedef const char *const * CARGV;
typedef struct {
SOCKET socket;
DWORD RpcAssocGroup;
} CLDATA, *const PCLDATA;
#ifdef _MSC_VER
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define vlmcsd_snprintf _snprintf
#define vlmcsd_vsnprintf _vsnprintf
#define vlmcsd_unlink DeleteFile
#define vlmcsd_strtoll _strtoi64
#else // !_MSC_VER
#define vlmcsd_snprintf snprintf
#define vlmcsd_vsnprintf vsnprintf
#define vlmcsd_strtoll strtoll
#define vlmcsd_unlink unlink
#endif // !_MSC_VER
#endif // __types_h

1443
src/vlmcs.c Normal file

File diff suppressed because it is too large Load Diff

29
src/vlmcs.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef VLMCS_H_
#define VLMCS_H_
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#if !defined(USE_MSRPC) && defined(_WIN32)
#include <winsock2.h>
#endif // defined(USE_MSRPC) && defined(_WIN32)
#include "types.h"
#ifndef USE_MSRPC
#include "rpc.h"
#else // USE_MSRPC
#include "msrpc-client.h"
#endif // USE_MSRPC
#include "kms.h"
#if MULTI_CALL_BINARY < 1
#define client_main main
#else
int client_main(int argc, CARGV argv);
#endif
int SendActivationRequest(const RpcCtx sock, RESPONSE *baseResponse, REQUEST *baseRequest, RESPONSE_RESULT *result, BYTE *const hwid);
#endif /* VLMCS_H_ */

1976
src/vlmcsd.c Normal file

File diff suppressed because it is too large Load Diff

71
src/vlmcsd.h Normal file
View File

@ -0,0 +1,71 @@
#ifndef __main_h
#define __main_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#define __T(x) #x
#define _T(x) __T(x)
extern char *fn_log;
#include "types.h"
//int main(int argc, CARGV);
extern void cleanup();
int newmain();
#if MULTI_CALL_BINARY < 1
#define server_main main
#else
int server_main(int argc, CARGV argv);
#endif
#ifndef SA_NOCLDWAIT // required for Cygwin
#define SA_NOCLDWAIT 0
#endif
#if !defined(NO_INI_FILE) || !defined(NO_CL_PIDS)
#define INI_PARAM_RANDOMIZATION_LEVEL 1
#define INI_PARAM_LCID 2
#define INI_PARAM_LISTEN 3
#define INI_PARAM_MAX_WORKERS 4
#define INI_PARAM_CONNECTION_TIMEOUT 5
#define INI_PARAM_PID_FILE 6
#define INI_PARAM_LOG_FILE 7
#define INI_PARAM_LOG_VERBOSE 8
#define INI_PARAM_ACTIVATION_INTERVAL 9
#define INI_PARAM_RENEWAL_INTERVAL 10
#define INI_PARAM_DISCONNECT_IMMEDIATELY 11
#define INI_PARAM_UID 12
#define INI_PARAM_GID 13
#define INI_PARAM_PORT 14
#define INI_PARAM_RPC_NDR64 15
#define INI_PARAM_RPC_BTFN 16
#define INI_PARAM_FREEBIND 17
#define INI_PARAM_PUBLIC_IP_PROTECTION_LEVEL 18
#define INI_PARAM_LOG_DATE_AND_TIME 19
#define INI_PARAM_HOST_BUILD 20
#define INI_PARAM_WHITELISTING_LEVEL 24
#define INI_PARAM_CHECK_CLIENT_TIME 25
#define INI_PARAM_MAINTAIN_CLIENTS 26
#define INI_PARAM_START_EMPTY 27
#define INI_PARAM_DATA_FILE 28
#define INI_PARAM_VPN 29
#define INI_PARAM_EXIT_LEVEL 30
#define INI_FILE_PASS_1 1
#define INI_FILE_PASS_2 2
#define INI_FILE_PASS_3 3
typedef struct IniFileParameter
{
const char* const Name;
uint_fast8_t Id;
} IniFileParameter_t, *PIniFileParameter_t;
#endif // NO_INI_FILE
#endif // __main_h

121
src/vlmcsdmulti.c Normal file
View File

@ -0,0 +1,121 @@
/* Multi-Call Binary for vlmcs and vlmcsd */
#define _CRT_SECURE_NO_WARNINGS
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#if MULTI_CALL_BINARY < 1
#error "Please define MULTI_CALL_BINARY=1 when compiling this file."
#endif
#include <stdio.h>
#if !_MSC_VER
#include <libgen.h>
#else // _MSC_VER
#include <stdlib.h>
#include "helpers.h"
#endif // _MSC_VER
#include "vlmcs.h"
#include "vlmcsd.h"
#include "types.h"
#include "shared_globals.h"
#include "output.h"
#if (defined(_WIN32) || defined(__CYGWIN__))
#define compare strcasecmp // Best for case-preserving (but otherwise case-insensitive) filesystems
#else // native Unix
#define compare strcmp // for case-sensitive filesystems
#endif // native Unix
#if _MSC_VER
static char* basename(const char* fullname)
{
size_t len = strlen(fullname);
char* filename = (char*)vlmcsd_malloc(len + 1);
char* extension = (char*)vlmcsd_malloc(len + 1);
static char result[64];
_splitpath(fullname, NULL, NULL, filename, extension);
if (strlen(filename) + strlen(extension) > 63)
{
*result = 0;
goto finally;
}
strcpy(result, filename);
strcat(result, extension);
finally:
free(filename);
free(extension);
return result;
}
#endif // _MSC_VER
int main(int argc, CARGV argv)
{
multi_argv = argv;
multi_argc = argc;
if (!compare(basename((char*)*argv), "vlmcsd"))
return server_main(argc, argv);
if (!compare(basename((char*)*argv), "vlmcs"))
return client_main(argc, argv);
#ifdef _WIN32
if (!compare(basename((char*)*argv), "vlmcsd.exe"))
return server_main(argc, argv);
if (!compare(basename((char*)*argv), "vlmcs.exe"))
return client_main(argc, argv);
#endif // _WIN32
if (argc > 1)
{
if (!strcmp((char*)argv[1], "vlmcsd"))
return server_main(argc - 1, argv + 1);
if (!strcmp((char*)argv[1], "vlmcs"))
return client_main(argc - 1, argv + 1);
}
errorout(
"vlmcsdmulti %s\n\n"
"Usage:\n"
"\t%s vlmcsd [<vlmcsd command line>]\n"
"\t%s vlmcs [<vlmcs command line>]\n\n",
Version, *argv, *argv
);
return VLMCSD_EINVAL;
}
#if _MSC_VER && !defined(_DEBUG)
int __stdcall WinStartUp(void)
{
WCHAR **szArgList;
int argc;
szArgList = CommandLineToArgvW(GetCommandLineW(), &argc);
int i;
char **argv = (char**)vlmcsd_malloc(sizeof(char*)*argc);
for (i = 0; i < argc; i++)
{
int size = WideCharToMultiByte(CP_UTF8, 0, szArgList[i], -1, argv[i], 0, NULL, NULL);
argv[i] = (char*)vlmcsd_malloc(size);
WideCharToMultiByte(CP_UTF8, 0, szArgList[i], -1, argv[i], size, NULL, NULL);
}
exit(main(argc, argv));
}
#endif // _MSC_VER && !defined(_DEBUG)&& !MULTI_CALL_BINARY

78
src/wingetopt.c Normal file
View File

@ -0,0 +1,78 @@
/*
POSIX getopt for Windows
AT&T Public License
Code given out at the 1985 UNIFORUM conference in Dallas.
Modified for vlmcsd by Hotbird64
*/
#ifdef _MSC_VER
#include "wingetopt.h"
//#include <stdio.h>
#include <string.h>
#define EOF (-1)
#define ERR(s, c) if(opterr){\
char errbuf[2];\
errbuf[0] = c; errbuf[1] = '\n';\
fputs(argv[0], stderr);\
fputs(s, stderr);\
fputc(c, stderr);}
//(void) write(2, argv[0], (unsigned)strlen(argv[0]));\
//(void) write(2, s, (unsigned)strlen(s));\
//(void) write(2, errbuf, 2);}
int opterr = 1;
int optind = 1;
int optopt;
char* optarg;
int getopt(int argc, char * const argv[], const char *opts)
{
static int sp = 1;
register int c;
register char *cp;
if (sp == 1)
if (optind >= argc ||
argv[optind][0] != '-' || argv[optind][1] == '\0')
return(EOF);
else if (strcmp(argv[optind], "--") == 0) {
optind++;
return(EOF);
}
optopt = c = argv[optind][sp];
if (c == ':' || (cp = strchr(opts, c)) == NULL) {
//ERR(": illegal option -- ", (char)c);
if (argv[optind][++sp] == '\0') {
optind++;
sp = 1;
}
return('?');
}
if (*++cp == ':') {
if (argv[optind][sp + 1] != '\0')
optarg = (char*)&argv[optind++][sp + 1];
else if (++optind >= argc) {
//ERR(": option requires an argument -- ", (char)c);
sp = 1;
return('?');
}
else
optarg = (char*)argv[optind++];
sp = 1;
}
else {
if (argv[optind][++sp] == '\0') {
sp = 1;
optind++;
}
optarg = NULL;
}
return(c);
}
#endif // _MSC_VER

31
src/wingetopt.h Normal file
View File

@ -0,0 +1,31 @@
/*
POSIX getopt for Windows
AT&T Public License
Code given out at the 1985 UNIFORUM conference in Dallas.
Modified for vlmcsd by Hotbird64
*/
#ifndef _WINGETOPT_H_
#define _WINGETOPT_H_
#ifdef _MSC_VER
#ifdef __cplusplus
extern "C" {
#endif
extern int opterr;
extern int optind;
extern int optopt;
extern char *optarg;
extern int getopt(int argc, char * const argv[], const char *optstring);
#ifdef __cplusplus
}
#endif
#endif // _MSC_VER
#endif // __wingetopt_h

372
src/wintap.c Normal file
View File

@ -0,0 +1,372 @@
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "helpers.h"
#include "wintap.h"
#ifndef NO_TAP
#include "types.h"
#include "endian.h"
#include "output.h"
#include "tap-windows.h"
#include <iphlpapi.h>
#if !_WIN32
#include <arpa/inet.h>
#endif // !_WIN32
static char* szIpAddress = "10.10.10.9";
static char* szMask = "30";
static char* szTapName;
static char *ActiveTapName, *AdapterClass;
static char* szLeaseDuration = "1d";
static uint32_t IpAddress, Mask, Network, Broadcast, DhcpServer; // These are host-endian (=little-endian) for easier calculations
static uint32_t Mtu;
static uint_fast8_t Cidr;
static HANDLE TapHandle;
static TapDriverVersion_t DriverVersion;
static IpPacket_t* IpPacket;
static uint32_t DhcpLeaseDuration;
static BOOL isAddressAssigned()
{
PMIB_IPADDRTABLE pIPAddrTable;
DWORD dwSize = 0;
BOOL result = FALSE;
pIPAddrTable = (PMIB_IPADDRTABLE)vlmcsd_malloc(sizeof(MIB_IPADDRTABLE));
const DWORD status = GetIpAddrTable(pIPAddrTable, &dwSize, 0);
free(pIPAddrTable);
if (status != ERROR_INSUFFICIENT_BUFFER) return FALSE;
pIPAddrTable = (MIB_IPADDRTABLE *)vlmcsd_malloc(dwSize);
if (GetIpAddrTable(pIPAddrTable, &dwSize, 0))
{
free(pIPAddrTable);
return FALSE;
}
PMIB_IPADDRROW row;
for (row = pIPAddrTable->table; row < pIPAddrTable->table + pIPAddrTable->dwNumEntries; row++)
{
if (
row->dwAddr == BE32(IpAddress) &&
!(row->wType & (MIB_IPADDR_DELETED | MIB_IPADDR_DISCONNECTED | MIB_IPADDR_TRANSIENT))
)
{
result = TRUE;
break;
}
}
free(pIPAddrTable);
return result;
}
static void parseTapArgument(char* argument)
{
char* equalSignPosition = strchr(argument, (int)'=');
char* slashPosition = strchr(argument, (int)'/');
char* colonPosition = strchr(argument, (int)':');
szTapName = argument;
if (equalSignPosition)
{
*equalSignPosition = 0;
szIpAddress = equalSignPosition + 1;
}
if (slashPosition)
{
*slashPosition = 0;
szMask = slashPosition + 1;
}
if (colonPosition)
{
*colonPosition = 0;
szLeaseDuration = colonPosition + 1;
}
IpAddress = BE32(inet_addr(szIpAddress));
if (IpAddress == BE32(INADDR_NONE))
{
printerrorf("Fatal: %s is not a valid IPv4 address\n", szIpAddress);
exit(VLMCSD_EINVAL);
}
char* next;
Cidr = (uint8_t)strtol(szMask, &next, 10);
if (*next || Cidr < 8 || Cidr > 30)
{
printerrorf("Fatal: /%s is not a valid CIDR mask between /8 and /30\n", szMask);
exit(VLMCSD_EINVAL);
}
if (!((DhcpLeaseDuration = timeSpanString2Seconds(szLeaseDuration))))
{
printerrorf("Fatal: No valid time span specified in option -%c.\n", 'O');
exit(VLMCSD_EINVAL);
}
Mask = (uint32_t)~(0xffffffff >> Cidr);
Network = IpAddress & Mask;
Broadcast = IpAddress | ~Mask;
DhcpServer = IpAddress + 1;
if (IpAddress <= Network || IpAddress + 1 >= Broadcast)
{
uint32_t lowerIpBE = BE32(Network + 1);
uint32_t upperIpBE = BE32(Broadcast - 2);
const char* szLower = vlmcsd_strdup(inet_ntoa(*(struct in_addr*)&lowerIpBE));
const char* szUpper = vlmcsd_strdup(inet_ntoa(*(struct in_addr*)&upperIpBE));
printerrorf("Fatal: For this subnet the IPv4 address must be ");
if (lowerIpBE == upperIpBE)
{
printerrorf("%s\n", szLower);
}
else
{
printerrorf("between %s and %s\n", szLower, szUpper);
}
exit(VLMCSD_EINVAL);
}
}
__noreturn static void WinErrorExit(DWORD error)
{
printerrorf("Registry read error: %s\n", win_strerror((int)error));
exit(error);
}
static HANDLE OpenTapHandle()
{
HANDLE handle = INVALID_HANDLE_VALUE;
HKEY regAdapterKey;
DWORD regResult;
if ((regResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0, KEY_READ | KEY_WOW64_64KEY, &regAdapterKey)) != ERROR_SUCCESS)
{
WinErrorExit(regResult);
}
char subKeyName[TAP_REGISTRY_DATA_SIZE];
DWORD i, subKeySize = sizeof(subKeyName);
for (i = 0; (regResult = RegEnumKeyEx(regAdapterKey, i, subKeyName, &subKeySize, NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS; i++)
{
HKEY regSubKey;
DWORD type, regDataSize;
char regData[TAP_REGISTRY_DATA_SIZE];
if (regResult) WinErrorExit(regResult);
if ((regResult = RegOpenKeyEx(regAdapterKey, subKeyName, 0, KEY_READ | KEY_WOW64_64KEY, &regSubKey)) == ERROR_SUCCESS)
{
regDataSize = sizeof(regData);
if (RegQueryValueEx(regSubKey, "ComponentId", NULL, &type, (LPBYTE)regData, &regDataSize) == ERROR_SUCCESS)
{
if (
type == REG_SZ &&
(
!strncmp(regData, "tap0801", sizeof(regData)) ||
!strncmp(regData, "tap0901", sizeof(regData)) ||
!strncmp(regData, "TEAMVIEWERVPN", sizeof(regData))
)
)
{
AdapterClass = vlmcsd_strdup(regData);
regDataSize = sizeof(regData);
if (RegQueryValueEx(regSubKey, "NetCfgInstanceId", NULL, &type, (LPBYTE)regData, &regDataSize) == ERROR_SUCCESS && type == REG_SZ)
{
HKEY connectionKey;
char connectionKeyName[TAP_REGISTRY_DATA_SIZE];
strncpy(connectionKeyName, NETWORK_CONNECTIONS_KEY "\\", sizeof(connectionKeyName));
strncat(connectionKeyName, regData, sizeof(connectionKeyName) - strlen(connectionKeyName) - 1);
strncat(connectionKeyName, "\\Connection", sizeof(connectionKeyName) - strlen(connectionKeyName) - 1);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, connectionKeyName, 0, KEY_READ | KEY_WOW64_64KEY, &connectionKey) == ERROR_SUCCESS)
{
char deviceName[TAP_REGISTRY_DATA_SIZE];
regDataSize = sizeof(deviceName);
if (RegQueryValueEx(connectionKey, "Name", NULL, &type, (LPBYTE)deviceName, &regDataSize) == ERROR_SUCCESS && type == REG_SZ)
{
if (!strcmp(szTapName, ".") || !strncasecmp(szTapName, deviceName, sizeof(deviceName)))
{
ActiveTapName = vlmcsd_strdup(deviceName);
strncpy(deviceName, USERMODEDEVICEDIR, sizeof(deviceName));
strncat(deviceName, regData, sizeof(deviceName) - strlen(deviceName) - 1);
strncat(deviceName, strcmp(AdapterClass, "TEAMVIEWERVPN") ? TAP_WIN_SUFFIX : ".dgt", sizeof(deviceName) - strlen(deviceName) - 1);
handle = CreateFile(deviceName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
}
}
}
RegCloseKey(connectionKey);
}
if (handle == INVALID_HANDLE_VALUE) free(AdapterClass);
}
}
}
RegCloseKey(regSubKey);
subKeySize = sizeof(subKeyName);
if (handle != INVALID_HANDLE_VALUE) break;
}
RegCloseKey(regAdapterKey);
if (handle == INVALID_HANDLE_VALUE)
{
printerrorf("Fatal: No compatible VPN adapter");
if (!strcmp(szTapName, "."))
{
printerrorf("s");
}
else
{
printerrorf(" with name \"%s\"", szTapName);
}
printerrorf(" available for use\n");
exit(ERROR_DEVICE_NOT_AVAILABLE);
}
return handle;
}
static int DevCtl(DWORD code, void* data, DWORD len)
{
if (!DeviceIoControl(TapHandle, code, data, len, data, len, &len, NULL))
{
const DWORD error = GetLastError();
printerrorf("Fatal: VPN adapter error: %s\n", win_strerror(error));
exit(error);
}
return len;
}
static DWORD WINAPI TapMirror(LPVOID data_unused)
{
while (TRUE)
{
DWORD bytesRead, bytesWritten;
if (!ReadFile(TapHandle, IpPacket, Mtu, &bytesRead, NULL)) break;
const uint32_t temp = IpPacket->ip_src;
IpPacket->ip_src = IpPacket->ip_dst;
IpPacket->ip_dst = temp;
if (!WriteFile(TapHandle, IpPacket, bytesRead, &bytesWritten, NULL)) break;
# if !defined(NO_LOG) && defined(_PEDANTIC)
if (bytesRead != bytesWritten) logger("Warning: VPN device \"%s\": %u bytes could not be written\n", ActiveTapName, bytesRead - bytesWritten);
# endif // !defined(NO_LOG) && defined(_PEDANTIC)
}
const DWORD error = GetLastError();
# ifndef NO_LOG
logger("Warning: VPN thread for device \"%s\" exiting: %s\n", ActiveTapName, win_strerror(error));
# endif // NO_LOG
free(ActiveTapName);
CloseHandle(TapHandle);
exitOnWarningLevel(1);
return error;
}
void startTap(char* const argument)
{
if (!strcmp(argument, "-")) return;
parseTapArgument(argument);
TapHandle = OpenTapHandle();
// Get MTU and driver version
DevCtl(TAP_WIN_IOCTL_GET_MTU, &Mtu, sizeof(Mtu));
DevCtl(TAP_WIN_IOCTL_GET_VERSION, &DriverVersion, sizeof(DriverVersion));
// Configure TUN mode
TapConfigTun_t tapTunCfg;
tapTunCfg.Address.s_addr = BE32(IpAddress);
tapTunCfg.Network.s_addr = BE32(Network);
tapTunCfg.Mask.s_addr = BE32(Mask);
DevCtl(TAP_WIN_IOCTL_CONFIG_TUN, &tapTunCfg, sizeof(tapTunCfg));
// Setup the drivers internal DHCP server
TapConfigDhcp_t tapDhcpCfg;
tapDhcpCfg.Address.s_addr = BE32(IpAddress);
tapDhcpCfg.Mask.s_addr = BE32(Mask);
tapDhcpCfg.DhcpServer.s_addr = BE32(IpAddress + 1);
tapDhcpCfg.LeaseDuration = DhcpLeaseDuration;
DevCtl(TAP_WIN_IOCTL_CONFIG_DHCP_MASQ, &tapDhcpCfg, sizeof(tapDhcpCfg));
// Connect the virtual network cable
BOOL isCableConnected = TRUE;
DevCtl(TAP_WIN_IOCTL_SET_MEDIA_STATUS, &isCableConnected, sizeof(isCableConnected));
// Allocate buffer and start mirror thread
IpPacket = (IpPacket_t*)vlmcsd_malloc(Mtu);
HANDLE threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TapMirror, NULL, 0, NULL);
if (!threadHandle)
{
DWORD error = GetLastError();
printerrorf("Fatal: Unable to start VPN thread: %s\n", win_strerror(error));
exit(error);
}
CloseHandle(threadHandle);
# ifndef NO_LOG
logger("%s %u.%u.%u device \"%s\" started\n", AdapterClass, DriverVersion.Major, DriverVersion.Minor, DriverVersion.Build, ActiveTapName);
# endif // NO_LOG
DWORD i;
BOOL isAssigned;
// Wait up to 4 seconds until the IP address is up and running
// so vlmcsd can actually bind to and listen on it
for (i = 0; !((isAssigned = isAddressAssigned())) && i < 20; i++) Sleep(200);
if (!isAssigned)
{
printerrorf("Warning: IPv4 address %s not assigned\n", szIpAddress);
}
else
{
# ifndef NO_LOG
logger("IPv4 address %s assigned\n", szIpAddress);
# endif // NO_LOG
}
}
#endif // NO_TAP

50
src/wintap.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef __WINTAP_H
#define __WINTAP_H
#define TAP_REGISTRY_DATA_SIZE 256
// Network-Endian (= Big-Endian)
typedef struct TapConfigTun
{
struct in_addr Address;
struct in_addr Network;
struct in_addr Mask;
} TapConfigTun_t, *PTapConfigTun_t;
// Network-Endian (= Big-Endian), except LeaseDuration
typedef struct TapConfigDhcp
{
struct in_addr Address;
struct in_addr Mask;
struct in_addr DhcpServer;
uint32_t LeaseDuration; // Host-Endian (=Little-Endian). Anything else is Big-Endian
} TapConfigDhcp_t, *PTapConfigDhcp_t;
typedef struct TapDriverVersion
{
uint32_t Major;
uint32_t Minor;
uint32_t Build;
uint32_t Revision;
} TapDriverVersion_t, *PTapDriverVersion_t;
// Network-Endian (= Big-Endian)
typedef struct IpPacket {
uint8_t ip_hl : 4, /* header length */
ip_v : 4; /* version */
uint8_t ip_tos; /* type of service */
int16_t ip_len; /* total length */
uint16_t ip_id; /* identification */
int16_t ip_off; /* fragment offset field */
uint8_t ip_ttl; /* time to live */
uint8_t ip_p; /* protocol */
uint16_t ip_sum; /* checksum */
uint32_t ip_src, ip_dst; /* source and dest address */
uint8_t payload[0];
} IpPacket_t, *PIpPacket_t;
void startTap(char* const argument);
#endif //__WINTAP_H