diff --git a/VisualStudio/libkms/libkms.vcxproj b/VisualStudio/libkms/libkms.vcxproj
new file mode 100644
index 0000000..5321b32
--- /dev/null
+++ b/VisualStudio/libkms/libkms.vcxproj
@@ -0,0 +1,236 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {2A0FC04D-C3C0-43E2-8812-53AE901C5395}
+ vlmcsdmulti
+ 8.1
+
+
+
+ DynamicLibrary
+ true
+ v140_xp
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120_xp
+ true
+ MultiByte
+
+
+ DynamicLibrary
+ true
+ v140_xp
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120_xp
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)..\
+ libkms32
+ false
+ .dll
+
+
+ $(SolutionDir)..\
+ libkms64
+ false
+ .dll
+
+
+ false
+ $(ProjectName)64
+ .dll
+
+
+ false
+ .dll
+ $(ProjectName)32
+
+
+
+ Level3
+ Disabled
+ true
+ Default
+ true
+ _USING_V110_SDK71_;_MBCS;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;_PEDANTIC;SIMPLE_SOCKETS;NO_TIMEOUT;NO_SIGHUP;NO_CL_PIDS;NO_EXTENDED_PRODUCT_LIST;NO_BASIC_PRODUCT_LIST;NO_LOG;NO_RANDOM_EPID;NO_INI_FILE;NO_HELP;NO_CUSTOM_INTERVALS;NO_PID_FILE;NO_USER_SWITCH;NO_VERBOSE_LOG;NO_LIMIT;NO_VERSION_INFORMATION;NO_PRIVATE_IP_DETECT;IS_LIBRARY=1
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ NotSet
+
+
+
+
+
+ Level3
+ Disabled
+ true
+ _USING_V110_SDK71_;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;_PEDANTIC;SIMPLE_SOCKETS;NO_TIMEOUT;NO_SIGHUP;NO_CL_PIDS;NO_EXTENDED_PRODUCT_LIST;NO_BASIC_PRODUCT_LIST;NO_LOG;NO_RANDOM_EPID;NO_INI_FILE;NO_HELP;NO_CUSTOM_INTERVALS;NO_PID_FILE;NO_USER_SWITCH;NO_VERBOSE_LOG;NO_LIMIT;NO_VERSION_INFORMATION;NO_PRIVATE_IP_DETECT;IS_LIBRARY=1
+ true
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ NotSet
+
+
+
+
+
+ Level3
+ MinSpace
+ true
+ true
+
+
+ Cdecl
+ None
+ AnySuitable
+ Size
+ true
+ true
+ false
+ false
+ Fast
+ false
+ false
+ false
+ false
+ true
+ _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;SIMPLE_SOCKETS;NO_TIMEOUT;NO_SIGHUP;NO_CL_PIDS;NO_EXTENDED_PRODUCT_LIST;NO_BASIC_PRODUCT_LIST;NO_LOG;NO_RANDOM_EPID;NO_INI_FILE;NO_HELP;NO_CUSTOM_INTERVALS;NO_PID_FILE;NO_USER_SWITCH;NO_VERBOSE_LOG;NO_LIMIT;NO_VERSION_INFORMATION;NO_PRIVATE_IP_DETECT;IS_LIBRARY=1
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ true
+ true
+ $(SolutionDir)\msvcrt.lib;Shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ false
+ NotSet
+ true
+ true
+
+
+ true
+ true
+
+
+
+
+
+ Level3
+ MinSpace
+ true
+ true
+
+
+ _USING_V110_SDK71_;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;SIMPLE_SOCKETS;NO_TIMEOUT;NO_SIGHUP;NO_CL_PIDS;NO_EXTENDED_PRODUCT_LIST;NO_BASIC_PRODUCT_LIST;NO_LOG;NO_RANDOM_EPID;NO_INI_FILE;NO_HELP;NO_CUSTOM_INTERVALS;NO_PID_FILE;NO_USER_SWITCH;NO_VERBOSE_LOG;NO_LIMIT;NO_VERSION_INFORMATION;NO_PRIVATE_IP_DETECT;IS_LIBRARY=1
+ None
+ false
+ true
+ AnySuitable
+ Size
+ true
+ false
+ false
+ Fast
+ false
+ false
+ false
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ true
+ true
+ $(SolutionDir)\msvcrt64.lib;Shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ true
+ false
+ NotSet
+ true
+
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VisualStudio/libkms/libkms.vcxproj.filters b/VisualStudio/libkms/libkms.vcxproj.filters
new file mode 100644
index 0000000..3260758
--- /dev/null
+++ b/VisualStudio/libkms/libkms.vcxproj.filters
@@ -0,0 +1,93 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/VisualStudio/msvcrt.lib b/VisualStudio/msvcrt.lib
new file mode 100755
index 0000000..5fba2bc
Binary files /dev/null and b/VisualStudio/msvcrt.lib differ
diff --git a/VisualStudio/msvcrt64.lib b/VisualStudio/msvcrt64.lib
new file mode 100755
index 0000000..8210ec5
Binary files /dev/null and b/VisualStudio/msvcrt64.lib differ
diff --git a/VisualStudio/vlmcs/vlmcs.vcxproj b/VisualStudio/vlmcs/vlmcs.vcxproj
new file mode 100644
index 0000000..477791d
--- /dev/null
+++ b/VisualStudio/vlmcs/vlmcs.vcxproj
@@ -0,0 +1,227 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {2B3F305D-6351-4F4A-A7F2-1F9B1988CDEE}
+ vlmcs
+ 8.1
+
+
+
+ Application
+ true
+ v140_xp
+ MultiByte
+
+
+ Application
+ false
+ v120_xp
+ true
+ MultiByte
+
+
+ Application
+ true
+ v140_xp
+ MultiByte
+
+
+ Application
+ false
+ v120_xp
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)..\
+ vlmcs-Windows-x86
+ false
+
+
+ $(SolutionDir)..\
+ vlmcs-Windows-x64
+ false
+
+
+ false
+
+
+ false
+
+
+
+ Level3
+ Disabled
+ true
+ Default
+ true
+ _USING_V110_SDK71_;_MBCS;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;_PEDANTIC
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ Console
+
+
+
+
+ Level3
+ Disabled
+ true
+ _USING_V110_SDK71_;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;_PEDANTIC
+ true
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ Console
+
+
+
+
+ Level3
+ MinSpace
+ true
+ true
+
+
+ Cdecl
+ None
+ AnySuitable
+ Size
+ true
+ true
+ false
+ false
+ Fast
+ false
+ false
+ false
+ false
+ true
+ _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions);_CRYPTO_WINDOWS
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ true
+ true
+ $(SolutionDir)\msvcrt.lib;Shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ false
+ Console
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+ Level3
+ MinSpace
+ true
+ true
+
+
+ _USING_V110_SDK71_;%(PreprocessorDefinitions);_CRYPTO_WINDOWS
+ None
+ false
+ true
+ AnySuitable
+ Size
+ true
+ false
+ false
+ Fast
+ false
+ false
+ false
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ true
+ true
+ $(SolutionDir)\msvcrt64.lib;Shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ true
+ false
+ Console
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VisualStudio/vlmcs/vlmcs.vcxproj.filters b/VisualStudio/vlmcs/vlmcs.vcxproj.filters
new file mode 100644
index 0000000..155ee42
--- /dev/null
+++ b/VisualStudio/vlmcs/vlmcs.vcxproj.filters
@@ -0,0 +1,102 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/VisualStudio/vlmcsd-2015-with-2013-c++-build-tools.sln b/VisualStudio/vlmcsd-2015-with-2013-c++-build-tools.sln
new file mode 100755
index 0000000..d237675
--- /dev/null
+++ b/VisualStudio/vlmcsd-2015-with-2013-c++-build-tools.sln
@@ -0,0 +1,58 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vlmcsd", "vlmcsd.vcxproj", "{918B4F5B-6356-451E-998C-5FCB29988170}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vlmcs", "vlmcs\vlmcs.vcxproj", "{2B3F305D-6351-4F4A-A7F2-1F9B1988CDEE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vlmcsdmulti", "vlmcsdmulti\vlmcsdmulti.vcxproj", "{7F07671D-1432-43E9-9D72-08435F216B5E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libkms", "libkms\libkms.vcxproj", "{2A0FC04D-C3C0-43E2-8812-53AE901C5395}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {918B4F5B-6356-451E-998C-5FCB29988170}.Debug|x64.ActiveCfg = Debug|x64
+ {918B4F5B-6356-451E-998C-5FCB29988170}.Debug|x64.Build.0 = Debug|x64
+ {918B4F5B-6356-451E-998C-5FCB29988170}.Debug|x86.ActiveCfg = Debug|Win32
+ {918B4F5B-6356-451E-998C-5FCB29988170}.Debug|x86.Build.0 = Debug|Win32
+ {918B4F5B-6356-451E-998C-5FCB29988170}.Release|x64.ActiveCfg = Release|x64
+ {918B4F5B-6356-451E-998C-5FCB29988170}.Release|x64.Build.0 = Release|x64
+ {918B4F5B-6356-451E-998C-5FCB29988170}.Release|x86.ActiveCfg = Release|Win32
+ {918B4F5B-6356-451E-998C-5FCB29988170}.Release|x86.Build.0 = Release|Win32
+ {2B3F305D-6351-4F4A-A7F2-1F9B1988CDEE}.Debug|x64.ActiveCfg = Debug|x64
+ {2B3F305D-6351-4F4A-A7F2-1F9B1988CDEE}.Debug|x64.Build.0 = Debug|x64
+ {2B3F305D-6351-4F4A-A7F2-1F9B1988CDEE}.Debug|x86.ActiveCfg = Debug|Win32
+ {2B3F305D-6351-4F4A-A7F2-1F9B1988CDEE}.Debug|x86.Build.0 = Debug|Win32
+ {2B3F305D-6351-4F4A-A7F2-1F9B1988CDEE}.Release|x64.ActiveCfg = Release|x64
+ {2B3F305D-6351-4F4A-A7F2-1F9B1988CDEE}.Release|x64.Build.0 = Release|x64
+ {2B3F305D-6351-4F4A-A7F2-1F9B1988CDEE}.Release|x86.ActiveCfg = Release|Win32
+ {2B3F305D-6351-4F4A-A7F2-1F9B1988CDEE}.Release|x86.Build.0 = Release|Win32
+ {7F07671D-1432-43E9-9D72-08435F216B5E}.Debug|x64.ActiveCfg = Debug|x64
+ {7F07671D-1432-43E9-9D72-08435F216B5E}.Debug|x64.Build.0 = Debug|x64
+ {7F07671D-1432-43E9-9D72-08435F216B5E}.Debug|x86.ActiveCfg = Debug|Win32
+ {7F07671D-1432-43E9-9D72-08435F216B5E}.Debug|x86.Build.0 = Debug|Win32
+ {7F07671D-1432-43E9-9D72-08435F216B5E}.Release|x64.ActiveCfg = Release|x64
+ {7F07671D-1432-43E9-9D72-08435F216B5E}.Release|x64.Build.0 = Release|x64
+ {7F07671D-1432-43E9-9D72-08435F216B5E}.Release|x86.ActiveCfg = Release|Win32
+ {7F07671D-1432-43E9-9D72-08435F216B5E}.Release|x86.Build.0 = Release|Win32
+ {2A0FC04D-C3C0-43E2-8812-53AE901C5395}.Debug|x64.ActiveCfg = Debug|x64
+ {2A0FC04D-C3C0-43E2-8812-53AE901C5395}.Debug|x64.Build.0 = Debug|x64
+ {2A0FC04D-C3C0-43E2-8812-53AE901C5395}.Debug|x86.ActiveCfg = Debug|Win32
+ {2A0FC04D-C3C0-43E2-8812-53AE901C5395}.Debug|x86.Build.0 = Debug|Win32
+ {2A0FC04D-C3C0-43E2-8812-53AE901C5395}.Release|x64.ActiveCfg = Release|x64
+ {2A0FC04D-C3C0-43E2-8812-53AE901C5395}.Release|x64.Build.0 = Release|x64
+ {2A0FC04D-C3C0-43E2-8812-53AE901C5395}.Release|x86.ActiveCfg = Release|Win32
+ {2A0FC04D-C3C0-43E2-8812-53AE901C5395}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/VisualStudio/vlmcsd.vcxproj b/VisualStudio/vlmcsd.vcxproj
new file mode 100755
index 0000000..7b97a7d
--- /dev/null
+++ b/VisualStudio/vlmcsd.vcxproj
@@ -0,0 +1,229 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {918B4F5B-6356-451E-998C-5FCB29988170}
+ vlmcsd
+
+
+
+
+
+ Application
+ true
+ v140_xp
+ MultiByte
+
+
+ Application
+ true
+ v140_xp
+ MultiByte
+
+
+ Application
+ false
+ v120_xp
+ true
+ MultiByte
+
+
+ Application
+ false
+ v120_xp
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ $(SolutionDir)..\
+ vlmcsd-Windows-x64
+
+
+ false
+ false
+ vlmcsd-Windows-x86
+ $(SolutionDir)..\
+
+
+
+ Level3
+ Disabled
+ true
+ true
+ _USING_V110_SDK71_;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;_PEDANTIC
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ Console
+ Iphlpapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ Disabled
+ true
+ _USING_V110_SDK71_;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;_PEDANTIC
+ true
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ Console
+ Iphlpapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ MinSpace
+ true
+ true
+
+
+ true
+ false
+ false
+ false
+ false
+ Cdecl
+ Default
+ None
+ false
+ true
+ AnySuitable
+ Size
+ true
+ Fast
+ false
+ false
+ false
+ MultiThreadedDLL
+ false
+ _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions);_CRYPTO_WINDOWS
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+ false
+
+
+ true
+ true
+ Console
+ $(SolutionDir)\msvcrt.lib;Iphlpapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ false
+
+ true
+ true
+ true
+ true
+ UseLinkTimeCodeGeneration
+ true
+
+
+
+
+ Level3
+ MinSpace
+ true
+ true
+
+
+ None
+ true
+ AnySuitable
+ Size
+ true
+ true
+ false
+ false
+ false
+ false
+ false
+ _USING_V110_SDK71_;%(PreprocessorDefinitions);_CRYPTO_WINDOWS
+ MultiThreadedDLL
+ false
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ true
+ true
+ Console
+ $(SolutionDir)\msvcrt64.lib;Iphlpapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ false
+ UseLinkTimeCodeGeneration
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VisualStudio/vlmcsd.vcxproj.filters b/VisualStudio/vlmcsd.vcxproj.filters
new file mode 100755
index 0000000..060dced
--- /dev/null
+++ b/VisualStudio/vlmcsd.vcxproj.filters
@@ -0,0 +1,102 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/VisualStudio/vlmcsdmulti/vlmcsdmulti.vcxproj b/VisualStudio/vlmcsdmulti/vlmcsdmulti.vcxproj
new file mode 100755
index 0000000..75a4a12
--- /dev/null
+++ b/VisualStudio/vlmcsdmulti/vlmcsdmulti.vcxproj
@@ -0,0 +1,231 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {7F07671D-1432-43E9-9D72-08435F216B5E}
+ vlmcsdmulti
+ 8.1
+
+
+
+ Application
+ true
+ v140_xp
+ MultiByte
+
+
+ Application
+ false
+ v120_xp
+ true
+ MultiByte
+
+
+ Application
+ true
+ v140_xp
+ MultiByte
+
+
+ Application
+ false
+ v120_xp
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)..\
+ vlmcsdmulti-Windows-x86
+ false
+
+
+ $(SolutionDir)..\
+ vlmcsdmulti-Windows-x64
+ false
+
+
+ false
+
+
+ false
+
+
+
+ Level3
+ Disabled
+ true
+ Default
+ true
+ _USING_V110_SDK71_;_MBCS;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;_PEDANTIC;MULTI_CALL_BINARY=1
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ Console
+
+
+
+
+ Level3
+ Disabled
+ true
+ _USING_V110_SDK71_;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;_PEDANTIC;MULTI_CALL_BINARY=1
+ true
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ Console
+
+
+
+
+ Level3
+ MinSpace
+ true
+ true
+
+
+ Cdecl
+ None
+ AnySuitable
+ Size
+ true
+ true
+ false
+ false
+ Fast
+ false
+ false
+ false
+ false
+ true
+ _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;MULTI_CALL_BINARY=1
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ true
+ true
+ $(SolutionDir)\msvcrt.lib;Shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ false
+ Console
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+ Level3
+ MinSpace
+ true
+ true
+
+
+ _USING_V110_SDK71_;%(PreprocessorDefinitions);_CRYPTO_WINDOWS;MULTI_CALL_BINARY=1
+ None
+ false
+ true
+ AnySuitable
+ Size
+ true
+ false
+ false
+ Fast
+ false
+ false
+ false
+ false
+ $(ExternalCompilerOptions) %(AdditionalOptions)
+
+
+ true
+ true
+ $(SolutionDir)\msvcrt64.lib;Shlwapi.lib;Iphlpapi.lib;Dnsapi.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ true
+ false
+ Console
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VisualStudio/vlmcsdmulti/vlmcsdmulti.vcxproj.filters b/VisualStudio/vlmcsdmulti/vlmcsdmulti.vcxproj.filters
new file mode 100755
index 0000000..be33279
--- /dev/null
+++ b/VisualStudio/vlmcsdmulti/vlmcsdmulti.vcxproj.filters
@@ -0,0 +1,114 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/crypto.c b/crypto.c
index 52cdba8..e73ffa3 100644
--- a/crypto.c
+++ b/crypto.c
@@ -117,7 +117,7 @@ void AesInitKey(AesCtx *Ctx, const BYTE *Key, int_fast8_t IsV6, int RijndaelKeyB
memcpy(Ctx->Key, Key, RijndaelKeyBytes);
- for ( i = RijndaelKeyDwords; i < ( Ctx->rounds + 1 ) << 2; i++ )
+ for ( i = (uint_fast8_t)RijndaelKeyDwords; i < ( Ctx->rounds + 1 ) << 2; i++ )
{
temp = Ctx->Key[ i - 1 ];
diff --git a/crypto.h b/crypto.h
index 54cbde1..0e5f7dc 100644
--- a/crypto.h
+++ b/crypto.h
@@ -14,12 +14,10 @@
#include "endian.h"
#include
-//#define AES_ROUNDS (10)
#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_ROUNDS (11)
#define V4_KEY_BYTES (20) // 160 Bits
#define ROR32(v, n) ( (v) << (32 - n) | (v) >> n )
@@ -39,7 +37,7 @@ typedef struct {
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 *iv, BYTE *data, size_t *len);
+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);
diff --git a/crypto_internal.c b/crypto_internal.c
index c0cf761..8733db3 100644
--- a/crypto_internal.c
+++ b/crypto_internal.c
@@ -95,7 +95,7 @@ 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 += len;
+ Ctx->Len += (unsigned int)len;
if ( len < r_len )
{
diff --git a/crypto_windows.c b/crypto_windows.c
index d844396..6a93be5 100644
--- a/crypto_windows.c
+++ b/crypto_windows.c
@@ -39,7 +39,7 @@ static int_fast8_t AcquireCryptContext()
{
if (!hRsaAesProvider)
{
- return CryptAcquireContextW
+ return (int_fast8_t)CryptAcquireContextW
(
&hRsaAesProvider, // Provider handle
NULL, // No key container name
@@ -163,7 +163,7 @@ int_fast8_t Sha256Hmac(const BYTE* key, BYTE* restrict data, DWORD len, BYTE* re
if (hKey) CryptDestroyKey(hKey);
if (hHmacHash) CryptDestroyHash(hHmacHash);
- return success;
+ return (int_fast8_t)success;
}
#endif // _WIN32 || __CYGWIN__
diff --git a/crypto_windows.h b/crypto_windows.h
index 6ab8c98..d26b3f3 100644
--- a/crypto_windows.h
+++ b/crypto_windows.h
@@ -11,6 +11,9 @@
#else // _WIN32 || __CYGWIN__
#include "types.h"
+#if _MSC_VER
+#include "Wincrypt.h"
+#endif
typedef struct _Sha2356HmacCtx
{
@@ -18,7 +21,7 @@ typedef struct _Sha2356HmacCtx
HCRYPTKEY hKey;
} Sha256HmacCtx;
-int_fast8_t Sha256(BYTE *data, DWORD len, BYTE *hash);
+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);
diff --git a/dns_srv.c b/dns_srv.c
index ccf2cd0..4af1a92 100644
--- a/dns_srv.c
+++ b/dns_srv.c
@@ -309,7 +309,7 @@ int getKmsServerList(kms_server_dns_ptr** serverlist, const char *const restrict
memset(kms_server, 0, sizeof(kms_server_dns_t));
- snprintf(kms_server->serverName, sizeof(kms_server->serverName), "%s:%hu", dns_iterator->Data.SRV.pNameTarget, dns_iterator->Data.SRV.wPort);
+ 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;
diff --git a/dns_srv.h b/dns_srv.h
index d24173d..70f5928 100644
--- a/dns_srv.h
+++ b/dns_srv.h
@@ -96,7 +96,7 @@ typedef enum __ns_class {
#endif
-int getKmsServerList(kms_server_dns_ptr** serverlist, const char *restrict query);
+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
diff --git a/floppy144.vfd b/floppy144.vfd
index 2ed1620..bddfc16 100644
Binary files a/floppy144.vfd and b/floppy144.vfd differ
diff --git a/helpers.c b/helpers.c
index 8372acb..9c85025 100644
--- a/helpers.c
+++ b/helpers.c
@@ -2,6 +2,10 @@
* Helper functions used by other modules
*/
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
@@ -10,7 +14,11 @@
#ifndef _WIN32
#include
#endif // _WIN32
+#ifndef _MSC_VER
#include
+#else
+#include "wingetopt.h"
+#endif
#include
#include
#include
@@ -20,6 +28,7 @@
#include "shared_globals.h"
+
/*
* UCS2 <-> UTF-8 functions
* All functions use little endian UCS2 since we only need it to communicate with Windows via RPC
@@ -72,7 +81,7 @@ int ucs2_to_utf8_char (const WCHAR ucs2_le, char *utf8)
const WCHAR ucs2 = LE16(ucs2_le);
if (ucs2 < 0x80) {
- utf8[0] = ucs2;
+ utf8[0] = (char)ucs2;
utf8[1] = '\0';
return 1;
}
@@ -153,7 +162,7 @@ BOOL stringToInt(const char *const szValue, const unsigned int min, const unsign
char *nextchar;
errno = 0;
- long long result = strtoll(szValue, &nextchar, 10);
+ long long result = vlmcsd_strtoll(szValue, &nextchar, 10);
if (errno || result < (long long)min || result > (long long)max || *nextchar)
{
@@ -177,7 +186,7 @@ int_fast8_t string2Uuid(const char *const restrict input, GUID *const restrict g
{
if (i == 8 || i == 13 || i == 18 || i == 23) continue;
- const char c = toupper((int)input[i]);
+ const char c = (char)toupper((int)input[i]);
if (c < '0' || c > 'F' || (c > '9' && c < 'A')) return FALSE;
}
@@ -211,7 +220,7 @@ void LEGUID(GUID *const restrict out, const GUID* const restrict in)
#endif
}
-
+#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)
{
@@ -226,7 +235,6 @@ __pure unsigned int getOptionArgumentInt(const char o, const unsigned int min, c
return result;
}
-
// Resets getopt() to start parsing from the beginning
void optReset(void)
{
@@ -241,7 +249,7 @@ void optReset(void)
optind = 1;
#endif
}
-
+#endif // !IS_LIBRARY
#if defined(_WIN32) || defined(USE_MSRPC)
@@ -295,9 +303,13 @@ void parseAddress(char *const addr, char** szHost, char** szPort)
// 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
}
diff --git a/kms.c b/kms.c
index 6aae692..f576272 100644
--- a/kms.c
+++ b/kms.c
@@ -3,6 +3,10 @@
#endif // CONFIG
#include CONFIG
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
#include
#include
#include
@@ -200,8 +204,8 @@ const KmsIdList ExtendedProductList [] = {
{ { 0xb3ca044e, 0xa358, 0x4d68, { 0x98, 0x83, 0xaa, 0xa2, 0x94, 0x1a, 0xca, 0x99, } } /*b3ca044e-a358-4d68-9883-aaa2941aca99*/, LOGTEXT("Windows Server 2012 R2 Standard"), EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2012R2 },
// Windows Server 2016
- { { 0x7b4433f4, 0xb1e7, 0x4788, { 0x89, 0x5a, 0xc4, 0x53, 0x78, 0xd3, 0x82, 0x53, } } /*7b4433f4-b1e7-4788-895a-c45378d38253*/, LOGTEXT("Windows Server 2016 Azure Core"), EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2016 },
- { { 0x3dbf341b, 0x5f6c, 0x4fa7, { 0xb9, 0x36, 0x69, 0x9d, 0xce, 0x9e, 0x26, 0x3f, } } /*3dbf341b-5f6c-4fa7-b936-699dce9e263f*/, LOGTEXT("Windows Server 2016 Cloud Storage"), EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2016 },
+ { { 0x3dbf341b, 0x5f6c, 0x4fa7, { 0xb9, 0x36, 0x69, 0x9d, 0xce, 0x9e, 0x26, 0x3f, } } /*3dbf341b-5f6c-4fa7-b936-699dce9e263f*/, LOGTEXT("Windows Server 2016 Azure Core"), EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2016 },
+ { { 0x7b4433f4, 0xb1e7, 0x4788, { 0x89, 0x5a, 0xc4, 0x53, 0x78, 0xd3, 0x82, 0x53, } } /*7b4433f4-b1e7-4788-895a-c45378d38253*/, LOGTEXT("Windows Server 2016 Cloud Storage"), EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2016 },
{ { 0x21c56779, 0xb449, 0x4d20, { 0xad, 0xfc, 0xee, 0xce, 0x0e, 0x1a, 0xd7, 0x4b, } } /*21c56779-b449-4d20-adfc-eece0e1ad74b*/, LOGTEXT("Windows Server 2016 Datacenter"), EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2016 },
{ { 0x2b5a1b0f, 0xa5ab, 0x4c54, { 0xac, 0x2f, 0xa6, 0xd9, 0x48, 0x24, 0xa2, 0x83, } } /*2b5a1b0f-a5ab-4c54-ac2f-a6d94824a283*/, LOGTEXT("Windows Server 2016 Essentials"), EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2016 },
{ { 0x8c1c5410, 0x9f39, 0x4805, { 0x8c, 0x9d, 0x63, 0xa0, 0x77, 0x06, 0x35, 0x8f, } } /*8c1c5410-9f39-4805-8c9d-63a07706358f*/, LOGTEXT("Windows Server 2016 Standard"), EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2016 },
@@ -495,6 +499,10 @@ static void generateRandomPid(int index, char *const szPid, int serverType, int1
time_t maxTime, kmsTime;
time(&maxTime);
+# ifndef BUILD_TIME
+# define BUILD_TIME 1474752907
+# endif
+
if (maxTime < (time_t)BUILD_TIME) // Just in case the system time is < 10/17/2013 1:00 pm
maxTime = (time_t)BUILD_TIME;
@@ -748,7 +756,7 @@ static BOOL __stdcall CreateResponseBaseCallback(const REQUEST *const baseReques
memcpy(&baseResponse->CMID, &baseRequest->CMID, sizeof(GUID));
memcpy(&baseResponse->ClientTime, &baseRequest->ClientTime, sizeof(FILETIME));
- baseResponse->Count = index == 1 || index == 2 ? LE32(10) : LE32(50);
+ baseResponse->Count = index > 0 && index < 4 ? LE32(10) : LE32(50);
baseResponse->VLActivationInterval = LE32(VLActivationInterval);
baseResponse->VLRenewalInterval = LE32(VLRenewalInterval);
@@ -833,10 +841,10 @@ static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptS
// The last 16 bytes of the hashed time slot are the actual HMAC key
if (!Sha256Hmac
(
- hash + halfHashSize, // Use last 16 bytes of SHA256 as HMAC key
- encrypt_start, // hash only the encrypted part of the v6 response
- encryptSize - sizeof(((RESPONSE_V6*)0)->HMAC), // encryptSize minus the HMAC itself
- hash // use same buffer for resulting hash where the key came from
+ hash + halfHashSize, // Use last 16 bytes of SHA256 as HMAC key
+ encrypt_start, // hash only the encrypted part of the v6 response
+ (DWORD)(encryptSize - sizeof(((RESPONSE_V6*)0)->HMAC)), // encryptSize minus the HMAC itself
+ hash // use same buffer for resulting hash where the key came from
))
{
return FALSE;
diff --git a/kms.h b/kms.h
index 5a87588..96bbc8c 100644
--- a/kms.h
+++ b/kms.h
@@ -6,7 +6,11 @@
#endif // CONFIG
#include CONFIG
+#if _MSC_VER
+#include
+#else
#include
+#endif // _MSC_VER
#include
#include "types.h"
//
diff --git a/libkms.c b/libkms.c
index bc1148c..bd50333 100644
--- a/libkms.c
+++ b/libkms.c
@@ -62,7 +62,7 @@ EXTERNC __declspec(EXTERNAL) SOCKET __cdecl ConnectToServer(const char* host, co
size_t adrlen = strlen(host) + 16;
char* RemoteAddr = (char*)alloca(adrlen);
- snprintf(RemoteAddr, adrlen, "[%s]:%s", host, port);
+ vlmcsd_snprintf(RemoteAddr, adrlen, "[%s]:%s", host, port);
sock = connectToAddress(RemoteAddr, addressFamily, FALSE);
if (sock == INVALID_RPCCTX)
@@ -161,7 +161,7 @@ EXTERNC __declspec(EXTERNAL) DWORD __cdecl StartKmsServer(const int port, Reques
# endif // _WIN32
defaultport = vlmcsd_malloc(16);
- snprintf((char*)defaultport, (size_t)16, "%i", port);
+ vlmcsd_snprintf((char*)defaultport, (size_t)16, "%i", port);
CreateResponseBase = requestCallback;
error = listenOnAllAddresses();
diff --git a/make_linux b/make_linux
index fa430c0..e1de3d7 100755
--- a/make_linux
+++ b/make_linux
@@ -70,10 +70,10 @@ export STAGING_DIR=.
# Windows 32-bit using MingW32-w64 toolchain on Ubuntu Linux
-export CLIENT_NAME=binaries/Windows/intel/vlmcs-Windows-x86.exe
-export PROGRAM_NAME=binaries/Windows/intel/vlmcsd-Windows-x86.exe
-export MULTI_NAME=binaries/Windows/intel/vlmcsdmulti-Windows-x86.exe
-export DLL_NAME=binaries/Windows/intel/libkms32.dll
+export CLIENT_NAME=binaries/Windows/intel/vlmcs-Windows-x86-gcc.exe
+export PROGRAM_NAME=binaries/Windows/intel/vlmcsd-Windows-x86-gcc.exe
+export MULTI_NAME=binaries/Windows/intel/vlmcsdmulti-Windows-x86-gcc.exe
+export DLL_NAME=binaries/Windows/intel/libkms32-gcc.dll
export THREADS=1
export CFLAGS="$SMALLCC"
export CC=i686-w64-mingw32-gcc
@@ -131,10 +131,10 @@ fi
# Windows 64-bit using MingW32-w64 toolchain on Ubuntu Linux
-export CLIENT_NAME=binaries/Windows/intel/vlmcs-Windows-x64.exe
-export PROGRAM_NAME=binaries/Windows/intel/vlmcsd-Windows-x64.exe
-export MULTI_NAME=binaries/Windows/intel/vlmcsdmulti-Windows-x64.exe
-export DLL_NAME=binaries/Windows/intel/libkms64.dll
+export CLIENT_NAME=binaries/Windows/intel/vlmcs-Windows-x64-gcc.exe
+export PROGRAM_NAME=binaries/Windows/intel/vlmcsd-Windows-x64-gcc.exe
+export MULTI_NAME=binaries/Windows/intel/vlmcsdmulti-Windows-x64-gcc.exe
+export DLL_NAME=binaries/Windows/intel/libkms64-gcc.dll
export THREADS=1
export CFLAGS="$SMALLCC"
export CC=x86_64-w64-mingw32-gcc
diff --git a/make_osx b/make_osx
index c8c0d8b..56bed23 100755
--- a/make_osx
+++ b/make_osx
@@ -46,10 +46,10 @@ PATH=~/toolchains/iOS5.1-MacOS-Lion/usr/bin:$PATH make $MAKEFLAGS allmulti MULTI
PATH=~/toolchains/gcc4.2/usr/bin:$PATH make -Bj allmulti SAFE_MODE=1 MULTI_NAME=vlmcsdmulti-MacOSX-ppc PROGRAM_NAME=vlmcsd-MacOSX-ppc CLIENT_NAME=vlmcs-MacOSX-ppc CC=gcc CFLAGS="$CFGCC42 -isysroot ~/toolchains/MacOSX10.5.sdk -arch ppc -mmacosx-version-min=10.0" && \
-make $MAKEFLAGS allmulti MULTI_NAME=vlmcsdmulti-MacOSX-x86-gcc CLIENT_NAME=vlmcs-MacOSX-x86-gcc PROGRAM_NAME=vlmcsd-MacOSX-x86-gcc CC=gcc-5 CFLAGS="$CFGCC" PLATFORMFLAGS="-m32 -march=core2 -mmacosx-version-min=10.11" && \
-make $MAKEFLAGS vlmcsd-MacOSX-x86-threads-gcc THREADS=1 PROGRAM_NAME=vlmcsd-MacOSX-x86-threads-gcc CC=gcc-5 CFLAGS="$CFGCC" PLATFORMFLAGS="-m32 -march=core2 -mmacosx-version-min=10.11" && \
-make $MAKEFLAGS allmulti MULTI_NAME=vlmcsdmulti-MacOSX-x64-gcc CLIENT_NAME=vlmcs-MacOSX-x64-gcc PROGRAM_NAME=vlmcsd-MacOSX-x64-gcc CC=gcc-5 CFLAGS="$CFGCC" PLATFORMFLAGS="-m64 -march=core2 -mmacosx-version-min=10.11" && \
-make $MAKEFLAGS vlmcsd-MacOSX-x64-threads-gcc THREADS=1 PROGRAM_NAME=vlmcsd-MacOSX-x64-threads-gcc CC=gcc-5 CFLAGS="$CFGCC" PLATFORMFLAGS="-m64 -march=core2 -mmacosx-version-min=10.11" && \
+make $MAKEFLAGS allmulti MULTI_NAME=vlmcsdmulti-MacOSX-x86-gcc CLIENT_NAME=vlmcs-MacOSX-x86-gcc PROGRAM_NAME=vlmcsd-MacOSX-x86-gcc CC=gcc-6 CFLAGS="$CFGCC" PLATFORMFLAGS="-m32 -march=core2 -mmacosx-version-min=10.11" && \
+make $MAKEFLAGS vlmcsd-MacOSX-x86-threads-gcc THREADS=1 PROGRAM_NAME=vlmcsd-MacOSX-x86-threads-gcc CC=gcc-6 CFLAGS="$CFGCC" PLATFORMFLAGS="-m32 -march=core2 -mmacosx-version-min=10.11" && \
+make $MAKEFLAGS allmulti MULTI_NAME=vlmcsdmulti-MacOSX-x64-gcc CLIENT_NAME=vlmcs-MacOSX-x64-gcc PROGRAM_NAME=vlmcsd-MacOSX-x64-gcc CC=gcc-6 CFLAGS="$CFGCC" PLATFORMFLAGS="-m64 -march=core2 -mmacosx-version-min=10.11" && \
+make $MAKEFLAGS vlmcsd-MacOSX-x64-threads-gcc THREADS=1 PROGRAM_NAME=vlmcsd-MacOSX-x64-threads-gcc CC=gcc-6 CFLAGS="$CFGCC" PLATFORMFLAGS="-m64 -march=core2 -mmacosx-version-min=10.11" && \
# Sign the iOS binaries
#ldid -S *iOS*
diff --git a/make_windows b/make_windows
index a82802e..128e563 100755
--- a/make_windows
+++ b/make_windows
@@ -1,8 +1,17 @@
#!/bin/bash
export VLMCSD_VERSION="svn`svnversion`"
+
+msbuild='/cygdrive/c/Program Files (x86)/MSBuild/14.0/bin/MSBuild.exe'
+version="$VLMCSD_VERSION, built $(date -u '+%Y-%m-%d %H:%M:%S') UTC"
+
rm -f cygkms*.dll libkms*.dll vlmcs-* vlmcsd-win* vlmcsd-cyg* vlmcsdmulti-* *_all.* vlmcsd.exe vlmcs.exe vlmcsdmulti.exe 2> /dev/null
+export ExternalCompilerOptions="/D VERSION=\"\\\"$version\\\"\" /D BUILD_TIME=$(date '+%s')"
+
+"$msbuild" VisualStudio/vlmcsd-2015-with-2013-c++-build-tools.sln /t:Rebuild /p:Configuration=Release /p:Platform=x86 /m /v:m
+"$msbuild" VisualStudio/vlmcsd-2015-with-2013-c++-build-tools.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64 /m /v:m
+
export CAT=2
export VERBOSE=3
NUMCPU=`cat /proc/cpuinfo | grep "processor" | wc -l`
@@ -35,10 +44,10 @@ make $MAKEFLAGS THREADS=1 MSRPC=1 DNS_PARSER=internal CLIENT_NAME=vlmcs-cygwin-m
export CAT=2
#unset CAT
-make $MAKEFLAGS libkms32.dll CRYPTO=windows FEATURES=minimum THREADS=1 DLL_NAME=libkms32.dll CC=i686-w64-MingW32-gcc.exe CFLAGS="$CF -flto=jobserver -fvisibility=hidden" PLATFORMFLAGS="$PF32" LDFLAGS="-static-libgcc $LFWIN32"
-make $MAKEFLAGS libkms64.dll CRYPTO=windows FEATURES=minimum THREADS=1 DLL_NAME=libkms64.dll CC=x86_64-w64-MingW32-gcc.exe CFLAGS="$CF -flto=jobserver -fvisibility=hidden" PLATFORMFLAGS="$PF64" LDFLAGS="-static-libgcc $LFWIN64"
-make $MAKEFLAGS allmulti THREADS=1 CRYPTO=windows CLIENT_NAME=vlmcs-Windows-x86 PROGRAM_NAME=vlmcsd-Windows-x86 MULTI_NAME=vlmcsdmulti-Windows-x86 CC=i686-w64-MingW32-gcc.exe CFLAGS="$CF -fno-lto" PLATFORMFLAGS="$PF32" LDFLAGS="$LFWIN32"
-make $MAKEFLAGS allmulti THREADS=1 CRYPTO=windows CLIENT_NAME=vlmcs-Windows-x64 PROGRAM_NAME=vlmcsd-Windows-x64 MULTI_NAME=vlmcsdmulti-Windows-x64 CC=x86_64-w64-MingW32-gcc.exe CFLAGS="$CF -fno-lto" PLATFORMFLAGS="$PF64" LDFLAGS="$LFWIN64"
+make $MAKEFLAGS libkms32-gcc.dll CRYPTO=windows FEATURES=minimum THREADS=1 DLL_NAME=libkms32-gcc.dll CC=i686-w64-MingW32-gcc.exe CFLAGS="$CF -flto=jobserver -fvisibility=hidden" PLATFORMFLAGS="$PF32" LDFLAGS="-static-libgcc $LFWIN32"
+make $MAKEFLAGS libkms64-gcc.dll CRYPTO=windows FEATURES=minimum THREADS=1 DLL_NAME=libkms64-gcc.dll CC=x86_64-w64-MingW32-gcc.exe CFLAGS="$CF -flto=jobserver -fvisibility=hidden" PLATFORMFLAGS="$PF64" LDFLAGS="-static-libgcc $LFWIN64"
+make $MAKEFLAGS allmulti THREADS=1 CRYPTO=windows CLIENT_NAME=vlmcs-Windows-x86-gcc PROGRAM_NAME=vlmcsd-Windows-x86-gcc MULTI_NAME=vlmcsdmulti-Windows-x86-gcc CC=i686-w64-MingW32-gcc.exe CFLAGS="$CF -fno-lto" PLATFORMFLAGS="$PF32" LDFLAGS="$LFWIN32"
+make $MAKEFLAGS allmulti THREADS=1 CRYPTO=windows CLIENT_NAME=vlmcs-Windows-x64-gcc PROGRAM_NAME=vlmcsd-Windows-x64-gcc MULTI_NAME=vlmcsdmulti-Windows-x64-gcc CC=x86_64-w64-MingW32-gcc.exe CFLAGS="$CF -fno-lto" PLATFORMFLAGS="$PF64" LDFLAGS="$LFWIN64"
unset CAT
make -Bj allmulti MSRPC=1 CRYPTO=windows CLIENT_NAME=vlmcs-Windows-msrpc-x86 PROGRAM_NAME=vlmcsd-Windows-msrpc-x86 MULTI_NAME=vlmcsdmulti-Windows-msrpc-x86 CC=i686-w64-MingW32-gcc.exe CFLAGS="$CFMSRPC -fno-lto" PLATFORMFLAGS="$PF32" LDFLAGS="$LFWIN32"
make $MAKEFLAGS allmulti THREADS=1 MSRPC=1 CRYPTO=windows CLIENT_NAME=vlmcs-Windows-msrpc-x64 PROGRAM_NAME=vlmcsd-Windows-msrpc-x64 MULTI_NAME=vlmcsdmulti-Windows-msrpc-x64 CC=x86_64-w64-MingW32-gcc.exe CFLAGS="$CFMSRPC -fno-lto" PLATFORMFLAGS="$PF64" LDFLAGS="$LFWIN64"
@@ -63,10 +72,11 @@ cp -p cygkms64.dll /usr/local/bin/cygkms.dll &
cp -p libkms32.dll /cygdrive/c/nttools/x86 &
cp -p libkms64.dll /cygdrive/c/nttools/x64 &
-cp -p vlmcsdmulti-Windows-x86.exe /cygdrive/c/nttools/x86/vlmcsdmulti.exe
+cp -p vlmcsd-Windows-x86.exe /cygdrive/c/nttools/x86/vlmcsd.exe
+cp -p vlmcs-Windows-x86.exe /cygdrive/c/nttools/x86/vlmcs.exe
-cmd /C mklink c:\\nttools\\x86\\vlmcsd.exe vlmcsdmulti.exe 2> /dev/null &
-cmd /C mklink c:\\nttools\\x86\\vlmcs.exe vlmcsdmulti.exe 2> /dev/null &
+#cmd /C mklink c:\\nttools\\x86\\vlmcsd.exe vlmcsdmulti.exe 2> /dev/null &
+#cmd /C mklink c:\\nttools\\x86\\vlmcs.exe vlmcsdmulti.exe 2> /dev/null &
echo "Installing man pages"
diff --git a/msrpc-client.h b/msrpc-client.h
index 17d2a0c..fba073d 100644
--- a/msrpc-client.h
+++ b/msrpc-client.h
@@ -2,6 +2,7 @@
* msrpc-client.h
*/
+#ifdef USE_MSRPC
#ifndef MSRPC_CLIENT_H_
#define MSRPC_CLIENT_H_
@@ -19,5 +20,6 @@ RpcStatus rpcSendRequest(const RpcCtx handle, BYTE* KmsRequest, size_t requestSi
RpcStatus closeRpc(RpcCtx s);
#define INVALID_RPCCTX ((RpcCtx)~0)
+#endif // USE_MSRPC
#endif /* MSRPC_CLIENT_H_ */
diff --git a/network.c b/network.c
index c90efa2..20e9898 100644
--- a/network.c
+++ b/network.c
@@ -40,12 +40,11 @@
#include "network.h"
#include "endian.h"
-#include "output.h"
+//#include "output.h"
#include "helpers.h"
#include "shared_globals.h"
#include "rpc.h"
-
#ifndef _WIN32
typedef ssize_t (*sendrecv_t)(int, void*, size_t, int);
#else
@@ -92,7 +91,7 @@ static int_fast8_t ip2str(char *restrict result, const size_t resultLength, cons
return FALSE;
}
- if ((unsigned int)snprintf(result, resultLength, socketAddress->sa_family == AF_INET6 ? fIPv6 : fIPv4, ipAddress, portNumber) > resultLength) return FALSE;
+ if ((unsigned int)vlmcsd_snprintf(result, resultLength, socketAddress->sa_family == AF_INET6 ? fIPv6 : fIPv4, ipAddress, portNumber) > resultLength) return FALSE;
return TRUE;
}
@@ -245,7 +244,7 @@ SOCKET connectToAddress(const char *const addr, const int AddressFamily, int_fas
// struct sockaddr_in* addr4 = (struct sockaddr_in*)sa->ai_addr;
// struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sa->ai_addr;
- if (ip2str(szAddr, sizeof(szAddr), sa->ai_addr, sa->ai_addrlen))
+ if (ip2str(szAddr, sizeof(szAddr), sa->ai_addr, (socklen_t)sa->ai_addrlen))
{
if (showHostName)
printf("Connecting to %s (%s) ... ", addr, szAddr);
@@ -274,7 +273,7 @@ SOCKET connectToAddress(const char *const addr, const int AddressFamily, int_fas
setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
# endif // !defined(NO_TIMEOUT) && !__minix__
- if (!connect(s, sa->ai_addr, sa->ai_addrlen))
+ if (!connect(s, sa->ai_addr, (int)sa->ai_addrlen))
{
printf("successful\n");
break;
@@ -310,7 +309,7 @@ static int_fast8_t allowSocketReuse(SOCKET s)
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (sockopt_t)&socketOption, sizeof(socketOption)))
{
# ifdef _PEDANTIC
- printerrorf("Warning: %s does not support socket option SO_REUSEADDR: %s\n", ipstr, vlmcsd_strerror(socket_errno));
+ printerrorf("Warning: Socket option SO_REUSEADDR unsupported: %s\n", vlmcsd_strerror(socket_errno));
# endif // _PEDANTIC
}
@@ -403,7 +402,7 @@ void getPrivateIPAddresses(int* numAddresses, char*** ipAddresses)
for (currentAdapter = firstAdapter, *numAddresses = 0; currentAdapter != NULL; currentAdapter = currentAdapter->Next)
{
- PIP_ADAPTER_UNICAST_ADDRESS_XP currentAddress;
+ PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
int length;
if (currentAdapter->OperStatus != IfOperStatusUp) continue;
@@ -418,7 +417,7 @@ void getPrivateIPAddresses(int* numAddresses, char*** ipAddresses)
for (currentAdapter = firstAdapter, *numAddresses = 0; currentAdapter != NULL; currentAdapter = currentAdapter->Next)
{
- PIP_ADAPTER_UNICAST_ADDRESS_XP currentAddress;
+ PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
int length;
if (currentAdapter->OperStatus != IfOperStatusUp) continue;
@@ -521,7 +520,7 @@ static int listenOnAddress(const struct addrinfo *const ai, SOCKET *s)
int error;
char ipstr[64];
- ip2str(ipstr, sizeof(ipstr), ai->ai_addr, ai->ai_addrlen);
+ ip2str(ipstr, sizeof(ipstr), ai->ai_addr, (socklen_t)ai->ai_addrlen);
//*s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
*s = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
@@ -615,7 +614,7 @@ static int listenOnAddress(const struct addrinfo *const ai, SOCKET *s)
# endif // HAVE_FREEBIND
- if (bind(*s, ai->ai_addr, ai->ai_addrlen) || listen(*s, SOMAXCONN))
+ if (bind(*s, ai->ai_addr, (int)ai->ai_addrlen) || listen(*s, SOMAXCONN))
{
error = socket_errno;
printerrorf("Warning: %s: %s\n", ipstr, vlmcsd_strerror(error));
@@ -696,7 +695,7 @@ static SOCKET network_accept_any()
if (SocketList[i] > maxSocket) maxSocket = SocketList[i];
}
- status = select(maxSocket + 1, &ListeningSocketsList, NULL, NULL, NULL);
+ status = select((int)maxSocket + 1, &ListeningSocketsList, NULL, NULL, NULL);
if (status < 0) return INVALID_SOCKET;
@@ -871,7 +870,7 @@ static void *serveClientThreadProc (PCLDATA clData)
#ifndef NO_SOCKETS
#if defined(USE_THREADS) && (defined(_WIN32) || defined(__CYGWIN__)) // Windows Threads
-static int serveClientAsyncWinThreads(const PCLDATA thr_CLData)
+static int serveClientAsyncWinThreads(PCLDATA thr_CLData)
{
wait_sem();
diff --git a/network.h b/network.h
index f46cd0f..987b6c2 100644
--- a/network.h
+++ b/network.h
@@ -13,6 +13,13 @@
#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);
diff --git a/ntservice.c b/ntservice.c
index 6eb021e..4b38855 100644
--- a/ntservice.c
+++ b/ntservice.c
@@ -14,7 +14,7 @@
SERVICE_STATUS gSvcStatus;
SERVICE_STATUS_HANDLE gSvcStatusHandle;
-static VOID WINAPI ServiceCtrlHandler(const DWORD dwCtrl)
+VOID WINAPI ServiceCtrlHandler(DWORD dwCtrl)
{
// Handle the requested control code.
diff --git a/output.c b/output.c
index 213f8d9..3d7f71d 100644
--- a/output.c
+++ b/output.c
@@ -2,6 +2,10 @@
#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
@@ -66,8 +70,12 @@ static void vlogger(const char *message, va_list args)
// We write everything to a string before we really log inside the critical section
// so formatting the output can be concurrent
- int len = strlen(mbstr);
- vsnprintf(mbstr + len, sizeof(mbstr) - len, message, args);
+ 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);
@@ -104,7 +112,7 @@ int printerrorf(const char *const fmt, ...)
# ifdef IS_LIBRARY
size_t len = strlen(ErrorMessage);
- vsnprintf(ErrorMessage + len, MESSAGE_BUFFER_SIZE - len - 1, fmt, arglist);
+ vlmcsd_vsnprintf(ErrorMessage + len, MESSAGE_BUFFER_SIZE - len - 1, fmt, arglist);
# else // !IS_LIBRARY
diff --git a/output.h b/output.h
index 12e2560..74fa0d5 100644
--- a/output.h
+++ b/output.h
@@ -7,6 +7,7 @@
#include CONFIG
#include
+#include "types.h"
#include "kms.h"
typedef int (*PRINTFUNC)(const char *const fmt, ...);
diff --git a/rpc.c b/rpc.c
index 7696e97..714ccc1 100644
--- a/rpc.c
+++ b/rpc.c
@@ -95,9 +95,9 @@ static void CheckRpcRequest(const RPC_REQUEST64 *const Request, const unsigned i
}
if (Ctx != *Ndr64Ctx)
- kmsMajorVersion = LE16(((WORD*)Request->Ndr.Data)[1]);
+ kmsMajorVersion = (uint_fast8_t)LE16(((WORD*)Request->Ndr.Data)[1]);
else
- kmsMajorVersion = LE16(((WORD*)Request->Ndr64.Data)[1]);
+ kmsMajorVersion = (uint_fast8_t)LE16(((WORD*)Request->Ndr64.Data)[1]);
if (kmsMajorVersion > 6)
{
@@ -394,11 +394,12 @@ static int rpcBind(const RPC_BIND_REQUEST *const Request, RPC_BIND_RESPONSE* Res
getsockname(sock, (struct sockaddr*)&addr, &socklen) ||
getnameinfo((struct sockaddr*)&addr, socklen, NULL, 0, (char*)Response->SecondaryAddress, sizeof(Response->SecondaryAddress), NI_NUMERICSERV))
{
- portNumberSize = Response->SecondaryAddressLength = 0;
+ portNumberSize = 0;
+ Response->SecondaryAddressLength = 0;
}
else
{
- portNumberSize = strlen((char*)Response->SecondaryAddress) + 1;
+ portNumberSize = (uint_fast8_t)strlen((char*)Response->SecondaryAddress) + 1;
Response->SecondaryAddressLength = LE16(portNumberSize);
}
@@ -542,7 +543,7 @@ void rpcServer(const SOCKET sock, const DWORD RpcAssocGroup, const char* const i
if (!_recv(sock, requestBuffer, request_len)) return;
// Request is invalid
- BYTE isValid = _Actions[_a].CheckRequestSize(requestBuffer, request_len, &NdrCtx, &Ndr64Ctx);
+ BYTE isValid = (BYTE)_Actions[_a].CheckRequestSize(requestBuffer, request_len, &NdrCtx, &Ndr64Ctx);
if (rpcRequestHeader.PacketType != RPC_PT_REQUEST && !isValid) return;
// Unable to create a valid response from request
@@ -552,7 +553,7 @@ void rpcServer(const SOCKET sock, const DWORD RpcAssocGroup, const char* const i
memcpy(rpcResponseHeader, &rpcRequestHeader, sizeof(RPC_HEADER));
- rpcResponseHeader->FragLength = LE16(response_len);
+ rpcResponseHeader->FragLength = LE16((WORD)response_len);
rpcResponseHeader->PacketType = _Actions[_a].ResponsePacketType;
if (rpcResponseHeader->PacketType == RPC_PT_ALTERCONTEXT_ACK)
@@ -710,7 +711,7 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const KmsRequest, const
RequestHeader = (RPC_HEADER*)_Request;
RpcRequest = (RPC_REQUEST64*)(_Request + sizeof(RPC_HEADER));
- createRpcRequestHeader(RequestHeader, RPC_PT_REQUEST, size);
+ createRpcRequestHeader(RequestHeader, RPC_PT_REQUEST, (WORD)size);
// Increment CallId for next Request
CallId++;
@@ -720,7 +721,7 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const KmsRequest, const
if (useNdr64)
{
RpcRequest->ContextId = LE16(1); // We negotiate NDR64 always as context 1
- RpcRequest->AllocHint = LE32(requestSize + sizeof(RpcRequest->Ndr64));
+ RpcRequest->AllocHint = LE32((DWORD)(requestSize + sizeof(RpcRequest->Ndr64)));
RpcRequest->Ndr64.DataLength = LE64((uint64_t)requestSize);
RpcRequest->Ndr64.DataSizeIs = LE64((uint64_t)requestSize);
memcpy(RpcRequest->Ndr64.Data, KmsRequest, requestSize);
@@ -728,9 +729,9 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const KmsRequest, const
else
{
RpcRequest->ContextId = 0; // We negotiate NDR32 always as context 0
- RpcRequest->AllocHint = LE32(requestSize + sizeof(RpcRequest->Ndr));
- RpcRequest->Ndr.DataLength = LE32(requestSize);
- RpcRequest->Ndr.DataSizeIs = LE32(requestSize);
+ RpcRequest->AllocHint = LE32((DWORD)(requestSize + sizeof(RpcRequest->Ndr)));
+ RpcRequest->Ndr.DataLength = LE32((DWORD)requestSize);
+ RpcRequest->Ndr.DataSizeIs = LE32((DWORD)requestSize);
memcpy(RpcRequest->Ndr.Data, KmsRequest, requestSize);
}
@@ -738,7 +739,7 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const KmsRequest, const
{
int bytesread;
- if (!_send(sock, _Request, size))
+ if (!_send(sock, _Request, (int)size))
{
printerrorf("\nFatal: Could not send RPC request\n");
status = RPC_S_COMM_FAILURE;
@@ -759,7 +760,7 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const KmsRequest, const
if (size > LE16(ResponseHeader.FragLength) - sizeof(ResponseHeader))
size = LE16(ResponseHeader.FragLength) - sizeof(ResponseHeader);
- if (!_recv(sock, &_Response, size))
+ if (!_recv(sock, &_Response, (int)size))
{
printerrorf("\nFatal: RPC response is incomplete\n");
status = RPC_S_COMM_FAILURE;
@@ -823,7 +824,7 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const KmsRequest, const
memset(*KmsResponse, 0, *responseSize + MAX_EXCESS_BYTES);
// Read up to 16 bytes more than bytes expected to detect faulty KMS emulators
- if ((bytesread = recv(sock, (char*)*KmsResponse, *responseSize + MAX_EXCESS_BYTES, 0)) < (int)*responseSize)
+ if ((bytesread = recv(sock, (char*)*KmsResponse, (int)(*responseSize) + MAX_EXCESS_BYTES, 0)) < (int)*responseSize)
{
printerrorf("\nFatal: No or incomplete KMS response received. Required %u bytes but only got %i\n",
(uint32_t)*responseSize,
@@ -897,12 +898,12 @@ RpcStatus rpcBindOrAlterClientContext(const RpcCtx sock, BYTE packetType, const
WORD ctxIndex = 0;
WORD i;
WORD CtxBTFN = (WORD)~0, CtxNDR64 = (WORD)~0;
- BYTE _Request[rpcBindSize];
+ BYTE* _Request = (BYTE*)alloca(rpcBindSize);
RequestHeader = (RPC_HEADER*)_Request;
bindRequest = (RPC_BIND_REQUEST* )(_Request + sizeof(RPC_HEADER));
- createRpcRequestHeader(RequestHeader, packetType, rpcBindSize);
+ createRpcRequestHeader(RequestHeader, packetType, (WORD)rpcBindSize);
RequestHeader->PacketFlags |= UseMultiplexedRpc ? RPC_PF_MULTIPLEX : 0;
bindRequest->AssocGroup = 0;
@@ -935,7 +936,7 @@ RpcStatus rpcBindOrAlterClientContext(const RpcCtx sock, BYTE packetType, const
CtxBTFN = ctxIndex;
}
- if (!_send(sock, _Request, rpcBindSize))
+ if (!_send(sock, _Request, (int)rpcBindSize))
{
printerrorf("\nFatal: Sending RPC bind request failed\n");
return RPC_S_COMM_FAILURE;
diff --git a/rpc.h b/rpc.h
index 18ac456..aae62cc 100644
--- a/rpc.h
+++ b/rpc.h
@@ -8,6 +8,15 @@
#include "types.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
+
+
#if !defined(_WIN32) && !defined(__CYGWIN__)
#define RPC_S_OK 0
#define RPC_S_INVALID_ARG 87
@@ -257,6 +266,7 @@ typedef struct {
} /*__packed*/ RPC_RESPONSE64;
+//#define RpcCtx SOCKET
typedef SOCKET RpcCtx;
typedef int RpcStatus;
@@ -304,7 +314,7 @@ typedef union _RPC_FLAGS
extern RPC_FLAGS RpcFlags;
-void rpcServer(const RpcCtx socket, const DWORD RpcAssocGroup, const char* const ipstr);
+void rpcServer(const SOCKET sock, const DWORD RpcAssocGroup, const char* const ipstr);
RpcStatus rpcBindClient(const RpcCtx sock, const int_fast8_t verbose);
RpcStatus rpcSendRequest(const RpcCtx socket, const BYTE *const KmsRequest, const size_t requestSize, BYTE **KmsResponse, size_t *const responseSize);
diff --git a/shared_globals.h b/shared_globals.h
index f35175b..ee339b6 100644
--- a/shared_globals.h
+++ b/shared_globals.h
@@ -33,7 +33,9 @@
#endif
#include
+#if !_MSC_VER
#include
+#endif
#include
#include
#include
diff --git a/types.h b/types.h
index ce948bc..35fddfa 100644
--- a/types.h
+++ b/types.h
@@ -1,6 +1,10 @@
#ifndef __types_h
#define __types_h
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
@@ -57,11 +61,6 @@
#endif // __GNUC__
#endif // alloca
-#ifndef alloca
-#if _MSC_VER
-#define alloca _malloca
-#endif // _MSC_VER
-#endif // alloca
#ifndef alloca
#ifdef __has_builtin // clang feature test
@@ -72,8 +71,15 @@
#endif // alloca
#ifndef alloca
+#if !_MSC_VER
#include
+#else
+#include
+//#define alloca _malloca
#endif
+//#define alloca _malloca
+//#endif // _MSC_VER
+#endif // alloca
#ifndef __packed
#if _MSC_VER
@@ -84,12 +90,20 @@
#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
@@ -157,7 +171,7 @@ typedef uint8_t ProdListIndex_t;
// Stupid MingW just uses rand() from msvcrt.dll which uses RAND_MAX of 0x7fff
#if RAND_MAX < 0x7fffffff
-#define rand32(x) ((uint32_t)((rand(x) << 17) | (rand(x) << 2) | (rand(x) & 3)))
+#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
@@ -285,11 +299,11 @@ typedef void* sockopt_t;
#undef IsEqualGUID
#define IsEqualGUID(a, b) ( !memcmp(a, b, sizeof(GUID)) )
-#ifndef __stdcall
+#if !defined(__stdcall) && !_MSC_VER
#define __stdcall
#endif
-#ifndef __cdecl
+#if !defined(__cdecl) && !_MSC_VER
#define __cdecl
#endif
@@ -301,4 +315,18 @@ typedef struct {
} 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 strtol // TODO: Get some 64-bit strtoll
+#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
diff --git a/vlmcs.1.html b/vlmcs.1.html
index c21e327..852a91b 100644
--- a/vlmcs.1.html
+++ b/vlmcs.1.html
@@ -1,5 +1,5 @@
-
+
diff --git a/vlmcs.1.pdf b/vlmcs.1.pdf
index 26b6ff3..ce207e5 100644
Binary files a/vlmcs.1.pdf and b/vlmcs.1.pdf differ
diff --git a/vlmcs.c b/vlmcs.c
index b1d6df9..07dd120 100644
--- a/vlmcs.c
+++ b/vlmcs.c
@@ -8,15 +8,24 @@
#endif
#include "vlmcs.h"
+#if _MSC_VER
+#include
+#endif
#include
#include
#include
#include
#include
+#if _MSC_VER
+#include "wingetopt.h"
+#else
#include
+#endif
#include
#include
+#ifndef _MSC_VER
#include
+#endif
#ifndef _WIN32
#include
#include
@@ -301,7 +310,7 @@ __noreturn static void showProducts(PRINTFUNC p)
for (currentProduct = ExtendedProductList; currentProduct->name; currentProduct++)
{
- uint_fast8_t len = strlen(currentProduct->name);
+ uint_fast8_t len = (uint_fast8_t)strlen(currentProduct->name);
if (len > longestString)
longestString = len;
@@ -538,7 +547,7 @@ static void parseCommandLinePass2(const char *const programName, const int argc,
case 'i':
- switch(getOptionArgumentInt(o, 4, 6))
+ switch(getOptionArgumentInt((char)o, 4, 6))
{
case 4:
AddressFamily = AF_INET;
@@ -564,13 +573,13 @@ static void parseCommandLinePass2(const char *const programName, const int argc,
case 'n': // Fixed number of Requests (regardless, whether they are required)
incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
- FixedRequests = getOptionArgumentInt(o, 1, INT_MAX);
+ FixedRequests = getOptionArgumentInt((char)o, 1, INT_MAX);
break;
case 'r': // Fake minimum required client count
incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
- ActiveLicensePack.N_Policy = getOptionArgumentInt(o, 0, INT_MAX);
+ ActiveLicensePack.N_Policy = getOptionArgumentInt((char)o, 0, INT_MAX);
break;
case 'c': // use a specific client GUID
@@ -596,7 +605,7 @@ static void parseCommandLinePass2(const char *const programName, const int argc,
case 'g': // Set custom "grace" time in minutes (default 30 days)
- BindingExpiration = getOptionArgumentInt(o, 0, INT_MAX);
+ BindingExpiration = getOptionArgumentInt((char)o, 0, INT_MAX);
break;
case 's': // Set specfic SKU ID
@@ -657,7 +666,7 @@ static void parseCommandLinePass2(const char *const programName, const int argc,
case 't':
- LicenseStatus = getOptionArgumentInt(o, 0, 0x7fffffff);
+ LicenseStatus = getOptionArgumentInt((char)o, 0, 0x7fffffff);
if ((unsigned int)LicenseStatus > 6) errorout("Warning: Correct license status is 0 <= license status <= 6.\n");
break;
@@ -913,13 +922,13 @@ int SendActivationRequest(const RpcCtx sock, RESPONSE *baseResponse, REQUEST *ba
if (LE16(((RESPONSE*)(response))->MajorVer) == 4)
{
RESPONSE_V4 response_v4;
- *result = DecryptResponseV4(&response_v4, responseSize, response, request);
+ *result = DecryptResponseV4(&response_v4, (const int)responseSize, response, request);
memcpy(baseResponse, &response_v4.ResponseBase, sizeof(RESPONSE));
}
else
{
RESPONSE_V6 response_v6;
- *result = DecryptResponseV6(&response_v6, responseSize, response, request, hwid);
+ *result = DecryptResponseV6(&response_v6, (int)responseSize, response, request, hwid);
memcpy(baseResponse, &response_v6.ResponseBase, sizeof(RESPONSE));
}
@@ -1000,7 +1009,7 @@ static void newIniBackupFile(const char* const restrict fname)
if (fclose(f))
{
errorout("Fatal: Cannot write to %s: %s\n", fname, strerror(errno));
- unlink(fname);
+ vlmcsd_unlink(fname);
exit(!0);
}
}
@@ -1009,7 +1018,9 @@ static void newIniBackupFile(const char* const restrict fname)
static void updateIniFile(iniFileEpidLines* const restrict lines)
{
int_fast8_t lineWritten[_countof(*lines)];
+# if !_MSC_VER
struct stat statbuf;
+# endif
uint_fast8_t i;
int_fast8_t iniFileExistedBefore = TRUE;
unsigned int lineNumber;
@@ -1021,6 +1032,13 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
strcpy(fn_bak, fn_ini_client);
strcat(fn_bak, "~");
+# if _MSC_VER
+ if (!PathFileExists(fn_ini_client))
+ {
+ iniFileExistedBefore = FALSE;
+ newIniBackupFile(fn_bak);
+ }
+# else
if (stat(fn_ini_client, &statbuf))
{
if (errno != ENOENT)
@@ -1034,9 +1052,10 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
newIniBackupFile(fn_bak);
}
}
+# endif
else
{
- unlink(fn_bak); // Required for Windows. Most Unix systems don't need it.
+ vlmcsd_unlink(fn_bak); // Required for Windows. Most Unix systems don't need it.
if (rename(fn_ini_client, fn_bak))
{
errorout("Fatal: Cannot create %s: %s\n", fn_bak, strerror(errno));
@@ -1110,11 +1129,12 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
exit(!0);
}
- if (!iniFileExistedBefore) unlink(fn_bak);
+ if (!iniFileExistedBefore) vlmcsd_unlink(fn_bak);
free(fn_bak);
}
+
static void grabServerData()
{
RpcCtx s = INVALID_RPCCTX;
@@ -1163,16 +1183,16 @@ static void grabServerData()
memset(ePID + 3 * PID_BUFFER_SIZE - 3, 0, 3);
}
- snprintf(lines[i], sizeof(lines[0]), "%s = %s", ePidGroup[i], ePID);
+ vlmcsd_snprintf(lines[i], sizeof(lines[0]), "%s = %s", ePidGroup[i], ePID);
if (response.MajorVer > 5)
{
len = strlen(lines[i]);
- snprintf (lines[i] + len, sizeof(lines[0]) - len, " / %02X %02X %02X %02X %02X %02X %02X %02X", hwid[0], hwid[1], hwid[2], hwid[3], hwid[4], hwid[5], hwid[6], hwid[7]);
+ vlmcsd_snprintf (lines[i] + len, sizeof(lines[0]) - len, " / %02X %02X %02X %02X %02X %02X %02X %02X", hwid[0], hwid[1], hwid[2], hwid[3], hwid[4], hwid[5], hwid[6], hwid[7]);
}
len = strlen(lines[i]);
- snprintf(lines[i] + len, sizeof(lines[0]) - len, "\n");
+ vlmcsd_snprintf(lines[i] + len, sizeof(lines[0]) - len, "\n");
}
@@ -1188,7 +1208,7 @@ static void grabServerData()
}
-int client_main(const int argc, CARGV argv)
+int client_main(int argc, CARGV argv)
{
#if defined(_WIN32) && !defined(USE_MSRPC)
@@ -1354,10 +1374,10 @@ static void CreateRequestBase(REQUEST *Request)
{
int len, len2;
unsigned int index = rand() % _countof(ClientDnsNames.first);
- len = utf8_to_ucs2(Request->WorkstationName, ClientDnsNames.first[index], WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
+ len = (int)utf8_to_ucs2(Request->WorkstationName, ClientDnsNames.first[index], WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
index = rand() % _countof(ClientDnsNames.second);
- len2 = utf8_to_ucs2(Request->WorkstationName + len, ClientDnsNames.second[index], WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
+ len2 = (int)utf8_to_ucs2(Request->WorkstationName + len, ClientDnsNames.second[index], WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
index = rand() % _countof(ClientDnsNames.tld);
utf8_to_ucs2(Request->WorkstationName + len + len2, ClientDnsNames.tld[index], WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
diff --git a/vlmcsd-floppy.7.html b/vlmcsd-floppy.7.html
index 310d69f..5a75f4a 100644
--- a/vlmcsd-floppy.7.html
+++ b/vlmcsd-floppy.7.html
@@ -1,5 +1,5 @@
-
+
diff --git a/vlmcsd-floppy.7.pdf b/vlmcsd-floppy.7.pdf
index 895b163..4b058c9 100644
Binary files a/vlmcsd-floppy.7.pdf and b/vlmcsd-floppy.7.pdf differ
diff --git a/vlmcsd.7.html b/vlmcsd.7.html
index 503d8f5..f454a0c 100644
--- a/vlmcsd.7.html
+++ b/vlmcsd.7.html
@@ -1,5 +1,5 @@
-
+
diff --git a/vlmcsd.7.pdf b/vlmcsd.7.pdf
index 6629bd1..dfe83cf 100644
Binary files a/vlmcsd.7.pdf and b/vlmcsd.7.pdf differ
diff --git a/vlmcsd.8.html b/vlmcsd.8.html
index 286f588..552285d 100644
--- a/vlmcsd.8.html
+++ b/vlmcsd.8.html
@@ -1,5 +1,5 @@
-
+
diff --git a/vlmcsd.8.pdf b/vlmcsd.8.pdf
index 50bdada..26c9ba3 100644
Binary files a/vlmcsd.8.pdf and b/vlmcsd.8.pdf differ
diff --git a/vlmcsd.c b/vlmcsd.c
index 3ea1bf1..0c62ec9 100644
--- a/vlmcsd.c
+++ b/vlmcsd.c
@@ -1,3 +1,7 @@
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
@@ -25,6 +29,10 @@
#include
#include
+#if _MSC_VER
+#include "wingetopt.h"
+#endif
+
#ifndef _WIN32
#include
#include
@@ -74,6 +82,7 @@
static const char* const optstring = "N:B:m:t:w:0:3:6:H:A:R:u:g:L:p:i:P:l:r:U:W:C:F:o:T:SseDdVvqkZ";
+
#if !defined(NO_SOCKETS) && !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
static uint_fast8_t maxsockets = 0;
@@ -170,28 +179,28 @@ static int shmid = -1;
#ifdef __NR_shmget
static int shmget(key_t key, size_t size, int shmflg)
{
- return syscall(__NR_shmget, key, size, shmflg);
+ return syscall(__NR_shmget, key, size, shmflg);
}
#endif // __NR_shmget
#ifdef __NR_shmat
static void *shmat(int shmid, const void *shmaddr, int shmflg)
{
- return (void *)syscall(__NR_shmat, shmid, shmaddr, shmflg);
+ return (void *)syscall(__NR_shmat, shmid, shmaddr, shmflg);
}
#endif // __NR_shmat
#ifdef __NR_shmdt
static int shmdt(const void *shmaddr)
{
- return syscall(__NR_shmdt, shmaddr);
+ return syscall(__NR_shmdt, shmaddr);
}
#endif // __NR_shmdt
#ifdef __NR_shmctl
static int shmctl(int shmid, int cmd, /*struct shmid_ds*/void *buf)
{
- return syscall(__NR_shmctl, shmid, cmd, buf);
+ return syscall(__NR_shmctl, shmid, cmd, buf);
}
#endif // __NR_shmctl
@@ -262,102 +271,102 @@ static __noreturn void usage()
static __noreturn void usage()
{
printerrorf("vlmcsd %s\n"
- "\nUsage:\n"
- " %s [ options ]\n\n"
- "Where:\n"
- #ifndef NO_CL_PIDS
- " -w always use for Windows\n"
- " -0 always use for Office2010\n"
- " -3 always use for Office2013\n"
- " -6 always use for Office2016\n"
- " -H always use hardware Id \n"
- #endif // NO_CL_PIDS
- #if !defined(_WIN32) && !defined(NO_USER_SWITCH)
- " -u set uid to \n"
- " -g set gid to \n"
- #endif // !defined(_WIN32) && !defined(NO_USER_SWITCH)
- #ifndef NO_RANDOM_EPID
- " -r 0|1|2\t\tset ePID randomization level (default 1)\n"
- " -C \t\tuse fixed in random ePIDs\n"
- #endif // NO_RANDOM_EPID
- #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"
- #else // !HAVE_GETIFADDR
- #ifndef USE_MSRPC
- " -o 0|2\t\tset protection level against clients with public IP addresses (default 0)\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"
- #endif // USE_MSRPC
- #endif // !HAVE_GETIFADDR
- #endif // !defined(NO_PRIVATE_IP_DETECT)
- #ifndef NO_SOCKETS
- #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"
- #if HAVE_FREEBIND
- " -F0, -F1\t\tdisable/enable binding to foreign IP addresses\n"
- #endif // HAVE_FREEBIND
- #else // defined(USE_MSRPC) || defined(SIMPLE_SOCKETS)
- " -P \t\tuse TCP port (default 1688)\n"
- #endif // defined(USE_MSRPC) || defined(SIMPLE_SOCKETS)
- #if !defined(NO_LIMIT) && !__minix__
- " -m \t\tHandle max. simultaneously (default no limit)\n"
- #endif // !defined(NO_LIMIT) && !__minix__
- #ifdef _NTSERVICE
- " -s install vlmcsd as an NT service. Ignores -e"
- #ifndef _WIN32
- ", -f and -D"
- #endif // _WIN32
- "\n"
- " -S remove vlmcsd service. Ignores all other options\n"
- " -U run NT service as . Must be used with -s\n"
- " -W optional for -U. Must be used with -s\n"
- #endif // _NTSERVICE
- #ifndef NO_LOG
- " -e log to stdout\n"
- #endif // NO_LOG
- #ifndef _WIN32 //
- " -D run in foreground\n"
- #else // _WIN32
- " -D does nothing. Provided for compatibility with POSIX versions only\n"
- #endif // _WIN32
- #endif // NO_SOCKETS
- #ifndef USE_MSRPC
- #if !defined(NO_TIMEOUT) && !__minix__
- " -t \t\tdisconnect clients after of inactivity (default 30)\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"
- " -N0, -N1\t\tdisable/enable NDR64\n"
- " -B0, -B1\t\tdisable/enable bind time feature negotiation\n"
- #endif // USE_MSRPC
- #ifndef NO_PID_FILE
- " -p write pid to \n"
- #endif // NO_PID_FILE
- #ifndef NO_INI_FILE
- " -i \t\tuse config file \n"
- #endif // NO_INI_FILE
- #ifndef NO_CUSTOM_INTERVALS
- " -R renew activation every (default 1w)\n"
- " -A retry activation every (default 2h)\n"
- #endif // NO_CUSTOM_INTERVALS
- #ifndef NO_LOG
- #ifndef _WIN32
- " -l syslog log to syslog\n"
- #endif // _WIN32
- " -l log to \n"
- " -T0, -T1\t\tdisable/enable logging with time and date (default -T1)\n"
- #ifndef NO_VERBOSE_LOG
- " -v\t\t\tlog verbose\n"
- " -q\t\t\tdon't log verbose (default)\n"
- #endif // NO_VERBOSE_LOG
- #endif // NO_LOG
- #ifndef NO_VERSION_INFORMATION
- " -V display version information and exit\n"
- #endif // NO_VERSION_INFORMATION
- ,
- Version, global_argv[0]);
+ "\nUsage:\n"
+ " %s [ options ]\n\n"
+ "Where:\n"
+#ifndef NO_CL_PIDS
+ " -w always use for Windows\n"
+ " -0 always use for Office2010\n"
+ " -3 always use for Office2013\n"
+ " -6 always use for Office2016\n"
+ " -H always use hardware Id \n"
+#endif // NO_CL_PIDS
+#if !defined(_WIN32) && !defined(NO_USER_SWITCH)
+ " -u set uid to \n"
+ " -g set gid to \n"
+#endif // !defined(_WIN32) && !defined(NO_USER_SWITCH)
+#ifndef NO_RANDOM_EPID
+ " -r 0|1|2\t\tset ePID randomization level (default 1)\n"
+ " -C \t\tuse fixed in random ePIDs\n"
+#endif // NO_RANDOM_EPID
+#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"
+#else // !HAVE_GETIFADDR
+#ifndef USE_MSRPC
+ " -o 0|2\t\tset protection level against clients with public IP addresses (default 0)\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"
+#endif // USE_MSRPC
+#endif // !HAVE_GETIFADDR
+#endif // !defined(NO_PRIVATE_IP_DETECT)
+#ifndef NO_SOCKETS
+#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"
+#if HAVE_FREEBIND
+ " -F0, -F1\t\tdisable/enable binding to foreign IP addresses\n"
+#endif // HAVE_FREEBIND
+#else // defined(USE_MSRPC) || defined(SIMPLE_SOCKETS)
+ " -P \t\tuse TCP port (default 1688)\n"
+#endif // defined(USE_MSRPC) || defined(SIMPLE_SOCKETS)
+#if !defined(NO_LIMIT) && !__minix__
+ " -m \t\tHandle max. simultaneously (default no limit)\n"
+#endif // !defined(NO_LIMIT) && !__minix__
+#ifdef _NTSERVICE
+ " -s install vlmcsd as an NT service. Ignores -e"
+#ifndef _WIN32
+ ", -f and -D"
+#endif // _WIN32
+ "\n"
+ " -S remove vlmcsd service. Ignores all other options\n"
+ " -U run NT service as . Must be used with -s\n"
+ " -W optional for -U. Must be used with -s\n"
+#endif // _NTSERVICE
+#ifndef NO_LOG
+ " -e log to stdout\n"
+#endif // NO_LOG
+#ifndef _WIN32 //
+ " -D run in foreground\n"
+#else // _WIN32
+ " -D does nothing. Provided for compatibility with POSIX versions only\n"
+#endif // _WIN32
+#endif // NO_SOCKETS
+#ifndef USE_MSRPC
+#if !defined(NO_TIMEOUT) && !__minix__
+ " -t \t\tdisconnect clients after of inactivity (default 30)\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"
+ " -N0, -N1\t\tdisable/enable NDR64\n"
+ " -B0, -B1\t\tdisable/enable bind time feature negotiation\n"
+#endif // USE_MSRPC
+#ifndef NO_PID_FILE
+ " -p write pid to \n"
+#endif // NO_PID_FILE
+#ifndef NO_INI_FILE
+ " -i \t\tuse config file \n"
+#endif // NO_INI_FILE
+#ifndef NO_CUSTOM_INTERVALS
+ " -R renew activation every (default 1w)\n"
+ " -A retry activation every (default 2h)\n"
+#endif // NO_CUSTOM_INTERVALS
+#ifndef NO_LOG
+#ifndef _WIN32
+ " -l syslog log to syslog\n"
+#endif // _WIN32
+ " -l log to \n"
+ " -T0, -T1\t\tdisable/enable logging with time and date (default -T1)\n"
+#ifndef NO_VERBOSE_LOG
+ " -v\t\t\tlog verbose\n"
+ " -q\t\t\tdon't log verbose (default)\n"
+#endif // NO_VERBOSE_LOG
+#endif // NO_LOG
+#ifndef NO_VERSION_INFORMATION
+ " -V display version information and exit\n"
+#endif // NO_VERSION_INFORMATION
+ ,
+ Version, global_argv[0]);
exit(!0);
}
@@ -371,27 +380,27 @@ __pure static DWORD timeSpanString2Minutes(const char *const restrict argument)
{
char *unitId;
- long long val = strtoll(argument, &unitId, 10);
+ long long val = vlmcsd_strtoll(argument, &unitId, 10);
- switch(toupper((int)*unitId))
+ switch (toupper((int)*unitId))
{
- case 0:
- case 'M':
- break;
- case 'H':
- val *= 60;
- break;
- case 'D':
- val *= 60 * 24;
- break;
- case 'W':
- val *= 60 * 24 * 7;
- break;
- case 'S':
- val /= 60;
- break;
- default:
- return 0;
+ case 0:
+ case 'M':
+ break;
+ case 'H':
+ val *= 60;
+ break;
+ case 'D':
+ val *= 60 * 24;
+ break;
+ case 'W':
+ val *= 60 * 24 * 7;
+ break;
+ case 'S':
+ val /= 60;
+ break;
+ default:
+ return 0;
}
if (val < 1) val = 1;
@@ -424,7 +433,7 @@ __pure static DWORD getTimeSpanFromCommandLine(const char *const restrict optarg
if (!val)
{
printerrorf("Fatal: No valid time span specified in option -%c.\n", optchar);
- exit (!0);
+ exit(!0);
}
return (DWORD)val;
@@ -464,7 +473,7 @@ static BOOL getIniFileArgumentInt(unsigned int *result, const char *const argume
if (!stringToInt(argument, min, max, &tempResult))
{
- snprintf(IniFileErrorBuffer, INIFILE_ERROR_BUFFERSIZE, "Must be integer between %u and %u", min, max);
+ vlmcsd_snprintf(IniFileErrorBuffer, INIFILE_ERROR_BUFFERSIZE, "Must be integer between %u and %u", min, max);
IniFileErrorMessage = IniFileErrorBuffer;
return FALSE;
}
@@ -492,7 +501,7 @@ static __pure int isControlCharOrSlash(const char c)
static void iniFileLineNextWord(const char **s)
{
- while ( **s && isspace((int)**s) ) (*s)++;
+ while (**s && isspace((int)**s)) (*s)++;
}
@@ -538,9 +547,9 @@ static BOOL setEpidFromIniFileLine(const char **s, const ProdListIndex_t index)
KmsResponseParameters[index].Epid = epidbuffer;
- #ifndef NO_LOG
+#ifndef NO_LOG
KmsResponseParameters[index].EpidSource = fn_ini;
- #endif //NO_LOG
+#endif //NO_LOG
return TRUE;
}
@@ -552,134 +561,134 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
BOOL success = TRUE;
const char *s = (const char*)iniarg;
- switch(id)
+ switch (id)
{
- case INI_PARAM_WINDOWS:
- setEpidFromIniFileLine(&s, EPID_INDEX_WINDOWS);
- setHwIdFromIniFileLine(&s, EPID_INDEX_WINDOWS);
- break;
-
- case INI_PARAM_OFFICE2010:
- setEpidFromIniFileLine(&s, EPID_INDEX_OFFICE2010);
- setHwIdFromIniFileLine(&s, EPID_INDEX_OFFICE2010);
- break;
-
- case INI_PARAM_OFFICE2013:
- setEpidFromIniFileLine(&s, EPID_INDEX_OFFICE2013);
- setHwIdFromIniFileLine(&s, EPID_INDEX_OFFICE2013);
- break;
-
- case INI_PARAM_OFFICE2016:
- setEpidFromIniFileLine(&s, EPID_INDEX_OFFICE2016);
- setHwIdFromIniFileLine(&s, EPID_INDEX_OFFICE2016);
- break;
+ case INI_PARAM_WINDOWS:
+ setEpidFromIniFileLine(&s, EPID_INDEX_WINDOWS);
+ setHwIdFromIniFileLine(&s, EPID_INDEX_WINDOWS);
+ break;
+
+ case INI_PARAM_OFFICE2010:
+ setEpidFromIniFileLine(&s, EPID_INDEX_OFFICE2010);
+ setHwIdFromIniFileLine(&s, EPID_INDEX_OFFICE2010);
+ break;
+
+ case INI_PARAM_OFFICE2013:
+ setEpidFromIniFileLine(&s, EPID_INDEX_OFFICE2013);
+ setHwIdFromIniFileLine(&s, EPID_INDEX_OFFICE2013);
+ break;
+
+ case INI_PARAM_OFFICE2016:
+ setEpidFromIniFileLine(&s, EPID_INDEX_OFFICE2016);
+ setHwIdFromIniFileLine(&s, EPID_INDEX_OFFICE2016);
+ break;
# if !defined(NO_USER_SWITCH) && !defined(_WIN32)
- case INI_PARAM_GID:
- {
- struct group *g;
- IniFileErrorMessage = "Invalid group id or name";
- if (!(gname = allocateStringArgument(iniarg))) return FALSE;
-
- if ((g = getgrnam(iniarg)))
- gid = g->gr_gid;
- else
- success = !GetNumericId(&gid, iniarg);
- break;
- }
+ case INI_PARAM_GID:
+ {
+ struct group *g;
+ IniFileErrorMessage = "Invalid group id or name";
+ if (!(gname = allocateStringArgument(iniarg))) return FALSE;
- case INI_PARAM_UID:
- {
- struct passwd *p;
- IniFileErrorMessage = "Invalid user id or name";
- if (!(uname = allocateStringArgument(iniarg))) return FALSE;
-
- if ((p = getpwnam(iniarg)))
- uid = p->pw_uid;
- else
- success = !GetNumericId(&uid, iniarg);
- break;
- }
+ if ((g = getgrnam(iniarg)))
+ gid = g->gr_gid;
+ else
+ success = !GetNumericId(&gid, iniarg);
+ break;
+ }
+
+ case INI_PARAM_UID:
+ {
+ struct passwd *p;
+ IniFileErrorMessage = "Invalid user id or name";
+ if (!(uname = allocateStringArgument(iniarg))) return FALSE;
+
+ if ((p = getpwnam(iniarg)))
+ uid = p->pw_uid;
+ else
+ success = !GetNumericId(&uid, iniarg);
+ break;
+ }
# endif // !defined(NO_USER_SWITCH) && !defined(_WIN32)
# ifndef NO_RANDOM_EPID
- case INI_PARAM_LCID:
- success = getIniFileArgumentInt(&result, iniarg, 0, 32767);
- if (success) Lcid = (uint16_t)result;
- break;
+ case INI_PARAM_LCID:
+ success = getIniFileArgumentInt(&result, iniarg, 0, 32767);
+ if (success) Lcid = (uint16_t)result;
+ break;
- case INI_PARAM_RANDOMIZATION_LEVEL:
- success = getIniFileArgumentInt(&result, iniarg, 0, 2);
- if (success) RandomizationLevel = (int_fast8_t)result;
- break;
+ case INI_PARAM_RANDOMIZATION_LEVEL:
+ success = getIniFileArgumentInt(&result, iniarg, 0, 2);
+ if (success) RandomizationLevel = (int_fast8_t)result;
+ break;
# endif // NO_RANDOM_EPID
# if (defined(USE_MSRPC) || defined(SIMPLE_SOCKETS) || defined(HAVE_GETIFADDR)) && !defined(NO_SOCKETS)
- case INI_PARAM_PORT:
- defaultport = allocateStringArgument(iniarg);
- break;
+ case INI_PARAM_PORT:
+ defaultport = allocateStringArgument(iniarg);
+ break;
# endif // (defined(USE_MSRPC) || defined(SIMPLE_SOCKETS) || defined(HAVE_GETIFADDR)) && !defined(NO_SOCKETS)
# if !defined(NO_SOCKETS) && !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
- case INI_PARAM_LISTEN:
- maxsockets++;
- return TRUE;
+ case INI_PARAM_LISTEN:
+ maxsockets++;
+ return TRUE;
# endif // !defined(NO_SOCKETS) && !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
# if !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !__minix__
- case INI_PARAM_MAX_WORKERS:
+ case INI_PARAM_MAX_WORKERS:
# ifdef USE_MSRPC
- success = getIniFileArgumentInt(&MaxTasks, iniarg, 1, RPC_C_LISTEN_MAX_CALLS_DEFAULT);
+ success = getIniFileArgumentInt(&MaxTasks, iniarg, 1, RPC_C_LISTEN_MAX_CALLS_DEFAULT);
# else // !USE_MSRPC
- success = getIniFileArgumentInt(&MaxTasks, iniarg, 1, SEM_VALUE_MAX);
+ success = getIniFileArgumentInt(&MaxTasks, iniarg, 1, SEM_VALUE_MAX);
# endif // !USE_MSRPC
- break;
+ break;
# endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !__minix__
# ifndef NO_PID_FILE
- case INI_PARAM_PID_FILE:
- fn_pid = allocateStringArgument(iniarg);
- break;
+ case INI_PARAM_PID_FILE:
+ fn_pid = allocateStringArgument(iniarg);
+ break;
# endif // NO_PID_FILE
# ifndef NO_LOG
- case INI_PARAM_LOG_FILE:
- fn_log = allocateStringArgument(iniarg);
- break;
+ case INI_PARAM_LOG_FILE:
+ fn_log = allocateStringArgument(iniarg);
+ break;
- case INI_PARAM_LOG_DATE_AND_TIME:
- success = getIniFileArgumentBool(&LogDateAndTime, iniarg);
- break;
+ case INI_PARAM_LOG_DATE_AND_TIME:
+ success = getIniFileArgumentBool(&LogDateAndTime, iniarg);
+ break;
# ifndef NO_VERBOSE_LOG
- case INI_PARAM_LOG_VERBOSE:
- success = getIniFileArgumentBool(&logverbose, iniarg);
- break;
+ case INI_PARAM_LOG_VERBOSE:
+ success = getIniFileArgumentBool(&logverbose, iniarg);
+ break;
# endif // NO_VERBOSE_LOG
# endif // NO_LOG
# ifndef NO_CUSTOM_INTERVALS
- case INI_PARAM_ACTIVATION_INTERVAL:
- success = getTimeSpanFromIniFile(&VLActivationInterval, iniarg);
- break;
+ case INI_PARAM_ACTIVATION_INTERVAL:
+ success = getTimeSpanFromIniFile(&VLActivationInterval, iniarg);
+ break;
- case INI_PARAM_RENEWAL_INTERVAL:
- success = getTimeSpanFromIniFile(&VLRenewalInterval, iniarg);
- break;
+ case INI_PARAM_RENEWAL_INTERVAL:
+ success = getTimeSpanFromIniFile(&VLRenewalInterval, iniarg);
+ break;
# endif // NO_CUSTOM_INTERVALS
@@ -687,54 +696,54 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
# if !defined(NO_TIMEOUT) && !__minix__
- case INI_PARAM_CONNECTION_TIMEOUT:
- success = getIniFileArgumentInt(&result, iniarg, 1, 600);
- if (success) ServerTimeout = (DWORD)result;
- break;
+ case INI_PARAM_CONNECTION_TIMEOUT:
+ success = getIniFileArgumentInt(&result, iniarg, 1, 600);
+ if (success) ServerTimeout = (DWORD)result;
+ break;
# endif // !defined(NO_TIMEOUT) && !__minix__
- case INI_PARAM_DISCONNECT_IMMEDIATELY:
- success = getIniFileArgumentBool(&DisconnectImmediately, iniarg);
- break;
+ case INI_PARAM_DISCONNECT_IMMEDIATELY:
+ success = getIniFileArgumentBool(&DisconnectImmediately, iniarg);
+ break;
- case INI_PARAM_RPC_NDR64:
- success = getIniFileArgumentBool(&UseRpcNDR64, iniarg);
- break;
+ case INI_PARAM_RPC_NDR64:
+ success = getIniFileArgumentBool(&UseRpcNDR64, iniarg);
+ break;
- case INI_PARAM_RPC_BTFN:
- success = getIniFileArgumentBool(&UseRpcBTFN, iniarg);
- break;
+ case INI_PARAM_RPC_BTFN:
+ success = getIniFileArgumentBool(&UseRpcBTFN, iniarg);
+ break;
# endif // USE_MSRPC
# if HAVE_FREEBIND
- case INI_PARAM_FREEBIND:
- success = getIniFileArgumentBool(&freebind, iniarg);
- break;
+ case INI_PARAM_FREEBIND:
+ success = getIniFileArgumentBool(&freebind, iniarg);
+ break;
# endif // HAVE_FREEBIND
# if !defined(NO_PRIVATE_IP_DETECT)
- case INI_PARAM_PUBLIC_IP_PROTECTION_LEVEL:
- success = getIniFileArgumentInt(&PublicIPProtectionLevel, iniarg, 0, 3);
+ case INI_PARAM_PUBLIC_IP_PROTECTION_LEVEL:
+ success = getIniFileArgumentInt(&PublicIPProtectionLevel, iniarg, 0, 3);
# if !HAVE_GETIFADDR
- if (PublicIPProtectionLevel & 1)
- {
- IniFileErrorMessage = "Must be 0 or 2";
- success = FALSE;
- }
+ if (PublicIPProtectionLevel & 1)
+ {
+ IniFileErrorMessage = "Must be 0 or 2";
+ success = FALSE;
+ }
# endif // !HAVE_GETIFADDR
- break;
+ break;
# endif // !defined(NO_PRIVATE_IP_DETECT)
- default:
- return FALSE;
+ default:
+ return FALSE;
}
return success;
@@ -790,7 +799,7 @@ static BOOL setupListeningSocketsFromIniFile(const char *s)
if (strncasecmp("Listen", s, 6)) return TRUE;
if (!getIniFileArgument(&s)) return TRUE;
- snprintf(IniFileErrorBuffer, INIFILE_ERROR_BUFFERSIZE, "Cannot listen on %s.", s);
+ vlmcsd_snprintf(IniFileErrorBuffer, INIFILE_ERROR_BUFFERSIZE, "Cannot listen on %s.", s);
IniFileErrorMessage = IniFileErrorBuffer;
return addListeningSocket(s);
}
@@ -809,7 +818,7 @@ static BOOL readIniFile(const uint_fast8_t pass)
IniFileErrorBuffer = (char*)vlmcsd_malloc(INIFILE_ERROR_BUFFERSIZE);
- if ( !(f = fopen(fn_ini, "r") )) return FALSE;
+ if (!(f = fopen(fn_ini, "r"))) return FALSE;
for (lineNumber = 1; (s = fgets(line, sizeof(line), f)); lineNumber++)
{
@@ -858,7 +867,7 @@ static BOOL readIniFile(const uint_fast8_t pass)
# ifdef _NTSERVICE
if (!installService)
# endif // _NTSERVICE
- logger("Read ini file %s\n", fn_ini);
+ logger("Read ini file %s\n", fn_ini);
}
# endif // !defined(NO_SOCKETS) && !defined(NO_LOG)
@@ -875,46 +884,46 @@ static void exec_self(char** argv)
{
# if __linux__ && defined(USE_AUXV)
- char *execname_ptr = (char*)getauxval(AT_EXECFN);
- if (execname_ptr) execv(execname_ptr, argv);
+ char *execname_ptr = (char*)getauxval(AT_EXECFN);
+ if (execname_ptr) execv(execname_ptr, argv);
# elif (__linux__ || __CYGWIN__) && !defined(NO_PROCFS)
- execv(realpath("/proc/self/exe", NULL), argv);
+ execv(realpath("/proc/self/exe", NULL), argv);
# elif (__FreeBSD__) && !defined(NO_PROCFS)
- 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)) execv(path, argv);
+ 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)) execv(path, argv);
# elif (__DragonFly__) && !defined(NO_PROCFS)
- execv(realpath("/proc/curproc/file", NULL), argv);
+ execv(realpath("/proc/curproc/file", NULL), argv);
# elif __NetBSD__ && !defined(NO_PROCFS)
- execv(realpath("/proc/curproc/exe", NULL), argv);
+ execv(realpath("/proc/curproc/exe", NULL), argv);
# elif __sun__
- const char* exename = getexecname();
- if (exename) execv(exename, argv);
+ const char* exename = getexecname();
+ if (exename) execv(exename, argv);
# elif __APPLE__
- char path[PATH_MAX + 1];
- uint32_t size = sizeof(path);
- if (_NSGetExecutablePath(path, &size) == 0) execv(path, argv);
+ char path[PATH_MAX + 1];
+ uint32_t size = sizeof(path);
+ if (_NSGetExecutablePath(path, &size) == 0) execv(path, argv);
# else
- execvp(argv[0], argv);
+ execvp(argv[0], argv);
# endif
}
@@ -940,11 +949,11 @@ static void HangupHandler(const int signal_unused)
exec_self((char**)argv_out);
# ifndef NO_LOG
- logger("Fatal: Unable to restart on SIGHUP: %s\n", strerror(errno));
+ logger("Fatal: Unable to restart on SIGHUP: %s\n", strerror(errno));
# endif
# ifndef NO_PID_FILE
- if (fn_pid) unlink(fn_pid);
+ if (fn_pid) unlink(fn_pid);
# endif // NO_PID_FILE
exit(errno);
}
@@ -972,9 +981,9 @@ static int daemonizeAndSetSignalAction()
sigemptyset(&sa.sa_mask);
# ifndef NO_LOG
- if ( !nodaemon) if (daemon(!0, logstdout))
+ if (!nodaemon) if (daemon(!0, logstdout))
# else // NO_LOG
- if ( !nodaemon) if (daemon(!0, 0))
+ if (!nodaemon) if (daemon(!0, 0))
# endif // NO_LOG
{
printerrorf("Fatal: Could not daemonize to background.\n");
@@ -990,7 +999,7 @@ static int daemonizeAndSetSignalAction()
# else // !(defined(CHILD_HANDLER) || __minix__)
sa.sa_handler = SIG_IGN;
# endif // !(defined(CHILD_HANDLER) || __minix__)
- sa.sa_flags = SA_NOCLDWAIT;
+ sa.sa_flags = SA_NOCLDWAIT;
if (sigaction(SIGCHLD, &sa, NULL))
return(errno);
@@ -998,14 +1007,14 @@ static int daemonizeAndSetSignalAction()
# endif // !USE_THREADS
sa.sa_handler = terminationHandler;
- sa.sa_flags = 0;
+ sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
# ifndef NO_SIGHUP
sa.sa_handler = HangupHandler;
- sa.sa_flags = SA_NODEFER;
+ sa.sa_flags = SA_NODEFER;
sigaction(SIGHUP, &sa, NULL);
# endif // NO_SIGHUP
}
@@ -1019,29 +1028,29 @@ static int daemonizeAndSetSignalAction()
static BOOL terminationHandler(const DWORD fdwCtrlType)
{
// What a lame substitute for Unix signal handling
- switch(fdwCtrlType)
+ switch (fdwCtrlType)
{
- case CTRL_C_EVENT:
- case CTRL_CLOSE_EVENT:
- case CTRL_BREAK_EVENT:
- case CTRL_LOGOFF_EVENT:
- case CTRL_SHUTDOWN_EVENT:
- cleanup();
- exit(0);
- default:
- return FALSE;
+ case CTRL_C_EVENT:
+ case CTRL_CLOSE_EVENT:
+ case CTRL_BREAK_EVENT:
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ cleanup();
+ exit(0);
+ default:
+ return FALSE;
}
}
static DWORD daemonizeAndSetSignalAction()
{
- if(!SetConsoleCtrlHandler( (PHANDLER_ROUTINE) terminationHandler, TRUE ))
+ if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)terminationHandler, TRUE))
{
- #ifndef NO_LOG
+#ifndef NO_LOG
DWORD rc = GetLastError();
logger("Warning: Could not register Windows signal handler: Error %u\n", rc);
- #endif // NO_LOG
+#endif // NO_LOG
}
return ERROR_SUCCESS;
@@ -1055,13 +1064,13 @@ static DWORD daemonizeAndSetSignalAction()
#if !defined(NO_INI_FILE) || !defined(NO_LOG) || !defined(NO_CL_PIDS)
__pure static char* getCommandLineArg(char *const restrict optarg)
{
- #if !defined (__CYGWIN__) || defined(USE_THREADS) || defined(NO_SOCKETS)
- return optarg;
- #else
- if (!IsNTService) return optarg;
+# if !defined (__CYGWIN__) || defined(USE_THREADS) || defined(NO_SOCKETS)
+ return optarg;
+# else
+ if (!IsNTService) return optarg;
- return allocateStringArgument(optarg);
- #endif
+ return allocateStringArgument(optarg);
+# endif
}
#endif // !defined(NO_INI_FILE) || !defined(NO_LOG) || !defined(NO_CL_PIDS)
@@ -1069,363 +1078,365 @@ __pure static char* getCommandLineArg(char *const restrict optarg)
static void parseGeneralArguments() {
int o;
- #ifndef NO_CL_PIDS
+#ifndef NO_CL_PIDS
BYTE* HwId;
- #endif // NO_CL_PIDS
+#endif // NO_CL_PIDS
- for (opterr = 0; ( o = getopt(global_argc, (char* const*)global_argv, optstring) ) > 0; ) switch (o)
+ for (opterr = 0; (o = getopt(global_argc, (char* const*)global_argv, (const char*)optstring)) > 0; ) switch (o)
{
- #if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
- case 'Z':
- IsRestarted = TRUE;
- nodaemon = TRUE;
- break;
- #endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
-
- #ifndef NO_CL_PIDS
-
- case 'w':
- KmsResponseParameters[EPID_INDEX_WINDOWS].Epid = getCommandLineArg(optarg);
- #ifndef NO_LOG
- KmsResponseParameters[EPID_INDEX_WINDOWS].EpidSource = "command line";
- #endif // NO_LOG
- break;
-
- case '0':
- KmsResponseParameters[EPID_INDEX_OFFICE2010].Epid = getCommandLineArg(optarg);
- #ifndef NO_LOG
- KmsResponseParameters[EPID_INDEX_OFFICE2010].EpidSource = "command line";
- #endif // NO_LOG
- break;
-
- case '3':
- KmsResponseParameters[EPID_INDEX_OFFICE2013].Epid = getCommandLineArg(optarg);
- #ifndef NO_LOG
- KmsResponseParameters[EPID_INDEX_OFFICE2013].EpidSource = "command line";
- #endif // NO_LOG
- break;
-
- case '6':
- KmsResponseParameters[EPID_INDEX_OFFICE2016].Epid = getCommandLineArg(optarg);
- #ifndef NO_LOG
- KmsResponseParameters[EPID_INDEX_OFFICE2016].EpidSource = "command line";
- #endif // NO_LOG
- break;
-
- case 'H':
- HwId = (BYTE*)vlmcsd_malloc(sizeof(((RESPONSE_V6 *)0)->HwId));
-
- hex2bin(HwId, optarg, sizeof(((RESPONSE_V6 *)0)->HwId));
-
- KmsResponseParameters[EPID_INDEX_WINDOWS].HwId =
+# if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
+ case 'Z':
+ IsRestarted = TRUE;
+ nodaemon = TRUE;
+ break;
+# endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
+
+# ifndef NO_CL_PIDS
+
+ case 'w':
+ KmsResponseParameters[EPID_INDEX_WINDOWS].Epid = getCommandLineArg(optarg);
+# ifndef NO_LOG
+ KmsResponseParameters[EPID_INDEX_WINDOWS].EpidSource = "command line";
+# endif // NO_LOG
+ break;
+
+ case '0':
+ KmsResponseParameters[EPID_INDEX_OFFICE2010].Epid = getCommandLineArg(optarg);
+# ifndef NO_LOG
+ KmsResponseParameters[EPID_INDEX_OFFICE2010].EpidSource = "command line";
+# endif // NO_LOG
+ break;
+
+ case '3':
+ KmsResponseParameters[EPID_INDEX_OFFICE2013].Epid = getCommandLineArg(optarg);
+# ifndef NO_LOG
+ KmsResponseParameters[EPID_INDEX_OFFICE2013].EpidSource = "command line";
+# endif // NO_LOG
+ break;
+
+ case '6':
+ KmsResponseParameters[EPID_INDEX_OFFICE2016].Epid = getCommandLineArg(optarg);
+# ifndef NO_LOG
+ KmsResponseParameters[EPID_INDEX_OFFICE2016].EpidSource = "command line";
+# endif // NO_LOG
+ break;
+
+ case 'H':
+ HwId = (BYTE*)vlmcsd_malloc(sizeof(((RESPONSE_V6 *)0)->HwId));
+
+ hex2bin(HwId, optarg, sizeof(((RESPONSE_V6 *)0)->HwId));
+
+ KmsResponseParameters[EPID_INDEX_WINDOWS].HwId =
KmsResponseParameters[EPID_INDEX_OFFICE2010].HwId =
KmsResponseParameters[EPID_INDEX_OFFICE2013].HwId =
KmsResponseParameters[EPID_INDEX_OFFICE2016].HwId = HwId;
- break;
-
- #endif // NO_CL_PIDS
-
- #ifndef NO_SOCKETS
-
- case 'P':
- ignoreIniFileParameter(INI_PARAM_PORT);
- #if !defined(SIMPLE_SOCKETS) && !defined(USE_MSRPC)
- ignoreIniFileParameter(INI_PARAM_LISTEN);
- #else
- defaultport = optarg;
- #endif // !SIMPLE_SOCKETS
- break;
-
- #if !defined(NO_LIMIT) && !__minix__
-
- case 'm':
- #ifdef USE_MSRPC
- MaxTasks = getOptionArgumentInt(o, 1, RPC_C_LISTEN_MAX_CALLS_DEFAULT);
- #else // !USE_MSRPC
- MaxTasks = getOptionArgumentInt(o, 1, SEM_VALUE_MAX);
- #endif // !USE_MSRPC
- ignoreIniFileParameter(INI_PARAM_MAX_WORKERS);
- break;
-
- #endif // !defined(NO_LIMIT) && !__minix__
- #endif // NO_SOCKETS
-
- #if !defined(NO_TIMEOUT) && !__minix__ && !defined(USE_MSRPC)
- case 't':
- ServerTimeout = getOptionArgumentInt(o, 1, 600);
- ignoreIniFileParameter(INI_PARAM_CONNECTION_TIMEOUT);
- break;
- #endif // !defined(NO_TIMEOUT) && !__minix__ && !defined(USE_MSRPC)
-
- #ifndef NO_PID_FILE
- case 'p':
- fn_pid = getCommandLineArg(optarg);
- ignoreIniFileParameter(INI_PARAM_PID_FILE);
- break;
- #endif
-
- #ifndef NO_INI_FILE
- case 'i':
- fn_ini = getCommandLineArg(optarg);
- if (!strcmp(fn_ini, "-")) fn_ini = NULL;
- break;
- #endif
-
- #ifndef NO_LOG
-
- case 'T':
- if (!getArgumentBool(&LogDateAndTime, optarg)) usage();
- ignoreIniFileParameter(INI_PARAM_LOG_DATE_AND_TIME);
- break;
-
- case 'l':
- fn_log = getCommandLineArg(optarg);
- ignoreIniFileParameter(INI_PARAM_LOG_FILE);
- break;
-
- #ifndef NO_VERBOSE_LOG
- case 'v':
- case 'q':
- logverbose = o == 'v';
- ignoreIniFileParameter(INI_PARAM_LOG_VERBOSE);
- break;
-
- #endif // NO_VERBOSE_LOG
- #endif // NO_LOG
-
- #if !defined(NO_PRIVATE_IP_DETECT)
- case 'o':
- ignoreIniFileParameter(INI_PARAM_PUBLIC_IP_PROTECTION_LEVEL);
- PublicIPProtectionLevel = getOptionArgumentInt(o, 0, 3);
-
- #if !HAVE_GETIFADDR
- if (PublicIPProtectionLevel & 1) usage();
- #endif // !HAVE_GETIFADDR
-
- break;
- #endif // !defined(NO_PRIVATE_IP_DETECT)
-
- #ifndef NO_SOCKETS
- #if !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
- case 'L':
- maxsockets++;
- ignoreIniFileParameter(INI_PARAM_LISTEN);
- break;
- #if HAVE_FREEBIND
- case 'F':
- if (!getArgumentBool(&freebind, optarg)) usage();
- ignoreIniFileParameter(INI_PARAM_FREEBIND);
- break;
- #endif // HAVE_FREEBIND
- #endif // !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
-
- #ifdef _NTSERVICE
- case 'U':
- ServiceUser = optarg;
- break;
-
- case 'W':
- ServicePassword = optarg;
- break;
-
- case 's':
- #ifndef USE_MSRPC
- if (InetdMode) usage();
- #endif // USE_MSRPC
- if (!IsNTService) installService = 1; // Install
- break;
-
- case 'S':
- if (!IsNTService) installService = 2; // Remove
- break;
- #endif // _NTSERVICE
-
- case 'D':
- #ifndef _WIN32
- nodaemon = 1;
- #else // _WIN32
- #ifdef _PEDANTIC
- printerrorf("Warning: Option -D has no effect in the Windows version of vlmcsd.\n");
- #endif // _PEDANTIC
- #endif // _WIN32
- break;
-
- #ifndef NO_LOG
-
- case 'e':
- logstdout = 1;
- break;
-
- #endif // NO_LOG
- #endif // NO_SOCKETS
-
- #ifndef NO_RANDOM_EPID
- case 'r':
- RandomizationLevel = (int_fast8_t)getOptionArgumentInt(o, 0, 2);
- ignoreIniFileParameter(INI_PARAM_RANDOMIZATION_LEVEL);
- break;
-
- case 'C':
- Lcid = (uint16_t)getOptionArgumentInt(o, 0, 32767);
-
- ignoreIniFileParameter(INI_PARAM_LCID);
-
- #ifdef _PEDANTIC
- if (!IsValidLcid(Lcid))
- {
- printerrorf("Warning: %s is not a valid LCID.\n", optarg);
- }
- #endif // _PEDANTIC
-
- break;
- #endif // NO_RANDOM_PID
-
- #if !defined(NO_USER_SWITCH) && !defined(_WIN32)
- case 'g':
- gname = optarg;
- ignoreIniFileParameter(INI_PARAM_GID);
- #ifndef NO_SIGHUP
- if (!IsRestarted)
- #endif // NO_SIGHUP
+ break;
+
+# endif // NO_CL_PIDS
+
+# ifndef NO_SOCKETS
+
+ case 'P':
+ ignoreIniFileParameter(INI_PARAM_PORT);
+# if !defined(SIMPLE_SOCKETS) && !defined(USE_MSRPC)
+ ignoreIniFileParameter(INI_PARAM_LISTEN);
+# else
+ defaultport = optarg;
+# endif // !SIMPLE_SOCKETS
+ break;
+
+# if !defined(NO_LIMIT) && !__minix__
+
+ case 'm':
+# ifdef USE_MSRPC
+ MaxTasks = getOptionArgumentInt(o, 1, RPC_C_LISTEN_MAX_CALLS_DEFAULT);
+# else // !USE_MSRPC
+ MaxTasks = getOptionArgumentInt((char)o, 1, SEM_VALUE_MAX);
+# endif // !USE_MSRPC
+ ignoreIniFileParameter(INI_PARAM_MAX_WORKERS);
+ break;
+
+# endif // !defined(NO_LIMIT) && !__minix__
+# endif // NO_SOCKETS
+
+# if !defined(NO_TIMEOUT) && !__minix__ && !defined(USE_MSRPC)
+ case 't':
+ ServerTimeout = getOptionArgumentInt((char)o, 1, 600);
+ ignoreIniFileParameter(INI_PARAM_CONNECTION_TIMEOUT);
+ break;
+# endif // !defined(NO_TIMEOUT) && !__minix__ && !defined(USE_MSRPC)
+
+# ifndef NO_PID_FILE
+ case 'p':
+ fn_pid = getCommandLineArg(optarg);
+ ignoreIniFileParameter(INI_PARAM_PID_FILE);
+ break;
+# endif
+
+# ifndef NO_INI_FILE
+ case 'i':
+ fn_ini = getCommandLineArg(optarg);
+ if (!strcmp(fn_ini, "-")) fn_ini = NULL;
+ break;
+# endif
+
+# ifndef NO_LOG
+
+ case 'T':
+ if (!getArgumentBool(&LogDateAndTime, optarg)) usage();
+ ignoreIniFileParameter(INI_PARAM_LOG_DATE_AND_TIME);
+ break;
+
+ case 'l':
+ fn_log = getCommandLineArg(optarg);
+ ignoreIniFileParameter(INI_PARAM_LOG_FILE);
+ break;
+
+# ifndef NO_VERBOSE_LOG
+ case 'v':
+ case 'q':
+ logverbose = o == 'v';
+ ignoreIniFileParameter(INI_PARAM_LOG_VERBOSE);
+ break;
+
+# endif // NO_VERBOSE_LOG
+# endif // NO_LOG
+
+# if !defined(NO_PRIVATE_IP_DETECT)
+ case 'o':
+ ignoreIniFileParameter(INI_PARAM_PUBLIC_IP_PROTECTION_LEVEL);
+ PublicIPProtectionLevel = getOptionArgumentInt((char)o, 0, 3);
+
+# if !HAVE_GETIFADDR
+ if (PublicIPProtectionLevel & 1) usage();
+# endif // !HAVE_GETIFADDR
+
+ break;
+# endif // !defined(NO_PRIVATE_IP_DETECT)
+
+# ifndef NO_SOCKETS
+# if !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
+ case 'L':
+ maxsockets++;
+ ignoreIniFileParameter(INI_PARAM_LISTEN);
+ break;
+# if HAVE_FREEBIND
+ case 'F':
+ if (!getArgumentBool(&freebind, optarg)) usage();
+ ignoreIniFileParameter(INI_PARAM_FREEBIND);
+ break;
+# endif // HAVE_FREEBIND
+# endif // !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS)
+
+# ifdef _NTSERVICE
+ case 'U':
+ ServiceUser = optarg;
+ break;
+
+ case 'W':
+ ServicePassword = optarg;
+ break;
+
+ case 's':
+# ifndef USE_MSRPC
+ if (InetdMode) usage();
+# endif // USE_MSRPC
+ if (!IsNTService) installService = 1; // Install
+ break;
+
+ case 'S':
+ if (!IsNTService) installService = 2; // Remove
+ break;
+# endif // _NTSERVICE
+
+ case 'D':
+# ifndef _WIN32
+ nodaemon = 1;
+# else // _WIN32
+# ifdef _PEDANTIC
+ printerrorf("Warning: Option -D has no effect in the Windows version of vlmcsd.\n");
+# endif // _PEDANTIC
+# endif // _WIN32
+ break;
+
+# ifndef NO_LOG
+
+ case 'e':
+ logstdout = 1;
+ break;
+
+# endif // NO_LOG
+# endif // NO_SOCKETS
+
+# ifndef NO_RANDOM_EPID
+ case 'r':
+ RandomizationLevel = (int_fast8_t)getOptionArgumentInt((char)o, 0, 2);
+ ignoreIniFileParameter(INI_PARAM_RANDOMIZATION_LEVEL);
+ break;
+
+ case 'C':
+ Lcid = (uint16_t)getOptionArgumentInt((char)o, 0, 32767);
+
+ ignoreIniFileParameter(INI_PARAM_LCID);
+
+# ifdef _PEDANTIC
+ if (!IsValidLcid(Lcid))
+ {
+ printerrorf("Warning: %s is not a valid LCID.\n", optarg);
+ }
+# endif // _PEDANTIC
+
+ break;
+# endif // NO_RANDOM_PID
+
+# if !defined(NO_USER_SWITCH) && !defined(_WIN32)
+ case 'g':
+ gname = optarg;
+ ignoreIniFileParameter(INI_PARAM_GID);
+# ifndef NO_SIGHUP
+ if (!IsRestarted)
+# endif // NO_SIGHUP
if (GetGid())
{
printerrorf("Fatal: %s for %s failed: %s\n", "setgid", gname, strerror(errno));
exit(errno);
}
- break;
-
- case 'u':
- uname = optarg;
- ignoreIniFileParameter(INI_PARAM_UID);
- #ifndef NO_SIGHUP
- if (!IsRestarted)
- #endif // NO_SIGHUP
+ break;
+
+ case 'u':
+ uname = optarg;
+ ignoreIniFileParameter(INI_PARAM_UID);
+# ifndef NO_SIGHUP
+ if (!IsRestarted)
+# endif // NO_SIGHUP
if (GetUid())
{
printerrorf("Fatal: %s for %s failed: %s\n", "setuid", uname, strerror(errno));
exit(errno);
}
- break;
- #endif // NO_USER_SWITCH && !_WIN32
-
- #ifndef NO_CUSTOM_INTERVALS
- case 'R':
- VLRenewalInterval = getTimeSpanFromCommandLine(optarg, o);
- ignoreIniFileParameter(INI_PARAM_RENEWAL_INTERVAL);
- break;
-
- case 'A':
- VLActivationInterval = getTimeSpanFromCommandLine(optarg, o);
- ignoreIniFileParameter(INI_PARAM_ACTIVATION_INTERVAL);
- break;
- #endif
-
- #ifndef USE_MSRPC
- case 'd':
- case 'k':
- DisconnectImmediately = o == 'd';
- ignoreIniFileParameter(INI_PARAM_DISCONNECT_IMMEDIATELY);
- break;
-
- case 'N':
- if (!getArgumentBool(&UseRpcNDR64, optarg)) usage();
- ignoreIniFileParameter(INI_PARAM_RPC_NDR64);
- break;
-
- case 'B':
- if (!getArgumentBool(&UseRpcBTFN, optarg)) usage();
- ignoreIniFileParameter(INI_PARAM_RPC_BTFN);
- break;
- #endif // !USE_MSRPC
-
- #ifndef NO_VERSION_INFORMATION
- case 'V':
- #ifdef _NTSERVICE
- if (IsNTService) break;
- #endif
- #if defined(__s390__) && !defined(__zarch__) && !defined(__s390x__)
- printf("vlmcsd %s %i-bit\n", Version, sizeof(void*) == 4 ? 31 : (int)sizeof(void*) << 3);
- #else
- printf("vlmcsd %s %i-bit\n", Version, (int)sizeof(void*) << 3);
- #endif // defined(__s390__) && !defined(__zarch__) && !defined(__s390x__)
- printPlatform();
- printCommonFlags();
- printServerFlags();
- exit(0);
- #endif // NO_VERSION_INFORMATION
-
- default:
- usage();
+ break;
+# endif // NO_USER_SWITCH && !_WIN32
+
+# ifndef NO_CUSTOM_INTERVALS
+ case 'R':
+ VLRenewalInterval = getTimeSpanFromCommandLine(optarg, (char)o);
+ ignoreIniFileParameter(INI_PARAM_RENEWAL_INTERVAL);
+ break;
+
+ case 'A':
+ VLActivationInterval = getTimeSpanFromCommandLine(optarg, (char)o);
+ ignoreIniFileParameter(INI_PARAM_ACTIVATION_INTERVAL);
+ break;
+# endif // NO_CUSTOM_INTERVALS
+
+# ifndef USE_MSRPC
+ case 'd':
+ case 'k':
+ DisconnectImmediately = o == 'd';
+ ignoreIniFileParameter(INI_PARAM_DISCONNECT_IMMEDIATELY);
+ break;
+
+ case 'N':
+ if (!getArgumentBool(&UseRpcNDR64, optarg)) usage();
+ ignoreIniFileParameter(INI_PARAM_RPC_NDR64);
+ break;
+
+ case 'B':
+ if (!getArgumentBool(&UseRpcBTFN, optarg)) usage();
+ ignoreIniFileParameter(INI_PARAM_RPC_BTFN);
+ break;
+# endif // !USE_MSRPC
+
+# ifndef NO_VERSION_INFORMATION
+ case 'V':
+# ifdef _NTSERVICE
+ if (IsNTService) break;
+# endif
+# if defined(__s390__) && !defined(__zarch__) && !defined(__s390x__)
+ printf("vlmcsd %s %i-bit\n", Version, sizeof(void*) == 4 ? 31 : (int)sizeof(void*) << 3);
+# else
+ printf("vlmcsd %s %i-bit\n", Version, (int)sizeof(void*) << 3);
+# endif // defined(__s390__) && !defined(__zarch__) && !defined(__s390x__)
+ printPlatform();
+ printCommonFlags();
+ printServerFlags();
+ exit(0);
+# endif // NO_VERSION_INFORMATION
+
+ default:
+ usage();
}
// Do not allow non-option arguments
if (optind != global_argc)
usage();
- #ifdef _NTSERVICE
+# ifdef _NTSERVICE
// -U and -W must be used with -s
if ((ServiceUser || *ServicePassword) && installService != 1) usage();
- #endif // _NTSERVICE
+# endif // _NTSERVICE
}
-#ifndef NO_PID_FILE
+#if !defined(NO_PID_FILE)
static void writePidFile()
{
# ifndef NO_SIGHUP
- if (IsRestarted) return;
+ if (IsRestarted) return;
# endif // NO_SIGHUP
if (fn_pid && !InetdMode)
{
FILE *_f = fopen(fn_pid, "w");
- if ( _f )
+ if (_f)
{
- fprintf(_f, "%u", (uint32_t)getpid());
+# if _MSC_VER
+ fprintf(_f, "%u", (unsigned int)GetCurrentProcessId());
+# else
+ fprintf(_f, "%u", (unsigned int)getpid());
+# endif
fclose(_f);
}
- #ifndef NO_LOG
+# ifndef NO_LOG
else
{
logger("Warning: Cannot write pid file '%s'. %s.\n", fn_pid, strerror(errno));
}
- #endif // NO_LOG
+# endif // NO_LOG
}
}
#else
-#define writePidFile(x)
-#endif // NO_PID_FILE
+#define writePidFile()
+#endif // !defined(NO_PID_FILE)
#if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
void cleanup()
{
-
if (!InetdMode)
{
- #ifndef NO_PID_FILE
- if (fn_pid) unlink(fn_pid);
- #endif // NO_PID_FILE
+# ifndef NO_PID_FILE
+ if (fn_pid) vlmcsd_unlink(fn_pid);
+# endif // NO_PID_FILE
closeAllListeningSockets();
- #if !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !defined(_WIN32) && !__minix__
+# if !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !defined(_WIN32) && !__minix__
sem_unlink("/vlmcsd");
- #if !defined(USE_THREADS) && !defined(CYGWIN)
+# if !defined(USE_THREADS) && !defined(CYGWIN)
if (shmid >= 0)
{
if (Semaphore != (sem_t*)-1) shmdt(Semaphore);
shmctl(shmid, IPC_RMID, NULL);
}
- #endif // !defined(USE_THREADS) && !defined(CYGWIN)
- #endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !defined(_WIN32) && !__minix__
+# endif // !defined(USE_THREADS) && !defined(CYGWIN)
+# endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !defined(_WIN32) && !__minix__
- #ifndef NO_LOG
+# ifndef NO_LOG
logger("vlmcsd %s was shutdown\n", Version);
- #endif // NO_LOG
+# endif // NO_LOG
}
-
}
#elif defined(USE_MSRPC)
@@ -1452,31 +1463,31 @@ __pure void cleanup() {}
// Get a semaphore for limiting the maximum concurrent tasks
static void allocateSemaphore(void)
{
- #ifdef USE_THREADS
- #define sharemode 0
- #else
- #define sharemode 1
- #endif
+# ifdef USE_THREADS
+# define sharemode 0
+# else
+# define sharemode 1
+# endif
- #ifndef _WIN32
+# ifndef _WIN32
sem_unlink("/vlmcsd");
- #endif
+# endif
- if(MaxTasks < SEM_VALUE_MAX && !InetdMode)
+ if (MaxTasks < SEM_VALUE_MAX && !InetdMode)
{
- #ifndef _WIN32
+# ifndef _WIN32
- #if !defined(USE_THREADS) && !defined(CYGWIN)
+# if !defined(USE_THREADS) && !defined(CYGWIN)
- if ((Semaphore = sem_open("/vlmcsd", O_CREAT /*| O_EXCL*/, 0700, MaxTasks)) == SEM_FAILED) // fails on many systems
+ if ((Semaphore = sem_open("/vlmcsd", O_CREAT /*| O_EXCL*/, 0700, MaxTasks)) == SEM_FAILED) // fails on many systems
{
// We didn't get a named Semaphore (/dev/shm on Linux) so let's try our own shared page
if (
- ( shmid = shmget(IPC_PRIVATE, sizeof(sem_t), IPC_CREAT | 0600) ) < 0 ||
- ( Semaphore = (sem_t*)shmat(shmid, NULL, 0) ) == (sem_t*)-1 ||
- sem_init(Semaphore, 1, MaxTasks) < 0
- )
+ (shmid = shmget(IPC_PRIVATE, sizeof(sem_t), IPC_CREAT | 0600)) < 0 ||
+ (Semaphore = (sem_t*)shmat(shmid, NULL, 0)) == (sem_t*)-1 ||
+ sem_init(Semaphore, 1, MaxTasks) < 0
+ )
{
int errno_save = errno;
if (Semaphore != (sem_t*)-1) shmdt(Semaphore);
@@ -1486,7 +1497,7 @@ static void allocateSemaphore(void)
}
}
- #else // THREADS or CYGWIN
+# else // THREADS or CYGWIN
Semaphore = (sem_t*)vlmcsd_malloc(sizeof(sem_t));
@@ -1494,16 +1505,16 @@ static void allocateSemaphore(void)
{
free(Semaphore);
- if ((Semaphore = sem_open("/vlmcsd", O_CREAT /*| O_EXCL*/, 0700, MaxTasks)) == SEM_FAILED)
+ if ((Semaphore = sem_open("/vlmcsd", O_CREAT /*| O_EXCL*/, 0700, MaxTasks)) == SEM_FAILED)
{
printerrorf("Warning: Could not create semaphore: %s\n", vlmcsd_strerror(errno));
MaxTasks = SEM_VALUE_MAX;
}
}
- #endif // THREADS or CYGWIN
+# endif // THREADS or CYGWIN
- #else // _WIN32
+# else // _WIN32
if (!(Semaphore = CreateSemaphoreA(NULL, MaxTasks, MaxTasks, NULL)))
{
@@ -1511,7 +1522,7 @@ static void allocateSemaphore(void)
MaxTasks = SEM_VALUE_MAX;
}
- #endif // _WIN32
+# endif // _WIN32
}
}
#endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !__minix__
@@ -1522,7 +1533,7 @@ int setupListeningSockets()
{
int o;
# if HAVE_GETIFADDR
- char** privateIPList;
+ char** privateIPList = NULL;
int numPrivateIPs = 0;
if (PublicIPProtectionLevel & 1) getPrivateIPAddresses(&numPrivateIPs, &privateIPList);
uint_fast8_t allocsockets = maxsockets ? (maxsockets + numPrivateIPs) : ((PublicIPProtectionLevel & 1) ? numPrivateIPs : 2);
@@ -1538,18 +1549,18 @@ int setupListeningSockets()
// Reset getopt since we've alread used it
optReset();
- for (opterr = 0; ( o = getopt(global_argc, (char* const*)global_argv, optstring) ) > 0; ) switch (o)
+ for (opterr = 0; (o = getopt(global_argc, (char* const*)global_argv, (const char*)optstring)) > 0; ) switch (o)
{
- case 'P':
- defaultport = optarg;
- break;
+ case 'P':
+ defaultport = optarg;
+ break;
- case 'L':
- addListeningSocket(optarg);
- break;
+ case 'L':
+ addListeningSocket(optarg);
+ break;
- default:
- break;
+ default:
+ break;
}
@@ -1558,10 +1569,10 @@ int setupListeningSockets()
{
if (fn_ini && !readIniFile(INI_FILE_PASS_2))
{
- #ifdef INI_FILE
+# ifdef INI_FILE
if (strcmp(fn_ini, INI_FILE))
- #endif // INI_FILE
- printerrorf("Warning: Can't read %s: %s\n", fn_ini, strerror(errno));
+# endif // INI_FILE
+ printerrorf("Warning: Can't read %s: %s\n", fn_ini, strerror(errno));
}
}
# endif
@@ -1606,17 +1617,13 @@ int setupListeningSockets()
int server_main(int argc, CARGV argv)
{
- #if !defined(_NTSERVICE) && !defined(NO_SOCKETS)
- int error;
- #endif // !defined(_NTSERVICE) && !defined(NO_SOCKETS)
-
// Initialize ePID / HwId parameters
memset(KmsResponseParameters, 0, sizeof(KmsResponseParameters));
global_argc = argc;
global_argv = argv;
- #ifdef _NTSERVICE // #endif is in newmain()
+# ifdef _NTSERVICE
DWORD lasterror = ERROR_SUCCESS;
if (!StartServiceCtrlDispatcher(NTServiceDispatchTable) && (lasterror = GetLastError()) == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
@@ -1626,109 +1633,118 @@ int server_main(int argc, CARGV argv)
}
return lasterror;
+# else // !_NTSERVICE
+ return newmain();
+# endif // !_NTSERVICE
}
int newmain()
{
- int error;
-
// Initialize thread synchronization objects for Windows and Cygwin
- #ifdef USE_THREADS
+# ifdef USE_THREADS
- #ifndef NO_LOG
- // Initialize the Critical Section for proper logging
+# ifndef NO_LOG
+// Initialize the Critical Section for proper logging
+# if _WIN32
InitializeCriticalSection(&logmutex);
- #endif // NO_LOG
+# endif // _WIN32
+# endif // NO_LOG
- #endif // USE_THREADS
+# endif // USE_THREADS
- #ifdef _WIN32
+# ifdef _WIN32
- #ifndef USE_MSRPC
- // Windows Sockets must be initialized
+# ifndef USE_MSRPC
WSADATA wsadata;
-
- if ((error = WSAStartup(0x0202, &wsadata)))
{
- printerrorf("Fatal: Could not initialize Windows sockets (Error: %d).\n", error);
- return error;
+ // Windows Sockets must be initialized
+ int error;
+ if ((error = WSAStartup(0x0202, &wsadata)))
+ {
+ printerrorf("Fatal: Could not initialize Windows sockets (Error: %d).\n", error);
+ return error;
+ }
}
- #endif // USE_MSRPC
+# endif // USE_MSRPC
// Windows can never daemonize
//nodaemon = 1;
- #else // __CYGWIN__
+# else // __CYGWIN__
// Do not daemonize if we are a Windows service
+# ifdef _NTSERVICE
if (IsNTService) nodaemon = 1;
+# endif
- #endif // _WIN32 / __CYGWIN__
- #endif // _NTSERVICE ( #ifdef is main(int argc, CARGV argv) )
+# endif // _WIN32 / __CYGWIN__
parseGeneralArguments(); // Does not return if an error occurs
- #if !defined(_WIN32) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
+# if !defined(_WIN32) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
struct stat statbuf;
fstat(STDIN_FILENO, &statbuf);
if (S_ISSOCK(statbuf.st_mode))
{
InetdMode = 1;
nodaemon = 1;
- #ifndef SIMPLE_SOCKETS
+# ifndef SIMPLE_SOCKETS
maxsockets = 0;
- #endif // SIMPLE_SOCKETS
- #ifndef NO_LOG
+# endif // SIMPLE_SOCKETS
+# ifndef NO_LOG
logstdout = 0;
- #endif // NO_LOG
+# endif // NO_LOG
}
- #endif // !defined(_WIN32) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
+# endif // !defined(_WIN32) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
+
+# ifndef NO_INI_FILE
- #ifndef NO_INI_FILE
if (fn_ini && !readIniFile(INI_FILE_PASS_1))
{
- #ifdef INI_FILE
+# ifdef INI_FILE
if (strcmp(fn_ini, INI_FILE))
- #endif // INI_FILE
- printerrorf("Warning: Can't read %s: %s\n", fn_ini, strerror(errno));
+# endif // INI_FILE
+ printerrorf("Warning: Can't read %s: %s\n", fn_ini, strerror(errno));
}
- #endif // NO_INI_FILE
- #if defined(USE_MSRPC) && !defined(NO_PRIVATE_IP_DETECT)
+# endif // NO_INI_FILE
+
+# if defined(USE_MSRPC) && !defined(NO_PRIVATE_IP_DETECT)
if (PublicIPProtectionLevel)
{
printerrorf("Warning: Public IP address protection using MS RPC is poor. See vlmcsd.8\n");
}
- #endif // defined(USE_MSRPC) && !defined(NO_PRIVATE_IP_DETECT)
+# endif // defined(USE_MSRPC) && !defined(NO_PRIVATE_IP_DETECT)
-#if !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !__minix__ && !defined(USE_MSRPC)
+# if !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !__minix__ && !defined(USE_MSRPC)
allocateSemaphore();
- #endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && __minix__
+# endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && __minix__
- #ifdef _NTSERVICE
+# ifdef _NTSERVICE
if (installService)
return NtServiceInstallation(installService, ServiceUser, ServicePassword);
- #endif // _NTSERVICE
+# endif // _NTSERVICE
- #if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
+# if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
if (!InetdMode)
{
- #ifdef SIMPLE_SOCKETS
+ int error;
+# ifdef SIMPLE_SOCKETS
if ((error = listenOnAllAddresses())) return error;
- #else // !SIMPLE_SOCKETS
+# else // !SIMPLE_SOCKETS
if ((error = setupListeningSockets())) return error;
- #endif // !SIMPLE_SOCKETS
+# endif // !SIMPLE_SOCKETS
}
- #endif // !defined(NO_SOCKETS) && !defined(USE_MSRPC)
+# endif // !defined(NO_SOCKETS) && !defined(USE_MSRPC)
// After sockets have been set up, we may switch to a lower privileged user
- #if !defined(_WIN32) && !defined(NO_USER_SWITCH)
+# if !defined(_WIN32) && !defined(NO_USER_SWITCH)
- #ifndef NO_SIGHUP
+# ifndef NO_SIGHUP
if (!IsRestarted)
{
- #endif // NO_SIGHUP
+# endif // NO_SIGHUP
if (gid != INVALID_GID)
{
if (setgid(gid))
@@ -1749,50 +1765,55 @@ int newmain()
printerrorf("Fatal: %s for %s failed: %s\n", "setuid", uname, strerror(errno));
return errno;
}
- #ifndef NO_SIGHUP
+# ifndef NO_SIGHUP
}
- #endif // NO_SIGHUP
+# endif // NO_SIGHUP
- #endif // !defined(_WIN32) && !defined(NO_USER_SWITCH)
+# endif // !defined(_WIN32) && !defined(NO_USER_SWITCH)
randomNumberInit();
// Randomization Level 1 means generate ePIDs at startup and use them during
// the lifetime of the process. So we generate them now
- #ifndef NO_RANDOM_EPID
+# ifndef NO_RANDOM_EPID
if (RandomizationLevel == 1) randomPidInit();
- #endif
+# endif
- #if !defined(NO_SOCKETS)
- #ifdef _WIN32
+# if !defined(NO_SOCKETS)
+# ifdef _WIN32
if (!IsNTService)
- #endif // _WIN32
- if ((error = daemonizeAndSetSignalAction())) return error;
- #endif // !defined(NO_SOCKETS)
+ {
+# endif // _WIN32
+ int error;
+ if ((error = daemonizeAndSetSignalAction())) return error;
+# ifdef _WIN32
+ }
+# endif // _WIN32
+# endif // !defined(NO_SOCKETS)
writePidFile();
- #if !defined(NO_LOG) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
+# if !defined(NO_LOG) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
if (!InetdMode)
logger("vlmcsd %s started successfully\n", Version);
- #endif // !defined(NO_LOG) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
+# endif // !defined(NO_LOG) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
- #if defined(_NTSERVICE) && !defined(USE_MSRPC)
+# if defined(_NTSERVICE) && !defined(USE_MSRPC)
if (IsNTService) ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 200);
- #endif // defined(_NTSERVICE) && !defined(USE_MSRPC)
+# endif // defined(_NTSERVICE) && !defined(USE_MSRPC)
int rc;
rc = runServer();
// Clean up things and exit
- #ifdef _NTSERVICE
+# ifdef _NTSERVICE
if (!ServiceShutdown)
- #endif
+# endif
cleanup();
- #ifdef _NTSERVICE
+# ifdef _NTSERVICE
else
ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
- #endif
+# endif
return rc;
}
diff --git a/vlmcsd.h b/vlmcsd.h
index a1c0a63..089ccff 100644
--- a/vlmcsd.h
+++ b/vlmcsd.h
@@ -16,9 +16,7 @@ extern char *fn_log;
//int main(int argc, CARGV);
extern void cleanup();
-#ifdef _NTSERVICE
int newmain();
-#endif
#if MULTI_CALL_BINARY < 1
#define server_main main
diff --git a/vlmcsd.ini.5.html b/vlmcsd.ini.5.html
index 78c20f7..8c6ec58 100644
--- a/vlmcsd.ini.5.html
+++ b/vlmcsd.ini.5.html
@@ -1,5 +1,5 @@
-
+
diff --git a/vlmcsd.ini.5.pdf b/vlmcsd.ini.5.pdf
index a209a60..eb282a7 100644
Binary files a/vlmcsd.ini.5.pdf and b/vlmcsd.ini.5.pdf differ
diff --git a/vlmcsdmulti.1.html b/vlmcsdmulti.1.html
index 93f2a84..183dcdd 100644
--- a/vlmcsdmulti.1.html
+++ b/vlmcsdmulti.1.html
@@ -1,5 +1,5 @@
-
+
diff --git a/vlmcsdmulti.1.pdf b/vlmcsdmulti.1.pdf
index 9d6ff63..d935b41 100644
Binary files a/vlmcsdmulti.1.pdf and b/vlmcsdmulti.1.pdf differ
diff --git a/vlmcsdmulti.c b/vlmcsdmulti.c
index 6e47d50..8e94efb 100644
--- a/vlmcsdmulti.c
+++ b/vlmcsdmulti.c
@@ -1,5 +1,7 @@
/* Multi-Call Binary for vlmcs and vlmcsd */
+#define _CRT_SECURE_NO_WARNINGS
+
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
@@ -9,9 +11,15 @@
#error "Please define MULTI_CALL_BINARY=1 when compiling this file."
#endif
-#include
#include
+#if !_MSC_VER
+#include
+#else // _MSC_VER
+#include
+#include "helpers.h"
+#endif // _MSC_VER
+
#include "vlmcs.h"
#include "vlmcsd.h"
#include "types.h"
@@ -24,6 +32,33 @@
#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;
@@ -35,29 +70,29 @@ int main(int argc, CARGV argv)
if (!compare(basename((char*)*argv), "vlmcs"))
return client_main(argc, argv);
- #ifdef _WIN32
+#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
+#endif // _WIN32
if (argc > 1)
{
- if (!strcmp((char*)argv[1],"vlmcsd"))
+ if (!strcmp((char*)argv[1], "vlmcsd"))
return server_main(argc - 1, argv + 1);
- if (!strcmp((char*)argv[1],"vlmcs"))
+ if (!strcmp((char*)argv[1], "vlmcs"))
return client_main(argc - 1, argv + 1);
}
errorout(
- "vlmcsdmulti %s\n\n"
- "Usage:\n"
- "\t%s vlmcsd []\n"
- "\t%s vlmcs []\n\n",
- Version, *argv, *argv
+ "vlmcsdmulti %s\n\n"
+ "Usage:\n"
+ "\t%s vlmcsd []\n"
+ "\t%s vlmcs []\n\n",
+ Version, *argv, *argv
);
return !0;
diff --git a/wingetopt.c b/wingetopt.c
new file mode 100644
index 0000000..0f62043
--- /dev/null
+++ b/wingetopt.c
@@ -0,0 +1,76 @@
+/*
+POSIX getopt for Windows
+
+AT&T Public License
+
+Code given out at the 1985 UNIFORUM conference in Dallas.
+*/
+
+#ifdef _MSC_VER
+
+#include "wingetopt.h"
+#include
+#include
+
+#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 /* __GNUC__ */
\ No newline at end of file
diff --git a/wingetopt.h b/wingetopt.h
new file mode 100644
index 0000000..a0f859e
--- /dev/null
+++ b/wingetopt.h
@@ -0,0 +1,32 @@
+/*
+POSIX getopt for Windows
+
+AT&T Public License
+
+Code given out at the 1985 UNIFORUM conference in Dallas.
+*/
+
+#ifndef _MSC_VER
+#include
+#endif
+#ifdef _MSC_VER
+
+#ifndef _WINGETOPT_H_
+#define _WINGETOPT_H_
+
+#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 /* _GETOPT_H_ */
+#endif /* __GNUC__ */
\ No newline at end of file