diff --git a/GNUmakefile b/GNUmakefile
index a2fa9ff..9dd9b42 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,6 +1,6 @@
.NOTPARALLEL:
-MAX_THREADS ?= 16
+MAX_THREADS ?= 4
PROGRAM_NAME ?= bin/vlmcsd
CLIENT_NAME ?= bin/vlmcs
diff --git a/VisualStudio/vlmcsd/vlmcsd.vcxproj b/VisualStudio/vlmcsd/vlmcsd.vcxproj
index 65770ba..070b3d8 100644
--- a/VisualStudio/vlmcsd/vlmcsd.vcxproj
+++ b/VisualStudio/vlmcsd/vlmcsd.vcxproj
@@ -22,6 +22,7 @@
{918B4F5B-6356-451E-998C-5FCB29988170}
vlmcsd-Windows
vlmcsd-Windows
+ 7.0
@@ -85,7 +86,7 @@
$(SolutionDir)!bin!\vlmcsd\Debug\x86
- vlmcsd-Windows-x86
+ vlmcsd-Windows-x64
$(SolutionDir)!bin!\vlmcsd\Debug\x64
diff --git a/src/config.h b/src/config.h
index 0fff472..b04cdd1 100644
--- a/src/config.h
+++ b/src/config.h
@@ -24,7 +24,7 @@
* Define your own version identifier here, e.g. '#define VERSION "my vlmcsd based on 1103"'
*/
-#define VERSION "- built version 6/17/23"
+#define VERSION __DATE__
#endif // VERSION
diff --git a/src/kms.h b/src/kms.h
index 063e919..d1a4394 100644
--- a/src/kms.h
+++ b/src/kms.h
@@ -54,7 +54,7 @@
#define ActivationInterval VLActivationInterval
#define RenewalInterval VLRenewalInterval
-#define MAX_CLIENTS 671
+#define MAX_CLIENTS 16777215
typedef struct
{
diff --git a/src/vlmcsd.c b/src/vlmcsd.c
index 5c283e8..b858c81 100644
--- a/src/vlmcsd.c
+++ b/src/vlmcsd.c
@@ -264,117 +264,149 @@ static __noreturn void usage()
static __noreturn void usage()
{
- printerrorf("vlmcsd %s\n"
+
+ printerrorf(
+ /////////////////////////////////////////////////////////////////////
+ //// VLMCSD Introduction
+ "Volume Management Service (vlmcsd)\n"
+ "Build Date: %s\n"
"\nUsage:\n"
- " %s [Options]\n\n"
- "Options:\n"
+ "\t%s [Options]\n\n"
+ "Available options:\n"
+ /////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////
+ //// Windows Intergration (With define User in LC)
# if !defined(_WIN32) && !defined(NO_USER_SWITCH)
" -u \t\tset uid to \n"
" -g \t\tset gid to \n"
# endif // !defined(_WIN32) && !defined(NO_USER_SWITCH)
+ /////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////
+ //// ePID stands for "Enhanced Privacy ID". It is a cryptographic scheme for providing anonymous signatures. Use EPID as Windows EPID.
+ //// CSVLK stands for "Microsoft Customer Specific Volume License Key", known as KMS activation host key.
# ifndef NO_CL_PIDS
- " -a =\tuse for \n"
+ " -a =\tUse an ePID value for a set of CSVLK.\n\t\t\tePID is known as privacy ID, points for an Windows action, while CSLVK is the key for KMS host to serve activation service.\n\n"
# endif // NO_CL_PIDS
+ /////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////
+ //// ePID randomization level is used
# ifndef NO_RANDOM_EPID
- " -r 0|1|2\t\tset ePID randomization level (default 1)\n"
- " -C \t\tuse fixed in random ePIDs\n"
- " -H \t\tuse fixed number in random ePIDs\n"
+ " -r (0|1|2)\t\tSet randomization level of the ePIDs (default is \"0\").\n\t\t\t\"0\" stands for no randomization, which also means VLMCSD will use the default ePID that is built-in. It is useful for emulating/replicating real KMS servers.\n\t\t\t\"1\" stands for randomization of each KMS request, but it also poses a risk of being detected non-genuine KMS Server, causing clients to fail to be activated.\n\t\t\t\"2\" is as same as the \"1\" option, but only for debugging.\n\n"
+ " -C \t\tUse fixed Windows Language Code Identifier in random ePIDs (default English US LCID=1033).\n\t\t\tSee https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c for correct LCIDs.\n\n"
+ " -H \t\tUse fixed Windows build number for activation.\n\t\t\tUseful when the client requires a proper KMS Server.\n\t\t\tSee all build numbers here: https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions\n\n"
# endif // NO_RANDOM_EPID
+ /////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////
+ //// IP Address treats, using rule of RFC 1918 and RFC 6598
# if !defined(NO_PRIVATE_IP_DETECT)
# if HAVE_GETIFADDR
- " -o 0|1|2|3\t\tset protection level against clients with public IP addresses (default 0)\n"
+ " -o (0|1|2|3)\t\tSet protection level against clients with public IP addresses (default 0)\n\t\t\t\"0\" for no protection, allowing all IP addresses to use KMS service\n\t\t\t\"1\" only allows VLMCSD service replies connection with IP addresses in the range define by RFC1918 + 169.254.0.0/16 + 127.0.0.0/8,\n\t\t\t but still accept connection from public IP addresses.\n\t\t\t\"2\" does not affect the interfaces, while it only check if the client is either external (outbound) and drops its TCP packets when detected\n\t\t\t\"3\" is the combination of \"1\" and \"2\", for dropping package to that public IP addresses and no reply to that IP addresses.\n\n"
# else // !HAVE_GETIFADDR
# ifndef USE_MSRPC
- " -o 0|2\t\tset protection level against clients with public IP addresses (default 0)\n"
+ " -o (0|2)\t\tSet protection level against clients with public IP addresses (default 0)\n\t\t\t\"0\" for no protection, allowing all IP addresses to use KMS service\n\t\t\t\"2\" does not affect the interfaces, while it only check if the client is either external (outbound) and drops its TCP packets when detected.\n\n"
# else // USE_MSRPC
- " -o 0|2\t\tset protection level against clients with public IP addresses (default 0). Limited use with MS RPC\n"
+ " -o (0|2)\t\tSet protection level against clients with public IP addresses (default 0)\n\t\t\t\"0\" for no protection, allowing all IP addresses to use KMS service\n\t\t\t\"2\" does not affect the interfaces, while it only check if the client is either external (outbound) and drops its TCP packets when detected.\n\n"
# endif // USE_MSRPC
# endif // !HAVE_GETIFADDR
# endif // !defined(NO_PRIVATE_IP_DETECT)
+ /////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////
+ //// TAP VPN Adapter
# ifndef NO_TAP
- " -O [=][/]\tuse VPN adapter with IPv4 address and CIDR \n"
+ " -O vpn-adapter-name[=ipv4-address][/cidr-mask][:dhcp-lease-duration]\n\t\t\tEnable another compatible VPN adapter for another activation interface. Only available on Windows/Cygwin.\n\t\t\tCompatible with TAP for Windows (version 8.2 or above) and TeamViewer VPN adapter.\n\n"
# endif
+ /////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////
+ //// VLMCSD SOCKETS
# ifndef NO_SOCKETS
- " -x \t\texit if warning reached (default 0)\n"
+ " -x (0|1)\t\tConfigure how VLMCSD deal with errors while operating (default 0)\n\t\t\t\"0\" will make VLMCSD stay as long as possible, only exit the interface that having problem (including VPN)\n\t\t\t\"1\" will exit VLMCSD process if there are any problem with any network interface.\n\n"
# if !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
- " -L [:]\tlisten on IP address with optional \n"
- " -P \t\tset TCP port for subsequent -L statements (default 1688)\n"
+ " -L [:port]\tListen on the specific IP Address (IPv4/IPv6) with port defined optionally.\n\n"
+ " -P \t\tSet the specific TCP port for subsequent \"-L\" statement (default 1688).\n\t\t\tIf you use \"-P\" alongside with \"-L\", \"-P\" must be specified before \"-L\".\n\n"
# if HAVE_FREEBIND
- " -F0, -F1\t\tdisable/enable binding to foreign IP addresses\n"
+ " -F0, -F1\t\tDisable/enable binding to foreign IP addresses\n\n"
# endif // HAVE_FREEBIND
# else // defined(USE_MSRPC) || defined(SIMPLE_SOCKETS)
- " -P \t\tuse TCP port (default 1688)\n"
+ " -P \t\tSet the specific TCP port for subsequent \"-L\" statement (default 1688).\n\t\t\tIf you use \"-P\" alongside \"-L\", \"-P\" must be specified before \"-L\".\n\n
# endif // defined(USE_MSRPC) || defined(SIMPLE_SOCKETS)
# if !defined(NO_LIMIT) && !__minix__
- " -m \t\tHandle max. simultaneously (default no limit)\n"
+ " -m \t\tMaximum clients VLMCSD can handle at the same time.\n\n"
# endif // !defined(NO_LIMIT) && !__minix__
# ifdef _NTSERVICE
- " -s\t\t\tinstall vlmcsd as an NT service. Ignores -e"
+ " -s\t\t\tInstall VLMCSD as a Windows NT service. Combine with another flags to install VLMCSD with custom runner. Disable \"-e\" log to command interface.\n\n"
# ifndef _WIN32
", -f and -D"
# endif // _WIN32
- "\n"
- " -S\t\t\tremove vlmcsd service. Ignores all other options\n"
- " -U \t\trun NT service as . Must be used with -s\n"
- " -W \t\toptional for -U. Must be used with -s\n"
+ " -S\t\t\tRemove VLMCSD service on Windows NT. It ignores all other options.\n\t\t\tAfter the service uninstallation is completed, you no longer can use VLMCSD as NT service, but still run it standalone.\n\n"
+ " -U \t\tRun VLMCSD with NT service as a existed user. Required flag of NT service installation for VLMCSD \"-s\"\n\n"
+ " -W \t\t(Optional) Password for running VLMCSD as a NT service. Required flag of NT service installation for VLMCSD \"-s\"\n\n"
# endif // _NTSERVICE
# ifndef NO_LOG
- " -e\t\t\tlog to stdout\n"
+ " -e\t\t\tLogging to command line interface (stdout). Useful when running VLMCSD on Docker Container, or floppy on Virtual Machine.\n\n"
# endif // NO_LOG
-# ifndef _WIN32 //
- " -D\t\t\trun in foreground\n"
-# else // _WIN32
- " -D\t\t\tdoes nothing. Provided for compatibility with POSIX versions only\n"
-# endif // _WIN32
+ " -D\t\t\tRun VLMCSD in foreground, useful when in the debugging.\n\t\t\tWindows is not compatible with this feature.\n\n"
# endif // NO_SOCKETS
+ /////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////
+ //// STRICT MODES FOR VLMCSD
# ifndef NO_STRICT_MODES
- " -K 0|1|2|3\t\tset white-listing level for KMS IDs (default -K0)\n"
- " -c0, -c1\t\tdisable/enable client time checking (default -c0)\n"
+ " -K (0|1|2|3)\t\tSet white-listing level which product VLMCSD accepts or refuses (default 0)\n\t\t\t\t0: Activate all products with an unknown, retail or beta/preview KMS IDs.\n\t\t\t\t1: Activate products with a retail or beta/preview KMS ID but refuse to activate products with an unknown KMS ID.\n\t\t\t\t2: Activate products with an unknown KMS ID but refuse products with a retail or beta/preview KMS ID.\n\t\t\t\t3: Activate only products with a known volume license RTM KMS ID and refuse all others.\n\n"
+ " -c (0|1)\t\tDisable (0)/Enable (1) client time checking. If the client time is different than 4 hours compare to the KMS Host, the host will deny the activation. (default 0).\n\t\t\tNote: It is recommended that the VLMCSD has a reliable time service (e.g. sync the time with time.windows.com).\n\n"
# ifndef NO_CLIENT_LIST
- " -M0, -M1\t\tdisable/enable maintaining clients (default -M0)\n"
- " -E0, -E1\t\tdisable/enable start with empty client list (default -E0, ignored if -M0)\n"
+ " -M (0|1)\t\tDisable (0)/Enable (1) maintaining clients (default 0).\n\t\t\tNote: Enabling this service is not recommended, except you have to do so to prevent the activation failling.\n\t\t\tIt is because the VLMCSD can only keep maximum of 16777215 clients. If that number exceed, VLMCSD will no longer accept any new connect, nor activation requests.\n\n"
+ " -E (0|1)\t\tDisable (0)/Enable (1) starting VLMCSD with empty client list (Default 0).\n\t\t\tNote: It is recommended to keep the default, because Office will not activate unless your KMS Host has at least 5 active clients.\n\t\t\tSee more: https://learn.microsoft.com/en-us/office/troubleshoot/administration/0xc004f038-computer-not-activate\n\n"
# endif // !NO_CLIENT_LIST
# endif // !NO_STRICT_MODES
+ /////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////
+ //// VLMCSD Client treats
# ifndef USE_MSRPC
# if !defined(NO_TIMEOUT) && !__minix__
- " -t \t\tdisconnect clients after of inactivity (default 30)\n"
+ " -t \t\tDisconnect client after an amount of time of inactivity (default 30)\n\n"
# endif // !defined(NO_TIMEOUT) && !__minix__
- " -d\t\t\tdisconnect clients after each request\n"
- " -k\t\t\tdon't disconnect clients after each request (default)\n"
+ " -d\t\t\tDisconnect each client after processing one activation request.\n\n"
+ " -k\t\t\tDo not disconnect clients after processing an activation request (default if \"-d\" defined in external VLMCSD configuration file).\n\n"
# ifndef SIMPLE_RPC
- " -N0, -N1\t\tdisable/enable NDR64\n"
- " -B0, -B1\t\tdisable/enable bind time feature negotiation\n"
+ " -N (0|1)\t\tDisable (0)/Enable (1) NDR64 (default 1).\n\t\t\tOnly useful when on Windows 7/Vista 32-bit, where enabling NDR64 will make VLMCSD by default running higher Windows build number.\n\n"
+ " -B (0|1)\t\tDisable (0)/Enable (1) bind time feature negotiation in RPC protocol.\n\n"
# endif // !SIMPLE_RPC
# endif // USE_MSRPC
# ifndef NO_PID_FILE
- " -p \t\twrite pid to \n"
+ " -p \t\tCreate pid file filename.\n\t\t\tThis is used by standard init scripts (typically found in \"/etc/init.d\"). The default is not to write a pid file.\n\n"
# endif // NO_PID_FILE
# ifndef NO_INI_FILE
- " -i \t\tuse config file \n"
+ " -i \t\tUse external VLMCSD configuration file. Default name of that file is \"vlmcsd.ini\".\n\n"
# endif // NO_INI_FILE
# ifndef NO_EXTERNAL_DATA
- " -j \t\tuse KMS data file \n"
+ " -j \t\tUse external VLMCSD ePID database. Default name of that file is \"vlmcsd.kmd\".\n\n"
# endif // !NO_EXTERNAL_DATA
# ifndef NO_CUSTOM_INTERVALS
- " -R \t\trenew activation every (default 1w)\n"
- " -A \t\tretry activation every (default 2h)\n"
+ " -R \t\tRenew activation every (default 1w).\n\n"
+ " -A \t\tRetry activation every , if the previous activation/reactivation is failed (default 2h).\n\n"
# endif // NO_CUSTOM_INTERVALS
# ifndef NO_LOG
# ifndef _WIN32
" -l syslog log to syslog\n"
# endif // _WIN32
- " -l \t\tlog to \n"
- " -T0, -T1\t\tdisable/enable logging with time and date (default -T1)\n"
+ " -l \t\tWrites VLMCSD log into a file.\n\t\t\tNote: Make sure you have read+write access to that file.\n\n"
+ " -T0, -T1\t\tDisable (0)/Enable logging client connection with time and date (default 1).\n\n"
# ifndef NO_VERBOSE_LOG
- " -v\t\t\tlog verbose\n"
- " -q\t\t\tdon't log verbose (default)\n"
+ " -v\t\t\tAllow logging verbose.\n\n"
+ " -q\t\t\tDon't allow log verbose (default).\n\n"
# endif // NO_VERBOSE_LOG
# endif // NO_LOG
# ifndef NO_VERSION_INFORMATION
- " -V\t\t\tdisplay version information and exit\n"
+ " -V\t\t\tDisplay version information and exit\n"
# endif // NO_VERSION_INFORMATION
- ,
- Version, global_argv[0]);
+ ,Version, global_argv[0]);
exit(VLMCSD_EINVAL);
}