softether-vpn/src/Cedar/CM.c

12529 lines
263 KiB
C

// SoftEther VPN Source Code - Stable Edition Repository
// Cedar Communication Module
//
// SoftEther VPN Server, Client and Bridge are free software under GPLv2.
//
// Copyright (c) Daiyuu Nobori.
// Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
// Copyright (c) SoftEther Corporation.
//
// All Rights Reserved.
//
// http://www.softether.org/
//
// Author: Daiyuu Nobori, Ph.D.
// Contributors:
// - ELIN (https://github.com/el1n)
// Comments: Tetsuo Sugiyama, Ph.D.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// version 2 as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License version 2
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
//
//
// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
//
// USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS
// YOU HAVE A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY
// CRIMINAL LAWS OR CIVIL RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS
// SOFTWARE IN OTHER COUNTRIES IS COMPLETELY AT YOUR OWN RISK. THE
// SOFTETHER VPN PROJECT HAS DEVELOPED AND DISTRIBUTED THIS SOFTWARE TO
// COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING CIVIL RIGHTS INCLUDING
// PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER COUNTRIES' LAWS OR
// CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES. WE HAVE
// NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
// INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+
// COUNTRIES AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE
// WORLD, WITH DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY
// COUNTRIES' LAWS, REGULATIONS AND CIVIL RIGHTS TO MAKE THE SOFTWARE
// COMPLY WITH ALL COUNTRIES' LAWS BY THE PROJECT. EVEN IF YOU WILL BE
// SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A PUBLIC SERVANT IN YOUR
// COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE LIABLE TO
// RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
// RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT
// JUST A STATEMENT FOR WARNING AND DISCLAIMER.
//
//
// SOURCE CODE CONTRIBUTION
// ------------------------
//
// Your contribution to SoftEther VPN Project is much appreciated.
// Please send patches to us through GitHub.
// Read the SoftEther VPN Patch Acceptance Policy in advance:
// http://www.softether.org/5-download/src/9.patch
//
//
// DEAR SECURITY EXPERTS
// ---------------------
//
// If you find a bug or a security vulnerability please kindly inform us
// about the problem immediately so that we can fix the security problem
// to protect a lot of users around the world as soon as possible.
//
// Our e-mail address for security reports is:
// softether-vpn-security [at] softether.org
//
// Please note that the above e-mail address is not a technical support
// inquiry address. If you need technical assistance, please visit
// http://www.softether.org/ and ask your question on the users forum.
//
// Thank you for your cooperation.
//
//
// NO MEMORY OR RESOURCE LEAKS
// ---------------------------
//
// The memory-leaks and resource-leaks verification under the stress
// test has been passed before release this source code.
// CM.c
// VPN Client Connection Manager for Win32
#include <GlobalConst.h>
#ifdef WIN32
#define CM_C
#define SM_C
#define MICROSOFT_C
#define _WIN32_WINNT 0x0502
#define WINVER 0x0502
#include <winsock2.h>
#include <windows.h>
#include <Iphlpapi.h>
#include <tlhelp32.h>
#include <shlobj.h>
#include <commctrl.h>
#include <Dbghelp.h>
#include <setupapi.h>
#include <regstr.h>
#include <process.h>
#include <psapi.h>
#include <wtsapi32.h>
#include <Ntsecapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <stdarg.h>
#include <time.h>
#include <errno.h>
#include <Mayaqua/Mayaqua.h>
#include <Cedar/Cedar.h>
#include "CMInner.h"
#include "SMInner.h"
#include "NMInner.h"
#include "EMInner.h"
#include "../PenCore/resource.h"
// Get the proxy server settings from the registry string of IE
bool CmGetProxyServerNameAndPortFromIeProxyRegStr(char *name, UINT name_size, UINT *port, char *str, char *server_type)
{
TOKEN_LIST *t;
UINT i;
bool ret = false;
// Validate arguments
if (name == NULL || port == NULL || str == NULL || server_type == NULL)
{
return false;
}
t = ParseToken(str, ";");
for (i = 0;i < t->NumTokens;i++)
{
char *s = t->Token[i];
UINT i;
Trim(s);
i = SearchStrEx(s, "=", 0, false);
if (i != INFINITE)
{
char tmp[MAX_PATH];
StrCpy(name, name_size, s);
name[i] = 0;
if (StrCmpi(name, server_type) == 0)
{
char *host;
StrCpy(tmp, sizeof(tmp), s + i + 1);
if (ParseHostPort(tmp, &host, port, 0))
{
StrCpy(name, name_size, host);
Free(host);
if (*port != 0)
{
ret = true;
}
break;
}
}
}
}
FreeToken(t);
return ret;
}
// Reflect the contents of the proxy settings to the connection settings
void CmProxyDlgSet(HWND hWnd, CLIENT_OPTION *o, CM_INTERNET_SETTING *setting)
{
// Validate arguments
if(hWnd == NULL || setting == NULL)
{
return;
}
// Make check in check-box
Check(hWnd, R_DIRECT_TCP, setting->ProxyType == PROXY_DIRECT);
Check(hWnd, R_HTTPS, setting->ProxyType == PROXY_HTTP);
Check(hWnd, R_SOCKS, setting->ProxyType == PROXY_SOCKS);
// Proxy Settings
if(setting->ProxyType != PROXY_DIRECT)
{
StrCpy(o->ProxyName, sizeof(setting->ProxyHostName), setting->ProxyHostName);
o->ProxyPort = setting->ProxyPort;
}
}
// Get the proxy settings of IE
void CmGetSystemInternetSetting(CM_INTERNET_SETTING *setting)
{
bool use_proxy;
// Validate arguments
if (setting == NULL)
{
return;
}
Zero(setting, sizeof(CM_INTERNET_SETTING));
use_proxy = MsRegReadInt(REG_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"ProxyEnable");
if (use_proxy)
{
char *str = MsRegReadStr(REG_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"ProxyServer");
if (str != NULL)
{
char name[MAX_HOST_NAME_LEN + 1];
UINT port;
if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),
&port, str, "https"))
{
setting->ProxyType = PROXY_HTTP;
StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);
setting->ProxyPort = port;
}
else if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),
&port, str, "http"))
{
setting->ProxyType = PROXY_HTTP;
StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);
setting->ProxyPort = port;
}
else if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),
&port, str, "socks"))
{
setting->ProxyType = PROXY_SOCKS;
StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);
setting->ProxyPort = port;
}
else
{
if (SearchStrEx(str, "=", 0, false) == INFINITE)
{
char *host;
UINT port;
if (ParseHostPort(str, &host, &port, 0))
{
if (port != 0)
{
setting->ProxyType = PROXY_HTTP;
StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), host);
setting->ProxyPort = port;
}
Free(host);
}
}
}
Free(str);
}
}
}
// For the proxy settings to go through, use the IE settings
void CmProxyDlgUseForIE(HWND hWnd, CLIENT_OPTION *o)
{
CM_INTERNET_SETTING s;
// Validate arguments
if(hWnd == NULL)
{
return;
}
Zero(&s, sizeof(s));
CmGetSystemInternetSetting(&s);
CmProxyDlgSet(hWnd, o, &s);
}
// Determine the bitmap ID of the smart card authentication screen
UINT CmGetSecureBitmapId(char *dest_hostname)
{
// Validate arguments
if (dest_hostname == NULL)
{
return 0;
}
if (EndWith(dest_hostname, ".cc.tsukuba.ac.jp"))
{
return BMP_TSUKUBA;
}
return 0;
}
// Activate the window of UAC
void CmSetUacWindowActive()
{
HWND hWnd;
if (MsIsVista() == false)
{
return;
}
hWnd = FindWindowA("$$$Secure UAP Dummy Window Class For Interim Dialog", NULL);
if (hWnd == NULL)
{
return;
}
SwitchToThisWindow(hWnd, true);
}
// UAC helper thread
void CmUacHelperThread(THREAD *thread, void *param)
{
CM_UAC_HELPER *c = (CM_UAC_HELPER *)param;
// Validate arguments
if (c == NULL)
{
return;
}
while (c->Halt == false)
{
CmSetUacWindowActive();
Wait(c->HaltEvent, 200);
}
}
// Start the UAC helper
void *CmStartUacHelper()
{
CM_UAC_HELPER *c = ZeroMalloc(sizeof(CM_UAC_HELPER));
c->HaltEvent = NewEvent();
c->Thread = NewThread(CmUacHelperThread, c);
return (void *)c;
}
// Stop the UAC helper
void CmStopUacHelper(void *p)
{
CM_UAC_HELPER *c = (CM_UAC_HELPER *)p;
// Validate arguments
if (c == NULL)
{
return;
}
c->Halt = true;
Set(c->HaltEvent);
WaitThread(c->Thread, INFINITE);
ReleaseEvent(c->HaltEvent);
ReleaseThread(c->Thread);
Free(c);
}
// Command invocation of the simple connection manager
void CmEasyDlgOnCommand(HWND hWnd, CM_EASY_DLG *d, WPARAM wParam, LPARAM lParam)
{
// Validate arguments
if (hWnd == NULL || d == NULL)
{
return;
}
switch (wParam)
{
case B_MODE:
Command(hWnd, CMD_CM_SETTING);
return;
case B_STATUS:
Command(hWnd, CMD_STATUS);
return;
case IDCANCEL:
Close(hWnd);
return;
}
if (wParam == CMD_CONNECT)
{
cm->ConnectStartedFlag = false;
}
CmMainWindowOnCommandEx(hWnd, wParam, lParam, true);
if (wParam == CMD_CONNECT && cm->ConnectStartedFlag)
{
// Close the window when the connection started successfully
Close(hWnd);
}
}
// Keyboard pressing of the simple connection manager
void CmEasyDlgOnKey(HWND hWnd, CM_EASY_DLG *d, bool ctrl, bool alt, UINT key)
{
// Validate arguments
if (hWnd == NULL)
{
return;
}
// Single key
switch (key)
{
case VK_RETURN:
Command(hWnd, IDOK);
break;
case VK_DELETE:
// Delete
if (IsFocus(hWnd, L_ACCOUNT))
{
// Operation on the account list
Command(hWnd, CMD_DELETE);
}
else
{
// Operation on the virtual LAN card list
Command(hWnd, CMD_DELETE_VLAN);
}
break;
case VK_F2:
// Change the name
Command(hWnd, CMD_RENAME);
break;
case VK_F5:
// Update the status
Command(hWnd, CMD_REFRESH);
break;
}
if (alt)
{
switch (key)
{
case 'Q':
// Close
Command(hWnd, CMD_QUIT);
break;
}
}
if (ctrl)
{
switch (key)
{
case 'G':
// Smart Card Manager
Command(hWnd, CMD_SECURE_MANAGER);
break;
case 'S':
// Show the status
Command(hWnd, CMD_STATUS);
break;
case 'I':
// Disconnect all connections
Command(hWnd, CMD_DISCONNECT_ALL);
break;
case 'D':
// Disconnect
Command(hWnd, CMD_DISCONNECT);
break;
case 'N':
// Create a new connection setting
Command(hWnd, CMD_NEW);
break;
case 'C':
// Creating a copy
Command(hWnd, CMD_CLONE);
break;
case 'T':
// Set to start-up connection
Command(hWnd, CMD_STARTUP);
break;
case 'A':
// Select all
Command(hWnd, CMD_SELECT_ALL);
break;
case 'L':
// Create a new virtual LAN card
Command(hWnd, CMD_NEW_VLAN);
break;
case 'P':
// Set the password
Command(hWnd, CMD_PASSWORD);
break;
case 'O':
// Option settings
Command(hWnd, CMD_TRAFFIC);
break;
case 'R':
// Certificate management
Command(hWnd, CMD_TRUST);
break;
case 'Q':
// Throughput
Command(hWnd, CMD_TRAFFIC);
break;
}
}
}
// Operation on the list view of the simple connection manager
void CmEasyDlgOnNotify(HWND hWnd, CM_EASY_DLG *d, NMHDR *n)
{
NMLVDISPINFOW *disp_info;
NMLVKEYDOWN *key;
// Validate arguments
if (hWnd == NULL || n == NULL)
{
return;
}
switch (n->idFrom)
{
case L_ACCOUNT:
switch (n->code)
{
case LVN_ITEMCHANGED:
CmEasyDlgUpdate(hWnd, d);
break;
case NM_DBLCLK:
// Double click
Command(hWnd, CMD_EASY_DBLCLICK);
break;
case NM_RCLICK:
// Right click
CmAccountListRightClick(hWnd);
break;
case LVN_ENDLABELEDITW:
// Change the name
disp_info = (NMLVDISPINFOW *)n;
if (disp_info->item.pszText != NULL)
{
wchar_t *new_name = disp_info->item.pszText;
wchar_t *old_name = LvGetStr(hWnd, L_ACCOUNT, disp_info->item.iItem, 0);
if (old_name != NULL)
{
if (UniStrCmp(new_name, old_name) != 0 && UniIsEmptyStr(new_name) == false)
{
RPC_RENAME_ACCOUNT a;
Zero(&a, sizeof(a));
UniStrCpy(a.OldName, sizeof(a.OldName), old_name);
UniStrCpy(a.NewName, sizeof(a.NewName), new_name);
if (CALL(hWnd, CcRenameAccount(cm->Client, &a)))
{
LvSetItem(hWnd, L_ACCOUNT, disp_info->item.iItem, 0, new_name);
}
}
Free(old_name);
}
}
break;
case LVN_KEYDOWN:
// Key-press
key = (NMLVKEYDOWN *)n;
if (key != NULL)
{
bool ctrl, alt;
UINT code = key->wVKey;
ctrl = (GetKeyState(VK_CONTROL) & 0x8000) == 0 ? false : true;
alt = (GetKeyState(VK_MENU) & 0x8000) == 0 ? false : true;
CmEasyDlgOnKey(hWnd, d, ctrl, alt, code);
}
break;
}
break;
}
}
// Send an update notification to the Simple Connection Manager
void CmRefreshEasy()
{
if (cm->hEasyWnd == NULL)
{
return;
}
SendMessage(cm->hEasyWnd, WM_CM_EASY_REFRESH, 0, 0);
}
// Initialze 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->MenuPopuping)
{
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->MenuPopuping = 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->MenuPopuping = 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;
}
index = LvGetSelected(hWnd, L_VLAN);
if (index != INFINITE)
{
wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);
if (s != NULL)
{
RPC_CLIENT_CREATE_VLAN c;
char str[MAX_SIZE];
Zero(&c, sizeof(c));
UniToStr(str, sizeof(str), s);
if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))
{
void *helper = NULL;
if (MsIsVista() == false)
{
ShowWindow(hWnd, SW_SHOWMINIMIZED);
}
if (MsIsVista())
{
helper = CmStartUacHelper();
}
CALL(hWnd, CcUpgradeVLan(cm->Client, &c));
CmStopUacHelper(helper);
if (MsIsVista() == false)
{
ShowWindow(hWnd, SW_SHOWNORMAL);
}
}
Free(s);
}
}
break;
case CMD_PASSWORD:
// Password setting
CmPassword(hWnd);
break;
case CMD_OPTION:
// Option
CmConfigDlg(hWnd);
break;
case CMD_LANGUAGE:
// Language settings
if (true)
{
wchar_t path[MAX_SIZE];
CombinePathW(path, sizeof(path), MsGetExeDirNameW(), L"vpnsetup.exe");
if (MsExecuteW(path, L"/language:yes") == false)
{
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SW_CHILD_PROCESS_ERROR"));
}
}
break;
case CMD_TRUST:
// Certificate management
CmTrustDlg(hWnd);
break;
case CMD_ABOUT:
// Version information
if (IsEnable(hWnd, 0))
{
AboutEx(hWnd, cm->Cedar, _UU("PRODUCT_NAME_VPN_CMGR"), cm->Update);
}
break;
case CMD_VOIDE_NONE:
cm->DisableVoice = true;
break;
case CMD_VOICE_NORMAL:
cm->DisableVoice = false;
cm->VoiceId = VOICE_SSK;
break;
case CMD_VOICE_ODD:
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("CM_EXT_VOICE_MSG")) == IDYES)
{
cm->DisableVoice = false;
cm->VoiceId = VOICE_AHO;
}
break;
case CMD_SECURE_MANAGER:
// Smart Card Manager
CmClientSecureManager(hWnd);
break;
case CMD_SECURE_SELECT:
// Select a smart card
CmClientSelectSecure(hWnd);
break;
case CMD_NETIF:
// State of the network device
if (IsEnable(hWnd, 0))
{
UtSpeedMeterEx(hWnd);
}
break;
case CMD_MMCSS:
// Optimization utility for Windows Vista
if (MsIsVista() == false)
{
MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_4"));
}
else
{
if (MsIsAdmin() == false)
{
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("VISTA_MMCSS_MSG_4"));
}
else
{
if (MsIsMMCSSNetworkThrottlingEnabled())
{
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("VISTA_MMCSS_MSG")) == IDYES)
{
MsSetMMCSSNetworkThrottlingEnable(false);
MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_5"));
}
}
else
{
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("VISTA_MMCSS_MSG_2")) == IDYES)
{
MsSetMMCSSNetworkThrottlingEnable(true);
MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_6"));
}
}
}
}
break;
case CMD_TRAFFIC:
// Communication traffic measurement
if (IsEnable(hWnd, 0))
{
CmTraffic(hWnd);
}
break;
case CMD_CM_SETTING:
// Operation mode setting
if (IsEnable(hWnd, 0))
{
if (CmSetting(hWnd))
{
CmApplyCmSetting();
}
}
break;
case CMD_WINNET:
// Windows network settings
ShowWindowsNetworkConnectionDialog();
break;
}
}
// Option dialog
void CmConfigDlg(HWND hWnd)
{
// Validate arguments
if (hWnd == NULL)
{
return;
}
Dialog(hWnd, D_CM_CONFIG, CmConfigDlgProc, NULL);
}
// Initialize the option dialog
void CmConfigDlgInit(HWND hWnd)
{
bool use_alpha;
UINT alpha_value;
UINT os;
CLIENT_CONFIG c;
// Validate arguments
if (hWnd == NULL)
{
return;
}
DlgFont(hWnd, S_WARNING, 10, true);
DlgFont(hWnd, S_INFO, 10, false);
Zero(&c, sizeof(c));
if (CALL(hWnd, CcGetClientConfig(cm->Client, &c)) == false)
{
EndDialog(hWnd, 0);
return;
}
Check(hWnd, R_ALLOW_REMOTE_CONFIG, c.AllowRemoteConfig);
Check(hWnd, R_USE_KEEP_CONNECT, c.UseKeepConnect);
SetTextA(hWnd, E_HOSTNAME, c.KeepConnectHost);
SetIntEx(hWnd, E_PORT, c.KeepConnectPort);
SetIntEx(hWnd, E_INTERVAL, c.KeepConnectInterval);
Check(hWnd, R_TCP, c.KeepConnectProtocol == CONNECTION_TCP);
Check(hWnd, R_UDP, c.KeepConnectProtocol == CONNECTION_UDP);
use_alpha = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "UseAlpha") == 0 ? false : true;
alpha_value = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "AlphaValue");
alpha_value = MAKESURE(alpha_value, 0, 100);
SetInt(hWnd, E_ALPHA_VALUE, alpha_value == 0 ? 50 : alpha_value);
Check(hWnd, R_ALPHA, use_alpha);
os = GetOsInfo()->OsType;
if (OS_IS_WINDOWS_NT(os) && GET_KETA(os, 100) >= 2)
{
Enable(hWnd, R_ALPHA);
}
else
{
Disable(hWnd, R_ALPHA);
}
CmConfigDlgRefresh(hWnd);
}
// Update the option dialog
void CmConfigDlgRefresh(HWND hWnd)
{
bool ok = true;
bool use_keep_connect;
// Validate arguments
if (hWnd == NULL)
{
return;
}
use_keep_connect = IsChecked(hWnd, R_USE_KEEP_CONNECT);
SetEnable(hWnd, S_HOSTNAME, use_keep_connect);
SetEnable(hWnd, S_PORT, use_keep_connect);
SetEnable(hWnd, S_INTERVAL, use_keep_connect);
SetEnable(hWnd, S_INTERVAL2, use_keep_connect);
SetEnable(hWnd, S_PROTOCOL, use_keep_connect);
SetEnable(hWnd, S_INFO, use_keep_connect);
SetEnable(hWnd, S_INFO2, use_keep_connect);
SetEnable(hWnd, E_HOSTNAME, use_keep_connect);
SetEnable(hWnd, E_PORT, use_keep_connect);
SetEnable(hWnd, E_INTERVAL, use_keep_connect);
SetEnable(hWnd, R_TCP, use_keep_connect);
SetEnable(hWnd, R_UDP, use_keep_connect);
SetEnable(hWnd, S_WARNING, IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG));
if (IsChecked(hWnd, R_USE_KEEP_CONNECT))
{
if (IsEmpty(hWnd, E_HOSTNAME))
{
ok = false;
}
if (IsChecked(hWnd, R_TCP) == false && IsChecked(hWnd, R_UDP) == false)
{
ok = false;
}
if (GetInt(hWnd, E_PORT) == 0 || GetInt(hWnd, E_PORT) >= 65536)
{
ok = false;
}
if (GetInt(hWnd, E_INTERVAL) == 0)
{
ok = false;
}
}
if (IsChecked(hWnd, R_ALPHA))
{
UINT i = GetInt(hWnd, E_ALPHA_VALUE);
if (i < 20 || i >= 100)
{
ok = false;
}
Enable(hWnd, E_ALPHA_VALUE);
}
else
{
Disable(hWnd, E_ALPHA_VALUE);
}
SetEnable(hWnd, IDOK, ok);
}
// Save the setting of the option dialog
void CmConfigDlgOnOk(HWND hWnd)
{
CLIENT_CONFIG c;
// Validate arguments
if (hWnd == NULL)
{
return;
}
Zero(&c, sizeof(c));
c.AllowRemoteConfig = IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG);
c.UseKeepConnect = IsChecked(hWnd, R_USE_KEEP_CONNECT);
GetTxtA(hWnd, E_HOSTNAME, c.KeepConnectHost, sizeof(c.KeepConnectHost));
c.KeepConnectPort = GetInt(hWnd, E_PORT);
c.KeepConnectInterval = GetInt(hWnd, E_INTERVAL);
if (IsChecked(hWnd, R_TCP))
{
c.KeepConnectProtocol = CONNECTION_TCP;
}
else if (IsChecked(hWnd, R_UDP))
{
c.KeepConnectProtocol = CONNECTION_UDP;
}
else
{
return;
}
if (c.UseKeepConnect)
{
if (c.KeepConnectInterval < KEEP_INTERVAL_MIN || c.KeepConnectInterval > KEEP_INTERVAL_MAX)
{
MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_KEEP_INTERVAL_MSG"),
KEEP_INTERVAL_MIN, KEEP_INTERVAL_MAX);
FocusEx(hWnd, E_INTERVAL);
return;
}
}
if (CALL(hWnd, CcSetClientConfig(cm->Client, &c)) == false)
{
return;
}
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "AlphaValue", GetInt(hWnd, E_ALPHA_VALUE));
MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "UseAlpha", IsChecked(hWnd, R_ALPHA));
EndDialog(hWnd, true);
}
// Option setting dialog procedure
UINT CmConfigDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
CmConfigDlgInit(hWnd);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case R_ALLOW_REMOTE_CONFIG:
case R_USE_KEEP_CONNECT:
case E_HOSTNAME:
case E_PORT:
case E_INTERVAL:
case R_ALPHA:
case E_ALPHA_VALUE:
CmConfigDlgRefresh(hWnd);
break;
}
switch (wParam)
{
case IDOK:
CmConfigDlgRefresh(hWnd);
CmConfigDlgOnOk(hWnd);
break;
case IDCANCEL:
Close(hWnd);
break;
case R_ALLOW_REMOTE_CONFIG:
if (IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG) == false)
{
if (cm->server_name != NULL)
{
// If the current user is remotely connected, show a warning
// when the user choose to disable the remote management
if (MsgBoxEx(hWnd, MB_ICONEXCLAMATION | MB_DEFBUTTON2 | MB_YESNO, _UU("CM_REMOTE_WARNING"),
cm->server_name, cm->server_name) == IDNO)
{
Check(hWnd, R_ALLOW_REMOTE_CONFIG, true);
}
}
}
break;
case R_USE_KEEP_CONNECT:
if (IsChecked(hWnd, R_USE_KEEP_CONNECT))
{
FocusEx(hWnd, E_HOSTNAME);
}
break;
case R_ALPHA:
if (IsChecked(hWnd, R_ALPHA))
{
FocusEx(hWnd, E_ALPHA_VALUE);
}
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, false);
break;
}
return 0;
}
// Create a shortcut
void CmSortcut(HWND hWnd, wchar_t *account_name)
{
wchar_t tmp[MAX_SIZE];
CM_ACCOUNT *a;
wchar_t *filename;
UCHAR key[SHA1_SIZE];
// Validate arguments
if (hWnd == NULL || account_name == NULL)
{
return;
}
// Get the account information
a = CmGetExistAccountObject(hWnd, account_name);
if (a == NULL)
{
return;
}
Copy(key, a->ShortcutKey, SHA1_SIZE);
if (IsZero(key, SHA1_SIZE))
{
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_SHORTCUT_UNSUPPORTED"));
}
else
{
// Determine the file name
UniFormat(tmp, sizeof(tmp), L"%s.lnk", account_name);
UniSafeFileName(tmp);
filename = SaveDlg(hWnd, _UU("CM_SHORTCUT_FILE"),
_UU("CM_SHORTCUT_SAVE_TITLE"), tmp, L".vpn");
if (filename != NULL)
{
char key_str[64];
wchar_t target[MAX_PATH];
wchar_t workdir[MAX_PATH];
wchar_t args[MAX_PATH];
wchar_t comment[MAX_SIZE];
wchar_t icon[MAX_PATH];
BinToStr(key_str, sizeof(key_str), key, SHA1_SIZE);
// Create a shortcut
UniStrCpy(target, sizeof(target), MsGetExeFileNameW());
UniStrCpy(workdir, sizeof(workdir), MsGetExeDirNameW());
StrToUni(args, sizeof(args), key_str);
UniFormat(comment, sizeof(comment), _UU("CM_SHORTCUT_COMMENT"), account_name);
UniStrCpy(icon, sizeof(icon), MsGetExeFileNameW());
if (CreateLink(filename, target, workdir, args, comment, icon, 1) == false)
{
MsgBox(hWnd, MB_ICONSTOP, _UU("CM_SHORTCUT_ERROR"));
}
Free(filename);
}
}
CmFreeAccountObject(hWnd, a);
}
// Export the account
void CmExportAccount(HWND hWnd, wchar_t *account_name)
{
wchar_t tmp[MAX_SIZE];
CM_ACCOUNT *a;
wchar_t *filename;
// Validate arguments
if (hWnd == NULL || account_name == NULL)
{
return;
}
// Get the account information
a = CmGetExistAccountObject(hWnd, account_name);
if (a == NULL)
{
return;
}
// Determine the file name
UniFormat(tmp, sizeof(tmp), L"%s.vpn", account_name);
UniSafeFileName(tmp);
filename = SaveDlg(hWnd, _UU("CM_ACCOUNT_SETTING_FILE"),
_UU("CM_ACCOUNT_SAVE_TITLE"), tmp, L".vpn");
if (filename != NULL)
{
RPC_CLIENT_CREATE_ACCOUNT t;
BUF *b;
BUF *b2;
wchar_t tmp[MAX_SIZE];
UCHAR *buf;
UINT buf_size;
UCHAR bom[] = {0xef, 0xbb, 0xbf, };
Zero(&t, sizeof(t));
t.ClientOption = a->ClientOption;
t.ClientAuth = a->ClientAuth;
t.StartupAccount = a->Startup;
t.CheckServerCert = a->CheckServerCert;
t.ServerCert = a->ServerCert;
t.ClientOption->FromAdminPack = false;
b = CiAccountToCfg(&t);
SeekBuf(b, 0, 0);
// Check whether the password is contained
if (CiHasAccountSensitiveInformation(b))
{
SeekBuf(b, 0, 0);
// Confirm that the user want to clear the password
if (MsgBox(hWnd, MB_YESNO | MB_ICONQUESTION, _UU("CM_ACCOUNT_MSG_SENSITIVE")) == IDYES)
{
// Erase
CiEraseSensitiveInAccount(b);
}
}
UniStrCpy(tmp, sizeof(tmp), filename);
b2 = NewBuf();
WriteBuf(b2, bom, sizeof(bom));
// Add a header part
buf_size = CalcUniToUtf8(_UU("CM_ACCOUNT_FILE_BANNER"));
buf = ZeroMalloc(buf_size + 32);
UniToUtf8(buf, buf_size, _UU("CM_ACCOUNT_FILE_BANNER"));
WriteBuf(b2, buf, StrLen((char *)buf));
WriteBuf(b2, b->Buf, b->Size);
SeekBuf(b2, 0, 0);
FreeBuf(b);
if (DumpBufW(b2, tmp) == false)
{
MsgBox(hWnd, MB_ICONSTOP, _UU("CM_FAILED_TO_SAVE_FILE"));
}
Free(filename);
FreeBuf(b2);
Free(buf);
}
CmFreeAccountObject(hWnd, a);
}
// Main process of importing account
void CmImportAccountMain(HWND hWnd, wchar_t *filename)
{
CmImportAccountMainEx(hWnd, filename, false);
}
void CmImportAccountMainEx(HWND hWnd, wchar_t *filename, bool overwrite)
{
wchar_t name[MAX_SIZE];
wchar_t tmp[MAX_SIZE];
BUF *b;
RPC_CLIENT_CREATE_ACCOUNT *t;
// Validate arguments
if (hWnd == NULL || filename == NULL)
{
return;
}
UniStrCpy(tmp, sizeof(tmp), filename);
b = ReadDumpW(tmp);
if (b == NULL)
{
MsgBox(hWnd, MB_ICONSTOP, _UU("CM_FAILED_TO_OPEN_FILE"));
return;
}
t = CiCfgToAccount(b);
if (t == NULL)
{
FreeBuf(b);
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("CM_ACCOUNT_PARSE_FAILED"));
return;
}
if (overwrite)
{
// If the same name already exists, remove it
if (LvSearchStr(hWnd, L_ACCOUNT, 0, t->ClientOption->AccountName) != INFINITE)
{
RPC_CLIENT_DELETE_ACCOUNT d;
RPC_CLIENT_GET_ACCOUNT get;
HWND h = cm->hEasyWnd == NULL ? hWnd : cm->hEasyWnd;
Zero(&d, sizeof(d));
UniStrCpy(d.AccountName, sizeof(d.AccountName), t->ClientOption->AccountName);
Zero(&get, sizeof(get));
UniStrCpy(get.AccountName, sizeof(get.AccountName), t->ClientOption->AccountName);
if (CcGetAccount(cm->Client, &get) == ERR_NO_ERROR)
{
// Inherit the information of some of the client option by getting
// the account information of the same name that already exists
if (get.ClientOption != NULL && get.ClientAuth != NULL)
{
CLIENT_OPTION *old_option = get.ClientOption;
CLIENT_AUTH *old_auth = get.ClientAuth;
// Inherit the connection parameters
t->ClientOption->ProxyType = old_option->ProxyType;
StrCpy(t->ClientOption->ProxyName, sizeof(t->ClientOption->ProxyName),
old_option->ProxyName);
t->ClientOption->ProxyPort = old_option->ProxyPort;
StrCpy(t->ClientOption->ProxyUsername, sizeof(t->ClientOption->ProxyUsername),
old_option->ProxyUsername);
StrCpy(t->ClientOption->ProxyPassword, sizeof(t->ClientOption->ProxyPassword),
old_option->ProxyPassword);
t->ClientOption->NumRetry = old_option->NumRetry;
t->ClientOption->RetryInterval = old_option->RetryInterval;
t->ClientOption->MaxConnection = old_option->MaxConnection;
t->ClientOption->UseEncrypt = old_option->UseEncrypt;
t->ClientOption->UseCompress = old_option->UseCompress;
t->ClientOption->HalfConnection = old_option->HalfConnection;
t->ClientOption->NoRoutingTracking = old_option->NoRoutingTracking;
StrCpy(t->ClientOption->DeviceName, sizeof(t->ClientOption->DeviceName),
old_option->DeviceName);
t->ClientOption->AdditionalConnectionInterval = old_option->AdditionalConnectionInterval;
t->ClientOption->ConnectionDisconnectSpan = old_option->ConnectionDisconnectSpan;
t->ClientOption->HideStatusWindow = old_option->HideStatusWindow;
t->ClientOption->RequireMonitorMode = old_option->RequireMonitorMode;
t->ClientOption->RequireBridgeRoutingMode = old_option->RequireBridgeRoutingMode;
t->ClientOption->DisableQoS = old_option->DisableQoS;
t->ClientOption->NoTls1 = old_option->NoTls1;
// Inherit the authentication data
CiFreeClientAuth(t->ClientAuth);
t->ClientAuth = CopyClientAuth(old_auth);
// Other Settings
t->StartupAccount = get.StartupAccount;
t->CheckServerCert = get.CheckServerCert;
if (t->ServerCert != NULL)
{
FreeX(t->ServerCert);
}
t->ServerCert = NULL;
if (get.ServerCert != NULL)
{
t->ServerCert = CloneX(get.ServerCert);
}
Copy(t->ShortcutKey, get.ShortcutKey, sizeof(t->ShortcutKey));
}
CiFreeClientGetAccount(&get);
}
if (CALL(h, CcDeleteAccount(cm->Client, &d)) == false)
{
CiFreeClientCreateAccount(t);
Free(t);
return;
}
CmRefreshAccountList(hWnd);
}
}
CmGenerateImportName(hWnd, name, sizeof(name), t->ClientOption->AccountName);
UniStrCpy(t->ClientOption->AccountName, sizeof(t->ClientOption->AccountName), name);
if (overwrite)
{
t->ClientOption->FromAdminPack = true;
}
CALL(hWnd, CcCreateAccount(cm->Client, t));
CiFreeClientCreateAccount(t);
Free(t);
FreeBuf(b);
if (overwrite)
{
// Start to connect the VPN
CmConnect(hWnd, name);
}
//MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_IMPORT_MESSAGE"), filename, name);
}
// Import an account
void CmImportAccount(HWND hWnd)
{
wchar_t *filename;
wchar_t tmp[MAX_SIZE];
// Validate arguments
if (hWnd == NULL)
{
return;
}
// Open the file
filename = OpenDlg(hWnd, _UU("CM_ACCOUNT_SETTING_FILE"), _UU("CM_ACCOUNT_OPEN_TITLE"));
if (filename == NULL)
{
return;
}
UniStrCpy(tmp, sizeof(tmp), filename);
Free(filename);
CmImportAccountMain(hWnd, tmp);
}
// Create a copy of the account
void CmCopyAccount(HWND hWnd, wchar_t *account_name)
{
wchar_t tmp[MAX_SIZE];
CM_ACCOUNT *a;
RPC_CLIENT_CREATE_ACCOUNT c;
// Validate arguments
if (hWnd == NULL || account_name == NULL)
{
return;
}
CmGenerateCopyName(hWnd, tmp, sizeof(tmp), account_name);
// Get an account information
a = CmGetExistAccountObject(hWnd, account_name);
if (a == NULL)
{
return;
}
// Change the account name
UniStrCpy(a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName), tmp);
// Write
Zero(&c, sizeof(c));
c.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
Copy(c.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
c.ClientAuth = CopyClientAuth(a->ClientAuth);
if (a->ServerCert)
{
c.ServerCert = CloneX(a->ServerCert);
}
c.CheckServerCert = a->CheckServerCert;
c.StartupAccount = false; // Don't copy the startup attribute
CALL(hWnd, CcCreateAccount(cm->Client, &c));
CiFreeClientCreateAccount(&c);
CmFreeAccountObject(hWnd, a);
}
// Update the Virtual LAN Card Name dialog
void CmNewVLanDlgUpdate(HWND hWnd)
{
bool ok = true;
char tmp[MAX_SIZE];
// Validate arguments
if (hWnd == NULL)
{
return;
}
GetTxtA(hWnd, E_NAME, tmp, sizeof(tmp));
if (IsSafeStr(tmp) == false)
{
ok = false;
}
if (SearchStrEx(tmp, " ", 0, false) != INFINITE)
{
ok = false;
}
Trim(tmp);
if (StrLen(tmp) == 0)
{
ok = false;
}
SetEnable(hWnd, IDOK, ok);
}
// Virtual LAN card name decision dialog procedure
UINT CmNewVLanDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
char *tmp = (char *)param;
char default_name[MAX_SIZE];
RPC_CLIENT_VERSION ver;
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
LimitText(hWnd, E_NAME, cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN);
FormatText(hWnd, S_INFO, cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN);
Zero(&ver, sizeof(ver));
if (CcGetClientVersion(cm->Client, &ver) == ERR_NO_ERROR)
{
if (ver.IsVLanNameRegulated)
{
Show(hWnd, S_WIN8);
}
}
if (CiGetNextRecommendedVLanName(cm->Client, default_name, sizeof(default_name)))
{
// Show a default virtual LAN card name candidate
SetTextA(hWnd, E_NAME, default_name);
}
CmNewVLanDlgUpdate(hWnd);
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
if (cm->Client->Win9x)
{
// For Windows 9x, show a confirmation message
if (MsgBox(hWnd, MB_ICONQUESTION | MB_OKCANCEL, _UU("CM_9X_VLAN_INSTALL")) == IDCANCEL)
{
break;
}
}
GetTxtA(hWnd, E_NAME, tmp, (cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN) + 1);
Trim(tmp);
if (CcGetClientVersion(cm->Client, &ver) == ERR_NO_ERROR)
{
if (ver.IsVLanNameRegulated)
{
if (CiIsValidVLanRegulatedName(tmp) == false)
{
// Virtual LAN card name isn't meeting the format
MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("D_CM_NEW_VLAN@S_WIN8"));
FocusEx(hWnd, E_NAME);
break;
}
}
}
EndDialog(hWnd, true);
break;
case IDCANCEL:
Close(hWnd);
break;
}
switch (LOWORD(wParam))
{
case E_NAME:
CmNewVLanDlgUpdate(hWnd);
break;
case R_USE_DISCONNECT:
if (IsChecked(hWnd, R_USE_DISCONNECT))
{
FocusEx(hWnd, E_DISCONNECT_SPAN);
}
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, false);
break;
}
return 0;
}
// Dialog to determine the new virtual LAN card name
char *CmNewVLanDlg(HWND hWnd)
{
char tmp[MAX_DEVICE_NAME_LEN + 1];
if (Dialog(hWnd, D_CM_NEW_VLAN, CmNewVLanDlgProc, tmp) == false)
{
return NULL;
}
return CopyStr(tmp);
}
// Update the advanced settings dialog
void CmDetailDlgUpdate(HWND hWnd, CM_ACCOUNT *a)
{
bool ok = true;
bool locked;
// Validate arguments
if (hWnd == NULL || a == NULL)
{
return;
}
locked = a->LockMode;
if (a->LinkMode || a->NatMode)
{
Disable(hWnd, R_NO_ROUTING);
}
else
{
if (cm->Client->Unix)
{
Disable(hWnd, R_NO_ROUTING);
}
}
SetEnable(hWnd, E_DISCONNECT_SPAN, IsChecked(hWnd, R_USE_DISCONNECT));
SetEnable(hWnd, IDOK, ok);
if (locked)
{
Disable(hWnd, C_NUM_TCP);
Disable(hWnd, S_STATIC5);
Disable(hWnd, S_STATIC8);
Disable(hWnd, E_INTERVAL);
Disable(hWnd, S_STATIC9);
Disable(hWnd, E_DISCONNECT_SPAN);
Disable(hWnd, S_STATIC10);
Disable(hWnd, S_STATIC11);
Disable(hWnd, R_USE_DISCONNECT);
Disable(hWnd, R_USE_HALF_CONNECTION);
Disable(hWnd, R_DISABLE_QOS);
Disable(hWnd, R_USE_ENCRYPT);
Disable(hWnd, R_USE_COMPRESS);
Disable(hWnd, R_BRIDGE);
Disable(hWnd, R_MONITOR);
Disable(hWnd, R_NO_ROUTING);
}
}
// Advanced Settings dialog procedure
UINT CmDetailDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
CM_ACCOUNT *a = (CM_ACCOUNT *)param;
UINT i;
UINT num;
wchar_t tmp[MAX_SIZE];
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
// Number of TCP connections
for (i = 1;i <= MAX_TCP_CONNECTION;i++)
{
UniFormat(tmp, sizeof(tmp), L"%u", i);
CbAddStr(hWnd, C_NUM_TCP, tmp, i);
}
CbSelect(hWnd, C_NUM_TCP, a->ClientOption->MaxConnection);
// Connection establishment interval
SetInt(hWnd, E_INTERVAL, a->ClientOption->AdditionalConnectionInterval);
// Lifetime
SetIntEx(hWnd, E_DISCONNECT_SPAN, a->ClientOption->ConnectionDisconnectSpan);
Check(hWnd, R_USE_DISCONNECT, a->ClientOption->ConnectionDisconnectSpan != 0);
Check(hWnd, R_USE_HALF_CONNECTION, a->ClientOption->HalfConnection);
Check(hWnd, R_USE_ENCRYPT, a->ClientOption->UseEncrypt);
Check(hWnd, R_USE_COMPRESS, a->ClientOption->UseCompress);
Check(hWnd, R_NO_ROUTING, a->ClientOption->NoRoutingTracking);
Check(hWnd, R_DISABLE_QOS, a->ClientOption->DisableQoS);
Check(hWnd, R_DISABLE_UDP, a->ClientOption->NoUdpAcceleration);
// Select the Connection Mode
if (a->LinkMode == false)
{
Check(hWnd, R_BRIDGE, a->ClientOption->RequireBridgeRoutingMode);
Check(hWnd, R_MONITOR, a->ClientOption->RequireMonitorMode);
}
else
{
Check(hWnd, R_BRIDGE, true);
Check(hWnd, R_MONITOR, false);
SetText(hWnd, S_MODE, _UU("CM_DETAIL_MODE_LINK_STR"));
Disable(hWnd, R_BRIDGE);
Disable(hWnd, R_MONITOR);
}
CmDetailDlgUpdate(hWnd, a);
Focus(hWnd, IDOK);
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
if (IsChecked(hWnd, R_USE_DISCONNECT) && GetInt(hWnd, E_DISCONNECT_SPAN) == 0)
{
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_NO_DISCONNECT_SPAN"));
FocusEx(hWnd, E_DISCONNECT_SPAN);
break;
}
num = GetInt(hWnd, C_NUM_TCP);
if (num == 0)
{
break;
}
if (num == 1 && IsChecked(hWnd, R_USE_HALF_CONNECTION))
{
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_HALF_MSG"));
Focus(hWnd, C_NUM_TCP);
break;
}
if (GetInt(hWnd, E_INTERVAL) < 1)
{
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_TOO_SMALL_INTERVAL"));
Focus(hWnd, E_INTERVAL);
break;
}
a->ClientOption->MaxConnection = num;
a->ClientOption->AdditionalConnectionInterval = GetInt(hWnd, E_INTERVAL);
if (IsChecked(hWnd, R_USE_DISCONNECT) == false)
{
a->ClientOption->ConnectionDisconnectSpan = 0;
}
else
{
a->ClientOption->ConnectionDisconnectSpan = GetInt(hWnd, E_DISCONNECT_SPAN);
}
a->ClientOption->HalfConnection = IsChecked(hWnd, R_USE_HALF_CONNECTION);
a->ClientOption->UseEncrypt = IsChecked(hWnd, R_USE_ENCRYPT);
a->ClientOption->UseCompress = IsChecked(hWnd, R_USE_COMPRESS);
a->ClientOption->NoRoutingTracking = IsChecked(hWnd, R_NO_ROUTING);
a->ClientOption->DisableQoS = IsChecked(hWnd, R_DISABLE_QOS);
a->ClientOption->NoUdpAcceleration = IsChecked(hWnd, R_DISABLE_UDP);
if (a->LinkMode)
{
a->ClientOption->RequireBridgeRoutingMode = true;
a->ClientOption->RequireMonitorMode = false;
}
else
{
a->ClientOption->RequireBridgeRoutingMode = IsChecked(hWnd, R_BRIDGE);
a->ClientOption->RequireMonitorMode = IsChecked(hWnd, R_MONITOR);
}
EndDialog(hWnd, true);
break;
case IDCANCEL:
Close(hWnd);
break;
}
switch (LOWORD(wParam))
{
case C_NUM_TCP:
case E_INTERVAL:
case E_DISCONNECT_SPAN:
case R_USE_DISCONNECT:
case R_USE_HALF_CONNECTION:
CmDetailDlgUpdate(hWnd, a);
break;
}
switch (wParam)
{
case R_USE_DISCONNECT:
if (IsChecked(hWnd, R_USE_DISCONNECT))
{
FocusEx(hWnd, E_DISCONNECT_SPAN);
}
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, false);
break;
}
return 0;
}
// Advanced Settings dialog
bool CmDetailDlg(HWND hWnd, CM_ACCOUNT *a)
{
// Validate arguments
if (hWnd == NULL || a == NULL)
{
return false;
}
return Dialog(hWnd, D_CM_DETAIL, CmDetailDlgProc, a);
}
// Update the account editing dialog procedure
void CmEditAccountDlgUpdate(HWND hWnd, CM_ACCOUNT *a)
{
bool ok = true;
char str[MAX_SIZE];
bool locked;
// Validate arguments
if (hWnd == NULL || a == NULL)
{
return;
}
locked = a->LockMode;
if (a->Inited == false)
{
return;
}
if (a->EditMode)
{
Disable(hWnd, E_ACCOUNT_NAME);
}
// The name of connection settings
GetTxt(hWnd, E_ACCOUNT_NAME, a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName));
UniTrim(a->ClientOption->AccountName);
// Host name
GetTxtA(hWnd, E_HOSTNAME, a->ClientOption->Hostname, sizeof(a->ClientOption->Hostname));
Trim(a->ClientOption->Hostname);
if (InStr(a->ClientOption->Hostname, "/tcp"))
{
Check(hWnd, R_DISABLE_NATT, true);
}
else
{
Check(hWnd, R_DISABLE_NATT, false);
}
SetEnable(hWnd, R_DISABLE_NATT, !IsEmptyStr(a->ClientOption->Hostname));
// Port number
a->ClientOption->Port = GetInt(hWnd, C_PORT);
// HUB name
GetTxtA(hWnd,C_HUBNAME, a->ClientOption->HubName, sizeof(a->ClientOption->HubName));
// Type of proxy
a->ClientOption->ProxyType = PROXY_DIRECT;
if (IsChecked(hWnd, R_HTTPS))
{
a->ClientOption->ProxyType = PROXY_HTTP;
}
if (IsChecked(hWnd, R_SOCKS))
{
a->ClientOption->ProxyType = PROXY_SOCKS;
}
// To validate the server certificate
a->CheckServerCert = IsChecked(hWnd, R_CHECK_CERT);
if (a->NatMode)
{
Disable(hWnd, R_CHECK_CERT);
Disable(hWnd, B_TRUST);
}
if (a->HideTrustCert)
{
Disable(hWnd, B_TRUST);
}
// Device name
StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName), "");
if (LvIsSelected(hWnd, L_VLAN))
{
wchar_t *s = LvGetStr(hWnd, L_VLAN, LvGetSelected(hWnd, L_VLAN), 0);
if (s != NULL)
{
char str[MAX_SIZE];
UniToStr(str, sizeof(str), s);
CmPrintNameToVLanName(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName), str);
Free(s);
}
}
// User authentication
a->ClientAuth->AuthType = CbGetSelect(hWnd, C_TYPE);
GetTxtA(hWnd, E_USERNAME, a->ClientAuth->Username, sizeof(a->ClientAuth->Username));
Trim(a->ClientAuth->Username);
switch (a->ClientAuth->AuthType)
{
case CLIENT_AUTHTYPE_PASSWORD:
// Password authentication
GetTxtA(hWnd, E_PASSWORD, str, sizeof(str));
if (StrCmp(str, HIDDEN_PASSWORD) != 0)
{
HashPassword(a->ClientAuth->HashedPassword, a->ClientAuth->Username, str);
}
break;
case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
// Plaintext password authentication
GetTxtA(hWnd, E_PASSWORD, str, sizeof(str));
if (StrCmp(str, HIDDEN_PASSWORD) != 0)
{
StrCpy(a->ClientAuth->PlainPassword, sizeof(a->ClientAuth->PlainPassword), str);
}
break;
}
// Reconnection option
if ((a->LinkMode || a->NatMode) || a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
{
Disable(hWnd, R_RETRY);
}
else
{
Enable(hWnd, R_RETRY);
}
if (IsChecked(hWnd, R_RETRY) == false)
{
a->ClientOption->NumRetry = 0;
}
else
{
if (IsChecked(hWnd, R_INFINITE))
{
a->ClientOption->NumRetry = INFINITE;
}
else
{
a->ClientOption->NumRetry = GetInt(hWnd, E_RETRY_NUM);
}
}
a->ClientOption->RetryInterval = GetInt(hWnd, E_RETRY_SPAN);
a->ClientOption->NoTls1 = IsChecked(hWnd, R_NOTLS1);
// Information determining
if (UniStrLen(a->ClientOption->AccountName) == 0 && a->NatMode == false)
{
ok = false;
}
if (StrLen(a->ClientOption->Hostname) == 0)
{
ok = false;
}
if (a->ClientOption->Port == 0 || a->ClientOption->Port >= 65536)
{
ok = false;
}
if (StrLen(a->ClientOption->HubName) == 0)
{
ok = false;
}
if (StrLen(a->ClientAuth->Username) == 0)
{
ok = false;
}
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
{
if (a->ClientAuth->ClientK == NULL || a->ClientAuth->ClientX == NULL)
{
ok = false;
}
}
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
{
if (IsEmptyStr(a->ClientAuth->SecurePrivateKeyName) || IsEmptyStr(a->ClientAuth->SecurePublicCertName))
{
ok = false;
}
}
// Display update
if (IsChecked(hWnd, R_RETRY) && IsEnable(hWnd, R_RETRY))
{
if (a->LinkMode == false && a->NatMode == false)
{
Enable(hWnd, R_INFINITE);
Enable(hWnd, E_RETRY_SPAN);
Enable(hWnd, S_RETRY_SPAN_1);
Enable(hWnd, S_RETRY_SPAN_2);
}
else
{
Disable(hWnd, R_INFINITE);
Disable(hWnd, E_RETRY_SPAN);
Disable(hWnd, S_RETRY_SPAN_1);
Disable(hWnd, S_RETRY_SPAN_2);
}
if (IsChecked(hWnd, R_INFINITE) == false)
{
Enable(hWnd, E_RETRY_NUM);
Enable(hWnd, S_RETRY_NUM_1);
Enable(hWnd, S_RETRY_NUM_2);
if (GetInt(hWnd, E_RETRY_NUM) == 0)
{
ok = false;
}
}
else
{
Disable(hWnd, E_RETRY_NUM);
Disable(hWnd, S_RETRY_NUM_1);
Disable(hWnd, S_RETRY_NUM_2);
}
}
else
{
Disable(hWnd, E_RETRY_NUM);
Disable(hWnd, E_RETRY_SPAN);
Disable(hWnd, R_INFINITE);
Disable(hWnd, S_RETRY_NUM_1);
Disable(hWnd, S_RETRY_NUM_2);
Disable(hWnd, S_RETRY_SPAN_1);
Disable(hWnd, S_RETRY_SPAN_2);
}
if (a->NatMode == false)
{
if (a->ServerCert == NULL)
{
SetText(hWnd, B_SERVER_CERT, _UU("CM_SERVER_CERT_1"));
Disable(hWnd, B_VIEW_SERVER_CERT);
}
else
{
SetText(hWnd, B_SERVER_CERT, _UU("CM_SERVER_CERT_2"));
Enable(hWnd, B_VIEW_SERVER_CERT);
}
}
else
{
Disable(hWnd, B_VIEW_SERVER_CERT);
Disable(hWnd, B_SERVER_CERT);
}
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT || a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
{
wchar_t tmp[MAX_SIZE * 2];
wchar_t issuer[MAX_SIZE];
wchar_t subject[MAX_SIZE];
wchar_t expires[MAX_SIZE];
SetIcon(hWnd, S_CERT, (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT) ? ICO_CERT : ICO_SECURE);
Hide(hWnd, S_PASSWORD);
Hide(hWnd, E_PASSWORD);
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
{
if (a->ClientAuth->ClientX != NULL)
{
Enable(hWnd, B_VIEW_CLIENT_CERT);
SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_CLIENT_CERT_2"));
GetPrintNameFromName(issuer, sizeof(issuer), a->ClientAuth->ClientX->issuer_name);
GetPrintNameFromName(subject, sizeof(subject), a->ClientAuth->ClientX->subject_name);
GetDateStrEx64(expires, sizeof(expires), SystemToLocal64(a->ClientAuth->ClientX->notAfter), NULL);
UniFormat(tmp, sizeof(tmp), _UU("CM_CERT_INFO"), subject, issuer, expires);
}
else
{
Disable(hWnd, B_VIEW_CLIENT_CERT);
SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_CLIENT_CERT_1"));
UniStrCpy(tmp, sizeof(tmp), _UU("CM_NO_CERT"));
}
SetText(hWnd, B_VIEW_CLIENT_CERT, _UU("CM_VIEW_CLIENT_CERT"));
Enable(hWnd, B_REGIST_CLIENT_CERT);
}
else
{
if (IsEmptyStr(a->ClientAuth->SecurePrivateKeyName) || IsEmptyStr(a->ClientAuth->SecurePublicCertName))
{
UniStrCpy(tmp, sizeof(tmp), _UU("CM_NO_SECURE"));
}
else
{
UniFormat(tmp, sizeof(tmp), _UU("CM_CERT_SECURE_INFO"),
a->ClientAuth->SecurePublicCertName, a->ClientAuth->SecurePrivateKeyName);
}
SetText(hWnd, B_VIEW_CLIENT_CERT, _UU("CM_SELECT_SECURE_DEVICE"));
SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_SELECT_CERT_INCARD"));
Enable(hWnd, B_VIEW_CLIENT_CERT);
if (SmGetCurrentSecureIdFromReg() == 0)
{
Disable(hWnd, B_REGIST_CLIENT_CERT);
}
else
{
Enable(hWnd, B_REGIST_CLIENT_CERT);
}
}
SetText(hWnd, S_CERT_INFO, tmp);
Show(hWnd, S_CERT);
Show(hWnd, S_CERT_INFO);
Show(hWnd, B_VIEW_CLIENT_CERT);
Show(hWnd, B_REGIST_CLIENT_CERT);
}
else
{
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_ANONYMOUS)
{
Hide(hWnd, S_PASSWORD);
Hide(hWnd, E_PASSWORD);
}
else
{
Show(hWnd, S_PASSWORD);
Show(hWnd, E_PASSWORD);
}
Hide(hWnd, S_CERT);
Hide(hWnd, S_CERT_INFO);
Hide(hWnd, B_VIEW_CLIENT_CERT);
Hide(hWnd, B_REGIST_CLIENT_CERT);
}
if (a->ClientOption->ProxyType != PROXY_DIRECT)
{
Enable(hWnd, B_PROXY_CONFIG);
if (StrLen(a->ClientOption->ProxyName) == 0)
{
ok = false;
}
if (a->ClientOption->ProxyPort == 0)
{
ok = false;
}
}
else
{
Disable(hWnd, B_PROXY_CONFIG);
}
if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PASSWORD)
{
bool b = true;
if (ok == false)
{
b = false;
}
if (a->LinkMode == false && a->NatMode == false)
{
SetEnable(hWnd, B_CHANGE_PASSWORD, b);
SetEnable(hWnd, S_CHANGE_PASSWORD, b);
Show(hWnd, B_CHANGE_PASSWORD);
Show(hWnd, S_CHANGE_PASSWORD);
}
else
{
Hide(hWnd, B_CHANGE_PASSWORD);
Hide(hWnd, S_CHANGE_PASSWORD);
}
}
else
{
Hide(hWnd, B_CHANGE_PASSWORD);
Hide(hWnd, S_CHANGE_PASSWORD);
}
if ((StrLen(a->ClientOption->DeviceName) == 0) && (a->LinkMode == false && a->NatMode == false))
{
ok = false;
}
if (a->LinkMode || a->NatMode)
{
Disable(hWnd, L_VLAN);
}
if (a->EditMode == false)
{
char tmp[MAX_SIZE];
GetTxtA(hWnd, E_HOSTNAME, tmp, sizeof(tmp));
Trim(tmp);
if (StartWith(tmp, "127.") || (StrCmpi(tmp, "localhost") == 0))
{
if (a->Flag1 == false)
{
a->Flag1 = true;
a->ClientOption->UseEncrypt = a->ClientOption->UseCompress = false;
a->ClientOption->MaxConnection = 1;
}
}
}
a->ClientOption->HideStatusWindow = IsChecked(hWnd, R_HIDE);
a->ClientOption->HideNicInfoWindow = IsChecked(hWnd, R_HIDE2);
if (locked)
{
SetEnable(hWnd, E_HOSTNAME, false);
SetEnable(hWnd, C_PORT, false);
SetEnable(hWnd, C_HUBNAME, false);
SetEnable(hWnd, S_STATIC2, false);
SetEnable(hWnd, S_STATIC3, false);
SetEnable(hWnd, S_STATIC4, false);
SetEnable(hWnd, S_STATIC5, false);
SetEnable(hWnd, S_STATIC66, false);
SetEnable(hWnd, S_STATIC7, false);
SetEnable(hWnd, S_STATIC11, false);
SetEnable(hWnd, R_CHECK_CERT, false);
SetEnable(hWnd, B_TRUST, false);
SetEnable(hWnd, B_SERVER_CERT, false);
SetEnable(hWnd, B_VIEW_SERVER_CERT, false);
SetEnable(hWnd, R_RETRY, false);
SetEnable(hWnd, S_RETRY_NUM_1, false);
SetEnable(hWnd, E_RETRY_NUM, false);
SetEnable(hWnd, S_RETRY_NUM_2, false);
SetEnable(hWnd, S_RETRY_SPAN_1, false);
SetEnable(hWnd, E_RETRY_SPAN, false);
SetEnable(hWnd, S_RETRY_SPAN_2, false);
SetEnable(hWnd, R_INFINITE, false);
}
SetEnable(hWnd, IDOK, ok);
}
// Initialize the account editing dialog
void CmEditAccountDlgInit(HWND hWnd, CM_ACCOUNT *a)
{
RPC_CLIENT_ENUM_VLAN v;
UINT i;
// Validate arguments
if (hWnd == NULL || a == NULL)
{
return;
}
if (a->LockMode)
{
SetText(hWnd, S_STATIC1, _UU("CM_EASY_ACCOUNT_WARNING"));
}
// Connection settings name
if (a->EditMode || a->NatMode)
{
Disable(hWnd, E_ACCOUNT_NAME);
}
if (a->NatMode || a->LinkMode)
{
Hide(hWnd, R_HIDE);
Hide(hWnd, R_HIDE2);
}
Check(hWnd, R_HIDE, a->ClientOption->HideStatusWindow);
Check(hWnd, R_HIDE2, a->ClientOption->HideNicInfoWindow);
if (a->NatMode)
{
Hide(hWnd, E_ACCOUNT_NAME);
Hide(hWnd, S_ACCOUNT_NAME);
}
if ((cm != NULL && cm->server_name != NULL) || a->LinkMode)
{
Hide(hWnd, B_IE);
}
SetText(hWnd, E_ACCOUNT_NAME, a->ClientOption->AccountName);
// Host name
SetTextA(hWnd, E_HOSTNAME, a->ClientOption->Hostname);
StrCpy(a->old_server_name, sizeof(a->old_server_name), a->ClientOption->Hostname);
if (InStr(a->ClientOption->Hostname, "/tcp"))
{
Check(hWnd, R_DISABLE_NATT, true);
}
else
{
Check(hWnd, R_DISABLE_NATT, false);
}
// Port number
CbSetHeight(hWnd, C_PORT, 18);
CbAddStr(hWnd, C_PORT, _UU("CM_PORT_1"), 0);
CbAddStr(hWnd, C_PORT, _UU("CM_PORT_2"), 0);
CbAddStr(hWnd, C_PORT, _UU("CM_PORT_3"), 0);
CbAddStr(hWnd, C_PORT, _UU("CM_PORT_4"), 0);
SetInt(hWnd, C_PORT, a->ClientOption->Port);
// Virtual HUB name
CbSetHeight(hWnd, C_HUBNAME, 18);
SetTextA(hWnd, C_HUBNAME, a->ClientOption->HubName);
// Type of proxy
Check(hWnd, R_DIRECT_TCP, a->ClientOption->ProxyType == PROXY_DIRECT);
Check(hWnd, R_HTTPS, a->ClientOption->ProxyType == PROXY_HTTP);
Check(hWnd, R_SOCKS, a->ClientOption->ProxyType == PROXY_SOCKS);
// Verify the server certificate
Check(hWnd, R_CHECK_CERT, a->CheckServerCert);
// LAN card list
if (a->NatMode == false && a->LinkMode == false)
{
Zero(&v, sizeof(v));
CcEnumVLan(cm->Client, &v);
LvInit(hWnd, L_VLAN);
LvInsertColumn(hWnd, L_VLAN, 0, L"DeviceName", 345);
for (i = 0;i < v.NumItem;i++)
{
wchar_t tmp[MAX_SIZE];
char str[MAX_SIZE];
CmVLanNameToPrintName(str, sizeof(str), v.Items[i]->DeviceName);
StrToUni(tmp, sizeof(tmp), str);
LvInsert(hWnd, L_VLAN, ICO_NIC_ONLINE, NULL, 1, tmp);
}
// LvAutoSize(hWnd, L_VLAN);
if (v.NumItem == 1)
{
// If only one virtual LAN card exists, initially select it
LvSelect(hWnd, L_VLAN, 0);
}
CiFreeClientEnumVLan(&v);
}
// Select the LAN card
if (StrLen(a->ClientOption->DeviceName) != 0)
{
char str[MAX_SIZE];
wchar_t tmp[MAX_SIZE];
UINT index;
CmVLanNameToPrintName(str, sizeof(str), a->ClientOption->DeviceName);
StrToUni(tmp, sizeof(tmp), str);
index = LvSearchStr(hWnd, L_VLAN, 0, tmp);
if (index != INFINITE)
{
LvSelect(hWnd, L_VLAN, index);
}
}
// Authentication type
CbSetHeight(hWnd, C_TYPE, 18);
CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_0"), CLIENT_AUTHTYPE_ANONYMOUS);
CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_1"), CLIENT_AUTHTYPE_PASSWORD);
CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_2"), CLIENT_AUTHTYPE_PLAIN_PASSWORD);
if (a->HideClientCertAuth == false)
{
// Certificate authentication is not available when HideClientCertAuth is true
CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_3"), CLIENT_AUTHTYPE_CERT);
}
if (a->HideSecureAuth == false)
{
// Authentication using a smart card
CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_4"), CLIENT_AUTHTYPE_SECURE);
}
// Select an authentication
CbSelect(hWnd, C_TYPE, a->ClientAuth->AuthType);
// User name
SetTextA(hWnd, E_USERNAME, a->ClientAuth->Username);
// Password
if (a->EditMode)
{
SetTextA(hWnd, E_PASSWORD, HIDDEN_PASSWORD);
}
// Reconnection times
if (a->ClientOption->NumRetry == 0)
{
Check(hWnd, R_RETRY, false);
}
else
{
Check(hWnd, R_RETRY, true);
if (a->ClientOption->NumRetry == INFINITE)
{
Check(hWnd, R_INFINITE, true);
}
else
{
Check(hWnd, R_INFINITE, false);
SetInt(hWnd, E_RETRY_NUM, a->ClientOption->NumRetry);
}
}
SetIntEx(hWnd, E_RETRY_SPAN, a->ClientOption->RetryInterval);
Check(hWnd, R_NOTLS1, a->ClientOption->NoTls1);
// Title
if (a->NatMode == false)
{
if (a->EditMode == false)
{
SetText(hWnd, 0, _UU("CM_ACCOUNT_TITLE_1"));
FocusEx(hWnd, E_ACCOUNT_NAME);
}
else
{
SetText(hWnd, 0, _UU("CM_ACCOUNT_TITLE_2"));
FormatText(hWnd, 0, a->ClientOption->AccountName);
FocusEx(hWnd, E_HOSTNAME);
}
}
else
{
SetText(hWnd, 0, _UU("NM_ACCOUNT_TITLE"));
FocusEx(hWnd, E_HOSTNAME);
}
if (a->LinkMode || a->NatMode)
{
Hide(hWnd, L_VLAN);
if (a->NatMode == false)
{
SetText(hWnd, S_VLAN_GROUP, _UU("SM_LINK_POLICY_GROUP"));
Show(hWnd, S_POLICY_1);
Show(hWnd, S_POLICY_2);
Show(hWnd, B_POLICY);
}
else
{
Hide(hWnd, S_VLAN_GROUP);
Show(hWnd, S_ROUTER_LOGO);
}
}
// Display update
a->Inited = true;
CmEditAccountDlgUpdate(hWnd, a);
}
// Account editing dialog procedure
UINT CmEditAccountDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
CM_ACCOUNT *a = (CM_ACCOUNT *)param;
NMHDR *n;
X *x;
K *k;
char tmp[MAX_PATH];
bool no_update_natt_check = false;
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
CmEditAccountDlgInit(hWnd, a);
if (a->EditMode == false && a->LinkMode == false && a->NatMode == false)
{
SetTimer(hWnd, 1, 100, NULL);
}
break;
case WM_TIMER:
switch (wParam)
{
case 1:
{
CM_INTERNET_SETTING s;
KillTimer(hWnd, 1);
Zero(&s, sizeof(s));
CmGetSystemInternetSetting(&s);
if (s.ProxyType != PROXY_DIRECT)
{
if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO,
_UU("CM_WOULDYOULOAD_IE_PROXY"),
s.ProxyHostName) == IDYES)
{
Command(hWnd, B_IE);
}
}
}
break;
}
break;
case WM_COMMAND:
switch (wParam)
{
case R_DISABLE_NATT:
Zero(tmp, sizeof(tmp));
GetTxtA(hWnd, E_HOSTNAME, tmp, sizeof(tmp));
if (IsChecked(hWnd, R_DISABLE_NATT))
{
if (InStr(tmp, "/tcp") == false)
{
Trim(tmp);
StrCat(tmp, sizeof(tmp), "/tcp");
SetTextA(hWnd, E_HOSTNAME, tmp);
}
}
else
{
if (InStr(tmp, "/tcp"))
{
UINT i = SearchStrEx(tmp, "/tcp", 0, false);
if (i != INFINITE)
{
tmp[i] = 0;
Trim(tmp);
SetTextA(hWnd, E_HOSTNAME, tmp);
}
}
}
CmEditAccountDlgStartEnumHub(hWnd, a);
break;
}
switch (LOWORD(wParam))
{
case E_ACCOUNT_NAME:
case E_HOSTNAME:
case C_PORT:
case C_HUBNAME:
case R_DIRECT_TCP:
case R_HTTPS:
case R_SOCKS:
case R_CHECK_CERT:
case C_TYPE:
case E_USERNAME:
case E_PASSWORD:
case R_RETRY:
case E_RETRY_NUM:
case E_RETRY_SPAN:
case R_INFINITE:
CmEditAccountDlgUpdate(hWnd, a);
break;
}
switch (HIWORD(wParam))
{
case EN_KILLFOCUS:
switch (LOWORD(wParam))
{
case E_HOSTNAME:
CmEditAccountDlgStartEnumHub(hWnd, a);
break;
}
break;
case BN_KILLFOCUS:
switch (LOWORD(wParam))
{
case R_DIRECT_TCP:
case R_HTTPS:
case R_SOCKS:
CmEditAccountDlgStartEnumHub(hWnd, a);
break;
}
break;
case CBN_KILLFOCUS:
switch (LOWORD(wParam))
{
case C_PORT:
CmEditAccountDlgStartEnumHub(hWnd, a);
break;
}
break;
case BN_PUSHED:
switch (LOWORD(wParam))
{
case R_DISABLE_NATT:
break;
}
break;
}
if (HIWORD(wParam) == 0)
{
CmEditAccountDlgUpdate(hWnd, a);
}
switch (wParam)
{
case B_POLICY:
// Policy
if (a->LinkMode || a->NatMode)
{
a->Policy.Access = true;
a->Policy.MonitorPort = false;
SmPolicyDlgEx2(hWnd, &a->Policy, _UU("SM_LINK_POLICY_CAPTION"), true, a->PolicyVer);
a->Policy.Access = true;
a->Policy.MonitorPort = false;
}
break;
case IDOK:
CmEditAccountDlgUpdate(hWnd, a);
CmEditAccountDlgOnOk(hWnd, a);
break;
case IDCANCEL:
Close(hWnd);
break;
case B_PROXY_CONFIG:
// Proxy Settings
if (CmProxyDlg(hWnd, a->ClientOption))
{
UINT n = GetInt(hWnd, C_PORT);
if (a->ClientOption->ProxyType == PROXY_HTTP &&
n != 443)
{
// Show a warning message if the destination port is
// other than 443 and HTTP proxy is used
if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("CM_HTTP_PROXY_WARNING"), n) == IDYES)
{
// Change the port number to 443
SetText(hWnd, C_PORT, _UU("CM_PORT_2"));
}
}
CmEditAccountDlgStartEnumHub(hWnd, a);
CmEditAccountDlgUpdate(hWnd, a);
}
break;
case B_IE:
// Use the IE settings
if(cm->server_name == NULL)
{
CmProxyDlgUseForIE(hWnd, a->ClientOption);
CmEditAccountDlgUpdate(hWnd, a);
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PROXY_FROM_IE"));
}
break;
case B_TRUST:
// CA
if (a->LinkMode == false)
{
CmTrustDlg(hWnd);
}
else
{
SmCaDlg(hWnd, a->Hub);
}
break;
case B_SERVER_CERT:
// Server certificate registration / delete
if (a->ServerCert == NULL)
{
if (CmLoadXFromFileOrSecureCard(hWnd, &x))
{
a->ServerCert = x;
CmEditAccountDlgUpdate(hWnd, a);
}
}
else
{
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_SERVER_CERT")) == IDYES)
{
FreeX(a->ServerCert);
a->ServerCert = NULL;
CmEditAccountDlgUpdate(hWnd, a);
}
}
break;
case B_VIEW_SERVER_CERT:
// Show the server certificate
if (a->ServerCert != NULL)
{
X *issuer = CmGetIssuer(a->ServerCert);
CertDlg(hWnd, a->ServerCert, issuer, true);
FreeX(issuer);
}
break;
case B_VIEW_CLIENT_CERT:
if (a->ClientAuth->AuthType != CLIENT_AUTHTYPE_SECURE)
{
// Show the client certificate
if (a->ClientAuth->ClientX != NULL)
{
X *issuer = CmGetIssuer(a->ClientAuth->ClientX);
CertDlg(hWnd, a->ClientAuth->ClientX, issuer, true);
FreeX(issuer);
}
}
else
{
UINT id;
// Select the type of smart card
SmSelectSecureId(hWnd);
id = SmGetCurrentSecureIdFromReg();
if (id != 0)
{
if (cm->server_name == NULL)
{
RPC_USE_SECURE t;
Zero(&t, sizeof(t));
t.DeviceId = id;
CcUseSecure(cm->Client, &t);
}
}
CmEditAccountDlgUpdate(hWnd, a);
}
break;
case B_REGIST_CLIENT_CERT:
if (a->ClientAuth->AuthType != CLIENT_AUTHTYPE_SECURE)
{
// Client certificate registration / deletion
if (a->ClientAuth->ClientX == NULL)
{
if (CmLoadXAndK(hWnd, &x, &k))
{
a->ClientAuth->ClientX = x;
a->ClientAuth->ClientK = k;
CmEditAccountDlgUpdate(hWnd, a);
}
}
else
{
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_CLIENT_CERT")) == IDYES)
{
FreeX(a->ClientAuth->ClientX);
FreeK(a->ClientAuth->ClientK);
a->ClientAuth->ClientX = NULL;
a->ClientAuth->ClientK = NULL;
CmEditAccountDlgUpdate(hWnd, a);
}
}
}
else
{
char cert[MAX_SECURE_DEVICE_FILE_LEN + 1], priv[MAX_SECURE_DEVICE_FILE_LEN + 1];
// Select a certificate in the smart card
if (SmSelectKeyPairEx(hWnd, cert, sizeof(cert), priv, sizeof(priv), CmGetSecureBitmapId(a->ClientOption->Hostname)))
{
StrCpy(a->ClientAuth->SecurePublicCertName, sizeof(a->ClientAuth->SecurePublicCertName), cert);
StrCpy(a->ClientAuth->SecurePrivateKeyName, sizeof(a->ClientAuth->SecurePrivateKeyName), priv);
CmEditAccountDlgUpdate(hWnd, a);
}
}
break;
case B_DETAIL:
// Advanced communication settings
if (CmDetailDlg(hWnd, a))
{
CmEditAccountDlgUpdate(hWnd, a);
}
break;
case B_CHANGE_PASSWORD:
// Change the password
CmChangePassword(hWnd, a->ClientOption, a->ClientOption->HubName,
a->ClientAuth->Username);
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, false);
break;
case WM_NOTIFY:
n = (NMHDR *)lParam;
switch (n->idFrom)
{
case L_VLAN:
switch (n->code)
{
case LVN_ITEMCHANGED:
CmEditAccountDlgUpdate(hWnd, a);
break;
}
break;
}
break;
}
return 0;
}
// Update the proxy server settings
void CmProxyDlgUpdate(HWND hWnd, CLIENT_OPTION *a)
{
bool ok = true;
// Validate arguments
if (hWnd == NULL || a == NULL)
{
return;
}
if (IsEmpty(hWnd, E_HOSTNAME))
{
ok = false;
}
if (GetInt(hWnd, C_PORT) == 0)
{
ok = false;
}
SetEnable(hWnd, IDOK, ok);
}
// Proxy server settings dialog c
UINT CmProxyDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
CLIENT_OPTION *a = (CLIENT_OPTION *)param;
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
SetTextA(hWnd, E_HOSTNAME, a->ProxyName);
CbSetHeight(hWnd, C_PORT, 18);
CbAddStr(hWnd, C_PORT, L"8080", 0);
CbAddStr(hWnd, C_PORT, L"1080", 0);
CbAddStr(hWnd, C_PORT, L"80", 0);
CbAddStr(hWnd, C_PORT, L"3128", 0);
CbAddStr(hWnd, C_PORT, L"443", 0);
CbAddStr(hWnd, C_PORT, L"9821", 0);
CbAddStr(hWnd, C_PORT, L"9801", 0);
SetIntEx(hWnd, C_PORT, a->ProxyPort);
SetTextA(hWnd, E_USERNAME, a->ProxyUsername);
SetTextA(hWnd, E_PASSWORD, a->ProxyPassword);
if (a->ProxyPort == 0)
{
if (a->ProxyType == PROXY_HTTP)
{
SetInt(hWnd, C_PORT, 8080);
}
else
{
SetInt(hWnd, C_PORT, 1080);
}
}
CmProxyDlgUpdate(hWnd, a);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case E_HOSTNAME:
case C_PORT:
case E_USERNAME:
case E_PASSWORD:
CmProxyDlgUpdate(hWnd, a);
break;
}
switch (wParam)
{
case IDOK:
GetTxtA(hWnd, E_HOSTNAME, a->ProxyName, sizeof(a->ProxyName));
GetTxtA(hWnd, E_USERNAME, a->ProxyUsername, sizeof(a->ProxyUsername));
GetTxtA(hWnd, E_PASSWORD, a->ProxyPassword, sizeof(a->ProxyPassword));
a->ProxyPort = GetInt(hWnd, C_PORT);
EndDialog(hWnd, true);
break;
case IDCANCEL:
Close(hWnd);
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, false);
break;
}
return 0;
}
// Proxy server settings
bool CmProxyDlg(HWND hWnd, CLIENT_OPTION *a)
{
// Validate arguments
if (a == NULL)
{
return false;
}
return Dialog(hWnd, D_CM_PROXY, CmProxyDlgProc, a);
}
// Get issuer of the specified certificate if it is known
X *CmGetIssuer(X *x)
{
RPC_GET_ISSUER a;
X *ret;
// Validate arguments
if (x == NULL)
{
return NULL;
}
Zero(&a, sizeof(a));
a.x = CloneX(x);
if (CALLEX(cm->hMainWnd, CcGetIssuer(cm->Client, &a)) == 0)
{
ret = CloneX(a.issuer_x);
}
else
{
ret = NULL;
}
CiFreeGetIssuer(&a);
return ret;
}
// Initialize the dialog
void CmLoadXFromFileOrSecureCardDlgInit(HWND hWnd, CM_LOADX *p)
{
UINT current;
// Validate arguments
if (hWnd == NULL || p == NULL)
{
return;
}
current = MsRegReadInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "CertLoadSource");
Check(hWnd, R_FROM_FILE, current == 0);
Check(hWnd, R_FROM_SECURE, current != 0);
SetFont(hWnd, S_INFO, Font(0, true));
CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
}
// Update the dialog control
void CmLoadXFromFileOrSecureCardDlgUpdate(HWND hWnd, CM_LOADX *p)
{
SECURE_DEVICE *dev;
wchar_t tmp[MAX_SIZE];
bool ok = true;
// Validate arguments
if (hWnd == NULL || p == NULL)
{
return;
}
dev = GetSecureDevice(SmGetCurrentSecureIdFromReg());
if (dev == NULL)
{
UniStrCpy(tmp, sizeof(tmp), _UU("SEC_CURRENT_NO_DEVICE"));
}
else
{
UniFormat(tmp, sizeof(tmp), _UU("SEC_CURRENT_DEVICE"), dev->DeviceName);
}
SetText(hWnd, S_INFO, tmp);
if (IsChecked(hWnd, R_FROM_SECURE))
{
if (dev == NULL)
{
ok = false;
}
}
SetEnable(hWnd, IDOK, ok);
SetEnable(hWnd, B_SELECT, IsChecked(hWnd, R_FROM_SECURE));
SetEnable(hWnd, S_CERT, IsChecked(hWnd, R_FROM_SECURE));
SetEnable(hWnd, S_FILE, IsChecked(hWnd, R_FROM_FILE));
}
// Certificate reading selection dialog procedure
UINT CmLoadXFromFileOrSecureCardDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
CM_LOADX *p = (CM_LOADX *)param;
X *x;
UINT current;
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
CmLoadXFromFileOrSecureCardDlgInit(hWnd, p);
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
current = (IsChecked(hWnd, R_FROM_FILE)) ? 0 : 1;
MsRegWriteInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "CertLoadSource", current);
if (current == 0)
{
// From file
if (CmLoadX(hWnd, &x))
{
p->x = x;
EndDialog(hWnd, true);
}
}
else
{
// From the smart card
char name[MAX_SIZE];
// Select the certificate name in the card
if (SmSelectKeyPair(hWnd, name, sizeof(name), NULL, 0))
{
// Read
WINUI_SECURE_BATCH batch[] =
{
{WINUI_SECURE_READ_CERT, name, true, NULL, NULL, NULL, NULL, NULL, NULL},
};
// Do reading
if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), SmGetCurrentSecureIdFromReg(), 0))
{
// Success
p->x = batch[0].OutputX;
EndDialog(hWnd, true);
}
}
}
break;
case IDCANCEL:
Close(hWnd);
break;
case R_FROM_FILE:
CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
break;
case R_FROM_SECURE:
CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
break;
case B_SELECT:
SmSelectSecureId(hWnd);
CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, false);
break;
}
return 0;
}
// Read certificate from a file or a smart card
bool CmLoadXFromFileOrSecureCard(HWND hWnd, X **x)
{
CM_LOADX p;
// Validate arguments
if (x == NULL)
{
return false;
}
Zero(&p, sizeof(p));
if (Dialog(hWnd, D_CM_LOAD_X, CmLoadXFromFileOrSecureCardDlgProc, &p) == false)
{
return false;
}
*x = p.x;
return true;
}
// Read the certificate
bool CmLoadX(HWND hWnd, X **x)
{
return CmLoadXEx(hWnd, x, NULL, 0);
}
bool CmLoadXEx(HWND hWnd, X **x, char *filename, UINT size)
{
wchar_t *filename_w = CopyStrToUni(filename);
bool ret;
ret = CmLoadXExW(hWnd, x, filename_w, size);
Free(filename_w);
return ret;
}
bool CmLoadXExW(HWND hWnd, X **x, wchar_t *filename, UINT size)
{
wchar_t *s;
bool is_p12;
wchar_t tmp[MAX_SIZE];
K *k;
// Validate arguments
if (x == NULL)
{
return false;
}
// Read the certificate
s = OpenDlg(hWnd, _UU("DLG_CERT_OR_P12_FILTER"), _UU("DLG_OPEN_CERT"));
if (s == NULL)
{
return false;
}
UniStrCpy(tmp, sizeof(tmp), s);
if (filename != NULL)
{
UniStrCpy(filename, size, tmp);
}
Free(s);
if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))
{
is_p12 = true;
}
else
{
is_p12 = false;
}
if (is_p12)
{
// Processing of PKCS#12
BUF *b = ReadDumpW(tmp);
P12 *p12;
if (b == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
return false;
}
p12 = BufToP12(b);
if (p12 == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
FreeBuf(b);
return false;
}
if (IsEncryptedP12(p12) == false)
{
if (ParseP12(p12, x, &k, NULL) == false)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
FreeP12(p12);
FreeBuf(b);
return false;
}
}
else
{
char password[MAX_SIZE];
if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)
{
FreeP12(p12);
FreeBuf(b);
return false;
}
else
{
if (ParseP12(p12, x, &k, password) == false)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
FreeP12(p12);
FreeBuf(b);
return false;
}
}
}
FreeP12(p12);
FreeBuf(b);
FreeK(k);
return true;
}
else
{
// Processing of X509
BUF *b = ReadDumpW(tmp);
X *x509;
if (b == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
return false;
}
x509 = BufToX(b, IsBase64(b));
FreeBuf(b);
if (x509 == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_X509_W"), tmp);
return false;
}
*x = x509;
return true;
}
}
// Read the secret key
bool CmLoadK(HWND hWnd, K **k)
{
return CmLoadKEx(hWnd, k, NULL, 0);
}
bool CmLoadKEx(HWND hWnd, K **k, char *filename, UINT size)
{
wchar_t *filename_w = CopyStrToUni(filename);
bool ret;
ret = CmLoadKExW(hWnd, k, filename_w, size);
Free(filename_w);
return ret;
}
bool CmLoadKExW(HWND hWnd, K **k, wchar_t *filename, UINT size)
{
wchar_t *s;
bool is_p12;
wchar_t tmp[MAX_SIZE];
// Validate arguments
if (k == NULL)
{
return false;
}
// Read the certificate
s = OpenDlg(hWnd, _UU("DLG_KEY_OR_P12_FILTER"), _UU("DLG_OPEN_KEY"));
if (s == NULL)
{
return false;
}
UniStrCpy(tmp, sizeof(tmp), s);
Free(s);
if (filename != NULL)
{
UniStrCpy(filename, size, tmp);
}
if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))
{
is_p12 = true;
}
else
{
is_p12 = false;
}
if (is_p12)
{
// Processing of PKCS#12
BUF *b = ReadDumpW(tmp);
P12 *p12;
if (b == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
return false;
}
p12 = BufToP12(b);
if (p12 == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
FreeBuf(b);
return false;
}
if (IsEncryptedP12(p12) == false)
{
X *x;
if (ParseP12(p12, &x, k, NULL) == false)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
FreeP12(p12);
FreeBuf(b);
return false;
}
FreeX(x);
}
else
{
char password[MAX_SIZE];
if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)
{
FreeP12(p12);
FreeBuf(b);
return false;
}
else
{
X *x;
if (ParseP12(p12, &x, k, password) == false)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
FreeP12(p12);
FreeBuf(b);
return false;
}
FreeX(x);
}
}
FreeP12(p12);
FreeBuf(b);
return true;
}
else
{
// Processing of private key
BUF *b = ReadDumpW(tmp);
K *key;
if (b == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
return false;
}
if (IsEncryptedK(b, true) == false)
{
key = BufToK(b, true, IsBase64(b), NULL);
}
else
{
char pass[MAX_SIZE];
if (PassphraseDlg(hWnd, pass, sizeof(pass), b, false) == false)
{
FreeBuf(b);
return false;
}
key = BufToK(b, true, IsBase64(b), pass);
}
if (key == NULL)
{
FreeBuf(b);
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_KEY_W"), tmp);
return false;
}
FreeBuf(b);
*k = key;
return true;
}
}
// Read a set of certificate and private key
bool CmLoadXAndK(HWND hWnd, X **x, K **k)
{
wchar_t *s;
bool is_p12;
wchar_t tmp[MAX_SIZE];
// Validate arguments
if (x == NULL || k == NULL)
{
return false;
}
START_FIRST:
// Read the certificate
s = OpenDlg(hWnd, _UU("DLG_CERT_OR_P12_FILTER"), _UU("DLG_OPEN_CERT"));
if (s == NULL)
{
return false;
}
UniStrCpy(tmp, sizeof(tmp), s);
Free(s);
if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))
{
is_p12 = true;
}
else
{
is_p12 = false;
}
if (is_p12)
{
// Processing of PKCS#12
BUF *b = ReadDumpW(tmp);
P12 *p12;
if (b == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
return false;
}
p12 = BufToP12(b);
if (p12 == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
FreeBuf(b);
return false;
}
if (IsEncryptedP12(p12) == false)
{
if (ParseP12(p12, x, k, NULL) == false)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
FreeP12(p12);
FreeBuf(b);
return false;
}
}
else
{
char password[MAX_SIZE];
if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)
{
FreeP12(p12);
FreeBuf(b);
return false;
}
else
{
if (ParseP12(p12, x, k, password) == false)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
FreeP12(p12);
FreeBuf(b);
return false;
}
}
}
if (CheckXandK(*x, *k) == false)
{
FreeX(*x);
FreeK(*k);
FreeP12(p12);
FreeBuf(b);
if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)
{
goto START_FIRST;
}
return false;
}
FreeP12(p12);
FreeBuf(b);
return true;
}
else
{
// Processing of X509
BUF *b = ReadDumpW(tmp);
X *x509;
K *key;
if (b == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
return false;
}
x509 = BufToX(b, IsBase64(b));
FreeBuf(b);
if (x509 == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_X509_W"), tmp);
return false;
}
// Read the secret key
s = OpenDlg(hWnd, _UU("DLG_KEY_FILTER"), _UU("DLG_OPEN_KEY_WITH_CERT"));
if (s == NULL)
{
FreeX(x509);
return false;
}
UniStrCpy(tmp, sizeof(tmp), s);
Free(s);
b = ReadDumpW(tmp);
if (b == NULL)
{
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
FreeX(x509);
return false;
}
if (IsEncryptedK(b, true) == false)
{
key = BufToK(b, true, IsBase64(b), NULL);
}
else
{
char pass[MAX_SIZE];
if (PassphraseDlg(hWnd, pass, sizeof(pass), b, false) == false)
{
FreeBuf(b);
FreeX(x509);
return false;
}
key = BufToK(b, true, IsBase64(b), pass);
}
if (key == NULL)
{
FreeBuf(b);
FreeX(x509);
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_KEY_W"), tmp);
return false;
}
if (CheckXandK(x509, key) == false)
{
FreeBuf(b);
FreeX(x509);
FreeK(key);
if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)
{
goto START_FIRST;
}
return false;
}
FreeBuf(b);
*x = x509;
*k = key;
return true;
}
}
// Virtual HUB enumeration start
void CmEditAccountDlgStartEnumHub(HWND hWnd, CM_ACCOUNT *a)
{
char server_name[MAX_HOST_NAME_LEN + 1];
UINT old_proxy_type;
// Validate arguments
if (hWnd == NULL || a == NULL)
{
return;
}
if (StrLen(a->ClientOption->Hostname) == 0)
{
return;
}
if (a->ClientOption->Port == 0)
{
return;
}
if (a->ClientOption->ProxyType != PROXY_DIRECT &&
(StrLen(a->ClientOption->ProxyName) == 0 ||
a->ClientOption->ProxyPort == 0))
{
return;
}
GetTxtA(hWnd, E_HOSTNAME, server_name, sizeof(server_name));
if (StrCmpi(server_name, a->old_server_name) == 0)
{
if (CbNum(hWnd, C_HUBNAME) != 0)
{
return;
}
}
else
{
StrCpy(a->old_server_name, sizeof(a->old_server_name), server_name);
CbReset(hWnd, C_HUBNAME);
}
old_proxy_type = a->ClientOption->ProxyType;
if (IsChecked(hWnd, R_DIRECT_TCP))
{
a->ClientOption->ProxyType = PROXY_DIRECT;
}
if (IsChecked(hWnd, R_HTTPS))
{
a->ClientOption->ProxyType = PROXY_HTTP;
}
if (IsChecked(hWnd, R_SOCKS))
{
a->ClientOption->ProxyType = PROXY_SOCKS;
}
CmEnumHubStart(hWnd, a->ClientOption);
a->ClientOption->ProxyType = old_proxy_type;
}
// [OK] button
void CmEditAccountDlgOnOk(HWND hWnd, CM_ACCOUNT *a)
{
RPC_CLIENT_CREATE_ACCOUNT c;
bool b;
// Validate arguments
if (hWnd == NULL || a == NULL)
{
return;
}
if (a->ClientOption->NumRetry != 0 && a->ClientOption->RetryInterval < 5)
{
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_RETRY_INTERVAL_ERROR"));
FocusEx(hWnd, E_RETRY_SPAN);
return;
}
CmEditAccountDlgUpdate(hWnd, a);
if (a->LinkMode == false && a->NatMode == false)
{
// Save the account
Zero(&c, sizeof(c));
c.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
Copy(c.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
c.ClientAuth = CopyClientAuth(a->ClientAuth);
c.CheckServerCert = a->CheckServerCert;
if (a->ServerCert != NULL)
{
c.ServerCert = CloneX(a->ServerCert);
}
c.StartupAccount = a->Startup;
if (a->EditMode == false)
{
b = CALL(hWnd, CcCreateAccount(cm->Client, &c));
}
else
{
b = CALL(hWnd, CcSetAccount(cm->Client, &c));
}
CiFreeClientCreateAccount(&c);
// Check whether this account is currently running
if (b)
{
RPC_CLIENT_GET_CONNECTION_STATUS st;
Zero(&st, sizeof(st));
UniStrCpy(st.AccountName, sizeof(st.AccountName), a->ClientOption->AccountName);
if (CALL(hWnd, CcGetAccountStatus(cm->Client, &st)))
{
if (st.Active)
{
MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_CURRENT_ACTIVE"),
st.AccountName);
}
}
}
if (b)
{
EndDialog(hWnd, true);
}
}
else
{
if (a->LinkMode)
{
// Link mode
RPC_CREATE_LINK t;
Zero(&t, sizeof(t));
StrCpy(t.HubName, sizeof(t.HubName), a->Hub->HubName);
t.Online = a->OnlineFlag;
Copy(&t.Policy, &a->Policy, sizeof(POLICY));
t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
Copy(t.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
t.ClientAuth = CopyClientAuth(a->ClientAuth);
t.CheckServerCert = a->CheckServerCert;
t.ServerCert = CloneX(a->ServerCert);
// Save the settings for cascade connection
if (a->EditMode)
{
if (CALL(hWnd, ScSetLink(a->Hub->Rpc, &t)))
{
if (a->OnlineFlag)
{
MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("SM_LINK_SAVE_ONLINE"), a->ClientOption->AccountName);
}
EndDialog(hWnd, true);
}
}
else
{
if (CALL(hWnd, ScCreateLink(a->Hub->Rpc, &t)))
{
if (a->Link_ConnectNow)
{
RPC_LINK tt;
Zero(&tt, sizeof(tt));
UniStrCpy(tt.AccountName, sizeof(tt.AccountName), a->ClientOption->AccountName);
StrCpy(tt.HubName, sizeof(tt.HubName), a->Hub->HubName);
CALL(hWnd, ScSetLinkOnline(a->Hub->Rpc, &tt));
}
EndDialog(hWnd, true);
}
}
FreeRpcCreateLink(&t);
}
else
{
// NAT mode
RPC_CREATE_LINK t;
Zero(&t, sizeof(t));
t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
Copy(t.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
t.ClientAuth = CopyClientAuth(a->ClientAuth);
if (CALL(hWnd, NcSetClientConfig(a->Rpc, &t)))
{
EndDialog(hWnd, true);
}
FreeRpcCreateLink(&t);
}
}
}
// Show the account editing dialog
bool CmEditAccountDlg(HWND hWnd, CM_ACCOUNT *a)
{
// Validate arguments
if (hWnd == NULL || a == NULL)
{
return false;
}
return Dialog(hWnd, D_CM_ACCOUNT, CmEditAccountDlgProc, a);
}
// Edit the account
void CmEditAccount(HWND hWnd, wchar_t *account_name)
{
CM_ACCOUNT *a;
// Validate arguments
if (hWnd == NULL || account_name == NULL)
{
return;
}
a = CmGetExistAccountObject(hWnd, account_name);
if (a == NULL)
{
return;
}
CmVoice("input_config");
if (CmEditAccountDlg(hWnd, a))
{
CmVoice("set_config");
}
CmFreeAccountObject(hWnd, a);
}
// Create an account
void CmNewAccount(HWND hWnd)
{
CM_ACCOUNT *a;
RPC_CLIENT_ENUM_VLAN t;
UINT num_vlan = 0;
// Validate arguments
if (hWnd == NULL)
{
return;
}
if (IsEnable(hWnd, 0) == false)
{
return;
}
Zero(&t, sizeof(t));
if (CcEnumVLan(cm->Client, &t) == ERR_NO_ERROR)
{
num_vlan = t.NumItem;
CiFreeClientEnumVLan(&t);
}
if (num_vlan == 0)
{
if (MsgBox(hWnd, MB_ICONINFORMATION | MB_YESNO, _UU("CM_NO_VLAN")) == IDNO)
{
return;
}
else
{
if (cm->server_name == NULL || cm->Client->Unix)
{
Command(hWnd, CMD_NEW_VLAN);
return;
}
else
{
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_VLAN_REMOTE_ERROR"));
}
return;
}
}
a = CmCreateNewAccountObject(hWnd);
if (a == NULL)
{
return;
}
CmVoice("input_config");
if (CmEditAccountDlg(hWnd, a))
{
CmVoice("new_config");
}
CmFreeAccountObject(hWnd, a);
}
// Release the account object
void CmFreeAccountObject(HWND hWnd, CM_ACCOUNT *a)
{
// Validate arguments
if (hWnd == NULL || a == NULL)
{
return;
}
Free(a->ClientOption);
CiFreeClientAuth(a->ClientAuth);
if (a->ServerCert != NULL)
{
FreeX(a->ServerCert);
}
Free(a);
}
// Get an existing account object
CM_ACCOUNT *CmGetExistAccountObject(HWND hWnd, wchar_t *account_name)
{
RPC_CLIENT_GET_ACCOUNT c;
CM_ACCOUNT *a;
// Validate arguments
if (hWnd == NULL)
{
return NULL;
}
Zero(&c, sizeof(c));
UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);
if (CALL(hWnd, CcGetAccount(cm->Client, &c)) == false)
{
return NULL;
}
a = ZeroMalloc(sizeof(CM_ACCOUNT));
a->EditMode = true;
a->CheckServerCert = c.CheckServerCert;
a->Startup = c.StartupAccount;
if (c.ServerCert != NULL)
{
a->ServerCert = CloneX(c.ServerCert);
}
a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
Copy(a->ClientOption, c.ClientOption, sizeof(CLIENT_OPTION));
a->ClientAuth = CopyClientAuth(c.ClientAuth);
Copy(a->ShortcutKey, c.ShortcutKey, SHA1_SIZE);
CiFreeClientGetAccount(&c);
a->LockMode = cm->CmSetting.LockMode;
return a;
}
// Create a new account object
CM_ACCOUNT *CmCreateNewAccountObject(HWND hWnd)
{
CM_ACCOUNT *a;
// Validate arguments
if (hWnd == NULL)
{
return NULL;
}
a = ZeroMalloc(sizeof(CM_ACCOUNT));
a->EditMode = false;
a->CheckServerCert = false;
a->Startup = false;
a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
// Initialize the client options
CmGenerateNewAccountName(hWnd, a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName));
a->ClientOption->Port = 443; // Default port number
a->ClientOption->NumRetry = INFINITE;
a->ClientOption->RetryInterval = 15;
a->ClientOption->MaxConnection = 1;
a->ClientOption->HalfConnection = false;
a->ClientOption->UseEncrypt = true;
a->ClientOption->AdditionalConnectionInterval = 1;
if (cm->Client->Unix)
{
a->ClientOption->NoRoutingTracking = true;
}
a->ClientAuth = ZeroMalloc(sizeof(CLIENT_AUTH));
// Password authentication
a->ClientAuth->AuthType = CLIENT_AUTHTYPE_PASSWORD;
return a;
}
// Create an imported account name
void CmGenerateImportName(HWND hWnd, wchar_t *name, UINT size, wchar_t *old_name)
{
UINT i;
// Validate arguments
if (name == NULL || hWnd == NULL)
{
return;
}
for (i = 1;;i++)
{
wchar_t tmp[MAX_SIZE];
if (i == 1)
{
UniFormat(tmp, sizeof(tmp), _UU("CM_IMPORT_NAME_1"), old_name);
}
else
{
UniFormat(tmp, sizeof(tmp), _UU("CM_IMPORT_NAME_2"), old_name, i);
}
if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)
{
UniStrCpy(name, size, tmp);
return;
}
}
}
// Create a copy name
void CmGenerateCopyName(HWND hWnd, wchar_t *name, UINT size, wchar_t *old_name)
{
UINT i;
// Validate arguments
if (name == NULL || hWnd == NULL)
{
return;
}
for (i = 1;;i++)
{
wchar_t tmp[MAX_SIZE];
if (i == 1)
{
UniFormat(tmp, sizeof(tmp), _UU("CM_COPY_NAME_1"), old_name);
}
else
{
UniFormat(tmp, sizeof(tmp), _UU("CM_COPY_NAME_2"), i, old_name);
}
if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)
{
UniStrCpy(name, size, tmp);
return;
}
}
}
// Create a new account name
void CmGenerateNewAccountName(HWND hWnd, wchar_t *name, UINT size)
{
UINT i;
// Validate arguments
if (name == NULL || hWnd == NULL)
{
return;
}
for (i = 1;;i++)
{
wchar_t tmp[MAX_SIZE];
if (i == 1)
{
UniFormat(tmp, sizeof(tmp), _UU("CM_NEW_ACCOUNT_NAME_1"));
}
else
{
UniFormat(tmp, sizeof(tmp), _UU("CM_NEW_ACCOUNT_NAME_2"), i);
}
if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)
{
UniStrCpy(name, size, tmp);
return;
}
}
}
// Show the policy list
void CmPolicyDlgPrint(HWND hWnd, CM_POLICY *p)
{
CmPolicyDlgPrintEx(hWnd, p, false);
}
void CmPolicyDlgPrintEx(HWND hWnd, CM_POLICY *p, bool cascade_mode)
{
CmPolicyDlgPrintEx2(hWnd, p, cascade_mode, POLICY_CURRENT_VERSION);
}
void CmPolicyDlgPrintEx2(HWND hWnd, CM_POLICY *p, bool cascade_mode, UINT ver)
{
POLICY *pol;
UINT i;
LVB *b;
// Validate arguments
if (hWnd == NULL || p == NULL)
{
return;
}
pol = p->Policy;
b = LvInsertStart();
for (i = 0;i < NUM_POLICY_ITEM;i++)
{
wchar_t tmp[MAX_SIZE];
if (cascade_mode)
{
if (PolicyIsSupportedForCascade(i) == false)
{
continue;
}
}
if (IS_POLICY_FOR_CURRENT_VER(i, ver))
{
if (policy_item[i].TypeInt == false)
{
// bool type
UniStrCpy(tmp, sizeof(tmp), POLICY_BOOL(pol, i) ? _UU("POL_BOOL_ENABLE") : (p->Extension ? _UU("POL_BOOL_DISABLE_EX") : _UU("POL_BOOL_DISABLE")));
}
else
{
// int type
if (policy_item[i].AllowZero && POLICY_INT(pol, i) == 0)
{
UniStrCpy(tmp, sizeof(tmp), _UU("POL_INT_ZERO"));
}
else
{
UniFormat(tmp, sizeof(tmp), _UU(policy_item[i].FormatStr), POLICY_INT(pol, i));
}
}
LvInsertAdd(b, ICO_MACHINE, (void *)i, 2, GetPolicyTitle(i), tmp);
}
}
LvInsertEnd(b, hWnd, L_POLICY);
}
// Policy list dialog box
UINT CmPolicyDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
CM_POLICY *p = (CM_POLICY *)param;
NMHDR *n;
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
FormatText(hWnd, 0, p->AccountName);
FormatText(hWnd, S_TITLE, p->AccountName);
p->hWnd = hWnd;
if (p->CmStatus != NULL)
{
p->CmStatus->hWndPolicy = hWnd;
}
// Initialize the column
LvInit(hWnd, L_POLICY);
LvInsertColumn(hWnd, L_POLICY, 0, _UU("POL_TITLE_STR"), 375);
LvInsertColumn(hWnd, L_POLICY, 1, _UU("POL_VALUE_STR"), 100);
// Display
CmPolicyDlgPrint(hWnd, p);
// Select the first
LvSelect(hWnd, L_POLICY, 0);
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
case IDCANCEL:
Close(hWnd);
break;
}
break;
case WM_NOTIFY:
n = (NMHDR *)lParam;
switch (n->idFrom)
{
case L_POLICY:
switch (n->code)
{
case LVN_ITEMCHANGED:
// Change selection
if (LvIsSelected(hWnd, L_POLICY) == false)
{
SetText(hWnd, S_DESCRIPTION, L"");
}
else
{
UINT index = LvGetSelected(hWnd, L_POLICY);
UINT id = (UINT)LvGetParam(hWnd, L_POLICY, index);
if (id < NUM_POLICY_ITEM)
{
SetText(hWnd, S_DESCRIPTION, GetPolicyDescription(id));
}
}
break;
}
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, 0);
break;
}
LvSortHander(hWnd, msg, wParam, lParam, L_POLICY);
return 0;
}
// Show the policy list dialog
void CmPolicyDlg(HWND hWnd, CM_STATUS *st)
{
RPC_CLIENT_GET_CONNECTION_STATUS s;
POLICY *policy;
CM_POLICY cp;
// Validate arguments
if (hWnd == NULL || st == NULL)
{
return;
}
// Get the policy
Zero(&s, sizeof(s));
UniStrCpy(s.AccountName, sizeof(s.AccountName), st->AccountName);
if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)
{
return;
}
if (s.Active == false)
{
return;
}
policy = &s.Policy;
Zero(&cp, sizeof(cp));
UniStrCpy(cp.AccountName, sizeof(cp.AccountName), st->AccountName);
cp.Policy = policy;
cp.CmStatus = st;
Dialog(hWnd, D_CM_POLICY, CmPolicyDlgProc, &cp);
st->hWndPolicy = NULL;
CiFreeClientGetConnectionStatus(&s);
}
// Show the certificate
void CmStatusDlgPrintCert(HWND hWnd, CM_STATUS *st, bool server)
{
RPC_CLIENT_GET_CONNECTION_STATUS s;
X *x, *issuer;
// Validate arguments
if (hWnd == NULL || st == NULL)
{
return;
}
// Get the latest information
Zero(&s, sizeof(s));
UniStrCpy(s.AccountName, sizeof(s.AccountName), st->AccountName);
if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)
{
Close(hWnd);
return;
}
if (s.Active == false)
{
// Disconnect
Close(hWnd);
return;
}
if (server == false)
{
// Show the client certificate
x = s.ClientX;
}
else
{
// Show the server certificate
x = s.ServerX;
}
cm->WindowCount++;
issuer = CmGetIssuer(x);
CertDlg(hWnd, x, issuer, true);
FreeX(issuer);
cm->WindowCount--;
CiFreeClientGetConnectionStatus(&s);
}
// Show the information of the status dialog
void CmStatusDlgPrint(HWND hWnd, CM_STATUS *cmst)
{
RPC_CLIENT_GET_CONNECTION_STATUS s;
LVB *b;
// Validate arguments
if (hWnd == NULL || cmst == NULL)
{
return;
}
// Get the latest information
Zero(&s, sizeof(s));
UniStrCpy(s.AccountName, sizeof(s.AccountName), cmst->AccountName);
if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)
{
Close(hWnd);
return;
}
if (s.Active == false)
{
// Disconnect
Close(hWnd);
return;
}
// Show the status in the list box in the status dialog
b = LvInsertStart();
CmPrintStatusToListView(b, &s);
LvInsertEnd(b, hWnd, L_STATUS);
LvAutoSize(hWnd, L_STATUS);
SetEnable(hWnd, B_POLICY, s.Connected);
SetEnable(hWnd, B_SERVER_CERT, s.ServerX != NULL);
SetEnable(hWnd, B_CLIENT_CERT, s.ClientX != NULL);
CiFreeClientGetConnectionStatus(&s);
}
// Show the status in the list box in the status dialog
void CmPrintStatusToListView(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s)
{
CmPrintStatusToListViewEx(b, s, false);
}
void CmPrintStatusToListViewEx(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s, bool server_mode)
{
wchar_t tmp[MAX_SIZE];
char str[MAX_SIZE];
char vv[128];
// Validate arguments
if (b == NULL || s == NULL)
{
return;
}
if (server_mode == false)
{
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_ACCOUNT_NAME"), s->AccountName);
if (s->Connected == false)
{
wchar_t *st = _UU("CM_ST_CONNECTED_FALSE");
switch (s->SessionStatus)
{
case CLIENT_STATUS_CONNECTING:
st = _UU("CM_ST_CONNECTING");
break;
case CLIENT_STATUS_NEGOTIATION:
st = _UU("CM_ST_NEGOTIATION");
break;
case CLIENT_STATUS_AUTH:
st = _UU("CM_ST_AUTH");
break;
case CLIENT_STATUS_ESTABLISHED:
st = _UU("CM_ST_ESTABLISHED");
break;
case CLIENT_STATUS_RETRY:
st = _UU("CM_ST_RETRY");
break;
case CLIENT_STATUS_IDLE:
st = _UU("CM_ST_IDLE");
break;
}
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CONNECTED"), st);
}
else
{
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CONNECTED"), _UU("CM_ST_CONNECTED_TRUE"));
}
}
if (s->Connected)
{
if (s->VLanId == 0)
{
UniStrCpy(tmp, sizeof(tmp), _UU("CM_ST_NO_VLAN"));
}
else
{
UniToStru(tmp, s->VLanId);
}
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_VLAN_ID"), tmp);
if (server_mode == false)
{
StrToUni(tmp, sizeof(tmp), s->ServerName);
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_NAME"), tmp);
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_PORT_TCP"), s->ServerPort);
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_PORT"), tmp);
}
StrToUni(tmp, sizeof(tmp), s->ServerProductName);
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_NAME"), tmp);
UniFormat(tmp, sizeof(tmp), L"%u.%02u", s->ServerProductVer / 100, s->ServerProductVer % 100);
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_VER"), tmp);
UniFormat(tmp, sizeof(tmp), L"Build %u", s->ServerProductBuild);
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_BUILD"), tmp);
}
GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->StartTime), NULL);
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_START_TIME"), tmp);
GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->FirstConnectionEstablisiedTime), NULL);
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_FIRST_ESTAB_TIME"), s->FirstConnectionEstablisiedTime == 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->NumConnectionsEatablished);
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_insteted_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_insteted_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_insteted_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