1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Cedar Communication Module
3 //
4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
5 //
6 // Copyright (c) Daiyuu Nobori.
7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
8 // Copyright (c) SoftEther Corporation.
9 // Copyright (c) all contributors on SoftEther VPN project in GitHub.
10 //
11 // All Rights Reserved.
12 //
13 // http://www.softether.org/
14 //
15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
17 // Contributors:
18 // - ELIN (https://github.com/el1n)
19 //
20 // License: The Apache License, Version 2.0
21 // https://www.apache.org/licenses/LICENSE-2.0
22 //
23 // DISCLAIMER
24 // ==========
25 //
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 // SOFTWARE.
33 //
34 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
35 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
36 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
37 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
38 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
39 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
40 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
41 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
42 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
43 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
44 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
45 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
46 // LAW OR COURT RULE.
47 //
48 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
49 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
50 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
51 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
52 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
53 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
54 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
55 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
56 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
57 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
58 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
59 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
60 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
61 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
62 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
63 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
64 // STATEMENT FOR WARNING AND DISCLAIMER.
65 //
66 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
67 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
68 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
69 //
70 //
71 // SOURCE CODE CONTRIBUTION
72 // ------------------------
73 //
74 // Your contribution to SoftEther VPN Project is much appreciated.
75 // Please send patches to us through GitHub.
76 // Read the SoftEther VPN Patch Acceptance Policy in advance:
77 // http://www.softether.org/5-download/src/9.patch
78 //
79 //
80 // DEAR SECURITY EXPERTS
81 // ---------------------
82 //
83 // If you find a bug or a security vulnerability please kindly inform us
84 // about the problem immediately so that we can fix the security problem
85 // to protect a lot of users around the world as soon as possible.
86 //
87 // Our e-mail address for security reports is:
88 // softether-vpn-security [at] softether.org
89 //
90 // Please note that the above e-mail address is not a technical support
91 // inquiry address. If you need technical assistance, please visit
92 // http://www.softether.org/ and ask your question on the users forum.
93 //
94 // Thank you for your cooperation.
95 //
96 //
97 // NO MEMORY OR RESOURCE LEAKS
98 // ---------------------------
99 //
100 // The memory-leaks and resource-leaks verification under the stress
101 // test has been passed before release this source code.
102
103
104 // CM.c
105 // VPN Client Connection Manager for Win32
106
107 #include <GlobalConst.h>
108
109 #ifdef WIN32
110
111 #define CM_C
112 #define SM_C
113 #define MICROSOFT_C
114
115 #define _WIN32_WINNT 0x0502
116 #define WINVER 0x0502
117 #include <winsock2.h>
118 #include <windows.h>
119 #include <Iphlpapi.h>
120 #include <tlhelp32.h>
121 #include <shlobj.h>
122 #include <commctrl.h>
123 #include <Dbghelp.h>
124 #include <setupapi.h>
125 #include <regstr.h>
126 #include <process.h>
127 #include <psapi.h>
128 #include <wtsapi32.h>
129 #include <Ntsecapi.h>
130 #include <stdio.h>
131 #include <stdlib.h>
132 #include <string.h>
133 #include <wchar.h>
134 #include <stdarg.h>
135 #include <time.h>
136 #include <errno.h>
137 #include <Mayaqua/Mayaqua.h>
138 #include <Cedar/Cedar.h>
139 #include "CMInner.h"
140 #include "SMInner.h"
141 #include "NMInner.h"
142 #include "EMInner.h"
143 #include "../PenCore/resource.h"
144
145
146 // Get the proxy server settings from the registry string of IE
CmGetProxyServerNameAndPortFromIeProxyRegStr(char * name,UINT name_size,UINT * port,char * str,char * server_type)147 bool CmGetProxyServerNameAndPortFromIeProxyRegStr(char *name, UINT name_size, UINT *port, char *str, char *server_type)
148 {
149 TOKEN_LIST *t;
150 UINT i;
151 bool ret = false;
152 // Validate arguments
153 if (name == NULL || port == NULL || str == NULL || server_type == NULL)
154 {
155 return false;
156 }
157
158 t = ParseToken(str, ";");
159
160 for (i = 0;i < t->NumTokens;i++)
161 {
162 char *s = t->Token[i];
163 UINT i;
164
165 Trim(s);
166
167 i = SearchStrEx(s, "=", 0, false);
168 if (i != INFINITE)
169 {
170 char tmp[MAX_PATH];
171
172 StrCpy(name, name_size, s);
173 name[i] = 0;
174
175 if (StrCmpi(name, server_type) == 0)
176 {
177 char *host;
178 StrCpy(tmp, sizeof(tmp), s + i + 1);
179
180 if (ParseHostPort(tmp, &host, port, 0))
181 {
182 StrCpy(name, name_size, host);
183 Free(host);
184
185 if (*port != 0)
186 {
187 ret = true;
188 }
189 break;
190 }
191 }
192 }
193 }
194
195 FreeToken(t);
196
197 return ret;
198 }
199
200
201 // Reflect the contents of the proxy settings to the connection settings
CmProxyDlgSet(HWND hWnd,CLIENT_OPTION * o,CM_INTERNET_SETTING * setting)202 void CmProxyDlgSet(HWND hWnd, CLIENT_OPTION *o, CM_INTERNET_SETTING *setting)
203 {
204 // Validate arguments
205 if(hWnd == NULL || setting == NULL)
206 {
207 return;
208 }
209
210 // Make check in check-box
211 Check(hWnd, R_DIRECT_TCP, setting->ProxyType == PROXY_DIRECT);
212 Check(hWnd, R_HTTPS, setting->ProxyType == PROXY_HTTP);
213 Check(hWnd, R_SOCKS, setting->ProxyType == PROXY_SOCKS);
214
215 // Proxy Settings
216 if(setting->ProxyType != PROXY_DIRECT)
217 {
218 StrCpy(o->ProxyName, sizeof(setting->ProxyHostName), setting->ProxyHostName);
219 o->ProxyPort = setting->ProxyPort;
220 }
221 }
222
223 // Get the proxy settings of IE
CmGetSystemInternetSetting(CM_INTERNET_SETTING * setting)224 void CmGetSystemInternetSetting(CM_INTERNET_SETTING *setting)
225 {
226 bool use_proxy;
227 // Validate arguments
228 if (setting == NULL)
229 {
230 return;
231 }
232
233 Zero(setting, sizeof(CM_INTERNET_SETTING));
234
235 use_proxy = MsRegReadInt(REG_CURRENT_USER,
236 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
237 "ProxyEnable");
238
239 if (use_proxy)
240 {
241 char *str = MsRegReadStr(REG_CURRENT_USER,
242 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
243 "ProxyServer");
244 if (str != NULL)
245 {
246 char name[MAX_HOST_NAME_LEN + 1];
247 UINT port;
248
249 if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),
250 &port, str, "https"))
251 {
252 setting->ProxyType = PROXY_HTTP;
253 StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);
254 setting->ProxyPort = port;
255 }
256 else if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),
257 &port, str, "http"))
258 {
259 setting->ProxyType = PROXY_HTTP;
260 StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);
261 setting->ProxyPort = port;
262 }
263 else if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),
264 &port, str, "socks"))
265 {
266 setting->ProxyType = PROXY_SOCKS;
267 StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);
268 setting->ProxyPort = port;
269 }
270 else
271 {
272 if (SearchStrEx(str, "=", 0, false) == INFINITE)
273 {
274 char *host;
275 UINT port;
276 if (ParseHostPort(str, &host, &port, 0))
277 {
278 if (port != 0)
279 {
280 setting->ProxyType = PROXY_HTTP;
281 StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), host);
282 setting->ProxyPort = port;
283 }
284 Free(host);
285 }
286 }
287 }
288
289 Free(str);
290 }
291 }
292 }
293
294 // For the proxy settings to go through, use the IE settings
CmProxyDlgUseForIE(HWND hWnd,CLIENT_OPTION * o)295 void CmProxyDlgUseForIE(HWND hWnd, CLIENT_OPTION *o)
296 {
297 CM_INTERNET_SETTING s;
298
299 // Validate arguments
300 if(hWnd == NULL)
301 {
302 return;
303 }
304
305 Zero(&s, sizeof(s));
306 CmGetSystemInternetSetting(&s);
307
308 CmProxyDlgSet(hWnd, o, &s);
309 }
310
311 // Determine the bitmap ID of the smart card authentication screen
CmGetSecureBitmapId(char * dest_hostname)312 UINT CmGetSecureBitmapId(char *dest_hostname)
313 {
314 // Validate arguments
315 if (dest_hostname == NULL)
316 {
317 return 0;
318 }
319
320 if (EndWith(dest_hostname, ".cc.tsukuba.ac.jp"))
321 {
322 return BMP_TSUKUBA;
323 }
324
325 return 0;
326 }
327
328 // Activate the window of UAC
CmSetUacWindowActive()329 void CmSetUacWindowActive()
330 {
331 HWND hWnd;
332
333 if (MsIsVista() == false)
334 {
335 return;
336 }
337
338 hWnd = FindWindowA("$$$Secure UAP Dummy Window Class For Interim Dialog", NULL);
339 if (hWnd == NULL)
340 {
341 return;
342 }
343
344 SwitchToThisWindow(hWnd, true);
345 }
346
347 // UAC helper thread
CmUacHelperThread(THREAD * thread,void * param)348 void CmUacHelperThread(THREAD *thread, void *param)
349 {
350 CM_UAC_HELPER *c = (CM_UAC_HELPER *)param;
351 // Validate arguments
352 if (c == NULL)
353 {
354 return;
355 }
356
357 while (c->Halt == false)
358 {
359 CmSetUacWindowActive();
360
361 Wait(c->HaltEvent, 200);
362 }
363 }
364
365 // Start the UAC helper
CmStartUacHelper()366 void *CmStartUacHelper()
367 {
368 CM_UAC_HELPER *c = ZeroMalloc(sizeof(CM_UAC_HELPER));
369
370 c->HaltEvent = NewEvent();
371 c->Thread = NewThread(CmUacHelperThread, c);
372
373 return (void *)c;
374 }
375
376 // Stop the UAC helper
CmStopUacHelper(void * p)377 void CmStopUacHelper(void *p)
378 {
379 CM_UAC_HELPER *c = (CM_UAC_HELPER *)p;
380 // Validate arguments
381 if (c == NULL)
382 {
383 return;
384 }
385
386 c->Halt = true;
387 Set(c->HaltEvent);
388 WaitThread(c->Thread, INFINITE);
389 ReleaseEvent(c->HaltEvent);
390 ReleaseThread(c->Thread);
391
392 Free(c);
393 }
394
395 // Command invocation of the simple connection manager
CmEasyDlgOnCommand(HWND hWnd,CM_EASY_DLG * d,WPARAM wParam,LPARAM lParam)396 void CmEasyDlgOnCommand(HWND hWnd, CM_EASY_DLG *d, WPARAM wParam, LPARAM lParam)
397 {
398 // Validate arguments
399 if (hWnd == NULL || d == NULL)
400 {
401 return;
402 }
403
404 switch (wParam)
405 {
406 case B_MODE:
407 Command(hWnd, CMD_CM_SETTING);
408 return;
409
410 case B_STATUS:
411 Command(hWnd, CMD_STATUS);
412 return;
413
414 case IDCANCEL:
415 Close(hWnd);
416 return;
417
418 }
419
420 if (wParam == CMD_CONNECT)
421 {
422 cm->ConnectStartedFlag = false;
423 }
424
425 CmMainWindowOnCommandEx(hWnd, wParam, lParam, true);
426
427 if (wParam == CMD_CONNECT && cm->ConnectStartedFlag)
428 {
429 // Close the window when the connection started successfully
430 Close(hWnd);
431 }
432 }
433
434 // Keyboard pressing of the simple connection manager
CmEasyDlgOnKey(HWND hWnd,CM_EASY_DLG * d,bool ctrl,bool alt,UINT key)435 void CmEasyDlgOnKey(HWND hWnd, CM_EASY_DLG *d, bool ctrl, bool alt, UINT key)
436 {
437 // Validate arguments
438 if (hWnd == NULL)
439 {
440 return;
441 }
442
443 // Single key
444 switch (key)
445 {
446 case VK_RETURN:
447 Command(hWnd, IDOK);
448 break;
449 case VK_DELETE:
450 // Delete
451 if (IsFocus(hWnd, L_ACCOUNT))
452 {
453 // Operation on the account list
454 Command(hWnd, CMD_DELETE);
455 }
456 else
457 {
458 // Operation on the virtual LAN card list
459 Command(hWnd, CMD_DELETE_VLAN);
460 }
461 break;
462 case VK_F2:
463 // Change the name
464 Command(hWnd, CMD_RENAME);
465 break;
466 case VK_F5:
467 // Update the status
468 Command(hWnd, CMD_REFRESH);
469 break;
470 }
471
472 if (alt)
473 {
474 switch (key)
475 {
476 case 'Q':
477 // Close
478 Command(hWnd, CMD_QUIT);
479 break;
480 }
481 }
482
483 if (ctrl)
484 {
485 switch (key)
486 {
487 case 'G':
488 // Smart Card Manager
489 Command(hWnd, CMD_SECURE_MANAGER);
490 break;
491 case 'S':
492 // Show the status
493 Command(hWnd, CMD_STATUS);
494 break;
495 case 'I':
496 // Disconnect all connections
497 Command(hWnd, CMD_DISCONNECT_ALL);
498 break;
499 case 'D':
500 // Disconnect
501 Command(hWnd, CMD_DISCONNECT);
502 break;
503 case 'N':
504 // Create a new connection setting
505 Command(hWnd, CMD_NEW);
506 break;
507 case 'C':
508 // Creating a copy
509 Command(hWnd, CMD_CLONE);
510 break;
511 case 'T':
512 // Set to start-up connection
513 Command(hWnd, CMD_STARTUP);
514 break;
515 case 'A':
516 // Select all
517 Command(hWnd, CMD_SELECT_ALL);
518 break;
519 case 'L':
520 // Create a new virtual LAN card
521 Command(hWnd, CMD_NEW_VLAN);
522 break;
523 case 'P':
524 // Set the password
525 Command(hWnd, CMD_PASSWORD);
526 break;
527 case 'O':
528 // Option settings
529 Command(hWnd, CMD_TRAFFIC);
530 break;
531 case 'R':
532 // Certificate management
533 Command(hWnd, CMD_TRUST);
534 break;
535 case 'Q':
536 // Throughput
537 Command(hWnd, CMD_TRAFFIC);
538 break;
539 }
540 }
541 }
542
543 // Operation on the list view of the simple connection manager
CmEasyDlgOnNotify(HWND hWnd,CM_EASY_DLG * d,NMHDR * n)544 void CmEasyDlgOnNotify(HWND hWnd, CM_EASY_DLG *d, NMHDR *n)
545 {
546 NMLVDISPINFOW *disp_info;
547 NMLVKEYDOWN *key;
548
549 // Validate arguments
550 if (hWnd == NULL || n == NULL)
551 {
552 return;
553 }
554
555 switch (n->idFrom)
556 {
557 case L_ACCOUNT:
558 switch (n->code)
559 {
560 case LVN_ITEMCHANGED:
561 CmEasyDlgUpdate(hWnd, d);
562 break;
563 case NM_DBLCLK:
564 // Double click
565 Command(hWnd, CMD_EASY_DBLCLICK);
566 break;
567 case NM_RCLICK:
568 // Right click
569 CmAccountListRightClick(hWnd);
570 break;
571 case LVN_ENDLABELEDITW:
572 // Change the name
573 disp_info = (NMLVDISPINFOW *)n;
574 if (disp_info->item.pszText != NULL)
575 {
576 wchar_t *new_name = disp_info->item.pszText;
577 wchar_t *old_name = LvGetStr(hWnd, L_ACCOUNT, disp_info->item.iItem, 0);
578
579 if (old_name != NULL)
580 {
581 if (UniStrCmp(new_name, old_name) != 0 && UniIsEmptyStr(new_name) == false)
582 {
583 RPC_RENAME_ACCOUNT a;
584 Zero(&a, sizeof(a));
585 UniStrCpy(a.OldName, sizeof(a.OldName), old_name);
586 UniStrCpy(a.NewName, sizeof(a.NewName), new_name);
587 if (CALL(hWnd, CcRenameAccount(cm->Client, &a)))
588 {
589 LvSetItem(hWnd, L_ACCOUNT, disp_info->item.iItem, 0, new_name);
590 }
591 }
592
593 Free(old_name);
594 }
595 }
596 break;
597 case LVN_KEYDOWN:
598 // Key-press
599 key = (NMLVKEYDOWN *)n;
600 if (key != NULL)
601 {
602 bool ctrl, alt;
603 UINT code = key->wVKey;
604 ctrl = (GetKeyState(VK_CONTROL) & 0x8000) == 0 ? false : true;
605 alt = (GetKeyState(VK_MENU) & 0x8000) == 0 ? false : true;
606 CmEasyDlgOnKey(hWnd, d, ctrl, alt, code);
607 }
608 break;
609 }
610 break;
611 }
612 }
613
614 // Send an update notification to the Simple Connection Manager
CmRefreshEasy()615 void CmRefreshEasy()
616 {
617 if (cm->hEasyWnd == NULL)
618 {
619 return;
620 }
621
622 SendMessage(cm->hEasyWnd, WM_CM_EASY_REFRESH, 0, 0);
623 }
624
625 // Initialze the Simple Connect Manager
CmEasyDlgInit(HWND hWnd,CM_EASY_DLG * d)626 void CmEasyDlgInit(HWND hWnd, CM_EASY_DLG *d)
627 {
628 HFONT hFontForList;
629 HFONT hFontButton;
630 HFONT hFontTitle;
631 HFONT hFontInfo;
632 HFONT hFontOther;
633 UINT i, num, num2, j;
634 bool b = false;
635 char *font_name = NULL;
636 bool font_bold = true;
637 // Validate arguments
638 if (hWnd == NULL || d == NULL)
639 {
640 return;
641 }
642
643 SetIcon(hWnd, 0, ICO_VPN);
644
645 // Window handle registration
646 cm->hEasyWnd = hWnd;
647
648 // Show in the center
649 Center(hWnd);
650
651 // Update the account list
652 CmInitAccountListEx(hWnd, true);
653
654 // Font settings of the list
655 if (cm->VistaStyle)
656 {
657 if (_GETLANG() == 0)
658 {
659 font_name = "Meiryo";
660 font_bold = false;
661 }
662 else if (_GETLANG() == 2)
663 {
664 font_name = "Microsoft YaHei";
665 font_bold = false;
666 }
667 }
668
669 hFontForList = GetFont(font_name, 14, font_bold, false, false, false);
670 hFontButton = GetFont(font_name, 13, font_bold, false, false, false);
671 hFontTitle = GetFont(font_name, 14, font_bold, false, false, false);
672 hFontInfo = GetFont(font_name, 11, font_bold, false, false, false);
673 hFontOther = GetDialogDefaultFont();
674
675 if (cm->VistaStyle)
676 {
677 hFontOther = GetMeiryoFont();
678 }
679
680 SetFont(hWnd, L_ACCOUNT, hFontForList);
681 SetFont(hWnd, IDOK, hFontButton);
682 SetFont(hWnd, S_TITLE, hFontTitle);
683 SetFont(hWnd, S_INFO, hFontInfo);
684 SetFont(hWnd, B_MODE, hFontOther);
685 SetFont(hWnd, IDCANCEL, hFontOther);
686 SetFont(hWnd, B_VGC, hFontOther);
687
688 SetShow(hWnd, B_VGC, cm->Client->IsVgcSupported);
689
690 CmEasyDlgRefresh(hWnd, d);
691
692 num = LvNum(hWnd, L_ACCOUNT);
693 num2 = 0;
694 j = 0;
695 for (i = 0;i < num;i++)
696 {
697 wchar_t *str = LvGetStr(hWnd, L_ACCOUNT, i, 1);
698
699 if (str != NULL)
700 {
701 if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)
702 {
703 num2++;
704 j = i;
705 }
706 Free(str);
707 }
708 }
709
710 if (num2 == 1)
711 {
712 LvSelect(hWnd, L_ACCOUNT, j);
713 b = true;
714 }
715
716 if (b == false)
717 {
718 if (UniIsEmptyStr(cm->EasyLastSelectedAccountName) == false)
719 {
720 i = LvSearchStr(hWnd, L_ACCOUNT, 0, cm->EasyLastSelectedAccountName);
721 if (i != INFINITE)
722 {
723 LvSelect(hWnd, L_ACCOUNT, i);
724 b = true;
725 }
726 }
727 }
728
729 if (b == false)
730 {
731 if (LvNum(hWnd, L_ACCOUNT) != 0)
732 {
733 LvSelect(hWnd, L_ACCOUNT, 0);
734 }
735 }
736
737 Focus(hWnd, L_ACCOUNT);
738
739 CmEasyDlgUpdate(hWnd, d);
740 }
741
742 // Update the Simple Connection Manager control
CmEasyDlgUpdate(HWND hWnd,CM_EASY_DLG * d)743 void CmEasyDlgUpdate(HWND hWnd, CM_EASY_DLG *d)
744 {
745 bool ok = true;
746 bool show_status = false;
747 wchar_t *button_str = _UU("CM_EASY_CONNECT_BUTTON_1");
748 wchar_t *info_str = _UU("CM_EASY_INFO_1");
749 wchar_t *title_str = _UU("CM_EASY_TITLE");
750 // Validate arguments
751 if (hWnd == NULL || d == NULL)
752 {
753 return;
754 }
755
756 if (LvIsSingleSelected(hWnd, L_ACCOUNT) == false)
757 {
758 ok = false;
759 }
760
761 if (ok)
762 {
763 UINT i = LvGetSelected(hWnd, L_ACCOUNT);
764 wchar_t *str = LvGetStr(hWnd, L_ACCOUNT, i, 1);
765
766 info_str = _UU("CM_EASY_INFO_2");
767
768 if (str != NULL)
769 {
770 if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)
771 {
772 button_str = _UU("CM_EASY_CONNECT_BUTTON_2");
773 show_status = true;
774 info_str = _UU("CM_EASY_INFO_3");
775
776 if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0)
777 {
778 title_str = _UU("CM_EASY_CONNECTED");
779 }
780 else
781 {
782 title_str = _UU("CM_EASY_CONNECTING");
783 }
784 }
785 Free(str);
786 }
787 }
788
789 SetShow(hWnd, B_STATUS, show_status);
790
791 SetText(hWnd, IDOK, button_str);
792 SetText(hWnd, S_INFO, info_str);
793 SetText(hWnd, S_TITLE, title_str);
794
795 SetShow(hWnd, IDOK, ok);
796 }
797
798 // Update the Simple Connect Manager content
CmEasyDlgRefresh(HWND hWnd,CM_EASY_DLG * d)799 void CmEasyDlgRefresh(HWND hWnd, CM_EASY_DLG *d)
800 {
801 // Validate arguments
802 if (hWnd == NULL || d == NULL)
803 {
804 return;
805 }
806
807 // Update the account list
808 CmRefreshAccountListEx(hWnd, true);
809
810 CmEasyDlgUpdate(hWnd, d);
811 }
812
813 // Dialog procedure of the simple connection manager
CmEasyDlg(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)814 UINT CmEasyDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
815 {
816 CM_EASY_DLG *d = (CM_EASY_DLG *)param;
817 NMHDR *n;
818 UINT i;
819 // Validate arguments
820 if (hWnd == NULL)
821 {
822 return 0;
823 }
824
825 switch (msg)
826 {
827 case WM_INITDIALOG:
828 CmEasyDlgInit(hWnd, d);
829 SetTimer(hWnd, 1, 10, NULL);
830 break;
831
832 case WM_TIMER:
833 switch (wParam)
834 {
835 case 1:
836 KillTimer(hWnd, 1);
837 SetForegroundWindow(hWnd);
838 SetActiveWindow(hWnd);
839 break;
840 }
841 break;
842
843 case WM_CM_EASY_REFRESH:
844 CmEasyDlgRefresh(hWnd, d);
845 break;
846
847 case WM_COMMAND:
848 CmEasyDlgOnCommand(hWnd, d, wParam, lParam);
849 break;
850
851 case WM_NOTIFY:
852 n = (NMHDR *)lParam;
853 CmEasyDlgOnNotify(hWnd, d, n);
854 break;
855
856 case WM_CLOSE:
857 i = LvGetSelected(hWnd, L_ACCOUNT);
858 if (i != INFINITE)
859 {
860 wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, i, 0);
861 if (s != NULL)
862 {
863 UniStrCpy(cm->EasyLastSelectedAccountName, sizeof(cm->EasyLastSelectedAccountName),
864 s);
865 Free(s);
866 }
867 }
868 else
869 {
870 Zero(cm->EasyLastSelectedAccountName, sizeof(cm->EasyLastSelectedAccountName));
871 }
872 EndDialog(hWnd, false);
873 break;
874 }
875
876 return 0;
877 }
878
879 // Show the window of the simple connection manager (This is called by a delaying timer)
CmMainWindowOnShowEasy(HWND hWnd)880 void CmMainWindowOnShowEasy(HWND hWnd)
881 {
882 CM_EASY_DLG d;
883
884 Zero(&d, sizeof(d));
885
886 if (cm->CmSetting.EasyMode == false)
887 {
888 // Not in simple mode
889 return;
890 }
891
892 if (cm->hEasyWnd != NULL)
893 {
894 // It is shown already
895 SetForegroundWindow(cm->hEasyWnd);
896 SetActiveWindow(cm->hEasyWnd);
897 return;
898 }
899
900 Dialog(NULL, D_CM_EASY, CmEasyDlg, &d);
901
902 cm->hEasyWnd = NULL;
903 }
904
905 // Show the window of the simple connection manager
CmShowEasy()906 void CmShowEasy()
907 {
908 SetTimer(cm->hMainWnd, 4, 2, NULL);
909 }
910
911 // Close the window of the simple connection manager
CmCloseEasy()912 void CmCloseEasy()
913 {
914 if (cm->hEasyWnd == NULL)
915 {
916 return;
917 }
918
919 SendMessage(cm->hEasyWnd, WM_CLOSE, 0, 0);
920 }
921
922 // Message processing for such as clicking on the tray icon
CmMainWindowOnTrayClicked(HWND hWnd,WPARAM wParam,LPARAM lParam)923 void CmMainWindowOnTrayClicked(HWND hWnd, WPARAM wParam, LPARAM lParam)
924 {
925 bool easymode = cm->CmSetting.EasyMode;
926
927 switch (wParam)
928 {
929 case 1:
930 switch (lParam)
931 {
932 case WM_LBUTTONDOWN:
933 case WM_RBUTTONDOWN:
934 // Click
935 if (easymode == false)
936 {
937 if (IsEnable(hWnd, 0))
938 {
939 CmShowTrayMenu(hWnd);
940 }
941 else
942 {
943 CmShowOrHideWindow(hWnd);
944 }
945 }
946 else
947 {
948 if (cm->hEasyWnd == NULL || IsEnable(cm->hEasyWnd, 0))
949 {
950 CmShowTrayMenu(hWnd);
951 }
952 else
953 {
954 //CmShowOrHideWindow(hWnd);
955 }
956 }
957 break;
958 case WM_LBUTTONDBLCLK:
959 case WM_RBUTTONDBLCLK:
960 // Double click
961 if (easymode == false)
962 {
963 if (IsEnable(hWnd, 0))
964 {
965 CmShowOrHideWindow(hWnd);
966 }
967 }
968 else
969 {
970 if (cm->hEasyWnd == NULL)
971 {
972 CmShowEasy();
973 }
974 else
975 {
976 SetForegroundWindow(cm->hEasyWnd);
977 SetActiveWindow(cm->hEasyWnd);
978 }
979 }
980 break;
981 }
982 break;
983 }
984 }
985
986 // Apply the setting of the operation mode
CmApplyCmSetting()987 void CmApplyCmSetting()
988 {
989 CM_SETTING a;
990 bool changed = false;
991
992 if (cm->CmSettingSupported == false)
993 {
994 return;
995 }
996
997 // Get the configuration of the current vpnclient
998 Zero(&a, sizeof(a));
999 CcGetCmSetting(cm->Client, &a);
1000
1001 // Check whether there is change point as compared to the previous CM_SETTING
1002 if (cm->CmSetting.EasyMode != a.EasyMode)
1003 {
1004 changed = true;
1005 }
1006 if (cm->CmSetting.LockMode != a.LockMode)
1007 {
1008 changed = true;
1009 }
1010
1011 Copy(&cm->CmSetting, &a, sizeof(CM_SETTING));
1012
1013 if (changed == false)
1014 {
1015 return;
1016 }
1017
1018 if (cm->StartupFinished)
1019 {
1020 if (IsShow(cm->hMainWnd, 0) && cm->CmSetting.EasyMode)
1021 {
1022 // Close the main window if it is shown
1023 Hide(cm->hMainWnd, 0);
1024 }
1025 else
1026 {
1027 WINDOWPLACEMENT current_pos;
1028 if (cm->CmSetting.EasyMode == false && IsShow(cm->hMainWnd, 0) == false)
1029 {
1030 // When restored to normal mode, restore the main window
1031 if (IsZero(&cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement)) == false)
1032 {
1033 cm->FakeWindowPlacement.flags = cm->FakeWindowPlacement.flags & ~SW_MINIMIZE;
1034 SetWindowPlacement(cm->hMainWnd, &cm->FakeWindowPlacement);
1035 Zero(&cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement));
1036 Hide(cm->hMainWnd, 0);
1037 }
1038 CmShowOrHideWindow(cm->hMainWnd);
1039 }
1040
1041 if (cm->CmSetting.EasyMode == false)
1042 {
1043 if (GetWindowPlacement(cm->hMainWnd, ¤t_pos))
1044 {
1045 if (current_pos.rcNormalPosition.right < 0 ||
1046 current_pos.rcNormalPosition.bottom < 0)
1047 {
1048 // If the window is off the screen for some reason,
1049 // return it in a visible place
1050 SetWindowPos(cm->hMainWnd, NULL, 0, 0, CM_DEFAULT_WIDTH, CM_DEFAULT_HEIGHT, SWP_NOREDRAW | SWP_SHOWWINDOW);
1051 Center(cm->hMainWnd);
1052 }
1053 }
1054 }
1055 }
1056
1057 Command(cm->hMainWnd, CMD_REFRESH);
1058 }
1059
1060 if (cm->CmSetting.EasyMode)
1061 {
1062 if (cm->StartupFinished == false && cm->StartupMode)
1063 {
1064 // Don't show in the case of /startup
1065 }
1066 else
1067 {
1068 CmShowEasy();
1069 }
1070 }
1071 else
1072 {
1073 CmCloseEasy();
1074 }
1075 }
1076
1077 // Initialize the operation mode changing dialog
CmSettingDlgInit(HWND hWnd,CM_SETTING_DLG * d)1078 void CmSettingDlgInit(HWND hWnd, CM_SETTING_DLG *d)
1079 {
1080 CM_SETTING a;
1081 // Validate arguments
1082 if (hWnd == NULL || d == NULL)
1083 {
1084 return;
1085 }
1086
1087 // Get the configuration of the current vpnclient
1088 Zero(&a, sizeof(a));
1089 CcGetCmSetting(cm->Client, &a);
1090
1091 Check(hWnd, R_EASY, a.EasyMode);
1092 Check(hWnd, R_NORMAL, a.EasyMode == false);
1093
1094 if (a.EasyMode == false)
1095 {
1096 Focus(hWnd, R_NORMAL);
1097 }
1098 else
1099 {
1100 Focus(hWnd, R_EASY);
1101 }
1102
1103 Check(hWnd, R_LOCK, a.LockMode);
1104
1105 SetEnable(hWnd, R_EASY, cm->CmEasyModeSupported);
1106
1107 if (a.LockMode)
1108 {
1109 if (IsZero(a.HashedPassword, sizeof(a.HashedPassword)) == false)
1110 {
1111 // Password is set
1112 SetText(hWnd, S_PASSWORD1, _UU("CM_SETTING_PASSWORD"));
1113 Hide(hWnd, S_PASSWORD3);
1114 Hide(hWnd, E_PASSWORD2);
1115
1116 d->CheckPassword = true;
1117 Copy(d->HashedPassword, a.HashedPassword, sizeof(d->HashedPassword));
1118 }
1119 }
1120
1121 SetShow(hWnd, S_VGS1, cm->Client->IsVgcSupported);
1122 SetShow(hWnd, S_VGS2, cm->Client->IsVgcSupported);
1123 SetShow(hWnd, S_VGS3, cm->Client->IsVgcSupported);
1124 SetShow(hWnd, B_VGS, cm->Client->IsVgcSupported);
1125
1126 CmSettingDlgUpdate(hWnd, d);
1127 }
1128
1129 // Update the operation mode changing dialog
CmSettingDlgUpdate(HWND hWnd,CM_SETTING_DLG * d)1130 void CmSettingDlgUpdate(HWND hWnd, CM_SETTING_DLG *d)
1131 {
1132 bool ok = true;
1133 char tmp1[MAX_SIZE], tmp2[MAX_SIZE];
1134 // Validate arguments
1135 if (hWnd == NULL || d == NULL)
1136 {
1137 return;
1138 }
1139
1140 GetTxtA(hWnd, E_PASSWORD1, tmp1, sizeof(tmp1));
1141 GetTxtA(hWnd, E_PASSWORD2, tmp2, sizeof(tmp2));
1142
1143 if (d->CheckPassword == false)
1144 {
1145 if (IsChecked(hWnd, R_LOCK))
1146 {
1147 if (StrCmp(tmp1, tmp2) != 0)
1148 {
1149 ok = false;
1150 }
1151 }
1152 }
1153 else
1154 {
1155 bool password_ok = false;
1156 UCHAR hash[SHA1_SIZE];
1157
1158 Hash(hash, tmp1, StrLen(tmp1), true);
1159 if (Cmp(hash, d->HashedPassword, sizeof(hash)) == 0)
1160 {
1161 password_ok = true;
1162 }
1163
1164 if (password_ok == false)
1165 {
1166 Check(hWnd, R_LOCK, true);
1167 Disable(hWnd, R_LOCK);
1168 }
1169 else
1170 {
1171 Enable(hWnd, R_LOCK);
1172 }
1173 }
1174
1175 SetEnable(hWnd, S_PASSWORD1, IsChecked(hWnd, R_LOCK));
1176 SetEnable(hWnd, S_PASSWORD2, IsChecked(hWnd, R_LOCK));
1177 SetEnable(hWnd, S_PASSWORD3, IsChecked(hWnd, R_LOCK));
1178 SetEnable(hWnd, E_PASSWORD1, IsChecked(hWnd, R_LOCK));
1179 SetEnable(hWnd, E_PASSWORD2, IsChecked(hWnd, R_LOCK));
1180
1181 SetEnable(hWnd, IDOK, ok);
1182 }
1183
1184 // Operation mode changing dialog OK
CmSettingDlgOnOk(HWND hWnd,CM_SETTING_DLG * d)1185 void CmSettingDlgOnOk(HWND hWnd, CM_SETTING_DLG *d)
1186 {
1187 CM_SETTING a;
1188 char tmp1[MAX_SIZE], tmp2[MAX_SIZE];
1189 // Validate arguments
1190 if (hWnd == NULL || d == NULL)
1191 {
1192 return;
1193 }
1194
1195 GetTxtA(hWnd, E_PASSWORD1, tmp1, sizeof(tmp1));
1196 GetTxtA(hWnd, E_PASSWORD2, tmp2, sizeof(tmp2));
1197
1198 Zero(&a, sizeof(a));
1199
1200 a.EasyMode = IsChecked(hWnd, R_EASY);
1201 a.LockMode = IsChecked(hWnd, R_LOCK);
1202
1203 if (a.LockMode)
1204 {
1205 if (d->CheckPassword && IsEnable(hWnd, R_LOCK) == false)
1206 {
1207 Copy(a.HashedPassword, d->HashedPassword, sizeof(a.HashedPassword));
1208 }
1209 else
1210 {
1211 if (StrLen(tmp1) >= 1)
1212 {
1213 Hash(a.HashedPassword, tmp1, StrLen(tmp1), true);
1214 }
1215 }
1216 }
1217
1218 CcSetCmSetting(cm->Client, &a);
1219
1220 EndDialog(hWnd, true);
1221 }
1222
1223 // Operation mode changing dialog
CmSettingDlg(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)1224 UINT CmSettingDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
1225 {
1226 CM_SETTING_DLG *d = (CM_SETTING_DLG *)param;
1227 // Validate arguments
1228 if (hWnd == NULL)
1229 {
1230 return 0;
1231 }
1232
1233 switch (msg)
1234 {
1235 case WM_INITDIALOG:
1236 CmSettingDlgInit(hWnd, d);
1237 break;
1238
1239 case WM_COMMAND:
1240 switch (LOWORD(wParam))
1241 {
1242 case R_EASY:
1243 case R_NORMAL:
1244 case R_LOCK:
1245 case E_PASSWORD1:
1246 case E_PASSWORD2:
1247 case IDOK:
1248 case IDCANCEL:
1249 CmSettingDlgUpdate(hWnd, d);
1250 break;
1251 }
1252 switch (wParam)
1253 {
1254 case IDOK:
1255 CmSettingDlgOnOk(hWnd, d);
1256 break;
1257
1258 case IDCANCEL:
1259 Close(hWnd);
1260 break;
1261
1262 case R_LOCK:
1263 if (IsChecked(hWnd, R_LOCK))
1264 {
1265 if (IsEmpty(hWnd, E_PASSWORD1))
1266 {
1267 Focus(hWnd, E_PASSWORD1);
1268 }
1269 }
1270 break;
1271
1272 }
1273 break;
1274
1275 case WM_CLOSE:
1276 EndDialog(hWnd, false);
1277 break;
1278 }
1279
1280 return 0;
1281 }
1282
1283
1284 // Change operation mode
CmSetting(HWND hWnd)1285 bool CmSetting(HWND hWnd)
1286 {
1287 CM_SETTING_DLG d;
1288
1289 Zero(&d, sizeof(d));
1290
1291 return Dialog(hWnd, D_CM_SETTING, CmSettingDlg, &d);
1292 }
1293
1294
1295 // Attempting thread for starting the UI Helper
CmTryToExecUiHelperThread(THREAD * thread,void * param)1296 void CmTryToExecUiHelperThread(THREAD *thread, void *param)
1297 {
1298 bool first_flag = true;
1299
1300 while (cm->TryExecUiHelperHalt == false && cm->WindowsShutdowning == false)
1301 {
1302 if (first_flag == false)
1303 {
1304 // Wait a little for other than the first time
1305 Wait(cm->TryExecUiHelperHaltEvent, CM_TRY_EXEC_UI_HELPER_INTERVAL * 2);
1306
1307 if (cm->TryExecUiHelperHalt || cm->WindowsShutdowning)
1308 {
1309 break;
1310 }
1311 }
1312 first_flag = false;
1313
1314 if (cm->TryExecUiHelperHalt == false && cm->WindowsShutdowning == false)
1315 {
1316 if (cm->TryExecUiHelperProcessHandle == NULL)
1317 {
1318 CmTryToExecUiHelper();
1319 }
1320 }
1321
1322 if (cm->TryExecUiHelperHalt || cm->WindowsShutdowning)
1323 {
1324 break;
1325 }
1326
1327 if (cm->TryExecUiHelperProcessHandle == NULL)
1328 {
1329 Wait(cm->TryExecUiHelperHaltEvent, CM_TRY_EXEC_UI_HELPER_INTERVAL);
1330 }
1331 else
1332 {
1333 HANDLE handles[2];
1334 handles[0] = cm->TryExecUiHelperProcessHandle;
1335 handles[1] = (HANDLE)cm->TryExecUiHelperHaltEvent->pData;
1336 WaitForMultipleObjects(2, handles, false, CM_TRY_EXEC_UI_HELPER_INTERVAL);
1337
1338 if (WaitForSingleObject(cm->TryExecUiHelperProcessHandle, 0) != WAIT_TIMEOUT)
1339 {
1340 CloseHandle(cm->TryExecUiHelperProcessHandle);
1341 cm->TryExecUiHelperProcessHandle = NULL;
1342 if (cm->TryExecUiHelperHalt || cm->WindowsShutdowning)
1343 {
1344 break;
1345 }
1346 Wait(cm->TryExecUiHelperHaltEvent, CM_TRY_EXEC_UI_HELPER_INTERVAL * 2);
1347 }
1348 }
1349 }
1350 }
1351
1352 // Stop the UI Helper
CmFreeTryToExecUiHelper()1353 void CmFreeTryToExecUiHelper()
1354 {
1355 cm->TryExecUiHelperHalt = true;
1356 Set(cm->TryExecUiHelperHaltEvent);
1357
1358 WaitThread(cm->TryExecUiHelperThread, INFINITE);
1359
1360 ReleaseThread(cm->TryExecUiHelperThread);
1361 cm->TryExecUiHelperThread = NULL;
1362
1363 ReleaseEvent(cm->TryExecUiHelperHaltEvent);
1364 cm->TryExecUiHelperHaltEvent = NULL;
1365
1366 cm->TryExecUiHelperHalt = false;
1367 cm->TryExecUiHelperProcessHandle = NULL;
1368 }
1369
1370 // Initialize the UI Helper starting
CmInitTryToExecUiHelper()1371 void CmInitTryToExecUiHelper()
1372 {
1373 cm->TryExecUiHelperProcessHandle = NULL;
1374 cm->TryExecUiHelperHalt = false;
1375 cm->TryExecUiHelperHaltEvent = NewEvent();
1376 cm->TryExecUiHelperThread = NewThread(CmTryToExecUiHelperThread, NULL);
1377 }
1378
1379 // Start the UI Helper
CmExecUiHelperMain()1380 void *CmExecUiHelperMain()
1381 {
1382 HANDLE h;
1383 wchar_t tmp[MAX_SIZE];
1384
1385 UniFormat(tmp, sizeof(tmp), L"%s\\%S", MsGetExeDirNameW(), CiGetVpnClientExeFileName());
1386
1387 // Start
1388 h = Win32RunExW(tmp, SVC_ARG_UIHELP_W, false);
1389
1390 return (void *)h;
1391 }
1392
1393 // Attempt to start the UI Helper
CmTryToExecUiHelper()1394 void CmTryToExecUiHelper()
1395 {
1396 HANDLE h;
1397 // Check that it isn't already running
1398 if (CnCheckAlreadyExists(false))
1399 {
1400 // It have already started
1401 return;
1402 }
1403
1404 h = (HANDLE)CmExecUiHelperMain();
1405
1406 if (h != NULL)
1407 {
1408 cm->TryExecUiHelperProcessHandle = h;
1409 }
1410 }
1411
1412 // Initialize the dialog
CmTrafficResultDlgInit(HWND hWnd,TT_RESULT * res)1413 void CmTrafficResultDlgInit(HWND hWnd, TT_RESULT *res)
1414 {
1415 LVB *ct;
1416 wchar_t tmp[MAX_SIZE];
1417 wchar_t tmp1[MAX_SIZE];
1418 wchar_t tmp2[MAX_SIZE];
1419 char str[MAX_SIZE];
1420 // Validate arguments
1421 if (hWnd == NULL || res == NULL)
1422 {
1423 return;
1424 }
1425
1426 SetIcon(hWnd, 0, ICO_SWITCH);
1427
1428 SetFont(hWnd, L_STATUS, GetFont(_SS("DEFAULT_FONT_2"), 10, false, false, false, false));
1429
1430 LvInit(hWnd, L_STATUS);
1431 LvSetStyle(hWnd, L_STATUS, LVS_EX_GRIDLINES);
1432 LvInsertColumn(hWnd, L_STATUS, 0, _UU("TTC_RES_COLUMN_1"), 100);
1433 LvInsertColumn(hWnd, L_STATUS, 1, _UU("TTC_RES_COLUMN_2"), 100);
1434 LvInsertColumn(hWnd, L_STATUS, 2, _UU("TTC_RES_COLUMN_3"), 100);
1435
1436 ct = LvInsertStart();
1437
1438 // Time that was used to measure
1439 GetSpanStrMilli(str, sizeof(str), res->Span);
1440 StrToUni(tmp, sizeof(tmp), str);
1441 LvInsertAdd(ct, ICO_DATETIME, NULL, 3, _UU("TTC_RES_SPAN"), tmp, L"");
1442
1443 // Correct the data for Ethernet frame
1444 LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_ETHER"), res->Raw ? _UU("SEC_NO") : _UU("SEC_YES"), L"");
1445
1446 // Amount of communication data of download direction
1447 ToStr3(str, sizeof(str), res->NumBytesDownload);
1448 UniFormat(tmp1, sizeof(tmp1), L"%S Bytes", str);
1449 ToStrByte1000(str, sizeof(str), res->NumBytesDownload);
1450 StrToUni(tmp2, sizeof(tmp2), str);
1451 LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BYTES_DOWNLOAD"), tmp1, tmp2);
1452
1453 // Amount of communication data of upload direction
1454 ToStr3(str, sizeof(str), res->NumBytesUpload);
1455 UniFormat(tmp1, sizeof(tmp1), L"%S Bytes", str);
1456 ToStrByte1000(str, sizeof(str), res->NumBytesUpload);
1457 StrToUni(tmp2, sizeof(tmp2), str);
1458 LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BYTES_UPLOAD"), tmp1, tmp2);
1459
1460 // Total amount of communication data
1461 ToStr3(str, sizeof(str), res->NumBytesTotal);
1462 UniFormat(tmp1, sizeof(tmp1), L"%S Bytes", str);
1463 ToStrByte1000(str, sizeof(str), res->NumBytesTotal);
1464 StrToUni(tmp2, sizeof(tmp2), str);
1465 LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BYTES_TOTAL"), tmp1, tmp2);
1466
1467 // Calculate the total throughput of input and output of the relay equipment
1468 LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_DOUBLE"), (res->Double == false) ? _UU("SEC_NO") : _UU("SEC_YES"), L"");
1469
1470 // Average throughput of download direction
1471 ToStr3(str, sizeof(str), res->BpsDownload);
1472 UniFormat(tmp1, sizeof(tmp1), L"%S bps", str);
1473 ToStrByte1000(str, sizeof(str), res->BpsDownload);
1474 ReplaceStr(str, sizeof(str), str, "Bytes", "bps");
1475 StrToUni(tmp2, sizeof(tmp2), str);
1476 LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BPS_DOWNLOAD"), tmp1, tmp2);
1477
1478 // Average throughput of upload direction
1479 ToStr3(str, sizeof(str), res->BpsUpload);
1480 UniFormat(tmp1, sizeof(tmp1), L"%S bps", str);
1481 ToStrByte1000(str, sizeof(str), res->BpsUpload);
1482 ReplaceStr(str, sizeof(str), str, "Bytes", "bps");
1483 StrToUni(tmp2, sizeof(tmp2), str);
1484 LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BPS_UPLOAD"), tmp1, tmp2);
1485
1486 // Total average throughput
1487 ToStr3(str, sizeof(str), res->BpsTotal);
1488 UniFormat(tmp1, sizeof(tmp1), L"%S bps", str);
1489 ToStrByte1000(str, sizeof(str), res->BpsTotal);
1490 ReplaceStr(str, sizeof(str), str, "Bytes", "bps");
1491 StrToUni(tmp2, sizeof(tmp2), str);
1492 LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BPS_TOTAL"), tmp1, tmp2);
1493
1494 LvInsertEnd(ct, hWnd, L_STATUS);
1495
1496 LvAutoSize(hWnd, L_STATUS);
1497 }
1498
1499 // Dialog procedure to display results of traffic measurements
CmTrafficResultDlg(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)1500 UINT CmTrafficResultDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
1501 {
1502 TT_RESULT *r = (TT_RESULT *)param;
1503 // Validate arguments
1504 if (hWnd == NULL)
1505 {
1506 return 0;
1507 }
1508
1509 switch (msg)
1510 {
1511 case WM_INITDIALOG:
1512 CmTrafficResultDlgInit(hWnd, r);
1513 break;
1514
1515 case WM_COMMAND:
1516 switch (wParam)
1517 {
1518 case IDOK:
1519 case IDCANCEL:
1520 Close(hWnd);
1521 break;
1522 }
1523 break;
1524
1525 case WM_CLOSE:
1526 EndDialog(hWnd, 0);
1527 break;
1528 }
1529
1530 return 0;
1531 }
1532
1533 // Display results of traffic measurement
CmTrafficResult(HWND hWnd,TT_RESULT * r)1534 void CmTrafficResult(HWND hWnd, TT_RESULT *r)
1535 {
1536 // Validate arguments
1537 if (r == NULL)
1538 {
1539 return;
1540 }
1541
1542 Dialog(hWnd, D_CM_TRAFFIC_RESULT, CmTrafficResultDlg, r);
1543 }
1544
1545 // Thread to wait for the termination of the client
CmTrafficRunDlgClientWaitThread(THREAD * t,void * param)1546 void CmTrafficRunDlgClientWaitThread(THREAD *t, void *param)
1547 {
1548 CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;
1549 TT_RESULT result;
1550 UINT ret;
1551 // Validate arguments
1552 if (t == NULL || param == NULL)
1553 {
1554 return;
1555 }
1556
1557 Zero(&result, sizeof(result));
1558 ret = FreeTtc(d->Ttc, &result);
1559 d->Ttc = NULL;
1560
1561 d->RetCode = ret;
1562 Copy(&d->Result, &result, sizeof(TT_RESULT));
1563
1564 PostMessage(d->hWnd, WM_APP + 66, 0, 0);
1565 }
1566
1567 // Append the string
CmTrafficRunDlgAddStr(HWND hWnd,wchar_t * str)1568 void CmTrafficRunDlgAddStr(HWND hWnd, wchar_t *str)
1569 {
1570 wchar_t *tmp;
1571 UINT tmp_size;
1572
1573 tmp_size = UniStrSize(str) + 32;
1574 tmp = Malloc(tmp_size);
1575 UniStrCpy(tmp, tmp_size, str);
1576 if (UniEndWith(str, L"\n") == false)
1577 {
1578 UniStrCat(tmp, tmp_size, L"\n");
1579 }
1580
1581 UniReplaceStrEx(tmp, tmp_size, tmp, L"\r\n", L"\n", false);
1582 UniReplaceStrEx(tmp, tmp_size, tmp, L"\n", L"\r\n", false);
1583
1584 if (MsIsNt())
1585 {
1586 SendMsg(hWnd, E_EDIT, EM_SETSEL, 0x7fffffff, 0x7fffffff);
1587 SendMsg(hWnd, E_EDIT, EM_REPLACESEL, false, (LPARAM)tmp);
1588 }
1589 else
1590 {
1591 char *s = CopyUniToStr(tmp);
1592 UINT len;
1593
1594 len = GetWindowTextLength(DlgItem(hWnd, E_EDIT));
1595 SendMsg(hWnd, E_EDIT, EM_SETSEL, 0x7fffffff, 0x7fffffff);
1596 SendMsg(hWnd, E_EDIT, EM_SETSEL, len, len);
1597 SendMsg(hWnd, E_EDIT, EM_REPLACESEL, false, (LPARAM)s);
1598 Free(s);
1599 }
1600
1601 Free(tmp);
1602 }
1603
1604 // Show the string
CmTrafficRunDlgPrintProc(void * param,wchar_t * str)1605 void CmTrafficRunDlgPrintProc(void *param, wchar_t *str)
1606 {
1607 CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;
1608 HWND hWnd;
1609 // Validate arguments
1610 if (param == NULL || str == NULL)
1611 {
1612 return;
1613 }
1614
1615 hWnd = d->hWnd;
1616
1617 PostMessage(hWnd, WM_APP + 64, 0, (LPARAM)UniCopyStr(str));
1618 }
1619
1620 // Thread for stop the measurement program
CmTrafficRunDlgHaltThread(THREAD * t,void * param)1621 void CmTrafficRunDlgHaltThread(THREAD *t, void *param)
1622 {
1623 CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;
1624 // Validate arguments
1625 if (t == NULL || param == NULL)
1626 {
1627 return;
1628 }
1629
1630 if (d->Setting->ServerMode)
1631 {
1632 // Stop the server
1633 d->RetCode = FreeTts(d->Tts);
1634
1635 PostMessage(d->hWnd, WM_APP + 65, 0, 0);
1636 }
1637 }
1638
1639 // Stop the measurement program
CmTrafficRunDlgHalt(HWND hWnd,CM_TRAFFIC_DLG * d)1640 void CmTrafficRunDlgHalt(HWND hWnd, CM_TRAFFIC_DLG *d)
1641 {
1642 // Validate arguments
1643 if (hWnd == NULL || d == NULL)
1644 {
1645 return;
1646 }
1647
1648 if (d->Started == false)
1649 {
1650 return;
1651 }
1652
1653 if (d->Setting->ServerMode)
1654 {
1655 if (d->HaltThread == NULL)
1656 {
1657 Disable(hWnd, IDCANCEL);
1658 d->HaltThread = NewThread(CmTrafficRunDlgHaltThread, d);
1659 }
1660 }
1661 else
1662 {
1663 if (d->ClientEndWaitThread != NULL)
1664 {
1665 StopTtc(d->Ttc);
1666 }
1667 else
1668 {
1669 EndDialog(hWnd, 0);
1670 }
1671 }
1672 }
1673
1674 // Start the operation of traffic measurement
CmTrafficRunDlgStart(HWND hWnd,CM_TRAFFIC_DLG * d)1675 void CmTrafficRunDlgStart(HWND hWnd, CM_TRAFFIC_DLG *d)
1676 {
1677 // Validate arguments
1678 if (hWnd == NULL || d == NULL)
1679 {
1680 return;
1681 }
1682
1683 if (d->Setting->ServerMode)
1684 {
1685 // Start the measurement server
1686 d->Tts = NewTts(d->Setting->Port, d, CmTrafficRunDlgPrintProc);
1687 }
1688 else
1689 {
1690 // Start the measurement client
1691 d->Ttc = NewTtc(d->Setting->Host, d->Setting->Port,
1692 d->Setting->NumTcp, d->Setting->Type, d->Setting->Span * 1000ULL,
1693 d->Setting->Double, d->Setting->Raw, CmTrafficRunDlgPrintProc, d);
1694
1695 d->ClientEndWaitThread = NewThread(CmTrafficRunDlgClientWaitThread, d);
1696 }
1697
1698 d->Started = true;
1699 }
1700
1701 // Traffic measurement operation dialog initialization
CmTrafficRunDlgInit(HWND hWnd,CM_TRAFFIC_DLG * d)1702 void CmTrafficRunDlgInit(HWND hWnd, CM_TRAFFIC_DLG *d)
1703 {
1704 // Validate arguments
1705 if (hWnd == NULL || d == NULL)
1706 {
1707 return;
1708 }
1709
1710 d->hWnd = hWnd;
1711
1712 SetIcon(hWnd, 0, ICO_SWITCH);
1713 DlgFont(hWnd, S_INFO, 11, false);
1714 SetFont(hWnd, E_EDIT, GetFont(_SS("DEFAULT_FONT_2"), 0, false, false,
1715 false, false));
1716
1717 Focus(hWnd, IDCANCEL);
1718 }
1719
1720 // Traffic measurement operation dialog procedure
CmTrafficRunDlg(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)1721 UINT CmTrafficRunDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
1722 {
1723 CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;
1724 wchar_t *s;
1725 // Validate arguments
1726 if (hWnd == NULL)
1727 {
1728 return 0;
1729 }
1730
1731 switch (msg)
1732 {
1733 case WM_INITDIALOG:
1734 CmTrafficRunDlgInit(hWnd, d);
1735
1736 SetTimer(hWnd, 1, 10, NULL);
1737 break;
1738
1739 case WM_APP + 64:
1740 // Add a string
1741 s = (wchar_t *)lParam;
1742 if (s != NULL)
1743 {
1744 CmTrafficRunDlgAddStr(hWnd, s);
1745 Free(s);
1746 }
1747 break;
1748
1749 case WM_APP + 65:
1750 // Stopping complete
1751 if (d->HaltThread != NULL)
1752 {
1753 WaitThread(d->HaltThread, INFINITE);
1754 ReleaseThread(d->HaltThread);
1755 d->HaltThread = NULL;
1756 EndDialog(hWnd, 0);
1757 }
1758 break;
1759
1760 case WM_APP + 66:
1761 // Show results
1762 if (d->RetCode == ERR_NO_ERROR)
1763 {
1764 CmTrafficResult(hWnd, &d->Result);
1765 }
1766
1767 if (d->ClientEndWaitThread != NULL)
1768 {
1769 WaitThread(d->ClientEndWaitThread, INFINITE);
1770 ReleaseThread(d->ClientEndWaitThread);
1771 d->ClientEndWaitThread = NULL;
1772 }
1773
1774 if (d->CloseDialogAfter)
1775 {
1776 EndDialog(hWnd, 0);
1777 }
1778 break;
1779
1780 case WM_TIMER:
1781 switch (wParam)
1782 {
1783 case 1:
1784 KillTimer(hWnd, 1);
1785
1786 CmTrafficRunDlgStart(hWnd, d);
1787 break;
1788 }
1789 break;
1790
1791 case WM_COMMAND:
1792 switch (wParam)
1793 {
1794 case IDOK:
1795 case IDCANCEL:
1796 Close(hWnd);
1797 break;
1798 }
1799 break;
1800
1801 case WM_CLOSE:
1802 d->CloseDialogAfter = true;
1803 CmTrafficRunDlgHalt(hWnd, d);
1804 return 1;
1805 }
1806
1807 return 0;
1808 }
1809
1810 // Execute a traffic measurement
CmExecTraffic(HWND hWnd,CM_TRAFFIC * t)1811 void CmExecTraffic(HWND hWnd, CM_TRAFFIC *t)
1812 {
1813 CM_TRAFFIC_DLG d;
1814 // Validate arguments
1815 if (t == NULL)
1816 {
1817 return;
1818 }
1819
1820 Zero(&d, sizeof(d));
1821 d.Setting = t;
1822 d.ResultShowEvent = NewEvent();
1823
1824 MsSetThreadPriorityHigh();
1825 Dialog(hWnd, D_CM_TRAFFIC_RUN, CmTrafficRunDlg, &d);
1826 MsRestoreThreadPriority();
1827
1828 ReleaseEvent(d.ResultShowEvent);
1829 }
1830
1831 // Write the settings to the registry
CmTrafficSaveToReg(CM_TRAFFIC * t)1832 void CmTrafficSaveToReg(CM_TRAFFIC *t)
1833 {
1834 // Validate arguments
1835 if (t == NULL)
1836 {
1837 return;
1838 }
1839
1840 MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "ServerMode", t->ServerMode ? 1 : 0);
1841 MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Double", t->Double ? 1 : 0);
1842 MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Raw", t->Raw ? 1 : 0);
1843 MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Port", t->Port);
1844 MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "NumTcp", t->NumTcp);
1845 MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Type", t->Type);
1846 MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Span", t->Span);
1847 MsRegWriteStr(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Host", t->Host);
1848 }
1849
1850 // Read the settings from the registry
CmTrafficLoadFromReg(CM_TRAFFIC * t)1851 bool CmTrafficLoadFromReg(CM_TRAFFIC *t)
1852 {
1853 char *s;
1854 // Validate arguments
1855 if (t == NULL)
1856 {
1857 return false;
1858 }
1859
1860 Zero(t, sizeof(CM_TRAFFIC));
1861
1862 if (MsRegIsKey(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY) == false)
1863 {
1864 return false;
1865 }
1866
1867 t->Double = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Double") == 0 ? false : true;
1868 t->Raw = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Raw") == 0 ? false : true;
1869 t->Port = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Port");
1870 if (t->Port == 0)
1871 {
1872 t->Port = TRAFFIC_DEFAULT_PORT;
1873 }
1874
1875 s = MsRegReadStr(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Host");
1876
1877 if (IsEmptyStr(s) == false)
1878 {
1879 Trim(s);
1880 StrCpy(t->Host, sizeof(t->Host), s);
1881 }
1882
1883 Free(s);
1884
1885 t->NumTcp = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "NumTcp");
1886 t->NumTcp = MAKESURE(t->NumTcp, 1, TRAFFIC_NUMTCP_MAX);
1887 t->Type = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Type");
1888
1889 if (t->Type != TRAFFIC_TYPE_DOWNLOAD && t->Type != TRAFFIC_TYPE_UPLOAD &&
1890 t->Type != TRAFFIC_TYPE_FULL)
1891 {
1892 t->Type = TRAFFIC_TYPE_FULL;
1893 }
1894
1895 t->Span = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Span");
1896 if (t->Span == 0)
1897 {
1898 t->Span = TRAFFIC_SPAN_DEFAULT;
1899 }
1900
1901 t->ServerMode = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "ServerMode") == 0 ? false : true;
1902
1903 return true;
1904 }
1905
1906 // Get the default settings
CmTrafficGetDefaultSetting(CM_TRAFFIC * t)1907 void CmTrafficGetDefaultSetting(CM_TRAFFIC *t)
1908 {
1909 // Validate arguments
1910 if (t == NULL)
1911 {
1912 return;
1913 }
1914
1915 Zero(t, sizeof(CM_TRAFFIC));
1916
1917 t->Double = false;
1918 t->Raw = false;
1919 t->Port = TRAFFIC_DEFAULT_PORT;
1920 t->NumTcp = TRAFFIC_NUMTCP_DEFAULT;
1921 t->Type = TRAFFIC_TYPE_FULL;
1922 t->Span = TRAFFIC_SPAN_DEFAULT;
1923 t->ServerMode = false;
1924 }
1925
1926 // Communication throughput measurement tool dialog initialization
CmTrafficDlgInit(HWND hWnd)1927 void CmTrafficDlgInit(HWND hWnd)
1928 {
1929 CM_TRAFFIC t;
1930 LIST *c1, *c2;
1931 UINT i;
1932 // Validate arguments
1933 if (hWnd == NULL)
1934 {
1935 return;
1936 }
1937
1938 DlgFont(hWnd, S_8, 9, true);
1939 DlgFont(hWnd, S_3, 9, true);
1940
1941 Zero(&t, sizeof(t));
1942 if (CmTrafficLoadFromReg(&t) == false)
1943 {
1944 CmTrafficGetDefaultSetting(&t);
1945 }
1946
1947 // Write the settings to the dialog
1948 Check(hWnd, R_SERVER, t.ServerMode);
1949 Check(hWnd, R_CLIENT, t.ServerMode == false);
1950
1951 c1 = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "HostCandidate");
1952 if (c1 != NULL)
1953 {
1954 UINT i;
1955
1956 CbReset(hWnd, C_HOST);
1957
1958 for (i = 0;i < LIST_NUM(c1);i++)
1959 {
1960 CANDIDATE *c = LIST_DATA(c1, i);
1961
1962 CbAddStr(hWnd, C_HOST, c->Str, 0);
1963 }
1964
1965 FreeCandidateList(c1);
1966 }
1967
1968 if (CbNum(hWnd, C_HOST) == 0)
1969 {
1970 CbAddStr(hWnd, C_HOST, L"speed.softether.com", 0);
1971 }
1972
1973 if (IsEmptyStr(t.Host) == false)
1974 {
1975 SetTextA(hWnd, C_HOST, t.Host);
1976 }
1977
1978 c2 = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "PortCandidate");
1979 if (c2 != NULL)
1980 {
1981 UINT i;
1982
1983 if (t.Port != 0)
1984 {
1985 wchar_t tmp[32];
1986
1987 UniToStru(tmp, t.Port);
1988
1989 AddCandidate(c2, tmp, 0);
1990 }
1991
1992 CbReset(hWnd, C_PORT);
1993
1994 for (i = 0;i < LIST_NUM(c2);i++)
1995 {
1996 CANDIDATE *c = LIST_DATA(c2, i);
1997
1998 CbAddStr(hWnd, C_PORT, c->Str, 0);
1999 }
2000
2001 FreeCandidateList(c2);
2002 }
2003
2004 CbReset(hWnd, C_NUM);
2005
2006 for (i = 1;i <= TRAFFIC_NUMTCP_MAX;i++)
2007 {
2008 wchar_t tmp[32];
2009
2010 UniToStru(tmp, i);
2011
2012 CbAddStr(hWnd, C_NUM, tmp, i);
2013 }
2014
2015 CbSelect(hWnd, C_NUM, t.NumTcp);
2016
2017 Check(hWnd, R_DOWNLOAD, t.Type == TRAFFIC_TYPE_DOWNLOAD);
2018 Check(hWnd, R_UPLOAD, t.Type == TRAFFIC_TYPE_UPLOAD);
2019 Check(hWnd, R_FULL, t.Type == TRAFFIC_TYPE_FULL);
2020
2021 Check(hWnd, R_ETHERNET, t.Raw ? false : true);
2022 Check(hWnd, R_DOUBLE, t.Double);
2023
2024 SetIntEx(hWnd, E_SPAN, t.Span);
2025
2026 CmTrafficDlgUpdate(hWnd);
2027 }
2028
2029 // Put the contents of the dialog to structure
CmTrafficDlgToStruct(HWND hWnd,CM_TRAFFIC * t)2030 void CmTrafficDlgToStruct(HWND hWnd, CM_TRAFFIC *t)
2031 {
2032 // Validate arguments
2033 if (hWnd == NULL || t == NULL)
2034 {
2035 return;
2036 }
2037
2038 Zero(t, sizeof(CM_TRAFFIC));
2039 t->ServerMode = IsChecked(hWnd, R_SERVER);
2040 GetTxtA(hWnd, C_HOST, t->Host, sizeof(t->Host));
2041 Trim(t->Host);
2042
2043 t->Port = GetInt(hWnd, C_PORT);
2044 t->NumTcp = CbGetSelect(hWnd, C_NUM);
2045 t->Span = GetInt(hWnd, E_SPAN);
2046 t->Raw = IsChecked(hWnd, R_ETHERNET) ? false : true;
2047 t->Double = IsChecked(hWnd, R_DOUBLE);
2048
2049 if (IsChecked(hWnd, R_DOWNLOAD))
2050 {
2051 t->Type = TRAFFIC_TYPE_DOWNLOAD;
2052 }
2053 else if (IsChecked(hWnd, R_UPLOAD))
2054 {
2055 t->Type = TRAFFIC_TYPE_UPLOAD;
2056 }
2057 else
2058 {
2059 t->Type = TRAFFIC_TYPE_FULL;
2060 }
2061 }
2062
2063 // Communication throughput measurement tool dialog update
CmTrafficDlgUpdate(HWND hWnd)2064 bool CmTrafficDlgUpdate(HWND hWnd)
2065 {
2066 CM_TRAFFIC t;
2067 bool ok = true;
2068 bool client_only;
2069 // Validate arguments
2070 if (hWnd == NULL)
2071 {
2072 return false;
2073 }
2074
2075 CmTrafficDlgToStruct(hWnd, &t);
2076
2077 client_only = t.ServerMode ? false : true;
2078
2079 SetEnable(hWnd, C_HOST, client_only);
2080 SetEnable(hWnd, S_5, client_only);
2081 SetEnable(hWnd, S_8, client_only);
2082 SetEnable(hWnd, S_9, client_only);
2083 SetEnable(hWnd, R_DOWNLOAD, client_only);
2084 SetEnable(hWnd, R_UPLOAD, client_only);
2085 SetEnable(hWnd, R_FULL, client_only);
2086 SetEnable(hWnd, S_10, client_only);
2087 SetEnable(hWnd, S_11, client_only);
2088 SetEnable(hWnd, C_NUM, client_only);
2089 SetEnable(hWnd, S_14, client_only);
2090 SetEnable(hWnd, S_12, client_only);
2091 SetEnable(hWnd, E_SPAN, client_only);
2092 SetEnable(hWnd, S_13, client_only);
2093 SetEnable(hWnd, R_ETHERNET, client_only);
2094 SetEnable(hWnd, R_DOUBLE, client_only);
2095
2096 if (t.Port == 0 || t.Port >= 65536)
2097 {
2098 ok = false;
2099 }
2100
2101 if (t.ServerMode == false)
2102 {
2103 if (IsEmptyStr(t.Host))
2104 {
2105 ok = false;
2106 }
2107
2108 if (t.NumTcp == 0 || t.NumTcp >= 33)
2109 {
2110 ok = false;
2111 }
2112
2113 if (t.Span == 0)
2114 {
2115 ok = false;
2116 }
2117
2118 if (t.Type == TRAFFIC_TYPE_FULL && ((t.NumTcp % 2) != 0))
2119 {
2120 ok = false;
2121 }
2122 }
2123
2124 SetEnable(hWnd, IDOK, ok);
2125
2126 return ok;
2127 }
2128
2129 // Communication throughput measurement tool dialog OK button
CmTrafficDlgOnOk(HWND hWnd)2130 void CmTrafficDlgOnOk(HWND hWnd)
2131 {
2132 CM_TRAFFIC t;
2133 LIST *c;
2134 // Validate arguments
2135 if (hWnd == NULL)
2136 {
2137 return;
2138 }
2139
2140 // Get the basic data
2141 CmTrafficDlgToStruct(hWnd, &t);
2142
2143 // Save to registry
2144 CmTrafficSaveToReg(&t);
2145
2146 // Retrieve and save the server name candidate
2147 if (IsEmptyStr(t.Host) == false)
2148 {
2149 c = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "HostCandidate");
2150 if (c != NULL)
2151 {
2152 wchar_t tmp[MAX_SIZE];
2153
2154 StrToUni(tmp, sizeof(tmp), t.Host);
2155 AddCandidate(c, tmp, 0);
2156
2157 WriteCandidateToReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, c, "HostCandidate");
2158
2159 FreeCandidateList(c);
2160 }
2161 }
2162
2163 if (t.Port != 0 && t.Port <= 65536)
2164 {
2165 // Retrieve and store the port number candidate
2166 c = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "PortCandidate");
2167 if (c != NULL)
2168 {
2169 wchar_t tmp[MAX_SIZE];
2170
2171 UniToStru(tmp, t.Port);
2172 AddCandidate(c, tmp, 0);
2173
2174 WriteCandidateToReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, c, "PortCandidate");
2175
2176 FreeCandidateList(c);
2177 }
2178 }
2179
2180 // Execute
2181 CmExecTraffic(hWnd, &t);
2182
2183 // Update the dialog
2184 CmTrafficDlgInit(hWnd);
2185 }
2186
2187 // Communication throughput measurement tool dialog procedure
CmTrafficDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)2188 UINT CmTrafficDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
2189 {
2190 // Validate arguments
2191 if (hWnd == NULL)
2192 {
2193 return 0;
2194 }
2195
2196 switch (msg)
2197 {
2198 case WM_INITDIALOG:
2199 SetIcon(hWnd, 0, ICO_SWITCH);
2200 CmTrafficDlgInit(hWnd);
2201 break;
2202
2203 case WM_COMMAND:
2204 switch (LOWORD(wParam))
2205 {
2206 case R_SERVER:
2207 case R_CLIENT:
2208 case C_HOST:
2209 case C_PORT:
2210 case R_DOWNLOAD:
2211 case R_UPLOAD:
2212 case R_FULL:
2213 case C_NUM:
2214 case E_SPAN:
2215 case R_ETHERNET:
2216 case R_DOUBLE:
2217 CmTrafficDlgUpdate(hWnd);
2218 break;
2219 }
2220
2221 switch (wParam)
2222 {
2223 case IDOK:
2224 CmTrafficDlgOnOk(hWnd);
2225 break;
2226
2227 case IDCANCEL:
2228 Close(hWnd);
2229 break;
2230 }
2231 break;
2232
2233 case WM_CLOSE:
2234 EndDialog(hWnd, 0);
2235 break;
2236 }
2237
2238 return 0;
2239 }
2240
2241 // Communication throughput measurement tool
CmTraffic(HWND hWnd)2242 void CmTraffic(HWND hWnd)
2243 {
2244 Dialog(hWnd, D_CM_TRAFFIC, CmTrafficDlgProc, NULL);
2245 }
2246
2247 // Delete old startup file
CmDeleteOldStartupTrayFile()2248 void CmDeleteOldStartupTrayFile()
2249 {
2250 char tmp[MAX_SIZE];
2251 char *tag = _SS("CM_JAPANESE_ONLY_OLD_STARTUP");
2252 if (IsEmptyStr(tag))
2253 {
2254 return;
2255 }
2256
2257 Format(tmp, sizeof(tmp), tag, MsGetCommonStartupDir());
2258
2259 FileDelete(tmp);
2260 }
2261
2262 // PKCS license confirmation dialog
CmPkcsEulaDlg(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)2263 UINT CmPkcsEulaDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
2264 {
2265 UINT id;
2266 SECURE_DEVICE *dev;
2267 char *name;
2268 // Validate arguments
2269 if (hWnd == NULL)
2270 {
2271 return 0;
2272 }
2273
2274 switch (msg)
2275 {
2276 case WM_INITDIALOG:
2277 id = (UINT)param;
2278 dev = GetSecureDevice(id);
2279 if (dev == NULL)
2280 {
2281 EndDialog(hWnd, 0);
2282 return 0;
2283 }
2284
2285 name = dev->ModuleName;
2286
2287 FormatText(hWnd, S_INFO_1, name);
2288 FormatText(hWnd, S_INFO_2, name, name);
2289 FormatText(hWnd, S_INFO_3, name);
2290
2291 break;
2292
2293 case WM_COMMAND:
2294 switch (wParam)
2295 {
2296 case IDOK:
2297 EndDialog(hWnd, 1);
2298 break;
2299
2300 case IDCANCEL:
2301 Close(hWnd);
2302 break;
2303 }
2304 break;
2305
2306 case WM_CLOSE:
2307 EndDialog(hWnd, 0);
2308 break;
2309 }
2310
2311 return 0;
2312 }
2313
2314 // Confirmation screen of whether the user accepts the EULA of the PKCS DLL
CmCheckPkcsEula(HWND hWnd,UINT id)2315 bool CmCheckPkcsEula(HWND hWnd, UINT id)
2316 {
2317 return (Dialog(hWnd, D_CM_PKCSEULA, CmPkcsEulaDlg, (void *)id) == 0) ? false : true;
2318 }
2319
2320 // Update controls
CmSecurePinDlgUpdate(HWND hWnd)2321 void CmSecurePinDlgUpdate(HWND hWnd)
2322 {
2323 char *tmp1, *tmp2, *tmp3;
2324 bool ok = true;
2325 // Validate arguments
2326 if (hWnd == NULL)
2327 {
2328 return;
2329 }
2330
2331 tmp1 = GetTextA(hWnd, E_PIN1);
2332 tmp2 = GetTextA(hWnd, E_PIN2);
2333 tmp3 = GetTextA(hWnd, E_PIN3);
2334 if (IsEmptyStr(tmp1))
2335 {
2336 ok = false;
2337 }
2338 if (IsEmptyStr(tmp2))
2339 {
2340 ok = false;
2341 }
2342 if (IsEmptyStr(tmp3))
2343 {
2344 ok = false;
2345 }
2346 if (StrCmp(tmp2, tmp3) != 0)
2347 {
2348 ok = false;
2349 }
2350 Free(tmp1);
2351 Free(tmp2);
2352 Free(tmp3);
2353 SetEnable(hWnd, IDOK, ok);
2354 }
2355
2356 // PIN code changing dialog
CmSecurePinDlg(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)2357 UINT CmSecurePinDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
2358 {
2359 UINT id = (UINT)param;
2360 char *src, *dst;
2361 SECURE *s;
2362 // Validate arguments
2363 if (hWnd == NULL)
2364 {
2365 return 0;
2366 }
2367
2368 switch (msg)
2369 {
2370 case WM_INITDIALOG:
2371 CmSecurePinDlgUpdate(hWnd);
2372 break;
2373
2374 case WM_COMMAND:
2375 switch (LOWORD(wParam))
2376 {
2377 case E_PIN1:
2378 case E_PIN2:
2379 case E_PIN3:
2380 CmSecurePinDlgUpdate(hWnd);
2381 break;
2382 }
2383
2384 switch (wParam)
2385 {
2386 case IDOK:
2387 src = GetTextA(hWnd, E_PIN1);
2388 dst = GetTextA(hWnd, E_PIN3);
2389
2390 Disable(hWnd, IDOK);
2391 Disable(hWnd, IDCANCEL);
2392
2393 s = OpenSec(id);
2394 if (s == NULL)
2395 {
2396 if (GetSecureDevice(id) != NULL)
2397 {
2398 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),
2399 GetSecureDevice(id)->DeviceName);
2400 }
2401 else
2402 {
2403 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),
2404 "Unknown");
2405 }
2406 }
2407 else
2408 {
2409 if (OpenSecSession(s, 0) == false)
2410 {
2411 if (GetSecureDevice(id) != NULL)
2412 {
2413 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),
2414 GetSecureDevice(id)->DeviceName);
2415 }
2416 else
2417 {
2418 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),
2419 "Unknown");
2420 }
2421 }
2422 else
2423 {
2424 if (LoginSec(s, src) == false)
2425 {
2426 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_CURRENT_BAD"));
2427 FocusEx(hWnd, E_PIN1);
2428 }
2429 else
2430 {
2431 if (ChangePin(s, src, dst) == false)
2432 {
2433 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_CHANGE_FAILED"));
2434 FocusEx(hWnd, E_PIN1);
2435 }
2436 else
2437 {
2438 // Clear the cache for PIN code
2439 cached_pin_code_expires = 0;
2440 cached_pin_code[0] = 0;
2441 MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_PIN_OK"));
2442 EndDialog(hWnd, true);
2443 }
2444
2445 LogoutSec(s);
2446 }
2447
2448 CloseSecSession(s);
2449 }
2450 CloseSec(s);
2451 }
2452
2453 Enable(hWnd, IDOK);
2454 Enable(hWnd, IDCANCEL);
2455
2456 Free(src);
2457 Free(dst);
2458 break;
2459
2460 case IDCANCEL:
2461 Close(hWnd);
2462 break;
2463 }
2464 break;
2465
2466 case WM_CLOSE:
2467 EndDialog(hWnd, false);
2468 break;
2469 }
2470
2471 return 0;
2472 }
2473
2474 // Change the PIN code
CmSecurePin(HWND hWnd,UINT id)2475 void CmSecurePin(HWND hWnd, UINT id)
2476 {
2477 // Validate arguments
2478 if (hWnd == NULL || id == 0 || CheckSecureDeviceId(id) == false)
2479 {
2480 return;
2481 }
2482
2483 Dialog(hWnd, D_CM_SECURE_PIN, CmSecurePinDlg, (void *)id);
2484 }
2485
2486 // Object type selection dialog
CmSecureTypeDlg(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)2487 UINT CmSecureTypeDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
2488 {
2489 UINT type;
2490 // Validate arguments
2491 if (hWnd == NULL)
2492 {
2493 return 0;
2494 }
2495
2496 switch (msg)
2497 {
2498 case WM_INITDIALOG:
2499 type = MsRegReadInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "DefaultImportType");
2500 Check(hWnd, R_DATA, type == SEC_DATA);
2501 Check(hWnd, R_CERT, type == SEC_X);
2502 Check(hWnd, R_KEY, type == SEC_K);
2503 goto UPDATE_CONTROL;
2504
2505 case WM_COMMAND:
2506 switch (wParam)
2507 {
2508 case IDOK:
2509 type = SEC_DATA;
2510 if (IsChecked(hWnd, R_CERT))
2511 {
2512 type = SEC_X;
2513 }
2514 else if (IsChecked(hWnd, R_KEY))
2515 {
2516 type = SEC_K;
2517 }
2518
2519 MsRegWriteInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "DefaultImportType", type);
2520
2521 EndDialog(hWnd, type);
2522 break;
2523
2524 case IDCANCEL:
2525 Close(hWnd);
2526 break;
2527 case R_CERT:
2528 case R_KEY:
2529 case R_DATA:
2530 UPDATE_CONTROL:
2531 SetEnable(hWnd, IDOK, IsChecked(hWnd, R_CERT) ||
2532 IsChecked(hWnd, R_KEY) ||
2533 IsChecked(hWnd, R_DATA));
2534 break;
2535 }
2536 break;
2537
2538 case WM_CLOSE:
2539 EndDialog(hWnd, INFINITE);
2540 break;
2541 }
2542
2543 return 0;
2544 }
2545
2546 // Object type selection
CmSecureType(HWND hWnd)2547 UINT CmSecureType(HWND hWnd)
2548 {
2549 return Dialog(hWnd, D_CM_SECURE_TYPE, CmSecureTypeDlg, NULL);
2550 }
2551
2552 // Initialize the dialog
CmSecureManagerDlgInit(HWND hWnd,UINT id)2553 void CmSecureManagerDlgInit(HWND hWnd, UINT id)
2554 {
2555 SECURE_DEVICE *dev;
2556 // Validate arguments
2557 if (hWnd == NULL || id == 0)
2558 {
2559 return;
2560 }
2561
2562 SetIcon(hWnd, 0, ICO_SECURE);
2563
2564 dev = GetSecureDevice(id);
2565 if (dev != NULL)
2566 {
2567 FormatText(hWnd, S_INFO, dev->DeviceName);
2568 }
2569
2570 SetFont(hWnd, B_BOLD, Font(0, true));
2571
2572 LvInit(hWnd, L_LIST);
2573 LvInsertColumn(hWnd, L_LIST, 0, _UU("SEC_MGR_COLUMN1"), 200);
2574 LvInsertColumn(hWnd, L_LIST, 1, _UU("SEC_MGR_COLUMN2"), 110);
2575
2576 CmSecureManagerDlgUpdate(hWnd, id);
2577 }
2578
2579 // Update controls
CmSecureManagerDlgUpdate(HWND hWnd,UINT id)2580 void CmSecureManagerDlgUpdate(HWND hWnd, UINT id)
2581 {
2582 bool b = true;
2583 bool read_only = IsJPKI(id);
2584 // Validate arguments
2585 if (hWnd == NULL)
2586 {
2587 return;
2588 }
2589
2590 if (LvIsSingleSelected(hWnd, L_LIST) == false)
2591 {
2592 b = false;
2593 }
2594
2595 SetEnable(hWnd, B_EXPORT, b && ((UINT)LvGetParam(hWnd, L_LIST, LvGetSelected(hWnd, L_LIST)) != SEC_K));
2596 SetEnable(hWnd, B_DELETE, b && (read_only == false));
2597 SetEnable(hWnd, B_PIN, (read_only == false));
2598 SetEnable(hWnd, B_IMPORT, (read_only == false));
2599 SetEnable(hWnd, B_NEW_CERT, (read_only == false));
2600 }
2601
2602 // Content update
CmSecureManagerDlgRefresh(HWND hWnd,UINT id)2603 void CmSecureManagerDlgRefresh(HWND hWnd, UINT id)
2604 {
2605 bool ret;
2606 LIST *o;
2607 WINUI_SECURE_BATCH batch[] =
2608 {
2609 {WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},
2610 };
2611 // Validate arguments
2612 if (hWnd == NULL || id == 0)
2613 {
2614 return;
2615 }
2616
2617 ret = SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0);
2618
2619 if (ret == false)
2620 {
2621 return;
2622 }
2623
2624 o = batch[0].EnumList;
2625 if (o != NULL)
2626 {
2627 CmSecureManagerDlgPrintList(hWnd, o);
2628
2629 FreeEnumSecObject(o);
2630 }
2631
2632 // update controls
2633 CmSecureManagerDlgUpdate(hWnd, id);
2634 }
2635
2636 // Show the list of secure objects
CmSecureManagerDlgPrintList(HWND hWnd,LIST * o)2637 void CmSecureManagerDlgPrintList(HWND hWnd, LIST *o)
2638 {
2639 CmSecureManagerDlgPrintListEx(hWnd, L_LIST, o, INFINITE);
2640 }
CmSecureManagerDlgPrintListEx(HWND hWnd,UINT id,LIST * o,UINT type)2641 void CmSecureManagerDlgPrintListEx(HWND hWnd, UINT id, LIST *o, UINT type)
2642 {
2643 UINT i;
2644 LVB *v;
2645 // Validate arguments
2646 if (hWnd == NULL || o == NULL)
2647 {
2648 return;
2649 }
2650
2651 LvReset(hWnd, id);
2652
2653 v = LvInsertStart();
2654
2655 for (i = 0;i < LIST_NUM(o);i++)
2656 {
2657 UINT icon = ICO_LOG2;
2658 wchar_t tmp1[MAX_SIZE], *tmp2, *tmp3;
2659 SEC_OBJ *obj = LIST_DATA(o, i);
2660
2661 if (type == INFINITE || obj->Type == type)
2662 {
2663 StrToUni(tmp1, sizeof(tmp1), obj->Name);
2664 tmp2 = CmSecureObjTypeToStr(obj->Type);
2665 tmp3 = obj->Private ? _UU("SEC_YES") : _UU("SEC_NO");
2666
2667 if (obj->Type == SEC_X)
2668 {
2669 icon = ICO_CERT;
2670 }
2671 else if (obj->Type == SEC_K || obj->Type == SEC_P)
2672 {
2673 icon = ICO_KEY;
2674 }
2675
2676 LvInsertAdd(v, icon, (void *)obj->Type, 2, tmp1, tmp2);
2677 }
2678 }
2679
2680 LvInsertEnd(v, hWnd, id);
2681 }
2682
2683 // Convert the type of secure object to a string
CmSecureObjTypeToStr(UINT type)2684 wchar_t *CmSecureObjTypeToStr(UINT type)
2685 {
2686 wchar_t *ret = _UU("SEC_TYPE_DATA");
2687
2688 if (type == SEC_X)
2689 {
2690 ret = _UU("SEC_TYPE_CERT");
2691 }
2692 else if (type == SEC_K)
2693 {
2694 ret = _UU("SEC_TYPE_KEY");
2695 }
2696 else if (type == SEC_P)
2697 {
2698 ret = _UU("SEC_TYPE_PUB");
2699 }
2700
2701 return ret;
2702 }
2703
2704 // Write by creating a new certificate
CmSecureManagerDlgNewCert(HWND hWnd,UINT id)2705 void CmSecureManagerDlgNewCert(HWND hWnd, UINT id)
2706 {
2707 X *x;
2708 K *k;
2709 char default_name[MAX_SIZE];
2710 char *object_name;
2711 bool ok = false;
2712 WINUI_SECURE_BATCH batch[] =
2713 {
2714 {WINUI_SECURE_WRITE_CERT, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL},
2715 {WINUI_SECURE_WRITE_KEY, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL},
2716 {WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},
2717 };
2718 // Validate arguments
2719 if (hWnd == NULL || id == 0)
2720 {
2721 return;
2722 }
2723
2724 // Dialog for creating certificate
2725 if (SmCreateCert(hWnd, &x, &k, true, NULL, false) == false)
2726 {
2727 return;
2728 }
2729 // Generate the default name
2730 GetPrintNameFromXA(default_name, sizeof(default_name), x);
2731 ConvertSafeFileName(default_name, sizeof(default_name), default_name);
2732
2733 object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),
2734 _UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_CERT, false, false);
2735
2736 if (object_name != NULL)
2737 {
2738 // Enumerate and write
2739 batch[0].InputX = x;
2740 batch[0].Name = object_name;
2741 batch[1].InputK = k;
2742 batch[1].Name = object_name;
2743
2744 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
2745 {
2746 // Failure
2747 }
2748 else
2749 {
2750 ok = true;
2751 }
2752
2753 Free(object_name);
2754 }
2755
2756 if (ok)
2757 {
2758 LIST *o = batch[2].EnumList;
2759
2760 CmSecureManagerDlgPrintList(hWnd, o);
2761
2762 FreeEnumSecObject(o);
2763
2764 MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_NEW_CERT_IMPORT_OK"));
2765 }
2766
2767 FreeX(x);
2768 FreeK(k);
2769 }
2770
2771 // Import
CmSecureManagerDlgImport(HWND hWnd,UINT id)2772 void CmSecureManagerDlgImport(HWND hWnd, UINT id)
2773 {
2774 UINT type;
2775 char name[MAX_SIZE];
2776 wchar_t tmp2[MAX_SIZE];
2777 wchar_t *tmp;
2778 wchar_t *filename;
2779 BUF *b;
2780 K *k;
2781 bool ok = false;
2782 X *x;
2783 WINUI_SECURE_BATCH batch[] =
2784 {
2785 {WINUI_SECURE_WRITE_DATA, name, true, NULL, NULL, NULL, NULL, NULL, NULL},
2786 {WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},
2787 };
2788 // Validate arguments
2789 if (hWnd == NULL || id == 0)
2790 {
2791 return;
2792 }
2793
2794 // Select the type of secure object
2795 type = CmSecureType(hWnd);
2796
2797 switch (type)
2798 {
2799 case SEC_DATA:
2800 // Data
2801 tmp = OpenDlg(hWnd, _UU("DLG_ALL_FILES"), _UU("SEC_IMPORT_DATA"));
2802 if (tmp == NULL)
2803 {
2804 return;
2805 }
2806
2807 filename = CopyUniStr(tmp);
2808 Free(tmp);
2809
2810 // Read the file
2811 b = ReadDumpW(filename);
2812 if (b == NULL)
2813 {
2814 // Read failure
2815 MsgBox(hWnd, MB_ICONSTOP, _UU("SEC_READ_FAILED"));
2816 }
2817 else
2818 {
2819 if (b->Size > MAX_SEC_DATA_SIZE)
2820 {
2821 // File size is too large
2822 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_DATA_TOO_BIG"), MAX_SEC_DATA_SIZE);
2823 }
2824 else
2825 {
2826 // Generate the default name
2827 char default_name[MAX_SIZE];
2828 wchar_t default_name_w[MAX_SIZE];
2829 char *object_name;
2830 GetFileNameFromFilePathW(default_name_w, sizeof(default_name_w), filename);
2831 UniToStr(default_name, sizeof(default_name), default_name_w);
2832 ConvertSafeFileName(default_name, sizeof(default_name), default_name);
2833
2834 object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),
2835 _UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_LOG2, false, false);
2836
2837 if (object_name != NULL)
2838 {
2839 // Enumerate and write
2840 batch[0].InputData = b;
2841 batch[0].Name = object_name;
2842
2843 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
2844 {
2845 // Failure
2846 }
2847 else
2848 {
2849 ok = true;
2850 }
2851
2852 Free(object_name);
2853 }
2854 }
2855
2856 FreeBuf(b);
2857 }
2858
2859 Free(filename);
2860 break;
2861
2862 case SEC_X:
2863 // Read a certificate
2864 if (CmLoadXExW(hWnd, &x, tmp2, sizeof(tmp2)))
2865 {
2866 // Generate the default name
2867 char default_name[MAX_SIZE];
2868 wchar_t default_name_w[MAX_PATH];
2869 char *object_name;
2870 GetFileNameFromFilePathW(default_name_w, sizeof(default_name_w), tmp2);
2871 UniToStr(default_name, sizeof(default_name), default_name_w);
2872 ConvertSafeFileName(default_name, sizeof(default_name), default_name);
2873
2874 object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),
2875 _UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_CERT, false, false);
2876
2877 if (object_name != NULL)
2878 {
2879 // Enumerate and write
2880 batch[0].Type = WINUI_SECURE_WRITE_CERT;
2881 batch[0].InputX = x;
2882 batch[0].Name = object_name;
2883
2884 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
2885 {
2886 // Failure
2887 }
2888 else
2889 {
2890 ok = true;
2891 }
2892
2893 Free(object_name);
2894 }
2895
2896 FreeX(x);
2897 }
2898
2899 break;
2900
2901 case SEC_K:
2902 // Secret key
2903 if (CmLoadKExW(hWnd, &k, tmp2, sizeof(tmp2)))
2904 {
2905 // Generate the default name
2906 char default_name[MAX_SIZE];
2907 wchar_t default_name_w[MAX_PATH];
2908 char *object_name;
2909 GetFileNameFromFilePathW(default_name_w, sizeof(default_name_w), tmp2);
2910 UniToStr(default_name, sizeof(default_name), default_name_w);
2911 ConvertSafeFileName(default_name, sizeof(default_name), default_name);
2912
2913 object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),
2914 _UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_KEY, false, false);
2915
2916 if (object_name != NULL)
2917 {
2918 // Enumerate and write
2919 batch[0].Type = WINUI_SECURE_WRITE_KEY;
2920 batch[0].InputK = k;
2921 batch[0].Name = object_name;
2922
2923 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
2924 {
2925 // Failure
2926 }
2927 else
2928 {
2929 ok = true;
2930 }
2931
2932 Free(object_name);
2933 }
2934
2935 FreeK(k);
2936 }
2937 break;
2938
2939 default:
2940 // Invalid
2941 return;
2942 }
2943
2944 if (ok)
2945 {
2946 LIST *o = batch[1].EnumList;
2947
2948 CmSecureManagerDlgPrintList(hWnd, o);
2949
2950 FreeEnumSecObject(o);
2951
2952 MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_OBJECT_IMPORT_OK"));
2953 }
2954 }
2955
2956 // Export the object
CmSecureManagerDlgExport(HWND hWnd,UINT id)2957 void CmSecureManagerDlgExport(HWND hWnd, UINT id)
2958 {
2959 char name[MAX_SIZE];
2960 UINT method = WINUI_SECURE_READ_DATA;
2961 char *tmp;
2962 UINT type;
2963 wchar_t filename[MAX_PATH];
2964 wchar_t *uni_tmp;
2965 X *x;
2966 BUF *b;
2967 wchar_t default_name[128];
2968 WINUI_SECURE_BATCH batch[] =
2969 {
2970 {WINUI_SECURE_READ_DATA, name, true, NULL, NULL, NULL, NULL, NULL, NULL},
2971 };
2972 UINT i;
2973 // Validate arguments
2974 if (hWnd == NULL || id == 0)
2975 {
2976 return;
2977 }
2978
2979 i = LvGetSelected(hWnd, L_LIST);
2980 if (i == INFINITE)
2981 {
2982 return;
2983 }
2984
2985 tmp = LvGetStrA(hWnd, L_LIST, i, 0);
2986 StrCpy(name, sizeof(name), tmp);
2987 Free(tmp);
2988
2989 type = (UINT)LvGetParam(hWnd, L_LIST, i);
2990
2991 switch (type)
2992 {
2993 case SEC_X:
2994 method = WINUI_SECURE_READ_CERT;
2995 break;
2996
2997 default:
2998 method = WINUI_SECURE_READ_DATA;
2999 break;
3000 }
3001
3002 batch[0].Type = method;
3003
3004 // Operate the smart card
3005 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
3006 {
3007 return;
3008 }
3009
3010 switch (type)
3011 {
3012 case SEC_X:
3013 // Certificate
3014 x = batch[0].OutputX;
3015
3016 CertDlg(hWnd, x, NULL, true);
3017
3018 FreeX(x);
3019 break;
3020
3021 default:
3022 // File
3023 b = batch[0].OutputData;
3024 StrToUni(default_name, sizeof(default_name), name);
3025 uni_tmp = SaveDlg(hWnd, _UU("DLG_ALL_FILES"), _UU("DLG_SAVE_FILE"), default_name, NULL);
3026
3027 if (uni_tmp != NULL)
3028 {
3029 UniStrCpy(filename, sizeof(filename), uni_tmp);
3030
3031 DumpBufW(b, filename);
3032
3033 Free(uni_tmp);
3034
3035 MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_OBJECT_EXPORT_OK"));
3036 }
3037
3038
3039 FreeBuf(b);
3040 break;
3041 }
3042 }
3043
3044 // Delete the object
CmSecureManagerDlgDelete(HWND hWnd,UINT id)3045 void CmSecureManagerDlgDelete(HWND hWnd, UINT id)
3046 {
3047 char name[MAX_SIZE];
3048 UINT method = WINUI_SECURE_DELETE_DATA;
3049 char *tmp;
3050 UINT type;
3051 LIST *o;
3052 WINUI_SECURE_BATCH batch[] =
3053 {
3054 {WINUI_SECURE_DELETE_OBJECT, name, false, NULL, NULL, NULL, NULL, NULL, NULL},
3055 {WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},
3056 };
3057 UINT i;
3058 // Validate arguments
3059 if (hWnd == NULL || id == 0)
3060 {
3061 return;
3062 }
3063
3064 i = LvGetSelected(hWnd, L_LIST);
3065 if (i == INFINITE)
3066 {
3067 return;
3068 }
3069
3070 tmp = LvGetStrA(hWnd, L_LIST, i, 0);
3071 StrCpy(name, sizeof(name), tmp);
3072 Free(tmp);
3073
3074 type = (UINT)LvGetParam(hWnd, L_LIST, i);
3075
3076 switch (type)
3077 {
3078 case SEC_X:
3079 method = WINUI_SECURE_DELETE_CERT;
3080 break;
3081
3082 case SEC_K:
3083 method = WINUI_SECURE_DELETE_KEY;
3084 break;
3085
3086 default:
3087 method = WINUI_SECURE_DELETE_DATA;
3088 break;
3089 }
3090
3091 batch[0].Type = method;
3092
3093 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)
3094 {
3095 return;
3096 }
3097
3098 o = batch[1].EnumList;
3099
3100 CmSecureManagerDlgPrintList(hWnd, o);
3101
3102 FreeEnumSecObject(o);
3103 }
3104
3105 static bool cm_secure_manager_no_new_cert = false;
3106
3107 // Smart Card Manager dialog
CmSecureManagerDlg(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)3108 UINT CmSecureManagerDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
3109 {
3110 NMHDR *n;
3111 UINT id = (UINT)param;
3112 // Validate arguments
3113 if (hWnd == NULL)
3114 {
3115 return 0;
3116 }
3117
3118 switch (msg)
3119 {
3120 case WM_INITDIALOG:
3121 CmSecureManagerDlgInit(hWnd, id);
3122
3123 if (cm_secure_manager_no_new_cert)
3124 {
3125 Hide(hWnd, B_NEW_CERT);
3126 }
3127
3128 SetTimer(hWnd, 1, 1, NULL);
3129 break;
3130
3131 case WM_COMMAND:
3132 switch (wParam)
3133 {
3134 case B_REFRESH:
3135 CmSecureManagerDlgRefresh(hWnd, id);
3136 break;
3137
3138 case B_IMPORT:
3139 CmSecureManagerDlgImport(hWnd, id);
3140 break;
3141
3142 case B_EXPORT:
3143 CmSecureManagerDlgExport(hWnd, id);
3144 break;
3145
3146 case B_DELETE:
3147 if (MsgBox(hWnd, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2,
3148 _UU("SEC_DELETE_MSG")) == IDYES)
3149 {
3150 CmSecureManagerDlgDelete(hWnd, id);
3151 }
3152 break;
3153
3154 case B_NEW_CERT:
3155 CmSecureManagerDlgNewCert(hWnd, id);
3156 break;
3157
3158 case B_PIN:
3159 CmSecurePin(hWnd, id);
3160 break;
3161
3162 case IDCANCEL:
3163 Close(hWnd);
3164 break;
3165 }
3166 break;
3167
3168 case WM_TIMER:
3169 switch (wParam)
3170 {
3171 case 1:
3172 KillTimer(hWnd, 1);
3173
3174 CmSecureManagerDlgRefresh(hWnd, id);
3175 break;
3176 }
3177 break;
3178
3179 case WM_CLOSE:
3180 EndDialog(hWnd, 0);
3181 break;
3182
3183 case WM_NOTIFY:
3184 n = (NMHDR *)lParam;
3185 switch (n->idFrom)
3186 {
3187 case L_LIST:
3188 switch (n->code)
3189 {
3190 case LVN_ITEMCHANGED:
3191 CmSecureManagerDlgUpdate(hWnd, id);
3192 break;
3193 }
3194 break;
3195 }
3196 break;
3197 }
3198
3199 return 0;
3200 }
3201
3202 // Smart Card Manager
CmSecureManager(HWND hWnd,UINT id)3203 void CmSecureManager(HWND hWnd, UINT id)
3204 {
3205 CmSecureManagerEx(hWnd, id, false);
3206 }
CmSecureManagerEx(HWND hWnd,UINT id,bool no_new_cert)3207 void CmSecureManagerEx(HWND hWnd, UINT id, bool no_new_cert)
3208 {
3209 // Validate arguments
3210 if (hWnd == NULL || id == 0)
3211 {
3212 return;
3213 }
3214
3215 // ID check
3216 if (CheckSecureDeviceId(id) == false)
3217 {
3218 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SEC_INVALID_ID"));
3219 return;
3220 }
3221
3222 if (no_new_cert)
3223 {
3224 cm_secure_manager_no_new_cert = true;
3225 }
3226 else
3227 {
3228 cm_secure_manager_no_new_cert = false;
3229 }
3230
3231 Dialog(hWnd, D_CM_SECURE_MANAGER, CmSecureManagerDlg, (void *)id);
3232 }
3233
3234 // Smart Card Manager for Client
CmClientSecureManager(HWND hWnd)3235 void CmClientSecureManager(HWND hWnd)
3236 {
3237 RPC_USE_SECURE t;
3238 UINT id;
3239
3240 Zero(&t, sizeof(t));
3241 CcGetUseSecure(cm->Client, &t);
3242
3243 id = t.DeviceId;
3244
3245 if (id == 0 || CheckSecureDeviceId(id) == false)
3246 {
3247 id = CmClientSelectSecure(hWnd);
3248 }
3249
3250 if (id == 0)
3251 {
3252 return;
3253 }
3254
3255 CmSecureManager(hWnd, id);
3256 }
3257
3258 // Initialize the dialog
CmSelectSecureDlgInit(HWND hWnd,UINT default_id)3259 void CmSelectSecureDlgInit(HWND hWnd, UINT default_id)
3260 {
3261 UINT i;
3262 LIST *o;
3263 LVB *v;
3264
3265 SetIcon(hWnd, 0, ICO_SECURE);
3266
3267 o = GetSecureDeviceList();
3268
3269 LvInit(hWnd, L_LIST);
3270 LvInsertColumn(hWnd, L_LIST, 0, _UU("SEC_COLUMN1"), 150);
3271 LvInsertColumn(hWnd, L_LIST, 1, _UU("SEC_COLUMN2"), 100);
3272 LvInsertColumn(hWnd, L_LIST, 2, _UU("SEC_COLUMN3"), 130);
3273 LvInsertColumn(hWnd, L_LIST, 3, _UU("SEC_COLUMN4"), 100);
3274
3275 v = LvInsertStart();
3276
3277 for (i = 0;i < LIST_NUM(o);i++)
3278 {
3279 wchar_t tmp1[MAX_SIZE];
3280 wchar_t *tmp2;
3281 wchar_t tmp3[MAX_SIZE];
3282 wchar_t tmp4[MAX_SIZE];
3283 SECURE_DEVICE *dev = LIST_DATA(o, i);
3284
3285 StrToUni(tmp1, sizeof(tmp1), dev->DeviceName);
3286 tmp2 = (dev->Type == SECURE_IC_CARD) ? _UU("SEC_SMART_CARD") : _UU("SEC_USB_TOKEN");
3287 StrToUni(tmp3, sizeof(tmp3), dev->Manufacturer);
3288 StrToUni(tmp4, sizeof(tmp4), dev->ModuleName);
3289
3290 LvInsertAdd(v, ICO_SECURE, (void *)dev->Id, 4, tmp1, tmp2, tmp3, tmp4);
3291 }
3292
3293 LvInsertEnd(v, hWnd, L_LIST);
3294
3295 if (default_id != 0)
3296 {
3297 LvSelect(hWnd, L_LIST, LvSearchParam(hWnd, L_LIST, (void *)default_id));
3298 }
3299
3300 ReleaseList(o);
3301
3302 // Control update
3303 CmSelectSecureDlgUpdate(hWnd);
3304 }
3305
3306 // Update controls of the dialog
CmSelectSecureDlgUpdate(HWND hWnd)3307 void CmSelectSecureDlgUpdate(HWND hWnd)
3308 {
3309 SetEnable(hWnd, IDOK, LvIsSingleSelected(hWnd, L_LIST));
3310 }
3311
3312 // Smart card selection dialog
CmSelectSecureDlg(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)3313 UINT CmSelectSecureDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
3314 {
3315 UINT default_id = (UINT)param;
3316 NMHDR *n = NULL;
3317 static UINT old_id;
3318 // Validate arguments
3319 if (hWnd == NULL)
3320 {
3321 return 0;
3322 }
3323
3324 switch (msg)
3325 {
3326 case WM_INITDIALOG:
3327 old_id = default_id;
3328 CmSelectSecureDlgInit(hWnd, default_id);
3329
3330 if (LvNum(hWnd, L_LIST) == 0)
3331 {
3332 // There is no smart card
3333 SetTimer(hWnd, 1, 100, NULL);
3334 }
3335 break;
3336
3337 case WM_TIMER:
3338 switch (wParam)
3339 {
3340 case 1:
3341 KillTimer(hWnd, 1);
3342
3343 Disable(hWnd, L_LIST);
3344 MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_NO_SECURE_DEVICE"));
3345 break;
3346 }
3347 break;
3348
3349 case WM_COMMAND:
3350 switch (wParam)
3351 {
3352 case IDOK:
3353 if (IsEnable(hWnd, IDOK))
3354 {
3355 UINT i = LvGetSelected(hWnd, L_LIST);
3356 if (i != INFINITE)
3357 {
3358 UINT id = (UINT)LvGetParam(hWnd, L_LIST, i);
3359
3360 if (old_id != id)
3361 {
3362 if (CmCheckPkcsEula(hWnd, id) == false)
3363 {
3364 break;
3365 }
3366 }
3367 EndDialog(hWnd, id);
3368 }
3369 }
3370 break;
3371
3372 case IDCANCEL:
3373 Close(hWnd);
3374 break;
3375 }
3376 break;
3377
3378 case WM_CLOSE:
3379 EndDialog(hWnd, 0);
3380 break;
3381
3382 case WM_NOTIFY:
3383 n = (NMHDR *)lParam;
3384 switch (n->idFrom)
3385 {
3386 case L_LIST:
3387 switch (n->code)
3388 {
3389 case LVN_ITEMCHANGED:
3390 CmSelectSecureDlgUpdate(hWnd);
3391 break;
3392 case NM_DBLCLK:
3393 Command(hWnd, IDOK);
3394 break;
3395 }
3396 break;
3397 }
3398 break;
3399 }
3400
3401 return 0;
3402 }
3403
3404 // Select the smart card device to be used
CmSelectSecure(HWND hWnd,UINT current_id)3405 UINT CmSelectSecure(HWND hWnd, UINT current_id)
3406 {
3407 return Dialog(hWnd, D_CM_SELECT_SECURE, CmSelectSecureDlg, (void *)current_id);
3408 }
3409
3410 // Select the smart card device to be used (client)
CmClientSelectSecure(HWND hWnd)3411 UINT CmClientSelectSecure(HWND hWnd)
3412 {
3413 UINT id;
3414 RPC_USE_SECURE t;
3415
3416 if (cm->server_name != NULL)
3417 {
3418 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("CM_SECURE_MUST_LOCAL"));
3419 return 0;
3420 }
3421
3422 Zero(&t, sizeof(t));
3423 CcGetUseSecure(cm->Client, &t);
3424
3425 id = t.DeviceId;
3426
3427 id = CmSelectSecure(hWnd, id);
3428 if (id != 0)
3429 {
3430 Zero(&t, sizeof(t));
3431 t.DeviceId = id;
3432
3433 CALL(hWnd, CcUseSecure(cm->Client, &t));
3434
3435 SmWriteSelectSecureIdReg(id);
3436 }
3437
3438 return id;
3439 }
3440
3441 // Shortcut connection
CmConnectShortcut(UCHAR * key)3442 void CmConnectShortcut(UCHAR *key)
3443 {
3444 UINT ret;
3445 // Validate arguments
3446 if (key == NULL)
3447 {
3448 return;
3449 }
3450
3451 // Attempt to connect
3452 ret = CcShortcut(key);
3453
3454 if (ret != ERR_NO_ERROR)
3455 {
3456 if (ret == ERR_ACCOUNT_ACTIVE)
3457 {
3458 // Because it is currently connected, to query whether or not to disconnect
3459 if (MsgBox(NULL, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_SHORTCUT_DISCONNECT")) == IDYES)
3460 {
3461 // Try to disconnect
3462 ret = CcShortcutDisconnect(key);
3463
3464 if (ret != ERR_NO_ERROR)
3465 {
3466 // Error
3467 MsgBox(NULL, MB_ICONEXCLAMATION, GetUniErrorStr(ret));
3468 }
3469 }
3470 }
3471 else
3472 {
3473 // Other errors
3474 MsgBox(NULL, MB_ICONEXCLAMATION, GetUniErrorStr(ret));
3475 }
3476 }
3477 }
3478
3479 // Play the audio guide
CmVoice(char * name)3480 void CmVoice(char *name)
3481 {
3482 UINT i;
3483 // Validate arguments
3484 if (name == NULL)
3485 {
3486 return;
3487 }
3488
3489 // Voice guidance features disappeared!!
3490 return;
3491
3492 if (cm->DisableVoice)
3493 {
3494 return;
3495 }
3496
3497 for (i = 0;i < sizeof(cm_voice) / sizeof(CM_VOICE);i++)
3498 {
3499 if (cm_voice[i].voice_id == cm->VoiceId)
3500 {
3501 char tmp[MAX_SIZE];
3502 Format(tmp, sizeof(tmp), "%s_%s.wav", cm_voice[i].perfix, name);
3503 MsPlaySound(tmp);
3504 return;
3505 }
3506 }
3507 }
3508
3509 // Update the password changing dialog
CmChangePasswordUpdate(HWND hWnd,CM_CHANGE_PASSWORD * p)3510 void CmChangePasswordUpdate(HWND hWnd, CM_CHANGE_PASSWORD *p)
3511 {
3512 bool ok = true;
3513 char *s1, *s2;
3514 // Validate arguments
3515 if (hWnd == NULL || p == NULL)
3516 {
3517 return;
3518 }
3519
3520 if (IsEmpty(hWnd, E_USERNAME))
3521 {
3522 ok = false;
3523 }
3524
3525 s1 = GetTextA(hWnd, E_NEW_PASSWORD1);
3526 s2 = GetTextA(hWnd, E_NEW_PASSWORD2);
3527
3528 if (StrCmp(s1, s2) != 0)
3529 {
3530 ok = false;
3531 }
3532
3533 Free(s1);
3534 Free(s2);
3535
3536 SetEnable(hWnd, IDOK, ok);
3537 }
3538
3539 // Password changing dialog procedure
CmChangePasswordProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)3540 UINT CmChangePasswordProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
3541 {
3542 CM_CHANGE_PASSWORD *p = (CM_CHANGE_PASSWORD *)param;
3543 char username[MAX_USERNAME_LEN + 1];
3544 char old_pass[MAX_PASSWORD_LEN + 1];
3545 char new_pass[MAX_PASSWORD_LEN + 1];
3546 UINT ret;
3547 // Validate arguments
3548 if (hWnd == NULL)
3549 {
3550 return 0;
3551 }
3552
3553 switch (msg)
3554 {
3555 case WM_INITDIALOG:
3556 SetTextA(hWnd, E_HUBNAME, p->HubName);
3557 SetTextA(hWnd, E_USERNAME, p->Username);
3558 FormatText(hWnd, S_TITLE, p->ClientOption->Hostname);
3559
3560 if (IsEmpty(hWnd, E_USERNAME))
3561 {
3562 FocusEx(hWnd, E_USERNAME);
3563 }
3564 else
3565 {
3566 FocusEx(hWnd, E_OLD_PASSWORD);
3567 }
3568
3569 CmChangePasswordUpdate(hWnd, p);
3570 break;
3571
3572 case WM_COMMAND:
3573 switch (LOWORD(wParam))
3574 {
3575 case E_USERNAME:
3576 case E_OLD_PASSWORD:
3577 case E_NEW_PASSWORD1:
3578 case E_NEW_PASSWORD2:
3579 CmChangePasswordUpdate(hWnd, p);
3580 break;
3581 }
3582
3583 switch (wParam)
3584 {
3585 case IDOK:
3586 GetTxtA(hWnd, E_USERNAME, username, sizeof(username));
3587 GetTxtA(hWnd, E_OLD_PASSWORD, old_pass, sizeof(old_pass));
3588 GetTxtA(hWnd, E_NEW_PASSWORD1, new_pass, sizeof(new_pass));
3589
3590 Disable(hWnd, E_USERNAME);
3591 Disable(hWnd, E_OLD_PASSWORD);
3592 Disable(hWnd, E_NEW_PASSWORD1);
3593 Disable(hWnd, E_NEW_PASSWORD2);
3594 Disable(hWnd, IDOK);
3595 Disable(hWnd, IDCANCEL);
3596
3597 ret = ChangePassword(cm->Cedar, p->ClientOption, p->HubName, username, old_pass, new_pass);
3598
3599 if (ret == ERR_NO_ERROR)
3600 {
3601 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PASSWORD_CHANGED"));
3602 EndDialog(hWnd, true);
3603 }
3604 else
3605 {
3606 MsgBox(hWnd, MB_ICONSTOP, _E(ret));
3607 Enable(hWnd, E_USERNAME);
3608 Enable(hWnd, E_OLD_PASSWORD);
3609 Enable(hWnd, E_NEW_PASSWORD1);
3610 Enable(hWnd, E_NEW_PASSWORD2);
3611 Enable(hWnd, IDOK);
3612 Enable(hWnd, IDCANCEL);
3613
3614 SetTextA(hWnd, E_OLD_PASSWORD, "");
3615 SetTextA(hWnd, E_NEW_PASSWORD1, "");
3616 SetTextA(hWnd, E_NEW_PASSWORD2, "");
3617
3618 Focus(hWnd, E_OLD_PASSWORD);
3619 }
3620
3621 break;
3622
3623 case IDCANCEL:
3624 Close(hWnd);
3625 break;
3626
3627 }
3628
3629 break;
3630
3631 case WM_CLOSE:
3632 EndDialog(hWnd, false);
3633 break;
3634 }
3635
3636 return 0;
3637 }
3638
3639 // Show the password changing dialog
CmChangePassword(HWND hWnd,CLIENT_OPTION * o,char * hubname,char * username)3640 void CmChangePassword(HWND hWnd, CLIENT_OPTION *o, char *hubname, char *username)
3641 {
3642 CM_CHANGE_PASSWORD p;
3643 // Validate arguments
3644 if (hWnd == NULL || o == NULL || hubname == NULL || username == NULL)
3645 {
3646 return;
3647 }
3648
3649 Zero(&p, sizeof(p));
3650 StrCpy(p.Username, sizeof(p.Username), username);
3651 StrCpy(p.HubName, sizeof(p.HubName), hubname);
3652 p.ClientOption = o;
3653
3654 CmVoice("password");
3655
3656 Dialog(hWnd, D_CM_CHANGE_PASSWORD, CmChangePasswordProc, &p);
3657 }
3658
3659 // Prohibit the installation of the virtual LAN card
CmStopInstallVLan(HWND hWnd)3660 bool CmStopInstallVLan(HWND hWnd)
3661 {
3662 if (cm->Client->Unix)
3663 {
3664 // There is no need to be prohibited if the client is an UNIX
3665 return true;
3666 }
3667 if (cm->Client->Win9x)
3668 {
3669 // There is no need to prohibit if the client is a Win9x
3670 return true;
3671 }
3672
3673 return true;
3674
3675 if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled())
3676 {
3677 if (MsGetCurrentTerminalSessionId() == 0)
3678 {
3679 // There is no need to prohibit
3680 return true;
3681 }
3682 else
3683 {
3684 // Prohibit to install the device drivers since
3685 // the user logged in other than the console session
3686 wchar_t *user = MsGetSessionUserName(0);
3687
3688 if (user == NULL)
3689 {
3690 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("CM_STOP_INST_VLAN_2"),
3691 MsIsTerminalServiceInstalled() ? _UU("CM_DESKTOP_MSG_LOCAL_TS") : _UU("CM_DESKTOP_MSG_LOCAL_SW"),
3692 MsGetCurrentTerminalSessionId());
3693 }
3694 else
3695 {
3696 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("CM_STOP_INST_VLAN_1"),
3697 MsIsTerminalServiceInstalled() ? _UU("CM_DESKTOP_MSG_LOCAL_TS") : _UU("CM_DESKTOP_MSG_LOCAL_SW"),
3698 MsGetCurrentTerminalSessionId(), 0, user);
3699 }
3700
3701 if (user != NULL)
3702 {
3703 Free(user);
3704 }
3705 return false;
3706 }
3707 }
3708 else
3709 {
3710 // There is no need to prohibit
3711 return true;
3712 }
3713 }
3714
3715 // Desktop difference warning message dialog initialization
CmDesktopDlgInit(HWND hWnd,wchar_t * account_name)3716 void CmDesktopDlgInit(HWND hWnd, wchar_t *account_name)
3717 {
3718 wchar_t tmp[2048];
3719 bool remote = false;
3720 bool user_switching = false;
3721 bool console_active = false;
3722 wchar_t *console_user = NULL;
3723 // Validate arguments
3724 if (hWnd == NULL)
3725 {
3726 return;
3727 }
3728
3729 FormatText(hWnd, 0, account_name);
3730 FormatText(hWnd, S_TITLE, account_name);
3731 DlgFont(hWnd, S_TITLE, 11, true);
3732 DlgFont(hWnd, S_INFO, 11, true);
3733 if (cm->server_name == NULL)
3734 {
3735 UniStrCpy(tmp, sizeof(tmp), _UU("CM_DESKTOP_LOCAL_PC"));
3736 }
3737 else
3738 {
3739 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_REMOTE_PC"), cm->server_name);
3740 }
3741 FormatText(hWnd, S_WARNING, tmp);
3742
3743 if (cm->server_name != NULL)
3744 {
3745 remote = true;
3746 }
3747 else
3748 {
3749 if (MsIsTerminalServiceInstalled())
3750 {
3751 user_switching = false;
3752 }
3753 else
3754 {
3755 user_switching = true;
3756 }
3757
3758 console_user = MsGetSessionUserName(0);
3759
3760 if (console_user == NULL)
3761 {
3762 console_active = false;
3763 }
3764 else
3765 {
3766 console_active = true;
3767 }
3768 }
3769
3770 // MSG1
3771 if (remote == false)
3772 {
3773 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_1"),
3774 user_switching ? _UU("CM_DESKTOP_MSG_LOCAL_SW") : _UU("CM_DESKTOP_MSG_LOCAL_TS"));
3775 }
3776 else
3777 {
3778 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_REMOTE_1"),
3779 cm->server_name);
3780 }
3781 SetText(hWnd, S_MSG_1, tmp);
3782
3783 // MSG2
3784 if (remote == false)
3785 {
3786 if (console_active)
3787 {
3788 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_21"),
3789 console_user, MsGetCurrentTerminalSessionId());
3790 }
3791 else
3792 {
3793 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_22"),
3794 MsGetCurrentTerminalSessionId());
3795 }
3796 }
3797 else
3798 {
3799 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_REMOTE_2"), cm->server_name);
3800 }
3801 SetText(hWnd, S_MSG_2, tmp);
3802
3803 // MSG3
3804 if (remote == false)
3805 {
3806 if (console_active)
3807 {
3808 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_31"),
3809 console_user, account_name);
3810 }
3811 else
3812 {
3813 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_32"),
3814 account_name);
3815 }
3816 }
3817 else
3818 {
3819 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_REMOTE_3"), cm->server_name,
3820 account_name);
3821 }
3822 SetText(hWnd, S_MSG_3, tmp);
3823
3824 if (console_user != NULL)
3825 {
3826 Free(console_user);
3827 }
3828 }
3829
3830 // Desktop difference warning message dialog
CmDesktopDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)3831 UINT CmDesktopDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
3832 {
3833 wchar_t *account_name = (wchar_t *)param;
3834 // Validate arguments
3835 if (hWnd == NULL)
3836 {
3837 return 0;
3838 }
3839
3840 switch (msg)
3841 {
3842 case WM_INITDIALOG:
3843 CmDesktopDlgInit(hWnd, account_name);
3844 break;
3845 case WM_COMMAND:
3846 switch (wParam)
3847 {
3848 case IDOK:
3849 EndDialog(hWnd, true);
3850 break;
3851 case IDCANCEL:
3852 Close(hWnd);
3853 break;
3854 }
3855 break;
3856 case WM_CLOSE:
3857 EndDialog(hWnd, false);
3858 break;
3859 }
3860
3861 return 0;
3862 }
3863
3864 // Show a warning message that the desktop is different, if necessary
CmWarningDesktop(HWND hWnd,wchar_t * account_name)3865 bool CmWarningDesktop(HWND hWnd, wchar_t *account_name)
3866 {
3867 // Validate arguments
3868 if (hWnd == NULL || account_name == NULL)
3869 {
3870 return false;
3871 }
3872
3873 if (cm->Client->Unix)
3874 {
3875 //There is no need for warning if the client is an UNIX
3876 return true;
3877 }
3878
3879 if (/*MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled() ||*/ (cm->server_name != NULL))
3880 {
3881 if (cm->server_name == NULL)
3882 {
3883 //if (MsGetCurrentTerminalSessionId() == 0)
3884 {
3885 // No need for warning
3886 return true;
3887 }
3888 }
3889 // There is a need for warning
3890 return Dialog(hWnd, D_CM_DESKTOP, CmDesktopDlgProc, account_name);
3891 }
3892 else
3893 {
3894 // No need for warning
3895 return true;
3896 }
3897 }
3898
3899 // Update the password setting dialog
CmPasswordRefresh(HWND hWnd)3900 void CmPasswordRefresh(HWND hWnd)
3901 {
3902 bool ok = true;
3903 // Validate arguments
3904 if (hWnd == NULL)
3905 {
3906 return;
3907 }
3908
3909 SetEnable(hWnd, E_PASSWORD, IsChecked(hWnd, R_USE_PASSWORD));
3910 SetEnable(hWnd, E_PASSWORD2, IsChecked(hWnd, R_USE_PASSWORD));
3911 SetEnable(hWnd, IDC_STATIC1, IsChecked(hWnd, R_USE_PASSWORD));
3912 SetEnable(hWnd, IDC_STATIC2, IsChecked(hWnd, R_USE_PASSWORD));
3913 SetEnable(hWnd, R_REMOTE_ONLY, IsChecked(hWnd, R_USE_PASSWORD));
3914
3915 if (IsChecked(hWnd, R_USE_PASSWORD))
3916 {
3917 char tmp1[MAX_SIZE];
3918 char tmp2[MAX_SIZE];
3919 if (IsEmpty(hWnd, E_PASSWORD))
3920 {
3921 ok = false;
3922 }
3923 GetTxtA(hWnd, E_PASSWORD, tmp1, sizeof(tmp1));
3924 GetTxtA(hWnd, E_PASSWORD2, tmp2, sizeof(tmp2));
3925 if (StrCmp(tmp1, tmp2) != 0)
3926 {
3927 ok = false;
3928 }
3929 if (StrCmp(tmp1, HIDDEN_PASSWORD) == 0)
3930 {
3931 ok = false;
3932 }
3933 }
3934
3935 SetEnable(hWnd, IDOK, ok);
3936 }
3937
3938 // Password setting procedure
CmPasswordProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)3939 UINT CmPasswordProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
3940 {
3941 RPC_CLIENT_PASSWORD_SETTING c;
3942 RPC_CLIENT_PASSWORD p;
3943 char tmp[MAX_SIZE];
3944 // Validate arguments
3945 if (hWnd == NULL)
3946 {
3947 return 0;
3948 }
3949
3950 switch (msg)
3951 {
3952 case WM_INITDIALOG:
3953 // Get the password setting
3954 if (CALL(hWnd, CcGetPasswordSetting(cm->Client, &c)))
3955 {
3956 Check(hWnd, R_USE_PASSWORD, c.IsPasswordPresented);
3957 if (c.IsPasswordPresented)
3958 {
3959 SetTextA(hWnd, E_PASSWORD, HIDDEN_PASSWORD);
3960 SetTextA(hWnd, E_PASSWORD2, HIDDEN_PASSWORD);
3961 FocusEx(hWnd, E_PASSWORD);
3962 Check(hWnd, R_REMOTE_ONLY, c.PasswordRemoteOnly);
3963 }
3964 else
3965 {
3966 Focus(hWnd, R_USE_PASSWORD);
3967 }
3968 }
3969 CmPasswordRefresh(hWnd);
3970 break;
3971 case WM_COMMAND:
3972 switch (wParam)
3973 {
3974 case R_USE_PASSWORD:
3975 if (IsChecked(hWnd, R_USE_PASSWORD))
3976 {
3977 FocusEx(hWnd, E_PASSWORD);
3978 }
3979 break;
3980 case IDOK:
3981 GetTxtA(hWnd, E_PASSWORD, tmp, sizeof(tmp));
3982 Zero(&p, sizeof(p));
3983 if (IsChecked(hWnd, R_USE_PASSWORD))
3984 {
3985 StrCpy(p.Password, sizeof(p.Password), tmp);
3986 p.PasswordRemoteOnly = IsChecked(hWnd, R_REMOTE_ONLY);
3987 }
3988
3989 if (CALL(hWnd, CcSetPassword(cm->Client, &p)))
3990 {
3991 if (StrLen(p.Password) > 0)
3992 {
3993 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PASSWORD_SET"));
3994 }
3995 else
3996 {
3997 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PASSWORD_REMOVE"));
3998 }
3999 EndDialog(hWnd, true);
4000 }
4001 break;
4002 case IDCANCEL:
4003 Close(hWnd);
4004 break;
4005 }
4006 switch (LOWORD(wParam))
4007 {
4008 case R_USE_PASSWORD:
4009 case R_REMOTE_ONLY:
4010 case E_PASSWORD:
4011 case E_PASSWORD2:
4012 CmPasswordRefresh(hWnd);
4013 break;
4014 }
4015 switch (wParam)
4016 {
4017 case R_REMOTE_ONLY:
4018 case R_USE_PASSWORD:
4019 if (IsChecked(hWnd, R_USE_PASSWORD))
4020 {
4021 FocusEx(hWnd, E_PASSWORD);
4022 }
4023 break;
4024 }
4025 break;
4026 case WM_CLOSE:
4027 EndDialog(hWnd, false);
4028 break;
4029 }
4030
4031 return 0;
4032 }
4033
4034 // Set the password
CmPassword(HWND hWnd)4035 void CmPassword(HWND hWnd)
4036 {
4037 // Validate arguments
4038 if (hWnd == NULL)
4039 {
4040 return;
4041 }
4042
4043 Dialog(hWnd, D_CM_PASSWORD, CmPasswordProc, NULL);
4044 }
4045
4046 // CA dialog update
CmTrustDlgUpdate(HWND hWnd)4047 void CmTrustDlgUpdate(HWND hWnd)
4048 {
4049 // Validate arguments
4050 if (hWnd == NULL)
4051 {
4052 return;
4053 }
4054
4055 SetEnable(hWnd, B_EXPORT, LvIsSelected(hWnd, L_CERT));
4056 SetEnable(hWnd, B_DELETE, LvIsSelected(hWnd, L_CERT) && cm->CmSetting.LockMode == false);
4057 SetEnable(hWnd, IDOK, LvIsSelected(hWnd, L_CERT));
4058 SetEnable(hWnd, B_IMPORT, cm->CmSetting.LockMode == false);
4059 }
4060
4061 // Update the list of certificates
CmTrustDlgRefresh(HWND hWnd)4062 void CmTrustDlgRefresh(HWND hWnd)
4063 {
4064 RPC_CLIENT_ENUM_CA c;
4065 // Validate arguments
4066 if (hWnd == NULL)
4067 {
4068 return;
4069 }
4070
4071 if (CALL(hWnd, CcEnumCa(cm->Client, &c)))
4072 {
4073 UINT i;
4074 LVB *b = LvInsertStart();
4075 for (i = 0;i < c.NumItem;i++)
4076 {
4077 RPC_CLIENT_ENUM_CA_ITEM *cert = c.Items[i];
4078 wchar_t tmp[MAX_SIZE];
4079
4080 GetDateStrEx64(tmp, sizeof(tmp), SystemToLocal64(cert->Expires), NULL);
4081 LvInsertAdd(b, ICO_CERT, (void *)cert->Key, 3,
4082 cert->SubjectName, cert->IssuerName, tmp);
4083 }
4084 LvInsertEnd(b, hWnd, L_CERT);
4085 CiFreeClientEnumCa(&c);
4086 }
4087
4088 CmTrustDlgUpdate(hWnd);
4089 }
4090
4091 // Import
CmTrustImport(HWND hWnd)4092 void CmTrustImport(HWND hWnd)
4093 {
4094 X *x;
4095 RPC_CERT c;
4096 if (CmLoadXFromFileOrSecureCard(hWnd, &x) == false)
4097 {
4098 return;
4099 }
4100
4101 Zero(&c, sizeof(c));
4102 c.x = x;
4103
4104 CALL(hWnd, CcAddCa(cm->Client, &c));
4105 CmVoice("new_cert");
4106
4107 FreeX(c.x);
4108 CmTrustDlgRefresh(hWnd);
4109 }
4110
4111 // Export
CmTrustExport(HWND hWnd)4112 void CmTrustExport(HWND hWnd)
4113 {
4114 UINT key;
4115 // Validate arguments
4116 if (hWnd == NULL)
4117 {
4118 return;
4119 }
4120
4121 key = (UINT)LvGetParam(hWnd, L_CERT, LvGetSelected(hWnd, L_CERT));
4122 if (key != INFINITE)
4123 {
4124 RPC_GET_CA a;
4125 Zero(&a, sizeof(a));
4126 a.Key = key;
4127
4128 if (CALL(hWnd, CcGetCa(cm->Client, &a)))
4129 {
4130 wchar_t *name;
4131 X *x = CloneX(a.x);
4132 CiFreeGetCa(&a);
4133
4134 // Save
4135 name = SaveDlg(hWnd, _UU("DLG_CERT_FILES"), _UU("DLG_SAVE_CERT"), NULL, L".cer");
4136 if (name != NULL)
4137 {
4138 wchar_t str[MAX_SIZE];
4139 UniStrCpy(str, sizeof(str), name);
4140 if (XToFileW(x, str, true))
4141 {
4142 MsgBox(hWnd, MB_ICONINFORMATION, _UU("DLG_CERT_SAVE_OK"));
4143 }
4144 else
4145 {
4146 MsgBox(hWnd, MB_ICONSTOP, _UU("DLG_CERT_SAVE_ERROR"));
4147 }
4148 Free(name);
4149 }
4150 FreeX(x);
4151 }
4152 }
4153 }
4154
4155 // Display
CmTrustView(HWND hWnd)4156 void CmTrustView(HWND hWnd)
4157 {
4158 UINT key;
4159 // Validate arguments
4160 if (hWnd == NULL)
4161 {
4162 return;
4163 }
4164
4165 key = (UINT)LvGetParam(hWnd, L_CERT, LvGetSelected(hWnd, L_CERT));
4166 if (key != INFINITE)
4167 {
4168 RPC_GET_CA a;
4169 Zero(&a, sizeof(a));
4170 a.Key = key;
4171
4172 if (CALL(hWnd, CcGetCa(cm->Client, &a)))
4173 {
4174 X *x = CloneX(a.x);
4175 X *x_issuer;
4176 CiFreeGetCa(&a);
4177
4178 x_issuer = CmGetIssuer(x);
4179 CertDlg(hWnd, x, x_issuer, true);
4180 FreeX(x);
4181 FreeX(x_issuer);
4182 }
4183 }
4184 }
4185
4186 // CA dialog procedure
CmTrustDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)4187 UINT CmTrustDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
4188 {
4189 NMHDR *n;
4190 UINT index;
4191 // Validate arguments
4192 if (hWnd == NULL)
4193 {
4194 return 0;
4195 }
4196
4197 switch (msg)
4198 {
4199 case WM_INITDIALOG:
4200 LvInit(hWnd, L_CERT);
4201 LvInsertColumn(hWnd, L_CERT, 0, _UU("CM_CERT_COLUMN_1"), 190);
4202 LvInsertColumn(hWnd, L_CERT, 1, _UU("CM_CERT_COLUMN_2"), 190);
4203 LvInsertColumn(hWnd, L_CERT, 2, _UU("CM_CERT_COLUMN_3"), 160);
4204 CmTrustDlgRefresh(hWnd);
4205 break;
4206 case WM_COMMAND:
4207 switch (wParam)
4208 {
4209 case B_IMPORT:
4210 CmTrustImport(hWnd);
4211 break;
4212 case B_EXPORT:
4213 CmTrustExport(hWnd);
4214 break;
4215 case B_DELETE:
4216 index = LvGetSelected(hWnd, L_CERT);
4217 if (index != INFINITE)
4218 {
4219 UINT key = (UINT)LvGetParam(hWnd, L_CERT, index);
4220 if (key != INFINITE)
4221 {
4222 if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_CERT_DELETE_MSG")) == IDYES)
4223 {
4224 RPC_CLIENT_DELETE_CA c;
4225 Zero(&c, sizeof(c));
4226 c.Key = key;
4227 if (CALL(hWnd, CcDeleteCa(cm->Client, &c)))
4228 {
4229 CmTrustDlgRefresh(hWnd);
4230 }
4231 }
4232 }
4233 }
4234 break;
4235 case IDOK:
4236 if (IsEnable(hWnd, IDOK))
4237 {
4238 CmTrustView(hWnd);
4239 }
4240 break;
4241 case IDCANCEL:
4242 Close(hWnd);
4243 break;
4244 }
4245 break;
4246 case WM_CLOSE:
4247 EndDialog(hWnd, 0);
4248 break;
4249 case WM_NOTIFY:
4250 n = (NMHDR *)lParam;
4251 switch (n->idFrom)
4252 {
4253 case L_CERT:
4254 switch (n->code)
4255 {
4256 case LVN_ITEMCHANGED:
4257 CmTrustDlgUpdate(hWnd);
4258 break;
4259 case NM_DBLCLK:
4260 Command(hWnd, IDOK);
4261 break;
4262 }
4263 break;
4264 }
4265 break;
4266 }
4267
4268 LvSortHander(hWnd, msg, wParam, lParam, L_CERT);
4269
4270 return 0;
4271 }
4272
4273 // Show the CA dialog
CmTrustDlg(HWND hWnd)4274 void CmTrustDlg(HWND hWnd)
4275 {
4276 Dialog(hWnd, D_CM_TRUST, CmTrustDlgProc, NULL);
4277 }
4278
4279 // Main window procedure
CmMainWindowProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)4280 UINT CmMainWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
4281 {
4282 NMHDR *n;
4283 static UINT taskbar_msg = 0;
4284 COPYDATASTRUCT *cpy;
4285 // Validate arguments
4286 if (hWnd == NULL)
4287 {
4288 return 0;
4289 }
4290
4291 if (taskbar_msg != 0 && msg == taskbar_msg)
4292 {
4293 // The task-bar is regenerated
4294 if (cm->TrayInited)
4295 {
4296 MsRestoreIconOnTray();
4297 }
4298 }
4299
4300 // CmSetForegroundProcessToCnService();
4301
4302 switch (msg)
4303 {
4304 case WM_CM_SETTING_CHANGED_MESSAGE:
4305 // CM_SETTING has changed
4306 CmApplyCmSetting();
4307 break;
4308 case WM_INITDIALOG:
4309 CmMainWindowOnInit(hWnd);
4310 taskbar_msg = RegisterWindowMessage("TaskbarCreated");
4311 CmEndStartupMutex();
4312 break;
4313 case WM_CM_SHOW:
4314 // Received a display request from another process
4315 if (cm->CmSetting.EasyMode == false)
4316 {
4317 ShowWindow(hWnd, SW_SHOWNORMAL);
4318 }
4319 else
4320 {
4321 if (cm->hEasyWnd == NULL)
4322 {
4323 CmShowEasy();
4324 }
4325 else
4326 {
4327 SetForegroundWindow(cm->hEasyWnd);
4328 SetActiveWindow(cm->hEasyWnd);
4329 }
4330 }
4331 break;
4332 case WM_COMMAND:
4333 CmMainWindowOnCommand(hWnd, wParam, lParam);
4334 break;
4335 case WM_SIZE:
4336 CmMainWindowOnSize(hWnd);
4337 break;
4338 case WM_CLOSE:
4339 if (cm->CmSetting.EasyMode == false)
4340 {
4341 CmShowOrHideWindow(hWnd);
4342 }
4343 else
4344 {
4345 if (cm->hEasyWnd == NULL)
4346 {
4347 CmShowEasy();
4348 }
4349 else
4350 {
4351 SetForegroundWindow(cm->hEasyWnd);
4352 SetActiveWindow(cm->hEasyWnd);
4353 }
4354 }
4355 return 1;
4356 case WM_INITMENUPOPUP:
4357 if (HIWORD(lParam) == false)
4358 {
4359 CmMainWindowOnPopupMenu(hWnd, (HMENU)wParam, LOWORD(lParam));
4360 }
4361 break;
4362 case WM_NOTIFY:
4363 n = (NMHDR *)lParam;
4364 if (n->idFrom == L_ACCOUNT && (n->code == LVN_BEGINLABELEDITW || n->code == LVN_BEGINLABELEDITA))
4365 {
4366 wchar_t *tmp = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
4367 if (tmp != NULL)
4368 {
4369 if (UniStrCmpi(tmp, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(tmp, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(tmp, _UU("CM_VGC_LINK")) == 0
4370 )
4371 {
4372 SendMsg(hWnd, L_ACCOUNT, LVM_CANCELEDITLABEL, 0, 0);
4373 Free(tmp);
4374 return true;
4375 }
4376 Free(tmp);
4377 }
4378 }
4379 CmMainWindowOnNotify(hWnd, (NMHDR *)lParam);
4380 break;
4381 case WM_CM_NOTIFY:
4382 CmRefreshVLanList(hWnd);
4383 CmRefreshAccountList(hWnd);
4384 CmRefreshStatusBar(hWnd);
4385 break;
4386 case WM_TIMER:
4387 switch (wParam)
4388 {
4389 case 1:
4390 CmSetForegroundProcessToCnService();
4391 break;
4392 case 2:
4393 CmPollingTray(hWnd);
4394 break;
4395 case 3:
4396 KillTimer(hWnd, 3);
4397 Hide(hWnd, 0);
4398 break;
4399 case 4:
4400 KillTimer(hWnd, 4);
4401 CmMainWindowOnShowEasy(hWnd);
4402 break;
4403 case 6:
4404 if (cm->Update == NULL)
4405 {
4406 if (cm->server_name == NULL)
4407 {
4408 if (CmGetNumConnected(hWnd) == 0)
4409 {
4410 cm->Update = InitUpdateUi(_UU("PRODUCT_NAME_VPN_CMGR"), NAME_OF_VPN_CLIENT_MANAGER, NULL,
4411 GetCurrentBuildDate(), CEDAR_BUILD, CEDAR_VER, ((cm->Client == NULL) ? NULL : cm->Client->ClientId),
4412 true);
4413 }
4414 }
4415 }
4416 break;
4417 }
4418 break;
4419 case WM_CM_TRAY_MESSAGE:
4420 // Message from the icon in the task tray
4421 CmMainWindowOnTrayClicked(hWnd, wParam, lParam);
4422 break;
4423 case WM_COPYDATA:
4424 cpy = (COPYDATASTRUCT *)lParam;
4425 if (cpy != NULL)
4426 {
4427 if (cpy->dwData == CM_IMPORT_FILENAME_MSG || cpy->dwData == CM_IMPORT_FILENAME_MSG_OVERWRITE)
4428 {
4429 char *filename = (char *)cpy->lpData;
4430
4431 if (cm->CmSetting.LockMode == false || cpy->dwData == CM_IMPORT_FILENAME_MSG_OVERWRITE)
4432 {
4433 wchar_t fullpath[MAX_PATH];
4434
4435 if (StrLen(filename) >= 2 && IsFileExists(filename))
4436 {
4437 StrToUni(fullpath, sizeof(fullpath), filename);
4438 }
4439 else
4440 {
4441 UniStrCpy(fullpath, sizeof(fullpath), (wchar_t *)filename);
4442 }
4443
4444 CmImportAccountMainEx(cm->hEasyWnd ? cm->hEasyWnd : hWnd, fullpath, cpy->dwData == CM_IMPORT_FILENAME_MSG_OVERWRITE);
4445 }
4446 else
4447 {
4448 MsgBox(cm->hEasyWnd ? cm->hEasyWnd : hWnd, MB_ICONEXCLAMATION | MB_SETFOREGROUND | MB_TOPMOST, _UU("CM_VPN_FILE_IMPORT_NG"));
4449 }
4450 }
4451 }
4452 break;
4453 case WM_QUERYENDSESSION:
4454 // Windows is about to terminate
4455 cm->WindowsShutdowning = true;
4456 CmSaveMainWindowPos(hWnd);
4457 SleepThread(256);
4458 break;
4459 case WM_ENDSESSION:
4460 // Windows has terminated
4461 _exit(0);
4462 break;
4463 }
4464
4465 LvSortHander(hWnd, msg, wParam, lParam, L_ACCOUNT);
4466 LvSortHander(hWnd, msg, wParam, lParam, L_VLAN);
4467
4468 return 0;
4469 }
4470
4471 // Specify the notification service to the foreground process
CmSetForegroundProcessToCnService()4472 void CmSetForegroundProcessToCnService()
4473 {
4474 if (cm->MenuPopuping)
4475 {
4476 return;
4477 }
4478 if (cm->server_name == NULL)
4479 {
4480 if (CnCheckAlreadyExists(false))
4481 {
4482 AllowFGWindow(MsRegReadInt(REG_CURRENT_USER,
4483 CM_REG_KEY, "NotifyServerProcessId"));
4484 }
4485 }
4486 }
4487
4488 // Show the [recent destination] sub-menu
CmCreateRecentSubMenu(HWND hWnd,UINT start_id)4489 HMENU CmCreateRecentSubMenu(HWND hWnd, UINT start_id)
4490 {
4491 HMENU h = NULL;
4492 UINT i;
4493 RPC_CLIENT_ENUM_ACCOUNT a;
4494 LIST *o;
4495 bool easy;
4496
4497 easy = cm->CmSetting.EasyMode;
4498
4499 Zero(&a, sizeof(a));
4500
4501 if (CcEnumAccount(cm->Client, &a) == ERR_NO_ERROR)
4502 {
4503 o = NewListFast(CiCompareClientAccountEnumItemByLastConnectDateTime);
4504
4505 for (i = 0;i < a.NumItem;i++)
4506 {
4507 RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = a.Items[i];
4508
4509 item->tmp1 = i;
4510
4511 if (item->LastConnectDateTime != 0)
4512 {
4513 Add(o, item);
4514 }
4515 }
4516
4517 Sort(o);
4518
4519 for (i = 0;i < MIN(LIST_NUM(o), CM_NUM_RECENT);i++)
4520 {
4521 RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = (RPC_CLIENT_ENUM_ACCOUNT_ITEM *)LIST_DATA(o, i);
4522 wchar_t tmp[MAX_PATH];
4523 wchar_t *account_name;
4524 char *server_name;
4525 char *hub_name;
4526 UINT pos;
4527
4528 if (h == NULL)
4529 {
4530 h = CreatePopupMenu();
4531 }
4532
4533 account_name = item->AccountName;
4534 server_name = item->ServerName;
4535 hub_name = item->HubName;
4536
4537 UniStrCpy(tmp, sizeof(tmp), account_name);
4538
4539 pos = LvSearchStr(hWnd, L_ACCOUNT, 0, account_name);
4540 if (pos != INFINITE)
4541 {
4542 MsAppendMenu(h, MF_STRING, start_id + pos, tmp);
4543 }
4544 }
4545
4546 ReleaseList(o);
4547
4548 CiFreeClientEnumAccount(&a);
4549 }
4550
4551 return h;
4552 }
4553
4554 // Show the sub-menu of the right-click menu in the task tray
CmCreateTraySubMenu(HWND hWnd,bool flag,UINT start_id)4555 HMENU CmCreateTraySubMenu(HWND hWnd, bool flag, UINT start_id)
4556 {
4557 HMENU h = NULL;
4558 UINT i, num;
4559 bool easy;
4560 // Validate arguments
4561 if (hWnd == NULL)
4562 {
4563 return NULL;
4564 }
4565
4566 easy = cm->CmSetting.EasyMode;
4567
4568 num = LvNum(hWnd, L_ACCOUNT);
4569
4570 for (i = 0;i < num;i++)
4571 {
4572 wchar_t *status_str = LvGetStr(hWnd, L_ACCOUNT, i, 1);
4573
4574 if (status_str != NULL)
4575 {
4576 bool b = false;
4577 bool is_account = false;
4578
4579 if (UniStrCmpi(status_str, _UU("CM_ACCOUNT_OFFLINE")) == 0)
4580 {
4581 if (flag == false)
4582 {
4583 b = true;
4584 }
4585
4586 is_account = true;
4587 }
4588
4589 if (UniStrCmpi(status_str, _UU("CM_ACCOUNT_ONLINE")) == 0 ||
4590 UniStrCmpi(status_str, _UU("CM_ACCOUNT_CONNECTING")) == 0)
4591 {
4592 if (flag == true)
4593 {
4594 b = true;
4595 }
4596
4597 is_account = true;
4598 }
4599
4600 if (b)
4601 {
4602 wchar_t tmp[MAX_PATH];
4603 wchar_t *account_name, *server_name;
4604 wchar_t *hub_name;
4605 if (h == NULL)
4606 {
4607 h = CreatePopupMenu();
4608 }
4609
4610 account_name = LvGetStr(hWnd, L_ACCOUNT, i, 0);
4611 server_name = LvGetStr(hWnd, L_ACCOUNT, i, 2);
4612 hub_name = LvGetStr(hWnd, L_ACCOUNT, i, 3);
4613
4614 if (easy == false)
4615 {
4616 UniFormat(tmp, sizeof(tmp), L"%s\t- %s [%s]", account_name, server_name, hub_name);
4617 }
4618 else
4619 {
4620 UniStrCpy(tmp, sizeof(tmp), account_name);
4621 }
4622
4623 MsAppendMenu(h, MF_STRING, start_id + i, tmp);
4624
4625 Free(account_name);
4626 Free(server_name);
4627 Free(hub_name);
4628 }
4629
4630 Free(status_str);
4631 }
4632 }
4633
4634 return h;
4635 }
4636
4637 // Display the right-click menu of the task tray
CmShowTrayMenu(HWND hWnd)4638 void CmShowTrayMenu(HWND hWnd)
4639 {
4640 HMENU h;
4641 POINT p;
4642 HMENU sub1, sub2, sub3, sub4;
4643 bool locked;
4644 bool easy;
4645 // Validate arguments
4646 if (hWnd == NULL)
4647 {
4648 return;
4649 }
4650
4651 cm->MenuPopuping = true;
4652
4653 locked = cm->CmSetting.LockMode;
4654 easy = cm->CmSetting.EasyMode;
4655
4656 // Create a menu
4657 h = CreatePopupMenu();
4658
4659 // Cancel
4660 MsAppendMenu(h, MF_ENABLED | MF_STRING, 100007, _UU("CM_TRAY_MENU_CANCEL"));
4661
4662 // Separator
4663 MsAppendMenu(h, MF_SEPARATOR, 10006, NULL);
4664
4665 if (locked == false && easy == false)
4666 {
4667 // Creating a new connection settings
4668 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_NEW, _UU("CM_TRAY_MENU_NEW"));
4669
4670 // Separator
4671 MsAppendMenu(h, MF_SEPARATOR, 10005, NULL);
4672 }
4673
4674 // Connection menu
4675 sub1 = CmCreateTraySubMenu(hWnd, false, CM_TRAY_MENU_CONNECT_ID_START);
4676 if (sub1 != NULL)
4677 {
4678 MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,
4679 (UINT_PTR)sub1, _UU("CM_TRAY_MENU_CONNECT"));
4680 }
4681
4682 // Disconnection menu
4683 sub2 = CmCreateTraySubMenu(hWnd, true, CM_TRAY_MENU_DISCONNECT_ID_START);
4684 if (sub2 != NULL)
4685 {
4686 MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,
4687 (UINT_PTR)sub2, _UU("CM_TRAY_MENU_DISCONNECT"));
4688 }
4689
4690 // Status Display menu
4691 sub3 = CmCreateTraySubMenu(hWnd, true, CM_TRAY_MENU_STATUS_ID_START);
4692 if (sub3 != NULL)
4693 {
4694 MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,
4695 (UINT_PTR)sub3, _UU("CM_TRAY_MENU_STATUS"));
4696 }
4697
4698 if (sub3 != NULL)
4699 {
4700 // Disconnect all connections
4701 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_DISCONNECT_ALL, _UU("CM_TRAY_MENU_DISCONNECT_ALL"));
4702 }
4703
4704 if (sub1 != NULL || sub2 != NULL || sub3 != NULL)
4705 {
4706 // Separator
4707 MsAppendMenu(h, MF_SEPARATOR, 10003, NULL);
4708 }
4709
4710 // Connect to the recently connected VPN server
4711 sub4 = CmCreateRecentSubMenu(hWnd, CM_TRAY_MENU_RECENT_ID_START);
4712 if (sub4 != NULL)
4713 {
4714 MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,
4715 (UINT_PTR)sub4, _UU("CM_TRAY_MENU_RECENT"));
4716 MsAppendMenu(h, MF_SEPARATOR, 10008, NULL);
4717 }
4718
4719 if (locked == false && easy == false)
4720 {
4721 // Communication throughput measurement
4722 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_TRAFFIC, _UU("CM_TRAY_MENU_TRAFFIC"));
4723 }
4724
4725 if (easy == false)
4726 {
4727 // Network device status
4728 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_NETIF, _UU("CM_TRAY_MENU_NETIF"));
4729 }
4730
4731 // Version information
4732 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_ABOUT, _UU("CM_TRAY_MENU_ABOUT"));
4733
4734 // Separator
4735 MsAppendMenu(h, MF_SEPARATOR, 10001, NULL);
4736
4737 // Change the operating mode
4738 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_CM_SETTING, _UU("CM_TRAY_MENU_SETTING"));
4739
4740 // Separator
4741 MsAppendMenu(h, MF_SEPARATOR, 10001, NULL);
4742
4743 // Hide the icon
4744 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_TRAYICON, _UU("CM_MENU@CMD_TRAYICON"));
4745
4746 // Separator
4747 MsAppendMenu(h, MF_SEPARATOR, 10001, NULL);
4748
4749 // Show or hide
4750 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_EXIT,
4751 IsHide(hWnd, 0) ? _UU("CM_TRAY_MENU_1_SHOW") : _UU("CM_TRAY_MENU_1_HIDE"));
4752
4753 // Quit
4754 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_QUIT, _UU("CM_TRAY_MENU_2_QUIT"));
4755
4756 // Show the menu
4757 GetCursorPos(&p);
4758
4759 SetForegroundWindow(hWnd);
4760 TrackPopupMenu(h, TPM_LEFTALIGN, p.x, p.y, 0, hWnd, NULL);
4761 PostMessage(hWnd, WM_NULL, 0, 0);
4762
4763 if (sub1 != NULL)
4764 {
4765 DestroyMenu(sub1);
4766 }
4767
4768 if (sub2 != NULL)
4769 {
4770 DestroyMenu(sub2);
4771 }
4772
4773 if (sub3 != NULL)
4774 {
4775 DestroyMenu(sub3);
4776 }
4777
4778 DestroyMenu(h);
4779
4780 cm->MenuPopuping = false;
4781 }
4782
4783 // Hide or show the main window
CmShowOrHideWindow(HWND hWnd)4784 void CmShowOrHideWindow(HWND hWnd)
4785 {
4786 // Validate arguments
4787 if (hWnd == NULL)
4788 {
4789 return;
4790 }
4791
4792 if (IsHide(hWnd, 0))
4793 {
4794 Show(hWnd, 0);
4795 if (IsIconic(hWnd))
4796 {
4797 ShowWindow(hWnd, SW_SHOWNORMAL);
4798 }
4799 SetForegroundWindow(hWnd);
4800 SetActiveWindow(hWnd);
4801 }
4802 else
4803 {
4804 CmSaveMainWindowPos(hWnd);
4805 Hide(hWnd, 0);
4806
4807 if (cm->TrayInited == false)
4808 {
4809 Command(hWnd, CMD_QUIT);
4810 return;
4811 }
4812 }
4813 }
4814
4815 // Right-clicked on the account list
CmAccountListRightClick(HWND hWnd)4816 void CmAccountListRightClick(HWND hWnd)
4817 {
4818 HMENU h;
4819 HMENU parent;
4820 UINT i;
4821 // Validate arguments
4822 if (hWnd == NULL)
4823 {
4824 return;
4825 }
4826
4827 // Load the menu
4828 h = LoadSubMenu(M_MAIN, 0, &parent);
4829 if (h == NULL)
4830 {
4831 return;
4832 }
4833
4834 InitMenuInternational(h, "CM_MENU");
4835
4836 // Remove the shortcut key
4837 RemoveShortcutKeyStrFromMenu(h);
4838
4839 // Delete the exit menu
4840 i = GetMenuItemPos(h, CMD_QUIT);
4841 if (i != INFINITE)
4842 {
4843 DeleteMenuItem(h, i);
4844 DeleteMenuItem(h, i - 1);
4845 DeleteMenuItem(h, i - 2);
4846 DeleteMenuItem(h, i - 3);
4847 }
4848
4849 // Set enable / disable
4850 CmMainWindowOnPopupMenu(hWnd, h, INFINITE);
4851
4852 if (h != NULL)
4853 {
4854 // Determine whether the selected account is under connecting
4855 UINT i = LvGetSelected(hWnd, L_ACCOUNT);
4856 wchar_t *str;
4857 bool is_connected = false;
4858 if (i != INFINITE)
4859 {
4860 str = LvGetStr(hWnd, L_ACCOUNT, i, 1);
4861 if (str != NULL)
4862 {
4863 if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)
4864 {
4865 // Connecting
4866 is_connected = true;
4867 }
4868 Free(str);
4869 }
4870 }
4871
4872 if (i == INFINITE)
4873 {
4874 // Bold the New menu
4875 SetMenuItemBold(h, GetMenuItemPos(h, CMD_NEW), true);
4876 }
4877 else
4878 {
4879 if (is_connected == false)
4880 {
4881 // Bold the connection menu
4882 SetMenuItemBold(h, GetMenuItemPos(h, CMD_CONNECT), true);
4883 }
4884 else
4885 {
4886 // Bold the status menu
4887 SetMenuItemBold(h, GetMenuItemPos(h, CMD_STATUS), true);
4888 }
4889 }
4890 }
4891
4892 // Show the menu
4893 PrintMenu(hWnd, h);
4894
4895 DestroyMenu(parent);
4896 }
4897
4898 // Right-clicked on the virtual LAN card list
CmVLanListRightClick(HWND hWnd)4899 void CmVLanListRightClick(HWND hWnd)
4900 {
4901 HMENU h;
4902 HMENU parent;
4903 // Validate arguments
4904 if (hWnd == NULL)
4905 {
4906 return;
4907 }
4908
4909 // Load the menu
4910 h = LoadSubMenu(M_MAIN, 3, &parent);
4911 if (h == NULL)
4912 {
4913 return;
4914 }
4915
4916 InitMenuInternational(h, "CM_MENU");
4917
4918 // Remove the shortcut key
4919 RemoveShortcutKeyStrFromMenu(h);
4920
4921 // Set enable / disable
4922 CmMainWindowOnPopupMenu(hWnd, h, INFINITE);
4923
4924 if (h != NULL)
4925 {
4926 // Examine whether the selected device is enabled
4927 UINT i = LvGetSelected(hWnd, L_VLAN);
4928 wchar_t *str;
4929 bool is_active = false;
4930 if (i != INFINITE)
4931 {
4932 str = LvGetStr(hWnd, L_VLAN, i, 1);
4933 if (str != NULL)
4934 {
4935 if (UniStrCmpi(str, _UU("CM_VLAN_ENABLED")) == 0)
4936 {
4937 // Enabled
4938 is_active = true;
4939 }
4940 Free(str);
4941 }
4942 }
4943
4944 if (i == INFINITE)
4945 {
4946 // Bold the New menu
4947 SetMenuItemBold(h, GetMenuItemPos(h, CMD_NEW_VLAN), true);
4948 }
4949 else
4950 {
4951 if (is_active == false)
4952 {
4953 // Bold the enable menu
4954 SetMenuItemBold(h, GetMenuItemPos(h, CMD_ENABLE_VLAN), true);
4955 }
4956 else
4957 {
4958 // Bold the Windows Network Setup menu
4959 SetMenuItemBold(h, GetMenuItemPos(h, CMD_WINNET), true);
4960 }
4961 }
4962 }
4963
4964 // Show the menu
4965 PrintMenu(hWnd, h);
4966
4967 DestroyMenu(parent);
4968 }
4969
4970 // Notify to the main window
CmMainWindowOnNotify(HWND hWnd,NMHDR * n)4971 void CmMainWindowOnNotify(HWND hWnd, NMHDR *n)
4972 {
4973 bool item_vlan;
4974 NMLVDISPINFOW *disp_info;
4975 NMLVKEYDOWN *key;
4976
4977 // Validate arguments
4978 if (hWnd == NULL || n == NULL)
4979 {
4980 return;
4981 }
4982
4983 switch (n->idFrom)
4984 {
4985 case L_ACCOUNT:
4986 case L_VLAN:
4987 if (n->idFrom == L_ACCOUNT)
4988 {
4989 item_vlan = false;
4990 }
4991 else
4992 {
4993 item_vlan = true;
4994 }
4995
4996 switch (n->code)
4997 {
4998 case NM_DBLCLK:
4999 // Double click
5000 CmOnKey(hWnd, false, false, VK_RETURN);
5001 break;
5002 case NM_RCLICK:
5003 // Right click
5004 if (item_vlan == false)
5005 {
5006 CmAccountListRightClick(hWnd);
5007 }
5008 else
5009 {
5010 CmVLanListRightClick(hWnd);
5011 }
5012 break;
5013 case LVN_ENDLABELEDITW:
5014 // Change the name
5015 disp_info = (NMLVDISPINFOW *)n;
5016 if (disp_info->item.pszText != NULL)
5017 {
5018 wchar_t *new_name = disp_info->item.pszText;
5019 wchar_t *old_name = LvGetStr(hWnd, L_ACCOUNT, disp_info->item.iItem, 0);
5020
5021 if (old_name != NULL)
5022 {
5023 if (UniStrCmp(new_name, old_name) != 0 && UniIsEmptyStr(new_name) == false)
5024 {
5025 RPC_RENAME_ACCOUNT a;
5026 Zero(&a, sizeof(a));
5027 UniStrCpy(a.OldName, sizeof(a.OldName), old_name);
5028 UniStrCpy(a.NewName, sizeof(a.NewName), new_name);
5029 if (CALL(hWnd, CcRenameAccount(cm->Client, &a)))
5030 {
5031 LvSetItem(hWnd, L_ACCOUNT, disp_info->item.iItem, 0, new_name);
5032 }
5033 }
5034
5035 Free(old_name);
5036 }
5037 }
5038 break;
5039 case LVN_KEYDOWN:
5040 // Key pressed
5041 key = (NMLVKEYDOWN *)n;
5042 if (key != NULL)
5043 {
5044 bool ctrl, alt;
5045 UINT code = key->wVKey;
5046 ctrl = (GetKeyState(VK_CONTROL) & 0x8000) == 0 ? false : true;
5047 alt = (GetKeyState(VK_MENU) & 0x8000) == 0 ? false : true;
5048 CmOnKey(hWnd, ctrl, alt, code);
5049 }
5050 break;
5051 }
5052 break;
5053 }
5054 }
5055
5056 // Keyboard pressed
CmOnKey(HWND hWnd,bool ctrl,bool alt,UINT key)5057 void CmOnKey(HWND hWnd, bool ctrl, bool alt, UINT key)
5058 {
5059 // Validate arguments
5060 if (hWnd == NULL)
5061 {
5062 return;
5063 }
5064
5065 // Single key
5066 switch (key)
5067 {
5068 case VK_RETURN:
5069 Command(hWnd, IDOK);
5070 break;
5071 case VK_DELETE:
5072 // Delete
5073 if (IsFocus(hWnd, L_ACCOUNT))
5074 {
5075 // Operation on the account list
5076 Command(hWnd, CMD_DELETE);
5077 }
5078 else
5079 {
5080 // Operation on the virtual LAN card list
5081 Command(hWnd, CMD_DELETE_VLAN);
5082 }
5083 break;
5084 case VK_F2:
5085 // Change the name
5086 Command(hWnd, CMD_RENAME);
5087 break;
5088 case VK_F5:
5089 // Update the status
5090 Command(hWnd, CMD_REFRESH);
5091 break;
5092 }
5093
5094 if (alt)
5095 {
5096 switch (key)
5097 {
5098 case 'Q':
5099 // Close
5100 Command(hWnd, CMD_QUIT);
5101 break;
5102 }
5103 }
5104
5105 if (ctrl)
5106 {
5107 switch (key)
5108 {
5109 case 'G':
5110 // Smart Card Manager
5111 Command(hWnd, CMD_SECURE_MANAGER);
5112 break;
5113 case 'S':
5114 // Show the state
5115 Command(hWnd, CMD_STATUS);
5116 break;
5117 case 'I':
5118 // Disconnect all connections
5119 Command(hWnd, CMD_DISCONNECT_ALL);
5120 break;
5121 case 'D':
5122 // Disconnect
5123 Command(hWnd, CMD_DISCONNECT);
5124 break;
5125 case 'N':
5126 // Create a new connection settings
5127 Command(hWnd, CMD_NEW);
5128 break;
5129 case 'C':
5130 // Creating a copy
5131 Command(hWnd, CMD_CLONE);
5132 break;
5133 case 'T':
5134 // Set to start-up connection
5135 Command(hWnd, CMD_STARTUP);
5136 break;
5137 case 'A':
5138 // Select all
5139 Command(hWnd, CMD_SELECT_ALL);
5140 break;
5141 case 'L':
5142 // Create a new virtual LAN card
5143 Command(hWnd, CMD_NEW_VLAN);
5144 break;
5145 case 'E':
5146 // Enable the virtual LAN card
5147 Command(hWnd, CMD_ENABLE_VLAN);
5148 break;
5149 case 'B':
5150 // Disable the virtual LAN card
5151 Command(hWnd, CMD_DISABLE_VLAN);
5152 break;
5153 case 'U':
5154 // Reinstall the driver
5155 Command(hWnd, CMD_REINSTALL);
5156 break;
5157 case 'W':
5158 // Configure Windows network connection
5159 Command(hWnd, CMD_WINNET);
5160 break;
5161 case 'P':
5162 // Set the password
5163 Command(hWnd, CMD_PASSWORD);
5164 break;
5165 case 'O':
5166 // Option settings
5167 Command(hWnd, CMD_TRAFFIC);
5168 break;
5169 case 'R':
5170 // Certificate management
5171 Command(hWnd, CMD_TRUST);
5172 break;
5173 case 'Q':
5174 // Throughput
5175 Command(hWnd, CMD_TRAFFIC);
5176 break;
5177 }
5178 }
5179 }
5180
5181 // Command of the main window
CmMainWindowOnCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)5182 void CmMainWindowOnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
5183 {
5184 CmMainWindowOnCommandEx(hWnd, wParam, lParam, false);
5185 }
CmMainWindowOnCommandEx(HWND hWnd,WPARAM wParam,LPARAM lParam,bool easy)5186 void CmMainWindowOnCommandEx(HWND hWnd, WPARAM wParam, LPARAM lParam, bool easy)
5187 {
5188 wchar_t *tmp;
5189 char *name;
5190 UINT index;
5191 UINT id;
5192 bool ctrl, alt;
5193 UINT flag = 0;
5194 // Validate arguments
5195 wchar_t *selected_name = NULL;
5196 UINT starter_id = 0;
5197 if (hWnd == NULL)
5198 {
5199 return;
5200 }
5201
5202 ctrl = (GetKeyState(VK_CONTROL) & 0x8000) == 0 ? false : true;
5203 alt = (GetKeyState(VK_MENU) & 0x8000) == 0 ? false : true;
5204
5205 if (wParam == IDOK)
5206 {
5207 tmp = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
5208 if (tmp != NULL)
5209 {
5210 if (UniStrCmpi(tmp, _UU("CM_NEW_ICON")) == 0)
5211 {
5212 Free(tmp);
5213 Command(hWnd, CMD_NEW);
5214 return;
5215 }
5216 if (UniStrCmpi(tmp, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(tmp, _UU("CM_VGC_LINK")) == 0)
5217 {
5218 Free(tmp);
5219 Command(hWnd, CMD_VGC_CONNECT);
5220 return;
5221 }
5222 Free(tmp);
5223 }
5224 }
5225
5226 if (CmIsEnabled(hWnd, (UINT)wParam) == false)
5227 {
5228 return;
5229 }
5230
5231 if (CM_TRAY_IS_CONNECT_ID(wParam))
5232 {
5233 // Connection request
5234 starter_id = CM_TRAY_MENU_CONNECT_ID_START;
5235 flag = 1;
5236 }
5237
5238 if (CM_TRAY_IS_STATUS_ID(wParam))
5239 {
5240 // Information display request
5241 starter_id = CM_TRAY_MENU_STATUS_ID_START;
5242 flag = 2;
5243 }
5244
5245 if (CM_TRAY_IS_DISCONNECT_ID(wParam))
5246 {
5247 // Disconnect request
5248 starter_id = CM_TRAY_MENU_DISCONNECT_ID_START;
5249 flag = 3;
5250 }
5251
5252 if (CM_TRAY_IS_RECENT_ID(wParam))
5253 {
5254 // Recent destinations
5255 starter_id = CM_TRAY_MENU_RECENT_ID_START;
5256 flag = 1;
5257 }
5258
5259 if (starter_id != 0)
5260 {
5261 UINT num;
5262
5263 id = (UINT)wParam - starter_id;
5264
5265 num = LvNum(hWnd, L_ACCOUNT);
5266
5267 if (id < num)
5268 {
5269 selected_name = LvGetStr(hWnd, L_ACCOUNT, id, 0);
5270
5271 if (selected_name != NULL)
5272 {
5273 if (UniStrCmpi(selected_name, _UU("CM_NEW_ICON")) != 0 &&
5274 UniStrCmpi(selected_name, _UU("CM_VGC_ICON")) != 0 &&
5275 UniStrCmpi(selected_name, _UU("CM_VGC_LINK")) != 0)
5276 {
5277 switch (flag)
5278 {
5279 case 1:
5280 CmConnect(hWnd, selected_name);
5281 break;
5282
5283 case 2:
5284 CmStatus(hWnd, selected_name);
5285 break;
5286
5287 case 3:
5288 CmDisconnect(hWnd, selected_name);
5289 break;
5290 }
5291 }
5292 }
5293
5294 Free(selected_name);
5295 }
5296 }
5297
5298 switch (wParam)
5299 {
5300 case IDOK:
5301 case CMD_EASY_DBLCLICK:
5302 // Property or connection
5303 if (IsFocus(hWnd, L_ACCOUNT) || (hWnd == cm->hEasyWnd))
5304 {
5305 // Operation about the account list
5306 if (alt == false)
5307 {
5308 UINT index = LvGetSelected(hWnd, L_ACCOUNT);
5309 bool b = false;
5310 if (index != INFINITE)
5311 {
5312 wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, index, 1);
5313 if (s != NULL)
5314 {
5315 if (UniStrCmpi(s, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(s, _UU("CM_ACCOUNT_CONNECTING")) == 0)
5316 {
5317 b = true;
5318 }
5319 Free(s);
5320 }
5321 }
5322
5323 if (b == false)
5324 {
5325 // Connection
5326 Command(hWnd, CMD_CONNECT);
5327 }
5328 else
5329 {
5330 if (hWnd != cm->hEasyWnd || wParam == CMD_EASY_DBLCLICK)
5331 {
5332 // Display status
5333 Command(hWnd, CMD_STATUS);
5334 }
5335 else
5336 {
5337 // Disconnect
5338 Command(hWnd, CMD_DISCONNECT);
5339 }
5340 }
5341 }
5342 else
5343 {
5344 // Property
5345 Command(hWnd, CMD_PROPERTY);
5346 }
5347 }
5348 else
5349 {
5350 // Configure Windows network connection
5351 Command(hWnd, CMD_WINNET);
5352 }
5353 break;
5354 case CMD_CONNECT:
5355 // Connection
5356 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
5357 if (tmp != NULL)
5358 {
5359 CmConnect(hWnd, tmp);
5360 Free(tmp);
5361 }
5362 break;
5363 case CMD_STATUS:
5364 // Show the status
5365 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
5366 if (tmp != NULL)
5367 {
5368 CmStatus(hWnd, tmp);
5369 Free(tmp);
5370 }
5371 break;
5372 case CMD_DISCONNECT_ALL:
5373 // Disconnect all connections
5374 CmDisconnectAll(hWnd);
5375 break;
5376 case CMD_DISCONNECT:
5377 // Disconnect
5378 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
5379 if (tmp != NULL)
5380 {
5381 CmDisconnect(hWnd, tmp);
5382 Free(tmp);
5383 }
5384 break;
5385 case CMD_NEW:
5386 // Create new
5387 CmNewAccount(hWnd);
5388 break;
5389
5390
5391 case CMD_CLONE:
5392 // Copy
5393 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
5394 if (tmp != NULL)
5395 {
5396 CmCopyAccount(hWnd, tmp);
5397 Free(tmp);
5398 }
5399 break;
5400 case CMD_SHORTCUT:
5401 // Create a shortcut
5402 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
5403 if (tmp != NULL)
5404 {
5405 CmSortcut(hWnd, tmp);
5406 Free(tmp);
5407 }
5408 break;
5409 case CMD_EXPORT_ACCOUNT:
5410 // Export settings
5411 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
5412 if (tmp != NULL)
5413 {
5414 CmExportAccount(hWnd, tmp);
5415 Free(tmp);
5416 }
5417 break;
5418 case CMD_IMPORT_ACCOUNT:
5419 // Import settings
5420 CmImportAccount(hWnd);
5421 break;
5422 case CMD_STARTUP:
5423 // Set to start-up connection
5424 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
5425 if (tmp != NULL)
5426 {
5427 RPC_CLIENT_DELETE_ACCOUNT c;
5428 Zero(&c, sizeof(c));
5429 UniStrCpy(c.AccountName, sizeof(c.AccountName), tmp);
5430 CALL(hWnd, CcSetStartupAccount(cm->Client, &c));
5431 CmVoice("set_startup");
5432 MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_SET_STARTUP"), tmp);
5433 Free(tmp);
5434 }
5435 break;
5436 case CMD_NOSTARTUP:
5437 // Unset the start-up connection
5438 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
5439 if (tmp != NULL)
5440 {
5441 if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2,
5442 _UU("CM_REMOVE_STARTUP"), tmp) == IDYES)
5443 {
5444 RPC_CLIENT_DELETE_ACCOUNT c;
5445 Zero(&c, sizeof(c));
5446 UniStrCpy(c.AccountName, sizeof(c.AccountName), tmp);
5447 CALL(hWnd, CcRemoveStartupAccount(cm->Client, &c));
5448 CmVoice("remove_startup");
5449 }
5450 Free(tmp);
5451 }
5452 break;
5453 case CMD_DELETE:
5454 // Delete
5455 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
5456 if (tmp != NULL)
5457 {
5458 CmDeleteAccount(hWnd, tmp);
5459 Free(tmp);
5460 }
5461 break;
5462 case CMD_RENAME:
5463 // Change the name
5464 Focus(hWnd, L_ACCOUNT);
5465 LvRename(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT));
5466 break;
5467 case CMD_PROPERTY:
5468 // Property
5469 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);
5470 if (tmp != NULL)
5471 {
5472 CmEditAccount(hWnd, tmp);
5473 Free(tmp);
5474 }
5475 break;
5476 case IDCANCEL:
5477 case CMD_EXIT:
5478 // Close
5479 Close(hWnd);
5480 break;
5481 case CMD_QUIT:
5482 // Exit
5483 CmMainWindowOnQuit(hWnd);
5484 break;
5485 case CMD_SELECT_ALL:
5486 // Select all
5487 LvSelectAll(hWnd, L_ACCOUNT);
5488 LvSelectAll(hWnd, L_VLAN);
5489 break;
5490 case CMD_SWITCH_SELECT:
5491 // Invert selection
5492 LvSwitchSelect(hWnd, L_ACCOUNT);
5493 LvSwitchSelect(hWnd, L_VLAN);
5494 break;
5495 case CMD_GRID:
5496 // Show grid
5497 cm->ShowGrid = !cm->ShowGrid;
5498 CmRefreshVLanListEx(hWnd, true);
5499 CmRefreshAccountListEx2(hWnd, false, true);
5500 break;
5501 case CMD_STATUSBAR:
5502 // Show the status bar
5503 if (cm->HideStatusBar == false)
5504 {
5505 cm->HideStatusBar = true;
5506 Hide(hWnd, S_STATUSBAR);
5507 CmMainWindowOnSize(hWnd);
5508 }
5509 else
5510 {
5511 cm->HideStatusBar = false;
5512 Show(hWnd, S_STATUSBAR);
5513 CmMainWindowOnSize(hWnd);
5514 }
5515 CmSaveMainWindowPos(hWnd);
5516 break;
5517 case CMD_VISTASTYLE:
5518 cm->VistaStyle = !cm->VistaStyle;
5519 CmRefreshEx(hWnd, true);
5520 CmSaveMainWindowPos(hWnd);
5521 break;
5522 case CMD_TRAYICON:
5523 // Tray icon display
5524 if (cm->HideTrayIcon == false)
5525 {
5526 cm->HideTrayIcon = true;
5527 CmFreeTray(hWnd);
5528
5529 if (IsHide(hWnd, 0))
5530 {
5531 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_TRAY_ICON_RESTORE"));
5532 }
5533 }
5534 else
5535 {
5536 cm->HideTrayIcon = false;
5537 if (cm->server_name == NULL)
5538 {
5539 CmInitTray(hWnd);
5540 }
5541 }
5542 break;
5543 case CMD_SHOWPORT:
5544 // Show the port number
5545 cm->ShowPort = !cm->ShowPort;
5546 CmRefresh(hWnd);
5547 break;
5548 case CMD_ICON:
5549 // Show the icon
5550 if (cm->IconView == false)
5551 {
5552 cm->IconView = true;
5553 CmRefresh(hWnd);
5554 }
5555 break;
5556 case CMD_DETAIL:
5557 // Show details
5558 if (cm->IconView)
5559 {
5560 cm->IconView = false;
5561 CmRefresh(hWnd);
5562 }
5563 break;
5564 case CMD_REFRESH:
5565 if (easy == false)
5566 {
5567 // Display update
5568 LvReset(hWnd, L_ACCOUNT);
5569 LvReset(hWnd, L_VLAN);
5570 CmRefresh(hWnd);
5571 }
5572 break;
5573 case CMD_NEW_VLAN:
5574 // Create a Virtual LAN card
5575 if (CmStopInstallVLan(hWnd) == false)
5576 {
5577 // Installation is prohibited
5578 break;
5579 }
5580 name = CmNewVLanDlg(hWnd);
5581 if (name != NULL)
5582 {
5583 wchar_t tmp[MAX_SIZE];
5584 void *helper = NULL;
5585 RPC_CLIENT_CREATE_VLAN c;
5586 Zero(&c, sizeof(c));
5587 StrCpy(c.DeviceName, sizeof(c.DeviceName), name);
5588 if (MsIsNt() == false)
5589 {
5590 // Change the title of the window
5591 GetTxt(hWnd, 0, tmp, sizeof(tmp));
5592 SetText(hWnd, 0, _UU("CM_VLAN_INSTALLING"));
5593 }
5594 // Minimize
5595 if (MsIsVista() == false)
5596 {
5597 ShowWindow(hWnd, SW_SHOWMINIMIZED);
5598 }
5599
5600 if (MsIsVista())
5601 {
5602 helper = CmStartUacHelper();
5603 }
5604
5605 if (CALL(hWnd, CcCreateVLan(cm->Client, &c)))
5606 {
5607 CmVoice("new_vlan");
5608 }
5609
5610 CmStopUacHelper(helper);
5611
5612 if (MsIsNt() == false)
5613 {
5614 // Restore the title of the window
5615 SetText(hWnd, 0, tmp);
5616 }
5617 // Restore
5618 if (MsIsVista() == false)
5619 {
5620 ShowWindow(hWnd, SW_SHOWNORMAL);
5621 }
5622 Free(name);
5623 }
5624 break;
5625 case CMD_DELETE_VLAN:
5626 // Delete the Virtual LAN card
5627 index = LvGetSelected(hWnd, L_VLAN);
5628 if (index != INFINITE)
5629 {
5630 if (cm->Client->Win9x == false)
5631 {
5632 // Windows 2000 or later
5633 wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);
5634 if (s != NULL)
5635 {
5636 RPC_CLIENT_CREATE_VLAN c;
5637 char str[MAX_SIZE];
5638 CmVoice("delete_vlan_1");
5639 if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_VLAN"), s) == IDYES)
5640 {
5641 Zero(&c, sizeof(c));
5642 UniToStr(str, sizeof(str), s);
5643 if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))
5644 {
5645 if (CALL(hWnd, CcDeleteVLan(cm->Client, &c)))
5646 {
5647 CmVoice("delete_vlan_2");
5648 }
5649 }
5650 }
5651 Free(s);
5652 }
5653 }
5654 else
5655 {
5656 // Windows 9x
5657 if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("CM_9X_VLAN_UNINSTALL")) == IDYES)
5658 {
5659 Run("rundll32.exe", "shell32.dll,Control_RunDLL NETCPL.CPL",
5660 false, false);
5661 }
5662 }
5663 }
5664 break;
5665 case CMD_ENABLE_VLAN:
5666 // Enable the virtual LAN card
5667 index = LvGetSelected(hWnd, L_VLAN);
5668 if (index != INFINITE)
5669 {
5670 wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);
5671 if (s != NULL)
5672 {
5673 RPC_CLIENT_CREATE_VLAN c;
5674 char str[MAX_SIZE];
5675 Zero(&c, sizeof(c));
5676 UniToStr(str, sizeof(str), s);
5677 if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))
5678 {
5679 CALL(hWnd, CcEnableVLan(cm->Client, &c));
5680 }
5681 Free(s);
5682 }
5683 }
5684 break;
5685 case CMD_DISABLE_VLAN:
5686 // Disable the virtual LAN card
5687 index = LvGetSelected(hWnd, L_VLAN);
5688 if (index != INFINITE)
5689 {
5690 wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);
5691 if (s != NULL)
5692 {
5693 RPC_CLIENT_CREATE_VLAN c;
5694 char str[MAX_SIZE];
5695 Zero(&c, sizeof(c));
5696 UniToStr(str, sizeof(str), s);
5697 if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))
5698 {
5699 CALL(hWnd, CcDisableVLan(cm->Client, &c));
5700 }
5701 Free(s);
5702 }
5703 }
5704 break;
5705 case CMD_REINSTALL:
5706 // Reinstall the virtual LAN card
5707 if (CmStopInstallVLan(hWnd) == false)
5708 {
5709 // Installation is prohibited
5710 break;
5711 }
5712 // Warning message
5713 if (MsgBox(hWnd, MB_ICONINFORMATION | MB_OKCANCEL, _UU("CM_VLAN_REINSTALL_MSG")) == IDCANCEL)
5714 {
5715 // Cancel
5716 break;
5717 }
5718 index = LvGetSelected(hWnd, L_VLAN);
5719 if (index != INFINITE)
5720 {
5721 wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);
5722 if (s != NULL)
5723 {
5724 RPC_CLIENT_CREATE_VLAN c;
5725 char str[MAX_SIZE];
5726 Zero(&c, sizeof(c));
5727 UniToStr(str, sizeof(str), s);
5728 if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))
5729 {
5730 void *helper = NULL;
5731
5732 if (MsIsVista() == false)
5733 {
5734 ShowWindow(hWnd, SW_SHOWMINIMIZED);
5735 }
5736
5737 if (MsIsVista())
5738 {
5739 helper = CmStartUacHelper();
5740 }
5741
5742 CALL(hWnd, CcUpgradeVLan(cm->Client, &c));
5743
5744 CmStopUacHelper(helper);
5745
5746 if (MsIsVista() == false)
5747 {
5748 ShowWindow(hWnd, SW_SHOWNORMAL);
5749 }
5750 }
5751 Free(s);
5752 }
5753 }
5754 break;
5755 case CMD_PASSWORD:
5756 // Password setting
5757 CmPassword(hWnd);
5758 break;
5759 case CMD_OPTION:
5760 // Option
5761 CmConfigDlg(hWnd);
5762 break;
5763 case CMD_LANGUAGE:
5764 // Language settings
5765 if (true)
5766 {
5767 wchar_t path[MAX_SIZE];
5768
5769 CombinePathW(path, sizeof(path), MsGetExeDirNameW(), L"vpnsetup.exe");
5770
5771 if (MsExecuteW(path, L"/language:yes") == false)
5772 {
5773 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SW_CHILD_PROCESS_ERROR"));
5774 }
5775 }
5776 break;
5777 case CMD_TRUST:
5778 // Certificate management
5779 CmTrustDlg(hWnd);
5780 break;
5781 case CMD_ABOUT:
5782 // Version information
5783 if (IsEnable(hWnd, 0))
5784 {
5785 AboutEx(hWnd, cm->Cedar, _UU("PRODUCT_NAME_VPN_CMGR"), cm->Update);
5786 }
5787 break;
5788 case CMD_VOIDE_NONE:
5789 cm->DisableVoice = true;
5790 break;
5791 case CMD_VOICE_NORMAL:
5792 cm->DisableVoice = false;
5793 cm->VoiceId = VOICE_SSK;
5794 break;
5795 case CMD_VOICE_ODD:
5796 if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("CM_EXT_VOICE_MSG")) == IDYES)
5797 {
5798 cm->DisableVoice = false;
5799 cm->VoiceId = VOICE_AHO;
5800 }
5801 break;
5802 case CMD_SECURE_MANAGER:
5803 // Smart Card Manager
5804 CmClientSecureManager(hWnd);
5805 break;
5806 case CMD_SECURE_SELECT:
5807 // Select a smart card
5808 CmClientSelectSecure(hWnd);
5809 break;
5810 case CMD_NETIF:
5811 // State of the network device
5812 if (IsEnable(hWnd, 0))
5813 {
5814 UtSpeedMeterEx(hWnd);
5815 }
5816 break;
5817 case CMD_MMCSS:
5818 // Optimization utility for Windows Vista
5819 if (MsIsVista() == false)
5820 {
5821 MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_4"));
5822 }
5823 else
5824 {
5825 if (MsIsAdmin() == false)
5826 {
5827 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("VISTA_MMCSS_MSG_4"));
5828 }
5829 else
5830 {
5831 if (MsIsMMCSSNetworkThrottlingEnabled())
5832 {
5833 if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("VISTA_MMCSS_MSG")) == IDYES)
5834 {
5835 MsSetMMCSSNetworkThrottlingEnable(false);
5836 MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_5"));
5837 }
5838 }
5839 else
5840 {
5841 if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("VISTA_MMCSS_MSG_2")) == IDYES)
5842 {
5843 MsSetMMCSSNetworkThrottlingEnable(true);
5844 MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_6"));
5845 }
5846 }
5847 }
5848 }
5849 break;
5850 case CMD_TRAFFIC:
5851 // Communication traffic measurement
5852 if (IsEnable(hWnd, 0))
5853 {
5854 CmTraffic(hWnd);
5855 }
5856 break;
5857 case CMD_CM_SETTING:
5858 // Operation mode setting
5859 if (IsEnable(hWnd, 0))
5860 {
5861 if (CmSetting(hWnd))
5862 {
5863 CmApplyCmSetting();
5864 }
5865 }
5866 break;
5867 case CMD_WINNET:
5868 // Windows network settings
5869 ShowWindowsNetworkConnectionDialog();
5870 break;
5871 }
5872 }
5873
5874 // Option dialog
CmConfigDlg(HWND hWnd)5875 void CmConfigDlg(HWND hWnd)
5876 {
5877 // Validate arguments
5878 if (hWnd == NULL)
5879 {
5880 return;
5881 }
5882
5883 Dialog(hWnd, D_CM_CONFIG, CmConfigDlgProc, NULL);
5884 }
5885
5886 // Initialize the option dialog
CmConfigDlgInit(HWND hWnd)5887 void CmConfigDlgInit(HWND hWnd)
5888 {
5889 bool use_alpha;
5890 UINT alpha_value;
5891 UINT os;
5892 CLIENT_CONFIG c;
5893 // Validate arguments
5894 if (hWnd == NULL)
5895 {
5896 return;
5897 }
5898
5899 DlgFont(hWnd, S_WARNING, 10, true);
5900 DlgFont(hWnd, S_INFO, 10, false);
5901
5902 Zero(&c, sizeof(c));
5903 if (CALL(hWnd, CcGetClientConfig(cm->Client, &c)) == false)
5904 {
5905 EndDialog(hWnd, 0);
5906 return;
5907 }
5908
5909 Check(hWnd, R_ALLOW_REMOTE_CONFIG, c.AllowRemoteConfig);
5910
5911 Check(hWnd, R_USE_KEEP_CONNECT, c.UseKeepConnect);
5912 SetTextA(hWnd, E_HOSTNAME, c.KeepConnectHost);
5913 SetIntEx(hWnd, E_PORT, c.KeepConnectPort);
5914 SetIntEx(hWnd, E_INTERVAL, c.KeepConnectInterval);
5915
5916 Check(hWnd, R_TCP, c.KeepConnectProtocol == CONNECTION_TCP);
5917 Check(hWnd, R_UDP, c.KeepConnectProtocol == CONNECTION_UDP);
5918
5919 use_alpha = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "UseAlpha") == 0 ? false : true;
5920 alpha_value = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "AlphaValue");
5921 alpha_value = MAKESURE(alpha_value, 0, 100);
5922
5923 SetInt(hWnd, E_ALPHA_VALUE, alpha_value == 0 ? 50 : alpha_value);
5924 Check(hWnd, R_ALPHA, use_alpha);
5925
5926 os = GetOsInfo()->OsType;
5927 if (OS_IS_WINDOWS_NT(os) && GET_KETA(os, 100) >= 2)
5928 {
5929 Enable(hWnd, R_ALPHA);
5930 }
5931 else
5932 {
5933 Disable(hWnd, R_ALPHA);
5934 }
5935
5936 CmConfigDlgRefresh(hWnd);
5937 }
5938
5939 // Update the option dialog
CmConfigDlgRefresh(HWND hWnd)5940 void CmConfigDlgRefresh(HWND hWnd)
5941 {
5942 bool ok = true;
5943 bool use_keep_connect;
5944 // Validate arguments
5945 if (hWnd == NULL)
5946 {
5947 return;
5948 }
5949
5950 use_keep_connect = IsChecked(hWnd, R_USE_KEEP_CONNECT);
5951 SetEnable(hWnd, S_HOSTNAME, use_keep_connect);
5952 SetEnable(hWnd, S_PORT, use_keep_connect);
5953 SetEnable(hWnd, S_INTERVAL, use_keep_connect);
5954 SetEnable(hWnd, S_INTERVAL2, use_keep_connect);
5955 SetEnable(hWnd, S_PROTOCOL, use_keep_connect);
5956 SetEnable(hWnd, S_INFO, use_keep_connect);
5957 SetEnable(hWnd, S_INFO2, use_keep_connect);
5958 SetEnable(hWnd, E_HOSTNAME, use_keep_connect);
5959 SetEnable(hWnd, E_PORT, use_keep_connect);
5960 SetEnable(hWnd, E_INTERVAL, use_keep_connect);
5961 SetEnable(hWnd, R_TCP, use_keep_connect);
5962 SetEnable(hWnd, R_UDP, use_keep_connect);
5963
5964 SetEnable(hWnd, S_WARNING, IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG));
5965
5966 if (IsChecked(hWnd, R_USE_KEEP_CONNECT))
5967 {
5968 if (IsEmpty(hWnd, E_HOSTNAME))
5969 {
5970 ok = false;
5971 }
5972 if (IsChecked(hWnd, R_TCP) == false && IsChecked(hWnd, R_UDP) == false)
5973 {
5974 ok = false;
5975 }
5976 if (GetInt(hWnd, E_PORT) == 0 || GetInt(hWnd, E_PORT) >= 65536)
5977 {
5978 ok = false;
5979 }
5980 if (GetInt(hWnd, E_INTERVAL) == 0)
5981 {
5982 ok = false;
5983 }
5984 }
5985
5986 if (IsChecked(hWnd, R_ALPHA))
5987 {
5988 UINT i = GetInt(hWnd, E_ALPHA_VALUE);
5989 if (i < 20 || i >= 100)
5990 {
5991 ok = false;
5992 }
5993 Enable(hWnd, E_ALPHA_VALUE);
5994 }
5995 else
5996 {
5997 Disable(hWnd, E_ALPHA_VALUE);
5998 }
5999
6000 SetEnable(hWnd, IDOK, ok);
6001 }
6002
6003 // Save the setting of the option dialog
CmConfigDlgOnOk(HWND hWnd)6004 void CmConfigDlgOnOk(HWND hWnd)
6005 {
6006 CLIENT_CONFIG c;
6007 // Validate arguments
6008 if (hWnd == NULL)
6009 {
6010 return;
6011 }
6012
6013 Zero(&c, sizeof(c));
6014 c.AllowRemoteConfig = IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG);
6015 c.UseKeepConnect = IsChecked(hWnd, R_USE_KEEP_CONNECT);
6016 GetTxtA(hWnd, E_HOSTNAME, c.KeepConnectHost, sizeof(c.KeepConnectHost));
6017 c.KeepConnectPort = GetInt(hWnd, E_PORT);
6018 c.KeepConnectInterval = GetInt(hWnd, E_INTERVAL);
6019 if (IsChecked(hWnd, R_TCP))
6020 {
6021 c.KeepConnectProtocol = CONNECTION_TCP;
6022 }
6023 else if (IsChecked(hWnd, R_UDP))
6024 {
6025 c.KeepConnectProtocol = CONNECTION_UDP;
6026 }
6027 else
6028 {
6029 return;
6030 }
6031
6032 if (c.UseKeepConnect)
6033 {
6034 if (c.KeepConnectInterval < KEEP_INTERVAL_MIN || c.KeepConnectInterval > KEEP_INTERVAL_MAX)
6035 {
6036 MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_KEEP_INTERVAL_MSG"),
6037 KEEP_INTERVAL_MIN, KEEP_INTERVAL_MAX);
6038 FocusEx(hWnd, E_INTERVAL);
6039 return;
6040 }
6041 }
6042
6043 if (CALL(hWnd, CcSetClientConfig(cm->Client, &c)) == false)
6044 {
6045 return;
6046 }
6047
6048 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "AlphaValue", GetInt(hWnd, E_ALPHA_VALUE));
6049 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "UseAlpha", IsChecked(hWnd, R_ALPHA));
6050
6051 EndDialog(hWnd, true);
6052 }
6053
6054 // Option setting dialog procedure
CmConfigDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)6055 UINT CmConfigDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
6056 {
6057 // Validate arguments
6058 if (hWnd == NULL)
6059 {
6060 return 0;
6061 }
6062
6063 switch (msg)
6064 {
6065 case WM_INITDIALOG:
6066 CmConfigDlgInit(hWnd);
6067 break;
6068 case WM_COMMAND:
6069 switch (LOWORD(wParam))
6070 {
6071 case R_ALLOW_REMOTE_CONFIG:
6072 case R_USE_KEEP_CONNECT:
6073 case E_HOSTNAME:
6074 case E_PORT:
6075 case E_INTERVAL:
6076 case R_ALPHA:
6077 case E_ALPHA_VALUE:
6078 CmConfigDlgRefresh(hWnd);
6079 break;
6080 }
6081
6082 switch (wParam)
6083 {
6084 case IDOK:
6085 CmConfigDlgRefresh(hWnd);
6086 CmConfigDlgOnOk(hWnd);
6087 break;
6088 case IDCANCEL:
6089 Close(hWnd);
6090 break;
6091 case R_ALLOW_REMOTE_CONFIG:
6092 if (IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG) == false)
6093 {
6094 if (cm->server_name != NULL)
6095 {
6096 // If the current user is remotely connected, show a warning
6097 // when the user choose to disable the remote management
6098 if (MsgBoxEx(hWnd, MB_ICONEXCLAMATION | MB_DEFBUTTON2 | MB_YESNO, _UU("CM_REMOTE_WARNING"),
6099 cm->server_name, cm->server_name) == IDNO)
6100 {
6101 Check(hWnd, R_ALLOW_REMOTE_CONFIG, true);
6102 }
6103 }
6104 }
6105 break;
6106 case R_USE_KEEP_CONNECT:
6107 if (IsChecked(hWnd, R_USE_KEEP_CONNECT))
6108 {
6109 FocusEx(hWnd, E_HOSTNAME);
6110 }
6111 break;
6112 case R_ALPHA:
6113 if (IsChecked(hWnd, R_ALPHA))
6114 {
6115 FocusEx(hWnd, E_ALPHA_VALUE);
6116 }
6117 break;
6118 }
6119 break;
6120 case WM_CLOSE:
6121 EndDialog(hWnd, false);
6122 break;
6123 }
6124
6125 return 0;
6126 }
6127
6128 // Create a shortcut
CmSortcut(HWND hWnd,wchar_t * account_name)6129 void CmSortcut(HWND hWnd, wchar_t *account_name)
6130 {
6131 wchar_t tmp[MAX_SIZE];
6132 CM_ACCOUNT *a;
6133 wchar_t *filename;
6134 UCHAR key[SHA1_SIZE];
6135 // Validate arguments
6136 if (hWnd == NULL || account_name == NULL)
6137 {
6138 return;
6139 }
6140
6141 // Get the account information
6142 a = CmGetExistAccountObject(hWnd, account_name);
6143 if (a == NULL)
6144 {
6145 return;
6146 }
6147
6148 Copy(key, a->ShortcutKey, SHA1_SIZE);
6149
6150 if (IsZero(key, SHA1_SIZE))
6151 {
6152 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_SHORTCUT_UNSUPPORTED"));
6153 }
6154 else
6155 {
6156 // Determine the file name
6157 UniFormat(tmp, sizeof(tmp), L"%s.lnk", account_name);
6158 UniSafeFileName(tmp);
6159
6160 filename = SaveDlg(hWnd, _UU("CM_SHORTCUT_FILE"),
6161 _UU("CM_SHORTCUT_SAVE_TITLE"), tmp, L".vpn");
6162
6163 if (filename != NULL)
6164 {
6165 char key_str[64];
6166 wchar_t target[MAX_PATH];
6167 wchar_t workdir[MAX_PATH];
6168 wchar_t args[MAX_PATH];
6169 wchar_t comment[MAX_SIZE];
6170 wchar_t icon[MAX_PATH];
6171
6172 BinToStr(key_str, sizeof(key_str), key, SHA1_SIZE);
6173
6174 // Create a shortcut
6175 UniStrCpy(target, sizeof(target), MsGetExeFileNameW());
6176 UniStrCpy(workdir, sizeof(workdir), MsGetExeDirNameW());
6177 StrToUni(args, sizeof(args), key_str);
6178 UniFormat(comment, sizeof(comment), _UU("CM_SHORTCUT_COMMENT"), account_name);
6179 UniStrCpy(icon, sizeof(icon), MsGetExeFileNameW());
6180
6181 if (CreateLink(filename, target, workdir, args, comment, icon, 1) == false)
6182 {
6183 MsgBox(hWnd, MB_ICONSTOP, _UU("CM_SHORTCUT_ERROR"));
6184 }
6185
6186 Free(filename);
6187 }
6188 }
6189
6190 CmFreeAccountObject(hWnd, a);
6191 }
6192
6193 // Export the account
CmExportAccount(HWND hWnd,wchar_t * account_name)6194 void CmExportAccount(HWND hWnd, wchar_t *account_name)
6195 {
6196 wchar_t tmp[MAX_SIZE];
6197 CM_ACCOUNT *a;
6198 wchar_t *filename;
6199 // Validate arguments
6200 if (hWnd == NULL || account_name == NULL)
6201 {
6202 return;
6203 }
6204
6205 // Get the account information
6206 a = CmGetExistAccountObject(hWnd, account_name);
6207 if (a == NULL)
6208 {
6209 return;
6210 }
6211
6212 // Determine the file name
6213 UniFormat(tmp, sizeof(tmp), L"%s.vpn", account_name);
6214 UniSafeFileName(tmp);
6215
6216 filename = SaveDlg(hWnd, _UU("CM_ACCOUNT_SETTING_FILE"),
6217 _UU("CM_ACCOUNT_SAVE_TITLE"), tmp, L".vpn");
6218
6219 if (filename != NULL)
6220 {
6221 RPC_CLIENT_CREATE_ACCOUNT t;
6222 BUF *b;
6223 BUF *b2;
6224 wchar_t tmp[MAX_SIZE];
6225 UCHAR *buf;
6226 UINT buf_size;
6227 UCHAR bom[] = {0xef, 0xbb, 0xbf, };
6228
6229 Zero(&t, sizeof(t));
6230 t.ClientOption = a->ClientOption;
6231 t.ClientAuth = a->ClientAuth;
6232 t.StartupAccount = a->Startup;
6233 t.CheckServerCert = a->CheckServerCert;
6234 t.ServerCert = a->ServerCert;
6235 t.ClientOption->FromAdminPack = false;
6236
6237 b = CiAccountToCfg(&t);
6238
6239 SeekBuf(b, 0, 0);
6240
6241 // Check whether the password is contained
6242 if (CiHasAccountSensitiveInformation(b))
6243 {
6244 SeekBuf(b, 0, 0);
6245
6246 // Confirm that the user want to clear the password
6247 if (MsgBox(hWnd, MB_YESNO | MB_ICONQUESTION, _UU("CM_ACCOUNT_MSG_SENSITIVE")) == IDYES)
6248 {
6249 // Erase
6250 CiEraseSensitiveInAccount(b);
6251 }
6252 }
6253
6254 UniStrCpy(tmp, sizeof(tmp), filename);
6255 b2 = NewBuf();
6256
6257 WriteBuf(b2, bom, sizeof(bom));
6258
6259 // Add a header part
6260 buf_size = CalcUniToUtf8(_UU("CM_ACCOUNT_FILE_BANNER"));
6261 buf = ZeroMalloc(buf_size + 32);
6262 UniToUtf8(buf, buf_size, _UU("CM_ACCOUNT_FILE_BANNER"));
6263
6264 WriteBuf(b2, buf, StrLen((char *)buf));
6265 WriteBuf(b2, b->Buf, b->Size);
6266 SeekBuf(b2, 0, 0);
6267
6268 FreeBuf(b);
6269
6270 if (DumpBufW(b2, tmp) == false)
6271 {
6272 MsgBox(hWnd, MB_ICONSTOP, _UU("CM_FAILED_TO_SAVE_FILE"));
6273 }
6274
6275 Free(filename);
6276 FreeBuf(b2);
6277 Free(buf);
6278 }
6279
6280 CmFreeAccountObject(hWnd, a);
6281 }
6282
6283 // Main process of importing account
CmImportAccountMain(HWND hWnd,wchar_t * filename)6284 void CmImportAccountMain(HWND hWnd, wchar_t *filename)
6285 {
6286 CmImportAccountMainEx(hWnd, filename, false);
6287 }
CmImportAccountMainEx(HWND hWnd,wchar_t * filename,bool overwrite)6288 void CmImportAccountMainEx(HWND hWnd, wchar_t *filename, bool overwrite)
6289 {
6290 wchar_t name[MAX_SIZE];
6291 wchar_t tmp[MAX_SIZE];
6292 BUF *b;
6293 RPC_CLIENT_CREATE_ACCOUNT *t;
6294 // Validate arguments
6295 if (hWnd == NULL || filename == NULL)
6296 {
6297 return;
6298 }
6299
6300 UniStrCpy(tmp, sizeof(tmp), filename);
6301
6302 b = ReadDumpW(tmp);
6303 if (b == NULL)
6304 {
6305 MsgBox(hWnd, MB_ICONSTOP, _UU("CM_FAILED_TO_OPEN_FILE"));
6306 return;
6307 }
6308
6309 t = CiCfgToAccount(b);
6310 if (t == NULL)
6311 {
6312 FreeBuf(b);
6313 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("CM_ACCOUNT_PARSE_FAILED"));
6314 return;
6315 }
6316
6317 if (overwrite)
6318 {
6319 // If the same name already exists, remove it
6320 if (LvSearchStr(hWnd, L_ACCOUNT, 0, t->ClientOption->AccountName) != INFINITE)
6321 {
6322 RPC_CLIENT_DELETE_ACCOUNT d;
6323 RPC_CLIENT_GET_ACCOUNT get;
6324 HWND h = cm->hEasyWnd == NULL ? hWnd : cm->hEasyWnd;
6325
6326 Zero(&d, sizeof(d));
6327 UniStrCpy(d.AccountName, sizeof(d.AccountName), t->ClientOption->AccountName);
6328
6329 Zero(&get, sizeof(get));
6330 UniStrCpy(get.AccountName, sizeof(get.AccountName), t->ClientOption->AccountName);
6331 if (CcGetAccount(cm->Client, &get) == ERR_NO_ERROR)
6332 {
6333 // Inherit the information of some of the client option by getting
6334 // the account information of the same name that already exists
6335 if (get.ClientOption != NULL && get.ClientAuth != NULL)
6336 {
6337 CLIENT_OPTION *old_option = get.ClientOption;
6338 CLIENT_AUTH *old_auth = get.ClientAuth;
6339
6340 // Inherit the connection parameters
6341 t->ClientOption->ProxyType = old_option->ProxyType;
6342 StrCpy(t->ClientOption->ProxyName, sizeof(t->ClientOption->ProxyName),
6343 old_option->ProxyName);
6344 t->ClientOption->ProxyPort = old_option->ProxyPort;
6345 StrCpy(t->ClientOption->ProxyUsername, sizeof(t->ClientOption->ProxyUsername),
6346 old_option->ProxyUsername);
6347 StrCpy(t->ClientOption->ProxyPassword, sizeof(t->ClientOption->ProxyPassword),
6348 old_option->ProxyPassword);
6349 t->ClientOption->NumRetry = old_option->NumRetry;
6350 t->ClientOption->RetryInterval = old_option->RetryInterval;
6351 t->ClientOption->MaxConnection = old_option->MaxConnection;
6352 t->ClientOption->UseEncrypt = old_option->UseEncrypt;
6353 t->ClientOption->UseCompress = old_option->UseCompress;
6354 t->ClientOption->HalfConnection = old_option->HalfConnection;
6355 t->ClientOption->NoRoutingTracking = old_option->NoRoutingTracking;
6356 StrCpy(t->ClientOption->DeviceName, sizeof(t->ClientOption->DeviceName),
6357 old_option->DeviceName);
6358 t->ClientOption->AdditionalConnectionInterval = old_option->AdditionalConnectionInterval;
6359 t->ClientOption->ConnectionDisconnectSpan = old_option->ConnectionDisconnectSpan;
6360 t->ClientOption->HideStatusWindow = old_option->HideStatusWindow;
6361 t->ClientOption->RequireMonitorMode = old_option->RequireMonitorMode;
6362 t->ClientOption->RequireBridgeRoutingMode = old_option->RequireBridgeRoutingMode;
6363 t->ClientOption->DisableQoS = old_option->DisableQoS;
6364 t->ClientOption->NoTls1 = old_option->NoTls1;
6365
6366 // Inherit the authentication data
6367 CiFreeClientAuth(t->ClientAuth);
6368 t->ClientAuth = CopyClientAuth(old_auth);
6369
6370 // Other Settings
6371 t->StartupAccount = get.StartupAccount;
6372 t->CheckServerCert = get.CheckServerCert;
6373 if (t->ServerCert != NULL)
6374 {
6375 FreeX(t->ServerCert);
6376 }
6377 t->ServerCert = NULL;
6378 if (get.ServerCert != NULL)
6379 {
6380 t->ServerCert = CloneX(get.ServerCert);
6381 }
6382 Copy(t->ShortcutKey, get.ShortcutKey, sizeof(t->ShortcutKey));
6383 }
6384
6385 CiFreeClientGetAccount(&get);
6386 }
6387
6388 if (CALL(h, CcDeleteAccount(cm->Client, &d)) == false)
6389 {
6390 CiFreeClientCreateAccount(t);
6391 Free(t);
6392 return;
6393 }
6394
6395 CmRefreshAccountList(hWnd);
6396 }
6397 }
6398
6399 CmGenerateImportName(hWnd, name, sizeof(name), t->ClientOption->AccountName);
6400 UniStrCpy(t->ClientOption->AccountName, sizeof(t->ClientOption->AccountName), name);
6401
6402 if (overwrite)
6403 {
6404 t->ClientOption->FromAdminPack = true;
6405 }
6406
6407 CALL(hWnd, CcCreateAccount(cm->Client, t));
6408
6409 CiFreeClientCreateAccount(t);
6410 Free(t);
6411
6412 FreeBuf(b);
6413
6414 if (overwrite)
6415 {
6416 // Start to connect the VPN
6417 CmConnect(hWnd, name);
6418 }
6419
6420 //MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_IMPORT_MESSAGE"), filename, name);
6421 }
6422
6423 // Import an account
CmImportAccount(HWND hWnd)6424 void CmImportAccount(HWND hWnd)
6425 {
6426 wchar_t *filename;
6427 wchar_t tmp[MAX_SIZE];
6428 // Validate arguments
6429 if (hWnd == NULL)
6430 {
6431 return;
6432 }
6433
6434 // Open the file
6435 filename = OpenDlg(hWnd, _UU("CM_ACCOUNT_SETTING_FILE"), _UU("CM_ACCOUNT_OPEN_TITLE"));
6436 if (filename == NULL)
6437 {
6438 return;
6439 }
6440
6441 UniStrCpy(tmp, sizeof(tmp), filename);
6442 Free(filename);
6443
6444 CmImportAccountMain(hWnd, tmp);
6445 }
6446
6447 // Create a copy of the account
CmCopyAccount(HWND hWnd,wchar_t * account_name)6448 void CmCopyAccount(HWND hWnd, wchar_t *account_name)
6449 {
6450 wchar_t tmp[MAX_SIZE];
6451 CM_ACCOUNT *a;
6452 RPC_CLIENT_CREATE_ACCOUNT c;
6453 // Validate arguments
6454 if (hWnd == NULL || account_name == NULL)
6455 {
6456 return;
6457 }
6458
6459 CmGenerateCopyName(hWnd, tmp, sizeof(tmp), account_name);
6460
6461 // Get an account information
6462 a = CmGetExistAccountObject(hWnd, account_name);
6463 if (a == NULL)
6464 {
6465 return;
6466 }
6467
6468 // Change the account name
6469 UniStrCpy(a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName), tmp);
6470
6471 // Write
6472 Zero(&c, sizeof(c));
6473 c.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
6474 Copy(c.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
6475 c.ClientAuth = CopyClientAuth(a->ClientAuth);
6476 if (a->ServerCert)
6477 {
6478 c.ServerCert = CloneX(a->ServerCert);
6479 }
6480 c.CheckServerCert = a->CheckServerCert;
6481 c.StartupAccount = false; // Don't copy the startup attribute
6482
6483 CALL(hWnd, CcCreateAccount(cm->Client, &c));
6484 CiFreeClientCreateAccount(&c);
6485
6486 CmFreeAccountObject(hWnd, a);
6487 }
6488
6489 // Update the Virtual LAN Card Name dialog
CmNewVLanDlgUpdate(HWND hWnd)6490 void CmNewVLanDlgUpdate(HWND hWnd)
6491 {
6492 bool ok = true;
6493 char tmp[MAX_SIZE];
6494 // Validate arguments
6495 if (hWnd == NULL)
6496 {
6497 return;
6498 }
6499
6500 GetTxtA(hWnd, E_NAME, tmp, sizeof(tmp));
6501 if (IsSafeStr(tmp) == false)
6502 {
6503 ok = false;
6504 }
6505 if (SearchStrEx(tmp, " ", 0, false) != INFINITE)
6506 {
6507 ok = false;
6508 }
6509
6510 Trim(tmp);
6511 if (StrLen(tmp) == 0)
6512 {
6513 ok = false;
6514 }
6515
6516 SetEnable(hWnd, IDOK, ok);
6517 }
6518
6519 // Virtual LAN card name decision dialog procedure
CmNewVLanDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)6520 UINT CmNewVLanDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
6521 {
6522 char *tmp = (char *)param;
6523 char default_name[MAX_SIZE];
6524 RPC_CLIENT_VERSION ver;
6525 // Validate arguments
6526 if (hWnd == NULL)
6527 {
6528 return 0;
6529 }
6530
6531 switch (msg)
6532 {
6533 case WM_INITDIALOG:
6534 LimitText(hWnd, E_NAME, cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN);
6535 FormatText(hWnd, S_INFO, cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN);
6536
6537 Zero(&ver, sizeof(ver));
6538
6539 if (CcGetClientVersion(cm->Client, &ver) == ERR_NO_ERROR)
6540 {
6541 if (ver.IsVLanNameRegulated)
6542 {
6543 Show(hWnd, S_WIN8);
6544 }
6545 }
6546
6547 if (CiGetNextRecommendedVLanName(cm->Client, default_name, sizeof(default_name)))
6548 {
6549 // Show a default virtual LAN card name candidate
6550 SetTextA(hWnd, E_NAME, default_name);
6551 }
6552
6553 CmNewVLanDlgUpdate(hWnd);
6554 break;
6555
6556 case WM_COMMAND:
6557 switch (wParam)
6558 {
6559 case IDOK:
6560 if (cm->Client->Win9x)
6561 {
6562 // For Windows 9x, show a confirmation message
6563 if (MsgBox(hWnd, MB_ICONQUESTION | MB_OKCANCEL, _UU("CM_9X_VLAN_INSTALL")) == IDCANCEL)
6564 {
6565 break;
6566 }
6567 }
6568 GetTxtA(hWnd, E_NAME, tmp, (cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN) + 1);
6569 Trim(tmp);
6570
6571 if (CcGetClientVersion(cm->Client, &ver) == ERR_NO_ERROR)
6572 {
6573 if (ver.IsVLanNameRegulated)
6574 {
6575 if (CiIsValidVLanRegulatedName(tmp) == false)
6576 {
6577 // Virtual LAN card name isn't meeting the format
6578 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("D_CM_NEW_VLAN@S_WIN8"));
6579
6580 FocusEx(hWnd, E_NAME);
6581 break;
6582 }
6583 }
6584 }
6585
6586 EndDialog(hWnd, true);
6587 break;
6588 case IDCANCEL:
6589 Close(hWnd);
6590 break;
6591 }
6592 switch (LOWORD(wParam))
6593 {
6594 case E_NAME:
6595 CmNewVLanDlgUpdate(hWnd);
6596 break;
6597
6598 case R_USE_DISCONNECT:
6599 if (IsChecked(hWnd, R_USE_DISCONNECT))
6600 {
6601 FocusEx(hWnd, E_DISCONNECT_SPAN);
6602 }
6603 break;
6604 }
6605 break;
6606
6607 case WM_CLOSE:
6608 EndDialog(hWnd, false);
6609 break;
6610 }
6611
6612 return 0;
6613 }
6614
6615 // Dialog to determine the new virtual LAN card name
CmNewVLanDlg(HWND hWnd)6616 char *CmNewVLanDlg(HWND hWnd)
6617 {
6618 char tmp[MAX_DEVICE_NAME_LEN + 1];
6619
6620 if (Dialog(hWnd, D_CM_NEW_VLAN, CmNewVLanDlgProc, tmp) == false)
6621 {
6622 return NULL;
6623 }
6624
6625 return CopyStr(tmp);
6626 }
6627
6628 // Update the advanced settings dialog
CmDetailDlgUpdate(HWND hWnd,CM_ACCOUNT * a)6629 void CmDetailDlgUpdate(HWND hWnd, CM_ACCOUNT *a)
6630 {
6631 bool ok = true;
6632 bool locked;
6633 // Validate arguments
6634 if (hWnd == NULL || a == NULL)
6635 {
6636 return;
6637 }
6638
6639 locked = a->LockMode;
6640
6641 if (a->LinkMode || a->NatMode)
6642 {
6643 Disable(hWnd, R_NO_ROUTING);
6644 }
6645 else
6646 {
6647 if (cm->Client->Unix)
6648 {
6649 Disable(hWnd, R_NO_ROUTING);
6650 }
6651 }
6652
6653 SetEnable(hWnd, E_DISCONNECT_SPAN, IsChecked(hWnd, R_USE_DISCONNECT));
6654
6655 SetEnable(hWnd, IDOK, ok);
6656
6657 if (locked)
6658 {
6659 Disable(hWnd, C_NUM_TCP);
6660 Disable(hWnd, S_STATIC5);
6661 Disable(hWnd, S_STATIC8);
6662 Disable(hWnd, E_INTERVAL);
6663 Disable(hWnd, S_STATIC9);
6664 Disable(hWnd, E_DISCONNECT_SPAN);
6665 Disable(hWnd, S_STATIC10);
6666 Disable(hWnd, S_STATIC11);
6667 Disable(hWnd, R_USE_DISCONNECT);
6668 Disable(hWnd, R_USE_HALF_CONNECTION);
6669 Disable(hWnd, R_DISABLE_QOS);
6670 Disable(hWnd, R_USE_ENCRYPT);
6671 Disable(hWnd, R_USE_COMPRESS);
6672 Disable(hWnd, R_BRIDGE);
6673 Disable(hWnd, R_MONITOR);
6674 Disable(hWnd, R_NO_ROUTING);
6675 }
6676 }
6677
6678 // Advanced Settings dialog procedure
CmDetailDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)6679 UINT CmDetailDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
6680 {
6681 CM_ACCOUNT *a = (CM_ACCOUNT *)param;
6682 UINT i;
6683 UINT num;
6684 wchar_t tmp[MAX_SIZE];
6685 // Validate arguments
6686 if (hWnd == NULL)
6687 {
6688 return 0;
6689 }
6690
6691 switch (msg)
6692 {
6693 case WM_INITDIALOG:
6694 // Number of TCP connections
6695 for (i = 1;i <= MAX_TCP_CONNECTION;i++)
6696 {
6697 UniFormat(tmp, sizeof(tmp), L"%u", i);
6698 CbAddStr(hWnd, C_NUM_TCP, tmp, i);
6699 }
6700 CbSelect(hWnd, C_NUM_TCP, a->ClientOption->MaxConnection);
6701
6702 // Connection establishment interval
6703 SetInt(hWnd, E_INTERVAL, a->ClientOption->AdditionalConnectionInterval);
6704
6705 // Lifetime
6706 SetIntEx(hWnd, E_DISCONNECT_SPAN, a->ClientOption->ConnectionDisconnectSpan);
6707 Check(hWnd, R_USE_DISCONNECT, a->ClientOption->ConnectionDisconnectSpan != 0);
6708 Check(hWnd, R_USE_HALF_CONNECTION, a->ClientOption->HalfConnection);
6709 Check(hWnd, R_USE_ENCRYPT, a->ClientOption->UseEncrypt);
6710 Check(hWnd, R_USE_COMPRESS, a->ClientOption->UseCompress);
6711 Check(hWnd, R_NO_ROUTING, a->ClientOption->NoRoutingTracking);
6712 Check(hWnd, R_DISABLE_QOS, a->ClientOption->DisableQoS);
6713 Check(hWnd, R_DISABLE_UDP, a->ClientOption->NoUdpAcceleration);
6714
6715 // Select the Connection Mode
6716 if (a->LinkMode == false)
6717 {
6718 Check(hWnd, R_BRIDGE, a->ClientOption->RequireBridgeRoutingMode);
6719 Check(hWnd, R_MONITOR, a->ClientOption->RequireMonitorMode);
6720 }
6721 else
6722 {
6723 Check(hWnd, R_BRIDGE, true);
6724 Check(hWnd, R_MONITOR, false);
6725
6726 SetText(hWnd, S_MODE, _UU("CM_DETAIL_MODE_LINK_STR"));
6727 Disable(hWnd, R_BRIDGE);
6728 Disable(hWnd, R_MONITOR);
6729 }
6730
6731 CmDetailDlgUpdate(hWnd, a);
6732 Focus(hWnd, IDOK);
6733 break;
6734 case WM_COMMAND:
6735 switch (wParam)
6736 {
6737 case IDOK:
6738 if (IsChecked(hWnd, R_USE_DISCONNECT) && GetInt(hWnd, E_DISCONNECT_SPAN) == 0)
6739 {
6740 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_NO_DISCONNECT_SPAN"));
6741 FocusEx(hWnd, E_DISCONNECT_SPAN);
6742 break;
6743 }
6744 num = GetInt(hWnd, C_NUM_TCP);
6745 if (num == 0)
6746 {
6747 break;
6748 }
6749 if (num == 1 && IsChecked(hWnd, R_USE_HALF_CONNECTION))
6750 {
6751 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_HALF_MSG"));
6752 Focus(hWnd, C_NUM_TCP);
6753 break;
6754 }
6755 if (GetInt(hWnd, E_INTERVAL) < 1)
6756 {
6757 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_TOO_SMALL_INTERVAL"));
6758 Focus(hWnd, E_INTERVAL);
6759 break;
6760 }
6761
6762 a->ClientOption->MaxConnection = num;
6763 a->ClientOption->AdditionalConnectionInterval = GetInt(hWnd, E_INTERVAL);
6764 if (IsChecked(hWnd, R_USE_DISCONNECT) == false)
6765 {
6766 a->ClientOption->ConnectionDisconnectSpan = 0;
6767 }
6768 else
6769 {
6770 a->ClientOption->ConnectionDisconnectSpan = GetInt(hWnd, E_DISCONNECT_SPAN);
6771 }
6772 a->ClientOption->HalfConnection = IsChecked(hWnd, R_USE_HALF_CONNECTION);
6773 a->ClientOption->UseEncrypt = IsChecked(hWnd, R_USE_ENCRYPT);
6774 a->ClientOption->UseCompress = IsChecked(hWnd, R_USE_COMPRESS);
6775 a->ClientOption->NoRoutingTracking = IsChecked(hWnd, R_NO_ROUTING);
6776 a->ClientOption->DisableQoS = IsChecked(hWnd, R_DISABLE_QOS);
6777 a->ClientOption->NoUdpAcceleration = IsChecked(hWnd, R_DISABLE_UDP);
6778
6779 if (a->LinkMode)
6780 {
6781 a->ClientOption->RequireBridgeRoutingMode = true;
6782 a->ClientOption->RequireMonitorMode = false;
6783 }
6784 else
6785 {
6786 a->ClientOption->RequireBridgeRoutingMode = IsChecked(hWnd, R_BRIDGE);
6787 a->ClientOption->RequireMonitorMode = IsChecked(hWnd, R_MONITOR);
6788 }
6789
6790 EndDialog(hWnd, true);
6791
6792 break;
6793 case IDCANCEL:
6794 Close(hWnd);
6795 break;
6796 }
6797 switch (LOWORD(wParam))
6798 {
6799 case C_NUM_TCP:
6800 case E_INTERVAL:
6801 case E_DISCONNECT_SPAN:
6802 case R_USE_DISCONNECT:
6803 case R_USE_HALF_CONNECTION:
6804 CmDetailDlgUpdate(hWnd, a);
6805 break;
6806 }
6807 switch (wParam)
6808 {
6809 case R_USE_DISCONNECT:
6810 if (IsChecked(hWnd, R_USE_DISCONNECT))
6811 {
6812 FocusEx(hWnd, E_DISCONNECT_SPAN);
6813 }
6814 break;
6815 }
6816 break;
6817 case WM_CLOSE:
6818 EndDialog(hWnd, false);
6819 break;
6820 }
6821
6822 return 0;
6823 }
6824
6825 // Advanced Settings dialog
CmDetailDlg(HWND hWnd,CM_ACCOUNT * a)6826 bool CmDetailDlg(HWND hWnd, CM_ACCOUNT *a)
6827 {
6828 // Validate arguments
6829 if (hWnd == NULL || a == NULL)
6830 {
6831 return false;
6832 }
6833
6834 return Dialog(hWnd, D_CM_DETAIL, CmDetailDlgProc, a);
6835 }
6836
6837 // Update the account editing dialog procedure
CmEditAccountDlgUpdate(HWND hWnd,CM_ACCOUNT * a)6838 void CmEditAccountDlgUpdate(HWND hWnd, CM_ACCOUNT *a)
6839 {
6840 bool ok = true;
6841 char str[MAX_SIZE];
6842 bool locked;
6843 // Validate arguments
6844 if (hWnd == NULL || a == NULL)
6845 {
6846 return;
6847 }
6848
6849 locked = a->LockMode;
6850
6851 if (a->Inited == false)
6852 {
6853 return;
6854 }
6855
6856 if (a->EditMode)
6857 {
6858 Disable(hWnd, E_ACCOUNT_NAME);
6859 }
6860
6861 // The name of connection settings
6862 GetTxt(hWnd, E_ACCOUNT_NAME, a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName));
6863 UniTrim(a->ClientOption->AccountName);
6864
6865 // Host name
6866 GetTxtA(hWnd, E_HOSTNAME, a->ClientOption->Hostname, sizeof(a->ClientOption->Hostname));
6867 Trim(a->ClientOption->Hostname);
6868
6869 if (InStr(a->ClientOption->Hostname, "/tcp"))
6870 {
6871 Check(hWnd, R_DISABLE_NATT, true);
6872 }
6873 else
6874 {
6875 Check(hWnd, R_DISABLE_NATT, false);
6876 }
6877
6878 SetEnable(hWnd, R_DISABLE_NATT, !IsEmptyStr(a->ClientOption->Hostname));
6879
6880 // Port number
6881 a->ClientOption->Port = GetInt(hWnd, C_PORT);
6882
6883 // HUB name
6884 GetTxtA(hWnd,C_HUBNAME, a->ClientOption->HubName, sizeof(a->ClientOption->HubName));
6885
6886 // Type of proxy
6887 a->ClientOption->ProxyType = PROXY_DIRECT;
6888 if (IsChecked(hWnd, R_HTTPS))
6889 {
6890 a->ClientOption->ProxyType = PROXY_HTTP;
6891 }
6892 if (IsChecked(hWnd, R_SOCKS))
6893 {
6894 a->ClientOption->ProxyType = PROXY_SOCKS;
6895 }
6896
6897 // To validate the server certificate
6898 a->CheckServerCert = IsChecked(hWnd, R_CHECK_CERT);
6899
6900 if (a->NatMode)
6901 {
6902 Disable(hWnd, R_CHECK_CERT);
6903 Disable(hWnd, B_TRUST);
6904 }
6905
6906 if (a->HideTrustCert)
6907 {
6908 Disable(hWnd, B_TRUST);
6909 }
6910
6911 // Device name
6912 StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName), "");
6913 if (LvIsSelected(hWnd, L_VLAN))
6914 {
6915 wchar_t *s = LvGetStr(hWnd, L_VLAN, LvGetSelected(hWnd, L_VLAN), 0);
6916 if (s != NULL)
6917 {
6918 char str[MAX_SIZE];
6919 UniToStr(str, sizeof(str), s);
6920 CmPrintNameToVLanName(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName), str);
6921 Free(s);
6922 }
6923 }
6924
6925 // User authentication
6926 a->ClientAuth->AuthType = CbGetSelect(hWnd, C_TYPE);
6927 GetTxtA(hWnd, E_USERNAME, a->ClientAuth->Username, sizeof(a->ClientAuth->Username));
6928 Trim(a->ClientAuth->Username);
6929 switch (a->ClientAuth->AuthType)
6930 {
6931 case CLIENT_AUTHTYPE_PASSWORD:
6932 // Password authentication
6933 GetTxtA(hWnd, E_PASSWORD, str, sizeof(str));
6934 if (StrCmp(str, HIDDEN_PASSWORD) != 0)
6935 {
6936 HashPassword(a->ClientAuth->HashedPassword, a->ClientAuth->Username, str);
6937 }
6938 break;
6939 case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
6940 // Plaintext password authentication
6941 GetTxtA(hWnd, E_PASSWORD, str, sizeof(str));
6942 if (StrCmp(str, HIDDEN_PASSWORD) != 0)
6943 {
6944 StrCpy(a->ClientAuth->PlainPassword, sizeof(a->ClientAuth->PlainPassword), str);
6945 }
6946 break;
6947 }
6948
6949 // Reconnection option
6950 if ((a->LinkMode || a->NatMode) || a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
6951 {
6952 Disable(hWnd, R_RETRY);
6953 }
6954 else
6955 {
6956 Enable(hWnd, R_RETRY);
6957 }
6958
6959 if (IsChecked(hWnd, R_RETRY) == false)
6960 {
6961 a->ClientOption->NumRetry = 0;
6962 }
6963 else
6964 {
6965 if (IsChecked(hWnd, R_INFINITE))
6966 {
6967 a->ClientOption->NumRetry = INFINITE;
6968 }
6969 else
6970 {
6971 a->ClientOption->NumRetry = GetInt(hWnd, E_RETRY_NUM);
6972 }
6973 }
6974 a->ClientOption->RetryInterval = GetInt(hWnd, E_RETRY_SPAN);
6975
6976 a->ClientOption->NoTls1 = IsChecked(hWnd, R_NOTLS1);
6977
6978 // Information determining
6979 if (UniStrLen(a->ClientOption->AccountName) == 0 && a->NatMode == false)
6980 {
6981 ok = false;
6982 }
6983 if (StrLen(a->ClientOption->Hostname) == 0)
6984 {
6985 ok = false;
6986 }
6987 if (a->ClientOption->Port == 0 || a->ClientOption->Port >= 65536)
6988 {
6989 ok = false;
6990 }
6991 if (StrLen(a->ClientOption->HubName) == 0)
6992 {
6993 ok = false;
6994 }
6995 if (StrLen(a->ClientAuth->Username) == 0)
6996 {
6997 ok = false;
6998 }
6999 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
7000 {
7001 if (a->ClientAuth->ClientK == NULL || a->ClientAuth->ClientX == NULL)
7002 {
7003 ok = false;
7004 }
7005 }
7006 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
7007 {
7008 if (IsEmptyStr(a->ClientAuth->SecurePrivateKeyName) || IsEmptyStr(a->ClientAuth->SecurePublicCertName))
7009 {
7010 ok = false;
7011 }
7012 }
7013
7014 // Display update
7015 if (IsChecked(hWnd, R_RETRY) && IsEnable(hWnd, R_RETRY))
7016 {
7017 if (a->LinkMode == false && a->NatMode == false)
7018 {
7019 Enable(hWnd, R_INFINITE);
7020 Enable(hWnd, E_RETRY_SPAN);
7021 Enable(hWnd, S_RETRY_SPAN_1);
7022 Enable(hWnd, S_RETRY_SPAN_2);
7023 }
7024 else
7025 {
7026 Disable(hWnd, R_INFINITE);
7027 Disable(hWnd, E_RETRY_SPAN);
7028 Disable(hWnd, S_RETRY_SPAN_1);
7029 Disable(hWnd, S_RETRY_SPAN_2);
7030 }
7031 if (IsChecked(hWnd, R_INFINITE) == false)
7032 {
7033 Enable(hWnd, E_RETRY_NUM);
7034 Enable(hWnd, S_RETRY_NUM_1);
7035 Enable(hWnd, S_RETRY_NUM_2);
7036 if (GetInt(hWnd, E_RETRY_NUM) == 0)
7037 {
7038 ok = false;
7039 }
7040 }
7041 else
7042 {
7043 Disable(hWnd, E_RETRY_NUM);
7044 Disable(hWnd, S_RETRY_NUM_1);
7045 Disable(hWnd, S_RETRY_NUM_2);
7046 }
7047 }
7048 else
7049 {
7050 Disable(hWnd, E_RETRY_NUM);
7051 Disable(hWnd, E_RETRY_SPAN);
7052 Disable(hWnd, R_INFINITE);
7053 Disable(hWnd, S_RETRY_NUM_1);
7054 Disable(hWnd, S_RETRY_NUM_2);
7055 Disable(hWnd, S_RETRY_SPAN_1);
7056 Disable(hWnd, S_RETRY_SPAN_2);
7057 }
7058
7059 if (a->NatMode == false)
7060 {
7061 if (a->ServerCert == NULL)
7062 {
7063 SetText(hWnd, B_SERVER_CERT, _UU("CM_SERVER_CERT_1"));
7064 Disable(hWnd, B_VIEW_SERVER_CERT);
7065 }
7066 else
7067 {
7068 SetText(hWnd, B_SERVER_CERT, _UU("CM_SERVER_CERT_2"));
7069 Enable(hWnd, B_VIEW_SERVER_CERT);
7070 }
7071 }
7072 else
7073 {
7074 Disable(hWnd, B_VIEW_SERVER_CERT);
7075 Disable(hWnd, B_SERVER_CERT);
7076 }
7077
7078 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT || a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
7079 {
7080 wchar_t tmp[MAX_SIZE * 2];
7081 wchar_t issuer[MAX_SIZE];
7082 wchar_t subject[MAX_SIZE];
7083 wchar_t expires[MAX_SIZE];
7084
7085 SetIcon(hWnd, S_CERT, (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT) ? ICO_CERT : ICO_SECURE);
7086
7087 Hide(hWnd, S_PASSWORD);
7088 Hide(hWnd, E_PASSWORD);
7089 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
7090 {
7091 if (a->ClientAuth->ClientX != NULL)
7092 {
7093 Enable(hWnd, B_VIEW_CLIENT_CERT);
7094 SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_CLIENT_CERT_2"));
7095 GetPrintNameFromName(issuer, sizeof(issuer), a->ClientAuth->ClientX->issuer_name);
7096 GetPrintNameFromName(subject, sizeof(subject), a->ClientAuth->ClientX->subject_name);
7097 GetDateStrEx64(expires, sizeof(expires), SystemToLocal64(a->ClientAuth->ClientX->notAfter), NULL);
7098 UniFormat(tmp, sizeof(tmp), _UU("CM_CERT_INFO"), subject, issuer, expires);
7099 }
7100 else
7101 {
7102 Disable(hWnd, B_VIEW_CLIENT_CERT);
7103 SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_CLIENT_CERT_1"));
7104 UniStrCpy(tmp, sizeof(tmp), _UU("CM_NO_CERT"));
7105 }
7106 SetText(hWnd, B_VIEW_CLIENT_CERT, _UU("CM_VIEW_CLIENT_CERT"));
7107
7108 Enable(hWnd, B_REGIST_CLIENT_CERT);
7109 }
7110 else
7111 {
7112 if (IsEmptyStr(a->ClientAuth->SecurePrivateKeyName) || IsEmptyStr(a->ClientAuth->SecurePublicCertName))
7113 {
7114 UniStrCpy(tmp, sizeof(tmp), _UU("CM_NO_SECURE"));
7115 }
7116 else
7117 {
7118 UniFormat(tmp, sizeof(tmp), _UU("CM_CERT_SECURE_INFO"),
7119 a->ClientAuth->SecurePublicCertName, a->ClientAuth->SecurePrivateKeyName);
7120 }
7121
7122 SetText(hWnd, B_VIEW_CLIENT_CERT, _UU("CM_SELECT_SECURE_DEVICE"));
7123 SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_SELECT_CERT_INCARD"));
7124 Enable(hWnd, B_VIEW_CLIENT_CERT);
7125
7126 if (SmGetCurrentSecureIdFromReg() == 0)
7127 {
7128 Disable(hWnd, B_REGIST_CLIENT_CERT);
7129 }
7130 else
7131 {
7132 Enable(hWnd, B_REGIST_CLIENT_CERT);
7133 }
7134 }
7135 SetText(hWnd, S_CERT_INFO, tmp);
7136 Show(hWnd, S_CERT);
7137 Show(hWnd, S_CERT_INFO);
7138 Show(hWnd, B_VIEW_CLIENT_CERT);
7139 Show(hWnd, B_REGIST_CLIENT_CERT);
7140 }
7141 else
7142 {
7143 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_ANONYMOUS)
7144 {
7145 Hide(hWnd, S_PASSWORD);
7146 Hide(hWnd, E_PASSWORD);
7147 }
7148 else
7149 {
7150 Show(hWnd, S_PASSWORD);
7151 Show(hWnd, E_PASSWORD);
7152 }
7153 Hide(hWnd, S_CERT);
7154 Hide(hWnd, S_CERT_INFO);
7155 Hide(hWnd, B_VIEW_CLIENT_CERT);
7156 Hide(hWnd, B_REGIST_CLIENT_CERT);
7157 }
7158
7159 if (a->ClientOption->ProxyType != PROXY_DIRECT)
7160 {
7161 Enable(hWnd, B_PROXY_CONFIG);
7162 if (StrLen(a->ClientOption->ProxyName) == 0)
7163 {
7164 ok = false;
7165 }
7166 if (a->ClientOption->ProxyPort == 0)
7167 {
7168 ok = false;
7169 }
7170 }
7171 else
7172 {
7173 Disable(hWnd, B_PROXY_CONFIG);
7174 }
7175
7176 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PASSWORD)
7177 {
7178 bool b = true;
7179
7180 if (ok == false)
7181 {
7182 b = false;
7183 }
7184
7185 if (a->LinkMode == false && a->NatMode == false)
7186 {
7187 SetEnable(hWnd, B_CHANGE_PASSWORD, b);
7188 SetEnable(hWnd, S_CHANGE_PASSWORD, b);
7189 Show(hWnd, B_CHANGE_PASSWORD);
7190 Show(hWnd, S_CHANGE_PASSWORD);
7191 }
7192 else
7193 {
7194 Hide(hWnd, B_CHANGE_PASSWORD);
7195 Hide(hWnd, S_CHANGE_PASSWORD);
7196 }
7197 }
7198 else
7199 {
7200 Hide(hWnd, B_CHANGE_PASSWORD);
7201 Hide(hWnd, S_CHANGE_PASSWORD);
7202 }
7203
7204 if ((StrLen(a->ClientOption->DeviceName) == 0) && (a->LinkMode == false && a->NatMode == false))
7205 {
7206 ok = false;
7207 }
7208
7209 if (a->LinkMode || a->NatMode)
7210 {
7211 Disable(hWnd, L_VLAN);
7212 }
7213
7214 if (a->EditMode == false)
7215 {
7216 char tmp[MAX_SIZE];
7217 GetTxtA(hWnd, E_HOSTNAME, tmp, sizeof(tmp));
7218 Trim(tmp);
7219
7220 if (StartWith(tmp, "127.") || (StrCmpi(tmp, "localhost") == 0))
7221 {
7222 if (a->Flag1 == false)
7223 {
7224 a->Flag1 = true;
7225 a->ClientOption->UseEncrypt = a->ClientOption->UseCompress = false;
7226 a->ClientOption->MaxConnection = 1;
7227 }
7228 }
7229 }
7230
7231 a->ClientOption->HideStatusWindow = IsChecked(hWnd, R_HIDE);
7232 a->ClientOption->HideNicInfoWindow = IsChecked(hWnd, R_HIDE2);
7233
7234 if (locked)
7235 {
7236 SetEnable(hWnd, E_HOSTNAME, false);
7237 SetEnable(hWnd, C_PORT, false);
7238 SetEnable(hWnd, C_HUBNAME, false);
7239 SetEnable(hWnd, S_STATIC2, false);
7240 SetEnable(hWnd, S_STATIC3, false);
7241 SetEnable(hWnd, S_STATIC4, false);
7242 SetEnable(hWnd, S_STATIC5, false);
7243 SetEnable(hWnd, S_STATIC66, false);
7244 SetEnable(hWnd, S_STATIC7, false);
7245 SetEnable(hWnd, S_STATIC11, false);
7246 SetEnable(hWnd, R_CHECK_CERT, false);
7247 SetEnable(hWnd, B_TRUST, false);
7248 SetEnable(hWnd, B_SERVER_CERT, false);
7249 SetEnable(hWnd, B_VIEW_SERVER_CERT, false);
7250 SetEnable(hWnd, R_RETRY, false);
7251 SetEnable(hWnd, S_RETRY_NUM_1, false);
7252 SetEnable(hWnd, E_RETRY_NUM, false);
7253 SetEnable(hWnd, S_RETRY_NUM_2, false);
7254 SetEnable(hWnd, S_RETRY_SPAN_1, false);
7255 SetEnable(hWnd, E_RETRY_SPAN, false);
7256 SetEnable(hWnd, S_RETRY_SPAN_2, false);
7257 SetEnable(hWnd, R_INFINITE, false);
7258 }
7259
7260 SetEnable(hWnd, IDOK, ok);
7261 }
7262
7263 // Initialize the account editing dialog
CmEditAccountDlgInit(HWND hWnd,CM_ACCOUNT * a)7264 void CmEditAccountDlgInit(HWND hWnd, CM_ACCOUNT *a)
7265 {
7266 RPC_CLIENT_ENUM_VLAN v;
7267 UINT i;
7268 // Validate arguments
7269 if (hWnd == NULL || a == NULL)
7270 {
7271 return;
7272 }
7273
7274 if (a->LockMode)
7275 {
7276 SetText(hWnd, S_STATIC1, _UU("CM_EASY_ACCOUNT_WARNING"));
7277 }
7278
7279 // Connection settings name
7280 if (a->EditMode || a->NatMode)
7281 {
7282 Disable(hWnd, E_ACCOUNT_NAME);
7283 }
7284
7285 if (a->NatMode || a->LinkMode)
7286 {
7287 Hide(hWnd, R_HIDE);
7288 Hide(hWnd, R_HIDE2);
7289 }
7290
7291 Check(hWnd, R_HIDE, a->ClientOption->HideStatusWindow);
7292 Check(hWnd, R_HIDE2, a->ClientOption->HideNicInfoWindow);
7293
7294 if (a->NatMode)
7295 {
7296 Hide(hWnd, E_ACCOUNT_NAME);
7297 Hide(hWnd, S_ACCOUNT_NAME);
7298 }
7299
7300 if ((cm != NULL && cm->server_name != NULL) || a->LinkMode)
7301 {
7302 Hide(hWnd, B_IE);
7303 }
7304
7305 SetText(hWnd, E_ACCOUNT_NAME, a->ClientOption->AccountName);
7306
7307 // Host name
7308 SetTextA(hWnd, E_HOSTNAME, a->ClientOption->Hostname);
7309 StrCpy(a->old_server_name, sizeof(a->old_server_name), a->ClientOption->Hostname);
7310
7311 if (InStr(a->ClientOption->Hostname, "/tcp"))
7312 {
7313 Check(hWnd, R_DISABLE_NATT, true);
7314 }
7315 else
7316 {
7317 Check(hWnd, R_DISABLE_NATT, false);
7318 }
7319
7320 // Port number
7321 CbSetHeight(hWnd, C_PORT, 18);
7322 CbAddStr(hWnd, C_PORT, _UU("CM_PORT_1"), 0);
7323 CbAddStr(hWnd, C_PORT, _UU("CM_PORT_2"), 0);
7324 CbAddStr(hWnd, C_PORT, _UU("CM_PORT_3"), 0);
7325 CbAddStr(hWnd, C_PORT, _UU("CM_PORT_4"), 0);
7326 SetInt(hWnd, C_PORT, a->ClientOption->Port);
7327
7328 // Virtual HUB name
7329 CbSetHeight(hWnd, C_HUBNAME, 18);
7330 SetTextA(hWnd, C_HUBNAME, a->ClientOption->HubName);
7331
7332 // Type of proxy
7333 Check(hWnd, R_DIRECT_TCP, a->ClientOption->ProxyType == PROXY_DIRECT);
7334 Check(hWnd, R_HTTPS, a->ClientOption->ProxyType == PROXY_HTTP);
7335 Check(hWnd, R_SOCKS, a->ClientOption->ProxyType == PROXY_SOCKS);
7336
7337 // Verify the server certificate
7338 Check(hWnd, R_CHECK_CERT, a->CheckServerCert);
7339
7340 // LAN card list
7341 if (a->NatMode == false && a->LinkMode == false)
7342 {
7343 Zero(&v, sizeof(v));
7344 CcEnumVLan(cm->Client, &v);
7345 LvInit(hWnd, L_VLAN);
7346 LvInsertColumn(hWnd, L_VLAN, 0, L"DeviceName", 345);
7347 for (i = 0;i < v.NumItem;i++)
7348 {
7349 wchar_t tmp[MAX_SIZE];
7350 char str[MAX_SIZE];
7351 CmVLanNameToPrintName(str, sizeof(str), v.Items[i]->DeviceName);
7352 StrToUni(tmp, sizeof(tmp), str);
7353 LvInsert(hWnd, L_VLAN, ICO_NIC_ONLINE, NULL, 1, tmp);
7354 }
7355 // LvAutoSize(hWnd, L_VLAN);
7356
7357 if (v.NumItem == 1)
7358 {
7359 // If only one virtual LAN card exists, initially select it
7360 LvSelect(hWnd, L_VLAN, 0);
7361 }
7362
7363 CiFreeClientEnumVLan(&v);
7364 }
7365
7366 // Select the LAN card
7367 if (StrLen(a->ClientOption->DeviceName) != 0)
7368 {
7369 char str[MAX_SIZE];
7370 wchar_t tmp[MAX_SIZE];
7371 UINT index;
7372 CmVLanNameToPrintName(str, sizeof(str), a->ClientOption->DeviceName);
7373 StrToUni(tmp, sizeof(tmp), str);
7374 index = LvSearchStr(hWnd, L_VLAN, 0, tmp);
7375 if (index != INFINITE)
7376 {
7377 LvSelect(hWnd, L_VLAN, index);
7378 }
7379 }
7380
7381 // Authentication type
7382 CbSetHeight(hWnd, C_TYPE, 18);
7383 CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_0"), CLIENT_AUTHTYPE_ANONYMOUS);
7384 CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_1"), CLIENT_AUTHTYPE_PASSWORD);
7385 CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_2"), CLIENT_AUTHTYPE_PLAIN_PASSWORD);
7386
7387 if (a->HideClientCertAuth == false)
7388 {
7389 // Certificate authentication is not available when HideClientCertAuth is true
7390 CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_3"), CLIENT_AUTHTYPE_CERT);
7391 }
7392
7393 if (a->HideSecureAuth == false)
7394 {
7395 // Authentication using a smart card
7396 CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_4"), CLIENT_AUTHTYPE_SECURE);
7397 }
7398
7399 // Select an authentication
7400 CbSelect(hWnd, C_TYPE, a->ClientAuth->AuthType);
7401
7402 // User name
7403 SetTextA(hWnd, E_USERNAME, a->ClientAuth->Username);
7404
7405 // Password
7406 if (a->EditMode)
7407 {
7408 SetTextA(hWnd, E_PASSWORD, HIDDEN_PASSWORD);
7409 }
7410
7411 // Reconnection times
7412 if (a->ClientOption->NumRetry == 0)
7413 {
7414 Check(hWnd, R_RETRY, false);
7415 }
7416 else
7417 {
7418 Check(hWnd, R_RETRY, true);
7419 if (a->ClientOption->NumRetry == INFINITE)
7420 {
7421 Check(hWnd, R_INFINITE, true);
7422 }
7423 else
7424 {
7425 Check(hWnd, R_INFINITE, false);
7426 SetInt(hWnd, E_RETRY_NUM, a->ClientOption->NumRetry);
7427 }
7428 }
7429 SetIntEx(hWnd, E_RETRY_SPAN, a->ClientOption->RetryInterval);
7430
7431 Check(hWnd, R_NOTLS1, a->ClientOption->NoTls1);
7432
7433 // Title
7434 if (a->NatMode == false)
7435 {
7436 if (a->EditMode == false)
7437 {
7438 SetText(hWnd, 0, _UU("CM_ACCOUNT_TITLE_1"));
7439 FocusEx(hWnd, E_ACCOUNT_NAME);
7440 }
7441 else
7442 {
7443 SetText(hWnd, 0, _UU("CM_ACCOUNT_TITLE_2"));
7444 FormatText(hWnd, 0, a->ClientOption->AccountName);
7445 FocusEx(hWnd, E_HOSTNAME);
7446 }
7447 }
7448 else
7449 {
7450 SetText(hWnd, 0, _UU("NM_ACCOUNT_TITLE"));
7451 FocusEx(hWnd, E_HOSTNAME);
7452 }
7453
7454 if (a->LinkMode || a->NatMode)
7455 {
7456 Hide(hWnd, L_VLAN);
7457
7458 if (a->NatMode == false)
7459 {
7460 SetText(hWnd, S_VLAN_GROUP, _UU("SM_LINK_POLICY_GROUP"));
7461 Show(hWnd, S_POLICY_1);
7462 Show(hWnd, S_POLICY_2);
7463 Show(hWnd, B_POLICY);
7464 }
7465 else
7466 {
7467 Hide(hWnd, S_VLAN_GROUP);
7468 Show(hWnd, S_ROUTER_LOGO);
7469 }
7470 }
7471
7472 // Display update
7473 a->Inited = true;
7474 CmEditAccountDlgUpdate(hWnd, a);
7475 }
7476
7477 // Account editing dialog procedure
CmEditAccountDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)7478 UINT CmEditAccountDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
7479 {
7480 CM_ACCOUNT *a = (CM_ACCOUNT *)param;
7481 NMHDR *n;
7482 X *x;
7483 K *k;
7484 char tmp[MAX_PATH];
7485 bool no_update_natt_check = false;
7486 // Validate arguments
7487 if (hWnd == NULL)
7488 {
7489 return 0;
7490 }
7491
7492 switch (msg)
7493 {
7494 case WM_INITDIALOG:
7495 CmEditAccountDlgInit(hWnd, a);
7496 if (a->EditMode == false && a->LinkMode == false && a->NatMode == false)
7497 {
7498 SetTimer(hWnd, 1, 100, NULL);
7499 }
7500 break;
7501 case WM_TIMER:
7502 switch (wParam)
7503 {
7504 case 1:
7505 {
7506 CM_INTERNET_SETTING s;
7507
7508 KillTimer(hWnd, 1);
7509
7510 Zero(&s, sizeof(s));
7511 CmGetSystemInternetSetting(&s);
7512
7513 if (s.ProxyType != PROXY_DIRECT)
7514 {
7515 if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO,
7516 _UU("CM_WOULDYOULOAD_IE_PROXY"),
7517 s.ProxyHostName) == IDYES)
7518 {
7519 Command(hWnd, B_IE);
7520 }
7521 }
7522 }
7523 break;
7524 }
7525 break;
7526 case WM_COMMAND:
7527 switch (wParam)
7528 {
7529 case R_DISABLE_NATT:
7530 Zero(tmp, sizeof(tmp));
7531 GetTxtA(hWnd, E_HOSTNAME, tmp, sizeof(tmp));
7532
7533 if (IsChecked(hWnd, R_DISABLE_NATT))
7534 {
7535 if (InStr(tmp, "/tcp") == false)
7536 {
7537 Trim(tmp);
7538
7539 StrCat(tmp, sizeof(tmp), "/tcp");
7540
7541 SetTextA(hWnd, E_HOSTNAME, tmp);
7542 }
7543 }
7544 else
7545 {
7546 if (InStr(tmp, "/tcp"))
7547 {
7548 UINT i = SearchStrEx(tmp, "/tcp", 0, false);
7549
7550 if (i != INFINITE)
7551 {
7552 tmp[i] = 0;
7553
7554 Trim(tmp);
7555
7556 SetTextA(hWnd, E_HOSTNAME, tmp);
7557 }
7558 }
7559 }
7560
7561 CmEditAccountDlgStartEnumHub(hWnd, a);
7562 break;
7563 }
7564 switch (LOWORD(wParam))
7565 {
7566 case E_ACCOUNT_NAME:
7567 case E_HOSTNAME:
7568 case C_PORT:
7569 case C_HUBNAME:
7570 case R_DIRECT_TCP:
7571 case R_HTTPS:
7572 case R_SOCKS:
7573 case R_CHECK_CERT:
7574 case C_TYPE:
7575 case E_USERNAME:
7576 case E_PASSWORD:
7577 case R_RETRY:
7578 case E_RETRY_NUM:
7579 case E_RETRY_SPAN:
7580 case R_INFINITE:
7581 CmEditAccountDlgUpdate(hWnd, a);
7582 break;
7583 }
7584 switch (HIWORD(wParam))
7585 {
7586 case EN_KILLFOCUS:
7587 switch (LOWORD(wParam))
7588 {
7589 case E_HOSTNAME:
7590 CmEditAccountDlgStartEnumHub(hWnd, a);
7591 break;
7592 }
7593 break;
7594 case BN_KILLFOCUS:
7595 switch (LOWORD(wParam))
7596 {
7597 case R_DIRECT_TCP:
7598 case R_HTTPS:
7599 case R_SOCKS:
7600 CmEditAccountDlgStartEnumHub(hWnd, a);
7601 break;
7602 }
7603 break;
7604 case CBN_KILLFOCUS:
7605 switch (LOWORD(wParam))
7606 {
7607 case C_PORT:
7608 CmEditAccountDlgStartEnumHub(hWnd, a);
7609 break;
7610 }
7611 break;
7612 case BN_PUSHED:
7613 switch (LOWORD(wParam))
7614 {
7615 case R_DISABLE_NATT:
7616 break;
7617 }
7618 break;
7619 }
7620 if (HIWORD(wParam) == 0)
7621 {
7622 CmEditAccountDlgUpdate(hWnd, a);
7623 }
7624 switch (wParam)
7625 {
7626 case B_POLICY:
7627 // Policy
7628 if (a->LinkMode || a->NatMode)
7629 {
7630 a->Policy.Access = true;
7631 a->Policy.MonitorPort = false;
7632 SmPolicyDlgEx2(hWnd, &a->Policy, _UU("SM_LINK_POLICY_CAPTION"), true, a->PolicyVer);
7633 a->Policy.Access = true;
7634 a->Policy.MonitorPort = false;
7635 }
7636 break;
7637 case IDOK:
7638 CmEditAccountDlgUpdate(hWnd, a);
7639 CmEditAccountDlgOnOk(hWnd, a);
7640 break;
7641 case IDCANCEL:
7642 Close(hWnd);
7643 break;
7644 case B_PROXY_CONFIG:
7645 // Proxy Settings
7646 if (CmProxyDlg(hWnd, a->ClientOption))
7647 {
7648 UINT n = GetInt(hWnd, C_PORT);
7649 if (a->ClientOption->ProxyType == PROXY_HTTP &&
7650 n != 443)
7651 {
7652 // Show a warning message if the destination port is
7653 // other than 443 and HTTP proxy is used
7654 if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("CM_HTTP_PROXY_WARNING"), n) == IDYES)
7655 {
7656 // Change the port number to 443
7657 SetText(hWnd, C_PORT, _UU("CM_PORT_2"));
7658 }
7659 }
7660 CmEditAccountDlgStartEnumHub(hWnd, a);
7661 CmEditAccountDlgUpdate(hWnd, a);
7662 }
7663 break;
7664 case B_IE:
7665 // Use the IE settings
7666 if(cm->server_name == NULL)
7667 {
7668 CmProxyDlgUseForIE(hWnd, a->ClientOption);
7669 CmEditAccountDlgUpdate(hWnd, a);
7670 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PROXY_FROM_IE"));
7671 }
7672 break;
7673 case B_TRUST:
7674 // CA
7675 if (a->LinkMode == false)
7676 {
7677 CmTrustDlg(hWnd);
7678 }
7679 else
7680 {
7681 SmCaDlg(hWnd, a->Hub);
7682 }
7683 break;
7684 case B_SERVER_CERT:
7685 // Server certificate registration / delete
7686 if (a->ServerCert == NULL)
7687 {
7688 if (CmLoadXFromFileOrSecureCard(hWnd, &x))
7689 {
7690 a->ServerCert = x;
7691 CmEditAccountDlgUpdate(hWnd, a);
7692 }
7693 }
7694 else
7695 {
7696 if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_SERVER_CERT")) == IDYES)
7697 {
7698 FreeX(a->ServerCert);
7699 a->ServerCert = NULL;
7700 CmEditAccountDlgUpdate(hWnd, a);
7701 }
7702 }
7703 break;
7704 case B_VIEW_SERVER_CERT:
7705 // Show the server certificate
7706 if (a->ServerCert != NULL)
7707 {
7708 X *issuer = CmGetIssuer(a->ServerCert);
7709 CertDlg(hWnd, a->ServerCert, issuer, true);
7710 FreeX(issuer);
7711 }
7712 break;
7713 case B_VIEW_CLIENT_CERT:
7714 if (a->ClientAuth->AuthType != CLIENT_AUTHTYPE_SECURE)
7715 {
7716 // Show the client certificate
7717 if (a->ClientAuth->ClientX != NULL)
7718 {
7719 X *issuer = CmGetIssuer(a->ClientAuth->ClientX);
7720 CertDlg(hWnd, a->ClientAuth->ClientX, issuer, true);
7721 FreeX(issuer);
7722 }
7723 }
7724 else
7725 {
7726 UINT id;
7727 // Select the type of smart card
7728 SmSelectSecureId(hWnd);
7729 id = SmGetCurrentSecureIdFromReg();
7730 if (id != 0)
7731 {
7732 if (cm->server_name == NULL)
7733 {
7734 RPC_USE_SECURE t;
7735
7736 Zero(&t, sizeof(t));
7737 t.DeviceId = id;
7738 CcUseSecure(cm->Client, &t);
7739 }
7740 }
7741 CmEditAccountDlgUpdate(hWnd, a);
7742 }
7743 break;
7744 case B_REGIST_CLIENT_CERT:
7745 if (a->ClientAuth->AuthType != CLIENT_AUTHTYPE_SECURE)
7746 {
7747 // Client certificate registration / deletion
7748 if (a->ClientAuth->ClientX == NULL)
7749 {
7750 if (CmLoadXAndK(hWnd, &x, &k))
7751 {
7752 a->ClientAuth->ClientX = x;
7753 a->ClientAuth->ClientK = k;
7754 CmEditAccountDlgUpdate(hWnd, a);
7755 }
7756 }
7757 else
7758 {
7759 if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_CLIENT_CERT")) == IDYES)
7760 {
7761 FreeX(a->ClientAuth->ClientX);
7762 FreeK(a->ClientAuth->ClientK);
7763 a->ClientAuth->ClientX = NULL;
7764 a->ClientAuth->ClientK = NULL;
7765 CmEditAccountDlgUpdate(hWnd, a);
7766 }
7767 }
7768 }
7769 else
7770 {
7771 char cert[MAX_SECURE_DEVICE_FILE_LEN + 1], priv[MAX_SECURE_DEVICE_FILE_LEN + 1];
7772
7773 // Select a certificate in the smart card
7774 if (SmSelectKeyPairEx(hWnd, cert, sizeof(cert), priv, sizeof(priv), CmGetSecureBitmapId(a->ClientOption->Hostname)))
7775 {
7776 StrCpy(a->ClientAuth->SecurePublicCertName, sizeof(a->ClientAuth->SecurePublicCertName), cert);
7777 StrCpy(a->ClientAuth->SecurePrivateKeyName, sizeof(a->ClientAuth->SecurePrivateKeyName), priv);
7778 CmEditAccountDlgUpdate(hWnd, a);
7779 }
7780 }
7781 break;
7782 case B_DETAIL:
7783 // Advanced communication settings
7784 if (CmDetailDlg(hWnd, a))
7785 {
7786 CmEditAccountDlgUpdate(hWnd, a);
7787 }
7788 break;
7789 case B_CHANGE_PASSWORD:
7790 // Change the password
7791 CmChangePassword(hWnd, a->ClientOption, a->ClientOption->HubName,
7792 a->ClientAuth->Username);
7793 break;
7794 }
7795 break;
7796 case WM_CLOSE:
7797 EndDialog(hWnd, false);
7798 break;
7799 case WM_NOTIFY:
7800 n = (NMHDR *)lParam;
7801 switch (n->idFrom)
7802 {
7803 case L_VLAN:
7804 switch (n->code)
7805 {
7806 case LVN_ITEMCHANGED:
7807 CmEditAccountDlgUpdate(hWnd, a);
7808 break;
7809 }
7810 break;
7811 }
7812 break;
7813 }
7814
7815 return 0;
7816 }
7817
7818 // Update the proxy server settings
CmProxyDlgUpdate(HWND hWnd,CLIENT_OPTION * a)7819 void CmProxyDlgUpdate(HWND hWnd, CLIENT_OPTION *a)
7820 {
7821 bool ok = true;
7822 // Validate arguments
7823 if (hWnd == NULL || a == NULL)
7824 {
7825 return;
7826 }
7827
7828 if (IsEmpty(hWnd, E_HOSTNAME))
7829 {
7830 ok = false;
7831 }
7832 if (GetInt(hWnd, C_PORT) == 0)
7833 {
7834 ok = false;
7835 }
7836
7837 SetEnable(hWnd, IDOK, ok);
7838 }
7839
7840 // Proxy server settings dialog c
CmProxyDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)7841 UINT CmProxyDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
7842 {
7843 CLIENT_OPTION *a = (CLIENT_OPTION *)param;
7844 // Validate arguments
7845 if (hWnd == NULL)
7846 {
7847 return 0;
7848 }
7849
7850 switch (msg)
7851 {
7852 case WM_INITDIALOG:
7853 SetTextA(hWnd, E_HOSTNAME, a->ProxyName);
7854 CbSetHeight(hWnd, C_PORT, 18);
7855 CbAddStr(hWnd, C_PORT, L"8080", 0);
7856 CbAddStr(hWnd, C_PORT, L"1080", 0);
7857 CbAddStr(hWnd, C_PORT, L"80", 0);
7858 CbAddStr(hWnd, C_PORT, L"3128", 0);
7859 CbAddStr(hWnd, C_PORT, L"443", 0);
7860 CbAddStr(hWnd, C_PORT, L"9821", 0);
7861 CbAddStr(hWnd, C_PORT, L"9801", 0);
7862 SetIntEx(hWnd, C_PORT, a->ProxyPort);
7863 SetTextA(hWnd, E_USERNAME, a->ProxyUsername);
7864 SetTextA(hWnd, E_PASSWORD, a->ProxyPassword);
7865 if (a->ProxyPort == 0)
7866 {
7867 if (a->ProxyType == PROXY_HTTP)
7868 {
7869 SetInt(hWnd, C_PORT, 8080);
7870 }
7871 else
7872 {
7873 SetInt(hWnd, C_PORT, 1080);
7874 }
7875 }
7876 CmProxyDlgUpdate(hWnd, a);
7877 break;
7878 case WM_COMMAND:
7879 switch (LOWORD(wParam))
7880 {
7881 case E_HOSTNAME:
7882 case C_PORT:
7883 case E_USERNAME:
7884 case E_PASSWORD:
7885 CmProxyDlgUpdate(hWnd, a);
7886 break;
7887 }
7888
7889 switch (wParam)
7890 {
7891 case IDOK:
7892 GetTxtA(hWnd, E_HOSTNAME, a->ProxyName, sizeof(a->ProxyName));
7893 GetTxtA(hWnd, E_USERNAME, a->ProxyUsername, sizeof(a->ProxyUsername));
7894 GetTxtA(hWnd, E_PASSWORD, a->ProxyPassword, sizeof(a->ProxyPassword));
7895 a->ProxyPort = GetInt(hWnd, C_PORT);
7896 EndDialog(hWnd, true);
7897 break;
7898 case IDCANCEL:
7899 Close(hWnd);
7900 break;
7901 }
7902 break;
7903 case WM_CLOSE:
7904 EndDialog(hWnd, false);
7905 break;
7906 }
7907
7908 return 0;
7909 }
7910
7911 // Proxy server settings
CmProxyDlg(HWND hWnd,CLIENT_OPTION * a)7912 bool CmProxyDlg(HWND hWnd, CLIENT_OPTION *a)
7913 {
7914 // Validate arguments
7915 if (a == NULL)
7916 {
7917 return false;
7918 }
7919
7920 return Dialog(hWnd, D_CM_PROXY, CmProxyDlgProc, a);
7921 }
7922
7923 // Get issuer of the specified certificate if it is known
CmGetIssuer(X * x)7924 X *CmGetIssuer(X *x)
7925 {
7926 RPC_GET_ISSUER a;
7927 X *ret;
7928 // Validate arguments
7929 if (x == NULL)
7930 {
7931 return NULL;
7932 }
7933
7934 Zero(&a, sizeof(a));
7935 a.x = CloneX(x);
7936 if (CALLEX(cm->hMainWnd, CcGetIssuer(cm->Client, &a)) == 0)
7937 {
7938 ret = CloneX(a.issuer_x);
7939 }
7940 else
7941 {
7942 ret = NULL;
7943 }
7944
7945 CiFreeGetIssuer(&a);
7946
7947 return ret;
7948 }
7949
7950 // Initialize the dialog
CmLoadXFromFileOrSecureCardDlgInit(HWND hWnd,CM_LOADX * p)7951 void CmLoadXFromFileOrSecureCardDlgInit(HWND hWnd, CM_LOADX *p)
7952 {
7953 UINT current;
7954 // Validate arguments
7955 if (hWnd == NULL || p == NULL)
7956 {
7957 return;
7958 }
7959
7960 current = MsRegReadInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "CertLoadSource");
7961
7962 Check(hWnd, R_FROM_FILE, current == 0);
7963 Check(hWnd, R_FROM_SECURE, current != 0);
7964
7965 SetFont(hWnd, S_INFO, Font(0, true));
7966
7967 CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
7968 }
7969
7970 // Update the dialog control
CmLoadXFromFileOrSecureCardDlgUpdate(HWND hWnd,CM_LOADX * p)7971 void CmLoadXFromFileOrSecureCardDlgUpdate(HWND hWnd, CM_LOADX *p)
7972 {
7973 SECURE_DEVICE *dev;
7974 wchar_t tmp[MAX_SIZE];
7975 bool ok = true;
7976 // Validate arguments
7977 if (hWnd == NULL || p == NULL)
7978 {
7979 return;
7980 }
7981
7982 dev = GetSecureDevice(SmGetCurrentSecureIdFromReg());
7983 if (dev == NULL)
7984 {
7985 UniStrCpy(tmp, sizeof(tmp), _UU("SEC_CURRENT_NO_DEVICE"));
7986 }
7987 else
7988 {
7989 UniFormat(tmp, sizeof(tmp), _UU("SEC_CURRENT_DEVICE"), dev->DeviceName);
7990 }
7991
7992 SetText(hWnd, S_INFO, tmp);
7993
7994 if (IsChecked(hWnd, R_FROM_SECURE))
7995 {
7996 if (dev == NULL)
7997 {
7998 ok = false;
7999 }
8000 }
8001
8002 SetEnable(hWnd, IDOK, ok);
8003 SetEnable(hWnd, B_SELECT, IsChecked(hWnd, R_FROM_SECURE));
8004 SetEnable(hWnd, S_CERT, IsChecked(hWnd, R_FROM_SECURE));
8005 SetEnable(hWnd, S_FILE, IsChecked(hWnd, R_FROM_FILE));
8006 }
8007
8008 // Certificate reading selection dialog procedure
CmLoadXFromFileOrSecureCardDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)8009 UINT CmLoadXFromFileOrSecureCardDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
8010 {
8011 CM_LOADX *p = (CM_LOADX *)param;
8012 X *x;
8013 UINT current;
8014 // Validate arguments
8015 if (hWnd == NULL)
8016 {
8017 return 0;
8018 }
8019
8020 switch (msg)
8021 {
8022 case WM_INITDIALOG:
8023 CmLoadXFromFileOrSecureCardDlgInit(hWnd, p);
8024 break;
8025
8026 case WM_COMMAND:
8027 switch (wParam)
8028 {
8029 case IDOK:
8030 current = (IsChecked(hWnd, R_FROM_FILE)) ? 0 : 1;
8031 MsRegWriteInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "CertLoadSource", current);
8032
8033 if (current == 0)
8034 {
8035 // From file
8036 if (CmLoadX(hWnd, &x))
8037 {
8038 p->x = x;
8039 EndDialog(hWnd, true);
8040 }
8041 }
8042 else
8043 {
8044 // From the smart card
8045 char name[MAX_SIZE];
8046
8047 // Select the certificate name in the card
8048 if (SmSelectKeyPair(hWnd, name, sizeof(name), NULL, 0))
8049 {
8050 // Read
8051 WINUI_SECURE_BATCH batch[] =
8052 {
8053 {WINUI_SECURE_READ_CERT, name, true, NULL, NULL, NULL, NULL, NULL, NULL},
8054 };
8055
8056 // Do reading
8057 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), SmGetCurrentSecureIdFromReg(), 0))
8058 {
8059 // Success
8060 p->x = batch[0].OutputX;
8061 EndDialog(hWnd, true);
8062 }
8063 }
8064 }
8065 break;
8066
8067 case IDCANCEL:
8068 Close(hWnd);
8069 break;
8070
8071 case R_FROM_FILE:
8072 CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
8073 break;
8074
8075 case R_FROM_SECURE:
8076 CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
8077 break;
8078
8079 case B_SELECT:
8080 SmSelectSecureId(hWnd);
8081 CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);
8082 break;
8083 }
8084 break;
8085
8086 case WM_CLOSE:
8087 EndDialog(hWnd, false);
8088 break;
8089 }
8090
8091 return 0;
8092 }
8093
8094 // Read certificate from a file or a smart card
CmLoadXFromFileOrSecureCard(HWND hWnd,X ** x)8095 bool CmLoadXFromFileOrSecureCard(HWND hWnd, X **x)
8096 {
8097 CM_LOADX p;
8098 // Validate arguments
8099 if (x == NULL)
8100 {
8101 return false;
8102 }
8103
8104 Zero(&p, sizeof(p));
8105 if (Dialog(hWnd, D_CM_LOAD_X, CmLoadXFromFileOrSecureCardDlgProc, &p) == false)
8106 {
8107 return false;
8108 }
8109
8110 *x = p.x;
8111
8112 return true;
8113 }
8114
8115 // Read the certificate
CmLoadX(HWND hWnd,X ** x)8116 bool CmLoadX(HWND hWnd, X **x)
8117 {
8118 return CmLoadXEx(hWnd, x, NULL, 0);
8119 }
CmLoadXEx(HWND hWnd,X ** x,char * filename,UINT size)8120 bool CmLoadXEx(HWND hWnd, X **x, char *filename, UINT size)
8121 {
8122 wchar_t *filename_w = CopyStrToUni(filename);
8123 bool ret;
8124
8125 ret = CmLoadXExW(hWnd, x, filename_w, size);
8126
8127 Free(filename_w);
8128
8129 return ret;
8130 }
CmLoadXExW(HWND hWnd,X ** x,wchar_t * filename,UINT size)8131 bool CmLoadXExW(HWND hWnd, X **x, wchar_t *filename, UINT size)
8132 {
8133 wchar_t *s;
8134 bool is_p12;
8135 wchar_t tmp[MAX_SIZE];
8136 K *k;
8137 // Validate arguments
8138 if (x == NULL)
8139 {
8140 return false;
8141 }
8142
8143 // Read the certificate
8144 s = OpenDlg(hWnd, _UU("DLG_CERT_OR_P12_FILTER"), _UU("DLG_OPEN_CERT"));
8145 if (s == NULL)
8146 {
8147 return false;
8148 }
8149 UniStrCpy(tmp, sizeof(tmp), s);
8150 if (filename != NULL)
8151 {
8152 UniStrCpy(filename, size, tmp);
8153 }
8154 Free(s);
8155 if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))
8156 {
8157 is_p12 = true;
8158 }
8159 else
8160 {
8161 is_p12 = false;
8162 }
8163
8164 if (is_p12)
8165 {
8166 // Processing of PKCS#12
8167 BUF *b = ReadDumpW(tmp);
8168 P12 *p12;
8169 if (b == NULL)
8170 {
8171 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
8172 return false;
8173 }
8174 p12 = BufToP12(b);
8175 if (p12 == NULL)
8176 {
8177 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
8178 FreeBuf(b);
8179 return false;
8180 }
8181 if (IsEncryptedP12(p12) == false)
8182 {
8183 if (ParseP12(p12, x, &k, NULL) == false)
8184 {
8185 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
8186 FreeP12(p12);
8187 FreeBuf(b);
8188 return false;
8189 }
8190 }
8191 else
8192 {
8193 char password[MAX_SIZE];
8194 if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)
8195 {
8196 FreeP12(p12);
8197 FreeBuf(b);
8198 return false;
8199 }
8200 else
8201 {
8202 if (ParseP12(p12, x, &k, password) == false)
8203 {
8204 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
8205 FreeP12(p12);
8206 FreeBuf(b);
8207 return false;
8208 }
8209 }
8210 }
8211 FreeP12(p12);
8212 FreeBuf(b);
8213 FreeK(k);
8214 return true;
8215 }
8216 else
8217 {
8218 // Processing of X509
8219 BUF *b = ReadDumpW(tmp);
8220 X *x509;
8221 if (b == NULL)
8222 {
8223 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
8224 return false;
8225 }
8226
8227 x509 = BufToX(b, IsBase64(b));
8228 FreeBuf(b);
8229 if (x509 == NULL)
8230 {
8231 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_X509_W"), tmp);
8232 return false;
8233 }
8234
8235 *x = x509;
8236 return true;
8237 }
8238 }
8239
8240 // Read the secret key
CmLoadK(HWND hWnd,K ** k)8241 bool CmLoadK(HWND hWnd, K **k)
8242 {
8243 return CmLoadKEx(hWnd, k, NULL, 0);
8244 }
CmLoadKEx(HWND hWnd,K ** k,char * filename,UINT size)8245 bool CmLoadKEx(HWND hWnd, K **k, char *filename, UINT size)
8246 {
8247 wchar_t *filename_w = CopyStrToUni(filename);
8248 bool ret;
8249
8250 ret = CmLoadKExW(hWnd, k, filename_w, size);
8251
8252 Free(filename_w);
8253
8254 return ret;
8255 }
CmLoadKExW(HWND hWnd,K ** k,wchar_t * filename,UINT size)8256 bool CmLoadKExW(HWND hWnd, K **k, wchar_t *filename, UINT size)
8257 {
8258 wchar_t *s;
8259 bool is_p12;
8260 wchar_t tmp[MAX_SIZE];
8261 // Validate arguments
8262 if (k == NULL)
8263 {
8264 return false;
8265 }
8266
8267 // Read the certificate
8268 s = OpenDlg(hWnd, _UU("DLG_KEY_OR_P12_FILTER"), _UU("DLG_OPEN_KEY"));
8269 if (s == NULL)
8270 {
8271 return false;
8272 }
8273 UniStrCpy(tmp, sizeof(tmp), s);
8274 Free(s);
8275 if (filename != NULL)
8276 {
8277 UniStrCpy(filename, size, tmp);
8278 }
8279 if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))
8280 {
8281 is_p12 = true;
8282 }
8283 else
8284 {
8285 is_p12 = false;
8286 }
8287
8288 if (is_p12)
8289 {
8290 // Processing of PKCS#12
8291 BUF *b = ReadDumpW(tmp);
8292 P12 *p12;
8293 if (b == NULL)
8294 {
8295 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
8296 return false;
8297 }
8298 p12 = BufToP12(b);
8299 if (p12 == NULL)
8300 {
8301 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
8302 FreeBuf(b);
8303 return false;
8304 }
8305 if (IsEncryptedP12(p12) == false)
8306 {
8307 X *x;
8308 if (ParseP12(p12, &x, k, NULL) == false)
8309 {
8310 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
8311 FreeP12(p12);
8312 FreeBuf(b);
8313 return false;
8314 }
8315
8316 FreeX(x);
8317 }
8318 else
8319 {
8320 char password[MAX_SIZE];
8321 if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)
8322 {
8323 FreeP12(p12);
8324 FreeBuf(b);
8325 return false;
8326 }
8327 else
8328 {
8329 X *x;
8330 if (ParseP12(p12, &x, k, password) == false)
8331 {
8332 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
8333 FreeP12(p12);
8334 FreeBuf(b);
8335 return false;
8336 }
8337
8338 FreeX(x);
8339 }
8340 }
8341 FreeP12(p12);
8342 FreeBuf(b);
8343 return true;
8344 }
8345 else
8346 {
8347 // Processing of private key
8348 BUF *b = ReadDumpW(tmp);
8349 K *key;
8350 if (b == NULL)
8351 {
8352 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
8353 return false;
8354 }
8355
8356 if (IsEncryptedK(b, true) == false)
8357 {
8358 key = BufToK(b, true, IsBase64(b), NULL);
8359 }
8360 else
8361 {
8362 char pass[MAX_SIZE];
8363 if (PassphraseDlg(hWnd, pass, sizeof(pass), b, false) == false)
8364 {
8365 FreeBuf(b);
8366 return false;
8367 }
8368 key = BufToK(b, true, IsBase64(b), pass);
8369 }
8370
8371 if (key == NULL)
8372 {
8373 FreeBuf(b);
8374 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_KEY_W"), tmp);
8375 return false;
8376 }
8377
8378 FreeBuf(b);
8379 *k = key;
8380 return true;
8381 }
8382 }
8383
8384 // Read a set of certificate and private key
CmLoadXAndK(HWND hWnd,X ** x,K ** k)8385 bool CmLoadXAndK(HWND hWnd, X **x, K **k)
8386 {
8387 wchar_t *s;
8388 bool is_p12;
8389 wchar_t tmp[MAX_SIZE];
8390 // Validate arguments
8391 if (x == NULL || k == NULL)
8392 {
8393 return false;
8394 }
8395 START_FIRST:
8396
8397 // Read the certificate
8398 s = OpenDlg(hWnd, _UU("DLG_CERT_OR_P12_FILTER"), _UU("DLG_OPEN_CERT"));
8399 if (s == NULL)
8400 {
8401 return false;
8402 }
8403 UniStrCpy(tmp, sizeof(tmp), s);
8404 Free(s);
8405 if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))
8406 {
8407 is_p12 = true;
8408 }
8409 else
8410 {
8411 is_p12 = false;
8412 }
8413
8414 if (is_p12)
8415 {
8416 // Processing of PKCS#12
8417 BUF *b = ReadDumpW(tmp);
8418 P12 *p12;
8419 if (b == NULL)
8420 {
8421 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
8422 return false;
8423 }
8424 p12 = BufToP12(b);
8425 if (p12 == NULL)
8426 {
8427 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
8428 FreeBuf(b);
8429 return false;
8430 }
8431 if (IsEncryptedP12(p12) == false)
8432 {
8433 if (ParseP12(p12, x, k, NULL) == false)
8434 {
8435 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
8436 FreeP12(p12);
8437 FreeBuf(b);
8438 return false;
8439 }
8440 }
8441 else
8442 {
8443 char password[MAX_SIZE];
8444 if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)
8445 {
8446 FreeP12(p12);
8447 FreeBuf(b);
8448 return false;
8449 }
8450 else
8451 {
8452 if (ParseP12(p12, x, k, password) == false)
8453 {
8454 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
8455 FreeP12(p12);
8456 FreeBuf(b);
8457 return false;
8458 }
8459 }
8460 }
8461 if (CheckXandK(*x, *k) == false)
8462 {
8463 FreeX(*x);
8464 FreeK(*k);
8465 FreeP12(p12);
8466 FreeBuf(b);
8467 if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)
8468 {
8469 goto START_FIRST;
8470 }
8471 return false;
8472 }
8473 FreeP12(p12);
8474 FreeBuf(b);
8475 return true;
8476 }
8477 else
8478 {
8479 // Processing of X509
8480 BUF *b = ReadDumpW(tmp);
8481 X *x509;
8482 K *key;
8483 if (b == NULL)
8484 {
8485 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
8486 return false;
8487 }
8488
8489 x509 = BufToX(b, IsBase64(b));
8490 FreeBuf(b);
8491 if (x509 == NULL)
8492 {
8493 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_X509_W"), tmp);
8494 return false;
8495 }
8496
8497 // Read the secret key
8498 s = OpenDlg(hWnd, _UU("DLG_KEY_FILTER"), _UU("DLG_OPEN_KEY_WITH_CERT"));
8499 if (s == NULL)
8500 {
8501 FreeX(x509);
8502 return false;
8503 }
8504 UniStrCpy(tmp, sizeof(tmp), s);
8505 Free(s);
8506
8507 b = ReadDumpW(tmp);
8508 if (b == NULL)
8509 {
8510 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
8511 FreeX(x509);
8512 return false;
8513 }
8514
8515 if (IsEncryptedK(b, true) == false)
8516 {
8517 key = BufToK(b, true, IsBase64(b), NULL);
8518 }
8519 else
8520 {
8521 char pass[MAX_SIZE];
8522 if (PassphraseDlg(hWnd, pass, sizeof(pass), b, false) == false)
8523 {
8524 FreeBuf(b);
8525 FreeX(x509);
8526 return false;
8527 }
8528 key = BufToK(b, true, IsBase64(b), pass);
8529 }
8530
8531 if (key == NULL)
8532 {
8533 FreeBuf(b);
8534 FreeX(x509);
8535 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_KEY_W"), tmp);
8536 return false;
8537 }
8538
8539 if (CheckXandK(x509, key) == false)
8540 {
8541 FreeBuf(b);
8542 FreeX(x509);
8543 FreeK(key);
8544 if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)
8545 {
8546 goto START_FIRST;
8547 }
8548 return false;
8549 }
8550
8551 FreeBuf(b);
8552 *x = x509;
8553 *k = key;
8554 return true;
8555 }
8556 }
8557
8558 // Virtual HUB enumeration start
CmEditAccountDlgStartEnumHub(HWND hWnd,CM_ACCOUNT * a)8559 void CmEditAccountDlgStartEnumHub(HWND hWnd, CM_ACCOUNT *a)
8560 {
8561 char server_name[MAX_HOST_NAME_LEN + 1];
8562 UINT old_proxy_type;
8563 // Validate arguments
8564 if (hWnd == NULL || a == NULL)
8565 {
8566 return;
8567 }
8568
8569
8570 if (StrLen(a->ClientOption->Hostname) == 0)
8571 {
8572 return;
8573 }
8574 if (a->ClientOption->Port == 0)
8575 {
8576 return;
8577 }
8578 if (a->ClientOption->ProxyType != PROXY_DIRECT &&
8579 (StrLen(a->ClientOption->ProxyName) == 0 ||
8580 a->ClientOption->ProxyPort == 0))
8581 {
8582 return;
8583 }
8584
8585 GetTxtA(hWnd, E_HOSTNAME, server_name, sizeof(server_name));
8586
8587 if (StrCmpi(server_name, a->old_server_name) == 0)
8588 {
8589 if (CbNum(hWnd, C_HUBNAME) != 0)
8590 {
8591 return;
8592 }
8593 }
8594 else
8595 {
8596 StrCpy(a->old_server_name, sizeof(a->old_server_name), server_name);
8597 CbReset(hWnd, C_HUBNAME);
8598 }
8599
8600 old_proxy_type = a->ClientOption->ProxyType;
8601
8602 if (IsChecked(hWnd, R_DIRECT_TCP))
8603 {
8604 a->ClientOption->ProxyType = PROXY_DIRECT;
8605 }
8606 if (IsChecked(hWnd, R_HTTPS))
8607 {
8608 a->ClientOption->ProxyType = PROXY_HTTP;
8609 }
8610 if (IsChecked(hWnd, R_SOCKS))
8611 {
8612 a->ClientOption->ProxyType = PROXY_SOCKS;
8613 }
8614
8615 CmEnumHubStart(hWnd, a->ClientOption);
8616
8617 a->ClientOption->ProxyType = old_proxy_type;
8618 }
8619
8620 // [OK] button
CmEditAccountDlgOnOk(HWND hWnd,CM_ACCOUNT * a)8621 void CmEditAccountDlgOnOk(HWND hWnd, CM_ACCOUNT *a)
8622 {
8623 RPC_CLIENT_CREATE_ACCOUNT c;
8624 bool b;
8625 // Validate arguments
8626 if (hWnd == NULL || a == NULL)
8627 {
8628 return;
8629 }
8630 if (a->ClientOption->NumRetry != 0 && a->ClientOption->RetryInterval < 5)
8631 {
8632 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_RETRY_INTERVAL_ERROR"));
8633 FocusEx(hWnd, E_RETRY_SPAN);
8634 return;
8635 }
8636
8637 CmEditAccountDlgUpdate(hWnd, a);
8638
8639 if (a->LinkMode == false && a->NatMode == false)
8640 {
8641 // Save the account
8642 Zero(&c, sizeof(c));
8643 c.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
8644 Copy(c.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
8645 c.ClientAuth = CopyClientAuth(a->ClientAuth);
8646 c.CheckServerCert = a->CheckServerCert;
8647 if (a->ServerCert != NULL)
8648 {
8649 c.ServerCert = CloneX(a->ServerCert);
8650 }
8651 c.StartupAccount = a->Startup;
8652
8653 if (a->EditMode == false)
8654 {
8655 b = CALL(hWnd, CcCreateAccount(cm->Client, &c));
8656 }
8657 else
8658 {
8659 b = CALL(hWnd, CcSetAccount(cm->Client, &c));
8660 }
8661
8662 CiFreeClientCreateAccount(&c);
8663
8664 // Check whether this account is currently running
8665 if (b)
8666 {
8667 RPC_CLIENT_GET_CONNECTION_STATUS st;
8668 Zero(&st, sizeof(st));
8669 UniStrCpy(st.AccountName, sizeof(st.AccountName), a->ClientOption->AccountName);
8670 if (CALL(hWnd, CcGetAccountStatus(cm->Client, &st)))
8671 {
8672 if (st.Active)
8673 {
8674 MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_CURRENT_ACTIVE"),
8675 st.AccountName);
8676 }
8677 }
8678 }
8679
8680 if (b)
8681 {
8682 EndDialog(hWnd, true);
8683 }
8684 }
8685 else
8686 {
8687 if (a->LinkMode)
8688 {
8689 // Link mode
8690 RPC_CREATE_LINK t;
8691
8692 Zero(&t, sizeof(t));
8693 StrCpy(t.HubName, sizeof(t.HubName), a->Hub->HubName);
8694 t.Online = a->OnlineFlag;
8695 Copy(&t.Policy, &a->Policy, sizeof(POLICY));
8696 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
8697 Copy(t.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
8698 t.ClientAuth = CopyClientAuth(a->ClientAuth);
8699 t.CheckServerCert = a->CheckServerCert;
8700 t.ServerCert = CloneX(a->ServerCert);
8701
8702 // Save the settings for cascade connection
8703 if (a->EditMode)
8704 {
8705 if (CALL(hWnd, ScSetLink(a->Hub->Rpc, &t)))
8706 {
8707 if (a->OnlineFlag)
8708 {
8709 MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("SM_LINK_SAVE_ONLINE"), a->ClientOption->AccountName);
8710 }
8711 EndDialog(hWnd, true);
8712 }
8713 }
8714 else
8715 {
8716 if (CALL(hWnd, ScCreateLink(a->Hub->Rpc, &t)))
8717 {
8718 if (a->Link_ConnectNow)
8719 {
8720 RPC_LINK tt;
8721
8722 Zero(&tt, sizeof(tt));
8723 UniStrCpy(tt.AccountName, sizeof(tt.AccountName), a->ClientOption->AccountName);
8724 StrCpy(tt.HubName, sizeof(tt.HubName), a->Hub->HubName);
8725
8726 CALL(hWnd, ScSetLinkOnline(a->Hub->Rpc, &tt));
8727 }
8728 EndDialog(hWnd, true);
8729 }
8730 }
8731
8732 FreeRpcCreateLink(&t);
8733 }
8734 else
8735 {
8736 // NAT mode
8737 RPC_CREATE_LINK t;
8738 Zero(&t, sizeof(t));
8739
8740 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
8741 Copy(t.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
8742 t.ClientAuth = CopyClientAuth(a->ClientAuth);
8743
8744 if (CALL(hWnd, NcSetClientConfig(a->Rpc, &t)))
8745 {
8746 EndDialog(hWnd, true);
8747 }
8748
8749 FreeRpcCreateLink(&t);
8750 }
8751 }
8752 }
8753
8754 // Show the account editing dialog
CmEditAccountDlg(HWND hWnd,CM_ACCOUNT * a)8755 bool CmEditAccountDlg(HWND hWnd, CM_ACCOUNT *a)
8756 {
8757 // Validate arguments
8758 if (hWnd == NULL || a == NULL)
8759 {
8760 return false;
8761 }
8762
8763 return Dialog(hWnd, D_CM_ACCOUNT, CmEditAccountDlgProc, a);
8764 }
8765
8766 // Edit the account
CmEditAccount(HWND hWnd,wchar_t * account_name)8767 void CmEditAccount(HWND hWnd, wchar_t *account_name)
8768 {
8769 CM_ACCOUNT *a;
8770 // Validate arguments
8771 if (hWnd == NULL || account_name == NULL)
8772 {
8773 return;
8774 }
8775
8776 a = CmGetExistAccountObject(hWnd, account_name);
8777 if (a == NULL)
8778 {
8779 return;
8780 }
8781
8782 CmVoice("input_config");
8783 if (CmEditAccountDlg(hWnd, a))
8784 {
8785 CmVoice("set_config");
8786 }
8787
8788 CmFreeAccountObject(hWnd, a);
8789 }
8790
8791 // Create an account
CmNewAccount(HWND hWnd)8792 void CmNewAccount(HWND hWnd)
8793 {
8794 CM_ACCOUNT *a;
8795 RPC_CLIENT_ENUM_VLAN t;
8796 UINT num_vlan = 0;
8797 // Validate arguments
8798 if (hWnd == NULL)
8799 {
8800 return;
8801 }
8802
8803 if (IsEnable(hWnd, 0) == false)
8804 {
8805 return;
8806 }
8807
8808 Zero(&t, sizeof(t));
8809 if (CcEnumVLan(cm->Client, &t) == ERR_NO_ERROR)
8810 {
8811 num_vlan = t.NumItem;
8812
8813 CiFreeClientEnumVLan(&t);
8814 }
8815
8816 if (num_vlan == 0)
8817 {
8818 if (MsgBox(hWnd, MB_ICONINFORMATION | MB_YESNO, _UU("CM_NO_VLAN")) == IDNO)
8819 {
8820 return;
8821 }
8822 else
8823 {
8824 if (cm->server_name == NULL || cm->Client->Unix)
8825 {
8826 Command(hWnd, CMD_NEW_VLAN);
8827 return;
8828 }
8829 else
8830 {
8831 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_VLAN_REMOTE_ERROR"));
8832 }
8833 return;
8834 }
8835 }
8836
8837 a = CmCreateNewAccountObject(hWnd);
8838 if (a == NULL)
8839 {
8840 return;
8841 }
8842
8843 CmVoice("input_config");
8844 if (CmEditAccountDlg(hWnd, a))
8845 {
8846 CmVoice("new_config");
8847 }
8848
8849 CmFreeAccountObject(hWnd, a);
8850 }
8851
8852 // Release the account object
CmFreeAccountObject(HWND hWnd,CM_ACCOUNT * a)8853 void CmFreeAccountObject(HWND hWnd, CM_ACCOUNT *a)
8854 {
8855 // Validate arguments
8856 if (hWnd == NULL || a == NULL)
8857 {
8858 return;
8859 }
8860
8861 Free(a->ClientOption);
8862 CiFreeClientAuth(a->ClientAuth);
8863 if (a->ServerCert != NULL)
8864 {
8865 FreeX(a->ServerCert);
8866 }
8867 Free(a);
8868 }
8869
8870 // Get an existing account object
CmGetExistAccountObject(HWND hWnd,wchar_t * account_name)8871 CM_ACCOUNT *CmGetExistAccountObject(HWND hWnd, wchar_t *account_name)
8872 {
8873 RPC_CLIENT_GET_ACCOUNT c;
8874 CM_ACCOUNT *a;
8875 // Validate arguments
8876 if (hWnd == NULL)
8877 {
8878 return NULL;
8879 }
8880
8881 Zero(&c, sizeof(c));
8882 UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);
8883 if (CALL(hWnd, CcGetAccount(cm->Client, &c)) == false)
8884 {
8885 return NULL;
8886 }
8887
8888 a = ZeroMalloc(sizeof(CM_ACCOUNT));
8889 a->EditMode = true;
8890 a->CheckServerCert = c.CheckServerCert;
8891 a->Startup = c.StartupAccount;
8892 if (c.ServerCert != NULL)
8893 {
8894 a->ServerCert = CloneX(c.ServerCert);
8895 }
8896 a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
8897 Copy(a->ClientOption, c.ClientOption, sizeof(CLIENT_OPTION));
8898 a->ClientAuth = CopyClientAuth(c.ClientAuth);
8899 Copy(a->ShortcutKey, c.ShortcutKey, SHA1_SIZE);
8900 CiFreeClientGetAccount(&c);
8901
8902 a->LockMode = cm->CmSetting.LockMode;
8903
8904 return a;
8905 }
8906
8907 // Create a new account object
CmCreateNewAccountObject(HWND hWnd)8908 CM_ACCOUNT *CmCreateNewAccountObject(HWND hWnd)
8909 {
8910 CM_ACCOUNT *a;
8911 // Validate arguments
8912 if (hWnd == NULL)
8913 {
8914 return NULL;
8915 }
8916
8917 a = ZeroMalloc(sizeof(CM_ACCOUNT));
8918 a->EditMode = false;
8919 a->CheckServerCert = false;
8920 a->Startup = false;
8921 a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
8922
8923 // Initialize the client options
8924 CmGenerateNewAccountName(hWnd, a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName));
8925 a->ClientOption->Port = 443; // Default port number
8926 a->ClientOption->NumRetry = INFINITE;
8927 a->ClientOption->RetryInterval = 15;
8928 a->ClientOption->MaxConnection = 1;
8929 a->ClientOption->HalfConnection = false;
8930 a->ClientOption->UseEncrypt = true;
8931 a->ClientOption->AdditionalConnectionInterval = 1;
8932
8933 if (cm->Client->Unix)
8934 {
8935 a->ClientOption->NoRoutingTracking = true;
8936 }
8937
8938 a->ClientAuth = ZeroMalloc(sizeof(CLIENT_AUTH));
8939
8940 // Password authentication
8941 a->ClientAuth->AuthType = CLIENT_AUTHTYPE_PASSWORD;
8942
8943 return a;
8944 }
8945
8946 // Create an imported account name
CmGenerateImportName(HWND hWnd,wchar_t * name,UINT size,wchar_t * old_name)8947 void CmGenerateImportName(HWND hWnd, wchar_t *name, UINT size, wchar_t *old_name)
8948 {
8949 UINT i;
8950 // Validate arguments
8951 if (name == NULL || hWnd == NULL)
8952 {
8953 return;
8954 }
8955
8956 for (i = 1;;i++)
8957 {
8958 wchar_t tmp[MAX_SIZE];
8959 if (i == 1)
8960 {
8961 UniFormat(tmp, sizeof(tmp), _UU("CM_IMPORT_NAME_1"), old_name);
8962 }
8963 else
8964 {
8965 UniFormat(tmp, sizeof(tmp), _UU("CM_IMPORT_NAME_2"), old_name, i);
8966 }
8967
8968 if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)
8969 {
8970 UniStrCpy(name, size, tmp);
8971 return;
8972 }
8973 }
8974 }
8975
8976 // Create a copy name
CmGenerateCopyName(HWND hWnd,wchar_t * name,UINT size,wchar_t * old_name)8977 void CmGenerateCopyName(HWND hWnd, wchar_t *name, UINT size, wchar_t *old_name)
8978 {
8979 UINT i;
8980 // Validate arguments
8981 if (name == NULL || hWnd == NULL)
8982 {
8983 return;
8984 }
8985
8986 for (i = 1;;i++)
8987 {
8988 wchar_t tmp[MAX_SIZE];
8989 if (i == 1)
8990 {
8991 UniFormat(tmp, sizeof(tmp), _UU("CM_COPY_NAME_1"), old_name);
8992 }
8993 else
8994 {
8995 UniFormat(tmp, sizeof(tmp), _UU("CM_COPY_NAME_2"), i, old_name);
8996 }
8997
8998 if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)
8999 {
9000 UniStrCpy(name, size, tmp);
9001 return;
9002 }
9003 }
9004 }
9005
9006 // Create a new account name
CmGenerateNewAccountName(HWND hWnd,wchar_t * name,UINT size)9007 void CmGenerateNewAccountName(HWND hWnd, wchar_t *name, UINT size)
9008 {
9009 UINT i;
9010 // Validate arguments
9011 if (name == NULL || hWnd == NULL)
9012 {
9013 return;
9014 }
9015
9016 for (i = 1;;i++)
9017 {
9018 wchar_t tmp[MAX_SIZE];
9019 if (i == 1)
9020 {
9021 UniFormat(tmp, sizeof(tmp), _UU("CM_NEW_ACCOUNT_NAME_1"));
9022 }
9023 else
9024 {
9025 UniFormat(tmp, sizeof(tmp), _UU("CM_NEW_ACCOUNT_NAME_2"), i);
9026 }
9027
9028 if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)
9029 {
9030 UniStrCpy(name, size, tmp);
9031 return;
9032 }
9033 }
9034 }
9035
9036 // Show the policy list
CmPolicyDlgPrint(HWND hWnd,CM_POLICY * p)9037 void CmPolicyDlgPrint(HWND hWnd, CM_POLICY *p)
9038 {
9039 CmPolicyDlgPrintEx(hWnd, p, false);
9040 }
CmPolicyDlgPrintEx(HWND hWnd,CM_POLICY * p,bool cascade_mode)9041 void CmPolicyDlgPrintEx(HWND hWnd, CM_POLICY *p, bool cascade_mode)
9042 {
9043 CmPolicyDlgPrintEx2(hWnd, p, cascade_mode, POLICY_CURRENT_VERSION);
9044 }
CmPolicyDlgPrintEx2(HWND hWnd,CM_POLICY * p,bool cascade_mode,UINT ver)9045 void CmPolicyDlgPrintEx2(HWND hWnd, CM_POLICY *p, bool cascade_mode, UINT ver)
9046 {
9047 POLICY *pol;
9048 UINT i;
9049 LVB *b;
9050 // Validate arguments
9051 if (hWnd == NULL || p == NULL)
9052 {
9053 return;
9054 }
9055
9056 pol = p->Policy;
9057
9058 b = LvInsertStart();
9059
9060 for (i = 0;i < NUM_POLICY_ITEM;i++)
9061 {
9062 wchar_t tmp[MAX_SIZE];
9063
9064 if (cascade_mode)
9065 {
9066 if (PolicyIsSupportedForCascade(i) == false)
9067 {
9068 continue;
9069 }
9070 }
9071
9072 if (IS_POLICY_FOR_CURRENT_VER(i, ver))
9073 {
9074 if (policy_item[i].TypeInt == false)
9075 {
9076 // bool type
9077 UniStrCpy(tmp, sizeof(tmp), POLICY_BOOL(pol, i) ? _UU("POL_BOOL_ENABLE") : (p->Extension ? _UU("POL_BOOL_DISABLE_EX") : _UU("POL_BOOL_DISABLE")));
9078 }
9079 else
9080 {
9081 // int type
9082 if (policy_item[i].AllowZero && POLICY_INT(pol, i) == 0)
9083 {
9084 UniStrCpy(tmp, sizeof(tmp), _UU("POL_INT_ZERO"));
9085 }
9086 else
9087 {
9088 UniFormat(tmp, sizeof(tmp), _UU(policy_item[i].FormatStr), POLICY_INT(pol, i));
9089 }
9090 }
9091
9092 LvInsertAdd(b, ICO_MACHINE, (void *)i, 2, GetPolicyTitle(i), tmp);
9093 }
9094 }
9095
9096 LvInsertEnd(b, hWnd, L_POLICY);
9097 }
9098
9099 // Policy list dialog box
CmPolicyDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)9100 UINT CmPolicyDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
9101 {
9102 CM_POLICY *p = (CM_POLICY *)param;
9103 NMHDR *n;
9104 // Validate arguments
9105 if (hWnd == NULL)
9106 {
9107 return 0;
9108 }
9109
9110 switch (msg)
9111 {
9112 case WM_INITDIALOG:
9113 FormatText(hWnd, 0, p->AccountName);
9114 FormatText(hWnd, S_TITLE, p->AccountName);
9115 p->hWnd = hWnd;
9116 if (p->CmStatus != NULL)
9117 {
9118 p->CmStatus->hWndPolicy = hWnd;
9119 }
9120
9121 // Initialize the column
9122 LvInit(hWnd, L_POLICY);
9123 LvInsertColumn(hWnd, L_POLICY, 0, _UU("POL_TITLE_STR"), 375);
9124 LvInsertColumn(hWnd, L_POLICY, 1, _UU("POL_VALUE_STR"), 100);
9125
9126 // Display
9127 CmPolicyDlgPrint(hWnd, p);
9128
9129 // Select the first
9130 LvSelect(hWnd, L_POLICY, 0);
9131 break;
9132
9133 case WM_COMMAND:
9134 switch (wParam)
9135 {
9136 case IDOK:
9137 case IDCANCEL:
9138 Close(hWnd);
9139 break;
9140 }
9141 break;
9142
9143 case WM_NOTIFY:
9144 n = (NMHDR *)lParam;
9145 switch (n->idFrom)
9146 {
9147 case L_POLICY:
9148 switch (n->code)
9149 {
9150 case LVN_ITEMCHANGED:
9151 // Change selection
9152 if (LvIsSelected(hWnd, L_POLICY) == false)
9153 {
9154 SetText(hWnd, S_DESCRIPTION, L"");
9155 }
9156 else
9157 {
9158 UINT index = LvGetSelected(hWnd, L_POLICY);
9159 UINT id = (UINT)LvGetParam(hWnd, L_POLICY, index);
9160 if (id < NUM_POLICY_ITEM)
9161 {
9162 SetText(hWnd, S_DESCRIPTION, GetPolicyDescription(id));
9163 }
9164 }
9165 break;
9166 }
9167 break;
9168 }
9169 break;
9170
9171 case WM_CLOSE:
9172 EndDialog(hWnd, 0);
9173 break;
9174 }
9175
9176 LvSortHander(hWnd, msg, wParam, lParam, L_POLICY);
9177
9178 return 0;
9179 }
9180
9181 // Show the policy list dialog
CmPolicyDlg(HWND hWnd,CM_STATUS * st)9182 void CmPolicyDlg(HWND hWnd, CM_STATUS *st)
9183 {
9184 RPC_CLIENT_GET_CONNECTION_STATUS s;
9185 POLICY *policy;
9186 CM_POLICY cp;
9187 // Validate arguments
9188 if (hWnd == NULL || st == NULL)
9189 {
9190 return;
9191 }
9192
9193 // Get the policy
9194 Zero(&s, sizeof(s));
9195 UniStrCpy(s.AccountName, sizeof(s.AccountName), st->AccountName);
9196 if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)
9197 {
9198 return;
9199 }
9200 if (s.Active == false)
9201 {
9202 return;
9203 }
9204
9205 policy = &s.Policy;
9206
9207 Zero(&cp, sizeof(cp));
9208 UniStrCpy(cp.AccountName, sizeof(cp.AccountName), st->AccountName);
9209 cp.Policy = policy;
9210 cp.CmStatus = st;
9211
9212 Dialog(hWnd, D_CM_POLICY, CmPolicyDlgProc, &cp);
9213
9214 st->hWndPolicy = NULL;
9215
9216 CiFreeClientGetConnectionStatus(&s);
9217 }
9218
9219 // Show the certificate
CmStatusDlgPrintCert(HWND hWnd,CM_STATUS * st,bool server)9220 void CmStatusDlgPrintCert(HWND hWnd, CM_STATUS *st, bool server)
9221 {
9222 RPC_CLIENT_GET_CONNECTION_STATUS s;
9223 X *x, *issuer;
9224 // Validate arguments
9225 if (hWnd == NULL || st == NULL)
9226 {
9227 return;
9228 }
9229
9230 // Get the latest information
9231 Zero(&s, sizeof(s));
9232 UniStrCpy(s.AccountName, sizeof(s.AccountName), st->AccountName);
9233 if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)
9234 {
9235 Close(hWnd);
9236 return;
9237 }
9238
9239 if (s.Active == false)
9240 {
9241 // Disconnect
9242 Close(hWnd);
9243 return;
9244 }
9245
9246 if (server == false)
9247 {
9248 // Show the client certificate
9249 x = s.ClientX;
9250 }
9251 else
9252 {
9253 // Show the server certificate
9254 x = s.ServerX;
9255 }
9256
9257 cm->WindowCount++;
9258 issuer = CmGetIssuer(x);
9259 CertDlg(hWnd, x, issuer, true);
9260 FreeX(issuer);
9261 cm->WindowCount--;
9262
9263 CiFreeClientGetConnectionStatus(&s);
9264 }
9265
9266 // Show the information of the status dialog
CmStatusDlgPrint(HWND hWnd,CM_STATUS * cmst)9267 void CmStatusDlgPrint(HWND hWnd, CM_STATUS *cmst)
9268 {
9269 RPC_CLIENT_GET_CONNECTION_STATUS s;
9270 LVB *b;
9271 // Validate arguments
9272 if (hWnd == NULL || cmst == NULL)
9273 {
9274 return;
9275 }
9276
9277 // Get the latest information
9278 Zero(&s, sizeof(s));
9279 UniStrCpy(s.AccountName, sizeof(s.AccountName), cmst->AccountName);
9280 if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)
9281 {
9282 Close(hWnd);
9283 return;
9284 }
9285
9286 if (s.Active == false)
9287 {
9288 // Disconnect
9289 Close(hWnd);
9290 return;
9291 }
9292
9293 // Show the status in the list box in the status dialog
9294 b = LvInsertStart();
9295 CmPrintStatusToListView(b, &s);
9296 LvInsertEnd(b, hWnd, L_STATUS);
9297
9298 LvAutoSize(hWnd, L_STATUS);
9299
9300 SetEnable(hWnd, B_POLICY, s.Connected);
9301
9302 SetEnable(hWnd, B_SERVER_CERT, s.ServerX != NULL);
9303 SetEnable(hWnd, B_CLIENT_CERT, s.ClientX != NULL);
9304
9305 CiFreeClientGetConnectionStatus(&s);
9306 }
9307
9308 // Show the status in the list box in the status dialog
CmPrintStatusToListView(LVB * b,RPC_CLIENT_GET_CONNECTION_STATUS * s)9309 void CmPrintStatusToListView(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s)
9310 {
9311 CmPrintStatusToListViewEx(b, s, false);
9312 }
CmPrintStatusToListViewEx(LVB * b,RPC_CLIENT_GET_CONNECTION_STATUS * s,bool server_mode)9313 void CmPrintStatusToListViewEx(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s, bool server_mode)
9314 {
9315 wchar_t tmp[MAX_SIZE];
9316 char str[MAX_SIZE];
9317 char vv[128];
9318 // Validate arguments
9319 if (b == NULL || s == NULL)
9320 {
9321 return;
9322 }
9323
9324 if (server_mode == false)
9325 {
9326 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_ACCOUNT_NAME"), s->AccountName);
9327
9328 if (s->Connected == false)
9329 {
9330 wchar_t *st = _UU("CM_ST_CONNECTED_FALSE");
9331 switch (s->SessionStatus)
9332 {
9333 case CLIENT_STATUS_CONNECTING:
9334 st = _UU("CM_ST_CONNECTING");
9335 break;
9336 case CLIENT_STATUS_NEGOTIATION:
9337 st = _UU("CM_ST_NEGOTIATION");
9338 break;
9339 case CLIENT_STATUS_AUTH:
9340 st = _UU("CM_ST_AUTH");
9341 break;
9342 case CLIENT_STATUS_ESTABLISHED:
9343 st = _UU("CM_ST_ESTABLISHED");
9344 break;
9345 case CLIENT_STATUS_RETRY:
9346 st = _UU("CM_ST_RETRY");
9347 break;
9348 case CLIENT_STATUS_IDLE:
9349 st = _UU("CM_ST_IDLE");
9350 break;
9351 }
9352 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CONNECTED"), st);
9353 }
9354 else
9355 {
9356 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CONNECTED"), _UU("CM_ST_CONNECTED_TRUE"));
9357 }
9358 }
9359
9360 if (s->Connected)
9361 {
9362 if (s->VLanId == 0)
9363 {
9364 UniStrCpy(tmp, sizeof(tmp), _UU("CM_ST_NO_VLAN"));
9365 }
9366 else
9367 {
9368 UniToStru(tmp, s->VLanId);
9369 }
9370
9371 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_VLAN_ID"), tmp);
9372
9373 if (server_mode == false)
9374 {
9375 StrToUni(tmp, sizeof(tmp), s->ServerName);
9376 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_NAME"), tmp);
9377
9378 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_PORT_TCP"), s->ServerPort);
9379 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_PORT"), tmp);
9380 }
9381
9382 StrToUni(tmp, sizeof(tmp), s->ServerProductName);
9383 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_NAME"), tmp);
9384
9385 UniFormat(tmp, sizeof(tmp), L"%u.%02u", s->ServerProductVer / 100, s->ServerProductVer % 100);
9386 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_VER"), tmp);
9387 UniFormat(tmp, sizeof(tmp), L"Build %u", s->ServerProductBuild);
9388 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_BUILD"), tmp);
9389 }
9390
9391 GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->StartTime), NULL);
9392 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_START_TIME"), tmp);
9393 GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->FirstConnectionEstablisiedTime), NULL);
9394 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_FIRST_ESTAB_TIME"), s->FirstConnectionEstablisiedTime == 0 ? _UU("CM_ST_NONE") : tmp);
9395
9396 if (s->Connected)
9397 {
9398 GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->CurrentConnectionEstablishTime), NULL);
9399 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CURR_ESTAB_TIME"), tmp);
9400 }
9401
9402 if (server_mode == false)
9403 {
9404 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_STR"), s->NumConnectionsEatablished);
9405 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_ESTABLISHED"), tmp);
9406 }
9407
9408 if (s->Connected)
9409 {
9410 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_HALF_CONNECTION"), s->HalfConnection ? _UU("CM_ST_HALF_TRUE") : _UU("CM_ST_HALF_FALSE"));
9411
9412 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_QOS"), s->QoS ? _UU("CM_ST_QOS_TRUE") : _UU("CM_ST_QOS_FALSE"));
9413
9414 UniFormat(tmp, sizeof(tmp), L"%u", s->NumTcpConnections);
9415 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_TCP"), tmp);
9416
9417 if (s->HalfConnection)
9418 {
9419 UniFormat(tmp, sizeof(tmp), L"%u", s->NumTcpConnectionsUpload);
9420 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_TCP_UPLOAD"), tmp);
9421 UniFormat(tmp, sizeof(tmp), L"%u", s->NumTcpConnectionsDownload);
9422 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_TCP_DOWNLOAD"), tmp);
9423 }
9424
9425 UniFormat(tmp, sizeof(tmp), L"%u", s->MaxTcpConnections);
9426 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_MAX_TCP"), tmp);
9427
9428 if (s->UseEncrypt == false)
9429 {
9430 UniStrCpy(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_FALSE"));
9431 }
9432 else
9433 {
9434 if (StrLen(s->CipherName) != 0)
9435 {
9436 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_TRUE"), s->CipherName);
9437 }
9438 else
9439 {
9440 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_TRUE2"));
9441 }
9442 }
9443 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_USE_ENCRYPT"), tmp);
9444
9445 if (s->UseCompress)
9446 {
9447 UINT percent = 0;
9448 if ((s->TotalRecvSize + s->TotalSendSize) > 0)
9449 {
9450 percent = (UINT)((UINT64)100 - (UINT64)(s->TotalRecvSizeReal + s->TotalSendSizeReal) * (UINT64)100 /
9451 (s->TotalRecvSize + s->TotalSendSize));
9452 percent = MAKESURE(percent, 0, 100);
9453 }
9454
9455 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_COMPRESS_TRUE"), percent);
9456 }
9457 else
9458 {
9459 UniStrCpy(tmp, sizeof(tmp), _UU("CM_ST_COMPRESS_FALSE"));
9460 }
9461 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_USE_COMPRESS"), tmp);
9462
9463 if (IsEmptyStr(s->UnderlayProtocol) == false)
9464 {
9465 StrToUni(tmp, sizeof(tmp), s->UnderlayProtocol);
9466 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp);
9467 }
9468
9469 if (IsEmptyStr(s->ProtocolDetails) == false)
9470 {
9471 StrToUni(tmp, sizeof(tmp), s->ProtocolDetails);
9472 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_PROTOCOL_DETAILS"), tmp);
9473 }
9474
9475 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));
9476 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));
9477
9478 StrToUni(tmp, sizeof(tmp), s->SessionName);
9479 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SESSION_NAME"), tmp);
9480
9481 StrToUni(tmp, sizeof(tmp), s->ConnectionName);
9482 if (UniStrCmpi(tmp, L"INITING") != 0)
9483 {
9484 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CONNECTION_NAME"), tmp);
9485 }
9486
9487 BinToStr(str, sizeof(str), s->SessionKey, sizeof(s->SessionKey));
9488 StrToUni(tmp, sizeof(tmp), str);
9489 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SESSION_KEY"), tmp);
9490
9491 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_BRIDGE_MODE"), s->IsBridgeMode ? _UU("CM_ST_YES") : _UU("CM_ST_NO"));
9492
9493 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_MONITOR_MODE"), s->IsMonitorMode ? _UU("CM_ST_YES") : _UU("CM_ST_NO"));
9494
9495 ToStr3(vv, sizeof(vv), s->TotalSendSize);
9496 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
9497 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_SIZE"), tmp);
9498
9499 ToStr3(vv, sizeof(vv), s->TotalRecvSize);
9500 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
9501 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_SIZE"), tmp);
9502
9503 ToStr3(vv, sizeof(vv), s->Traffic.Send.UnicastCount);
9504 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);
9505 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_UCAST_NUM"), tmp);
9506
9507 ToStr3(vv, sizeof(vv), s->Traffic.Send.UnicastBytes);
9508 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
9509 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_UCAST_SIZE"), tmp);
9510
9511 ToStr3(vv, sizeof(vv), s->Traffic.Send.BroadcastCount);
9512 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);
9513 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_BCAST_NUM"), tmp);
9514
9515 ToStr3(vv, sizeof(vv), s->Traffic.Send.BroadcastBytes);
9516 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
9517 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_BCAST_SIZE"), tmp);
9518
9519 ToStr3(vv, sizeof(vv), s->Traffic.Recv.UnicastCount);
9520 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);
9521 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_UCAST_NUM"), tmp);
9522
9523 ToStr3(vv, sizeof(vv), s->Traffic.Recv.UnicastBytes);
9524 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
9525 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_UCAST_SIZE"), tmp);
9526
9527 ToStr3(vv, sizeof(vv), s->Traffic.Recv.BroadcastCount);
9528 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);
9529 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_BCAST_NUM"), tmp);
9530
9531 ToStr3(vv, sizeof(vv), s->Traffic.Recv.BroadcastBytes);
9532 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);
9533 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_BCAST_SIZE"), tmp);
9534 }
9535 }
9536
9537 // Status dialog procedure
CmStatusDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)9538 UINT CmStatusDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
9539 {
9540 wchar_t tmp[MAX_SIZE];
9541 CM_STATUS *s = (CM_STATUS *)param;
9542 // Validate arguments
9543 if (hWnd == NULL)
9544 {
9545 return 0;
9546 }
9547
9548 switch (msg)
9549 {
9550 case WM_INITDIALOG:
9551 SetIcon(hWnd, 0, ICO_TOWER);
9552 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_TITLE"), s->AccountName);
9553 SetText(hWnd, 0, tmp);
9554 FormatText(hWnd, S_TITLE, s->AccountName);
9555 DlgFont(hWnd, S_TITLE, 0, 1);
9556
9557 Add(cm->StatusWindowList, hWnd);
9558
9559 SetTimer(hWnd, 1, 500, NULL);
9560
9561 LvInitEx(hWnd, L_STATUS, true);
9562 ListView_SetImageList(DlgItem(hWnd, L_STATUS), NULL, LVSIL_NORMAL);
9563 ListView_SetImageList(DlgItem(hWnd, L_STATUS), NULL, LVSIL_SMALL);
9564 LvInsertColumn(hWnd, L_STATUS, 0, _UU("CM_ST_COLUMN_1"), 160);
9565 LvInsertColumn(hWnd, L_STATUS, 1, _UU("CM_ST_COLUMN_2"), 270);
9566
9567 CmStatusDlgPrint(hWnd, s);
9568
9569 break;
9570 case WM_TIMER:
9571 switch (wParam)
9572 {
9573 case 1:
9574 KillTimer(hWnd, 1);
9575 CmStatusDlgPrint(hWnd, s);
9576 SetTimer(hWnd, 1, 500, NULL);
9577 break;
9578 }
9579 break;
9580 case WM_COMMAND:
9581 switch (wParam)
9582 {
9583 case IDOK:
9584 case IDCANCEL:
9585 // Close
9586 Close(hWnd);
9587 break;
9588 case B_POLICY:
9589 // Show the policy
9590 CmPolicyDlg(hWnd, s);
9591 break;
9592 case B_SERVER_CERT:
9593 CmStatusDlgPrintCert(hWnd, s, true);
9594 break;
9595 case B_CLIENT_CERT:
9596 CmStatusDlgPrintCert(hWnd, s, false);
9597 break;
9598 }
9599 break;
9600 case WM_CLOSE:
9601 Delete(cm->StatusWindowList, hWnd);
9602 if (s->hWndPolicy != NULL)
9603 {
9604 EndDialog(s->hWndPolicy, false);
9605 s->hWndPolicy = NULL;
9606 }
9607 EndDialog(hWnd, false);
9608 break;
9609 }
9610
9611 return 0;
9612 }
9613
9614 // Show the status dialog
CmStatusDlg(HWND hWnd,wchar_t * account_name)9615 void CmStatusDlg(HWND hWnd, wchar_t *account_name)
9616 {
9617 CM_STATUS *s;
9618 // Validate arguments
9619 if (hWnd == NULL || account_name == NULL)
9620 {
9621 return;
9622 }
9623
9624 s = ZeroMalloc(sizeof(CM_STATUS));
9625 UniStrCpy(s->AccountName, sizeof(s->AccountName), account_name);
9626
9627 Dialog(hWnd, D_CONNECTION_STATUS, CmStatusDlgProc, s);
9628
9629 Free(s);
9630 }
9631
9632 // Show the status
CmStatus(HWND hWnd,wchar_t * account_name)9633 void CmStatus(HWND hWnd, wchar_t *account_name)
9634 {
9635 UINT i;
9636 wchar_t tmp[MAX_SIZE];
9637 // Validate arguments
9638 if (hWnd == NULL || account_name == NULL)
9639 {
9640 return;
9641 }
9642
9643 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_TITLE"), account_name);
9644
9645 for (i = 0;i < LIST_NUM(cm->StatusWindowList);i++)
9646 {
9647 HWND h = LIST_DATA(cm->StatusWindowList, i);
9648 if (h != NULL)
9649 {
9650 wchar_t tmp2[MAX_SIZE];
9651 if (GetTxt(h, 0, tmp2, sizeof(tmp2)))
9652 {
9653 if (UniStrCmpi(tmp2, tmp) == 0)
9654 {
9655 SetActiveWindow(h);
9656 return;
9657 }
9658 }
9659 }
9660 }
9661
9662 CmStatusDlg(hWnd, account_name);
9663 }
9664
9665 // Delete
CmDeleteAccount(HWND hWnd,wchar_t * account_name)9666 void CmDeleteAccount(HWND hWnd, wchar_t *account_name)
9667 {
9668 RPC_CLIENT_DELETE_ACCOUNT c;
9669 // Validate arguments
9670 if (hWnd == NULL || account_name == NULL)
9671 {
9672 return;
9673 }
9674 Zero(&c, sizeof(c));
9675 UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);
9676
9677 CmVoice("delete_config_1");
9678 if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_ACCOUNT_MSG"), account_name)
9679 == IDNO)
9680 {
9681 return;
9682 }
9683
9684 CALL(hWnd, CcDeleteAccount(cm->Client, &c));
9685 CmVoice("delete_config_2");
9686 }
9687
9688 // Disconnect
CmDisconnect(HWND hWnd,wchar_t * account_name)9689 void CmDisconnect(HWND hWnd, wchar_t *account_name)
9690 {
9691 RPC_CLIENT_CONNECT c;
9692 // Validate arguments
9693 if (hWnd == NULL || account_name == NULL)
9694 {
9695 return;
9696 }
9697
9698 Zero(&c, sizeof(c));
9699 UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);
9700
9701 cm->PositiveDisconnectFlag = true;
9702
9703 CALL(hWnd, CcDisconnect(cm->Client, &c));
9704 }
9705
9706 // Show the promotional window
SmShowPublicVpnServerHtml(HWND hWnd)9707 void SmShowPublicVpnServerHtml(HWND hWnd)
9708 {
9709 char *langstr = _SS("LANGSTR");
9710
9711 if(StrCmpi(langstr, "Japanese") == 0)
9712 {
9713 ShowHtml(hWnd, PUBLIC_SERVER_HTML, PUBLIC_SERVER_TAG);
9714 }
9715 else
9716 {
9717 ShowHtml(hWnd, PUBLIC_SERVER_HTML_EN, PUBLIC_SERVER_TAG);
9718 }
9719 }
9720
9721 // Connection
CmConnect(HWND hWnd,wchar_t * account_name)9722 void CmConnect(HWND hWnd, wchar_t *account_name)
9723 {
9724 RPC_CLIENT_CONNECT c;
9725 UINT i;
9726 // Validate arguments
9727 if (hWnd == NULL || account_name == NULL)
9728 {
9729 return;
9730 }
9731
9732 if (IsEnable(hWnd, 0) == false)
9733 {
9734 return;
9735 }
9736
9737 if (hWnd == cm->hMainWnd)
9738 {
9739 if (LvNum(hWnd, L_VLAN) == 0 && cm->Client->Win9x)
9740 {
9741 if (MsgBox(hWnd, MB_ICONINFORMATION | MB_YESNO, _UU("CM_NO_VLAN_2")) == IDNO)
9742 {
9743 return;
9744 }
9745 else
9746 {
9747 if (cm->server_name == NULL || cm->Client->Unix)
9748 {
9749 Command(hWnd, CMD_NEW_VLAN);
9750 return;
9751 }
9752 else
9753 {
9754 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_VLAN_REMOTE_ERROR"));
9755 }
9756 return;
9757 }
9758 }
9759 }
9760
9761 // (If necessary) display a warning
9762 if (CmWarningDesktop(hWnd, account_name) == false)
9763 {
9764 return;
9765 }
9766
9767 if (cm->server_name == NULL)
9768 {
9769 if (cm->BadProcessChecked == false)
9770 {
9771 cm->BadProcessChecked = true;
9772
9773 CheckBadProcesses(hWnd);
9774 }
9775 }
9776
9777 if (cm->server_name == NULL)
9778 {
9779 // Check the Windows version
9780 RPC_WINVER winver;
9781 wchar_t winver_msg_client[3800];
9782
9783 GetWinVer(&winver);
9784 Zero(winver_msg_client, sizeof(winver_msg_client));
9785
9786 if (IsSupportedWinVer(&winver) == false)
9787 {
9788 SYSTEMTIME st;
9789
9790 LocalTime(&st);
9791
9792 UniFormat(winver_msg_client, sizeof(winver_msg_client), _UU("WINVER_ERROR_FORMAT"),
9793 _UU("WINVER_ERROR_PC_LOCAL"),
9794 winver.Title,
9795 _UU("WINVER_ERROR_VPNCLIENT"),
9796 SUPPORTED_WINDOWS_LIST,
9797 _UU("WINVER_ERROR_PC_LOCAL"),
9798 _UU("WINVER_ERROR_VPNCLIENT"),
9799 _UU("WINVER_ERROR_VPNCLIENT"),
9800 _UU("WINVER_ERROR_VPNCLIENT"),
9801 st.wYear, st.wMonth);
9802 }
9803
9804 if (UniIsEmptyStr(winver_msg_client) == false)
9805 {
9806 OnceMsgEx(hWnd, _UU("WINVER_TITLE"), winver_msg_client,
9807 true, ICO_WARNING, NULL);
9808 }
9809 }
9810
9811 i = LvSearchStr(hWnd, L_ACCOUNT, 0, account_name);
9812 if (i != INFINITE)
9813 {
9814 wchar_t *tmp = LvGetStr(hWnd, L_ACCOUNT, i, 2);
9815 if (tmp != NULL)
9816 {
9817 wchar_t tag[MAX_SIZE];
9818 StrToUni(tag, sizeof(tag), PUBLIC_SERVER_NAME);
9819
9820 if (UniSearchStrEx(tmp, tag, 0, false) != INFINITE)
9821 {
9822 SmShowPublicVpnServerHtml(hWnd);
9823 }
9824
9825 Free(tmp);
9826 }
9827 }
9828
9829 if (cm->CheckedAndShowedAdminPackMessage == false)
9830 {
9831 cm->CheckedAndShowedAdminPackMessage = true;
9832 //CmCheckAndShowAdminPackTrialVersionNoticeMessage(NULL);
9833 }
9834
9835 Zero(&c, sizeof(c));
9836 UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);
9837
9838 CmSetForegroundProcessToCnService();
9839
9840 if (CALL(hWnd, CcConnect(cm->Client, &c)))
9841 {
9842 cm->ConnectStartedFlag = true;
9843 }
9844 }
9845
9846 // Determine whether to bold the specified menu item
CmIsBold(UINT id)9847 bool CmIsBold(UINT id)
9848 {
9849 return false;
9850 }
9851
9852 // Determine whether to enable the specified menu item
CmIsEnabled(HWND hWnd,UINT id)9853 bool CmIsEnabled(HWND hWnd, UINT id)
9854 {
9855 UINT index;
9856 wchar_t *name;
9857 bool locked = false;
9858 // Validate arguments
9859 if (hWnd == NULL)
9860 {
9861 return false;
9862 }
9863
9864 locked = cm->CmSetting.LockMode;
9865
9866 if (locked)
9867 {
9868 switch (id)
9869 {
9870 case CMD_NEW:
9871 case CMD_CLONE:
9872 case CMD_IMPORT_ACCOUNT:
9873 case CMD_DELETE:
9874 case CMD_OPTION:
9875 case CMD_VOIDE_NONE:
9876 case CMD_VOICE_NORMAL:
9877 case CMD_VOICE_ODD:
9878 case CMD_STARTUP:
9879 case CMD_NOSTARTUP:
9880 case CMD_TRAFFIC:
9881 case CMD_MMCSS:
9882 return false;
9883 case CMD_NEW_VLAN:
9884 case CMD_ENABLE_VLAN:
9885 case CMD_DISABLE_VLAN:
9886 case CMD_DELETE_VLAN:
9887 case CMD_REINSTALL:
9888 case CMD_WINNET:
9889 if (cm->CmEasyModeSupported)
9890 {
9891 return false;
9892 }
9893 }
9894 }
9895
9896 switch (id)
9897 {
9898 case CMD_LANGUAGE:
9899 return MsIsNt();
9900 case CMD_SHOWPORT:
9901 case CMD_GRID:
9902 if (cm->IconView)
9903 {
9904 return false;
9905 }
9906 return true;
9907 case CMD_MMCSS:
9908 if (MsIsVista() == false || IsEmptyStr(cm->server_name) == false)
9909 {
9910 return false;
9911 }
9912 if (OS_IS_SERVER(GetOsType()))
9913 {
9914 return false;
9915 }
9916 return true;
9917 case CMD_TRAYICON:
9918 case CMD_TRAFFIC:
9919 return (cm->server_name == NULL);
9920 case CMD_NETIF:
9921 if (MsIsNt() == false)
9922 {
9923 return false;
9924 }
9925 return (cm->server_name == NULL);
9926 case CMD_CM_SETTING:
9927 return cm->CmSettingSupported;
9928 case CMD_CONNECT:
9929 case CMD_DISCONNECT:
9930 case CMD_STATUS:
9931 case CMD_RENAME:
9932 case CMD_DELETE:
9933 if (LvIsMultiMasked(hWnd, L_ACCOUNT))
9934 {
9935 return false;
9936 }
9937 if (LvIsSelected(hWnd, L_ACCOUNT) == false)
9938 {
9939 return false;
9940 }
9941 else
9942 {
9943 // Determine whether the selected account is under connecting
9944 UINT i = LvGetSelected(hWnd, L_ACCOUNT);
9945 wchar_t *str = LvGetStr(hWnd, L_ACCOUNT, i, 1);
9946 wchar_t *name = LvGetStr(hWnd, L_ACCOUNT, i, 0);
9947 bool is_connected = false;
9948 if (str != NULL)
9949 {
9950 if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)
9951 {
9952 is_connected = true;
9953 }
9954 Free(str);
9955 }
9956 if (name != NULL)
9957 {
9958 if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_LINK")) == 0)
9959 {
9960 Free(name);
9961 return false;
9962 }
9963 Free(name);
9964 }
9965 if (id == CMD_CONNECT || id == CMD_RENAME || id == CMD_DELETE)
9966 {
9967 return !is_connected;
9968 }
9969 else
9970 {
9971 return is_connected;
9972 }
9973 }
9974 break;
9975 case CMD_DISCONNECT_ALL:
9976 if (CmGetNumConnected(hWnd) == 0)
9977 {
9978 return false;
9979 }
9980 else
9981 {
9982 return true;
9983 }
9984 case CMD_SHORTCUT:
9985 // Create a shortcut
9986 if (cm->Client->Rpc->Sock->RemoteIP.addr[0] != 127)
9987 {
9988 return false;
9989 }
9990 case CMD_EXPORT_ACCOUNT:
9991 if (LvIsMultiMasked(hWnd, L_ACCOUNT))
9992 {
9993 return false;
9994 }
9995 name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
9996 if (name != NULL)
9997 {
9998 if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_LINK")) == 0
9999 )
10000 {
10001 Free(name);
10002 return false;
10003 }
10004 Free(name);
10005 }
10006 return LvIsSelected(hWnd, L_ACCOUNT);
10007 case CMD_CLONE:
10008 if (LvIsMultiMasked(hWnd, L_ACCOUNT))
10009 {
10010 return false;
10011 }
10012 name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
10013 if (name != NULL)
10014 {
10015 if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_LINK")) == 0
10016 )
10017 {
10018 Free(name);
10019 return false;
10020 }
10021 Free(name);
10022 }
10023 return LvIsSelected(hWnd, L_ACCOUNT);
10024 case CMD_STARTUP:
10025 case CMD_NOSTARTUP:
10026 name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
10027 if (name != NULL)
10028 {
10029 if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_LINK")) == 0
10030 )
10031 {
10032 Free(name);
10033 return false;
10034 }
10035 Free(name);
10036 }
10037 if (LvIsMultiMasked(hWnd, L_ACCOUNT))
10038 {
10039 return false;
10040 }
10041 if (LvIsSelected(hWnd, L_ACCOUNT) == false)
10042 {
10043 return false;
10044 }
10045 else
10046 {
10047 // Determine whether the selected account is a startup account
10048 UINT i = LvGetSelected(hWnd, L_ACCOUNT);
10049 bool is_startup = (bool)LvGetParam(hWnd, L_ACCOUNT, i);
10050 if (id == CMD_STARTUP)
10051 {
10052 return !is_startup;
10053 }
10054 else
10055 {
10056 return is_startup;
10057 }
10058 }
10059 break;
10060 case CMD_NEW_VLAN:
10061 if (cm->Client->Unix == false && cm->Client->Win9x == false)
10062 {
10063 if (cm->server_name != NULL)
10064 {
10065 return false;
10066 }
10067 }
10068 if (cm->Client->Win9x)
10069 {
10070 if (LvNum(hWnd, L_VLAN) >= 1)
10071 {
10072 // You can not install two or more virtual LAN cards in Win9x
10073 return false;
10074 }
10075 }
10076 break;
10077 case CMD_PROPERTY:
10078 name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);
10079 if (name != NULL)
10080 {
10081 if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(name, _UU("CM_VGC_LINK")) == 0)
10082 {
10083 Free(name);
10084 return false;
10085 }
10086 Free(name);
10087 }
10088 if (LvIsMultiMasked(hWnd, L_ACCOUNT))
10089 {
10090 return false;
10091 }
10092 return LvIsSelected(hWnd, L_ACCOUNT);
10093 case CMD_DELETE_VLAN:
10094 if (LvIsMultiMasked(hWnd, L_VLAN))
10095 {
10096 return false;
10097 }
10098 return LvIsSelected(hWnd, L_VLAN);
10099 case CMD_ENABLE_VLAN:
10100 if (cm->Client->Win9x)
10101 {
10102 return false;
10103 }
10104 if (LvIsMultiMasked(hWnd, L_VLAN))
10105 {
10106 return false;
10107 }
10108 index = LvGetSelected(hWnd, L_VLAN);
10109 if (index == INFINITE)
10110 {
10111 return false;
10112 }
10113 else
10114 {
10115 wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 1);
10116 if (s != NULL)
10117 {
10118 if (UniStrCmpi(s, _UU("CM_VLAN_DISABLED")) == 0)
10119 {
10120 Free(s);
10121 return true;
10122 }
10123 Free(s);
10124 }
10125 return false;
10126 }
10127 break;
10128 case CMD_DISABLE_VLAN:
10129 if (cm->Client->Win9x)
10130 {
10131 return false;
10132 }
10133 if (LvIsMultiMasked(hWnd, L_VLAN))
10134 {
10135 return false;
10136 }
10137 index = LvGetSelected(hWnd, L_VLAN);
10138 if (index == INFINITE)
10139 {
10140 return false;
10141 }
10142 else
10143 {
10144 wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 1);
10145 if (s != NULL)
10146 {
10147 if (UniStrCmpi(s, _UU("CM_VLAN_ENABLED")) == 0)
10148 {
10149 Free(s);
10150 return true;
10151 }
10152 Free(s);
10153 }
10154 return false;
10155 }
10156 break;
10157 case CMD_REINSTALL:
10158 if (cm->server_name != NULL)
10159 {
10160 return false;
10161 }
10162 if (cm->Client->Win9x || cm->Client->Unix)
10163 {
10164 // Upgrading the virtual LAN card on a UNIX system or Win9x is unavailable
10165 return false;
10166 }
10167 if (LvIsMultiMasked(hWnd, L_VLAN))
10168 {
10169 return false;
10170 }
10171 return LvIsSelected(hWnd, L_VLAN);
10172 case CMD_WINNET:
10173 {
10174 UINT os_type = GetOsInfo()->OsType;
10175
10176 if (OS_IS_WINDOWS_NT(os_type) && GET_KETA(os_type, 100) >= 2)
10177 {
10178 if (cm->server_name != NULL)
10179 {
10180 return false;
10181 }
10182
10183 return true;
10184 }
10185 else
10186 {
10187 return false;
10188 }
10189 }
10190 break;
10191 case CMD_EXIT:
10192 return cm->TrayInited;
10193 }
10194 return true;
10195 }
10196
10197 // Convert a VLAN device name to the display name
CmVLanNameToPrintName(char * str,UINT size,char * name)10198 void CmVLanNameToPrintName(char *str, UINT size, char *name)
10199 {
10200 // Validate arguments
10201 if (str == NULL || name == NULL)
10202 {
10203 return;
10204 }
10205
10206 Format(str, size, VLAN_ADAPTER_NAME_TAG, name);
10207 }
10208
10209 // Convert a display name to a VLAN device name
CmPrintNameToVLanName(char * name,UINT size,char * str)10210 bool CmPrintNameToVLanName(char *name, UINT size, char *str)
10211 {
10212 // Validate arguments
10213 if (name == NULL || str == NULL)
10214 {
10215 return false;
10216 }
10217
10218 if (StartWith(str, VLAN_ADAPTER_NAME))
10219 {
10220 if (StrLen(str) < (StrLen(VLAN_ADAPTER_NAME) + 3))
10221 {
10222 return false;
10223 }
10224
10225 StrCpy(name, size, str + StrLen(VLAN_ADAPTER_NAME) + 3);
10226
10227 return true;
10228 }
10229
10230 if (StartWith(str, VLAN_ADAPTER_NAME_OLD))
10231 {
10232 if (StrLen(str) < (StrLen(VLAN_ADAPTER_NAME_OLD) + 3))
10233 {
10234 return false;
10235 }
10236
10237 StrCpy(name, size, str + StrLen(VLAN_ADAPTER_NAME_OLD) + 3);
10238
10239 return true;
10240 }
10241
10242 return false;
10243 }
10244
10245 // Initialize the account list
CmInitAccountList(HWND hWnd)10246 void CmInitAccountList(HWND hWnd)
10247 {
10248 CmInitAccountListEx(hWnd, false);
10249 }
CmInitAccountListEx(HWND hWnd,bool easy)10250 void CmInitAccountListEx(HWND hWnd, bool easy)
10251 {
10252 UINT width[5];
10253 BUF *b;
10254 // Validate arguments
10255 if (hWnd == NULL)
10256 {
10257 return;
10258 }
10259
10260 // Read the setting
10261 b = MsRegReadBin(REG_CURRENT_USER, CM_REG_KEY, "AccountListColumnWidth");
10262 if ((b != NULL) && (b->Size == sizeof(width)))
10263 {
10264 Copy(width, b->Buf, sizeof(width));
10265 }
10266 else if ((b != NULL) && (b->Size == (sizeof(width) - sizeof(UINT))))
10267 {
10268 // Migrating from previous versions
10269 Zero(width, sizeof(width));
10270 Copy(width, b->Buf, sizeof(width) - sizeof(UINT));
10271 width[4] = width[3];
10272 width[3] = 0;
10273 }
10274 else
10275 {
10276 Zero(width, sizeof(width));
10277 }
10278 FreeBuf(b);
10279
10280 LvInitEx2(hWnd, L_ACCOUNT, false, easy);
10281
10282 // LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_TRACKSELECT);
10283
10284 // Initialize the column
10285 if (easy == false)
10286 {
10287 LvInsertColumn(hWnd, L_ACCOUNT, 0, _UU("CM_ACCOUNT_COLUMN_1"), width[0] == 0 ? 215 : width[0]);
10288 LvInsertColumn(hWnd, L_ACCOUNT, 1, _UU("CM_ACCOUNT_COLUMN_2"), width[1] == 0 ? 80 : width[1]);
10289 LvInsertColumn(hWnd, L_ACCOUNT, 2, _UU("CM_ACCOUNT_COLUMN_3"), width[2] == 0 ? 220 : width[2]);
10290 LvInsertColumn(hWnd, L_ACCOUNT, 3, _UU("CM_ACCOUNT_COLUMN_3_2"), width[3] == 0 ? 90 : width[3]);
10291 LvInsertColumn(hWnd, L_ACCOUNT, 4, _UU("CM_ACCOUNT_COLUMN_4"), (width[4] == 0 || width[4] == 250) ? 120 : width[4]);
10292 }
10293 else
10294 {
10295 LvInsertColumn(hWnd, L_ACCOUNT, 0, _UU("CM_ACCOUNT_COLUMN_1"), 345);
10296 LvInsertColumn(hWnd, L_ACCOUNT, 1, _UU("CM_ACCOUNT_COLUMN_2"), 140);
10297 LvInsertColumn(hWnd, L_ACCOUNT, 2, _UU("CM_ACCOUNT_COLUMN_3"), 0);
10298 LvInsertColumn(hWnd, L_ACCOUNT, 3, _UU("CM_ACCOUNT_COLUMN_3_2"), 0);
10299 LvInsertColumn(hWnd, L_ACCOUNT, 4, _UU("CM_ACCOUNT_COLUMN_4"), 0);
10300 }
10301 }
10302
10303 // Release the account list
CmSaveAccountListPos(HWND hWnd)10304 void CmSaveAccountListPos(HWND hWnd)
10305 {
10306 UINT width[5];
10307 UINT i;
10308 // Validate arguments
10309 if (hWnd == NULL)
10310 {
10311 return;
10312 }
10313
10314 for (i = 0;i < 5;i++)
10315 {
10316 width[i] = LvGetColumnWidth(hWnd, L_ACCOUNT, i);
10317 }
10318
10319 MsRegWriteBin(REG_CURRENT_USER, CM_REG_KEY, "AccountListColumnWidth", width, sizeof(width));
10320 }
10321
10322 // Initialize the VLAN list
CmInitVLanList(HWND hWnd)10323 void CmInitVLanList(HWND hWnd)
10324 {
10325 UINT width[4];
10326 BUF *b;
10327 // Validate arguments
10328 if (hWnd == NULL)
10329 {
10330 return;
10331 }
10332
10333 // Read the setting
10334 b = MsRegReadBin(REG_CURRENT_USER, CM_REG_KEY, "VLanListColumnWidth");
10335 if ((b != NULL) && (b->Size == sizeof(width)))
10336 {
10337 Copy(width, b->Buf, sizeof(width));
10338 }
10339 else
10340 {
10341 Zero(width, sizeof(width));
10342 }
10343 FreeBuf(b);
10344
10345 LvInit(hWnd, L_VLAN);
10346
10347 // LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_TRACKSELECT);
10348
10349 // Initialize the column
10350 LvInsertColumn(hWnd, L_VLAN, 0, _UU("CM_VLAN_COLUMN_1"), width[0] == 0 ? 310 : width[0]);
10351 LvInsertColumn(hWnd, L_VLAN, 1, _UU("CM_VLAN_COLUMN_2"), width[1] == 0 ? 120 : width[1]);
10352 LvInsertColumn(hWnd, L_VLAN, 2, _UU("CM_VLAN_COLUMN_3"), width[2] == 0 ? 175 : width[2]);
10353 LvInsertColumn(hWnd, L_VLAN, 3, _UU("CM_VLAN_COLUMN_4"), width[3] == 0 ? 120 : width[3]);
10354 }
10355
10356 // Release the VLAN list
CmSaveVLanListPos(HWND hWnd)10357 void CmSaveVLanListPos(HWND hWnd)
10358 {
10359 UINT width[4];
10360 UINT i;
10361 // Validate arguments
10362 if (hWnd == NULL)
10363 {
10364 return;
10365 }
10366
10367 for (i = 0;i < 4;i++)
10368 {
10369 width[i] = LvGetColumnWidth(hWnd, L_VLAN, i);
10370 }
10371
10372 MsRegWriteBin(REG_CURRENT_USER, CM_REG_KEY, "VLanListColumnWidth", width, sizeof(width));
10373 }
10374
10375 // Update the account list
CmRefreshAccountList(HWND hWnd)10376 void CmRefreshAccountList(HWND hWnd)
10377 {
10378 CmRefreshAccountListEx(hWnd, false);
10379 CmRefreshEasy();
10380 }
CmRefreshAccountListEx(HWND hWnd,bool easy)10381 void CmRefreshAccountListEx(HWND hWnd, bool easy)
10382 {
10383 CmRefreshAccountListEx2(hWnd, easy, false);
10384 }
CmRefreshAccountListEx2(HWND hWnd,bool easy,bool style_changed)10385 void CmRefreshAccountListEx2(HWND hWnd, bool easy, bool style_changed)
10386 {
10387 UINT num = 0;
10388 RPC_CLIENT_ENUM_ACCOUNT a;
10389 UINT num_connecting = 0, num_connected = 0;
10390 wchar_t tmp[MAX_SIZE];
10391 wchar_t new_inserted_item[MAX_ACCOUNT_NAME_LEN + 1];
10392 bool select_new_insteted_item = true;
10393 // Validate arguments
10394 if (hWnd == NULL)
10395 {
10396 return;
10397 }
10398
10399 // Switching of icon / detail view
10400 LvSetView(hWnd, L_ACCOUNT, cm->IconView == false || easy);
10401
10402 // Show grid
10403 if (cm->ShowGrid || easy)
10404 {
10405 LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_GRIDLINES);
10406 }
10407 else
10408 {
10409 LvRemoveStyle(hWnd, L_ACCOUNT, LVS_EX_GRIDLINES);
10410 }
10411
10412 if (style_changed)
10413 {
10414 // Change the font
10415 if (easy == false)
10416 {
10417 if (cm->VistaStyle)
10418 {
10419 SetFontMeiryo(hWnd, L_ACCOUNT, 9);
10420 }
10421 else
10422 {
10423 SetFontDefault(hWnd, L_ACCOUNT);
10424 }
10425
10426 if (cm->VistaStyle && (cm->IconView == false))
10427 {
10428 LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_FULLROWSELECT);
10429 }
10430 else
10431 {
10432 LvRemoveStyle(hWnd, L_ACCOUNT, LVS_EX_FULLROWSELECT);
10433 }
10434 }
10435 }
10436
10437 Zero(new_inserted_item, sizeof(new_inserted_item));
10438
10439 if (LvNum(hWnd, L_ACCOUNT) == 0)
10440 {
10441 select_new_insteted_item = false;
10442 }
10443
10444 // Enumerate the account list
10445 if (CALL(hWnd, CcEnumAccount(cm->Client, &a)))
10446 {
10447 UINT i;
10448 LVB *b = LvInsertStart();
10449
10450 if (cm->CmSetting.LockMode == false && (easy == false))
10451 {
10452 // Creating a new connection
10453 LvInsertAdd(b, ICO_NEW, NULL, 4, _UU("CM_NEW_ICON"), L"", L"", L"");
10454
10455 if (cm->Client->IsVgcSupported)
10456 {
10457 // VPN Gate
10458 LvInsertAdd(b, ICO_RESEARCH, NULL, 4, _UU("CM_VGC_ICON"), L"", L"", L"");
10459 }
10460 else if (cm->Client->ShowVgcLink)
10461 {
10462 // VPN Gate Link
10463 LvInsertAdd(b, ICO_INTERNET, NULL, 4, _UU("CM_VGC_LINK"), L"", L"", L"");
10464 }
10465 }
10466
10467 for (i = 0;i < a.NumItem;i++)
10468 {
10469 RPC_CLIENT_ENUM_ACCOUNT_ITEM *t = a.Items[i];
10470 UINT icon;
10471 wchar_t tmp[MAX_SIZE];
10472 wchar_t tmp2[MAX_SIZE];
10473 char tmp3[MAX_SIZE];
10474 wchar_t tmp4[MAX_SIZE];
10475 IP ip;
10476 char ip_str[MAX_SIZE];
10477
10478 // Special treatment in the case of IPv6 address
10479 if (StrToIP6(&ip, t->ServerName) && StartWith(t->ServerName, "[") == false)
10480 {
10481 Format(ip_str, sizeof(ip_str),
10482 "[%s]", t->ServerName);
10483 }
10484 else
10485 {
10486 StrCpy(ip_str, sizeof(ip_str), t->ServerName);
10487 }
10488
10489 // Determine the icon
10490 if (t->Active == false)
10491 {
10492 if (t->StartupAccount == false)
10493 {
10494 icon = ICO_SERVER_OFFLINE;
10495 }
10496 else
10497 {
10498 icon = ICO_SERVER_OFFLINE_EX;
10499 }
10500 }
10501 else
10502 {
10503 num++;
10504 if (t->StartupAccount == false)
10505 {
10506 icon = ICO_SERVER_ONLINE;
10507 }
10508 else
10509 {
10510 icon = ICO_SERVER_ONLINE_EX;
10511 }
10512 }
10513
10514 // Adding
10515 if (easy == false)
10516 {
10517 //CmVLanNameToPrintName(tmp3, sizeof(tmp3), t->DeviceName);
10518 StrCpy(tmp3, sizeof(tmp3), t->DeviceName);
10519 StrToUni(tmp, sizeof(tmp), tmp3);
10520 }
10521 else
10522 {
10523 StrToUni(tmp, sizeof(tmp), t->DeviceName);
10524 }
10525
10526 if (t->Port == 0 || cm->ShowPort == false)
10527 {
10528 // Port number is unknown
10529 UniFormat(tmp2, sizeof(tmp2), L"%S (%s)", ip_str, CmGetProtocolName(t->ProxyType));
10530 }
10531 else
10532 {
10533 // Port number are also shown
10534 UniFormat(tmp2, sizeof(tmp2), L"%S:%u (%s)", ip_str, t->Port, CmGetProtocolName(t->ProxyType));
10535 }
10536
10537 if (LvSearchStr(hWnd, L_ACCOUNT, 0, t->AccountName) == INFINITE)
10538 {
10539 UniStrCpy(new_inserted_item, sizeof(new_inserted_item), t->AccountName);
10540 }
10541
10542 // Virtual HUB name
10543 StrToUni(tmp4, sizeof(tmp4), t->HubName);
10544
10545 if (easy == false)
10546 {
10547 LvInsertAdd(b, icon, (void *)t->StartupAccount, 5, t->AccountName,
10548 t->Active == false ? _UU("CM_ACCOUNT_OFFLINE") :
10549 (t->Connected ? _UU("CM_ACCOUNT_ONLINE") : _UU("CM_ACCOUNT_CONNECTING")),
10550 tmp2, tmp4,
10551 tmp);
10552 }
10553 else
10554 {
10555 LvInsertAdd(b, icon, (void *)t->StartupAccount, 5, t->AccountName,
10556 t->Active == false ? _UU("CM_ACCOUNT_OFFLINE") :
10557 (t->Connected ? _UU("CM_ACCOUNT_ONLINE") : _UU("CM_ACCOUNT_CONNECTING")),
10558 tmp2, tmp4,
10559 tmp);
10560 }
10561
10562 if (t->Active)
10563 {
10564 if (t->Connected)
10565 {
10566 num_connected++;
10567 }
10568 else
10569 {
10570 num_connecting++;
10571 }
10572 }
10573 }
10574
10575 LvInsertEnd(b, hWnd, L_ACCOUNT);
10576
10577 CiFreeClientEnumAccount(&a);
10578
10579 if (select_new_insteted_item)
10580 {
10581 if (UniStrLen(new_inserted_item) >= 1)
10582 {
10583 LvSelect(hWnd, L_ACCOUNT, INFINITE);
10584 LvSelect(hWnd, L_ACCOUNT, LvSearchStr(hWnd, L_ACCOUNT, 0, new_inserted_item));
10585 }
10586 }
10587 }
10588
10589 if (easy == false)
10590 {
10591 // For voice guidance, detect new connection and connection lost
10592 if (cm->UpdateConnectedNumFlag == false)
10593 {
10594 cm->UpdateConnectedNumFlag = true;
10595 cm->OldConnectedNum = num;
10596 }
10597 else
10598 {
10599 if (cm->OldConnectedNum != num)
10600 {
10601 if (cm->OldConnectedNum < num)
10602 {
10603 CmVoice("connect");
10604 }
10605 else
10606 {
10607 CmVoice("disconnect");
10608
10609 if (cm->CmSetting.EasyMode && cm->PositiveDisconnectFlag == false)
10610 {
10611 CmShowEasy();
10612 }
10613
10614 cm->PositiveDisconnectFlag = false;
10615 }
10616 cm->OldConnectedNum = num;
10617 }
10618 }
10619
10620 if (num_connecting == 0 && num_connected == 0)
10621 {
10622 // There is no connecting or connected account
10623 UniStrCpy(tmp, sizeof(tmp), _UU("CM_TRAY_NOT_CONNECTED"));
10624 }
10625 else if (num_connected == 0)
10626 {
10627 // There is only connecting account
10628 UniFormat(tmp, sizeof(tmp), _UU("CM_TRAY_CONNECTED_1"), num_connecting);
10629 }
10630 else if (num_connecting == 0)
10631 {
10632 // There is only connected account
10633 UniFormat(tmp, sizeof(tmp), _UU("CM_TRAY_CONNECTED_2"), num_connected);
10634 }
10635 else
10636 {
10637 // There are both
10638 UniFormat(tmp, sizeof(tmp), _UU("CM_TRAY_CONNECTED_0"), num_connected, num_connecting);
10639 }
10640
10641 if (num_connecting == 0 && num_connected == 0)
10642 {
10643 cm->TrayAnimation = false;
10644 cm->TraySpeedAnimation = false;
10645 }
10646 else
10647 {
10648 cm->TrayAnimation = true;
10649
10650 if (num_connecting == 0)
10651 {
10652 cm->TraySpeedAnimation = false;
10653 }
10654 else
10655 {
10656 cm->TraySpeedAnimation = true;
10657 }
10658 }
10659
10660 CmChangeTrayString(hWnd, tmp);
10661 }
10662
10663 Refresh(hWnd);
10664
10665 //Updated the Jump List
10666 CmUpdateJumpList(0);
10667 }
10668
10669 // Updating the VLAN list
CmRefreshVLanList(HWND hWnd)10670 void CmRefreshVLanList(HWND hWnd)
10671 {
10672 CmRefreshVLanListEx(hWnd, false);
10673 }
CmRefreshVLanListEx(HWND hWnd,bool style_changed)10674 void CmRefreshVLanListEx(HWND hWnd, bool style_changed)
10675 {
10676 RPC_CLIENT_ENUM_VLAN e;
10677 // Validate arguments
10678 if (hWnd == NULL)
10679 {
10680 return;
10681 }
10682
10683 LvSetView(hWnd, L_VLAN, cm->IconView == false);
10684
10685 // Show grid
10686 if (cm->ShowGrid)
10687 {
10688 LvSetStyle(hWnd, L_VLAN, LVS_EX_GRIDLINES);
10689 }
10690 else
10691 {
10692 LvRemoveStyle(hWnd, L_VLAN, LVS_EX_GRIDLINES);
10693 }
10694
10695 if (style_changed)
10696 {
10697 // Change the font
10698 if (cm->VistaStyle)
10699 {
10700 SetFontMeiryo(hWnd, L_VLAN, 9);
10701 }
10702 else
10703 {
10704 SetFontDefault(hWnd, L_VLAN);
10705 }
10706
10707 if (cm->VistaStyle && (cm->IconView == false))
10708 {
10709 LvSetStyle(hWnd, L_VLAN, LVS_EX_FULLROWSELECT);
10710 }
10711 else
10712 {
10713 LvRemoveStyle(hWnd, L_VLAN, LVS_EX_FULLROWSELECT);
10714 }
10715 }
10716
10717 // Enumeration
10718 Zero(&e, sizeof(e));
10719 if (CALL(hWnd, CcEnumVLan(cm->Client, &e)))
10720 {
10721 LVB *b = LvInsertStart();
10722 UINT i;
10723 for (i = 0;i < e.NumItem;i++)
10724 {
10725 wchar_t name[MAX_SIZE];
10726 wchar_t mac[MAX_SIZE];
10727 wchar_t ver[MAX_SIZE];
10728 char str[MAX_SIZE];
10729 wchar_t *status;
10730 RPC_CLIENT_ENUM_VLAN_ITEM *v = e.Items[i];
10731
10732 // Device name
10733 CmVLanNameToPrintName(str, sizeof(str), v->DeviceName);
10734 StrToUni(name, sizeof(name), str);
10735
10736 // Status
10737 status = v->Enabled ? _UU("CM_VLAN_ENABLED") : _UU("CM_VLAN_DISABLED");
10738
10739 // MAC address
10740 StrToUni(mac, sizeof(mac), v->MacAddress);
10741
10742 // Version
10743 StrToUni(ver, sizeof(ver), v->Version);
10744
10745 LvInsertAdd(b, v->Enabled ? ICO_NIC_ONLINE : ICO_NIC_OFFLINE, NULL, 4,
10746 name, status, mac, ver);
10747 }
10748 LvInsertEnd(b, hWnd, L_VLAN);
10749
10750 CiFreeClientEnumVLan(&e);
10751 }
10752 }
10753
10754 // Get a protocol name string
CmGetProtocolName(UINT n)10755 wchar_t *CmGetProtocolName(UINT n)
10756 {
10757 return GetProtocolName(n);
10758 }
10759
10760 // Display update
CmRefresh(HWND hWnd)10761 void CmRefresh(HWND hWnd)
10762 {
10763 CmRefreshEx(hWnd, false);
10764 }
CmRefreshEx(HWND hWnd,bool style_changed)10765 void CmRefreshEx(HWND hWnd, bool style_changed)
10766 {
10767 // Validate arguments
10768 if (hWnd == NULL)
10769 {
10770 return;
10771 }
10772
10773 // Update size
10774 CmMainWindowOnSize(hWnd);
10775
10776 // Updating the VLAN list
10777 CmRefreshVLanListEx(hWnd, style_changed);
10778
10779 // Update the account list
10780 CmRefreshAccountListEx2(hWnd, false, style_changed);
10781
10782 // Update the status bar
10783 CmRefreshStatusBar(hWnd);
10784 }
10785
10786 // Determine whether to check the specified menu item
CmIsChecked(UINT id)10787 bool CmIsChecked(UINT id)
10788 {
10789 switch (id)
10790 {
10791 case CMD_TRAYICON:
10792 return cm->HideTrayIcon == false;
10793 case CMD_STATUSBAR:
10794 return cm->HideStatusBar == false;
10795 case CMD_VISTASTYLE:
10796 return cm->VistaStyle;
10797 case CMD_ICON:
10798 return cm->IconView;
10799 case CMD_DETAIL:
10800 return cm->IconView == false;
10801 case CMD_GRID:
10802 return cm->ShowGrid;
10803 case CMD_VOIDE_NONE:
10804 return cm->DisableVoice;
10805 case CMD_SHOWPORT:
10806 return cm->ShowPort;
10807 case CMD_VOICE_NORMAL:
10808 if (cm->DisableVoice)
10809 {
10810 return false;
10811 }
10812 else
10813 {
10814 return cm->VoiceId == VOICE_SSK;
10815 }
10816 case CMD_VOICE_ODD:
10817 if (cm->DisableVoice)
10818 {
10819 return false;
10820 }
10821 else
10822 {
10823 return cm->VoiceId == VOICE_AHO;
10824 }
10825 }
10826 return false;
10827 }
10828
10829 // The menu popped-up
CmMainWindowOnPopupMenu(HWND hWnd,HMENU hMenu,UINT pos)10830 void CmMainWindowOnPopupMenu(HWND hWnd, HMENU hMenu, UINT pos)
10831 {
10832 UINT num_menu, i, id;
10833 // Validate arguments
10834 if (hWnd == NULL || hMenu == NULL)
10835 {
10836 return;
10837 }
10838
10839 num_menu = GetMenuItemCount(hMenu);
10840 for (i = 0;i < num_menu;i++)
10841 {
10842 id = GetMenuItemID(hMenu, i);
10843
10844 if (id != INFINITE)
10845 {
10846 bool enable_flag = CmIsEnabled(hWnd, id);
10847 bool checked_flag = CmIsChecked(id);
10848 bool bold_flag = CmIsBold(id);
10849 MENUITEMINFO info;
10850
10851 Zero(&info, sizeof(info));
10852 info.cbSize = sizeof(info);
10853 info.fMask = MIIM_STATE;
10854 info.fState = (enable_flag ? MFS_ENABLED : MFS_DISABLED) |
10855 (checked_flag ? MFS_CHECKED : MFS_UNCHECKED) |
10856 (bold_flag ? MFS_DEFAULT : 0);
10857
10858 if (id == CMD_ICON || id == CMD_DETAIL || id == CMD_VOIDE_NONE ||
10859 id == CMD_VOICE_NORMAL || id == CMD_VOICE_ODD)
10860 {
10861 info.fMask |= MIIM_FTYPE;
10862 info.fType = MFT_RADIOCHECK;
10863 }
10864
10865 SetMenuItemInfo(hMenu, id, false, &info);
10866 }
10867
10868 if (id == CMD_RECENT)
10869 {
10870 HMENU sub = CmCreateRecentSubMenu(hWnd, CM_TRAY_MENU_RECENT_ID_START);
10871
10872 if (sub != NULL)
10873 {
10874 DeleteMenu(hMenu, i, MF_BYPOSITION);
10875 MsInsertMenu(hMenu, i, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,
10876 (UINT_PTR)sub, _UU("CM_TRAY_MENU_RECENT"));
10877 }
10878 else
10879 {
10880 MENUITEMINFO info;
10881
10882 Zero(&info, sizeof(info));
10883 info.cbSize = sizeof(info);
10884 info.fMask = MIIM_STATE;
10885 info.fState = MFS_DISABLED;
10886
10887 SetMenuItemInfo(hMenu, id, false, &info);
10888 }
10889 }
10890 }
10891 }
10892
10893 // Set the main window title
CmGenerateMainWindowTitle()10894 wchar_t *CmGenerateMainWindowTitle()
10895 {
10896 wchar_t tmp[MAX_SIZE];
10897 if (cm->server_name == NULL)
10898 {
10899 UniFormat(tmp, sizeof(tmp), L"%s", _UU("CM_TITLE"));
10900 }
10901 else
10902 {
10903 UniFormat(tmp, sizeof(tmp), L"%s - %S", _UU("CM_TITLE"), cm->server_name);
10904 }
10905
10906 return CopyUniStr(tmp);
10907 }
10908
10909 // Initialize the task tray
CmInitTray(HWND hWnd)10910 void CmInitTray(HWND hWnd)
10911 {
10912 bool ret;
10913 // Validate arguments
10914 if (hWnd == NULL)
10915 {
10916 return;
10917 }
10918
10919 if (cm->server_name != NULL)
10920 {
10921 return;
10922 }
10923
10924 if (cm->TrayInited)
10925 {
10926 return;
10927 }
10928
10929 ret = MsShowIconOnTray(hWnd, LoadSmallIcon(CmGetTrayIconId(false, 0)), _UU("CM_TRAY_INITING"), WM_CM_TRAY_MESSAGE);
10930
10931 cm->TrayInited = true;
10932 cm->TrayAnimation = false;
10933 cm->TraySucceed = ret;
10934
10935 SetTimer(hWnd, 2, CM_TRAY_ANIMATION_INTERVAL / 4, NULL);
10936 }
10937
10938 // Change the string in the task tray
CmChangeTrayString(HWND hWnd,wchar_t * str)10939 void CmChangeTrayString(HWND hWnd, wchar_t *str)
10940 {
10941 // Validate arguments
10942 if (hWnd == NULL || str == NULL)
10943 {
10944 return;
10945 }
10946 if (cm->TrayInited == false)
10947 {
10948 return;
10949 }
10950
10951 MsChangeIconOnTray(NULL, str);
10952 }
10953
10954 // Release the task tray
CmFreeTray(HWND hWnd)10955 void CmFreeTray(HWND hWnd)
10956 {
10957 // Validate arguments
10958 if (hWnd == NULL)
10959 {
10960 return;
10961 }
10962
10963 if (cm->TrayInited == false)
10964 {
10965 return;
10966 }
10967
10968 MsHideIconOnTray();
10969
10970 cm->TrayInited = false;
10971 }
CmFreeTrayExternal(void * hWnd)10972 void CmFreeTrayExternal(void *hWnd)
10973 {
10974 CmFreeTray((HWND)hWnd);
10975 }
10976
10977 // Periodical processing to the task tray
CmPollingTray(HWND hWnd)10978 void CmPollingTray(HWND hWnd)
10979 {
10980 UINT interval;
10981 bool ret;
10982 // Validate arguments
10983 if (hWnd == NULL)
10984 {
10985 return;
10986 }
10987
10988 if (cm->TrayInited == false)
10989 {
10990 return;
10991 }
10992
10993 ret = MsChangeIconOnTrayEx(LoadSmallIcon(CmGetTrayIconId(cm->TrayAnimation, cm->TrayAnimationCounter)),
10994 NULL, NULL, NULL, NIIF_NONE, !cm->TraySucceed);
10995
10996 if (cm->TraySucceed == false)
10997 {
10998 cm->TraySucceed = ret;
10999 }
11000
11001 cm->TrayAnimationCounter++;
11002
11003 KillTimer(hWnd, 2);
11004 interval = CM_TRAY_ANIMATION_INTERVAL / 4;
11005 if (cm->TraySpeedAnimation)
11006 {
11007 interval /= 4;
11008 }
11009 SetTimer(hWnd, 2, interval, NULL);
11010 }
11011
11012 // Get the icon ID of the task tray for animation
CmGetTrayIconId(bool animation,UINT animation_counter)11013 UINT CmGetTrayIconId(bool animation, UINT animation_counter)
11014 {
11015 if (animation == false)
11016 {
11017 return ICO_TRAY0;
11018 }
11019 else
11020 {
11021 switch (animation_counter % 4)
11022 {
11023 case 0:
11024 return ICO_TRAY1;
11025
11026 case 1:
11027 return ICO_TRAY2;
11028
11029 case 2:
11030 return ICO_TRAY3;
11031
11032 default:
11033 return ICO_TRAY4;
11034 }
11035 }
11036 }
11037
11038 // Initialize the main window
CmMainWindowOnInit(HWND hWnd)11039 void CmMainWindowOnInit(HWND hWnd)
11040 {
11041 wchar_t *s;
11042 BUF *b;
11043 bool startup_mode = cm->StartupMode;
11044 CM_SETTING a;
11045 bool fake = false;
11046 // Validate arguments
11047 if (hWnd == NULL)
11048 {
11049 return;
11050 }
11051
11052 // Font settings of list
11053 SetFontMeiryo(hWnd, L_ACCOUNT, 9);
11054 SetFontMeiryo(hWnd, L_VLAN, 9);
11055
11056 // Get the configuration of the current vpnclient
11057 Zero(&a, sizeof(a));
11058 CcGetCmSetting(cm->Client, &a);
11059
11060 if (a.EasyMode)
11061 {
11062 fake = true;
11063 }
11064
11065 InitMenuInternational(GetMenu(hWnd), "CM_MENU");
11066
11067 cm->HideStatusBar = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "HideStatusBar");
11068 cm->HideTrayIcon = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "HideTrayIcon");
11069 cm->IconView = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "IconView");
11070 cm->ShowGrid = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "ShowGrid");
11071
11072 if (MsRegIsValue(REG_CURRENT_USER, CM_REG_KEY, "VistaStyle"))
11073 {
11074 cm->VistaStyle = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "VistaStyle");
11075 }
11076 else
11077 {
11078 cm->VistaStyle = MsIsVista();
11079 }
11080
11081 if (MsRegIsValue(REG_CURRENT_USER, CM_REG_KEY, "ShowPort"))
11082 {
11083 cm->ShowPort = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "ShowPort");
11084 }
11085 else
11086 {
11087 cm->ShowPort = false;
11088 }
11089
11090 if (MsRegIsValue(REG_CURRENT_USER, CM_REG_KEY, "DisableVoice"))
11091 {
11092 cm->DisableVoice = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "DisableVoice");
11093 }
11094 else
11095 {
11096 cm->DisableVoice = true;
11097 }
11098 cm->VoiceId = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "VoiceId");
11099
11100 cm->StatusWindowList = NewList(NULL);
11101
11102 SetIcon(hWnd, 0, ICO_VPN);
11103
11104 s = CmGenerateMainWindowTitle();
11105 SetText(hWnd, 0, s);
11106 Free(s);
11107
11108 // Initialize the window position
11109 b = MsRegReadBin(REG_CURRENT_USER, CM_REG_KEY, "WindowPlacement");
11110 if (b != NULL && b->Size == sizeof(WINDOWPLACEMENT))
11111 {
11112 // Restore the window position
11113 WINDOWPLACEMENT *p;
11114 p = ZeroMalloc(b->Size);
11115 Copy(p, b->Buf, b->Size);
11116
11117 if (startup_mode)
11118 {
11119 p->showCmd = SW_SHOWMINIMIZED;
11120 }
11121
11122 if (fake)
11123 {
11124 Copy(&cm->FakeWindowPlacement, p, sizeof(WINDOWPLACEMENT));
11125 }
11126 else
11127 {
11128 SetWindowPlacement(hWnd, p);
11129 }
11130 Free(p);
11131 }
11132 else
11133 {
11134 // Initialize the window position
11135 SetWindowPos(hWnd, NULL, 0, 0, CM_DEFAULT_WIDTH, CM_DEFAULT_HEIGHT, SWP_NOREDRAW);
11136 Center(hWnd);
11137 if (startup_mode)
11138 {
11139 ShowWindow(hWnd, SW_SHOWMINIMIZED);
11140 }
11141
11142 if (fake)
11143 {
11144 WINDOWPLACEMENT p;
11145
11146 Zero(&p, sizeof(p));
11147 p.length = sizeof(p);
11148 GetWindowPlacement(hWnd, &p);
11149 Copy(&cm->FakeWindowPlacement, &p, sizeof(WINDOWPLACEMENT));
11150 }
11151 }
11152 FreeBuf(b);
11153
11154 if (fake)
11155 {
11156 SetWindowPos(hWnd, NULL, -200, -200, 100, 100,
11157 SWP_NOREDRAW | SWP_SHOWWINDOW);
11158 }
11159
11160 // Initialize the status bar related items
11161 cm->hMainWnd = hWnd;
11162 cm->hStatusBar = CreateStatusWindowW(WS_CHILD |
11163 (cm->HideStatusBar == false ? WS_VISIBLE : 0),
11164 _UU("CM_TITLE"),
11165 hWnd, S_STATUSBAR);
11166
11167 UniStrCpy(cm->StatudBar1, sizeof(cm->StatudBar1), _UU("CM_TITLE"));
11168 UniStrCpy(cm->StatudBar2, sizeof(cm->StatudBar2), _UU("CM_CONN_NO"));
11169 UniFormat(cm->StatudBar3, sizeof(cm->StatudBar3), _UU("CM_PRODUCT_NAME"), CEDAR_BUILD);
11170
11171 cm->Icon2 = LoadSmallIcon(ICO_SERVER_OFFLINE);
11172 cm->Icon3 = LoadSmallIcon(ICO_VPN);
11173
11174 // Initialize the account list
11175 CmInitAccountList(hWnd);
11176
11177 // Initialize the VLAN list
11178 CmInitVLanList(hWnd);
11179
11180 // Display update
11181 CmRefreshEx(hWnd, true);
11182
11183 // Start a thread of notification client
11184 CmInitNotifyClientThread();
11185
11186 // Timer setting
11187 SetTimer(hWnd, 1, 128, NULL);
11188 SetTimer(hWnd, 6, 5000, NULL);
11189
11190 // Initialize the task tray
11191 if (cm->server_name == NULL)
11192 {
11193 if (cm->HideTrayIcon == false)
11194 {
11195 CmInitTray(hWnd);
11196 }
11197 }
11198
11199 CmVoice("start");
11200
11201 if (startup_mode || a.EasyMode)
11202 {
11203 SetTimer(hWnd, 3, 1, NULL);
11204 }
11205
11206 if (cm->import_file_name != NULL)
11207 {
11208 // Import a file specified as an argument
11209 CmSendImportMessage(hWnd, cm->import_file_name, cm->CmSettingInitialFlag == CM_SETTING_INIT_NONE ? CM_IMPORT_FILENAME_MSG : CM_IMPORT_FILENAME_MSG_OVERWRITE);
11210 /*if (a.LockMode == false)
11211 {
11212 CmImportAccountMainEx(hWnd, cm->import_file_name, cm->CmSettingInitialFlag != CM_SETTING_INIT_NONE);
11213 }
11214 else
11215 {
11216 MsgBox(cm->hEasyWnd ? cm->hEasyWnd : hWnd, MB_ICONEXCLAMATION, _UU("CM_VPN_FILE_IMPORT_NG"));
11217 }*/
11218 }
11219
11220 // Apply the CM_SETTING
11221 CmApplyCmSetting();
11222
11223 cm->StartupFinished = true;
11224 }
11225
11226 // Start a thread of notification client
CmInitNotifyClientThread()11227 void CmInitNotifyClientThread()
11228 {
11229 cm->NotifyClient = CcConnectNotify(cm->Client);
11230 if (cm->NotifyClient == false)
11231 {
11232 Close(cm->hMainWnd);
11233 exit(0);
11234 }
11235 cm->NotifyClientThread = NewThread(CmNotifyClientThread, NULL);
11236 }
11237
11238 // Notification client thread
CmNotifyClientThread(THREAD * thread,void * param)11239 void CmNotifyClientThread(THREAD *thread, void *param)
11240 {
11241 NOTIFY_CLIENT *nc;
11242 // Validate arguments
11243 if (thread == NULL)
11244 {
11245 return;
11246 }
11247
11248 nc = cm->NotifyClient;
11249
11250 // Wait for the next notification
11251 while (cm->Halt == false)
11252 {
11253 if (CcWaitNotify(nc))
11254 {
11255 // Send a message
11256 PostMessage(cm->hMainWnd, WM_CM_NOTIFY, 0, 0);
11257 }
11258 else
11259 {
11260 // Disconnected
11261 if (cm->Halt == false)
11262 {
11263 if (cm != NULL)
11264 {
11265 CmFreeTrayExternal((void *)cm->hMainWnd);
11266 }
11267 CncExit();
11268 exit(0);
11269 }
11270 break;
11271 }
11272 }
11273 }
11274
11275 // Stop the thread of the notification client
CmFreeNotifyClientThread()11276 void CmFreeNotifyClientThread()
11277 {
11278 cm->Halt = true;
11279
11280 // Disconnect
11281 CcStopNotify(cm->NotifyClient);
11282
11283 // Wait for the termination of the thread
11284 WaitThread(cm->NotifyClientThread, INFINITE);
11285
11286 // Connection termination
11287 CcDisconnectNotify(cm->NotifyClient);
11288 ReleaseThread(cm->NotifyClientThread);
11289 }
11290
11291 // Resize the main window
CmMainWindowOnSize(HWND hWnd)11292 void CmMainWindowOnSize(HWND hWnd)
11293 {
11294 RECT r;
11295 UINT client_width, client_height;
11296 UINT status_height;
11297 // Validate arguments
11298 if (hWnd == NULL)
11299 {
11300 return;
11301 }
11302
11303 // Get the size of the client area of the main window
11304 GetClientRect(hWnd, &r);
11305 client_width = MAX(r.right - r.left, 0);
11306 client_height = MAX(r.bottom - r.top, 0);
11307
11308 SendMsg(hWnd, S_STATUSBAR, WM_SIZE, 0, 0);
11309
11310 // Get the size of the status bar
11311 GetWindowRect(DlgItem(hWnd, S_STATUSBAR), &r);
11312 status_height = MAX(r.bottom - r.top, 0);
11313
11314 if (cm->HideStatusBar == false)
11315 {
11316 client_height = MAX(client_height - status_height, 0);
11317 }
11318
11319 MoveWindow(DlgItem(hWnd, L_ACCOUNT), 0, 0, client_width, client_height * 3 / 5 - 3, true);
11320 MoveWindow(DlgItem(hWnd, L_VLAN), 0, client_height * 3 / 5, client_width, client_height * 2 / 5, true);
11321
11322 // Re-draw the status bar
11323 CmRedrawStatusBar(hWnd);
11324 }
11325
11326 // Disconnect all accounts currently connected
CmDisconnectAll(HWND hWnd)11327 void CmDisconnectAll(HWND hWnd)
11328 {
11329 UINT i, num;
11330 LIST *o;
11331 // Validate arguments
11332 if (hWnd == NULL)
11333 {
11334 return;
11335 }
11336
11337 // Display a warning
11338 num = CmGetNumConnected(hWnd);
11339 if (num == 0)
11340 {
11341 return;
11342 }
11343
11344 if (MsgBoxEx(hWnd, MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DISCONNECT_ALL"), num) == IDNO)
11345 {
11346 return;
11347 }
11348
11349 cm->PositiveDisconnectFlag = true;
11350
11351 // Create a list of connected items
11352 o = NewListFast(NULL);
11353
11354 num = LvNum(hWnd, L_ACCOUNT);
11355 for (i = 0;i < num;i++)
11356 {
11357 wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, i, 1);
11358 if (s != NULL)
11359 {
11360 if (UniStrCmpi(s, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(s, _UU("CM_ACCOUNT_CONNECTING")) == 0)
11361 {
11362 Add(o, LvGetStr(hWnd, L_ACCOUNT, i, 0));
11363 }
11364 Free(s);
11365 }
11366 }
11367
11368 for (i = 0;i < LIST_NUM(o);i++)
11369 {
11370 wchar_t *s = LIST_DATA(o, i);
11371 if (s != NULL)
11372 {
11373 CmDisconnect(hWnd, s);
11374 Free(s);
11375 }
11376 }
11377
11378 ReleaseList(o);
11379 }
11380
11381 // Get a number of currently connected connection settings
CmGetNumConnected(HWND hWnd)11382 UINT CmGetNumConnected(HWND hWnd)
11383 {
11384 UINT i, num, num_active;
11385 // Validate arguments
11386 if (hWnd == NULL)
11387 {
11388 return 0;
11389 }
11390
11391 num_active = 0;
11392 num = LvNum(hWnd, L_ACCOUNT);
11393 for (i = 0;i < num;i++)
11394 {
11395 wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, i, 1);
11396 if (s != NULL)
11397 {
11398 if (UniStrCmpi(s, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(s, _UU("CM_ACCOUNT_CONNECTING")) == 0)
11399 {
11400 num_active++;
11401 }
11402 Free(s);
11403 }
11404 }
11405
11406 return num_active;
11407 }
11408
11409 // Update the status bar information
CmRefreshStatusBar(HWND hWnd)11410 void CmRefreshStatusBar(HWND hWnd)
11411 {
11412 UINT num_active = CmGetNumConnected(hWnd);
11413 // Validate arguments
11414 if (hWnd == NULL)
11415 {
11416 return;
11417 }
11418
11419 if (num_active == 0)
11420 {
11421 UniStrCpy(cm->StatudBar2, sizeof(cm->StatudBar2), _UU("CM_CONN_NO"));
11422 cm->Icon2 = LoadSmallIcon(ICO_SERVER_OFFLINE);
11423 }
11424 else
11425 {
11426 UniFormat(cm->StatudBar2, sizeof(cm->StatudBar2), _UU("CM_NUM_CONN_COUNT"), num_active);
11427 cm->Icon2 = LoadSmallIcon(ICO_SERVER_ONLINE);
11428 }
11429
11430 CmRedrawStatusBar(hWnd);
11431 }
11432
11433 // Re-draw the status bar
CmRedrawStatusBar(HWND hWnd)11434 void CmRedrawStatusBar(HWND hWnd)
11435 {
11436 HWND h;
11437 RECT r;
11438 int width;
11439 int x1, x2, x3;
11440 int xx[3];
11441 wchar_t tmp[MAX_SIZE];
11442 HICON icon;
11443 // Validate arguments
11444 if (hWnd == NULL)
11445 {
11446 return;
11447 }
11448
11449 h = cm->hStatusBar;
11450
11451 // Get the width of the status bar
11452 GetWindowRect(h, &r);
11453 width = MAX(r.right - r.left, 0);
11454 x2 = (UINT)(180.0 * GetTextScalingFactor());
11455 x3 = (UINT)(245.0 * GetTextScalingFactor());
11456 x1 = MAX(width - x2 - x3, 0);
11457
11458 // Divide into three parts
11459 xx[0] = x1;
11460 xx[1] = x2 + x1;
11461 xx[2] = x3 + x2 + x1;
11462 SendMsg(h, 0, SB_SETPARTS, 3, (LPARAM)xx);
11463
11464 // Set an icon
11465 icon = (HICON)SendMsg(h, 0, SB_GETICON, 1, 0);
11466 if (icon != cm->Icon2)
11467 {
11468 SendMsg(h, 0, SB_SETICON, 1, (LPARAM)cm->Icon2);
11469 }
11470
11471 icon = (HICON)SendMsg(h, 0, SB_GETICON, 2, 0);
11472 if (icon != cm->Icon3)
11473 {
11474 SendMsg(h, 0, SB_SETICON, 2, (LPARAM)cm->Icon3);
11475 }
11476
11477 // Set a string
11478 SendMsg(h, 0, SB_GETTEXTW, 0, (LPARAM)tmp);
11479 if (UniStrCmp(tmp, cm->StatudBar1))
11480 {
11481 SendMsg(h, 0, SB_SETTEXTW, 0, (LPARAM)cm->StatudBar1);
11482 }
11483
11484 SendMsg(h, 0, SB_GETTEXTW, 1, (LPARAM)tmp);
11485 if (UniStrCmp(tmp, cm->StatudBar2))
11486 {
11487 SendMsg(h, 0, SB_SETTEXTW, 1, (LPARAM)cm->StatudBar2);
11488 }
11489
11490 SendMsg(h, 0, SB_GETTEXTW, 2, (LPARAM)tmp);
11491 if (UniStrCmp(tmp, cm->StatudBar3))
11492 {
11493 SendMsg(h, 0, SB_SETTEXTW, 2, (LPARAM)cm->StatudBar3);
11494 }
11495 }
11496
11497 // Save the position information of the main window
CmSaveMainWindowPos(HWND hWnd)11498 void CmSaveMainWindowPos(HWND hWnd)
11499 {
11500 WINDOWPLACEMENT p;
11501 // Validate arguments
11502 if (hWnd == NULL)
11503 {
11504 return;
11505 }
11506
11507 // Save settings
11508 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "HideStatusBar", cm->HideStatusBar);
11509 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "HideTrayIcon", cm->HideTrayIcon);
11510 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "IconView", cm->IconView);
11511 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "ShowGrid", cm->ShowGrid);
11512 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "DisableVoice", cm->DisableVoice);
11513 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "VoiceId", cm->VoiceId);
11514 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "VistaStyle", cm->VistaStyle);
11515 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "ShowPort", cm->ShowPort);
11516
11517 // Save the window position
11518 Zero(&p, sizeof(p));
11519 p.length = sizeof(p);
11520 GetWindowPlacement(hWnd, &p);
11521
11522 if (IsZero(&cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement)) == false)
11523 {
11524 Copy(&p, &cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement));
11525 }
11526
11527 MsRegWriteBin(REG_CURRENT_USER, CM_REG_KEY, "WindowPlacement", &p, sizeof(p));
11528
11529 CmSaveAccountListPos(hWnd);
11530 CmSaveVLanListPos(hWnd);
11531 }
11532
11533 // Close the main window
CmMainWindowOnQuit(HWND hWnd)11534 void CmMainWindowOnQuit(HWND hWnd)
11535 {
11536 UINT i;
11537 // Validate arguments
11538 if (hWnd == NULL)
11539 {
11540 return;
11541 }
11542
11543 if (cm->TrayInited)
11544 {
11545 if (MsgBox(hWnd, MB_YESNO | MB_ICONQUESTION,
11546 _UU("CM_EXIT_MESSAGE")) == IDNO)
11547 {
11548 return;
11549 }
11550 }
11551
11552 if (cm->OnCloseDispatched)
11553 {
11554 return;
11555 }
11556 cm->OnCloseDispatched = true;
11557
11558 CmCloseEasy();
11559
11560 // Release the tray icon
11561 CmFreeTray(hWnd);
11562
11563 // Save the position information of the main window
11564 CmSaveMainWindowPos(hWnd);
11565
11566 // Close the status window
11567 for (i = 0;i < LIST_NUM(cm->StatusWindowList);i++)
11568 {
11569 HWND h = LIST_DATA(cm->StatusWindowList, i);
11570 //EndDialog(h, 0);
11571 PostMessage(h, WM_CLOSE, 0, 0);
11572 }
11573
11574 ReleaseList(cm->StatusWindowList);
11575 cm->StatusWindowList = NULL;
11576
11577 if (cm->WindowCount != 0)
11578 {
11579 // Abort
11580 exit(0);
11581 }
11582
11583 // Close
11584 CmFreeNotifyClientThread();
11585
11586 EndDialog(hWnd, false);
11587 }
11588
11589 // Start the mutex to be used in starting
CmStartStartupMutex()11590 bool CmStartStartupMutex()
11591 {
11592 INSTANCE *o = NewSingleInstance(STARTUP_MUTEX_NAME);
11593
11594 if (o == NULL)
11595 {
11596 return false;
11597 }
11598
11599 cm->StartupMutex = o;
11600
11601 return true;
11602 }
11603
11604 // Release the mutex to be used in starting
CmEndStartupMutex()11605 void CmEndStartupMutex()
11606 {
11607 if (cm->StartupMutex != NULL)
11608 {
11609 FreeSingleInstance(cm->StartupMutex);
11610
11611 cm->StartupMutex = NULL;
11612 }
11613 }
11614
11615 // Main window
MainCMWindow()11616 void MainCMWindow()
11617 {
11618 HWND h;
11619 wchar_t *s;
11620 CM_SETTING a;
11621
11622 if (CmStartStartupMutex() == false)
11623 {
11624 return;
11625 }
11626
11627 s = CmGenerateMainWindowTitle();
11628 h = SearchWindow(s);
11629 Free(s);
11630
11631 Zero(&a, sizeof(a));
11632 CcGetCmSetting(cm->Client, &a);
11633 if (cm->server_name != NULL && a.EasyMode)
11634 {
11635 CmEndStartupMutex();
11636 MsgBox(NULL, MB_ICONEXCLAMATION, _UU("CM_EASY_MODE_NOT_ON_REMOTE"));
11637 return;
11638 }
11639
11640 // Change the operating mode
11641 if (cm->CmSettingSupported)
11642 {
11643 if (cm->CmSettingInitialFlag == CM_SETTING_INIT_SELECT)
11644 {
11645 if (h != NULL)
11646 {
11647 CmEndStartupMutex();
11648 }
11649
11650 // Show the selection screen
11651 CmSetting(NULL);
11652
11653 if (h != NULL)
11654 {
11655 goto SEND_MESSAGES;
11656 }
11657 else
11658 {
11659 return;
11660 }
11661 }
11662 else if ((cm->CmSettingInitialFlag == CM_SETTING_INIT_EASY && cm->CmEasyModeSupported) || cm->CmSettingInitialFlag == CM_SETTING_INIT_NORMAL)
11663 {
11664 // State transition
11665 CM_SETTING a;
11666
11667 Zero(&a, sizeof(a));
11668 CcGetCmSetting(cm->Client, &a);
11669
11670 if (cm->CmSettingInitialFlag == CM_SETTING_INIT_EASY)
11671 {
11672 a.EasyMode = true;
11673 }
11674 else
11675 {
11676 a.EasyMode = false;
11677 }
11678
11679 CcSetCmSetting(cm->Client, &a);
11680 }
11681 }
11682
11683 if (h == NULL)
11684 {
11685 // Create a window because there is no window of the same title
11686 if (cm->server_name == NULL)
11687 {
11688 CmInitTryToExecUiHelper();
11689
11690 if (IsDebug() == false)
11691 {
11692 CnWaitForCnServiceReady();
11693 }
11694 }
11695 Dialog(NULL, D_CM_MAIN, CmMainWindowProc, NULL);
11696 CmFreeTryToExecUiHelper();
11697 }
11698 else
11699 {
11700 SEND_MESSAGES:
11701 CmEndStartupMutex();
11702
11703 // If a window of the same title already exists, activate it and exit itself
11704 SetForegroundWindow(h);
11705 SendMessage(h, WM_CM_SHOW, 0, 0);
11706 SetForegroundWindow(h);
11707
11708 if (cm->CmSettingInitialFlag != CM_SETTING_INIT_NONE && cm->CmSettingInitialFlag != CM_SETTING_INIT_CONNECT)
11709 {
11710 // Notify since CM_SETTING has been changed
11711 SendMessage(h, WM_CM_SETTING_CHANGED_MESSAGE, 0, 0);
11712 }
11713
11714 if (cm->import_file_name != NULL)
11715 {
11716 UINT msg;
11717 if (cm->CmSettingInitialFlag == CM_SETTING_INIT_NONE)
11718 {
11719 msg = CM_IMPORT_FILENAME_MSG;
11720 }
11721 else
11722 {
11723 msg = CM_IMPORT_FILENAME_MSG_OVERWRITE;
11724 }
11725
11726 CmSendImportMessage(h, cm->import_file_name, msg);
11727 }
11728 }
11729
11730 CmEndStartupMutex();
11731 }
11732
11733 // Send an import message
CmSendImportMessage(HWND hWnd,wchar_t * filename,UINT msg)11734 void CmSendImportMessage(HWND hWnd, wchar_t *filename, UINT msg)
11735 {
11736 COPYDATASTRUCT cpy;
11737 // Validate arguments
11738 if (hWnd == NULL || filename == NULL)
11739 {
11740 return;
11741 }
11742
11743 // Specify the file to be imported
11744 Zero(&cpy, sizeof(cpy));
11745
11746 cpy.cbData = UniStrSize(filename);
11747 cpy.lpData = filename;
11748 cpy.dwData = msg;
11749
11750 SendMessage(hWnd, WM_COPYDATA, 0, (LPARAM)&cpy);
11751 }
11752
11753 // Login dialog
CmLoginDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)11754 UINT CmLoginDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
11755 {
11756 // Validate arguments
11757 wchar_t server_name[MAX_SIZE];
11758 char password[MAX_PASSWORD_LEN + 1];
11759 bool bad_pass;
11760 if (hWnd == NULL)
11761 {
11762 return 0;
11763 }
11764
11765 switch (msg)
11766 {
11767 case WM_INITDIALOG:
11768 if (cm->server_name != NULL)
11769 {
11770 StrToUni(server_name, sizeof(server_name), cm->server_name);
11771 }
11772 else
11773 {
11774 UniStrCpy(server_name, sizeof(server_name), _UU("CM_PW_LOCALMACHINE"));
11775 }
11776 FormatText(hWnd, S_TITLE, server_name);
11777 break;
11778
11779 case WM_COMMAND:
11780 switch (wParam)
11781 {
11782 case IDOK:
11783 if (cm->server_name != NULL)
11784 {
11785 StrToUni(server_name, sizeof(server_name), cm->server_name);
11786 }
11787 else
11788 {
11789 UniStrCpy(server_name, sizeof(server_name), _UU("CM_PW_LOCALMACHINE"));
11790 }
11791 GetTxtA(hWnd, E_PASSWORD, password, sizeof(password));
11792 cm->Client = CcConnectRpc(cm->server_name == NULL ? "127.0.0.1" : cm->server_name,
11793 password, &bad_pass, NULL, 0);
11794 if (cm->Client == NULL)
11795 {
11796 MsgBox(hWnd, MB_ICONSTOP, _UU("CM_BAD_PASSWORD"));
11797 FocusEx(hWnd, E_PASSWORD);
11798 }
11799 else
11800 {
11801 EndDialog(hWnd, true);
11802 }
11803 break;
11804 case IDCANCEL:
11805 Close(hWnd);
11806 break;
11807 }
11808 break;
11809
11810 case WM_CLOSE:
11811 EndDialog(hWnd, false);
11812 break;
11813 }
11814
11815 return 0;
11816 }
11817
11818 // Login
LoginCM()11819 bool LoginCM()
11820 {
11821 // Try to login with an empty password first
11822 bool bad_pass, no_remote;
11823 wchar_t server_name[MAX_SIZE];
11824 RPC_CLIENT_VERSION a;
11825
11826 RETRY:
11827 if (cm->server_name != NULL)
11828 {
11829 StrToUni(server_name, sizeof(server_name), cm->server_name);
11830 }
11831 else
11832 {
11833 UniStrCpy(server_name, sizeof(server_name), _UU("CM_PW_LOCALMACHINE"));
11834 }
11835
11836 // Attempt to connect
11837 if ((cm->Client = CcConnectRpc(
11838 cm->server_name == NULL ? "localhost" : cm->server_name,
11839 cm->password == NULL ? "" : cm->password, &bad_pass, &no_remote, cm->StartupMode == false ? 0 : 60000)) == NULL)
11840 {
11841 if (no_remote)
11842 {
11843 // Remote connection was denied
11844 if (MsgBoxEx(NULL, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("CM_NO_REMOTE"), server_name) == IDRETRY)
11845 {
11846 // Retry
11847 goto RETRY;
11848 }
11849 else
11850 {
11851 return false;
11852 }
11853 }
11854 else if (bad_pass)
11855 {
11856 if (Dialog(NULL, D_CM_LOGIN, CmLoginDlgProc, NULL) == false)
11857 {
11858 return false;
11859 }
11860 }
11861 else
11862 {
11863 // Connection failure
11864 if (cm->StartupMode == false && MsgBoxEx(NULL, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("CM_CONNECT_FAILED"), server_name) == IDRETRY)
11865 {
11866 // Retry
11867 goto RETRY;
11868 }
11869 else
11870 {
11871 return false;
11872 }
11873 }
11874 }
11875
11876 Zero(&a, sizeof(a));
11877 CcGetClientVersion(cm->Client, &a);
11878 if (a.ClientBuildInt >= 5192)
11879 {
11880 cm->CmSettingSupported = true;
11881 cm->CmEasyModeSupported = true;
11882 if (OS_IS_WINDOWS_9X(a.OsType))
11883 {
11884 cm->CmEasyModeSupported = false;
11885 }
11886 }
11887
11888 return true;
11889 }
11890
11891 // Main process
MainCM()11892 void MainCM()
11893 {
11894 // If there is /remote in the argument, show the screen of the remote connection
11895 TOKEN_LIST *cmdline = GetCommandLineToken();
11896
11897 UINT i = 0;
11898 bool isRemote = false;
11899
11900 if (cm->server_name != NULL)
11901 {
11902 Free(cm->server_name);
11903 }
11904 cm->server_name = NULL;
11905
11906 if (cm->password != NULL)
11907 {
11908 Free(cm->password);
11909 }
11910 cm->password = NULL;
11911
11912 for(i = 0; i < cmdline->NumTokens; ++i)
11913 {
11914 if (StrCmpi(cmdline->Token[i], "/remote") == 0)
11915 {
11916 isRemote = true;
11917 }
11918 else if (StrCmpi(cmdline->Token[i], "/hostname") == 0 && i + 1 < cmdline->NumTokens)
11919 {
11920 isRemote = true;
11921 if (cm->server_name != NULL)
11922 {
11923 Free(cm->server_name);
11924 }
11925 cm->server_name = CopyStr(cmdline->Token[++i]);
11926 }
11927 else if (StrCmpi(cmdline->Token[i], "/password") == 0 && i + 1 < cmdline->NumTokens)
11928 {
11929 if (cm->password != NULL)
11930 {
11931 Free(cm->password);
11932 }
11933 cm->password = CopyStr(cmdline->Token[++i]);
11934 }
11935 else if (StrCmpi(cmdline->Token[i], "/startup") == 0)
11936 {
11937 // Startup mode
11938 cm->StartupMode = true;
11939 }
11940 }
11941
11942 if (isRemote && cm->server_name == NULL)
11943 {
11944 char *hostname = RemoteDlg(NULL, CM_REG_KEY, ICO_VPN, _UU("CM_TITLE"), _UU("CM_REMOTE_TITLE"), NULL);
11945 if (hostname == NULL)
11946 {
11947 return;
11948 }
11949 if (cm->server_name != NULL)
11950 {
11951 Free(cm->server_name);
11952 }
11953 cm->server_name = NULL;
11954 if (StrCmpi(hostname, "localhost") != 0 && StrCmpi(hostname, "127.0.0.1") != 0 )
11955 {
11956 cm->server_name = hostname;
11957 }
11958 }
11959
11960 FreeToken(cmdline);
11961
11962 if (IsZero(cm->ShortcutKey, SHA1_SIZE) == false)
11963 {
11964 //if (MsGetCurrentTerminalSessionId() == 0)
11965 {
11966 // Start the shortcut connection
11967 CmConnectShortcut(cm->ShortcutKey);
11968 }/*
11969 else
11970 {
11971 MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("CM_SHORTCUT_DESKTOP_MSG"),
11972 MsGetCurrentTerminalSessionId());
11973 }*/
11974 return;
11975 }
11976
11977 // Login
11978 if (LoginCM() == false)
11979 {
11980 return;
11981 }
11982
11983 //Update the jump list
11984 CmUpdateJumpList(0);
11985
11986 // Main window
11987 MainCMWindow();
11988
11989 // Log out
11990 LogoutCM();
11991
11992 if (cm->Update != NULL)
11993 {
11994 FreeUpdateUi(cm->Update);
11995 cm->Update = NULL;
11996 }
11997 }
11998
11999 // Log out
LogoutCM()12000 void LogoutCM()
12001 {
12002 if (cm->Client != NULL)
12003 {
12004 CcDisconnectRpc(cm->Client);
12005 }
12006 }
12007
12008 // Client Connection Manager start function
CMExec()12009 void CMExec()
12010 {
12011 // Initialize
12012 InitCM(true);
12013
12014 // Main process
12015 MainCM();
12016
12017 // Release
12018 FreeCM();
12019 }
12020
12021 // HUB enumeration thread
CmEnumHubThread(THREAD * t,void * param)12022 void CmEnumHubThread(THREAD *t, void *param)
12023 {
12024 CM_ENUM_HUB *e = (CM_ENUM_HUB *)param;
12025 HWND hWnd;
12026 // Validate arguments
12027 if (t == NULL || param == NULL)
12028 {
12029 return;
12030 }
12031
12032 e->Thread = t;
12033 hWnd = e->hWnd;
12034 LockList(cm->EnumHubList);
12035 {
12036 Add(cm->EnumHubList, e);
12037 }
12038 UnlockList(cm->EnumHubList);
12039
12040 // Thread initialization is completed
12041 NoticeThreadInit(t);
12042
12043 // Create a session
12044 e->Session = NewRpcSession(cm->Cedar, e->ClientOption);
12045 if (e->Session)
12046 {
12047 // Enumeration of HUB
12048 e->Hub = EnumHub(e->Session);
12049
12050 if (e->Hub != NULL)
12051 {
12052 // Enumeration completed
12053 // Add to the combo box
12054 if (CbNum(hWnd, C_HUBNAME) == 0)
12055 {
12056 UINT i;
12057 wchar_t tmp[MAX_SIZE];
12058 for (i = 0;i < e->Hub->NumTokens;i++)
12059 {
12060 StrToUni(tmp, sizeof(tmp), e->Hub->Token[i]);
12061 CbAddStr(hWnd, C_HUBNAME, tmp, 0);
12062 }
12063 }
12064
12065 // Release the memory
12066 FreeToken(e->Hub);
12067 }
12068
12069 // Release the session
12070 ReleaseSession(e->Session);
12071 }
12072
12073 LockList(cm->EnumHubList);
12074 {
12075 Delete(cm->EnumHubList, e);
12076 }
12077 UnlockList(cm->EnumHubList);
12078
12079 Free(e->ClientOption);
12080 Free(e);
12081 }
12082
12083 // The start of the HUB enumeration
CmEnumHubStart(HWND hWnd,CLIENT_OPTION * o)12084 void CmEnumHubStart(HWND hWnd, CLIENT_OPTION *o)
12085 {
12086 CM_ENUM_HUB *e;
12087 THREAD *t;
12088 // Validate arguments
12089 if (hWnd == NULL || o == NULL)
12090 {
12091 return;
12092 }
12093
12094 if (StrLen(o->Hostname) == 0 ||
12095 o->Port == 0)
12096 {
12097 return;
12098 }
12099
12100 if (o->ProxyType != PROXY_DIRECT)
12101 {
12102 if (StrLen(o->ProxyName) == 0 ||
12103 o->ProxyPort == 0)
12104 {
12105 return;
12106 }
12107 }
12108
12109 if (LvNum(hWnd, C_HUBNAME) != 0)
12110 {
12111 return;
12112 }
12113
12114 e = ZeroMalloc(sizeof(CM_ENUM_HUB));
12115 e->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
12116 e->hWnd = hWnd;
12117 Copy(e->ClientOption, o, sizeof(CLIENT_OPTION));
12118
12119 t = NewThread(CmEnumHubThread, e);
12120 WaitThreadInit(t);
12121 ReleaseThread(t);
12122 }
12123
12124 // Initialize the HUB enumeration process
CmInitEnumHub()12125 void CmInitEnumHub()
12126 {
12127 cm->EnumHubList = NewList(NULL);
12128 }
12129
12130 // Release the HUB enumeration process
CmFreeEnumHub()12131 void CmFreeEnumHub()
12132 {
12133 LIST *o;
12134 UINT i;
12135 if (cm->EnumHubList == NULL)
12136 {
12137 return;
12138 }
12139
12140 o = NewList(NULL);
12141 LockList(cm->EnumHubList);
12142 {
12143 UINT i;
12144 for (i = 0;i < LIST_NUM(cm->EnumHubList);i++)
12145 {
12146 CM_ENUM_HUB *e = LIST_DATA(cm->EnumHubList, i);
12147 Add(o, e->Thread);
12148 AddRef(e->Thread->ref);
12149 }
12150 }
12151 UnlockList(cm->EnumHubList);
12152
12153 for (i = 0;i < LIST_NUM(o);i++)
12154 {
12155 THREAD *t = LIST_DATA(o, i);
12156 WaitThread(t, INFINITE);
12157 ReleaseThread(t);
12158 }
12159 ReleaseList(o);
12160
12161 ReleaseList(cm->EnumHubList);
12162 }
12163
12164 // Initialize the Client Connection Manager
12165
InitCM(bool set_app_id)12166 void InitCM(bool set_app_id)
12167 {
12168 UNI_TOKEN_LIST *ut;
12169 if (cm != NULL)
12170 {
12171 return;
12172 }
12173
12174 if (set_app_id)
12175 {
12176 if(JL_SetCurrentProcessExplicitAppUserModelID(APPID_CM) != S_OK)
12177 {
12178 }
12179 }
12180
12181 CmDeleteOldStartupTrayFile();
12182
12183 MsSetShutdownParameters(0x4ff, SHUTDOWN_NORETRY);
12184
12185 // Memory allocation
12186 cm = ZeroMalloc(sizeof(CM));
12187
12188 // If the command line argument is set treat it as a server name
12189 ut = GetCommandLineUniToken();
12190
12191 if (ut->NumTokens >= 1)
12192 {
12193 if (UniStrLen(ut->Token[0]) != 0)
12194 {
12195 if (UniStrCmpi(ut->Token[0], L"cm") != 0 && ut->Token[0][0] != L'/')
12196 {
12197 BUF *b = UniStrToBin(ut->Token[0]);
12198 if (b->Size == SHA1_SIZE)
12199 {
12200 // Treated as a shortcut key for the connection settings
12201 Copy(cm->ShortcutKey, b->Buf, SHA1_SIZE);
12202 }
12203 else
12204 {
12205 if (UniEndWith(ut->Token[0], L".vpn") == false)
12206 {
12207 // Treated as a server name
12208 cm->server_name = CopyUniToStr(ut->Token[0]);
12209 }
12210 else
12211 {
12212 // Treated as import file name
12213 cm->import_file_name = CopyUniStr(ut->Token[0]);
12214 }
12215 }
12216 FreeBuf(b);
12217 }
12218 else if (UniStrCmpi(ut->Token[0], L"/easy") == 0)
12219 {
12220 // Simple mode
12221 if (ut->NumTokens >= 2)
12222 {
12223 // Connection settings to be imported is specified
12224 cm->import_file_name = CopyUniStr(ut->Token[1]);
12225 }
12226
12227 cm->CmSettingInitialFlag = CM_SETTING_INIT_EASY;
12228 }
12229 else if (UniStrCmpi(ut->Token[0], L"/normal") == 0)
12230 {
12231 // Normal mode
12232 if (ut->NumTokens >= 2)
12233 {
12234 // Connection settings to be imported is specified
12235 cm->import_file_name = CopyUniStr(ut->Token[1]);
12236 }
12237
12238 cm->CmSettingInitialFlag = CM_SETTING_INIT_NORMAL;
12239 }
12240 else if (UniStrCmpi(ut->Token[0], L"/connect") == 0)
12241 {
12242 // Import process by the simple installer
12243 if (ut->NumTokens >= 2)
12244 {
12245 // Connection settings to be imported is specified
12246 cm->import_file_name = CopyUniStr(ut->Token[1]);
12247 }
12248
12249 cm->CmSettingInitialFlag = CM_SETTING_INIT_CONNECT;
12250 }
12251 else if (UniStrCmpi(ut->Token[0], L"/select") == 0)
12252 {
12253 // Selection screen
12254 cm->CmSettingInitialFlag = CM_SETTING_INIT_SELECT;
12255 }
12256 }
12257 }
12258
12259 UniFreeToken(ut);
12260
12261 InitWinUi(_UU("CM_TITLE"), _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE"));
12262
12263 // Alpha blending related
12264 UseAlpha = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "UseAlpha");
12265 AlphaValue = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "AlphaValue");
12266
12267 cm->Cedar = NewCedar(NULL, NULL);
12268 CmInitEnumHub();
12269 }
12270
12271 // Stop the Client Connection Manager
FreeCM()12272 void FreeCM()
12273 {
12274 if (cm == NULL)
12275 {
12276 return;
12277 }
12278
12279 CmFreeEnumHub();
12280 ReleaseCedar(cm->Cedar);
12281
12282 FreeWinUi();
12283
12284 // Release the memory
12285 if (cm->server_name != NULL)
12286 {
12287 Free(cm->server_name);
12288 }
12289 Free(cm);
12290 cm = NULL;
12291 }
12292
12293
12294
12295 //////////////////////////////////////////////////////////////////////////
12296 //JumpList ToDo
12297 // By Takao Ito
CmUpdateJumpList(UINT start_id)12298 void *CmUpdateJumpList(UINT start_id)
12299 {
12300 HMENU h = NULL;
12301 UINT i;
12302 RPC_CLIENT_ENUM_ACCOUNT a;
12303 LIST *o;
12304 bool easy;
12305
12306 JL_PCustomDestinationList pcdl;
12307 JL_PObjectCollection poc;
12308 JL_PShellLink shell;
12309 JL_PObjectArray poaRemoved;
12310
12311 HRESULT hr;
12312
12313 if (cm->server_name != NULL)
12314 {
12315 // Is not used in the case of an external PC
12316 return NULL;
12317 }
12318
12319 //Try to add
12320 if(SUCCEEDED(JL_CreateCustomDestinationList(&pcdl,APPID_CM)))
12321 {
12322
12323 JL_DeleteJumpList(pcdl,APPID_CM);
12324
12325 easy = cm->CmSetting.EasyMode;
12326
12327 Zero(&a, sizeof(a));
12328
12329
12330 if (CcEnumAccount(cm->Client, &a) == ERR_NO_ERROR)
12331 {
12332 o = NewListFast(CiCompareClientAccountEnumItemByLastConnectDateTime);
12333
12334 for (i = 0;i < a.NumItem;i++)
12335 {
12336 RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = a.Items[i];
12337
12338 item->tmp1 = i;
12339
12340 if (item->LastConnectDateTime != 0)
12341 {
12342 Add(o, item);
12343 }
12344 }
12345
12346 Sort(o);
12347
12348 if(LIST_NUM(o) > 0)
12349 {
12350
12351 if(SUCCEEDED(JL_BeginList(pcdl, &poaRemoved)))
12352 {
12353
12354
12355 //Create a collection
12356 if(SUCCEEDED(JL_CreateObjectCollection(&poc)))
12357 {
12358
12359 for (i = 0;i < MIN(LIST_NUM(o), CM_NUM_RECENT);i++)
12360 {
12361
12362 RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = (RPC_CLIENT_ENUM_ACCOUNT_ITEM *)LIST_DATA(o, i);
12363 // wchar_t tmp[MAX_PATH];
12364 wchar_t *account_name;
12365 char *server_name;
12366 char *hub_name;
12367 // CM_ACCOUNT *a;
12368 UCHAR key[SHA1_SIZE];
12369 RPC_CLIENT_GET_ACCOUNT c;
12370
12371
12372 account_name = item->AccountName;
12373 server_name = item->ServerName;
12374 hub_name = item->HubName;
12375
12376
12377
12378 //
12379 //a = CmGetExistAccountObject(hWnd, account_name);
12380
12381
12382 //if (a == NULL)
12383 //{
12384 //continue;
12385 //}
12386
12387 //Copy(key, a->ShortcutKey, SHA1_SIZE);
12388 //
12389
12390 Zero(&c, sizeof(c));
12391 UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);
12392 if (CALL(NULL, CcGetAccount(cm->Client, &c)) == false)
12393 {
12394 break;
12395 }
12396
12397 Copy(key, c.ShortcutKey, SHA1_SIZE);
12398
12399 if (IsZero(key, SHA1_SIZE))
12400 {
12401 //MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_SHORTCUT_UNSUPPORTED"));
12402 }
12403 else
12404 {
12405
12406 //wchar_t target[MAX_PATH];
12407 ////wchar_t workdir[MAX_PATH];
12408 //wchar_t args[MAX_PATH];
12409 ////wchar_t comment[MAX_SIZE];
12410 //wchar_t icon[MAX_PATH];
12411
12412 char key_str[64];
12413 wchar_t target[MAX_PATH];
12414 //wchar_t workdir[MAX_PATH];
12415 wchar_t args[MAX_PATH];
12416 wchar_t commentW[MAX_SIZE];
12417 wchar_t icon[MAX_PATH];
12418 int iconNum;
12419
12420 //char icon = "C:\\Server.ico";
12421
12422 BinToStr(key_str, sizeof(key_str), key, SHA1_SIZE);
12423 UniStrCpy(target, sizeof(target), MsGetExeFileNameW());
12424 StrToUni(args, sizeof(args), key_str);
12425 UniStrCpy(icon, sizeof(icon), MsGetExeFileNameW());
12426 UniFormat(commentW, sizeof(commentW), _UU("CM_SHORTCUT_COMMENT"), account_name);
12427
12428 if(item->Connected)
12429 {
12430 iconNum = 1;
12431 }
12432 else
12433 {
12434 iconNum = 2;
12435 }
12436
12437 hr = JL_CreateShellLink(
12438 target,
12439 args,
12440 account_name,
12441 icon,iconNum,
12442 commentW,
12443 &shell);
12444
12445 if(SUCCEEDED(hr))
12446 {
12447
12448 if(SUCCEEDED(JL_ObjectCollectionAddShellLink(poc, shell)))
12449 {
12450 //Print("Add JumpList %d c:%s\n",i, comment);
12451 //wprintf(comment);
12452 }
12453 JL_ReleaseShellLink(shell);
12454 }
12455 }
12456
12457 CiFreeClientGetAccount(&c);
12458 }
12459
12460 hr = JL_AddCategoryToList(pcdl,poc,_UU("CM_JUMPLIST_RCCONNECT"),poaRemoved);
12461
12462 if(SUCCEEDED(hr))
12463 {
12464 //wprintf(L"AddCategory\n");
12465
12466 hr = JL_CommitList(pcdl);
12467 if(SUCCEEDED(hr))
12468 {
12469 //wprintf(L"JumpList Commit\n");
12470 }
12471 }
12472 else
12473 {
12474 //wprintf(L"Erro JumpList AddCategory %x\n", hr);
12475 }
12476
12477 //Release
12478 JL_ReleaseObjectCollection(poc);
12479 }
12480 }
12481
12482 }
12483
12484
12485 ReleaseList(o);
12486
12487 CiFreeClientEnumAccount(&a);
12488 }
12489
12490
12491
12492
12493 /*
12494 JL_BeginList(pcdl, &poaRemoved);
12495
12496 JL_CreateObjectCollection(&poc);
12497
12498 // Tesht
12499 for (i = 0; i < 5; i++)
12500 {
12501
12502 JL_CreateShellLink(
12503 "",
12504 "",
12505 L"Connect",
12506 NULL,0,
12507 NULL,
12508 &shell);
12509 JL_ObjectCollectionAddShellLink(poc, shell);
12510
12511 JL_ReleaseShellLink(shell);
12512
12513 }
12514
12515 JL_AddCategoryToList(pcdl,poc,_UU("CM_JUMPLIST_RCCONNECT"),poaRemoved);
12516 JL_CommitList(pcdl);
12517 JL_ReleaseObjectCollection(poc);
12518
12519 JL_ReleaseCustomDestinationList(pcdl);
12520 */
12521
12522 }
12523
12524 return h;
12525 }
12526
12527
12528
12529 #endif // WIN32
12530
12531
12532