1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-07 10:10:41 +03:00
SoftEtherVPN/src/Cedar/CM.c
Joshua Perry 28e8d4bcce Retry connection on untrusted server certificate
With server certificate validation enabled, vpnclient unconditionally
stopped connection on untrusted server certificate. Added account
configuration parameter to retry connection if server certivicate failed
validation.
2018-08-05 20:48:16 +02:00

12542 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
#define SECURITY_WIN32
#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 <security.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, &current_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.RetryOnServerCert = a->RetryOnServerCert;
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;
t->RetryOnServerCert = get.RetryOnServerCert;
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.RetryOnServerCert = a->RetryOnServerCert;
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->RetryOnServerCert = c.RetryOnServerCert;
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->RetryOnServerCert = 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