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