mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-23 09:59:52 +03:00
f96ac3644a
* Improvements on the behavior of the reinstall command of Windows Virtual Network Adapters. When reinstalling the device driver of the Virtual Network Driver card, we changed the behavior as to cleanup the older driver before installing the newer driver. * Improvement of the senetence. Add the same sentence to the Taiwan language file. * Delete the old MsUpgradeVLanWithoutLock_old() function.
12535 lines
263 KiB
C
12535 lines
263 KiB
C
// SoftEther VPN Source Code - Developer Edition Master Branch
|
|
// Cedar Communication Module
|
|
//
|
|
// SoftEther VPN Server, Client and Bridge are free software under GPLv2.
|
|
//
|
|
// Copyright (c) Daiyuu Nobori.
|
|
// Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
|
|
// Copyright (c) SoftEther Corporation.
|
|
//
|
|
// All Rights Reserved.
|
|
//
|
|
// http://www.softether.org/
|
|
//
|
|
// Author: Daiyuu Nobori, Ph.D.
|
|
// Contributors:
|
|
// - ELIN (https://github.com/el1n)
|
|
// 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.
|
|
|
|
|
|
// CM.c
|
|
// VPN Client Connection Manager for Win32
|
|
|
|
#include <GlobalConst.h>
|
|
|
|
#ifdef WIN32
|
|
|
|
#define CM_C
|
|
#define SM_C
|
|
#define MICROSOFT_C
|
|
|
|
#define _WIN32_WINNT 0x0502
|
|
#define WINVER 0x0502
|
|
#include <winsock2.h>
|
|
#include <windows.h>
|
|
#include <Iphlpapi.h>
|
|
#include <tlhelp32.h>
|
|
#include <shlobj.h>
|
|
#include <commctrl.h>
|
|
#include <Dbghelp.h>
|
|
#include <setupapi.h>
|
|
#include <regstr.h>
|
|
#include <process.h>
|
|
#include <psapi.h>
|
|
#include <wtsapi32.h>
|
|
#include <Ntsecapi.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <wchar.h>
|
|
#include <stdarg.h>
|
|
#include <time.h>
|
|
#include <errno.h>
|
|
#include <Mayaqua/Mayaqua.h>
|
|
#include <Cedar/Cedar.h>
|
|
#include "CMInner.h"
|
|
#include "SMInner.h"
|
|
#include "NMInner.h"
|
|
#include "EMInner.h"
|
|
#include "../PenCore/resource.h"
|
|
|
|
|
|
// Get the proxy server settings from the registry string of IE
|
|
bool CmGetProxyServerNameAndPortFromIeProxyRegStr(char *name, UINT name_size, UINT *port, char *str, char *server_type)
|
|
{
|
|
TOKEN_LIST *t;
|
|
UINT i;
|
|
bool ret = false;
|
|
// Validate arguments
|
|
if (name == NULL || port == NULL || str == NULL || server_type == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
t = ParseToken(str, ";");
|
|
|
|
for (i = 0;i < t->NumTokens;i++)
|
|
{
|
|
char *s = t->Token[i];
|
|
UINT i;
|
|
|
|
Trim(s);
|
|
|
|
i = SearchStrEx(s, "=", 0, false);
|
|
if (i != INFINITE)
|
|
{
|
|
char tmp[MAX_PATH];
|
|
|
|
StrCpy(name, name_size, s);
|
|
name[i] = 0;
|
|
|
|
if (StrCmpi(name, server_type) == 0)
|
|
{
|
|
char *host;
|
|
StrCpy(tmp, sizeof(tmp), s + i + 1);
|
|
|
|
if (ParseHostPort(tmp, &host, port, 0))
|
|
{
|
|
StrCpy(name, name_size, host);
|
|
Free(host);
|
|
|
|
if (*port != 0)
|
|
{
|
|
ret = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
FreeToken(t);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
// Reflect the contents of the proxy settings to the connection settings
|
|
void CmProxyDlgSet(HWND hWnd, CLIENT_OPTION *o, CM_INTERNET_SETTING *setting)
|
|
{
|
|
// Validate arguments
|
|
if(hWnd == NULL || setting == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Make check in check-box
|
|
Check(hWnd, R_DIRECT_TCP, setting->ProxyType == PROXY_DIRECT);
|
|
Check(hWnd, R_HTTPS, setting->ProxyType == PROXY_HTTP);
|
|
Check(hWnd, R_SOCKS, setting->ProxyType == PROXY_SOCKS);
|
|
|
|
// Proxy Settings
|
|
if(setting->ProxyType != PROXY_DIRECT)
|
|
{
|
|
StrCpy(o->ProxyName, sizeof(setting->ProxyHostName), setting->ProxyHostName);
|
|
o->ProxyPort = setting->ProxyPort;
|
|
}
|
|
}
|
|
|
|
// Get the proxy settings of IE
|
|
void CmGetSystemInternetSetting(CM_INTERNET_SETTING *setting)
|
|
{
|
|
bool use_proxy;
|
|
// Validate arguments
|
|
if (setting == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Zero(setting, sizeof(CM_INTERNET_SETTING));
|
|
|
|
use_proxy = MsRegReadInt(REG_CURRENT_USER,
|
|
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
|
|
"ProxyEnable");
|
|
|
|
if (use_proxy)
|
|
{
|
|
char *str = MsRegReadStr(REG_CURRENT_USER,
|
|
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
|
|
"ProxyServer");
|
|
if (str != NULL)
|
|
{
|
|
char name[MAX_HOST_NAME_LEN + 1];
|
|
UINT port;
|
|
|
|
if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),
|
|
&port, str, "https"))
|
|
{
|
|
setting->ProxyType = PROXY_HTTP;
|
|
StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);
|
|
setting->ProxyPort = port;
|
|
}
|
|
else if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),
|
|
&port, str, "http"))
|
|
{
|
|
setting->ProxyType = PROXY_HTTP;
|
|
StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);
|
|
setting->ProxyPort = port;
|
|
}
|
|
else if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),
|
|
&port, str, "socks"))
|
|
{
|
|
setting->ProxyType = PROXY_SOCKS;
|
|
StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);
|
|
setting->ProxyPort = port;
|
|
}
|
|
else
|
|
{
|
|
if (SearchStrEx(str, "=", 0, false) == INFINITE)
|
|
{
|
|
char *host;
|
|
UINT port;
|
|
if (ParseHostPort(str, &host, &port, 0))
|
|
{
|
|
if (port != 0)
|
|
{
|
|
setting->ProxyType = PROXY_HTTP;
|
|
StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), host);
|
|
setting->ProxyPort = port;
|
|
}
|
|
Free(host);
|
|
}
|
|
}
|
|
}
|
|
|
|
Free(str);
|
|
}
|
|
}
|
|
}
|
|
|
|
// For the proxy settings to go through, use the IE settings
|
|
void CmProxyDlgUseForIE(HWND hWnd, CLIENT_OPTION *o)
|
|
{
|
|
CM_INTERNET_SETTING s;
|
|
|
|
// Validate arguments
|
|
if(hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Zero(&s, sizeof(s));
|
|
CmGetSystemInternetSetting(&s);
|
|
|
|
CmProxyDlgSet(hWnd, o, &s);
|
|
}
|
|
|
|
// Determine the bitmap ID of the smart card authentication screen
|
|
UINT CmGetSecureBitmapId(char *dest_hostname)
|
|
{
|
|
// Validate arguments
|
|
if (dest_hostname == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (EndWith(dest_hostname, ".cc.tsukuba.ac.jp"))
|
|
{
|
|
return BMP_TSUKUBA;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Activate the window of UAC
|
|
void CmSetUacWindowActive()
|
|
{
|
|
HWND hWnd;
|
|
|
|
if (MsIsVista() == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
hWnd = FindWindowA("$$$Secure UAP Dummy Window Class For Interim Dialog", NULL);
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SwitchToThisWindow(hWnd, true);
|
|
}
|
|
|
|
// UAC helper thread
|
|
void CmUacHelperThread(THREAD *thread, void *param)
|
|
{
|
|
CM_UAC_HELPER *c = (CM_UAC_HELPER *)param;
|
|
// Validate arguments
|
|
if (c == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
while (c->Halt == false)
|
|
{
|
|
CmSetUacWindowActive();
|
|
|
|
Wait(c->HaltEvent, 200);
|
|
}
|
|
}
|
|
|
|
// Start the UAC helper
|
|
void *CmStartUacHelper()
|
|
{
|
|
CM_UAC_HELPER *c = ZeroMalloc(sizeof(CM_UAC_HELPER));
|
|
|
|
c->HaltEvent = NewEvent();
|
|
c->Thread = NewThread(CmUacHelperThread, c);
|
|
|
|
return (void *)c;
|
|
}
|
|
|
|
// Stop the UAC helper
|
|
void CmStopUacHelper(void *p)
|
|
{
|
|
CM_UAC_HELPER *c = (CM_UAC_HELPER *)p;
|
|
// Validate arguments
|
|
if (c == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
c->Halt = true;
|
|
Set(c->HaltEvent);
|
|
WaitThread(c->Thread, INFINITE);
|
|
ReleaseEvent(c->HaltEvent);
|
|
ReleaseThread(c->Thread);
|
|
|
|
Free(c);
|
|
}
|
|
|
|
// Command invocation of the simple connection manager
|
|
void CmEasyDlgOnCommand(HWND hWnd, CM_EASY_DLG *d, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || d == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (wParam)
|
|
{
|
|
case B_MODE:
|
|
Command(hWnd, CMD_CM_SETTING);
|
|
return;
|
|
|
|
case B_STATUS:
|
|
Command(hWnd, CMD_STATUS);
|
|
return;
|
|
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
return;
|
|
|
|
}
|
|
|
|
if (wParam == CMD_CONNECT)
|
|
{
|
|
cm->ConnectStartedFlag = false;
|
|
}
|
|
|
|
CmMainWindowOnCommandEx(hWnd, wParam, lParam, true);
|
|
|
|
if (wParam == CMD_CONNECT && cm->ConnectStartedFlag)
|
|
{
|
|
// Close the window when the connection started successfully
|
|
Close(hWnd);
|
|
}
|
|
}
|
|
|
|
// Keyboard pressing of the simple connection manager
|
|
void CmEasyDlgOnKey(HWND hWnd, CM_EASY_DLG *d, bool ctrl, bool alt, UINT key)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Single key
|
|
switch (key)
|
|
{
|
|
case VK_RETURN:
|
|
Command(hWnd, IDOK);
|
|
break;
|
|
case VK_DELETE:
|
|
// Delete
|
|
if (IsFocus(hWnd, L_ACCOUNT))
|
|
{
|
|
// Operation on the account list
|
|
Command(hWnd, CMD_DELETE);
|
|
}
|
|
else
|
|
{
|
|
// Operation on the virtual LAN card list
|
|
Command(hWnd, CMD_DELETE_VLAN);
|
|
}
|
|
break;
|
|
case VK_F2:
|
|
// Change the name
|
|
Command(hWnd, CMD_RENAME);
|
|
break;
|
|
case VK_F5:
|
|
// Update the status
|
|
Command(hWnd, CMD_REFRESH);
|
|
break;
|
|
}
|
|
|
|
if (alt)
|
|
{
|
|
switch (key)
|
|
{
|
|
case 'Q':
|
|
// Close
|
|
Command(hWnd, CMD_QUIT);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ctrl)
|
|
{
|
|
switch (key)
|
|
{
|
|
case 'G':
|
|
// Smart Card Manager
|
|
Command(hWnd, CMD_SECURE_MANAGER);
|
|
break;
|
|
case 'S':
|
|
// Show the status
|
|
Command(hWnd, CMD_STATUS);
|
|
break;
|
|
case 'I':
|
|
// Disconnect all connections
|
|
Command(hWnd, CMD_DISCONNECT_ALL);
|
|
break;
|
|
case 'D':
|
|
// Disconnect
|
|
Command(hWnd, CMD_DISCONNECT);
|
|
break;
|
|
case 'N':
|
|
// Create a new connection setting
|
|
Command(hWnd, CMD_NEW);
|
|
break;
|
|
case 'C':
|
|
// Creating a copy
|
|
Command(hWnd, CMD_CLONE);
|
|
break;
|
|
case 'T':
|
|
// Set to start-up connection
|
|
Command(hWnd, CMD_STARTUP);
|
|
break;
|
|
case 'A':
|
|
// Select all
|
|
Command(hWnd, CMD_SELECT_ALL);
|
|
break;
|
|
case 'L':
|
|
// Create a new virtual LAN card
|
|
Command(hWnd, CMD_NEW_VLAN);
|
|
break;
|
|
case 'P':
|
|
// Set the password
|
|
Command(hWnd, CMD_PASSWORD);
|
|
break;
|
|
case 'O':
|
|
// Option settings
|
|
Command(hWnd, CMD_TRAFFIC);
|
|
break;
|
|
case 'R':
|
|
// Certificate management
|
|
Command(hWnd, CMD_TRUST);
|
|
break;
|
|
case 'Q':
|
|
// Throughput
|
|
Command(hWnd, CMD_TRAFFIC);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Operation on the list view of the simple connection manager
|
|
void CmEasyDlgOnNotify(HWND hWnd, CM_EASY_DLG *d, NMHDR *n)
|
|
{
|
|
NMLVDISPINFOW *disp_info;
|
|
NMLVKEYDOWN *key;
|
|
|
|
// Validate arguments
|
|
if (hWnd == NULL || n == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (n->idFrom)
|
|
{
|
|
case L_ACCOUNT:
|
|
switch (n->code)
|
|
{
|
|
case LVN_ITEMCHANGED:
|
|
CmEasyDlgUpdate(hWnd, d);
|
|
break;
|
|
case NM_DBLCLK:
|
|
// Double click
|
|
Command(hWnd, CMD_EASY_DBLCLICK);
|
|
break;
|
|
case NM_RCLICK:
|
|
// Right click
|
|
CmAccountListRightClick(hWnd);
|
|
break;
|
|
case LVN_ENDLABELEDITW:
|
|
// Change the name
|
|
disp_info = (NMLVDISPINFOW *)n;
|
|
if (disp_info->item.pszText != NULL)
|
|
{
|
|
wchar_t *new_name = disp_info->item.pszText;
|
|
wchar_t *old_name = LvGetStr(hWnd, L_ACCOUNT, disp_info->item.iItem, 0);
|
|
|
|
if (old_name != NULL)
|
|
{
|
|
if (UniStrCmp(new_name, old_name) != 0 && UniIsEmptyStr(new_name) == false)
|
|
{
|
|
RPC_RENAME_ACCOUNT a;
|
|
Zero(&a, sizeof(a));
|
|
UniStrCpy(a.OldName, sizeof(a.OldName), old_name);
|
|
UniStrCpy(a.NewName, sizeof(a.NewName), new_name);
|
|
if (CALL(hWnd, CcRenameAccount(cm->Client, &a)))
|
|
{
|
|
LvSetItem(hWnd, L_ACCOUNT, disp_info->item.iItem, 0, new_name);
|
|
}
|
|
}
|
|
|
|
Free(old_name);
|
|
}
|
|
}
|
|
break;
|
|
case LVN_KEYDOWN:
|
|
// Key-press
|
|
key = (NMLVKEYDOWN *)n;
|
|
if (key != NULL)
|
|
{
|
|
bool ctrl, alt;
|
|
UINT code = key->wVKey;
|
|
ctrl = (GetKeyState(VK_CONTROL) & 0x8000) == 0 ? false : true;
|
|
alt = (GetKeyState(VK_MENU) & 0x8000) == 0 ? false : true;
|
|
CmEasyDlgOnKey(hWnd, d, ctrl, alt, code);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Send an update notification to the Simple Connection Manager
|
|
void CmRefreshEasy()
|
|
{
|
|
if (cm->hEasyWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SendMessage(cm->hEasyWnd, WM_CM_EASY_REFRESH, 0, 0);
|
|
}
|
|
|
|
// Initialize the Simple Connect Manager
|
|
void CmEasyDlgInit(HWND hWnd, CM_EASY_DLG *d)
|
|
{
|
|
HFONT hFontForList;
|
|
HFONT hFontButton;
|
|
HFONT hFontTitle;
|
|
HFONT hFontInfo;
|
|
HFONT hFontOther;
|
|
UINT i, num, num2, j;
|
|
bool b = false;
|
|
char *font_name = NULL;
|
|
bool font_bold = true;
|
|
// Validate arguments
|
|
if (hWnd == NULL || d == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetIcon(hWnd, 0, ICO_VPN);
|
|
|
|
// Window handle registration
|
|
cm->hEasyWnd = hWnd;
|
|
|
|
// Show in the center
|
|
Center(hWnd);
|
|
|
|
// Update the account list
|
|
CmInitAccountListEx(hWnd, true);
|
|
|
|
// Font settings of the list
|
|
if (cm->VistaStyle)
|
|
{
|
|
if (_GETLANG() == 0)
|
|
{
|
|
font_name = "Meiryo";
|
|
font_bold = false;
|
|
}
|
|
else if (_GETLANG() == 2)
|
|
{
|
|
font_name = "Microsoft YaHei";
|
|
font_bold = false;
|
|
}
|
|
}
|
|
|
|
hFontForList = GetFont(font_name, 14, font_bold, false, false, false);
|
|
hFontButton = GetFont(font_name, 13, font_bold, false, false, false);
|
|
hFontTitle = GetFont(font_name, 14, font_bold, false, false, false);
|
|
hFontInfo = GetFont(font_name, 11, font_bold, false, false, false);
|
|
hFontOther = GetDialogDefaultFont();
|
|
|
|
if (cm->VistaStyle)
|
|
{
|
|
hFontOther = GetMeiryoFont();
|
|
}
|
|
|
|
SetFont(hWnd, L_ACCOUNT, hFontForList);
|
|
SetFont(hWnd, IDOK, hFontButton);
|
|
SetFont(hWnd, S_TITLE, hFontTitle);
|
|
SetFont(hWnd, S_INFO, hFontInfo);
|
|
SetFont(hWnd, B_MODE, hFontOther);
|
|
SetFont(hWnd, IDCANCEL, hFontOther);
|
|
SetFont(hWnd, B_VGC, hFontOther);
|
|
|
|
SetShow(hWnd, B_VGC, cm->Client->IsVgcSupported);
|
|
|
|
CmEasyDlgRefresh(hWnd, d);
|
|
|
|
num = LvNum(hWnd, L_ACCOUNT);
|
|
num2 = 0;
|
|
j = 0;
|
|
for (i = 0;i < num;i++)
|
|
{
|
|
wchar_t *str = LvGetStr(hWnd, L_ACCOUNT, i, 1);
|
|
|
|
if (str != NULL)
|
|
{
|
|
if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)
|
|
{
|
|
num2++;
|
|
j = i;
|
|
}
|
|
Free(str);
|
|
}
|
|
}
|
|
|
|
if (num2 == 1)
|
|
{
|
|
LvSelect(hWnd, L_ACCOUNT, j);
|
|
b = true;
|
|
}
|
|
|
|
if (b == false)
|
|
{
|
|
if (UniIsEmptyStr(cm->EasyLastSelectedAccountName) == false)
|
|
{
|
|
i = LvSearchStr(hWnd, L_ACCOUNT, 0, cm->EasyLastSelectedAccountName);
|
|
if (i != INFINITE)
|
|
{
|
|
LvSelect(hWnd, L_ACCOUNT, i);
|
|
b = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (b == false)
|
|
{
|
|
if (LvNum(hWnd, L_ACCOUNT) != 0)
|
|
{
|
|
LvSelect(hWnd, L_ACCOUNT, 0);
|
|
}
|
|
}
|
|
|
|
Focus(hWnd, L_ACCOUNT);
|
|
|
|
CmEasyDlgUpdate(hWnd, d);
|
|
}
|
|
|
|
// Update the Simple Connection Manager control
|
|
void CmEasyDlgUpdate(HWND hWnd, CM_EASY_DLG *d)
|
|
{
|
|
bool ok = true;
|
|
bool show_status = false;
|
|
wchar_t *button_str = _UU("CM_EASY_CONNECT_BUTTON_1");
|
|
wchar_t *info_str = _UU("CM_EASY_INFO_1");
|
|
wchar_t *title_str = _UU("CM_EASY_TITLE");
|
|
// Validate arguments
|
|
if (hWnd == NULL || d == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (LvIsSingleSelected(hWnd, L_ACCOUNT) == false)
|
|
{
|
|
ok = false;
|
|
}
|
|
|
|
if (ok)
|
|
{
|
|
UINT i = LvGetSelected(hWnd, L_ACCOUNT);
|
|
wchar_t *str = LvGetStr(hWnd, L_ACCOUNT, i, 1);
|
|
|
|
info_str = _UU("CM_EASY_INFO_2");
|
|
|
|
if (str != NULL)
|
|
{
|
|
if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)
|
|
{
|
|
button_str = _UU("CM_EASY_CONNECT_BUTTON_2");
|
|
show_status = true;
|
|
info_str = _UU("CM_EASY_INFO_3");
|
|
|
|
if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0)
|
|
{
|
|
title_str = _UU("CM_EASY_CONNECTED");
|
|
}
|
|
else
|
|
{
|
|
title_str = _UU("CM_EASY_CONNECTING");
|
|
}
|
|
}
|
|
Free(str);
|
|
}
|
|
}
|
|
|
|
SetShow(hWnd, B_STATUS, show_status);
|
|
|
|
SetText(hWnd, IDOK, button_str);
|
|
SetText(hWnd, S_INFO, info_str);
|
|
SetText(hWnd, S_TITLE, title_str);
|
|
|
|
SetShow(hWnd, IDOK, ok);
|
|
}
|
|
|
|
// Update the Simple Connect Manager content
|
|
void CmEasyDlgRefresh(HWND hWnd, CM_EASY_DLG *d)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || d == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Update the account list
|
|
CmRefreshAccountListEx(hWnd, true);
|
|
|
|
CmEasyDlgUpdate(hWnd, d);
|
|
}
|
|
|
|
// Dialog procedure of the simple connection manager
|
|
UINT CmEasyDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
CM_EASY_DLG *d = (CM_EASY_DLG *)param;
|
|
NMHDR *n;
|
|
UINT i;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CmEasyDlgInit(hWnd, d);
|
|
SetTimer(hWnd, 1, 10, NULL);
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
switch (wParam)
|
|
{
|
|
case 1:
|
|
KillTimer(hWnd, 1);
|
|
SetForegroundWindow(hWnd);
|
|
SetActiveWindow(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CM_EASY_REFRESH:
|
|
CmEasyDlgRefresh(hWnd, d);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
CmEasyDlgOnCommand(hWnd, d, wParam, lParam);
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
n = (NMHDR *)lParam;
|
|
CmEasyDlgOnNotify(hWnd, d, n);
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
i = LvGetSelected(hWnd, L_ACCOUNT);
|
|
if (i != INFINITE)
|
|
{
|
|
wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, i, 0);
|
|
if (s != NULL)
|
|
{
|
|
UniStrCpy(cm->EasyLastSelectedAccountName, sizeof(cm->EasyLastSelectedAccountName),
|
|
s);
|
|
Free(s);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Zero(cm->EasyLastSelectedAccountName, sizeof(cm->EasyLastSelectedAccountName));
|
|
}
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Show the window of the simple connection manager (This is called by a delaying timer)
|
|
void CmMainWindowOnShowEasy(HWND hWnd)
|
|
{
|
|
CM_EASY_DLG d;
|
|
|
|
Zero(&d, sizeof(d));
|
|
|
|
if (cm->CmSetting.EasyMode == false)
|
|
{
|
|
// Not in simple mode
|
|
return;
|
|
}
|
|
|
|
if (cm->hEasyWnd != NULL)
|
|
{
|
|
// It is shown already
|
|
SetForegroundWindow(cm->hEasyWnd);
|
|
SetActiveWindow(cm->hEasyWnd);
|
|
return;
|
|
}
|
|
|
|
Dialog(NULL, D_CM_EASY, CmEasyDlg, &d);
|
|
|
|
cm->hEasyWnd = NULL;
|
|
}
|
|
|
|
// Show the window of the simple connection manager
|
|
void CmShowEasy()
|
|
{
|
|
SetTimer(cm->hMainWnd, 4, 2, NULL);
|
|
}
|
|
|
|
// Close the window of the simple connection manager
|
|
void CmCloseEasy()
|
|
{
|
|
if (cm->hEasyWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SendMessage(cm->hEasyWnd, WM_CLOSE, 0, 0);
|
|
}
|
|
|
|
// Message processing for such as clicking on the tray icon
|
|
void CmMainWindowOnTrayClicked(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
bool easymode = cm->CmSetting.EasyMode;
|
|
|
|
switch (wParam)
|
|
{
|
|
case 1:
|
|
switch (lParam)
|
|
{
|
|
case WM_LBUTTONDOWN:
|
|
case WM_RBUTTONDOWN:
|
|
// Click
|
|
if (easymode == false)
|
|
{
|
|
if (IsEnable(hWnd, 0))
|
|
{
|
|
CmShowTrayMenu(hWnd);
|
|
}
|
|
else
|
|
{
|
|
CmShowOrHideWindow(hWnd);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (cm->hEasyWnd == NULL || IsEnable(cm->hEasyWnd, 0))
|
|
{
|
|
CmShowTrayMenu(hWnd);
|
|
}
|
|
else
|
|
{
|
|
//CmShowOrHideWindow(hWnd);
|
|
}
|
|
}
|
|
break;
|
|
case WM_LBUTTONDBLCLK:
|
|
case WM_RBUTTONDBLCLK:
|
|
// Double click
|
|
if (easymode == false)
|
|
{
|
|
if (IsEnable(hWnd, 0))
|
|
{
|
|
CmShowOrHideWindow(hWnd);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (cm->hEasyWnd == NULL)
|
|
{
|
|
CmShowEasy();
|
|
}
|
|
else
|
|
{
|
|
SetForegroundWindow(cm->hEasyWnd);
|
|
SetActiveWindow(cm->hEasyWnd);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Apply the setting of the operation mode
|
|
void CmApplyCmSetting()
|
|
{
|
|
CM_SETTING a;
|
|
bool changed = false;
|
|
|
|
if (cm->CmSettingSupported == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the configuration of the current vpnclient
|
|
Zero(&a, sizeof(a));
|
|
CcGetCmSetting(cm->Client, &a);
|
|
|
|
// Check whether there is change point as compared to the previous CM_SETTING
|
|
if (cm->CmSetting.EasyMode != a.EasyMode)
|
|
{
|
|
changed = true;
|
|
}
|
|
if (cm->CmSetting.LockMode != a.LockMode)
|
|
{
|
|
changed = true;
|
|
}
|
|
|
|
Copy(&cm->CmSetting, &a, sizeof(CM_SETTING));
|
|
|
|
if (changed == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (cm->StartupFinished)
|
|
{
|
|
if (IsShow(cm->hMainWnd, 0) && cm->CmSetting.EasyMode)
|
|
{
|
|
// Close the main window if it is shown
|
|
Hide(cm->hMainWnd, 0);
|
|
}
|
|
else
|
|
{
|
|
WINDOWPLACEMENT current_pos;
|
|
if (cm->CmSetting.EasyMode == false && IsShow(cm->hMainWnd, 0) == false)
|
|
{
|
|
// When restored to normal mode, restore the main window
|
|
if (IsZero(&cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement)) == false)
|
|
{
|
|
cm->FakeWindowPlacement.flags = cm->FakeWindowPlacement.flags & ~SW_MINIMIZE;
|
|
SetWindowPlacement(cm->hMainWnd, &cm->FakeWindowPlacement);
|
|
Zero(&cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement));
|
|
Hide(cm->hMainWnd, 0);
|
|
}
|
|
CmShowOrHideWindow(cm->hMainWnd);
|
|
}
|
|
|
|
if (cm->CmSetting.EasyMode == false)
|
|
{
|
|
if (GetWindowPlacement(cm->hMainWnd, ¤t_pos))
|
|
{
|
|
if (current_pos.rcNormalPosition.right < 0 ||
|
|
current_pos.rcNormalPosition.bottom < 0)
|
|
{
|
|
// If the window is off the screen for some reason,
|
|
// return it in a visible place
|
|
SetWindowPos(cm->hMainWnd, NULL, 0, 0, CM_DEFAULT_WIDTH, CM_DEFAULT_HEIGHT, SWP_NOREDRAW | SWP_SHOWWINDOW);
|
|
Center(cm->hMainWnd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Command(cm->hMainWnd, CMD_REFRESH);
|
|
}
|
|
|
|
if (cm->CmSetting.EasyMode)
|
|
{
|
|
if (cm->StartupFinished == false && cm->StartupMode)
|
|
{
|
|
// Don't show in the case of /startup
|
|
}
|
|
else
|
|
{
|
|
CmShowEasy();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CmCloseEasy();
|
|
}
|
|
}
|
|
|
|
// Initialize the operation mode changing dialog
|
|
void CmSettingDlgInit(HWND hWnd, CM_SETTING_DLG *d)
|
|
{
|
|
CM_SETTING a;
|
|
// Validate arguments
|
|
if (hWnd == NULL || d == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the configuration of the current vpnclient
|
|
Zero(&a, sizeof(a));
|
|
CcGetCmSetting(cm->Client, &a);
|
|
|
|
Check(hWnd, R_EASY, a.EasyMode);
|
|
Check(hWnd, R_NORMAL, a.EasyMode == false);
|
|
|
|
if (a.EasyMode == false)
|
|
{
|
|
Focus(hWnd, R_NORMAL);
|
|
}
|
|
else
|
|
{
|
|
Focus(hWnd, R_EASY);
|
|
}
|
|
|
|
Check(hWnd, R_LOCK, a.LockMode);
|
|
|
|
SetEnable(hWnd, R_EASY, cm->CmEasyModeSupported);
|
|
|
|
if (a.LockMode)
|
|
{
|
|
if (IsZero(a.HashedPassword, sizeof(a.HashedPassword)) == false)
|
|
{
|
|
// Password is set
|
|
SetText(hWnd, S_PASSWORD1, _UU("CM_SETTING_PASSWORD"));
|
|
Hide(hWnd, S_PASSWORD3);
|
|
Hide(hWnd, E_PASSWORD2);
|
|
|
|
d->CheckPassword = true;
|
|
Copy(d->HashedPassword, a.HashedPassword, sizeof(d->HashedPassword));
|
|
}
|
|
}
|
|
|
|
SetShow(hWnd, S_VGS1, cm->Client->IsVgcSupported);
|
|
SetShow(hWnd, S_VGS2, cm->Client->IsVgcSupported);
|
|
SetShow(hWnd, S_VGS3, cm->Client->IsVgcSupported);
|
|
SetShow(hWnd, B_VGS, cm->Client->IsVgcSupported);
|
|
|
|
CmSettingDlgUpdate(hWnd, d);
|
|
}
|
|
|
|
// Update the operation mode changing dialog
|
|
void CmSettingDlgUpdate(HWND hWnd, CM_SETTING_DLG *d)
|
|
{
|
|
bool ok = true;
|
|
char tmp1[MAX_SIZE], tmp2[MAX_SIZE];
|
|
// Validate arguments
|
|
if (hWnd == NULL || d == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GetTxtA(hWnd, E_PASSWORD1, tmp1, sizeof(tmp1));
|
|
GetTxtA(hWnd, E_PASSWORD2, tmp2, sizeof(tmp2));
|
|
|
|
if (d->CheckPassword == false)
|
|
{
|
|
if (IsChecked(hWnd, R_LOCK))
|
|
{
|
|
if (StrCmp(tmp1, tmp2) != 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bool password_ok = false;
|
|
UCHAR hash[SHA1_SIZE];
|
|
|
|
Hash(hash, tmp1, StrLen(tmp1), true);
|
|
if (Cmp(hash, d->HashedPassword, sizeof(hash)) == 0)
|
|
{
|
|
password_ok = true;
|
|
}
|
|
|
|
if (password_ok == false)
|
|
{
|
|
Check(hWnd, R_LOCK, true);
|
|
Disable(hWnd, R_LOCK);
|
|
}
|
|
else
|
|
{
|
|
Enable(hWnd, R_LOCK);
|
|
}
|
|
}
|
|
|
|
SetEnable(hWnd, S_PASSWORD1, IsChecked(hWnd, R_LOCK));
|
|
SetEnable(hWnd, S_PASSWORD2, IsChecked(hWnd, R_LOCK));
|
|
SetEnable(hWnd, S_PASSWORD3, IsChecked(hWnd, R_LOCK));
|
|
SetEnable(hWnd, E_PASSWORD1, IsChecked(hWnd, R_LOCK));
|
|
SetEnable(hWnd, E_PASSWORD2, IsChecked(hWnd, R_LOCK));
|
|
|
|
SetEnable(hWnd, IDOK, ok);
|
|
}
|
|
|
|
// Operation mode changing dialog OK
|
|
void CmSettingDlgOnOk(HWND hWnd, CM_SETTING_DLG *d)
|
|
{
|
|
CM_SETTING a;
|
|
char tmp1[MAX_SIZE], tmp2[MAX_SIZE];
|
|
// Validate arguments
|
|
if (hWnd == NULL || d == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GetTxtA(hWnd, E_PASSWORD1, tmp1, sizeof(tmp1));
|
|
GetTxtA(hWnd, E_PASSWORD2, tmp2, sizeof(tmp2));
|
|
|
|
Zero(&a, sizeof(a));
|
|
|
|
a.EasyMode = IsChecked(hWnd, R_EASY);
|
|
a.LockMode = IsChecked(hWnd, R_LOCK);
|
|
|
|
if (a.LockMode)
|
|
{
|
|
if (d->CheckPassword && IsEnable(hWnd, R_LOCK) == false)
|
|
{
|
|
Copy(a.HashedPassword, d->HashedPassword, sizeof(a.HashedPassword));
|
|
}
|
|
else
|
|
{
|
|
if (StrLen(tmp1) >= 1)
|
|
{
|
|
Hash(a.HashedPassword, tmp1, StrLen(tmp1), true);
|
|
}
|
|
}
|
|
}
|
|
|
|
CcSetCmSetting(cm->Client, &a);
|
|
|
|
EndDialog(hWnd, true);
|
|
}
|
|
|
|
// Operation mode changing dialog
|
|
UINT CmSettingDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
CM_SETTING_DLG *d = (CM_SETTING_DLG *)param;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CmSettingDlgInit(hWnd, d);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case R_EASY:
|
|
case R_NORMAL:
|
|
case R_LOCK:
|
|
case E_PASSWORD1:
|
|
case E_PASSWORD2:
|
|
case IDOK:
|
|
case IDCANCEL:
|
|
CmSettingDlgUpdate(hWnd, d);
|
|
break;
|
|
}
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
CmSettingDlgOnOk(hWnd, d);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
|
|
case R_LOCK:
|
|
if (IsChecked(hWnd, R_LOCK))
|
|
{
|
|
if (IsEmpty(hWnd, E_PASSWORD1))
|
|
{
|
|
Focus(hWnd, E_PASSWORD1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// Change operation mode
|
|
bool CmSetting(HWND hWnd)
|
|
{
|
|
CM_SETTING_DLG d;
|
|
|
|
Zero(&d, sizeof(d));
|
|
|
|
return Dialog(hWnd, D_CM_SETTING, CmSettingDlg, &d);
|
|
}
|
|
|
|
|
|
// Attempting thread for starting the UI Helper
|
|
void CmTryToExecUiHelperThread(THREAD *thread, void *param)
|
|
{
|
|
bool first_flag = true;
|
|
|
|
while (cm->TryExecUiHelperHalt == false && cm->WindowsShutdowning == false)
|
|
{
|
|
if (first_flag == false)
|
|
{
|
|
// Wait a little for other than the first time
|
|
Wait(cm->TryExecUiHelperHaltEvent, CM_TRY_EXEC_UI_HELPER_INTERVAL * 2);
|
|
|
|
if (cm->TryExecUiHelperHalt || cm->WindowsShutdowning)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
first_flag = false;
|
|
|
|
if (cm->TryExecUiHelperHalt == false && cm->WindowsShutdowning == false)
|
|
{
|
|
if (cm->TryExecUiHelperProcessHandle == NULL)
|
|
{
|
|
CmTryToExecUiHelper();
|
|
}
|
|
}
|
|
|
|
if (cm->TryExecUiHelperHalt || cm->WindowsShutdowning)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (cm->TryExecUiHelperProcessHandle == NULL)
|
|
{
|
|
Wait(cm->TryExecUiHelperHaltEvent, CM_TRY_EXEC_UI_HELPER_INTERVAL);
|
|
}
|
|
else
|
|
{
|
|
HANDLE handles[2];
|
|
handles[0] = cm->TryExecUiHelperProcessHandle;
|
|
handles[1] = (HANDLE)cm->TryExecUiHelperHaltEvent->pData;
|
|
WaitForMultipleObjects(2, handles, false, CM_TRY_EXEC_UI_HELPER_INTERVAL);
|
|
|
|
if (WaitForSingleObject(cm->TryExecUiHelperProcessHandle, 0) != WAIT_TIMEOUT)
|
|
{
|
|
CloseHandle(cm->TryExecUiHelperProcessHandle);
|
|
cm->TryExecUiHelperProcessHandle = NULL;
|
|
if (cm->TryExecUiHelperHalt || cm->WindowsShutdowning)
|
|
{
|
|
break;
|
|
}
|
|
Wait(cm->TryExecUiHelperHaltEvent, CM_TRY_EXEC_UI_HELPER_INTERVAL * 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Stop the UI Helper
|
|
void CmFreeTryToExecUiHelper()
|
|
{
|
|
cm->TryExecUiHelperHalt = true;
|
|
Set(cm->TryExecUiHelperHaltEvent);
|
|
|
|
WaitThread(cm->TryExecUiHelperThread, INFINITE);
|
|
|
|
ReleaseThread(cm->TryExecUiHelperThread);
|
|
cm->TryExecUiHelperThread = NULL;
|
|
|
|
ReleaseEvent(cm->TryExecUiHelperHaltEvent);
|
|
cm->TryExecUiHelperHaltEvent = NULL;
|
|
|
|
cm->TryExecUiHelperHalt = false;
|
|
cm->TryExecUiHelperProcessHandle = NULL;
|
|
}
|
|
|
|
// Initialize the UI Helper starting
|
|
void CmInitTryToExecUiHelper()
|
|
{
|
|
cm->TryExecUiHelperProcessHandle = NULL;
|
|
cm->TryExecUiHelperHalt = false;
|
|
cm->TryExecUiHelperHaltEvent = NewEvent();
|
|
cm->TryExecUiHelperThread = NewThread(CmTryToExecUiHelperThread, NULL);
|
|
}
|
|
|
|
// Start the UI Helper
|
|
void *CmExecUiHelperMain()
|
|
{
|
|
HANDLE h;
|
|
wchar_t tmp[MAX_SIZE];
|
|
|
|
UniFormat(tmp, sizeof(tmp), L"%s\\%S", MsGetExeDirNameW(), CiGetVpnClientExeFileName());
|
|
|
|
// Start
|
|
h = Win32RunExW(tmp, SVC_ARG_UIHELP_W, false);
|
|
|
|
return (void *)h;
|
|
}
|
|
|
|
// Attempt to start the UI Helper
|
|
void CmTryToExecUiHelper()
|
|
{
|
|
HANDLE h;
|
|
// Check that it isn't already running
|
|
if (CnCheckAlreadyExists(false))
|
|
{
|
|
// It have already started
|
|
return;
|
|
}
|
|
|
|
h = (HANDLE)CmExecUiHelperMain();
|
|
|
|
if (h != NULL)
|
|
{
|
|
cm->TryExecUiHelperProcessHandle = h;
|
|
}
|
|
}
|
|
|
|
// Initialize the dialog
|
|
void CmTrafficResultDlgInit(HWND hWnd, TT_RESULT *res)
|
|
{
|
|
LVB *ct;
|
|
wchar_t tmp[MAX_SIZE];
|
|
wchar_t tmp1[MAX_SIZE];
|
|
wchar_t tmp2[MAX_SIZE];
|
|
char str[MAX_SIZE];
|
|
// Validate arguments
|
|
if (hWnd == NULL || res == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetIcon(hWnd, 0, ICO_SWITCH);
|
|
|
|
SetFont(hWnd, L_STATUS, GetFont(_SS("DEFAULT_FONT_2"), 10, false, false, false, false));
|
|
|
|
LvInit(hWnd, L_STATUS);
|
|
LvSetStyle(hWnd, L_STATUS, LVS_EX_GRIDLINES);
|
|
LvInsertColumn(hWnd, L_STATUS, 0, _UU("TTC_RES_COLUMN_1"), 100);
|
|
LvInsertColumn(hWnd, L_STATUS, 1, _UU("TTC_RES_COLUMN_2"), 100);
|
|
LvInsertColumn(hWnd, L_STATUS, 2, _UU("TTC_RES_COLUMN_3"), 100);
|
|
|
|
ct = LvInsertStart();
|
|
|
|
// Time that was used to measure
|
|
GetSpanStrMilli(str, sizeof(str), res->Span);
|
|
StrToUni(tmp, sizeof(tmp), str);
|
|
LvInsertAdd(ct, ICO_DATETIME, NULL, 3, _UU("TTC_RES_SPAN"), tmp, L"");
|
|
|
|
// Correct the data for Ethernet frame
|
|
LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_ETHER"), res->Raw ? _UU("SEC_NO") : _UU("SEC_YES"), L"");
|
|
|
|
// Amount of communication data of download direction
|
|
ToStr3(str, sizeof(str), res->NumBytesDownload);
|
|
UniFormat(tmp1, sizeof(tmp1), L"%S Bytes", str);
|
|
ToStrByte1000(str, sizeof(str), res->NumBytesDownload);
|
|
StrToUni(tmp2, sizeof(tmp2), str);
|
|
LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BYTES_DOWNLOAD"), tmp1, tmp2);
|
|
|
|
// Amount of communication data of upload direction
|
|
ToStr3(str, sizeof(str), res->NumBytesUpload);
|
|
UniFormat(tmp1, sizeof(tmp1), L"%S Bytes", str);
|
|
ToStrByte1000(str, sizeof(str), res->NumBytesUpload);
|
|
StrToUni(tmp2, sizeof(tmp2), str);
|
|
LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BYTES_UPLOAD"), tmp1, tmp2);
|
|
|
|
// Total amount of communication data
|
|
ToStr3(str, sizeof(str), res->NumBytesTotal);
|
|
UniFormat(tmp1, sizeof(tmp1), L"%S Bytes", str);
|
|
ToStrByte1000(str, sizeof(str), res->NumBytesTotal);
|
|
StrToUni(tmp2, sizeof(tmp2), str);
|
|
LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BYTES_TOTAL"), tmp1, tmp2);
|
|
|
|
// Calculate the total throughput of input and output of the relay equipment
|
|
LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_DOUBLE"), (res->Double == false) ? _UU("SEC_NO") : _UU("SEC_YES"), L"");
|
|
|
|
// Average throughput of download direction
|
|
ToStr3(str, sizeof(str), res->BpsDownload);
|
|
UniFormat(tmp1, sizeof(tmp1), L"%S bps", str);
|
|
ToStrByte1000(str, sizeof(str), res->BpsDownload);
|
|
ReplaceStr(str, sizeof(str), str, "Bytes", "bps");
|
|
StrToUni(tmp2, sizeof(tmp2), str);
|
|
LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BPS_DOWNLOAD"), tmp1, tmp2);
|
|
|
|
// Average throughput of upload direction
|
|
ToStr3(str, sizeof(str), res->BpsUpload);
|
|
UniFormat(tmp1, sizeof(tmp1), L"%S bps", str);
|
|
ToStrByte1000(str, sizeof(str), res->BpsUpload);
|
|
ReplaceStr(str, sizeof(str), str, "Bytes", "bps");
|
|
StrToUni(tmp2, sizeof(tmp2), str);
|
|
LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BPS_UPLOAD"), tmp1, tmp2);
|
|
|
|
// Total average throughput
|
|
ToStr3(str, sizeof(str), res->BpsTotal);
|
|
UniFormat(tmp1, sizeof(tmp1), L"%S bps", str);
|
|
ToStrByte1000(str, sizeof(str), res->BpsTotal);
|
|
ReplaceStr(str, sizeof(str), str, "Bytes", "bps");
|
|
StrToUni(tmp2, sizeof(tmp2), str);
|
|
LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BPS_TOTAL"), tmp1, tmp2);
|
|
|
|
LvInsertEnd(ct, hWnd, L_STATUS);
|
|
|
|
LvAutoSize(hWnd, L_STATUS);
|
|
}
|
|
|
|
// Dialog procedure to display results of traffic measurements
|
|
UINT CmTrafficResultDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
TT_RESULT *r = (TT_RESULT *)param;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CmTrafficResultDlgInit(hWnd, r);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Display results of traffic measurement
|
|
void CmTrafficResult(HWND hWnd, TT_RESULT *r)
|
|
{
|
|
// Validate arguments
|
|
if (r == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Dialog(hWnd, D_CM_TRAFFIC_RESULT, CmTrafficResultDlg, r);
|
|
}
|
|
|
|
// Thread to wait for the termination of the client
|
|
void CmTrafficRunDlgClientWaitThread(THREAD *t, void *param)
|
|
{
|
|
CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;
|
|
TT_RESULT result;
|
|
UINT ret;
|
|
// Validate arguments
|
|
if (t == NULL || param == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Zero(&result, sizeof(result));
|
|
ret = FreeTtc(d->Ttc, &result);
|
|
d->Ttc = NULL;
|
|
|
|
d->RetCode = ret;
|
|
Copy(&d->Result, &result, sizeof(TT_RESULT));
|
|
|
|
PostMessage(d->hWnd, WM_APP + 66, 0, 0);
|
|
}
|
|
|
|
// Append the string
|
|
void CmTrafficRunDlgAddStr(HWND hWnd, wchar_t *str)
|
|
{
|
|
wchar_t *tmp;
|
|
UINT tmp_size;
|
|
|
|
tmp_size = UniStrSize(str) + 32;
|
|
tmp = Malloc(tmp_size);
|
|
UniStrCpy(tmp, tmp_size, str);
|
|
if (UniEndWith(str, L"\n") == false)
|
|
{
|
|
UniStrCat(tmp, tmp_size, L"\n");
|
|
}
|
|
|
|
UniReplaceStrEx(tmp, tmp_size, tmp, L"\r\n", L"\n", false);
|
|
UniReplaceStrEx(tmp, tmp_size, tmp, L"\n", L"\r\n", false);
|
|
|
|
if (MsIsNt())
|
|
{
|
|
SendMsg(hWnd, E_EDIT, EM_SETSEL, 0x7fffffff, 0x7fffffff);
|
|
SendMsg(hWnd, E_EDIT, EM_REPLACESEL, false, (LPARAM)tmp);
|
|
}
|
|
else
|
|
{
|
|
char *s = CopyUniToStr(tmp);
|
|
UINT len;
|
|
|
|
len = GetWindowTextLength(DlgItem(hWnd, E_EDIT));
|
|
SendMsg(hWnd, E_EDIT, EM_SETSEL, 0x7fffffff, 0x7fffffff);
|
|
SendMsg(hWnd, E_EDIT, EM_SETSEL, len, len);
|
|
SendMsg(hWnd, E_EDIT, EM_REPLACESEL, false, (LPARAM)s);
|
|
Free(s);
|
|
}
|
|
|
|
Free(tmp);
|
|
}
|
|
|
|
// Show the string
|
|
void CmTrafficRunDlgPrintProc(void *param, wchar_t *str)
|
|
{
|
|
CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;
|
|
HWND hWnd;
|
|
// Validate arguments
|
|
if (param == NULL || str == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
hWnd = d->hWnd;
|
|
|
|
PostMessage(hWnd, WM_APP + 64, 0, (LPARAM)UniCopyStr(str));
|
|
}
|
|
|
|
// Thread for stop the measurement program
|
|
void CmTrafficRunDlgHaltThread(THREAD *t, void *param)
|
|
{
|
|
CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;
|
|
// Validate arguments
|
|
if (t == NULL || param == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (d->Setting->ServerMode)
|
|
{
|
|
// Stop the server
|
|
d->RetCode = FreeTts(d->Tts);
|
|
|
|
PostMessage(d->hWnd, WM_APP + 65, 0, 0);
|
|
}
|
|
}
|
|
|
|
// Stop the measurement program
|
|
void CmTrafficRunDlgHalt(HWND hWnd, CM_TRAFFIC_DLG *d)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || d == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (d->Started == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (d->Setting->ServerMode)
|
|
{
|
|
if (d->HaltThread == NULL)
|
|
{
|
|
Disable(hWnd, IDCANCEL);
|
|
d->HaltThread = NewThread(CmTrafficRunDlgHaltThread, d);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (d->ClientEndWaitThread != NULL)
|
|
{
|
|
StopTtc(d->Ttc);
|
|
}
|
|
else
|
|
{
|
|
EndDialog(hWnd, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Start the operation of traffic measurement
|
|
void CmTrafficRunDlgStart(HWND hWnd, CM_TRAFFIC_DLG *d)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || d == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (d->Setting->ServerMode)
|
|
{
|
|
// Start the measurement server
|
|
d->Tts = NewTts(d->Setting->Port, d, CmTrafficRunDlgPrintProc);
|
|
}
|
|
else
|
|
{
|
|
// Start the measurement client
|
|
d->Ttc = NewTtc(d->Setting->Host, d->Setting->Port,
|
|
d->Setting->NumTcp, d->Setting->Type, d->Setting->Span * 1000ULL,
|
|
d->Setting->Double, d->Setting->Raw, CmTrafficRunDlgPrintProc, d);
|
|
|
|
d->ClientEndWaitThread = NewThread(CmTrafficRunDlgClientWaitThread, d);
|
|
}
|
|
|
|
d->Started = true;
|
|
}
|
|
|
|
// Traffic measurement operation dialog initialization
|
|
void CmTrafficRunDlgInit(HWND hWnd, CM_TRAFFIC_DLG *d)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || d == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
d->hWnd = hWnd;
|
|
|
|
SetIcon(hWnd, 0, ICO_SWITCH);
|
|
DlgFont(hWnd, S_INFO, 11, false);
|
|
SetFont(hWnd, E_EDIT, GetFont(_SS("DEFAULT_FONT_2"), 0, false, false,
|
|
false, false));
|
|
|
|
Focus(hWnd, IDCANCEL);
|
|
}
|
|
|
|
// Traffic measurement operation dialog procedure
|
|
UINT CmTrafficRunDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;
|
|
wchar_t *s;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CmTrafficRunDlgInit(hWnd, d);
|
|
|
|
SetTimer(hWnd, 1, 10, NULL);
|
|
break;
|
|
|
|
case WM_APP + 64:
|
|
// Add a string
|
|
s = (wchar_t *)lParam;
|
|
if (s != NULL)
|
|
{
|
|
CmTrafficRunDlgAddStr(hWnd, s);
|
|
Free(s);
|
|
}
|
|
break;
|
|
|
|
case WM_APP + 65:
|
|
// Stopping complete
|
|
if (d->HaltThread != NULL)
|
|
{
|
|
WaitThread(d->HaltThread, INFINITE);
|
|
ReleaseThread(d->HaltThread);
|
|
d->HaltThread = NULL;
|
|
EndDialog(hWnd, 0);
|
|
}
|
|
break;
|
|
|
|
case WM_APP + 66:
|
|
// Show results
|
|
if (d->RetCode == ERR_NO_ERROR)
|
|
{
|
|
CmTrafficResult(hWnd, &d->Result);
|
|
}
|
|
|
|
if (d->ClientEndWaitThread != NULL)
|
|
{
|
|
WaitThread(d->ClientEndWaitThread, INFINITE);
|
|
ReleaseThread(d->ClientEndWaitThread);
|
|
d->ClientEndWaitThread = NULL;
|
|
}
|
|
|
|
if (d->CloseDialogAfter)
|
|
{
|
|
EndDialog(hWnd, 0);
|
|
}
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
switch (wParam)
|
|
{
|
|
case 1:
|
|
KillTimer(hWnd, 1);
|
|
|
|
CmTrafficRunDlgStart(hWnd, d);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
d->CloseDialogAfter = true;
|
|
CmTrafficRunDlgHalt(hWnd, d);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Execute a traffic measurement
|
|
void CmExecTraffic(HWND hWnd, CM_TRAFFIC *t)
|
|
{
|
|
CM_TRAFFIC_DLG d;
|
|
// Validate arguments
|
|
if (t == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Zero(&d, sizeof(d));
|
|
d.Setting = t;
|
|
d.ResultShowEvent = NewEvent();
|
|
|
|
MsSetThreadPriorityHigh();
|
|
Dialog(hWnd, D_CM_TRAFFIC_RUN, CmTrafficRunDlg, &d);
|
|
MsRestoreThreadPriority();
|
|
|
|
ReleaseEvent(d.ResultShowEvent);
|
|
}
|
|
|
|
// Write the settings to the registry
|
|
void CmTrafficSaveToReg(CM_TRAFFIC *t)
|
|
{
|
|
// Validate arguments
|
|
if (t == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "ServerMode", t->ServerMode ? 1 : 0);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Double", t->Double ? 1 : 0);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Raw", t->Raw ? 1 : 0);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Port", t->Port);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "NumTcp", t->NumTcp);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Type", t->Type);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Span", t->Span);
|
|
MsRegWriteStr(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Host", t->Host);
|
|
}
|
|
|
|
// Read the settings from the registry
|
|
bool CmTrafficLoadFromReg(CM_TRAFFIC *t)
|
|
{
|
|
char *s;
|
|
// Validate arguments
|
|
if (t == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Zero(t, sizeof(CM_TRAFFIC));
|
|
|
|
if (MsRegIsKey(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY) == false)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
t->Double = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Double") == 0 ? false : true;
|
|
t->Raw = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Raw") == 0 ? false : true;
|
|
t->Port = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Port");
|
|
if (t->Port == 0)
|
|
{
|
|
t->Port = TRAFFIC_DEFAULT_PORT;
|
|
}
|
|
|
|
s = MsRegReadStr(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Host");
|
|
|
|
if (IsEmptyStr(s) == false)
|
|
{
|
|
Trim(s);
|
|
StrCpy(t->Host, sizeof(t->Host), s);
|
|
}
|
|
|
|
Free(s);
|
|
|
|
t->NumTcp = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "NumTcp");
|
|
t->NumTcp = MAKESURE(t->NumTcp, 1, TRAFFIC_NUMTCP_MAX);
|
|
t->Type = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Type");
|
|
|
|
if (t->Type != TRAFFIC_TYPE_DOWNLOAD && t->Type != TRAFFIC_TYPE_UPLOAD &&
|
|
t->Type != TRAFFIC_TYPE_FULL)
|
|
{
|
|
t->Type = TRAFFIC_TYPE_FULL;
|
|
}
|
|
|
|
t->Span = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Span");
|
|
if (t->Span == 0)
|
|
{
|
|
t->Span = TRAFFIC_SPAN_DEFAULT;
|
|
}
|
|
|
|
t->ServerMode = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "ServerMode") == 0 ? false : true;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Get the default settings
|
|
void CmTrafficGetDefaultSetting(CM_TRAFFIC *t)
|
|
{
|
|
// Validate arguments
|
|
if (t == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Zero(t, sizeof(CM_TRAFFIC));
|
|
|
|
t->Double = false;
|
|
t->Raw = false;
|
|
t->Port = TRAFFIC_DEFAULT_PORT;
|
|
t->NumTcp = TRAFFIC_NUMTCP_DEFAULT;
|
|
t->Type = TRAFFIC_TYPE_FULL;
|
|
t->Span = TRAFFIC_SPAN_DEFAULT;
|
|
t->ServerMode = false;
|
|
}
|
|
|
|
// Communication throughput measurement tool dialog initialization
|
|
void CmTrafficDlgInit(HWND hWnd)
|
|
{
|
|
CM_TRAFFIC t;
|
|
LIST *c1, *c2;
|
|
UINT i;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DlgFont(hWnd, S_8, 9, true);
|
|
DlgFont(hWnd, S_3, 9, true);
|
|
|
|
Zero(&t, sizeof(t));
|
|
if (CmTrafficLoadFromReg(&t) == false)
|
|
{
|
|
CmTrafficGetDefaultSetting(&t);
|
|
}
|
|
|
|
// Write the settings to the dialog
|
|
Check(hWnd, R_SERVER, t.ServerMode);
|
|
Check(hWnd, R_CLIENT, t.ServerMode == false);
|
|
|
|
c1 = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "HostCandidate");
|
|
if (c1 != NULL)
|
|
{
|
|
UINT i;
|
|
|
|
CbReset(hWnd, C_HOST);
|
|
|
|
for (i = 0;i < LIST_NUM(c1);i++)
|
|
{
|
|
CANDIDATE *c = LIST_DATA(c1, i);
|
|
|
|
CbAddStr(hWnd, C_HOST, c->Str, 0);
|
|
}
|
|
|
|
FreeCandidateList(c1);
|
|
}
|
|
|
|
if (CbNum(hWnd, C_HOST) == 0)
|
|
{
|
|
CbAddStr(hWnd, C_HOST, L"speed.softether.com", 0);
|
|
}
|
|
|
|
if (IsEmptyStr(t.Host) == false)
|
|
{
|
|
SetTextA(hWnd, C_HOST, t.Host);
|
|
}
|
|
|
|
c2 = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "PortCandidate");
|
|
if (c2 != NULL)
|
|
{
|
|
UINT i;
|
|
|
|
if (t.Port != 0)
|
|
{
|
|
wchar_t tmp[32];
|
|
|
|
UniToStru(tmp, t.Port);
|
|
|
|
AddCandidate(c2, tmp, 0);
|
|
}
|
|
|
|
CbReset(hWnd, C_PORT);
|
|
|
|
for (i = 0;i < LIST_NUM(c2);i++)
|
|
{
|
|
CANDIDATE *c = LIST_DATA(c2, i);
|
|
|
|
CbAddStr(hWnd, C_PORT, c->Str, 0);
|
|
}
|
|
|
|
FreeCandidateList(c2);
|
|
}
|
|
|
|
CbReset(hWnd, C_NUM);
|
|
|
|
for (i = 1;i <= TRAFFIC_NUMTCP_MAX;i++)
|
|
{
|
|
wchar_t tmp[32];
|
|
|
|
UniToStru(tmp, i);
|
|
|
|
CbAddStr(hWnd, C_NUM, tmp, i);
|
|
}
|
|
|
|
CbSelect(hWnd, C_NUM, t.NumTcp);
|
|
|
|
Check(hWnd, R_DOWNLOAD, t.Type == TRAFFIC_TYPE_DOWNLOAD);
|
|
Check(hWnd, R_UPLOAD, t.Type == TRAFFIC_TYPE_UPLOAD);
|
|
Check(hWnd, R_FULL, t.Type == TRAFFIC_TYPE_FULL);
|
|
|
|
Check(hWnd, R_ETHERNET, t.Raw ? false : true);
|
|
Check(hWnd, R_DOUBLE, t.Double);
|
|
|
|
SetIntEx(hWnd, E_SPAN, t.Span);
|
|
|
|
CmTrafficDlgUpdate(hWnd);
|
|
}
|
|
|
|
// Put the contents of the dialog to structure
|
|
void CmTrafficDlgToStruct(HWND hWnd, CM_TRAFFIC *t)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || t == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Zero(t, sizeof(CM_TRAFFIC));
|
|
t->ServerMode = IsChecked(hWnd, R_SERVER);
|
|
GetTxtA(hWnd, C_HOST, t->Host, sizeof(t->Host));
|
|
Trim(t->Host);
|
|
|
|
t->Port = GetInt(hWnd, C_PORT);
|
|
t->NumTcp = CbGetSelect(hWnd, C_NUM);
|
|
t->Span = GetInt(hWnd, E_SPAN);
|
|
t->Raw = IsChecked(hWnd, R_ETHERNET) ? false : true;
|
|
t->Double = IsChecked(hWnd, R_DOUBLE);
|
|
|
|
if (IsChecked(hWnd, R_DOWNLOAD))
|
|
{
|
|
t->Type = TRAFFIC_TYPE_DOWNLOAD;
|
|
}
|
|
else if (IsChecked(hWnd, R_UPLOAD))
|
|
{
|
|
t->Type = TRAFFIC_TYPE_UPLOAD;
|
|
}
|
|
else
|
|
{
|
|
t->Type = TRAFFIC_TYPE_FULL;
|
|
}
|
|
}
|
|
|
|
// Communication throughput measurement tool dialog update
|
|
bool CmTrafficDlgUpdate(HWND hWnd)
|
|
{
|
|
CM_TRAFFIC t;
|
|
bool ok = true;
|
|
bool client_only;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
CmTrafficDlgToStruct(hWnd, &t);
|
|
|
|
client_only = t.ServerMode ? false : true;
|
|
|
|
SetEnable(hWnd, C_HOST, client_only);
|
|
SetEnable(hWnd, S_5, client_only);
|
|
SetEnable(hWnd, S_8, client_only);
|
|
SetEnable(hWnd, S_9, client_only);
|
|
SetEnable(hWnd, R_DOWNLOAD, client_only);
|
|
SetEnable(hWnd, R_UPLOAD, client_only);
|
|
SetEnable(hWnd, R_FULL, client_only);
|
|
SetEnable(hWnd, S_10, client_only);
|
|
SetEnable(hWnd, S_11, client_only);
|
|
SetEnable(hWnd, C_NUM, client_only);
|
|
SetEnable(hWnd, S_14, client_only);
|
|
SetEnable(hWnd, S_12, client_only);
|
|
SetEnable(hWnd, E_SPAN, client_only);
|
|
SetEnable(hWnd, S_13, client_only);
|
|
SetEnable(hWnd, R_ETHERNET, client_only);
|
|
SetEnable(hWnd, R_DOUBLE, client_only);
|
|
|
|
if (t.Port == 0 || t.Port >= 65536)
|
|
{
|
|
ok = false;
|
|
}
|
|
|
|
if (t.ServerMode == false)
|
|
{
|
|
if (IsEmptyStr(t.Host))
|
|
{
|
|
ok = false;
|
|
}
|
|
|
|
if (t.NumTcp == 0 || t.NumTcp >= 33)
|
|
{
|
|
ok = false;
|
|
}
|
|
|
|
if (t.Span == 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
|
|
if (t.Type == TRAFFIC_TYPE_FULL && ((t.NumTcp % 2) != 0))
|
|
{
|
|
ok = false;
|
|
}
|
|
}
|
|
|
|
SetEnable(hWnd, IDOK, ok);
|
|
|
|
return ok;
|
|
}
|
|
|
|
// Communication throughput measurement tool dialog OK button
|
|
void CmTrafficDlgOnOk(HWND hWnd)
|
|
{
|
|
CM_TRAFFIC t;
|
|
LIST *c;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the basic data
|
|
CmTrafficDlgToStruct(hWnd, &t);
|
|
|
|
// Save to registry
|
|
CmTrafficSaveToReg(&t);
|
|
|
|
// Retrieve and save the server name candidate
|
|
if (IsEmptyStr(t.Host) == false)
|
|
{
|
|
c = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "HostCandidate");
|
|
if (c != NULL)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
|
|
StrToUni(tmp, sizeof(tmp), t.Host);
|
|
AddCandidate(c, tmp, 0);
|
|
|
|
WriteCandidateToReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, c, "HostCandidate");
|
|
|
|
FreeCandidateList(c);
|
|
}
|
|
}
|
|
|
|
if (t.Port != 0 && t.Port <= 65536)
|
|
{
|
|
// Retrieve and store the port number candidate
|
|
c = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "PortCandidate");
|
|
if (c != NULL)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
|
|
UniToStru(tmp, t.Port);
|
|
AddCandidate(c, tmp, 0);
|
|
|
|
WriteCandidateToReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, c, "PortCandidate");
|
|
|
|
FreeCandidateList(c);
|
|
}
|
|
}
|
|
|
|
// Execute
|
|
CmExecTraffic(hWnd, &t);
|
|
|
|
// Update the dialog
|
|
CmTrafficDlgInit(hWnd);
|
|
}
|
|
|
|
// Communication throughput measurement tool dialog procedure
|
|
UINT CmTrafficDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetIcon(hWnd, 0, ICO_SWITCH);
|
|
CmTrafficDlgInit(hWnd);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case R_SERVER:
|
|
case R_CLIENT:
|
|
case C_HOST:
|
|
case C_PORT:
|
|
case R_DOWNLOAD:
|
|
case R_UPLOAD:
|
|
case R_FULL:
|
|
case C_NUM:
|
|
case E_SPAN:
|
|
case R_ETHERNET:
|
|
case R_DOUBLE:
|
|
CmTrafficDlgUpdate(hWnd);
|
|
break;
|
|
}
|
|
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
CmTrafficDlgOnOk(hWnd);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Communication throughput measurement tool
|
|
void CmTraffic(HWND hWnd)
|
|
{
|
|
Dialog(hWnd, D_CM_TRAFFIC, CmTrafficDlgProc, NULL);
|
|
}
|
|
|
|
// Delete old startup file
|
|
void CmDeleteOldStartupTrayFile()
|
|
{
|
|
char tmp[MAX_SIZE];
|
|
char *tag = _SS("CM_JAPANESE_ONLY_OLD_STARTUP");
|
|
if (IsEmptyStr(tag))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Format(tmp, sizeof(tmp), tag, MsGetCommonStartupDir());
|
|
|
|
FileDelete(tmp);
|
|
}
|
|
|
|
// PKCS license confirmation dialog
|
|
UINT CmPkcsEulaDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
UINT id;
|
|
SECURE_DEVICE *dev;
|
|
char *name;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
id = (UINT)param;
|
|
dev = GetSecureDevice(id);
|
|
if (dev == NULL)
|
|
{
|
|
EndDialog(hWnd, 0);
|
|
return 0;
|
|
}
|
|
|
|
name = dev->ModuleName;
|
|
|
|
FormatText(hWnd, S_INFO_1, name);
|
|
FormatText(hWnd, S_INFO_2, name, name);
|
|
FormatText(hWnd, S_INFO_3, name);
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
EndDialog(hWnd, 1);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Confirmation screen of whether the user accepts the EULA of the PKCS DLL
|
|
bool CmCheckPkcsEula(HWND hWnd, UINT id)
|
|
{
|
|
return (Dialog(hWnd, D_CM_PKCSEULA, CmPkcsEulaDlg, (void *)id) == 0) ? false : true;
|
|
}
|
|
|
|
// Update controls
|
|
void CmSecurePinDlgUpdate(HWND hWnd)
|
|
{
|
|
char *tmp1, *tmp2, *tmp3;
|
|
bool ok = true;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
tmp1 = GetTextA(hWnd, E_PIN1);
|
|
tmp2 = GetTextA(hWnd, E_PIN2);
|
|
tmp3 = GetTextA(hWnd, E_PIN3);
|
|
if (IsEmptyStr(tmp1))
|
|
{
|
|
ok = false;
|
|
}
|
|
if (IsEmptyStr(tmp2))
|
|
{
|
|
ok = false;
|
|
}
|
|
if (IsEmptyStr(tmp3))
|
|
{
|
|
ok = false;
|
|
}
|
|
if (StrCmp(tmp2, tmp3) != 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
Free(tmp1);
|
|
Free(tmp2);
|
|
Free(tmp3);
|
|
SetEnable(hWnd, IDOK, ok);
|
|
}
|
|
|
|
// PIN code changing dialog
|
|
UINT CmSecurePinDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
UINT id = (UINT)param;
|
|
char *src, *dst;
|
|
SECURE *s;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CmSecurePinDlgUpdate(hWnd);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case E_PIN1:
|
|
case E_PIN2:
|
|
case E_PIN3:
|
|
CmSecurePinDlgUpdate(hWnd);
|
|
break;
|
|
}
|
|
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
src = GetTextA(hWnd, E_PIN1);
|
|
dst = GetTextA(hWnd, E_PIN3);
|
|
|
|
Disable(hWnd, IDOK);
|
|
Disable(hWnd, IDCANCEL);
|
|
|
|
s = OpenSec(id);
|
|
if (s == NULL)
|
|
{
|
|
if (GetSecureDevice(id) != NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),
|
|
GetSecureDevice(id)->DeviceName);
|
|
}
|
|
else
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),
|
|
"Unknown");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (OpenSecSession(s, 0) == false)
|
|
{
|
|
if (GetSecureDevice(id) != NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),
|
|
GetSecureDevice(id)->DeviceName);
|
|
}
|
|
else
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),
|
|
"Unknown");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (LoginSec(s, src) == false)
|
|
{
|
|
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_CURRENT_BAD"));
|
|
FocusEx(hWnd, E_PIN1);
|
|
}
|
|
else
|
|
{
|
|
if (ChangePin(s, src, dst) == false)
|
|
{
|
|
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_CHANGE_FAILED"));
|
|
FocusEx(hWnd, E_PIN1);
|
|
}
|
|
else
|
|
{
|
|
// Clear the cache for PIN code
|
|
cached_pin_code_expires = 0;
|
|
cached_pin_code[0] = 0;
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_PIN_OK"));
|
|
EndDialog(hWnd, true);
|
|
}
|
|
|
|
LogoutSec(s);
|
|
}
|
|
|
|
CloseSecSession(s);
|
|
}
|
|
CloseSec(s);
|
|
}
|
|
|
|
Enable(hWnd, IDOK);
|
|
Enable(hWnd, IDCANCEL);
|
|
|
|
Free(src);
|
|
Free(dst);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Change the PIN code
|
|
void CmSecurePin(HWND hWnd, UINT id)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || id == 0 || CheckSecureDeviceId(id) == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Dialog(hWnd, D_CM_SECURE_PIN, CmSecurePinDlg, (void *)id);
|
|
}
|
|
|
|
// Object type selection dialog
|
|
UINT CmSecureTypeDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
UINT type;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
type = MsRegReadInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "DefaultImportType");
|
|
Check(hWnd, R_DATA, type == SEC_DATA);
|
|
Check(hWnd, R_CERT, type == SEC_X);
|
|
Check(hWnd, R_KEY, type == SEC_K);
|
|
goto UPDATE_CONTROL;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
type = SEC_DATA;
|
|
if (IsChecked(hWnd, R_CERT))
|
|
{
|
|
type = SEC_X;
|
|
}
|
|
else if (IsChecked(hWnd, R_KEY))
|
|
{
|
|
type = SEC_K;
|
|
}
|
|
|
|
MsRegWriteInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "DefaultImportType", type);
|
|
|
|
EndDialog(hWnd, type);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
case R_CERT:
|
|
case R_KEY:
|
|
case R_DATA:
|
|
UPDATE_CONTROL:
|
|
SetEnable(hWnd, IDOK, IsChecked(hWnd, R_CERT) ||
|
|
IsChecked(hWnd, R_KEY) ||
|
|
IsChecked(hWnd, R_DATA));
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, INFINITE);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Object type selection
|
|
UINT CmSecureType(HWND hWnd)
|
|
{
|
|
return Dialog(hWnd, D_CM_SECURE_TYPE, CmSecureTypeDlg, NULL);
|
|
}
|
|
|
|
// Initialize the dialog
|
|
void CmSecureManagerDlgInit(HWND hWnd, UINT id)
|
|
{
|
|
SECURE_DEVICE *dev;
|
|
// Validate arguments
|
|
if (hWnd == NULL || id == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetIcon(hWnd, 0, ICO_SECURE);
|
|
|
|
dev = GetSecureDevice(id);
|
|
if (dev != NULL)
|
|
{
|
|
FormatText(hWnd, S_INFO, dev->DeviceName);
|
|
}
|
|
|
|
SetFont(hWnd, B_BOLD, Font(0, true));
|
|
|
|
LvInit(hWnd, L_LIST);
|
|
LvInsertColumn(hWnd, L_LIST, 0, _UU("SEC_MGR_COLUMN1"), 200);
|
|
LvInsertColumn(hWnd, L_LIST, 1, _UU("SEC_MGR_COLUMN2"), 110);
|
|
|
|
CmSecureManagerDlgUpdate(hWnd, id);
|
|
}
|
|
|
|
// Update controls
|
|
void CmSecureManagerDlgUpdate(HWND hWnd, UINT id)
|
|
{
|
|
bool b = true;
|
|
bool read_only = IsJPKI(id);
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (LvIsSingleSelected(hWnd, L_LIST) == false)
|
|
{
|
|
b = false;
|
|
}
|
|
|
|
SetEnable(hWnd, B_EXPORT, b && ((UINT)LvGetParam(hWnd, L_LIST, LvGetSelected(hWnd, L_LIST)) != SEC_K));
|
|
SetEnable(hWnd, B_DELETE, b && (read_only == false));
|
|
SetEnable(hWnd, B_PIN, (read_only == false));
|
|
SetEnable(hWnd, B_IMPORT, (read_only == false));
|
|
SetEnable(hWnd, B_NEW_CERT, (read_only == false));
|
|
}
|
|
|
|
// Content update
|
|
void CmSecureManagerDlgRefresh(HWND hWnd, UINT id)
|
|
{
|
|
bool ret;
|
|
LIST *o;
|
|
WINUI_SECURE_BATCH batch[] =
|
|
{
|
|
{WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},
|
|
};
|
|
// Validate arguments
|
|
if (hWnd == NULL || id == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ret = SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0);
|
|
|
|
if (ret == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
o = batch[0].EnumList;
|
|
if (o != NULL)
|
|
{
|
|
CmSecureManagerDlgPrintList(hWnd, o);
|
|
|
|
FreeEnumSecObject(o);
|
|
}
|
|
|
|
// update controls
|
|
CmSecureManagerDlgUpdate(hWnd, id);
|
|
}
|
|
|
|
// Show the list of secure objects
|
|
void CmSecureManagerDlgPrintList(HWND hWnd, LIST *o)
|
|
{
|
|
CmSecureManagerDlgPrintListEx(hWnd, L_LIST, o, INFINITE);
|
|
}
|
|
void CmSecureManagerDlgPrintListEx(HWND hWnd, UINT id, LIST *o, UINT type)
|
|
{
|
|
UINT i;
|
|
LVB *v;
|
|
// Validate arguments
|
|
if (hWnd == NULL || o == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LvReset(hWnd, id);
|
|
|
|
v = LvInsertStart();
|
|
|
|
for (i = 0;i < LIST_NUM(o);i++)
|
|
{
|
|
UINT icon = ICO_LOG2;
|
|
wchar_t tmp1[MAX_SIZE], *tmp2, *tmp3;
|
|
SEC_OBJ *obj = LIST_DATA(o, i);
|
|
|
|
if (type == INFINITE || obj->Type == type)
|
|
{
|
|
StrToUni(tmp1, sizeof(tmp1), obj->Name);
|
|
tmp2 = CmSecureObjTypeToStr(obj->Type);
|
|
tmp3 = obj->Private ? _UU("SEC_YES") : _UU("SEC_NO");
|
|
|
|
if (obj->Type == SEC_X)
|
|
{
|
|
icon = ICO_CERT;
|
|
}
|
|
else if (obj->Type == SEC_K || obj->Type == SEC_P)
|
|
{
|
|
icon = ICO_KEY;
|
|
}
|
|
|
|
LvInsertAdd(v, icon, (void *)obj->Type, 2, tmp1, tmp2);
|
|
}
|
|
}
|
|
|
|
LvInsertEnd(v, hWnd, id);
|
|
}
|
|
|
|
// Convert the type of secure object to a string
|
|
wchar_t *CmSecureObjTypeToStr(UINT type)
|
|
{
|
|
wchar_t *ret = _UU("SEC_TYPE_DATA");
|
|
|
|
if (type == SEC_X)
|
|
{
|
|
ret = _UU("SEC_TYPE_CERT");
|
|
}
|
|
else if (type == SEC_K)
|
|
{
|
|
ret = _UU("SEC_TYPE_KEY");
|
|
}
|
|
else if (type == SEC_P)
|
|
{
|
|
ret = _UU("SEC_TYPE_PUB");
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Write by creating a new certificate
|
|
void CmSecureManagerDlgNewCert(HWND hWnd, UINT id)
|
|
{
|
|
X *x;
|
|
K *k;
|
|
char default_name[MAX_SIZE];
|
|
char *object_name;
|
|
bool ok = false;
|
|
WINUI_SECURE_BATCH batch[] =
|
|
{
|
|
{WINUI_SECURE_WRITE_CERT, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL},
|
|
{WINUI_SECURE_WRITE_KEY, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL},
|
|
{WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},
|
|
};
|
|
// Validate arguments
|
|
if (hWnd == NULL || id == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Dialog for creating certificate
|
|
if (SmCreateCert(hWnd, &x, &k, true, NULL, false) == false)
|
|
{
|
|
return;
|
|
}
|
|
// Generate the default name
|
|
GetPrintNameFromXA(default_name, sizeof(default_name), x);
|
|
ConvertSafeFileName(default_name, sizeof(default_name), default_name);
|
|
|
|
object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),
|
|
_UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_CERT, false, false);
|
|
|
|
if (object_name != NULL)
|
|
{
|
|
// Enumerate and write
|
|
batch[0].InputX = x;
|
|
batch[0].Name = object_name;
|
|
batch[1].InputK = k;
|
|
batch[1].Name = object_name;
|
|
|
|
if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
|
|
{
|
|
// Failure
|
|
}
|
|
else
|
|
{
|
|
ok = true;
|
|
}
|
|
|
|
Free(object_name);
|
|
}
|
|
|
|
if (ok)
|
|
{
|
|
LIST *o = batch[2].EnumList;
|
|
|
|
CmSecureManagerDlgPrintList(hWnd, o);
|
|
|
|
FreeEnumSecObject(o);
|
|
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_NEW_CERT_IMPORT_OK"));
|
|
}
|
|
|
|
FreeX(x);
|
|
FreeK(k);
|
|
}
|
|
|
|
// Import
|
|
void CmSecureManagerDlgImport(HWND hWnd, UINT id)
|
|
{
|
|
UINT type;
|
|
char name[MAX_SIZE];
|
|
wchar_t tmp2[MAX_SIZE];
|
|
wchar_t *tmp;
|
|
wchar_t *filename;
|
|
BUF *b;
|
|
K *k;
|
|
bool ok = false;
|
|
X *x;
|
|
WINUI_SECURE_BATCH batch[] =
|
|
{
|
|
{WINUI_SECURE_WRITE_DATA, name, true, NULL, NULL, NULL, NULL, NULL, NULL},
|
|
{WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},
|
|
};
|
|
// Validate arguments
|
|
if (hWnd == NULL || id == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Select the type of secure object
|
|
type = CmSecureType(hWnd);
|
|
|
|
switch (type)
|
|
{
|
|
case SEC_DATA:
|
|
// Data
|
|
tmp = OpenDlg(hWnd, _UU("DLG_ALL_FILES"), _UU("SEC_IMPORT_DATA"));
|
|
if (tmp == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
filename = CopyUniStr(tmp);
|
|
Free(tmp);
|
|
|
|
// Read the file
|
|
b = ReadDumpW(filename);
|
|
if (b == NULL)
|
|
{
|
|
// Read failure
|
|
MsgBox(hWnd, MB_ICONSTOP, _UU("SEC_READ_FAILED"));
|
|
}
|
|
else
|
|
{
|
|
if (b->Size > MAX_SEC_DATA_SIZE)
|
|
{
|
|
// File size is too large
|
|
MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_DATA_TOO_BIG"), MAX_SEC_DATA_SIZE);
|
|
}
|
|
else
|
|
{
|
|
// Generate the default name
|
|
char default_name[MAX_SIZE];
|
|
wchar_t default_name_w[MAX_SIZE];
|
|
char *object_name;
|
|
GetFileNameFromFilePathW(default_name_w, sizeof(default_name_w), filename);
|
|
UniToStr(default_name, sizeof(default_name), default_name_w);
|
|
ConvertSafeFileName(default_name, sizeof(default_name), default_name);
|
|
|
|
object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),
|
|
_UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_LOG2, false, false);
|
|
|
|
if (object_name != NULL)
|
|
{
|
|
// Enumerate and write
|
|
batch[0].InputData = b;
|
|
batch[0].Name = object_name;
|
|
|
|
if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
|
|
{
|
|
// Failure
|
|
}
|
|
else
|
|
{
|
|
ok = true;
|
|
}
|
|
|
|
Free(object_name);
|
|
}
|
|
}
|
|
|
|
FreeBuf(b);
|
|
}
|
|
|
|
Free(filename);
|
|
break;
|
|
|
|
case SEC_X:
|
|
// Read a certificate
|
|
if (CmLoadXExW(hWnd, &x, tmp2, sizeof(tmp2)))
|
|
{
|
|
// Generate the default name
|
|
char default_name[MAX_SIZE];
|
|
wchar_t default_name_w[MAX_PATH];
|
|
char *object_name;
|
|
GetFileNameFromFilePathW(default_name_w, sizeof(default_name_w), tmp2);
|
|
UniToStr(default_name, sizeof(default_name), default_name_w);
|
|
ConvertSafeFileName(default_name, sizeof(default_name), default_name);
|
|
|
|
object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),
|
|
_UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_CERT, false, false);
|
|
|
|
if (object_name != NULL)
|
|
{
|
|
// Enumerate and write
|
|
batch[0].Type = WINUI_SECURE_WRITE_CERT;
|
|
batch[0].InputX = x;
|
|
batch[0].Name = object_name;
|
|
|
|
if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
|
|
{
|
|
// Failure
|
|
}
|
|
else
|
|
{
|
|
ok = true;
|
|
}
|
|
|
|
Free(object_name);
|
|
}
|
|
|
|
FreeX(x);
|
|
}
|
|
|
|
break;
|
|
|
|
case SEC_K:
|
|
// Secret key
|
|
if (CmLoadKExW(hWnd, &k, tmp2, sizeof(tmp2)))
|
|
{
|
|
// Generate the default name
|
|
char default_name[MAX_SIZE];
|
|
wchar_t default_name_w[MAX_PATH];
|
|
char *object_name;
|
|
GetFileNameFromFilePathW(default_name_w, sizeof(default_name_w), tmp2);
|
|
UniToStr(default_name, sizeof(default_name), default_name_w);
|
|
ConvertSafeFileName(default_name, sizeof(default_name), default_name);
|
|
|
|
object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),
|
|
_UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_KEY, false, false);
|
|
|
|
if (object_name != NULL)
|
|
{
|
|
// Enumerate and write
|
|
batch[0].Type = WINUI_SECURE_WRITE_KEY;
|
|
batch[0].InputK = k;
|
|
batch[0].Name = object_name;
|
|
|
|
if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
|
|
{
|
|
// Failure
|
|
}
|
|
else
|
|
{
|
|
ok = true;
|
|
}
|
|
|
|
Free(object_name);
|
|
}
|
|
|
|
FreeK(k);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
// Invalid
|
|
return;
|
|
}
|
|
|
|
if (ok)
|
|
{
|
|
LIST *o = batch[1].EnumList;
|
|
|
|
CmSecureManagerDlgPrintList(hWnd, o);
|
|
|
|
FreeEnumSecObject(o);
|
|
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_OBJECT_IMPORT_OK"));
|
|
}
|
|
}
|
|
|
|
// Export the object
|
|
void CmSecureManagerDlgExport(HWND hWnd, UINT id)
|
|
{
|
|
char name[MAX_SIZE];
|
|
UINT method = WINUI_SECURE_READ_DATA;
|
|
char *tmp;
|
|
UINT type;
|
|
wchar_t filename[MAX_PATH];
|
|
wchar_t *uni_tmp;
|
|
X *x;
|
|
BUF *b;
|
|
wchar_t default_name[128];
|
|
WINUI_SECURE_BATCH batch[] =
|
|
{
|
|
{WINUI_SECURE_READ_DATA, name, true, NULL, NULL, NULL, NULL, NULL, NULL},
|
|
};
|
|
UINT i;
|
|
// Validate arguments
|
|
if (hWnd == NULL || id == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
i = LvGetSelected(hWnd, L_LIST);
|
|
if (i == INFINITE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
tmp = LvGetStrA(hWnd, L_LIST, i, 0);
|
|
StrCpy(name, sizeof(name), tmp);
|
|
Free(tmp);
|
|
|
|
type = (UINT)LvGetParam(hWnd, L_LIST, i);
|
|
|
|
switch (type)
|
|
{
|
|
case SEC_X:
|
|
method = WINUI_SECURE_READ_CERT;
|
|
break;
|
|
|
|
default:
|
|
method = WINUI_SECURE_READ_DATA;
|
|
break;
|
|
}
|
|
|
|
batch[0].Type = method;
|
|
|
|
// Operate the smart card
|
|
if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (type)
|
|
{
|
|
case SEC_X:
|
|
// Certificate
|
|
x = batch[0].OutputX;
|
|
|
|
CertDlg(hWnd, x, NULL, true);
|
|
|
|
FreeX(x);
|
|
break;
|
|
|
|
default:
|
|
// File
|
|
b = batch[0].OutputData;
|
|
StrToUni(default_name, sizeof(default_name), name);
|
|
uni_tmp = SaveDlg(hWnd, _UU("DLG_ALL_FILES"), _UU("DLG_SAVE_FILE"), default_name, NULL);
|
|
|
|
if (uni_tmp != NULL)
|
|
{
|
|
UniStrCpy(filename, sizeof(filename), uni_tmp);
|
|
|
|
DumpBufW(b, filename);
|
|
|
|
Free(uni_tmp);
|
|
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_OBJECT_EXPORT_OK"));
|
|
}
|
|
|
|
|
|
FreeBuf(b);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Delete the object
|
|
void CmSecureManagerDlgDelete(HWND hWnd, UINT id)
|
|
{
|
|
char name[MAX_SIZE];
|
|
UINT method = WINUI_SECURE_DELETE_DATA;
|
|
char *tmp;
|
|
UINT type;
|
|
LIST *o;
|
|
WINUI_SECURE_BATCH batch[] =
|
|
{
|
|
{WINUI_SECURE_DELETE_OBJECT, name, false, NULL, NULL, NULL, NULL, NULL, NULL},
|
|
{WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},
|
|
};
|
|
UINT i;
|
|
// Validate arguments
|
|
if (hWnd == NULL || id == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
i = LvGetSelected(hWnd, L_LIST);
|
|
if (i == INFINITE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
tmp = LvGetStrA(hWnd, L_LIST, i, 0);
|
|
StrCpy(name, sizeof(name), tmp);
|
|
Free(tmp);
|
|
|
|
type = (UINT)LvGetParam(hWnd, L_LIST, i);
|
|
|
|
switch (type)
|
|
{
|
|
case SEC_X:
|
|
method = WINUI_SECURE_DELETE_CERT;
|
|
break;
|
|
|
|
case SEC_K:
|
|
method = WINUI_SECURE_DELETE_KEY;
|
|
break;
|
|
|
|
default:
|
|
method = WINUI_SECURE_DELETE_DATA;
|
|
break;
|
|
}
|
|
|
|
batch[0].Type = method;
|
|
|
|
if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
o = batch[1].EnumList;
|
|
|
|
CmSecureManagerDlgPrintList(hWnd, o);
|
|
|
|
FreeEnumSecObject(o);
|
|
}
|
|
|
|
static bool cm_secure_manager_no_new_cert = false;
|
|
|
|
// Smart Card Manager dialog
|
|
UINT CmSecureManagerDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
NMHDR *n;
|
|
UINT id = (UINT)param;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CmSecureManagerDlgInit(hWnd, id);
|
|
|
|
if (cm_secure_manager_no_new_cert)
|
|
{
|
|
Hide(hWnd, B_NEW_CERT);
|
|
}
|
|
|
|
SetTimer(hWnd, 1, 1, NULL);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case B_REFRESH:
|
|
CmSecureManagerDlgRefresh(hWnd, id);
|
|
break;
|
|
|
|
case B_IMPORT:
|
|
CmSecureManagerDlgImport(hWnd, id);
|
|
break;
|
|
|
|
case B_EXPORT:
|
|
CmSecureManagerDlgExport(hWnd, id);
|
|
break;
|
|
|
|
case B_DELETE:
|
|
if (MsgBox(hWnd, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2,
|
|
_UU("SEC_DELETE_MSG")) == IDYES)
|
|
{
|
|
CmSecureManagerDlgDelete(hWnd, id);
|
|
}
|
|
break;
|
|
|
|
case B_NEW_CERT:
|
|
CmSecureManagerDlgNewCert(hWnd, id);
|
|
break;
|
|
|
|
case B_PIN:
|
|
CmSecurePin(hWnd, id);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
switch (wParam)
|
|
{
|
|
case 1:
|
|
KillTimer(hWnd, 1);
|
|
|
|
CmSecureManagerDlgRefresh(hWnd, id);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
n = (NMHDR *)lParam;
|
|
switch (n->idFrom)
|
|
{
|
|
case L_LIST:
|
|
switch (n->code)
|
|
{
|
|
case LVN_ITEMCHANGED:
|
|
CmSecureManagerDlgUpdate(hWnd, id);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Smart Card Manager
|
|
void CmSecureManager(HWND hWnd, UINT id)
|
|
{
|
|
CmSecureManagerEx(hWnd, id, false);
|
|
}
|
|
void CmSecureManagerEx(HWND hWnd, UINT id, bool no_new_cert)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || id == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// ID check
|
|
if (CheckSecureDeviceId(id) == false)
|
|
{
|
|
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SEC_INVALID_ID"));
|
|
return;
|
|
}
|
|
|
|
if (no_new_cert)
|
|
{
|
|
cm_secure_manager_no_new_cert = true;
|
|
}
|
|
else
|
|
{
|
|
cm_secure_manager_no_new_cert = false;
|
|
}
|
|
|
|
Dialog(hWnd, D_CM_SECURE_MANAGER, CmSecureManagerDlg, (void *)id);
|
|
}
|
|
|
|
// Smart Card Manager for Client
|
|
void CmClientSecureManager(HWND hWnd)
|
|
{
|
|
RPC_USE_SECURE t;
|
|
UINT id;
|
|
|
|
Zero(&t, sizeof(t));
|
|
CcGetUseSecure(cm->Client, &t);
|
|
|
|
id = t.DeviceId;
|
|
|
|
if (id == 0 || CheckSecureDeviceId(id) == false)
|
|
{
|
|
id = CmClientSelectSecure(hWnd);
|
|
}
|
|
|
|
if (id == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CmSecureManager(hWnd, id);
|
|
}
|
|
|
|
// Initialize the dialog
|
|
void CmSelectSecureDlgInit(HWND hWnd, UINT default_id)
|
|
{
|
|
UINT i;
|
|
LIST *o;
|
|
LVB *v;
|
|
|
|
SetIcon(hWnd, 0, ICO_SECURE);
|
|
|
|
o = GetSecureDeviceList();
|
|
|
|
LvInit(hWnd, L_LIST);
|
|
LvInsertColumn(hWnd, L_LIST, 0, _UU("SEC_COLUMN1"), 150);
|
|
LvInsertColumn(hWnd, L_LIST, 1, _UU("SEC_COLUMN2"), 100);
|
|
LvInsertColumn(hWnd, L_LIST, 2, _UU("SEC_COLUMN3"), 130);
|
|
LvInsertColumn(hWnd, L_LIST, 3, _UU("SEC_COLUMN4"), 100);
|
|
|
|
v = LvInsertStart();
|
|
|
|
for (i = 0;i < LIST_NUM(o);i++)
|
|
{
|
|
wchar_t tmp1[MAX_SIZE];
|
|
wchar_t *tmp2;
|
|
wchar_t tmp3[MAX_SIZE];
|
|
wchar_t tmp4[MAX_SIZE];
|
|
SECURE_DEVICE *dev = LIST_DATA(o, i);
|
|
|
|
StrToUni(tmp1, sizeof(tmp1), dev->DeviceName);
|
|
tmp2 = (dev->Type == SECURE_IC_CARD) ? _UU("SEC_SMART_CARD") : _UU("SEC_USB_TOKEN");
|
|
StrToUni(tmp3, sizeof(tmp3), dev->Manufacturer);
|
|
StrToUni(tmp4, sizeof(tmp4), dev->ModuleName);
|
|
|
|
LvInsertAdd(v, ICO_SECURE, (void *)dev->Id, 4, tmp1, tmp2, tmp3, tmp4);
|
|
}
|
|
|
|
LvInsertEnd(v, hWnd, L_LIST);
|
|
|
|
if (default_id != 0)
|
|
{
|
|
LvSelect(hWnd, L_LIST, LvSearchParam(hWnd, L_LIST, (void *)default_id));
|
|
}
|
|
|
|
ReleaseList(o);
|
|
|
|
// Control update
|
|
CmSelectSecureDlgUpdate(hWnd);
|
|
}
|
|
|
|
// Update controls of the dialog
|
|
void CmSelectSecureDlgUpdate(HWND hWnd)
|
|
{
|
|
SetEnable(hWnd, IDOK, LvIsSingleSelected(hWnd, L_LIST));
|
|
}
|
|
|
|
// Smart card selection dialog
|
|
UINT CmSelectSecureDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
UINT default_id = (UINT)param;
|
|
NMHDR *n = NULL;
|
|
static UINT old_id;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
old_id = default_id;
|
|
CmSelectSecureDlgInit(hWnd, default_id);
|
|
|
|
if (LvNum(hWnd, L_LIST) == 0)
|
|
{
|
|
// There is no smart card
|
|
SetTimer(hWnd, 1, 100, NULL);
|
|
}
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
switch (wParam)
|
|
{
|
|
case 1:
|
|
KillTimer(hWnd, 1);
|
|
|
|
Disable(hWnd, L_LIST);
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_NO_SECURE_DEVICE"));
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
if (IsEnable(hWnd, IDOK))
|
|
{
|
|
UINT i = LvGetSelected(hWnd, L_LIST);
|
|
if (i != INFINITE)
|
|
{
|
|
UINT id = (UINT)LvGetParam(hWnd, L_LIST, i);
|
|
|
|
if (old_id != id)
|
|
{
|
|
if (CmCheckPkcsEula(hWnd, id) == false)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
EndDialog(hWnd, id);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
n = (NMHDR *)lParam;
|
|
switch (n->idFrom)
|
|
{
|
|
case L_LIST:
|
|
switch (n->code)
|
|
{
|
|
case LVN_ITEMCHANGED:
|
|
CmSelectSecureDlgUpdate(hWnd);
|
|
break;
|
|
case NM_DBLCLK:
|
|
Command(hWnd, IDOK);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Select the smart card device to be used
|
|
UINT CmSelectSecure(HWND hWnd, UINT current_id)
|
|
{
|
|
return Dialog(hWnd, D_CM_SELECT_SECURE, CmSelectSecureDlg, (void *)current_id);
|
|
}
|
|
|
|
// Select the smart card device to be used (client)
|
|
UINT CmClientSelectSecure(HWND hWnd)
|
|
{
|
|
UINT id;
|
|
RPC_USE_SECURE t;
|
|
|
|
if (cm->server_name != NULL)
|
|
{
|
|
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("CM_SECURE_MUST_LOCAL"));
|
|
return 0;
|
|
}
|
|
|
|
Zero(&t, sizeof(t));
|
|
CcGetUseSecure(cm->Client, &t);
|
|
|
|
id = t.DeviceId;
|
|
|
|
id = CmSelectSecure(hWnd, id);
|
|
if (id != 0)
|
|
{
|
|
Zero(&t, sizeof(t));
|
|
t.DeviceId = id;
|
|
|
|
CALL(hWnd, CcUseSecure(cm->Client, &t));
|
|
|
|
SmWriteSelectSecureIdReg(id);
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
// Shortcut connection
|
|
void CmConnectShortcut(UCHAR *key)
|
|
{
|
|
UINT ret;
|
|
// Validate arguments
|
|
if (key == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Attempt to connect
|
|
ret = CcShortcut(key);
|
|
|
|
if (ret != ERR_NO_ERROR)
|
|
{
|
|
if (ret == ERR_ACCOUNT_ACTIVE)
|
|
{
|
|
// Because it is currently connected, to query whether or not to disconnect
|
|
if (MsgBox(NULL, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_SHORTCUT_DISCONNECT")) == IDYES)
|
|
{
|
|
// Try to disconnect
|
|
ret = CcShortcutDisconnect(key);
|
|
|
|
if (ret != ERR_NO_ERROR)
|
|
{
|
|
// Error
|
|
MsgBox(NULL, MB_ICONEXCLAMATION, GetUniErrorStr(ret));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Other errors
|
|
MsgBox(NULL, MB_ICONEXCLAMATION, GetUniErrorStr(ret));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Play the audio guide
|
|
void CmVoice(char *name)
|
|
{
|
|
UINT i;
|
|
// Validate arguments
|
|
if (name == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Voice guidance features disappeared!!
|
|
return;
|
|
|
|
if (cm->DisableVoice)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (i = 0;i < sizeof(cm_voice) / sizeof(CM_VOICE);i++)
|
|
{
|
|
if (cm_voice[i].voice_id == cm->VoiceId)
|
|
{
|
|
char tmp[MAX_SIZE];
|
|
Format(tmp, sizeof(tmp), "%s_%s.wav", cm_voice[i].perfix, name);
|
|
MsPlaySound(tmp);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Update the password changing dialog
|
|
void CmChangePasswordUpdate(HWND hWnd, CM_CHANGE_PASSWORD *p)
|
|
{
|
|
bool ok = true;
|
|
char *s1, *s2;
|
|
// Validate arguments
|
|
if (hWnd == NULL || p == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IsEmpty(hWnd, E_USERNAME))
|
|
{
|
|
ok = false;
|
|
}
|
|
|
|
s1 = GetTextA(hWnd, E_NEW_PASSWORD1);
|
|
s2 = GetTextA(hWnd, E_NEW_PASSWORD2);
|
|
|
|
if (StrCmp(s1, s2) != 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
|
|
Free(s1);
|
|
Free(s2);
|
|
|
|
SetEnable(hWnd, IDOK, ok);
|
|
}
|
|
|
|
// Password changing dialog procedure
|
|
UINT CmChangePasswordProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
CM_CHANGE_PASSWORD *p = (CM_CHANGE_PASSWORD *)param;
|
|
char username[MAX_USERNAME_LEN + 1];
|
|
char old_pass[MAX_PASSWORD_LEN + 1];
|
|
char new_pass[MAX_PASSWORD_LEN + 1];
|
|
UINT ret;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetTextA(hWnd, E_HUBNAME, p->HubName);
|
|
SetTextA(hWnd, E_USERNAME, p->Username);
|
|
FormatText(hWnd, S_TITLE, p->ClientOption->Hostname);
|
|
|
|
if (IsEmpty(hWnd, E_USERNAME))
|
|
{
|
|
FocusEx(hWnd, E_USERNAME);
|
|
}
|
|
else
|
|
{
|
|
FocusEx(hWnd, E_OLD_PASSWORD);
|
|
}
|
|
|
|
CmChangePasswordUpdate(hWnd, p);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case E_USERNAME:
|
|
case E_OLD_PASSWORD:
|
|
case E_NEW_PASSWORD1:
|
|
case E_NEW_PASSWORD2:
|
|
CmChangePasswordUpdate(hWnd, p);
|
|
break;
|
|
}
|
|
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
GetTxtA(hWnd, E_USERNAME, username, sizeof(username));
|
|
GetTxtA(hWnd, E_OLD_PASSWORD, old_pass, sizeof(old_pass));
|
|
GetTxtA(hWnd, E_NEW_PASSWORD1, new_pass, sizeof(new_pass));
|
|
|
|
Disable(hWnd, E_USERNAME);
|
|
Disable(hWnd, E_OLD_PASSWORD);
|
|
Disable(hWnd, E_NEW_PASSWORD1);
|
|
Disable(hWnd, E_NEW_PASSWORD2);
|
|
Disable(hWnd, IDOK);
|
|
Disable(hWnd, IDCANCEL);
|
|
|
|
ret = ChangePassword(cm->Cedar, p->ClientOption, p->HubName, username, old_pass, new_pass);
|
|
|
|
if (ret == ERR_NO_ERROR)
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PASSWORD_CHANGED"));
|
|
EndDialog(hWnd, true);
|
|
}
|
|
else
|
|
{
|
|
MsgBox(hWnd, MB_ICONSTOP, _E(ret));
|
|
Enable(hWnd, E_USERNAME);
|
|
Enable(hWnd, E_OLD_PASSWORD);
|
|
Enable(hWnd, E_NEW_PASSWORD1);
|
|
Enable(hWnd, E_NEW_PASSWORD2);
|
|
Enable(hWnd, IDOK);
|
|
Enable(hWnd, IDCANCEL);
|
|
|
|
SetTextA(hWnd, E_OLD_PASSWORD, "");
|
|
SetTextA(hWnd, E_NEW_PASSWORD1, "");
|
|
SetTextA(hWnd, E_NEW_PASSWORD2, "");
|
|
|
|
Focus(hWnd, E_OLD_PASSWORD);
|
|
}
|
|
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Show the password changing dialog
|
|
void CmChangePassword(HWND hWnd, CLIENT_OPTION *o, char *hubname, char *username)
|
|
{
|
|
CM_CHANGE_PASSWORD p;
|
|
// Validate arguments
|
|
if (hWnd == NULL || o == NULL || hubname == NULL || username == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Zero(&p, sizeof(p));
|
|
StrCpy(p.Username, sizeof(p.Username), username);
|
|
StrCpy(p.HubName, sizeof(p.HubName), hubname);
|
|
p.ClientOption = o;
|
|
|
|
CmVoice("password");
|
|
|
|
Dialog(hWnd, D_CM_CHANGE_PASSWORD, CmChangePasswordProc, &p);
|
|
}
|
|
|
|
// Prohibit the installation of the virtual LAN card
|
|
bool CmStopInstallVLan(HWND hWnd)
|
|
{
|
|
if (cm->Client->Unix)
|
|
{
|
|
// There is no need to be prohibited if the client is an UNIX
|
|
return true;
|
|
}
|
|
if (cm->Client->Win9x)
|
|
{
|
|
// There is no need to prohibit if the client is a Win9x
|
|
return true;
|
|
}
|
|
|
|
return true;
|
|
|
|
if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled())
|
|
{
|
|
if (MsGetCurrentTerminalSessionId() == 0)
|
|
{
|
|
// There is no need to prohibit
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// Prohibit to install the device drivers since
|
|
// the user logged in other than the console session
|
|
wchar_t *user = MsGetSessionUserName(0);
|
|
|
|
if (user == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("CM_STOP_INST_VLAN_2"),
|
|
MsIsTerminalServiceInstalled() ? _UU("CM_DESKTOP_MSG_LOCAL_TS") : _UU("CM_DESKTOP_MSG_LOCAL_SW"),
|
|
MsGetCurrentTerminalSessionId());
|
|
}
|
|
else
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("CM_STOP_INST_VLAN_1"),
|
|
MsIsTerminalServiceInstalled() ? _UU("CM_DESKTOP_MSG_LOCAL_TS") : _UU("CM_DESKTOP_MSG_LOCAL_SW"),
|
|
MsGetCurrentTerminalSessionId(), 0, user);
|
|
}
|
|
|
|
if (user != NULL)
|
|
{
|
|
Free(user);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// There is no need to prohibit
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Desktop difference warning message dialog initialization
|
|
void CmDesktopDlgInit(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
wchar_t tmp[2048];
|
|
bool remote = false;
|
|
bool user_switching = false;
|
|
bool console_active = false;
|
|
wchar_t *console_user = NULL;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
FormatText(hWnd, 0, account_name);
|
|
FormatText(hWnd, S_TITLE, account_name);
|
|
DlgFont(hWnd, S_TITLE, 11, true);
|
|
DlgFont(hWnd, S_INFO, 11, true);
|
|
if (cm->server_name == NULL)
|
|
{
|
|
UniStrCpy(tmp, sizeof(tmp), _UU("CM_DESKTOP_LOCAL_PC"));
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_REMOTE_PC"), cm->server_name);
|
|
}
|
|
FormatText(hWnd, S_WARNING, tmp);
|
|
|
|
if (cm->server_name != NULL)
|
|
{
|
|
remote = true;
|
|
}
|
|
else
|
|
{
|
|
if (MsIsTerminalServiceInstalled())
|
|
{
|
|
user_switching = false;
|
|
}
|
|
else
|
|
{
|
|
user_switching = true;
|
|
}
|
|
|
|
console_user = MsGetSessionUserName(0);
|
|
|
|
if (console_user == NULL)
|
|
{
|
|
console_active = false;
|
|
}
|
|
else
|
|
{
|
|
console_active = true;
|
|
}
|
|
}
|
|
|
|
// MSG1
|
|
if (remote == false)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_1"),
|
|
user_switching ? _UU("CM_DESKTOP_MSG_LOCAL_SW") : _UU("CM_DESKTOP_MSG_LOCAL_TS"));
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_REMOTE_1"),
|
|
cm->server_name);
|
|
}
|
|
SetText(hWnd, S_MSG_1, tmp);
|
|
|
|
// MSG2
|
|
if (remote == false)
|
|
{
|
|
if (console_active)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_21"),
|
|
console_user, MsGetCurrentTerminalSessionId());
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_22"),
|
|
MsGetCurrentTerminalSessionId());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_REMOTE_2"), cm->server_name);
|
|
}
|
|
SetText(hWnd, S_MSG_2, tmp);
|
|
|
|
// MSG3
|
|
if (remote == false)
|
|
{
|
|
if (console_active)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_31"),
|
|
console_user, account_name);
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_32"),
|
|
account_name);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_REMOTE_3"), cm->server_name,
|
|
account_name);
|
|
}
|
|
SetText(hWnd, S_MSG_3, tmp);
|
|
|
|
if (console_user != NULL)
|
|
{
|
|
Free(console_user);
|
|
}
|
|
}
|
|
|
|
// Desktop difference warning message dialog
|
|
UINT CmDesktopDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
wchar_t *account_name = (wchar_t *)param;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CmDesktopDlgInit(hWnd, account_name);
|
|
break;
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
EndDialog(hWnd, true);
|
|
break;
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Show a warning message that the desktop is different, if necessary
|
|
bool CmWarningDesktop(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || account_name == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (cm->Client->Unix)
|
|
{
|
|
//There is no need for warning if the client is an UNIX
|
|
return true;
|
|
}
|
|
|
|
if (/*MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled() ||*/ (cm->server_name != NULL))
|
|
{
|
|
if (cm->server_name == NULL)
|
|
{
|
|
//if (MsGetCurrentTerminalSessionId() == 0)
|
|
{
|
|
// No need for warning
|
|
return true;
|
|
}
|
|
}
|
|
// There is a need for warning
|
|
return Dialog(hWnd, D_CM_DESKTOP, CmDesktopDlgProc, account_name);
|
|
}
|
|
else
|
|
{
|
|
// No need for warning
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Update the password setting dialog
|
|
void CmPasswordRefresh(HWND hWnd)
|
|
{
|
|
bool ok = true;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetEnable(hWnd, E_PASSWORD, IsChecked(hWnd, R_USE_PASSWORD));
|
|
SetEnable(hWnd, E_PASSWORD2, IsChecked(hWnd, R_USE_PASSWORD));
|
|
SetEnable(hWnd, IDC_STATIC1, IsChecked(hWnd, R_USE_PASSWORD));
|
|
SetEnable(hWnd, IDC_STATIC2, IsChecked(hWnd, R_USE_PASSWORD));
|
|
SetEnable(hWnd, R_REMOTE_ONLY, IsChecked(hWnd, R_USE_PASSWORD));
|
|
|
|
if (IsChecked(hWnd, R_USE_PASSWORD))
|
|
{
|
|
char tmp1[MAX_SIZE];
|
|
char tmp2[MAX_SIZE];
|
|
if (IsEmpty(hWnd, E_PASSWORD))
|
|
{
|
|
ok = false;
|
|
}
|
|
GetTxtA(hWnd, E_PASSWORD, tmp1, sizeof(tmp1));
|
|
GetTxtA(hWnd, E_PASSWORD2, tmp2, sizeof(tmp2));
|
|
if (StrCmp(tmp1, tmp2) != 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
if (StrCmp(tmp1, HIDDEN_PASSWORD) == 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
}
|
|
|
|
SetEnable(hWnd, IDOK, ok);
|
|
}
|
|
|
|
// Password setting procedure
|
|
UINT CmPasswordProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
RPC_CLIENT_PASSWORD_SETTING c;
|
|
RPC_CLIENT_PASSWORD p;
|
|
char tmp[MAX_SIZE];
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
// Get the password setting
|
|
if (CALL(hWnd, CcGetPasswordSetting(cm->Client, &c)))
|
|
{
|
|
Check(hWnd, R_USE_PASSWORD, c.IsPasswordPresented);
|
|
if (c.IsPasswordPresented)
|
|
{
|
|
SetTextA(hWnd, E_PASSWORD, HIDDEN_PASSWORD);
|
|
SetTextA(hWnd, E_PASSWORD2, HIDDEN_PASSWORD);
|
|
FocusEx(hWnd, E_PASSWORD);
|
|
Check(hWnd, R_REMOTE_ONLY, c.PasswordRemoteOnly);
|
|
}
|
|
else
|
|
{
|
|
Focus(hWnd, R_USE_PASSWORD);
|
|
}
|
|
}
|
|
CmPasswordRefresh(hWnd);
|
|
break;
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case R_USE_PASSWORD:
|
|
if (IsChecked(hWnd, R_USE_PASSWORD))
|
|
{
|
|
FocusEx(hWnd, E_PASSWORD);
|
|
}
|
|
break;
|
|
case IDOK:
|
|
GetTxtA(hWnd, E_PASSWORD, tmp, sizeof(tmp));
|
|
Zero(&p, sizeof(p));
|
|
if (IsChecked(hWnd, R_USE_PASSWORD))
|
|
{
|
|
StrCpy(p.Password, sizeof(p.Password), tmp);
|
|
p.PasswordRemoteOnly = IsChecked(hWnd, R_REMOTE_ONLY);
|
|
}
|
|
|
|
if (CALL(hWnd, CcSetPassword(cm->Client, &p)))
|
|
{
|
|
if (StrLen(p.Password) > 0)
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PASSWORD_SET"));
|
|
}
|
|
else
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PASSWORD_REMOVE"));
|
|
}
|
|
EndDialog(hWnd, true);
|
|
}
|
|
break;
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case R_USE_PASSWORD:
|
|
case R_REMOTE_ONLY:
|
|
case E_PASSWORD:
|
|
case E_PASSWORD2:
|
|
CmPasswordRefresh(hWnd);
|
|
break;
|
|
}
|
|
switch (wParam)
|
|
{
|
|
case R_REMOTE_ONLY:
|
|
case R_USE_PASSWORD:
|
|
if (IsChecked(hWnd, R_USE_PASSWORD))
|
|
{
|
|
FocusEx(hWnd, E_PASSWORD);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Set the password
|
|
void CmPassword(HWND hWnd)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Dialog(hWnd, D_CM_PASSWORD, CmPasswordProc, NULL);
|
|
}
|
|
|
|
// CA dialog update
|
|
void CmTrustDlgUpdate(HWND hWnd)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetEnable(hWnd, B_EXPORT, LvIsSelected(hWnd, L_CERT));
|
|
SetEnable(hWnd, B_DELETE, LvIsSelected(hWnd, L_CERT) && cm->CmSetting.LockMode == false);
|
|
SetEnable(hWnd, IDOK, LvIsSelected(hWnd, L_CERT));
|
|
SetEnable(hWnd, B_IMPORT, cm->CmSetting.LockMode == false);
|
|
}
|
|
|
|
// Update the list of certificates
|
|
void CmTrustDlgRefresh(HWND hWnd)
|
|
{
|
|
RPC_CLIENT_ENUM_CA c;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (CALL(hWnd, CcEnumCa(cm->Client, &c)))
|
|
{
|
|
UINT i;
|
|
LVB *b = LvInsertStart();
|
|
for (i = 0;i < c.NumItem;i++)
|
|
{
|
|
RPC_CLIENT_ENUM_CA_ITEM *cert = c.Items[i];
|
|
wchar_t tmp[MAX_SIZE];
|
|
|
|
GetDateStrEx64(tmp, sizeof(tmp), SystemToLocal64(cert->Expires), NULL);
|
|
LvInsertAdd(b, ICO_CERT, (void *)cert->Key, 3,
|
|
cert->SubjectName, cert->IssuerName, tmp);
|
|
}
|
|
LvInsertEnd(b, hWnd, L_CERT);
|
|
CiFreeClientEnumCa(&c);
|
|
}
|
|
|
|
CmTrustDlgUpdate(hWnd);
|
|
}
|
|
|
|
// Import
|
|
void CmTrustImport(HWND hWnd)
|
|
{
|
|
X *x;
|
|
RPC_CERT c;
|
|
if (CmLoadXFromFileOrSecureCard(hWnd, &x) == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Zero(&c, sizeof(c));
|
|
c.x = x;
|
|
|
|
CALL(hWnd, CcAddCa(cm->Client, &c));
|
|
CmVoice("new_cert");
|
|
|
|
FreeX(c.x);
|
|
CmTrustDlgRefresh(hWnd);
|
|
}
|
|
|
|
// Export
|
|
void CmTrustExport(HWND hWnd)
|
|
{
|
|
UINT key;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
key = (UINT)LvGetParam(hWnd, L_CERT, LvGetSelected(hWnd, L_CERT));
|
|
if (key != INFINITE)
|
|
{
|
|
RPC_GET_CA a;
|
|
Zero(&a, sizeof(a));
|
|
a.Key = key;
|
|
|
|
if (CALL(hWnd, CcGetCa(cm->Client, &a)))
|
|
{
|
|
wchar_t *name;
|
|
X *x = CloneX(a.x);
|
|
CiFreeGetCa(&a);
|
|
|
|
// Save
|
|
name = SaveDlg(hWnd, _UU("DLG_CERT_FILES"), _UU("DLG_SAVE_CERT"), NULL, L".cer");
|
|
if (name != NULL)
|
|
{
|
|
wchar_t str[MAX_SIZE];
|
|
UniStrCpy(str, sizeof(str), name);
|
|
if (XToFileW(x, str, true))
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("DLG_CERT_SAVE_OK"));
|
|
}
|
|
else
|
|
{
|
|
MsgBox(hWnd, MB_ICONSTOP, _UU("DLG_CERT_SAVE_ERROR"));
|
|
}
|
|
Free(name);
|
|
}
|
|
FreeX(x);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Display
|
|
void CmTrustView(HWND hWnd)
|
|
{
|
|
UINT key;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
key = (UINT)LvGetParam(hWnd, L_CERT, LvGetSelected(hWnd, L_CERT));
|
|
if (key != INFINITE)
|
|
{
|
|
RPC_GET_CA a;
|
|
Zero(&a, sizeof(a));
|
|
a.Key = key;
|
|
|
|
if (CALL(hWnd, CcGetCa(cm->Client, &a)))
|
|
{
|
|
X *x = CloneX(a.x);
|
|
X *x_issuer;
|
|
CiFreeGetCa(&a);
|
|
|
|
x_issuer = CmGetIssuer(x);
|
|
CertDlg(hWnd, x, x_issuer, true);
|
|
FreeX(x);
|
|
FreeX(x_issuer);
|
|
}
|
|
}
|
|
}
|
|
|
|
// CA dialog procedure
|
|
UINT CmTrustDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
NMHDR *n;
|
|
UINT index;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
LvInit(hWnd, L_CERT);
|
|
LvInsertColumn(hWnd, L_CERT, 0, _UU("CM_CERT_COLUMN_1"), 190);
|
|
LvInsertColumn(hWnd, L_CERT, 1, _UU("CM_CERT_COLUMN_2"), 190);
|
|
LvInsertColumn(hWnd, L_CERT, 2, _UU("CM_CERT_COLUMN_3"), 160);
|
|
CmTrustDlgRefresh(hWnd);
|
|
break;
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case B_IMPORT:
|
|
CmTrustImport(hWnd);
|
|
break;
|
|
case B_EXPORT:
|
|
CmTrustExport(hWnd);
|
|
break;
|
|
case B_DELETE:
|
|
index = LvGetSelected(hWnd, L_CERT);
|
|
if (index != INFINITE)
|
|
{
|
|
UINT key = (UINT)LvGetParam(hWnd, L_CERT, index);
|
|
if (key != INFINITE)
|
|
{
|
|
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_CERT_DELETE_MSG")) == IDYES)
|
|
{
|
|
RPC_CLIENT_DELETE_CA c;
|
|
Zero(&c, sizeof(c));
|
|
c.Key = key;
|
|
if (CALL(hWnd, CcDeleteCa(cm->Client, &c)))
|
|
{
|
|
CmTrustDlgRefresh(hWnd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case IDOK:
|
|
if (IsEnable(hWnd, IDOK))
|
|
{
|
|
CmTrustView(hWnd);
|
|
}
|
|
break;
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
case WM_NOTIFY:
|
|
n = (NMHDR *)lParam;
|
|
switch (n->idFrom)
|
|
{
|
|
case L_CERT:
|
|
switch (n->code)
|
|
{
|
|
case LVN_ITEMCHANGED:
|
|
CmTrustDlgUpdate(hWnd);
|
|
break;
|
|
case NM_DBLCLK:
|
|
Command(hWnd, IDOK);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
LvSortHander(hWnd, msg, wParam, lParam, L_CERT);
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Show the CA dialog
|
|
void CmTrustDlg(HWND hWnd)
|
|
{
|
|
Dialog(hWnd, D_CM_TRUST, CmTrustDlgProc, NULL);
|
|
}
|
|
|
|
// Main window procedure
|
|
UINT CmMainWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
NMHDR *n;
|
|
static UINT taskbar_msg = 0;
|
|
COPYDATASTRUCT *cpy;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (taskbar_msg != 0 && msg == taskbar_msg)
|
|
{
|
|
// The task-bar is regenerated
|
|
if (cm->TrayInited)
|
|
{
|
|
MsRestoreIconOnTray();
|
|
}
|
|
}
|
|
|
|
// CmSetForegroundProcessToCnService();
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_CM_SETTING_CHANGED_MESSAGE:
|
|
// CM_SETTING has changed
|
|
CmApplyCmSetting();
|
|
break;
|
|
case WM_INITDIALOG:
|
|
CmMainWindowOnInit(hWnd);
|
|
taskbar_msg = RegisterWindowMessage("TaskbarCreated");
|
|
CmEndStartupMutex();
|
|
break;
|
|
case WM_CM_SHOW:
|
|
// Received a display request from another process
|
|
if (cm->CmSetting.EasyMode == false)
|
|
{
|
|
ShowWindow(hWnd, SW_SHOWNORMAL);
|
|
}
|
|
else
|
|
{
|
|
if (cm->hEasyWnd == NULL)
|
|
{
|
|
CmShowEasy();
|
|
}
|
|
else
|
|
{
|
|
SetForegroundWindow(cm->hEasyWnd);
|
|
SetActiveWindow(cm->hEasyWnd);
|
|
}
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
CmMainWindowOnCommand(hWnd, wParam, lParam);
|
|
break;
|
|
case WM_SIZE:
|
|
CmMainWindowOnSize(hWnd);
|
|
break;
|
|
case WM_CLOSE:
|
|
if (cm->CmSetting.EasyMode == false)
|
|
{
|
|
CmShowOrHideWindow(hWnd);
|
|
}
|
|
else
|
|
{
|
|
if (cm->hEasyWnd == NULL)
|
|
{
|
|
CmShowEasy();
|
|
}
|
|
else
|
|
{
|
|
SetForegroundWindow(cm->hEasyWnd);
|
|
SetActiveWindow(cm->hEasyWnd);
|
|
}
|
|
}
|
|
return 1;
|
|
case WM_INITMENUPOPUP:
|
|
if (HIWORD(lParam) == false)
|
|
{
|
|
CmMainWindowOnPopupMenu(hWnd, (HMENU)wParam, LOWORD(lParam));
|
|
}
|
|
break;
|
|
case WM_NOTIFY:
|
|
n = (NMHDR *)lParam;
|
|
if (n->idFrom == L_ACCOUNT && (n->code == LVN_BEGINLABELEDITW || n->code == LVN_BEGINLABELEDITA))
|
|
{
|
|
wchar_t *tmp = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
|
|
if (tmp != NULL)
|
|
{
|
|
if (UniStrCmpi(tmp, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(tmp, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(tmp, _UU("CM_VGC_LINK")) == 0
|
|
)
|
|
{
|
|
SendMsg(hWnd, L_ACCOUNT, LVM_CANCELEDITLABEL, 0, 0);
|
|
Free(tmp);
|
|
return true;
|
|
}
|
|
Free(tmp);
|
|
}
|
|
}
|
|
CmMainWindowOnNotify(hWnd, (NMHDR *)lParam);
|
|
break;
|
|
case WM_CM_NOTIFY:
|
|
CmRefreshVLanList(hWnd);
|
|
CmRefreshAccountList(hWnd);
|
|
CmRefreshStatusBar(hWnd);
|
|
break;
|
|
case WM_TIMER:
|
|
switch (wParam)
|
|
{
|
|
case 1:
|
|
CmSetForegroundProcessToCnService();
|
|
break;
|
|
case 2:
|
|
CmPollingTray(hWnd);
|
|
break;
|
|
case 3:
|
|
KillTimer(hWnd, 3);
|
|
Hide(hWnd, 0);
|
|
break;
|
|
case 4:
|
|
KillTimer(hWnd, 4);
|
|
CmMainWindowOnShowEasy(hWnd);
|
|
break;
|
|
case 6:
|
|
if (cm->Update == NULL)
|
|
{
|
|
if (cm->server_name == NULL)
|
|
{
|
|
if (CmGetNumConnected(hWnd) == 0)
|
|
{
|
|
cm->Update = InitUpdateUi(_UU("PRODUCT_NAME_VPN_CMGR"), NAME_OF_VPN_CLIENT_MANAGER, NULL,
|
|
GetCurrentBuildDate(), CEDAR_BUILD, CEDAR_VER, ((cm->Client == NULL) ? NULL : cm->Client->ClientId),
|
|
true);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case WM_CM_TRAY_MESSAGE:
|
|
// Message from the icon in the task tray
|
|
CmMainWindowOnTrayClicked(hWnd, wParam, lParam);
|
|
break;
|
|
case WM_COPYDATA:
|
|
cpy = (COPYDATASTRUCT *)lParam;
|
|
if (cpy != NULL)
|
|
{
|
|
if (cpy->dwData == CM_IMPORT_FILENAME_MSG || cpy->dwData == CM_IMPORT_FILENAME_MSG_OVERWRITE)
|
|
{
|
|
char *filename = (char *)cpy->lpData;
|
|
|
|
if (cm->CmSetting.LockMode == false || cpy->dwData == CM_IMPORT_FILENAME_MSG_OVERWRITE)
|
|
{
|
|
wchar_t fullpath[MAX_PATH];
|
|
|
|
if (StrLen(filename) >= 2 && IsFileExists(filename))
|
|
{
|
|
StrToUni(fullpath, sizeof(fullpath), filename);
|
|
}
|
|
else
|
|
{
|
|
UniStrCpy(fullpath, sizeof(fullpath), (wchar_t *)filename);
|
|
}
|
|
|
|
CmImportAccountMainEx(cm->hEasyWnd ? cm->hEasyWnd : hWnd, fullpath, cpy->dwData == CM_IMPORT_FILENAME_MSG_OVERWRITE);
|
|
}
|
|
else
|
|
{
|
|
MsgBox(cm->hEasyWnd ? cm->hEasyWnd : hWnd, MB_ICONEXCLAMATION | MB_SETFOREGROUND | MB_TOPMOST, _UU("CM_VPN_FILE_IMPORT_NG"));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case WM_QUERYENDSESSION:
|
|
// Windows is about to terminate
|
|
cm->WindowsShutdowning = true;
|
|
CmSaveMainWindowPos(hWnd);
|
|
SleepThread(256);
|
|
break;
|
|
case WM_ENDSESSION:
|
|
// Windows has terminated
|
|
_exit(0);
|
|
break;
|
|
}
|
|
|
|
LvSortHander(hWnd, msg, wParam, lParam, L_ACCOUNT);
|
|
LvSortHander(hWnd, msg, wParam, lParam, L_VLAN);
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Specify the notification service to the foreground process
|
|
void CmSetForegroundProcessToCnService()
|
|
{
|
|
if (cm->PopupMenuOpen)
|
|
{
|
|
return;
|
|
}
|
|
if (cm->server_name == NULL)
|
|
{
|
|
if (CnCheckAlreadyExists(false))
|
|
{
|
|
AllowFGWindow(MsRegReadInt(REG_CURRENT_USER,
|
|
CM_REG_KEY, "NotifyServerProcessId"));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Show the [recent destination] sub-menu
|
|
HMENU CmCreateRecentSubMenu(HWND hWnd, UINT start_id)
|
|
{
|
|
HMENU h = NULL;
|
|
UINT i;
|
|
RPC_CLIENT_ENUM_ACCOUNT a;
|
|
LIST *o;
|
|
bool easy;
|
|
|
|
easy = cm->CmSetting.EasyMode;
|
|
|
|
Zero(&a, sizeof(a));
|
|
|
|
if (CcEnumAccount(cm->Client, &a) == ERR_NO_ERROR)
|
|
{
|
|
o = NewListFast(CiCompareClientAccountEnumItemByLastConnectDateTime);
|
|
|
|
for (i = 0;i < a.NumItem;i++)
|
|
{
|
|
RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = a.Items[i];
|
|
|
|
item->tmp1 = i;
|
|
|
|
if (item->LastConnectDateTime != 0)
|
|
{
|
|
Add(o, item);
|
|
}
|
|
}
|
|
|
|
Sort(o);
|
|
|
|
for (i = 0;i < MIN(LIST_NUM(o), CM_NUM_RECENT);i++)
|
|
{
|
|
RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = (RPC_CLIENT_ENUM_ACCOUNT_ITEM *)LIST_DATA(o, i);
|
|
wchar_t tmp[MAX_PATH];
|
|
wchar_t *account_name;
|
|
char *server_name;
|
|
char *hub_name;
|
|
UINT pos;
|
|
|
|
if (h == NULL)
|
|
{
|
|
h = CreatePopupMenu();
|
|
}
|
|
|
|
account_name = item->AccountName;
|
|
server_name = item->ServerName;
|
|
hub_name = item->HubName;
|
|
|
|
UniStrCpy(tmp, sizeof(tmp), account_name);
|
|
|
|
pos = LvSearchStr(hWnd, L_ACCOUNT, 0, account_name);
|
|
if (pos != INFINITE)
|
|
{
|
|
MsAppendMenu(h, MF_STRING, start_id + pos, tmp);
|
|
}
|
|
}
|
|
|
|
ReleaseList(o);
|
|
|
|
CiFreeClientEnumAccount(&a);
|
|
}
|
|
|
|
return h;
|
|
}
|
|
|
|
// Show the sub-menu of the right-click menu in the task tray
|
|
HMENU CmCreateTraySubMenu(HWND hWnd, bool flag, UINT start_id)
|
|
{
|
|
HMENU h = NULL;
|
|
UINT i, num;
|
|
bool easy;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
easy = cm->CmSetting.EasyMode;
|
|
|
|
num = LvNum(hWnd, L_ACCOUNT);
|
|
|
|
for (i = 0;i < num;i++)
|
|
{
|
|
wchar_t *status_str = LvGetStr(hWnd, L_ACCOUNT, i, 1);
|
|
|
|
if (status_str != NULL)
|
|
{
|
|
bool b = false;
|
|
bool is_account = false;
|
|
|
|
if (UniStrCmpi(status_str, _UU("CM_ACCOUNT_OFFLINE")) == 0)
|
|
{
|
|
if (flag == false)
|
|
{
|
|
b = true;
|
|
}
|
|
|
|
is_account = true;
|
|
}
|
|
|
|
if (UniStrCmpi(status_str, _UU("CM_ACCOUNT_ONLINE")) == 0 ||
|
|
UniStrCmpi(status_str, _UU("CM_ACCOUNT_CONNECTING")) == 0)
|
|
{
|
|
if (flag == true)
|
|
{
|
|
b = true;
|
|
}
|
|
|
|
is_account = true;
|
|
}
|
|
|
|
if (b)
|
|
{
|
|
wchar_t tmp[MAX_PATH];
|
|
wchar_t *account_name, *server_name;
|
|
wchar_t *hub_name;
|
|
if (h == NULL)
|
|
{
|
|
h = CreatePopupMenu();
|
|
}
|
|
|
|
account_name = LvGetStr(hWnd, L_ACCOUNT, i, 0);
|
|
server_name = LvGetStr(hWnd, L_ACCOUNT, i, 2);
|
|
hub_name = LvGetStr(hWnd, L_ACCOUNT, i, 3);
|
|
|
|
if (easy == false)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), L"%s\t- %s [%s]", account_name, server_name, hub_name);
|
|
}
|
|
else
|
|
{
|
|
UniStrCpy(tmp, sizeof(tmp), account_name);
|
|
}
|
|
|
|
MsAppendMenu(h, MF_STRING, start_id + i, tmp);
|
|
|
|
Free(account_name);
|
|
Free(server_name);
|
|
Free(hub_name);
|
|
}
|
|
|
|
Free(status_str);
|
|
}
|
|
}
|
|
|
|
return h;
|
|
}
|
|
|
|
// Display the right-click menu of the task tray
|
|
void CmShowTrayMenu(HWND hWnd)
|
|
{
|
|
HMENU h;
|
|
POINT p;
|
|
HMENU sub1, sub2, sub3, sub4;
|
|
bool locked;
|
|
bool easy;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
cm->PopupMenuOpen = true;
|
|
|
|
locked = cm->CmSetting.LockMode;
|
|
easy = cm->CmSetting.EasyMode;
|
|
|
|
// Create a menu
|
|
h = CreatePopupMenu();
|
|
|
|
// Cancel
|
|
MsAppendMenu(h, MF_ENABLED | MF_STRING, 100007, _UU("CM_TRAY_MENU_CANCEL"));
|
|
|
|
// Separator
|
|
MsAppendMenu(h, MF_SEPARATOR, 10006, NULL);
|
|
|
|
if (locked == false && easy == false)
|
|
{
|
|
// Creating a new connection settings
|
|
MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_NEW, _UU("CM_TRAY_MENU_NEW"));
|
|
|
|
// Separator
|
|
MsAppendMenu(h, MF_SEPARATOR, 10005, NULL);
|
|
}
|
|
|
|
// Connection menu
|
|
sub1 = CmCreateTraySubMenu(hWnd, false, CM_TRAY_MENU_CONNECT_ID_START);
|
|
if (sub1 != NULL)
|
|
{
|
|
MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,
|
|
(UINT_PTR)sub1, _UU("CM_TRAY_MENU_CONNECT"));
|
|
}
|
|
|
|
// Disconnection menu
|
|
sub2 = CmCreateTraySubMenu(hWnd, true, CM_TRAY_MENU_DISCONNECT_ID_START);
|
|
if (sub2 != NULL)
|
|
{
|
|
MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,
|
|
(UINT_PTR)sub2, _UU("CM_TRAY_MENU_DISCONNECT"));
|
|
}
|
|
|
|
// Status Display menu
|
|
sub3 = CmCreateTraySubMenu(hWnd, true, CM_TRAY_MENU_STATUS_ID_START);
|
|
if (sub3 != NULL)
|
|
{
|
|
MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,
|
|
(UINT_PTR)sub3, _UU("CM_TRAY_MENU_STATUS"));
|
|
}
|
|
|
|
if (sub3 != NULL)
|
|
{
|
|
// Disconnect all connections
|
|
MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_DISCONNECT_ALL, _UU("CM_TRAY_MENU_DISCONNECT_ALL"));
|
|
}
|
|
|
|
if (sub1 != NULL || sub2 != NULL || sub3 != NULL)
|
|
{
|
|
// Separator
|
|
MsAppendMenu(h, MF_SEPARATOR, 10003, NULL);
|
|
}
|
|
|
|
// Connect to the recently connected VPN server
|
|
sub4 = CmCreateRecentSubMenu(hWnd, CM_TRAY_MENU_RECENT_ID_START);
|
|
if (sub4 != NULL)
|
|
{
|
|
MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,
|
|
(UINT_PTR)sub4, _UU("CM_TRAY_MENU_RECENT"));
|
|
MsAppendMenu(h, MF_SEPARATOR, 10008, NULL);
|
|
}
|
|
|
|
if (locked == false && easy == false)
|
|
{
|
|
// Communication throughput measurement
|
|
MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_TRAFFIC, _UU("CM_TRAY_MENU_TRAFFIC"));
|
|
}
|
|
|
|
if (easy == false)
|
|
{
|
|
// Network device status
|
|
MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_NETIF, _UU("CM_TRAY_MENU_NETIF"));
|
|
}
|
|
|
|
// Version information
|
|
MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_ABOUT, _UU("CM_TRAY_MENU_ABOUT"));
|
|
|
|
// Separator
|
|
MsAppendMenu(h, MF_SEPARATOR, 10001, NULL);
|
|
|
|
// Change the operating mode
|
|
MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_CM_SETTING, _UU("CM_TRAY_MENU_SETTING"));
|
|
|
|
// Separator
|
|
MsAppendMenu(h, MF_SEPARATOR, 10001, NULL);
|
|
|
|
// Hide the icon
|
|
MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_TRAYICON, _UU("CM_MENU@CMD_TRAYICON"));
|
|
|
|
// Separator
|
|
MsAppendMenu(h, MF_SEPARATOR, 10001, NULL);
|
|
|
|
// Show or hide
|
|
MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_EXIT,
|
|
IsHide(hWnd, 0) ? _UU("CM_TRAY_MENU_1_SHOW") : _UU("CM_TRAY_MENU_1_HIDE"));
|
|
|
|
// Quit
|
|
MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_QUIT, _UU("CM_TRAY_MENU_2_QUIT"));
|
|
|
|
// Show the menu
|
|
GetCursorPos(&p);
|
|
|
|
SetForegroundWindow(hWnd);
|
|
TrackPopupMenu(h, TPM_LEFTALIGN, p.x, p.y, 0, hWnd, NULL);
|
|
PostMessage(hWnd, WM_NULL, 0, 0);
|
|
|
|
if (sub1 != NULL)
|
|
{
|
|
DestroyMenu(sub1);
|
|
}
|
|
|
|
if (sub2 != NULL)
|
|
{
|
|
DestroyMenu(sub2);
|
|
}
|
|
|
|
if (sub3 != NULL)
|
|
{
|
|
DestroyMenu(sub3);
|
|
}
|
|
|
|
DestroyMenu(h);
|
|
|
|
cm->PopupMenuOpen = false;
|
|
}
|
|
|
|
// Hide or show the main window
|
|
void CmShowOrHideWindow(HWND hWnd)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IsHide(hWnd, 0))
|
|
{
|
|
Show(hWnd, 0);
|
|
if (IsIconic(hWnd))
|
|
{
|
|
ShowWindow(hWnd, SW_SHOWNORMAL);
|
|
}
|
|
SetForegroundWindow(hWnd);
|
|
SetActiveWindow(hWnd);
|
|
}
|
|
else
|
|
{
|
|
CmSaveMainWindowPos(hWnd);
|
|
Hide(hWnd, 0);
|
|
|
|
if (cm->TrayInited == false)
|
|
{
|
|
Command(hWnd, CMD_QUIT);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Right-clicked on the account list
|
|
void CmAccountListRightClick(HWND hWnd)
|
|
{
|
|
HMENU h;
|
|
HMENU parent;
|
|
UINT i;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Load the menu
|
|
h = LoadSubMenu(M_MAIN, 0, &parent);
|
|
if (h == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
InitMenuInternational(h, "CM_MENU");
|
|
|
|
// Remove the shortcut key
|
|
RemoveShortcutKeyStrFromMenu(h);
|
|
|
|
// Delete the exit menu
|
|
i = GetMenuItemPos(h, CMD_QUIT);
|
|
if (i != INFINITE)
|
|
{
|
|
DeleteMenuItem(h, i);
|
|
DeleteMenuItem(h, i - 1);
|
|
DeleteMenuItem(h, i - 2);
|
|
DeleteMenuItem(h, i - 3);
|
|
}
|
|
|
|
// Set enable / disable
|
|
CmMainWindowOnPopupMenu(hWnd, h, INFINITE);
|
|
|
|
if (h != NULL)
|
|
{
|
|
// Determine whether the selected account is under connecting
|
|
UINT i = LvGetSelected(hWnd, L_ACCOUNT);
|
|
wchar_t *str;
|
|
bool is_connected = false;
|
|
if (i != INFINITE)
|
|
{
|
|
str = LvGetStr(hWnd, L_ACCOUNT, i, 1);
|
|
if (str != NULL)
|
|
{
|
|
if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)
|
|
{
|
|
// Connecting
|
|
is_connected = true;
|
|
}
|
|
Free(str);
|
|
}
|
|
}
|
|
|
|
if (i == INFINITE)
|
|
{
|
|
// Bold the New menu
|
|
SetMenuItemBold(h, GetMenuItemPos(h, CMD_NEW), true);
|
|
}
|
|
else
|
|
{
|
|
if (is_connected == false)
|
|
{
|
|
// Bold the connection menu
|
|
SetMenuItemBold(h, GetMenuItemPos(h, CMD_CONNECT), true);
|
|
}
|
|
else
|
|
{
|
|
// Bold the status menu
|
|
SetMenuItemBold(h, GetMenuItemPos(h, CMD_STATUS), true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Show the menu
|
|
PrintMenu(hWnd, h);
|
|
|
|
DestroyMenu(parent);
|
|
}
|
|
|
|
// Right-clicked on the virtual LAN card list
|
|
void CmVLanListRightClick(HWND hWnd)
|
|
{
|
|
HMENU h;
|
|
HMENU parent;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Load the menu
|
|
h = LoadSubMenu(M_MAIN, 3, &parent);
|
|
if (h == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
InitMenuInternational(h, "CM_MENU");
|
|
|
|
// Remove the shortcut key
|
|
RemoveShortcutKeyStrFromMenu(h);
|
|
|
|
// Set enable / disable
|
|
CmMainWindowOnPopupMenu(hWnd, h, INFINITE);
|
|
|
|
if (h != NULL)
|
|
{
|
|
// Examine whether the selected device is enabled
|
|
UINT i = LvGetSelected(hWnd, L_VLAN);
|
|
wchar_t *str;
|
|
bool is_active = false;
|
|
if (i != INFINITE)
|
|
{
|
|
str = LvGetStr(hWnd, L_VLAN, i, 1);
|
|
if (str != NULL)
|
|
{
|
|
if (UniStrCmpi(str, _UU("CM_VLAN_ENABLED")) == 0)
|
|
{
|
|
// Enabled
|
|
is_active = true;
|
|
}
|
|
Free(str);
|
|
}
|
|
}
|
|
|
|
if (i == INFINITE)
|
|
{
|
|
// Bold the New menu
|
|
SetMenuItemBold(h, GetMenuItemPos(h, CMD_NEW_VLAN), true);
|
|
}
|
|
else
|
|
{
|
|
if (is_active == false)
|
|
{
|
|
// Bold the enable menu
|
|
SetMenuItemBold(h, GetMenuItemPos(h, CMD_ENABLE_VLAN), true);
|
|
}
|
|
else
|
|
{
|
|
// Bold the Windows Network Setup menu
|
|
SetMenuItemBold(h, GetMenuItemPos(h, CMD_WINNET), true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Show the menu
|
|
PrintMenu(hWnd, h);
|
|
|
|
DestroyMenu(parent);
|
|
}
|
|
|
|
// Notify to the main window
|
|
void CmMainWindowOnNotify(HWND hWnd, NMHDR *n)
|
|
{
|
|
bool item_vlan;
|
|
NMLVDISPINFOW *disp_info;
|
|
NMLVKEYDOWN *key;
|
|
|
|
// Validate arguments
|
|
if (hWnd == NULL || n == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (n->idFrom)
|
|
{
|
|
case L_ACCOUNT:
|
|
case L_VLAN:
|
|
if (n->idFrom == L_ACCOUNT)
|
|
{
|
|
item_vlan = false;
|
|
}
|
|
else
|
|
{
|
|
item_vlan = true;
|
|
}
|
|
|
|
switch (n->code)
|
|
{
|
|
case NM_DBLCLK:
|
|
// Double click
|
|
CmOnKey(hWnd, false, false, VK_RETURN);
|
|
break;
|
|
case NM_RCLICK:
|
|
// Right click
|
|
if (item_vlan == false)
|
|
{
|
|
CmAccountListRightClick(hWnd);
|
|
}
|
|
else
|
|
{
|
|
CmVLanListRightClick(hWnd);
|
|
}
|
|
break;
|
|
case LVN_ENDLABELEDITW:
|
|
// Change the name
|
|
disp_info = (NMLVDISPINFOW *)n;
|
|
if (disp_info->item.pszText != NULL)
|
|
{
|
|
wchar_t *new_name = disp_info->item.pszText;
|
|
wchar_t *old_name = LvGetStr(hWnd, L_ACCOUNT, disp_info->item.iItem, 0);
|
|
|
|
if (old_name != NULL)
|
|
{
|
|
if (UniStrCmp(new_name, old_name) != 0 && UniIsEmptyStr(new_name) == false)
|
|
{
|
|
RPC_RENAME_ACCOUNT a;
|
|
Zero(&a, sizeof(a));
|
|
UniStrCpy(a.OldName, sizeof(a.OldName), old_name);
|
|
UniStrCpy(a.NewName, sizeof(a.NewName), new_name);
|
|
if (CALL(hWnd, CcRenameAccount(cm->Client, &a)))
|
|
{
|
|
LvSetItem(hWnd, L_ACCOUNT, disp_info->item.iItem, 0, new_name);
|
|
}
|
|
}
|
|
|
|
Free(old_name);
|
|
}
|
|
}
|
|
break;
|
|
case LVN_KEYDOWN:
|
|
// Key pressed
|
|
key = (NMLVKEYDOWN *)n;
|
|
if (key != NULL)
|
|
{
|
|
bool ctrl, alt;
|
|
UINT code = key->wVKey;
|
|
ctrl = (GetKeyState(VK_CONTROL) & 0x8000) == 0 ? false : true;
|
|
alt = (GetKeyState(VK_MENU) & 0x8000) == 0 ? false : true;
|
|
CmOnKey(hWnd, ctrl, alt, code);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Keyboard pressed
|
|
void CmOnKey(HWND hWnd, bool ctrl, bool alt, UINT key)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Single key
|
|
switch (key)
|
|
{
|
|
case VK_RETURN:
|
|
Command(hWnd, IDOK);
|
|
break;
|
|
case VK_DELETE:
|
|
// Delete
|
|
if (IsFocus(hWnd, L_ACCOUNT))
|
|
{
|
|
// Operation on the account list
|
|
Command(hWnd, CMD_DELETE);
|
|
}
|
|
else
|
|
{
|
|
// Operation on the virtual LAN card list
|
|
Command(hWnd, CMD_DELETE_VLAN);
|
|
}
|
|
break;
|
|
case VK_F2:
|
|
// Change the name
|
|
Command(hWnd, CMD_RENAME);
|
|
break;
|
|
case VK_F5:
|
|
// Update the status
|
|
Command(hWnd, CMD_REFRESH);
|
|
break;
|
|
}
|
|
|
|
if (alt)
|
|
{
|
|
switch (key)
|
|
{
|
|
case 'Q':
|
|
// Close
|
|
Command(hWnd, CMD_QUIT);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ctrl)
|
|
{
|
|
switch (key)
|
|
{
|
|
case 'G':
|
|
// Smart Card Manager
|
|
Command(hWnd, CMD_SECURE_MANAGER);
|
|
break;
|
|
case 'S':
|
|
// Show the state
|
|
Command(hWnd, CMD_STATUS);
|
|
break;
|
|
case 'I':
|
|
// Disconnect all connections
|
|
Command(hWnd, CMD_DISCONNECT_ALL);
|
|
break;
|
|
case 'D':
|
|
// Disconnect
|
|
Command(hWnd, CMD_DISCONNECT);
|
|
break;
|
|
case 'N':
|
|
// Create a new connection settings
|
|
Command(hWnd, CMD_NEW);
|
|
break;
|
|
case 'C':
|
|
// Creating a copy
|
|
Command(hWnd, CMD_CLONE);
|
|
break;
|
|
case 'T':
|
|
// Set to start-up connection
|
|
Command(hWnd, CMD_STARTUP);
|
|
break;
|
|
case 'A':
|
|
// Select all
|
|
Command(hWnd, CMD_SELECT_ALL);
|
|
break;
|
|
case 'L':
|
|
// Create a new virtual LAN card
|
|
Command(hWnd, CMD_NEW_VLAN);
|
|
break;
|
|
case 'E':
|
|
// Enable the virtual LAN card
|
|
Command(hWnd, CMD_ENABLE_VLAN);
|
|
break;
|
|
case 'B':
|
|
// Disable the virtual LAN card
|
|
Command(hWnd, CMD_DISABLE_VLAN);
|
|
break;
|
|
case 'U':
|
|
// Reinstall the driver
|
|
Command(hWnd, CMD_REINSTALL);
|
|
break;
|
|
case 'W':
|
|
// Configure Windows network connection
|
|
Command(hWnd, CMD_WINNET);
|
|
break;
|
|
case 'P':
|
|
// Set the password
|
|
Command(hWnd, CMD_PASSWORD);
|
|
break;
|
|
case 'O':
|
|
// Option settings
|
|
Command(hWnd, CMD_TRAFFIC);
|
|
break;
|
|
case 'R':
|
|
// Certificate management
|
|
Command(hWnd, CMD_TRUST);
|
|
break;
|
|
case 'Q':
|
|
// Throughput
|
|
Command(hWnd, CMD_TRAFFIC);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Command of the main window
|
|
void CmMainWindowOnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CmMainWindowOnCommandEx(hWnd, wParam, lParam, false);
|
|
}
|
|
void CmMainWindowOnCommandEx(HWND hWnd, WPARAM wParam, LPARAM lParam, bool easy)
|
|
{
|
|
wchar_t *tmp;
|
|
char *name;
|
|
UINT index;
|
|
UINT id;
|
|
bool ctrl, alt;
|
|
UINT flag = 0;
|
|
// Validate arguments
|
|
wchar_t *selected_name = NULL;
|
|
UINT starter_id = 0;
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ctrl = (GetKeyState(VK_CONTROL) & 0x8000) == 0 ? false : true;
|
|
alt = (GetKeyState(VK_MENU) & 0x8000) == 0 ? false : true;
|
|
|
|
if (wParam == IDOK)
|
|
{
|
|
tmp = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
|
|
if (tmp != NULL)
|
|
{
|
|
if (UniStrCmpi(tmp, _UU("CM_NEW_ICON")) == 0)
|
|
{
|
|
Free(tmp);
|
|
Command(hWnd, CMD_NEW);
|
|
return;
|
|
}
|
|
if (UniStrCmpi(tmp, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(tmp, _UU("CM_VGC_LINK")) == 0)
|
|
{
|
|
Free(tmp);
|
|
Command(hWnd, CMD_VGC_CONNECT);
|
|
return;
|
|
}
|
|
Free(tmp);
|
|
}
|
|
}
|
|
|
|
if (CmIsEnabled(hWnd, (UINT)wParam) == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (CM_TRAY_IS_CONNECT_ID(wParam))
|
|
{
|
|
// Connection request
|
|
starter_id = CM_TRAY_MENU_CONNECT_ID_START;
|
|
flag = 1;
|
|
}
|
|
|
|
if (CM_TRAY_IS_STATUS_ID(wParam))
|
|
{
|
|
// Information display request
|
|
starter_id = CM_TRAY_MENU_STATUS_ID_START;
|
|
flag = 2;
|
|
}
|
|
|
|
if (CM_TRAY_IS_DISCONNECT_ID(wParam))
|
|
{
|
|
// Disconnect request
|
|
starter_id = CM_TRAY_MENU_DISCONNECT_ID_START;
|
|
flag = 3;
|
|
}
|
|
|
|
if (CM_TRAY_IS_RECENT_ID(wParam))
|
|
{
|
|
// Recent destinations
|
|
starter_id = CM_TRAY_MENU_RECENT_ID_START;
|
|
flag = 1;
|
|
}
|
|
|
|
if (starter_id != 0)
|
|
{
|
|
UINT num;
|
|
|
|
id = (UINT)wParam - starter_id;
|
|
|
|
num = LvNum(hWnd, L_ACCOUNT);
|
|
|
|
if (id < num)
|
|
{
|
|
selected_name = LvGetStr(hWnd, L_ACCOUNT, id, 0);
|
|
|
|
if (selected_name != NULL)
|
|
{
|
|
if (UniStrCmpi(selected_name, _UU("CM_NEW_ICON")) != 0 &&
|
|
UniStrCmpi(selected_name, _UU("CM_VGC_ICON")) != 0 &&
|
|
UniStrCmpi(selected_name, _UU("CM_VGC_LINK")) != 0)
|
|
{
|
|
switch (flag)
|
|
{
|
|
case 1:
|
|
CmConnect(hWnd, selected_name);
|
|
break;
|
|
|
|
case 2:
|
|
CmStatus(hWnd, selected_name);
|
|
break;
|
|
|
|
case 3:
|
|
CmDisconnect(hWnd, selected_name);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Free(selected_name);
|
|
}
|
|
}
|
|
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
case CMD_EASY_DBLCLICK:
|
|
// Property or connection
|
|
if (IsFocus(hWnd, L_ACCOUNT) || (hWnd == cm->hEasyWnd))
|
|
{
|
|
// Operation about the account list
|
|
if (alt == false)
|
|
{
|
|
UINT index = LvGetSelected(hWnd, L_ACCOUNT);
|
|
bool b = false;
|
|
if (index != INFINITE)
|
|
{
|
|
wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, index, 1);
|
|
if (s != NULL)
|
|
{
|
|
if (UniStrCmpi(s, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(s, _UU("CM_ACCOUNT_CONNECTING")) == 0)
|
|
{
|
|
b = true;
|
|
}
|
|
Free(s);
|
|
}
|
|
}
|
|
|
|
if (b == false)
|
|
{
|
|
// Connection
|
|
Command(hWnd, CMD_CONNECT);
|
|
}
|
|
else
|
|
{
|
|
if (hWnd != cm->hEasyWnd || wParam == CMD_EASY_DBLCLICK)
|
|
{
|
|
// Display status
|
|
Command(hWnd, CMD_STATUS);
|
|
}
|
|
else
|
|
{
|
|
// Disconnect
|
|
Command(hWnd, CMD_DISCONNECT);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Property
|
|
Command(hWnd, CMD_PROPERTY);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Configure Windows network connection
|
|
Command(hWnd, CMD_WINNET);
|
|
}
|
|
break;
|
|
case CMD_CONNECT:
|
|
// Connection
|
|
tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
|
|
if (tmp != NULL)
|
|
{
|
|
CmConnect(hWnd, tmp);
|
|
Free(tmp);
|
|
}
|
|
break;
|
|
case CMD_STATUS:
|
|
// Show the status
|
|
tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
|
|
if (tmp != NULL)
|
|
{
|
|
CmStatus(hWnd, tmp);
|
|
Free(tmp);
|
|
}
|
|
break;
|
|
case CMD_DISCONNECT_ALL:
|
|
// Disconnect all connections
|
|
CmDisconnectAll(hWnd);
|
|
break;
|
|
case CMD_DISCONNECT:
|
|
// Disconnect
|
|
tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
|
|
if (tmp != NULL)
|
|
{
|
|
CmDisconnect(hWnd, tmp);
|
|
Free(tmp);
|
|
}
|
|
break;
|
|
case CMD_NEW:
|
|
// Create new
|
|
CmNewAccount(hWnd);
|
|
break;
|
|
|
|
|
|
case CMD_CLONE:
|
|
// Copy
|
|
tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
|
|
if (tmp != NULL)
|
|
{
|
|
CmCopyAccount(hWnd, tmp);
|
|
Free(tmp);
|
|
}
|
|
break;
|
|
case CMD_SHORTCUT:
|
|
// Create a shortcut
|
|
tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
|
|
if (tmp != NULL)
|
|
{
|
|
CmSortcut(hWnd, tmp);
|
|
Free(tmp);
|
|
}
|
|
break;
|
|
case CMD_EXPORT_ACCOUNT:
|
|
// Export settings
|
|
tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
|
|
if (tmp != NULL)
|
|
{
|
|
CmExportAccount(hWnd, tmp);
|
|
Free(tmp);
|
|
}
|
|
break;
|
|
case CMD_IMPORT_ACCOUNT:
|
|
// Import settings
|
|
CmImportAccount(hWnd);
|
|
break;
|
|
case CMD_STARTUP:
|
|
// Set to start-up connection
|
|
tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
|
|
if (tmp != NULL)
|
|
{
|
|
RPC_CLIENT_DELETE_ACCOUNT c;
|
|
Zero(&c, sizeof(c));
|
|
UniStrCpy(c.AccountName, sizeof(c.AccountName), tmp);
|
|
CALL(hWnd, CcSetStartupAccount(cm->Client, &c));
|
|
CmVoice("set_startup");
|
|
MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_SET_STARTUP"), tmp);
|
|
Free(tmp);
|
|
}
|
|
break;
|
|
case CMD_NOSTARTUP:
|
|
// Unset the start-up connection
|
|
tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
|
|
if (tmp != NULL)
|
|
{
|
|
if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2,
|
|
_UU("CM_REMOVE_STARTUP"), tmp) == IDYES)
|
|
{
|
|
RPC_CLIENT_DELETE_ACCOUNT c;
|
|
Zero(&c, sizeof(c));
|
|
UniStrCpy(c.AccountName, sizeof(c.AccountName), tmp);
|
|
CALL(hWnd, CcRemoveStartupAccount(cm->Client, &c));
|
|
CmVoice("remove_startup");
|
|
}
|
|
Free(tmp);
|
|
}
|
|
break;
|
|
case CMD_DELETE:
|
|
// Delete
|
|
tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
|
|
if (tmp != NULL)
|
|
{
|
|
CmDeleteAccount(hWnd, tmp);
|
|
Free(tmp);
|
|
}
|
|
break;
|
|
case CMD_RENAME:
|
|
// Change the name
|
|
Focus(hWnd, L_ACCOUNT);
|
|
LvRename(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT));
|
|
break;
|
|
case CMD_PROPERTY:
|
|
// Property
|
|
tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
|
|
if (tmp != NULL)
|
|
{
|
|
CmEditAccount(hWnd, tmp);
|
|
Free(tmp);
|
|
}
|
|
break;
|
|
case IDCANCEL:
|
|
case CMD_EXIT:
|
|
// Close
|
|
Close(hWnd);
|
|
break;
|
|
case CMD_QUIT:
|
|
// Exit
|
|
CmMainWindowOnQuit(hWnd);
|
|
break;
|
|
case CMD_SELECT_ALL:
|
|
// Select all
|
|
LvSelectAll(hWnd, L_ACCOUNT);
|
|
LvSelectAll(hWnd, L_VLAN);
|
|
break;
|
|
case CMD_SWITCH_SELECT:
|
|
// Invert selection
|
|
LvSwitchSelect(hWnd, L_ACCOUNT);
|
|
LvSwitchSelect(hWnd, L_VLAN);
|
|
break;
|
|
case CMD_GRID:
|
|
// Show grid
|
|
cm->ShowGrid = !cm->ShowGrid;
|
|
CmRefreshVLanListEx(hWnd, true);
|
|
CmRefreshAccountListEx2(hWnd, false, true);
|
|
break;
|
|
case CMD_STATUSBAR:
|
|
// Show the status bar
|
|
if (cm->HideStatusBar == false)
|
|
{
|
|
cm->HideStatusBar = true;
|
|
Hide(hWnd, S_STATUSBAR);
|
|
CmMainWindowOnSize(hWnd);
|
|
}
|
|
else
|
|
{
|
|
cm->HideStatusBar = false;
|
|
Show(hWnd, S_STATUSBAR);
|
|
CmMainWindowOnSize(hWnd);
|
|
}
|
|
CmSaveMainWindowPos(hWnd);
|
|
break;
|
|
case CMD_VISTASTYLE:
|
|
cm->VistaStyle = !cm->VistaStyle;
|
|
CmRefreshEx(hWnd, true);
|
|
CmSaveMainWindowPos(hWnd);
|
|
break;
|
|
case CMD_TRAYICON:
|
|
// Tray icon display
|
|
if (cm->HideTrayIcon == false)
|
|
{
|
|
cm->HideTrayIcon = true;
|
|
CmFreeTray(hWnd);
|
|
|
|
if (IsHide(hWnd, 0))
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_TRAY_ICON_RESTORE"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cm->HideTrayIcon = false;
|
|
if (cm->server_name == NULL)
|
|
{
|
|
CmInitTray(hWnd);
|
|
}
|
|
}
|
|
break;
|
|
case CMD_SHOWPORT:
|
|
// Show the port number
|
|
cm->ShowPort = !cm->ShowPort;
|
|
CmRefresh(hWnd);
|
|
break;
|
|
case CMD_ICON:
|
|
// Show the icon
|
|
if (cm->IconView == false)
|
|
{
|
|
cm->IconView = true;
|
|
CmRefresh(hWnd);
|
|
}
|
|
break;
|
|
case CMD_DETAIL:
|
|
// Show details
|
|
if (cm->IconView)
|
|
{
|
|
cm->IconView = false;
|
|
CmRefresh(hWnd);
|
|
}
|
|
break;
|
|
case CMD_REFRESH:
|
|
if (easy == false)
|
|
{
|
|
// Display update
|
|
LvReset(hWnd, L_ACCOUNT);
|
|
LvReset(hWnd, L_VLAN);
|
|
CmRefresh(hWnd);
|
|
}
|
|
break;
|
|
case CMD_NEW_VLAN:
|
|
// Create a Virtual LAN card
|
|
if (CmStopInstallVLan(hWnd) == false)
|
|
{
|
|
// Installation is prohibited
|
|
break;
|
|
}
|
|
name = CmNewVLanDlg(hWnd);
|
|
if (name != NULL)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
void *helper = NULL;
|
|
RPC_CLIENT_CREATE_VLAN c;
|
|
Zero(&c, sizeof(c));
|
|
StrCpy(c.DeviceName, sizeof(c.DeviceName), name);
|
|
if (MsIsNt() == false)
|
|
{
|
|
// Change the title of the window
|
|
GetTxt(hWnd, 0, tmp, sizeof(tmp));
|
|
SetText(hWnd, 0, _UU("CM_VLAN_INSTALLING"));
|
|
}
|
|
// Minimize
|
|
if (MsIsVista() == false)
|
|
{
|
|
ShowWindow(hWnd, SW_SHOWMINIMIZED);
|
|
}
|
|
|
|
if (MsIsVista())
|
|
{
|
|
helper = CmStartUacHelper();
|
|
}
|
|
|
|
if (CALL(hWnd, CcCreateVLan(cm->Client, &c)))
|
|
{
|
|
CmVoice("new_vlan");
|
|
}
|
|
|
|
CmStopUacHelper(helper);
|
|
|
|
if (MsIsNt() == false)
|
|
{
|
|
// Restore the title of the window
|
|
SetText(hWnd, 0, tmp);
|
|
}
|
|
// Restore
|
|
if (MsIsVista() == false)
|
|
{
|
|
ShowWindow(hWnd, SW_SHOWNORMAL);
|
|
}
|
|
Free(name);
|
|
}
|
|
break;
|
|
case CMD_DELETE_VLAN:
|
|
// Delete the Virtual LAN card
|
|
index = LvGetSelected(hWnd, L_VLAN);
|
|
if (index != INFINITE)
|
|
{
|
|
if (cm->Client->Win9x == false)
|
|
{
|
|
// Windows 2000 or later
|
|
wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);
|
|
if (s != NULL)
|
|
{
|
|
RPC_CLIENT_CREATE_VLAN c;
|
|
char str[MAX_SIZE];
|
|
CmVoice("delete_vlan_1");
|
|
if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_VLAN"), s) == IDYES)
|
|
{
|
|
Zero(&c, sizeof(c));
|
|
UniToStr(str, sizeof(str), s);
|
|
if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))
|
|
{
|
|
if (CALL(hWnd, CcDeleteVLan(cm->Client, &c)))
|
|
{
|
|
CmVoice("delete_vlan_2");
|
|
}
|
|
}
|
|
}
|
|
Free(s);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Windows 9x
|
|
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("CM_9X_VLAN_UNINSTALL")) == IDYES)
|
|
{
|
|
Run("rundll32.exe", "shell32.dll,Control_RunDLL NETCPL.CPL",
|
|
false, false);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CMD_ENABLE_VLAN:
|
|
// Enable the virtual LAN card
|
|
index = LvGetSelected(hWnd, L_VLAN);
|
|
if (index != INFINITE)
|
|
{
|
|
wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);
|
|
if (s != NULL)
|
|
{
|
|
RPC_CLIENT_CREATE_VLAN c;
|
|
char str[MAX_SIZE];
|
|
Zero(&c, sizeof(c));
|
|
UniToStr(str, sizeof(str), s);
|
|
if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))
|
|
{
|
|
CALL(hWnd, CcEnableVLan(cm->Client, &c));
|
|
}
|
|
Free(s);
|
|
}
|
|
}
|
|
break;
|
|
case CMD_DISABLE_VLAN:
|
|
// Disable the virtual LAN card
|
|
index = LvGetSelected(hWnd, L_VLAN);
|
|
if (index != INFINITE)
|
|
{
|
|
wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);
|
|
if (s != NULL)
|
|
{
|
|
RPC_CLIENT_CREATE_VLAN c;
|
|
char str[MAX_SIZE];
|
|
Zero(&c, sizeof(c));
|
|
UniToStr(str, sizeof(str), s);
|
|
if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))
|
|
{
|
|
CALL(hWnd, CcDisableVLan(cm->Client, &c));
|
|
}
|
|
Free(s);
|
|
}
|
|
}
|
|
break;
|
|
case CMD_REINSTALL:
|
|
// Reinstall the virtual LAN card
|
|
if (CmStopInstallVLan(hWnd) == false)
|
|
{
|
|
// Installation is prohibited
|
|
break;
|
|
}
|
|
// Warning message
|
|
if (MsgBox(hWnd, MB_ICONINFORMATION | MB_OKCANCEL, _UU("CM_VLAN_REINSTALL_MSG")) == IDCANCEL)
|
|
{
|
|
// Cancel
|
|
break;
|
|
}
|
|
index = LvGetSelected(hWnd, L_VLAN);
|
|
if (index != INFINITE)
|
|
{
|
|
wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);
|
|
if (s != NULL)
|
|
{
|
|
RPC_CLIENT_CREATE_VLAN c;
|
|
char str[MAX_SIZE];
|
|
Zero(&c, sizeof(c));
|
|
UniToStr(str, sizeof(str), s);
|
|
if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))
|
|
{
|
|
void *helper = NULL;
|
|
|
|
if (MsIsVista() == false)
|
|
{
|
|
ShowWindow(hWnd, SW_SHOWMINIMIZED);
|
|
}
|
|
|
|
if (MsIsVista())
|
|
{
|
|
helper = CmStartUacHelper();
|
|
}
|
|
|
|
CALL(hWnd, CcUpgradeVLan(cm->Client, &c));
|
|
|
|
CmStopUacHelper(helper);
|
|
|
|
if (MsIsVista() == false)
|
|
{
|
|
ShowWindow(hWnd, SW_SHOWNORMAL);
|
|
}
|
|
}
|
|
Free(s);
|
|
}
|
|
}
|
|
break;
|
|
case CMD_PASSWORD:
|
|
// Password setting
|
|
CmPassword(hWnd);
|
|
break;
|
|
case CMD_OPTION:
|
|
// Option
|
|
CmConfigDlg(hWnd);
|
|
break;
|
|
case CMD_LANGUAGE:
|
|
// Language settings
|
|
if (true)
|
|
{
|
|
wchar_t path[MAX_SIZE];
|
|
|
|
CombinePathW(path, sizeof(path), MsGetExeDirNameW(), L"vpnsetup.exe");
|
|
|
|
if (MsExecuteW(path, L"/language:yes") == false)
|
|
{
|
|
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SW_CHILD_PROCESS_ERROR"));
|
|
}
|
|
}
|
|
break;
|
|
case CMD_TRUST:
|
|
// Certificate management
|
|
CmTrustDlg(hWnd);
|
|
break;
|
|
case CMD_ABOUT:
|
|
// Version information
|
|
if (IsEnable(hWnd, 0))
|
|
{
|
|
AboutEx(hWnd, cm->Cedar, _UU("PRODUCT_NAME_VPN_CMGR"), cm->Update);
|
|
}
|
|
break;
|
|
case CMD_VOIDE_NONE:
|
|
cm->DisableVoice = true;
|
|
break;
|
|
case CMD_VOICE_NORMAL:
|
|
cm->DisableVoice = false;
|
|
cm->VoiceId = VOICE_SSK;
|
|
break;
|
|
case CMD_VOICE_ODD:
|
|
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("CM_EXT_VOICE_MSG")) == IDYES)
|
|
{
|
|
cm->DisableVoice = false;
|
|
cm->VoiceId = VOICE_AHO;
|
|
}
|
|
break;
|
|
case CMD_SECURE_MANAGER:
|
|
// Smart Card Manager
|
|
CmClientSecureManager(hWnd);
|
|
break;
|
|
case CMD_SECURE_SELECT:
|
|
// Select a smart card
|
|
CmClientSelectSecure(hWnd);
|
|
break;
|
|
case CMD_NETIF:
|
|
// State of the network device
|
|
if (IsEnable(hWnd, 0))
|
|
{
|
|
UtSpeedMeterEx(hWnd);
|
|
}
|
|
break;
|
|
case CMD_MMCSS:
|
|
// Optimization utility for Windows Vista
|
|
if (MsIsVista() == false)
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_4"));
|
|
}
|
|
else
|
|
{
|
|
if (MsIsAdmin() == false)
|
|
{
|
|
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("VISTA_MMCSS_MSG_4"));
|
|
}
|
|
else
|
|
{
|
|
if (MsIsMMCSSNetworkThrottlingEnabled())
|
|
{
|
|
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("VISTA_MMCSS_MSG")) == IDYES)
|
|
{
|
|
MsSetMMCSSNetworkThrottlingEnable(false);
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_5"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("VISTA_MMCSS_MSG_2")) == IDYES)
|
|
{
|
|
MsSetMMCSSNetworkThrottlingEnable(true);
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_6"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CMD_TRAFFIC:
|
|
// Communication traffic measurement
|
|
if (IsEnable(hWnd, 0))
|
|
{
|
|
CmTraffic(hWnd);
|
|
}
|
|
break;
|
|
case CMD_CM_SETTING:
|
|
// Operation mode setting
|
|
if (IsEnable(hWnd, 0))
|
|
{
|
|
if (CmSetting(hWnd))
|
|
{
|
|
CmApplyCmSetting();
|
|
}
|
|
}
|
|
break;
|
|
case CMD_WINNET:
|
|
// Windows network settings
|
|
ShowWindowsNetworkConnectionDialog();
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Option dialog
|
|
void CmConfigDlg(HWND hWnd)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Dialog(hWnd, D_CM_CONFIG, CmConfigDlgProc, NULL);
|
|
}
|
|
|
|
// Initialize the option dialog
|
|
void CmConfigDlgInit(HWND hWnd)
|
|
{
|
|
bool use_alpha;
|
|
UINT alpha_value;
|
|
UINT os;
|
|
CLIENT_CONFIG c;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DlgFont(hWnd, S_WARNING, 10, true);
|
|
DlgFont(hWnd, S_INFO, 10, false);
|
|
|
|
Zero(&c, sizeof(c));
|
|
if (CALL(hWnd, CcGetClientConfig(cm->Client, &c)) == false)
|
|
{
|
|
EndDialog(hWnd, 0);
|
|
return;
|
|
}
|
|
|
|
Check(hWnd, R_ALLOW_REMOTE_CONFIG, c.AllowRemoteConfig);
|
|
|
|
Check(hWnd, R_USE_KEEP_CONNECT, c.UseKeepConnect);
|
|
SetTextA(hWnd, E_HOSTNAME, c.KeepConnectHost);
|
|
SetIntEx(hWnd, E_PORT, c.KeepConnectPort);
|
|
SetIntEx(hWnd, E_INTERVAL, c.KeepConnectInterval);
|
|
|
|
Check(hWnd, R_TCP, c.KeepConnectProtocol == CONNECTION_TCP);
|
|
Check(hWnd, R_UDP, c.KeepConnectProtocol == CONNECTION_UDP);
|
|
|
|
use_alpha = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "UseAlpha") == 0 ? false : true;
|
|
alpha_value = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "AlphaValue");
|
|
alpha_value = MAKESURE(alpha_value, 0, 100);
|
|
|
|
SetInt(hWnd, E_ALPHA_VALUE, alpha_value == 0 ? 50 : alpha_value);
|
|
Check(hWnd, R_ALPHA, use_alpha);
|
|
|
|
os = GetOsInfo()->OsType;
|
|
if (OS_IS_WINDOWS_NT(os) && GET_KETA(os, 100) >= 2)
|
|
{
|
|
Enable(hWnd, R_ALPHA);
|
|
}
|
|
else
|
|
{
|
|
Disable(hWnd, R_ALPHA);
|
|
}
|
|
|
|
CmConfigDlgRefresh(hWnd);
|
|
}
|
|
|
|
// Update the option dialog
|
|
void CmConfigDlgRefresh(HWND hWnd)
|
|
{
|
|
bool ok = true;
|
|
bool use_keep_connect;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
use_keep_connect = IsChecked(hWnd, R_USE_KEEP_CONNECT);
|
|
SetEnable(hWnd, S_HOSTNAME, use_keep_connect);
|
|
SetEnable(hWnd, S_PORT, use_keep_connect);
|
|
SetEnable(hWnd, S_INTERVAL, use_keep_connect);
|
|
SetEnable(hWnd, S_INTERVAL2, use_keep_connect);
|
|
SetEnable(hWnd, S_PROTOCOL, use_keep_connect);
|
|
SetEnable(hWnd, S_INFO, use_keep_connect);
|
|
SetEnable(hWnd, S_INFO2, use_keep_connect);
|
|
SetEnable(hWnd, E_HOSTNAME, use_keep_connect);
|
|
SetEnable(hWnd, E_PORT, use_keep_connect);
|
|
SetEnable(hWnd, E_INTERVAL, use_keep_connect);
|
|
SetEnable(hWnd, R_TCP, use_keep_connect);
|
|
SetEnable(hWnd, R_UDP, use_keep_connect);
|
|
|
|
SetEnable(hWnd, S_WARNING, IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG));
|
|
|
|
if (IsChecked(hWnd, R_USE_KEEP_CONNECT))
|
|
{
|
|
if (IsEmpty(hWnd, E_HOSTNAME))
|
|
{
|
|
ok = false;
|
|
}
|
|
if (IsChecked(hWnd, R_TCP) == false && IsChecked(hWnd, R_UDP) == false)
|
|
{
|
|
ok = false;
|
|
}
|
|
if (GetInt(hWnd, E_PORT) == 0 || GetInt(hWnd, E_PORT) >= 65536)
|
|
{
|
|
ok = false;
|
|
}
|
|
if (GetInt(hWnd, E_INTERVAL) == 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
}
|
|
|
|
if (IsChecked(hWnd, R_ALPHA))
|
|
{
|
|
UINT i = GetInt(hWnd, E_ALPHA_VALUE);
|
|
if (i < 20 || i >= 100)
|
|
{
|
|
ok = false;
|
|
}
|
|
Enable(hWnd, E_ALPHA_VALUE);
|
|
}
|
|
else
|
|
{
|
|
Disable(hWnd, E_ALPHA_VALUE);
|
|
}
|
|
|
|
SetEnable(hWnd, IDOK, ok);
|
|
}
|
|
|
|
// Save the setting of the option dialog
|
|
void CmConfigDlgOnOk(HWND hWnd)
|
|
{
|
|
CLIENT_CONFIG c;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Zero(&c, sizeof(c));
|
|
c.AllowRemoteConfig = IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG);
|
|
c.UseKeepConnect = IsChecked(hWnd, R_USE_KEEP_CONNECT);
|
|
GetTxtA(hWnd, E_HOSTNAME, c.KeepConnectHost, sizeof(c.KeepConnectHost));
|
|
c.KeepConnectPort = GetInt(hWnd, E_PORT);
|
|
c.KeepConnectInterval = GetInt(hWnd, E_INTERVAL);
|
|
if (IsChecked(hWnd, R_TCP))
|
|
{
|
|
c.KeepConnectProtocol = CONNECTION_TCP;
|
|
}
|
|
else if (IsChecked(hWnd, R_UDP))
|
|
{
|
|
c.KeepConnectProtocol = CONNECTION_UDP;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (c.UseKeepConnect)
|
|
{
|
|
if (c.KeepConnectInterval < KEEP_INTERVAL_MIN || c.KeepConnectInterval > KEEP_INTERVAL_MAX)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_KEEP_INTERVAL_MSG"),
|
|
KEEP_INTERVAL_MIN, KEEP_INTERVAL_MAX);
|
|
FocusEx(hWnd, E_INTERVAL);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (CALL(hWnd, CcSetClientConfig(cm->Client, &c)) == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "AlphaValue", GetInt(hWnd, E_ALPHA_VALUE));
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "UseAlpha", IsChecked(hWnd, R_ALPHA));
|
|
|
|
EndDialog(hWnd, true);
|
|
}
|
|
|
|
// Option setting dialog procedure
|
|
UINT CmConfigDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CmConfigDlgInit(hWnd);
|
|
break;
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case R_ALLOW_REMOTE_CONFIG:
|
|
case R_USE_KEEP_CONNECT:
|
|
case E_HOSTNAME:
|
|
case E_PORT:
|
|
case E_INTERVAL:
|
|
case R_ALPHA:
|
|
case E_ALPHA_VALUE:
|
|
CmConfigDlgRefresh(hWnd);
|
|
break;
|
|
}
|
|
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
CmConfigDlgRefresh(hWnd);
|
|
CmConfigDlgOnOk(hWnd);
|
|
break;
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
case R_ALLOW_REMOTE_CONFIG:
|
|
if (IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG) == false)
|
|
{
|
|
if (cm->server_name != NULL)
|
|
{
|
|
// If the current user is remotely connected, show a warning
|
|
// when the user choose to disable the remote management
|
|
if (MsgBoxEx(hWnd, MB_ICONEXCLAMATION | MB_DEFBUTTON2 | MB_YESNO, _UU("CM_REMOTE_WARNING"),
|
|
cm->server_name, cm->server_name) == IDNO)
|
|
{
|
|
Check(hWnd, R_ALLOW_REMOTE_CONFIG, true);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case R_USE_KEEP_CONNECT:
|
|
if (IsChecked(hWnd, R_USE_KEEP_CONNECT))
|
|
{
|
|
FocusEx(hWnd, E_HOSTNAME);
|
|
}
|
|
break;
|
|
case R_ALPHA:
|
|
if (IsChecked(hWnd, R_ALPHA))
|
|
{
|
|
FocusEx(hWnd, E_ALPHA_VALUE);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Create a shortcut
|
|
void CmSortcut(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
CM_ACCOUNT *a;
|
|
wchar_t *filename;
|
|
UCHAR key[SHA1_SIZE];
|
|
// Validate arguments
|
|
if (hWnd == NULL || account_name == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the account information
|
|
a = CmGetExistAccountObject(hWnd, account_name);
|
|
if (a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Copy(key, a->ShortcutKey, SHA1_SIZE);
|
|
|
|
if (IsZero(key, SHA1_SIZE))
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_SHORTCUT_UNSUPPORTED"));
|
|
}
|
|
else
|
|
{
|
|
// Determine the file name
|
|
UniFormat(tmp, sizeof(tmp), L"%s.lnk", account_name);
|
|
UniSafeFileName(tmp);
|
|
|
|
filename = SaveDlg(hWnd, _UU("CM_SHORTCUT_FILE"),
|
|
_UU("CM_SHORTCUT_SAVE_TITLE"), tmp, L".vpn");
|
|
|
|
if (filename != NULL)
|
|
{
|
|
char key_str[64];
|
|
wchar_t target[MAX_PATH];
|
|
wchar_t workdir[MAX_PATH];
|
|
wchar_t args[MAX_PATH];
|
|
wchar_t comment[MAX_SIZE];
|
|
wchar_t icon[MAX_PATH];
|
|
|
|
BinToStr(key_str, sizeof(key_str), key, SHA1_SIZE);
|
|
|
|
// Create a shortcut
|
|
UniStrCpy(target, sizeof(target), MsGetExeFileNameW());
|
|
UniStrCpy(workdir, sizeof(workdir), MsGetExeDirNameW());
|
|
StrToUni(args, sizeof(args), key_str);
|
|
UniFormat(comment, sizeof(comment), _UU("CM_SHORTCUT_COMMENT"), account_name);
|
|
UniStrCpy(icon, sizeof(icon), MsGetExeFileNameW());
|
|
|
|
if (CreateLink(filename, target, workdir, args, comment, icon, 1) == false)
|
|
{
|
|
MsgBox(hWnd, MB_ICONSTOP, _UU("CM_SHORTCUT_ERROR"));
|
|
}
|
|
|
|
Free(filename);
|
|
}
|
|
}
|
|
|
|
CmFreeAccountObject(hWnd, a);
|
|
}
|
|
|
|
// Export the account
|
|
void CmExportAccount(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
CM_ACCOUNT *a;
|
|
wchar_t *filename;
|
|
// Validate arguments
|
|
if (hWnd == NULL || account_name == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the account information
|
|
a = CmGetExistAccountObject(hWnd, account_name);
|
|
if (a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Determine the file name
|
|
UniFormat(tmp, sizeof(tmp), L"%s.vpn", account_name);
|
|
UniSafeFileName(tmp);
|
|
|
|
filename = SaveDlg(hWnd, _UU("CM_ACCOUNT_SETTING_FILE"),
|
|
_UU("CM_ACCOUNT_SAVE_TITLE"), tmp, L".vpn");
|
|
|
|
if (filename != NULL)
|
|
{
|
|
RPC_CLIENT_CREATE_ACCOUNT t;
|
|
BUF *b;
|
|
BUF *b2;
|
|
wchar_t tmp[MAX_SIZE];
|
|
UCHAR *buf;
|
|
UINT buf_size;
|
|
UCHAR bom[] = {0xef, 0xbb, 0xbf, };
|
|
|
|
Zero(&t, sizeof(t));
|
|
t.ClientOption = a->ClientOption;
|
|
t.ClientAuth = a->ClientAuth;
|
|
t.StartupAccount = a->Startup;
|
|
t.CheckServerCert = a->CheckServerCert;
|
|
t.ServerCert = a->ServerCert;
|
|
t.ClientOption->FromAdminPack = false;
|
|
|
|
b = CiAccountToCfg(&t);
|
|
|
|
SeekBuf(b, 0, 0);
|
|
|
|
// Check whether the password is contained
|
|
if (CiHasAccountSensitiveInformation(b))
|
|
{
|
|
SeekBuf(b, 0, 0);
|
|
|
|
// Confirm that the user want to clear the password
|
|
if (MsgBox(hWnd, MB_YESNO | MB_ICONQUESTION, _UU("CM_ACCOUNT_MSG_SENSITIVE")) == IDYES)
|
|
{
|
|
// Erase
|
|
CiEraseSensitiveInAccount(b);
|
|
}
|
|
}
|
|
|
|
UniStrCpy(tmp, sizeof(tmp), filename);
|
|
b2 = NewBuf();
|
|
|
|
WriteBuf(b2, bom, sizeof(bom));
|
|
|
|
// Add a header part
|
|
buf_size = CalcUniToUtf8(_UU("CM_ACCOUNT_FILE_BANNER"));
|
|
buf = ZeroMalloc(buf_size + 32);
|
|
UniToUtf8(buf, buf_size, _UU("CM_ACCOUNT_FILE_BANNER"));
|
|
|
|
WriteBuf(b2, buf, StrLen((char *)buf));
|
|
WriteBuf(b2, b->Buf, b->Size);
|
|
SeekBuf(b2, 0, 0);
|
|
|
|
FreeBuf(b);
|
|
|
|
if (DumpBufW(b2, tmp) == false)
|
|
{
|
|
MsgBox(hWnd, MB_ICONSTOP, _UU("CM_FAILED_TO_SAVE_FILE"));
|
|
}
|
|
|
|
Free(filename);
|
|
FreeBuf(b2);
|
|
Free(buf);
|
|
}
|
|
|
|
CmFreeAccountObject(hWnd, a);
|
|
}
|
|
|
|
// Main process of importing account
|
|
void CmImportAccountMain(HWND hWnd, wchar_t *filename)
|
|
{
|
|
CmImportAccountMainEx(hWnd, filename, false);
|
|
}
|
|
void CmImportAccountMainEx(HWND hWnd, wchar_t *filename, bool overwrite)
|
|
{
|
|
wchar_t name[MAX_SIZE];
|
|
wchar_t tmp[MAX_SIZE];
|
|
BUF *b;
|
|
RPC_CLIENT_CREATE_ACCOUNT *t;
|
|
// Validate arguments
|
|
if (hWnd == NULL || filename == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
UniStrCpy(tmp, sizeof(tmp), filename);
|
|
|
|
b = ReadDumpW(tmp);
|
|
if (b == NULL)
|
|
{
|
|
MsgBox(hWnd, MB_ICONSTOP, _UU("CM_FAILED_TO_OPEN_FILE"));
|
|
return;
|
|
}
|
|
|
|
t = CiCfgToAccount(b);
|
|
if (t == NULL)
|
|
{
|
|
FreeBuf(b);
|
|
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("CM_ACCOUNT_PARSE_FAILED"));
|
|
return;
|
|
}
|
|
|
|
if (overwrite)
|
|
{
|
|
// If the same name already exists, remove it
|
|
if (LvSearchStr(hWnd, L_ACCOUNT, 0, t->ClientOption->AccountName) != INFINITE)
|
|
{
|
|
RPC_CLIENT_DELETE_ACCOUNT d;
|
|
RPC_CLIENT_GET_ACCOUNT get;
|
|
HWND h = cm->hEasyWnd == NULL ? hWnd : cm->hEasyWnd;
|
|
|
|
Zero(&d, sizeof(d));
|
|
UniStrCpy(d.AccountName, sizeof(d.AccountName), t->ClientOption->AccountName);
|
|
|
|
Zero(&get, sizeof(get));
|
|
UniStrCpy(get.AccountName, sizeof(get.AccountName), t->ClientOption->AccountName);
|
|
if (CcGetAccount(cm->Client, &get) == ERR_NO_ERROR)
|
|
{
|
|
// Inherit the information of some of the client option by getting
|
|
// the account information of the same name that already exists
|
|
if (get.ClientOption != NULL && get.ClientAuth != NULL)
|
|
{
|
|
CLIENT_OPTION *old_option = get.ClientOption;
|
|
CLIENT_AUTH *old_auth = get.ClientAuth;
|
|
|
|
// Inherit the connection parameters
|
|
t->ClientOption->ProxyType = old_option->ProxyType;
|
|
StrCpy(t->ClientOption->ProxyName, sizeof(t->ClientOption->ProxyName),
|
|
old_option->ProxyName);
|
|
t->ClientOption->ProxyPort = old_option->ProxyPort;
|
|
StrCpy(t->ClientOption->ProxyUsername, sizeof(t->ClientOption->ProxyUsername),
|
|
old_option->ProxyUsername);
|
|
StrCpy(t->ClientOption->ProxyPassword, sizeof(t->ClientOption->ProxyPassword),
|
|
old_option->ProxyPassword);
|
|
t->ClientOption->NumRetry = old_option->NumRetry;
|
|
t->ClientOption->RetryInterval = old_option->RetryInterval;
|
|
t->ClientOption->MaxConnection = old_option->MaxConnection;
|
|
t->ClientOption->UseEncrypt = old_option->UseEncrypt;
|
|
t->ClientOption->UseCompress = old_option->UseCompress;
|
|
t->ClientOption->HalfConnection = old_option->HalfConnection;
|
|
t->ClientOption->NoRoutingTracking = old_option->NoRoutingTracking;
|
|
StrCpy(t->ClientOption->DeviceName, sizeof(t->ClientOption->DeviceName),
|
|
old_option->DeviceName);
|
|
t->ClientOption->AdditionalConnectionInterval = old_option->AdditionalConnectionInterval;
|
|
t->ClientOption->ConnectionDisconnectSpan = old_option->ConnectionDisconnectSpan;
|
|
t->ClientOption->HideStatusWindow = old_option->HideStatusWindow;
|
|
t->ClientOption->RequireMonitorMode = old_option->RequireMonitorMode;
|
|
t->ClientOption->RequireBridgeRoutingMode = old_option->RequireBridgeRoutingMode;
|
|
t->ClientOption->DisableQoS = old_option->DisableQoS;
|
|
t->ClientOption->NoTls1 = old_option->NoTls1;
|
|
|
|
// Inherit the authentication data
|
|
CiFreeClientAuth(t->ClientAuth);
|
|
t->ClientAuth = CopyClientAuth(old_auth);
|
|
|
|
// Other Settings
|
|
t->StartupAccount = get.StartupAccount;
|
|
t->CheckServerCert = get.CheckServerCert;
|
|
if (t->ServerCert != NULL)
|
|
{
|
|
FreeX(t->ServerCert);
|
|
}
|
|
t->ServerCert = NULL;
|
|
if (get.ServerCert != NULL)
|
|
{
|
|
t->ServerCert = CloneX(get.ServerCert);
|
|
}
|
|
Copy(t->ShortcutKey, get.ShortcutKey, sizeof(t->ShortcutKey));
|
|
}
|
|
|
|
CiFreeClientGetAccount(&get);
|
|
}
|
|
|
|
if (CALL(h, CcDeleteAccount(cm->Client, &d)) == false)
|
|
{
|
|
CiFreeClientCreateAccount(t);
|
|
Free(t);
|
|
return;
|
|
}
|
|
|
|
CmRefreshAccountList(hWnd);
|
|
}
|
|
}
|
|
|
|
CmGenerateImportName(hWnd, name, sizeof(name), t->ClientOption->AccountName);
|
|
UniStrCpy(t->ClientOption->AccountName, sizeof(t->ClientOption->AccountName), name);
|
|
|
|
if (overwrite)
|
|
{
|
|
t->ClientOption->FromAdminPack = true;
|
|
}
|
|
|
|
CALL(hWnd, CcCreateAccount(cm->Client, t));
|
|
|
|
CiFreeClientCreateAccount(t);
|
|
Free(t);
|
|
|
|
FreeBuf(b);
|
|
|
|
if (overwrite)
|
|
{
|
|
// Start to connect the VPN
|
|
CmConnect(hWnd, name);
|
|
}
|
|
|
|
//MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_IMPORT_MESSAGE"), filename, name);
|
|
}
|
|
|
|
// Import an account
|
|
void CmImportAccount(HWND hWnd)
|
|
{
|
|
wchar_t *filename;
|
|
wchar_t tmp[MAX_SIZE];
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Open the file
|
|
filename = OpenDlg(hWnd, _UU("CM_ACCOUNT_SETTING_FILE"), _UU("CM_ACCOUNT_OPEN_TITLE"));
|
|
if (filename == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
UniStrCpy(tmp, sizeof(tmp), filename);
|
|
Free(filename);
|
|
|
|
CmImportAccountMain(hWnd, tmp);
|
|
}
|
|
|
|
// Create a copy of the account
|
|
void CmCopyAccount(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
CM_ACCOUNT *a;
|
|
RPC_CLIENT_CREATE_ACCOUNT c;
|
|
// Validate arguments
|
|
if (hWnd == NULL || account_name == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CmGenerateCopyName(hWnd, tmp, sizeof(tmp), account_name);
|
|
|
|
// Get an account information
|
|
a = CmGetExistAccountObject(hWnd, account_name);
|
|
if (a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Change the account name
|
|
UniStrCpy(a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName), tmp);
|
|
|
|
// Write
|
|
Zero(&c, sizeof(c));
|
|
c.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
|
|
Copy(c.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
|
|
c.ClientAuth = CopyClientAuth(a->ClientAuth);
|
|
if (a->ServerCert)
|
|
{
|
|
c.ServerCert = CloneX(a->ServerCert);
|
|
}
|
|
c.CheckServerCert = a->CheckServerCert;
|
|
c.StartupAccount = false; // Don't copy the startup attribute
|
|
|
|
CALL(hWnd, CcCreateAccount(cm->Client, &c));
|
|
CiFreeClientCreateAccount(&c);
|
|
|
|
CmFreeAccountObject(hWnd, a);
|
|
}
|
|
|
|
// Update the Virtual LAN Card Name dialog
|
|
void CmNewVLanDlgUpdate(HWND hWnd)
|
|
{
|
|
bool ok = true;
|
|
char tmp[MAX_SIZE];
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GetTxtA(hWnd, E_NAME, tmp, sizeof(tmp));
|
|
if (IsSafeStr(tmp) == false)
|
|
{
|
|
ok = false;
|
|
}
|
|
if (SearchStrEx(tmp, " ", 0, false) != INFINITE)
|
|
{
|
|
ok = false;
|
|
}
|
|
|
|
Trim(tmp);
|
|
if (StrLen(tmp) == 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
|
|
SetEnable(hWnd, IDOK, ok);
|
|
}
|
|
|
|
// Virtual LAN card name decision dialog procedure
|
|
UINT CmNewVLanDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
char *tmp = (char *)param;
|
|
char default_name[MAX_SIZE];
|
|
RPC_CLIENT_VERSION ver;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
LimitText(hWnd, E_NAME, cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN);
|
|
FormatText(hWnd, S_INFO, cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN);
|
|
|
|
Zero(&ver, sizeof(ver));
|
|
|
|
if (CcGetClientVersion(cm->Client, &ver) == ERR_NO_ERROR)
|
|
{
|
|
if (ver.IsVLanNameRegulated)
|
|
{
|
|
Show(hWnd, S_WIN8);
|
|
}
|
|
}
|
|
|
|
if (CiGetNextRecommendedVLanName(cm->Client, default_name, sizeof(default_name)))
|
|
{
|
|
// Show a default virtual LAN card name candidate
|
|
SetTextA(hWnd, E_NAME, default_name);
|
|
}
|
|
|
|
CmNewVLanDlgUpdate(hWnd);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
if (cm->Client->Win9x)
|
|
{
|
|
// For Windows 9x, show a confirmation message
|
|
if (MsgBox(hWnd, MB_ICONQUESTION | MB_OKCANCEL, _UU("CM_9X_VLAN_INSTALL")) == IDCANCEL)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
GetTxtA(hWnd, E_NAME, tmp, (cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN) + 1);
|
|
Trim(tmp);
|
|
|
|
if (CcGetClientVersion(cm->Client, &ver) == ERR_NO_ERROR)
|
|
{
|
|
if (ver.IsVLanNameRegulated)
|
|
{
|
|
if (CiIsValidVLanRegulatedName(tmp) == false)
|
|
{
|
|
// Virtual LAN card name isn't meeting the format
|
|
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("D_CM_NEW_VLAN@S_WIN8"));
|
|
|
|
FocusEx(hWnd, E_NAME);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
EndDialog(hWnd, true);
|
|
break;
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case E_NAME:
|
|
CmNewVLanDlgUpdate(hWnd);
|
|
break;
|
|
|
|
case R_USE_DISCONNECT:
|
|
if (IsChecked(hWnd, R_USE_DISCONNECT))
|
|
{
|
|
FocusEx(hWnd, E_DISCONNECT_SPAN);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Dialog to determine the new virtual LAN card name
|
|
char *CmNewVLanDlg(HWND hWnd)
|
|
{
|
|
char tmp[MAX_DEVICE_NAME_LEN + 1];
|
|
|
|
if (Dialog(hWnd, D_CM_NEW_VLAN, CmNewVLanDlgProc, tmp) == false)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return CopyStr(tmp);
|
|
}
|
|
|
|
// Update the advanced settings dialog
|
|
void CmDetailDlgUpdate(HWND hWnd, CM_ACCOUNT *a)
|
|
{
|
|
bool ok = true;
|
|
bool locked;
|
|
// Validate arguments
|
|
if (hWnd == NULL || a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
locked = a->LockMode;
|
|
|
|
if (a->LinkMode || a->NatMode)
|
|
{
|
|
Disable(hWnd, R_NO_ROUTING);
|
|
}
|
|
else
|
|
{
|
|
if (cm->Client->Unix)
|
|
{
|
|
Disable(hWnd, R_NO_ROUTING);
|
|
}
|
|
}
|
|
|
|
SetEnable(hWnd, E_DISCONNECT_SPAN, IsChecked(hWnd, R_USE_DISCONNECT));
|
|
|
|
SetEnable(hWnd, IDOK, ok);
|
|
|
|
if (locked)
|
|
{
|
|
Disable(hWnd, C_NUM_TCP);
|
|
Disable(hWnd, S_STATIC5);
|
|
Disable(hWnd, S_STATIC8);
|
|
Disable(hWnd, E_INTERVAL);
|
|
Disable(hWnd, S_STATIC9);
|
|
Disable(hWnd, E_DISCONNECT_SPAN);
|
|
Disable(hWnd, S_STATIC10);
|
|
Disable(hWnd, S_STATIC11);
|
|
Disable(hWnd, R_USE_DISCONNECT);
|
|
Disable(hWnd, R_USE_HALF_CONNECTION);
|
|
Disable(hWnd, R_DISABLE_QOS);
|
|
Disable(hWnd, R_USE_ENCRYPT);
|
|
Disable(hWnd, R_USE_COMPRESS);
|
|
Disable(hWnd, R_BRIDGE);
|
|
Disable(hWnd, R_MONITOR);
|
|
Disable(hWnd, R_NO_ROUTING);
|
|
}
|
|
}
|
|
|
|
// Advanced Settings dialog procedure
|
|
UINT CmDetailDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
CM_ACCOUNT *a = (CM_ACCOUNT *)param;
|
|
UINT i;
|
|
UINT num;
|
|
wchar_t tmp[MAX_SIZE];
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
// Number of TCP connections
|
|
for (i = 1;i <= MAX_TCP_CONNECTION;i++)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), L"%u", i);
|
|
CbAddStr(hWnd, C_NUM_TCP, tmp, i);
|
|
}
|
|
CbSelect(hWnd, C_NUM_TCP, a->ClientOption->MaxConnection);
|
|
|
|
// Connection establishment interval
|
|
SetInt(hWnd, E_INTERVAL, a->ClientOption->AdditionalConnectionInterval);
|
|
|
|
// Lifetime
|
|
SetIntEx(hWnd, E_DISCONNECT_SPAN, a->ClientOption->ConnectionDisconnectSpan);
|
|
Check(hWnd, R_USE_DISCONNECT, a->ClientOption->ConnectionDisconnectSpan != 0);
|
|
Check(hWnd, R_USE_HALF_CONNECTION, a->ClientOption->HalfConnection);
|
|
Check(hWnd, R_USE_ENCRYPT, a->ClientOption->UseEncrypt);
|
|
Check(hWnd, R_USE_COMPRESS, a->ClientOption->UseCompress);
|
|
Check(hWnd, R_NO_ROUTING, a->ClientOption->NoRoutingTracking);
|
|
Check(hWnd, R_DISABLE_QOS, a->ClientOption->DisableQoS);
|
|
Check(hWnd, R_DISABLE_UDP, a->ClientOption->NoUdpAcceleration);
|
|
|
|
// Select the Connection Mode
|
|
if (a->LinkMode == false)
|
|
{
|
|
Check(hWnd, R_BRIDGE, a->ClientOption->RequireBridgeRoutingMode);
|
|
Check(hWnd, R_MONITOR, a->ClientOption->RequireMonitorMode);
|
|
}
|
|
else
|
|
{
|
|
Check(hWnd, R_BRIDGE, true);
|
|
Check(hWnd, R_MONITOR, false);
|
|
|
|
SetText(hWnd, S_MODE, _UU("CM_DETAIL_MODE_LINK_STR"));
|
|
Disable(hWnd, R_BRIDGE);
|
|
Disable(hWnd, R_MONITOR);
|
|
}
|
|
|
|
CmDetailDlgUpdate(hWnd, a);
|
|
Focus(hWnd, IDOK);
|
|
break;
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
if (IsChecked(hWnd, R_USE_DISCONNECT) && GetInt(hWnd, E_DISCONNECT_SPAN) == 0)
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_NO_DISCONNECT_SPAN"));
|
|
FocusEx(hWnd, E_DISCONNECT_SPAN);
|
|
break;
|
|
}
|
|
num = GetInt(hWnd, C_NUM_TCP);
|
|
if (num == 0)
|
|
{
|
|
break;
|
|
}
|
|
if (num == 1 && IsChecked(hWnd, R_USE_HALF_CONNECTION))
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_HALF_MSG"));
|
|
Focus(hWnd, C_NUM_TCP);
|
|
break;
|
|
}
|
|
if (GetInt(hWnd, E_INTERVAL) < 1)
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_TOO_SMALL_INTERVAL"));
|
|
Focus(hWnd, E_INTERVAL);
|
|
break;
|
|
}
|
|
|
|
a->ClientOption->MaxConnection = num;
|
|
a->ClientOption->AdditionalConnectionInterval = GetInt(hWnd, E_INTERVAL);
|
|
if (IsChecked(hWnd, R_USE_DISCONNECT) == false)
|
|
{
|
|
a->ClientOption->ConnectionDisconnectSpan = 0;
|
|
}
|
|
else
|
|
{
|
|
a->ClientOption->ConnectionDisconnectSpan = GetInt(hWnd, E_DISCONNECT_SPAN);
|
|
}
|
|
a->ClientOption->HalfConnection = IsChecked(hWnd, R_USE_HALF_CONNECTION);
|
|
a->ClientOption->UseEncrypt = IsChecked(hWnd, R_USE_ENCRYPT);
|
|
a->ClientOption->UseCompress = IsChecked(hWnd, R_USE_COMPRESS);
|
|
a->ClientOption->NoRoutingTracking = IsChecked(hWnd, R_NO_ROUTING);
|
|
a->ClientOption->DisableQoS = IsChecked(hWnd, R_DISABLE_QOS);
|
|
a->ClientOption->NoUdpAcceleration = IsChecked(hWnd, R_DISABLE_UDP);
|
|
|
|
if (a->LinkMode)
|
|
{
|
|
a->ClientOption->RequireBridgeRoutingMode = true;
|
|
a->ClientOption->RequireMonitorMode = false;
|
|
}
|
|
else
|
|
{
|
|
a->ClientOption->RequireBridgeRoutingMode = IsChecked(hWnd, R_BRIDGE);
|
|
a->ClientOption->RequireMonitorMode = IsChecked(hWnd, R_MONITOR);
|
|
}
|
|
|
|
EndDialog(hWnd, true);
|
|
|
|
break;
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case C_NUM_TCP:
|
|
case E_INTERVAL:
|
|
case E_DISCONNECT_SPAN:
|
|
case R_USE_DISCONNECT:
|
|
case R_USE_HALF_CONNECTION:
|
|
CmDetailDlgUpdate(hWnd, a);
|
|
break;
|
|
}
|
|
switch (wParam)
|
|
{
|
|
case R_USE_DISCONNECT:
|
|
if (IsChecked(hWnd, R_USE_DISCONNECT))
|
|
{
|
|
FocusEx(hWnd, E_DISCONNECT_SPAN);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Advanced Settings dialog
|
|
bool CmDetailDlg(HWND hWnd, CM_ACCOUNT *a)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || a == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return Dialog(hWnd, D_CM_DETAIL, CmDetailDlgProc, a);
|
|
}
|
|
|
|
// Update the account editing dialog procedure
|
|
void CmEditAccountDlgUpdate(HWND hWnd, CM_ACCOUNT *a)
|
|
{
|
|
bool ok = true;
|
|
char str[MAX_SIZE];
|
|
bool locked;
|
|
// Validate arguments
|
|
if (hWnd == NULL || a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
locked = a->LockMode;
|
|
|
|
if (a->Inited == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (a->EditMode)
|
|
{
|
|
Disable(hWnd, E_ACCOUNT_NAME);
|
|
}
|
|
|
|
// The name of connection settings
|
|
GetTxt(hWnd, E_ACCOUNT_NAME, a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName));
|
|
UniTrim(a->ClientOption->AccountName);
|
|
|
|
// Host name
|
|
GetTxtA(hWnd, E_HOSTNAME, a->ClientOption->Hostname, sizeof(a->ClientOption->Hostname));
|
|
Trim(a->ClientOption->Hostname);
|
|
|
|
if (InStr(a->ClientOption->Hostname, "/tcp"))
|
|
{
|
|
Check(hWnd, R_DISABLE_NATT, true);
|
|
}
|
|
else
|
|
{
|
|
Check(hWnd, R_DISABLE_NATT, false);
|
|
}
|
|
|
|
SetEnable(hWnd, R_DISABLE_NATT, !IsEmptyStr(a->ClientOption->Hostname));
|
|
|
|
// Port number
|
|
a->ClientOption->Port = GetInt(hWnd, C_PORT);
|
|
|
|
// HUB name
|
|
GetTxtA(hWnd,C_HUBNAME, a->ClientOption->HubName, sizeof(a->ClientOption->HubName));
|
|
|
|
// Type of proxy
|
|
a->ClientOption->ProxyType = PROXY_DIRECT;
|
|
if (IsChecked(hWnd, R_HTTPS))
|
|
{
|
|
a->ClientOption->ProxyType = PROXY_HTTP;
|
|
}
|
|
if (IsChecked(hWnd, R_SOCKS))
|
|
{
|
|
a->ClientOption->ProxyType = PROXY_SOCKS;
|
|
}
|
|
|
|
// To validate the server certificate
|
|
a->CheckServerCert = IsChecked(hWnd, R_CHECK_CERT);
|
|
|
|
if (a->NatMode)
|
|
{
|
|
Disable(hWnd, R_CHECK_CERT);
|
|
Disable(hWnd, B_TRUST);
|
|
}
|
|
|
|
if (a->HideTrustCert)
|
|
{
|
|
Disable(hWnd, B_TRUST);
|
|
}
|
|
|
|
// Device name
|
|
StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName), "");
|
|
if (LvIsSelected(hWnd, L_VLAN))
|
|
{
|
|
wchar_t *s = LvGetStr(hWnd, L_VLAN, LvGetSelected(hWnd, L_VLAN), 0);
|
|
if (s != NULL)
|
|
{
|
|
char str[MAX_SIZE];
|
|
UniToStr(str, sizeof(str), s);
|
|
CmPrintNameToVLanName(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName), str);
|
|
Free(s);
|
|
}
|
|
}
|
|
|
|
// User authentication
|
|
a->ClientAuth->AuthType = CbGetSelect(hWnd, C_TYPE);
|
|
GetTxtA(hWnd, E_USERNAME, a->ClientAuth->Username, sizeof(a->ClientAuth->Username));
|
|
Trim(a->ClientAuth->Username);
|
|
switch (a->ClientAuth->AuthType)
|
|
{
|
|
case CLIENT_AUTHTYPE_PASSWORD:
|
|
// Password authentication
|
|
GetTxtA(hWnd, E_PASSWORD, str, sizeof(str));
|
|
if (StrCmp(str, HIDDEN_PASSWORD) != 0)
|
|
{
|
|
HashPassword(a->ClientAuth->HashedPassword, a->ClientAuth->Username, str);
|
|
}
|
|
break;
|
|
case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
|
|
// Plaintext password authentication
|
|
GetTxtA(hWnd, E_PASSWORD, str, sizeof(str));
|
|
if (StrCmp(str, HIDDEN_PASSWORD) != 0)
|
|
{
|
|
StrCpy(a->ClientAuth->PlainPassword, sizeof(a->ClientAuth->PlainPassword), str);
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Reconnection option
|
|
if ((a->LinkMode || a->NatMode) || a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
|
|
{
|
|
Disable(hWnd, R_RETRY);
|
|
}
|
|
else
|
|
{
|
|
Enable(hWnd, R_RETRY);
|
|
}
|
|
|
|
if (IsChecked(hWnd, R_RETRY) == false)
|
|
{
|
|
a->ClientOption->NumRetry = 0;
|
|
}
|
|
else
|
|
{
|
|
if (IsChecked(hWnd, R_INFINITE))
|
|
{
|
|
a->ClientOption->NumRetry = INFINITE;
|
|
}
|
|
else
|
|
{
|
|
a->ClientOption->NumRetry = GetInt(hWnd, E_RETRY_NUM);
|
|
}
|
|
}
|
|
a->ClientOption->RetryInterval = GetInt(hWnd, E_RETRY_SPAN);
|
|
|
|
a->ClientOption->NoTls1 = IsChecked(hWnd, R_NOTLS1);
|
|
|
|
// Information determining
|
|
if (UniStrLen(a->ClientOption->AccountName) == 0 && a->NatMode == false)
|
|
{
|
|
ok = false;
|
|
}
|
|
if (StrLen(a->ClientOption->Hostname) == 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
if (a->ClientOption->Port == 0 || a->ClientOption->Port >= 65536)
|
|
{
|
|
ok = false;
|
|
}
|
|
if (StrLen(a->ClientOption->HubName) == 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
if (StrLen(a->ClientAuth->Username) == 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
|
|
{
|
|
if (a->ClientAuth->ClientK == NULL || a->ClientAuth->ClientX == NULL)
|
|
{
|
|
ok = false;
|
|
}
|
|
}
|
|
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
|
|
{
|
|
if (IsEmptyStr(a->ClientAuth->SecurePrivateKeyName) || IsEmptyStr(a->ClientAuth->SecurePublicCertName))
|
|
{
|
|
ok = false;
|
|
}
|
|
}
|
|
|
|
// Display update
|
|
if (IsChecked(hWnd, R_RETRY) && IsEnable(hWnd, R_RETRY))
|
|
{
|
|
if (a->LinkMode == false && a->NatMode == false)
|
|
{
|
|
Enable(hWnd, R_INFINITE);
|
|
Enable(hWnd, E_RETRY_SPAN);
|
|
Enable(hWnd, S_RETRY_SPAN_1);
|
|
Enable(hWnd, S_RETRY_SPAN_2);
|
|
}
|
|
else
|
|
{
|
|
Disable(hWnd, R_INFINITE);
|
|
Disable(hWnd, E_RETRY_SPAN);
|
|
Disable(hWnd, S_RETRY_SPAN_1);
|
|
Disable(hWnd, S_RETRY_SPAN_2);
|
|
}
|
|
if (IsChecked(hWnd, R_INFINITE) == false)
|
|
{
|
|
Enable(hWnd, E_RETRY_NUM);
|
|
Enable(hWnd, S_RETRY_NUM_1);
|
|
Enable(hWnd, S_RETRY_NUM_2);
|
|
if (GetInt(hWnd, E_RETRY_NUM) == 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Disable(hWnd, E_RETRY_NUM);
|
|
Disable(hWnd, S_RETRY_NUM_1);
|
|
Disable(hWnd, S_RETRY_NUM_2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Disable(hWnd, E_RETRY_NUM);
|
|
Disable(hWnd, E_RETRY_SPAN);
|
|
Disable(hWnd, R_INFINITE);
|
|
Disable(hWnd, S_RETRY_NUM_1);
|
|
Disable(hWnd, S_RETRY_NUM_2);
|
|
Disable(hWnd, S_RETRY_SPAN_1);
|
|
Disable(hWnd, S_RETRY_SPAN_2);
|
|
}
|
|
|
|
if (a->NatMode == false)
|
|
{
|
|
if (a->ServerCert == NULL)
|
|
{
|
|
SetText(hWnd, B_SERVER_CERT, _UU("CM_SERVER_CERT_1"));
|
|
Disable(hWnd, B_VIEW_SERVER_CERT);
|
|
}
|
|
else
|
|
{
|
|
SetText(hWnd, B_SERVER_CERT, _UU("CM_SERVER_CERT_2"));
|
|
Enable(hWnd, B_VIEW_SERVER_CERT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Disable(hWnd, B_VIEW_SERVER_CERT);
|
|
Disable(hWnd, B_SERVER_CERT);
|
|
}
|
|
|
|
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT || a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
|
|
{
|
|
wchar_t tmp[MAX_SIZE * 2];
|
|
wchar_t issuer[MAX_SIZE];
|
|
wchar_t subject[MAX_SIZE];
|
|
wchar_t expires[MAX_SIZE];
|
|
|
|
SetIcon(hWnd, S_CERT, (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT) ? ICO_CERT : ICO_SECURE);
|
|
|
|
Hide(hWnd, S_PASSWORD);
|
|
Hide(hWnd, E_PASSWORD);
|
|
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
|
|
{
|
|
if (a->ClientAuth->ClientX != NULL)
|
|
{
|
|
Enable(hWnd, B_VIEW_CLIENT_CERT);
|
|
SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_CLIENT_CERT_2"));
|
|
GetPrintNameFromName(issuer, sizeof(issuer), a->ClientAuth->ClientX->issuer_name);
|
|
GetPrintNameFromName(subject, sizeof(subject), a->ClientAuth->ClientX->subject_name);
|
|
GetDateStrEx64(expires, sizeof(expires), SystemToLocal64(a->ClientAuth->ClientX->notAfter), NULL);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_CERT_INFO"), subject, issuer, expires);
|
|
}
|
|
else
|
|
{
|
|
Disable(hWnd, B_VIEW_CLIENT_CERT);
|
|
SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_CLIENT_CERT_1"));
|
|
UniStrCpy(tmp, sizeof(tmp), _UU("CM_NO_CERT"));
|
|
}
|
|
SetText(hWnd, B_VIEW_CLIENT_CERT, _UU("CM_VIEW_CLIENT_CERT"));
|
|
|
|
Enable(hWnd, B_REGIST_CLIENT_CERT);
|
|
}
|
|
else
|
|
{
|
|
if (IsEmptyStr(a->ClientAuth->SecurePrivateKeyName) || IsEmptyStr(a->ClientAuth->SecurePublicCertName))
|
|
{
|
|
UniStrCpy(tmp, sizeof(tmp), _UU("CM_NO_SECURE"));
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_CERT_SECURE_INFO"),
|
|
a->ClientAuth->SecurePublicCertName, a->ClientAuth->SecurePrivateKeyName);
|
|
}
|
|
|
|
SetText(hWnd, B_VIEW_CLIENT_CERT, _UU("CM_SELECT_SECURE_DEVICE"));
|
|
SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_SELECT_CERT_INCARD"));
|
|
Enable(hWnd, B_VIEW_CLIENT_CERT);
|
|
|
|
if (SmGetCurrentSecureIdFromReg() == 0)
|
|
{
|
|
Disable(hWnd, B_REGIST_CLIENT_CERT);
|
|
}
|
|
else
|
|
{
|
|
Enable(hWnd, B_REGIST_CLIENT_CERT);
|
|
}
|
|
}
|
|
SetText(hWnd, S_CERT_INFO, tmp);
|
|
Show(hWnd, S_CERT);
|
|
Show(hWnd, S_CERT_INFO);
|
|
Show(hWnd, B_VIEW_CLIENT_CERT);
|
|
Show(hWnd, B_REGIST_CLIENT_CERT);
|
|
}
|
|
else
|
|
{
|
|
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_ANONYMOUS)
|
|
{
|
|
Hide(hWnd, S_PASSWORD);
|
|
Hide(hWnd, E_PASSWORD);
|
|
}
|
|
else
|
|
{
|
|
Show(hWnd, S_PASSWORD);
|
|
Show(hWnd, E_PASSWORD);
|
|
}
|
|
Hide(hWnd, S_CERT);
|
|
Hide(hWnd, S_CERT_INFO);
|
|
Hide(hWnd, B_VIEW_CLIENT_CERT);
|
|
Hide(hWnd, B_REGIST_CLIENT_CERT);
|
|
}
|
|
|
|
if (a->ClientOption->ProxyType != PROXY_DIRECT)
|
|
{
|
|
Enable(hWnd, B_PROXY_CONFIG);
|
|
if (StrLen(a->ClientOption->ProxyName) == 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
if (a->ClientOption->ProxyPort == 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Disable(hWnd, B_PROXY_CONFIG);
|
|
}
|
|
|
|
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PASSWORD)
|
|
{
|
|
bool b = true;
|
|
|
|
if (ok == false)
|
|
{
|
|
b = false;
|
|
}
|
|
|
|
if (a->LinkMode == false && a->NatMode == false)
|
|
{
|
|
SetEnable(hWnd, B_CHANGE_PASSWORD, b);
|
|
SetEnable(hWnd, S_CHANGE_PASSWORD, b);
|
|
Show(hWnd, B_CHANGE_PASSWORD);
|
|
Show(hWnd, S_CHANGE_PASSWORD);
|
|
}
|
|
else
|
|
{
|
|
Hide(hWnd, B_CHANGE_PASSWORD);
|
|
Hide(hWnd, S_CHANGE_PASSWORD);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Hide(hWnd, B_CHANGE_PASSWORD);
|
|
Hide(hWnd, S_CHANGE_PASSWORD);
|
|
}
|
|
|
|
if ((StrLen(a->ClientOption->DeviceName) == 0) && (a->LinkMode == false && a->NatMode == false))
|
|
{
|
|
ok = false;
|
|
}
|
|
|
|
if (a->LinkMode || a->NatMode)
|
|
{
|
|
Disable(hWnd, L_VLAN);
|
|
}
|
|
|
|
if (a->EditMode == false)
|
|
{
|
|
char tmp[MAX_SIZE];
|
|
GetTxtA(hWnd, E_HOSTNAME, tmp, sizeof(tmp));
|
|
Trim(tmp);
|
|
|
|
if (StartWith(tmp, "127.") || (StrCmpi(tmp, "localhost") == 0))
|
|
{
|
|
if (a->Flag1 == false)
|
|
{
|
|
a->Flag1 = true;
|
|
a->ClientOption->UseEncrypt = a->ClientOption->UseCompress = false;
|
|
a->ClientOption->MaxConnection = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
a->ClientOption->HideStatusWindow = IsChecked(hWnd, R_HIDE);
|
|
a->ClientOption->HideNicInfoWindow = IsChecked(hWnd, R_HIDE2);
|
|
|
|
if (locked)
|
|
{
|
|
SetEnable(hWnd, E_HOSTNAME, false);
|
|
SetEnable(hWnd, C_PORT, false);
|
|
SetEnable(hWnd, C_HUBNAME, false);
|
|
SetEnable(hWnd, S_STATIC2, false);
|
|
SetEnable(hWnd, S_STATIC3, false);
|
|
SetEnable(hWnd, S_STATIC4, false);
|
|
SetEnable(hWnd, S_STATIC5, false);
|
|
SetEnable(hWnd, S_STATIC66, false);
|
|
SetEnable(hWnd, S_STATIC7, false);
|
|
SetEnable(hWnd, S_STATIC11, false);
|
|
SetEnable(hWnd, R_CHECK_CERT, false);
|
|
SetEnable(hWnd, B_TRUST, false);
|
|
SetEnable(hWnd, B_SERVER_CERT, false);
|
|
SetEnable(hWnd, B_VIEW_SERVER_CERT, false);
|
|
SetEnable(hWnd, R_RETRY, false);
|
|
SetEnable(hWnd, S_RETRY_NUM_1, false);
|
|
SetEnable(hWnd, E_RETRY_NUM, false);
|
|
SetEnable(hWnd, S_RETRY_NUM_2, false);
|
|
SetEnable(hWnd, S_RETRY_SPAN_1, false);
|
|
SetEnable(hWnd, E_RETRY_SPAN, false);
|
|
SetEnable(hWnd, S_RETRY_SPAN_2, false);
|
|
SetEnable(hWnd, R_INFINITE, false);
|
|
}
|
|
|
|
SetEnable(hWnd, IDOK, ok);
|
|
}
|
|
|
|
// Initialize the account editing dialog
|
|
void CmEditAccountDlgInit(HWND hWnd, CM_ACCOUNT *a)
|
|
{
|
|
RPC_CLIENT_ENUM_VLAN v;
|
|
UINT i;
|
|
// Validate arguments
|
|
if (hWnd == NULL || a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (a->LockMode)
|
|
{
|
|
SetText(hWnd, S_STATIC1, _UU("CM_EASY_ACCOUNT_WARNING"));
|
|
}
|
|
|
|
// Connection settings name
|
|
if (a->EditMode || a->NatMode)
|
|
{
|
|
Disable(hWnd, E_ACCOUNT_NAME);
|
|
}
|
|
|
|
if (a->NatMode || a->LinkMode)
|
|
{
|
|
Hide(hWnd, R_HIDE);
|
|
Hide(hWnd, R_HIDE2);
|
|
}
|
|
|
|
Check(hWnd, R_HIDE, a->ClientOption->HideStatusWindow);
|
|
Check(hWnd, R_HIDE2, a->ClientOption->HideNicInfoWindow);
|
|
|
|
if (a->NatMode)
|
|
{
|
|
Hide(hWnd, E_ACCOUNT_NAME);
|
|
Hide(hWnd, S_ACCOUNT_NAME);
|
|
}
|
|
|
|
if ((cm != NULL && cm->server_name != NULL) || a->LinkMode)
|
|
{
|
|
Hide(hWnd, B_IE);
|
|
}
|
|
|
|
SetText(hWnd, E_ACCOUNT_NAME, a->ClientOption->AccountName);
|
|
|
|
// Host name
|
|
SetTextA(hWnd, E_HOSTNAME, a->ClientOption->Hostname);
|
|
StrCpy(a->old_server_name, sizeof(a->old_server_name), a->ClientOption->Hostname);
|
|
|
|
if (InStr(a->ClientOption->Hostname, "/tcp"))
|
|
{
|
|
Check(hWnd, R_DISABLE_NATT, true);
|
|
}
|
|
else
|
|
{
|
|
Check(hWnd, R_DISABLE_NATT, false);
|
|
}
|
|
|
|
// Port number
|
|
CbSetHeight(hWnd, C_PORT, 18);
|
|
CbAddStr(hWnd, C_PORT, _UU("CM_PORT_1"), 0);
|
|
CbAddStr(hWnd, C_PORT, _UU("CM_PORT_2"), 0);
|
|
CbAddStr(hWnd, C_PORT, _UU("CM_PORT_3"), 0);
|
|
CbAddStr(hWnd, C_PORT, _UU("CM_PORT_4"), 0);
|
|
SetInt(hWnd, C_PORT, a->ClientOption->Port);
|
|
|
|
// Virtual HUB name
|
|
CbSetHeight(hWnd, C_HUBNAME, 18);
|
|
SetTextA(hWnd, C_HUBNAME, a->ClientOption->HubName);
|
|
|
|
// Type of proxy
|
|
Check(hWnd, R_DIRECT_TCP, a->ClientOption->ProxyType == PROXY_DIRECT);
|
|
Check(hWnd, R_HTTPS, a->ClientOption->ProxyType == PROXY_HTTP);
|
|
Check(hWnd, R_SOCKS, a->ClientOption->ProxyType == PROXY_SOCKS);
|
|
|
|
// Verify the server certificate
|
|
Check(hWnd, R_CHECK_CERT, a->CheckServerCert);
|
|
|
|
// LAN card list
|
|
if (a->NatMode == false && a->LinkMode == false)
|
|
{
|
|
Zero(&v, sizeof(v));
|
|
CcEnumVLan(cm->Client, &v);
|
|
LvInit(hWnd, L_VLAN);
|
|
LvInsertColumn(hWnd, L_VLAN, 0, L"DeviceName", 345);
|
|
for (i = 0;i < v.NumItem;i++)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
char str[MAX_SIZE];
|
|
CmVLanNameToPrintName(str, sizeof(str), v.Items[i]->DeviceName);
|
|
StrToUni(tmp, sizeof(tmp), str);
|
|
LvInsert(hWnd, L_VLAN, ICO_NIC_ONLINE, NULL, 1, tmp);
|
|
}
|
|
// LvAutoSize(hWnd, L_VLAN);
|
|
|
|
if (v.NumItem == 1)
|
|
{
|
|
// If only one virtual LAN card exists, initially select it
|
|
LvSelect(hWnd, L_VLAN, 0);
|
|
}
|
|
|
|
CiFreeClientEnumVLan(&v);
|
|
}
|
|
|
|
// Select the LAN card
|
|
if (StrLen(a->ClientOption->DeviceName) != 0)
|
|
{
|
|
char str[MAX_SIZE];
|
|
wchar_t tmp[MAX_SIZE];
|
|
UINT index;
|
|
CmVLanNameToPrintName(str, sizeof(str), a->ClientOption->DeviceName);
|
|
StrToUni(tmp, sizeof(tmp), str);
|
|
index = LvSearchStr(hWnd, L_VLAN, 0, tmp);
|
|
if (index != INFINITE)
|
|
{
|
|
LvSelect(hWnd, L_VLAN, index);
|
|
}
|
|
}
|
|
|
|
// Authentication type
|
|
CbSetHeight(hWnd, C_TYPE, 18);
|
|
CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_0"), CLIENT_AUTHTYPE_ANONYMOUS);
|
|
CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_1"), CLIENT_AUTHTYPE_PASSWORD);
|
|
CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_2"), CLIENT_AUTHTYPE_PLAIN_PASSWORD);
|
|
|
|
if (a->HideClientCertAuth == false)
|
|
{
|
|
// Certificate authentication is not available when HideClientCertAuth is true
|
|
CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_3"), CLIENT_AUTHTYPE_CERT);
|
|
}
|
|
|
|
if (a->HideSecureAuth == false)
|
|
{
|
|
// Authentication using a smart card
|
|
CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_4"), CLIENT_AUTHTYPE_SECURE);
|
|
}
|
|
|
|
// Select an authentication
|
|
CbSelect(hWnd, C_TYPE, a->ClientAuth->AuthType);
|
|
|
|
// User name
|
|
SetTextA(hWnd, E_USERNAME, a->ClientAuth->Username);
|
|
|
|
// Password
|
|
if (a->EditMode)
|
|
{
|
|
SetTextA(hWnd, E_PASSWORD, HIDDEN_PASSWORD);
|
|
}
|
|
|
|
// Reconnection times
|
|
if (a->ClientOption->NumRetry == 0)
|
|
{
|
|
Check(hWnd, R_RETRY, false);
|
|
}
|
|
else
|
|
{
|
|
Check(hWnd, R_RETRY, true);
|
|
if (a->ClientOption->NumRetry == INFINITE)
|
|
{
|
|
Check(hWnd, R_INFINITE, true);
|
|
}
|
|
else
|
|
{
|
|
Check(hWnd, R_INFINITE, false);
|
|
SetInt(hWnd, E_RETRY_NUM, a->ClientOption->NumRetry);
|
|
}
|
|
}
|
|
SetIntEx(hWnd, E_RETRY_SPAN, a->ClientOption->RetryInterval);
|
|
|
|
Check(hWnd, R_NOTLS1, a->ClientOption->NoTls1);
|
|
|
|
// Title
|
|
if (a->NatMode == false)
|
|
{
|
|
if (a->EditMode == false)
|
|
{
|
|
SetText(hWnd, 0, _UU("CM_ACCOUNT_TITLE_1"));
|
|
FocusEx(hWnd, E_ACCOUNT_NAME);
|
|
}
|
|
else
|
|
{
|
|
SetText(hWnd, 0, _UU("CM_ACCOUNT_TITLE_2"));
|
|
FormatText(hWnd, 0, a->ClientOption->AccountName);
|
|
FocusEx(hWnd, E_HOSTNAME);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetText(hWnd, 0, _UU("NM_ACCOUNT_TITLE"));
|
|
FocusEx(hWnd, E_HOSTNAME);
|
|
}
|
|
|
|
if (a->LinkMode || a->NatMode)
|
|
{
|
|
Hide(hWnd, L_VLAN);
|
|
|
|
if (a->NatMode == false)
|
|
{
|
|
SetText(hWnd, S_VLAN_GROUP, _UU("SM_LINK_POLICY_GROUP"));
|
|
Show(hWnd, S_POLICY_1);
|
|
Show(hWnd, S_POLICY_2);
|
|
Show(hWnd, B_POLICY);
|
|
}
|
|
else
|
|
{
|
|
Hide(hWnd, S_VLAN_GROUP);
|
|
Show(hWnd, S_ROUTER_LOGO);
|
|
}
|
|
}
|
|
|
|
// Display update
|
|
a->Inited = true;
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
}
|
|
|
|
// Account editing dialog procedure
|
|
UINT CmEditAccountDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
CM_ACCOUNT *a = (CM_ACCOUNT *)param;
|
|
NMHDR *n;
|
|
X *x;
|
|
K *k;
|
|
char tmp[MAX_PATH];
|
|
bool no_update_natt_check = false;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CmEditAccountDlgInit(hWnd, a);
|
|
if (a->EditMode == false && a->LinkMode == false && a->NatMode == false)
|
|
{
|
|
SetTimer(hWnd, 1, 100, NULL);
|
|
}
|
|
break;
|
|
case WM_TIMER:
|
|
switch (wParam)
|
|
{
|
|
case 1:
|
|
{
|
|
CM_INTERNET_SETTING s;
|
|
|
|
KillTimer(hWnd, 1);
|
|
|
|
Zero(&s, sizeof(s));
|
|
CmGetSystemInternetSetting(&s);
|
|
|
|
if (s.ProxyType != PROXY_DIRECT)
|
|
{
|
|
if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO,
|
|
_UU("CM_WOULDYOULOAD_IE_PROXY"),
|
|
s.ProxyHostName) == IDYES)
|
|
{
|
|
Command(hWnd, B_IE);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case R_DISABLE_NATT:
|
|
Zero(tmp, sizeof(tmp));
|
|
GetTxtA(hWnd, E_HOSTNAME, tmp, sizeof(tmp));
|
|
|
|
if (IsChecked(hWnd, R_DISABLE_NATT))
|
|
{
|
|
if (InStr(tmp, "/tcp") == false)
|
|
{
|
|
Trim(tmp);
|
|
|
|
StrCat(tmp, sizeof(tmp), "/tcp");
|
|
|
|
SetTextA(hWnd, E_HOSTNAME, tmp);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (InStr(tmp, "/tcp"))
|
|
{
|
|
UINT i = SearchStrEx(tmp, "/tcp", 0, false);
|
|
|
|
if (i != INFINITE)
|
|
{
|
|
tmp[i] = 0;
|
|
|
|
Trim(tmp);
|
|
|
|
SetTextA(hWnd, E_HOSTNAME, tmp);
|
|
}
|
|
}
|
|
}
|
|
|
|
CmEditAccountDlgStartEnumHub(hWnd, a);
|
|
break;
|
|
}
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case E_ACCOUNT_NAME:
|
|
case E_HOSTNAME:
|
|
case C_PORT:
|
|
case C_HUBNAME:
|
|
case R_DIRECT_TCP:
|
|
case R_HTTPS:
|
|
case R_SOCKS:
|
|
case R_CHECK_CERT:
|
|
case C_TYPE:
|
|
case E_USERNAME:
|
|
case E_PASSWORD:
|
|
case R_RETRY:
|
|
case E_RETRY_NUM:
|
|
case E_RETRY_SPAN:
|
|
case R_INFINITE:
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
break;
|
|
}
|
|
switch (HIWORD(wParam))
|
|
{
|
|
case EN_KILLFOCUS:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case E_HOSTNAME:
|
|
CmEditAccountDlgStartEnumHub(hWnd, a);
|
|
break;
|
|
}
|
|
break;
|
|
case BN_KILLFOCUS:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case R_DIRECT_TCP:
|
|
case R_HTTPS:
|
|
case R_SOCKS:
|
|
CmEditAccountDlgStartEnumHub(hWnd, a);
|
|
break;
|
|
}
|
|
break;
|
|
case CBN_KILLFOCUS:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case C_PORT:
|
|
CmEditAccountDlgStartEnumHub(hWnd, a);
|
|
break;
|
|
}
|
|
break;
|
|
case BN_PUSHED:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case R_DISABLE_NATT:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
if (HIWORD(wParam) == 0)
|
|
{
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
}
|
|
switch (wParam)
|
|
{
|
|
case B_POLICY:
|
|
// Policy
|
|
if (a->LinkMode || a->NatMode)
|
|
{
|
|
a->Policy.Access = true;
|
|
a->Policy.MonitorPort = false;
|
|
SmPolicyDlgEx2(hWnd, &a->Policy, _UU("SM_LINK_POLICY_CAPTION"), true, a->PolicyVer);
|
|
a->Policy.Access = true;
|
|
a->Policy.MonitorPort = false;
|
|
}
|
|
break;
|
|
case IDOK:
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
CmEditAccountDlgOnOk(hWnd, a);
|
|
break;
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
case B_PROXY_CONFIG:
|
|
// Proxy Settings
|
|
if (CmProxyDlg(hWnd, a->ClientOption))
|
|
{
|
|
UINT n = GetInt(hWnd, C_PORT);
|
|
if (a->ClientOption->ProxyType == PROXY_HTTP &&
|
|
n != 443)
|
|
{
|
|
// Show a warning message if the destination port is
|
|
// other than 443 and HTTP proxy is used
|
|
if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("CM_HTTP_PROXY_WARNING"), n) == IDYES)
|
|
{
|
|
// Change the port number to 443
|
|
SetText(hWnd, C_PORT, _UU("CM_PORT_2"));
|
|
}
|
|
}
|
|
CmEditAccountDlgStartEnumHub(hWnd, a);
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
}
|
|
break;
|
|
case B_IE:
|
|
// Use the IE settings
|
|
if(cm->server_name == NULL)
|
|
{
|
|
CmProxyDlgUseForIE(hWnd, a->ClientOption);
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PROXY_FROM_IE"));
|
|
}
|
|
break;
|
|
case B_TRUST:
|
|
// CA
|
|
if (a->LinkMode == false)
|
|
{
|
|
CmTrustDlg(hWnd);
|
|
}
|
|
else
|
|
{
|
|
SmCaDlg(hWnd, a->Hub);
|
|
}
|
|
break;
|
|
case B_SERVER_CERT:
|
|
// Server certificate registration / delete
|
|
if (a->ServerCert == NULL)
|
|
{
|
|
if (CmLoadXFromFileOrSecureCard(hWnd, &x))
|
|
{
|
|
a->ServerCert = x;
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_SERVER_CERT")) == IDYES)
|
|
{
|
|
FreeX(a->ServerCert);
|
|
a->ServerCert = NULL;
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
}
|
|
}
|
|
break;
|
|
case B_VIEW_SERVER_CERT:
|
|
// Show the server certificate
|
|
if (a->ServerCert != NULL)
|
|
{
|
|
X *issuer = CmGetIssuer(a->ServerCert);
|
|
CertDlg(hWnd, a->ServerCert, issuer, true);
|
|
FreeX(issuer);
|
|
}
|
|
break;
|
|
case B_VIEW_CLIENT_CERT:
|
|
if (a->ClientAuth->AuthType != CLIENT_AUTHTYPE_SECURE)
|
|
{
|
|
// Show the client certificate
|
|
if (a->ClientAuth->ClientX != NULL)
|
|
{
|
|
X *issuer = CmGetIssuer(a->ClientAuth->ClientX);
|
|
CertDlg(hWnd, a->ClientAuth->ClientX, issuer, true);
|
|
FreeX(issuer);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UINT id;
|
|
// Select the type of smart card
|
|
SmSelectSecureId(hWnd);
|
|
id = SmGetCurrentSecureIdFromReg();
|
|
if (id != 0)
|
|
{
|
|
if (cm->server_name == NULL)
|
|
{
|
|
RPC_USE_SECURE t;
|
|
|
|
Zero(&t, sizeof(t));
|
|
t.DeviceId = id;
|
|
CcUseSecure(cm->Client, &t);
|
|
}
|
|
}
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
}
|
|
break;
|
|
case B_REGIST_CLIENT_CERT:
|
|
if (a->ClientAuth->AuthType != CLIENT_AUTHTYPE_SECURE)
|
|
{
|
|
// Client certificate registration / deletion
|
|
if (a->ClientAuth->ClientX == NULL)
|
|
{
|
|
if (CmLoadXAndK(hWnd, &x, &k))
|
|
{
|
|
a->ClientAuth->ClientX = x;
|
|
a->ClientAuth->ClientK = k;
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_CLIENT_CERT")) == IDYES)
|
|
{
|
|
FreeX(a->ClientAuth->ClientX);
|
|
FreeK(a->ClientAuth->ClientK);
|
|
a->ClientAuth->ClientX = NULL;
|
|
a->ClientAuth->ClientK = NULL;
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char cert[MAX_SECURE_DEVICE_FILE_LEN + 1], priv[MAX_SECURE_DEVICE_FILE_LEN + 1];
|
|
|
|
// Select a certificate in the smart card
|
|
if (SmSelectKeyPairEx(hWnd, cert, sizeof(cert), priv, sizeof(priv), CmGetSecureBitmapId(a->ClientOption->Hostname)))
|
|
{
|
|
StrCpy(a->ClientAuth->SecurePublicCertName, sizeof(a->ClientAuth->SecurePublicCertName), cert);
|
|
StrCpy(a->ClientAuth->SecurePrivateKeyName, sizeof(a->ClientAuth->SecurePrivateKeyName), priv);
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
}
|
|
}
|
|
break;
|
|
case B_DETAIL:
|
|
// Advanced communication settings
|
|
if (CmDetailDlg(hWnd, a))
|
|
{
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
}
|
|
break;
|
|
case B_CHANGE_PASSWORD:
|
|
// Change the password
|
|
CmChangePassword(hWnd, a->ClientOption, a->ClientOption->HubName,
|
|
a->ClientAuth->Username);
|
|
break;
|
|
}
|
|
break;
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
case WM_NOTIFY:
|
|
n = (NMHDR *)lParam;
|
|
switch (n->idFrom)
|
|
{
|
|
case L_VLAN:
|
|
switch (n->code)
|
|
{
|
|
case LVN_ITEMCHANGED:
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Update the proxy server settings
|
|
void CmProxyDlgUpdate(HWND hWnd, CLIENT_OPTION *a)
|
|
{
|
|
bool ok = true;
|
|
// Validate arguments
|
|
if (hWnd == NULL || a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IsEmpty(hWnd, E_HOSTNAME))
|
|
{
|
|
ok = false;
|
|
}
|
|
if (GetInt(hWnd, C_PORT) == 0)
|
|
{
|
|
ok = false;
|
|
}
|
|
|
|
SetEnable(hWnd, IDOK, ok);
|
|
}
|
|
|
|
// Proxy server settings dialog c
|
|
UINT CmProxyDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
CLIENT_OPTION *a = (CLIENT_OPTION *)param;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetTextA(hWnd, E_HOSTNAME, a->ProxyName);
|
|
CbSetHeight(hWnd, C_PORT, 18);
|
|
CbAddStr(hWnd, C_PORT, L"8080", 0);
|
|
CbAddStr(hWnd, C_PORT, L"1080", 0);
|
|
CbAddStr(hWnd, C_PORT, L"80", 0);
|
|
CbAddStr(hWnd, C_PORT, L"3128", 0);
|
|
CbAddStr(hWnd, C_PORT, L"443", 0);
|
|
CbAddStr(hWnd, C_PORT, L"9821", 0);
|
|
CbAddStr(hWnd, C_PORT, L"9801", 0);
|
|
SetIntEx(hWnd, C_PORT, a->ProxyPort);
|
|
SetTextA(hWnd, E_USERNAME, a->ProxyUsername);
|
|
SetTextA(hWnd, E_PASSWORD, a->ProxyPassword);
|
|
if (a->ProxyPort == 0)
|
|
{
|
|
if (a->ProxyType == PROXY_HTTP)
|
|
{
|
|
SetInt(hWnd, C_PORT, 8080);
|
|
}
|
|
else
|
|
{
|
|
SetInt(hWnd, C_PORT, 1080);
|
|
}
|
|
}
|
|
CmProxyDlgUpdate(hWnd, a);
|
|
break;
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case E_HOSTNAME:
|
|
case C_PORT:
|
|
case E_USERNAME:
|
|
case E_PASSWORD:
|
|
CmProxyDlgUpdate(hWnd, a);
|
|
break;
|
|
}
|
|
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
GetTxtA(hWnd, E_HOSTNAME, a->ProxyName, sizeof(a->ProxyName));
|
|
GetTxtA(hWnd, E_USERNAME, a->ProxyUsername, sizeof(a->ProxyUsername));
|
|
GetTxtA(hWnd, E_PASSWORD, a->ProxyPassword, sizeof(a->ProxyPassword));
|
|
a->ProxyPort = GetInt(hWnd, C_PORT);
|
|
EndDialog(hWnd, true);
|
|
break;
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Proxy server settings
|
|
bool CmProxyDlg(HWND hWnd, CLIENT_OPTION *a)
|
|
{
|
|
// Validate arguments
|
|
if (a == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return Dialog(hWnd, D_CM_PROXY, CmProxyDlgProc, a);
|
|
}
|
|
|
|
// Get issuer of the specified certificate if it is known
|
|
X *CmGetIssuer(X *x)
|
|
{
|
|
RPC_GET_ISSUER a;
|
|
X *ret;
|
|
// Validate arguments
|
|
if (x == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
Zero(&a, sizeof(a));
|
|
a.x = CloneX(x);
|
|
if (CALLEX(cm->hMainWnd, CcGetIssuer(cm->Client, &a)) == 0)
|
|
{
|
|
ret = CloneX(a.issuer_x);
|
|
}
|
|
else
|
|
{
|
|
ret = NULL;
|
|
}
|
|
|
|
CiFreeGetIssuer(&a);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Initialize the dialog
|
|
void CmLoadXFromFileOrSecureCardDlgInit(HWND hWnd, CM_LOADX *p)
|
|
{
|
|
UINT current;
|
|
// Validate arguments
|
|
if (hWnd == NULL || p == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
current = MsRegReadInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "CertLoadSource");
|
|
|
|
Check(hWnd, R_FROM_FILE, current == 0);
|
|
Check(hWnd, R_FROM_SECURE, current != 0);
|
|
|
|
SetFont(hWnd, S_INFO, Font(0, true));
|
|
|
|
CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
|
|
}
|
|
|
|
// Update the dialog control
|
|
void CmLoadXFromFileOrSecureCardDlgUpdate(HWND hWnd, CM_LOADX *p)
|
|
{
|
|
SECURE_DEVICE *dev;
|
|
wchar_t tmp[MAX_SIZE];
|
|
bool ok = true;
|
|
// Validate arguments
|
|
if (hWnd == NULL || p == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
dev = GetSecureDevice(SmGetCurrentSecureIdFromReg());
|
|
if (dev == NULL)
|
|
{
|
|
UniStrCpy(tmp, sizeof(tmp), _UU("SEC_CURRENT_NO_DEVICE"));
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("SEC_CURRENT_DEVICE"), dev->DeviceName);
|
|
}
|
|
|
|
SetText(hWnd, S_INFO, tmp);
|
|
|
|
if (IsChecked(hWnd, R_FROM_SECURE))
|
|
{
|
|
if (dev == NULL)
|
|
{
|
|
ok = false;
|
|
}
|
|
}
|
|
|
|
SetEnable(hWnd, IDOK, ok);
|
|
SetEnable(hWnd, B_SELECT, IsChecked(hWnd, R_FROM_SECURE));
|
|
SetEnable(hWnd, S_CERT, IsChecked(hWnd, R_FROM_SECURE));
|
|
SetEnable(hWnd, S_FILE, IsChecked(hWnd, R_FROM_FILE));
|
|
}
|
|
|
|
// Certificate reading selection dialog procedure
|
|
UINT CmLoadXFromFileOrSecureCardDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
CM_LOADX *p = (CM_LOADX *)param;
|
|
X *x;
|
|
UINT current;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CmLoadXFromFileOrSecureCardDlgInit(hWnd, p);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
current = (IsChecked(hWnd, R_FROM_FILE)) ? 0 : 1;
|
|
MsRegWriteInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "CertLoadSource", current);
|
|
|
|
if (current == 0)
|
|
{
|
|
// From file
|
|
if (CmLoadX(hWnd, &x))
|
|
{
|
|
p->x = x;
|
|
EndDialog(hWnd, true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// From the smart card
|
|
char name[MAX_SIZE];
|
|
|
|
// Select the certificate name in the card
|
|
if (SmSelectKeyPair(hWnd, name, sizeof(name), NULL, 0))
|
|
{
|
|
// Read
|
|
WINUI_SECURE_BATCH batch[] =
|
|
{
|
|
{WINUI_SECURE_READ_CERT, name, true, NULL, NULL, NULL, NULL, NULL, NULL},
|
|
};
|
|
|
|
// Do reading
|
|
if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), SmGetCurrentSecureIdFromReg(), 0))
|
|
{
|
|
// Success
|
|
p->x = batch[0].OutputX;
|
|
EndDialog(hWnd, true);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
|
|
case R_FROM_FILE:
|
|
CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
|
|
break;
|
|
|
|
case R_FROM_SECURE:
|
|
CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
|
|
break;
|
|
|
|
case B_SELECT:
|
|
SmSelectSecureId(hWnd);
|
|
CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Read certificate from a file or a smart card
|
|
bool CmLoadXFromFileOrSecureCard(HWND hWnd, X **x)
|
|
{
|
|
CM_LOADX p;
|
|
// Validate arguments
|
|
if (x == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Zero(&p, sizeof(p));
|
|
if (Dialog(hWnd, D_CM_LOAD_X, CmLoadXFromFileOrSecureCardDlgProc, &p) == false)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
*x = p.x;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Read the certificate
|
|
bool CmLoadX(HWND hWnd, X **x)
|
|
{
|
|
return CmLoadXEx(hWnd, x, NULL, 0);
|
|
}
|
|
bool CmLoadXEx(HWND hWnd, X **x, char *filename, UINT size)
|
|
{
|
|
wchar_t *filename_w = CopyStrToUni(filename);
|
|
bool ret;
|
|
|
|
ret = CmLoadXExW(hWnd, x, filename_w, size);
|
|
|
|
Free(filename_w);
|
|
|
|
return ret;
|
|
}
|
|
bool CmLoadXExW(HWND hWnd, X **x, wchar_t *filename, UINT size)
|
|
{
|
|
wchar_t *s;
|
|
bool is_p12;
|
|
wchar_t tmp[MAX_SIZE];
|
|
K *k;
|
|
// Validate arguments
|
|
if (x == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Read the certificate
|
|
s = OpenDlg(hWnd, _UU("DLG_CERT_OR_P12_FILTER"), _UU("DLG_OPEN_CERT"));
|
|
if (s == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
UniStrCpy(tmp, sizeof(tmp), s);
|
|
if (filename != NULL)
|
|
{
|
|
UniStrCpy(filename, size, tmp);
|
|
}
|
|
Free(s);
|
|
if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))
|
|
{
|
|
is_p12 = true;
|
|
}
|
|
else
|
|
{
|
|
is_p12 = false;
|
|
}
|
|
|
|
if (is_p12)
|
|
{
|
|
// Processing of PKCS#12
|
|
BUF *b = ReadDumpW(tmp);
|
|
P12 *p12;
|
|
if (b == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
|
|
return false;
|
|
}
|
|
p12 = BufToP12(b);
|
|
if (p12 == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
if (IsEncryptedP12(p12) == false)
|
|
{
|
|
if (ParseP12(p12, x, &k, NULL) == false)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char password[MAX_SIZE];
|
|
if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)
|
|
{
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if (ParseP12(p12, x, &k, password) == false)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
FreeK(k);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// Processing of X509
|
|
BUF *b = ReadDumpW(tmp);
|
|
X *x509;
|
|
if (b == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
|
|
return false;
|
|
}
|
|
|
|
x509 = BufToX(b, IsBase64(b));
|
|
FreeBuf(b);
|
|
if (x509 == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_X509_W"), tmp);
|
|
return false;
|
|
}
|
|
|
|
*x = x509;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Read the secret key
|
|
bool CmLoadK(HWND hWnd, K **k)
|
|
{
|
|
return CmLoadKEx(hWnd, k, NULL, 0);
|
|
}
|
|
bool CmLoadKEx(HWND hWnd, K **k, char *filename, UINT size)
|
|
{
|
|
wchar_t *filename_w = CopyStrToUni(filename);
|
|
bool ret;
|
|
|
|
ret = CmLoadKExW(hWnd, k, filename_w, size);
|
|
|
|
Free(filename_w);
|
|
|
|
return ret;
|
|
}
|
|
bool CmLoadKExW(HWND hWnd, K **k, wchar_t *filename, UINT size)
|
|
{
|
|
wchar_t *s;
|
|
bool is_p12;
|
|
wchar_t tmp[MAX_SIZE];
|
|
// Validate arguments
|
|
if (k == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Read the certificate
|
|
s = OpenDlg(hWnd, _UU("DLG_KEY_OR_P12_FILTER"), _UU("DLG_OPEN_KEY"));
|
|
if (s == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
UniStrCpy(tmp, sizeof(tmp), s);
|
|
Free(s);
|
|
if (filename != NULL)
|
|
{
|
|
UniStrCpy(filename, size, tmp);
|
|
}
|
|
if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))
|
|
{
|
|
is_p12 = true;
|
|
}
|
|
else
|
|
{
|
|
is_p12 = false;
|
|
}
|
|
|
|
if (is_p12)
|
|
{
|
|
// Processing of PKCS#12
|
|
BUF *b = ReadDumpW(tmp);
|
|
P12 *p12;
|
|
if (b == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
|
|
return false;
|
|
}
|
|
p12 = BufToP12(b);
|
|
if (p12 == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
if (IsEncryptedP12(p12) == false)
|
|
{
|
|
X *x;
|
|
if (ParseP12(p12, &x, k, NULL) == false)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
|
|
FreeX(x);
|
|
}
|
|
else
|
|
{
|
|
char password[MAX_SIZE];
|
|
if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)
|
|
{
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
X *x;
|
|
if (ParseP12(p12, &x, k, password) == false)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
|
|
FreeX(x);
|
|
}
|
|
}
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// Processing of private key
|
|
BUF *b = ReadDumpW(tmp);
|
|
K *key;
|
|
if (b == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
|
|
return false;
|
|
}
|
|
|
|
if (IsEncryptedK(b, true) == false)
|
|
{
|
|
key = BufToK(b, true, IsBase64(b), NULL);
|
|
}
|
|
else
|
|
{
|
|
char pass[MAX_SIZE];
|
|
if (PassphraseDlg(hWnd, pass, sizeof(pass), b, false) == false)
|
|
{
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
key = BufToK(b, true, IsBase64(b), pass);
|
|
}
|
|
|
|
if (key == NULL)
|
|
{
|
|
FreeBuf(b);
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_KEY_W"), tmp);
|
|
return false;
|
|
}
|
|
|
|
FreeBuf(b);
|
|
*k = key;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Read a set of certificate and private key
|
|
bool CmLoadXAndK(HWND hWnd, X **x, K **k)
|
|
{
|
|
wchar_t *s;
|
|
bool is_p12;
|
|
wchar_t tmp[MAX_SIZE];
|
|
// Validate arguments
|
|
if (x == NULL || k == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
START_FIRST:
|
|
|
|
// Read the certificate
|
|
s = OpenDlg(hWnd, _UU("DLG_CERT_OR_P12_FILTER"), _UU("DLG_OPEN_CERT"));
|
|
if (s == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
UniStrCpy(tmp, sizeof(tmp), s);
|
|
Free(s);
|
|
if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))
|
|
{
|
|
is_p12 = true;
|
|
}
|
|
else
|
|
{
|
|
is_p12 = false;
|
|
}
|
|
|
|
if (is_p12)
|
|
{
|
|
// Processing of PKCS#12
|
|
BUF *b = ReadDumpW(tmp);
|
|
P12 *p12;
|
|
if (b == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
|
|
return false;
|
|
}
|
|
p12 = BufToP12(b);
|
|
if (p12 == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
if (IsEncryptedP12(p12) == false)
|
|
{
|
|
if (ParseP12(p12, x, k, NULL) == false)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char password[MAX_SIZE];
|
|
if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)
|
|
{
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if (ParseP12(p12, x, k, password) == false)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
if (CheckXandK(*x, *k) == false)
|
|
{
|
|
FreeX(*x);
|
|
FreeK(*k);
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)
|
|
{
|
|
goto START_FIRST;
|
|
}
|
|
return false;
|
|
}
|
|
FreeP12(p12);
|
|
FreeBuf(b);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// Processing of X509
|
|
BUF *b = ReadDumpW(tmp);
|
|
X *x509;
|
|
K *key;
|
|
if (b == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
|
|
return false;
|
|
}
|
|
|
|
x509 = BufToX(b, IsBase64(b));
|
|
FreeBuf(b);
|
|
if (x509 == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_X509_W"), tmp);
|
|
return false;
|
|
}
|
|
|
|
// Read the secret key
|
|
s = OpenDlg(hWnd, _UU("DLG_KEY_FILTER"), _UU("DLG_OPEN_KEY_WITH_CERT"));
|
|
if (s == NULL)
|
|
{
|
|
FreeX(x509);
|
|
return false;
|
|
}
|
|
UniStrCpy(tmp, sizeof(tmp), s);
|
|
Free(s);
|
|
|
|
b = ReadDumpW(tmp);
|
|
if (b == NULL)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
|
|
FreeX(x509);
|
|
return false;
|
|
}
|
|
|
|
if (IsEncryptedK(b, true) == false)
|
|
{
|
|
key = BufToK(b, true, IsBase64(b), NULL);
|
|
}
|
|
else
|
|
{
|
|
char pass[MAX_SIZE];
|
|
if (PassphraseDlg(hWnd, pass, sizeof(pass), b, false) == false)
|
|
{
|
|
FreeBuf(b);
|
|
FreeX(x509);
|
|
return false;
|
|
}
|
|
key = BufToK(b, true, IsBase64(b), pass);
|
|
}
|
|
|
|
if (key == NULL)
|
|
{
|
|
FreeBuf(b);
|
|
FreeX(x509);
|
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_KEY_W"), tmp);
|
|
return false;
|
|
}
|
|
|
|
if (CheckXandK(x509, key) == false)
|
|
{
|
|
FreeBuf(b);
|
|
FreeX(x509);
|
|
FreeK(key);
|
|
if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)
|
|
{
|
|
goto START_FIRST;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
FreeBuf(b);
|
|
*x = x509;
|
|
*k = key;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Virtual HUB enumeration start
|
|
void CmEditAccountDlgStartEnumHub(HWND hWnd, CM_ACCOUNT *a)
|
|
{
|
|
char server_name[MAX_HOST_NAME_LEN + 1];
|
|
UINT old_proxy_type;
|
|
// Validate arguments
|
|
if (hWnd == NULL || a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
if (StrLen(a->ClientOption->Hostname) == 0)
|
|
{
|
|
return;
|
|
}
|
|
if (a->ClientOption->Port == 0)
|
|
{
|
|
return;
|
|
}
|
|
if (a->ClientOption->ProxyType != PROXY_DIRECT &&
|
|
(StrLen(a->ClientOption->ProxyName) == 0 ||
|
|
a->ClientOption->ProxyPort == 0))
|
|
{
|
|
return;
|
|
}
|
|
|
|
GetTxtA(hWnd, E_HOSTNAME, server_name, sizeof(server_name));
|
|
|
|
if (StrCmpi(server_name, a->old_server_name) == 0)
|
|
{
|
|
if (CbNum(hWnd, C_HUBNAME) != 0)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
StrCpy(a->old_server_name, sizeof(a->old_server_name), server_name);
|
|
CbReset(hWnd, C_HUBNAME);
|
|
}
|
|
|
|
old_proxy_type = a->ClientOption->ProxyType;
|
|
|
|
if (IsChecked(hWnd, R_DIRECT_TCP))
|
|
{
|
|
a->ClientOption->ProxyType = PROXY_DIRECT;
|
|
}
|
|
if (IsChecked(hWnd, R_HTTPS))
|
|
{
|
|
a->ClientOption->ProxyType = PROXY_HTTP;
|
|
}
|
|
if (IsChecked(hWnd, R_SOCKS))
|
|
{
|
|
a->ClientOption->ProxyType = PROXY_SOCKS;
|
|
}
|
|
|
|
CmEnumHubStart(hWnd, a->ClientOption);
|
|
|
|
a->ClientOption->ProxyType = old_proxy_type;
|
|
}
|
|
|
|
// [OK] button
|
|
void CmEditAccountDlgOnOk(HWND hWnd, CM_ACCOUNT *a)
|
|
{
|
|
RPC_CLIENT_CREATE_ACCOUNT c;
|
|
bool b;
|
|
// Validate arguments
|
|
if (hWnd == NULL || a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
if (a->ClientOption->NumRetry != 0 && a->ClientOption->RetryInterval < 5)
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_RETRY_INTERVAL_ERROR"));
|
|
FocusEx(hWnd, E_RETRY_SPAN);
|
|
return;
|
|
}
|
|
|
|
CmEditAccountDlgUpdate(hWnd, a);
|
|
|
|
if (a->LinkMode == false && a->NatMode == false)
|
|
{
|
|
// Save the account
|
|
Zero(&c, sizeof(c));
|
|
c.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
|
|
Copy(c.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
|
|
c.ClientAuth = CopyClientAuth(a->ClientAuth);
|
|
c.CheckServerCert = a->CheckServerCert;
|
|
if (a->ServerCert != NULL)
|
|
{
|
|
c.ServerCert = CloneX(a->ServerCert);
|
|
}
|
|
c.StartupAccount = a->Startup;
|
|
|
|
if (a->EditMode == false)
|
|
{
|
|
b = CALL(hWnd, CcCreateAccount(cm->Client, &c));
|
|
}
|
|
else
|
|
{
|
|
b = CALL(hWnd, CcSetAccount(cm->Client, &c));
|
|
}
|
|
|
|
CiFreeClientCreateAccount(&c);
|
|
|
|
// Check whether this account is currently running
|
|
if (b)
|
|
{
|
|
RPC_CLIENT_GET_CONNECTION_STATUS st;
|
|
Zero(&st, sizeof(st));
|
|
UniStrCpy(st.AccountName, sizeof(st.AccountName), a->ClientOption->AccountName);
|
|
if (CALL(hWnd, CcGetAccountStatus(cm->Client, &st)))
|
|
{
|
|
if (st.Active)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_CURRENT_ACTIVE"),
|
|
st.AccountName);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (b)
|
|
{
|
|
EndDialog(hWnd, true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (a->LinkMode)
|
|
{
|
|
// Link mode
|
|
RPC_CREATE_LINK t;
|
|
|
|
Zero(&t, sizeof(t));
|
|
StrCpy(t.HubName, sizeof(t.HubName), a->Hub->HubName);
|
|
t.Online = a->OnlineFlag;
|
|
Copy(&t.Policy, &a->Policy, sizeof(POLICY));
|
|
t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
|
|
Copy(t.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
|
|
t.ClientAuth = CopyClientAuth(a->ClientAuth);
|
|
t.CheckServerCert = a->CheckServerCert;
|
|
t.ServerCert = CloneX(a->ServerCert);
|
|
|
|
// Save the settings for cascade connection
|
|
if (a->EditMode)
|
|
{
|
|
if (CALL(hWnd, ScSetLink(a->Hub->Rpc, &t)))
|
|
{
|
|
if (a->OnlineFlag)
|
|
{
|
|
MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("SM_LINK_SAVE_ONLINE"), a->ClientOption->AccountName);
|
|
}
|
|
EndDialog(hWnd, true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (CALL(hWnd, ScCreateLink(a->Hub->Rpc, &t)))
|
|
{
|
|
if (a->Link_ConnectNow)
|
|
{
|
|
RPC_LINK tt;
|
|
|
|
Zero(&tt, sizeof(tt));
|
|
UniStrCpy(tt.AccountName, sizeof(tt.AccountName), a->ClientOption->AccountName);
|
|
StrCpy(tt.HubName, sizeof(tt.HubName), a->Hub->HubName);
|
|
|
|
CALL(hWnd, ScSetLinkOnline(a->Hub->Rpc, &tt));
|
|
}
|
|
EndDialog(hWnd, true);
|
|
}
|
|
}
|
|
|
|
FreeRpcCreateLink(&t);
|
|
}
|
|
else
|
|
{
|
|
// NAT mode
|
|
RPC_CREATE_LINK t;
|
|
Zero(&t, sizeof(t));
|
|
|
|
t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
|
|
Copy(t.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
|
|
t.ClientAuth = CopyClientAuth(a->ClientAuth);
|
|
|
|
if (CALL(hWnd, NcSetClientConfig(a->Rpc, &t)))
|
|
{
|
|
EndDialog(hWnd, true);
|
|
}
|
|
|
|
FreeRpcCreateLink(&t);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Show the account editing dialog
|
|
bool CmEditAccountDlg(HWND hWnd, CM_ACCOUNT *a)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || a == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return Dialog(hWnd, D_CM_ACCOUNT, CmEditAccountDlgProc, a);
|
|
}
|
|
|
|
// Edit the account
|
|
void CmEditAccount(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
CM_ACCOUNT *a;
|
|
// Validate arguments
|
|
if (hWnd == NULL || account_name == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
a = CmGetExistAccountObject(hWnd, account_name);
|
|
if (a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CmVoice("input_config");
|
|
if (CmEditAccountDlg(hWnd, a))
|
|
{
|
|
CmVoice("set_config");
|
|
}
|
|
|
|
CmFreeAccountObject(hWnd, a);
|
|
}
|
|
|
|
// Create an account
|
|
void CmNewAccount(HWND hWnd)
|
|
{
|
|
CM_ACCOUNT *a;
|
|
RPC_CLIENT_ENUM_VLAN t;
|
|
UINT num_vlan = 0;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IsEnable(hWnd, 0) == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Zero(&t, sizeof(t));
|
|
if (CcEnumVLan(cm->Client, &t) == ERR_NO_ERROR)
|
|
{
|
|
num_vlan = t.NumItem;
|
|
|
|
CiFreeClientEnumVLan(&t);
|
|
}
|
|
|
|
if (num_vlan == 0)
|
|
{
|
|
if (MsgBox(hWnd, MB_ICONINFORMATION | MB_YESNO, _UU("CM_NO_VLAN")) == IDNO)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
if (cm->server_name == NULL || cm->Client->Unix)
|
|
{
|
|
Command(hWnd, CMD_NEW_VLAN);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_VLAN_REMOTE_ERROR"));
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
a = CmCreateNewAccountObject(hWnd);
|
|
if (a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CmVoice("input_config");
|
|
if (CmEditAccountDlg(hWnd, a))
|
|
{
|
|
CmVoice("new_config");
|
|
}
|
|
|
|
CmFreeAccountObject(hWnd, a);
|
|
}
|
|
|
|
// Release the account object
|
|
void CmFreeAccountObject(HWND hWnd, CM_ACCOUNT *a)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || a == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Free(a->ClientOption);
|
|
CiFreeClientAuth(a->ClientAuth);
|
|
if (a->ServerCert != NULL)
|
|
{
|
|
FreeX(a->ServerCert);
|
|
}
|
|
Free(a);
|
|
}
|
|
|
|
// Get an existing account object
|
|
CM_ACCOUNT *CmGetExistAccountObject(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
RPC_CLIENT_GET_ACCOUNT c;
|
|
CM_ACCOUNT *a;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
Zero(&c, sizeof(c));
|
|
UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);
|
|
if (CALL(hWnd, CcGetAccount(cm->Client, &c)) == false)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
a = ZeroMalloc(sizeof(CM_ACCOUNT));
|
|
a->EditMode = true;
|
|
a->CheckServerCert = c.CheckServerCert;
|
|
a->Startup = c.StartupAccount;
|
|
if (c.ServerCert != NULL)
|
|
{
|
|
a->ServerCert = CloneX(c.ServerCert);
|
|
}
|
|
a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
|
|
Copy(a->ClientOption, c.ClientOption, sizeof(CLIENT_OPTION));
|
|
a->ClientAuth = CopyClientAuth(c.ClientAuth);
|
|
Copy(a->ShortcutKey, c.ShortcutKey, SHA1_SIZE);
|
|
CiFreeClientGetAccount(&c);
|
|
|
|
a->LockMode = cm->CmSetting.LockMode;
|
|
|
|
return a;
|
|
}
|
|
|
|
// Create a new account object
|
|
CM_ACCOUNT *CmCreateNewAccountObject(HWND hWnd)
|
|
{
|
|
CM_ACCOUNT *a;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
a = ZeroMalloc(sizeof(CM_ACCOUNT));
|
|
a->EditMode = false;
|
|
a->CheckServerCert = false;
|
|
a->Startup = false;
|
|
a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
|
|
|
|
// Initialize the client options
|
|
CmGenerateNewAccountName(hWnd, a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName));
|
|
a->ClientOption->Port = 443; // Default port number
|
|
a->ClientOption->NumRetry = INFINITE;
|
|
a->ClientOption->RetryInterval = 15;
|
|
a->ClientOption->MaxConnection = 1;
|
|
a->ClientOption->HalfConnection = false;
|
|
a->ClientOption->UseEncrypt = true;
|
|
a->ClientOption->AdditionalConnectionInterval = 1;
|
|
|
|
if (cm->Client->Unix)
|
|
{
|
|
a->ClientOption->NoRoutingTracking = true;
|
|
}
|
|
|
|
a->ClientAuth = ZeroMalloc(sizeof(CLIENT_AUTH));
|
|
|
|
// Password authentication
|
|
a->ClientAuth->AuthType = CLIENT_AUTHTYPE_PASSWORD;
|
|
|
|
return a;
|
|
}
|
|
|
|
// Create an imported account name
|
|
void CmGenerateImportName(HWND hWnd, wchar_t *name, UINT size, wchar_t *old_name)
|
|
{
|
|
UINT i;
|
|
// Validate arguments
|
|
if (name == NULL || hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (i = 1;;i++)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
if (i == 1)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_IMPORT_NAME_1"), old_name);
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_IMPORT_NAME_2"), old_name, i);
|
|
}
|
|
|
|
if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)
|
|
{
|
|
UniStrCpy(name, size, tmp);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create a copy name
|
|
void CmGenerateCopyName(HWND hWnd, wchar_t *name, UINT size, wchar_t *old_name)
|
|
{
|
|
UINT i;
|
|
// Validate arguments
|
|
if (name == NULL || hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (i = 1;;i++)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
if (i == 1)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_COPY_NAME_1"), old_name);
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_COPY_NAME_2"), i, old_name);
|
|
}
|
|
|
|
if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)
|
|
{
|
|
UniStrCpy(name, size, tmp);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create a new account name
|
|
void CmGenerateNewAccountName(HWND hWnd, wchar_t *name, UINT size)
|
|
{
|
|
UINT i;
|
|
// Validate arguments
|
|
if (name == NULL || hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (i = 1;;i++)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
if (i == 1)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_NEW_ACCOUNT_NAME_1"));
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_NEW_ACCOUNT_NAME_2"), i);
|
|
}
|
|
|
|
if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)
|
|
{
|
|
UniStrCpy(name, size, tmp);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Show the policy list
|
|
void CmPolicyDlgPrint(HWND hWnd, CM_POLICY *p)
|
|
{
|
|
CmPolicyDlgPrintEx(hWnd, p, false);
|
|
}
|
|
void CmPolicyDlgPrintEx(HWND hWnd, CM_POLICY *p, bool cascade_mode)
|
|
{
|
|
CmPolicyDlgPrintEx2(hWnd, p, cascade_mode, POLICY_CURRENT_VERSION);
|
|
}
|
|
void CmPolicyDlgPrintEx2(HWND hWnd, CM_POLICY *p, bool cascade_mode, UINT ver)
|
|
{
|
|
POLICY *pol;
|
|
UINT i;
|
|
LVB *b;
|
|
// Validate arguments
|
|
if (hWnd == NULL || p == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pol = p->Policy;
|
|
|
|
b = LvInsertStart();
|
|
|
|
for (i = 0;i < NUM_POLICY_ITEM;i++)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
|
|
if (cascade_mode)
|
|
{
|
|
if (PolicyIsSupportedForCascade(i) == false)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (IS_POLICY_FOR_CURRENT_VER(i, ver))
|
|
{
|
|
if (policy_item[i].TypeInt == false)
|
|
{
|
|
// bool type
|
|
UniStrCpy(tmp, sizeof(tmp), POLICY_BOOL(pol, i) ? _UU("POL_BOOL_ENABLE") : (p->Extension ? _UU("POL_BOOL_DISABLE_EX") : _UU("POL_BOOL_DISABLE")));
|
|
}
|
|
else
|
|
{
|
|
// int type
|
|
if (policy_item[i].AllowZero && POLICY_INT(pol, i) == 0)
|
|
{
|
|
UniStrCpy(tmp, sizeof(tmp), _UU("POL_INT_ZERO"));
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU(policy_item[i].FormatStr), POLICY_INT(pol, i));
|
|
}
|
|
}
|
|
|
|
LvInsertAdd(b, ICO_MACHINE, (void *)i, 2, GetPolicyTitle(i), tmp);
|
|
}
|
|
}
|
|
|
|
LvInsertEnd(b, hWnd, L_POLICY);
|
|
}
|
|
|
|
// Policy list dialog box
|
|
UINT CmPolicyDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
CM_POLICY *p = (CM_POLICY *)param;
|
|
NMHDR *n;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
FormatText(hWnd, 0, p->AccountName);
|
|
FormatText(hWnd, S_TITLE, p->AccountName);
|
|
p->hWnd = hWnd;
|
|
if (p->CmStatus != NULL)
|
|
{
|
|
p->CmStatus->hWndPolicy = hWnd;
|
|
}
|
|
|
|
// Initialize the column
|
|
LvInit(hWnd, L_POLICY);
|
|
LvInsertColumn(hWnd, L_POLICY, 0, _UU("POL_TITLE_STR"), 375);
|
|
LvInsertColumn(hWnd, L_POLICY, 1, _UU("POL_VALUE_STR"), 100);
|
|
|
|
// Display
|
|
CmPolicyDlgPrint(hWnd, p);
|
|
|
|
// Select the first
|
|
LvSelect(hWnd, L_POLICY, 0);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
n = (NMHDR *)lParam;
|
|
switch (n->idFrom)
|
|
{
|
|
case L_POLICY:
|
|
switch (n->code)
|
|
{
|
|
case LVN_ITEMCHANGED:
|
|
// Change selection
|
|
if (LvIsSelected(hWnd, L_POLICY) == false)
|
|
{
|
|
SetText(hWnd, S_DESCRIPTION, L"");
|
|
}
|
|
else
|
|
{
|
|
UINT index = LvGetSelected(hWnd, L_POLICY);
|
|
UINT id = (UINT)LvGetParam(hWnd, L_POLICY, index);
|
|
if (id < NUM_POLICY_ITEM)
|
|
{
|
|
SetText(hWnd, S_DESCRIPTION, GetPolicyDescription(id));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, 0);
|
|
break;
|
|
}
|
|
|
|
LvSortHander(hWnd, msg, wParam, lParam, L_POLICY);
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Show the policy list dialog
|
|
void CmPolicyDlg(HWND hWnd, CM_STATUS *st)
|
|
{
|
|
RPC_CLIENT_GET_CONNECTION_STATUS s;
|
|
POLICY *policy;
|
|
CM_POLICY cp;
|
|
// Validate arguments
|
|
if (hWnd == NULL || st == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the policy
|
|
Zero(&s, sizeof(s));
|
|
UniStrCpy(s.AccountName, sizeof(s.AccountName), st->AccountName);
|
|
if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)
|
|
{
|
|
return;
|
|
}
|
|
if (s.Active == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
policy = &s.Policy;
|
|
|
|
Zero(&cp, sizeof(cp));
|
|
UniStrCpy(cp.AccountName, sizeof(cp.AccountName), st->AccountName);
|
|
cp.Policy = policy;
|
|
cp.CmStatus = st;
|
|
|
|
Dialog(hWnd, D_CM_POLICY, CmPolicyDlgProc, &cp);
|
|
|
|
st->hWndPolicy = NULL;
|
|
|
|
CiFreeClientGetConnectionStatus(&s);
|
|
}
|
|
|
|
// Show the certificate
|
|
void CmStatusDlgPrintCert(HWND hWnd, CM_STATUS *st, bool server)
|
|
{
|
|
RPC_CLIENT_GET_CONNECTION_STATUS s;
|
|
X *x, *issuer;
|
|
// Validate arguments
|
|
if (hWnd == NULL || st == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the latest information
|
|
Zero(&s, sizeof(s));
|
|
UniStrCpy(s.AccountName, sizeof(s.AccountName), st->AccountName);
|
|
if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)
|
|
{
|
|
Close(hWnd);
|
|
return;
|
|
}
|
|
|
|
if (s.Active == false)
|
|
{
|
|
// Disconnect
|
|
Close(hWnd);
|
|
return;
|
|
}
|
|
|
|
if (server == false)
|
|
{
|
|
// Show the client certificate
|
|
x = s.ClientX;
|
|
}
|
|
else
|
|
{
|
|
// Show the server certificate
|
|
x = s.ServerX;
|
|
}
|
|
|
|
cm->WindowCount++;
|
|
issuer = CmGetIssuer(x);
|
|
CertDlg(hWnd, x, issuer, true);
|
|
FreeX(issuer);
|
|
cm->WindowCount--;
|
|
|
|
CiFreeClientGetConnectionStatus(&s);
|
|
}
|
|
|
|
// Show the information of the status dialog
|
|
void CmStatusDlgPrint(HWND hWnd, CM_STATUS *cmst)
|
|
{
|
|
RPC_CLIENT_GET_CONNECTION_STATUS s;
|
|
LVB *b;
|
|
// Validate arguments
|
|
if (hWnd == NULL || cmst == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the latest information
|
|
Zero(&s, sizeof(s));
|
|
UniStrCpy(s.AccountName, sizeof(s.AccountName), cmst->AccountName);
|
|
if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)
|
|
{
|
|
Close(hWnd);
|
|
return;
|
|
}
|
|
|
|
if (s.Active == false)
|
|
{
|
|
// Disconnect
|
|
Close(hWnd);
|
|
return;
|
|
}
|
|
|
|
// Show the status in the list box in the status dialog
|
|
b = LvInsertStart();
|
|
CmPrintStatusToListView(b, &s);
|
|
LvInsertEnd(b, hWnd, L_STATUS);
|
|
|
|
LvAutoSize(hWnd, L_STATUS);
|
|
|
|
SetEnable(hWnd, B_POLICY, s.Connected);
|
|
|
|
SetEnable(hWnd, B_SERVER_CERT, s.ServerX != NULL);
|
|
SetEnable(hWnd, B_CLIENT_CERT, s.ClientX != NULL);
|
|
|
|
CiFreeClientGetConnectionStatus(&s);
|
|
}
|
|
|
|
// Show the status in the list box in the status dialog
|
|
void CmPrintStatusToListView(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s)
|
|
{
|
|
CmPrintStatusToListViewEx(b, s, false);
|
|
}
|
|
void CmPrintStatusToListViewEx(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s, bool server_mode)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
char str[MAX_SIZE];
|
|
char vv[128];
|
|
// Validate arguments
|
|
if (b == NULL || s == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (server_mode == false)
|
|
{
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_ACCOUNT_NAME"), s->AccountName);
|
|
|
|
if (s->Connected == false)
|
|
{
|
|
wchar_t *st = _UU("CM_ST_CONNECTED_FALSE");
|
|
switch (s->SessionStatus)
|
|
{
|
|
case CLIENT_STATUS_CONNECTING:
|
|
st = _UU("CM_ST_CONNECTING");
|
|
break;
|
|
case CLIENT_STATUS_NEGOTIATION:
|
|
st = _UU("CM_ST_NEGOTIATION");
|
|
break;
|
|
case CLIENT_STATUS_AUTH:
|
|
st = _UU("CM_ST_AUTH");
|
|
break;
|
|
case CLIENT_STATUS_ESTABLISHED:
|
|
st = _UU("CM_ST_ESTABLISHED");
|
|
break;
|
|
case CLIENT_STATUS_RETRY:
|
|
st = _UU("CM_ST_RETRY");
|
|
break;
|
|
case CLIENT_STATUS_IDLE:
|
|
st = _UU("CM_ST_IDLE");
|
|
break;
|
|
}
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CONNECTED"), st);
|
|
}
|
|
else
|
|
{
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CONNECTED"), _UU("CM_ST_CONNECTED_TRUE"));
|
|
}
|
|
}
|
|
|
|
if (s->Connected)
|
|
{
|
|
if (s->VLanId == 0)
|
|
{
|
|
UniStrCpy(tmp, sizeof(tmp), _UU("CM_ST_NO_VLAN"));
|
|
}
|
|
else
|
|
{
|
|
UniToStru(tmp, s->VLanId);
|
|
}
|
|
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_VLAN_ID"), tmp);
|
|
|
|
if (server_mode == false)
|
|
{
|
|
StrToUni(tmp, sizeof(tmp), s->ServerName);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_NAME"), tmp);
|
|
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_PORT_TCP"), s->ServerPort);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_PORT"), tmp);
|
|
}
|
|
|
|
StrToUni(tmp, sizeof(tmp), s->ServerProductName);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_NAME"), tmp);
|
|
|
|
UniFormat(tmp, sizeof(tmp), L"%u.%02u", s->ServerProductVer / 100, s->ServerProductVer % 100);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_VER"), tmp);
|
|
UniFormat(tmp, sizeof(tmp), L"Build %u", s->ServerProductBuild);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_BUILD"), tmp);
|
|
}
|
|
|
|
GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->StartTime), NULL);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_START_TIME"), tmp);
|
|
GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->FirstConnectionEstablishedTime), NULL);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_FIRST_ESTAB_TIME"), s->FirstConnectionEstablishedTime == 0 ? _UU("CM_ST_NONE") : tmp);
|
|
|
|
if (s->Connected)
|
|
{
|
|
GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->CurrentConnectionEstablishTime), NULL);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CURR_ESTAB_TIME"), tmp);
|
|
}
|
|
|
|
if (server_mode == false)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_STR"), s->NumConnectionsEstablished);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_ESTABLISHED"), tmp);
|
|
}
|
|
|
|
if (s->Connected)
|
|
{
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_HALF_CONNECTION"), s->HalfConnection ? _UU("CM_ST_HALF_TRUE") : _UU("CM_ST_HALF_FALSE"));
|
|
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_QOS"), s->QoS ? _UU("CM_ST_QOS_TRUE") : _UU("CM_ST_QOS_FALSE"));
|
|
|
|
UniFormat(tmp, sizeof(tmp), L"%u", s->NumTcpConnections);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_TCP"), tmp);
|
|
|
|
if (s->HalfConnection)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), L"%u", s->NumTcpConnectionsUpload);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_TCP_UPLOAD"), tmp);
|
|
UniFormat(tmp, sizeof(tmp), L"%u", s->NumTcpConnectionsDownload);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_TCP_DOWNLOAD"), tmp);
|
|
}
|
|
|
|
UniFormat(tmp, sizeof(tmp), L"%u", s->MaxTcpConnections);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_MAX_TCP"), tmp);
|
|
|
|
if (s->UseEncrypt == false)
|
|
{
|
|
UniStrCpy(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_FALSE"));
|
|
}
|
|
else
|
|
{
|
|
if (StrLen(s->CipherName) != 0)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_TRUE"), s->CipherName);
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_TRUE2"));
|
|
}
|
|
}
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_USE_ENCRYPT"), tmp);
|
|
|
|
if (s->UseCompress)
|
|
{
|
|
UINT percent = 0;
|
|
if ((s->TotalRecvSize + s->TotalSendSize) > 0)
|
|
{
|
|
percent = (UINT)((UINT64)100 - (UINT64)(s->TotalRecvSizeReal + s->TotalSendSizeReal) * (UINT64)100 /
|
|
(s->TotalRecvSize + s->TotalSendSize));
|
|
percent = MAKESURE(percent, 0, 100);
|
|
}
|
|
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_COMPRESS_TRUE"), percent);
|
|
}
|
|
else
|
|
{
|
|
UniStrCpy(tmp, sizeof(tmp), _UU("CM_ST_COMPRESS_FALSE"));
|
|
}
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_USE_COMPRESS"), tmp);
|
|
|
|
if (IsEmptyStr(s->UnderlayProtocol) == false)
|
|
{
|
|
StrToUni(tmp, sizeof(tmp), s->UnderlayProtocol);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp);
|
|
}
|
|
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));
|
|
|
|
StrToUni(tmp, sizeof(tmp), s->SessionName);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SESSION_NAME"), tmp);
|
|
|
|
StrToUni(tmp, sizeof(tmp), s->ConnectionName);
|
|
if (UniStrCmpi(tmp, L"INITING") != 0)
|
|
{
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CONNECTION_NAME"), tmp);
|
|
}
|
|
|
|
BinToStr(str, sizeof(str), s->SessionKey, sizeof(s->SessionKey));
|
|
StrToUni(tmp, sizeof(tmp), str);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SESSION_KEY"), tmp);
|
|
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_BRIDGE_MODE"), s->IsBridgeMode ? _UU("CM_ST_YES") : _UU("CM_ST_NO"));
|
|
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_MONITOR_MODE"), s->IsMonitorMode ? _UU("CM_ST_YES") : _UU("CM_ST_NO"));
|
|
|
|
ToStr3(vv, sizeof(vv), s->TotalSendSize);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_SIZE"), tmp);
|
|
|
|
ToStr3(vv, sizeof(vv), s->TotalRecvSize);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_SIZE"), tmp);
|
|
|
|
ToStr3(vv, sizeof(vv), s->Traffic.Send.UnicastCount);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_UCAST_NUM"), tmp);
|
|
|
|
ToStr3(vv, sizeof(vv), s->Traffic.Send.UnicastBytes);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_UCAST_SIZE"), tmp);
|
|
|
|
ToStr3(vv, sizeof(vv), s->Traffic.Send.BroadcastCount);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_BCAST_NUM"), tmp);
|
|
|
|
ToStr3(vv, sizeof(vv), s->Traffic.Send.BroadcastBytes);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_BCAST_SIZE"), tmp);
|
|
|
|
ToStr3(vv, sizeof(vv), s->Traffic.Recv.UnicastCount);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_UCAST_NUM"), tmp);
|
|
|
|
ToStr3(vv, sizeof(vv), s->Traffic.Recv.UnicastBytes);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_UCAST_SIZE"), tmp);
|
|
|
|
ToStr3(vv, sizeof(vv), s->Traffic.Recv.BroadcastCount);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_BCAST_NUM"), tmp);
|
|
|
|
ToStr3(vv, sizeof(vv), s->Traffic.Recv.BroadcastBytes);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
|
|
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_BCAST_SIZE"), tmp);
|
|
}
|
|
}
|
|
|
|
// Status dialog procedure
|
|
UINT CmStatusDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
CM_STATUS *s = (CM_STATUS *)param;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetIcon(hWnd, 0, ICO_TOWER);
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_TITLE"), s->AccountName);
|
|
SetText(hWnd, 0, tmp);
|
|
FormatText(hWnd, S_TITLE, s->AccountName);
|
|
DlgFont(hWnd, S_TITLE, 0, 1);
|
|
|
|
Add(cm->StatusWindowList, hWnd);
|
|
|
|
SetTimer(hWnd, 1, 500, NULL);
|
|
|
|
LvInitEx(hWnd, L_STATUS, true);
|
|
ListView_SetImageList(DlgItem(hWnd, L_STATUS), NULL, LVSIL_NORMAL);
|
|
ListView_SetImageList(DlgItem(hWnd, L_STATUS), NULL, LVSIL_SMALL);
|
|
LvInsertColumn(hWnd, L_STATUS, 0, _UU("CM_ST_COLUMN_1"), 160);
|
|
LvInsertColumn(hWnd, L_STATUS, 1, _UU("CM_ST_COLUMN_2"), 270);
|
|
|
|
CmStatusDlgPrint(hWnd, s);
|
|
|
|
break;
|
|
case WM_TIMER:
|
|
switch (wParam)
|
|
{
|
|
case 1:
|
|
KillTimer(hWnd, 1);
|
|
CmStatusDlgPrint(hWnd, s);
|
|
SetTimer(hWnd, 1, 500, NULL);
|
|
break;
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
case IDCANCEL:
|
|
// Close
|
|
Close(hWnd);
|
|
break;
|
|
case B_POLICY:
|
|
// Show the policy
|
|
CmPolicyDlg(hWnd, s);
|
|
break;
|
|
case B_SERVER_CERT:
|
|
CmStatusDlgPrintCert(hWnd, s, true);
|
|
break;
|
|
case B_CLIENT_CERT:
|
|
CmStatusDlgPrintCert(hWnd, s, false);
|
|
break;
|
|
}
|
|
break;
|
|
case WM_CLOSE:
|
|
Delete(cm->StatusWindowList, hWnd);
|
|
if (s->hWndPolicy != NULL)
|
|
{
|
|
EndDialog(s->hWndPolicy, false);
|
|
s->hWndPolicy = NULL;
|
|
}
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Show the status dialog
|
|
void CmStatusDlg(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
CM_STATUS *s;
|
|
// Validate arguments
|
|
if (hWnd == NULL || account_name == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
s = ZeroMalloc(sizeof(CM_STATUS));
|
|
UniStrCpy(s->AccountName, sizeof(s->AccountName), account_name);
|
|
|
|
Dialog(hWnd, D_CONNECTION_STATUS, CmStatusDlgProc, s);
|
|
|
|
Free(s);
|
|
}
|
|
|
|
// Show the status
|
|
void CmStatus(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
UINT i;
|
|
wchar_t tmp[MAX_SIZE];
|
|
// Validate arguments
|
|
if (hWnd == NULL || account_name == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_TITLE"), account_name);
|
|
|
|
for (i = 0;i < LIST_NUM(cm->StatusWindowList);i++)
|
|
{
|
|
HWND h = LIST_DATA(cm->StatusWindowList, i);
|
|
if (h != NULL)
|
|
{
|
|
wchar_t tmp2[MAX_SIZE];
|
|
if (GetTxt(h, 0, tmp2, sizeof(tmp2)))
|
|
{
|
|
if (UniStrCmpi(tmp2, tmp) == 0)
|
|
{
|
|
SetActiveWindow(h);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CmStatusDlg(hWnd, account_name);
|
|
}
|
|
|
|
// Delete
|
|
void CmDeleteAccount(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
RPC_CLIENT_DELETE_ACCOUNT c;
|
|
// Validate arguments
|
|
if (hWnd == NULL || account_name == NULL)
|
|
{
|
|
return;
|
|
}
|
|
Zero(&c, sizeof(c));
|
|
UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);
|
|
|
|
CmVoice("delete_config_1");
|
|
if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_ACCOUNT_MSG"), account_name)
|
|
== IDNO)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CALL(hWnd, CcDeleteAccount(cm->Client, &c));
|
|
CmVoice("delete_config_2");
|
|
}
|
|
|
|
// Disconnect
|
|
void CmDisconnect(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
RPC_CLIENT_CONNECT c;
|
|
// Validate arguments
|
|
if (hWnd == NULL || account_name == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Zero(&c, sizeof(c));
|
|
UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);
|
|
|
|
cm->PositiveDisconnectFlag = true;
|
|
|
|
CALL(hWnd, CcDisconnect(cm->Client, &c));
|
|
}
|
|
|
|
// Show the promotional window
|
|
void SmShowPublicVpnServerHtml(HWND hWnd)
|
|
{
|
|
char *langstr = _SS("LANGSTR");
|
|
|
|
if(StrCmpi(langstr, "Japanese") == 0)
|
|
{
|
|
ShowHtml(hWnd, PUBLIC_SERVER_HTML, PUBLIC_SERVER_TAG);
|
|
}
|
|
else
|
|
{
|
|
ShowHtml(hWnd, PUBLIC_SERVER_HTML_EN, PUBLIC_SERVER_TAG);
|
|
}
|
|
}
|
|
|
|
// Connection
|
|
void CmConnect(HWND hWnd, wchar_t *account_name)
|
|
{
|
|
RPC_CLIENT_CONNECT c;
|
|
UINT i;
|
|
// Validate arguments
|
|
if (hWnd == NULL || account_name == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IsEnable(hWnd, 0) == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (hWnd == cm->hMainWnd)
|
|
{
|
|
if (LvNum(hWnd, L_VLAN) == 0 && cm->Client->Win9x)
|
|
{
|
|
if (MsgBox(hWnd, MB_ICONINFORMATION | MB_YESNO, _UU("CM_NO_VLAN_2")) == IDNO)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
if (cm->server_name == NULL || cm->Client->Unix)
|
|
{
|
|
Command(hWnd, CMD_NEW_VLAN);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_VLAN_REMOTE_ERROR"));
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// (If necessary) display a warning
|
|
if (CmWarningDesktop(hWnd, account_name) == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (cm->server_name == NULL)
|
|
{
|
|
if (cm->BadProcessChecked == false)
|
|
{
|
|
cm->BadProcessChecked = true;
|
|
|
|
CheckBadProcesses(hWnd);
|
|
}
|
|
}
|
|
|
|
if (cm->server_name == NULL)
|
|
{
|
|
// Check the Windows version
|
|
RPC_WINVER winver;
|
|
wchar_t winver_msg_client[3800];
|
|
|
|
GetWinVer(&winver);
|
|
Zero(winver_msg_client, sizeof(winver_msg_client));
|
|
|
|
if (IsSupportedWinVer(&winver) == false)
|
|
{
|
|
SYSTEMTIME st;
|
|
|
|
LocalTime(&st);
|
|
|
|
UniFormat(winver_msg_client, sizeof(winver_msg_client), _UU("WINVER_ERROR_FORMAT"),
|
|
_UU("WINVER_ERROR_PC_LOCAL"),
|
|
winver.Title,
|
|
_UU("WINVER_ERROR_VPNCLIENT"),
|
|
SUPPORTED_WINDOWS_LIST,
|
|
_UU("WINVER_ERROR_PC_LOCAL"),
|
|
_UU("WINVER_ERROR_VPNCLIENT"),
|
|
_UU("WINVER_ERROR_VPNCLIENT"),
|
|
_UU("WINVER_ERROR_VPNCLIENT"),
|
|
st.wYear, st.wMonth);
|
|
}
|
|
|
|
if (UniIsEmptyStr(winver_msg_client) == false)
|
|
{
|
|
OnceMsgEx(hWnd, _UU("WINVER_TITLE"), winver_msg_client,
|
|
true, ICO_WARNING, NULL);
|
|
}
|
|
}
|
|
|
|
i = LvSearchStr(hWnd, L_ACCOUNT, 0, account_name);
|
|
if (i != INFINITE)
|
|
{
|
|
wchar_t *tmp = LvGetStr(hWnd, L_ACCOUNT, i, 2);
|
|
if (tmp != NULL)
|
|
{
|
|
wchar_t tag[MAX_SIZE];
|
|
StrToUni(tag, sizeof(tag), PUBLIC_SERVER_NAME);
|
|
|
|
if (UniSearchStrEx(tmp, tag, 0, false) != INFINITE)
|
|
{
|
|
SmShowPublicVpnServerHtml(hWnd);
|
|
}
|
|
|
|
Free(tmp);
|
|
}
|
|
}
|
|
|
|
if (cm->CheckedAndShowedAdminPackMessage == false)
|
|
{
|
|
cm->CheckedAndShowedAdminPackMessage = true;
|
|
//CmCheckAndShowAdminPackTrialVersionNoticeMessage(NULL);
|
|
}
|
|
|
|
Zero(&c, sizeof(c));
|
|
UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);
|
|
|
|
CmSetForegroundProcessToCnService();
|
|
|
|
if (CALL(hWnd, CcConnect(cm->Client, &c)))
|
|
{
|
|
cm->ConnectStartedFlag = true;
|
|
}
|
|
}
|
|
|
|
// Determine whether to bold the specified menu item
|
|
bool CmIsBold(UINT id)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Determine whether to enable the specified menu item
|
|
bool CmIsEnabled(HWND hWnd, UINT id)
|
|
{
|
|
UINT index;
|
|
wchar_t *name;
|
|
bool locked = false;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
locked = cm->CmSetting.LockMode;
|
|
|
|
if (locked)
|
|
{
|
|
switch (id)
|
|
{
|
|
case CMD_NEW:
|
|
case CMD_CLONE:
|
|
case CMD_IMPORT_ACCOUNT:
|
|
case CMD_DELETE:
|
|
case CMD_OPTION:
|
|
case CMD_VOIDE_NONE:
|
|
case CMD_VOICE_NORMAL:
|
|
case CMD_VOICE_ODD:
|
|
case CMD_STARTUP:
|
|
case CMD_NOSTARTUP:
|
|
case CMD_TRAFFIC:
|
|
case CMD_MMCSS:
|
|
return false;
|
|
case CMD_NEW_VLAN:
|
|
case CMD_ENABLE_VLAN:
|
|
case CMD_DISABLE_VLAN:
|
|
case CMD_DELETE_VLAN:
|
|
case CMD_REINSTALL:
|
|
case CMD_WINNET:
|
|
if (cm->CmEasyModeSupported)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (id)
|
|
{
|
|
case CMD_LANGUAGE:
|
|
return MsIsNt();
|
|
case CMD_SHOWPORT:
|
|
case CMD_GRID:
|
|
if (cm->IconView)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
case CMD_MMCSS:
|
|
if (MsIsVista() == false || IsEmptyStr(cm->server_name) == false)
|
|
{
|
|
return false;
|
|
}
|
|
if (OS_IS_SERVER(GetOsType()))
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
case CMD_TRAYICON:
|
|
case CMD_TRAFFIC:
|
|
return (cm->server_name == NULL);
|
|
case CMD_NETIF:
|
|
if (MsIsNt() == false)
|
|
{
|
|
return false;
|
|
}
|
|
return (cm->server_name == NULL);
|
|
case CMD_CM_SETTING:
|
|
return cm->CmSettingSupported;
|
|
case CMD_CONNECT:
|
|
case CMD_DISCONNECT:
|
|
case CMD_STATUS:
|
|
case CMD_RENAME:
|
|
case CMD_DELETE:
|
|
if (LvIsMultiMasked(hWnd, L_ACCOUNT))
|
|
{
|
|
return false;
|
|
}
|
|
if (LvIsSelected(hWnd, L_ACCOUNT) == false)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
// Determine whether the selected account is under connecting
|
|
UINT i = LvGetSelected(hWnd, L_ACCOUNT);
|
|
wchar_t *str = LvGetStr(hWnd, L_ACCOUNT, i, 1);
|
|
wchar_t *name = LvGetStr(hWnd, L_ACCOUNT, i, 0);
|
|
bool is_connected = false;
|
|
if (str != NULL)
|
|
{
|
|
if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)
|
|
{
|
|
is_connected = true;
|
|
}
|
|
Free(str);
|
|
}
|
|
if (name != NULL)
|
|
{
|
|
if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_LINK")) == 0)
|
|
{
|
|
Free(name);
|
|
return false;
|
|
}
|
|
Free(name);
|
|
}
|
|
if (id == CMD_CONNECT || id == CMD_RENAME || id == CMD_DELETE)
|
|
{
|
|
return !is_connected;
|
|
}
|
|
else
|
|
{
|
|
return is_connected;
|
|
}
|
|
}
|
|
break;
|
|
case CMD_DISCONNECT_ALL:
|
|
if (CmGetNumConnected(hWnd) == 0)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
case CMD_SHORTCUT:
|
|
// Create a shortcut
|
|
if (cm->Client->Rpc->Sock->RemoteIP.addr[0] != 127)
|
|
{
|
|
return false;
|
|
}
|
|
case CMD_EXPORT_ACCOUNT:
|
|
if (LvIsMultiMasked(hWnd, L_ACCOUNT))
|
|
{
|
|
return false;
|
|
}
|
|
name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
|
|
if (name != NULL)
|
|
{
|
|
if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_LINK")) == 0
|
|
)
|
|
{
|
|
Free(name);
|
|
return false;
|
|
}
|
|
Free(name);
|
|
}
|
|
return LvIsSelected(hWnd, L_ACCOUNT);
|
|
case CMD_CLONE:
|
|
if (LvIsMultiMasked(hWnd, L_ACCOUNT))
|
|
{
|
|
return false;
|
|
}
|
|
name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
|
|
if (name != NULL)
|
|
{
|
|
if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_LINK")) == 0
|
|
)
|
|
{
|
|
Free(name);
|
|
return false;
|
|
}
|
|
Free(name);
|
|
}
|
|
return LvIsSelected(hWnd, L_ACCOUNT);
|
|
case CMD_STARTUP:
|
|
case CMD_NOSTARTUP:
|
|
name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
|
|
if (name != NULL)
|
|
{
|
|
if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_LINK")) == 0
|
|
)
|
|
{
|
|
Free(name);
|
|
return false;
|
|
}
|
|
Free(name);
|
|
}
|
|
if (LvIsMultiMasked(hWnd, L_ACCOUNT))
|
|
{
|
|
return false;
|
|
}
|
|
if (LvIsSelected(hWnd, L_ACCOUNT) == false)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
// Determine whether the selected account is a startup account
|
|
UINT i = LvGetSelected(hWnd, L_ACCOUNT);
|
|
bool is_startup = (bool)LvGetParam(hWnd, L_ACCOUNT, i);
|
|
if (id == CMD_STARTUP)
|
|
{
|
|
return !is_startup;
|
|
}
|
|
else
|
|
{
|
|
return is_startup;
|
|
}
|
|
}
|
|
break;
|
|
case CMD_NEW_VLAN:
|
|
if (cm->Client->Unix == false && cm->Client->Win9x == false)
|
|
{
|
|
if (cm->server_name != NULL)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
if (cm->Client->Win9x)
|
|
{
|
|
if (LvNum(hWnd, L_VLAN) >= 1)
|
|
{
|
|
// You can not install two or more virtual LAN cards in Win9x
|
|
return false;
|
|
}
|
|
}
|
|
break;
|
|
case CMD_PROPERTY:
|
|
name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
|
|
if (name != NULL)
|
|
{
|
|
if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_LINK")) == 0)
|
|
{
|
|
Free(name);
|
|
return false;
|
|
}
|
|
Free(name);
|
|
}
|
|
if (LvIsMultiMasked(hWnd, L_ACCOUNT))
|
|
{
|
|
return false;
|
|
}
|
|
return LvIsSelected(hWnd, L_ACCOUNT);
|
|
case CMD_DELETE_VLAN:
|
|
if (LvIsMultiMasked(hWnd, L_VLAN))
|
|
{
|
|
return false;
|
|
}
|
|
return LvIsSelected(hWnd, L_VLAN);
|
|
case CMD_ENABLE_VLAN:
|
|
if (cm->Client->Win9x)
|
|
{
|
|
return false;
|
|
}
|
|
if (LvIsMultiMasked(hWnd, L_VLAN))
|
|
{
|
|
return false;
|
|
}
|
|
index = LvGetSelected(hWnd, L_VLAN);
|
|
if (index == INFINITE)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 1);
|
|
if (s != NULL)
|
|
{
|
|
if (UniStrCmpi(s, _UU("CM_VLAN_DISABLED")) == 0)
|
|
{
|
|
Free(s);
|
|
return true;
|
|
}
|
|
Free(s);
|
|
}
|
|
return false;
|
|
}
|
|
break;
|
|
case CMD_DISABLE_VLAN:
|
|
if (cm->Client->Win9x)
|
|
{
|
|
return false;
|
|
}
|
|
if (LvIsMultiMasked(hWnd, L_VLAN))
|
|
{
|
|
return false;
|
|
}
|
|
index = LvGetSelected(hWnd, L_VLAN);
|
|
if (index == INFINITE)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 1);
|
|
if (s != NULL)
|
|
{
|
|
if (UniStrCmpi(s, _UU("CM_VLAN_ENABLED")) == 0)
|
|
{
|
|
Free(s);
|
|
return true;
|
|
}
|
|
Free(s);
|
|
}
|
|
return false;
|
|
}
|
|
break;
|
|
case CMD_REINSTALL:
|
|
if (cm->server_name != NULL)
|
|
{
|
|
return false;
|
|
}
|
|
if (cm->Client->Win9x || cm->Client->Unix)
|
|
{
|
|
// Upgrading the virtual LAN card on a UNIX system or Win9x is unavailable
|
|
return false;
|
|
}
|
|
if (LvIsMultiMasked(hWnd, L_VLAN))
|
|
{
|
|
return false;
|
|
}
|
|
return LvIsSelected(hWnd, L_VLAN);
|
|
case CMD_WINNET:
|
|
{
|
|
UINT os_type = GetOsInfo()->OsType;
|
|
|
|
if (OS_IS_WINDOWS_NT(os_type) && GET_KETA(os_type, 100) >= 2)
|
|
{
|
|
if (cm->server_name != NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
break;
|
|
case CMD_EXIT:
|
|
return cm->TrayInited;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Convert a VLAN device name to the display name
|
|
void CmVLanNameToPrintName(char *str, UINT size, char *name)
|
|
{
|
|
// Validate arguments
|
|
if (str == NULL || name == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Format(str, size, VLAN_ADAPTER_NAME_TAG, name);
|
|
}
|
|
|
|
// Convert a display name to a VLAN device name
|
|
bool CmPrintNameToVLanName(char *name, UINT size, char *str)
|
|
{
|
|
// Validate arguments
|
|
if (name == NULL || str == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (StartWith(str, VLAN_ADAPTER_NAME))
|
|
{
|
|
if (StrLen(str) < (StrLen(VLAN_ADAPTER_NAME) + 3))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
StrCpy(name, size, str + StrLen(VLAN_ADAPTER_NAME) + 3);
|
|
|
|
return true;
|
|
}
|
|
|
|
if (StartWith(str, VLAN_ADAPTER_NAME_OLD))
|
|
{
|
|
if (StrLen(str) < (StrLen(VLAN_ADAPTER_NAME_OLD) + 3))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
StrCpy(name, size, str + StrLen(VLAN_ADAPTER_NAME_OLD) + 3);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Initialize the account list
|
|
void CmInitAccountList(HWND hWnd)
|
|
{
|
|
CmInitAccountListEx(hWnd, false);
|
|
}
|
|
void CmInitAccountListEx(HWND hWnd, bool easy)
|
|
{
|
|
UINT width[5];
|
|
BUF *b;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Read the setting
|
|
b = MsRegReadBin(REG_CURRENT_USER, CM_REG_KEY, "AccountListColumnWidth");
|
|
if ((b != NULL) && (b->Size == sizeof(width)))
|
|
{
|
|
Copy(width, b->Buf, sizeof(width));
|
|
}
|
|
else if ((b != NULL) && (b->Size == (sizeof(width) - sizeof(UINT))))
|
|
{
|
|
// Migrating from previous versions
|
|
Zero(width, sizeof(width));
|
|
Copy(width, b->Buf, sizeof(width) - sizeof(UINT));
|
|
width[4] = width[3];
|
|
width[3] = 0;
|
|
}
|
|
else
|
|
{
|
|
Zero(width, sizeof(width));
|
|
}
|
|
FreeBuf(b);
|
|
|
|
LvInitEx2(hWnd, L_ACCOUNT, false, easy);
|
|
|
|
// LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_TRACKSELECT);
|
|
|
|
// Initialize the column
|
|
if (easy == false)
|
|
{
|
|
LvInsertColumn(hWnd, L_ACCOUNT, 0, _UU("CM_ACCOUNT_COLUMN_1"), width[0] == 0 ? 215 : width[0]);
|
|
LvInsertColumn(hWnd, L_ACCOUNT, 1, _UU("CM_ACCOUNT_COLUMN_2"), width[1] == 0 ? 80 : width[1]);
|
|
LvInsertColumn(hWnd, L_ACCOUNT, 2, _UU("CM_ACCOUNT_COLUMN_3"), width[2] == 0 ? 220 : width[2]);
|
|
LvInsertColumn(hWnd, L_ACCOUNT, 3, _UU("CM_ACCOUNT_COLUMN_3_2"), width[3] == 0 ? 90 : width[3]);
|
|
LvInsertColumn(hWnd, L_ACCOUNT, 4, _UU("CM_ACCOUNT_COLUMN_4"), (width[4] == 0 || width[4] == 250) ? 120 : width[4]);
|
|
}
|
|
else
|
|
{
|
|
LvInsertColumn(hWnd, L_ACCOUNT, 0, _UU("CM_ACCOUNT_COLUMN_1"), 345);
|
|
LvInsertColumn(hWnd, L_ACCOUNT, 1, _UU("CM_ACCOUNT_COLUMN_2"), 140);
|
|
LvInsertColumn(hWnd, L_ACCOUNT, 2, _UU("CM_ACCOUNT_COLUMN_3"), 0);
|
|
LvInsertColumn(hWnd, L_ACCOUNT, 3, _UU("CM_ACCOUNT_COLUMN_3_2"), 0);
|
|
LvInsertColumn(hWnd, L_ACCOUNT, 4, _UU("CM_ACCOUNT_COLUMN_4"), 0);
|
|
}
|
|
}
|
|
|
|
// Release the account list
|
|
void CmSaveAccountListPos(HWND hWnd)
|
|
{
|
|
UINT width[5];
|
|
UINT i;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (i = 0;i < 5;i++)
|
|
{
|
|
width[i] = LvGetColumnWidth(hWnd, L_ACCOUNT, i);
|
|
}
|
|
|
|
MsRegWriteBin(REG_CURRENT_USER, CM_REG_KEY, "AccountListColumnWidth", width, sizeof(width));
|
|
}
|
|
|
|
// Initialize the VLAN list
|
|
void CmInitVLanList(HWND hWnd)
|
|
{
|
|
UINT width[4];
|
|
BUF *b;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Read the setting
|
|
b = MsRegReadBin(REG_CURRENT_USER, CM_REG_KEY, "VLanListColumnWidth");
|
|
if ((b != NULL) && (b->Size == sizeof(width)))
|
|
{
|
|
Copy(width, b->Buf, sizeof(width));
|
|
}
|
|
else
|
|
{
|
|
Zero(width, sizeof(width));
|
|
}
|
|
FreeBuf(b);
|
|
|
|
LvInit(hWnd, L_VLAN);
|
|
|
|
// LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_TRACKSELECT);
|
|
|
|
// Initialize the column
|
|
LvInsertColumn(hWnd, L_VLAN, 0, _UU("CM_VLAN_COLUMN_1"), width[0] == 0 ? 310 : width[0]);
|
|
LvInsertColumn(hWnd, L_VLAN, 1, _UU("CM_VLAN_COLUMN_2"), width[1] == 0 ? 120 : width[1]);
|
|
LvInsertColumn(hWnd, L_VLAN, 2, _UU("CM_VLAN_COLUMN_3"), width[2] == 0 ? 175 : width[2]);
|
|
LvInsertColumn(hWnd, L_VLAN, 3, _UU("CM_VLAN_COLUMN_4"), width[3] == 0 ? 120 : width[3]);
|
|
}
|
|
|
|
// Release the VLAN list
|
|
void CmSaveVLanListPos(HWND hWnd)
|
|
{
|
|
UINT width[4];
|
|
UINT i;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (i = 0;i < 4;i++)
|
|
{
|
|
width[i] = LvGetColumnWidth(hWnd, L_VLAN, i);
|
|
}
|
|
|
|
MsRegWriteBin(REG_CURRENT_USER, CM_REG_KEY, "VLanListColumnWidth", width, sizeof(width));
|
|
}
|
|
|
|
// Update the account list
|
|
void CmRefreshAccountList(HWND hWnd)
|
|
{
|
|
CmRefreshAccountListEx(hWnd, false);
|
|
CmRefreshEasy();
|
|
}
|
|
void CmRefreshAccountListEx(HWND hWnd, bool easy)
|
|
{
|
|
CmRefreshAccountListEx2(hWnd, easy, false);
|
|
}
|
|
void CmRefreshAccountListEx2(HWND hWnd, bool easy, bool style_changed)
|
|
{
|
|
UINT num = 0;
|
|
RPC_CLIENT_ENUM_ACCOUNT a;
|
|
UINT num_connecting = 0, num_connected = 0;
|
|
wchar_t tmp[MAX_SIZE];
|
|
wchar_t new_inserted_item[MAX_ACCOUNT_NAME_LEN + 1];
|
|
bool select_new_inserted_item = true;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Switching of icon / detail view
|
|
LvSetView(hWnd, L_ACCOUNT, cm->IconView == false || easy);
|
|
|
|
// Show grid
|
|
if (cm->ShowGrid || easy)
|
|
{
|
|
LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_GRIDLINES);
|
|
}
|
|
else
|
|
{
|
|
LvRemoveStyle(hWnd, L_ACCOUNT, LVS_EX_GRIDLINES);
|
|
}
|
|
|
|
if (style_changed)
|
|
{
|
|
// Change the font
|
|
if (easy == false)
|
|
{
|
|
if (cm->VistaStyle)
|
|
{
|
|
SetFontMeiryo(hWnd, L_ACCOUNT, 9);
|
|
}
|
|
else
|
|
{
|
|
SetFontDefault(hWnd, L_ACCOUNT);
|
|
}
|
|
|
|
if (cm->VistaStyle && (cm->IconView == false))
|
|
{
|
|
LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_FULLROWSELECT);
|
|
}
|
|
else
|
|
{
|
|
LvRemoveStyle(hWnd, L_ACCOUNT, LVS_EX_FULLROWSELECT);
|
|
}
|
|
}
|
|
}
|
|
|
|
Zero(new_inserted_item, sizeof(new_inserted_item));
|
|
|
|
if (LvNum(hWnd, L_ACCOUNT) == 0)
|
|
{
|
|
select_new_inserted_item = false;
|
|
}
|
|
|
|
// Enumerate the account list
|
|
if (CALL(hWnd, CcEnumAccount(cm->Client, &a)))
|
|
{
|
|
UINT i;
|
|
LVB *b = LvInsertStart();
|
|
|
|
if (cm->CmSetting.LockMode == false && (easy == false))
|
|
{
|
|
// Creating a new connection
|
|
LvInsertAdd(b, ICO_NEW, NULL, 4, _UU("CM_NEW_ICON"), L"", L"", L"");
|
|
|
|
if (cm->Client->IsVgcSupported)
|
|
{
|
|
// VPN Gate
|
|
LvInsertAdd(b, ICO_RESEARCH, NULL, 4, _UU("CM_VGC_ICON"), L"", L"", L"");
|
|
}
|
|
else if (cm->Client->ShowVgcLink)
|
|
{
|
|
// VPN Gate Link
|
|
LvInsertAdd(b, ICO_INTERNET, NULL, 4, _UU("CM_VGC_LINK"), L"", L"", L"");
|
|
}
|
|
}
|
|
|
|
for (i = 0;i < a.NumItem;i++)
|
|
{
|
|
RPC_CLIENT_ENUM_ACCOUNT_ITEM *t = a.Items[i];
|
|
UINT icon;
|
|
wchar_t tmp[MAX_SIZE];
|
|
wchar_t tmp2[MAX_SIZE];
|
|
char tmp3[MAX_SIZE];
|
|
wchar_t tmp4[MAX_SIZE];
|
|
IP ip;
|
|
char ip_str[MAX_SIZE];
|
|
|
|
// Special treatment in the case of IPv6 address
|
|
if (StrToIP6(&ip, t->ServerName) && StartWith(t->ServerName, "[") == false)
|
|
{
|
|
Format(ip_str, sizeof(ip_str),
|
|
"[%s]", t->ServerName);
|
|
}
|
|
else
|
|
{
|
|
StrCpy(ip_str, sizeof(ip_str), t->ServerName);
|
|
}
|
|
|
|
// Determine the icon
|
|
if (t->Active == false)
|
|
{
|
|
if (t->StartupAccount == false)
|
|
{
|
|
icon = ICO_SERVER_OFFLINE;
|
|
}
|
|
else
|
|
{
|
|
icon = ICO_SERVER_OFFLINE_EX;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
num++;
|
|
if (t->StartupAccount == false)
|
|
{
|
|
icon = ICO_SERVER_ONLINE;
|
|
}
|
|
else
|
|
{
|
|
icon = ICO_SERVER_ONLINE_EX;
|
|
}
|
|
}
|
|
|
|
// Adding
|
|
if (easy == false)
|
|
{
|
|
//CmVLanNameToPrintName(tmp3, sizeof(tmp3), t->DeviceName);
|
|
StrCpy(tmp3, sizeof(tmp3), t->DeviceName);
|
|
StrToUni(tmp, sizeof(tmp), tmp3);
|
|
}
|
|
else
|
|
{
|
|
StrToUni(tmp, sizeof(tmp), t->DeviceName);
|
|
}
|
|
|
|
if (t->Port == 0 || cm->ShowPort == false)
|
|
{
|
|
// Port number is unknown
|
|
UniFormat(tmp2, sizeof(tmp2), L"%S (%s)", ip_str, CmGetProtocolName(t->ProxyType));
|
|
}
|
|
else
|
|
{
|
|
// Port number are also shown
|
|
UniFormat(tmp2, sizeof(tmp2), L"%S:%u (%s)", ip_str, t->Port, CmGetProtocolName(t->ProxyType));
|
|
}
|
|
|
|
if (LvSearchStr(hWnd, L_ACCOUNT, 0, t->AccountName) == INFINITE)
|
|
{
|
|
UniStrCpy(new_inserted_item, sizeof(new_inserted_item), t->AccountName);
|
|
}
|
|
|
|
// Virtual HUB name
|
|
StrToUni(tmp4, sizeof(tmp4), t->HubName);
|
|
|
|
if (easy == false)
|
|
{
|
|
LvInsertAdd(b, icon, (void *)t->StartupAccount, 5, t->AccountName,
|
|
t->Active == false ? _UU("CM_ACCOUNT_OFFLINE") :
|
|
(t->Connected ? _UU("CM_ACCOUNT_ONLINE") : _UU("CM_ACCOUNT_CONNECTING")),
|
|
tmp2, tmp4,
|
|
tmp);
|
|
}
|
|
else
|
|
{
|
|
LvInsertAdd(b, icon, (void *)t->StartupAccount, 5, t->AccountName,
|
|
t->Active == false ? _UU("CM_ACCOUNT_OFFLINE") :
|
|
(t->Connected ? _UU("CM_ACCOUNT_ONLINE") : _UU("CM_ACCOUNT_CONNECTING")),
|
|
tmp2, tmp4,
|
|
tmp);
|
|
}
|
|
|
|
if (t->Active)
|
|
{
|
|
if (t->Connected)
|
|
{
|
|
num_connected++;
|
|
}
|
|
else
|
|
{
|
|
num_connecting++;
|
|
}
|
|
}
|
|
}
|
|
|
|
LvInsertEnd(b, hWnd, L_ACCOUNT);
|
|
|
|
CiFreeClientEnumAccount(&a);
|
|
|
|
if (select_new_inserted_item)
|
|
{
|
|
if (UniStrLen(new_inserted_item) >= 1)
|
|
{
|
|
LvSelect(hWnd, L_ACCOUNT, INFINITE);
|
|
LvSelect(hWnd, L_ACCOUNT, LvSearchStr(hWnd, L_ACCOUNT, 0, new_inserted_item));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (easy == false)
|
|
{
|
|
// For voice guidance, detect new connection and connection lost
|
|
if (cm->UpdateConnectedNumFlag == false)
|
|
{
|
|
cm->UpdateConnectedNumFlag = true;
|
|
cm->OldConnectedNum = num;
|
|
}
|
|
else
|
|
{
|
|
if (cm->OldConnectedNum != num)
|
|
{
|
|
if (cm->OldConnectedNum < num)
|
|
{
|
|
CmVoice("connect");
|
|
}
|
|
else
|
|
{
|
|
CmVoice("disconnect");
|
|
|
|
if (cm->CmSetting.EasyMode && cm->PositiveDisconnectFlag == false)
|
|
{
|
|
CmShowEasy();
|
|
}
|
|
|
|
cm->PositiveDisconnectFlag = false;
|
|
}
|
|
cm->OldConnectedNum = num;
|
|
}
|
|
}
|
|
|
|
if (num_connecting == 0 && num_connected == 0)
|
|
{
|
|
// There is no connecting or connected account
|
|
UniStrCpy(tmp, sizeof(tmp), _UU("CM_TRAY_NOT_CONNECTED"));
|
|
}
|
|
else if (num_connected == 0)
|
|
{
|
|
// There is only connecting account
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_TRAY_CONNECTED_1"), num_connecting);
|
|
}
|
|
else if (num_connecting == 0)
|
|
{
|
|
// There is only connected account
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_TRAY_CONNECTED_2"), num_connected);
|
|
}
|
|
else
|
|
{
|
|
// There are both
|
|
UniFormat(tmp, sizeof(tmp), _UU("CM_TRAY_CONNECTED_0"), num_connected, num_connecting);
|
|
}
|
|
|
|
if (num_connecting == 0 && num_connected == 0)
|
|
{
|
|
cm->TrayAnimation = false;
|
|
cm->TraySpeedAnimation = false;
|
|
}
|
|
else
|
|
{
|
|
cm->TrayAnimation = true;
|
|
|
|
if (num_connecting == 0)
|
|
{
|
|
cm->TraySpeedAnimation = false;
|
|
}
|
|
else
|
|
{
|
|
cm->TraySpeedAnimation = true;
|
|
}
|
|
}
|
|
|
|
CmChangeTrayString(hWnd, tmp);
|
|
}
|
|
|
|
Refresh(hWnd);
|
|
|
|
//Updated the Jump List
|
|
CmUpdateJumpList(0);
|
|
}
|
|
|
|
// Updating the VLAN list
|
|
void CmRefreshVLanList(HWND hWnd)
|
|
{
|
|
CmRefreshVLanListEx(hWnd, false);
|
|
}
|
|
void CmRefreshVLanListEx(HWND hWnd, bool style_changed)
|
|
{
|
|
RPC_CLIENT_ENUM_VLAN e;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LvSetView(hWnd, L_VLAN, cm->IconView == false);
|
|
|
|
// Show grid
|
|
if (cm->ShowGrid)
|
|
{
|
|
LvSetStyle(hWnd, L_VLAN, LVS_EX_GRIDLINES);
|
|
}
|
|
else
|
|
{
|
|
LvRemoveStyle(hWnd, L_VLAN, LVS_EX_GRIDLINES);
|
|
}
|
|
|
|
if (style_changed)
|
|
{
|
|
// Change the font
|
|
if (cm->VistaStyle)
|
|
{
|
|
SetFontMeiryo(hWnd, L_VLAN, 9);
|
|
}
|
|
else
|
|
{
|
|
SetFontDefault(hWnd, L_VLAN);
|
|
}
|
|
|
|
if (cm->VistaStyle && (cm->IconView == false))
|
|
{
|
|
LvSetStyle(hWnd, L_VLAN, LVS_EX_FULLROWSELECT);
|
|
}
|
|
else
|
|
{
|
|
LvRemoveStyle(hWnd, L_VLAN, LVS_EX_FULLROWSELECT);
|
|
}
|
|
}
|
|
|
|
// Enumeration
|
|
Zero(&e, sizeof(e));
|
|
if (CALL(hWnd, CcEnumVLan(cm->Client, &e)))
|
|
{
|
|
LVB *b = LvInsertStart();
|
|
UINT i;
|
|
for (i = 0;i < e.NumItem;i++)
|
|
{
|
|
wchar_t name[MAX_SIZE];
|
|
wchar_t mac[MAX_SIZE];
|
|
wchar_t ver[MAX_SIZE];
|
|
char str[MAX_SIZE];
|
|
wchar_t *status;
|
|
RPC_CLIENT_ENUM_VLAN_ITEM *v = e.Items[i];
|
|
|
|
// Device name
|
|
CmVLanNameToPrintName(str, sizeof(str), v->DeviceName);
|
|
StrToUni(name, sizeof(name), str);
|
|
|
|
// Status
|
|
status = v->Enabled ? _UU("CM_VLAN_ENABLED") : _UU("CM_VLAN_DISABLED");
|
|
|
|
// MAC address
|
|
StrToUni(mac, sizeof(mac), v->MacAddress);
|
|
|
|
// Version
|
|
StrToUni(ver, sizeof(ver), v->Version);
|
|
|
|
LvInsertAdd(b, v->Enabled ? ICO_NIC_ONLINE : ICO_NIC_OFFLINE, NULL, 4,
|
|
name, status, mac, ver);
|
|
}
|
|
LvInsertEnd(b, hWnd, L_VLAN);
|
|
|
|
CiFreeClientEnumVLan(&e);
|
|
}
|
|
}
|
|
|
|
// Get a protocol name string
|
|
wchar_t *CmGetProtocolName(UINT n)
|
|
{
|
|
return GetProtocolName(n);
|
|
}
|
|
|
|
// Display update
|
|
void CmRefresh(HWND hWnd)
|
|
{
|
|
CmRefreshEx(hWnd, false);
|
|
}
|
|
void CmRefreshEx(HWND hWnd, bool style_changed)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Update size
|
|
CmMainWindowOnSize(hWnd);
|
|
|
|
// Updating the VLAN list
|
|
CmRefreshVLanListEx(hWnd, style_changed);
|
|
|
|
// Update the account list
|
|
CmRefreshAccountListEx2(hWnd, false, style_changed);
|
|
|
|
// Update the status bar
|
|
CmRefreshStatusBar(hWnd);
|
|
}
|
|
|
|
// Determine whether to check the specified menu item
|
|
bool CmIsChecked(UINT id)
|
|
{
|
|
switch (id)
|
|
{
|
|
case CMD_TRAYICON:
|
|
return cm->HideTrayIcon == false;
|
|
case CMD_STATUSBAR:
|
|
return cm->HideStatusBar == false;
|
|
case CMD_VISTASTYLE:
|
|
return cm->VistaStyle;
|
|
case CMD_ICON:
|
|
return cm->IconView;
|
|
case CMD_DETAIL:
|
|
return cm->IconView == false;
|
|
case CMD_GRID:
|
|
return cm->ShowGrid;
|
|
case CMD_VOIDE_NONE:
|
|
return cm->DisableVoice;
|
|
case CMD_SHOWPORT:
|
|
return cm->ShowPort;
|
|
case CMD_VOICE_NORMAL:
|
|
if (cm->DisableVoice)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return cm->VoiceId == VOICE_SSK;
|
|
}
|
|
case CMD_VOICE_ODD:
|
|
if (cm->DisableVoice)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return cm->VoiceId == VOICE_AHO;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// The menu popped-up
|
|
void CmMainWindowOnPopupMenu(HWND hWnd, HMENU hMenu, UINT pos)
|
|
{
|
|
UINT num_menu, i, id;
|
|
// Validate arguments
|
|
if (hWnd == NULL || hMenu == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
num_menu = GetMenuItemCount(hMenu);
|
|
for (i = 0;i < num_menu;i++)
|
|
{
|
|
id = GetMenuItemID(hMenu, i);
|
|
|
|
if (id != INFINITE)
|
|
{
|
|
bool enable_flag = CmIsEnabled(hWnd, id);
|
|
bool checked_flag = CmIsChecked(id);
|
|
bool bold_flag = CmIsBold(id);
|
|
MENUITEMINFO info;
|
|
|
|
Zero(&info, sizeof(info));
|
|
info.cbSize = sizeof(info);
|
|
info.fMask = MIIM_STATE;
|
|
info.fState = (enable_flag ? MFS_ENABLED : MFS_DISABLED) |
|
|
(checked_flag ? MFS_CHECKED : MFS_UNCHECKED) |
|
|
(bold_flag ? MFS_DEFAULT : 0);
|
|
|
|
if (id == CMD_ICON || id == CMD_DETAIL || id == CMD_VOIDE_NONE ||
|
|
id == CMD_VOICE_NORMAL || id == CMD_VOICE_ODD)
|
|
{
|
|
info.fMask |= MIIM_FTYPE;
|
|
info.fType = MFT_RADIOCHECK;
|
|
}
|
|
|
|
SetMenuItemInfo(hMenu, id, false, &info);
|
|
}
|
|
|
|
if (id == CMD_RECENT)
|
|
{
|
|
HMENU sub = CmCreateRecentSubMenu(hWnd, CM_TRAY_MENU_RECENT_ID_START);
|
|
|
|
if (sub != NULL)
|
|
{
|
|
DeleteMenu(hMenu, i, MF_BYPOSITION);
|
|
MsInsertMenu(hMenu, i, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,
|
|
(UINT_PTR)sub, _UU("CM_TRAY_MENU_RECENT"));
|
|
}
|
|
else
|
|
{
|
|
MENUITEMINFO info;
|
|
|
|
Zero(&info, sizeof(info));
|
|
info.cbSize = sizeof(info);
|
|
info.fMask = MIIM_STATE;
|
|
info.fState = MFS_DISABLED;
|
|
|
|
SetMenuItemInfo(hMenu, id, false, &info);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set the main window title
|
|
wchar_t *CmGenerateMainWindowTitle()
|
|
{
|
|
wchar_t tmp[MAX_SIZE];
|
|
if (cm->server_name == NULL)
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), L"%s", _UU("CM_TITLE"));
|
|
}
|
|
else
|
|
{
|
|
UniFormat(tmp, sizeof(tmp), L"%s - %S", _UU("CM_TITLE"), cm->server_name);
|
|
}
|
|
|
|
return CopyUniStr(tmp);
|
|
}
|
|
|
|
// Initialize the task tray
|
|
void CmInitTray(HWND hWnd)
|
|
{
|
|
bool ret;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (cm->server_name != NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (cm->TrayInited)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ret = MsShowIconOnTray(hWnd, LoadSmallIcon(CmGetTrayIconId(false, 0)), _UU("CM_TRAY_INITING"), WM_CM_TRAY_MESSAGE);
|
|
|
|
cm->TrayInited = true;
|
|
cm->TrayAnimation = false;
|
|
cm->TraySucceed = ret;
|
|
|
|
SetTimer(hWnd, 2, CM_TRAY_ANIMATION_INTERVAL / 4, NULL);
|
|
}
|
|
|
|
// Change the string in the task tray
|
|
void CmChangeTrayString(HWND hWnd, wchar_t *str)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL || str == NULL)
|
|
{
|
|
return;
|
|
}
|
|
if (cm->TrayInited == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
MsChangeIconOnTray(NULL, str);
|
|
}
|
|
|
|
// Release the task tray
|
|
void CmFreeTray(HWND hWnd)
|
|
{
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (cm->TrayInited == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
MsHideIconOnTray();
|
|
|
|
cm->TrayInited = false;
|
|
}
|
|
void CmFreeTrayExternal(void *hWnd)
|
|
{
|
|
CmFreeTray((HWND)hWnd);
|
|
}
|
|
|
|
// Periodical processing to the task tray
|
|
void CmPollingTray(HWND hWnd)
|
|
{
|
|
UINT interval;
|
|
bool ret;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (cm->TrayInited == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ret = MsChangeIconOnTrayEx(LoadSmallIcon(CmGetTrayIconId(cm->TrayAnimation, cm->TrayAnimationCounter)),
|
|
NULL, NULL, NULL, NIIF_NONE, !cm->TraySucceed);
|
|
|
|
if (cm->TraySucceed == false)
|
|
{
|
|
cm->TraySucceed = ret;
|
|
}
|
|
|
|
cm->TrayAnimationCounter++;
|
|
|
|
KillTimer(hWnd, 2);
|
|
interval = CM_TRAY_ANIMATION_INTERVAL / 4;
|
|
if (cm->TraySpeedAnimation)
|
|
{
|
|
interval /= 4;
|
|
}
|
|
SetTimer(hWnd, 2, interval, NULL);
|
|
}
|
|
|
|
// Get the icon ID of the task tray for animation
|
|
UINT CmGetTrayIconId(bool animation, UINT animation_counter)
|
|
{
|
|
if (animation == false)
|
|
{
|
|
return ICO_TRAY0;
|
|
}
|
|
else
|
|
{
|
|
switch (animation_counter % 4)
|
|
{
|
|
case 0:
|
|
return ICO_TRAY1;
|
|
|
|
case 1:
|
|
return ICO_TRAY2;
|
|
|
|
case 2:
|
|
return ICO_TRAY3;
|
|
|
|
default:
|
|
return ICO_TRAY4;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Initialize the main window
|
|
void CmMainWindowOnInit(HWND hWnd)
|
|
{
|
|
wchar_t *s;
|
|
BUF *b;
|
|
bool startup_mode = cm->StartupMode;
|
|
CM_SETTING a;
|
|
bool fake = false;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Font settings of list
|
|
SetFontMeiryo(hWnd, L_ACCOUNT, 9);
|
|
SetFontMeiryo(hWnd, L_VLAN, 9);
|
|
|
|
// Get the configuration of the current vpnclient
|
|
Zero(&a, sizeof(a));
|
|
CcGetCmSetting(cm->Client, &a);
|
|
|
|
if (a.EasyMode)
|
|
{
|
|
fake = true;
|
|
}
|
|
|
|
InitMenuInternational(GetMenu(hWnd), "CM_MENU");
|
|
|
|
cm->HideStatusBar = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "HideStatusBar");
|
|
cm->HideTrayIcon = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "HideTrayIcon");
|
|
cm->IconView = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "IconView");
|
|
cm->ShowGrid = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "ShowGrid");
|
|
|
|
if (MsRegIsValue(REG_CURRENT_USER, CM_REG_KEY, "VistaStyle"))
|
|
{
|
|
cm->VistaStyle = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "VistaStyle");
|
|
}
|
|
else
|
|
{
|
|
cm->VistaStyle = MsIsVista();
|
|
}
|
|
|
|
if (MsRegIsValue(REG_CURRENT_USER, CM_REG_KEY, "ShowPort"))
|
|
{
|
|
cm->ShowPort = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "ShowPort");
|
|
}
|
|
else
|
|
{
|
|
cm->ShowPort = false;
|
|
}
|
|
|
|
if (MsRegIsValue(REG_CURRENT_USER, CM_REG_KEY, "DisableVoice"))
|
|
{
|
|
cm->DisableVoice = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "DisableVoice");
|
|
}
|
|
else
|
|
{
|
|
cm->DisableVoice = true;
|
|
}
|
|
cm->VoiceId = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "VoiceId");
|
|
|
|
cm->StatusWindowList = NewList(NULL);
|
|
|
|
SetIcon(hWnd, 0, ICO_VPN);
|
|
|
|
s = CmGenerateMainWindowTitle();
|
|
SetText(hWnd, 0, s);
|
|
Free(s);
|
|
|
|
// Initialize the window position
|
|
b = MsRegReadBin(REG_CURRENT_USER, CM_REG_KEY, "WindowPlacement");
|
|
if (b != NULL && b->Size == sizeof(WINDOWPLACEMENT))
|
|
{
|
|
// Restore the window position
|
|
WINDOWPLACEMENT *p;
|
|
p = ZeroMalloc(b->Size);
|
|
Copy(p, b->Buf, b->Size);
|
|
|
|
if (startup_mode)
|
|
{
|
|
p->showCmd = SW_SHOWMINIMIZED;
|
|
}
|
|
|
|
if (fake)
|
|
{
|
|
Copy(&cm->FakeWindowPlacement, p, sizeof(WINDOWPLACEMENT));
|
|
}
|
|
else
|
|
{
|
|
SetWindowPlacement(hWnd, p);
|
|
}
|
|
Free(p);
|
|
}
|
|
else
|
|
{
|
|
// Initialize the window position
|
|
SetWindowPos(hWnd, NULL, 0, 0, CM_DEFAULT_WIDTH, CM_DEFAULT_HEIGHT, SWP_NOREDRAW);
|
|
Center(hWnd);
|
|
if (startup_mode)
|
|
{
|
|
ShowWindow(hWnd, SW_SHOWMINIMIZED);
|
|
}
|
|
|
|
if (fake)
|
|
{
|
|
WINDOWPLACEMENT p;
|
|
|
|
Zero(&p, sizeof(p));
|
|
p.length = sizeof(p);
|
|
GetWindowPlacement(hWnd, &p);
|
|
Copy(&cm->FakeWindowPlacement, &p, sizeof(WINDOWPLACEMENT));
|
|
}
|
|
}
|
|
FreeBuf(b);
|
|
|
|
if (fake)
|
|
{
|
|
SetWindowPos(hWnd, NULL, -200, -200, 100, 100,
|
|
SWP_NOREDRAW | SWP_SHOWWINDOW);
|
|
}
|
|
|
|
// Initialize the status bar related items
|
|
cm->hMainWnd = hWnd;
|
|
cm->hStatusBar = CreateStatusWindowW(WS_CHILD |
|
|
(cm->HideStatusBar == false ? WS_VISIBLE : 0),
|
|
_UU("CM_TITLE"),
|
|
hWnd, S_STATUSBAR);
|
|
|
|
UniStrCpy(cm->StatudBar1, sizeof(cm->StatudBar1), _UU("CM_TITLE"));
|
|
UniStrCpy(cm->StatudBar2, sizeof(cm->StatudBar2), _UU("CM_CONN_NO"));
|
|
UniFormat(cm->StatudBar3, sizeof(cm->StatudBar3), _UU("CM_PRODUCT_NAME"), CEDAR_BUILD);
|
|
|
|
cm->Icon2 = LoadSmallIcon(ICO_SERVER_OFFLINE);
|
|
cm->Icon3 = LoadSmallIcon(ICO_VPN);
|
|
|
|
// Initialize the account list
|
|
CmInitAccountList(hWnd);
|
|
|
|
// Initialize the VLAN list
|
|
CmInitVLanList(hWnd);
|
|
|
|
// Display update
|
|
CmRefreshEx(hWnd, true);
|
|
|
|
// Start a thread of notification client
|
|
CmInitNotifyClientThread();
|
|
|
|
// Timer setting
|
|
SetTimer(hWnd, 1, 128, NULL);
|
|
SetTimer(hWnd, 6, 5000, NULL);
|
|
|
|
// Initialize the task tray
|
|
if (cm->server_name == NULL)
|
|
{
|
|
if (cm->HideTrayIcon == false)
|
|
{
|
|
CmInitTray(hWnd);
|
|
}
|
|
}
|
|
|
|
CmVoice("start");
|
|
|
|
if (startup_mode || a.EasyMode)
|
|
{
|
|
SetTimer(hWnd, 3, 1, NULL);
|
|
}
|
|
|
|
if (cm->import_file_name != NULL)
|
|
{
|
|
// Import a file specified as an argument
|
|
CmSendImportMessage(hWnd, cm->import_file_name, cm->CmSettingInitialFlag == CM_SETTING_INIT_NONE ? CM_IMPORT_FILENAME_MSG : CM_IMPORT_FILENAME_MSG_OVERWRITE);
|
|
/*if (a.LockMode == false)
|
|
{
|
|
CmImportAccountMainEx(hWnd, cm->import_file_name, cm->CmSettingInitialFlag != CM_SETTING_INIT_NONE);
|
|
}
|
|
else
|
|
{
|
|
MsgBox(cm->hEasyWnd ? cm->hEasyWnd : hWnd, MB_ICONEXCLAMATION, _UU("CM_VPN_FILE_IMPORT_NG"));
|
|
}*/
|
|
}
|
|
|
|
// Apply the CM_SETTING
|
|
CmApplyCmSetting();
|
|
|
|
cm->StartupFinished = true;
|
|
}
|
|
|
|
// Start a thread of notification client
|
|
void CmInitNotifyClientThread()
|
|
{
|
|
cm->NotifyClient = CcConnectNotify(cm->Client);
|
|
if (cm->NotifyClient == false)
|
|
{
|
|
Close(cm->hMainWnd);
|
|
exit(0);
|
|
}
|
|
cm->NotifyClientThread = NewThread(CmNotifyClientThread, NULL);
|
|
}
|
|
|
|
// Notification client thread
|
|
void CmNotifyClientThread(THREAD *thread, void *param)
|
|
{
|
|
NOTIFY_CLIENT *nc;
|
|
// Validate arguments
|
|
if (thread == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
nc = cm->NotifyClient;
|
|
|
|
// Wait for the next notification
|
|
while (cm->Halt == false)
|
|
{
|
|
if (CcWaitNotify(nc))
|
|
{
|
|
// Send a message
|
|
PostMessage(cm->hMainWnd, WM_CM_NOTIFY, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
// Disconnected
|
|
if (cm->Halt == false)
|
|
{
|
|
if (cm != NULL)
|
|
{
|
|
CmFreeTrayExternal((void *)cm->hMainWnd);
|
|
}
|
|
CncExit();
|
|
exit(0);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Stop the thread of the notification client
|
|
void CmFreeNotifyClientThread()
|
|
{
|
|
cm->Halt = true;
|
|
|
|
// Disconnect
|
|
CcStopNotify(cm->NotifyClient);
|
|
|
|
// Wait for the termination of the thread
|
|
WaitThread(cm->NotifyClientThread, INFINITE);
|
|
|
|
// Connection termination
|
|
CcDisconnectNotify(cm->NotifyClient);
|
|
ReleaseThread(cm->NotifyClientThread);
|
|
}
|
|
|
|
// Resize the main window
|
|
void CmMainWindowOnSize(HWND hWnd)
|
|
{
|
|
RECT r;
|
|
UINT client_width, client_height;
|
|
UINT status_height;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the size of the client area of the main window
|
|
GetClientRect(hWnd, &r);
|
|
client_width = MAX(r.right - r.left, 0);
|
|
client_height = MAX(r.bottom - r.top, 0);
|
|
|
|
SendMsg(hWnd, S_STATUSBAR, WM_SIZE, 0, 0);
|
|
|
|
// Get the size of the status bar
|
|
GetWindowRect(DlgItem(hWnd, S_STATUSBAR), &r);
|
|
status_height = MAX(r.bottom - r.top, 0);
|
|
|
|
if (cm->HideStatusBar == false)
|
|
{
|
|
client_height = MAX(client_height - status_height, 0);
|
|
}
|
|
|
|
MoveWindow(DlgItem(hWnd, L_ACCOUNT), 0, 0, client_width, client_height * 3 / 5 - 3, true);
|
|
MoveWindow(DlgItem(hWnd, L_VLAN), 0, client_height * 3 / 5, client_width, client_height * 2 / 5, true);
|
|
|
|
// Re-draw the status bar
|
|
CmRedrawStatusBar(hWnd);
|
|
}
|
|
|
|
// Disconnect all accounts currently connected
|
|
void CmDisconnectAll(HWND hWnd)
|
|
{
|
|
UINT i, num;
|
|
LIST *o;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Display a warning
|
|
num = CmGetNumConnected(hWnd);
|
|
if (num == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (MsgBoxEx(hWnd, MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DISCONNECT_ALL"), num) == IDNO)
|
|
{
|
|
return;
|
|
}
|
|
|
|
cm->PositiveDisconnectFlag = true;
|
|
|
|
// Create a list of connected items
|
|
o = NewListFast(NULL);
|
|
|
|
num = LvNum(hWnd, L_ACCOUNT);
|
|
for (i = 0;i < num;i++)
|
|
{
|
|
wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, i, 1);
|
|
if (s != NULL)
|
|
{
|
|
if (UniStrCmpi(s, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(s, _UU("CM_ACCOUNT_CONNECTING")) == 0)
|
|
{
|
|
Add(o, LvGetStr(hWnd, L_ACCOUNT, i, 0));
|
|
}
|
|
Free(s);
|
|
}
|
|
}
|
|
|
|
for (i = 0;i < LIST_NUM(o);i++)
|
|
{
|
|
wchar_t *s = LIST_DATA(o, i);
|
|
if (s != NULL)
|
|
{
|
|
CmDisconnect(hWnd, s);
|
|
Free(s);
|
|
}
|
|
}
|
|
|
|
ReleaseList(o);
|
|
}
|
|
|
|
// Get a number of currently connected connection settings
|
|
UINT CmGetNumConnected(HWND hWnd)
|
|
{
|
|
UINT i, num, num_active;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
num_active = 0;
|
|
num = LvNum(hWnd, L_ACCOUNT);
|
|
for (i = 0;i < num;i++)
|
|
{
|
|
wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, i, 1);
|
|
if (s != NULL)
|
|
{
|
|
if (UniStrCmpi(s, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(s, _UU("CM_ACCOUNT_CONNECTING")) == 0)
|
|
{
|
|
num_active++;
|
|
}
|
|
Free(s);
|
|
}
|
|
}
|
|
|
|
return num_active;
|
|
}
|
|
|
|
// Update the status bar information
|
|
void CmRefreshStatusBar(HWND hWnd)
|
|
{
|
|
UINT num_active = CmGetNumConnected(hWnd);
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (num_active == 0)
|
|
{
|
|
UniStrCpy(cm->StatudBar2, sizeof(cm->StatudBar2), _UU("CM_CONN_NO"));
|
|
cm->Icon2 = LoadSmallIcon(ICO_SERVER_OFFLINE);
|
|
}
|
|
else
|
|
{
|
|
UniFormat(cm->StatudBar2, sizeof(cm->StatudBar2), _UU("CM_NUM_CONN_COUNT"), num_active);
|
|
cm->Icon2 = LoadSmallIcon(ICO_SERVER_ONLINE);
|
|
}
|
|
|
|
CmRedrawStatusBar(hWnd);
|
|
}
|
|
|
|
// Re-draw the status bar
|
|
void CmRedrawStatusBar(HWND hWnd)
|
|
{
|
|
HWND h;
|
|
RECT r;
|
|
int width;
|
|
int x1, x2, x3;
|
|
int xx[3];
|
|
wchar_t tmp[MAX_SIZE];
|
|
HICON icon;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
h = cm->hStatusBar;
|
|
|
|
// Get the width of the status bar
|
|
GetWindowRect(h, &r);
|
|
width = MAX(r.right - r.left, 0);
|
|
x2 = (UINT)(180.0 * GetTextScalingFactor());
|
|
x3 = (UINT)(245.0 * GetTextScalingFactor());
|
|
x1 = MAX(width - x2 - x3, 0);
|
|
|
|
// Divide into three parts
|
|
xx[0] = x1;
|
|
xx[1] = x2 + x1;
|
|
xx[2] = x3 + x2 + x1;
|
|
SendMsg(h, 0, SB_SETPARTS, 3, (LPARAM)xx);
|
|
|
|
// Set an icon
|
|
icon = (HICON)SendMsg(h, 0, SB_GETICON, 1, 0);
|
|
if (icon != cm->Icon2)
|
|
{
|
|
SendMsg(h, 0, SB_SETICON, 1, (LPARAM)cm->Icon2);
|
|
}
|
|
|
|
icon = (HICON)SendMsg(h, 0, SB_GETICON, 2, 0);
|
|
if (icon != cm->Icon3)
|
|
{
|
|
SendMsg(h, 0, SB_SETICON, 2, (LPARAM)cm->Icon3);
|
|
}
|
|
|
|
// Set a string
|
|
SendMsg(h, 0, SB_GETTEXTW, 0, (LPARAM)tmp);
|
|
if (UniStrCmp(tmp, cm->StatudBar1))
|
|
{
|
|
SendMsg(h, 0, SB_SETTEXTW, 0, (LPARAM)cm->StatudBar1);
|
|
}
|
|
|
|
SendMsg(h, 0, SB_GETTEXTW, 1, (LPARAM)tmp);
|
|
if (UniStrCmp(tmp, cm->StatudBar2))
|
|
{
|
|
SendMsg(h, 0, SB_SETTEXTW, 1, (LPARAM)cm->StatudBar2);
|
|
}
|
|
|
|
SendMsg(h, 0, SB_GETTEXTW, 2, (LPARAM)tmp);
|
|
if (UniStrCmp(tmp, cm->StatudBar3))
|
|
{
|
|
SendMsg(h, 0, SB_SETTEXTW, 2, (LPARAM)cm->StatudBar3);
|
|
}
|
|
}
|
|
|
|
// Save the position information of the main window
|
|
void CmSaveMainWindowPos(HWND hWnd)
|
|
{
|
|
WINDOWPLACEMENT p;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Save settings
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "HideStatusBar", cm->HideStatusBar);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "HideTrayIcon", cm->HideTrayIcon);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "IconView", cm->IconView);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "ShowGrid", cm->ShowGrid);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "DisableVoice", cm->DisableVoice);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "VoiceId", cm->VoiceId);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "VistaStyle", cm->VistaStyle);
|
|
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "ShowPort", cm->ShowPort);
|
|
|
|
// Save the window position
|
|
Zero(&p, sizeof(p));
|
|
p.length = sizeof(p);
|
|
GetWindowPlacement(hWnd, &p);
|
|
|
|
if (IsZero(&cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement)) == false)
|
|
{
|
|
Copy(&p, &cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement));
|
|
}
|
|
|
|
MsRegWriteBin(REG_CURRENT_USER, CM_REG_KEY, "WindowPlacement", &p, sizeof(p));
|
|
|
|
CmSaveAccountListPos(hWnd);
|
|
CmSaveVLanListPos(hWnd);
|
|
}
|
|
|
|
// Close the main window
|
|
void CmMainWindowOnQuit(HWND hWnd)
|
|
{
|
|
UINT i;
|
|
// Validate arguments
|
|
if (hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (cm->TrayInited)
|
|
{
|
|
if (MsgBox(hWnd, MB_YESNO | MB_ICONQUESTION,
|
|
_UU("CM_EXIT_MESSAGE")) == IDNO)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (cm->OnCloseDispatched)
|
|
{
|
|
return;
|
|
}
|
|
cm->OnCloseDispatched = true;
|
|
|
|
CmCloseEasy();
|
|
|
|
// Release the tray icon
|
|
CmFreeTray(hWnd);
|
|
|
|
// Save the position information of the main window
|
|
CmSaveMainWindowPos(hWnd);
|
|
|
|
// Close the status window
|
|
for (i = 0;i < LIST_NUM(cm->StatusWindowList);i++)
|
|
{
|
|
HWND h = LIST_DATA(cm->StatusWindowList, i);
|
|
//EndDialog(h, 0);
|
|
PostMessage(h, WM_CLOSE, 0, 0);
|
|
}
|
|
|
|
ReleaseList(cm->StatusWindowList);
|
|
cm->StatusWindowList = NULL;
|
|
|
|
if (cm->WindowCount != 0)
|
|
{
|
|
// Abort
|
|
exit(0);
|
|
}
|
|
|
|
// Close
|
|
CmFreeNotifyClientThread();
|
|
|
|
EndDialog(hWnd, false);
|
|
}
|
|
|
|
// Start the mutex to be used in starting
|
|
bool CmStartStartupMutex()
|
|
{
|
|
INSTANCE *o = NewSingleInstance(STARTUP_MUTEX_NAME);
|
|
|
|
if (o == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
cm->StartupMutex = o;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Release the mutex to be used in starting
|
|
void CmEndStartupMutex()
|
|
{
|
|
if (cm->StartupMutex != NULL)
|
|
{
|
|
FreeSingleInstance(cm->StartupMutex);
|
|
|
|
cm->StartupMutex = NULL;
|
|
}
|
|
}
|
|
|
|
// Main window
|
|
void MainCMWindow()
|
|
{
|
|
HWND h;
|
|
wchar_t *s;
|
|
CM_SETTING a;
|
|
|
|
if (CmStartStartupMutex() == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
s = CmGenerateMainWindowTitle();
|
|
h = SearchWindow(s);
|
|
Free(s);
|
|
|
|
Zero(&a, sizeof(a));
|
|
CcGetCmSetting(cm->Client, &a);
|
|
if (cm->server_name != NULL && a.EasyMode)
|
|
{
|
|
CmEndStartupMutex();
|
|
MsgBox(NULL, MB_ICONEXCLAMATION, _UU("CM_EASY_MODE_NOT_ON_REMOTE"));
|
|
return;
|
|
}
|
|
|
|
// Change the operating mode
|
|
if (cm->CmSettingSupported)
|
|
{
|
|
if (cm->CmSettingInitialFlag == CM_SETTING_INIT_SELECT)
|
|
{
|
|
if (h != NULL)
|
|
{
|
|
CmEndStartupMutex();
|
|
}
|
|
|
|
// Show the selection screen
|
|
CmSetting(NULL);
|
|
|
|
if (h != NULL)
|
|
{
|
|
goto SEND_MESSAGES;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else if ((cm->CmSettingInitialFlag == CM_SETTING_INIT_EASY && cm->CmEasyModeSupported) || cm->CmSettingInitialFlag == CM_SETTING_INIT_NORMAL)
|
|
{
|
|
// State transition
|
|
CM_SETTING a;
|
|
|
|
Zero(&a, sizeof(a));
|
|
CcGetCmSetting(cm->Client, &a);
|
|
|
|
if (cm->CmSettingInitialFlag == CM_SETTING_INIT_EASY)
|
|
{
|
|
a.EasyMode = true;
|
|
}
|
|
else
|
|
{
|
|
a.EasyMode = false;
|
|
}
|
|
|
|
CcSetCmSetting(cm->Client, &a);
|
|
}
|
|
}
|
|
|
|
if (h == NULL)
|
|
{
|
|
// Create a window because there is no window of the same title
|
|
if (cm->server_name == NULL)
|
|
{
|
|
CmInitTryToExecUiHelper();
|
|
|
|
if (IsDebug() == false)
|
|
{
|
|
CnWaitForCnServiceReady();
|
|
}
|
|
}
|
|
Dialog(NULL, D_CM_MAIN, CmMainWindowProc, NULL);
|
|
CmFreeTryToExecUiHelper();
|
|
}
|
|
else
|
|
{
|
|
SEND_MESSAGES:
|
|
CmEndStartupMutex();
|
|
|
|
// If a window of the same title already exists, activate it and exit itself
|
|
SetForegroundWindow(h);
|
|
SendMessage(h, WM_CM_SHOW, 0, 0);
|
|
SetForegroundWindow(h);
|
|
|
|
if (cm->CmSettingInitialFlag != CM_SETTING_INIT_NONE && cm->CmSettingInitialFlag != CM_SETTING_INIT_CONNECT)
|
|
{
|
|
// Notify since CM_SETTING has been changed
|
|
SendMessage(h, WM_CM_SETTING_CHANGED_MESSAGE, 0, 0);
|
|
}
|
|
|
|
if (cm->import_file_name != NULL)
|
|
{
|
|
UINT msg;
|
|
if (cm->CmSettingInitialFlag == CM_SETTING_INIT_NONE)
|
|
{
|
|
msg = CM_IMPORT_FILENAME_MSG;
|
|
}
|
|
else
|
|
{
|
|
msg = CM_IMPORT_FILENAME_MSG_OVERWRITE;
|
|
}
|
|
|
|
CmSendImportMessage(h, cm->import_file_name, msg);
|
|
}
|
|
}
|
|
|
|
CmEndStartupMutex();
|
|
}
|
|
|
|
// Send an import message
|
|
void CmSendImportMessage(HWND hWnd, wchar_t *filename, UINT msg)
|
|
{
|
|
COPYDATASTRUCT cpy;
|
|
// Validate arguments
|
|
if (hWnd == NULL || filename == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Specify the file to be imported
|
|
Zero(&cpy, sizeof(cpy));
|
|
|
|
cpy.cbData = UniStrSize(filename);
|
|
cpy.lpData = filename;
|
|
cpy.dwData = msg;
|
|
|
|
SendMessage(hWnd, WM_COPYDATA, 0, (LPARAM)&cpy);
|
|
}
|
|
|
|
// Login dialog
|
|
UINT CmLoginDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
|
|
{
|
|
// Validate arguments
|
|
wchar_t server_name[MAX_SIZE];
|
|
char password[MAX_PASSWORD_LEN + 1];
|
|
bool bad_pass;
|
|
if (hWnd == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
if (cm->server_name != NULL)
|
|
{
|
|
StrToUni(server_name, sizeof(server_name), cm->server_name);
|
|
}
|
|
else
|
|
{
|
|
UniStrCpy(server_name, sizeof(server_name), _UU("CM_PW_LOCALMACHINE"));
|
|
}
|
|
FormatText(hWnd, S_TITLE, server_name);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
if (cm->server_name != NULL)
|
|
{
|
|
StrToUni(server_name, sizeof(server_name), cm->server_name);
|
|
}
|
|
else
|
|
{
|
|
UniStrCpy(server_name, sizeof(server_name), _UU("CM_PW_LOCALMACHINE"));
|
|
}
|
|
GetTxtA(hWnd, E_PASSWORD, password, sizeof(password));
|
|
cm->Client = CcConnectRpc(cm->server_name == NULL ? "127.0.0.1" : cm->server_name,
|
|
password, &bad_pass, NULL, 0);
|
|
if (cm->Client == NULL)
|
|
{
|
|
MsgBox(hWnd, MB_ICONSTOP, _UU("CM_BAD_PASSWORD"));
|
|
FocusEx(hWnd, E_PASSWORD);
|
|
}
|
|
else
|
|
{
|
|
EndDialog(hWnd, true);
|
|
}
|
|
break;
|
|
case IDCANCEL:
|
|
Close(hWnd);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
EndDialog(hWnd, false);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Login
|
|
bool LoginCM()
|
|
{
|
|
// Try to login with an empty password first
|
|
bool bad_pass, no_remote;
|
|
wchar_t server_name[MAX_SIZE];
|
|
RPC_CLIENT_VERSION a;
|
|
|
|
RETRY:
|
|
if (cm->server_name != NULL)
|
|
{
|
|
StrToUni(server_name, sizeof(server_name), cm->server_name);
|
|
}
|
|
else
|
|
{
|
|
UniStrCpy(server_name, sizeof(server_name), _UU("CM_PW_LOCALMACHINE"));
|
|
}
|
|
|
|
// Attempt to connect
|
|
if ((cm->Client = CcConnectRpc(
|
|
cm->server_name == NULL ? "localhost" : cm->server_name,
|
|
cm->password == NULL ? "" : cm->password, &bad_pass, &no_remote, cm->StartupMode == false ? 0 : 60000)) == NULL)
|
|
{
|
|
if (no_remote)
|
|
{
|
|
// Remote connection was denied
|
|
if (MsgBoxEx(NULL, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("CM_NO_REMOTE"), server_name) == IDRETRY)
|
|
{
|
|
// Retry
|
|
goto RETRY;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if (bad_pass)
|
|
{
|
|
if (Dialog(NULL, D_CM_LOGIN, CmLoginDlgProc, NULL) == false)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Connection failure
|
|
if (cm->StartupMode == false && MsgBoxEx(NULL, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("CM_CONNECT_FAILED"), server_name) == IDRETRY)
|
|
{
|
|
// Retry
|
|
goto RETRY;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
Zero(&a, sizeof(a));
|
|
CcGetClientVersion(cm->Client, &a);
|
|
if (a.ClientBuildInt >= 5192)
|
|
{
|
|
cm->CmSettingSupported = true;
|
|
cm->CmEasyModeSupported = true;
|
|
if (OS_IS_WINDOWS_9X(a.OsType))
|
|
{
|
|
cm->CmEasyModeSupported = false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Main process
|
|
void MainCM()
|
|
{
|
|
// If there is /remote in the argument, show the screen of the remote connection
|
|
TOKEN_LIST *cmdline = GetCommandLineToken();
|
|
|
|
UINT i = 0;
|
|
bool isRemote = false;
|
|
|
|
if (cm->server_name != NULL)
|
|
{
|
|
Free(cm->server_name);
|
|
}
|
|
cm->server_name = NULL;
|
|
|
|
if (cm->password != NULL)
|
|
{
|
|
Free(cm->password);
|
|
}
|
|
cm->password = NULL;
|
|
|
|
for(i = 0; i < cmdline->NumTokens; ++i)
|
|
{
|
|
if (StrCmpi(cmdline->Token[i], "/remote") == 0)
|
|
{
|
|
isRemote = true;
|
|
}
|
|
else if (StrCmpi(cmdline->Token[i], "/hostname") == 0 && i + 1 < cmdline->NumTokens)
|
|
{
|
|
isRemote = true;
|
|
if (cm->server_name != NULL)
|
|
{
|
|
Free(cm->server_name);
|
|
}
|
|
cm->server_name = CopyStr(cmdline->Token[++i]);
|
|
}
|
|
else if (StrCmpi(cmdline->Token[i], "/password") == 0 && i + 1 < cmdline->NumTokens)
|
|
{
|
|
if (cm->password != NULL)
|
|
{
|
|
Free(cm->password);
|
|
}
|
|
cm->password = CopyStr(cmdline->Token[++i]);
|
|
}
|
|
else if (StrCmpi(cmdline->Token[i], "/startup") == 0)
|
|
{
|
|
// Startup mode
|
|
cm->StartupMode = true;
|
|
}
|
|
}
|
|
|
|
if (isRemote && cm->server_name == NULL)
|
|
{
|
|
char *hostname = RemoteDlg(NULL, CM_REG_KEY, ICO_VPN, _UU("CM_TITLE"), _UU("CM_REMOTE_TITLE"), NULL);
|
|
if (hostname == NULL)
|
|
{
|
|
return;
|
|
}
|
|
if (cm->server_name != NULL)
|
|
{
|
|
Free(cm->server_name);
|
|
}
|
|
cm->server_name = NULL;
|
|
if (StrCmpi(hostname, "localhost") != 0 && StrCmpi(hostname, "127.0.0.1") != 0 )
|
|
{
|
|
cm->server_name = hostname;
|
|
}
|
|
}
|
|
|
|
FreeToken(cmdline);
|
|
|
|
if (IsZero(cm->ShortcutKey, SHA1_SIZE) == false)
|
|
{
|
|
//if (MsGetCurrentTerminalSessionId() == 0)
|
|
{
|
|
// Start the shortcut connection
|
|
CmConnectShortcut(cm->ShortcutKey);
|
|
}/*
|
|
else
|
|
{
|
|
MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("CM_SHORTCUT_DESKTOP_MSG"),
|
|
MsGetCurrentTerminalSessionId());
|
|
}*/
|
|
return;
|
|
}
|
|
|
|
// Login
|
|
if (LoginCM() == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//Update the jump list
|
|
CmUpdateJumpList(0);
|
|
|
|
// Main window
|
|
MainCMWindow();
|
|
|
|
// Log out
|
|
LogoutCM();
|
|
|
|
if (cm->Update != NULL)
|
|
{
|
|
FreeUpdateUi(cm->Update);
|
|
cm->Update = NULL;
|
|
}
|
|
}
|
|
|
|
// Log out
|
|
void LogoutCM()
|
|
{
|
|
if (cm->Client != NULL)
|
|
{
|
|
CcDisconnectRpc(cm->Client);
|
|
}
|
|
}
|
|
|
|
// Client Connection Manager start function
|
|
void CMExec()
|
|
{
|
|
// Initialize
|
|
InitCM(true);
|
|
|
|
// Main process
|
|
MainCM();
|
|
|
|
// Release
|
|
FreeCM();
|
|
}
|
|
|
|
// HUB enumeration thread
|
|
void CmEnumHubThread(THREAD *t, void *param)
|
|
{
|
|
CM_ENUM_HUB *e = (CM_ENUM_HUB *)param;
|
|
HWND hWnd;
|
|
// Validate arguments
|
|
if (t == NULL || param == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
e->Thread = t;
|
|
hWnd = e->hWnd;
|
|
LockList(cm->EnumHubList);
|
|
{
|
|
Add(cm->EnumHubList, e);
|
|
}
|
|
UnlockList(cm->EnumHubList);
|
|
|
|
// Thread initialization is completed
|
|
NoticeThreadInit(t);
|
|
|
|
// Create a session
|
|
e->Session = NewRpcSession(cm->Cedar, e->ClientOption);
|
|
if (e->Session)
|
|
{
|
|
// Enumeration of HUB
|
|
e->Hub = EnumHub(e->Session);
|
|
|
|
if (e->Hub != NULL)
|
|
{
|
|
// Enumeration completed
|
|
// Add to the combo box
|
|
if (CbNum(hWnd, C_HUBNAME) == 0)
|
|
{
|
|
UINT i;
|
|
wchar_t tmp[MAX_SIZE];
|
|
for (i = 0;i < e->Hub->NumTokens;i++)
|
|
{
|
|
StrToUni(tmp, sizeof(tmp), e->Hub->Token[i]);
|
|
CbAddStr(hWnd, C_HUBNAME, tmp, 0);
|
|
}
|
|
}
|
|
|
|
// Release the memory
|
|
FreeToken(e->Hub);
|
|
}
|
|
|
|
// Release the session
|
|
ReleaseSession(e->Session);
|
|
}
|
|
|
|
LockList(cm->EnumHubList);
|
|
{
|
|
Delete(cm->EnumHubList, e);
|
|
}
|
|
UnlockList(cm->EnumHubList);
|
|
|
|
Free(e->ClientOption);
|
|
Free(e);
|
|
}
|
|
|
|
// The start of the HUB enumeration
|
|
void CmEnumHubStart(HWND hWnd, CLIENT_OPTION *o)
|
|
{
|
|
CM_ENUM_HUB *e;
|
|
THREAD *t;
|
|
// Validate arguments
|
|
if (hWnd == NULL || o == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (StrLen(o->Hostname) == 0 ||
|
|
o->Port == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (o->ProxyType != PROXY_DIRECT)
|
|
{
|
|
if (StrLen(o->ProxyName) == 0 ||
|
|
o->ProxyPort == 0)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (LvNum(hWnd, C_HUBNAME) != 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
e = ZeroMalloc(sizeof(CM_ENUM_HUB));
|
|
e->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
|
|
e->hWnd = hWnd;
|
|
Copy(e->ClientOption, o, sizeof(CLIENT_OPTION));
|
|
|
|
t = NewThread(CmEnumHubThread, e);
|
|
WaitThreadInit(t);
|
|
ReleaseThread(t);
|
|
}
|
|
|
|
// Initialize the HUB enumeration process
|
|
void CmInitEnumHub()
|
|
{
|
|
cm->EnumHubList = NewList(NULL);
|
|
}
|
|
|
|
// Release the HUB enumeration process
|
|
void CmFreeEnumHub()
|
|
{
|
|
LIST *o;
|
|
UINT i;
|
|
if (cm->EnumHubList == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
o = NewList(NULL);
|
|
LockList(cm->EnumHubList);
|
|
{
|
|
UINT i;
|
|
for (i = 0;i < LIST_NUM(cm->EnumHubList);i++)
|
|
{
|
|
CM_ENUM_HUB *e = LIST_DATA(cm->EnumHubList, i);
|
|
Add(o, e->Thread);
|
|
AddRef(e->Thread->ref);
|
|
}
|
|
}
|
|
UnlockList(cm->EnumHubList);
|
|
|
|
for (i = 0;i < LIST_NUM(o);i++)
|
|
{
|
|
THREAD *t = LIST_DATA(o, i);
|
|
WaitThread(t, INFINITE);
|
|
ReleaseThread(t);
|
|
}
|
|
ReleaseList(o);
|
|
|
|
ReleaseList(cm->EnumHubList);
|
|
}
|
|
|
|
// Initialize the Client Connection Manager
|
|
|
|
void InitCM(bool set_app_id)
|
|
{
|
|
UNI_TOKEN_LIST *ut;
|
|
if (cm != NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (set_app_id)
|
|
{
|
|
if(JL_SetCurrentProcessExplicitAppUserModelID(APPID_CM) != S_OK)
|
|
{
|
|
}
|
|
}
|
|
|
|
CmDeleteOldStartupTrayFile();
|
|
|
|
MsSetShutdownParameters(0x4ff, SHUTDOWN_NORETRY);
|
|
|
|
// Memory allocation
|
|
cm = ZeroMalloc(sizeof(CM));
|
|
|
|
// If the command line argument is set treat it as a server name
|
|
ut = GetCommandLineUniToken();
|
|
|
|
if (ut->NumTokens >= 1)
|
|
{
|
|
if (UniStrLen(ut->Token[0]) != 0)
|
|
{
|
|
if (UniStrCmpi(ut->Token[0], L"cm") != 0 && ut->Token[0][0] != L'/')
|
|
{
|
|
BUF *b = UniStrToBin(ut->Token[0]);
|
|
if (b->Size == SHA1_SIZE)
|
|
{
|
|
// Treated as a shortcut key for the connection settings
|
|
Copy(cm->ShortcutKey, b->Buf, SHA1_SIZE);
|
|
}
|
|
else
|
|
{
|
|
if (UniEndWith(ut->Token[0], L".vpn") == false)
|
|
{
|
|
// Treated as a server name
|
|
cm->server_name = CopyUniToStr(ut->Token[0]);
|
|
}
|
|
else
|
|
{
|
|
// Treated as import file name
|
|
cm->import_file_name = CopyUniStr(ut->Token[0]);
|
|
}
|
|
}
|
|
FreeBuf(b);
|
|
}
|
|
else if (UniStrCmpi(ut->Token[0], L"/easy") == 0)
|
|
{
|
|
// Simple mode
|
|
if (ut->NumTokens >= 2)
|
|
{
|
|
// Connection settings to be imported is specified
|
|
cm->import_file_name = CopyUniStr(ut->Token[1]);
|
|
}
|
|
|
|
cm->CmSettingInitialFlag = CM_SETTING_INIT_EASY;
|
|
}
|
|
else if (UniStrCmpi(ut->Token[0], L"/normal") == 0)
|
|
{
|
|
// Normal mode
|
|
if (ut->NumTokens >= 2)
|
|
{
|
|
// Connection settings to be imported is specified
|
|
cm->import_file_name = CopyUniStr(ut->Token[1]);
|
|
}
|
|
|
|
cm->CmSettingInitialFlag = CM_SETTING_INIT_NORMAL;
|
|
}
|
|
else if (UniStrCmpi(ut->Token[0], L"/connect") == 0)
|
|
{
|
|
// Import process by the simple installer
|
|
if (ut->NumTokens >= 2)
|
|
{
|
|
// Connection settings to be imported is specified
|
|
cm->import_file_name = CopyUniStr(ut->Token[1]);
|
|
}
|
|
|
|
cm->CmSettingInitialFlag = CM_SETTING_INIT_CONNECT;
|
|
}
|
|
else if (UniStrCmpi(ut->Token[0], L"/select") == 0)
|
|
{
|
|
// Selection screen
|
|
cm->CmSettingInitialFlag = CM_SETTING_INIT_SELECT;
|
|
}
|
|
}
|
|
}
|
|
|
|
UniFreeToken(ut);
|
|
|
|
InitWinUi(_UU("CM_TITLE"), _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE"));
|
|
|
|
// Alpha blending related
|
|
UseAlpha = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "UseAlpha");
|
|
AlphaValue = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "AlphaValue");
|
|
|
|
cm->Cedar = NewCedar(NULL, NULL);
|
|
CmInitEnumHub();
|
|
}
|
|
|
|
// Stop the Client Connection Manager
|
|
void FreeCM()
|
|
{
|
|
if (cm == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CmFreeEnumHub();
|
|
ReleaseCedar(cm->Cedar);
|
|
|
|
FreeWinUi();
|
|
|
|
// Release the memory
|
|
if (cm->server_name != NULL)
|
|
{
|
|
Free(cm->server_name);
|
|
}
|
|
Free(cm);
|
|
cm = NULL;
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//JumpList ToDo
|
|
// By Takao Ito
|
|
void *CmUpdateJumpList(UINT start_id)
|
|
{
|
|
HMENU h = NULL;
|
|
UINT i;
|
|
RPC_CLIENT_ENUM_ACCOUNT a;
|
|
LIST *o;
|
|
bool easy;
|
|
|
|
JL_PCustomDestinationList pcdl;
|
|
JL_PObjectCollection poc;
|
|
JL_PShellLink shell;
|
|
JL_PObjectArray poaRemoved;
|
|
|
|
HRESULT hr;
|
|
|
|
if (cm->server_name != NULL)
|
|
{
|
|
// Is not used in the case of an external PC
|
|
return NULL;
|
|
}
|
|
|
|
//Try to add
|
|
if(SUCCEEDED(JL_CreateCustomDestinationList(&pcdl,APPID_CM)))
|
|
{
|
|
|
|
JL_DeleteJumpList(pcdl,APPID_CM);
|
|
|
|
easy = cm->CmSetting.EasyMode;
|
|
|
|
Zero(&a, sizeof(a));
|
|
|
|
|
|
if (CcEnumAccount(cm->Client, &a) == ERR_NO_ERROR)
|
|
{
|
|
o = NewListFast(CiCompareClientAccountEnumItemByLastConnectDateTime);
|
|
|
|
for (i = 0;i < a.NumItem;i++)
|
|
{
|
|
RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = a.Items[i];
|
|
|
|
item->tmp1 = i;
|
|
|
|
if (item->LastConnectDateTime != 0)
|
|
{
|
|
Add(o, item);
|
|
}
|
|
}
|
|
|
|
Sort(o);
|
|
|
|
if(LIST_NUM(o) > 0)
|
|
{
|
|
|
|
if(SUCCEEDED(JL_BeginList(pcdl, &poaRemoved)))
|
|
{
|
|
|
|
|
|
//Create a collection
|
|
if(SUCCEEDED(JL_CreateObjectCollection(&poc)))
|
|
{
|
|
|
|
for (i = 0;i < MIN(LIST_NUM(o), CM_NUM_RECENT);i++)
|
|
{
|
|
|
|
RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = (RPC_CLIENT_ENUM_ACCOUNT_ITEM *)LIST_DATA(o, i);
|
|
// wchar_t tmp[MAX_PATH];
|
|
wchar_t *account_name;
|
|
char *server_name;
|
|
char *hub_name;
|
|
// CM_ACCOUNT *a;
|
|
UCHAR key[SHA1_SIZE];
|
|
RPC_CLIENT_GET_ACCOUNT c;
|
|
|
|
|
|
account_name = item->AccountName;
|
|
server_name = item->ServerName;
|
|
hub_name = item->HubName;
|
|
|
|
|
|
|
|
//
|
|
//a = CmGetExistAccountObject(hWnd, account_name);
|
|
|
|
|
|
//if (a == NULL)
|
|
//{
|
|
//continue;
|
|
//}
|
|
|
|
//Copy(key, a->ShortcutKey, SHA1_SIZE);
|
|
//
|
|
|
|
Zero(&c, sizeof(c));
|
|
UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);
|
|
if (CALL(NULL, CcGetAccount(cm->Client, &c)) == false)
|
|
{
|
|
break;
|
|
}
|
|
|
|
Copy(key, c.ShortcutKey, SHA1_SIZE);
|
|
|
|
if (IsZero(key, SHA1_SIZE))
|
|
{
|
|
//MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_SHORTCUT_UNSUPPORTED"));
|
|
}
|
|
else
|
|
{
|
|
|
|
//wchar_t target[MAX_PATH];
|
|
////wchar_t workdir[MAX_PATH];
|
|
//wchar_t args[MAX_PATH];
|
|
////wchar_t comment[MAX_SIZE];
|
|
//wchar_t icon[MAX_PATH];
|
|
|
|
char key_str[64];
|
|
wchar_t target[MAX_PATH];
|
|
//wchar_t workdir[MAX_PATH];
|
|
wchar_t args[MAX_PATH];
|
|
wchar_t commentW[MAX_SIZE];
|
|
wchar_t icon[MAX_PATH];
|
|
int iconNum;
|
|
|
|
//char icon = "C:\\Server.ico";
|
|
|
|
BinToStr(key_str, sizeof(key_str), key, SHA1_SIZE);
|
|
UniStrCpy(target, sizeof(target), MsGetExeFileNameW());
|
|
StrToUni(args, sizeof(args), key_str);
|
|
UniStrCpy(icon, sizeof(icon), MsGetExeFileNameW());
|
|
UniFormat(commentW, sizeof(commentW), _UU("CM_SHORTCUT_COMMENT"), account_name);
|
|
|
|
if(item->Connected)
|
|
{
|
|
iconNum = 1;
|
|
}
|
|
else
|
|
{
|
|
iconNum = 2;
|
|
}
|
|
|
|
hr = JL_CreateShellLink(
|
|
target,
|
|
args,
|
|
account_name,
|
|
icon,iconNum,
|
|
commentW,
|
|
&shell);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
|
|
if(SUCCEEDED(JL_ObjectCollectionAddShellLink(poc, shell)))
|
|
{
|
|
//Print("Add JumpList %d c:%s\n",i, comment);
|
|
//wprintf(comment);
|
|
}
|
|
JL_ReleaseShellLink(shell);
|
|
}
|
|
}
|
|
|
|
CiFreeClientGetAccount(&c);
|
|
}
|
|
|
|
hr = JL_AddCategoryToList(pcdl,poc,_UU("CM_JUMPLIST_RCCONNECT"),poaRemoved);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
//wprintf(L"AddCategory\n");
|
|
|
|
hr = JL_CommitList(pcdl);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
//wprintf(L"JumpList Commit\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//wprintf(L"Erro JumpList AddCategory %x\n", hr);
|
|
}
|
|
|
|
//Release
|
|
JL_ReleaseObjectCollection(poc);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
ReleaseList(o);
|
|
|
|
CiFreeClientEnumAccount(&a);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
JL_BeginList(pcdl, &poaRemoved);
|
|
|
|
JL_CreateObjectCollection(&poc);
|
|
|
|
// Tesht
|
|
for (i = 0; i < 5; i++)
|
|
{
|
|
|
|
JL_CreateShellLink(
|
|
"",
|
|
"",
|
|
L"Connect",
|
|
NULL,0,
|
|
NULL,
|
|
&shell);
|
|
JL_ObjectCollectionAddShellLink(poc, shell);
|
|
|
|
JL_ReleaseShellLink(shell);
|
|
|
|
}
|
|
|
|
JL_AddCategoryToList(pcdl,poc,_UU("CM_JUMPLIST_RCCONNECT"),poaRemoved);
|
|
JL_CommitList(pcdl);
|
|
JL_ReleaseObjectCollection(poc);
|
|
|
|
JL_ReleaseCustomDestinationList(pcdl);
|
|
*/
|
|
|
|
}
|
|
|
|
return h;
|
|
}
|
|
|
|
|
|
|
|
#endif // WIN32
|
|
|
|
|