2017-10-19 05:48:23 +03:00
// SoftEther VPN Source Code - Developer Edition Master Branch
2014-01-04 17:00:08 +04:00
// Mayaqua Kernel
// Microsoft.c
// For Microsoft Windows code
// (not compiled on non-Windows environments)
2021-04-05 05:48:25 +03:00
# ifdef OS_WIN32
2014-01-04 17:00:08 +04:00
# define MICROSOFT_C
2021-04-05 05:48:25 +03:00
# include "Microsoft.h"
# include "FileIO.h"
# include "GlobalConst.h"
# include "Internat.h"
# include "Memory.h"
# include "Object.h"
# include "Str.h"
# include "Table.h"
# include "Tick64.h"
# include "Win32.h"
// TODO: Mayaqua should not depend on Cedar.
# include <Cedar/Cedar.h>
# include <Cedar/Client.h>
# include <Cedar/CM.h>
# include <Cedar/WinUi.h>
# define SECURITY_WIN32
// The struct is defined in Microsoft's <cfg.h>, but Mayaqua's one gets included instead.
typedef enum _PNP_VETO_TYPE {
PNP_VetoTypeUnknown , // Name is unspecified
PNP_VetoLegacyDevice , // Name is an Instance Path
PNP_VetoPendingClose , // Name is an Instance Path
PNP_VetoWindowsApp , // Name is a Module
PNP_VetoWindowsService , // Name is a Service
PNP_VetoOutstandingOpen , // Name is an Instance Path
PNP_VetoDevice , // Name is an Instance Path
PNP_VetoDriver , // Name is a Driver Service Name
PNP_VetoIllegalDeviceRequest , // Name is an Instance Path
PNP_VetoInsufficientPower , // Name is unspecified
PNP_VetoNonDisableable , // Name is an Instance Path
PNP_VetoLegacyDriver , // Name is a Service
PNP_VetoInsufficientRights , // Name is unspecified
PNP_VetoAlreadyRemoved , // Name is unspecified
} PNP_VETO_TYPE , * PPNP_VETO_TYPE ;
# include <AclAPI.h>
2014-01-04 17:00:08 +04:00
# include <cfgmgr32.h>
2021-04-05 05:48:25 +03:00
# include <DbgHelp.h>
2021-04-03 03:25:19 +03:00
# include <dwmapi.h>
2021-04-05 05:48:25 +03:00
# include <iphlpapi.h>
# include <mmsystem.h>
# include <Msi.h>
# include <nb30.h>
2021-04-03 03:25:19 +03:00
# include <newdev.h>
2021-04-05 05:48:25 +03:00
# include <NTSecAPI.h>
# include <Psapi.h>
# include <sddl.h>
# include <security.h>
# include <shellapi.h>
# include <ShlObj.h>
# include <SoftPub.h>
# include <WtsApi32.h>
2014-01-04 17:00:08 +04:00
static MS * ms = NULL ;
// Global variable
UINT64 ms_uint64_1 = 0 ;
// Adapter list related
static LOCK * lock_adapter_list = NULL ;
static MS_ADAPTER_LIST * last_adapter_list = NULL ;
// Service related
static SERVICE_STATUS_HANDLE ssh = NULL ;
static SERVICE_STATUS status = { 0 } ;
static HANDLE service_stop_event = NULL ;
static BOOL ( WINAPI * _StartServiceCtrlDispatcher ) ( CONST LPSERVICE_TABLE_ENTRY ) = NULL ;
static SERVICE_STATUS_HANDLE ( WINAPI * _RegisterServiceCtrlHandler ) ( LPCTSTR , LPHANDLER_FUNCTION ) = NULL ;
static BOOL ( WINAPI * _SetServiceStatus ) ( SERVICE_STATUS_HANDLE , LPSERVICE_STATUS ) = NULL ;
static char g_service_name [ MAX_SIZE ] ;
static SERVICE_FUNCTION * g_start , * g_stop ;
static bool exiting = false ;
static bool wnd_end ;
static bool is_usermode = false ;
static HICON tray_icon ;
static NOTIFYICONDATAW nid_nt ;
static bool tray_inited = false ;
static HWND hWndUsermode = NULL ;
static HANDLE hLsa = NULL ;
static ULONG lsa_package_id = 0 ;
static TOKEN_SOURCE lsa_token_source ;
static LOCK * vlan_lock = NULL ;
2015-04-03 23:58:09 +03:00
static COUNTER * suspend_handler_singleton = NULL ;
static COUNTER * vlan_card_counter = NULL ;
static volatile BOOL vlan_card_should_stop_flag = false ;
2015-05-31 13:02:35 +03:00
static volatile BOOL vlan_is_in_suspend_mode = false ;
static volatile UINT64 vlan_suspend_mode_begin_tick = 0 ;
2014-01-04 17:00:08 +04:00
// msi.dll
static HINSTANCE hMsi = NULL ;
static UINT ( WINAPI * _MsiGetProductInfoW ) ( LPCWSTR , LPCWSTR , LPWSTR , LPDWORD ) = NULL ;
static UINT ( WINAPI * _MsiConfigureProductW ) ( LPCWSTR , int , INSTALLSTATE ) = NULL ;
static INSTALLUILEVEL ( WINAPI * _MsiSetInternalUI ) ( INSTALLUILEVEL , HWND * ) = NULL ;
static INSTALLSTATE ( WINAPI * _MsiLocateComponentW ) ( LPCWSTR , LPWSTR , LPDWORD ) = NULL ;
typedef struct MS_MSCHAPV2_PARAMS
{
wchar_t Username [ MAX_SIZE ] ;
wchar_t Workstation [ MAX_SIZE ] ;
wchar_t Domain [ MAX_SIZE ] ;
UCHAR ClientResponse24 [ 24 ] ;
UCHAR ResponseBuffer [ MAX_SIZE ] ;
} MS_MSCHAPV2_PARAMS ;
2018-04-22 12:21:19 +03:00
// The function which should be called once as soon as possible after the process is started
void MsInitProcessCallOnce ( )
{
// Mitigate the DLL injection attack
char system_dir [ MAX_PATH ] ;
char kernel32_path [ MAX_PATH ] ;
UINT len ;
HINSTANCE hKernel32 ;
// Get the full path of kernel32.dll
memset ( system_dir , 0 , sizeof ( system_dir ) ) ;
GetSystemDirectory ( system_dir , sizeof ( system_dir ) ) ;
len = lstrlenA ( system_dir ) ;
if ( system_dir [ len ] = = ' \\ ' )
{
system_dir [ len ] = 0 ;
}
wsprintfA ( kernel32_path , " %s \\ kernel32.dll " , system_dir ) ;
// Load kernel32.dll
hKernel32 = LoadLibraryA ( kernel32_path ) ;
if ( hKernel32 ! = NULL )
{
BOOL ( WINAPI * _SetDllDirectoryA ) ( LPCTSTR ) ;
_SetDllDirectoryA = ( BOOL ( WINAPI * ) ( LPCTSTR ) )
GetProcAddress ( hKernel32 , " SetDllDirectoryA " ) ;
if ( _SetDllDirectoryA ! = NULL )
{
_SetDllDirectoryA ( " " ) ;
}
FreeLibrary ( hKernel32 ) ;
}
}
2014-01-04 17:00:08 +04:00
// Collect the information of the VPN software
bool MsCollectVpnInfo ( BUF * bat , char * tmpdir , char * svc_name , wchar_t * config_name , wchar_t * logdir_name )
{
wchar_t * inst_dir ;
char subkey [ MAX_PATH ] ;
bool ret = false ;
wchar_t tmpdir_w [ MAX_PATH ] ;
// Validate arguments
if ( bat = = NULL | | tmpdir = = NULL | | svc_name = = NULL | | config_name = = NULL | | logdir_name = = NULL )
{
return false ;
}
StrToUni ( tmpdir_w , sizeof ( tmpdir_w ) , tmpdir ) ;
Format ( subkey , sizeof ( subkey ) , " SOFTWARE \\ " GC_REG_COMPANY_NAME " \\ Setup Wizard Settings \\ %s " , svc_name ) ;
inst_dir = MsRegReadStrEx2W ( REG_LOCAL_MACHINE , subkey , " InstalledDir " , false , true ) ;
if ( UniIsEmptyStr ( inst_dir ) = = false )
{
wchar_t config_src [ MAX_PATH ] ;
wchar_t config_dst [ MAX_PATH ] ;
wchar_t log_dir [ MAX_PATH ] ;
DIRLIST * dir ;
UINT64 max_dt_file = 0 ;
// config file
CombinePathW ( config_src , sizeof ( config_src ) , inst_dir , config_name ) ;
UniFormat ( config_dst , sizeof ( config_dst ) , L " %s \\ %S_%s " , tmpdir_w , svc_name , config_name ) ;
ret = FileCopyExW ( config_src , config_dst , false ) ;
// Log file
CombinePathW ( log_dir , sizeof ( log_dir ) , inst_dir , logdir_name ) ;
dir = EnumDirW ( log_dir ) ;
if ( dir ! = NULL )
{
UINT i ;
DIRENT * latest_log = NULL ;
for ( i = 0 ; i < dir - > NumFiles ; i + + )
{
DIRENT * e = dir - > File [ i ] ;
// Get the most recent file
if ( max_dt_file < = e - > UpdateDate )
{
max_dt_file = e - > UpdateDate ;
latest_log = e ;
}
}
if ( latest_log ! = NULL )
{
wchar_t fullpath [ MAX_SIZE ] ;
IO * f ;
// Open the log file
CombinePathW ( fullpath , sizeof ( fullpath ) , log_dir , latest_log - > FileNameW ) ;
f = FileOpenExW ( fullpath , false , false ) ;
if ( f ! = NULL )
{
UINT size = FileSize ( f ) ;
if ( size > = 1 )
{
UINT copy_size = 1024 * 1024 ;
UINT seek_size = 0 ;
UCHAR * buf ;
if ( copy_size < size )
{
seek_size = size - copy_size ;
}
else
{
copy_size = size ;
}
FileSeek ( f , 0 , seek_size ) ;
buf = Malloc ( copy_size + 3 ) ;
buf [ 0 ] = 0xEF ;
buf [ 1 ] = 0xBB ;
buf [ 2 ] = 0xBF ;
if ( FileRead ( f , buf + 3 , copy_size ) )
{
char log_dst_filename [ MAX_PATH ] ;
Format ( log_dst_filename , sizeof ( log_dst_filename ) , " %s \\ lastlog_%s_%s " ,
tmpdir , svc_name , latest_log - > FileName ) ;
SaveFile ( log_dst_filename , buf , copy_size + 3 ) ;
}
Free ( buf ) ;
}
FileClose ( f ) ;
}
}
FreeDir ( dir ) ;
}
}
Free ( inst_dir ) ;
return ret ;
}
// Save the system information
bool MsSaveSystemInfo ( wchar_t * dst_filename )
{
char tmpdir [ MAX_PATH ] ;
UCHAR rand_data [ SHA1_SIZE ] ;
char rand_str [ MAX_SIZE ] ;
char filename_bat [ MAX_PATH ] ;
BUF * bat ;
char tmp [ MAX_PATH ] ;
char cmd [ MAX_PATH ] ;
char cmd_arg [ MAX_PATH ] ;
bool ret = false ;
DIRLIST * dir ;
UINT i ;
// Validate arguments
if ( dst_filename = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
if ( MsIsAdmin ( ) = = false )
2014-01-04 17:00:08 +04:00
{
return false ;
}
Rand ( rand_data , sizeof ( rand_data ) ) ;
BinToStr ( rand_str , sizeof ( rand_str ) , rand_data , 4 ) ;
// Create a temporary directory
Format ( tmpdir , sizeof ( tmpdir ) , " %s \\ Temp \\ se_support_%s " , MsGetWindowsDir ( ) , rand_str ) ;
MakeDirEx ( tmpdir ) ;
// Create a batch file
CombinePath ( filename_bat , sizeof ( filename_bat ) , tmpdir , " make_system_info.cmd " ) ;
bat = NewBuf ( ) ;
Format ( tmp , sizeof ( tmp ) , " systeminfo > %s \\ SystemInfo.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " ipconfig > %s \\ ipconfig.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " netsh dump > %s \\ netsh.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " route print > %s \\ route.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " netstat -nab > %s \\ netstat_nab.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " netstat -nao > %s \\ netstat_nao.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " netstat -na > %s \\ netstat_na.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " netstat -fab > %s \\ netstat_fab.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " netstat -fao > %s \\ netstat_fao.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " netstat -fa > %s \\ netstat_fa.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " netstat -ab > %s \\ netstat_ab.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " netstat -ao > %s \\ netstat_ao.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " netstat -a > %s \\ netstat_a.txt " , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
Format ( tmp , sizeof ( tmp ) , " \" %s \\ Common Files \\ Microsoft Shared \\ MSInfo \\ msinfo32.exe \" /report %s \\ SystemInfo.txt " , MsGetProgramFilesDir ( ) , tmpdir ) ;
WriteBufLine ( bat , tmp ) ;
// Collect the information of the VPN software
MsCollectVpnInfo ( bat , tmpdir , " vpnclient " , L " vpn_client.config " , L " client_log " ) ;
MsCollectVpnInfo ( bat , tmpdir , " vpnserver " , L " vpn_server.config " , L " server_log " ) ;
MsCollectVpnInfo ( bat , tmpdir , " vpnbridge " , L " vpn_bridge.config " , L " server_log " ) ;
MsCollectVpnInfo ( bat , tmpdir , " sevpnclient " , L " vpn_client.config " , L " client_log " ) ;
MsCollectVpnInfo ( bat , tmpdir , " sevpnserver " , L " vpn_server.config " , L " server_log " ) ;
MsCollectVpnInfo ( bat , tmpdir , " sevpnbridge " , L " vpn_bridge.config " , L " server_log " ) ;
WriteBufLine ( bat , " " ) ;
DumpBuf ( bat , filename_bat ) ;
FreeBuf ( bat ) ;
// Run the batch file
CombinePath ( cmd , sizeof ( cmd ) , MsGetSystem32Dir ( ) , " cmd.exe " ) ;
Format ( cmd_arg , sizeof ( cmd_arg ) , " /C %s " , filename_bat ) ;
if ( Win32Run ( cmd , cmd_arg , false , true ) )
{
dir = EnumDir ( tmpdir ) ;
if ( dir ! = NULL )
{
ZIP_PACKER * zip ;
zip = NewZipPacker ( ) ;
for ( i = 0 ; i < dir - > NumFiles ; i + + )
{
char * name = dir - > File [ i ] - > FileName ;
char full [ MAX_PATH ] ;
CombinePath ( full , sizeof ( full ) , tmpdir , name ) ;
ZipAddRealFile ( zip , name , SystemTime64 ( ) , 0 , full ) ;
}
FreeDir ( dir ) ;
ret = ZipWriteW ( zip , dst_filename ) ;
FreeZipPacker ( zip ) ;
}
}
// Delete the temporary directory
dir = EnumDir ( tmpdir ) ;
if ( dir ! = NULL )
{
for ( i = 0 ; i < dir - > NumFiles ; i + + )
{
char * name = dir - > File [ i ] - > FileName ;
char full [ MAX_PATH ] ;
CombinePath ( full , sizeof ( full ) , tmpdir , name ) ;
if ( EndWith ( full , " .txt " ) | | EndWith ( full , " .cmd " ) | | EndWith ( full , " .config " ) | | EndWith ( full , " .log " ) )
{
FileDelete ( full ) ;
}
}
FreeDir ( dir ) ;
}
DeleteDir ( tmpdir ) ;
return ret ;
}
// Determine whether this is running in a VM
bool MsIsInVmMain ( )
{
char * bat_data = " On Error Resume Next \r \n \r \n Dim str \r \n \r \n Set wmi_svc = GetObject( \" winmgmts:{impersonationLevel=impersonate}! \\ \\ . \\ root \\ cimv2 \" ) \r \n \r \n Set items = wmi_svc.ExecQuery( \" Select * from Win32_BaseBoard \" ) \r \n \r \n For Each item in items \r \n str = str & item.Manufacturer \r \n Next \r \n \r \n Set items = Nothing \r \n \r \n Set items = wmi_svc.ExecQuery( \" Select * from Win32_ComputerSystem \" ) \r \n \r \n For Each item in items \r \n str = str & item.Manufacturer \r \n Next \r \n \r \n Set items = Nothing \r \n \r \n Set wmi_svc = Nothing \r \n \r \n str = LCase(str) \r \n \r \n Dim ret \r \n \r \n ret = 0 \r \n \r \n if InStr(str, \" microsoft corporation \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" vmware \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" virtualbox \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" virtualpc \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" xen \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" hvm \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" domu \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" kvm \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" oracle vm \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" qemu \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" parallels \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" xvm \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" virtual \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n if InStr(str, \" bochs \" ) > 0 then \r \n ret = 1 \r \n end if \r \n \r \n wscript.quit ret \r \n \r \n " ;
wchar_t bat_filename [ MAX_SIZE ] ;
wchar_t cscript_exe [ MAX_SIZE ] ;
wchar_t tmp [ MAX_SIZE ] ;
void * process ;
bool ret = false ;
CombinePathW ( bat_filename , sizeof ( bat_filename ) , MsGetMyTempDirW ( ) , L " detectvm.vbs " ) ;
if ( DumpDataW ( bat_data , StrLen ( bat_data ) , bat_filename ) = = false )
{
return false ;
}
CombinePathW ( cscript_exe , sizeof ( cscript_exe ) , MsGetSystem32DirW ( ) , L " cscript.exe " ) ;
UniFormat ( tmp , sizeof ( tmp ) , L " \" %s \" " , bat_filename ) ;
process = Win32RunEx3W ( cscript_exe , tmp , true , NULL , true ) ;
if ( process = = NULL )
{
return false ;
}
if ( Win32WaitProcess ( process , 30000 ) )
{
DWORD exit_code = 0 ;
if ( GetExitCodeProcess ( process , & exit_code ) )
{
if ( exit_code = = 1 )
{
ret = true ;
}
}
}
Win32CloseProcess ( process ) ;
return ret ;
}
bool MsIsInVm ( )
{
static bool flag_detected = false ;
static bool flag_is_vm = false ;
if ( flag_detected = = false )
{
flag_is_vm = MsIsInVmMain ( ) ;
flag_detected = true ;
}
return flag_is_vm ;
}
// Get the current module handle
void * MsGetCurrentModuleHandle ( )
{
return ms - > hInst ;
}
// Resource enumeration procedure
2021-03-01 03:46:11 +03:00
BOOL CALLBACK MsEnumResourcesInternalProc ( HMODULE hModule , const char * type , char * name , LONG_PTR lParam )
2014-01-04 17:00:08 +04:00
{
LIST * o = ( LIST * ) lParam ;
// Validate arguments
if ( type = = NULL | | name = = NULL | | o = = NULL )
{
return true ;
}
Add ( o , CopyStr ( name ) ) ;
return true ;
}
// Enumeration of resources
TOKEN_LIST * MsEnumResources ( void * hModule , char * type )
{
LIST * o ;
TOKEN_LIST * ret ;
// Validate arguments
if ( hModule = = NULL )
{
hModule = MsGetCurrentModuleHandle ( ) ;
}
if ( type = = NULL )
{
return NullToken ( ) ;
}
o = NewListFast ( NULL ) ;
if ( EnumResourceNamesA ( hModule , type , MsEnumResourcesInternalProc , ( LONG_PTR ) o ) = = false )
{
ReleaseList ( o ) ;
return NullToken ( ) ;
}
ret = ListToTokenList ( o ) ;
FreeStrList ( o ) ;
return ret ;
}
// Get whether the locale ID of the current user is Japanese
bool MsIsCurrentUserLocaleIdJapanese ( )
{
UINT lcid = MsGetUserLocaleId ( ) ;
if ( lcid = = 1041 )
{
return true ;
}
return false ;
}
// Get the locale ID of the user
UINT MsGetUserLocaleId ( )
{
static UINT lcid_cache = 0 ;
if ( lcid_cache = = 0 )
{
lcid_cache = ( UINT ) GetUserDefaultLCID ( ) ;
}
return lcid_cache ;
}
// Set a secure ACL to the specified file or directory
bool MsSetFileSecureAcl ( wchar_t * path )
{
SID * sid_system ;
SID * sid_admin ;
bool ret = false ;
// Validate arguments
if ( path = = NULL )
{
return false ;
}
sid_system = MsGetSidFromAccountName ( " SYSTEM " ) ;
sid_admin = MsGetSidFromAccountName ( " Administrators " ) ;
if ( sid_system ! = NULL & & sid_admin ! = NULL )
{
UINT acl_size = 4096 ;
ACL * acl ;
acl = ZeroMalloc ( acl_size ) ;
if ( InitializeAcl ( acl , acl_size , 2 ) )
{
2021-04-03 03:25:19 +03:00
if ( AddAccessAllowedAceEx ( acl , 2 , CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE , GENERIC_ALL , sid_system ) & &
AddAccessAllowedAceEx ( acl , 2 , CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE , GENERIC_ALL , sid_admin ) )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
if ( SetNamedSecurityInfoW ( path , SE_FILE_OBJECT , DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION , NULL , NULL , acl , NULL ) = = ERROR_SUCCESS )
2014-01-04 17:00:08 +04:00
{
ret = true ;
}
}
}
Free ( acl ) ;
}
MsFreeSid ( sid_system ) ;
MsFreeSid ( sid_admin ) ;
return ret ;
}
// Disable the minimization function of the number of network connections by WCM
void MsDisableWcmNetworkMinimize ( )
{
MS_WCM_POLICY_VALUE v ;
bool b ;
2021-04-03 03:25:19 +03:00
if ( MsIsWindows8 ( ) = = false )
2014-01-04 17:00:08 +04:00
{
return ;
}
2021-04-03 03:25:19 +03:00
HMODULE hWcmapi = LoadLibrary ( " wcmapi.dll " ) ;
if ( ! hWcmapi )
2014-01-04 17:00:08 +04:00
{
return ;
}
2021-04-03 03:25:19 +03:00
typedef DWORD ( WINAPI * PWCMSETPROPERTY ) ( const GUID * , LPCWSTR , MS_WCM_PROPERTY , PVOID , DWORD , const BYTE * ) ;
PWCMSETPROPERTY WcmSetProperty = ( PWCMSETPROPERTY ) GetProcAddress ( hWcmapi , " WcmSetProperty " ) ;
2014-01-04 17:00:08 +04:00
Zero ( & v , sizeof ( v ) ) ;
v . fIsGroupPolicy = true ;
v . fValue = false ;
b = false ;
2021-04-03 03:25:19 +03:00
WcmSetProperty ( NULL , NULL , ms_wcm_global_property_minimize_policy , NULL , sizeof ( v ) , ( const BYTE * ) & v ) ;
WcmSetProperty ( NULL , NULL , ms_wcm_global_property_minimize_policy , NULL , sizeof ( b ) , ( const BYTE * ) & b ) ;
2014-01-04 17:00:08 +04:00
Zero ( & v , sizeof ( v ) ) ;
v . fIsGroupPolicy = true ;
v . fValue = false ;
b = false ;
2021-04-03 03:25:19 +03:00
WcmSetProperty ( NULL , NULL , ms_wcm_global_property_domain_policy , NULL , sizeof ( v ) , ( const BYTE * ) & v ) ;
WcmSetProperty ( NULL , NULL , ms_wcm_global_property_domain_policy , NULL , sizeof ( b ) , ( const BYTE * ) & b ) ;
2014-01-04 17:00:08 +04:00
Zero ( & v , sizeof ( v ) ) ;
v . fIsGroupPolicy = false ;
v . fValue = false ;
2021-04-03 03:25:19 +03:00
WcmSetProperty ( NULL , NULL , ms_wcm_global_property_minimize_policy , NULL , sizeof ( v ) , ( const BYTE * ) & v ) ;
WcmSetProperty ( NULL , NULL , ms_wcm_global_property_minimize_policy , NULL , sizeof ( b ) , ( const BYTE * ) & b ) ;
2014-01-04 17:00:08 +04:00
Zero ( & v , sizeof ( v ) ) ;
v . fIsGroupPolicy = false ;
v . fValue = false ;
2021-04-03 03:25:19 +03:00
WcmSetProperty ( NULL , NULL , ms_wcm_global_property_domain_policy , NULL , sizeof ( v ) , ( const BYTE * ) & v ) ;
WcmSetProperty ( NULL , NULL , ms_wcm_global_property_domain_policy , NULL , sizeof ( b ) , ( const BYTE * ) & b ) ;
FreeLibrary ( hWcmapi ) ;
2014-01-04 17:00:08 +04:00
}
// Request the MS-CHAPv2 authentication to the LSA
bool MsPerformMsChapV2AuthByLsa ( char * username , UCHAR * challenge8 , UCHAR * client_response_24 , UCHAR * ret_pw_hash_hash )
{
bool ret = false ;
char user [ MAX_SIZE ] ;
char domain [ MAX_SIZE ] ;
wchar_t workstation [ MAX_SIZE + 1 ] ;
LSA_STRING origin ;
MSV1_0_LM20_LOGON * m ;
MS_MSCHAPV2_PARAMS * p ;
UINT m_size ;
DWORD sz ;
void * profile_buffer = NULL ;
LUID logon_id ;
2021-03-01 03:46:11 +03:00
ULONG profile_buffer_size = 0 ;
2014-01-04 17:00:08 +04:00
UINT i ;
HANDLE hLogon = NULL ;
QUOTA_LIMITS q ;
char * origin_str = " SE-VPN " ;
NTSTATUS sub_status = 0 ;
// Validate arguments
if ( username = = NULL | | challenge8 = = NULL | | client_response_24 = = NULL | | ret_pw_hash_hash = = NULL )
{
return false ;
}
if ( hLsa = = NULL )
{
return false ;
}
ParseNtUsername ( username , user , sizeof ( user ) , domain , sizeof ( domain ) , false ) ;
// Get the machine name
Zero ( workstation , sizeof ( workstation ) ) ;
sz = MAX_SIZE ;
GetComputerNameW ( workstation , & sz ) ;
// Build a MSV1_0_INTERACTIVE_LOGON
m_size = sizeof ( MSV1_0_LM20_LOGON ) + sizeof ( MS_MSCHAPV2_PARAMS ) ;
m = ZeroMalloc ( m_size ) ;
p = ( MS_MSCHAPV2_PARAMS * ) ( ( ( UCHAR * ) m ) + sizeof ( MSV1_0_LM20_LOGON ) ) ;
StrToUni ( p - > Username , sizeof ( p - > Username ) , user ) ;
StrToUni ( p - > Domain , sizeof ( p - > Domain ) , domain ) ;
UniStrCpy ( p - > Workstation , sizeof ( p - > Workstation ) , workstation ) ;
Copy ( p - > ClientResponse24 , client_response_24 , 24 ) ;
m - > MessageType = MsV1_0Lm20Logon ;
// User name
m - > UserName . Length = m - > UserName . MaximumLength = ( USHORT ) ( UniStrLen ( p - > Username ) * sizeof ( wchar_t ) ) ;
m - > UserName . Buffer = p - > Username ;
// Workstation name
m - > Workstation . Length = m - > Workstation . MaximumLength = ( USHORT ) ( UniStrLen ( p - > Workstation ) * sizeof ( wchar_t ) ) ;
m - > Workstation . Buffer = p - > Workstation ;
// Domain name
if ( IsEmptyUniStr ( p - > Domain ) = = false )
{
m - > LogonDomainName . Length = m - > LogonDomainName . MaximumLength = ( USHORT ) ( UniStrLen ( p - > Domain ) * sizeof ( wchar_t ) ) ;
m - > LogonDomainName . Buffer = p - > Domain ;
}
// Challenge
Copy ( m - > ChallengeToClient , challenge8 , 8 ) ;
// Response
m - > CaseInsensitiveChallengeResponse . Length = m - > CaseInsensitiveChallengeResponse . MaximumLength = 24 ;
m - > CaseInsensitiveChallengeResponse . Buffer = p - > ClientResponse24 ;
m - > CaseSensitiveChallengeResponse . Length = m - > CaseSensitiveChallengeResponse . MaximumLength = sizeof ( p - > ResponseBuffer ) ;
m - > CaseSensitiveChallengeResponse . Buffer = p - > ResponseBuffer ;
m - > ParameterControl = MSV1_0_ALLOW_MSVCHAPV2 ;
Zero ( & origin , sizeof ( origin ) ) ;
origin . Length = origin . MaximumLength = StrLen ( origin_str ) ;
origin . Buffer = origin_str ;
Zero ( & logon_id , sizeof ( logon_id ) ) ;
Zero ( & q , sizeof ( q ) ) ;
2021-04-03 03:25:19 +03:00
i = LsaLogonUser ( hLsa , & origin , Network , lsa_package_id , m , m_size , NULL , & lsa_token_source ,
2014-01-04 17:00:08 +04:00
& profile_buffer , & profile_buffer_size , & logon_id , & hLogon , & q , & sub_status ) ;
if ( i = = 0 )
{
if ( profile_buffer ! = NULL )
{
MSV1_0_LM20_LOGON_PROFILE * response = ( MSV1_0_LM20_LOGON_PROFILE * ) profile_buffer ;
Copy ( ret_pw_hash_hash , response - > UserSessionKey , 16 ) ;
ret = true ;
2021-04-03 03:25:19 +03:00
LsaFreeReturnBuffer ( profile_buffer ) ;
2014-01-04 17:00:08 +04:00
}
CloseHandle ( hLogon ) ;
}
Free ( m ) ;
return ret ;
}
// Send a pulse
void MsSendGlobalPulse ( void * p )
{
HANDLE h ;
// Validate arguments
if ( p = = NULL )
{
return ;
}
h = ( HANDLE ) p ;
PulseEvent ( h ) ;
}
// Release a pulse
void MsCloseGlobalPulse ( void * p )
{
HANDLE h ;
// Validate arguments
if ( p = = NULL )
{
return ;
}
h = ( HANDLE ) p ;
CloseHandle ( h ) ;
}
// Wait for arriving the pulse
bool MsWaitForGlobalPulse ( void * p , UINT timeout )
{
HANDLE h ;
UINT ret ;
// Validate arguments
if ( p = = NULL )
{
return false ;
}
if ( timeout = = TIMEOUT_INFINITE )
{
timeout = INFINITE ;
}
h = ( HANDLE ) p ;
ret = WaitForSingleObject ( h , timeout ) ;
if ( ret = = WAIT_OBJECT_0 )
{
return true ;
}
return false ;
}
// Open or create a pulse
void * MsOpenOrCreateGlobalPulse ( char * name )
{
UCHAR hash [ 20 ] ;
char tmp [ MAX_SIZE ] ;
char tmp2 [ MAX_SIZE ] ;
HANDLE h ;
// Validate arguments
if ( name = = NULL )
{
return NULL ;
}
StrCpy ( tmp , sizeof ( tmp ) , name ) ;
Trim ( tmp ) ;
StrUpper ( tmp ) ;
2018-09-22 07:35:30 +03:00
Sha1 ( hash , name , StrLen ( name ) ) ;
2014-01-04 17:00:08 +04:00
BinToStr ( tmp , sizeof ( tmp ) , hash , sizeof ( hash ) ) ;
2021-04-03 03:25:19 +03:00
Format ( tmp2 , sizeof ( tmp2 ) , " Global \\ GlobalPulse_%s " , tmp ) ;
2014-01-04 17:00:08 +04:00
h = CreateEvent ( NULL , true , false , tmp2 ) ;
return ( void * ) h ;
}
// Stop the IPsec service
bool MsStopIPsecService ( )
{
if ( MsIsServiceRunning ( MsGetIPsecServiceName ( ) ) )
{
Debug ( " Stopping Windows Service: %s \n " , MsGetIPsecServiceName ( ) ) ;
if ( MsStopService ( MsGetIPsecServiceName ( ) ) )
{
return true ;
}
}
return false ;
}
// Start the IPsec service
bool MsStartIPsecService ( )
{
if ( MsIsServiceRunning ( MsGetIPsecServiceName ( ) ) = = false )
{
Debug ( " Starting Windows Service: %s \n " , MsGetIPsecServiceName ( ) ) ;
return MsStartService ( MsGetIPsecServiceName ( ) ) ;
}
return false ;
}
// Get the IPsec service name
char * MsGetIPsecServiceName ( )
{
2021-04-03 03:25:19 +03:00
return " ikeext " ;
2014-01-04 17:00:08 +04:00
}
// Initialize the global lock
void * MsInitGlobalLock ( char * name , bool ts_local )
{
char tmp [ MAX_SIZE ] ;
HANDLE h ;
// Validate arguments
if ( name = = NULL )
{
name = " default_global_lock " ;
}
if ( ts_local )
{
HashInstanceNameLocal ( tmp , sizeof ( tmp ) , name ) ;
}
else
{
HashInstanceName ( tmp , sizeof ( tmp ) , name ) ;
}
h = CreateMutexA ( NULL , false , tmp ) ;
if ( h = = NULL | | h = = INVALID_HANDLE_VALUE )
{
return NULL ;
}
return ( void * ) h ;
}
// Get a global lock
void MsGlobalLock ( void * p )
{
HANDLE h = ( HANDLE ) p ;
// Validate arguments
if ( h = = NULL )
{
return ;
}
WaitForSingleObject ( p , INFINITE ) ;
}
// Unlock the global lock
void MsGlobalUnlock ( void * p )
{
HANDLE h = ( HANDLE ) p ;
// Validate arguments
if ( h = = NULL )
{
return ;
}
ReleaseMutex ( h ) ;
}
// Release the global lock
void MsFreeGlobalLock ( void * p )
{
HANDLE h = ( HANDLE ) p ;
// Validate arguments
if ( h = = NULL )
{
return ;
}
CloseHandle ( h ) ;
}
// Set the mode not to show the errors
void MsSetErrorModeToSilent ( )
{
SetErrorMode ( SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX ) ;
}
// Get the file information
bool MsGetFileInformation ( void * h , void * info )
{
// Validate arguments
if ( h = = INVALID_HANDLE_VALUE | | info = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
return GetFileInformationByHandle ( h , info ) ;
2014-01-04 17:00:08 +04:00
}
// Set the shutdown parameters of the process
void MsSetShutdownParameters ( UINT level , UINT flag )
{
2021-04-03 03:25:19 +03:00
SetProcessShutdownParameters ( level , flag ) ;
2014-01-04 17:00:08 +04:00
}
// Restart of MMCSS
void MsRestartMMCSS ( )
{
MsStopService ( " CTAudSvcService " ) ;
MsStopService ( " audiosrv " ) ;
MsStopService ( " MMCSS " ) ;
MsStartService ( " MMCSS " ) ;
MsStartService ( " audiosrv " ) ;
MsStartService ( " CTAudSvcService " ) ;
}
// Enable / disable network throttling by MMCSS
void MsSetMMCSSNetworkThrottlingEnable ( bool enable )
{
UINT value ;
if ( enable )
{
value = 0x0000000a ;
}
else
{
value = 0xffffffff ;
}
MsRegWriteIntEx2 ( REG_LOCAL_MACHINE , MMCSS_PROFILE_KEYNAME , " NetworkThrottlingIndex " ,
value ,
false , true ) ;
MsRestartMMCSS ( ) ;
}
// Examine whether the Network throttling by MMCSS is enabled
bool MsIsMMCSSNetworkThrottlingEnabled ( )
{
UINT value ;
if ( MsRegIsKeyEx2 ( REG_LOCAL_MACHINE , MMCSS_PROFILE_KEYNAME , false , true ) = = false )
{
return false ;
}
value = MsRegReadIntEx2 ( REG_LOCAL_MACHINE , MMCSS_PROFILE_KEYNAME ,
" NetworkThrottlingIndex " , false , true ) ;
if ( value = = 0 )
{
return false ;
}
if ( value = = 0x0000000a )
{
return true ;
}
return false ;
}
2018-05-30 00:20:47 +03:00
typedef struct _ASTAT_
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
ADAPTER_STATUS adapt ;
NAME_BUFFER NameBuff [ 30 ] ;
} ASTAT , * PASTAT ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
// Get the precise time from the value of the high-resolution counter
double MsGetHiResTimeSpan ( UINT64 diff )
{
LARGE_INTEGER t ;
UINT64 freq ;
if ( QueryPerformanceFrequency ( & t ) = = false )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
freq = 1000ULL ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
else
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
Copy ( & freq , & t , sizeof ( UINT64 ) ) ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
return ( double ) diff / ( double ) freq ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
UINT64 MsGetHiResTimeSpanUSec ( UINT64 diff )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
LARGE_INTEGER t ;
UINT64 freq ;
if ( QueryPerformanceFrequency ( & t ) = = false )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
freq = 1000ULL ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
else
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
Copy ( & freq , & t , sizeof ( UINT64 ) ) ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
return ( UINT64 ) ( diff ) * 1000ULL * 1000ULL / ( UINT64 ) freq ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
// Get a high-resolution counter
UINT64 MsGetHiResCounter ( )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
LARGE_INTEGER t ;
UINT64 ret ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
if ( QueryPerformanceCounter ( & t ) = = false )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
return Tick64 ( ) ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
Copy ( & ret , & t , sizeof ( UINT64 ) ) ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
return ret ;
}
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
// System-wide updating notification
void MsUpdateSystem ( )
{
static DWORD dw = 0 ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
SendMessageTimeoutA ( HWND_BROADCAST , WM_WININICHANGE , 0 , 0 , SMTO_NORMAL , 1 , ( PDWORD_PTR ) & dw ) ;
SleepThread ( 25 ) ;
SendMessageTimeoutA ( HWND_BROADCAST , WM_SETTINGCHANGE , 0 , ( LPARAM ) " Environment " , SMTO_NORMAL , 1 , ( PDWORD_PTR ) & dw ) ;
SleepThread ( 25 ) ;
SHChangeNotify ( SHCNE_GLOBALEVENTS , SHCNF_IDLIST | SHCNF_FLUSHNOWAIT | SHCNF_NOTIFYRECURSIVE , NULL , NULL ) ;
SleepThread ( 25 ) ;
SHChangeNotify ( SHCNE_GLOBALEVENTS , SHCNF_IDLIST , NULL , NULL ) ;
SleepThread ( 25 ) ;
SHChangeNotify ( SHCNE_ASSOCCHANGED , SHCNF_IDLIST | SHCNF_FLUSHNOWAIT | SHCNF_NOTIFYRECURSIVE , NULL , NULL ) ;
SleepThread ( 25 ) ;
SHChangeNotify ( SHCNE_ASSOCCHANGED , SHCNF_IDLIST , NULL , NULL ) ;
SleepThread ( 25 ) ;
SHChangeNotify ( SHCNE_ALLEVENTS , SHCNF_IDLIST | SHCNF_FLUSHNOWAIT | SHCNF_NOTIFYRECURSIVE , NULL , NULL ) ;
SleepThread ( 25 ) ;
SHChangeNotify ( SHCNE_ALLEVENTS , SHCNF_IDLIST , NULL , NULL ) ;
SleepThread ( 25 ) ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
// Wait for the process termination
UINT MsWaitProcessExit ( void * process_handle )
2014-03-26 07:38:30 +04:00
{
2018-05-30 00:20:47 +03:00
HANDLE h = ( HANDLE ) process_handle ;
2021-03-01 03:46:11 +03:00
DWORD ret = 1 ;
2018-05-30 00:20:47 +03:00
if ( h = = NULL )
2014-03-26 07:38:30 +04:00
{
2018-05-30 00:20:47 +03:00
return 1 ;
2014-03-26 07:38:30 +04:00
}
2018-05-30 00:20:47 +03:00
while ( true )
2014-03-26 07:38:30 +04:00
{
2018-05-30 00:20:47 +03:00
WaitForSingleObject ( h , INFINITE ) ;
2014-03-26 07:38:30 +04:00
2018-05-30 00:20:47 +03:00
ret = 1 ;
if ( GetExitCodeProcess ( h , & ret ) = = false )
2014-03-26 07:38:30 +04:00
{
2018-05-30 00:20:47 +03:00
break ;
}
2014-03-26 07:38:30 +04:00
2018-05-30 00:20:47 +03:00
if ( ret ! = STILL_ACTIVE )
{
2014-03-26 07:38:30 +04:00
break ;
}
}
2018-05-30 00:20:47 +03:00
CloseHandle ( h ) ;
2014-03-26 07:38:30 +04:00
return ret ;
}
2018-05-30 00:20:47 +03:00
// Execution of the file (to get process handle)
bool MsExecuteEx ( char * exe , char * arg , void * * process_handle )
2014-03-26 07:38:30 +04:00
{
2018-05-30 00:20:47 +03:00
return MsExecuteEx2 ( exe , arg , process_handle , false ) ;
2014-03-26 07:38:30 +04:00
}
2018-05-30 00:20:47 +03:00
bool MsExecuteEx2 ( char * exe , char * arg , void * * process_handle , bool runas )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
SHELLEXECUTEINFO info ;
HANDLE h ;
2014-01-04 17:00:08 +04:00
// Validate arguments
2018-05-30 00:20:47 +03:00
if ( exe = = NULL | | process_handle = = NULL )
2014-01-04 17:00:08 +04:00
{
return false ;
}
2018-05-30 00:20:47 +03:00
Zero ( & info , sizeof ( info ) ) ;
info . cbSize = sizeof ( info ) ;
info . lpVerb = ( runas ? " runas " : " open " ) ;
info . lpFile = exe ;
info . fMask = SEE_MASK_NOCLOSEPROCESS ;
info . lpParameters = arg ;
info . nShow = SW_SHOWNORMAL ;
if ( ShellExecuteEx ( & info ) = = false )
2014-01-04 17:00:08 +04:00
{
return false ;
}
2018-05-30 00:20:47 +03:00
h = info . hProcess ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
* process_handle = ( void * ) h ;
return true ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
bool MsExecuteEx2W ( wchar_t * exe , wchar_t * arg , void * * process_handle , bool runas )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
SHELLEXECUTEINFOW info ;
HANDLE h ;
2014-01-04 17:00:08 +04:00
// Validate arguments
2018-05-30 00:20:47 +03:00
if ( exe = = NULL | | process_handle = = NULL )
2014-01-04 17:00:08 +04:00
{
return false ;
}
if ( IsNt ( ) = = false )
{
2018-05-30 00:20:47 +03:00
char exe_a [ MAX_SIZE ] ;
char arg_a [ MAX_SIZE ] ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
UniToStr ( exe_a , sizeof ( exe_a ) , exe ) ;
UniToStr ( arg_a , sizeof ( arg_a ) , arg ) ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
return MsExecuteEx ( exe_a , arg_a , process_handle ) ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
Zero ( & info , sizeof ( info ) ) ;
info . cbSize = sizeof ( info ) ;
info . lpVerb = ( runas ? L " runas " : L " open " ) ;
info . lpFile = exe ;
info . fMask = SEE_MASK_NOCLOSEPROCESS ;
info . lpParameters = arg ;
info . nShow = SW_SHOWNORMAL ;
if ( ShellExecuteExW ( & info ) = = false )
2014-01-04 17:00:08 +04:00
{
return false ;
}
2018-05-30 00:20:47 +03:00
h = info . hProcess ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
* process_handle = ( void * ) h ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
return true ;
}
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
// Close the handle
void MsCloseHandle ( void * handle )
{
if ( handle ! = NULL )
{
CloseHandle ( handle ) ;
2014-01-04 17:00:08 +04:00
}
}
2018-05-30 00:20:47 +03:00
// Execution of the file
bool MsExecute ( char * exe , char * arg )
{
return MsExecute2 ( exe , arg , false ) ;
}
bool MsExecute2 ( char * exe , char * arg , bool runas )
2014-01-04 17:00:08 +04:00
{
DWORD d ;
// Validate arguments
2018-05-30 00:20:47 +03:00
if ( exe = = NULL )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
return false ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
d = ( DWORD ) ShellExecuteA ( NULL , ( runas ? " runas " : " open " ) , exe , arg , MsGetExeDirName ( ) , SW_SHOWNORMAL ) ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
if ( d > 32 )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
return true ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
return false ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
bool MsExecuteW ( wchar_t * exe , wchar_t * arg )
{
return MsExecute2W ( exe , arg , false ) ;
}
bool MsExecute2W ( wchar_t * exe , wchar_t * arg , bool runas )
2014-01-04 17:00:08 +04:00
{
DWORD d ;
// Validate arguments
2018-05-30 00:20:47 +03:00
if ( exe = = NULL )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
return false ;
2014-01-04 17:00:08 +04:00
}
if ( IsNt ( ) = = false )
{
2018-05-30 00:20:47 +03:00
char exe_a [ MAX_SIZE ] ;
char arg_a [ MAX_SIZE ] ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
UniToStr ( exe_a , sizeof ( exe_a ) , exe ) ;
UniToStr ( arg_a , sizeof ( arg_a ) , arg ) ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
return MsExecute ( exe_a , arg_a ) ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
d = ( DWORD ) ShellExecuteW ( NULL , ( runas ? L " runas " : L " open " ) , exe , arg , MsGetExeDirNameW ( ) , SW_SHOWNORMAL ) ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
if ( d > 32 )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
return true ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
return false ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
// Recursive directory creation
void MsUniMakeDirEx ( wchar_t * name )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
UINT wp ;
wchar_t * tmp ;
UINT i , len ;
2014-01-04 17:00:08 +04:00
// Validate arguments
2018-05-30 00:20:47 +03:00
if ( name = = NULL )
2014-01-04 17:00:08 +04:00
{
return ;
}
2018-05-30 00:20:47 +03:00
tmp = ZeroMalloc ( UniStrSize ( name ) * 2 ) ;
wp = 0 ;
len = UniStrLen ( name ) ;
for ( i = 0 ; i < len ; i + + )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
wchar_t c = name [ i ] ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
if ( c = = ' \\ ' )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
if ( UniStrCmpi ( tmp , L " \\ \\ " ) ! = 0 & & UniStrCmpi ( tmp , L " \\ " ) ! = 0 )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
MsUniMakeDir ( tmp ) ;
2014-01-04 17:00:08 +04:00
}
}
2018-05-30 00:20:47 +03:00
tmp [ wp + + ] = c ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
Free ( tmp ) ;
2014-01-04 17:00:08 +04:00
2018-05-30 00:20:47 +03:00
MsUniMakeDir ( name ) ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
// Create a directory
bool MsUniMakeDir ( wchar_t * name )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
// Validate arguments
if ( name = = NULL )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
return false ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
return CreateDirectoryW ( name , NULL ) ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
bool MsMakeDir ( char * name )
2014-01-04 17:00:08 +04:00
{
// Validate arguments
2018-05-30 00:20:47 +03:00
if ( name = = NULL )
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
return false ;
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
return CreateDirectoryA ( name , NULL ) ;
2014-01-04 17:00:08 +04:00
}
static wchar_t ms_computer_name_full_cache [ MAX_SIZE ] = { 0 } ;
// Get the full name of the computer
void MsGetComputerNameFullEx ( wchar_t * name , UINT size , bool with_cache )
{
2021-03-01 03:46:11 +03:00
DWORD size2 = size ;
2014-01-04 17:00:08 +04:00
// Validate arguments
UniStrCpy ( name , size , L " " ) ;
if ( name = = NULL | | size = = 0 )
{
return ;
}
if ( with_cache )
{
if ( UniIsEmptyStr ( ms_computer_name_full_cache ) = = false )
{
UniStrCpy ( name , size , ms_computer_name_full_cache ) ;
return ;
}
}
2021-04-03 03:25:19 +03:00
if ( GetComputerNameExW ( ComputerNameDnsFullyQualified , name , & size2 ) = = false )
2014-01-04 17:00:08 +04:00
{
char tmp [ MAX_SIZE ] ;
MsGetComputerName ( tmp , sizeof ( tmp ) ) ;
StrToUni ( name , size , tmp ) ;
}
if ( with_cache )
{
UniStrCpy ( ms_computer_name_full_cache , sizeof ( ms_computer_name_full_cache ) , name ) ;
}
}
// Get the computer name
void MsGetComputerName ( char * name , UINT size )
{
DWORD sz ;
// Validate arguments
if ( name = = NULL )
{
return ;
}
sz = size ;
GetComputerName ( name , & sz ) ;
}
// Get the hash value of the position of the mouse cursor
UINT MsGetCursorPosHash ( )
{
POINT p ;
Zero ( & p , sizeof ( p ) ) ;
if ( GetCursorPos ( & p ) = = false )
{
return 0 ;
}
return MAKELONG ( ( USHORT ) p . x , ( USHORT ) p . y ) ;
}
// Start the process as a standard user privileges
void * MsRunAsUserExW ( wchar_t * filename , wchar_t * arg , bool hide )
{
void * ret = MsRunAsUserExInnerW ( filename , arg , hide ) ;
if ( ret = = NULL )
{
Debug ( " MsRunAsUserExInner Failed. \n " ) ;
ret = Win32RunExW ( filename , arg , hide ) ;
}
return ret ;
}
void * MsRunAsUserExInnerW ( wchar_t * filename , wchar_t * arg , bool hide )
{
STARTUPINFOW info ;
PROCESS_INFORMATION ret ;
wchar_t cmdline [ MAX_SIZE ] ;
wchar_t name [ MAX_PATH ] ;
HANDLE hToken ;
// Validate arguments
if ( filename = = NULL )
{
return NULL ;
}
UniStrCpy ( name , sizeof ( name ) , filename ) ;
UniTrim ( name ) ;
if ( UniSearchStr ( name , L " \" " , 0 ) = = INFINITE )
{
if ( arg = = NULL )
{
UniFormat ( cmdline , sizeof ( cmdline ) , L " %s " , name ) ;
}
else
{
UniFormat ( cmdline , sizeof ( cmdline ) , L " %s %s " , name , arg ) ;
}
}
else
{
if ( arg = = NULL )
{
UniFormat ( cmdline , sizeof ( cmdline ) , L " \" %s \" " , name ) ;
}
else
{
UniFormat ( cmdline , sizeof ( cmdline ) , L " \" %s \" %s " , name , arg ) ;
}
}
Zero ( & info , sizeof ( info ) ) ;
Zero ( & ret , sizeof ( ret ) ) ;
info . cb = sizeof ( info ) ;
info . dwFlags = STARTF_USESHOWWINDOW ;
info . wShowWindow = ( hide = = false ? SW_SHOWDEFAULT : SW_HIDE ) ;
UniTrim ( cmdline ) ;
hToken = MsCreateUserToken ( ) ;
if ( hToken = = NULL )
{
return NULL ;
}
2021-04-03 03:25:19 +03:00
if ( CreateProcessAsUserW ( hToken , NULL , cmdline , NULL , NULL , FALSE ,
2014-01-04 17:00:08 +04:00
( hide = = false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE ) | NORMAL_PRIORITY_CLASS ,
NULL , NULL , & info , & ret ) = = FALSE )
{
return NULL ;
}
CloseHandle ( hToken ) ;
CloseHandle ( ret . hThread ) ;
return ret . hProcess ;
}
// Get the SID from the account name
SID * MsGetSidFromAccountName ( char * name )
{
SID * sid ;
2021-03-01 03:46:11 +03:00
DWORD sid_size = 4096 ;
2014-01-04 17:00:08 +04:00
char * domain_name ;
2021-03-01 03:46:11 +03:00
DWORD domain_name_size = 4096 ;
2014-01-04 17:00:08 +04:00
SID_NAME_USE use = SidTypeUser ;
// Validate arguments
if ( name = = NULL )
{
return NULL ;
}
sid = ZeroMalloc ( sid_size ) ;
domain_name = ZeroMalloc ( domain_name_size ) ;
2021-04-03 03:25:19 +03:00
if ( LookupAccountNameA ( NULL , name , sid , & sid_size , domain_name , & domain_name_size , & use ) = = false )
2014-01-04 17:00:08 +04:00
{
Free ( sid ) ;
Free ( domain_name ) ;
return NULL ;
}
Free ( domain_name ) ;
return sid ;
}
// Release the SID
void MsFreeSid ( SID * sid )
{
// Validate arguments
if ( sid = = NULL )
{
return ;
}
Free ( sid ) ;
}
// Create a token of standard user
HANDLE MsCreateUserToken ( )
{
2021-03-01 03:46:11 +03:00
const char * medium_sid = " S-1-16-8192 " ;
PSID sid = NULL ;
2014-01-04 17:00:08 +04:00
TOKEN_MANDATORY_LABEL til ;
HANDLE hCurrentToken , hNewToken ;
Zero ( & til , sizeof ( til ) ) ;
2021-04-03 03:25:19 +03:00
if ( ConvertStringSidToSidA ( medium_sid , & sid ) = = false )
2014-01-04 17:00:08 +04:00
{
return NULL ;
}
til . Label . Attributes = SE_GROUP_INTEGRITY ;
til . Label . Sid = sid ;
2021-04-03 03:25:19 +03:00
if ( OpenProcessToken ( GetCurrentProcess ( ) , MAXIMUM_ALLOWED , & hCurrentToken ) = = false )
2014-01-04 17:00:08 +04:00
{
LocalFree ( sid ) ;
return NULL ;
}
2021-04-03 03:25:19 +03:00
if ( DuplicateTokenEx ( hCurrentToken , MAXIMUM_ALLOWED , NULL ,
2014-01-04 17:00:08 +04:00
SecurityImpersonation , TokenPrimary , & hNewToken ) = = false )
{
CloseHandle ( hCurrentToken ) ;
LocalFree ( sid ) ;
return NULL ;
}
2021-04-05 05:48:25 +03:00
if ( SetTokenInformation ( hNewToken , TokenIntegrityLevel , & til ,
2014-01-04 17:00:08 +04:00
sizeof ( TOKEN_MANDATORY_LABEL ) + GetLengthSid ( sid ) ) = = false )
{
CloseHandle ( hNewToken ) ;
CloseHandle ( hCurrentToken ) ;
LocalFree ( sid ) ;
return NULL ;
}
CloseHandle ( hCurrentToken ) ;
LocalFree ( sid ) ;
return hNewToken ;
}
2019-06-29 19:20:52 +03:00
// Check whether SHA-2 kernel mode signature is supported
bool MsIsSha2KernelModeSignatureSupported ( )
{
HINSTANCE hDll ;
bool ret = false ;
if ( MsIsWindows8 ( ) )
{
return true ;
}
hDll = LoadLibrary ( " Wintrust.dll " ) ;
if ( hDll = = NULL )
{
return false ;
}
if ( GetProcAddress ( hDll , " CryptCATAdminAcquireContext2 " ) ! = NULL )
{
ret = true ;
}
FreeLibrary ( hDll ) ;
return ret ;
}
// Check whether KB3033929 is required
bool MsIsKB3033929RequiredAndMissing ( )
{
OS_INFO * info = GetOsInfo ( ) ;
if ( info = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
if ( GET_KETA ( info - > OsType , 100 ) = = 6 )
2019-06-29 19:20:52 +03:00
{
2021-04-03 03:25:19 +03:00
if ( MsIsX64 ( ) )
2019-06-29 19:20:52 +03:00
{
2021-04-03 03:25:19 +03:00
if ( MsIsSha2KernelModeSignatureSupported ( ) = = false )
2019-06-29 19:20:52 +03:00
{
2021-04-03 03:25:19 +03:00
return true ;
2019-06-29 19:20:52 +03:00
}
}
}
return false ;
}
2014-01-04 17:00:08 +04:00
// Check the digital signature of the file
bool MsCheckFileDigitalSignatureW ( HWND hWnd , wchar_t * name , bool * danger )
{
HRESULT ret = S_OK ;
wchar_t * tmp ;
LONG ( WINAPI * _WinVerifyTrust ) ( HWND , GUID * , LPVOID ) = NULL ;
HINSTANCE hDll ;
// Validate arguments
if ( name = = NULL )
{
return false ;
}
if ( danger ! = NULL )
{
* danger = false ;
}
tmp = name ;
hDll = LoadLibrary ( " Wintrust.dll " ) ;
if ( hDll = = NULL )
{
return false ;
}
_WinVerifyTrust =
( LONG ( __stdcall * ) ( HWND , GUID * , LPVOID ) )
GetProcAddress ( hDll , " WinVerifyTrust " ) ;
if ( _WinVerifyTrust = = NULL )
{
FreeLibrary ( hDll ) ;
return false ;
}
else
{
GUID action_id = WINTRUST_ACTION_GENERIC_VERIFY_V2 ;
WINTRUST_FILE_INFO file ;
WINTRUST_DATA data ;
Zero ( & file , sizeof ( file ) ) ;
file . cbStruct = sizeof ( file ) ;
file . pcwszFilePath = tmp ;
Zero ( & data , sizeof ( data ) ) ;
data . cbStruct = sizeof ( data ) ;
data . fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN ;
data . dwUIChoice = ( hWnd ! = NULL ? WTD_UI_NOGOOD : WTD_UI_NONE ) ;
data . dwProvFlags = WTD_REVOCATION_CHECK_CHAIN ;
data . dwUnionChoice = WTD_CHOICE_FILE ;
data . pFile = & file ;
ret = _WinVerifyTrust ( hWnd , & action_id , & data ) ;
if ( ret = = ERROR_SUCCESS & & danger ! = NULL )
{
if ( hWnd ! = NULL )
{
if ( MsCheckFileDigitalSignatureW ( NULL , name , NULL ) = = false )
{
// It's a dangerous file, but the user had to select the [OK]
* danger = true ;
}
}
}
}
FreeLibrary ( hDll ) ;
if ( ret ! = ERROR_SUCCESS )
{
return false ;
}
return true ;
}
// Disable the WoW64 redirection
void * MsDisableWow64FileSystemRedirection ( )
{
void * p = NULL ;
if ( MsIs64BitWindows ( ) = = false )
{
return NULL ;
}
2021-04-03 03:25:19 +03:00
if ( Wow64DisableWow64FsRedirection ( & p ) = = false )
2014-01-04 17:00:08 +04:00
{
return NULL ;
}
if ( p = = NULL )
{
p = ( void * ) 0x12345678 ;
}
return p ;
}
// Restore the WoW64 redirection
void MsRestoreWow64FileSystemRedirection ( void * p )
{
// Validate arguments
if ( p = = NULL )
{
return ;
}
if ( p = = ( void * ) 0x12345678 )
{
p = NULL ;
}
if ( MsIs64BitWindows ( ) = = false )
{
return ;
}
2021-04-03 03:25:19 +03:00
Wow64RevertWow64FsRedirection ( p ) ;
2014-01-04 17:00:08 +04:00
}
// Get whether the x64 version of Windows is currently running
bool MsIsX64 ( )
{
SYSTEM_INFO info ;
if ( MsIs64BitWindows ( ) = = false )
{
return false ;
}
Zero ( & info , sizeof ( info ) ) ;
2021-04-03 03:25:19 +03:00
GetNativeSystemInfo ( & info ) ;
2014-01-04 17:00:08 +04:00
if ( info . wProcessorArchitecture = = PROCESSOR_ARCHITECTURE_AMD64 )
{
return true ;
}
return false ;
}
// Get whether the IA64 version of Windows is currently running
bool MsIsIA64 ( )
{
if ( MsIs64BitWindows ( ) = = false )
{
return false ;
}
if ( MsIsX64 ( ) )
{
return false ;
}
return true ;
}
// Acquisition whether it's a 64bit Windows
bool MsIs64BitWindows ( )
{
if ( Is64 ( ) )
{
return true ;
}
2021-04-03 03:25:19 +03:00
BOOL b = false ;
if ( IsWow64Process ( GetCurrentProcess ( ) , & b ) = = false )
{
return false ;
2014-01-04 17:00:08 +04:00
}
2021-04-03 03:25:19 +03:00
return b ;
2014-01-04 17:00:08 +04:00
}
// Windows Firewall registration
void MsRegistWindowsFirewallEx2 ( char * title , char * exe , char * dir )
{
char tmp [ MAX_PATH ] ;
// Validate arguments
if ( title = = NULL | | exe = = NULL )
{
return ;
}
if ( dir = = NULL | | IsEmptyStr ( dir ) )
{
dir = MsGetExeDirName ( ) ;
}
ConbinePath ( tmp , sizeof ( tmp ) , dir , exe ) ;
if ( IsFileExists ( tmp ) = = false )
{
return ;
}
MsRegistWindowsFirewallEx ( title , tmp ) ;
}
void MsRegistWindowsFirewallEx ( char * title , char * exe )
{
char * data =
" Option Explicit \r \n Const NET_FW_PROFILE_DOMAIN = 0 \r \n Const NET_FW_PROFILE_STANDARD = 1 \r \n "
" Const NET_FW_SCOPE_ALL = 0 \r \n Const NET_FW_IP_VERSION_ANY = 2 \r \n Dim fwMgr \r \n "
" Set fwMgr = CreateObject( \" HNetCfg.FwMgr \" ) \r \n Dim profile \r \n "
" Set profile = fwMgr.LocalPolicy.CurrentProfile \r \n Dim app \r \n "
" Set app = CreateObject( \" HNetCfg.FwAuthorizedApplication \" ) \r \n "
" app.ProcessImageFileName = \" $PATH$ \" \r \n app.Name = \" $TITLE$ \" \r \n "
" app.Scope = NET_FW_SCOPE_ALL \r \n app.IpVersion = NET_FW_IP_VERSION_ANY \r \n "
" app.Enabled = TRUE \r \n On Error Resume Next \r \n profile.AuthorizedApplications. "
" Add app \r \n " ;
char * tmp ;
UINT tmp_size ;
char filename [ MAX_PATH ] ;
char cscript [ MAX_PATH ] ;
char arg [ MAX_PATH ] ;
IO * o ;
char hash [ MAX_PATH ] ;
UCHAR hashbin [ SHA1_SIZE ] ;
UCHAR file_hash_bin [ SHA1_SIZE ] ;
char file_hash_str [ MAX_SIZE ] ;
// Validate arguments
if ( title = = NULL | | exe = = NULL )
{
return ;
}
if ( MsIsAdmin ( ) = = false )
{
return ;
}
2021-04-03 03:25:19 +03:00
data = " Option Explicit \r \n \r \n Const PROFILES_ALL = 7 \r \n Const NET_FW_ACTION_ALLOWNET_FW_ACTION_ALLOW = 1 \r \n "
" \r \n Dim policy2 \r \n Dim rules \r \n Dim new_rule \r \n \r \n On Error Resume Next \r \n \r \n "
" Set policy2 = CreateObject( \" HNetCfg.FwPolicy2 \" ) \r \n Set rules = policy2.Rules \r \n "
" Set new_rule = CreateObject( \" HNetCfg.FWRule \" ) \r \n new_rule.Name = \" $TITLE$ \" \r \n "
" new_rule.Description = \" $TITLE$ \" \r \n new_rule.ApplicationName = \" $PATH$ \" \r \n "
" new_rule.Enabled = TRUE \r \n new_rule.Profiles = PROFILES_ALL \r \n new_rule.Action = "
" NET_FW_ACTION_ALLOWNET_FW_ACTION_ALLOW \r \n rules.Add new_rule \r \n \r \n " ;
2014-01-04 17:00:08 +04:00
tmp_size = StrLen ( data ) * 4 ;
tmp = ZeroMalloc ( tmp_size ) ;
2018-09-22 07:35:30 +03:00
Sha1 ( hashbin , exe , StrLen ( exe ) ) ;
2014-01-04 17:00:08 +04:00
BinToStr ( hash , sizeof ( hash ) , hashbin , 6 ) ;
ReplaceStrEx ( tmp , tmp_size , data , " $TITLE$ " , title , false ) ;
ReplaceStrEx ( tmp , tmp_size , tmp , " $PATH$ " , exe , false ) ;
2018-09-22 07:35:30 +03:00
Sha1 ( file_hash_bin , tmp , StrLen ( tmp ) ) ;
2014-01-04 17:00:08 +04:00
BinToStr ( file_hash_str , sizeof ( file_hash_str ) , file_hash_bin , sizeof ( file_hash_bin ) ) ;
2021-04-03 03:25:19 +03:00
if ( MsRegReadIntEx2 ( REG_LOCAL_MACHINE , SOFTETHER_FW_SCRIPT_HASH , file_hash_str , false , true ) = = 0 )
2014-01-04 17:00:08 +04:00
{
Format ( filename , sizeof ( filename ) , " %s \\ winfire_%s.vbs " , MsGetMyTempDir ( ) , hash ) ;
o = FileCreate ( filename ) ;
FileWrite ( o , tmp , StrLen ( tmp ) ) ;
FileClose ( o ) ;
Format ( cscript , sizeof ( cscript ) , " %s \\ cscript.exe " , MsGetSystem32Dir ( ) ) ;
Format ( arg , sizeof ( arg ) , " \" %s \" " , filename ) ;
if ( Run ( cscript , arg , true , false ) )
{
MsRegWriteIntEx2 ( REG_LOCAL_MACHINE , SOFTETHER_FW_SCRIPT_HASH , file_hash_str , 1 , false , true ) ;
}
Debug ( " cscript %s \n " , arg ) ;
}
Free ( tmp ) ;
}
// Run driver installer for Vista
bool MsExecDriverInstaller ( char * arg )
{
wchar_t tmp [ MAX_PATH ] ;
wchar_t hamcore_dst [ MAX_PATH ] ;
wchar_t hamcore_src [ MAX_PATH ] ;
wchar_t lang_config_src [ MAX_PATH ] ;
wchar_t lang_config_dst [ MAX_PATH ] ;
HANDLE h ;
2021-03-01 03:46:11 +03:00
DWORD retcode ;
2014-01-04 17:00:08 +04:00
SHELLEXECUTEINFOW info ;
wchar_t * arg_w ;
// Validate arguments
if ( arg = = NULL )
{
return false ;
}
UniFormat ( hamcore_dst , sizeof ( hamcore_dst ) , L " %s \\ hamcore.se2 " , MsGetMyTempDirW ( ) ) ;
UniFormat ( hamcore_src , sizeof ( hamcore_src ) , L " %s \\ hamcore.se2 " , MsGetExeDirNameW ( ) ) ;
// Extract the File
UniFormat ( tmp , sizeof ( tmp ) , VISTA_DRIVER_INSTALLER_DST , MsGetMyTempDirW ( ) ) ;
2020-07-27 08:25:00 +03:00
if ( FileCopyW ( VISTA_DRIVER_INSTALLER_SRC , tmp ) = = false )
2014-01-04 17:00:08 +04:00
{
return false ;
}
if ( FileCopyW ( hamcore_src , hamcore_dst ) = = false )
{
return false ;
}
ConbinePathW ( lang_config_src , sizeof ( lang_config_src ) , MsGetExeDirNameW ( ) , L " lang.config " ) ;
ConbinePathW ( lang_config_dst , sizeof ( lang_config_dst ) , MsGetMyTempDirW ( ) , L " lang.config " ) ;
FileCopyW ( lang_config_src , lang_config_dst ) ;
arg_w = CopyStrToUni ( arg ) ;
// Run
Zero ( & info , sizeof ( info ) ) ;
info . cbSize = sizeof ( info ) ;
info . lpVerb = L " open " ;
info . lpFile = tmp ;
2021-03-12 07:46:20 +03:00
info . lpDirectory = MsGetMyTempDirW ( ) ;
2014-01-04 17:00:08 +04:00
info . fMask = SEE_MASK_NOCLOSEPROCESS ;
info . lpParameters = arg_w ;
info . nShow = SW_SHOWNORMAL ;
if ( ShellExecuteExW ( & info ) = = false )
{
Free ( arg_w ) ;
return false ;
}
Free ( arg_w ) ;
h = info . hProcess ;
retcode = 1 ;
while ( true )
{
// Wait for completion
WaitForSingleObject ( h , INFINITE ) ;
// Get the exit code
retcode = 1 ;
if ( GetExitCodeProcess ( h , & retcode ) = = false )
{
break ;
}
if ( retcode ! = STILL_ACTIVE )
{
break ;
}
}
CloseHandle ( h ) ;
if ( retcode & 1 )
{
return false ;
}
return true ;
}
// Get the locale of the current thread
UINT MsGetThreadLocale ( )
{
return ( UINT ) GetThreadLocale ( ) ;
}
// Set the width of the current console
UINT MsSetConsoleWidth ( UINT size )
{
HANDLE h = GetStdHandle ( STD_OUTPUT_HANDLE ) ;
CONSOLE_SCREEN_BUFFER_INFO info ;
COORD c ;
UINT old_x , old_y ;
// Validate arguments
if ( size = = 0 )
{
return 0 ;
}
if ( h = = INVALID_HANDLE_VALUE )
{
return 0 ;
}
Zero ( & info , sizeof ( info ) ) ;
if ( GetConsoleScreenBufferInfo ( h , & info ) = = false )
{
return 0 ;
}
old_x = info . dwSize . X ;
old_y = info . dwSize . Y ;
c . X = size ;
c . Y = old_y ;
SetConsoleScreenBufferSize ( h , c ) ;
return old_x ;
}
// Get the width of the current console
UINT MsGetConsoleWidth ( )
{
HANDLE h = GetStdHandle ( STD_OUTPUT_HANDLE ) ;
CONSOLE_SCREEN_BUFFER_INFO info ;
if ( h = = INVALID_HANDLE_VALUE )
{
return 80 ;
}
Zero ( & info , sizeof ( info ) ) ;
if ( GetConsoleScreenBufferInfo ( h , & info ) = = false )
{
return 80 ;
}
return info . dwSize . X ;
}
// Disable the MS-IME
bool MsDisableIme ( )
{
HINSTANCE h ;
bool ret = false ;
char dll_name [ MAX_PATH ] ;
BOOL ( WINAPI * _ImmDisableIME ) ( DWORD ) ;
Format ( dll_name , sizeof ( dll_name ) , " %s \\ imm32.dll " , MsGetSystem32Dir ( ) ) ;
h = MsLoadLibrary ( dll_name ) ;
if ( h = = NULL )
{
return false ;
}
_ImmDisableIME = ( BOOL ( __stdcall * ) ( DWORD ) ) GetProcAddress ( h , " ImmDisableIME " ) ;
if ( _ImmDisableIME ! = NULL )
{
ret = _ImmDisableIME ( - 1 ) ;
}
FreeLibrary ( h ) ;
return ret ;
}
// Display the current time
void MsPrintTick ( )
{
UINT tick = timeGetTime ( ) ;
static UINT tick_init = 0 ;
if ( tick_init = = 0 )
{
tick_init = tick ;
tick = 0 ;
}
else
{
tick - = tick_init ;
}
printf ( " [%u] \n " , tick ) ;
}
// LoadLibrary compatible for hamcore (Read as a data file)
void * MsLoadLibraryAsDataFileW ( wchar_t * name )
{
BUF * b ;
wchar_t tmp_dll_name [ MAX_SIZE ] ;
char hash_str [ MAX_SIZE ] ;
UCHAR hash [ SHA1_SIZE ] ;
// Validate arguments
if ( name = = NULL )
{
return NULL ;
}
2018-09-22 07:35:30 +03:00
Sha0 ( hash , name , UniStrLen ( name ) ) ;
2014-01-04 17:00:08 +04:00
BinToStr ( hash_str , sizeof ( hash_str ) , hash , 4 ) ;
UniFormat ( tmp_dll_name , sizeof ( tmp_dll_name ) , L " %s \\ %S.dll " , MsGetMyTempDirW ( ) , hash_str ) ;
if ( IsFileExistsW ( tmp_dll_name ) = = false )
{
b = ReadDumpW ( name ) ;
if ( b = = NULL )
{
return NULL ;
}
DumpBufW ( b , tmp_dll_name ) ;
FreeBuf ( b ) ;
}
return LoadLibraryExW ( tmp_dll_name , NULL , LOAD_LIBRARY_AS_DATAFILE ) ;
}
void * MsLoadLibraryAsDataFile ( char * name )
{
wchar_t name_w [ MAX_SIZE ] ;
// Validate arguments
if ( name = = NULL )
{
return NULL ;
}
StrToUni ( name_w , sizeof ( name_w ) , name ) ;
return MsLoadLibraryAsDataFileW ( name_w ) ;
}
// LoadLibrary (compatible for Hamcore)
void * MsLoadLibraryW ( wchar_t * name )
{
BUF * b ;
wchar_t tmp_dll_name [ MAX_SIZE ] ;
char hash_str [ MAX_SIZE ] ;
UCHAR hash [ SHA1_SIZE ] ;
// Validate arguments
if ( name = = NULL )
{
return NULL ;
}
2018-09-22 07:35:30 +03:00
Sha0 ( hash , name , UniStrSize ( name ) ) ;
2014-01-04 17:00:08 +04:00
BinToStr ( hash_str , sizeof ( hash_str ) , hash , 4 ) ;
UniFormat ( tmp_dll_name , sizeof ( tmp_dll_name ) , L " %s \\ %S.dll " , MsGetMyTempDirW ( ) , hash_str ) ;
if ( IsFileExistsW ( tmp_dll_name ) = = false )
{
b = ReadDumpW ( name ) ;
if ( b = = NULL )
{
return NULL ;
}
DumpBufW ( b , tmp_dll_name ) ;
FreeBuf ( b ) ;
}
if ( IsNt ( ) )
{
return LoadLibraryW ( tmp_dll_name ) ;
}
else
{
char tmp_dll_name_a [ MAX_SIZE ] ;
HINSTANCE ret ;
UniToStr ( tmp_dll_name_a , sizeof ( tmp_dll_name_a ) , tmp_dll_name ) ;
ret = LoadLibraryA ( tmp_dll_name_a ) ;
return ret ;
}
}
void * MsLoadLibrary ( char * name )
{
wchar_t name_w [ MAX_SIZE ] ;
// Validate arguments
if ( name = = NULL )
{
return NULL ;
}
StrToUni ( name_w , sizeof ( name_w ) , name ) ;
return MsLoadLibraryW ( name_w ) ;
}
// Search for the adapter by GUID
MS_ADAPTER * MsGetAdapterByGuid ( char * guid )
{
MS_ADAPTER_LIST * o ;
MS_ADAPTER * ret = NULL ;
// Validate arguments
if ( guid = = NULL )
{
return NULL ;
}
o = MsCreateAdapterList ( ) ;
if ( o = = NULL )
{
return NULL ;
}
ret = MsGetAdapterByGuidFromList ( o , guid ) ;
MsFreeAdapterList ( o ) ;
return ret ;
}
MS_ADAPTER * MsGetAdapterByGuidFromList ( MS_ADAPTER_LIST * o , char * guid )
{
MS_ADAPTER * ret = NULL ;
UINT i ;
// Validate arguments
if ( o = = NULL | | guid = = NULL )
{
return NULL ;
}
for ( i = 0 ; i < o - > Num ; i + + )
{
if ( StrCmpi ( o - > Adapters [ i ] - > Guid , guid ) = = 0 )
{
ret = MsCloneAdapter ( o - > Adapters [ i ] ) ;
break ;
}
}
return ret ;
}
// Get a single adapter
MS_ADAPTER * MsGetAdapter ( char * title )
{
MS_ADAPTER_LIST * o ;
MS_ADAPTER * ret = NULL ;
UINT i ;
// Validate arguments
if ( title = = NULL )
{
return NULL ;
}
o = MsCreateAdapterList ( ) ;
if ( o = = NULL )
{
return NULL ;
}
for ( i = 0 ; i < o - > Num ; i + + )
{
if ( StrCmpi ( o - > Adapters [ i ] - > Title , title ) = = 0 )
{
ret = MsCloneAdapter ( o - > Adapters [ i ] ) ;
break ;
}
}
MsFreeAdapterList ( o ) ;
return ret ;
}
// 32-bit overflow checking
# define CHECK_32BIT_OVERFLOW(old_value, new_value) \
{ \
if ( ( old_value ) > ( new_value ) ) \
{ \
( new_value ) + = ( ( UINT64 ) 4294967296ULL ) ; \
} \
}
// Get the TCP/IP information of the specified adapter
void MsGetAdapterTcpIpInformation ( MS_ADAPTER * a )
{
IP_ADAPTER_INFO * info , * info_top ;
2021-03-01 03:46:11 +03:00
ULONG info_size ;
ULONG ret ;
2014-01-04 17:00:08 +04:00
// Validate arguments
if ( a = = NULL )
{
return ;
}
info_top = ZeroMalloc ( sizeof ( IP_ADAPTER_INFO ) ) ;
info_size = sizeof ( IP_ADAPTER_INFO ) ;
2021-04-03 03:25:19 +03:00
ret = GetAdaptersInfo ( info_top , & info_size ) ;
2014-01-04 17:00:08 +04:00
if ( ret = = ERROR_INSUFFICIENT_BUFFER | | ret = = ERROR_BUFFER_OVERFLOW )
{
Free ( info_top ) ;
info_size * = 2 ;
info_top = ZeroMalloc ( info_size ) ;
2021-04-03 03:25:19 +03:00
if ( GetAdaptersInfo ( info_top , & info_size ) ! = NO_ERROR )
2014-01-04 17:00:08 +04:00
{
Free ( info_top ) ;
return ;
}
}
else if ( ret ! = NO_ERROR )
{
Free ( info_top ) ;
return ;
}
// Search for their own entry
info = info_top ;
while ( info ! = NULL )
{
if ( info - > Index = = a - > Index )
{
IP_ADDR_STRING * s ;
// IP address
a - > NumIpAddress = 0 ;
s = & info - > IpAddressList ;
while ( s ! = NULL )
{
if ( a - > NumIpAddress < MAX_MS_ADAPTER_IP_ADDRESS )
{
StrToIP ( & a - > IpAddresses [ a - > NumIpAddress ] , s - > IpAddress . String ) ;
StrToIP ( & a - > SubnetMasks [ a - > NumIpAddress ] , s - > IpMask . String ) ;
a - > NumIpAddress + + ;
}
s = s - > Next ;
}
// Gateway
a - > NumGateway = 0 ;
s = & info - > GatewayList ;
while ( s ! = NULL )
{
if ( a - > NumGateway < MAX_MS_ADAPTER_IP_ADDRESS )
{
StrToIP ( & a - > Gateways [ a - > NumGateway ] , s - > IpAddress . String ) ;
a - > NumGateway + + ;
}
s = s - > Next ;
}
// DHCP Server
a - > UseDhcp = ( info - > DhcpEnabled = = 0 ? false : true ) ;
if ( a - > UseDhcp )
{
SYSTEMTIME st ;
StrToIP ( & a - > DhcpServer , info - > DhcpServer . IpAddress . String ) ;
TimeToSystem ( & st , info - > LeaseObtained ) ;
a - > DhcpLeaseStart = SystemToUINT64 ( & st ) ;
TimeToSystem ( & st , info - > LeaseExpires ) ;
a - > DhcpLeaseExpires = SystemToUINT64 ( & st ) ;
}
// WINS server
a - > UseWins = info - > HaveWins ;
if ( a - > UseWins )
{
StrToIP ( & a - > PrimaryWinsServer , info - > PrimaryWinsServer . IpAddress . String ) ;
StrToIP ( & a - > SecondaryWinsServer , info - > SecondaryWinsServer . IpAddress . String ) ;
}
StrCpy ( a - > Guid , sizeof ( a - > Guid ) , info - > AdapterName ) ;
a - > Info = true ;
break ;
}
info = info - > Next ;
}
Free ( info_top ) ;
}
// Generation of adapter list
MS_ADAPTER_LIST * MsCreateAdapterList ( )
{
return MsCreateAdapterListEx ( false ) ;
}
MS_ADAPTER_LIST * MsCreateAdapterListEx ( bool no_info )
{
MS_ADAPTER_LIST * ret ;
if ( no_info )
{
ret = MsCreateAdapterListInnerEx ( true ) ;
return ret ;
}
Lock ( lock_adapter_list ) ;
{
MS_ADAPTER_LIST * old = last_adapter_list ;
UINT i ;
// Fetch a new adapter list
ret = MsCreateAdapterListInner ( ) ;
if ( ret = = NULL )
{
Unlock ( lock_adapter_list ) ;
return NULL ;
}
// Check whether the previously acquired item exists for each entry
// in the list of adapters have been taken
for ( i = 0 ; i < ret - > Num ; i + + )
{
UINT j ;
for ( j = 0 ; j < old - > Num ; j + + )
{
MS_ADAPTER * o = old - > Adapters [ j ] ;
MS_ADAPTER * n = ret - > Adapters [ i ] ;
if ( StrCmpi ( o - > Title , n - > Title ) = = 0 )
{
// If the value of older item is small, increment it
CHECK_32BIT_OVERFLOW ( o - > RecvBytes , n - > RecvBytes ) ;
CHECK_32BIT_OVERFLOW ( o - > RecvPacketsBroadcast , n - > RecvPacketsBroadcast ) ;
CHECK_32BIT_OVERFLOW ( o - > RecvPacketsUnicast , n - > RecvPacketsUnicast ) ;
CHECK_32BIT_OVERFLOW ( o - > SendBytes , n - > SendBytes ) ;
CHECK_32BIT_OVERFLOW ( o - > SendPacketsBroadcast , n - > SendPacketsBroadcast ) ;
CHECK_32BIT_OVERFLOW ( o - > SendPacketsUnicast , n - > SendPacketsUnicast ) ;
break ;
}
}
}
// Release the old adapter list
MsFreeAdapterList ( old ) ;
// Save a clone of the adapter list that newly acquired
last_adapter_list = MsCloneAdapterList ( ret ) ;
}
Unlock ( lock_adapter_list ) ;
return ret ;
}
// Initialization of the adapter module list
void MsInitAdapterListModule ( )
{
lock_adapter_list = NewLock ( NULL ) ;
last_adapter_list = MsCreateAdapterListInner ( ) ;
}
// Release of the adapter module list
void MsFreeAdapterListModule ( )
{
if ( last_adapter_list ! = NULL )
{
MsFreeAdapterList ( last_adapter_list ) ;
last_adapter_list = NULL ;
}
DeleteLock ( lock_adapter_list ) ;
lock_adapter_list = NULL ;
}
// Clone the adapter list
MS_ADAPTER_LIST * MsCloneAdapterList ( MS_ADAPTER_LIST * o )
{
MS_ADAPTER_LIST * ret ;
UINT i ;
// Validate arguments
if ( o = = NULL )
{
return NULL ;
}
ret = ZeroMalloc ( sizeof ( MS_ADAPTER_LIST ) ) ;
ret - > Num = o - > Num ;
ret - > Adapters = ZeroMalloc ( sizeof ( MS_ADAPTER * ) * ret - > Num ) ;
for ( i = 0 ; i < ret - > Num ; i + + )
{
ret - > Adapters [ i ] = ZeroMalloc ( sizeof ( MS_ADAPTER ) ) ;
Copy ( ret - > Adapters [ i ] , o - > Adapters [ i ] , sizeof ( MS_ADAPTER ) ) ;
}
return ret ;
}
// Clone the adapter
MS_ADAPTER * MsCloneAdapter ( MS_ADAPTER * a )
{
MS_ADAPTER * ret ;
// Validate arguments
if ( a = = NULL )
{
return NULL ;
}
ret = ZeroMalloc ( sizeof ( MS_ADAPTER ) ) ;
Copy ( ret , a , sizeof ( MS_ADAPTER ) ) ;
return ret ;
}
// Creating an adapters list
MS_ADAPTER_LIST * MsCreateAdapterListInner ( )
{
return MsCreateAdapterListInnerEx ( false ) ;
}
MS_ADAPTER_LIST * MsCreateAdapterListInnerEx ( bool no_info )
{
2021-04-03 03:25:19 +03:00
return MsCreateAdapterListInnerExVista ( no_info ) ;
2014-01-04 17:00:08 +04:00
}
// Creating an adapters list (Windows Vista version)
MS_ADAPTER_LIST * MsCreateAdapterListInnerExVista ( bool no_info )
{
LIST * o ;
UINT i ;
UINT retcode ;
2021-03-01 03:46:11 +03:00
PMIB_IF_TABLE2 table ;
2014-01-04 17:00:08 +04:00
MS_ADAPTER_LIST * ret ;
2021-04-03 03:25:19 +03:00
retcode = GetIfTable2 ( & table ) ;
2014-01-04 17:00:08 +04:00
if ( retcode ! = NO_ERROR | | table = = NULL )
{
return ZeroMalloc ( sizeof ( MS_ADAPTER_LIST ) ) ;
}
o = NewListFast ( NULL ) ;
for ( i = 0 ; i < table - > NumEntries ; i + + )
{
MIB_IF_ROW2 * r = & table - > Table [ i ] ;
wchar_t title [ MAX_PATH ] ;
MS_ADAPTER * a ;
UINT j ;
//if (r->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED || r->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
{
//if (r->dwType & IF_TYPE_ETHERNET_CSMACD)
{
for ( j = 1 ; ; j + + )
{
UINT k ;
bool exists ;
if ( j = = 1 )
{
UniStrCpy ( title , sizeof ( title ) , r - > Description ) ;
}
else
{
UniFormat ( title , sizeof ( title ) , L " %s (%u) " , r - > Description , j ) ;
}
exists = false ;
for ( k = 0 ; k < LIST_NUM ( o ) ; k + + )
{
MS_ADAPTER * a = LIST_DATA ( o , k ) ;
if ( UniStrCmpi ( a - > TitleW , title ) = = 0 )
{
exists = true ;
break ;
}
}
if ( exists = = false )
{
break ;
}
}
a = ZeroMalloc ( sizeof ( MS_ADAPTER ) ) ;
// Create an adapter information
UniStrCpy ( a - > TitleW , sizeof ( a - > TitleW ) , title ) ;
UniToStr ( a - > Title , sizeof ( a - > Title ) , title ) ;
a - > Index = r - > InterfaceIndex ;
a - > Type = r - > Type ;
a - > Status = ConvertMidStatusVistaToXp ( r - > OperStatus ) ;
a - > Mtu = r - > Mtu ;
a - > Speed = MAX ( ( UINT ) r - > TransmitLinkSpeed , ( UINT ) r - > ReceiveLinkSpeed ) ;
a - > AddressSize = MIN ( sizeof ( a - > Address ) , r - > PhysicalAddressLength ) ;
Copy ( a - > Address , r - > PhysicalAddress , a - > AddressSize ) ;
a - > RecvBytes = r - > InOctets ;
a - > RecvPacketsBroadcast = r - > InNUcastPkts ;
a - > RecvPacketsUnicast = r - > InUcastPkts ;
a - > SendBytes = r - > OutOctets ;
a - > SendPacketsBroadcast = r - > OutNUcastPkts ;
a - > SendPacketsUnicast = r - > OutUcastPkts ;
if ( r - > MediaType = = NdisMediumWirelessWan | | r - > PhysicalMediumType = = NdisPhysicalMediumWirelessLan | |
r - > PhysicalMediumType = = NdisPhysicalMediumWirelessWan | | r - > PhysicalMediumType = = NdisPhysicalMediumWiMax | |
r - > Type = = IF_TYPE_IEEE80211 )
{
a - > IsWireless = true ;
}
if ( a - > IsWireless | |
r - > Type ! = IF_TYPE_ETHERNET_CSMACD | |
r - > MediaType ! = NdisMedium802_3 | |
( r - > PhysicalMediumType ! = 0 & & r - > PhysicalMediumType ! = NdisPhysicalMedium802_3 ) )
{
a - > IsNotEthernetLan = true ;
}
// TCP/IP information acquisition
if ( no_info = = false )
{
MsGetAdapterTcpIpInformation ( a ) ;
}
Add ( o , a ) ;
}
}
}
ret = ZeroMalloc ( sizeof ( MS_ADAPTER_LIST ) ) ;
ret - > Num = LIST_NUM ( o ) ;
ret - > Adapters = ToArray ( o ) ;
ReleaseList ( o ) ;
2021-04-03 03:25:19 +03:00
FreeMibTable ( table ) ;
2014-01-04 17:00:08 +04:00
return ret ;
}
// Convert the MIB Operational Status from Vista format to XP format
UINT ConvertMidStatusVistaToXp ( UINT st )
{
switch ( st )
{
case IfOperStatusUp :
return MIB_IF_OPER_STATUS_CONNECTED ;
case IfOperStatusDown :
return MIB_IF_OPER_STATUS_DISCONNECTED ;
}
return MIB_IF_OPER_STATUS_NON_OPERATIONAL ;
}
// Release the adapter list
void MsFreeAdapterList ( MS_ADAPTER_LIST * o )
{
UINT i ;
// Validate arguments
if ( o = = NULL )
{
return ;
}
for ( i = 0 ; i < o - > Num ; i + + )
{
MsFreeAdapter ( o - > Adapters [ i ] ) ;
}
Free ( o - > Adapters ) ;
Free ( o ) ;
}
// Release the adapter information
void MsFreeAdapter ( MS_ADAPTER * a )
{
// Validate arguments
if ( a = = NULL )
{
return ;
}
Free ( a ) ;
}
// Get the status string of the adapter
wchar_t * MsGetAdapterStatusStr ( UINT status )
{
wchar_t * ret ;
switch ( status )
{
case MIB_IF_OPER_STATUS_NON_OPERATIONAL :
ret = _UU ( " MS_NON_OPERATIONAL " ) ;
break ;
case MIB_IF_OPER_STATUS_UNREACHABLE :
ret = _UU ( " MS_UNREACHABLE " ) ;
break ;
case MIB_IF_OPER_STATUS_DISCONNECTED :
ret = _UU ( " MS_DISCONNECTED " ) ;
break ;
case MIB_IF_OPER_STATUS_CONNECTING :
ret = _UU ( " MS_CONNECTING " ) ;
break ;
case MIB_IF_OPER_STATUS_CONNECTED :
ret = _UU ( " MS_CONNECTED " ) ;
break ;
default :
ret = _UU ( " MS_OPERATIONAL " ) ;
break ;
}
return ret ;
}
// Get the type string of the adapter
wchar_t * MsGetAdapterTypeStr ( UINT type )
{
wchar_t * ret ;
switch ( type )
{
2018-10-03 10:10:27 +03:00
case IF_TYPE_PROP_VIRTUAL :
ret = _UU ( " MS_VIRTUAL " ) ;
break ;
2014-01-04 17:00:08 +04:00
case MIB_IF_TYPE_ETHERNET :
ret = _UU ( " MS_ETHERNET " ) ;
break ;
case IF_TYPE_IEEE80211 :
ret = _UU ( " MS_WLAN " ) ;
break ;
case MIB_IF_TYPE_TOKENRING :
ret = _UU ( " MS_TOKENRING " ) ;
break ;
case MIB_IF_TYPE_FDDI :
ret = _UU ( " MS_FDDI " ) ;
break ;
case MIB_IF_TYPE_PPP :
ret = _UU ( " MS_PPP " ) ;
break ;
case MIB_IF_TYPE_LOOPBACK :
ret = _UU ( " MS_LOOPBACK " ) ;
break ;
case MIB_IF_TYPE_SLIP :
ret = _UU ( " MS_SLIP " ) ;
break ;
default :
ret = _UU ( " MS_OTHER " ) ;
break ;
}
return ret ;
}
// Kill the process of specified EXE file name
UINT MsKillProcessByExeName ( wchar_t * name )
{
LIST * o ;
UINT me , i ;
UINT num = 0 ;
// Validate arguments
if ( name = = NULL )
{
return 0 ;
}
o = MsGetProcessList ( ) ;
me = MsGetProcessId ( ) ;
for ( i = 0 ; i < LIST_NUM ( o ) ; i + + )
{
MS_PROCESS * p = LIST_DATA ( o , i ) ;
if ( p - > ProcessId ! = me )
{
if ( UniStrCmpi ( p - > ExeFilenameW , name ) = = 0 )
{
if ( MsKillProcess ( p - > ProcessId ) )
{
num + + ;
}
}
}
}
MsFreeProcessList ( o ) ;
return num ;
}
// Terminate all instances except the EXE itself
void MsKillOtherInstance ( )
{
MsKillOtherInstanceEx ( NULL ) ;
}
void MsKillOtherInstanceEx ( char * exclude_svcname )
{
UINT me , i ;
wchar_t me_path [ MAX_PATH ] ;
wchar_t me_path_short [ MAX_PATH ] ;
LIST * o = MsGetProcessList ( ) ;
UINT e_procid = 0 ;
UINT e_procid2 = 0 ;
if ( exclude_svcname ! = NULL )
{
e_procid = MsReadCallingServiceManagerProcessId ( exclude_svcname , false ) ;
e_procid2 = MsReadCallingServiceManagerProcessId ( exclude_svcname , true ) ;
}
me = MsGetProcessId ( ) ;
MsGetCurrentProcessExeNameW ( me_path , sizeof ( me_path ) ) ;
MsGetShortPathNameW ( me_path , me_path_short , sizeof ( me_path_short ) ) ;
for ( i = 0 ; i < LIST_NUM ( o ) ; i + + )
{
MS_PROCESS * p = LIST_DATA ( o , i ) ;
if ( p - > ProcessId ! = me )
{
if ( ( e_procid = = 0 | | ( e_procid ! = p - > ProcessId ) ) & & ( e_procid2 = = 0 | | ( e_procid2 ! = p - > ProcessId ) ) )
{
wchar_t tmp [ MAX_PATH ] ;
MsGetShortPathNameW ( p - > ExeFilenameW , tmp , sizeof ( tmp ) ) ;
if ( UniStrCmpi ( me_path_short , tmp ) = = 0 )
{
MsKillProcess ( p - > ProcessId ) ;
}
}
}
}
MsFreeProcessList ( o ) ;
}
// Get the short file name
bool MsGetShortPathNameA ( char * long_path , char * short_path , UINT short_path_size )
{
// Validate arguments
if ( long_path = = NULL | | short_path = = NULL )
{
return false ;
}
if ( GetShortPathNameA ( long_path , short_path , short_path_size ) = = 0 )
{
StrCpy ( short_path , short_path_size , long_path ) ;
return false ;
}
return true ;
}
bool MsGetShortPathNameW ( wchar_t * long_path , wchar_t * short_path , UINT short_path_size )
{
// Validate arguments
if ( long_path = = NULL | | short_path = = NULL )
{
return false ;
}
if ( IsNt ( ) = = false )
{
char short_path_a [ MAX_SIZE ] ;
char long_path_a [ MAX_SIZE ] ;
bool ret ;
UniToStr ( long_path_a , sizeof ( long_path_a ) , long_path ) ;
ret = MsGetShortPathNameA ( long_path_a , short_path_a , sizeof ( short_path_a ) ) ;
StrToUni ( short_path , short_path_size , short_path_a ) ;
return ret ;
}
if ( GetShortPathNameW ( long_path , short_path , short_path_size ) = = 0 )
{
UniStrCpy ( short_path , short_path_size , long_path ) ;
return false ;
}
return true ;
}
// Kill the specified process
bool MsKillProcess ( UINT id )
{
HANDLE h ;
// Validate arguments
if ( id = = 0 )
{
return false ;
}
h = OpenProcess ( PROCESS_TERMINATE , FALSE , id ) ;
if ( h = = NULL )
{
return false ;
}
if ( TerminateProcess ( h , 0 ) = = FALSE )
{
CloseHandle ( h ) ;
return false ;
}
CloseHandle ( h ) ;
return true ;
}
// Get the current EXE file name
void MsGetCurrentProcessExeNameW ( wchar_t * name , UINT size )
{
UINT id ;
LIST * o ;
MS_PROCESS * p ;
// Validate arguments
if ( name = = NULL )
{
return ;
}
id = MsGetCurrentProcessId ( ) ;
o = MsGetProcessList ( ) ;
p = MsSearchProcessById ( o , id ) ;
if ( p ! = NULL )
{
p = MsSearchProcessById ( o , id ) ;
UniStrCpy ( name , size , p - > ExeFilenameW ) ;
}
else
{
UniStrCpy ( name , size , MsGetExeFileNameW ( ) ) ;
}
MsFreeProcessList ( o ) ;
}
// Search the process by the process ID
MS_PROCESS * MsSearchProcessById ( LIST * o , UINT id )
{
MS_PROCESS * p , t ;
// Validate arguments
if ( o = = NULL )
{
return NULL ;
}
Zero ( & t , sizeof ( t ) ) ;
t . ProcessId = id ;
p = Search ( o , & t ) ;
return p ;
}
// Compare the Process List items
int MsCompareProcessList ( void * p1 , void * p2 )
{
MS_PROCESS * e1 , * e2 ;
if ( p1 = = NULL | | p2 = = NULL )
{
return 0 ;
}
e1 = * ( MS_PROCESS * * ) p1 ;
e2 = * ( MS_PROCESS * * ) p2 ;
if ( e1 = = NULL | | e2 = = NULL )
{
return 0 ;
}
if ( e1 - > ProcessId > e2 - > ProcessId )
{
return 1 ;
}
else if ( e1 - > ProcessId < e2 - > ProcessId )
{
return - 1 ;
}
else
{
return 0 ;
}
}
// Release of the process list
void MsFreeProcessList ( LIST * o )
{
UINT i ;
// Validate arguments
if ( o = = NULL )
{
return ;
}
for ( i = 0 ; i < LIST_NUM ( o ) ; i + + )
{
MS_PROCESS * p = LIST_DATA ( o , i ) ;
Free ( p ) ;
}
ReleaseList ( o ) ;
}
// Get the Process List (for WinNT)
LIST * MsGetProcessListNt ( )
{
LIST * o ;
UINT max = 16384 ;
DWORD * processes ;
2021-03-01 03:46:11 +03:00
DWORD needed ;
UINT num ;
2014-01-04 17:00:08 +04:00
UINT i ;
o = NewListFast ( MsCompareProcessList ) ;
processes = ZeroMalloc ( sizeof ( DWORD ) * max ) ;
2021-04-03 03:25:19 +03:00
if ( EnumProcesses ( processes , sizeof ( DWORD ) * max , & needed ) = = FALSE )
2014-01-04 17:00:08 +04:00
{
Free ( processes ) ;
return NULL ;
}
num = needed / sizeof ( DWORD ) ;
for ( i = 0 ; i < num ; i + + )
{
UINT id = processes [ i ] ;
HANDLE h = OpenProcess ( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ ,
false , id ) ;
if ( h ! = NULL )
{
HINSTANCE hInst = NULL ;
DWORD needed ;
char exe [ MAX_SIZE ] ;
wchar_t exe_w [ MAX_SIZE ] ;
bool ok = false ;
DWORD sz1 , sz2 ;
sz1 = sizeof ( exe ) - 1 ;
sz2 = sizeof ( exe_w ) / sizeof ( wchar_t ) - 1 ;
2021-04-03 03:25:19 +03:00
if ( EnumProcessModules ( h , & hInst , sizeof ( hInst ) , & needed ) = = false )
2014-01-04 17:00:08 +04:00
{
hInst = NULL ;
}
2021-04-03 03:25:19 +03:00
if ( GetModuleFileNameExA ( h , hInst , exe , sizeof ( exe ) - 1 ) & &
GetModuleFileNameExW ( h , hInst , exe_w , sizeof ( exe_w ) / sizeof ( wchar_t ) - 1 ) )
2014-01-04 17:00:08 +04:00
{
ok = true ;
}
2021-04-03 03:25:19 +03:00
else if ( QueryFullProcessImageNameA ( h , 0 , exe , & sz1 ) & &
QueryFullProcessImageNameW ( h , 0 , exe_w , & sz2 ) )
2014-01-04 17:00:08 +04:00
{
ok = true ;
}
if ( ok )
{
MS_PROCESS * p = ZeroMalloc ( sizeof ( MS_PROCESS ) ) ;
StrCpy ( p - > ExeFilename , sizeof ( p - > ExeFilename ) , exe ) ;
UniStrCpy ( p - > ExeFilenameW , sizeof ( p - > ExeFilenameW ) , exe_w ) ;
p - > ProcessId = id ;
Add ( o , p ) ;
}
CloseHandle ( h ) ;
}
}
Sort ( o ) ;
Free ( processes ) ;
return o ;
}
2021-04-03 03:25:19 +03:00
// Get the Process List
LIST * MsGetProcessList ( )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
return MsGetProcessListNt ( ) ;
}
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
// Force to run the current thread on a single CPU
void MsSetThreadSingleCpu ( )
{
SetThreadAffinityMask ( GetCurrentThread ( ) , 1 ) ;
}
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
// Playback of sound
void MsPlaySound ( char * name )
{
char tmp [ MAX_SIZE ] ;
char wav [ MAX_SIZE ] ;
char * temp ;
BUF * b ;
// Validate arguments
if ( name = = NULL )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
return ;
}
2014-01-04 17:00:08 +04:00
Format ( tmp , sizeof ( tmp ) , " |%s " , name ) ;
b = ReadDump ( tmp ) ;
if ( b = = NULL )
{
return ;
}
temp = MsGetMyTempDir ( ) ;
Format ( wav , sizeof ( tmp ) , " %s \\ %s " , temp , name ) ;
DumpBuf ( b , wav ) ;
PlaySound ( wav , NULL , SND_ASYNC | SND_FILENAME | SND_NODEFAULT ) ;
FreeBuf ( b ) ;
}
// Show an icon in the task tray
bool MsShowIconOnTray ( HWND hWnd , HICON icon , wchar_t * tooltip , UINT msg )
{
bool ret = true ;
// Validate arguments
if ( hWnd = = NULL | | icon = = NULL )
{
return true ;
}
2021-04-03 03:25:19 +03:00
Zero ( & nid_nt , sizeof ( nid_nt ) ) ;
nid_nt . cbSize = sizeof ( nid_nt ) ;
nid_nt . hWnd = hWnd ;
nid_nt . uID = 1 ;
nid_nt . uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO ;
nid_nt . uCallbackMessage = msg ;
nid_nt . hIcon = icon ;
UniStrCpy ( nid_nt . szTip , sizeof ( nid_nt . szTip ) , tooltip ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
ret = Shell_NotifyIconW ( NIM_ADD , & nid_nt ) ;
2014-01-04 17:00:08 +04:00
tray_inited = true ;
return ret ;
}
// Restore the icon in the task tray
void MsRestoreIconOnTray ( )
{
if ( tray_inited = = false )
{
return ;
}
2021-04-03 03:25:19 +03:00
Shell_NotifyIconW ( NIM_ADD , & nid_nt ) ;
2014-01-04 17:00:08 +04:00
}
// Change the icon in the task tray
void MsChangeIconOnTray ( HICON icon , wchar_t * tooltip )
{
MsChangeIconOnTrayEx ( icon , tooltip , NULL , NULL , NIIF_NONE , false ) ;
}
bool MsChangeIconOnTrayEx ( HICON icon , wchar_t * tooltip , wchar_t * info_title , wchar_t * info , UINT info_flags , bool add )
{
bool changed = false ;
bool ret = true ;
if ( tray_inited = = false )
{
return ret ;
}
if ( icon ! = NULL )
{
2021-04-03 03:25:19 +03:00
if ( nid_nt . hIcon ! = icon )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
changed = true ;
nid_nt . hIcon = icon ;
2014-01-04 17:00:08 +04:00
}
}
if ( tooltip ! = NULL )
{
2021-04-03 03:25:19 +03:00
wchar_t tmp [ MAX_SIZE ] ;
UniStrCpy ( tmp , sizeof ( tmp ) , tooltip ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
if ( UniStrCmp ( nid_nt . szTip , tmp ) ! = 0 )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
UniStrCpy ( nid_nt . szTip , sizeof ( nid_nt . szTip ) , tmp ) ;
changed = true ;
2014-01-04 17:00:08 +04:00
}
}
if ( info_title ! = NULL & & info ! = NULL )
{
2021-04-03 03:25:19 +03:00
wchar_t tmp1 [ MAX_SIZE ] ;
wchar_t tmp2 [ MAX_PATH ] ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
UniStrCpy ( tmp1 , sizeof ( tmp1 ) , info_title ) ;
UniStrCpy ( tmp2 , sizeof ( tmp2 ) , info ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
if ( UniStrCmp ( nid_nt . szInfo , tmp1 ) ! = 0 | |
UniStrCmp ( nid_nt . szInfoTitle , tmp2 ) ! = 0 )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
UniStrCpy ( nid_nt . szInfo , sizeof ( nid_nt . szInfo ) , tmp1 ) ;
UniStrCpy ( nid_nt . szInfoTitle , sizeof ( nid_nt . szInfoTitle ) , tmp2 ) ;
nid_nt . dwInfoFlags = info_flags ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
changed = true ;
2014-01-04 17:00:08 +04:00
}
}
if ( changed | | add )
{
UINT op = ( add ? NIM_ADD : NIM_MODIFY ) ;
2021-04-03 03:25:19 +03:00
ret = Shell_NotifyIconW ( op , & nid_nt ) ;
2014-01-04 17:00:08 +04:00
}
return ret ;
}
// Remove the icon in the task tray
void MsHideIconOnTray ( )
{
2021-04-03 03:25:19 +03:00
Shell_NotifyIconW ( NIM_DELETE , & nid_nt ) ;
2014-01-04 17:00:08 +04:00
tray_inited = false ;
}
// Insert a menu item
bool MsInsertMenu ( HMENU hMenu , UINT pos , UINT flags , UINT_PTR id_new_item , wchar_t * lp_new_item )
{
2021-04-03 03:25:19 +03:00
return InsertMenuW ( hMenu , pos , flags , id_new_item , lp_new_item ) ;
2014-01-04 17:00:08 +04:00
}
// Adding a menu item
bool MsAppendMenu ( HMENU hMenu , UINT flags , UINT_PTR id , wchar_t * str )
{
2021-04-03 03:25:19 +03:00
return AppendMenuW ( hMenu , flags , id , str ) ;
2014-01-04 17:00:08 +04:00
}
// Display the menu
void MsUserModeTrayMenu ( HWND hWnd )
{
HMENU h ;
POINT p ;
wchar_t tmp [ MAX_SIZE ] ;
wchar_t caption [ MAX_SIZE ] ;
// Validate arguments
if ( hWnd = = NULL )
{
return ;
}
// Create a menu
h = CreatePopupMenu ( ) ;
MsAppendMenu ( h , MF_ENABLED | MF_STRING , 10001 , _UU ( " SVC_USERMODE_MENU_1 " ) ) ;
MsAppendMenu ( h , MF_SEPARATOR , 10002 , NULL ) ;
2021-04-03 03:25:19 +03:00
GetWindowTextW ( hWnd , caption , sizeof ( caption ) / sizeof ( caption [ 0 ] ) ) ;
2014-01-04 17:00:08 +04:00
UniFormat ( tmp , sizeof ( tmp ) , _UU ( " SVC_USERMODE_MENU_2 " ) , caption ) ;
MsAppendMenu ( h , MF_ENABLED | MF_STRING , 10003 , tmp ) ;
// Display the menu
GetCursorPos ( & p ) ;
SetForegroundWindow ( hWnd ) ;
TrackPopupMenu ( h , TPM_LEFTALIGN , p . x , p . y , 0 , hWnd , NULL ) ;
PostMessage ( hWnd , WM_NULL , 0 , 0 ) ;
DestroyMenu ( h ) ;
}
// Window procedure for the user mode
LRESULT CALLBACK MsUserModeWindowProc ( HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam )
{
wchar_t tmp [ MAX_SIZE ] ;
char title [ MAX_SIZE ] ;
wchar_t title_w [ MAX_SIZE ] ;
char value_name [ MAX_SIZE ] ;
static UINT taskbar_msg = 0 ;
// Validate arguments
if ( hWnd = = NULL )
{
return 0 ;
}
if ( msg = = taskbar_msg & & taskbar_msg ! = 0 )
{
// The taskbar was regenerated
2021-04-03 03:25:19 +03:00
if ( MsRegReadInt ( REG_CURRENT_USER , SVC_USERMODE_SETTING_KEY , value_name ) = = 0 )
2014-01-04 17:00:08 +04:00
{
MsRestoreIconOnTray ( ) ;
}
}
switch ( msg )
{
case WM_ENDSESSION :
// Resume
if ( wParam = = false )
{
break ;
}
case WM_CREATE :
// Start
exiting = false ;
g_start ( ) ;
GetWindowText ( hWnd , title , sizeof ( title ) ) ;
StrToUni ( title_w , sizeof ( title_w ) , title ) ;
UniFormat ( tmp , sizeof ( tmp ) , _UU ( " SVC_TRAY_TOOLTIP " ) , title ) ;
if ( taskbar_msg = = 0 )
{
taskbar_msg = RegisterWindowMessage ( " TaskbarCreated " ) ;
}
Format ( value_name , sizeof ( value_name ) , SVC_HIDETRAY_REG_VALUE , title_w ) ;
2021-04-03 03:25:19 +03:00
if ( MsRegReadInt ( REG_CURRENT_USER , SVC_USERMODE_SETTING_KEY , value_name ) = = 0 )
2014-01-04 17:00:08 +04:00
{
MsShowIconOnTray ( hWnd , tray_icon , tmp , WM_APP + 33 ) ;
}
break ;
case WM_APP + 33 :
if ( wParam = = 1 )
{
// The operation to the icon in the task tray
switch ( lParam )
{
case WM_RBUTTONDOWN :
// Right click
MsUserModeTrayMenu ( hWnd ) ;
break ;
case WM_LBUTTONDBLCLK :
// Left double-click
break ;
}
}
break ;
case WM_LBUTTONDOWN :
MsUserModeTrayMenu ( hWnd ) ;
break ;
case WM_QUERYENDSESSION :
if ( exiting = = false )
{
exiting = true ;
MsHideIconOnTray ( ) ;
g_stop ( ) ;
DestroyWindow ( hWnd ) ;
}
return TRUE ;
case WM_CLOSE :
// Stop
if ( exiting = = false )
{
exiting = true ;
g_stop ( ) ;
MsHideIconOnTray ( ) ;
DestroyWindow ( hWnd ) ;
}
break ;
case WM_DESTROY :
wnd_end = true ;
break ;
case WM_COMMAND :
switch ( wParam )
{
case 10001 :
GetWindowText ( hWnd , title , sizeof ( title ) ) ;
StrToUni ( title_w , sizeof ( title_w ) , title ) ;
// Display a confirmation message
if ( MsgBoxEx ( hWnd , MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2 |
MB_SYSTEMMODAL , _UU ( " SVC_HIDE_TRAY_MSG " ) , title , title ) = = IDOK )
{
char tmp [ MAX_SIZE ] ;
Format ( tmp , sizeof ( tmp ) , SVC_HIDETRAY_REG_VALUE , title_w ) ;
// Write to the registry
MsRegWriteInt ( REG_CURRENT_USER , SVC_USERMODE_SETTING_KEY , tmp , 1 ) ;
// Hide the icon
MsHideIconOnTray ( ) ;
}
break ;
case 10003 :
SendMessage ( hWnd , WM_CLOSE , 0 , 0 ) ;
break ;
}
break ;
}
return DefWindowProc ( hWnd , msg , wParam , lParam ) ;
}
// Get whether this instance is in user mode
bool MsIsUserMode ( )
{
return is_usermode ;
}
// Only run the test (for debugging)
void MsTestOnly ( )
{
g_start ( ) ;
GetLine ( NULL , 0 ) ;
g_stop ( ) ;
_exit ( 0 ) ;
}
// Stop the user-mode service
void MsStopUserModeSvc ( char * svc_name )
{
void * p ;
// Validate arguments
if ( svc_name = = NULL )
{
return ;
}
p = MsCreateUserModeSvcGlocalPulse ( svc_name ) ;
if ( p = = NULL )
{
return ;
}
MsSendGlobalPulse ( p ) ;
MsCloseGlobalPulse ( p ) ;
}
// Creating a global pulse for user-mode service
void * MsCreateUserModeSvcGlocalPulse ( char * svc_name )
{
char name [ MAX_SIZE ] ;
// Validate arguments
if ( svc_name = = NULL )
{
return NULL ;
}
MsGenerateUserModeSvcGlobalPulseName ( name , sizeof ( name ) , svc_name ) ;
return MsOpenOrCreateGlobalPulse ( name ) ;
}
// Get the global pulse name for the user-mode service
void MsGenerateUserModeSvcGlobalPulseName ( char * name , UINT size , char * svc_name )
{
wchar_t tmp [ MAX_SIZE ] ;
UCHAR hash [ SHA1_SIZE ] ;
// Validate arguments
if ( name = = NULL | | svc_name = = NULL )
{
return ;
}
UniFormat ( tmp , sizeof ( tmp ) , L " usersvc_%S_@_%s " , svc_name , MsGetUserNameW ( ) ) ;
UniTrim ( tmp ) ;
UniStrUpper ( tmp ) ;
2018-09-22 07:35:30 +03:00
Sha1 ( hash , tmp , UniStrLen ( tmp ) * sizeof ( wchar_t ) ) ;
2014-01-04 17:00:08 +04:00
BinToStr ( name , size , hash , sizeof ( hash ) ) ;
}
2015-04-03 23:58:09 +03:00
// Declare the beginning of use of a VLAN card
void MsBeginVLanCard ( )
{
Inc ( vlan_card_counter ) ;
}
// Declare the ending of use of a VLAN card
void MsEndVLanCard ( )
{
Dec ( vlan_card_counter ) ;
}
// Return the flag whether the VLAN cards must be stopped
bool MsIsVLanCardShouldStop ( )
{
return vlan_card_should_stop_flag ;
}
// Suspend procs
void MsProcEnterSuspend ( )
{
UINT64 giveup_tick = Tick64 ( ) + 2000 ;
2015-05-31 13:02:35 +03:00
UINT num = Count ( vlan_card_counter ) ;
vlan_is_in_suspend_mode = true ;
2015-04-03 23:58:09 +03:00
vlan_card_should_stop_flag = true ;
2015-05-31 13:02:35 +03:00
vlan_suspend_mode_begin_tick = Tick64 ( ) ;
2015-04-03 23:58:09 +03:00
while ( true )
{
UINT64 now = Tick64 ( ) ;
if ( now > = giveup_tick )
{
break ;
}
if ( Count ( vlan_card_counter ) = = 0 )
{
break ;
}
SleepThread ( 100 ) ;
}
if ( num > = 1 )
{
2015-05-31 13:02:35 +03:00
SleepThread ( 3000 ) ;
2015-04-03 23:58:09 +03:00
}
}
void MsProcLeaveSuspend ( )
{
vlan_card_should_stop_flag = false ;
2015-05-31 13:02:35 +03:00
vlan_is_in_suspend_mode = false ;
vlan_suspend_mode_begin_tick = Tick64 ( ) ;
}
UINT64 MsGetSuspendModeBeginTick ( )
{
if ( vlan_is_in_suspend_mode )
{
return Tick64 ( ) ;
}
return vlan_suspend_mode_begin_tick ;
2015-04-03 23:58:09 +03:00
}
// Suspend handler window proc
LRESULT CALLBACK MsSuspendHandlerWindowProc ( HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam )
{
MS_SUSPEND_HANDLER * h ;
CREATESTRUCT * cs ;
// Validate arguments
if ( hWnd = = NULL )
{
return 0 ;
}
h = ( MS_SUSPEND_HANDLER * ) GetWindowLongPtrA ( hWnd , GWLP_USERDATA ) ;
if ( h = = NULL & & msg ! = WM_CREATE )
{
goto LABEL_END ;
}
switch ( msg )
{
case WM_CREATE :
cs = ( CREATESTRUCT * ) lParam ;
h = ( MS_SUSPEND_HANDLER * ) cs - > lpCreateParams ;
SetWindowLongPtrA ( hWnd , GWLP_USERDATA , ( LONG_PTR ) h ) ;
break ;
case WM_POWERBROADCAST :
2021-04-03 03:25:19 +03:00
switch ( wParam )
2015-04-03 23:58:09 +03:00
{
2021-04-03 03:25:19 +03:00
case PBT_APMSUSPEND :
MsProcEnterSuspend ( ) ;
return 1 ;
case PBT_APMRESUMEAUTOMATIC :
case PBT_APMRESUMESUSPEND :
MsProcLeaveSuspend ( ) ;
return 1 ;
2015-04-03 23:58:09 +03:00
}
break ;
case WM_CLOSE :
/*if (h->AboutToClose == false)
{
return 0 ;
} */
break ;
case WM_DESTROY :
PostQuitMessage ( 0 ) ;
break ;
}
LABEL_END :
return DefWindowProc ( hWnd , msg , wParam , lParam ) ;
}
// Suspend handler thread
void MsSuspendHandlerThreadProc ( THREAD * thread , void * param )
{
char wndclass_name [ MAX_PATH ] ;
WNDCLASS wc ;
HWND hWnd ;
MSG msg ;
MS_SUSPEND_HANDLER * h = ( MS_SUSPEND_HANDLER * ) param ;
// Validate arguments
if ( h = = NULL | | thread = = NULL )
{
return ;
}
Format ( wndclass_name , sizeof ( wndclass_name ) , " WNDCLASS_%X " , Rand32 ( ) ) ;
Zero ( & wc , sizeof ( wc ) ) ;
wc . hbrBackground = ( HBRUSH ) GetStockObject ( WHITE_BRUSH ) ;
wc . hCursor = LoadCursor ( NULL , IDC_ARROW ) ;
wc . hIcon = NULL ;
wc . hInstance = ms - > hInst ;
wc . lpfnWndProc = MsSuspendHandlerWindowProc ;
wc . lpszClassName = wndclass_name ;
if ( RegisterClassA ( & wc ) = = 0 )
{
NoticeThreadInit ( thread ) ;
return ;
}
hWnd = CreateWindowA ( wndclass_name , wndclass_name , WS_OVERLAPPEDWINDOW ,
CW_USEDEFAULT , CW_USEDEFAULT , CW_USEDEFAULT , CW_USEDEFAULT ,
NULL , NULL , ms - > hInst , h ) ;
h - > hWnd = hWnd ;
NoticeThreadInit ( thread ) ;
if ( hWnd = = NULL )
{
UnregisterClassA ( wndclass_name , ms - > hInst ) ;
return ;
}
//ShowWindow(hWnd, SW_SHOWNORMAL);
while ( GetMessage ( & msg , NULL , 0 , 0 ) )
{
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
vlan_card_should_stop_flag = false ;
2015-05-31 13:02:35 +03:00
vlan_is_in_suspend_mode = false ;
vlan_suspend_mode_begin_tick = 0 ;
2015-04-03 23:58:09 +03:00
DestroyWindow ( hWnd ) ;
UnregisterClassA ( wndclass_name , ms - > hInst ) ;
}
// New suspend handler
MS_SUSPEND_HANDLER * MsNewSuspendHandler ( )
{
THREAD * t ;
MS_SUSPEND_HANDLER * h ;
if ( Inc ( suspend_handler_singleton ) > = 2 )
{
Dec ( suspend_handler_singleton ) ;
return NULL ;
}
2015-05-31 13:02:35 +03:00
vlan_card_should_stop_flag = false ;
vlan_is_in_suspend_mode = false ;
vlan_suspend_mode_begin_tick = 0 ;
2015-04-03 23:58:09 +03:00
h = ZeroMalloc ( sizeof ( MS_SUSPEND_HANDLER ) ) ;
t = NewThread ( MsSuspendHandlerThreadProc , h ) ;
WaitThreadInit ( t ) ;
h - > Thread = t ;
return h ;
}
void MsFreeSuspendHandler ( MS_SUSPEND_HANDLER * h )
{
// Validate arguments
if ( h = = NULL )
{
return ;
}
if ( h - > hWnd ! = NULL )
{
h - > AboutToClose = true ;
PostMessageA ( h - > hWnd , WM_CLOSE , 0 , 0 ) ;
}
WaitThread ( h - > Thread , INFINITE ) ;
ReleaseThread ( h - > Thread ) ;
Free ( h ) ;
Dec ( suspend_handler_singleton ) ;
vlan_card_should_stop_flag = false ;
}
2014-01-04 17:00:08 +04:00
// Start in user mode
void MsUserModeW ( wchar_t * title , SERVICE_FUNCTION * start , SERVICE_FUNCTION * stop , UINT icon )
{
WNDCLASS wc ;
HINSTANCE hDll ;
HWND hWnd ;
MSG msg ;
INSTANCE * inst ;
char title_a [ MAX_PATH ] ;
MS_USERMODE_SVC_PULSE_THREAD_PARAM p ;
THREAD * recv_thread = NULL ;
// Validate arguments
if ( title = = NULL | | start = = NULL | | stop = = NULL )
{
return ;
}
UniToStr ( title_a , sizeof ( title_a ) , title ) ;
is_usermode = true ;
g_start = start ;
g_stop = stop ;
inst = NewSingleInstance ( NULL ) ;
if ( inst = = NULL )
{
2021-04-03 03:25:19 +03:00
MsgBoxEx ( NULL , MB_ICONINFORMATION , _UU ( " SVC_USERMODE_MUTEX " ) , ms - > ExeFileNameW ) ;
2014-01-04 17:00:08 +04:00
return ;
}
if ( Is64 ( ) )
{
2020-07-27 08:25:00 +03:00
hDll = MsLoadLibraryAsDataFile ( PENCORE_DLL_NAME ) ;
2014-01-04 17:00:08 +04:00
}
else
{
2020-07-27 08:25:00 +03:00
hDll = MsLoadLibrary ( PENCORE_DLL_NAME ) ;
2014-01-04 17:00:08 +04:00
}
// Read icon
tray_icon = LoadImage ( hDll , MAKEINTRESOURCE ( icon ) , IMAGE_ICON , 16 , 16 ,
2021-04-03 03:25:19 +03:00
LR_SHARED | LR_VGACOLOR ) ;
2014-01-04 17:00:08 +04:00
// Creating the main window
Zero ( & wc , sizeof ( wc ) ) ;
wc . hbrBackground = ( HBRUSH ) GetStockObject ( WHITE_BRUSH ) ;
wc . hCursor = LoadCursor ( NULL , IDC_ARROW ) ;
wc . hIcon = LoadIcon ( hDll , MAKEINTRESOURCE ( icon ) ) ;
wc . hInstance = ms - > hInst ;
wc . lpfnWndProc = MsUserModeWindowProc ;
wc . lpszClassName = title_a ;
if ( RegisterClass ( & wc ) = = 0 )
{
return ;
}
hWnd = CreateWindow ( title_a , title_a , WS_OVERLAPPEDWINDOW ,
CW_USEDEFAULT , CW_USEDEFAULT , CW_USEDEFAULT , CW_USEDEFAULT ,
NULL , NULL , ms - > hInst , NULL ) ;
if ( hWnd = = NULL )
{
return ;
}
Zero ( & p , sizeof ( p ) ) ;
p . hWnd = hWnd ;
p . GlobalPulse = MsCreateUserModeSvcGlocalPulse ( g_service_name ) ;
if ( p . GlobalPulse ! = NULL )
{
// Start the global pulse monitoring thread for termination
p . Halt = false ;
recv_thread = NewThread ( MsUserModeGlobalPulseRecvThread , & p ) ;
}
hWndUsermode = hWnd ;
wnd_end = false ;
// Window loop
while ( wnd_end = = false )
{
GetMessage ( & msg , NULL , 0 , 0 ) ;
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
FreeSingleInstance ( inst ) ;
p . hWnd = NULL ;
hWndUsermode = NULL ;
if ( p . GlobalPulse ! = NULL )
{
// Terminate the monitoring thread of termination global pulse
p . Halt = true ;
MsSendGlobalPulse ( p . GlobalPulse ) ;
WaitThread ( recv_thread , INFINITE ) ;
ReleaseThread ( recv_thread ) ;
MsCloseGlobalPulse ( p . GlobalPulse ) ;
}
// Might abort
_exit ( 0 ) ;
}
// The thread that wait for global pulse to stop the user mode service
void MsUserModeGlobalPulseRecvThread ( THREAD * thread , void * param )
{
MS_USERMODE_SVC_PULSE_THREAD_PARAM * p = ( MS_USERMODE_SVC_PULSE_THREAD_PARAM * ) param ;
// Validate arguments
if ( thread = = NULL | | p = = NULL )
{
return ;
}
while ( p - > Halt = = false )
{
if ( MsWaitForGlobalPulse ( p - > GlobalPulse , INFINITE ) )
{
break ;
}
}
if ( p - > hWnd ! = NULL )
{
PostMessageA ( p - > hWnd , WM_CLOSE , 0 , 0 ) ;
}
}
// Service stopping procedure main thread
void MsServiceStoperMainThread ( THREAD * t , void * p )
{
// Stopping procedure
g_stop ( ) ;
}
// Service stop procedure
bool MsServiceStopProc ( )
{
THREAD * thread ;
bool ret = true ;
UINT64 selfkill_timeout = Tick64 ( ) + SVC_SELFKILL_TIMEOUT ;
thread = NewThread ( MsServiceStoperMainThread , NULL ) ;
while ( WaitThread ( thread , 250 ) = = false )
{
if ( Tick64 ( ) > = selfkill_timeout )
{
// Suicide when it freezes
ret = false ;
break ;
}
// During stopping procedure to complete, call the SetServiceStatus periodically
status . dwWin32ExitCode = 0 ;
status . dwWaitHint = 100000 ;
status . dwCheckPoint + + ;
status . dwCurrentState = SERVICE_STOP_PENDING ;
_SetServiceStatus ( ssh , & status ) ;
}
// Report that the stopping is complete
status . dwWin32ExitCode = 0 ;
status . dwWaitHint = 0 ;
status . dwCheckPoint = 0 ;
status . dwCurrentState = SERVICE_STOPPED ;
_SetServiceStatus ( ssh , & status ) ;
if ( ret = = false )
{
// Force termination here if this has committed suicide
_exit ( - 1 ) ;
}
else
{
ReleaseThread ( thread ) ;
}
return ret ;
}
// Service handler
2021-03-01 03:46:11 +03:00
void CALLBACK MsServiceHandler ( DWORD opcode )
2014-01-04 17:00:08 +04:00
{
switch ( opcode )
{
case SERVICE_CONTROL_SHUTDOWN :
case SERVICE_CONTROL_STOP :
// Stopping request
status . dwWin32ExitCode = 0 ;
status . dwWaitHint = 100000 ;
status . dwCheckPoint = 0 ;
status . dwCurrentState = SERVICE_STOP_PENDING ;
// Set the stopping event
if ( service_stop_event ! = NULL )
{
SetEvent ( service_stop_event ) ;
}
break ;
}
_SetServiceStatus ( ssh , & status ) ;
}
// Dispatch function of the service
2021-03-01 03:46:11 +03:00
void CALLBACK MsServiceDispatcher ( DWORD argc , LPTSTR * argv )
2014-01-04 17:00:08 +04:00
{
// Creating a stopping event
service_stop_event = CreateEventA ( NULL , true , false , NULL ) ;
// Preparing for the service
Zero ( & status , sizeof ( status ) ) ;
status . dwServiceType = SERVICE_WIN32 ;
status . dwCurrentState = SERVICE_START_PENDING ;
status . dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ;
ssh = _RegisterServiceCtrlHandler ( g_service_name , MsServiceHandler ) ;
if ( ssh = = NULL )
{
MessageBox ( NULL , " RegisterServiceCtrlHandler() Failed. " , " MsServiceDispatcher() " , MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION ) ;
return ;
}
status . dwWaitHint = 300000 ;
status . dwCheckPoint = 0 ;
status . dwCheckPoint + + ;
status . dwCurrentState = SERVICE_START_PENDING ;
_SetServiceStatus ( ssh , & status ) ;
// Report the start completion
status . dwWaitHint = 0 ;
status . dwCheckPoint = 0 ;
status . dwCurrentState = SERVICE_RUNNING ;
_SetServiceStatus ( ssh , & status ) ;
//// Initialization
// Start of the Mayaqua
2018-10-08 05:03:58 +03:00
# if defined(_DEBUG) || defined(DEBUG) // In VC++ compilers, the macro is "_DEBUG", not "DEBUG".
// If set memcheck = true, the program will be vitally slow since it will log all malloc() / realloc() / free() calls to find the cause of memory leak.
// For normal debug we set memcheck = false.
// Please set memcheck = true if you want to test the cause of memory leaks.
InitMayaqua ( false , true , 0 , NULL ) ;
2018-09-15 20:12:21 +03:00
# else
2014-01-04 17:00:08 +04:00
InitMayaqua ( false , false , 0 , NULL ) ;
2018-09-15 20:12:21 +03:00
# endif
2014-01-04 17:00:08 +04:00
// Stop the MS-IME
MsDisableIme ( ) ;
// Service operation start
g_start ( ) ;
MsUpdateServiceConfig ( g_service_name ) ;
// Wait for the stopping event to be signaled state
WaitForSingleObject ( service_stop_event , INFINITE ) ;
// Service operation stop
MsServiceStopProc ( ) ;
}
// Start as a test mode
void MsTestMode ( char * title , SERVICE_FUNCTION * start , SERVICE_FUNCTION * stop )
{
wchar_t * title_w = CopyStrToUni ( title ) ;
MsTestModeW ( title_w , start , stop ) ;
Free ( title_w ) ;
}
void MsTestModeW ( wchar_t * title , SERVICE_FUNCTION * start , SERVICE_FUNCTION * stop )
{
INSTANCE * inst ;
// Validate arguments
if ( title = = NULL | | start = = NULL | | stop = = NULL )
{
return ;
}
is_usermode = true ;
inst = NewSingleInstance ( NULL ) ;
if ( inst = = NULL )
{
// Already started
MsgBoxEx ( NULL , MB_ICONINFORMATION , _UU ( " SVC_TEST_MUTEX " ) , ms - > ExeFileNameW ) ;
return ;
}
// Start
start ( ) ;
// Display the message
MsgBoxEx ( NULL , MB_ICONINFORMATION | MB_SYSTEMMODAL , _UU ( " SVC_TEST_MSG " ) , title ) ;
// Stop
stop ( ) ;
FreeSingleInstance ( inst ) ;
}
// Write the process ID of the process which is calling the service manager
void MsWriteCallingServiceManagerProcessId ( char * svcname , UINT pid )
{
char tmp [ MAX_PATH ] ;
Format ( tmp , sizeof ( tmp ) , SVC_CALLING_SM_PROCESS_ID_KEY , svcname ) ;
if ( pid ! = 0 )
{
MsRegWriteInt ( REG_LOCAL_MACHINE , tmp , SVC_CALLING_SM_PROCESS_ID_VALUE , pid ) ;
MsRegWriteInt ( REG_CURRENT_USER , tmp , SVC_CALLING_SM_PROCESS_ID_VALUE , pid ) ;
}
else
{
MsRegDeleteValue ( REG_LOCAL_MACHINE , tmp , SVC_CALLING_SM_PROCESS_ID_VALUE ) ;
MsRegDeleteKey ( REG_LOCAL_MACHINE , tmp ) ;
MsRegDeleteValue ( REG_CURRENT_USER , tmp , SVC_CALLING_SM_PROCESS_ID_VALUE ) ;
MsRegDeleteKey ( REG_CURRENT_USER , tmp ) ;
}
}
// Get the process ID of the process which is calling the service manager
UINT MsReadCallingServiceManagerProcessId ( char * svcname , bool current_user )
{
char tmp [ MAX_PATH ] ;
// Validate arguments
if ( svcname = = NULL )
{
return 0 ;
}
Format ( tmp , sizeof ( tmp ) , SVC_CALLING_SM_PROCESS_ID_KEY , svcname ) ;
return MsRegReadInt ( current_user ? REG_CURRENT_USER : REG_LOCAL_MACHINE , tmp , SVC_CALLING_SM_PROCESS_ID_VALUE ) ;
}
// Service main function
UINT MsService ( char * name , SERVICE_FUNCTION * start , SERVICE_FUNCTION * stop , UINT icon , char * cmd_line )
{
UINT mode ;
UINT ret = 0 ;
char * arg ;
wchar_t * arg_w ;
TOKEN_LIST * t = NULL ;
UNI_TOKEN_LIST * ut = NULL ;
char * service_name ;
wchar_t * service_title ;
wchar_t * service_description ;
wchar_t * service_title_uni ;
char tmp [ MAX_SIZE ] ;
bool restoreReg = false ;
bool silent = false ;
bool is_win32_service_mode = false ;
// Validate arguments
if ( name = = NULL | | start = = NULL | | stop = = NULL )
{
return ret ;
}
g_start = start ;
g_stop = stop ;
StrCpy ( g_service_name , sizeof ( g_service_name ) , name ) ;
StrLower ( g_service_name ) ;
// Determine whether it's in Win32 service mode
if ( cmd_line ! = NULL & & lstrcmpiA ( cmd_line , SVC_ARG_SERVICE ) = = 0 )
{
HINSTANCE h_advapi32 = LoadLibraryA ( " advapi32.dll " ) ;
if ( h_advapi32 ! = NULL )
{
// Check whether there is the SCM in the service mode
_StartServiceCtrlDispatcher =
( BOOL ( __stdcall * ) ( const LPSERVICE_TABLE_ENTRY ) )
GetProcAddress ( h_advapi32 , " StartServiceCtrlDispatcherW " ) ;
_RegisterServiceCtrlHandler =
( SERVICE_STATUS_HANDLE ( __stdcall * ) ( LPCTSTR , LPHANDLER_FUNCTION ) )
GetProcAddress ( h_advapi32 , " RegisterServiceCtrlHandlerW " ) ;
_SetServiceStatus =
( BOOL ( __stdcall * ) ( SERVICE_STATUS_HANDLE , LPSERVICE_STATUS ) )
GetProcAddress ( h_advapi32 , " SetServiceStatus " ) ;
if ( _StartServiceCtrlDispatcher ! = NULL & &
_RegisterServiceCtrlHandler ! = NULL & &
_SetServiceStatus ! = NULL )
{
is_win32_service_mode = true ;
}
}
}
// Run the service using the SCM in the case of Win32 service mode
if ( is_win32_service_mode )
{
SERVICE_TABLE_ENTRY dispatch_table [ ] =
{
{ " " , MsServiceDispatcher } ,
{ NULL , NULL } ,
} ;
MsSetErrorModeToSilent ( ) ;
if ( _StartServiceCtrlDispatcher ( dispatch_table ) = = false )
{
MessageBox ( NULL , " StartServiceCtrlDispatcher() Failed. " , " MsServiceMode() " , MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION ) ;
}
else
{
MsUpdateServiceConfig ( g_service_name ) ;
}
// Abort here in the case of using the SCM
_exit ( 0 ) ;
return 0 ;
}
// Start of the Mayaqua
2018-10-08 05:03:58 +03:00
# if defined(_DEBUG) || defined(DEBUG) // In VC++ compilers, the macro is "_DEBUG", not "DEBUG".
// If set memcheck = true, the program will be vitally slow since it will log all malloc() / realloc() / free() calls to find the cause of memory leak.
// For normal debug we set memcheck = false.
// Please set memcheck = true if you want to test the cause of memory leaks.
InitMayaqua ( false , true , 0 , NULL ) ;
2018-09-15 20:12:21 +03:00
# else
2014-01-04 17:00:08 +04:00
InitMayaqua ( false , false , 0 , NULL ) ;
2018-09-15 20:12:21 +03:00
# endif
2014-01-04 17:00:08 +04:00
// Stop the MS-IME
MsDisableIme ( ) ;
// Get the information about the service from the string table
Format ( tmp , sizeof ( tmp ) , SVC_NAME , name ) ;
service_name = _SS ( tmp ) ;
Format ( tmp , sizeof ( tmp ) , SVC_TITLE , name ) ;
service_title = _UU ( tmp ) ;
service_title_uni = _UU ( tmp ) ;
Format ( tmp , sizeof ( tmp ) , SVC_DESCRIPT , name ) ;
service_description = _UU ( tmp ) ;
if ( StrLen ( service_name ) = = 0 | | UniStrLen ( service_title ) = = 0 )
{
// The service information isn't found
MsgBoxEx ( NULL , MB_ICONSTOP , _UU ( " SVC_NOT_FOUND " ) , name ) ;
}
else
{
wchar_t path [ MAX_SIZE ] ;
// Check the argument
mode = SVC_MODE_NONE ;
t = GetCommandLineToken ( ) ;
arg = NULL ;
ut = GetCommandLineUniToken ( ) ;
arg_w = NULL ;
if ( t - > NumTokens > = 1 )
{
arg = t - > Token [ 0 ] ;
}
if ( t - > NumTokens > = 2 )
{
if ( StrCmpi ( t - > Token [ 1 ] , SVC_ARG_SILENT ) = = 0 )
{
silent = true ;
}
}
if ( ut - > NumTokens > = 1 )
{
arg_w = ut - > Token [ 0 ] ;
}
if ( arg ! = NULL )
{
if ( StrCmpi ( arg , SVC_ARG_INSTALL ) = = 0 )
{
mode = SVC_MODE_INSTALL ;
}
if ( StrCmpi ( arg , SVC_ARG_UNINSTALL ) = = 0 )
{
mode = SVC_MODE_UNINSTALL ;
}
if ( StrCmpi ( arg , SVC_ARG_START ) = = 0 )
{
mode = SVC_MODE_START ;
}
if ( StrCmpi ( arg , SVC_ARG_STOP ) = = 0 )
{
mode = SVC_MODE_STOP ;
}
if ( StrCmpi ( arg , SVC_ARG_TEST ) = = 0 )
{
mode = SVC_MODE_TEST ;
}
if ( StrCmpi ( arg , SVC_ARG_USERMODE ) = = 0 )
{
mode = SVC_MODE_USERMODE ;
}
if ( StrCmpi ( arg , SVC_ARG_SETUP_INSTALL ) = = 0 )
{
mode = SVC_MODE_SETUP_INSTALL ;
}
if ( StrCmpi ( arg , SVC_ARG_SETUP_UNINSTALL ) = = 0 )
{
mode = SVC_MODE_SETUP_UNINSTALL ;
}
if ( StrCmpi ( arg , SVC_ARG_TCP ) = = 0 )
{
mode = SVC_MODE_TCP ;
}
if ( StrCmpi ( arg , SVC_ARG_TCP_UAC ) = = 0 )
{
mode = SVC_MODE_TCP_UAC ;
}
if ( StrCmpi ( arg , SVC_ARG_TCP_SETUP ) = = 0 )
{
mode = SVC_MODE_TCPSETUP ;
}
if ( StrCmpi ( arg , SVC_ARG_TRAFFIC ) = = 0 )
{
mode = SVC_MODE_TRAFFIC ;
}
if ( StrCmpi ( arg , SVC_ARG_UIHELP ) = = 0 )
{
mode = SVC_MODE_UIHELP ;
}
if ( StrCmpi ( arg , SVC_ARG_USERMODE_SHOWTRAY ) = = 0 )
{
char tmp [ MAX_SIZE ] ;
mode = SVC_MODE_USERMODE ;
Format ( tmp , sizeof ( tmp ) , SVC_HIDETRAY_REG_VALUE , service_title ) ;
MsRegDeleteValue ( REG_CURRENT_USER , SVC_USERMODE_SETTING_KEY , tmp ) ;
}
if ( StrCmpi ( arg , SVC_ARG_USERMODE_HIDETRAY ) = = 0 )
{
char tmp [ MAX_SIZE ] ;
mode = SVC_MODE_USERMODE ;
Format ( tmp , sizeof ( tmp ) , SVC_HIDETRAY_REG_VALUE , service_title ) ;
MsRegWriteInt ( REG_CURRENT_USER , SVC_USERMODE_SETTING_KEY , tmp , 1 ) ;
}
if ( StrCmpi ( arg , SVC_ARG_SERVICE ) = = 0 )
{
mode = SVC_MODE_SERVICE ;
}
if ( mode ! = SVC_MODE_NONE )
{
// Network Config
MsInitGlobalNetworkConfig ( ) ;
}
}
// Get the command-line name when running as a service
UniFormat ( path , sizeof ( path ) , SVC_RUN_COMMANDLINE , ms - > ExeFileNameW ) ;
if ( ( mode = = SVC_MODE_INSTALL | | mode = = SVC_MODE_UNINSTALL | | mode = = SVC_MODE_START | |
mode = = SVC_MODE_STOP | | mode = = SVC_MODE_SERVICE ) & &
( ms - > IsNt = = false ) )
{
// Tried to use the command for the NT in non-WindowsNT system
MsgBox ( NULL , MB_ICONSTOP , _UU ( " SVC_NT_ONLY " ) ) ;
}
else if ( ( mode = = SVC_MODE_INSTALL | | mode = = SVC_MODE_UNINSTALL | | mode = = SVC_MODE_START | |
mode = = SVC_MODE_STOP | | mode = = SVC_MODE_SERVICE ) & &
( ms - > IsAdmin = = false ) )
{
2018-05-17 00:47:10 +03:00
// Do not have Administrators privilege
2014-01-04 17:00:08 +04:00
MsgBox ( NULL , MB_ICONEXCLAMATION , _UU ( " SVC_NOT_ADMIN " ) ) ;
}
else
{
// Performs processing depend on mode
switch ( mode )
{
case SVC_MODE_NONE :
// Exit by showing a guidance message
if ( arg_w ! = NULL & & UniEndWith ( arg_w , L " .vpn " ) )
{
if ( MsgBox ( NULL , MB_ICONQUESTION | MB_YESNO , _UU ( " CM_VPN_FILE_CLICKED " ) ) = = IDYES )
{
wchar_t vpncmgr [ MAX_PATH ] ;
wchar_t filename [ MAX_PATH ] ;
UniFormat ( filename , sizeof ( filename ) , L " \" %s \" " , arg_w ) ;
2020-07-27 08:25:00 +03:00
UniFormat ( vpncmgr , sizeof ( vpncmgr ) , L " %s \\ vpncmgr.exe " , MsGetExeDirNameW ( ) ) ;
2014-01-04 17:00:08 +04:00
RunW ( vpncmgr , filename , false , false ) ;
}
}
else
{
MsgBoxEx ( NULL , MB_ICONINFORMATION , _UU ( " SVC_HELP " ) ,
service_title , service_name , service_title , service_title , service_name , service_title , service_name , service_title , service_name , service_title , service_name , service_title , service_title ) ;
}
break ;
case SVC_MODE_SETUP_INSTALL :
// Setup.exe installation mode
// Uninstall the old version
MsWriteCallingServiceManagerProcessId ( service_name , MsGetCurrentProcessId ( ) ) ;
restoreReg = true ;
if ( MsIsServiceInstalled ( service_name ) )
{
if ( MsIsServiceRunning ( service_name ) )
{
MsStopService ( service_name ) ;
}
MsUninstallService ( service_name ) ;
}
if ( MsInstallServiceW ( service_name , service_title , service_description , path ) = = false )
{
ret = 1 ;
}
MsStartService ( service_name ) ;
MsWriteCallingServiceManagerProcessId ( service_name , 0 ) ;
break ;
case SVC_MODE_SETUP_UNINSTALL :
// Setup.exe uninstall mode
MsWriteCallingServiceManagerProcessId ( service_name , MsGetCurrentProcessId ( ) ) ;
restoreReg = true ;
if ( MsIsServiceInstalled ( service_name ) )
{
if ( MsIsServiceRunning ( service_name ) )
{
MsStopService ( service_name ) ;
}
if ( MsUninstallService ( service_name ) = = false )
{
ret = 1 ;
}
}
break ;
case SVC_MODE_INSTALL :
// Install the service
// Check whether it is already installed
MsWriteCallingServiceManagerProcessId ( service_name , MsGetCurrentProcessId ( ) ) ;
restoreReg = true ;
if ( MsIsServiceInstalled ( service_name ) )
{
// Already installed
// Show a message asking if you want to uninstall
if ( silent = = true )
{
// Always cancel the operation
break ;
}
if ( MsgBoxEx ( NULL , MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2 , _UU ( " SVC_ALREADY_INSTALLED " ) ,
service_title , service_name ) = = IDNO )
{
// Cancel the operation
break ;
}
else
{
// Whether the existing service is working?
if ( MsIsServiceRunning ( service_name ) )
{
// Try to stop
if ( MsStopService ( service_name ) = = false )
{
// Failed to stop
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONSTOP , _UU ( " SVC_STOP_FAILED " ) ,
service_title , service_name ) ;
}
break ;
}
}
// Uninstall
if ( MsUninstallService ( service_name ) = = false )
{
// Failed to uninstall
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONSTOP , _UU ( " SVC_UNINSTALL_FAILED " ) ,
service_title , service_name ) ;
}
break ;
}
}
}
// Do the installation
if ( MsInstallServiceW ( service_name , service_title , service_description , path ) = = false )
{
// Failed to install
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONSTOP , _UU ( " SVC_INSTALL_FAILED " ) ,
service_title , service_name ) ;
}
break ;
}
// Start the service
if ( MsStartService ( service_name ) = = false )
{
// Failed to start
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONEXCLAMATION , _UU ( " SVC_INSTALL_FAILED_2 " ) ,
service_title , service_name , path ) ;
}
break ;
}
// All successful
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONINFORMATION , _UU ( " SVC_INSTALL_OK " ) ,
service_title , service_name , path ) ;
}
break ;
case SVC_MODE_UNINSTALL :
// Uninstall the service
// Check whether it is already installed
MsWriteCallingServiceManagerProcessId ( service_name , MsGetCurrentProcessId ( ) ) ;
restoreReg = true ;
if ( MsIsServiceInstalled ( service_name ) = = false )
{
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONEXCLAMATION , _UU ( " SVC_NOT_INSTALLED " ) ,
service_title , service_name , path ) ;
}
break ;
}
// If the service is currently running, stop it
if ( MsIsServiceRunning ( service_name ) )
{
// Stop the service
if ( MsStopService ( service_name ) = = false )
{
// Failed to stop
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONSTOP , _UU ( " SVC_STOP_FAILED " ) ,
service_title , service_name ) ;
}
break ;
}
}
// Uninstall the service
if ( MsUninstallService ( service_name ) = = false )
{
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONSTOP , _UU ( " SVC_UNINSTALL_FAILED " ) ,
service_title , service_name ) ;
}
break ;
}
// All successful
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONINFORMATION , _UU ( " SVC_UNINSTALL_OK " ) ,
service_title , service_name ) ;
}
break ;
case SVC_MODE_START :
// Start the service
MsWriteCallingServiceManagerProcessId ( service_name , MsGetCurrentProcessId ( ) ) ;
restoreReg = true ;
if ( MsIsServiceInstalled ( service_name ) = = false )
{
// Service is not installed
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONEXCLAMATION , _UU ( " SVC_NOT_INSTALLED " ) ,
service_title , service_name ) ;
}
break ;
}
// Confirm whether the service is running
if ( MsIsServiceRunning ( service_name ) )
{
// Service is running
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONINFORMATION , _UU ( " SVR_ALREADY_START " ) ,
service_title , service_name ) ;
}
break ;
}
// Start the service
if ( MsStartService ( service_name ) = = false )
{
// Failed to start
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONEXCLAMATION , _UU ( " SVC_START_FAILED " ) ,
service_title , service_name ) ;
}
break ;
}
// All successful
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONINFORMATION , _UU ( " SVC_START_OK " ) ,
service_title , service_name ) ;
}
break ;
case SVC_MODE_STOP :
// Stop the service
MsWriteCallingServiceManagerProcessId ( service_name , MsGetCurrentProcessId ( ) ) ;
restoreReg = true ;
if ( MsIsServiceInstalled ( service_name ) = = false )
{
// Service is not installed
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONEXCLAMATION , _UU ( " SVC_NOT_INSTALLED " ) ,
service_title , service_name ) ;
}
break ;
}
// Confirm whether the service is running
if ( MsIsServiceRunning ( service_name ) = = false )
{
// The service is stopped
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONINFORMATION , _UU ( " SVC_ALREADY_STOP " ) ,
service_title , service_name ) ;
}
break ;
}
// Stop the service
if ( MsStopService ( service_name ) = = false )
{
// Failed to stop
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONEXCLAMATION , _UU ( " SVC_STOP_FAILED " ) ,
service_title , service_name ) ;
}
break ;
}
// All successful
if ( silent = = false )
{
MsgBoxEx ( NULL , MB_ICONINFORMATION , _UU ( " SVC_STOP_OK " ) ,
service_title , service_name ) ;
}
break ;
case SVC_MODE_TEST :
// Test mode
MsTestModeW ( service_title , start , stop ) ;
break ;
case SVC_MODE_USERMODE :
// User mode
MsUserModeW ( service_title , start , stop , icon ) ;
break ;
case SVC_MODE_SERVICE :
// Run as a service
2018-05-17 00:47:10 +03:00
// Obsoleted (2012.12.31) (Do this in the above code)
2014-01-04 17:00:08 +04:00
//MsServiceMode(start, stop);
break ;
case SVC_MODE_TCP :
case SVC_MODE_TCP_UAC :
// TCP Utility
InitCedar ( ) ;
InitWinUi ( service_title_uni , NULL , 0 ) ;
2021-04-03 03:25:19 +03:00
if ( MsIsAdmin ( ) = = false & & mode ! = SVC_MODE_TCP_UAC )
2014-01-04 17:00:08 +04:00
{
void * handle = NULL ;
if ( MsExecuteEx2W ( ms - > ExeFileNameW , SVC_ARG_TCP_UAC_W , & handle , true ) = = false )
{
ShowTcpIpConfigUtil ( NULL , true ) ;
}
else
{
MsWaitProcessExit ( handle ) ;
}
}
else
{
ShowTcpIpConfigUtil ( NULL , true ) ;
}
FreeWinUi ( ) ;
FreeCedar ( ) ;
break ;
case SVC_MODE_TCPSETUP :
// TCP optimization mode (This is called by the installer)
InitCedar ( ) ;
InitWinUi ( service_title_uni , NULL , 0 ) ;
2021-04-03 03:25:19 +03:00
if ( MsIsAdmin ( ) = = false )
2014-01-04 17:00:08 +04:00
{
void * handle = NULL ;
if ( MsExecuteEx2W ( ms - > ExeFileNameW , arg_w , & handle , true ) = = false )
{
ShowTcpIpConfigUtil ( NULL , false ) ;
}
else
{
MsWaitProcessExit ( handle ) ;
}
}
else
{
ShowTcpIpConfigUtil ( NULL , false ) ;
}
FreeWinUi ( ) ;
FreeCedar ( ) ;
break ;
case SVC_MODE_TRAFFIC :
// Communication throughput measurement tool
InitCedar ( ) ;
InitWinUi ( service_title_uni , NULL , 0 ) ;
CmTraffic ( NULL ) ;
FreeWinUi ( ) ;
FreeCedar ( ) ;
break ;
case SVC_MODE_UIHELP :
// Starting the UI Helper
CnStart ( ) ;
break ;
}
}
FreeToken ( t ) ;
UniFreeToken ( ut ) ;
if ( restoreReg )
{
MsWriteCallingServiceManagerProcessId ( service_name , 0 ) ;
}
}
FreeMayaqua ( ) ;
return 0 ;
}
// Get the user name of the specified session
wchar_t * MsGetSessionUserName ( UINT session_id )
{
if ( MsIsTerminalServiceInstalled ( ) | | MsIsUserSwitchingInstalled ( ) )
{
wchar_t * ret ;
wchar_t * name ;
2021-03-01 03:46:11 +03:00
DWORD size = 0 ;
2021-04-03 03:25:19 +03:00
if ( WTSQuerySessionInformationW ( WTS_CURRENT_SERVER_HANDLE , session_id ,
WTSUserName , ( LPWSTR * ) & name , & size ) = = false )
2014-01-04 17:00:08 +04:00
{
return NULL ;
}
if ( name = = NULL | | UniStrLen ( name ) = = 0 )
{
ret = NULL ;
}
else
{
ret = UniCopyStr ( name ) ;
}
2021-04-03 03:25:19 +03:00
WTSFreeMemory ( name ) ;
2014-01-04 17:00:08 +04:00
return ret ;
}
return NULL ;
}
// Get whether the current terminal session is active
bool MsIsCurrentTerminalSessionActive ( )
{
return MsIsTerminalSessionActive ( MsGetCurrentTerminalSessionId ( ) ) ;
}
// Get whether the specified terminal session is active
bool MsIsTerminalSessionActive ( UINT session_id )
{
if ( MsIsTerminalServiceInstalled ( ) | | MsIsUserSwitchingInstalled ( ) )
{
UINT * status = NULL ;
2021-03-01 03:46:11 +03:00
DWORD size = sizeof ( status ) ;
2014-01-04 17:00:08 +04:00
bool active = true ;
2021-04-03 03:25:19 +03:00
if ( WTSQuerySessionInformationW ( WTS_CURRENT_SERVER_HANDLE , session_id ,
WTSConnectState , ( LPWSTR * ) & status , & size ) = = false )
2014-01-04 17:00:08 +04:00
{
return true ;
}
switch ( * status )
{
case WTSDisconnected :
case WTSShadow :
case WTSIdle :
case WTSDown :
case WTSReset :
active = false ;
break ;
}
2021-04-03 03:25:19 +03:00
WTSFreeMemory ( status ) ;
2014-01-04 17:00:08 +04:00
return active ;
}
return true ;
}
// Get the current terminal session ID
UINT MsGetCurrentTerminalSessionId ( )
{
if ( MsIsTerminalServiceInstalled ( ) | | MsIsUserSwitchingInstalled ( ) )
{
UINT ret ;
UINT * session_id = NULL ;
2021-03-01 03:46:11 +03:00
DWORD size = sizeof ( session_id ) ;
2021-04-03 03:25:19 +03:00
if ( WTSQuerySessionInformationW ( WTS_CURRENT_SERVER_HANDLE , WTS_CURRENT_SESSION ,
WTSSessionId , ( LPWSTR * ) & session_id , & size ) = = false )
2014-01-04 17:00:08 +04:00
{
return 0 ;
}
ret = * session_id ;
2021-04-03 03:25:19 +03:00
WTSFreeMemory ( session_id ) ;
2014-01-04 17:00:08 +04:00
return ret ;
}
return 0 ;
}
// Examine whether the user switching is installed
bool MsIsUserSwitchingInstalled ( )
{
OSVERSIONINFOEX i ;
Zero ( & i , sizeof ( i ) ) ;
i . dwOSVersionInfoSize = sizeof ( i ) ;
if ( GetVersionEx ( ( OSVERSIONINFO * ) & i ) = = false )
{
return false ;
}
if ( i . wSuiteMask & VER_SUITE_SINGLEUSERTS )
{
return true ;
}
return false ;
}
// Examine whether the Terminal Services is installed
bool MsIsTerminalServiceInstalled ( )
{
OSVERSIONINFOEX i ;
Zero ( & i , sizeof ( i ) ) ;
i . dwOSVersionInfoSize = sizeof ( i ) ;
if ( GetVersionEx ( ( OSVERSIONINFO * ) & i ) = = false )
{
return false ;
}
if ( i . wSuiteMask & VER_SUITE_TERMINAL | | i . wSuiteMask & VER_SUITE_SINGLEUSERTS )
{
return true ;
}
return false ;
}
// Stop the service
bool MsStopService ( char * name )
{
SC_HANDLE sc , service ;
bool ret = false ;
// Validate arguments
if ( name = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
sc = OpenSCManager ( NULL , NULL , SC_MANAGER_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( sc = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
service = OpenService ( sc , name , SERVICE_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( service ! = NULL )
{
SERVICE_STATUS st ;
2021-04-03 03:25:19 +03:00
ret = ControlService ( service , SERVICE_CONTROL_STOP , & st ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( service ) ;
2014-01-04 17:00:08 +04:00
}
if ( ret )
{
UINT64 end = Tick64 ( ) + 10000ULL ;
while ( Tick64 ( ) < end )
{
if ( MsIsServiceRunning ( name ) = = false )
{
break ;
}
SleepThread ( 250 ) ;
}
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( sc ) ;
2014-01-04 17:00:08 +04:00
return ret ;
}
// Start the service
bool MsStartService ( char * name )
{
return MsStartServiceEx ( name , NULL ) ;
}
bool MsStartServiceEx ( char * name , UINT * error_code )
{
SC_HANDLE sc , service ;
bool ret = false ;
static UINT dummy = 0 ;
// Validate arguments
if ( name = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
2014-01-04 17:00:08 +04:00
if ( error_code = = NULL )
{
error_code = & dummy ;
}
* error_code = 0 ;
2021-04-03 03:25:19 +03:00
sc = OpenSCManager ( NULL , NULL , SC_MANAGER_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( sc = = NULL )
{
* error_code = GetLastError ( ) ;
return false ;
}
2021-04-03 03:25:19 +03:00
service = OpenService ( sc , name , SERVICE_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( service ! = NULL )
{
2021-04-03 03:25:19 +03:00
ret = StartService ( service , 0 , NULL ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( service ) ;
2014-01-04 17:00:08 +04:00
}
else
{
* error_code = GetLastError ( ) ;
}
if ( ret )
{
UINT64 end = Tick64 ( ) + 10000ULL ;
while ( Tick64 ( ) < end )
{
if ( MsIsServiceRunning ( name ) )
{
break ;
}
SleepThread ( 250 ) ;
}
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( sc ) ;
2014-01-04 17:00:08 +04:00
return ret ;
}
// Get whether the service is running
bool MsIsServiceRunning ( char * name )
{
SC_HANDLE sc , service ;
bool ret = false ;
// Validate arguments
if ( name = = NULL | | IsEmptyStr ( name ) )
{
return false ;
}
2021-04-03 03:25:19 +03:00
sc = OpenSCManager ( NULL , NULL , GENERIC_READ ) ;
2014-01-04 17:00:08 +04:00
if ( sc = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
service = OpenService ( sc , name , GENERIC_READ ) ;
2014-01-04 17:00:08 +04:00
if ( service ! = NULL )
{
SERVICE_STATUS st ;
Zero ( & st , sizeof ( st ) ) ;
2021-04-03 03:25:19 +03:00
if ( QueryServiceStatus ( service , & st ) )
2014-01-04 17:00:08 +04:00
{
switch ( st . dwCurrentState )
{
case SERVICE_CONTINUE_PENDING :
case SERVICE_PAUSE_PENDING :
case SERVICE_PAUSED :
case SERVICE_RUNNING :
case SERVICE_START_PENDING :
case SERVICE_STOP_PENDING :
ret = true ;
break ;
}
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( service ) ;
2014-01-04 17:00:08 +04:00
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( sc ) ;
2014-01-04 17:00:08 +04:00
return ret ;
}
// Uninstall the service
bool MsUninstallService ( char * name )
{
SC_HANDLE sc , service ;
bool ret = false ;
// Validate arguments
if ( name = = NULL )
{
return false ;
}
MsStopService ( name ) ;
2021-04-03 03:25:19 +03:00
sc = OpenSCManager ( NULL , NULL , SC_MANAGER_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( sc = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
service = OpenService ( sc , name , SERVICE_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( service ! = NULL )
{
2021-04-03 03:25:19 +03:00
if ( DeleteService ( service ) )
2014-01-04 17:00:08 +04:00
{
ret = true ;
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( service ) ;
2014-01-04 17:00:08 +04:00
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( sc ) ;
2014-01-04 17:00:08 +04:00
if ( ret )
{
SleepThread ( 2000 ) ;
}
return ret ;
}
// Update the title and description of the service
bool MsSetServiceDescription ( char * name , wchar_t * description )
{
SC_HANDLE sc , service ;
// Validate arguments
if ( name = = NULL | | description = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
sc = OpenSCManager ( NULL , NULL , SC_MANAGER_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( sc = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
service = OpenService ( sc , name , SERVICE_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( service ! = NULL )
{
if ( GET_KETA ( GetOsInfo ( ) - > OsType , 100 ) > = 2 )
{
SERVICE_DESCRIPTIONW d ;
if ( UniIsEmptyStr ( description ) = = false )
{
Zero ( & d , sizeof ( d ) ) ;
d . lpDescription = description ;
2021-04-03 03:25:19 +03:00
ChangeServiceConfig2 ( service , SERVICE_CONFIG_DESCRIPTION , & d ) ;
2014-01-04 17:00:08 +04:00
}
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( service ) ;
2014-01-04 17:00:08 +04:00
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( sc ) ;
2014-01-04 17:00:08 +04:00
return true ;
}
// Update the service setting
bool MsUpdateServiceConfig ( char * name )
{
SC_HANDLE sc , service ;
// Validate arguments
if ( name = = NULL )
{
return false ;
}
// Whether just after Windows startup (deadlock prevention)
if ( timeGetTime ( ) < = ( 60 * 30 * 1000 ) )
{
if ( MsRegReadInt ( REG_LOCAL_MACHINE , " Software \\ " GC_REG_COMPANY_NAME " \\ Update Service Config " , name ) ! = 0 )
{
return false ;
}
}
2021-04-03 03:25:19 +03:00
sc = OpenSCManager ( NULL , NULL , SC_MANAGER_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( sc = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
service = OpenService ( sc , name , SERVICE_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( service ! = NULL )
{
if ( GET_KETA ( GetOsInfo ( ) - > OsType , 100 ) > = 2 )
{
SERVICE_FAILURE_ACTIONS action ;
SC_ACTION * e ;
Zero ( & action , sizeof ( action ) ) ;
e = ZeroMalloc ( sizeof ( SC_ACTION ) * 3 ) ;
e [ 0 ] . Delay = 10000 ; e [ 0 ] . Type = SC_ACTION_RESTART ;
e [ 1 ] . Delay = 10000 ; e [ 1 ] . Type = SC_ACTION_RESTART ;
e [ 2 ] . Delay = 10000 ; e [ 2 ] . Type = SC_ACTION_RESTART ;
action . cActions = 3 ;
action . lpsaActions = e ;
action . dwResetPeriod = 1 * 60 * 60 * 24 ;
2021-04-03 03:25:19 +03:00
ChangeServiceConfig2 ( service , SERVICE_CONFIG_FAILURE_ACTIONS , & action ) ;
2014-01-04 17:00:08 +04:00
MsRegWriteInt ( REG_LOCAL_MACHINE , " Software \\ " GC_REG_COMPANY_NAME " \\ Update Service Config " , name , 1 ) ;
}
if ( GET_KETA ( GetOsInfo ( ) - > OsType , 100 ) > = 2 )
{
SERVICE_DESCRIPTIONW d ;
wchar_t * description ;
char dname [ MAX_SIZE ] ;
Format ( dname , sizeof ( dname ) , " SVC_%s_DESCRIPT " , name ) ;
description = _UU ( dname ) ;
if ( UniIsEmptyStr ( description ) = = false )
{
Zero ( & d , sizeof ( d ) ) ;
d . lpDescription = description ;
2021-04-03 03:25:19 +03:00
ChangeServiceConfig2 ( service , SERVICE_CONFIG_DESCRIPTION , & d ) ;
2014-01-04 17:00:08 +04:00
}
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( service ) ;
2014-01-04 17:00:08 +04:00
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( sc ) ;
2014-01-04 17:00:08 +04:00
return true ;
}
// Install the device driver
bool MsInstallDeviceDriverW ( char * name , wchar_t * title , wchar_t * path , UINT * error_code )
{
SC_HANDLE sc , service ;
bool ret = false ;
wchar_t name_w [ MAX_SIZE ] ;
static UINT temp_int = 0 ;
// Validate arguments
if ( name = = NULL | | title = = NULL | | path = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
2014-01-04 17:00:08 +04:00
if ( error_code = = NULL )
{
error_code = & temp_int ;
}
* error_code = 0 ;
StrToUni ( name_w , sizeof ( name_w ) , name ) ;
2021-04-03 03:25:19 +03:00
sc = OpenSCManager ( NULL , NULL , SC_MANAGER_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( sc = = NULL )
{
* error_code = GetLastError ( ) ;
return false ;
}
2021-04-03 03:25:19 +03:00
service = CreateServiceW ( sc , name_w , title , SERVICE_ALL_ACCESS ,
2014-01-04 17:00:08 +04:00
SERVICE_KERNEL_DRIVER , SERVICE_DEMAND_START ,
SERVICE_ERROR_NORMAL , path , NULL , NULL , NULL , NULL , NULL ) ;
if ( service ! = NULL )
{
ret = true ;
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( service ) ;
2014-01-04 17:00:08 +04:00
}
else
{
* error_code = GetLastError ( ) ;
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( sc ) ;
2014-01-04 17:00:08 +04:00
if ( ret )
{
SleepThread ( 2000 ) ;
}
return ret ;
}
// Install the service
bool MsInstallServiceW ( char * name , wchar_t * title , wchar_t * description , wchar_t * path )
{
return MsInstallServiceExW ( name , title , description , path , NULL ) ;
}
bool MsInstallServiceExW ( char * name , wchar_t * title , wchar_t * description , wchar_t * path , UINT * error_code )
{
SC_HANDLE sc , service ;
bool ret = false ;
wchar_t name_w [ MAX_SIZE ] ;
static UINT temp_int = 0 ;
// Validate arguments
if ( name = = NULL | | title = = NULL | | path = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
2014-01-04 17:00:08 +04:00
if ( error_code = = NULL )
{
error_code = & temp_int ;
}
* error_code = 0 ;
StrToUni ( name_w , sizeof ( name_w ) , name ) ;
2021-04-03 03:25:19 +03:00
sc = OpenSCManager ( NULL , NULL , SC_MANAGER_ALL_ACCESS ) ;
2014-01-04 17:00:08 +04:00
if ( sc = = NULL )
{
* error_code = GetLastError ( ) ;
return false ;
}
2021-04-03 03:25:19 +03:00
service = CreateServiceW ( sc , name_w , title , SERVICE_ALL_ACCESS ,
SERVICE_WIN32_OWN_PROCESS , SERVICE_AUTO_START ,
2014-01-04 17:00:08 +04:00
SERVICE_ERROR_NORMAL , path , NULL , NULL , NULL , NULL , NULL ) ;
if ( service ! = NULL )
{
ret = true ;
if ( GET_KETA ( GetOsInfo ( ) - > OsType , 100 ) > = 2 )
{
SERVICE_DESCRIPTIONW d ;
SERVICE_FAILURE_ACTIONS action ;
SC_ACTION * e ;
Zero ( & d , sizeof ( d ) ) ;
d . lpDescription = description ;
2021-04-03 03:25:19 +03:00
ChangeServiceConfig2 ( service , SERVICE_CONFIG_DESCRIPTION , & d ) ;
2014-01-04 17:00:08 +04:00
Zero ( & action , sizeof ( action ) ) ;
e = ZeroMalloc ( sizeof ( SC_ACTION ) * 3 ) ;
e [ 0 ] . Delay = 10000 ; e [ 0 ] . Type = SC_ACTION_RESTART ;
e [ 1 ] . Delay = 10000 ; e [ 1 ] . Type = SC_ACTION_RESTART ;
e [ 2 ] . Delay = 10000 ; e [ 2 ] . Type = SC_ACTION_RESTART ;
action . cActions = 3 ;
action . lpsaActions = e ;
action . dwResetPeriod = 1 * 60 * 60 * 24 ;
2021-04-03 03:25:19 +03:00
ChangeServiceConfig2 ( service , SERVICE_CONFIG_FAILURE_ACTIONS , & action ) ;
2014-01-04 17:00:08 +04:00
Free ( e ) ;
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( service ) ;
2014-01-04 17:00:08 +04:00
}
else
{
* error_code = GetLastError ( ) ;
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( sc ) ;
2014-01-04 17:00:08 +04:00
if ( ret )
{
SleepThread ( 2000 ) ;
}
return ret ;
}
// Check whether the specified service is installed
bool MsIsServiceInstalled ( char * name )
{
SC_HANDLE sc ;
SC_HANDLE service ;
bool ret = false ;
// Validate arguments
if ( name = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
sc = OpenSCManager ( NULL , NULL , GENERIC_READ ) ;
2014-01-04 17:00:08 +04:00
if ( sc = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
service = OpenService ( sc , name , GENERIC_READ ) ;
2014-01-04 17:00:08 +04:00
if ( service ! = NULL )
{
ret = true ;
}
2021-04-03 03:25:19 +03:00
CloseServiceHandle ( service ) ;
CloseServiceHandle ( sc ) ;
2014-01-04 17:00:08 +04:00
return ret ;
}
// Kill the process
void MsTerminateProcess ( )
{
TerminateProcess ( GetCurrentProcess ( ) , 0 ) ;
_exit ( 0 ) ;
}
// Get the Process ID
UINT MsGetProcessId ( )
{
return GetCurrentProcessId ( ) ;
}
// Lower the priority of the thread to lowest
void MsSetThreadPriorityIdle ( )
{
SetThreadPriority ( GetCurrentThread ( ) , THREAD_PRIORITY_IDLE ) ;
}
// Raise the priority of a thread
void MsSetThreadPriorityHigh ( )
{
SetThreadPriority ( GetCurrentThread ( ) , THREAD_PRIORITY_ABOVE_NORMAL ) ;
}
// Raise the priority of the thread to highest
void MsSetThreadPriorityRealtime ( )
{
SetThreadPriority ( GetCurrentThread ( ) , THREAD_PRIORITY_ABOVE_NORMAL ) ;
SetThreadPriority ( GetCurrentThread ( ) , THREAD_PRIORITY_HIGHEST ) ;
SetThreadPriority ( GetCurrentThread ( ) , THREAD_PRIORITY_TIME_CRITICAL ) ;
}
// Restore the priority of the thread
void MsRestoreThreadPriority ( )
{
SetThreadPriority ( GetCurrentThread ( ) , THREAD_PRIORITY_NORMAL ) ;
}
// Check whether should show the TCP setting application
bool MsIsShouldShowTcpConfigApp ( )
{
MS_TCP tcp1 , tcp2 ;
if ( MsIsTcpConfigSupported ( ) = = false )
{
return false ;
}
MsGetTcpConfig ( & tcp1 ) ;
if ( MsLoadTcpConfigReg ( & tcp2 ) = = false )
{
return true ;
}
if ( Cmp ( & tcp1 , & tcp2 , sizeof ( MS_TCP ) ! = 0 ) )
{
return true ;
}
return false ;
}
// Apply the temporary settings data of registry to the TCP parameter of the Windows
void MsApplyTcpConfig ( )
{
if ( MsIsTcpConfigSupported ( ) )
{
MS_TCP tcp ;
if ( MsLoadTcpConfigReg ( & tcp ) )
{
MsSetTcpConfig ( & tcp ) ;
}
}
}
// Check whether the dynamic configuration of TCP is supported in current state
bool MsIsTcpConfigSupported ( )
{
2021-04-03 03:25:19 +03:00
return MsIsAdmin ( ) ;
2014-01-04 17:00:08 +04:00
}
// Read the TCP settings from the registry setting
bool MsLoadTcpConfigReg ( MS_TCP * tcp )
{
// Validate arguments
if ( tcp = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
Zero ( tcp , sizeof ( MS_TCP ) ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
if ( MsRegIsValueEx ( REG_LOCAL_MACHINE , MS_REG_TCP_SETTING_KEY , " RecvWindowSize " , true ) = = false | |
MsRegIsValueEx ( REG_LOCAL_MACHINE , MS_REG_TCP_SETTING_KEY , " SendWindowSize " , true ) = = false )
2014-01-04 17:00:08 +04:00
{
return false ;
}
2021-04-03 03:25:19 +03:00
tcp - > RecvWindowSize = MsRegReadIntEx ( REG_LOCAL_MACHINE , MS_REG_TCP_SETTING_KEY , " RecvWindowSize " , true ) ;
tcp - > SendWindowSize = MsRegReadIntEx ( REG_LOCAL_MACHINE , MS_REG_TCP_SETTING_KEY , " SendWindowSize " , true ) ;
return true ;
2014-01-04 17:00:08 +04:00
}
// Remove the TCP settings from the registry
void MsDeleteTcpConfigReg ( )
{
2021-04-03 03:25:19 +03:00
if ( MsIsAdmin ( ) )
2014-01-04 17:00:08 +04:00
{
MsRegDeleteKeyEx ( REG_LOCAL_MACHINE , MS_REG_TCP_SETTING_KEY , true ) ;
}
}
// Write the TCP settings to the registry setting
void MsSaveTcpConfigReg ( MS_TCP * tcp )
{
// Validate arguments
if ( tcp = = NULL )
{
return ;
}
2021-04-03 03:25:19 +03:00
if ( MsIsAdmin ( ) )
2014-01-04 17:00:08 +04:00
{
MsRegWriteIntEx ( REG_LOCAL_MACHINE , MS_REG_TCP_SETTING_KEY , " RecvWindowSize " , tcp - > RecvWindowSize , true ) ;
MsRegWriteIntEx ( REG_LOCAL_MACHINE , MS_REG_TCP_SETTING_KEY , " SendWindowSize " , tcp - > SendWindowSize , true ) ;
}
}
// Get the current TCP settings
void MsGetTcpConfig ( MS_TCP * tcp )
{
// Validate arguments
if ( tcp = = NULL )
{
return ;
}
Zero ( tcp , sizeof ( MS_TCP ) ) ;
2021-04-03 03:25:19 +03:00
UINT v ;
// Initialize the network setting
MsInitGlobalNetworkConfig ( ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
// Read the value of TcpWindowSize or GlobalMaxTcpWindowSize if there is
v = MsRegReadInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " , " TcpWindowSize " ) ;
tcp - > RecvWindowSize = MAX ( tcp - > RecvWindowSize , v ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
v = MsRegReadInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " , " GlobalMaxTcpWindowSize " ) ;
tcp - > RecvWindowSize = MAX ( tcp - > RecvWindowSize , v ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
v = MsRegReadInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ AFD \\ Parameters " , " DefaultReceiveWindow " ) ;
tcp - > RecvWindowSize = MAX ( tcp - > RecvWindowSize , v ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
// Read the value of DefaultSendWindow if there is
tcp - > SendWindowSize = MsRegReadInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ AFD \\ Parameters " , " DefaultSendWindow " ) ;
2014-01-04 17:00:08 +04:00
}
// Write the TCP settings
void MsSetTcpConfig ( MS_TCP * tcp )
{
// Validate arguments
if ( tcp = = NULL )
{
return ;
}
2021-04-03 03:25:19 +03:00
if ( MsIsAdmin ( ) )
2014-01-04 17:00:08 +04:00
{
bool window_scaling = false ;
UINT tcp1323opts ;
if ( tcp - > RecvWindowSize > = 65536 | | tcp - > SendWindowSize > = 65536 )
{
window_scaling = true ;
}
// Set the Tcp1323Opts
tcp1323opts = MsRegReadInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " , " Tcp1323Opts " ) ;
if ( window_scaling )
{
if ( tcp1323opts = = 0 )
{
tcp1323opts = 1 ;
}
if ( tcp1323opts = = 2 )
{
tcp1323opts = 3 ;
}
}
else
{
if ( tcp1323opts = = 1 )
{
tcp1323opts = 0 ;
}
if ( tcp1323opts = = 3 )
{
tcp1323opts = 2 ;
}
}
MsRegWriteInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " , " Tcp1323Opts " , tcp1323opts ) ;
// Set the Receive Window
if ( tcp - > RecvWindowSize = = 0 )
{
MsRegDeleteValue ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ AFD \\ Parameters " ,
" DefaultReceiveWindow " ) ;
MsRegDeleteValue ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " ,
" TcpWindowSize " ) ;
MsRegDeleteValue ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " ,
" GlobalMaxTcpWindowSize " ) ;
}
else
{
MsRegWriteInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ AFD \\ Parameters " ,
" DefaultReceiveWindow " , tcp - > RecvWindowSize ) ;
MsRegWriteInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " ,
" TcpWindowSize " , tcp - > RecvWindowSize ) ;
MsRegWriteInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " ,
" GlobalMaxTcpWindowSize " , tcp - > RecvWindowSize ) ;
}
// Setting the Send Window
if ( tcp - > SendWindowSize = = 0 )
{
MsRegDeleteValue ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ AFD \\ Parameters " ,
" DefaultSendWindow " ) ;
}
else
{
MsRegWriteInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ AFD \\ Parameters " ,
" DefaultSendWindow " , tcp - > SendWindowSize ) ;
}
}
}
// Initialize the global network settings
void MsInitGlobalNetworkConfig ( )
{
2021-04-03 03:25:19 +03:00
UINT current_window_size = MsRegReadInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " , " TcpWindowSize " ) ;
if ( current_window_size = = 65535 | | current_window_size = = 5980160 | |
current_window_size = = 16777216 | | current_window_size = = 16777214 )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
// Remove the strange value which is written by older version of PacketiX VPN
MsRegDeleteValue ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ AFD \\ Parameters " ,
" DefaultReceiveWindow " ) ;
MsRegDeleteValue ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ AFD \\ Parameters " ,
" DefaultSendWindow " ) ;
MsRegDeleteValue ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " ,
" Tcp1323Opts " ) ;
MsRegDeleteValue ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " ,
" TcpWindowSize " ) ;
MsRegDeleteValue ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " ,
" GlobalMaxTcpWindowSize " ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
// Set vpn_no_change = true
MsRegWriteInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " , " vpn_no_change " , 1 ) ;
MsRegWriteInt ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ AFD \\ Parameters " , " vpn_no_change " , 1 ) ;
2014-01-04 17:00:08 +04:00
}
MsApplyTcpConfig ( ) ;
}
// Process disabling other off-loading of network and others
void MsDisableNetworkOffloadingEtc ( )
{
wchar_t netsh [ MAX_SIZE ] ;
UINT exec_timeout = 10000 ;
// Get the path of netsh.exe
CombinePathW ( netsh , sizeof ( netsh ) , MsGetSystem32DirW ( ) , L " netsh.exe " ) ;
// Registry settings
MsRegWriteIntEx2 ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " , " DisableTaskOffload " , 1 , false , true ) ;
MsRegWriteIntEx2 ( REG_LOCAL_MACHINE , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " , " TcpNumConnections " , TCP_MAX_NUM_CONNECTIONS , false , true ) ;
2021-04-03 03:25:19 +03:00
Win32RunAndWaitProcess ( netsh , L " int ipv4 set global taskoffload=disabled " , true , true , exec_timeout ) ;
SleepThread ( 250 ) ;
Win32RunAndWaitProcess ( netsh , L " int ipv6 set global taskoffload=disabled " , true , true , exec_timeout ) ;
SleepThread ( 250 ) ;
Win32RunAndWaitProcess ( netsh , L " int tcp set global chimney=disabled " , true , true , exec_timeout ) ;
SleepThread ( 250 ) ;
2014-01-04 17:00:08 +04:00
}
// Upgrade the virtual LAN card
bool MsUpgradeVLan ( char * tag_name , char * connection_tag_name , char * instance_name , MS_DRIVER_VER * ver )
{
bool ret ;
Lock ( vlan_lock ) ;
{
ret = MsUpgradeVLanWithoutLock ( tag_name , connection_tag_name , instance_name , ver ) ;
}
Unlock ( vlan_lock ) ;
return ret ;
}
bool MsUpgradeVLanWithoutLock ( char * tag_name , char * connection_tag_name , char * instance_name , MS_DRIVER_VER * ver )
{
char hwid [ MAX_PATH ] ;
wchar_t hwid_w [ MAX_PATH ] ;
bool ret = false ;
UCHAR old_mac_address [ 6 ] ;
char * s ;
// Validate arguments
if ( instance_name = = NULL | | tag_name = = NULL | | connection_tag_name = = NULL | | ver = = NULL )
{
return false ;
}
if ( MsIsInfCatalogRequired ( ) )
{
if ( MsIsValidVLanInstanceNameForInfCatalog ( instance_name ) = = false )
{
return false ;
}
StrUpper ( instance_name ) ;
}
Zero ( hwid , sizeof ( hwid ) ) ;
Format ( hwid , sizeof ( hwid ) , DRIVER_DEVICE_ID_TAG , instance_name ) ;
StrToUni ( hwid_w , sizeof ( hwid_w ) , hwid ) ;
// Examine whether the virtual LAN card with the specified name has already registered
if ( MsIsVLanExists ( tag_name , instance_name ) = = false )
{
// Not registered
return false ;
}
// Get the previous MAC address
s = MsGetMacAddress ( tag_name , instance_name ) ;
if ( s = = NULL )
{
Zero ( old_mac_address , 6 ) ;
}
else
{
BUF * b ;
b = StrToBin ( s ) ;
Free ( s ) ;
if ( b - > Size = = 6 )
{
Copy ( old_mac_address , b - > Buf , b - > Size ) ;
}
else
{
Zero ( old_mac_address , 6 ) ;
}
FreeBuf ( b ) ;
}
2018-05-24 23:57:54 +03:00
ret = MsUninstallVLanWithoutLock ( instance_name ) ;
2014-01-04 17:00:08 +04:00
2018-05-24 23:57:54 +03:00
ret = MsInstallVLanWithoutLock ( tag_name , connection_tag_name , instance_name , ver ) ;
2014-01-04 17:00:08 +04:00
return ret ;
}
// Child window enumeration procedure
2021-03-01 03:46:11 +03:00
BOOL CALLBACK MsEnumChildWindowProc ( HWND hWnd , LPARAM lParam )
2014-01-04 17:00:08 +04:00
{
LIST * o = ( LIST * ) lParam ;
if ( o ! = NULL )
{
MsEnumChildWindows ( o , hWnd ) ;
}
return true ;
}
// Enumerate specified window and all the its child windows
LIST * MsEnumChildWindows ( LIST * o , HWND hWnd )
{
// Validate arguments
if ( hWnd = = NULL )
{
return NULL ;
}
if ( o = = NULL )
{
o = NewListFast ( NULL ) ;
}
MsAddWindowToList ( o , hWnd ) ;
EnumChildWindows ( hWnd , MsEnumChildWindowProc , ( LPARAM ) o ) ;
return o ;
}
// Add a window to the list
void MsAddWindowToList ( LIST * o , HWND hWnd )
{
// Validate arguments
if ( o = = NULL | | hWnd = = NULL )
{
return ;
}
if ( IsInList ( o , hWnd ) = = false )
{
Add ( o , hWnd ) ;
}
}
// Enumeration of the window that the thread owns
2021-03-01 03:46:11 +03:00
BOOL CALLBACK MsEnumThreadWindowProc ( HWND hWnd , LPARAM lParam )
2014-01-04 17:00:08 +04:00
{
LIST * o = ( LIST * ) lParam ;
if ( o = = NULL )
{
return false ;
}
MsEnumChildWindows ( o , hWnd ) ;
return true ;
}
// Window enumeration procedure
BOOL CALLBACK EnumTopWindowProc ( HWND hWnd , LPARAM lParam )
{
LIST * o = ( LIST * ) lParam ;
HWND hParent ;
char c1 [ MAX_SIZE ] , c2 [ MAX_SIZE ] ;
// Validate arguments
if ( hWnd = = NULL | | o = = NULL )
{
return TRUE ;
}
Zero ( c1 , sizeof ( c1 ) ) ;
Zero ( c2 , sizeof ( c2 ) ) ;
hParent = GetParent ( hWnd ) ;
GetClassName ( hWnd , c1 , sizeof ( c1 ) ) ;
if ( hParent ! = NULL )
{
GetClassName ( hParent , c2 , sizeof ( c2 ) ) ;
}
if ( StrCmpi ( c1 , " SysIPAddress32 " ) ! = 0 & & ( IsEmptyStr ( c2 ) | | StrCmpi ( c2 , " SysIPAddress32 " ) ! = 0 ) )
{
AddWindow ( o , hWnd ) ;
}
return TRUE ;
}
// Child window enumeration procedure
BOOL CALLBACK EnumChildWindowProc ( HWND hWnd , LPARAM lParam )
{
ENUM_CHILD_WINDOW_PARAM * p = ( ENUM_CHILD_WINDOW_PARAM * ) lParam ;
LIST * o ;
HWND hParent ;
char c1 [ MAX_SIZE ] , c2 [ MAX_SIZE ] ;
2016-04-24 17:49:31 +03:00
bool ok = false ;
2014-01-04 17:00:08 +04:00
// Validate arguments
if ( hWnd = = NULL | | p = = NULL )
{
return TRUE ;
}
o = p - > o ;
Zero ( c1 , sizeof ( c1 ) ) ;
Zero ( c2 , sizeof ( c2 ) ) ;
hParent = GetParent ( hWnd ) ;
GetClassName ( hWnd , c1 , sizeof ( c1 ) ) ;
if ( hParent ! = NULL )
{
GetClassName ( hParent , c2 , sizeof ( c2 ) ) ;
}
if ( p - > include_ipcontrol | | ( StrCmpi ( c1 , " SysIPAddress32 " ) ! = 0 & & ( IsEmptyStr ( c2 ) | | StrCmpi ( c2 , " SysIPAddress32 " ) ! = 0 ) ) )
2016-04-24 17:49:31 +03:00
{
ok = true ;
}
if ( MsIsWine ( ) )
{
if ( StrCmpi ( c1 , " SysIPAddress32 " ) = = 0 | | StrCmpi ( c2 , " SysIPAddress32 " ) = = 0 )
{
ok = true ;
}
}
if ( ok )
2014-01-04 17:00:08 +04:00
{
AddWindow ( o , hWnd ) ;
if ( p - > no_recursion = = false )
{
EnumChildWindows ( hWnd , EnumChildWindowProc , ( LPARAM ) p ) ;
}
}
return TRUE ;
}
LIST * EnumAllTopWindow ( )
{
LIST * o = NewWindowList ( ) ;
EnumWindows ( EnumTopWindowProc , ( LPARAM ) o ) ;
return o ;
}
// Enumerate the child windows of all that is in the specified window
LIST * EnumAllChildWindow ( HWND hWnd )
{
return EnumAllChildWindowEx ( hWnd , false , false , false ) ;
}
LIST * EnumAllChildWindowEx ( HWND hWnd , bool no_recursion , bool include_ipcontrol , bool no_self )
{
ENUM_CHILD_WINDOW_PARAM p ;
LIST * o = NewWindowList ( ) ;
Zero ( & p , sizeof ( p ) ) ;
p . include_ipcontrol = include_ipcontrol ;
p . no_recursion = no_recursion ;
p . o = o ;
if ( no_self = = false )
{
AddWindow ( o , hWnd ) ;
}
EnumChildWindows ( hWnd , EnumChildWindowProc , ( LPARAM ) & p ) ;
return o ;
}
// Release of the window list
void FreeWindowList ( LIST * o )
{
UINT i ;
// Validate arguments
if ( o = = NULL )
{
return ;
}
for ( i = 0 ; i < LIST_NUM ( o ) ; i + + )
{
HWND * e = LIST_DATA ( o , i ) ;
Free ( e ) ;
}
ReleaseList ( o ) ;
}
// Add a window to the window list
void AddWindow ( LIST * o , HWND hWnd )
{
HWND t , * e ;
// Validate arguments
if ( o = = NULL | | hWnd = = NULL )
{
return ;
}
t = hWnd ;
if ( Search ( o , & t ) ! = NULL )
{
return ;
}
e = ZeroMalloc ( sizeof ( HWND ) ) ;
* e = hWnd ;
Insert ( o , e ) ;
}
// Comparison of the window list items
int CmpWindowList ( void * p1 , void * p2 )
{
HWND * h1 , * h2 ;
if ( p1 = = NULL | | p2 = = NULL )
{
return 0 ;
}
h1 = * ( HWND * * ) p1 ;
h2 = * ( HWND * * ) p2 ;
if ( h1 = = NULL | | h2 = = NULL )
{
return 0 ;
}
return Cmp ( h1 , h2 , sizeof ( HWND ) ) ;
}
// Creating a new window list
LIST * NewWindowList ( )
{
return NewListFast ( CmpWindowList ) ;
}
// Determine whether it's Windows 7 or later
bool MsIsWindows7 ( )
{
OS_INFO * info = GetOsInfo ( ) ;
if ( info = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
if ( GET_KETA ( info - > OsType , 100 ) > = 6 )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
return true ;
2014-01-04 17:00:08 +04:00
}
return false ;
}
2014-10-03 19:09:23 +04:00
// Determine whether it's Windows 10 or later
bool MsIsWindows10 ( )
{
OS_INFO * info = GetOsInfo ( ) ;
if ( info = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
if ( GET_KETA ( info - > OsType , 100 ) = = 7 )
2014-10-03 19:09:23 +04:00
{
2021-04-03 03:25:19 +03:00
if ( GET_KETA ( info - > OsType , 1 ) > = 2 )
2014-10-03 19:09:23 +04:00
{
return true ;
}
}
2021-04-03 03:25:19 +03:00
if ( GET_KETA ( info - > OsType , 100 ) > = 8 )
{
return true ;
}
2014-10-03 19:09:23 +04:00
return false ;
}
2014-02-16 22:16:50 +04:00
// Determine whether it's Windows 8.1 or later
bool MsIsWindows81 ( )
{
OS_INFO * info = GetOsInfo ( ) ;
if ( info = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
if ( GET_KETA ( info - > OsType , 100 ) = = 7 )
2014-02-16 22:16:50 +04:00
{
2021-04-03 03:25:19 +03:00
if ( GET_KETA ( info - > OsType , 1 ) > = 1 )
2014-02-16 22:16:50 +04:00
{
return true ;
}
}
2021-04-03 03:25:19 +03:00
if ( GET_KETA ( info - > OsType , 100 ) > = 8 )
{
return true ;
}
2014-02-16 22:16:50 +04:00
return false ;
}
// Determine whether it's Windows 8 or later
2014-01-04 17:00:08 +04:00
bool MsIsWindows8 ( )
{
OS_INFO * info = GetOsInfo ( ) ;
if ( info = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
if ( GET_KETA ( info - > OsType , 100 ) > = 7 )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
return true ;
2014-01-04 17:00:08 +04:00
}
return false ;
}
// Whether INF catalog signature is required
bool MsIsInfCatalogRequired ( )
{
return MsIsWindows8 ( ) ;
}
// Get the process path of the owner of the window
bool MsGetWindowOwnerProcessExeName ( char * path , UINT size , HWND hWnd )
{
DWORD procId = 0 ;
// Validate arguments
if ( path = = NULL | | hWnd = = NULL )
{
return false ;
}
GetWindowThreadProcessId ( hWnd , & procId ) ;
if ( procId = = 0 )
{
return false ;
}
if ( MsGetProcessExeName ( path , size , procId ) = = false )
{
return false ;
}
return true ;
}
// Get the process path from process ID
bool MsGetProcessExeName ( char * path , UINT size , UINT id )
{
LIST * o ;
MS_PROCESS * proc ;
bool ret = false ;
// Validate arguments
if ( path = = NULL )
{
return false ;
}
o = MsGetProcessList ( ) ;
proc = MsSearchProcessById ( o , id ) ;
if ( proc ! = NULL )
{
ret = true ;
StrCpy ( path , size , proc - > ExeFilename ) ;
}
MsFreeProcessList ( o ) ;
return ret ;
}
// Close the alert dialog
bool MsCloseWarningWindow ( NO_WARNING * nw , UINT thread_id )
{
UINT i ;
LIST * o ;
bool ret = false ;
bool press = false ;
2021-04-03 03:25:19 +03:00
if ( nw - > StartTimer = = 0 )
2014-01-04 17:00:08 +04:00
{
press = true ;
}
if ( nw - > StartTick ! = 0 & & nw - > StartTick < = Tick64 ( ) )
{
press = true ;
}
2021-04-03 03:25:19 +03:00
o = EnumAllTopWindow ( ) ;
2014-01-04 17:00:08 +04:00
for ( i = 0 ; i < LIST_NUM ( o ) ; i + + )
{
HWND hWnd ;
2016-11-27 11:43:14 +03:00
if ( nw - > Halt )
{
break ;
}
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
hWnd = * ( ( HWND * ) LIST_DATA ( o , i ) ) ;
2014-01-04 17:00:08 +04:00
if ( hWnd ! = NULL )
{
2021-04-03 03:25:19 +03:00
if ( true )
2014-01-04 17:00:08 +04:00
{
// Get whether this window is a warning screen of driver
2021-04-03 03:25:19 +03:00
if ( true )
2014-01-04 17:00:08 +04:00
{
// Windows Vista
char exe [ MAX_PATH ] ;
if ( MsGetWindowOwnerProcessExeName ( exe , sizeof ( exe ) , hWnd ) )
{
if ( EndWith ( exe , " rundll32.exe " ) )
{
LIST * o ;
HWND h ;
UINT i ;
o = EnumAllChildWindow ( hWnd ) ;
if ( o ! = NULL )
{
for ( i = 0 ; i < LIST_NUM ( o ) ; i + + )
{
char tmp [ MAX_SIZE ] ;
h = * ( ( HWND * ) LIST_DATA ( o , i ) ) ;
Zero ( tmp , sizeof ( tmp ) ) ;
GetClassNameA ( h , tmp , sizeof ( tmp ) ) ;
if ( StrCmpi ( tmp , " DirectUIHWND " ) = = 0 )
{
LIST * o = EnumAllChildWindow ( h ) ;
if ( o ! = NULL )
{
UINT j ;
UINT numDirectUIHWND = 0 ;
UINT numButton = 0 ;
HWND hButton1 = NULL ;
HWND hButton2 = NULL ;
for ( j = 0 ; j < LIST_NUM ( o ) ; j + + )
{
HWND hh ;
char tmp [ MAX_SIZE ] ;
hh = * ( ( HWND * ) LIST_DATA ( o , j ) ) ;
Zero ( tmp , sizeof ( tmp ) ) ;
GetClassNameA ( hh , tmp , sizeof ( tmp ) ) ;
if ( StrCmpi ( tmp , " DirectUIHWND " ) = = 0 )
{
numDirectUIHWND + + ;
}
if ( StrCmpi ( tmp , " button " ) = = 0 )
{
numButton + + ;
if ( hButton1 = = NULL )
{
hButton1 = hh ;
}
else
{
hButton2 = hh ;
}
}
}
if ( ( numDirectUIHWND = = 1 | | numDirectUIHWND = = 2 ) & & numButton = = 2 )
{
if ( hButton1 ! = NULL & & hButton2 ! = NULL )
{
HWND hButton ;
HWND hParent ;
RECT r1 , r2 ;
GetWindowRect ( hButton1 , & r1 ) ;
GetWindowRect ( hButton2 , & r2 ) ;
hButton = hButton1 ;
if ( numDirectUIHWND = = 1 )
{
// Warning that there is no signature
if ( r1 . top < r2 . top )
{
hButton = hButton2 ;
}
}
else
{
// Notification that there is signature
if ( r1 . left > = r2 . left )
{
hButton = hButton2 ;
}
}
hParent = GetParent ( hButton ) ;
// Press the OK button since it was found
if ( press )
{
PostMessage ( hParent , WM_COMMAND , 1 , 0 ) ;
}
ret = true ;
}
}
FreeWindowList ( o ) ;
}
}
}
FreeWindowList ( o ) ;
}
}
}
}
}
}
}
2021-04-03 03:25:19 +03:00
FreeWindowList ( o ) ;
2014-01-04 17:00:08 +04:00
if ( press = = false )
{
if ( ret )
{
ret = false ;
if ( nw - > StartTick = = 0 )
{
nw - > StartTick = Tick64 ( ) + nw - > StartTimer ;
}
}
}
return ret ;
}
// Thread to suppress a warning message
void MsNoWarningThreadProc ( THREAD * thread , void * param )
{
NO_WARNING * nw ;
UINT interval ;
UINT i ;
bool found0 = false ;
// Validate arguments
if ( thread = = NULL )
{
return ;
}
nw = ( NO_WARNING * ) param ;
nw - > NoWarningThread = thread ;
AddRef ( thread - > ref ) ;
NoticeThreadInit ( thread ) ;
2021-04-03 03:25:19 +03:00
interval = 1000 ;
2014-01-04 17:00:08 +04:00
i = 0 ;
while ( nw - > Halt = = false )
{
bool found = false ;
// Close the alert dialog
found = MsCloseWarningWindow ( nw , nw - > ThreadId ) ;
if ( i = = 0 )
{
found0 = found ;
}
else
{
if ( found0 = = false & & found )
{
break ;
}
}
i + + ;
// Loop until the command incomes from parent thread
Wait ( nw - > HaltEvent , interval ) ;
}
}
// Initialize the procedure to turn off the warning sound
char * MsNoWarningSoundInit ( )
{
char * ret = MsRegReadStr ( REG_CURRENT_USER , " AppEvents \\ Schemes \\ Apps \\ .Default \\ SystemAsterisk \\ .Current " , " " ) ;
if ( IsEmptyStr ( ret ) )
{
Free ( ret ) ;
ret = NULL ;
}
else
{
MsRegWriteStr ( REG_CURRENT_USER ,
" AppEvents \\ Schemes \\ Apps \\ .Default \\ SystemAsterisk \\ .Current " ,
" " , " " ) ;
}
return ret ;
}
// Release of procedure to turn off the warning sound
void MsNoWarningSoundFree ( char * s )
{
// Validate arguments
if ( s = = NULL )
{
return ;
}
MsRegWriteStrExpand ( REG_CURRENT_USER ,
" AppEvents \\ Schemes \\ Apps \\ .Default \\ SystemAsterisk \\ .Current " ,
" " , s ) ;
Free ( s ) ;
}
// The start of the procedure to suppress the warning
NO_WARNING * MsInitNoWarning ( )
{
return MsInitNoWarningEx ( 0 ) ;
}
NO_WARNING * MsInitNoWarningEx ( UINT start_timer )
{
THREAD * thread ;
NO_WARNING * nw = ZeroMalloc ( sizeof ( NO_WARNING ) ) ;
nw - > StartTimer = ( UINT64 ) start_timer ;
nw - > ThreadId = GetCurrentThreadId ( ) ;
nw - > HaltEvent = NewEvent ( ) ;
thread = NewThread ( MsNoWarningThreadProc , nw ) ;
WaitThreadInit ( thread ) ;
ReleaseThread ( thread ) ;
return nw ;
}
// End of the procedure to suppress the warning
void MsFreeNoWarning ( NO_WARNING * nw )
{
// Validate arguments
if ( nw = = NULL )
{
return ;
}
nw - > Halt = true ;
Set ( nw - > HaltEvent ) ;
WaitThread ( nw - > NoWarningThread , INFINITE ) ;
2021-04-03 03:25:19 +03:00
ReleaseThread ( nw - > NoWarningThread ) ;
2014-01-04 17:00:08 +04:00
ReleaseEvent ( nw - > HaltEvent ) ;
Free ( nw ) ;
}
// Obtain the name of the directory that the inf catalog file is stored
void MsGetInfCatalogDir ( char * dst , UINT size )
{
// Validate arguments
if ( dst = = NULL )
{
return ;
}
2015-05-31 13:02:35 +03:00
Format ( dst , size , " |DriverPackages \\ %s \\ %s " , ( MsIsWindows10 ( ) ? " Neo6_Win10 " : " Neo6_Win8 " ) , ( MsIsX64 ( ) ? " x64 " : " x86 " ) ) ;
2014-01-04 17:00:08 +04:00
}
// Examine whether the virtual LAN card name can be used as a instance name of the VLAN
bool MsIsValidVLanInstanceNameForInfCatalog ( char * instance_name )
{
char src_dir [ MAX_SIZE ] ;
char tmp [ MAX_SIZE ] ;
bool ret ;
// Validate arguments
if ( instance_name = = NULL )
{
return false ;
}
MsGetInfCatalogDir ( src_dir , sizeof ( src_dir ) ) ;
2015-05-31 13:02:35 +03:00
Format ( tmp , sizeof ( tmp ) , " %s \\ Neo6_%s_%s.inf " , src_dir , ( MsIsX64 ( ) ? " x64 " : " x86 " ) , instance_name ) ;
2014-01-04 17:00:08 +04:00
ret = IsFile ( tmp ) ;
return ret ;
}
// Delete the device information that is about the device which failed during the installation of the same name before installing the virtual LAN card
void MsDeleteTroubleVLAN ( char * tag_name , char * instance_name )
{
HDEVINFO dev_info ;
SP_DEVINFO_LIST_DETAIL_DATA detail_data ;
SP_DEVINFO_DATA data ;
UINT i ;
char target_name [ MAX_SIZE ] ;
LIST * o ;
// Validate arguments
if ( tag_name = = NULL | | instance_name = = NULL )
{
return ;
}
Format ( target_name , sizeof ( target_name ) , DRIVER_DEVICE_ID_TAG , instance_name ) ;
// Create a device information list
dev_info = SetupDiGetClassDevsEx ( NULL , NULL , NULL , DIGCF_ALLCLASSES | DIGCF_PRESENT , NULL , NULL , NULL ) ;
if ( dev_info = = NULL )
{
return ;
}
Zero ( & detail_data , sizeof ( detail_data ) ) ;
detail_data . cbSize = sizeof ( detail_data ) ;
if ( SetupDiGetDeviceInfoListDetail ( dev_info , & detail_data ) = = false )
{
MsDestroyDevInfo ( dev_info ) ;
return ;
}
Zero ( & data , sizeof ( data ) ) ;
data . cbSize = sizeof ( data ) ;
// Enumeration start
o = NewListFast ( NULL ) ;
for ( i = 0 ; SetupDiEnumDeviceInfo ( dev_info , i , & data ) ; i + + )
{
char * buffer ;
UINT buffer_size = 8092 ;
DWORD data_type ;
buffer = ZeroMalloc ( buffer_size ) ;
if ( SetupDiGetDeviceRegistryProperty ( dev_info , & data , SPDRP_HARDWAREID , & data_type , ( PBYTE ) buffer , buffer_size , NULL ) )
{
if ( StrCmpi ( buffer , target_name ) = = 0 )
{
// Found
SP_DEVINFO_DATA * data2 = Clone ( & data , sizeof ( SP_DEVINFO_DATA ) ) ;
Add ( o , data2 ) ;
}
}
Free ( buffer ) ;
}
for ( i = 0 ; i < LIST_NUM ( o ) ; i + + )
{
SP_DEVINFO_DATA * data = LIST_DATA ( o , i ) ;
bool ret ;
ret = SetupDiRemoveDevice ( dev_info , data ) ;
Debug ( " Deleting Troubled NIC %u: %u \n " , i , ret ) ;
Free ( data ) ;
}
ReleaseList ( o ) ;
MsDestroyDevInfo ( dev_info ) ;
}
// Install a virtual LAN card
bool MsInstallVLan ( char * tag_name , char * connection_tag_name , char * instance_name , MS_DRIVER_VER * ver )
{
bool ret ;
Lock ( vlan_lock ) ;
{
ret = MsInstallVLanWithoutLock ( tag_name , connection_tag_name , instance_name , ver ) ;
}
Unlock ( vlan_lock ) ;
return ret ;
}
bool MsInstallVLanWithoutLock ( char * tag_name , char * connection_tag_name , char * instance_name , MS_DRIVER_VER * ver )
{
wchar_t infpath [ MAX_PATH ] ;
char hwid [ MAX_PATH ] ;
wchar_t hwid_w [ MAX_PATH ] ;
bool ret = false ;
char neo_sys [ MAX_PATH ] ;
UCHAR new_mac_address [ 6 ] ;
UINT i ;
// Validate arguments
if ( instance_name = = NULL | | tag_name = = NULL | | connection_tag_name = = NULL | | ver = = NULL )
{
return false ;
}
if ( MsIsInfCatalogRequired ( ) )
{
if ( MsIsValidVLanInstanceNameForInfCatalog ( instance_name ) = = false )
{
Debug ( " MsIsValidVLanInstanceNameForInfCatalog() returns false. \n " ) ;
return false ;
}
StrUpper ( instance_name ) ;
}
Zero ( hwid , sizeof ( hwid ) ) ;
Format ( hwid , sizeof ( hwid ) , DRIVER_DEVICE_ID_TAG , instance_name ) ;
StrToUni ( hwid_w , sizeof ( hwid_w ) , hwid ) ;
// Examine whether the virtual LAN card with the specified name has already registered
if ( MsIsVLanExists ( tag_name , instance_name ) )
{
// Already be registered
Debug ( " MsIsVLanExists() returns true. \n " ) ;
return false ;
}
// Determining destination .sys file name of the installation
if ( MsIsInfCatalogRequired ( ) = = false )
{
if ( MsMakeNewNeoDriverFilename ( neo_sys , sizeof ( neo_sys ) ) = = false )
{
return false ;
}
}
else
{
2015-05-31 13:02:35 +03:00
if ( MsIsWindows10 ( ) = = false )
{
Format ( neo_sys , sizeof ( neo_sys ) , " Neo_%s.sys " , instance_name ) ;
}
else
{
Format ( neo_sys , sizeof ( neo_sys ) , " Neo6_%s_%s.sys " , ( MsIsX64 ( ) ? " x64 " : " x86 " ) , instance_name ) ;
}
2014-01-04 17:00:08 +04:00
}
// Starting the Installation
if ( MsStartDriverInstall ( instance_name , NULL , neo_sys , new_mac_address , ver ) = = false )
{
return false ;
}
MsGetDriverPath ( instance_name , NULL , NULL , infpath , NULL , NULL , NULL , neo_sys ) ;
// Delete the device information that is left on fail of installation
2021-04-03 03:25:19 +03:00
MsDeleteTroubleVLAN ( tag_name , instance_name ) ;
2014-01-04 17:00:08 +04:00
// Call the Win32 API
ret = MsInstallVLanInternal ( infpath , hwid_w , hwid ) ;
// Installation complete
MsFinishDriverInstall ( instance_name , neo_sys ) ;
for ( i = 0 ; i < 5 ; i + + )
{
MsInitNetworkConfig ( tag_name , instance_name , connection_tag_name ) ;
if ( MsIsInfCatalogRequired ( ) )
{
// Write the MAC address
char mac_address_str [ MAX_SIZE ] ;
BinToStr ( mac_address_str , sizeof ( mac_address_str ) , new_mac_address , sizeof ( new_mac_address ) ) ;
MsSetMacAddress ( VLAN_ADAPTER_NAME_TAG , instance_name , mac_address_str ) ;
}
2021-04-03 03:25:19 +03:00
SleepThread ( 1000 ) ;
2014-01-04 17:00:08 +04:00
}
if ( ret )
{
MsDisableVLan ( instance_name ) ;
2021-04-03 03:25:19 +03:00
SleepThread ( 1000 ) ;
2014-01-04 17:00:08 +04:00
MsEnableVLan ( instance_name ) ;
}
return ret ;
}
// Test function
void MsTest ( )
{
}
// Install a virtual LAN card (by calling Win32 API)
bool MsInstallVLanInternal ( wchar_t * infpath , wchar_t * hwid_w , char * hwid )
{
2021-03-01 03:46:11 +03:00
BOOL need_reboot ;
2014-01-04 17:00:08 +04:00
bool ret = false ;
wchar_t inf_class_name [ MAX_PATH ] ;
GUID inf_class_guid ;
HDEVINFO device_info ;
SP_DEVINFO_DATA device_info_data ;
// Validate arguments
if ( infpath = = NULL | | hwid_w = = NULL | | hwid = = NULL )
{
return false ;
}
Debug ( " MsInstallVLanInternal('%S', '%S', '%s'); \n " ,
infpath , hwid_w , hwid ) ;
Zero ( & inf_class_guid , sizeof ( inf_class_guid ) ) ;
Zero ( & device_info , sizeof ( device_info ) ) ;
Zero ( & device_info_data , sizeof ( device_info_data ) ) ;
Zero ( inf_class_name , sizeof ( inf_class_name ) ) ;
// Get the class GUID of the inf file
if ( SetupDiGetINFClassW ( infpath , & inf_class_guid , inf_class_name , sizeof ( inf_class_name ) , NULL ) )
{
// Get the device information set
device_info = SetupDiCreateDeviceInfoList ( & inf_class_guid , NULL ) ;
if ( device_info ! = INVALID_HANDLE_VALUE )
{
// Windows 2000 or later
Zero ( & device_info_data , sizeof ( device_info_data ) ) ;
device_info_data . cbSize = sizeof ( device_info_data ) ;
if ( SetupDiCreateDeviceInfoW ( device_info , inf_class_name , & inf_class_guid ,
NULL , NULL , DICD_GENERATE_ID , & device_info_data ) )
{
char hwid_copy [ MAX_SIZE ] ;
Zero ( hwid_copy , sizeof ( hwid_copy ) ) ;
StrCpy ( hwid_copy , sizeof ( hwid_copy ) , hwid ) ;
// Set the registry information
if ( SetupDiSetDeviceRegistryProperty ( device_info , & device_info_data ,
SPDRP_HARDWAREID , ( BYTE * ) hwid_copy , sizeof ( hwid_copy ) ) )
{
2021-04-03 03:25:19 +03:00
NO_WARNING * nw = MsInitNoWarning ( ) ;
2014-01-04 17:00:08 +04:00
// Start the class installer
if ( SetupDiCallClassInstaller ( DIF_REGISTERDEVICE , device_info ,
& device_info_data ) )
{
// Do the installation
2021-04-03 03:25:19 +03:00
if ( UpdateDriverForPlugAndPlayDevicesW (
2014-01-04 17:00:08 +04:00
NULL , hwid_w , infpath , 1 , & need_reboot ) )
{
ret = true ;
}
else
{
// Installation Failed
Debug ( " UpdateDriverForPlugAndPlayDevicesW Error: %X \n " , GetLastError ( ) ) ;
if ( SetupDiCallClassInstaller ( DIF_REMOVE , device_info ,
& device_info_data ) = = false )
{
Debug ( " SetupDiCallClassInstaller for Delete Failed. Err=%X \n " , GetLastError ( ) ) ;
}
if ( SetupDiRemoveDevice ( device_info , & device_info_data ) = = false )
{
Debug ( " SetupDiRemoveDevice for Delete Failed. Err=%X \n " , GetLastError ( ) ) ;
}
}
}
else
{
Debug ( " SetupDiCallClassInstaller for Create Error: %X \n " , GetLastError ( ) ) ;
}
MsFreeNoWarning ( nw ) ;
}
else
{
Debug ( " SetupDiSetDeviceRegistryProperty Error: %X \n " , GetLastError ( ) ) ;
}
}
else
{
Debug ( " SetupDiCreateDeviceInfoW Error: %X \n " , GetLastError ( ) ) ;
}
// Remove the device information set
SetupDiDestroyDeviceInfoList ( device_info ) ;
}
else
{
Debug ( " SetupDiCreateDeviceInfoList Error: %X \n " , GetLastError ( ) ) ;
}
}
else
{
Debug ( " SetupDiGetINFClassW Error: %X \n " , GetLastError ( ) ) ;
}
return ret ;
}
// Get the device information from the device ID
HDEVINFO MsGetDevInfoFromDeviceId ( SP_DEVINFO_DATA * dev_info_data , char * device_id )
{
HDEVINFO dev_info ;
SP_DEVINFO_LIST_DETAIL_DATA detail_data ;
SP_DEVINFO_DATA data ;
UINT i ;
bool found ;
char target_name [ MAX_SIZE ] ;
// Validate arguments
if ( dev_info_data = = NULL | | device_id = = NULL )
{
return NULL ;
}
StrCpy ( target_name , sizeof ( target_name ) , device_id ) ;
// Create a device information list
dev_info = SetupDiGetClassDevsEx ( NULL , NULL , NULL , DIGCF_ALLCLASSES | DIGCF_PRESENT , NULL , NULL , NULL ) ;
if ( dev_info = = NULL )
{
return NULL ;
}
Zero ( & detail_data , sizeof ( detail_data ) ) ;
detail_data . cbSize = sizeof ( detail_data ) ;
if ( SetupDiGetDeviceInfoListDetail ( dev_info , & detail_data ) = = false )
{
MsDestroyDevInfo ( dev_info ) ;
return NULL ;
}
Zero ( & data , sizeof ( data ) ) ;
data . cbSize = sizeof ( data ) ;
// Enumeration start
found = false ;
for ( i = 0 ; SetupDiEnumDeviceInfo ( dev_info , i , & data ) ; i + + )
{
char * buffer ;
UINT buffer_size = 8092 ;
DWORD data_type ;
buffer = ZeroMalloc ( buffer_size ) ;
if ( SetupDiGetDeviceRegistryProperty ( dev_info , & data , SPDRP_HARDWAREID , & data_type , ( PBYTE ) buffer , buffer_size , NULL ) )
{
if ( StrCmpi ( buffer , target_name ) = = 0 )
{
// Found
found = true ;
}
}
Free ( buffer ) ;
if ( found )
{
break ;
}
}
if ( found = = false )
{
MsDestroyDevInfo ( dev_info ) ;
return NULL ;
}
else
{
Copy ( dev_info_data , & data , sizeof ( data ) ) ;
return dev_info ;
}
}
// Examine whether the specified device is operating
bool MsIsDeviceRunning ( HDEVINFO info , SP_DEVINFO_DATA * dev_info_data )
{
SP_DEVINFO_LIST_DETAIL_DATA detail ;
2021-03-01 03:46:11 +03:00
DWORD status = 0 , problem = 0 ;
2014-01-04 17:00:08 +04:00
// Validate arguments
if ( info = = NULL | | dev_info_data = = NULL )
{
return false ;
}
Zero ( & detail , sizeof ( detail ) ) ;
detail . cbSize = sizeof ( detail ) ;
if ( SetupDiGetDeviceInfoListDetail ( info , & detail ) = = false | |
2021-04-03 03:25:19 +03:00
CM_Get_DevNode_Status_Ex ( & status , & problem , dev_info_data - > DevInst ,
2014-01-04 17:00:08 +04:00
0 , detail . RemoteMachineHandle ) ! = CR_SUCCESS )
{
return false ;
}
if ( status & 8 )
{
return true ;
}
else
{
return false ;
}
}
// Start the specified device
bool MsStartDevice ( HDEVINFO info , SP_DEVINFO_DATA * dev_info_data )
{
SP_PROPCHANGE_PARAMS p ;
// Validate arguments
if ( info = = NULL | | dev_info_data = = NULL )
{
return false ;
}
Zero ( & p , sizeof ( p ) ) ;
p . ClassInstallHeader . cbSize = sizeof ( SP_CLASSINSTALL_HEADER ) ;
p . ClassInstallHeader . InstallFunction = DIF_PROPERTYCHANGE ;
p . StateChange = DICS_ENABLE ;
p . Scope = DICS_FLAG_GLOBAL ;
if ( SetupDiSetClassInstallParams ( info , dev_info_data , & p . ClassInstallHeader , sizeof ( p ) ) )
{
SetupDiCallClassInstaller ( DIF_PROPERTYCHANGE , info , dev_info_data ) ;
}
Zero ( & p , sizeof ( p ) ) ;
p . ClassInstallHeader . cbSize = sizeof ( SP_CLASSINSTALL_HEADER ) ;
p . ClassInstallHeader . InstallFunction = DIF_PROPERTYCHANGE ;
p . StateChange = DICS_ENABLE ;
p . Scope = DICS_FLAG_CONFIGSPECIFIC ;
if ( SetupDiSetClassInstallParams ( info , dev_info_data , & p . ClassInstallHeader , sizeof ( p ) ) = = false | |
SetupDiCallClassInstaller ( DIF_PROPERTYCHANGE , info , dev_info_data ) = = false )
{
return false ;
}
return true ;
}
// Stop the specified device
bool MsStopDevice ( HDEVINFO info , SP_DEVINFO_DATA * dev_info_data )
{
SP_PROPCHANGE_PARAMS p ;
// Validate arguments
if ( info = = NULL | | dev_info_data = = NULL )
{
return false ;
}
Zero ( & p , sizeof ( p ) ) ;
p . ClassInstallHeader . cbSize = sizeof ( SP_CLASSINSTALL_HEADER ) ;
p . ClassInstallHeader . InstallFunction = DIF_PROPERTYCHANGE ;
p . StateChange = DICS_DISABLE ;
p . Scope = DICS_FLAG_CONFIGSPECIFIC ;
if ( SetupDiSetClassInstallParams ( info , dev_info_data , & p . ClassInstallHeader , sizeof ( p ) ) = = false | |
SetupDiCallClassInstaller ( DIF_PROPERTYCHANGE , info , dev_info_data ) = = false )
{
return false ;
}
return true ;
}
// Remove the specified device
bool MsDeleteDevice ( HDEVINFO info , SP_DEVINFO_DATA * dev_info_data )
{
SP_REMOVEDEVICE_PARAMS p ;
SP_DEVINFO_LIST_DETAIL_DATA detail ;
char device_id [ MAX_PATH ] ;
CONFIGRET ret ;
// Validate arguments
if ( info = = NULL | | dev_info_data = = NULL )
{
return false ;
}
Zero ( & detail , sizeof ( detail ) ) ;
detail . cbSize = sizeof ( detail ) ;
if ( SetupDiGetDeviceInfoListDetail ( info , & detail ) = = false )
{
Debug ( " SetupDiGetDeviceInfoListDetail Failed. Err=0x%X \n " , GetLastError ( ) ) ;
return false ;
}
2021-04-03 03:25:19 +03:00
ret = CM_Get_Device_ID_Ex ( dev_info_data - > DevInst , device_id , sizeof ( device_id ) ,
2014-01-04 17:00:08 +04:00
0 , detail . RemoteMachineHandle ) ;
if ( ret ! = CR_SUCCESS )
{
Debug ( " CM_Get_Device_ID_Ex Failed. Err=0x%X \n " , ret ) ;
return false ;
}
Zero ( & p , sizeof ( p ) ) ;
p . ClassInstallHeader . cbSize = sizeof ( SP_CLASSINSTALL_HEADER ) ;
p . ClassInstallHeader . InstallFunction = DIF_REMOVE ;
p . Scope = DI_REMOVEDEVICE_GLOBAL ;
if ( SetupDiSetClassInstallParams ( info , dev_info_data , & p . ClassInstallHeader , sizeof ( p ) ) = = false )
{
Debug ( " SetupDiSetClassInstallParams Failed. Err=0x%X \n " , GetLastError ( ) ) ;
return false ;
}
if ( SetupDiCallClassInstaller ( DIF_REMOVE , info , dev_info_data ) = = false )
{
Debug ( " SetupDiCallClassInstaller Failed. Err=0x%X \n " , GetLastError ( ) ) ;
return false ;
}
return true ;
}
// Enable the virtual LAN card
bool MsEnableVLan ( char * instance_name )
{
bool ret ;
Lock ( vlan_lock ) ;
{
ret = MsEnableVLanWithoutLock ( instance_name ) ;
}
Unlock ( vlan_lock ) ;
return ret ;
}
bool MsEnableVLanWithoutLock ( char * instance_name )
{
char tmp [ MAX_PATH ] ;
HDEVINFO h ;
bool ret ;
SP_DEVINFO_DATA data ;
// Validate arguments
if ( instance_name = = NULL )
{
return false ;
}
Format ( tmp , sizeof ( tmp ) , DRIVER_DEVICE_ID_TAG , instance_name ) ;
h = MsGetDevInfoFromDeviceId ( & data , tmp ) ;
if ( h = = NULL )
{
return false ;
}
ret = MsStartDevice ( h , & data ) ;
MsDestroyDevInfo ( h ) ;
return ret ;
}
// Disable the virtual LAN card
bool MsDisableVLan ( char * instance_name )
{
bool ret ;
Lock ( vlan_lock ) ;
{
ret = MsDisableVLanWithoutLock ( instance_name ) ;
}
Unlock ( vlan_lock ) ;
return ret ;
}
bool MsDisableVLanWithoutLock ( char * instance_name )
{
char tmp [ MAX_PATH ] ;
HDEVINFO h ;
bool ret ;
SP_DEVINFO_DATA data ;
// Validate arguments
if ( instance_name = = NULL )
{
return false ;
}
Format ( tmp , sizeof ( tmp ) , DRIVER_DEVICE_ID_TAG , instance_name ) ;
h = MsGetDevInfoFromDeviceId ( & data , tmp ) ;
if ( h = = NULL )
{
return false ;
}
ret = MsStopDevice ( h , & data ) ;
MsDestroyDevInfo ( h ) ;
return ret ;
}
// Restart the virtual LAN card
void MsRestartVLan ( char * instance_name )
{
Lock ( vlan_lock ) ;
{
MsRestartVLanWithoutLock ( instance_name ) ;
}
Unlock ( vlan_lock ) ;
}
void MsRestartVLanWithoutLock ( char * instance_name )
{
// Validate arguments
if ( instance_name = = NULL )
{
return ;
}
if ( MsIsVLanEnabled ( instance_name ) = = false )
{
return ;
}
MsDisableVLan ( instance_name ) ;
MsEnableVLan ( instance_name ) ;
}
// Get whether the virtual LAN card is working
bool MsIsVLanEnabled ( char * instance_name )
{
bool ret ;
Lock ( vlan_lock ) ;
{
ret = MsIsVLanEnabledWithoutLock ( instance_name ) ;
}
Unlock ( vlan_lock ) ;
return ret ;
}
bool MsIsVLanEnabledWithoutLock ( char * instance_name )
{
char tmp [ MAX_PATH ] ;
HDEVINFO h ;
bool ret ;
SP_DEVINFO_DATA data ;
// Validate arguments
if ( instance_name = = NULL )
{
return false ;
}
Format ( tmp , sizeof ( tmp ) , DRIVER_DEVICE_ID_TAG , instance_name ) ;
h = MsGetDevInfoFromDeviceId ( & data , tmp ) ;
if ( h = = NULL )
{
return false ;
}
ret = MsIsDeviceRunning ( h , & data ) ;
MsDestroyDevInfo ( h ) ;
return ret ;
}
// Uninstall the virtual LAN card
bool MsUninstallVLan ( char * instance_name )
{
bool ret ;
Lock ( vlan_lock ) ;
{
ret = MsUninstallVLanWithoutLock ( instance_name ) ;
}
Unlock ( vlan_lock ) ;
return ret ;
}
bool MsUninstallVLanWithoutLock ( char * instance_name )
{
char tmp [ MAX_PATH ] ;
HDEVINFO h ;
bool ret ;
SP_DEVINFO_DATA data ;
// Validate arguments
if ( instance_name = = NULL )
{
return false ;
}
Format ( tmp , sizeof ( tmp ) , DRIVER_DEVICE_ID_TAG , instance_name ) ;
h = MsGetDevInfoFromDeviceId ( & data , tmp ) ;
if ( h = = NULL )
{
return false ;
}
ret = MsDeleteDevice ( h , & data ) ;
MsDestroyDevInfo ( h ) ;
return ret ;
}
// Dispose the device information
void MsDestroyDevInfo ( HDEVINFO info )
{
// Validate arguments
if ( info = = NULL )
{
return ;
}
SetupDiDestroyDeviceInfoList ( info ) ;
}
// Start the driver installation
bool MsStartDriverInstall ( char * instance_name , UCHAR * mac_address , char * neo_sys , UCHAR * ret_mac_address , MS_DRIVER_VER * ver )
{
wchar_t src_inf [ MAX_PATH ] ;
wchar_t src_sys [ MAX_PATH ] ;
wchar_t dest_inf [ MAX_PATH ] ;
wchar_t dest_sys [ MAX_PATH ] ;
wchar_t src_cat [ MAX_PATH ] ;
wchar_t dst_cat [ MAX_PATH ] ;
UCHAR mac_address_bin [ 6 ] ;
char mac_address_str [ 32 ] ;
UINT size ;
char * tmp ;
BUF * b ;
IO * io ;
char str_year [ 16 ] ;
char str_month [ 16 ] ;
char str_day [ 16 ] ;
char str_major [ 16 ] ;
char str_minor [ 16 ] ;
char str_build [ 16 ] ;
// Validate arguments
if ( instance_name = = NULL | | neo_sys = = NULL | | ver = = NULL )
{
return false ;
}
Format ( str_year , sizeof ( str_year ) , " %04d " , ver - > Year ) ;
Format ( str_month , sizeof ( str_month ) , " %02d " , ver - > Month ) ;
Format ( str_day , sizeof ( str_day ) , " %02d " , ver - > Day ) ;
ToStr ( str_major , ver - > Major ) ;
ToStr ( str_minor , ver - > Minor ) ;
ToStr ( str_build , ver - > Build ) ;
MsGetDriverPath ( instance_name , src_inf , src_sys , dest_inf , dest_sys , src_cat , dst_cat , neo_sys ) ;
Debug ( " MsStartDriverInstall \n " ) ;
Debug ( " instance_name: %s \n " , instance_name ) ;
Debug ( " src_inf: %S \n " , src_inf ) ;
Debug ( " src_sys: %S \n " , src_sys ) ;
Debug ( " dest_inf: %S \n " , dest_inf ) ;
Debug ( " dest_sys: %S \n " , dest_sys ) ;
Debug ( " src_cat: %S \n " , src_cat ) ;
Debug ( " dst_cat: %S \n " , dst_cat ) ;
Debug ( " neo_sys: %s \n " , neo_sys ) ;
// Processing INF file
io = FileOpenW ( src_inf , false ) ;
if ( io = = NULL )
{
return false ;
}
size = FileSize ( io ) ;
tmp = ZeroMalloc ( size * 2 ) ;
if ( FileRead ( io , tmp , size ) = = false )
{
FileClose ( io ) ;
Free ( tmp ) ;
return false ;
}
FileClose ( io ) ;
if ( mac_address = = NULL )
{
MsGenMacAddress ( mac_address_bin ) ;
}
else
{
Copy ( mac_address_bin , mac_address , 6 ) ;
}
BinToStr ( mac_address_str , sizeof ( mac_address_str ) , mac_address_bin , sizeof ( mac_address_bin ) ) ;
//ReplaceStrEx(tmp, size * 2, tmp, "$TAG_DRIVER_VER$", DRIVER_VER_STR, false);
ReplaceStrEx ( tmp , size * 2 , tmp , " $TAG_INSTANCE_NAME$ " , instance_name , false ) ;
ReplaceStrEx ( tmp , size * 2 , tmp , " $TAG_MAC_ADDRESS$ " , mac_address_str , false ) ;
ReplaceStrEx ( tmp , size * 2 , tmp , " $TAG_SYS_NAME$ " , neo_sys , false ) ;
ReplaceStrEx ( tmp , size * 2 , tmp , " $YEAR$ " , str_year , false ) ;
ReplaceStrEx ( tmp , size * 2 , tmp , " $MONTH$ " , str_month , false ) ;
ReplaceStrEx ( tmp , size * 2 , tmp , " $DAY$ " , str_day , false ) ;
ReplaceStrEx ( tmp , size * 2 , tmp , " $VER_MAJOR$ " , str_major , false ) ;
ReplaceStrEx ( tmp , size * 2 , tmp , " $VER_MINOR$ " , str_minor , false ) ;
ReplaceStrEx ( tmp , size * 2 , tmp , " $VER_BUILD$ " , str_build , false ) ;
io = FileCreateW ( dest_inf ) ;
if ( io = = NULL )
{
Free ( tmp ) ;
return false ;
}
FileWrite ( io , tmp , StrLen ( tmp ) ) ;
FileClose ( io ) ;
Free ( tmp ) ;
// Processing the SYS file
b = ReadDumpW ( src_sys ) ;
if ( b = = NULL )
{
return false ;
}
if ( DumpBufW ( b , dest_sys ) = = false )
{
FreeBuf ( b ) ;
return false ;
}
FreeBuf ( b ) ;
// Copy of the catalog file
if ( IsEmptyUniStr ( src_cat ) = = false & & IsEmptyUniStr ( dst_cat ) = = false )
{
if ( FileCopyW ( src_cat , dst_cat ) = = false )
{
return false ;
}
}
if ( ret_mac_address ! = NULL )
{
Copy ( ret_mac_address , mac_address_bin , 6 ) ;
}
return true ;
}
// Generation of the MAC address
void MsGenMacAddress ( UCHAR * mac )
{
UCHAR hash_src [ 40 ] ;
UCHAR hash [ 20 ] ;
UINT64 now ;
// Validate arguments
if ( mac = = NULL )
{
return ;
}
Rand ( hash_src , 40 ) ;
now = SystemTime64 ( ) ;
Copy ( hash_src , & now , sizeof ( now ) ) ;
2018-09-22 07:35:30 +03:00
Sha0 ( hash , hash_src , sizeof ( hash_src ) ) ;
2014-01-04 17:00:08 +04:00
2018-04-22 12:24:29 +03:00
mac [ 0 ] = 0x5E ;
mac [ 1 ] = hash [ 0 ] ;
mac [ 2 ] = hash [ 1 ] ;
mac [ 3 ] = hash [ 2 ] ;
mac [ 4 ] = hash [ 3 ] ;
mac [ 5 ] = hash [ 4 ] ;
2014-01-04 17:00:08 +04:00
}
// Finish the driver installation
void MsFinishDriverInstall ( char * instance_name , char * neo_sys )
{
wchar_t src_inf [ MAX_PATH ] ;
wchar_t src_sys [ MAX_PATH ] ;
wchar_t dest_inf [ MAX_PATH ] ;
wchar_t dest_sys [ MAX_PATH ] ;
wchar_t src_cat [ MAX_SIZE ] ;
wchar_t dst_cat [ MAX_SIZE ] ;
// Validate arguments
if ( instance_name = = NULL )
{
return ;
}
MsGetDriverPath ( instance_name , src_inf , src_sys , dest_inf , dest_sys , src_cat , dst_cat , neo_sys ) ;
// Delete the files
FileDeleteW ( dest_inf ) ;
FileDeleteW ( dest_sys ) ;
if ( IsEmptyUniStr ( dst_cat ) = = false )
{
FileDeleteW ( dst_cat ) ;
}
}
// Get the path to the driver file
2021-04-03 03:25:19 +03:00
void MsGetDriverPath ( char * instance_name , wchar_t * src_inf , wchar_t * src_sys , wchar_t * dest_inf , wchar_t * dest_sys , wchar_t * src_cat , wchar_t * dest_cat , char * neo_sys )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
wchar_t * src_filename ;
wchar_t * src_sys_filename ;
2014-01-04 17:00:08 +04:00
// Validate arguments
if ( instance_name = = NULL )
{
return ;
}
2021-04-03 03:25:19 +03:00
if ( MsIsX64 ( ) )
2014-01-04 17:00:08 +04:00
{
2015-05-31 13:02:35 +03:00
src_filename = L " |DriverPackages \\ Neo \\ x64 \\ Neo_x64.inf " ;
src_sys_filename = L " |DriverPackages \\ Neo \\ x64 \\ Neo_x64.sys " ;
}
2021-04-03 03:25:19 +03:00
else
{
src_filename = L " |DriverPackages \\ Neo \\ x86 \\ Neo_x86.inf " ;
src_sys_filename = L " |DriverPackages \\ Neo \\ x86 \\ Neo_x86.sys " ;
}
2015-05-31 13:02:35 +03:00
if ( MsIsWindows7 ( ) )
{
// Use the NDIS 6.2 driver for Windows 7 or later
2014-01-04 17:00:08 +04:00
if ( MsIsX64 ( ) )
{
2015-05-31 13:02:35 +03:00
src_filename = L " |DriverPackages \\ Neo6 \\ x64 \\ Neo6_x64.inf " ;
src_sys_filename = L " |DriverPackages \\ Neo6 \\ x64 \\ Neo6_x64.sys " ;
2014-01-04 17:00:08 +04:00
}
else
{
2015-05-31 13:02:35 +03:00
src_filename = L " |DriverPackages \\ Neo6 \\ x86 \\ Neo6_x86.inf " ;
src_sys_filename = L " |DriverPackages \\ Neo6 \\ x86 \\ Neo6_x86.sys " ;
2014-01-04 17:00:08 +04:00
}
}
2015-05-31 13:02:35 +03:00
if ( MsIsInfCatalogRequired ( ) )
2014-01-04 17:00:08 +04:00
{
2015-05-31 13:02:35 +03:00
// Windows 8 or later
2014-01-04 17:00:08 +04:00
if ( MsIsX64 ( ) )
{
2015-05-31 13:02:35 +03:00
src_filename = L " |DriverPackages \\ Neo6_Win8 \\ x64 \\ Neo6_x64.inf " ;
src_sys_filename = L " |DriverPackages \\ Neo6_Win8 \\ x64 \\ Neo6_x64.sys " ;
2014-01-04 17:00:08 +04:00
}
else
{
2015-05-31 13:02:35 +03:00
src_filename = L " |DriverPackages \\ Neo6_Win8 \\ x86 \\ Neo6_x86.inf " ;
src_sys_filename = L " |DriverPackages \\ Neo6_Win8 \\ x86 \\ Neo6_x86.sys " ;
2014-01-04 17:00:08 +04:00
}
}
if ( src_inf ! = NULL )
{
if ( MsIsInfCatalogRequired ( ) = = false )
{
2015-05-31 13:02:35 +03:00
// Windows 7 or before
2014-01-04 17:00:08 +04:00
UniStrCpy ( src_inf , MAX_PATH , src_filename ) ;
}
else
{
2015-05-31 13:02:35 +03:00
// Windows 8.1 or later
2014-01-04 17:00:08 +04:00
char tmp [ MAX_SIZE ] ;
MsGetInfCatalogDir ( tmp , sizeof ( tmp ) ) ;
2015-05-31 13:02:35 +03:00
UniFormat ( src_inf , MAX_PATH , L " %S \\ Neo6_%S_%S.inf " , tmp , ( MsIsX64 ( ) ? " x64 " : " x86 " ) , instance_name ) ;
2014-01-04 17:00:08 +04:00
}
}
if ( src_sys ! = NULL )
{
UniStrCpy ( src_sys , MAX_PATH , src_sys_filename ) ;
2015-05-31 13:02:35 +03:00
if ( MsIsWindows10 ( ) )
{
UniFormat ( src_sys , MAX_PATH , L " |DriverPackages \\ Neo6_Win10 \\ %S \\ Neo6_%S_%S.sys " ,
( MsIsX64 ( ) ? " x64 " : " x86 " ) , ( MsIsX64 ( ) ? " x64 " : " x86 " ) , instance_name ) ;
}
2014-01-04 17:00:08 +04:00
}
if ( dest_inf ! = NULL )
{
char inf_name [ MAX_PATH ] ;
2015-05-31 13:02:35 +03:00
if ( MsIsInfCatalogRequired ( ) = = false )
{
Format ( inf_name , sizeof ( inf_name ) , " Neo_%s.inf " , instance_name ) ;
}
else
{
Format ( inf_name , sizeof ( inf_name ) , " Neo6_%s_%s.inf " , ( MsIsX64 ( ) ? " x64 " : " x86 " ) , instance_name ) ;
}
2014-01-04 17:00:08 +04:00
UniFormat ( dest_inf , MAX_PATH , L " %s \\ %S " , ms - > MyTempDirW , inf_name ) ;
}
if ( dest_sys ! = NULL )
{
char sys_name [ MAX_PATH ] ;
StrCpy ( sys_name , sizeof ( sys_name ) , neo_sys ) ;
UniFormat ( dest_sys , MAX_PATH , L " %s \\ %S " , ms - > MyTempDirW , sys_name ) ;
}
if ( src_cat ! = NULL )
{
if ( MsIsInfCatalogRequired ( ) )
{
char tmp [ MAX_SIZE ] ;
MsGetInfCatalogDir ( tmp , sizeof ( tmp ) ) ;
2015-05-31 13:02:35 +03:00
if ( MsIsWindows8 ( ) = = false )
{
// Windows Vista and Windows 7 uses SHA-1 catalog files
// (Unused? Never reach here!)
UniFormat ( src_cat , MAX_PATH , L " %S \\ inf.cat " , tmp ) ;
}
else
{
// Windows 8 or above uses SHA-256 catalog files
UniFormat ( src_cat , MAX_PATH , L " %S \\ inf2.cat " , tmp ) ;
}
if ( MsIsWindows10 ( ) )
{
// Windows 10
UniFormat ( src_cat , MAX_PATH , L " %S \\ Neo6_%S_%S.cat " , tmp , ( MsIsX64 ( ) ? " x64 " : " x86 " ) , instance_name ) ;
}
2014-01-04 17:00:08 +04:00
}
else
{
UniStrCpy ( src_cat , MAX_PATH , L " " ) ;
}
}
if ( dest_cat ! = NULL )
{
if ( MsIsInfCatalogRequired ( ) )
{
2015-05-31 13:02:35 +03:00
if ( MsIsWindows10 ( ) = = false )
{
UniFormat ( dest_cat , MAX_PATH , L " %s \\ inf_%S.cat " , ms - > MyTempDirW , instance_name ) ;
}
else
{
UniFormat ( dest_cat , MAX_PATH , L " %s \\ Neo6_%S_%S.cat " , ms - > MyTempDirW , ( MsIsX64 ( ) ? " x64 " : " x86 " ) , instance_name ) ;
}
2014-01-04 17:00:08 +04:00
}
else
{
UniStrCpy ( dest_cat , MAX_PATH , L " " ) ;
}
}
}
void MsGetDriverPathA ( char * instance_name , char * src_inf , char * src_sys , char * dest_inf , char * dest_sys , char * src_cat , char * dst_cat , char * neo_sys )
{
wchar_t src_inf_w [ MAX_PATH ] ;
wchar_t src_sys_w [ MAX_PATH ] ;
wchar_t dest_inf_w [ MAX_PATH ] ;
wchar_t dest_sys_w [ MAX_PATH ] ;
wchar_t src_cat_w [ MAX_PATH ] ;
wchar_t dst_cat_w [ MAX_PATH ] ;
// Validate arguments
if ( instance_name = = NULL )
{
return ;
}
MsGetDriverPath ( instance_name , src_inf_w , src_sys_w , dest_inf_w , dest_sys_w , src_cat_w , dst_cat_w , neo_sys ) ;
UniToStr ( src_inf , MAX_PATH , src_inf_w ) ;
UniToStr ( src_sys , MAX_PATH , src_sys_w ) ;
UniToStr ( dest_inf , MAX_PATH , dest_inf_w ) ;
UniToStr ( dest_sys , MAX_PATH , dest_sys_w ) ;
UniToStr ( src_cat , MAX_PATH , src_cat_w ) ;
UniToStr ( dst_cat , MAX_PATH , dst_cat_w ) ;
}
// Examine whether the virtual LAN card with the specified name has already registered
bool MsIsVLanExists ( char * tag_name , char * instance_name )
{
char * guid ;
// Validate arguments
if ( instance_name = = NULL | | tag_name = = NULL )
{
return false ;
}
guid = MsGetNetworkAdapterGuid ( tag_name , instance_name ) ;
if ( guid = = NULL )
{
return false ;
}
Free ( guid ) ;
return true ;
}
// Delete VPN temporary directories that remain in the system but not used
void MsDeleteTempDir ( )
{
HANDLE h ;
wchar_t dir_mask [ MAX_PATH ] ;
WIN32_FIND_DATAA data_a ;
WIN32_FIND_DATAW data_w ;
Zero ( & data_a , sizeof ( data_a ) ) ;
Zero ( & data_w , sizeof ( data_w ) ) ;
UniFormat ( dir_mask , sizeof ( dir_mask ) , L " %s \\ * " , ms - > TempDirW ) ;
if ( IsNt ( ) )
{
h = FindFirstFileW ( dir_mask , & data_w ) ;
}
else
{
char * tmp_a = CopyUniToStr ( dir_mask ) ;
h = FindFirstFileA ( tmp_a , & data_a ) ;
Free ( tmp_a ) ;
}
if ( h ! = INVALID_HANDLE_VALUE )
{
bool b = true ;
do
{
if ( IsNt ( ) = = false )
{
Zero ( & data_w , sizeof ( data_w ) ) ;
StrToUni ( data_w . cFileName , sizeof ( data_w . cFileName ) , data_a . cFileName ) ;
data_w . dwFileAttributes = data_a . dwFileAttributes ;
data_w . ftCreationTime = data_a . ftCreationTime ;
data_w . ftLastWriteTime = data_a . ftLastWriteTime ;
data_w . nFileSizeHigh = data_a . nFileSizeHigh ;
data_w . nFileSizeLow = data_a . nFileSizeLow ;
}
if ( UniStrCmpi ( data_w . cFileName , L " . " ) ! = 0 & &
UniStrCmpi ( data_w . cFileName , L " .. " ) ! = 0 )
{
if ( data_w . dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
{
if ( UniStartWith ( data_w . cFileName , L " VPN_ " ) & & UniStrLen ( data_w . cFileName ) = = 8 )
{
wchar_t lock_file_name [ MAX_PATH ] ;
wchar_t dir_name [ MAX_PATH ] ;
bool delete_now = false ;
IO * io ;
UniFormat ( dir_name , sizeof ( dir_name ) , L " %s \\ %s " ,
ms - > TempDirW , data_w . cFileName ) ;
MsGenLockFile ( lock_file_name , sizeof ( lock_file_name ) , dir_name ) ;
io = FileOpenExW ( lock_file_name , false , false ) ;
if ( io ! = NULL )
{
// Mark to delete if the lock file is not locked
FileClose ( io ) ;
io = FileOpenW ( lock_file_name , true ) ;
if ( io ! = NULL )
{
delete_now = true ;
FileClose ( io ) ;
}
}
else
{
DIRLIST * d ;
// Mark to delete if all files in this folder are not locked
delete_now = true ;
d = EnumDirW ( dir_name ) ;
if ( d ! = NULL )
{
UINT i ;
for ( i = 0 ; i < d - > NumFiles ; i + + )
{
wchar_t full_path [ MAX_PATH ] ;
UniFormat ( full_path , sizeof ( full_path ) , L " %s \\ %s " , dir_name , d - > File [ i ] - > FileNameW ) ;
io = FileOpenW ( full_path , true ) ;
if ( io ! = NULL )
{
delete_now = true ;
FileClose ( io ) ;
}
}
FreeDir ( d ) ;
}
}
if ( delete_now )
{
MsDeleteAllFileW ( dir_name ) ;
Win32DeleteDirW ( dir_name ) ;
}
}
}
}
Zero ( & data_w , sizeof ( data_w ) ) ;
Zero ( & data_a , sizeof ( data_a ) ) ;
if ( IsNt ( ) )
{
b = FindNextFileW ( h , & data_w ) ;
}
else
{
b = FindNextFileA ( h , & data_a ) ;
}
}
while ( b ) ;
FindClose ( h ) ;
}
}
// Delete all the files in the specified directory
void MsDeleteAllFile ( char * dir )
{
HANDLE h ;
char file_mask [ MAX_PATH ] ;
WIN32_FIND_DATA data ;
// Validate arguments
if ( dir = = NULL | | IsEmptyStr ( dir ) )
{
return ;
}
Format ( file_mask , sizeof ( file_mask ) , " %s \\ *.* " , dir ) ;
h = FindFirstFile ( file_mask , & data ) ;
if ( h ! = INVALID_HANDLE_VALUE )
{
do
{
if ( StrCmpi ( data . cFileName , " . " ) ! = 0 & &
StrCmpi ( data . cFileName , " .. " ) ! = 0 )
{
char fullpath [ MAX_PATH ] ;
Format ( fullpath , sizeof ( fullpath ) , " %s \\ %s " , dir , data . cFileName ) ;
if ( ( data . dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) = = false )
{
DeleteFile ( fullpath ) ;
}
else
{
MsDeleteAllFile ( fullpath ) ;
RemoveDirectory ( fullpath ) ;
}
}
}
while ( FindNextFile ( h , & data ) ) ;
FindClose ( h ) ;
}
}
void MsDeleteAllFileW ( wchar_t * dir )
{
HANDLE h ;
wchar_t file_mask [ MAX_PATH ] ;
WIN32_FIND_DATAW data ;
// Validate arguments
if ( dir = = NULL | | UniIsEmptyStr ( dir ) )
{
return ;
}
if ( IsNt ( ) = = false )
{
char * dir_a = CopyUniToStr ( dir ) ;
MsDeleteAllFile ( dir_a ) ;
Free ( dir_a ) ;
return ;
}
UniFormat ( file_mask , sizeof ( file_mask ) , L " %s \\ *.* " , dir ) ;
h = FindFirstFileW ( file_mask , & data ) ;
if ( h ! = INVALID_HANDLE_VALUE )
{
do
{
if ( UniStrCmpi ( data . cFileName , L " . " ) ! = 0 & &
UniStrCmpi ( data . cFileName , L " .. " ) ! = 0 )
{
wchar_t fullpath [ MAX_PATH ] ;
UniFormat ( fullpath , sizeof ( fullpath ) , L " %s \\ %s " , dir , data . cFileName ) ;
if ( ( data . dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) = = false )
{
DeleteFileW ( fullpath ) ;
}
else
{
MsDeleteAllFileW ( fullpath ) ;
RemoveDirectoryW ( fullpath ) ;
}
}
}
while ( FindNextFileW ( h , & data ) ) ;
FindClose ( h ) ;
}
}
// Initialize the temporary directory
void MsInitTempDir ( )
{
wchar_t tmp [ MAX_PATH ] ;
wchar_t tmp2 [ 16 ] ;
UCHAR random [ 2 ] ;
wchar_t lockfilename [ MAX_PATH ] ;
UINT num = 0 ;
// Delete the unused temporary directory
MsDeleteTempDir ( ) ;
// Determine the name of the temporary directory
while ( true )
{
random [ 0 ] = rand ( ) % 256 ;
random [ 1 ] = rand ( ) % 256 ;
BinToStrW ( tmp2 , sizeof ( tmp2 ) , random , sizeof ( random ) ) ;
UniFormat ( tmp , sizeof ( tmp ) , L " %s \\ VPN_%s " , ms - > TempDirW , tmp2 ) ;
// Create Directory
if ( MakeDirW ( tmp ) )
{
break ;
}
if ( ( num + + ) > = 100 )
{
// Failed many times
char msg [ MAX_SIZE ] ;
Format ( msg , sizeof ( msg ) ,
" Couldn't create Temporary Directory: %s \r \n \r \n "
" Please contact your system administrator. " ,
tmp ) ;
exit ( 0 ) ;
}
}
ms - > MyTempDirW = CopyUniStr ( tmp ) ;
ms - > MyTempDir = CopyUniToStr ( tmp ) ;
// Create a lock file
MsGenLockFile ( lockfilename , sizeof ( lockfilename ) , ms - > MyTempDirW ) ;
ms - > LockFile = FileCreateW ( lockfilename ) ;
}
// Release the temporary directory
void MsFreeTempDir ( )
{
wchar_t lock_file_name [ MAX_SIZE ] ;
// Delete the lock file
MsGenLockFile ( lock_file_name , sizeof ( lock_file_name ) , ms - > MyTempDirW ) ;
FileClose ( ms - > LockFile ) ;
// Memory release
Free ( ms - > MyTempDir ) ;
Free ( ms - > MyTempDirW ) ;
ms - > MyTempDir = NULL ;
ms - > MyTempDirW = NULL ;
// Delete directory
MsDeleteTempDir ( ) ;
}
// Generation of the name of the lock file
void MsGenLockFile ( wchar_t * name , UINT size , wchar_t * temp_dir )
{
// Validate arguments
if ( name = = NULL | | temp_dir = = NULL )
{
return ;
}
UniFormat ( name , size , L " %s \\ VPN_Lock.dat " , temp_dir ) ;
}
// Normalization of the configuration of the interface metric of the default gateway in the network configuration
void MsNormalizeInterfaceDefaultGatewaySettings ( char * tag_name , char * instance_name )
{
char tmp [ MAX_SIZE ] ;
char netsh [ MAX_PATH ] ;
char * config_str ;
char tmp2 [ MAX_SIZE ] ;
UINT if_index ;
UINT if_metric ;
// Validate arguments
if ( tag_name = = NULL | | instance_name = = NULL )
{
return ;
}
Debug ( " MsNormalizeInterfaceDefaultGatewaySettings() \n " ) ;
Format ( tmp2 , sizeof ( tmp2 ) , tag_name , instance_name ) ;
if_index = Win32GetVLanInterfaceID ( tmp2 ) ;
Debug ( " if_index=%u \n " , if_index ) ;
if ( if_index = = 0 )
{
return ;
}
CombinePath ( netsh , sizeof ( netsh ) , MsGetSystem32Dir ( ) , " netsh.exe " ) ;
// Set the interface metric value
config_str = MsGetNetworkAdapterGuid ( tag_name , instance_name ) ;
if ( config_str ! = NULL )
{
LIST * o ;
LIST * o2 ;
Debug ( " MsNormalizeInterfaceDefaultGatewaySettings() \n " ) ;
Debug ( " if_index(%s) = %u \n " , instance_name , if_index ) ;
Format ( tmp , sizeof ( tmp ) , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters \\ Interfaces \\ %s " ,
config_str ) ;
o = MsRegReadStrList ( REG_LOCAL_MACHINE , tmp , " DefaultGateway " ) ;
o2 = MsRegReadStrList ( REG_LOCAL_MACHINE , tmp , " DefaultGatewayMetric " ) ;
if_metric = MsRegReadInt ( REG_LOCAL_MACHINE , tmp , " InterfaceMetric " ) ;
Debug ( " if_metric = %u \n " , if_metric ) ;
if ( if_metric ! = 0 )
{
if ( o ! = NULL )
{
UINT i ;
for ( i = 0 ; i < LIST_NUM ( o ) ; i + + )
{
char * s = LIST_DATA ( o , i ) ;
char tmp [ MAX_SIZE ] ;
2021-03-01 03:46:11 +03:00
UINT current_metric = 0 ;
2014-01-04 17:00:08 +04:00
if ( o2 ! = NULL )
{
if ( LIST_NUM ( o2 ) > i )
{
current_metric = ToInt ( LIST_DATA ( o2 , i ) ) ;
}
}
Debug ( " gateway[%u] = %s \n " , i , s ) ;
Debug ( " current_metric[%u] = %u \n " , i , current_metric ) ;
if ( current_metric = = 0 )
{
if ( IsEmptyStr ( s ) = = false )
{
Format ( tmp , sizeof ( tmp ) , " int ipv4 delete route prefix=0.0.0.0/0 interface=%u nexthop=%s " ,
if_index , s ) ;
Debug ( " netsh %s \n " , tmp ) ;
Run ( netsh , tmp , true , true ) ;
Format ( tmp , sizeof ( tmp ) , " int ipv4 add route prefix=0.0.0.0/0 interface=%u nexthop=%s metric=%u " ,
if_index , s , if_metric ) ;
Debug ( " netsh %s \n " , tmp ) ;
Run ( netsh , tmp , true , true ) ;
}
}
}
}
}
FreeStrList ( o ) ;
FreeStrList ( o2 ) ;
Free ( config_str ) ;
}
}
// Initialization of the network configuration
void MsInitNetworkConfig ( char * tag_name , char * instance_name , char * connection_tag_name )
{
char tmp [ MAX_SIZE ] ;
char * config_str ;
// Validate arguments
if ( tag_name = = NULL | | instance_name = = NULL | | connection_tag_name = = NULL )
{
return ;
}
// Settings such as string
Format ( tmp , sizeof ( tmp ) , connection_tag_name , instance_name ) ;
MsSetNetworkConfig ( tag_name , instance_name , tmp , true ) ;
// Set the interface metric value
config_str = MsGetNetworkAdapterGuid ( tag_name , instance_name ) ;
if ( config_str ! = NULL )
{
Format ( tmp , sizeof ( tmp ) , " SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters \\ Interfaces \\ %s " ,
config_str ) ;
MsRegWriteInt ( REG_LOCAL_MACHINE , tmp , " InterfaceMetric " , 1 ) ;
MsRegWriteInt ( REG_LOCAL_MACHINE , tmp , " EnableDeadGWDetect " , 0 ) ;
if ( MsRegReadInt ( REG_LOCAL_MACHINE ,
" SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " ,
" packetix_no_optimize " ) = = 0 )
{
MsRegWriteInt ( REG_LOCAL_MACHINE ,
" SYSTEM \\ CurrentControlSet \\ Services \\ Tcpip \\ Parameters " ,
" EnableDeadGWDetect " ,
0 ) ;
}
Free ( config_str ) ;
}
}
// Configure the network settings
void MsSetNetworkConfig ( char * tag_name , char * instance_name , char * friendly_name , bool show_icon )
{
char * key ;
char * old_name ;
// Validate arguments
if ( tag_name = = NULL | | instance_name = = NULL | | friendly_name = = NULL )
{
return ;
}
key = MsGetNetworkConfigRegKeyNameFromInstanceName ( tag_name , instance_name ) ;
if ( key = = NULL )
{
return ;
}
old_name = MsRegReadStr ( REG_LOCAL_MACHINE , key , " Name " ) ;
if ( old_name ! = NULL )
{
2021-04-03 03:25:19 +03:00
if ( true )
2014-01-04 17:00:08 +04:00
{
char arg [ MAX_PATH ] ;
char netsh [ MAX_PATH ] ;
Format ( netsh , sizeof ( netsh ) , " %s \\ netsh.exe " , MsGetSystem32Dir ( ) ) ;
if ( StrCmp ( old_name , friendly_name ) ! = 0 )
{
Format ( arg , sizeof ( arg ) , " interface set interface name= \" %s \" newname= \" %s \" " ,
old_name , friendly_name ) ;
Run ( netsh , arg , true , true ) ;
}
Format ( arg , sizeof ( arg ) , " netsh interface ipv4 set interface interface= \" %s \" metric=1 " ,
friendly_name ) ;
Run ( netsh , arg , true , true ) ;
}
}
if ( StrCmp ( old_name , friendly_name ) ! = 0 )
{
MsRegWriteStr ( REG_LOCAL_MACHINE , key , " Name " , friendly_name ) ;
}
MsRegWriteInt ( REG_LOCAL_MACHINE , key , " ShowIcon " , show_icon ? 1 : 0 ) ;
Free ( key ) ;
Free ( old_name ) ;
}
// Get the network configuration key name by the instance name
char * MsGetNetworkConfigRegKeyNameFromInstanceName ( char * tag_name , char * instance_name )
{
char * guid , * ret ;
// Validate arguments
if ( tag_name = = NULL | | instance_name = = NULL )
{
return NULL ;
}
guid = MsGetNetworkAdapterGuid ( tag_name , instance_name ) ;
if ( guid = = NULL )
{
return NULL ;
}
ret = MsGetNetworkConfigRegKeyNameFromGuid ( guid ) ;
Free ( guid ) ;
return ret ;
}
// Get the network configuration key name by the GUID
char * MsGetNetworkConfigRegKeyNameFromGuid ( char * guid )
{
char tmp [ MAX_SIZE ] ;
// Validate arguments
if ( guid = = NULL )
{
return NULL ;
}
Format ( tmp , sizeof ( tmp ) ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Network \\ {4D36E972-E325-11CE-BFC1-08002BE10318} \\ %s \\ Connection " ,
guid ) ;
return CopyStr ( tmp ) ;
}
// Configuring the MAC address
void MsSetMacAddress ( char * tag_name , char * instance_name , char * mac_address )
{
TOKEN_LIST * key_list ;
UINT i ;
char dest_name [ MAX_SIZE ] ;
char mac_str [ MAX_SIZE ] ;
// Validate arguments
if ( tag_name = = NULL | | instance_name = = NULL )
{
return ;
}
// Normalization of the MAC address
if ( NormalizeMacAddress ( mac_str , sizeof ( mac_str ) , mac_address ) = = false )
{
return ;
}
// Generate the desired name
Format ( dest_name , sizeof ( dest_name ) , tag_name , instance_name ) ;
// Enumerate the key
2021-04-03 03:25:19 +03:00
key_list = MsRegEnumKey ( REG_LOCAL_MACHINE ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} " ) ;
2014-01-04 17:00:08 +04:00
if ( key_list = = NULL )
{
return ;
}
for ( i = 0 ; i < key_list - > NumTokens ; i + + )
{
char * key_name = key_list - > Token [ i ] ;
char full_key_name [ MAX_SIZE ] ;
char * driver_desc ;
2021-04-03 03:25:19 +03:00
Format ( full_key_name , sizeof ( full_key_name ) ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} \\ %s " ,
key_name ) ;
2014-01-04 17:00:08 +04:00
// Read the DriverDesc
driver_desc = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " DriverDesc " ) ;
if ( driver_desc ! = NULL )
{
if ( StrCmpi ( dest_name , driver_desc ) = = 0 )
{
// Writing of the MAC address
MsRegWriteStr ( REG_LOCAL_MACHINE , full_key_name , " NetworkAddress " , mac_str ) ;
Free ( driver_desc ) ;
// Restarting the driver
MsRestartVLan ( instance_name ) ;
break ;
}
Free ( driver_desc ) ;
}
}
FreeToken ( key_list ) ;
return ;
}
// Get the file name of the device driver
char * MsGetDriverFileName ( char * tag_name , char * instance_name )
{
TOKEN_LIST * key_list ;
UINT i ;
char * ret = NULL ;
char dest_name [ MAX_SIZE ] ;
// Validate arguments
if ( tag_name = = NULL | | instance_name = = NULL )
{
return NULL ;
}
// Generate the desired name
Format ( dest_name , sizeof ( dest_name ) , tag_name , instance_name ) ;
// Enumerate the key
2021-04-03 03:25:19 +03:00
key_list = MsRegEnumKey ( REG_LOCAL_MACHINE ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} " ) ;
2014-01-04 17:00:08 +04:00
if ( key_list = = NULL )
{
return NULL ;
}
for ( i = 0 ; i < key_list - > NumTokens ; i + + )
{
char * key_name = key_list - > Token [ i ] ;
char full_key_name [ MAX_SIZE ] ;
char * driver_desc ;
2021-04-03 03:25:19 +03:00
Format ( full_key_name , sizeof ( full_key_name ) ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} \\ %s " ,
key_name ) ;
2014-01-04 17:00:08 +04:00
// Read the DriverDesc
2018-05-30 00:20:47 +03:00
driver_desc = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " DriverDesc " ) ;
if ( driver_desc ! = NULL )
{
if ( StrCmpi ( dest_name , driver_desc ) = = 0 )
{
// Read the file name
ret = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " DeviceVxDs " ) ;
2014-01-04 17:00:08 +04:00
Free ( driver_desc ) ;
break ;
}
Free ( driver_desc ) ;
}
}
FreeToken ( key_list ) ;
return ret ;
}
2018-05-30 00:20:47 +03:00
// Get the version of the device driver
char * MsGetDriverVersion ( char * tag_name , char * instance_name )
2014-01-04 17:00:08 +04:00
{
TOKEN_LIST * key_list ;
2018-05-30 00:20:47 +03:00
TOKEN_LIST * t ;
2014-01-04 17:00:08 +04:00
UINT i ;
char * ret = NULL ;
char dest_name [ MAX_SIZE ] ;
// Validate arguments
if ( tag_name = = NULL | | instance_name = = NULL )
{
return NULL ;
}
// Generate the desired name
Format ( dest_name , sizeof ( dest_name ) , tag_name , instance_name ) ;
// Enumerate the key
2021-04-03 03:25:19 +03:00
key_list = MsRegEnumKey ( REG_LOCAL_MACHINE ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} " ) ;
2014-01-04 17:00:08 +04:00
if ( key_list = = NULL )
{
return NULL ;
}
for ( i = 0 ; i < key_list - > NumTokens ; i + + )
{
char * key_name = key_list - > Token [ i ] ;
char full_key_name [ MAX_SIZE ] ;
char * driver_desc ;
2021-04-03 03:25:19 +03:00
Format ( full_key_name , sizeof ( full_key_name ) ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} \\ %s " ,
key_name ) ;
2014-01-04 17:00:08 +04:00
// Read the DriverDesc
driver_desc = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " DriverDesc " ) ;
if ( driver_desc ! = NULL )
{
if ( StrCmpi ( dest_name , driver_desc ) = = 0 )
{
2018-05-30 00:20:47 +03:00
// Read the version information
ret = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " DriverVersion " ) ;
if ( ret = = NULL )
{
ret = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " NeoVersion " ) ;
}
2014-01-04 17:00:08 +04:00
Free ( driver_desc ) ;
break ;
}
Free ( driver_desc ) ;
}
}
FreeToken ( key_list ) ;
2018-05-30 00:20:47 +03:00
if ( ret = = NULL )
{
return NULL ;
}
t = ParseToken ( ret , " , " ) ;
if ( t - > NumTokens = = 2 )
{
Free ( ret ) ;
ret = CopyStr ( t - > Token [ 1 ] ) ;
}
FreeToken ( t ) ;
2014-01-04 17:00:08 +04:00
return ret ;
}
// Get the MAC address
char * MsGetMacAddress ( char * tag_name , char * instance_name )
{
TOKEN_LIST * key_list ;
UINT i ;
char * ret = NULL ;
char dest_name [ MAX_SIZE ] ;
// Validate arguments
if ( tag_name = = NULL | | instance_name = = NULL )
{
return NULL ;
}
// Generate the desired name
Format ( dest_name , sizeof ( dest_name ) , tag_name , instance_name ) ;
// Enumerate the key
2021-04-03 03:25:19 +03:00
key_list = MsRegEnumKey ( REG_LOCAL_MACHINE ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} " ) ;
2014-01-04 17:00:08 +04:00
if ( key_list = = NULL )
{
return NULL ;
}
for ( i = 0 ; i < key_list - > NumTokens ; i + + )
{
char * key_name = key_list - > Token [ i ] ;
char full_key_name [ MAX_SIZE ] ;
char * driver_desc ;
2021-04-03 03:25:19 +03:00
Format ( full_key_name , sizeof ( full_key_name ) ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} \\ %s " ,
key_name ) ;
2014-01-04 17:00:08 +04:00
// Read the DriverDesc
driver_desc = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " DriverDesc " ) ;
if ( driver_desc ! = NULL )
{
if ( StrCmpi ( dest_name , driver_desc ) = = 0 )
{
// Read the MAC address
ret = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " NetworkAddress " ) ;
if ( IsEmptyStr ( ret ) = = false )
{
// Insert hyphens between the MAC address elements
BUF * b = StrToBin ( ret ) ;
if ( b ! = NULL & & b - > Size = = 6 )
{
char tmp [ MAX_SIZE ] ;
MacToStr ( tmp , sizeof ( tmp ) , b - > Buf ) ;
Free ( ret ) ;
ret = CopyStr ( tmp ) ;
}
FreeBuf ( b ) ;
}
Free ( driver_desc ) ;
break ;
}
Free ( driver_desc ) ;
}
}
FreeToken ( key_list ) ;
return ret ;
}
// Check whether the device name of the virtual LAN card exists really
bool MsCheckVLanDeviceIdFromRootEnum ( char * name )
{
TOKEN_LIST * t ;
char * root ;
char * keyname ;
UINT i ;
bool ret ;
// Validate arguments
if ( name = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
root = " SYSTEM \\ CurrentControlSet \\ Enum \\ Root \\ NET " ;
keyname = " HardwareID " ;
2014-01-04 17:00:08 +04:00
t = MsRegEnumKey ( REG_LOCAL_MACHINE , root ) ;
if ( t = = NULL )
{
return false ;
}
ret = false ;
for ( i = 0 ; i < t - > NumTokens ; i + + )
{
char * subname = t - > Token [ i ] ;
char fullname [ MAX_SIZE ] ;
char * value ;
Format ( fullname , sizeof ( fullname ) , " %s \\ %s " , root , subname ) ;
value = MsRegReadStr ( REG_LOCAL_MACHINE , fullname , keyname ) ;
if ( value ! = NULL )
{
if ( StrCmpi ( value , name ) = = 0 )
{
ret = true ;
}
Free ( value ) ;
}
if ( ret )
{
break ;
}
}
FreeToken ( t ) ;
return ret ;
}
// Get the GUID of the network adapter
char * MsGetNetworkAdapterGuid ( char * tag_name , char * instance_name )
{
TOKEN_LIST * key_list ;
UINT i ;
char * ret = NULL ;
char dest_name [ MAX_SIZE ] ;
// Validate arguments
if ( tag_name = = NULL | | instance_name = = NULL )
{
return NULL ;
}
// Generate the desired name
Format ( dest_name , sizeof ( dest_name ) , tag_name , instance_name ) ;
// Enumerate the key
2021-04-03 03:25:19 +03:00
key_list = MsRegEnumKey ( REG_LOCAL_MACHINE ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} " ) ;
2014-01-04 17:00:08 +04:00
if ( key_list = = NULL )
{
return NULL ;
}
for ( i = 0 ; i < key_list - > NumTokens ; i + + )
{
char * key_name = key_list - > Token [ i ] ;
char full_key_name [ MAX_SIZE ] ;
char * driver_desc ;
char * device_id ;
2021-04-03 03:25:19 +03:00
Format ( full_key_name , sizeof ( full_key_name ) ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} \\ %s " ,
key_name ) ;
2014-01-04 17:00:08 +04:00
device_id = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " MatchingDeviceId " ) ;
if ( device_id ! = NULL )
{
if ( MsCheckVLanDeviceIdFromRootEnum ( device_id ) )
{
// Read the DriverDesc
driver_desc = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " DriverDesc " ) ;
if ( driver_desc ! = NULL )
{
if ( StrCmpi ( dest_name , driver_desc ) = = 0 )
{
// Read the NetCfgInstanceId
2021-04-03 03:25:19 +03:00
ret = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " NetCfgInstanceId " ) ;
2014-01-04 17:00:08 +04:00
Free ( driver_desc ) ;
Free ( device_id ) ;
break ;
}
Free ( driver_desc ) ;
}
}
Free ( device_id ) ;
}
}
FreeToken ( key_list ) ;
return ret ;
}
// Get the network connection name
wchar_t * MsGetNetworkConnectionName ( char * guid )
{
wchar_t * ncname = NULL ;
// Validate arguments
if ( guid = = NULL )
{
return NULL ;
}
// Get the network connection name
if ( IsNt ( ) ! = false & & GetOsInfo ( ) - > OsType > = OSTYPE_WINDOWS_2000_PROFESSIONAL )
{
char tmp [ MAX_SIZE ] ;
Format ( tmp , sizeof ( tmp ) , " SYSTEM \\ CurrentControlSet \\ Control \\ Network \\ {4D36E972-E325-11CE-BFC1-08002BE10318} \\ %s \\ Connection " , guid ) ;
ncname = MsRegReadStrW ( REG_LOCAL_MACHINE , tmp , " Name " ) ;
}
return ncname ;
}
// Generate driver file name for the new Neo
bool MsMakeNewNeoDriverFilename ( char * name , UINT size )
{
TOKEN_LIST * t = MsEnumNeoDriverFilenames ( ) ;
UINT i ;
bool ret = false ;
i = 0 ;
while ( true )
{
char tmp [ MAX_PATH ] ;
UINT n ;
i + + ;
if ( i > = 10000 )
{
break ;
}
n = Rand32 ( ) % DRIVER_INSTALL_SYS_NAME_TAG_MAXID ;
MsGenerateNeoDriverFilenameFromInt ( tmp , sizeof ( tmp ) , n ) ;
if ( IsInToken ( t , tmp ) = = false )
{
StrCpy ( name , size , tmp ) ;
ret = true ;
break ;
}
}
FreeToken ( t ) ;
return ret ;
}
// Generate the driver file name of Neo from a integer
void MsGenerateNeoDriverFilenameFromInt ( char * name , UINT size , UINT n )
{
Format ( name , size , DRIVER_INSTALL_SYS_NAME_TAG_NEW , n ) ;
}
// Enumeration of the driver file names of installed Neo
TOKEN_LIST * MsEnumNeoDriverFilenames ( )
{
TOKEN_LIST * neos = MsEnumNetworkAdaptersNeo ( ) ;
LIST * o = NewListFast ( NULL ) ;
TOKEN_LIST * ret ;
UINT i ;
for ( i = 0 ; i < neos - > NumTokens ; i + + )
{
char filename [ MAX_PATH ] ;
2018-05-17 00:47:10 +03:00
if ( MsGetNeoDriverFilename ( filename , sizeof ( filename ) , neos - > Token [ i ] ) )
2014-01-04 17:00:08 +04:00
{
Add ( o , CopyStr ( filename ) ) ;
}
}
FreeToken ( neos ) ;
ret = ListToTokenList ( o ) ;
FreeStrList ( o ) ;
return ret ;
}
// Get the driver file name of Neo
2018-05-17 00:47:10 +03:00
bool MsGetNeoDriverFilename ( char * name , UINT size , char * instance_name )
2014-01-04 17:00:08 +04:00
{
char tmp [ MAX_SIZE ] ;
char * ret ;
// Validate arguments
if ( name = = NULL | | instance_name = = NULL )
{
return false ;
}
Format ( tmp , sizeof ( tmp ) , " SYSTEM \\ CurrentControlSet \\ Services \\ Neo_%s " , instance_name ) ;
ret = MsRegReadStr ( REG_LOCAL_MACHINE , tmp , " ImagePath " ) ;
if ( ret = = NULL )
{
return false ;
}
GetFileNameFromFilePath ( name , size , ret ) ;
Free ( ret ) ;
return true ;
}
// Enumeration of the network adapter (only Neo)
TOKEN_LIST * MsEnumNetworkAdaptersNeo ( )
{
TOKEN_LIST * key_list ;
TOKEN_LIST * ret ;
LIST * o ;
UINT i ;
// Enumerate the key
2021-04-03 03:25:19 +03:00
key_list = MsRegEnumKey ( REG_LOCAL_MACHINE ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} " ) ;
2014-01-04 17:00:08 +04:00
if ( key_list = = NULL )
{
return NULL ;
}
o = NewListFast ( CompareStr ) ;
for ( i = 0 ; i < key_list - > NumTokens ; i + + )
{
char * key_name = key_list - > Token [ i ] ;
char full_key_name [ MAX_SIZE ] ;
char * driver_desc ;
char * device_id ;
2021-04-03 03:25:19 +03:00
Format ( full_key_name , sizeof ( full_key_name ) ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} \\ %s " ,
key_name ) ;
2014-01-04 17:00:08 +04:00
// Read the DriverDesc
driver_desc = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " DriverDesc " ) ;
if ( driver_desc ! = NULL )
{
// Check whether it starts with the specific name
device_id = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " MatchingDeviceId " ) ;
if ( device_id ! = NULL )
{
if ( MsCheckVLanDeviceIdFromRootEnum ( device_id ) )
{
char * tag = " neoadapter_ " ;
if ( StartWith ( device_id , tag ) )
{
char tmp [ MAX_SIZE ] ;
StrCpy ( tmp , sizeof ( tmp ) , & device_id [ StrLen ( tag ) ] ) ;
Add ( o , CopyStr ( tmp ) ) ;
}
}
Free ( device_id ) ;
}
Free ( driver_desc ) ;
}
}
FreeToken ( key_list ) ;
ret = ZeroMalloc ( sizeof ( TOKEN_LIST ) ) ;
ret - > NumTokens = LIST_NUM ( o ) ;
ret - > Token = ZeroMalloc ( sizeof ( char * ) * ret - > NumTokens ) ;
for ( i = 0 ; i < ret - > NumTokens ; i + + )
{
ret - > Token [ i ] = LIST_DATA ( o , i ) ;
}
ReleaseList ( o ) ;
return ret ;
}
// Enumeration of the network adapter
TOKEN_LIST * MsEnumNetworkAdapters ( char * start_with_name , char * start_with_name_2 )
{
TOKEN_LIST * key_list ;
TOKEN_LIST * ret ;
LIST * o ;
UINT i ;
// Enumerate the key
2021-04-03 03:25:19 +03:00
key_list = MsRegEnumKey ( REG_LOCAL_MACHINE ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} " ) ;
2014-01-04 17:00:08 +04:00
if ( key_list = = NULL )
{
return NULL ;
}
o = NewListFast ( CompareStr ) ;
for ( i = 0 ; i < key_list - > NumTokens ; i + + )
{
char * key_name = key_list - > Token [ i ] ;
char full_key_name [ MAX_SIZE ] ;
char * driver_desc ;
char * device_id ;
2021-04-03 03:25:19 +03:00
Format ( full_key_name , sizeof ( full_key_name ) ,
" SYSTEM \\ CurrentControlSet \\ Control \\ Class \\ {4D36E972-E325-11CE-BFC1-08002bE10318} \\ %s " ,
key_name ) ;
2014-01-04 17:00:08 +04:00
// Read the DriverDesc
driver_desc = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " DriverDesc " ) ;
if ( driver_desc ! = NULL )
{
// Check whether it starts with the specific name
if ( ( IsEmptyStr ( start_with_name ) & & IsEmptyStr ( start_with_name_2 ) ) | |
( StartWith ( driver_desc , start_with_name ) | | StartWith ( driver_desc , start_with_name_2 ) ) )
{
device_id = MsRegReadStr ( REG_LOCAL_MACHINE , full_key_name , " MatchingDeviceId " ) ;
if ( device_id ! = NULL )
{
if ( MsCheckVLanDeviceIdFromRootEnum ( device_id ) )
{
char instance_name [ MAX_SIZE ] ;
// Extract only the instance name from the name
if ( StartWith ( driver_desc , start_with_name ) )
{
if ( StrLen ( driver_desc ) > ( StrLen ( start_with_name ) + 3 ) )
{
StrCpy ( instance_name , sizeof ( instance_name ) ,
driver_desc + StrLen ( start_with_name ) + 3 ) ;
Add ( o , CopyStr ( instance_name ) ) ;
}
}
else
{
if ( StrLen ( driver_desc ) > ( StrLen ( start_with_name_2 ) + 3 ) )
{
StrCpy ( instance_name , sizeof ( instance_name ) ,
2018-05-30 00:20:47 +03:00
driver_desc + StrLen ( start_with_name_2 ) + 3 ) ;
Add ( o , CopyStr ( instance_name ) ) ;
}
}
}
Free ( device_id ) ;
}
}
2016-11-27 11:43:14 +03:00
2018-05-30 00:20:47 +03:00
Free ( driver_desc ) ;
}
}
2016-11-27 11:43:14 +03:00
2018-05-30 00:20:47 +03:00
FreeToken ( key_list ) ;
2016-11-27 11:43:14 +03:00
2018-05-30 00:20:47 +03:00
ret = ZeroMalloc ( sizeof ( TOKEN_LIST ) ) ;
ret - > NumTokens = LIST_NUM ( o ) ;
ret - > Token = ZeroMalloc ( sizeof ( char * ) * ret - > NumTokens ) ;
for ( i = 0 ; i < ret - > NumTokens ; i + + )
2016-11-27 11:43:14 +03:00
{
2018-05-30 00:20:47 +03:00
ret - > Token [ i ] = LIST_DATA ( o , i ) ;
2016-11-27 11:43:14 +03:00
}
2018-05-30 00:20:47 +03:00
ReleaseList ( o ) ;
2016-11-27 11:43:14 +03:00
2018-05-30 00:20:47 +03:00
return ret ;
2016-11-27 11:43:14 +03:00
}
2018-05-30 00:20:47 +03:00
// Attempt to logon to the domain
bool MsCheckLogon ( wchar_t * username , char * password )
2016-11-27 11:43:14 +03:00
{
2018-05-30 00:20:47 +03:00
wchar_t password_unicode [ MAX_SIZE ] ;
HANDLE h ;
// Validate arguments
if ( username = = NULL | | password = = NULL )
2016-11-27 11:43:14 +03:00
{
2018-05-30 00:20:47 +03:00
return false ;
2016-11-27 11:43:14 +03:00
}
2018-05-30 00:20:47 +03:00
StrToUni ( password_unicode , sizeof ( password_unicode ) , password ) ;
2016-11-27 11:43:14 +03:00
2018-05-30 00:20:47 +03:00
if ( GET_KETA ( GetOsInfo ( ) - > OsType , 100 ) > = 2 )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
if ( LogonUserW ( username , NULL , password_unicode , LOGON32_LOGON_NETWORK , LOGON32_PROVIDER_DEFAULT , & h ) = = false )
2018-05-30 00:20:47 +03:00
{
// Logon failure
return false ;
}
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
else
2014-01-04 17:00:08 +04:00
{
2018-05-30 00:20:47 +03:00
char username_ansi [ MAX_SIZE ] ;
UniToStr ( username_ansi , sizeof ( username_ansi ) , username ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
if ( LogonUserA ( username_ansi , NULL , password , LOGON32_LOGON_NETWORK , LOGON32_PROVIDER_DEFAULT , & h ) = = false )
2018-05-30 00:20:47 +03:00
{
// Logon failure
return false ;
}
2014-01-04 17:00:08 +04:00
}
2018-05-30 00:20:47 +03:00
CloseHandle ( h ) ;
2014-01-04 17:00:08 +04:00
return true ;
}
// Execute the shutdown
bool MsShutdown ( bool reboot , bool force )
{
UINT flag = 0 ;
// Get the privilege
if ( MsEnablePrivilege ( SE_SHUTDOWN_NAME , true ) = = false )
{
return false ;
}
flag | = ( reboot ? EWX_REBOOT : EWX_SHUTDOWN ) ;
flag | = ( force ? EWX_FORCE : 0 ) ;
// Execute the shutdown
if ( ExitWindowsEx ( flag , 0 ) = = false )
{
MsEnablePrivilege ( SE_SHUTDOWN_NAME , false ) ;
return false ;
}
// Release of privilege
MsEnablePrivilege ( SE_SHUTDOWN_NAME , false ) ;
return true ;
}
// Enable or disable the privilege
bool MsEnablePrivilege ( char * name , bool enable )
{
HANDLE hToken ;
LUID luid ;
TOKEN_PRIVILEGES * tp ;
bool ret ;
// Validate arguments
if ( name = = NULL )
{
return false ;
}
// Open the process token
2021-04-03 03:25:19 +03:00
if ( OpenProcessToken ( ms - > hCurrentProcess , TOKEN_ADJUST_PRIVILEGES , & hToken ) = = false )
2014-01-04 17:00:08 +04:00
{
return false ;
}
// Get a local unique identifier
2021-04-03 03:25:19 +03:00
if ( LookupPrivilegeValue ( NULL , name , & luid ) = = FALSE )
2014-01-04 17:00:08 +04:00
{
CloseHandle ( hToken ) ;
return false ;
}
// Create a structure to enable / disable the privilege
tp = ZeroMalloc ( sizeof ( TOKEN_PRIVILEGES ) ) ;
tp - > PrivilegeCount = 1 ;
tp - > Privileges [ 0 ] . Attributes = enable ? SE_PRIVILEGE_ENABLED : 0 ;
Copy ( & tp - > Privileges [ 0 ] . Luid , & luid , sizeof ( LUID ) ) ;
// Manipulate the privilege
2021-04-03 03:25:19 +03:00
ret = AdjustTokenPrivileges ( hToken , false , tp , sizeof ( TOKEN_PRIVILEGES ) , 0 , 0 ) ;
2014-01-04 17:00:08 +04:00
Free ( tp ) ;
CloseHandle ( hToken ) ;
return ret ;
}
2016-04-24 17:49:31 +03:00
// Get whether the current system is WINE
bool MsIsWine ( )
{
bool ret = false ;
if ( ms = = NULL )
{
HINSTANCE h = LoadLibrary ( " kernel32.dll " ) ;
if ( h ! = NULL )
{
if ( GetProcAddress ( h , " wine_get_unix_file_name " ) ! = NULL )
{
ret = true ;
}
FreeLibrary ( h ) ;
}
}
else
{
ret = ms - > IsWine ;
}
return ret ;
}
2014-01-04 17:00:08 +04:00
// Get whether the current user is an Admin
bool MsIsAdmin ( )
{
return ms - > IsAdmin ;
}
// Get whether the screen color is like to Aero of Windows Vista or later
bool MsIsAeroColor ( )
{
2021-04-03 03:25:19 +03:00
UINT r = GetSysColor ( COLOR_MENU ) ;
2014-01-04 17:00:08 +04:00
if ( r = = 0xFFFFFF | | r = = 0xF0F0F0 | | r > = 0xF00000 )
{
return true ;
}
if ( MsIsAeroEnabled ( ) )
{
return true ;
}
return false ;
}
// Get whether Aero is enabled
bool MsIsAeroEnabled ( )
{
2021-04-03 03:25:19 +03:00
BOOL ret = false ;
if ( DwmIsCompositionEnabled ( & ret ) ! = S_OK )
2014-01-04 17:00:08 +04:00
{
return false ;
}
return ret ;
}
// Generate an access mask to force accessing to the 32 bit registry key for 64 bit application
2020-08-15 09:31:45 +03:00
UINT MsRegAccessMaskFor64BitEx ( bool force32bit , bool force64bit )
2014-01-04 17:00:08 +04:00
{
if ( MsIs64BitWindows ( ) = = false )
{
return 0 ;
}
if ( force32bit )
{
return KEY_WOW64_32KEY ;
}
if ( force64bit )
{
return KEY_WOW64_64KEY ;
}
return 0 ;
}
2015-10-19 15:30:51 +03:00
// Load the hive
bool MsRegLoadHive ( UINT root , wchar_t * keyname , wchar_t * filename )
{
LONG ret ;
if ( keyname = = NULL | | filename = = NULL )
{
WHERE ;
return false ;
}
2021-04-03 03:25:19 +03:00
ret = RegLoadKeyW ( MsGetRootKeyFromInt ( root ) , keyname , filename ) ;
2015-10-19 15:30:51 +03:00
if ( ret ! = ERROR_SUCCESS )
{
Debug ( " RegLoadKeyW: %S %S %u \n " , keyname , filename , GetLastError ( ) ) ;
return false ;
}
WHERE ;
return true ;
}
// Unload the hive
bool MsRegUnloadHive ( UINT root , wchar_t * keyname )
{
LONG ret ;
if ( keyname = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
ret = RegUnLoadKeyW ( MsGetRootKeyFromInt ( root ) , keyname ) ;
2015-10-19 15:30:51 +03:00
if ( ret ! = ERROR_SUCCESS )
{
Debug ( " RegUnLoadKeyW: %u \n " , GetLastError ( ) ) ;
return false ;
}
return true ;
}
2014-01-04 17:00:08 +04:00
// Delete the value
bool MsRegDeleteValue ( UINT root , char * keyname , char * valuename )
{
return MsRegDeleteValueEx ( root , keyname , valuename , false ) ;
}
bool MsRegDeleteValueEx ( UINT root , char * keyname , char * valuename , bool force32bit )
{
return MsRegDeleteValueEx2 ( root , keyname , valuename , force32bit , false ) ;
}
bool MsRegDeleteValueEx2 ( UINT root , char * keyname , char * valuename , bool force32bit , bool force64bit )
{
HKEY h ;
bool ret ;
// Validate arguments
if ( keyname = = NULL )
{
return false ;
}
if ( RegOpenKeyEx ( MsGetRootKeyFromInt ( root ) , keyname , 0 , KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx ( force32bit , force64bit ) , & h ) ! = ERROR_SUCCESS )
{
return false ;
}
if ( RegDeleteValue ( h , valuename ) ! = ERROR_SUCCESS )
{
ret = false ;
}
else
{
ret = true ;
}
RegCloseKey ( h ) ;
return ret ;
}
// Delete the key
bool MsRegDeleteKey ( UINT root , char * keyname )
{
return MsRegDeleteKeyEx ( root , keyname , false ) ;
}
bool MsRegDeleteKeyEx ( UINT root , char * keyname , bool force32bit )
{
return MsRegDeleteKeyEx2 ( root , keyname , force32bit , false ) ;
}
bool MsRegDeleteKeyEx2 ( UINT root , char * keyname , bool force32bit , bool force64bit )
{
// Validate arguments
if ( keyname = = NULL )
{
return false ;
}
2021-04-03 03:25:19 +03:00
if ( RegDeleteKeyExA ( MsGetRootKeyFromInt ( root ) , keyname , MsRegAccessMaskFor64BitEx ( force32bit , force64bit ) , 0 ) ! = ERROR_SUCCESS )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
return false ;
2014-01-04 17:00:08 +04:00
}
return true ;
}
// Enumeration of values
TOKEN_LIST * MsRegEnumValue ( UINT root , char * keyname )
{
return MsRegEnumValueEx ( root , keyname , false ) ;
}
TOKEN_LIST * MsRegEnumValueEx ( UINT root , char * keyname , bool force32bit )
{
return MsRegEnumValueEx2 ( root , keyname , force32bit , false ) ;
}
TOKEN_LIST * MsRegEnumValueEx2 ( UINT root , char * keyname , bool force32bit , bool force64bit )
{
HKEY h ;
UINT i ;
TOKEN_LIST * t ;
LIST * o ;
if ( keyname = = NULL )
{
h = MsGetRootKeyFromInt ( root ) ;
}
else
{
if ( RegOpenKeyEx ( MsGetRootKeyFromInt ( root ) , keyname , 0 , KEY_READ | MsRegAccessMaskFor64BitEx ( force32bit , force64bit ) , & h ) ! = ERROR_SUCCESS )
{
return NULL ;
}
}
o = NewListFast ( CompareStr ) ;
for ( i = 0 ; ; i + + )
{
char tmp [ MAX_SIZE ] ;
UINT ret ;
2021-03-01 03:46:11 +03:00
DWORD size = sizeof ( tmp ) ;
2014-01-04 17:00:08 +04:00
Zero ( tmp , sizeof ( tmp ) ) ;
ret = RegEnumValue ( h , i , tmp , & size , NULL , NULL , NULL , NULL ) ;
if ( ret = = ERROR_NO_MORE_ITEMS )
{
break ;
}
else if ( ret ! = ERROR_SUCCESS )
{
break ;
}
Add ( o , CopyStr ( tmp ) ) ;
}
Sort ( o ) ;
t = ZeroMalloc ( sizeof ( TOKEN_LIST ) ) ;
t - > NumTokens = LIST_NUM ( o ) ;
t - > Token = ZeroMalloc ( sizeof ( char * ) * t - > NumTokens ) ;
for ( i = 0 ; i < t - > NumTokens ; i + + )
{
t - > Token [ i ] = LIST_DATA ( o , i ) ;
}
ReleaseList ( o ) ;
if ( keyname ! = NULL )
{
RegCloseKey ( h ) ;
}
return t ;
}
// Enumeration of the keys
TOKEN_LIST * MsRegEnumKey ( UINT root , char * keyname )
{
return MsRegEnumKeyEx ( root , keyname , false ) ;
}
TOKEN_LIST * MsRegEnumKeyEx ( UINT root , char * keyname , bool force32bit )
{
return MsRegEnumKeyEx2 ( root , keyname , force32bit , false ) ;
}
TOKEN_LIST * MsRegEnumKeyEx2 ( UINT root , char * keyname , bool force32bit , bool force64bit )
{
HKEY h ;
UINT i ;
TOKEN_LIST * t ;
LIST * o ;
if ( keyname = = NULL )
{
h = MsGetRootKeyFromInt ( root ) ;
}
else
{
if ( RegOpenKeyEx ( MsGetRootKeyFromInt ( root ) , keyname , 0 , KEY_READ | MsRegAccessMaskFor64BitEx ( force32bit , force64bit ) , & h ) ! = ERROR_SUCCESS )
{
return NULL ;
}
}
o = NewListFast ( CompareStr ) ;
for ( i = 0 ; ; i + + )
{
char tmp [ MAX_SIZE ] ;
UINT ret ;
2021-03-01 03:46:11 +03:00
DWORD size = sizeof ( tmp ) ;
2014-01-04 17:00:08 +04:00
FILETIME ft ;
Zero ( tmp , sizeof ( tmp ) ) ;
ret = RegEnumKeyEx ( h , i , tmp , & size , NULL , NULL , NULL , & ft ) ;
if ( ret = = ERROR_NO_MORE_ITEMS )
{
break ;
}
else if ( ret ! = ERROR_SUCCESS )
{
break ;
}
Add ( o , CopyStr ( tmp ) ) ;
}
Sort ( o ) ;
t = ZeroMalloc ( sizeof ( TOKEN_LIST ) ) ;
t - > NumTokens = LIST_NUM ( o ) ;
t - > Token = ZeroMalloc ( sizeof ( char * ) * t - > NumTokens ) ;
for ( i = 0 ; i < t - > NumTokens ; i + + )
{
t - > Token [ i ] = LIST_DATA ( o , i ) ;
}
ReleaseList ( o ) ;
if ( keyname ! = NULL )
{
RegCloseKey ( h ) ;
}
return t ;
}
// Set the binary data
bool MsRegWriteBin ( UINT root , char * keyname , char * valuename , void * data , UINT size )
{
return MsRegWriteBinEx ( root , keyname , valuename , data , size , false ) ;
}
bool MsRegWriteBinEx ( UINT root , char * keyname , char * valuename , void * data , UINT size , bool force32bit )
{
return MsRegWriteBinEx2 ( root , keyname , valuename , data , size , force32bit , false ) ;
}
bool MsRegWriteBinEx2 ( UINT root , char * keyname , char * valuename , void * data , UINT size , bool force32bit , bool force64bit )
{
// Validate arguments
if ( keyname = = NULL | | ( size ! = 0 & & data = = NULL ) )
{
return false ;
}
return MsRegWriteValueEx2 ( root , keyname , valuename , REG_BINARY , data , size , force32bit , force64bit ) ;
}
// Set the integer value
bool MsRegWriteInt ( UINT root , char * keyname , char * valuename , UINT value )
{
return MsRegWriteIntEx ( root , keyname , valuename , value , false ) ;
}
bool MsRegWriteIntEx ( UINT root , char * keyname , char * valuename , UINT value , bool force32bit )
{
return MsRegWriteIntEx2 ( root , keyname , valuename , value , force32bit , false ) ;
}
bool MsRegWriteIntEx2 ( UINT root , char * keyname , char * valuename , UINT value , bool force32bit , bool force64bit )
{
// Validate arguments
if ( keyname = = NULL )
{
return false ;
}
// Endian correction
if ( IsBigEndian ( ) )
{
value = Swap32 ( value ) ;
}
return MsRegWriteValueEx2 ( root , keyname , valuename , REG_DWORD_LITTLE_ENDIAN , & value , sizeof ( UINT ) , force32bit , force64bit ) ;
}
// Set the string
bool MsRegWriteStrExpand ( UINT root , char * keyname , char * valuename , char * str )
{
return MsRegWriteStrExpandEx ( root , keyname , valuename , str , false ) ;
}
bool MsRegWriteStrExpandEx ( UINT root , char * keyname , char * valuename , char * str , bool force32bit )
{
return MsRegWriteStrExpandEx2 ( root , keyname , valuename , str , force32bit , false ) ;
}
bool MsRegWriteStrExpandEx2 ( UINT root , char * keyname , char * valuename , char * str , bool force32bit , bool force64bit )
{
// Validate arguments
if ( keyname = = NULL | | str = = NULL )
{
return false ;
}
return MsRegWriteValueEx2 ( root , keyname , valuename , REG_EXPAND_SZ , str , StrSize ( str ) , force32bit , force64bit ) ;
}
bool MsRegWriteStrExpandW ( UINT root , char * keyname , char * valuename , wchar_t * str )
{
return MsRegWriteStrExpandExW ( root , keyname , valuename , str , false ) ;
}
bool MsRegWriteStrExpandExW ( UINT root , char * keyname , char * valuename , wchar_t * str , bool force32bit )
{
return MsRegWriteStrExpandEx2W ( root , keyname , valuename , str , force32bit , false ) ;
}
bool MsRegWriteStrExpandEx2W ( UINT root , char * keyname , char * valuename , wchar_t * str , bool force32bit , bool force64bit )
{
// Validate arguments
if ( keyname = = NULL | | str = = NULL )
{
return false ;
}
return MsRegWriteValueEx2W ( root , keyname , valuename , REG_EXPAND_SZ , str , UniStrSize ( str ) , force32bit , force64bit ) ;
}
bool MsRegWriteStr ( UINT root , char * keyname , char * valuename , char * str )
{
return MsRegWriteStrEx ( root , keyname , valuename , str , false ) ;
}
bool MsRegWriteStrEx ( UINT root , char * keyname , char * valuename , char * str , bool force32bit )
{
return MsRegWriteStrEx2 ( root , keyname , valuename , str , force32bit , false ) ;
}
bool MsRegWriteStrEx2 ( UINT root , char * keyname , char * valuename , char * str , bool force32bit , bool force64bit )
{
// Validate arguments
if ( keyname = = NULL | | str = = NULL )
{
return false ;
}
return MsRegWriteValueEx2 ( root , keyname , valuename , REG_SZ , str , StrSize ( str ) , force32bit , force64bit ) ;
}
bool MsRegWriteStrW ( UINT root , char * keyname , char * valuename , wchar_t * str )
{
return MsRegWriteStrExW ( root , keyname , valuename , str , false ) ;
}
bool MsRegWriteStrExW ( UINT root , char * keyname , char * valuename , wchar_t * str , bool force32bit )
{
return MsRegWriteStrEx2W ( root , keyname , valuename , str , force32bit , false ) ;
}
bool MsRegWriteStrEx2W ( UINT root , char * keyname , char * valuename , wchar_t * str , bool force32bit , bool force64bit )
{
// Validate arguments
if ( keyname = = NULL | | str = = NULL )
{
return false ;
}
return MsRegWriteValueEx2W ( root , keyname , valuename , REG_SZ , str , UniStrSize ( str ) , force32bit , force64bit ) ;
}
// Set the value
bool MsRegWriteValueEx2 ( UINT root , char * keyname , char * valuename , UINT type , void * data , UINT size , bool force32bit , bool force64bit )
{
HKEY h ;
// Validate arguments
if ( keyname = = NULL | | ( size ! = 0 & & data = = NULL ) )
{
return false ;
}
// Create a key
MsRegNewKeyEx2 ( root , keyname , force32bit , force64bit ) ;
// Open the key
if ( RegOpenKeyEx ( MsGetRootKeyFromInt ( root ) , keyname , 0 , KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx ( force32bit , force64bit ) , & h ) ! = ERROR_SUCCESS )
{
return false ;
}
// Write the value
if ( RegSetValueEx ( h , valuename , 0 , type , data , size ) ! = ERROR_SUCCESS )
{
RegCloseKey ( h ) ;
return false ;
}
// Close the key
RegCloseKey ( h ) ;
return true ;
}
bool MsRegWriteValueEx2W ( UINT root , char * keyname , char * valuename , UINT type , void * data , UINT size , bool force32bit , bool force64bit )
{
HKEY h ;
wchar_t * valuename_w ;
// Validate arguments
if ( keyname = = NULL | | ( size ! = 0 & & data = = NULL ) )
{
return false ;
}
if ( IsNt ( ) = = false )
{
UINT size_a ;
void * data_a ;
bool ret ;
if ( type = = REG_SZ | | type = = REG_MULTI_SZ | | type = = REG_EXPAND_SZ )
{
data_a = CopyUniToStr ( data ) ;
size_a = StrSize ( data_a ) ;
}
else
{
data_a = Clone ( data , size ) ;
size_a = size ;
}
ret = MsRegWriteValueEx2 ( root , keyname , valuename , type , data_a , size_a , force32bit , force64bit ) ;
Free ( data_a ) ;
return ret ;
}
// Create a key
MsRegNewKeyEx2 ( root , keyname , force32bit , force64bit ) ;
// Open the key
if ( RegOpenKeyEx ( MsGetRootKeyFromInt ( root ) , keyname , 0 , KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx ( force32bit , force64bit ) , & h ) ! = ERROR_SUCCESS )
{
return false ;
}
valuename_w = CopyStrToUni ( valuename ) ;
// Write the value
if ( RegSetValueExW ( h , valuename_w , 0 , type , data , size ) ! = ERROR_SUCCESS )
{
RegCloseKey ( h ) ;
Free ( valuename_w ) ;
return false ;
}
// Close the key
RegCloseKey ( h ) ;
Free ( valuename_w ) ;
return true ;
}
// Get the binary data
BUF * MsRegReadBin ( UINT root , char * keyname , char * valuename )
{
return MsRegReadBinEx ( root , keyname , valuename , false ) ;
}
BUF * MsRegReadBinEx ( UINT root , char * keyname , char * valuename , bool force32bit )
{
return MsRegReadBinEx2 ( root , keyname , valuename , force32bit , false ) ;
}
BUF * MsRegReadBinEx2 ( UINT root , char * keyname , char * valuename , bool force32bit , bool force64bit )
{
char * ret ;
2021-03-01 03:46:11 +03:00
DWORD type , size ;
2014-01-04 17:00:08 +04:00
BUF * b ;
// Validate arguments
if ( keyname = = NULL | | valuename = = NULL )
{
return 0 ;
}
// Read the value
2021-03-01 03:46:11 +03:00
if ( MsRegReadValueEx2 ( root , keyname , valuename , ( void * * ) & ret , & type , & size , force32bit , force64bit ) = = false )
2014-01-04 17:00:08 +04:00
{
return 0 ;
}
b = NewBuf ( ) ;
WriteBuf ( b , ret , size ) ;
SeekBuf ( b , 0 , 0 ) ;
Free ( ret ) ;
return b ;
}
// Get an integer value
UINT MsRegReadInt ( UINT root , char * keyname , char * valuename )
{
return MsRegReadIntEx ( root , keyname , valuename , false ) ;
}
UINT MsRegReadIntEx ( UINT root , char * keyname , char * valuename , bool force32bit )
{
return MsRegReadIntEx2 ( root , keyname , valuename , force32bit , false ) ;
}
UINT MsRegReadIntEx2 ( UINT root , char * keyname , char * valuename , bool force32bit , bool force64bit )
{
char * ret ;
2021-03-01 03:46:11 +03:00
DWORD type , size ;
2014-01-04 17:00:08 +04:00
UINT value ;
// Validate arguments
if ( keyname = = NULL | | valuename = = NULL )
{
return 0 ;
}
// Read the value
2021-03-01 03:46:11 +03:00
if ( MsRegReadValueEx2 ( root , keyname , valuename , ( void * * ) & ret , & type , & size , force32bit , force64bit ) = = false )
2014-01-04 17:00:08 +04:00
{
return 0 ;
}
// Check the type
if ( type ! = REG_DWORD_LITTLE_ENDIAN & & type ! = REG_DWORD_BIG_ENDIAN )
{
// It is not a DWORD
Free ( ret ) ;
return 0 ;
}
// Check the size
if ( size ! = sizeof ( UINT ) )
{
Free ( ret ) ;
return 0 ;
}
Copy ( & value , ret , sizeof ( UINT ) ) ;
Free ( ret ) ;
// Endian conversion
if ( IsLittleEndian ( ) )
{
# ifdef REG_DWORD_BIG_ENDIAN
if ( type = = REG_DWORD_BIG_ENDIAN )
{
value = Swap32 ( value ) ;
}
# endif // REG_DWORD_BIG_ENDIAN
}
else
{
# ifdef REG_DWORD_LITTLE_ENDIAN_FLAG
if ( type = = REG_DWORD_LITTLE_ENDIAN_FLAG )
{
value = Swap32 ( value ) ;
}
# endif // REG_DWORD_LITTLE_ENDIAN_FLAG
}
return value ;
}
// Get a string list
LIST * MsRegReadStrList ( UINT root , char * keyname , char * valuename )
{
return MsRegReadStrListEx ( root , keyname , valuename , false ) ;
}
LIST * MsRegReadStrListEx ( UINT root , char * keyname , char * valuename , bool force32bit )
{
return MsRegReadStrListEx2 ( root , keyname , valuename , force32bit , false ) ;
}
LIST * MsRegReadStrListEx2 ( UINT root , char * keyname , char * valuename , bool force32bit , bool force64bit )
{
LIST * o ;
char * ret ;
2021-03-01 03:46:11 +03:00
DWORD type , size ;
2014-01-04 17:00:08 +04:00
// Validate arguments
if ( keyname = = NULL | | valuename = = NULL )
{
return NULL ;
}
// Read the value
2021-03-01 03:46:11 +03:00
if ( MsRegReadValueEx2 ( root , keyname , valuename , ( void * * ) & ret , & type , & size , force32bit , force64bit ) = = false )
2014-01-04 17:00:08 +04:00
{
return NULL ;
}
// Check the type
if ( type ! = REG_MULTI_SZ )
{
// It is not a string list
Free ( ret ) ;
return NULL ;
}
if ( size < 2 )
{
// Invalid size
Free ( ret ) ;
return NULL ;
}
if ( ret [ size - 1 ] ! = 0 )
{
// Invalid data
Free ( ret ) ;
return NULL ;
}
// Creating a list
o = StrToStrList ( ret , size ) ;
Free ( ret ) ;
return o ;
}
// Get a string
char * MsRegReadStr ( UINT root , char * keyname , char * valuename )
{
return MsRegReadStrEx ( root , keyname , valuename , false ) ;
}
char * MsRegReadStrEx ( UINT root , char * keyname , char * valuename , bool force32bit )
{
return MsRegReadStrEx2 ( root , keyname , valuename , force32bit , false ) ;
}
char * MsRegReadStrEx2 ( UINT root , char * keyname , char * valuename , bool force32bit , bool force64bit )
{
char * ret ;
2021-03-01 03:46:11 +03:00
DWORD type , size ;
2014-01-04 17:00:08 +04:00
// Validate arguments
if ( keyname = = NULL | | valuename = = NULL )
{
return NULL ;
}
// Read the value
2021-03-01 03:46:11 +03:00
if ( MsRegReadValueEx2 ( root , keyname , valuename , ( void * * ) & ret , & type , & size , force32bit , force64bit ) = = false )
2014-01-04 17:00:08 +04:00
{
return NULL ;
}
// Check the type
if ( type ! = REG_SZ & & type ! = REG_EXPAND_SZ & & type ! = REG_MULTI_SZ )
{
// It is not a string
Free ( ret ) ;
if ( type = = REG_MULTI_SZ )
{
// It is a string list
LIST * o = MsRegReadStrList ( root , keyname , valuename ) ;
if ( o ! = NULL )
{
if ( LIST_NUM ( o ) > = 1 )
{
ret = CopyStr ( LIST_DATA ( o , 0 ) ) ;
FreeStrList ( o ) ;
return ret ;
}
}
}
return NULL ;
}
if ( size = = 0 )
{
// Invalid size
Free ( ret ) ;
return CopyStr ( " " ) ;
}
if ( ret [ size - 1 ] ! = 0 )
{
// Invalid data
Free ( ret ) ;
return NULL ;
}
return ret ;
}
wchar_t * MsRegReadStrW ( UINT root , char * keyname , char * valuename )
{
return MsRegReadStrExW ( root , keyname , valuename , false ) ;
}
wchar_t * MsRegReadStrExW ( UINT root , char * keyname , char * valuename , bool force32bit )
{
return MsRegReadStrEx2W ( root , keyname , valuename , force32bit , false ) ;
}
wchar_t * MsRegReadStrEx2W ( UINT root , char * keyname , char * valuename , bool force32bit , bool force64bit )
{
wchar_t * ret ;
2021-03-01 03:46:11 +03:00
DWORD type , size ;
2014-01-04 17:00:08 +04:00
// Validate arguments
if ( keyname = = NULL | | valuename = = NULL )
{
return NULL ;
}
// Read the value
2021-03-01 03:46:11 +03:00
if ( MsRegReadValueEx2W ( root , keyname , valuename , ( void * * ) & ret , & type , & size , force32bit , force64bit ) = = false )
2014-01-04 17:00:08 +04:00
{
return NULL ;
}
// Check the type
if ( type ! = REG_SZ & & type ! = REG_EXPAND_SZ )
{
// It is not a string
Free ( ret ) ;
return NULL ;
}
if ( ret [ size / sizeof ( wchar_t ) - 1 ] ! = 0 )
{
// Invalid data
Free ( ret ) ;
return NULL ;
}
return ret ;
}
// Read the value
2021-03-01 03:46:11 +03:00
bool MsRegReadValueEx2 ( UINT root , char * keyname , char * valuename , void * * data , DWORD * type , DWORD * size , bool force32bit , bool force64bit )
2014-01-04 17:00:08 +04:00
{
HKEY h ;
UINT ret ;
// Validate arguments
if ( keyname = = NULL | | data = = NULL | | type = = NULL | | size = = NULL )
{
return false ;
}
* type = 0 ;
* size = 0 ;
// Open the key
if ( RegOpenKeyEx ( MsGetRootKeyFromInt ( root ) , keyname , 0 , KEY_READ | MsRegAccessMaskFor64BitEx ( force32bit , force64bit ) , & h ) ! = ERROR_SUCCESS )
{
return false ;
}
// Open up the value
* data = ZeroMalloc ( * size ) ;
ret = RegQueryValueEx ( h , valuename , 0 , type , * data , size ) ;
if ( ret = = ERROR_SUCCESS )
{
// Reading is complete
RegCloseKey ( h ) ;
return true ;
}
if ( ret ! = ERROR_MORE_DATA )
{
// Strange error occurs
Free ( * data ) ;
* data = NULL ;
RegCloseKey ( h ) ;
return false ;
}
// Get the data by re-allocating memory
* data = ReAlloc ( * data , * size ) ;
ret = RegQueryValueEx ( h , valuename , 0 , type , * data , size ) ;
if ( ret ! = ERROR_SUCCESS )
{
// An error has occured
Free ( * data ) ;
* data = NULL ;
RegCloseKey ( h ) ;
}
RegCloseKey ( h ) ;
return true ;
}
2021-03-01 03:46:11 +03:00
bool MsRegReadValueEx2W ( UINT root , char * keyname , char * valuename , void * * data , DWORD * type , DWORD * size , bool force32bit , bool force64bit )
2014-01-04 17:00:08 +04:00
{
HKEY h ;
UINT ret ;
wchar_t * valuename_w ;
// Validate arguments
if ( keyname = = NULL | | data = = NULL | | type = = NULL | | size = = NULL )
{
return false ;
}
* type = 0 ;
* size = 0 ;
if ( IsNt ( ) = = false )
{
bool ret ;
void * data_a = NULL ;
2021-03-01 03:46:11 +03:00
DWORD type_a = 0 , size_a = 0 ;
2014-01-04 17:00:08 +04:00
ret = MsRegReadValueEx2 ( root , keyname , valuename , & data_a , & type_a , & size_a , force32bit , force64bit ) ;
if ( ret ! = false )
{
if ( type_a = = REG_SZ | | type_a = = REG_MULTI_SZ | | type_a = = REG_EXPAND_SZ )
{
* data = CopyStrToUni ( data_a ) ;
Free ( data_a ) ;
size_a = UniStrSize ( * data ) ;
}
else
{
* data = data_a ;
}
* type = type_a ;
* size = size_a ;
}
return ret ;
}
// Open the key
if ( RegOpenKeyEx ( MsGetRootKeyFromInt ( root ) , keyname , 0 , KEY_READ | MsRegAccessMaskFor64BitEx ( force32bit , force64bit ) , & h ) ! = ERROR_SUCCESS )
{
return false ;
}
valuename_w = CopyStrToUni ( valuename ) ;
// Open up the value
* data = ZeroMalloc ( * size ) ;
ret = RegQueryValueExW ( h , valuename_w , 0 , type , * data , size ) ;
if ( ret = = ERROR_SUCCESS )
{
// Reading is complete
RegCloseKey ( h ) ;
Free ( valuename_w ) ;
return true ;
}
if ( ret ! = ERROR_MORE_DATA )
{
// Strange error occurs
Free ( * data ) ;
* data = NULL ;
Free ( valuename_w ) ;
RegCloseKey ( h ) ;
return false ;
}
// Get the data by re-allocating memory
* data = ReAlloc ( * data , * size ) ;
ret = RegQueryValueExW ( h , valuename_w , 0 , type , * data , size ) ;
if ( ret ! = ERROR_SUCCESS )
{
// An error has occured
Free ( * data ) ;
* data = NULL ;
Free ( valuename_w ) ;
RegCloseKey ( h ) ;
}
Free ( valuename_w ) ;
RegCloseKey ( h ) ;
return true ;
}
// Confirm that the specified value exists on the registry
bool MsRegIsValue ( UINT root , char * keyname , char * valuename )
{
return MsRegIsValueEx ( root , keyname , valuename , false ) ;
}
bool MsRegIsValueEx ( UINT root , char * keyname , char * valuename , bool force32bit )
{
return MsRegIsValueEx2 ( root , keyname , valuename , force32bit , false ) ;
}
bool MsRegIsValueEx2 ( UINT root , char * keyname , char * valuename , bool force32bit , bool force64bit )
{
HKEY h ;
2021-03-01 03:46:11 +03:00
DWORD type , size ;
2014-01-04 17:00:08 +04:00
UINT ret ;
// Validate arguments
if ( keyname = = NULL )
{
return false ;
}
// Open the key
if ( RegOpenKeyEx ( MsGetRootKeyFromInt ( root ) , keyname , 0 , KEY_READ | MsRegAccessMaskFor64BitEx ( force32bit , force64bit ) , & h ) ! = ERROR_SUCCESS )
{
return false ;
}
// Open up the value
size = 0 ;
ret = RegQueryValueEx ( h , valuename , 0 , & type , NULL , & size ) ;
if ( ret = = ERROR_SUCCESS | | ret = = ERROR_MORE_DATA )
{
RegCloseKey ( h ) ;
return true ;
}
RegCloseKey ( h ) ;
return false ;
}
// Create a key in the registry
bool MsRegNewKeyEx2 ( UINT root , char * keyname , bool force32bit , bool force64bit )
{
HKEY h ;
// Validate arguments
if ( keyname = = NULL )
{
return false ;
}
// Confirm whether there is the key
if ( MsRegIsKeyEx2 ( root , keyname , force32bit , force64bit ) )
{
// Already exists
return true ;
}
// Create a key
if ( RegCreateKeyEx ( MsGetRootKeyFromInt ( root ) , keyname , 0 , NULL , REG_OPTION_NON_VOLATILE ,
KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx ( force32bit , force64bit ) , NULL , & h , NULL ) ! = ERROR_SUCCESS )
{
// Failed
return false ;
}
RegCloseKey ( h ) ;
return true ;
}
// Confirm the specified key exists on the registry
bool MsRegIsKey ( UINT root , char * name )
{
return MsRegIsKeyEx ( root , name , false ) ;
}
bool MsRegIsKeyEx ( UINT root , char * name , bool force32bit )
{
return MsRegIsKeyEx2 ( root , name , force32bit , false ) ;
}
bool MsRegIsKeyEx2 ( UINT root , char * name , bool force32bit , bool force64bit )
{
HKEY h ;
// Validate arguments
if ( name = = NULL )
{
return false ;
}
if ( RegOpenKeyEx ( MsGetRootKeyFromInt ( root ) , name , 0 , KEY_READ | MsRegAccessMaskFor64BitEx ( force32bit , force64bit ) , & h ) ! = ERROR_SUCCESS )
{
return false ;
}
RegCloseKey ( h ) ;
return true ;
}
// Getting root key handle
HKEY MsGetRootKeyFromInt ( UINT root )
{
switch ( root )
{
case REG_CLASSES_ROOT :
return HKEY_CLASSES_ROOT ;
case REG_LOCAL_MACHINE :
return HKEY_LOCAL_MACHINE ;
case REG_CURRENT_USER :
return HKEY_CURRENT_USER ;
case REG_USERS :
return HKEY_USERS ;
}
return NULL ;
}
// Cut the executable file name from the command line string (Unicode version)
wchar_t * MsCutExeNameFromUniCommandLine ( wchar_t * str )
{
// Validate arguments
if ( str = = NULL )
{
return NULL ;
}
if ( str [ 0 ] ! = L ' \" ' )
{
UINT i = UniSearchStrEx ( str , L " " , 0 , true ) ;
if ( i = = INFINITE )
{
return str + UniStrLen ( str ) ;
}
else
{
return str + i + 1 ;
}
}
else
{
str + + ;
while ( true )
{
if ( ( * str ) = = 0 )
{
return str + UniStrLen ( str ) ;
}
if ( ( * str ) = = L ' \" ' )
{
break ;
}
str + + ;
}
while ( true )
{
if ( ( * str ) = = 0 )
{
return str + UniStrLen ( str ) ;
}
if ( ( * str ) = = L ' ' )
{
return str + 1 ;
}
str + + ;
}
}
}
// Cut the executable file name from the command line string
char * MsCutExeNameFromCommandLine ( char * str )
{
// Validate arguments
if ( str = = NULL )
{
return NULL ;
}
if ( str [ 0 ] ! = ' \" ' )
{
UINT i = SearchStrEx ( str , " " , 0 , true ) ;
if ( i = = INFINITE )
{
return str + StrLen ( str ) ;
}
else
{
return str + i + 1 ;
}
}
else
{
str + + ;
while ( true )
{
if ( ( * str ) = = 0 )
{
return str + StrLen ( str ) ;
}
if ( ( * str ) = = ' \" ' )
{
break ;
}
str + + ;
}
while ( true )
{
if ( ( * str ) = = 0 )
{
return str + StrLen ( str ) ;
}
if ( ( * str ) = = ' ' )
{
return str + 1 ;
}
str + + ;
}
}
}
// Get the Process handle
void * MsGetCurrentProcess ( )
{
return ms - > hCurrentProcess ;
}
// Get the Process ID
UINT MsGetCurrentProcessId ( )
{
return ms - > CurrentProcessId ;
}
// Get the EXE file name
char * MsGetExeFileName ( )
{
return ms = = NULL ? " Unknown " : ms - > ExeFileName ;
}
// Get the name of the directory where the EXE file is in
char * MsGetExeDirName ( )
{
return ms - > ExeFileDir ;
}
wchar_t * MsGetExeDirNameW ( )
{
return ms - > ExeFileDirW ;
}
// Get the special directory name
char * MsGetSpecialDir ( int id )
{
LPITEMIDLIST t = NULL ;
char tmp [ MAX_PATH ] ;
if ( SHGetSpecialFolderLocation ( NULL , id , & t ) ! = S_OK )
{
return CopyStr ( ms - > ExeFileDir ) ;
}
if ( SHGetPathFromIDList ( t , tmp ) = = false )
{
return CopyStr ( ms - > ExeFileDir ) ;
}
Win32NukuEn ( tmp , sizeof ( tmp ) , tmp ) ;
return CopyStr ( tmp ) ;
}
wchar_t * MsGetSpecialDirW ( int id )
{
LPITEMIDLIST t = NULL ;
wchar_t tmp [ MAX_PATH ] ;
if ( IsNt ( ) = = false )
{
char * tmp = MsGetSpecialDir ( id ) ;
wchar_t * ret = CopyStrToUni ( tmp ) ;
Free ( tmp ) ;
return ret ;
}
if ( SHGetSpecialFolderLocation ( NULL , id , & t ) ! = S_OK )
{
return UniCopyStr ( ms - > ExeFileDirW ) ;
}
if ( SHGetPathFromIDListW ( t , tmp ) = = false )
{
return UniCopyStr ( ms - > ExeFileDirW ) ;
}
Win32NukuEnW ( tmp , sizeof ( tmp ) , tmp ) ;
return UniCopyStr ( tmp ) ;
}
// Get all the special directory
void MsGetSpecialDirs ( )
{
char tmp [ MAX_PATH ] ;
// System32
GetSystemDirectory ( tmp , sizeof ( tmp ) ) ;
Win32NukuEn ( tmp , sizeof ( tmp ) , tmp ) ;
ms - > System32Dir = CopyStr ( tmp ) ;
ms - > System32DirW = CopyStrToUni ( tmp ) ;
// The Windows directory is parent of the System32 directory
Win32GetDirFromPath ( tmp , sizeof ( tmp ) , tmp ) ;
Win32NukuEn ( tmp , sizeof ( tmp ) , tmp ) ;
ms - > WindowsDir = CopyStr ( tmp ) ;
ms - > WindowsDirW = CopyStrToUni ( tmp ) ;
// Temp directory under the Windows directory
Format ( tmp , sizeof ( tmp ) , " %s \\ Temp " , ms - > WindowsDir ) ;
ms - > WinTempDir = CopyStr ( tmp ) ;
ms - > WinTempDirW = CopyStrToUni ( tmp ) ;
MsUniMakeDirEx ( ms - > WinTempDirW ) ;
// System drive
tmp [ 2 ] = 0 ;
ms - > WindowsDrive = CopyStr ( tmp ) ;
ms - > WindowsDriveW = CopyStrToUni ( tmp ) ;
// Temp
GetTempPath ( MAX_PATH , tmp ) ;
Win32NukuEn ( tmp , sizeof ( tmp ) , tmp ) ;
ms - > TempDir = CopyStr ( tmp ) ;
// Get the Temp (Unicode)
if ( IsNt ( ) )
{
wchar_t tmp_w [ MAX_PATH ] ;
GetTempPathW ( MAX_PATH , tmp_w ) ;
Win32NukuEnW ( tmp_w , sizeof ( tmp_w ) , tmp_w ) ;
ms - > TempDirW = CopyUniStr ( tmp_w ) ;
}
else
{
ms - > TempDirW = CopyStrToUni ( tmp ) ;
}
MakeDirExW ( ms - > TempDirW ) ;
MakeDirEx ( ms - > TempDir ) ;
// Program Files
ms - > ProgramFilesDir = MsGetSpecialDir ( CSIDL_PROGRAM_FILES ) ;
if ( StrCmpi ( ms - > ProgramFilesDir , ms - > ExeFileDir ) = = 0 )
{
char tmp [ MAX_PATH ] ;
Format ( tmp , sizeof ( tmp ) , " %s \\ Program Files " , ms - > WindowsDrive ) ;
Free ( ms - > ProgramFilesDir ) ;
ms - > ProgramFilesDir = CopyStr ( tmp ) ;
}
ms - > ProgramFilesDirW = MsGetSpecialDirW ( CSIDL_PROGRAM_FILES ) ;
if ( UniStrCmpi ( ms - > ProgramFilesDirW , ms - > ExeFileDirW ) = = 0 )
{
wchar_t tmp [ MAX_PATH ] ;
UniFormat ( tmp , sizeof ( tmp ) , L " %s \\ Program Files " , ms - > WindowsDriveW ) ;
Free ( ms - > ProgramFilesDirW ) ;
ms - > ProgramFilesDirW = UniCopyStr ( tmp ) ;
}
// Program Files (x86)
ms - > ProgramFilesDirX86 = MsGetSpecialDir ( CSIDL_PROGRAM_FILESX86 ) ;
if ( StrCmpi ( ms - > ProgramFilesDirX86 , ms - > ExeFileDir ) = = 0 )
{
if ( MsIs64BitWindows ( ) )
{
char tmp [ MAX_PATH ] ;
Format ( tmp , sizeof ( tmp ) , " %s \\ Program Files (x86) " , ms - > WindowsDrive ) ;
Free ( ms - > ProgramFilesDirX86 ) ;
ms - > ProgramFilesDirX86 = CopyStr ( tmp ) ;
}
else
{
Free ( ms - > ProgramFilesDirX86 ) ;
ms - > ProgramFilesDirX86 = CopyStr ( ms - > ProgramFilesDir ) ;
}
}
ms - > ProgramFilesDirX86W = MsGetSpecialDirW ( CSIDL_PROGRAM_FILESX86 ) ;
if ( UniStrCmpi ( ms - > ProgramFilesDirX86W , ms - > ExeFileDirW ) = = 0 )
{
if ( MsIs64BitWindows ( ) )
{
wchar_t tmp [ MAX_PATH ] ;
UniFormat ( tmp , sizeof ( tmp ) , L " %s \\ Program Files (x86) " , ms - > WindowsDriveW ) ;
Free ( ms - > ProgramFilesDirX86W ) ;
ms - > ProgramFilesDirX86W = UniCopyStr ( tmp ) ;
}
else
{
Free ( ms - > ProgramFilesDirX86W ) ;
ms - > ProgramFilesDirX86W = UniCopyStr ( ms - > ProgramFilesDirW ) ;
}
}
// Program Files (x64)
if ( MsIs64BitWindows ( ) )
{
if ( Is64 ( ) )
{
ms - > ProgramFilesDirX64 = CopyStr ( ms - > ProgramFilesDir ) ;
ms - > ProgramFilesDirX64W = CopyUniStr ( ms - > ProgramFilesDirW ) ;
}
else
{
char tmpa [ MAX_SIZE ] ;
wchar_t tmpw [ MAX_SIZE ] ;
ReplaceStrEx ( tmpa , sizeof ( tmpa ) , ms - > ProgramFilesDir , " \\ Program Files (x86) " , " \\ Program Files " , false ) ;
UniReplaceStrEx ( tmpw , sizeof ( tmpw ) , ms - > ProgramFilesDirW , L " \\ Program Files (x86) " , L " \\ Program Files " , false ) ;
ms - > ProgramFilesDirX64 = CopyStr ( tmpa ) ;
ms - > ProgramFilesDirX64W = CopyUniStr ( tmpw ) ;
}
}
else
{
ms - > ProgramFilesDirX64 = CopyStr ( ms - > ProgramFilesDir ) ;
ms - > ProgramFilesDirX64W = CopyUniStr ( ms - > ProgramFilesDirW ) ;
}
2021-04-03 03:25:19 +03:00
// Common start menu
ms - > CommonStartMenuDir = MsGetSpecialDir ( CSIDL_COMMON_STARTMENU ) ;
ms - > CommonStartMenuDirW = MsGetSpecialDirW ( CSIDL_COMMON_STARTMENU ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
// Common program
ms - > CommonProgramsDir = MsGetSpecialDir ( CSIDL_COMMON_PROGRAMS ) ;
ms - > CommonProgramsDirW = MsGetSpecialDirW ( CSIDL_COMMON_PROGRAMS ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
// Common startup
ms - > CommonStartupDir = MsGetSpecialDir ( CSIDL_COMMON_STARTUP ) ;
ms - > CommonStartupDirW = MsGetSpecialDirW ( CSIDL_COMMON_STARTUP ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
// Common application data
ms - > CommonAppDataDir = MsGetSpecialDir ( CSIDL_COMMON_APPDATA ) ;
ms - > CommonAppDataDirW = MsGetSpecialDirW ( CSIDL_COMMON_APPDATA ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
// Common desktop
ms - > CommonDesktopDir = MsGetSpecialDir ( CSIDL_COMMON_DESKTOPDIRECTORY ) ;
ms - > CommonDesktopDirW = MsGetSpecialDirW ( CSIDL_COMMON_DESKTOPDIRECTORY ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
// Local Settings
ms - > LocalAppDataDir = MsGetSpecialDir ( CSIDL_LOCAL_APPDATA ) ;
ms - > LocalAppDataDirW = MsGetSpecialDirW ( CSIDL_LOCAL_APPDATA ) ;
2014-01-04 17:00:08 +04:00
}
// Check whether the current user is a Administrators
bool MsCheckIsAdmin ( )
{
UCHAR test_bit [ 32 ] ;
UCHAR tmp [ 32 ] ;
UCHAR exe_hash [ SHA1_SIZE ] ;
char * name_tag = " Vpn_Check_Admin_Key_%u " ;
DWORD type ;
DWORD size ;
char name [ MAX_SIZE ] ;
2018-09-22 07:35:30 +03:00
Sha1 ( exe_hash , MsGetExeFileNameW ( ) , UniStrLen ( MsGetExeFileNameW ( ) ) ) ;
2014-01-04 17:00:08 +04:00
Format ( name , sizeof ( name ) , name_tag , * ( ( UINT * ) exe_hash ) ) ;
Rand ( test_bit , sizeof ( test_bit ) ) ;
if ( RegSetValueEx ( HKEY_LOCAL_MACHINE , name , 0 , REG_BINARY , test_bit , sizeof ( test_bit ) ) ! = ERROR_SUCCESS )
{
return false ;
}
size = sizeof ( tmp ) ;
if ( RegQueryValueEx ( HKEY_LOCAL_MACHINE , name , 0 , & type , tmp , & size ) ! = ERROR_SUCCESS )
{
RegDeleteValue ( HKEY_LOCAL_MACHINE , name ) ;
return false ;
}
RegDeleteValue ( HKEY_LOCAL_MACHINE , name ) ;
if ( Cmp ( test_bit , tmp , 32 ) ! = 0 )
{
return false ;
}
return true ;
}
// Library initialization
void MsInit ( )
{
char * str_ansi ;
wchar_t * str_unicode ;
OSVERSIONINFO os ;
char tmp [ MAX_SIZE ] ;
2021-03-01 03:46:11 +03:00
DWORD size ;
2014-01-04 17:00:08 +04:00
if ( ms ! = NULL )
{
// Already initialized
return ;
}
2015-04-03 23:58:09 +03:00
suspend_handler_singleton = NewCounter ( ) ;
vlan_card_counter = NewCounter ( ) ;
vlan_card_should_stop_flag = false ;
2014-01-04 17:00:08 +04:00
ms = ZeroMalloc ( sizeof ( MS ) ) ;
// Getting instance handle
ms - > hInst = GetModuleHandle ( NULL ) ;
// Get the KERNEL32.DLL
ms - > hKernel32 = LoadLibrary ( " kernel32.dll " ) ;
// Get a command line string from the OS
str_ansi = CopyStr ( GetCommandLineA ( ) ) ;
Trim ( str_ansi ) ;
str_unicode = UniCopyStr ( GetCommandLineW ( ) ) ;
UniTrim ( str_unicode ) ;
SetCommandLineStr ( MsCutExeNameFromCommandLine ( str_ansi ) ) ;
SetCommandLineUniStr ( MsCutExeNameFromUniCommandLine ( str_unicode ) ) ;
Free ( str_unicode ) ;
Free ( str_ansi ) ;
// Get the version of the OS
Zero ( & os , sizeof ( os ) ) ;
os . dwOSVersionInfoSize = sizeof ( os ) ;
GetVersionEx ( & os ) ;
2021-04-03 03:25:19 +03:00
ms - > IsAdmin = MsCheckIsAdmin ( ) ;
2014-01-04 17:00:08 +04:00
2016-04-24 17:49:31 +03:00
if ( GetProcAddress ( ms - > hKernel32 , " wine_get_unix_file_name " ) ! = NULL )
{
ms - > IsWine = true ;
}
2014-01-04 17:00:08 +04:00
// Get information about the current process
ms - > hCurrentProcess = GetCurrentProcess ( ) ;
ms - > CurrentProcessId = GetCurrentProcessId ( ) ;
// Get the EXE file name
GetModuleFileName ( NULL , tmp , sizeof ( tmp ) ) ;
ms - > ExeFileName = CopyStr ( tmp ) ;
Win32GetDirFromPath ( tmp , sizeof ( tmp ) , tmp ) ;
ms - > ExeFileDir = CopyStr ( tmp ) ;
// Get the EXE file name (Unicode)
if ( IsNt ( ) )
{
wchar_t tmp_w [ MAX_PATH ] ;
GetModuleFileNameW ( NULL , tmp_w , sizeof ( tmp_w ) ) ;
ms - > ExeFileNameW = CopyUniStr ( tmp_w ) ;
Win32GetDirFromPathW ( tmp_w , sizeof ( tmp_w ) , tmp_w ) ;
ms - > ExeFileDirW = CopyUniStr ( tmp_w ) ;
}
else
{
ms - > ExeFileNameW = CopyStrToUni ( ms - > ExeFileName ) ;
ms - > ExeFileDirW = CopyStrToUni ( ms - > ExeFileDir ) ;
}
// Get the special directories
MsGetSpecialDirs ( ) ;
// Initialize the temporary directory
MsInitTempDir ( ) ;
// Get the user name
size = sizeof ( tmp ) ;
GetUserName ( tmp , & size ) ;
ms - > UserName = CopyStr ( tmp ) ;
// Get the user name (Unicode)
2021-04-03 03:25:19 +03:00
wchar_t tmp_w [ MAX_PATH ] ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
size = sizeof ( tmp_w ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
GetUserNameW ( tmp_w , & size ) ;
ms - > UserNameW = CopyUniStr ( tmp_w ) ;
2014-01-04 17:00:08 +04:00
// Get the full user name
2021-04-03 03:25:19 +03:00
size = sizeof ( tmp ) ;
if ( GetUserNameExA ( NameSamCompatible , tmp , & size ) )
2014-01-04 17:00:08 +04:00
{
2021-04-03 03:25:19 +03:00
ms - > UserNameEx = CopyStr ( tmp ) ;
}
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
size = sizeof ( tmp_w ) ;
if ( GetUserNameExW ( NameSamCompatible , tmp_w , & size ) )
{
ms - > UserNameExW = CopyUniStr ( tmp_w ) ;
2014-01-04 17:00:08 +04:00
}
if ( ms - > UserNameEx = = NULL )
{
ms - > UserNameEx = CopyStr ( ms - > UserName ) ;
}
if ( ms - > UserNameExW = = NULL )
{
ms - > UserNameExW = CopyUniStr ( ms - > UserNameW ) ;
}
// Initialization of the adapter list
MsInitAdapterListModule ( ) ;
// Initialization of minidump base file name
if ( true )
{
wchar_t tmp [ MAX_PATH ] ;
if ( MsIsAdmin ( ) )
{
CombinePathW ( tmp , sizeof ( tmp ) , ms - > ExeFileDirW , L " vpn_debug \\ dump " ) ;
}
else
{
CombinePathW ( tmp , sizeof ( tmp ) , ms - > TempDirW , L " vpn_debug \\ dump " ) ;
}
ms - > MinidumpBaseFileNameW = CopyUniStr ( tmp ) ;
}
MsSetEnableMinidump ( true ) ;
2021-04-03 03:25:19 +03:00
SetUnhandledExceptionFilter ( MsExceptionHandler ) ;
2014-01-04 17:00:08 +04:00
// Open a LSA handle
hLsa = NULL ;
lsa_package_id = 0 ;
2021-04-03 03:25:19 +03:00
MsEnablePrivilege ( SE_TCB_NAME , true ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
HANDLE h = NULL ;
NTSTATUS ret = LsaConnectUntrusted ( & h ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
if ( ret = = 0 )
{
LSA_STRING pkg_name ;
ULONG ul = 0 ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
Zero ( & pkg_name , sizeof ( pkg_name ) ) ;
pkg_name . Buffer = MSV1_0_PACKAGE_NAME ;
pkg_name . Length = pkg_name . MaximumLength = StrLen ( MSV1_0_PACKAGE_NAME ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
ret = LsaLookupAuthenticationPackage ( h , & pkg_name , & ul ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
if ( ret = = 0 )
{
Zero ( & lsa_token_source , sizeof ( lsa_token_source ) ) ;
2014-01-04 17:00:08 +04:00
2021-04-03 03:25:19 +03:00
AllocateLocallyUniqueId ( & lsa_token_source . SourceIdentifier ) ;
Copy ( lsa_token_source . SourceName , " SE-VPN " , 8 ) ;
lsa_package_id = ul ;
hLsa = h ;
}
else
{
LsaDeregisterLogonProcess ( h ) ;
2014-01-04 17:00:08 +04:00
}
}
// Read the msi.dll
if ( hMsi = = NULL )
{
hMsi = LoadLibrary ( " msi.dll " ) ;
if ( hMsi ! = NULL )
{
_MsiConfigureProductW =
( UINT ( __stdcall * ) ( LPCWSTR , int , INSTALLSTATE ) ) GetProcAddress ( hMsi , " MsiConfigureProductW " ) ;
_MsiGetProductInfoW =
( UINT ( __stdcall * ) ( LPCWSTR , LPCWSTR , LPWSTR , LPDWORD ) ) GetProcAddress ( hMsi , " MsiGetProductInfoW " ) ;
_MsiSetInternalUI =
( INSTALLUILEVEL ( __stdcall * ) ( INSTALLUILEVEL , HWND * ) ) GetProcAddress ( hMsi , " MsiSetInternalUI " ) ;
_MsiLocateComponentW =
( INSTALLSTATE ( __stdcall * ) ( LPCWSTR , LPWSTR , LPDWORD ) ) GetProcAddress ( hMsi , " MsiLocateComponentW " ) ;
}
}
// Lock created
vlan_lock = NewLock ( ) ;
}
// Uninstall the MSI product
bool MsMsiUninstall ( char * product_code , HWND hWnd , bool * reboot_required )
{
wchar_t * product_code_w ;
bool ret = false ;
INSTALLUILEVEL old_level ;
HWND old_hwnd ;
UINT r ;
// Validate arguments
if ( product_code = = NULL )
{
return false ;
}
if ( _MsiSetInternalUI = = NULL | | _MsiConfigureProductW = = NULL )
{
return false ;
}
if ( reboot_required ! = NULL )
{
* reboot_required = false ;
}
product_code_w = CopyStrToUni ( product_code ) ;
old_hwnd = hWnd ;
old_level = _MsiSetInternalUI ( INSTALLUILEVEL_PROGRESSONLY , & old_hwnd ) ;
r = _MsiConfigureProductW ( product_code_w , INSTALLLEVEL_DEFAULT , INSTALLSTATE_ABSENT ) ;
if ( r = = ERROR_SUCCESS | | r = = ERROR_SUCCESS_REBOOT_INITIATED | | r = = ERROR_SUCCESS_REBOOT_REQUIRED )
{
ret = true ;
if ( r = = ERROR_SUCCESS_REBOOT_INITIATED | | r = = ERROR_SUCCESS_REBOOT_REQUIRED )
{
if ( reboot_required ! = NULL )
{
* reboot_required = true ;
}
}
}
if ( old_level ! = INSTALLUILEVEL_NOCHANGE )
{
_MsiSetInternalUI ( old_level , & old_hwnd ) ;
}
Free ( product_code_w ) ;
return ret ;
}
// Get the installation directory of the MSI component
bool MsGetMsiInstalledDir ( char * component_code , wchar_t * dir , UINT dir_size )
{
wchar_t * component_code_w ;
bool ret = false ;
wchar_t tmp [ MAX_SIZE ] ;
2021-03-01 03:46:11 +03:00
DWORD sz = sizeof ( tmp ) / sizeof ( wchar_t ) ;
2014-01-04 17:00:08 +04:00
// Validate arguments
if ( component_code = = NULL | | dir = = NULL )
{
return false ;
}
if ( _MsiGetProductInfoW = = NULL )
{
return false ;
}
component_code_w = CopyStrToUni ( component_code ) ;
Zero ( tmp , sizeof ( tmp ) ) ;
if ( _MsiLocateComponentW ( component_code_w , tmp , & sz ) = = INSTALLSTATE_LOCAL )
{
if ( UniIsEmptyStr ( tmp ) = = false )
{
GetDirNameFromFilePathW ( dir , dir_size , tmp ) ;
ret = true ;
}
}
Free ( component_code_w ) ;
return ret ;
}
2019-08-04 04:26:41 +03:00
// Determine whether minidump is enabled
bool MsIsMinidumpEnabled ( )
{
return ms - > MiniDumpEnabled ;
}
2014-01-04 17:00:08 +04:00
// Determine whether to create a minidump
void MsSetEnableMinidump ( bool enabled )
{
ms - > MiniDumpEnabled = enabled ;
}
// Output the minidump
void MsWriteMinidump ( wchar_t * filename , void * ex )
{
wchar_t tmp [ MAX_PATH ] ;
wchar_t dir [ MAX_PATH ] ;
HANDLE h ;
MINIDUMP_EXCEPTION_INFORMATION info ;
struct _EXCEPTION_POINTERS * exp = ( struct _EXCEPTION_POINTERS * ) ex ;
if ( filename ! = NULL )
{
UniStrCpy ( tmp , sizeof ( tmp ) , filename ) ;
}
else
{
SYSTEMTIME tm ;
Zero ( & tm , sizeof ( tm ) ) ;
GetLocalTime ( & tm ) ;
UniFormat ( tmp , sizeof ( tmp ) , L " %s_%04u%02u%02u_%02u%02u%02u.dmp " ,
ms - > MinidumpBaseFileNameW ,
tm . wYear , tm . wMonth , tm . wDay , tm . wHour , tm . wMinute , tm . wSecond ) ;
}
GetDirNameFromFilePathW ( dir , sizeof ( dir ) , tmp ) ;
CreateDirectoryW ( dir , NULL ) ;
Zero ( & info , sizeof ( info ) ) ;
if ( exp ! = NULL )
{
info . ThreadId = GetCurrentThreadId ( ) ;
info . ExceptionPointers = exp ;
info . ClientPointers = true ;
}
h = CreateFileW ( tmp , GENERIC_READ | GENERIC_WRITE ,
FILE_SHARE_READ , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL ,
NULL ) ;
if ( h ! = INVALID_HANDLE_VALUE )
{
2021-04-03 03:25:19 +03:00
MiniDumpWriteDump ( ms - > hCurrentProcess , ms - > CurrentProcessId ,
2014-01-04 17:00:08 +04:00
h ,
MiniDumpNormal | MiniDumpWithFullMemory | MiniDumpWithDataSegs |
MiniDumpWithHandleData
,
info . ThreadId = = 0 ? NULL : & info , NULL , NULL ) ;
FlushFileBuffers ( h ) ;
CloseHandle ( h ) ;
}
}
// Exception handler
LONG CALLBACK MsExceptionHandler ( struct _EXCEPTION_POINTERS * ExceptionInfo )
{
if ( ms - > MiniDumpEnabled )
{
MsWriteMinidump ( NULL , ExceptionInfo ) ;
}
return EXCEPTION_CONTINUE_SEARCH ;
}
// Release of the library
void MsFree ( )
{
if ( ms = = NULL )
{
// Uninitialized
return ;
}
// Release the LSA
if ( hLsa ! = NULL )
{
2021-04-03 03:25:19 +03:00
LsaDeregisterLogonProcess ( hLsa ) ;
2014-01-04 17:00:08 +04:00
hLsa = NULL ;
}
// Release of the adapter list
MsFreeAdapterListModule ( ) ;
// Release of the temporary directory
MsFreeTempDir ( ) ;
// Memory release
// ANSI
Free ( ms - > WindowsDir ) ;
Free ( ms - > System32Dir ) ;
Free ( ms - > TempDir ) ;
Free ( ms - > WinTempDir ) ;
Free ( ms - > WindowsDrive ) ;
Free ( ms - > ProgramFilesDir ) ;
Free ( ms - > CommonStartMenuDir ) ;
Free ( ms - > CommonProgramsDir ) ;
Free ( ms - > CommonStartupDir ) ;
Free ( ms - > CommonAppDataDir ) ;
Free ( ms - > CommonDesktopDir ) ;
Free ( ms - > PersonalStartMenuDir ) ;
Free ( ms - > PersonalProgramsDir ) ;
Free ( ms - > PersonalStartupDir ) ;
Free ( ms - > PersonalAppDataDir ) ;
Free ( ms - > PersonalDesktopDir ) ;
Free ( ms - > MyDocumentsDir ) ;
Free ( ms - > ExeFileDir ) ;
Free ( ms - > ExeFileName ) ;
Free ( ms - > UserName ) ;
Free ( ms - > UserNameEx ) ;
Free ( ms - > LocalAppDataDir ) ;
Free ( ms - > ProgramFilesDirX86 ) ;
Free ( ms - > ProgramFilesDirX64 ) ;
// Unicode
Free ( ms - > WindowsDirW ) ;
Free ( ms - > System32DirW ) ;
Free ( ms - > TempDirW ) ;
Free ( ms - > WinTempDirW ) ;
Free ( ms - > WindowsDriveW ) ;
Free ( ms - > ProgramFilesDirW ) ;
Free ( ms - > CommonStartMenuDirW ) ;
Free ( ms - > CommonProgramsDirW ) ;
Free ( ms - > CommonStartupDirW ) ;
Free ( ms - > CommonAppDataDirW ) ;
Free ( ms - > CommonDesktopDirW ) ;
Free ( ms - > PersonalStartMenuDirW ) ;
Free ( ms - > PersonalProgramsDirW ) ;
Free ( ms - > PersonalStartupDirW ) ;
Free ( ms - > PersonalAppDataDirW ) ;
Free ( ms - > PersonalDesktopDirW ) ;
Free ( ms - > MyDocumentsDirW ) ;
Free ( ms - > ExeFileDirW ) ;
Free ( ms - > ExeFileNameW ) ;
Free ( ms - > UserNameW ) ;
Free ( ms - > UserNameExW ) ;
Free ( ms - > LocalAppDataDirW ) ;
Free ( ms - > MinidumpBaseFileNameW ) ;
Free ( ms - > ProgramFilesDirX86W ) ;
Free ( ms - > ProgramFilesDirX64W ) ;
Free ( ms ) ;
ms = NULL ;
// Delete the lock
DeleteLock ( vlan_lock ) ;
vlan_lock = NULL ;
2015-04-03 23:58:09 +03:00
DeleteCounter ( suspend_handler_singleton ) ;
suspend_handler_singleton = NULL ;
DeleteCounter ( vlan_card_counter ) ;
vlan_card_counter = NULL ;
vlan_card_should_stop_flag = false ;
2014-01-04 17:00:08 +04:00
}
// Directory acquisition related
char * MsGetWindowsDir ( )
{
return ms - > WindowsDir ;
}
wchar_t * MsGetWindowsDirW ( )
{
return ms - > WindowsDirW ;
}
char * MsGetSystem32Dir ( )
{
return ms - > System32Dir ;
}
char * MsGetTempDir ( )
{
return ms - > TempDir ;
}
char * MsGetProgramFilesDir ( )
{
return ms - > ProgramFilesDir ;
}
char * MsGetCommonStartupDir ( )
{
return ms - > CommonStartupDir ;
}
char * MsGetMyTempDir ( )
{
return ms - > MyTempDir ;
}
wchar_t * MsGetExeFileNameW ( )
{
return ms = = NULL ? L " Unknown " : ms - > ExeFileNameW ;
}
wchar_t * MsGetExeFileDirW ( )
{
return ms - > ExeFileDirW ;
}
wchar_t * MsGetSystem32DirW ( )
{
return ms - > System32DirW ;
}
wchar_t * MsGetTempDirW ( )
{
return ms - > TempDirW ;
}
wchar_t * MsGetCommonStartMenuDirW ( )
{
return ms - > CommonStartMenuDirW ;
}
wchar_t * MsGetCommonProgramsDirW ( )
{
return ms - > CommonProgramsDirW ;
}
wchar_t * MsGetProgramFilesDirX64W ( )
{
return ms - > ProgramFilesDirX64W ;
}
wchar_t * MsGetCommonStartupDirW ( )
{
return ms - > CommonStartupDirW ;
}
wchar_t * MsGetCommonDesktopDirW ( )
{
return ms - > CommonDesktopDirW ;
}
wchar_t * MsGetPersonalStartMenuDirW ( )
{
if ( ms - > PersonalStartMenuDirW = = NULL )
{
ms - > PersonalStartMenuDirW = MsGetSpecialDirW ( CSIDL_STARTMENU ) ;
}
return ms - > PersonalStartMenuDirW ;
}
wchar_t * MsGetPersonalProgramsDirW ( )
{
if ( ms - > PersonalProgramsDirW = = NULL )
{
ms - > PersonalProgramsDirW = MsGetSpecialDirW ( CSIDL_PROGRAMS ) ;
}
return ms - > PersonalProgramsDirW ;
}
wchar_t * MsGetPersonalStartupDirW ( )
{
if ( ms - > PersonalStartupDirW = = NULL )
{
ms - > PersonalStartupDirW = MsGetSpecialDirW ( CSIDL_STARTUP ) ;
}
return ms - > PersonalStartupDirW ;
}
wchar_t * MsGetPersonalAppDataDirW ( )
{
if ( ms - > PersonalAppDataDirW = = NULL )
{
ms - > PersonalAppDataDirW = MsGetSpecialDirW ( CSIDL_APPDATA ) ;
}
return ms - > PersonalAppDataDirW ;
}
wchar_t * MsGetPersonalDesktopDirW ( )
{
if ( ms - > PersonalDesktopDirW = = NULL )
{
ms - > PersonalDesktopDirW = MsGetSpecialDirW ( CSIDL_DESKTOP ) ;
}
return ms - > PersonalDesktopDirW ;
}
wchar_t * MsGetMyTempDirW ( )
{
return ms - > MyTempDirW ;
}
wchar_t * MsGetUserNameW ( )
{
return ms - > UserNameW ;
}
# endif // WIN32