// SoftEther VPN Source Code // Mayaqua Kernel // // SoftEther VPN Server, Client and Bridge are free software under GPLv2. // // Copyright (c) Daiyuu Nobori, Ph.D.. // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan. // Copyright (c) SoftEther Corporation. // // All Rights Reserved. // // http://www.softether.org/ // // Author: Daiyuu Nobori // Comments: Tetsuo Sugiyama, Ph.D. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License version 2 // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE // AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE. // // // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, // UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, // MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS // SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS // SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER // CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL // DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING, // MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR // SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO // EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, // JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION // AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN // THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE. // // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS // YOU HAVE A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY // CRIMINAL LAWS OR CIVIL RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS // SOFTWARE IN OTHER COUNTRIES IS COMPLETELY AT YOUR OWN RISK. THE // SOFTETHER VPN PROJECT HAS DEVELOPED AND DISTRIBUTED THIS SOFTWARE TO // COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING CIVIL RIGHTS INCLUDING // PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER COUNTRIES' LAWS OR // CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES. WE HAVE // NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ // COUNTRIES AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE // WORLD, WITH DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY // COUNTRIES' LAWS, REGULATIONS AND CIVIL RIGHTS TO MAKE THE SOFTWARE // COMPLY WITH ALL COUNTRIES' LAWS BY THE PROJECT. EVEN IF YOU WILL BE // SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A PUBLIC SERVANT IN YOUR // COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE LIABLE TO // RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT // JUST A STATEMENT FOR WARNING AND DISCLAIMER. // // // SOURCE CODE CONTRIBUTION // ------------------------ // // Your contribution to SoftEther VPN Project is much appreciated. // Please send patches to us through GitHub. // Read the SoftEther VPN Patch Acceptance Policy in advance: // http://www.softether.org/5-download/src/9.patch // // // DEAR SECURITY EXPERTS // --------------------- // // If you find a bug or a security vulnerability please kindly inform us // about the problem immediately so that we can fix the security problem // to protect a lot of users around the world as soon as possible. // // Our e-mail address for security reports is: // softether-vpn-security [at] softether.org // // Please note that the above e-mail address is not a technical support // inquiry address. If you need technical assistance, please visit // http://www.softether.org/ and ask your question on the users forum. // // Thank you for your cooperation. // // // NO MEMORY OR RESOURCE LEAKS // --------------------------- // // The memory-leaks and resource-leaks verification under the stress // test has been passed before release this source code. // Microsoft.c // For Microsoft Windows code // (not compiled on non-Windows environments) #include #ifdef WIN32 #define MICROSOFT_C 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_VETO_TYPE, *PPNP_VETO_TYPE; #define _WIN32_IE 0x0600 #define _WIN32_WINNT 0x0502 #define WINVER 0x0502 #define SECURITY_WIN32 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static MS *ms = NULL; // Function prototype UINT MsgBox(HWND hWnd, UINT flag, wchar_t *msg); UINT MsgBoxEx(HWND hWnd, UINT flag, wchar_t *msg, ...); void ShowTcpIpConfigUtil(HWND hWnd, bool util_mode); void CmTraffic(HWND hWnd); void CnStart(); void InitCedar(); void FreeCedar(); void InitWinUi(wchar_t *software_name, char *font, UINT fontsize); void FreeWinUi(); // 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 bool wts_is_locked_flag = false; static HICON tray_icon; static NOTIFYICONDATA nid; static NOTIFYICONDATAW nid_nt; static bool service_for_9x_mode = false; static THREAD *service_stopper_thread = NULL; 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; static COUNTER *suspend_handler_singleton = NULL; static COUNTER *vlan_card_counter = NULL; static volatile BOOL vlan_card_should_stop_flag = false; static volatile BOOL vlan_is_in_suspend_mode = false; static volatile UINT64 vlan_suspend_mode_begin_tick = 0; // 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; #define SE_GROUP_INTEGRITY (0x00000020L) typedef enum _TOKEN_INFORMATION_CLASS_VISTA { VistaTokenUser = 1, VistaTokenGroups, VistaTokenPrivileges, VistaTokenOwner, VistaTokenPrimaryGroup, VistaTokenDefaultDacl, VistaTokenSource, VistaTokenType, VistaTokenImpersonationLevel, VistaTokenStatistics, VistaTokenRestrictedSids, VistaTokenSessionId, VistaTokenGroupsAndPrivileges, VistaTokenSessionReference, VistaTokenSandBoxInert, VistaTokenAuditPolicy, VistaTokenOrigin, VistaTokenElevationType, VistaTokenLinkedToken, VistaTokenElevation, VistaTokenHasRestrictions, VistaTokenAccessInformation, VistaTokenVirtualizationAllowed, VistaTokenVirtualizationEnabled, VistaTokenIntegrityLevel, VistaTokenUIAccess, VistaTokenMandatoryPolicy, VistaTokenLogonSid, VistaMaxTokenInfoClass } TOKEN_INFORMATION_CLASS_VISTA, *PTOKEN_INFORMATION_CLASS_VISTA; 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; // 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; } if (MsIsAdmin() == false || MsIsWin2000OrGreater() == false) { 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\nDim str\r\n\r\nSet wmi_svc = GetObject(\"winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2\")\r\n\r\nSet items = wmi_svc.ExecQuery(\"Select * from Win32_BaseBoard\")\r\n\r\nFor Each item in items\r\n str = str & item.Manufacturer\r\nNext\r\n\r\nSet items = Nothing\r\n\r\nSet items = wmi_svc.ExecQuery(\"Select * from Win32_ComputerSystem\")\r\n\r\nFor Each item in items\r\n str = str & item.Manufacturer\r\nNext\r\n\r\nSet items = Nothing\r\n\r\nSet wmi_svc = Nothing\r\n\r\nstr = LCase(str)\r\n\r\nDim ret\r\n\r\nret = 0\r\n\r\nif InStr(str, \"microsoft corporation\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"vmware\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"virtualbox\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"virtualpc\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"xen\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"hvm\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"domu\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"kvm\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"oracle vm\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"qemu\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"parallels\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"xvm\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"virtual\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"bochs\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nwscript.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; if (MsIsNt() == false) { return false; } if (MsIsWin2000OrGreater() == false) { return 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 bool CALLBACK MsEnumResourcesInternalProc(HMODULE hModule, const char *type, char *name, LONG_PTR lParam) { 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; } // Get the locale ID of the system UINT MsGetSystemLocaleId() { static UINT lcid_cache = 0; if (lcid_cache == 0) { lcid_cache = (UINT)GetSystemDefaultLCID(); } 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; } if (ms->nt == NULL) { return false; } if (ms->nt->SetNamedSecurityInfoW == NULL || ms->nt->AddAccessAllowedAceEx == 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)) { if (ms->nt->AddAccessAllowedAceEx(acl, 2, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, GENERIC_ALL, sid_system) && ms->nt->AddAccessAllowedAceEx(acl, 2, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, GENERIC_ALL, sid_admin)) { if (ms->nt->SetNamedSecurityInfoW(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, acl, NULL) == ERROR_SUCCESS) { 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; if (ms->nt == NULL) { return; } if (ms->nt->WcmQueryProperty == NULL || ms->nt->WcmSetProperty == NULL || ms->nt->WcmFreeMemory == NULL || ms->nt->WcmGetProfileList == NULL) { return; } if (MsIsWindows8() == false) { return; } Zero(&v, sizeof(v)); v.fIsGroupPolicy = true; v.fValue = false; b = false; ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_minimize_policy, NULL, sizeof(v), (const BYTE *)&v); ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_minimize_policy, NULL, sizeof(b), (const BYTE *)&b); Zero(&v, sizeof(v)); v.fIsGroupPolicy = true; v.fValue = false; b = false; ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_domain_policy, NULL, sizeof(v), (const BYTE *)&v); ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_domain_policy, NULL, sizeof(b), (const BYTE *)&b); Zero(&v, sizeof(v)); v.fIsGroupPolicy = false; v.fValue = false; ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_minimize_policy, NULL, sizeof(v), (const BYTE *)&v); ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_minimize_policy, NULL, sizeof(b), (const BYTE *)&b); Zero(&v, sizeof(v)); v.fIsGroupPolicy = false; v.fValue = false; ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_domain_policy, NULL, sizeof(v), (const BYTE *)&v); ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_domain_policy, NULL, sizeof(b), (const BYTE *)&b); } // 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; UINT profile_buffer_size = 0; 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)); i = ms->nt->LsaLogonUser(hLsa, &origin, Network, lsa_package_id, m, m_size, NULL, &lsa_token_source, &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; ms->nt->LsaFreeReturnBuffer(profile_buffer); } 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); HashSha1(hash, name, StrLen(name)); BinToStr(tmp, sizeof(tmp), hash, sizeof(hash)); Format(tmp2, sizeof(tmp2), "GlobalPulse_%s", tmp); if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType)) { if (GET_KETA(GetOsInfo()->OsType, 100) >= 2 || GetOsInfo()->OsType == OSTYPE_WINDOWS_NT_4_TERMINAL_SERVER) { Format(tmp2, sizeof(tmp2), "Global\\GlobalPulse_%s", tmp); } } 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() { char *svc_name = "PolicyAgent"; if (MsIsVista()) { svc_name = "ikeext"; } return svc_name; } // 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; } if (MsIsNt() == false) { return false; } if (ms->nt->GetFileInformationByHandle == NULL) { return false; } return ms->nt->GetFileInformationByHandle(h, info); } // Set the shutdown parameters of the process void MsSetShutdownParameters(UINT level, UINT flag) { if (MsIsNt() == false) { return; } if (ms->nt == false || ms->nt->SetProcessShutdownParameters == NULL) { return; } ms->nt->SetProcessShutdownParameters(level, flag); } // Get whether the version of the OS is Windows XP or Windows Vista or later bool MsIsWinXPOrWinVista() { OS_INFO *info = GetOsInfo(); if (info == NULL) { return false; } if (OS_IS_WINDOWS_NT(info->OsType) == false) { return false; } if (GET_KETA(info->OsType, 100) >= 3) { return true; } return false; } // Write to the event log bool MsWriteEventLog(void *p, UINT type, wchar_t *str) { MS_EVENTLOG *g = (MS_EVENTLOG *)p; wchar_t *strings[2]; UINT id = 0; UINT typeapi = 0; // Validate arguments if (g == NULL || type >= 5 || str == NULL) { return false; } strings[0] = str; switch (type) { case MS_EVENTLOG_TYPE_INFORMATION: id = MS_RC_EVENTLOG_TYPE_INFORMATION; typeapi = EVENTLOG_INFORMATION_TYPE; break; case MS_EVENTLOG_TYPE_WARNING: id = MS_RC_EVENTLOG_TYPE_WARNING; typeapi = EVENTLOG_WARNING_TYPE; break; case MS_EVENTLOG_TYPE_ERROR: id = MS_RC_EVENTLOG_TYPE_ERROR; typeapi = EVENTLOG_ERROR_TYPE; break; } return ms->nt->ReportEventW(g->hEventLog, typeapi, 0, id, NULL, 1, 0, strings, NULL); } // Release of the event log void MsFreeEventLog(void *p) { MS_EVENTLOG *g = (MS_EVENTLOG *)p; // Validate arguments if (g == NULL) { return; } ms->nt->DeregisterEventSource(g->hEventLog); Free(g); } // Initialization of the event log void *MsInitEventLog(wchar_t *src_name) { MS_EVENTLOG *g; HANDLE h; wchar_t keyname[MAX_PATH]; char keyname_a[MAX_PATH]; wchar_t *exename; // Validate arguments if (src_name == NULL) { return NULL; } // Write the key to the registry exename = MsGetExeFileNameW(); UniFormat(keyname, sizeof(keyname), L"SYSTEM\\CurrentControlSet\\Services\\Eventlog\\Application\\%s", src_name); UniToStr(keyname_a, sizeof(keyname_a), keyname); MsRegWriteStrExpandExW(REG_LOCAL_MACHINE, keyname_a, "EventMessageFile", exename, false); MsRegWriteIntEx(REG_LOCAL_MACHINE, keyname_a, "TypesSupported", 7, false); h = ms->nt->RegisterEventSourceW(NULL, src_name); if (h == NULL) { return NULL; } g = ZeroMalloc(sizeof(MS_EVENTLOG)); g->hEventLog = h; return (void *)g; } // Empty the clipboard void MsDeleteClipboard() { OpenClipboard(NULL); EmptyClipboard(); CloseClipboard(); } // Get the process ID of the clipboard owner UINT MsGetClipboardOwnerProcessId() { HWND hWnd = GetClipboardOwner(); DWORD pid = 0; if (hWnd == NULL) { return 0; } GetWindowThreadProcessId(hWnd, &pid); return pid; } // 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 (MsIsVista() == false) { return; } 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 (MsIsVista() == false) { return false; } 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; } // Delete all the subkeys void MsRegDeleteSubkeys(UINT root, char *keyname, bool force32bit, bool force64bit) { TOKEN_LIST *t; UINT i; // Validate arguments if (keyname == NULL) { return; } t = MsRegEnumKeyEx2(root, keyname, force32bit, force64bit); if (t == NULL) { return; } for (i = 0;i < t->NumTokens;i++) { char tmp[MAX_PATH]; Format(tmp, sizeof(tmp), "%s\\%s", keyname, t->Token[i]); MsRegDeleteKeyEx2(root, tmp, force32bit, force64bit); } FreeToken(t); } // Convert the data in the buffer to the subkey of the registry void MsBufToRegSubkeys(UINT root, char *keyname, BUF *b, bool overwrite, bool force32bit, bool force64bit) { UINT i; UINT a; UINT num_keys; // Validate arguments if (keyname == NULL || b == NULL) { return; } SeekBuf(b, 0, 0); num_keys = ReadBufInt(b); for (i = 0;i < num_keys;i++) { char subkeyname[MAX_PATH]; char fullkeyname[MAX_PATH]; UINT j; UINT num_values; Zero(subkeyname, sizeof(subkeyname)); ReadBufStr(b, subkeyname, sizeof(subkeyname)); Format(fullkeyname, sizeof(fullkeyname), "%s\\%s", keyname, subkeyname); num_values = ReadBufInt(b); for (j = 0;j < num_values;j++) { char valuename[MAX_PATH]; char data[MAX_SIZE]; Zero(valuename, sizeof(valuename)); ReadBufStr(b, valuename, sizeof(valuename)); a = ReadBufInt(b); if (a == 0) { Zero(data, sizeof(data)); ReadBufStr(b, data, sizeof(data)); if (overwrite || MsRegIsValueEx2(root, fullkeyname, valuename, force32bit, force64bit) == false) { MsRegWriteStrEx2(root, fullkeyname, valuename, data, force32bit, force64bit); } } else { if (overwrite || MsRegIsValueEx2(root, fullkeyname, valuename, force32bit, force64bit) == false) { MsRegWriteIntEx2(root, fullkeyname, valuename, ReadBufInt(b), force32bit, force64bit); } } } } } // Convert data in the registry subkey to the buffer BUF *MsRegSubkeysToBuf(UINT root, char *keyname, bool force32bit, bool force64bit) { TOKEN_LIST *t; UINT i; BUF *b; // Validate arguments if (keyname == NULL) { return NULL; } t = MsRegEnumKeyEx2(root, keyname, force32bit, force64bit); if (t == NULL) { return NULL; } b = NewBuf(); WriteBufInt(b, t->NumTokens); for (i = 0;i < t->NumTokens;i++) { char *name = t->Token[i]; char tmp[MAX_PATH]; TOKEN_LIST *v; Format(tmp, sizeof(tmp), "%s\\%s", keyname, name); WriteBufStr(b, name); v = MsRegEnumValueEx2(root, tmp, force32bit, force64bit); if (v == NULL) { WriteBufInt(b, 0); } else { UINT j; WriteBufInt(b, v->NumTokens); for (j = 0;j < v->NumTokens;j++) { char *valuename = v->Token[j]; char *str; WriteBufStr(b, valuename); str = MsRegReadStrEx2(root, tmp, valuename, force32bit, force64bit); if (str != NULL) { WriteBufInt(b, 0); WriteBufStr(b, str); Free(str); } else { WriteBufInt(b, 1); WriteBufInt(b, MsRegReadIntEx2(root, tmp, valuename, force32bit, force64bit)); } } FreeToken(v); } } FreeToken(t); return b; } // Get the process name of the specified process ID bool MsGetProcessNameFromId(wchar_t *exename, UINT exename_size, UINT pid) { LIST *o; bool ret = false; UINT i; // Validate arguments if (pid == 0) { return false; } o = MsGetProcessList(); for (i = 0;i < LIST_NUM(o);i++) { MS_PROCESS *proc = LIST_DATA(o, i); if (proc->ProcessId == pid) { if (exename != NULL) { UniStrCpy(exename, exename_size, proc->ExeFilenameW); } ret = true; break; } } MsFreeProcessList(o); return ret; } // Check whether the specified process ID exists bool MsIsProcessIdExists(UINT pid) { return MsGetProcessNameFromId(NULL, 0, pid); } // Check whether the process of specified EXE file name exists bool MsIsProcessExists(char *exename) { LIST *o; bool ret = false; UINT i; // Validate arguments if (exename == NULL) { return false; } o = MsGetProcessList(); for (i = 0;i < LIST_NUM(o);i++) { MS_PROCESS *proc = LIST_DATA(o, i); char exe[MAX_PATH]; GetFileNameFromFilePath(exe, sizeof(exe), proc->ExeFilename); if (StrCmpi(exename, exe) == 0) { ret = true; break; } } MsFreeProcessList(o); return ret; } bool MsIsProcessExistsW(wchar_t *exename) { LIST *o; bool ret = false; UINT i; // Validate arguments if (exename == NULL) { return false; } o = MsGetProcessList(); for (i = 0;i < LIST_NUM(o);i++) { MS_PROCESS *proc = LIST_DATA(o, i); wchar_t exe[MAX_PATH]; GetFileNameFromFilePathW(exe, sizeof(exe), proc->ExeFilenameW); if (UniStrCmpi(exename, exe) == 0) { ret = true; break; } } MsFreeProcessList(o); return ret; } typedef struct _ASTAT_ { ADAPTER_STATUS adapt; NAME_BUFFER NameBuff[30]; } ASTAT, *PASTAT; // 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) { freq = 1000ULL; } else { Copy(&freq, &t, sizeof(UINT64)); } return (double)diff / (double)freq; } UINT64 MsGetHiResTimeSpanUSec(UINT64 diff) { LARGE_INTEGER t; UINT64 freq; if (QueryPerformanceFrequency(&t) == false) { freq = 1000ULL; } else { Copy(&freq, &t, sizeof(UINT64)); } return (UINT64)(diff) * 1000ULL * 1000ULL / (UINT64)freq; } // Get a high-resolution counter UINT64 MsGetHiResCounter() { LARGE_INTEGER t; UINT64 ret; if (QueryPerformanceCounter(&t) == false) { return Tick64(); } Copy(&ret, &t, sizeof(UINT64)); return ret; } // Whether the Welcome screen is used bool MsIsUseWelcomeLogin() { UINT os_type; if (MsIsNt() == false) { return false; } os_type = GetOsInfo()->OsType; if (OS_IS_WINDOWS_NT(os_type)) { if (GET_KETA(os_type, 100) == 3) { if (MsRegReadIntEx2(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "LogonType", false, true) == 0) { return false; } else { return true; } } } return false; } // Get a physical MAC address of the computer bool MsGetPhysicalMacAddress(void *address) { // Validate arguments if (address == NULL) { return false; } if (MsGetPhysicalMacAddressFromApi(address)) { return true; } if (MsGetPhysicalMacAddressFromNetbios(address)) { return true; } return false; } // Get the physical MAC address (from API) bool MsGetPhysicalMacAddressFromApi(void *address) { MS_ADAPTER_LIST *o; UINT i; bool ret = false; // Validate arguments if (address == NULL) { return false; } Zero(address, 6); o = MsCreateAdapterList(); for (i = 0;i < o->Num;i++) { MS_ADAPTER *a = o->Adapters[i]; if (a->AddressSize == 6 && a->Mtu == 1500) { bool b = false; switch (a->Type) { case MIB_IF_TYPE_OTHER: case MIB_IF_TYPE_ETHERNET: b = true; break; case MIB_IF_TYPE_TOKENRING: case MIB_IF_TYPE_FDDI: case MIB_IF_TYPE_PPP: case MIB_IF_TYPE_LOOPBACK: case MIB_IF_TYPE_SLIP: b = false; break; default: b = true; break; } if (b) { if (SearchStrEx(a->Title, "WAN", 0, false) == INFINITE) { if (a->Status == MIB_IF_OPER_STATUS_CONNECTED || a->Status == MIB_IF_OPER_STATUS_OPERATIONAL) { if (a->AddressSize == 6) { if (IsZero(a->Address, 6) == false) { if (Cmp(address, a->Address, 6) <= 0) { Copy(address, a->Address, 6); ret = true; } } } } } } } } MsFreeAdapterList(o); return ret; } // Get the physical MAC address (from NetBIOS) bool MsGetPhysicalMacAddressFromNetbios(void *address) { NCB ncb; UCHAR ret; LANA_ENUM lenum; UINT i; ASTAT adapter; bool b = false; // Validate arguments if (address == NULL) { return false; } Zero(&ncb, sizeof(ncb)); Zero(&lenum, sizeof(lenum)); ncb.ncb_command = NCBENUM; ncb.ncb_buffer = (UCHAR *)&lenum; ncb.ncb_length = sizeof(lenum); ret = Netbios(&ncb); Zero(address, 6); for (i = 0;i < lenum.length;i++) { Zero(&ncb, sizeof(ncb)); ncb.ncb_command = NCBRESET; ncb.ncb_lana_num = lenum.lana[i]; ret = Netbios(&ncb); Zero(&ncb, sizeof(ncb)); ncb.ncb_command = NCBASTAT; ncb.ncb_lana_num = lenum.lana[i]; StrCpy(ncb.ncb_callname, sizeof(ncb.ncb_callname), "* "); Zero(&adapter, sizeof(adapter)); ncb.ncb_buffer = (char *)&adapter; ncb.ncb_length = sizeof(adapter); ret = Netbios(&ncb); if (ret == 0) { if (Cmp(address, adapter.adapt.adapter_address, 6) <= 0) { Copy(address, adapter.adapt.adapter_address, 6); b = true; } } } return b; } // System-wide updating notification void MsUpdateSystem() { static DWORD dw = 0; 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); } // Get whether the specified path points to a local drive bool MsIsLocalDrive(char *name) { char tmp[MAX_PATH]; UINT ret; // Validate arguments if (name == NULL) { return false; } Zero(tmp, sizeof(tmp)); InnerFilePath(tmp, sizeof(tmp), name); if (StartWith(tmp, "\\\\")) { // Network directory return false; } if (tmp[1] != ':' || tmp[2] != '\\') { // Not a drive letter return false; } tmp[3] = 0; ret = GetDriveType(tmp); if (ret == DRIVE_REMOTE || ret == DRIVE_CDROM || ret == DRIVE_RAMDISK) { return false; } return true; } bool MsIsLocalDriveW(wchar_t *name) { char name_a[MAX_PATH]; UniToStr(name_a, sizeof(name_a), name); return MsIsLocalDrive(name_a); } // Get whether the specified file is locked bool MsIsFileLocked(char *name) { HANDLE h; char tmp[MAX_PATH]; // Validate arguments if (name == NULL) { return false; } InnerFilePath(tmp, sizeof(tmp), name); h = CreateFile(tmp, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL); if (h == INVALID_HANDLE_VALUE) { return true; } CloseHandle(h); return false; } bool MsIsFileLockedW(wchar_t *name) { HANDLE h; wchar_t tmp[MAX_PATH]; // Validate arguments if (name == NULL) { return false; } if (IsNt() == false) { char name_a[MAX_SIZE]; UniToStr(name_a, sizeof(name_a), name); return MsIsFileLocked(name_a); } InnerFilePathW(tmp, sizeof(tmp), name); h = CreateFileW(tmp, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL); if (h == INVALID_HANDLE_VALUE) { return true; } CloseHandle(h); return false; } // Wait for the process termination UINT MsWaitProcessExit(void *process_handle) { HANDLE h = (HANDLE)process_handle; UINT ret = 1; if (h == NULL) { return 1; } while (true) { WaitForSingleObject(h, INFINITE); ret = 1; if (GetExitCodeProcess(h, &ret) == false) { break; } if (ret != STILL_ACTIVE) { break; } } CloseHandle(h); return ret; } // Execution of the file (to get process handle) bool MsExecuteEx(char *exe, char *arg, void **process_handle) { return MsExecuteEx2(exe, arg, process_handle, false); } bool MsExecuteEx2(char *exe, char *arg, void **process_handle, bool runas) { SHELLEXECUTEINFO info; HANDLE h; // Validate arguments if (exe == NULL || process_handle == NULL) { return false; } 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) { return false; } h = info.hProcess; *process_handle = (void *)h; return true; } bool MsExecuteExW(wchar_t *exe, wchar_t *arg, void **process_handle) { return MsExecuteEx2W(exe, arg, process_handle, false); } bool MsExecuteEx2W(wchar_t *exe, wchar_t *arg, void **process_handle, bool runas) { SHELLEXECUTEINFOW info; HANDLE h; // Validate arguments if (exe == NULL || process_handle == NULL) { return false; } if (IsNt() == false) { char exe_a[MAX_SIZE]; char arg_a[MAX_SIZE]; UniToStr(exe_a, sizeof(exe_a), exe); UniToStr(arg_a, sizeof(arg_a), arg); return MsExecuteEx(exe_a, arg_a, process_handle); } 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) { return false; } h = info.hProcess; *process_handle = (void *)h; return true; } // Close the handle void MsCloseHandle(void *handle) { if (handle != NULL) { CloseHandle(handle); } } // Execution of the file bool MsExecute(char *exe, char *arg) { return MsExecute2(exe, arg, false); } bool MsExecute2(char *exe, char *arg, bool runas) { DWORD d; // Validate arguments if (exe == NULL) { return false; } d = (DWORD)ShellExecuteA(NULL, (runas ? "runas" : "open"), exe, arg, MsGetExeDirName(), SW_SHOWNORMAL); if (d > 32) { return true; } return false; } bool MsExecuteW(wchar_t *exe, wchar_t *arg) { return MsExecute2W(exe, arg, false); } bool MsExecute2W(wchar_t *exe, wchar_t *arg, bool runas) { DWORD d; // Validate arguments if (exe == NULL) { return false; } if (IsNt() == false) { char exe_a[MAX_SIZE]; char arg_a[MAX_SIZE]; UniToStr(exe_a, sizeof(exe_a), exe); UniToStr(arg_a, sizeof(arg_a), arg); return MsExecute(exe_a, arg_a); } d = (DWORD)ShellExecuteW(NULL, (runas ? L"runas" : L"open"), exe, arg, MsGetExeDirNameW(), SW_SHOWNORMAL); if (d > 32) { return true; } return false; } // Recursive directory creation void MsUniMakeDirEx(wchar_t *name) { UINT wp; wchar_t *tmp; UINT i, len; // Validate arguments if (name == NULL) { return; } tmp = ZeroMalloc(UniStrSize(name) * 2); wp = 0; len = UniStrLen(name); for (i = 0;i < len;i++) { wchar_t c = name[i]; if (c == '\\') { if (UniStrCmpi(tmp, L"\\\\") != 0 && UniStrCmpi(tmp, L"\\") != 0) { MsUniMakeDir(tmp); } } tmp[wp++] = c; } Free(tmp); MsUniMakeDir(name); } void MsMakeDirEx(char *name) { wchar_t *name_w = CopyStrToUni(name); MsUniMakeDirEx(name_w); Free(name_w); } // Create a directory bool MsUniMakeDir(wchar_t *name) { // Validate arguments if (name == NULL) { return false; } if (MsIsNt() == false) { char *s = CopyUniToStr(name); bool ret = MsMakeDir(s); Free(s); return ret; } return CreateDirectoryW(name, NULL); } bool MsMakeDir(char *name) { // Validate arguments if (name == NULL) { return false; } return CreateDirectoryA(name, NULL); } // Delete the directory bool MsUniDirectoryDelete(wchar_t *name) { // Validate arguments if (name == NULL) { return false; } if (MsIsNt() == false) { char *s = CopyUniToStr(name); bool ret = MsDirectoryDelete(s); Free(s); return ret; } return RemoveDirectoryW(name); } bool MsDirectoryDelete(char *name) { // Validate arguments if (name == NULL) { return false; } return RemoveDirectoryA(name); } // Delete the File bool MsUniFileDelete(wchar_t *name) { // Validate arguments if (name == NULL) { return false; } if (MsIsNt() == false) { bool ret; char *s = CopyUniToStr(name); ret = MsFileDelete(s); Free(s); return ret; } return DeleteFileW(name); } bool MsFileDelete(char *name) { // Validate arguments if (name == NULL) { return false; } return DeleteFileA(name); } // Get whether the specified file name is a directory bool MsUniIsDirectory(wchar_t *name) { DWORD ret; // Validate arguments if (name == NULL) { return false; } if (MsIsNt() == false) { char *s = CopyUniToStr(name); ret = MsIsDirectory(s); Free(s); return ret; } ret = GetFileAttributesW(name); if (ret == 0xffffffff) { return false; } if (ret & FILE_ATTRIBUTE_DIRECTORY) { return true; } return false; } bool MsIsDirectoryW(wchar_t *name) { return MsUniIsDirectory(name); } bool MsIsDirectory(char *name) { DWORD ret; char tmp[MAX_PATH]; // Validate arguments if (name == NULL) { return false; } InnerFilePath(tmp, sizeof(tmp), name); ret = GetFileAttributesA(tmp); if (ret == 0xffffffff) { return false; } if (ret & FILE_ATTRIBUTE_DIRECTORY) { return true; } return false; } // Extract the Cabinet from the MSI file bool MsExtractCabFromMsi(char *msi, char *cab) { wchar_t msi_w[MAX_PATH]; wchar_t cab_w[MAX_PATH]; StrToUni(msi_w, sizeof(msi_w), msi); StrToUni(cab_w, sizeof(cab_w), cab); return MsExtractCabFromMsiW(msi_w, cab_w); } bool MsExtractCabFromMsiW(wchar_t *msi, wchar_t *cab) { BUF *b; bool ret = false; UINT i; char sign[] = {'M', 'S', 'C', 'F', 0, 0, 0, 0,}; void *pointer = NULL; UINT current_pos = 0; UINT sign_size; // Validate arguments if (msi == NULL || cab == NULL) { return false; } // Read the MSI b = ReadDumpW(msi); if (b == NULL) { return false; } if (b->Size < 128) { FreeBuf(b); return false; } sign_size = sizeof(sign); // Search for "MSCF" for (i = 0;i < (b->Size - sign_size);i++) { char *p = ((UCHAR *)b->Buf) + i; if (Cmp(p, sign, sign_size) == 0) { pointer = p; current_pos = i; } } if (pointer != NULL) { UINT size = b->Size - current_pos; BUF *b2 = NewBuf(); WriteBuf(b2, pointer, size); ret = DumpBufW(b2, cab); FreeBuf(b2); } FreeBuf(b); return ret; } // Retrieve a file from Cabinet file bool MsExtractCab(char *cab_name, char *dest_dir_name) { wchar_t cab_name_w[MAX_SIZE]; wchar_t dest_dir_name_w[MAX_SIZE]; StrToUni(cab_name_w, sizeof(cab_name_w), cab_name); StrToUni(dest_dir_name_w, sizeof(dest_dir_name_w), dest_dir_name); return MsExtractCabW(cab_name_w, dest_dir_name_w); } bool MsExtractCabW(wchar_t *cab_name, wchar_t *dest_dir_name) { wchar_t cabarc[MAX_PATH]; wchar_t arg[MAX_PATH * 2]; wchar_t tmp[MAX_PATH]; // Validate arguments if (cab_name == NULL || dest_dir_name == NULL) { return false; } if (MsGetCabarcExeFilenameW(cabarc, sizeof(cabarc)) == false) { return false; } UniStrCpy(tmp, sizeof(tmp), dest_dir_name); if (UniEndWith(tmp, L"\\")) { tmp[UniStrLen(tmp) - 1] = 0; } UniFormat(arg, sizeof(arg), L"-o X \"%s\" * \"%s\"\\", cab_name, tmp); MakeDirW(dest_dir_name); if (RunW(cabarc, arg, true, true) == false) { return false; } return true; } // Extract of cabarc.exe bool MsGetCabarcExeFilename(char *name, UINT size) { // Validate arguments if (name == NULL) { return false; } ConbinePath(name, size, MsGetMyTempDir(), "cabarc.exe"); if (IsFileExists(name)) { return true; } if (FileCopy("|cabarc.exe", name) == false) { return false; } return true; } bool MsGetCabarcExeFilenameW(wchar_t *name, UINT size) { // Validate arguments if (name == NULL) { return false; } ConbinePathW(name, size, MsGetMyTempDirW(), L"cabarc.exe"); if (IsFileExistsW(name)) { return true; } if (FileCopyW(L"|cabarc.exe", name) == false) { return false; } return true; } // Extract the Cabinet file from EXE file bool MsExtractCabinetFileFromExe(char *exe, char *cab) { BUF *b; // Validate arguments if (exe == NULL || cab == NULL) { return false; } b = MsExtractResourceFromExe(exe, RT_RCDATA, "CABINET"); if (b == NULL) { return false; } if (DumpBuf(b, cab) == false) { FreeBuf(b); return false; } FreeBuf(b); return true; } bool MsExtractCabinetFileFromExeW(wchar_t *exe, wchar_t *cab) { BUF *b; // Validate arguments if (exe == NULL || cab == NULL) { return false; } b = MsExtractResourceFromExeW(exe, RT_RCDATA, "CABINET"); if (b == NULL) { return false; } if (DumpBufW(b, cab) == false) { FreeBuf(b); return false; } FreeBuf(b); return true; } // Extract the resource from EXE file BUF *MsExtractResourceFromExe(char *exe, char *type, char *name) { HINSTANCE h; HRSRC hr; HGLOBAL hg; UINT size; void *data; BUF *buf; // Validate arguments if (exe == NULL || type == NULL || name == NULL) { return NULL; } h = LoadLibraryExA(exe, NULL, LOAD_LIBRARY_AS_DATAFILE); if (h == NULL) { return NULL; } hr = FindResourceA(h, name, type); if (hr == NULL) { FreeLibrary(h); return NULL; } hg = LoadResource(h, hr); if (hg == NULL) { FreeLibrary(h); return NULL; } size = SizeofResource(h, hr); data = (void *)LockResource(hg); buf = NewBuf(); WriteBuf(buf, data, size); FreeResource(hg); FreeLibrary(h); SeekBuf(buf, 0, 0); return buf; } BUF *MsExtractResourceFromExeW(wchar_t *exe, char *type, char *name) { HINSTANCE h; HRSRC hr; HGLOBAL hg; UINT size; void *data; BUF *buf; // Validate arguments if (exe == NULL || type == NULL || name == NULL) { return NULL; } if (IsNt() == false) { char exe_a[MAX_PATH]; UniToStr(exe_a, sizeof(exe_a), exe); return MsExtractResourceFromExe(exe_a, type, name); } h = LoadLibraryExW(exe, NULL, LOAD_LIBRARY_AS_DATAFILE); if (h == NULL) { return NULL; } hr = FindResource(h, name, type); if (hr == NULL) { FreeLibrary(h); return NULL; } hg = LoadResource(h, hr); if (hg == NULL) { FreeLibrary(h); return NULL; } size = SizeofResource(h, hr); data = (void *)LockResource(hg); buf = NewBuf(); WriteBuf(buf, data, size); FreeResource(hg); FreeLibrary(h); SeekBuf(buf, 0, 0); return buf; } // Get the version information of the file bool MsGetFileVersion(char *name, UINT *v1, UINT *v2, UINT *v3, UINT *v4) { void *data; UINT size; DWORD h; bool ret = false; // Validate arguments if (name == NULL) { return false; } h = 0; size = GetFileVersionInfoSize(name, &h); if (size == 0) { return false; } data = ZeroMalloc(size); if (GetFileVersionInfoA(name, 0, size, data)) { VS_FIXEDFILEINFO *info = NULL; UINT info_size = 0; if (VerQueryValueA(data, "\\", &info, &info_size)) { if (v1 != NULL) { *v1 = HIWORD(info->dwFileVersionMS); } if (v2 != NULL) { *v2 = LOWORD(info->dwFileVersionMS); } if (v3 != NULL) { *v3 = HIWORD(info->dwFileVersionLS); } if (v4 != NULL) { *v4 = LOWORD(info->dwFileVersionLS); } ret = true; } } Free(data); return ret; } bool MsGetFileVersionW(wchar_t *name, UINT *v1, UINT *v2, UINT *v3, UINT *v4) { void *data; UINT size; DWORD h; bool ret = false; // Validate arguments if (name == NULL) { return false; } if (IsNt() == false) { char name_a[MAX_PATH]; UniToStr(name_a, sizeof(name_a), name); return MsGetFileVersion(name_a, v1, v2, v3, v4); } h = 0; size = GetFileVersionInfoSizeW(name, &h); if (size == 0) { return false; } data = ZeroMalloc(size); if (GetFileVersionInfoW(name, 0, size, data)) { VS_FIXEDFILEINFO *info = NULL; UINT info_size = 0; if (VerQueryValue(data, "\\", &info, &info_size)) { if (v1 != NULL) { *v1 = HIWORD(info->dwFileVersionMS); } if (v2 != NULL) { *v2 = LOWORD(info->dwFileVersionMS); } if (v3 != NULL) { *v3 = HIWORD(info->dwFileVersionLS); } if (v4 != NULL) { *v4 = LOWORD(info->dwFileVersionLS); } ret = true; } } Free(data); return ret; } // Set the file to a hidden file void MsSetFileToHidden(char *name) { char tmp[MAX_PATH]; DWORD d; // Validate arguments if (name == NULL) { return; } NormalizePath(tmp, sizeof(tmp), name); d = GetFileAttributesA(tmp); if (d != INVALID_FILE_ATTRIBUTES) { d |= FILE_ATTRIBUTE_HIDDEN; SetFileAttributesA(tmp, d); } } void MsSetFileToHiddenW(wchar_t *name) { wchar_t tmp[MAX_PATH]; DWORD d; // Validate arguments if (name == NULL) { return; } if (IsNt() == false) { char name_a[MAX_SIZE]; UniToStr(name_a, sizeof(name_a), name); MsSetFileToHidden(name_a); return; } NormalizePathW(tmp, sizeof(tmp), name); d = GetFileAttributesW(tmp); if (d != INVALID_FILE_ATTRIBUTES) { d |= FILE_ATTRIBUTE_HIDDEN; SetFileAttributesW(tmp, d); } } // Sleep prevention thread void MsNoSleepThread(THREAD *thread, void *param) { MS_NOSLEEP *e; EXECUTION_STATE (WINAPI *_SetThreadExecutionState)(EXECUTION_STATE); HINSTANCE hKernel32; // Validate arguments if (thread == NULL || param == NULL) { return; } hKernel32 = LoadLibrary("kernel32.dll"); _SetThreadExecutionState = (EXECUTION_STATE (__stdcall *)(EXECUTION_STATE)) GetProcAddress(hKernel32, "SetThreadExecutionState"); e = (MS_NOSLEEP *)param; while (e->Halt == false) { DWORD flag = ES_SYSTEM_REQUIRED; if (e->NoScreenSaver) { flag |= ES_DISPLAY_REQUIRED; } if (_SetThreadExecutionState != NULL) { _SetThreadExecutionState(flag); } Wait(e->HaltEvent, 30 * 1000); } FreeLibrary(hKernel32); } // Sleep prevention thread (for Windows Vista) void MsNoSleepThreadVista(THREAD *thread, void *param) { MS_NOSLEEP *e; char *key = "Control Panel\\Desktop"; UINT64 last_set_flag = 0; UINT last_c_x = INFINITE, last_c_y = INFINITE; UINT64 last_mouse_move_time = 0; EXECUTION_STATE (WINAPI *_SetThreadExecutionState)(EXECUTION_STATE); HINSTANCE hKernel32; // Validate arguments if (thread == NULL || param == NULL) { return; } hKernel32 = LoadLibrary("kernel32.dll"); _SetThreadExecutionState = (EXECUTION_STATE (__stdcall *)(EXECUTION_STATE)) GetProcAddress(hKernel32, "SetThreadExecutionState"); e = (MS_NOSLEEP *)param; while (e->Halt == false) { DWORD flag = ES_SYSTEM_REQUIRED; UINT64 now = Tick64(); POINT p; bool mouse_move = false; Zero(&p, sizeof(p)); GetCursorPos(&p); if (p.x != last_c_x || p.y != last_c_y) { if (last_c_x != INFINITE && last_c_y != INFINITE) { mouse_move = true; } last_c_x = p.x; last_c_y = p.y; } if (mouse_move) { last_mouse_move_time = now; } if (last_mouse_move_time == 0 || (now > (last_mouse_move_time + 50000ULL))) { wchar_t *active; wchar_t *exe; // Remove the configuration of the screen saver If the mouse does not move more than 50 seconds active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive"); exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE"); if (UniToInt(active) != 0 && UniIsEmptyStr(exe) == false) { // Screen saver is set UniStrCpy(e->ScreenSaveActive, sizeof(e->ScreenSaveActive), active); UniStrCpy(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE), exe); MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", L"0"); MsRegDeleteValue(REG_CURRENT_USER, key, "SCRNSAVE.EXE"); Debug("Push SS Settings.\n"); } Free(active); Free(exe); last_mouse_move_time = now; } else { if (mouse_move) { if (UniIsEmptyStr(e->ScreenSaveActive) == false && UniIsEmptyStr(e->SCRNSAVE_EXE) == false) { // Restore the settings of screen saver if the screen saver // is not set when the mouse is moved wchar_t *active; wchar_t *exe; active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive"); exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE"); if (UniToInt(active) != 0 && UniIsEmptyStr(exe) == false) { } else { MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", e->ScreenSaveActive); MsRegWriteStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE", e->SCRNSAVE_EXE); Zero(e->ScreenSaveActive, sizeof(e->ScreenSaveActive)); Zero(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE)); Debug("Pop SS Settings.\n"); } Free(active); Free(exe); } } } if (last_set_flag == 0 || (now > (last_set_flag + 50000ULL))) { // Flag set (interval 50 seconds) last_set_flag = now; if (_SetThreadExecutionState != NULL) { _SetThreadExecutionState(flag); } } Wait(e->HaltEvent, 512); } if (true) { // Restore the settings of the screen saver wchar_t *active; wchar_t *exe; if (UniIsEmptyStr(e->ScreenSaveActive) == false && UniIsEmptyStr(e->SCRNSAVE_EXE) == false) { active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive"); exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE"); if (UniToInt(active) != 0 && UniIsEmptyStr(exe) != 0) { } else { MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", e->ScreenSaveActive); MsRegWriteStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE", e->SCRNSAVE_EXE); Zero(e->ScreenSaveActive, sizeof(e->ScreenSaveActive)); Zero(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE)); Debug("Pop SS Settings.\n"); } Free(active); Free(exe); } } FreeLibrary(hKernel32); } // The start of the sleep prevention void *MsNoSleepStart(bool no_screensaver) { MS_NOSLEEP *e; bool is_vista = MsIsVista(); bool is_nt_4 = false; UINT os_type = GetOsInfo()->OsType; if (OS_IS_WINDOWS_NT(os_type)) { if (GET_KETA(os_type, 100) == 1) { is_nt_4 = true; } } e = ZeroMalloc(sizeof(MS_NOSLEEP)); e->HaltEvent = NewEvent(); e->NoScreenSaver = no_screensaver; if (e->NoScreenSaver == false || (is_vista == false && is_nt_4 == false)) { e->Thread = NewThread(MsNoSleepThread, e); } else { e->Thread = NewThread(MsNoSleepThreadVista, e); } return (void *)e; } // Stop the Sleep prevention void MsNoSleepEnd(void *p) { MS_NOSLEEP *e; // Validate arguments if (p == NULL) { return; } e = (MS_NOSLEEP *)p; e->Halt = true; Set(e->HaltEvent); WaitThread(e->Thread, INFINITE); ReleaseThread(e->Thread); ReleaseEvent(e->HaltEvent); Free(e); } static wchar_t ms_computer_name_full_cache[MAX_SIZE] = {0}; // Get the full name of the computer void MsGetComputerNameFull(wchar_t *name, UINT size) { MsGetComputerNameFullEx(name, size, false); } void MsGetComputerNameFullEx(wchar_t *name, UINT size, bool with_cache) { UINT size2 = size; // 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; } } if (MsIsNt() == false || ms->nt->GetComputerNameExW == NULL || ms->nt->GetComputerNameExW(ComputerNameDnsFullyQualified, name, &size2) == false) { 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 *MsRunAsUserEx(char *filename, char *arg, bool hide) { void *ret = MsRunAsUserExInner(filename, arg, hide); if (ret == NULL) { Debug("MsRunAsUserExInner Failed.\n"); ret = Win32RunEx(filename, arg, hide); } return ret; } 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 *MsRunAsUserExInner(char *filename, char *arg, bool hide) { void *ret; wchar_t *filename_w; wchar_t *arg_w; filename_w = CopyStrToUni(filename); arg_w = CopyStrToUni(arg); ret = MsRunAsUserExInnerW(filename_w, arg_w, hide); Free(filename_w); Free(arg_w); 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; } if (MsIsVista() == false) { // Can not be used in non-Windows Vista 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; } if (ms->nt->CreateProcessAsUserW(hToken, NULL, cmdline, NULL, NULL, FALSE, (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; UINT sid_size = 4096; char *domain_name; UINT domain_name_size = 4096; SID_NAME_USE use = SidTypeUser; // Validate arguments if (name == NULL) { return NULL; } if (MsIsNt() == false) { return NULL; } sid = ZeroMalloc(sid_size); domain_name = ZeroMalloc(domain_name_size); if (ms->nt->LookupAccountNameA(NULL, name, sid, &sid_size, domain_name, &domain_name_size, &use) == false) { 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() { char *medium_sid = "S-1-16-8192"; char *administrators_sid = "S-1-5-32-544"; SID *sid = NULL; TOKEN_MANDATORY_LABEL til; HANDLE hCurrentToken, hNewToken; if (MsIsNt() == false) { return NULL; } if (ms->nt->ConvertStringSidToSidA == NULL || ms->nt->OpenProcessToken == NULL || ms->nt->DuplicateTokenEx == NULL || ms->nt->GetTokenInformation == NULL || ms->nt->SetTokenInformation == NULL) { return NULL; } Zero(&til, sizeof(til)); if (ms->nt->ConvertStringSidToSidA(medium_sid, &sid) == false) { return NULL; } til.Label.Attributes = SE_GROUP_INTEGRITY; til.Label.Sid = sid; if (ms->nt->OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hCurrentToken) == false) { LocalFree(sid); return NULL; } if (ms->nt->DuplicateTokenEx(hCurrentToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hNewToken) == false) { CloseHandle(hCurrentToken); LocalFree(sid); return NULL; } if (ms->nt->SetTokenInformation(hNewToken, VistaTokenIntegrityLevel, &til, sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(sid)) == false) { CloseHandle(hNewToken); CloseHandle(hCurrentToken); LocalFree(sid); return NULL; } CloseHandle(hCurrentToken); LocalFree(sid); return hNewToken; } // Check the digital signature of the file bool MsCheckFileDigitalSignature(HWND hWnd, char *name, bool *danger) { wchar_t tmp[MAX_PATH]; swprintf(tmp, sizeof(tmp), L"%S", name); return MsCheckFileDigitalSignatureW(hWnd, tmp, danger); } 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; } // Enable or disable the WoW64 redirection void MsSetWow64FileSystemRedirectionEnable(bool enable) { if (MsIs64BitWindows() == false) { return; } if (ms->nt->Wow64EnableWow64FsRedirection == NULL) { return; } ms->nt->Wow64EnableWow64FsRedirection(enable ? 1 : 0); } // Disable the WoW64 redirection void *MsDisableWow64FileSystemRedirection() { void *p = NULL; if (MsIs64BitWindows() == false) { return NULL; } if (ms->nt->Wow64DisableWow64FsRedirection == NULL || ms->nt->Wow64RevertWow64FsRedirection == NULL) { return NULL; } if (ms->nt->Wow64DisableWow64FsRedirection(&p) == false) { 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; } if (ms->nt->Wow64DisableWow64FsRedirection == NULL || ms->nt->Wow64RevertWow64FsRedirection == NULL) { return; } ms->nt->Wow64RevertWow64FsRedirection(p); } // Get whether the x64 version of Windows is currently running bool MsIsX64() { SYSTEM_INFO info; if (MsIs64BitWindows() == false) { return false; } if (ms->nt->GetNativeSystemInfo == NULL) { return false; } Zero(&info, sizeof(info)); ms->nt->GetNativeSystemInfo(&info); 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; } else { if (MsIsNt() == false) { return false; } else { if (ms == NULL || ms->nt == NULL) { return false; } if (ms->nt->IsWow64Process == NULL) { return false; } else { bool b = false; if (ms->nt->IsWow64Process(GetCurrentProcess(), &b) == false) { return false; } return b; } } } } // 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\nConst NET_FW_PROFILE_DOMAIN = 0\r\nConst NET_FW_PROFILE_STANDARD = 1\r\n" "Const NET_FW_SCOPE_ALL = 0\r\nConst NET_FW_IP_VERSION_ANY = 2\r\nDim fwMgr\r\n" "Set fwMgr = CreateObject(\"HNetCfg.FwMgr\")\r\nDim profile\r\n" "Set profile = fwMgr.LocalPolicy.CurrentProfile\r\nDim app\r\n" "Set app = CreateObject(\"HNetCfg.FwAuthorizedApplication\")\r\n" "app.ProcessImageFileName = \"$PATH$\"\r\napp.Name = \"$TITLE$\"\r\n" "app.Scope = NET_FW_SCOPE_ALL\r\napp.IpVersion = NET_FW_IP_VERSION_ANY\r\n" "app.Enabled = TRUE\r\nOn Error Resume Next\r\nprofile.AuthorizedApplications." "Add app\r\n"; char *tmp; UINT tmp_size; char filename[MAX_PATH]; char cscript[MAX_PATH]; char arg[MAX_PATH]; UINT ostype; 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; } // OS check (This Is not performed except Windows XP, Windows Server 2003, Windows Vista or later) ostype = GetOsInfo()->OsType; if (OS_IS_WINDOWS_NT(ostype) == false) { return; } if (MsIsAdmin() == false) { return; } if (MsIsVista()) { data = "Option Explicit\r\n\r\nConst PROFILES_ALL = 7\r\nConst NET_FW_ACTION_ALLOWNET_FW_ACTION_ALLOW = 1\r\n" "\r\nDim policy2\r\nDim rules\r\nDim new_rule\r\n\r\nOn Error Resume Next\r\n\r\n" "Set policy2 = CreateObject(\"HNetCfg.FwPolicy2\")\r\nSet rules = policy2.Rules\r\n" "Set new_rule = CreateObject(\"HNetCfg.FWRule\")\r\nnew_rule.Name = \"$TITLE$\"\r\n" "new_rule.Description = \"$TITLE$\"\r\nnew_rule.ApplicationName = \"$PATH$\"\r\n" "new_rule.Enabled = TRUE\r\nnew_rule.Profiles = PROFILES_ALL\r\nnew_rule.Action = " "NET_FW_ACTION_ALLOWNET_FW_ACTION_ALLOW\r\nrules.Add new_rule\r\n\r\n"; } tmp_size = StrLen(data) * 4; tmp = ZeroMalloc(tmp_size); HashSha1(hashbin, exe, StrLen(exe)); BinToStr(hash, sizeof(hash), hashbin, 6); ReplaceStrEx(tmp, tmp_size, data, "$TITLE$", title, false); ReplaceStrEx(tmp, tmp_size, tmp, "$PATH$", exe, false); HashSha1(file_hash_bin, tmp, StrLen(tmp)); BinToStr(file_hash_str, sizeof(file_hash_str), file_hash_bin, sizeof(file_hash_bin)); if (MsIsVista() == false || MsRegReadIntEx2(REG_LOCAL_MACHINE, SOFTETHER_FW_SCRIPT_HASH, file_hash_str, false, true) == 0) { 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; UINT retcode; SHELLEXECUTEINFOW info; wchar_t *src_exe; 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 src_exe = VISTA_DRIVER_INSTALLER_SRC; if (MsIsX64()) { src_exe = VISTA_DRIVER_INSTALLER_SRC_X64; } if (MsIsIA64()) { src_exe = VISTA_DRIVER_INSTALLER_SRC_IA64; } UniFormat(tmp, sizeof(tmp), VISTA_DRIVER_INSTALLER_DST, MsGetMyTempDirW()); if (FileCopyW(src_exe, tmp) == false) { 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; 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; } Hash(hash, name, UniStrLen(name), true); 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); } // Simple LoadLibaray void *MsLoadLibraryRawW(wchar_t *name) { // Validate arguments if (name == NULL) { return NULL; } if (MsIsNt()) { return LoadLibraryW(name); } else { char tmp[MAX_PATH]; UniToStr(tmp, sizeof(tmp), name); return LoadLibraryA(tmp); } } // 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; } Hash(hash, name, UniStrSize(name), true); 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); } // Release of the library void MsFreeLibrary(void *h) { // Validate arguments if (h == NULL) { return; } FreeLibrary(h); } // Get the function pointer in the DLL void *MsGetProcAddress(void *h, char *name) { // Validate arguments if (h == NULL || name == NULL) { return NULL; } return (void *)GetProcAddress(h, name); } // 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; UINT info_size; UINT ret; // Validate arguments if (a == NULL) { return; } if (w32net->GetAdaptersInfo == NULL) { return; } info_top = ZeroMalloc(sizeof(IP_ADAPTER_INFO)); info_size = sizeof(IP_ADAPTER_INFO); ret = w32net->GetAdaptersInfo(info_top, &info_size); if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW) { Free(info_top); info_size *= 2; info_top = ZeroMalloc(info_size); if (w32net->GetAdaptersInfo(info_top, &info_size) != NO_ERROR) { 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) { LIST *o; UINT i; UINT retcode; MIB_IFTABLE *table; UINT table_size = sizeof(MIB_IFTABLE); MS_ADAPTER_LIST *ret; if (w32net->GetIfTable2 != NULL && w32net->FreeMibTable != NULL) { return MsCreateAdapterListInnerExVista(no_info); } if (w32net->GetIfTable == NULL) { return ZeroMalloc(sizeof(MS_ADAPTER_LIST)); } table = ZeroMalloc(table_size); retcode = w32net->GetIfTable(table, &table_size, TRUE); if (retcode == ERROR_INSUFFICIENT_BUFFER || retcode == ERROR_BUFFER_OVERFLOW) { Free(table); table_size *= 2; table = ZeroMalloc(table_size); if (w32net->GetIfTable(table, &table_size, TRUE) != NO_ERROR) { Free(table); return ZeroMalloc(sizeof(MS_ADAPTER_LIST)); } } else if (retcode != NO_ERROR) { Free(table); return ZeroMalloc(sizeof(MS_ADAPTER_LIST)); } o = NewListFast(NULL); for (i = 0;i < table->dwNumEntries;i++) { MIB_IFROW *r = &table->table[i]; char title[MAX_PATH]; UINT num = 0; 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) { StrCpy(title, sizeof(title), (char *)r->bDescr); } else { Format(title, sizeof(title), "%s (%u)", (char *)r->bDescr, j); } exists = false; for (k = 0;k < LIST_NUM(o);k++) { MS_ADAPTER *a = LIST_DATA(o, k); if (StrCmpi(a->Title, title) == 0) { exists = true; break; } } if (exists == false) { break; } } a = ZeroMalloc(sizeof(MS_ADAPTER)); // Create an adapter information StrCpy(a->Title, sizeof(a->Title), title); StrToUni(a->TitleW, sizeof(a->TitleW), title); a->Index = r->dwIndex; a->Type = r->dwType; a->Status = r->dwOperStatus; a->Mtu = r->dwMtu; a->Speed = r->dwSpeed; a->AddressSize = MIN(sizeof(a->Address), r->dwPhysAddrLen); Copy(a->Address, r->bPhysAddr, a->AddressSize); a->RecvBytes = r->dwInOctets; a->RecvPacketsBroadcast = r->dwInNUcastPkts; a->RecvPacketsUnicast = r->dwInUcastPkts; a->SendBytes = r->dwOutOctets; a->SendPacketsBroadcast = r->dwOutNUcastPkts; a->SendPacketsUnicast = r->dwOutUcastPkts; if (a->Type != IF_TYPE_ETHERNET_CSMACD) { 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); Free(table); return ret; } // Creating an adapters list (Windows Vista version) MS_ADAPTER_LIST *MsCreateAdapterListInnerExVista(bool no_info) { LIST *o; UINT i; UINT retcode; MIB_IF_TABLE2 *table; UINT table_size = sizeof(MIB_IFTABLE); MS_ADAPTER_LIST *ret; if (w32net->GetIfTable2 == NULL || w32net->FreeMibTable == NULL) { return ZeroMalloc(sizeof(MS_ADAPTER_LIST)); } retcode = w32net->GetIfTable2(&table); 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]; UINT num = 0; 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); w32net->FreeMibTable(table); 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) { 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 MsGetCurrentProcessExeName(char *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); StrCpy(name, size, p->ExeFilename); } else { StrCpy(name, size, MsGetExeFileName()); } MsFreeProcessList(o); } 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; } } // Display the process list void MsPrintProcessList(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); UniPrint(L"%-4u: %s\n", p->ProcessId, p->ExeFilenameW); } } // 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; UINT needed, num; UINT i; o = NewListFast(MsCompareProcessList); if (ms->nt->EnumProcesses == NULL) { return o; } processes = ZeroMalloc(sizeof(DWORD) * max); if (ms->nt->EnumProcesses(processes, sizeof(DWORD) * max, &needed) == FALSE) { 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; if (ms->nt->EnumProcessModules(h, &hInst, sizeof(hInst), &needed) == false) { hInst = NULL; } if (ms->nt->GetModuleFileNameExA(h, hInst, exe, sizeof(exe) - 1) && ms->nt->GetModuleFileNameExW(h, hInst, exe_w, sizeof(exe_w) / sizeof(wchar_t) - 1)) { ok = true; } else if (ms->nt->QueryFullProcessImageNameA != NULL && ms->nt->QueryFullProcessImageNameW != NULL && ms->nt->QueryFullProcessImageNameA(h, 0, exe, &sz1) && ms->nt->QueryFullProcessImageNameW(h, 0, exe_w, &sz2)) { 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; } // Get the Process List (for Win9x) LIST *MsGetProcessList9x() { HANDLE h; LIST *o; HANDLE (WINAPI *CreateToolhelp32Snapshot)(DWORD, DWORD); BOOL (WINAPI *Process32First)(HANDLE, LPPROCESSENTRY32); BOOL (WINAPI *Process32Next)(HANDLE, LPPROCESSENTRY32); CreateToolhelp32Snapshot = (HANDLE (__stdcall *)(DWORD,DWORD)) GetProcAddress(ms->hKernel32, "CreateToolhelp32Snapshot"); Process32First = (BOOL (__stdcall *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress(ms->hKernel32, "Process32First"); Process32Next = (BOOL (__stdcall *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress(ms->hKernel32, "Process32Next"); o = NewListFast(MsCompareProcessList); if (CreateToolhelp32Snapshot != NULL && Process32First != NULL && Process32Next != NULL) { h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (h != INVALID_HANDLE_VALUE) { PROCESSENTRY32 e; Zero(&e, sizeof(e)); e.dwSize = sizeof(e); if (Process32First(h, &e)) { while (true) { MS_PROCESS *p = ZeroMalloc(sizeof(MS_PROCESS)); StrCpy(p->ExeFilename, sizeof(p->ExeFilename), e.szExeFile); StrToUni(p->ExeFilenameW, sizeof(p->ExeFilenameW), p->ExeFilename); p->ProcessId = e.th32ProcessID; Add(o, p); if (Process32Next(h, &e) == false) { break; } } } CloseHandle(h); } } Sort(o); return o; } // Get the Process List LIST *MsGetProcessList() { if (MsIsNt() == false) { // Windows 9x return MsGetProcessList9x(); } else { // Windows NT, 2000, XP return MsGetProcessListNt(); } } // Force to run the current thread on a single CPU void MsSetThreadSingleCpu() { SetThreadAffinityMask(GetCurrentThread(), 1); } // Playback of sound void MsPlaySound(char *name) { char tmp[MAX_SIZE]; char wav[MAX_SIZE]; char *temp; BUF *b; // Validate arguments if (name == NULL) { return; } 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; } if (MsIsNt() == false) { Zero(&nid, sizeof(nid)); nid.cbSize = sizeof(nid); nid.hWnd = hWnd; nid.uID = 1; nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO; nid.uCallbackMessage = msg; nid.hIcon = icon; UniToStr(nid.szTip, sizeof(nid.szTip), tooltip); ret = Shell_NotifyIcon(NIM_ADD, &nid); } else { 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); ret = Shell_NotifyIconW(NIM_ADD, &nid_nt); } tray_inited = true; return ret; } // Check whether the task tray has been initialized bool MsIsTrayInited() { return tray_inited; } // Restore the icon in the task tray void MsRestoreIconOnTray() { if (tray_inited == false) { return; } if (MsIsNt() == false) { Shell_NotifyIcon(NIM_ADD, &nid); } else { Shell_NotifyIconW(NIM_ADD, &nid_nt); } } // Change the icon in the task tray (go over!) void MsChangeIconOnTrayEx2(void *icon, wchar_t *tooltip, wchar_t *info_title, wchar_t *info, UINT info_flags) { MsChangeIconOnTrayEx((HICON)icon, tooltip, info_title, info, info_flags, false); } // 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) { if (MsIsNt() == false) { if (nid.hIcon != icon) { changed = true; nid.hIcon = icon; } } else { if (nid_nt.hIcon != icon) { changed = true; nid_nt.hIcon = icon; } } } if (tooltip != NULL) { if (MsIsNt() == false) { char tmp[MAX_SIZE]; UniToStr(tmp, sizeof(tmp), tooltip); if (StrCmp(nid.szTip, tmp) != 0) { StrCpy(nid.szTip, sizeof(nid.szTip), tmp); changed = true; } } else { wchar_t tmp[MAX_SIZE]; UniStrCpy(tmp, sizeof(tmp), tooltip); if (UniStrCmp(nid_nt.szTip, tmp) != 0) { UniStrCpy(nid_nt.szTip, sizeof(nid_nt.szTip), tmp); changed = true; } } } if (info_title != NULL && info != NULL) { if (MsIsNt() == false) { char tmp1[MAX_SIZE]; char tmp2[MAX_PATH]; UniToStr(tmp1, sizeof(tmp1), info_title); UniToStr(tmp2, sizeof(tmp2), info); if (StrCmp(nid.szInfo, tmp1) != 0 || StrCmp(nid.szInfoTitle, tmp2) != 0) { StrCpy(nid.szInfo, sizeof(nid.szInfo), tmp1); StrCpy(nid.szInfoTitle, sizeof(nid.szInfoTitle), tmp2); nid.dwInfoFlags = info_flags; changed = true; } } else { wchar_t tmp1[MAX_SIZE]; wchar_t tmp2[MAX_PATH]; UniStrCpy(tmp1, sizeof(tmp1), info_title); UniStrCpy(tmp2, sizeof(tmp2), info); if (UniStrCmp(nid_nt.szInfo, tmp1) != 0 || UniStrCmp(nid_nt.szInfoTitle, tmp2) != 0) { UniStrCpy(nid_nt.szInfo, sizeof(nid_nt.szInfo), tmp1); UniStrCpy(nid_nt.szInfoTitle, sizeof(nid_nt.szInfoTitle), tmp2); nid_nt.dwInfoFlags = info_flags; changed = true; } } } if (changed || add) { UINT op = (add ? NIM_ADD : NIM_MODIFY); if (MsIsNt() == false) { ret = Shell_NotifyIcon(op, &nid); } else { ret = Shell_NotifyIconW(op, &nid_nt); } } return ret; } // Remove the icon in the task tray void MsHideIconOnTray() { if (MsIsNt() == false) { Shell_NotifyIcon(NIM_DELETE, &nid); } else { Shell_NotifyIconW(NIM_DELETE, &nid_nt); } 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) { bool ret; if (MsIsNt()) { ret = InsertMenuW(hMenu, pos, flags, id_new_item, lp_new_item); } else { char *s = CopyUniToStr(lp_new_item); ret = InsertMenuA(hMenu, pos, flags, id_new_item, s); Free(s); } return ret; } // Adding a menu item bool MsAppendMenu(HMENU hMenu, UINT flags, UINT_PTR id, wchar_t *str) { bool ret; if (MsIsNt()) { ret = AppendMenuW(hMenu, flags, id, str); } else { char *s = CopyUniToStr(str); ret = AppendMenuA(hMenu, flags, id, s); Free(s); } return ret; } // 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); if (MsIsNt()) { GetWindowTextW(hWnd, caption, sizeof(caption)); } else { char tmp[MAX_SIZE]; GetWindowTextA(hWnd, tmp, sizeof(tmp)); StrToUni(caption, sizeof(caption), tmp); } 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 if (MsRegReadInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, value_name) == 0 && service_for_9x_mode == false) { 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); if (MsRegReadInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, value_name) == 0 && service_for_9x_mode == false) { 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 the name of PenCore.dll char *MsGetPenCoreDllFileName() { /*if (Is64()) { if (IsX64()) { return PENCORE_DLL_NAME_X64; } else { return PENCORE_DLL_NAME_IA64; } } else*/ { return PENCORE_DLL_NAME; } } // Get whether this instance is in user mode bool MsIsUserMode() { return is_usermode; } // Command to terminate the user-mode from the service side void MsStopUserModeFromService() { if (hWndUsermode != NULL) { PostMessage(hWndUsermode, WM_CLOSE, 0, 0); } } // 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); HashSha1(hash, tmp, UniStrLen(tmp) * sizeof(wchar_t)); BinToStr(name, size, hash, sizeof(hash)); } // 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; UINT num = Count(vlan_card_counter); vlan_is_in_suspend_mode = true; vlan_card_should_stop_flag = true; vlan_suspend_mode_begin_tick = Tick64(); while (true) { UINT64 now = Tick64(); if (now >= giveup_tick) { break; } if (Count(vlan_card_counter) == 0) { break; } SleepThread(100); } if (num >= 1) { SleepThread(3000); } } void MsProcLeaveSuspend() { vlan_card_should_stop_flag = false; 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; } // 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: if (MsIsVista()) { switch (wParam) { case PBT_APMSUSPEND: MsProcEnterSuspend(); return 1; case PBT_APMRESUMEAUTOMATIC: case PBT_APMRESUMESUSPEND: MsProcLeaveSuspend(); return 1; } } 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; vlan_is_in_suspend_mode = false; vlan_suspend_mode_begin_tick = 0; 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; } vlan_card_should_stop_flag = false; vlan_is_in_suspend_mode = false; vlan_suspend_mode_begin_tick = 0; 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; } // Start in user mode void MsUserMode(char *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon) { wchar_t *title_w = CopyStrToUni(title); MsUserModeW(title_w, start, stop, icon); Free(title_w); } 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) { if (service_for_9x_mode == false) { // Do not display an error if Win9x service mode MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_USERMODE_MUTEX"), ms->ExeFileNameW); } return; } if (Is64()) { hDll = MsLoadLibraryAsDataFile(MsGetPenCoreDllFileName()); } else { hDll = MsLoadLibrary(MsGetPenCoreDllFileName()); } // Read icon tray_icon = LoadImage(hDll, MAKEINTRESOURCE(icon), IMAGE_ICON, 16, 16, (MsIsNt() ? LR_SHARED : 0) | LR_VGACOLOR); // 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 void CALLBACK MsServiceHandler(DWORD opcode) { 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 void CALLBACK MsServiceDispatcher(DWORD argc, LPTSTR *argv) { // 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 InitMayaqua(false, false, 0, NULL); // 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); } // Dispatch function of the service void CALLBACK MsScmDispatcher(DWORD argc, LPTSTR *argv) { } // 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 InitMayaqua(false, false, 0, NULL); // 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_WIN9X_SERVICE) == 0) { mode = SVC_MODE_WIN9X_SERVICE; } if (StrCmpi(arg, SVC_ARG_WIN9X_INSTALL) == 0) { mode = SVC_MODE_WIN9X_INSTALL; } if (StrCmpi(arg, SVC_ARG_WIN9X_UNINSTALL) == 0) { mode = SVC_MODE_WIN9X_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)) { // Do not have Administrators privillage 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); if (Is64() == false) { UniFormat(vpncmgr, sizeof(vpncmgr), L"%s\\vpncmgr.exe", MsGetExeDirNameW()); } else { UniFormat(vpncmgr, sizeof(vpncmgr), L"%s\\vpncmgr_x64.exe", MsGetExeDirNameW()); } 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_WIN9X_SERVICE: // Win9x service mode (hide icon in the task tray unconditionally) if (MsIsNt()) { // Don't do this on Windows 2000 or later break; } service_for_9x_mode = true; // Not a oblivion to break case SVC_MODE_USERMODE: // User mode MsUserModeW(service_title, start, stop, icon); break; case SVC_MODE_WIN9X_INSTALL: // Win9x installation mode MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId()); restoreReg = true; if (MsIsNt() == false) { // Adding a registry key char cmdline[MAX_PATH]; Format(cmdline, sizeof(cmdline), "\"%s\" %s", MsGetExeFileName(), SVC_ARG_WIN9X_SERVICE); MsRegWriteStr(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_1, name, cmdline); MsRegWriteStr(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_2, name, cmdline); // Start //Run(MsGetExeFileName(), SVC_ARG_WIN9X_SERVICE, false, false); } break; case SVC_MODE_WIN9X_UNINSTALL: // Win9x uninstall mode MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId()); restoreReg = true; if (MsIsNt() == false) { // Delete the registry key MsRegDeleteValue(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_1, name); MsRegDeleteValue(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_2, name); // Terminate all the processes of PacketiX VPN Client other than itself MsKillOtherInstance(); } break; case SVC_MODE_SERVICE: // Run as a service // Obsolated (2012.12.31) (Do this in the above code) //MsServiceMode(start, stop); break; case SVC_MODE_TCP: case SVC_MODE_TCP_UAC: // TCP Utility InitCedar(); InitWinUi(service_title_uni, NULL, 0); if (MsIsVista() && MsIsAdmin() == false && mode != SVC_MODE_TCP_UAC) { 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); if (MsIsVista() && MsIsAdmin() == false) { 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; UINT size = 0; if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id, WTSUserName, (wchar_t *)&name, &size) == false) { return NULL; } if (name == NULL || UniStrLen(name) == 0) { ret = NULL; } else { ret = UniCopyStr(name); } ms->nt->WTSFreeMemory(name); return ret; } return NULL; } // Get whether the current desktop is available for the VNC bool MsIsCurrentDesktopAvailableForVnc() { if (MsIsNt() == false) { return true; } if (MsIsCurrentTerminalSessionActive() == false) { return false; } if (ms->nt->OpenDesktopA == NULL || ms->nt->CloseDesktop == NULL || ms->nt->SwitchDesktop == NULL) { return true; } else { HDESK hDesk = ms->nt->OpenDesktopA("default", 0, false, DESKTOP_SWITCHDESKTOP); bool ret; if (hDesk == NULL) { return false; } ret = ms->nt->SwitchDesktop(hDesk); ms->nt->CloseDesktop(hDesk); return ret; } } // 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; UINT size = sizeof(status); bool active = true; if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id, WTSConnectState, (wchar_t *)&status, &size) == false) { return true; } switch (*status) { case WTSDisconnected: case WTSShadow: case WTSIdle: case WTSDown: case WTSReset: active = false; break; } ms->nt->WTSFreeMemory(status); return active; } return true; } // Get the current terminal session ID UINT MsGetCurrentTerminalSessionId() { if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled()) { UINT ret; UINT *session_id = NULL; UINT size = sizeof(session_id); if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSSessionId, (wchar_t *)&session_id, &size) == false) { return 0; } ret = *session_id; ms->nt->WTSFreeMemory(session_id); return ret; } return 0; } // Examine whether the Terminal Services is installed and the multiple sessions can log in bool MsIsTerminalServiceMultiUserInstalled() { OS_INFO *info = GetOsInfo(); OSVERSIONINFOEX i; if (MsIsTerminalServiceInstalled() == false) { return false; } if (OS_IS_SERVER(info->OsType) == false) { return false; } Zero(&i, sizeof(i)); i.dwOSVersionInfoSize = sizeof(i); if (GetVersionEx((OSVERSIONINFO *)&i) == false) { return false; } if (i.wSuiteMask & VER_SUITE_SINGLEUSERTS) { return false; } return true; } // Examine whether the user switching is installed bool MsIsUserSwitchingInstalled() { OS_INFO *info = GetOsInfo(); OSVERSIONINFOEX i; if (OS_IS_WINDOWS_NT(info->OsType) == false) { return false; } if (ms->nt->WTSDisconnectSession == NULL || ms->nt->WTSFreeMemory == NULL || ms->nt->WTSQuerySessionInformation == NULL) { return false; } if (GET_KETA(info->OsType, 100) < 2) { return false; } 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; } // Enable the remote desktop bool MsEnableRemoteDesktop() { OS_INFO *info = GetOsInfo(); if (MsIsRemoteDesktopAvailable() == false) { return false; } if (MsIsRemoteDesktopEnabled()) { return true; } if (GET_KETA(info->OsType, 100) == 2) { // Windows 2000 return false; } if (MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Terminal Server", "fDenyTSConnections", 0) == false) { return false; } if (MsIsVista()) { if (MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp", "UserAuthentication", 0) == false) { return false; } } return true; } // Examine whether the Remote Desktop is enabled bool MsIsRemoteDesktopEnabled() { OS_INFO *info = GetOsInfo(); if (MsIsRemoteDesktopAvailable() == false) { return false; } if (GET_KETA(info->OsType, 100) == 2) { // Windows 2000 return MsIsServiceRunning("TermService"); } else { // Windows XP or later bool b = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Terminal Server", "fDenyTSConnections"); if (MsIsVista() == false) { return b ? false : true; } else { if (b) { return false; } else { if (MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp", "UserAuthentication")) { return false; } else { return true; } } } } } // Examine whether the remote desktop becomes available by registry operation bool MsIsRemoteDesktopCanEnableByRegistory() { OS_INFO *info = GetOsInfo(); if (MsIsRemoteDesktopAvailable() == false) { return false; } if (GET_KETA(info->OsType, 100) == 2) { // Windows 2000 return false; } else { // Others return true; } } // Examine whether it's running on Windows 2000 bool MsIsWin2000() { OS_INFO *info = GetOsInfo(); if (OS_IS_WINDOWS_NT(info->OsType) == false) { return false; } if (GET_KETA(info->OsType, 100) == 2) { return true; } return false; } // Examine whether Windows 2000 or later bool MsIsWin2000OrGreater() { OS_INFO *info = GetOsInfo(); if (OS_IS_WINDOWS_NT(info->OsType) == false) { return false; } if (GET_KETA(info->OsType, 100) >= 2) { return true; } return false; } // Examine whether Windows XP or later bool MsIsWinXPOrGreater() { OS_INFO *info = GetOsInfo(); if (OS_IS_WINDOWS_NT(info->OsType) == false) { return false; } if (GET_KETA(info->OsType, 100) >= 3) { return true; } return false; } // Examine whether the remote desktop is available bool MsIsRemoteDesktopAvailable() { OS_INFO *info = GetOsInfo(); if (MsIsTerminalServiceInstalled() == false) { return false; } if (GET_KETA(info->OsType, 100) == 2) { // Windows 2000 if (info->OsType == 2200) { // Windows 2000 Professional return false; } else { // Windows 2000 server series return true; } } else if (GET_KETA(info->OsType, 100) == 3) { // Windows XP if (info->OsType == OSTYPE_WINDOWS_XP_HOME) { // Home Edition return false; } else { // Professional Edition return true; } } else if (GET_KETA(info->OsType, 100) == 4) { // Windows Server 2003 return true; } else if (GET_KETA(info->OsType, 100) >= 5) { // Windows Vista or later OSVERSIONINFOEX i; Zero(&i, sizeof(i)); i.dwOSVersionInfoSize = sizeof(i); if (GetVersionEx((OSVERSIONINFO *)&i) == false) { return false; } if (i.wSuiteMask & VER_SUITE_PERSONAL) { // Home series return false; } else { return true; } } return false; } // Examine whether the Terminal Services is installed bool MsIsTerminalServiceInstalled() { OS_INFO *info = GetOsInfo(); OSVERSIONINFOEX i; if (OS_IS_WINDOWS_NT(info->OsType) == false) { return false; } if (ms->nt->WTSDisconnectSession == NULL || ms->nt->WTSFreeMemory == NULL || ms->nt->WTSQuerySessionInformation == NULL) { return false; } if (GET_KETA(info->OsType, 100) < 2) { return false; } 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; } if (ms->IsNt == false) { return false; } sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (sc == NULL) { return false; } service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS); if (service != NULL) { SERVICE_STATUS st; ret = ms->nt->ControlService(service, SERVICE_CONTROL_STOP, &st); ms->nt->CloseServiceHandle(service); } if (ret) { UINT64 end = Tick64() + 10000ULL; while (Tick64() < end) { if (MsIsServiceRunning(name) == false) { break; } SleepThread(250); } } ms->nt->CloseServiceHandle(sc); 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; } if (ms->IsNt == false) { return false; } if (error_code == NULL) { error_code = &dummy; } *error_code = 0; sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (sc == NULL) { *error_code = GetLastError(); return false; } service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS); if (service != NULL) { ret = ms->nt->StartService(service, 0, NULL); ms->nt->CloseServiceHandle(service); } else { *error_code = GetLastError(); } if (ret) { UINT64 end = Tick64() + 10000ULL; while (Tick64() < end) { if (MsIsServiceRunning(name)) { break; } SleepThread(250); } } ms->nt->CloseServiceHandle(sc); 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; } if (ms->IsNt == false) { return false; } sc = ms->nt->OpenSCManager(NULL, NULL, GENERIC_READ); if (sc == NULL) { return false; } service = ms->nt->OpenService(sc, name, GENERIC_READ); if (service != NULL) { SERVICE_STATUS st; Zero(&st, sizeof(st)); if (ms->nt->QueryServiceStatus(service, &st)) { 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; } } ms->nt->CloseServiceHandle(service); } ms->nt->CloseServiceHandle(sc); return ret; } // Uninstall the service bool MsUninstallService(char *name) { SC_HANDLE sc, service; bool ret = false; // Validate arguments if (name == NULL) { return false; } if (ms->IsNt == false) { return false; } MsStopService(name); sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (sc == NULL) { return false; } service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS); if (service != NULL) { if (ms->nt->DeleteService(service)) { ret = true; } ms->nt->CloseServiceHandle(service); } ms->nt->CloseServiceHandle(sc); 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; } sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (sc == NULL) { return false; } service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS); if (service != NULL) { if (GET_KETA(GetOsInfo()->OsType, 100) >= 2) { SERVICE_DESCRIPTIONW d; if (UniIsEmptyStr(description) == false) { Zero(&d, sizeof(d)); d.lpDescription = description; ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &d); } } ms->nt->CloseServiceHandle(service); } ms->nt->CloseServiceHandle(sc); 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; } } sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (sc == NULL) { return false; } service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS); 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; ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_FAILURE_ACTIONS, &action); 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; ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &d); } } ms->nt->CloseServiceHandle(service); } ms->nt->CloseServiceHandle(sc); 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; } if (ms->IsNt == false) { return false; } if (error_code == NULL) { error_code = &temp_int; } *error_code = 0; StrToUni(name_w, sizeof(name_w), name); sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (sc == NULL) { *error_code = GetLastError(); return false; } service = ms->nt->CreateServiceW(sc, name_w, title, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, path, NULL, NULL, NULL, NULL, NULL); if (service != NULL) { ret = true; ms->nt->CloseServiceHandle(service); } else { *error_code = GetLastError(); } ms->nt->CloseServiceHandle(sc); if (ret) { SleepThread(2000); } return ret; } // Install the service bool MsInstallService(char *name, char *title, wchar_t *description, char *path) { wchar_t title_w[MAX_PATH]; wchar_t path_w[MAX_PATH]; // Validate arguments if (name == NULL || title == NULL || path == NULL) { return false; } StrToUni(title_w, sizeof(title_w), title); StrToUni(path_w, sizeof(path_w), path); return MsInstallServiceW(name, title_w, description, path_w); } 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; } if (ms->IsNt == false) { return false; } if (error_code == NULL) { error_code = &temp_int; } *error_code = 0; StrToUni(name_w, sizeof(name_w), name); sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (sc == NULL) { *error_code = GetLastError(); return false; } service = ms->nt->CreateServiceW(sc, name_w, title, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | (MsIsVista() ? 0 : SERVICE_INTERACTIVE_PROCESS), SERVICE_AUTO_START, 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; ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &d); 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; ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_FAILURE_ACTIONS, &action); Free(e); } ms->nt->CloseServiceHandle(service); } else { *error_code = GetLastError(); } ms->nt->CloseServiceHandle(sc); 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; } if (ms->IsNt == false) { return false; } sc = ms->nt->OpenSCManager(NULL, NULL, GENERIC_READ); if (sc == NULL) { return false; } service = ms->nt->OpenService(sc, name, GENERIC_READ); if (service != NULL) { ret = true; } ms->nt->CloseServiceHandle(service); ms->nt->CloseServiceHandle(sc); return ret; } // Kill the process void MsTerminateProcess() { TerminateProcess(GetCurrentProcess(), 0); _exit(0); } // Get the Process ID UINT MsGetProcessId() { return GetCurrentProcessId(); } // Get the MS structure MS *MsGetMs() { return ms; } // 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); } // Lower the priority of the thread void MsSetThreadPriorityLow() { SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_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() { if (MsIsNt() && MsIsAdmin()) { UINT type = GetOsInfo()->OsType; if (GET_KETA(type, 100) >= 2) { return true; } } return false; } // Read the TCP settings from the registry setting bool MsLoadTcpConfigReg(MS_TCP *tcp) { // Validate arguments if (tcp == NULL) { return false; } if (MsIsNt()) { Zero(tcp, sizeof(MS_TCP)); 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) { return false; } 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; } else { return false; } } // Remove the TCP settings from the registry void MsDeleteTcpConfigReg() { if (MsIsNt() && MsIsAdmin()) { 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; } if (MsIsNt() && MsIsAdmin()) { 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)); if (MsIsNt()) { UINT v; // Initialize the network setting MsInitGlobalNetworkConfig(); // 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); v = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "GlobalMaxTcpWindowSize"); tcp->RecvWindowSize = MAX(tcp->RecvWindowSize, v); v = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters", "DefaultReceiveWindow"); tcp->RecvWindowSize = MAX(tcp->RecvWindowSize, v); // Read the value of DefaultSendWindow if there is tcp->SendWindowSize = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters", "DefaultSendWindow"); } } // Write the TCP settings void MsSetTcpConfig(MS_TCP *tcp) { // Validate arguments if (tcp == NULL) { return; } if (MsIsNt() && MsIsAdmin()) { 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() { if (MsIsNt()) { UINT current_window_size; 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) { // 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"); // 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); } } else { if (MsRegReadInt(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\MSTCP", "packetix_no_optimize") == 0) { // Disable the DeadGWDetect MsRegWriteStr(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\MSTCP", "DeadGWDetect", "0"); } } MsApplyTcpConfig(); } // Process disabling other off-loading of network and others void MsDisableNetworkOffloadingEtc() { wchar_t netsh[MAX_SIZE]; UINT exec_timeout = 10000; if (MsIsNt() == false) { return; } // 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); if (MsIsVista() == false) { // Windows Server 2003 or earlier MsRegWriteIntEx2(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "EnableRSS", 1, false, true); MsRegWriteIntEx2(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "EnableTCPChimney", 1, false, true); MsRegWriteIntEx2(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "EnableTCPA", 1, false, true); Win32RunAndWaitProcess(netsh, L"netsh int ip set chimney disabled", true, true, exec_timeout); SleepThread(250); } else { // Windows Vista or later 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); } } // 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) { wchar_t infpath[MAX_PATH]; char hwid[MAX_PATH]; wchar_t hwid_w[MAX_PATH]; bool ret = false; bool need_reboot; bool before_status; UCHAR old_mac_address[6]; UCHAR new_mac_address[6]; char *s; NO_WARNING *nw; char neo_sys[MAX_PATH]; char *reg_key; UINT i; // Validate arguments if (instance_name == NULL || tag_name == NULL || connection_tag_name == NULL || ver == NULL) { return false; } if (MsIsNt() == false) { // Can not be upgraded in Windows 9x 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; } reg_key = MsGetNetCfgRegKeyName(tag_name, instance_name); if (IsEmptyStr(reg_key) == false) { // Add a value to the registry key MsRegWriteInt(REG_LOCAL_MACHINE, reg_key, "*IfType", 6); MsRegWriteInt(REG_LOCAL_MACHINE, reg_key, "*MediaType", 0); MsRegWriteInt(REG_LOCAL_MACHINE, reg_key, "*PhysicalMediaType", 0); } Free(reg_key); // Get the .sys file name that is currently being used if (MsGetNeoDeiverFilename(neo_sys, sizeof(neo_sys), instance_name) == false) { if (MsIsInfCatalogRequired()) { // Can not be upgraded if getting current .sys file name failed // in the Windows 8 or later return false; } // Create a new file name because it is unknown if (MsMakeNewNeoDriverFilename(neo_sys, sizeof(neo_sys)) == false) { // Failure return false; } } // Get the current operating status before_status = MsIsVLanEnabled(instance_name); // 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); } // Starting the installation if (MsStartDriverInstall(instance_name, IsZero(old_mac_address, 6) ? NULL : old_mac_address, neo_sys, new_mac_address, ver) == false) { return false; } MsGetDriverPath(instance_name, NULL, NULL, infpath, NULL, NULL, NULL, neo_sys); nw = NULL; //if (MsIsVista() == false) { nw = MsInitNoWarning(); } // Do the installation if (ms->nt->UpdateDriverForPlugAndPlayDevicesW( NULL, hwid_w, infpath, 1, &need_reboot)) { ret = true; } MsFreeNoWarning(nw); // 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); } SleepThread(MsIsVista() ? 1000 : 300); } SleepThread(MsIsVista() ? 1000 : 300); // Restore operation if (before_status) { MsEnableVLan(instance_name); } else { MsDisableVLan(instance_name); } return ret; } // Test for Windows 9x void MsWin9xTest() { } // Update the CompatibleIDs of virtual LAN card void MsUpdateCompatibleIDs(char *instance_name) { TOKEN_LIST *t; char id[MAX_SIZE]; char device_title[MAX_SIZE]; char device_title_old[MAX_SIZE]; // Validate arguments if (instance_name == NULL) { return; } Format(id, sizeof(id), DRIVER_DEVICE_ID_TAG, instance_name); Format(device_title, sizeof(device_title), VLAN_ADAPTER_NAME_TAG, instance_name); Format(device_title_old, sizeof(device_title_old), VLAN_ADAPTER_NAME_TAG_OLD, instance_name); t = MsRegEnumKey(REG_LOCAL_MACHINE, "Enum\\Root\\Net"); if (t != NULL) { UINT i; for (i = 0;i < t->NumTokens;i++) { char keyname[MAX_PATH]; char *str; char *title; Format(keyname, sizeof(keyname), "Enum\\Root\\Net\\%s", t->Token[i]); title = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "DeviceDesc"); if (title != NULL) { if (StrCmpi(title, device_title) == 0 || StrCmpi(title, device_title_old) == 0) { Format(keyname, sizeof(keyname), "Enum\\Root\\Net\\%s",t->Token[i]); str = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "CompatibleIDs"); if (str != NULL) { Free(str); } else { MsRegWriteStr(REG_LOCAL_MACHINE, keyname, "CompatibleIDs", id); } } Free(title); } } FreeToken(t); } MsRegWriteStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", "SourcePath", ms->System32Dir); } // Installing the virtual LAN card (for Win9x) bool MsInstallVLan9x(char *instance_name, MS_DRIVER_VER *ver) { char sysdir[MAX_PATH]; char infdir[MAX_PATH]; char otherdir[MAX_PATH]; char syspath[MAX_PATH]; char syspath2[MAX_PATH]; char infpath[MAX_PATH]; char vpn16[MAX_PATH]; char infpath_src[MAX_PATH]; char syspath_src[MAX_PATH]; char neo_sys[MAX_PATH]; // Validate arguments if (instance_name == NULL || ver == NULL) { return false; } StrCpy(sysdir, sizeof(sysdir), MsGetSystem32Dir()); Format(infdir, sizeof(infdir), "%s\\inf", MsGetWindowsDir()); Format(otherdir, sizeof(otherdir), "%s\\other", infdir); Format(syspath, sizeof(syspath), "%s\\Neo_%s.sys", sysdir, instance_name); Format(syspath2, sizeof(syspath2), "%s\\Neo_%s.sys", infdir, instance_name); Format(infpath, sizeof(infpath), "%s\\Neo_%s.inf", infdir, instance_name); Format(vpn16, sizeof(vpn16), "%s\\vpn16.exe", MsGetMyTempDir()); MakeDir(otherdir); Format(neo_sys, sizeof(neo_sys), "Neo_%s.sys", instance_name); // Copy of vpn16.exe FileCopy("|vpn16.exe", vpn16); // Starting the installation if (MsStartDriverInstall(instance_name, NULL, neo_sys, NULL, ver) == false) { return false; } MsGetDriverPathA(instance_name, NULL, NULL, infpath_src, syspath_src, NULL, NULL, neo_sys); // Copy of the inf file FileCopy(infpath_src, infpath); // Copy of the sys file FileCopy(syspath_src, syspath); // Install the device driver if (Run(vpn16, instance_name, false, true) == false) { return false; } // Update the CompatibleIDs MsUpdateCompatibleIDs(instance_name); return true; } // Child window enumeration procedure bool CALLBACK MsEnumChildWindowProc(HWND hWnd, LPARAM lParam) { 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 bool CALLBACK MsEnumThreadWindowProc(HWND hWnd, LPARAM lParam) { 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]; bool ok = false; // 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))) { ok = true; } if (MsIsWine()) { if (StrCmpi(c1, "SysIPAddress32") == 0 || StrCmpi(c2, "SysIPAddress32") == 0) { ok = true; } } if (ok) { AddWindow(o, hWnd); if (p->no_recursion == false) { EnumChildWindows(hWnd, EnumChildWindowProc, (LPARAM)p); } } return TRUE; } LIST *EnumAllWindow() { return EnumAllWindowEx(false, false); } LIST *EnumAllWindowEx(bool no_recursion, bool include_ipcontrol) { ENUM_CHILD_WINDOW_PARAM p; LIST *o = NewWindowList(); Zero(&p, sizeof(p)); p.o = o; p.no_recursion = no_recursion; p.include_ipcontrol = include_ipcontrol; EnumWindows(EnumChildWindowProc, (LPARAM)&p); return o; } 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 Vista or later bool MsIsVista() { OS_INFO *info = GetOsInfo(); if (info == NULL) { return false; } if (OS_IS_WINDOWS_NT(info->OsType)) { if (GET_KETA(info->OsType, 100) >= 5) { return true; } } return false; } // Determine whether it's Windows 7 or later bool MsIsWindows7() { OS_INFO *info = GetOsInfo(); if (info == NULL) { return false; } if (OS_IS_WINDOWS_NT(info->OsType)) { if (GET_KETA(info->OsType, 100) >= 6) { return true; } } return false; } // Determine whether it's Windows 10 or later bool MsIsWindows10() { OS_INFO *info = GetOsInfo(); if (info == NULL) { return false; } if (OS_IS_WINDOWS_NT(info->OsType)) { if (GET_KETA(info->OsType, 100) == 7) { if (GET_KETA(info->OsType, 1) >= 2) { return true; } } if (GET_KETA(info->OsType, 100) >= 8) { return true; } } return false; } // Determine whether it's Windows 8.1 or later bool MsIsWindows81() { OS_INFO *info = GetOsInfo(); if (info == NULL) { return false; } if (OS_IS_WINDOWS_NT(info->OsType)) { if (GET_KETA(info->OsType, 100) == 7) { if (GET_KETA(info->OsType, 1) >= 1) { return true; } } if (GET_KETA(info->OsType, 100) >= 8) { return true; } } return false; } // Determine whether it's Windows 8 or later bool MsIsWindows8() { OS_INFO *info = GetOsInfo(); if (info == NULL) { return false; } if (OS_IS_WINDOWS_NT(info->OsType)) { if (GET_KETA(info->OsType, 100) >= 7) { return true; } } 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; } bool MsGetWindowOwnerProcessExeNameW(wchar_t *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 (MsGetProcessExeNameW(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; } bool MsGetProcessExeNameW(wchar_t *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; UniStrCpy(path, size, proc->ExeFilenameW); } 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; if (MsIsVista() == false || nw->StartTimer == 0) { press = true; } if (nw->StartTick != 0 && nw->StartTick <= Tick64()) { press = true; } if (MsIsVista() == false) { o = NewListFast(NULL); EnumThreadWindows(thread_id, MsEnumThreadWindowProc, (LPARAM)o); } else { o = EnumAllTopWindow(); } for (i = 0;i < LIST_NUM(o);i++) { HWND hWnd; if (nw->Halt) { break; } if (MsIsVista() == false) { hWnd = LIST_DATA(o, i); } else { hWnd = *((HWND *)LIST_DATA(o, i)); } if (hWnd != NULL) { OS_INFO *info = GetOsInfo(); if (MsIsNt()) { // Get whether this window is a warning screen of driver if (MsIsVista() == false) { // Other than Windows Vista HWND hStatic, hOk, hCancel, hDetail; hStatic = GetDlgItem(hWnd, 0x14C1); hOk = GetDlgItem(hWnd, 0x14B7); hCancel = GetDlgItem(hWnd, 0x14BA); hDetail = GetDlgItem(hWnd, 0x14B9); if ((hStatic != NULL || hDetail != NULL) && hOk != NULL && hCancel != NULL) { char tmp[MAX_SIZE]; bool b = false; if (GetClassName(hStatic, tmp, sizeof(tmp)) != 0) { if (StrCmpi(tmp, "static") == 0) { b = true; } } if (GetClassName(hDetail, tmp, sizeof(tmp)) != 0) { if (StrCmpi(tmp, "button") == 0) { b = true; } } if (b) { if (GetClassName(hOk, tmp, sizeof(tmp)) != 0) { if (StrCmpi(tmp, "button") == 0) { if (GetClassName(hCancel, tmp, sizeof(tmp)) != 0) { if (StrCmpi(tmp, "button") == 0) { // Press the OK button since it was found PostMessage(hWnd, WM_COMMAND, 0x14B7, 0); ret = true; } } } } } } } else { // 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); } } } } } } } if (MsIsVista() == false) { ReleaseList(o); } else { FreeWindowList(o); } 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); interval = 50; if (MsIsVista()) { interval = 1000; } 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; // Get the current sound file name if (MsIsVista() == false) { wchar_t *tmp; // Turn off the unnecessary warning tone in Windows XP or earlier tmp = MsRegReadStrW(REG_CURRENT_USER, "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current", ""); if (UniIsEmptyStr(tmp) == false) { nw->SoundFileName = CopyUniStr(tmp); MsRegWriteStrW(REG_CURRENT_USER, "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current", "", L""); } Free(tmp); } 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); ReleaseThread(nw->NoWarningThread); ReleaseEvent(nw->HaltEvent); if (MsIsVista() == false) { if (nw->SoundFileName != NULL) { MsRegWriteStrExpandW(REG_CURRENT_USER, "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current", "", nw->SoundFileName); Free(nw->SoundFileName); } } 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; } Format(dst, size, "|DriverPackages\\%s\\%s", (MsIsWindows10() ? "Neo6_Win10" : "Neo6_Win8"), (MsIsX64() ? "x64" : "x86")); } // 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)); Format(tmp, sizeof(tmp), "%s\\Neo6_%s_%s.inf", src_dir, (MsIsX64() ? "x64" : "x86"), instance_name); 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 (MsIsNt() == false) { // For Windows 9x return MsInstallVLan9x(instance_name, ver); } 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 { 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); } } // 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 if (MsIsNt()) { MsDeleteTroubleVLAN(tag_name, instance_name); } // 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); } SleepThread(MsIsVista() ? 1000 : 300); } if (ret) { MsDisableVLan(instance_name); SleepThread(MsIsVista() ? 1000 : 300); 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) { bool need_reboot; 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))) { NO_WARNING *nw = NULL; //if (MsIsVista() == false) { nw = MsInitNoWarning(); } // Start the class installer if (SetupDiCallClassInstaller(DIF_REGISTERDEVICE, device_info, &device_info_data)) { // Do the installation if (ms->nt->UpdateDriverForPlugAndPlayDevicesW( 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; UINT status = 0, problem = 0; // Validate arguments if (info == NULL || dev_info_data == NULL) { return false; } Zero(&detail, sizeof(detail)); detail.cbSize = sizeof(detail); if (SetupDiGetDeviceInfoListDetail(info, &detail) == false || ms->nt->CM_Get_DevNode_Status_Ex(&status, &problem, dev_info_data->DevInst, 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; } ret = ms->nt->CM_Get_Device_ID_Ex(dev_info_data->DevInst, device_id, sizeof(device_id), 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; } if (MsIsNt() == false) { 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; } if (MsIsNt() == false) { 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 (MsIsNt() == false) { 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; } if (MsIsNt() == false) { return true; } 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); if (MsIsVista()) { //ReplaceStrEx(tmp, size * 2, tmp, "\"100\"", "\"2000\"", 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)); Hash(hash, hash_src, sizeof(hash_src), true); mac[0] = 0x00; mac[1] = 0xAC; mac[2] = hash[0]; mac[3] = hash[1]; mac[4] = hash[2]; mac[5] = hash[3]; } // 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 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) { wchar_t *src_filename; wchar_t *src_sys_filename; // Validate arguments if (instance_name == NULL) { return; } // WinNT x86 src_filename = L"|DriverPackages\\Neo\\x86\\Neo_x86.inf"; src_sys_filename = L"|DriverPackages\\Neo\\x86\\Neo_x86.sys"; if (MsIsNt() == false) { // Win9x src_filename = L"|DriverPackages\\Neo9x\\x86\\Neo9x_x86.inf"; src_sys_filename = L"|DriverPackages\\Neo9x\\x86\\Neo9x_x86.sys"; } else if (MsIsX64()) { // WinNT x64 src_filename = L"|DriverPackages\\Neo\\x64\\Neo_x64.inf"; src_sys_filename = L"|DriverPackages\\Neo\\x64\\Neo_x64.sys"; } if (MsIsWindows7()) { // Use the NDIS 6.2 driver for Windows 7 or later if (MsIsX64()) { src_filename = L"|DriverPackages\\Neo6\\x64\\Neo6_x64.inf"; src_sys_filename = L"|DriverPackages\\Neo6\\x64\\Neo6_x64.sys"; } else { src_filename = L"|DriverPackages\\Neo6\\x86\\Neo6_x86.inf"; src_sys_filename = L"|DriverPackages\\Neo6\\x86\\Neo6_x86.sys"; } } if (MsIsInfCatalogRequired()) { // Windows 8 or later if (MsIsX64()) { src_filename = L"|DriverPackages\\Neo6_Win8\\x64\\Neo6_x64.inf"; src_sys_filename = L"|DriverPackages\\Neo6_Win8\\x64\\Neo6_x64.sys"; } else { src_filename = L"|DriverPackages\\Neo6_Win8\\x86\\Neo6_x86.inf"; src_sys_filename = L"|DriverPackages\\Neo6_Win8\\x86\\Neo6_x86.sys"; } } if (src_inf != NULL) { if (MsIsInfCatalogRequired() == false) { // Windows 7 or before UniStrCpy(src_inf, MAX_PATH, src_filename); } else { // Windows 8.1 or later char tmp[MAX_SIZE]; MsGetInfCatalogDir(tmp, sizeof(tmp)); UniFormat(src_inf, MAX_PATH, L"%S\\Neo6_%S_%S.inf", tmp, (MsIsX64() ? "x64" : "x86"), instance_name); } } if (src_sys != NULL) { UniStrCpy(src_sys, MAX_PATH, src_sys_filename); if (MsIsWindows10()) { UniFormat(src_sys, MAX_PATH, L"|DriverPackages\\Neo6_Win10\\%S\\Neo6_%S_%S.sys", (MsIsX64() ? "x64" : "x86"), (MsIsX64() ? "x64" : "x86"), instance_name); } } if (dest_inf != NULL) { char inf_name[MAX_PATH]; 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); } 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)); 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); } } else { UniStrCpy(src_cat, MAX_PATH, L""); } } if (dest_cat != NULL) { if (MsIsInfCatalogRequired()) { 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); } } 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; } // Create a temporary file based on the extension IO *MsCreateTempFileByExt(char *ext) { char *tmp = MsCreateTempFileNameByExt(ext); IO *ret; if (tmp == NULL) { return NULL; } ret = FileCreate(tmp); Free(tmp); return ret; } // Create a temporary file with the specified extension char *MsCreateTempFileNameByExt(char *ext) { UCHAR rand[2]; char *ret = NULL; // Validate arguments if (ext == NULL) { ext = "tmp"; } if (ext[0] == '.') { ext++; } if (StrLen(ext) == 0) { ext = "tmp"; } while (true) { char new_filename[MAX_PATH]; char *fullpath; char rand_str[MAX_PATH]; IO *io; Rand(rand, sizeof(rand)); BinToStr(rand_str, sizeof(rand_str), rand, sizeof(rand)); Format(new_filename, sizeof(new_filename), "__%s.%s", rand_str, ext); fullpath = MsCreateTempFileName(new_filename); io = FileOpen(fullpath, false); if (io == NULL) { ret = fullpath; break; } FileClose(io); Free(fullpath); } return ret; } // Create a temporary file IO *MsCreateTempFile(char *name) { IO *ret; char *tmp; // Validate arguments if (name == NULL) { return NULL; } tmp = MsCreateTempFileName(name); if (tmp == NULL) { return NULL; } ret = FileCreate(tmp); Free(tmp); return ret; } // Create a temporary file name char *MsCreateTempFileName(char *name) { char tmp[MAX_PATH]; // Validate arguments if (name == NULL) { return NULL; } Format(tmp, sizeof(tmp), "%s\\%s", ms->MyTempDir, name); return CopyStr(tmp); } // 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"); if (MsIsVista() == false) { Debug("MsIsVista() == false\n"); return; } 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]; char *cm = NULL; UINT current_metric; 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; } if (MsIsNt() == false) { 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) { if (MsIsVista()) { 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 if (MsIsNt()) { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"); } else { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Class\\Net"); } 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; if (MsIsNt()) { Format(full_key_name, sizeof(full_key_name), "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s", key_name); } else { Format(full_key_name, sizeof(full_key_name), "System\\CurrentControlSet\\Services\\Class\\Net\\%s", key_name); } // 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 if (MsIsNt()) { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"); } else { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Class\\Net"); } 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; if (MsIsNt()) { Format(full_key_name, sizeof(full_key_name), "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s", key_name); } else { Format(full_key_name, sizeof(full_key_name), "System\\CurrentControlSet\\Services\\Class\\Net\\%s", key_name); } // 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 file name ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DeviceVxDs"); Free(driver_desc); break; } Free(driver_desc); } } FreeToken(key_list); return ret; } // Get the version of the device driver char *MsGetDriverVersion(char *tag_name, char *instance_name) { TOKEN_LIST *key_list; TOKEN_LIST *t; 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 if (MsIsNt()) { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"); } else { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Class\\Net"); } 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; if (MsIsNt()) { Format(full_key_name, sizeof(full_key_name), "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s", key_name); } else { Format(full_key_name, sizeof(full_key_name), "System\\CurrentControlSet\\Services\\Class\\Net\\%s", key_name); } // 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 version information ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverVersion"); if (ret == NULL) { ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "NeoVersion"); } Free(driver_desc); break; } Free(driver_desc); } } FreeToken(key_list); if (ret == NULL) { return NULL; } t = ParseToken(ret, ", "); if (t->NumTokens == 2) { Free(ret); ret = CopyStr(t->Token[1]); } FreeToken(t); return ret; } // Get the registry key of the NETCFG of the virtual LAN card char *MsGetNetCfgRegKeyName(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 if (MsIsNt()) { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"); } else { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Class\\Net"); } 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; if (MsIsNt()) { Format(full_key_name, sizeof(full_key_name), "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s", key_name); } else { Format(full_key_name, sizeof(full_key_name), "System\\CurrentControlSet\\Services\\Class\\Net\\%s", key_name); } // Read the DriverDesc driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc"); if (driver_desc != NULL) { if (StrCmpi(dest_name, driver_desc) == 0) { ret = CopyStr(full_key_name); Free(driver_desc); break; } Free(driver_desc); } } FreeToken(key_list); 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 if (MsIsNt()) { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"); } else { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Class\\Net"); } 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; if (MsIsNt()) { Format(full_key_name, sizeof(full_key_name), "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s", key_name); } else { Format(full_key_name, sizeof(full_key_name), "System\\CurrentControlSet\\Services\\Class\\Net\\%s", key_name); } // 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; } if (MsIsNt()) { root = "SYSTEM\\CurrentControlSet\\Enum\\Root\\NET"; keyname = "HardwareID"; } else { root = "Enum\\Root\\Net"; keyname = "CompatibleIDs"; } 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 if (MsIsNt()) { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"); } else { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Class\\Net"); } 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; if (MsIsNt()) { Format(full_key_name, sizeof(full_key_name), "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s", key_name); } else { Format(full_key_name, sizeof(full_key_name), "System\\CurrentControlSet\\Services\\Class\\Net\\%s", key_name); } 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 if (MsIsNt()) { ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "NetCfgInstanceId"); } else { ret = CopyStr(""); } 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]; if (MsGetNeoDeiverFilename(filename, sizeof(filename), neos->Token[i])) { Add(o, CopyStr(filename)); } } FreeToken(neos); ret = ListToTokenList(o); FreeStrList(o); return ret; } // Get the driver file name of Neo bool MsGetNeoDeiverFilename(char *name, UINT size, char *instance_name) { 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 if (MsIsNt()) { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"); } else { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Class\\Net"); } 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; if (MsIsNt()) { Format(full_key_name, sizeof(full_key_name), "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s", key_name); } else { Format(full_key_name, sizeof(full_key_name), "System\\CurrentControlSet\\Services\\Class\\Net\\%s", key_name); } // 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 if (MsIsNt()) { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"); } else { key_list = MsRegEnumKey(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Class\\Net"); } 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; if (MsIsNt()) { Format(full_key_name, sizeof(full_key_name), "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s", key_name); } else { Format(full_key_name, sizeof(full_key_name), "System\\CurrentControlSet\\Services\\Class\\Net\\%s", key_name); } // 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), driver_desc + StrLen(start_with_name_2) + 3); Add(o, CopyStr(instance_name)); } } } 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; } // Attempt to logon to the domain bool MsCheckLogon(wchar_t *username, char *password) { wchar_t password_unicode[MAX_SIZE]; HANDLE h; // Validate arguments if (username == NULL || password == NULL) { return false; } if (MsIsNt() == false) { return false; } StrToUni(password_unicode, sizeof(password_unicode), password); if (GET_KETA(GetOsInfo()->OsType, 100) >= 2) { if (ms->nt->LogonUserW(username, NULL, password_unicode, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false) { // Logon failure return false; } } else { char username_ansi[MAX_SIZE]; UniToStr(username_ansi, sizeof(username_ansi), username); if (ms->nt->LogonUserA(username_ansi, NULL, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false) { // Logon failure return false; } } CloseHandle(h); return true; } // Attempt to logon to the domain bool MsIsPasswordEmpty(wchar_t *username) { HANDLE h; // Validate arguments if (username == NULL) { return false; } if (MsIsNt() == false) { return false; } if (GET_KETA(GetOsInfo()->OsType, 100) >= 2) { if (ms->nt->LogonUserW(username, NULL, L"", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false) { // Logon failure if (GetLastError() == 1327) { // Password is empty return true; } else { // The password is not correct return false; } } } else { char username_ansi[MAX_SIZE]; UniToStr(username_ansi, sizeof(username_ansi), username); if (ms->nt->LogonUserA(username_ansi, NULL, "", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false) { // Logon failure if (GetLastError() == 1327) { // Password is empty return true; } else { // The password is not correct return false; } } } CloseHandle(h); // Since successful logon, the password should be empty return false; } // Determine if the workstation is locked by using WTS API bool MsDetermineIsLockedByWtsApi() { return wts_is_locked_flag; } // IsLocked Window Proc LRESULT CALLBACK MsIsLockedWindowHandlerWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { MS_ISLOCKED *d = NULL; CREATESTRUCT *cs; // Validate arguments if (hWnd == NULL) { return 0; } d = (MS_ISLOCKED *)GetWindowLongPtrA(hWnd, GWLP_USERDATA); if (d == NULL && msg != WM_CREATE) { goto LABEL_END; } switch (msg) { case WM_CREATE: cs = (CREATESTRUCT *)lParam; d = (MS_ISLOCKED *)cs->lpCreateParams; SetWindowLongPtrA(hWnd, GWLP_USERDATA, (LONG_PTR)d); ms->nt->WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_THIS_SESSION); wts_is_locked_flag = false; break; case WM_WTSSESSION_CHANGE: { char tmp[MAX_SIZE]; GetDateTimeStr64(tmp, sizeof(tmp), LocalTime64()); switch (wParam) { case WTS_SESSION_LOCK: Debug("%s: Enter Lock\n", tmp); d->IsLockedFlag = true; wts_is_locked_flag = true; break; case WTS_SESSION_UNLOCK: Debug("%s: Enter Unlock\n", tmp); d->IsLockedFlag = false; wts_is_locked_flag = false; break; } } break; case WM_DESTROY: Debug("Unregister\n"); ms->nt->WTSUnRegisterSessionNotification(hWnd); PostQuitMessage(0); break; } LABEL_END: return DefWindowProc(hWnd, msg, wParam, lParam); } // IsLocked thread proc void MsIsLockedThreadProc(THREAD *thread, void *param) { MS_ISLOCKED *d = (MS_ISLOCKED *)param; char wndclass_name[MAX_PATH]; WNDCLASS wc; HWND hWnd; MSG msg; // Validate arguments if (d == 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 = MsIsLockedWindowHandlerWindowProc; 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, d); d->hWnd = hWnd; NoticeThreadInit(thread); if (hWnd == NULL) { UnregisterClassA(wndclass_name, ms->hInst); return; } while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } DestroyWindow(hWnd); UnregisterClassA(wndclass_name, ms->hInst); } // Create new IsLocked thread MS_ISLOCKED *MsNewIsLocked() { MS_ISLOCKED *d; THREAD *t; SleepThread(5000); if (IsNt() == false || ms->nt->WTSRegisterSessionNotification == NULL || ms->nt->WTSUnRegisterSessionNotification == NULL) { return NULL; } d = ZeroMalloc(sizeof(MS_ISLOCKED)); t = NewThread(MsIsLockedThreadProc, d); WaitThreadInit(t); d->Thread = t; return d; } // Stop and free the IsLocked thread void MsFreeIsLocked(MS_ISLOCKED *d) { if (d == NULL) { return; } if (d->hWnd != NULL) { PostMessageA(d->hWnd, WM_CLOSE, 0, 0); } WaitThread(d->Thread, INFINITE); ReleaseThread(d->Thread); Free(d); } // Execution of shutdown (NT) bool MsShutdownEx(bool reboot, bool force, UINT time_limit, char *message) { if (MsIsNt() == false) { return MsShutdown(reboot, force); } // Get the privilege if (MsEnablePrivilege(SE_SHUTDOWN_NAME, true) == false) { return false; } // Execute the shutdown if (ms->nt->InitiateSystemShutdown(NULL, message, time_limit, force, reboot) == false) { MsEnablePrivilege(SE_SHUTDOWN_NAME, false); return false; } // Release of privilege MsEnablePrivilege(SE_SHUTDOWN_NAME, false); 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; NT_API *nt = ms->nt; LUID luid; TOKEN_PRIVILEGES *tp; bool ret; // Validate arguments if (name == NULL) { return false; } if (MsIsNt() == false) { return true; } // Open the process token if (nt->OpenProcessToken(ms->hCurrentProcess, TOKEN_ADJUST_PRIVILEGES, &hToken) == false) { return false; } // Get a local unique identifier if (nt->LookupPrivilegeValue(NULL, name, &luid) == FALSE) { 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 ret = nt->AdjustTokenPrivileges(hToken, false, tp, sizeof(TOKEN_PRIVILEGES), 0, 0); Free(tp); CloseHandle(hToken); return ret; } // Get whether the current OS is a NT system bool MsIsNt() { if (ms == NULL) { OSVERSIONINFO os; Zero(&os, sizeof(os)); os.dwOSVersionInfoSize = sizeof(os); GetVersionEx(&os); if (os.dwPlatformId == VER_PLATFORM_WIN32_NT) { return true; } else { return false; } } return ms->IsNt; } // 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; } // Get whether the current user is an Admin bool MsIsAdmin() { return ms->IsAdmin; } // Load the NT system function NT_API *MsLoadNtApiFunctions() { NT_API *nt = ZeroMalloc(sizeof(NT_API)); OSVERSIONINFO info; Zero(&info, sizeof(info)); info.dwOSVersionInfoSize = sizeof(info); GetVersionEx(&info); nt->hKernel32 = LoadLibrary("kernel32.dll"); if (nt->hKernel32 == NULL) { Free(nt); return NULL; } nt->hAdvapi32 = LoadLibrary("advapi32.dll"); if (nt->hAdvapi32 == NULL) { Free(nt); return NULL; } nt->hShell32 = LoadLibrary("shell32.dll"); if (nt->hShell32 == NULL) { FreeLibrary(nt->hAdvapi32); Free(nt); return NULL; } nt->hPsApi = LoadLibrary("psapi.dll"); if (info.dwMajorVersion >= 5) { nt->hNewDev = LoadLibrary("newdev.dll"); if (nt->hNewDev == NULL) { FreeLibrary(nt->hShell32); FreeLibrary(nt->hAdvapi32); Free(nt); return NULL; } nt->hSetupApi = LoadLibrary("setupapi.dll"); } nt->hSecur32 = LoadLibrary("secur32.dll"); nt->hUser32 = LoadLibrary("user32.dll"); nt->hDbgHelp = LoadLibrary("dbghelp.dll"); nt->hWcmapi = LoadLibrary("wcmapi.dll"); nt->hDwmapi = LoadLibrary("dwmapi.dll"); // Read the function nt->GetComputerNameExW = (BOOL (__stdcall *)(COMPUTER_NAME_FORMAT,LPWSTR,LPDWORD)) GetProcAddress(nt->hKernel32, "GetComputerNameExW"); nt->IsWow64Process = (BOOL (__stdcall *)(HANDLE,BOOL *)) GetProcAddress(nt->hKernel32, "IsWow64Process"); nt->GetFileInformationByHandle = (BOOL (__stdcall *)(HANDLE,LPBY_HANDLE_FILE_INFORMATION)) GetProcAddress(nt->hKernel32, "GetFileInformationByHandle"); nt->GetProcessHeap = (HANDLE (__stdcall *)()) GetProcAddress(nt->hKernel32, "GetProcessHeap"); nt->SetProcessShutdownParameters = (BOOL (__stdcall *)(DWORD,DWORD)) GetProcAddress(nt->hKernel32, "SetProcessShutdownParameters"); nt->GetNativeSystemInfo = (void (__stdcall *)(SYSTEM_INFO *)) GetProcAddress(nt->hKernel32, "GetNativeSystemInfo"); nt->AdjustTokenPrivileges = (BOOL (__stdcall *)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD)) GetProcAddress(nt->hAdvapi32, "AdjustTokenPrivileges"); nt->LookupPrivilegeValue = (BOOL (__stdcall *)(char *,char *,PLUID)) GetProcAddress(nt->hAdvapi32, "LookupPrivilegeValueA"); nt->OpenProcessToken = (BOOL (__stdcall *)(HANDLE,DWORD,PHANDLE)) GetProcAddress(nt->hAdvapi32, "OpenProcessToken"); nt->InitiateSystemShutdown = (BOOL (__stdcall *)(LPTSTR,LPTSTR,DWORD,BOOL,BOOL)) GetProcAddress(nt->hAdvapi32, "InitiateSystemShutdownA"); nt->LogonUserW = (BOOL (__stdcall *)(wchar_t *,wchar_t *,wchar_t *,DWORD,DWORD,HANDLE *)) GetProcAddress(nt->hAdvapi32, "LogonUserW"); nt->LogonUserA = (BOOL (__stdcall *)(char *,char *,char *,DWORD,DWORD,HANDLE * )) GetProcAddress(nt->hAdvapi32, "LogonUserA"); nt->DuplicateTokenEx = (BOOL (__stdcall *)(HANDLE,DWORD,SECURITY_ATTRIBUTES *,SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,HANDLE *)) GetProcAddress(nt->hAdvapi32, "DuplicateTokenEx"); nt->ConvertStringSidToSidA = (BOOL (__stdcall *)(LPCSTR,PSID *)) GetProcAddress(nt->hAdvapi32, "ConvertStringSidToSidA"); nt->GetTokenInformation = (BOOL (__stdcall *)(HANDLE,TOKEN_INFORMATION_CLASS,void *,DWORD,PDWORD)) GetProcAddress(nt->hAdvapi32, "GetTokenInformation"); nt->SetTokenInformation = (BOOL (__stdcall *)(HANDLE,TOKEN_INFORMATION_CLASS,void *,DWORD)) GetProcAddress(nt->hAdvapi32, "SetTokenInformation"); nt->CreateProcessAsUserA = (BOOL (__stdcall *)(HANDLE,LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,void *,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION)) GetProcAddress(nt->hAdvapi32, "CreateProcessAsUserA"); nt->CreateProcessAsUserW = (BOOL (__stdcall *)(HANDLE,LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,void *,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION)) GetProcAddress(nt->hAdvapi32, "CreateProcessAsUserW"); nt->LookupAccountSidA = (BOOL (__stdcall *)(LPCSTR,PSID,LPSTR,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE)) GetProcAddress(nt->hAdvapi32, "LookupAccountSidA"); nt->LookupAccountNameA = (BOOL (__stdcall *)(LPCSTR,LPCSTR,PSID,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE)) GetProcAddress(nt->hAdvapi32, "LookupAccountNameA"); nt->SetNamedSecurityInfoW = (DWORD (__stdcall *)(LPWSTR,UINT,SECURITY_INFORMATION,PSID,PSID,PACL,PACL)) GetProcAddress(nt->hAdvapi32, "SetNamedSecurityInfoW"); nt->AddAccessAllowedAceEx = (BOOL (__stdcall *)(PACL,DWORD,DWORD,DWORD,PSID)) GetProcAddress(nt->hAdvapi32, "AddAccessAllowedAceEx"); nt->QueryFullProcessImageNameA = (BOOL (__stdcall *)(HANDLE,DWORD,LPSTR,PDWORD)) GetProcAddress(nt->hKernel32, "QueryFullProcessImageNameA"); nt->QueryFullProcessImageNameW = (BOOL (__stdcall *)(HANDLE,DWORD,LPWSTR,PDWORD)) GetProcAddress(nt->hKernel32, "QueryFullProcessImageNameW"); nt->RegLoadKeyW = (LSTATUS (__stdcall *)(HKEY,LPCWSTR,LPCWSTR)) GetProcAddress(nt->hAdvapi32, "RegLoadKeyW"); nt->RegUnLoadKeyW = (LSTATUS (__stdcall *)(HKEY,LPCWSTR)) GetProcAddress(nt->hAdvapi32, "RegUnLoadKeyW"); if (info.dwMajorVersion >= 5) { nt->UpdateDriverForPlugAndPlayDevicesW = (BOOL (__stdcall *)(HWND,wchar_t *,wchar_t *,UINT,BOOL *)) GetProcAddress(nt->hNewDev, "UpdateDriverForPlugAndPlayDevicesW"); nt->CM_Get_Device_ID_ExA = (UINT (__stdcall *)(DWORD,char *,UINT,UINT,HANDLE)) GetProcAddress(nt->hSetupApi, "CM_Get_Device_ID_ExA"); nt->CM_Get_DevNode_Status_Ex = (UINT (__stdcall *)(UINT *,UINT *,DWORD,UINT,HANDLE)) GetProcAddress(nt->hSetupApi, "CM_Get_DevNode_Status_Ex"); } nt->hWtsApi32 = LoadLibrary("wtsapi32.dll"); if (nt->hWtsApi32 != NULL) { // Terminal Services related API nt->WTSQuerySessionInformation = (UINT (__stdcall *)(HANDLE,DWORD,WTS_INFO_CLASS,wchar_t *,DWORD *)) GetProcAddress(nt->hWtsApi32, "WTSQuerySessionInformationW"); nt->WTSFreeMemory = (void (__stdcall *)(void *)) GetProcAddress(nt->hWtsApi32, "WTSFreeMemory"); nt->WTSDisconnectSession = (BOOL (__stdcall *)(HANDLE,DWORD,BOOL)) GetProcAddress(nt->hWtsApi32, "WTSDisconnectSession"); nt->WTSEnumerateSessionsA = (BOOL (__stdcall *)(HANDLE,DWORD,DWORD,PWTS_SESSION_INFOA *,DWORD *)) GetProcAddress(nt->hWtsApi32, "WTSEnumerateSessionsA"); nt->WTSRegisterSessionNotification = (BOOL (__stdcall *)(HWND,DWORD)) GetProcAddress(nt->hWtsApi32, "WTSRegisterSessionNotification"); nt->WTSUnRegisterSessionNotification = (BOOL (__stdcall *)(HWND)) GetProcAddress(nt->hWtsApi32, "WTSUnRegisterSessionNotification"); } // Service related API nt->OpenSCManager = (SC_HANDLE (__stdcall *)(LPCTSTR,LPCTSTR,DWORD)) GetProcAddress(nt->hAdvapi32, "OpenSCManagerA"); nt->CreateServiceA = (SC_HANDLE (__stdcall *)(SC_HANDLE,LPCTSTR,LPCTSTR,DWORD,DWORD,DWORD,DWORD,LPCTSTR,LPCTSTR,LPDWORD,LPCTSTR,LPCTSTR,LPCTSTR)) GetProcAddress(nt->hAdvapi32, "CreateServiceA"); nt->CreateServiceW = (SC_HANDLE (__stdcall *)(SC_HANDLE,LPCWSTR,LPCWSTR,DWORD,DWORD,DWORD,DWORD,LPCWSTR,LPCWSTR,LPDWORD,LPCWSTR,LPCWSTR,LPCWSTR)) GetProcAddress(nt->hAdvapi32, "CreateServiceW"); nt->ChangeServiceConfig2 = (BOOL (__stdcall *)(SC_HANDLE,DWORD,LPVOID)) GetProcAddress(nt->hAdvapi32, "ChangeServiceConfig2W"); nt->CloseServiceHandle = (BOOL (__stdcall *)(SC_HANDLE)) GetProcAddress(nt->hAdvapi32, "CloseServiceHandle"); nt->OpenService = (SC_HANDLE (__stdcall *)(SC_HANDLE,LPCTSTR,DWORD)) GetProcAddress(nt->hAdvapi32, "OpenServiceA"); nt->QueryServiceStatus = (BOOL (__stdcall *)(SC_HANDLE,LPSERVICE_STATUS)) GetProcAddress(nt->hAdvapi32, "QueryServiceStatus"); nt->StartService = (BOOL (__stdcall *)(SC_HANDLE,DWORD,LPCTSTR)) GetProcAddress(nt->hAdvapi32, "StartServiceA"); nt->ControlService = (BOOL (__stdcall *)(SC_HANDLE,DWORD,LPSERVICE_STATUS)) GetProcAddress(nt->hAdvapi32, "ControlService"); nt->SetServiceStatus = (BOOL (__stdcall *)(SERVICE_STATUS_HANDLE,LPSERVICE_STATUS)) GetProcAddress(nt->hAdvapi32, "SetServiceStatus"); nt->RegisterServiceCtrlHandler = (SERVICE_STATUS_HANDLE (__stdcall *)(LPCTSTR,LPHANDLER_FUNCTION)) GetProcAddress(nt->hAdvapi32, "RegisterServiceCtrlHandlerW"); nt->StartServiceCtrlDispatcher = (BOOL (__stdcall *)(const LPSERVICE_TABLE_ENTRY)) GetProcAddress(nt->hAdvapi32, "StartServiceCtrlDispatcherW"); nt->DeleteService = (BOOL (__stdcall *)(SC_HANDLE)) GetProcAddress(nt->hAdvapi32, "DeleteService"); nt->RegisterEventSourceW = (HANDLE (__stdcall *)(LPCWSTR,LPCWSTR)) GetProcAddress(nt->hAdvapi32, "RegisterEventSourceW"); nt->ReportEventW = (BOOL (__stdcall *)(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCWSTR *,LPVOID)) GetProcAddress(nt->hAdvapi32, "ReportEventW"); nt->DeregisterEventSource = (BOOL (__stdcall *)(HANDLE)) GetProcAddress(nt->hAdvapi32, "DeregisterEventSource"); nt->Wow64DisableWow64FsRedirection = (BOOL (__stdcall *)(void **)) GetProcAddress(nt->hKernel32, "Wow64DisableWow64FsRedirection"); nt->Wow64EnableWow64FsRedirection = (BOOLEAN (__stdcall *)(BOOLEAN)) GetProcAddress(nt->hKernel32, "Wow64EnableWow64FsRedirection"); nt->Wow64RevertWow64FsRedirection = (BOOL (__stdcall *)(void *)) GetProcAddress(nt->hKernel32, "Wow64RevertWow64FsRedirection"); if (nt->hPsApi != NULL) { // Process related API nt->EnumProcesses = (BOOL (__stdcall *)(DWORD *,DWORD,DWORD *)) GetProcAddress(nt->hPsApi, "EnumProcesses"); nt->EnumProcessModules = (BOOL (__stdcall *)(HANDLE,HMODULE * ,DWORD,DWORD *)) GetProcAddress(nt->hPsApi, "EnumProcessModules"); nt->GetModuleFileNameExA = (DWORD (__stdcall *)(HANDLE,HMODULE,LPSTR,DWORD)) GetProcAddress(nt->hPsApi, "GetModuleFileNameExA"); nt->GetModuleFileNameExW = (DWORD (__stdcall *)(HANDLE,HMODULE,LPWSTR,DWORD)) GetProcAddress(nt->hPsApi, "GetModuleFileNameExW"); nt->GetProcessImageFileNameA = (DWORD (__stdcall *)(HANDLE,LPSTR,DWORD)) GetProcAddress(nt->hPsApi, "GetProcessImageFileNameA"); nt->GetProcessImageFileNameW = (DWORD (__stdcall *)(HANDLE,LPWSTR,DWORD)) GetProcAddress(nt->hPsApi, "GetProcessImageFileNameW"); } // Registry related API nt->RegDeleteKeyExA = (LONG (__stdcall *)(HKEY,LPCTSTR,REGSAM,DWORD)) GetProcAddress(nt->hAdvapi32, "RegDeleteKeyExA"); // Security related API if (nt->hSecur32 != NULL) { nt->GetUserNameExA = (BOOL (__stdcall *)(EXTENDED_NAME_FORMAT,LPSTR,PULONG)) GetProcAddress(nt->hSecur32, "GetUserNameExA"); nt->GetUserNameExW = (BOOL (__stdcall *)(EXTENDED_NAME_FORMAT,LPWSTR,PULONG)) GetProcAddress(nt->hSecur32, "GetUserNameExW"); nt->LsaConnectUntrusted = (NTSTATUS (__stdcall *)(PHANDLE)) GetProcAddress(nt->hSecur32, "LsaConnectUntrusted"); nt->LsaLookupAuthenticationPackage = (NTSTATUS (__stdcall *)(HANDLE,PLSA_STRING,PULONG)) GetProcAddress(nt->hSecur32, "LsaLookupAuthenticationPackage"); nt->LsaLogonUser = (NTSTATUS (__stdcall *)(HANDLE,PLSA_STRING,SECURITY_LOGON_TYPE,ULONG,PVOID,ULONG,PTOKEN_GROUPS,PTOKEN_SOURCE,PVOID,PULONG,PLUID,PHANDLE,PQUOTA_LIMITS,PNTSTATUS)) GetProcAddress(nt->hSecur32, "LsaLogonUser"); nt->LsaDeregisterLogonProcess = (NTSTATUS (__stdcall *)(HANDLE)) GetProcAddress(nt->hSecur32, "LsaDeregisterLogonProcess"); nt->LsaFreeReturnBuffer = (NTSTATUS (__stdcall *)(PVOID)) GetProcAddress(nt->hSecur32, "LsaFreeReturnBuffer"); } // WCM related API of Windows 8 if (nt->hWcmapi != NULL) { nt->WcmQueryProperty = (DWORD (__stdcall *)(const GUID *,LPCWSTR,MS_WCM_PROPERTY,PVOID,PDWORD,PBYTE *)) GetProcAddress(nt->hWcmapi, "WcmQueryProperty"); nt->WcmSetProperty = (DWORD (__stdcall *)(const GUID *,LPCWSTR,MS_WCM_PROPERTY,PVOID,DWORD,const BYTE *)) GetProcAddress(nt->hWcmapi, "WcmSetProperty"); nt->WcmFreeMemory = (void (__stdcall *)(PVOID)) GetProcAddress(nt->hWcmapi, "WcmFreeMemory"); nt->WcmGetProfileList = (DWORD (__stdcall *)(PVOID,MS_WCM_PROFILE_INFO_LIST **)) GetProcAddress(nt->hWcmapi, "WcmGetProfileList"); } nt->AllocateLocallyUniqueId = (BOOL (__stdcall *)(PLUID)) GetProcAddress(nt->hAdvapi32, "AllocateLocallyUniqueId"); // Desktop related API if (nt->hUser32 != NULL) { nt->SwitchDesktop = (BOOL (__stdcall *)(HDESK)) GetProcAddress(nt->hUser32, "SwitchDesktop"); nt->OpenDesktopA = (HDESK (__stdcall *)(LPTSTR,DWORD,BOOL,ACCESS_MASK)) GetProcAddress(nt->hUser32, "OpenDesktopA"); nt->CloseDesktop = (BOOL (__stdcall *)(HDESK)) GetProcAddress(nt->hUser32, "CloseDesktop"); } // DWM API if (nt->hDwmapi) { nt->DwmIsCompositionEnabled = (HRESULT (__stdcall *)(BOOL *)) GetProcAddress(nt->hDwmapi, "DwmIsCompositionEnabled"); } // Debug related API if (nt->hDbgHelp != NULL) { nt->MiniDumpWriteDump = (BOOL (__stdcall *)(HANDLE,DWORD,HANDLE,MINIDUMP_TYPE,PMINIDUMP_EXCEPTION_INFORMATION,PMINIDUMP_USER_STREAM_INFORMATION,PMINIDUMP_CALLBACK_INFORMATION)) GetProcAddress(nt->hDbgHelp, "MiniDumpWriteDump"); } return nt; } // Release of NT system function void MsFreeNtApiFunctions(NT_API *nt) { // Validate arguments if (nt == NULL) { return; } if (nt->hSecur32 != NULL) { FreeLibrary(nt->hSecur32); } if (nt->hNewDev != NULL) { FreeLibrary(nt->hSetupApi); FreeLibrary(nt->hNewDev); } FreeLibrary(nt->hAdvapi32); FreeLibrary(nt->hShell32); if (nt->hWtsApi32 != NULL) { FreeLibrary(nt->hWtsApi32); } if (nt->hPsApi != NULL) { FreeLibrary(nt->hPsApi); } if (nt->hUser32 != NULL) { FreeLibrary(nt->hUser32); } if (nt->hDbgHelp != NULL) { FreeLibrary(nt->hDbgHelp); } if (nt->hWcmapi != NULL) { FreeLibrary(nt->hWcmapi); } if (nt->hDwmapi != NULL) { FreeLibrary(nt->hDwmapi); } FreeLibrary(nt->hKernel32); Free(nt); } // Get whether the screen color is like to Aero of Windows Vista or later bool MsIsAeroColor() { UINT r; if (MsIsNt() == false) { return false; } if (MsIsVista() == false) { return false; } r = GetSysColor(COLOR_MENU); if (r == 0xFFFFFF || r == 0xF0F0F0 || r >= 0xF00000) { return true; } if (MsIsAeroEnabled()) { return true; } return false; } // Get whether Aero is enabled bool MsIsAeroEnabled() { bool ret; if (MsIsNt() == false) { return false; } if (ms->nt->DwmIsCompositionEnabled == NULL) { return false; } ret = false; if (ms->nt->DwmIsCompositionEnabled(&ret) != S_OK) { return false; } return ret; } // Generate an access mask to force accessing to the 32 bit registry key for 64 bit application DWORD MsRegAccessMaskFor64Bit(bool force32bit) { return MsRegAccessMaskFor64BitEx(force32bit, false); } DWORD MsRegAccessMaskFor64BitEx(bool force32bit, bool force64bit) { if (MsIs64BitWindows() == false) { return 0; } if (force32bit) { return KEY_WOW64_32KEY; } if (force64bit) { return KEY_WOW64_64KEY; } return 0; } // Load the hive bool MsRegLoadHive(UINT root, wchar_t *keyname, wchar_t *filename) { LONG ret; if (keyname == NULL || filename == NULL) { WHERE; return false; } if (ms->nt == NULL || ms->nt->RegLoadKeyW == NULL || ms->nt->RegUnLoadKeyW == NULL) { WHERE; return false; } ret = ms->nt->RegLoadKeyW(MsGetRootKeyFromInt(root), keyname, filename); 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; } if (ms->nt == NULL || ms->nt->RegLoadKeyW == NULL || ms->nt->RegUnLoadKeyW == NULL) { return false; } ret = ms->nt->RegUnLoadKeyW(MsGetRootKeyFromInt(root), keyname); if (ret != ERROR_SUCCESS) { Debug("RegUnLoadKeyW: %u\n", GetLastError()); return false; } return true; } // 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; } if (MsIsNt() && ms->nt->RegDeleteKeyExA != NULL) { if (ms->nt->RegDeleteKeyExA(MsGetRootKeyFromInt(root), keyname, MsRegAccessMaskFor64BitEx(force32bit, force64bit), 0) != ERROR_SUCCESS) { return false; } } else { if (RegDeleteKey(MsGetRootKeyFromInt(root), keyname) != ERROR_SUCCESS) { return false; } } 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; UINT size = sizeof(tmp); 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; UINT size = sizeof(tmp); 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 MsRegWriteValue(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size) { return MsRegWriteValueEx(root, keyname, valuename, type, data, size, false); } bool MsRegWriteValueEx(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit) { return MsRegWriteValueEx2(root, keyname, valuename, type, data, size, force32bit, false); } 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 MsRegWriteValueW(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size) { return MsRegWriteValueExW(root, keyname, valuename, type, data, size, false); } bool MsRegWriteValueExW(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit) { return MsRegWriteValueEx2W(root, keyname, valuename, type, data, size, force32bit, false); } 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; UINT type, size; BUF *b; // Validate arguments if (keyname == NULL || valuename == NULL) { return 0; } // Read the value if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false) { 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; UINT type, size; UINT value; // Validate arguments if (keyname == NULL || valuename == NULL) { return 0; } // Read the value if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false) { 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; UINT type, size; // Validate arguments if (keyname == NULL || valuename == NULL) { return NULL; } // Read the value if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false) { 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; UINT type, size; // Validate arguments if (keyname == NULL || valuename == NULL) { return NULL; } // Read the value if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false) { 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; UINT type, size; // Validate arguments if (keyname == NULL || valuename == NULL) { return NULL; } // Read the value if (MsRegReadValueEx2W(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false) { 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 bool MsRegReadValue(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size) { return MsRegReadValueEx(root, keyname, valuename, data, type, size, false); } bool MsRegReadValueEx(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit) { return MsRegReadValueEx2(root, keyname, valuename, data, type, size, force32bit, false); } bool MsRegReadValueEx2(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit, bool force64bit) { 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; } bool MsRegReadValueW(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size) { return MsRegReadValueExW(root, keyname, valuename, data, type, size, false); } bool MsRegReadValueExW(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit) { return MsRegReadValueEx2W(root, keyname, valuename, data, type, size, force32bit, false); } bool MsRegReadValueEx2W(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit, bool force64bit) { 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; UINT type_a = 0, size_a = 0; 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; } // Get the size and type of value bool MsRegGetValueTypeAndSize(UINT root, char *keyname, char *valuename, UINT *type, UINT *size) { return MsRegGetValueTypeAndSizeEx(root, keyname, valuename, type, size, false); } bool MsRegGetValueTypeAndSizeEx(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit) { return MsRegGetValueTypeAndSizeEx2(root, keyname, valuename, type, size, force32bit, false); } bool MsRegGetValueTypeAndSizeEx2(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit, bool force64bit) { HKEY h; UINT ret; // Validate arguments if (keyname == NULL) { return false; } if (type != NULL) { *type = 0; } if (size != NULL) { *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 ret = RegQueryValueEx(h, valuename, 0, type, NULL, size); if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) { RegCloseKey(h); return true; } RegCloseKey(h); return false; } bool MsRegGetValueTypeAndSizeW(UINT root, char *keyname, char *valuename, UINT *type, UINT *size) { return MsRegGetValueTypeAndSizeExW(root, keyname, valuename, type, size, false); } bool MsRegGetValueTypeAndSizeExW(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit) { return MsRegGetValueTypeAndSizeEx2W(root, keyname, valuename, type, size, force32bit, false); } bool MsRegGetValueTypeAndSizeEx2W(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit, bool force64bit) { HKEY h; UINT ret; wchar_t *valuename_w; // Validate arguments if (keyname == NULL) { return false; } if (type != NULL) { *type = 0; } if (size != NULL) { *size = 0; } if (IsNt() == false) { UINT type_a = 0; UINT size_a = 0; bool ret = MsRegGetValueTypeAndSizeEx2(root, keyname, valuename, &type_a, &size_a, force32bit, force64bit); if (type_a == REG_SZ || type_a == REG_MULTI_SZ || type_a == REG_EXPAND_SZ) { size_a = size_a * sizeof(wchar_t); } if (type != NULL) { *type = type_a; } if (size != NULL) { *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 ret = RegQueryValueExW(h, valuename_w, 0, type, NULL, size); Free(valuename_w); if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) { RegCloseKey(h); return true; } RegCloseKey(h); return false; } // 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; UINT type, size; 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 MsRegNewKey(UINT root, char *keyname) { return MsRegNewKeyEx(root, keyname, false); } bool MsRegNewKeyEx(UINT root, char *keyname, bool force32bit) { return MsRegNewKeyEx2(root, keyname, force32bit, false); } 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); } if (MsIsNt()) { // Common start menu ms->CommonStartMenuDir = MsGetSpecialDir(CSIDL_COMMON_STARTMENU); ms->CommonStartMenuDirW = MsGetSpecialDirW(CSIDL_COMMON_STARTMENU); // Common program ms->CommonProgramsDir = MsGetSpecialDir(CSIDL_COMMON_PROGRAMS); ms->CommonProgramsDirW = MsGetSpecialDirW(CSIDL_COMMON_PROGRAMS); // Common startup ms->CommonStartupDir = MsGetSpecialDir(CSIDL_COMMON_STARTUP); ms->CommonStartupDirW = MsGetSpecialDirW(CSIDL_COMMON_STARTUP); // Common application data ms->CommonAppDataDir = MsGetSpecialDir(CSIDL_COMMON_APPDATA); ms->CommonAppDataDirW = MsGetSpecialDirW(CSIDL_COMMON_APPDATA); // Common desktop ms->CommonDesktopDir = MsGetSpecialDir(CSIDL_COMMON_DESKTOPDIRECTORY); ms->CommonDesktopDirW = MsGetSpecialDirW(CSIDL_COMMON_DESKTOPDIRECTORY); // Local Settings ms->LocalAppDataDir = MsGetSpecialDir(CSIDL_LOCAL_APPDATA); ms->LocalAppDataDirW = MsGetSpecialDirW(CSIDL_LOCAL_APPDATA); } else { // Start menu of the individual ms->PersonalStartMenuDir = MsGetSpecialDir(CSIDL_STARTMENU); ms->CommonStartMenuDir = CopyStr(ms->PersonalStartMenuDir); ms->PersonalStartMenuDirW = MsGetSpecialDirW(CSIDL_STARTMENU); ms->CommonStartMenuDirW = CopyUniStr(ms->PersonalStartMenuDirW); // Program of the individual ms->PersonalProgramsDir = MsGetSpecialDir(CSIDL_PROGRAMS); ms->CommonProgramsDir = CopyStr(ms->PersonalProgramsDir); ms->PersonalProgramsDirW = MsGetSpecialDirW(CSIDL_PROGRAMS); ms->CommonProgramsDirW = CopyUniStr(ms->PersonalProgramsDirW); // Start-up of the individual ms->PersonalStartupDir = MsGetSpecialDir(CSIDL_STARTUP); ms->CommonStartupDir = CopyStr(ms->PersonalStartupDir); ms->PersonalStartupDirW = MsGetSpecialDirW(CSIDL_STARTUP); ms->CommonStartupDirW = CopyUniStr(ms->PersonalStartupDirW); // Application data of the individual ms->PersonalAppDataDir = MsGetSpecialDir(CSIDL_APPDATA); ms->CommonAppDataDir = CopyStr(ms->PersonalAppDataDir); ms->PersonalAppDataDirW = MsGetSpecialDirW(CSIDL_APPDATA); ms->CommonAppDataDirW = CopyUniStr(ms->PersonalAppDataDirW); // Desktops of the individual ms->PersonalDesktopDir = MsGetSpecialDir(CSIDL_DESKTOP); ms->CommonDesktopDir = CopyStr(ms->PersonalDesktopDir); ms->PersonalDesktopDirW = MsGetSpecialDirW(CSIDL_DESKTOP); ms->CommonDesktopDirW = CopyUniStr(ms->PersonalDesktopDirW); // Local Settings ms->LocalAppDataDir = CopyStr(ms->PersonalAppDataDir); ms->LocalAppDataDirW = CopyUniStr(ms->PersonalAppDataDirW); } } // 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]; HashSha1(exe_hash, MsGetExeFileNameW(), UniStrLen(MsGetExeFileNameW())); 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]; UINT size; if (ms != NULL) { // Already initialized return; } suspend_handler_singleton = NewCounter(); vlan_card_counter = NewCounter(); vlan_card_should_stop_flag = false; 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); if (os.dwPlatformId == VER_PLATFORM_WIN32_NT) { // NT series ms->IsNt = true; ms->nt = MsLoadNtApiFunctions(); if (ms->nt == NULL) { ms->IsNt = false; ms->IsAdmin = true; } else { // Whether I am an Administrators ms->IsAdmin = MsCheckIsAdmin(); } } else { // In 9x system: Impersonate a Administrators always ms->IsAdmin = true; } if (GetProcAddress(ms->hKernel32, "wine_get_unix_file_name") != NULL) { ms->IsWine = true; } // 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) if (IsNt()) { wchar_t tmp_w[MAX_PATH]; size = sizeof(tmp_w); GetUserNameW(tmp_w, &size); ms->UserNameW = CopyUniStr(tmp_w); } else { ms->UserNameW = CopyStrToUni(ms->UserName); } // Get the full user name if (ms->nt != NULL && ms->nt->GetUserNameExA != NULL) { wchar_t tmp_w[MAX_PATH]; size = sizeof(tmp); if (ms->nt->GetUserNameExA(NameSamCompatible, tmp, &size)) { ms->UserNameEx = CopyStr(tmp); } size = sizeof(tmp_w); if (ms->nt->GetUserNameExW(NameSamCompatible, tmp_w, &size)) { ms->UserNameExW = CopyUniStr(tmp_w); } } 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); if (MsIsNt()) { if (ms->nt->MiniDumpWriteDump != NULL) { SetUnhandledExceptionFilter(MsExceptionHandler); } } // Open a LSA handle hLsa = NULL; lsa_package_id = 0; if (MsIsNt()) { MsEnablePrivilege(SE_TCB_NAME, true); if (ms->nt->AllocateLocallyUniqueId != NULL && ms->nt->LsaConnectUntrusted != NULL && ms->nt->LsaLookupAuthenticationPackage != NULL && ms->nt->LsaLogonUser != NULL && ms->nt->LsaDeregisterLogonProcess != NULL && ms->nt->LsaFreeReturnBuffer != NULL) { HANDLE h = NULL; NTSTATUS ret = ms->nt->LsaConnectUntrusted(&h); if (ret == 0) { LSA_STRING pkg_name; ULONG ul = 0; Zero(&pkg_name, sizeof(pkg_name)); pkg_name.Buffer = MSV1_0_PACKAGE_NAME; pkg_name.Length = pkg_name.MaximumLength = StrLen(MSV1_0_PACKAGE_NAME); ret = ms->nt->LsaLookupAuthenticationPackage(h, &pkg_name, &ul); if (ret == 0) { Zero(&lsa_token_source, sizeof(lsa_token_source)); ms->nt->AllocateLocallyUniqueId(&lsa_token_source.SourceIdentifier); Copy(lsa_token_source.SourceName, "SE-VPN ", 8); lsa_package_id = ul; hLsa = h; } else { ms->nt->LsaDeregisterLogonProcess(h); } } } } // 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]; UINT sz = sizeof(tmp) / sizeof(wchar_t); // 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; } // 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) { ms->nt->MiniDumpWriteDump(ms->hCurrentProcess, ms->CurrentProcessId, 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) { ms->nt->LsaDeregisterLogonProcess(hLsa); hLsa = NULL; } // Release of the adapter list MsFreeAdapterListModule(); // Release of the temporary directory MsFreeTempDir(); if (ms->IsNt) { // Release of NT series API MsFreeNtApiFunctions(ms->nt); } // 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; DeleteCounter(suspend_handler_singleton); suspend_handler_singleton = NULL; DeleteCounter(vlan_card_counter); vlan_card_counter = NULL; vlan_card_should_stop_flag = false; } // Directory acquisition related char *MsGetCommonAppDataDir() { return ms->CommonAppDataDir; } char *MsGetLocalAppDataDir() { return ms->LocalAppDataDir; } char *MsGetWindowsDir() { return ms->WindowsDir; } wchar_t *MsGetWindowsDirW() { return ms->WindowsDirW; } char *MsGetSystem32Dir() { return ms->System32Dir; } char *MsGetTempDir() { return ms->TempDir; } char *MsGetWindowsDrive() { return ms->WindowsDrive; } char *MsGetProgramFilesDir() { return ms->ProgramFilesDir; } char *MsGetProgramFilesDirX86() { return ms->ProgramFilesDirX86; } char *MsGetProgramFilesDirX64() { return ms->ProgramFilesDirX64; } char *MsGetCommonStartMenuDir() { return ms->CommonStartMenuDir; } char *MsGetCommonProgramsDir() { return ms->CommonProgramsDir; } char *MsGetCommonStartupDir() { return ms->CommonStartupDir; } char *MsGetCommonDesktopDir() { return ms->CommonDesktopDir; } char *MsGetPersonalStartMenuDir() { if (ms->PersonalStartMenuDir == NULL) { ms->PersonalStartMenuDir = MsGetSpecialDir(CSIDL_STARTMENU); } return ms->PersonalStartMenuDir; } char *MsGetPersonalProgramsDir() { if (ms->PersonalProgramsDir == NULL) { ms->PersonalProgramsDir = MsGetSpecialDir(CSIDL_PROGRAMS); } return ms->PersonalProgramsDir; } char *MsGetPersonalStartupDir() { if (ms->PersonalStartupDir == NULL) { ms->PersonalStartupDir = MsGetSpecialDir(CSIDL_STARTUP); } return ms->PersonalStartupDir; } char *MsGetPersonalAppDataDir() { if (ms->PersonalAppDataDir == NULL) { ms->PersonalAppDataDir = MsGetSpecialDir(CSIDL_APPDATA); } return ms->PersonalAppDataDir; } char *MsGetPersonalDesktopDir() { if (ms->PersonalDesktopDir == NULL) { ms->PersonalDesktopDir = MsGetSpecialDir(CSIDL_DESKTOP); } return ms->PersonalDesktopDir; } char *MsGetMyDocumentsDir() { if (ms->MyDocumentsDir == NULL) { ms->MyDocumentsDir = MsGetSpecialDir(CSIDL_PERSONAL); } return ms->MyDocumentsDir; } char *MsGetMyTempDir() { return ms->MyTempDir; } char *MsGetUserName() { return ms->UserName; } char *MsGetUserNameEx() { return ms->UserNameEx; } char *MsGetWinTempDir() { return ms->WinTempDir; } wchar_t *MsGetExeFileNameW() { return ms == NULL ? L"Unknown" : ms->ExeFileNameW; } wchar_t *MsGetExeFileDirW() { return ms->ExeFileDirW; } wchar_t *MsGetWindowDirW() { return ms->WindowsDirW; } wchar_t *MsGetSystem32DirW() { return ms->System32DirW; } wchar_t *MsGetTempDirW() { return ms->TempDirW; } wchar_t *MsGetWindowsDriveW() { return ms->WindowsDriveW; } wchar_t *MsGetProgramFilesDirW() { return ms->ProgramFilesDirW; } wchar_t *MsGetCommonStartMenuDirW() { return ms->CommonStartMenuDirW; } wchar_t *MsGetCommonProgramsDirW() { return ms->CommonProgramsDirW; } wchar_t *MsGetProgramFilesDirX86W() { return ms->ProgramFilesDirX86W; } wchar_t *MsGetProgramFilesDirX64W() { return ms->ProgramFilesDirX64W; } wchar_t *MsGetCommonStartupDirW() { return ms->CommonStartupDirW; } wchar_t *MsGetCommonAppDataDirW() { return ms->CommonAppDataDirW; } 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 *MsGetMyDocumentsDirW() { if (ms->MyDocumentsDirW == NULL) { ms->MyDocumentsDirW = MsGetSpecialDirW(CSIDL_PERSONAL); } return ms->MyDocumentsDirW; } wchar_t *MsGetLocalAppDataDirW() { return ms->LocalAppDataDirW; } wchar_t *MsGetMyTempDirW() { return ms->MyTempDirW; } wchar_t *MsGetUserNameW() { return ms->UserNameW; } wchar_t *MsGetUserNameExW() { return ms->UserNameExW; } wchar_t *MsGetWinTempDirW() { return ms->WinTempDirW; } #endif // WIN32