* tar xzf utvpn-src-unix-v101-7101-public-2010.06.27.tar.gz
[lab.git] / utvpn / utvpn-unix-v101-7101-public / src / Cedar / CM.c
1 // SoftEther UT-VPN SourceCode\r
2 // \r
3 // Copyright (C) 2004-2010 SoftEther Corporation.\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.\r
6 // All Rights Reserved.\r
7 // \r
8 // http://utvpn.tsukuba.ac.jp/\r
9 // \r
10 // This program is free software; you can redistribute it and/or\r
11 // modify it under the terms of the GNU General Public License\r
12 // version 2 as published by the Free Software Foundation.\r
13 // \r
14 // This program is distributed in the hope that it will be useful,\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
17 // GNU General Public License for more details.\r
18 // \r
19 // You should have received a copy of the GNU General Public License version 2\r
20 // along with this program; if not, write to the Free Software\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
22 // \r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。\r
28 // \r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって\r
32 // ホストされています。\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、\r
34 // および、試験または研究のために利用が行われることを想定して配布\r
35 // しています。\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に\r
37 // あります。\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース\r
42 // に組み込みさせていただきます。\r
43 // \r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。\r
46 // \r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意\r
51 // ください。\r
52 // \r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、\r
58 // 公益保護にご協力いただきますようお願い申し上げます。\r
59 // \r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客\r
62 // を保護するための努力を行います。\r
63 // \r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/\r
65 // 日本国内の脆弱性情報届出受付公的機関:\r
66 //         独立行政法人 情報処理推進機構\r
67 //         http://www.ipa.go.jp/security/vuln/report/\r
68 // \r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/\r
71 \r
72 // -----------------------------------------------\r
73 // [ChangeLog]\r
74 // 2010.05.20\r
75 //  新規リリース by SoftEther\r
76 // -----------------------------------------------\r
77 \r
78 // CM.c\r
79 // Win32 用 SoftEther UT-VPN クライアント接続マネージャ\r
80 \r
81 \r
82 #ifdef  WIN32\r
83 \r
84 #define CM_C\r
85 #define SM_C\r
86 #define MICROSOFT_C\r
87 \r
88 #define _WIN32_WINNT            0x0502\r
89 #define WINVER                          0x0502\r
90 #include <winsock2.h>\r
91 #include <windows.h>\r
92 #include <Iphlpapi.h>\r
93 #include <tlhelp32.h>\r
94 #include <shlobj.h>\r
95 #include <commctrl.h>\r
96 #include <Dbghelp.h>\r
97 #include <setupapi.h>\r
98 #include <regstr.h>\r
99 #include <process.h>\r
100 #include <psapi.h>\r
101 #include <wtsapi32.h>\r
102 #include <stdio.h>\r
103 #include <stdlib.h>\r
104 #include <string.h>\r
105 #include <wchar.h>\r
106 #include <stdarg.h>\r
107 #include <time.h>\r
108 #include <errno.h>\r
109 #include <Mayaqua/Mayaqua.h>\r
110 #include <Cedar/Cedar.h>\r
111 #include "CMInner.h"\r
112 #include "SMInner.h"\r
113 #include "NMInner.h"\r
114 #include "../PenCore/resource.h"\r
115 \r
116 // IE のレジストリ文字列からプロキシサーバーの設定を取得する\r
117 bool CmGetProxyServerNameAndPortFromIeProxyRegStr(char *name, UINT name_size, UINT *port, char *str, char *server_type)\r
118 {\r
119         TOKEN_LIST *t;\r
120         UINT i;\r
121         bool ret = false;\r
122         // 引数チェック\r
123         if (name == NULL || port == NULL || str == NULL || server_type == NULL)\r
124         {\r
125                 return false;\r
126         }\r
127 \r
128         t = ParseToken(str, ";");\r
129 \r
130         for (i = 0;i < t->NumTokens;i++)\r
131         {\r
132                 char *s = t->Token[i];\r
133                 UINT i;\r
134 \r
135                 Trim(s);\r
136 \r
137                 i = SearchStrEx(s, "=", 0, false);\r
138                 if (i != INFINITE)\r
139                 {\r
140                         char tmp[MAX_PATH];\r
141 \r
142                         StrCpy(name, name_size, s);\r
143                         name[i] = 0;\r
144 \r
145                         if (StrCmpi(name, server_type) == 0)\r
146                         {\r
147                                 char *host;\r
148                                 StrCpy(tmp, sizeof(tmp), s + i + 1);\r
149 \r
150                                 if (ParseHostPort(tmp, &host, port, 0))\r
151                                 {\r
152                                         StrCpy(name, name_size, host);\r
153                                         Free(host);\r
154 \r
155                                         if (*port != 0)\r
156                                         {\r
157                                                 ret = true;\r
158                                         }\r
159                                         break;\r
160                                 }\r
161                         }\r
162                 }\r
163         }\r
164 \r
165         FreeToken(t);\r
166 \r
167         return ret;\r
168 }\r
169 \r
170 \r
171 // 接続設定にプロキシ設定の内容を反映する\r
172 void CmProxyDlgSet(HWND hWnd, CLIENT_OPTION *o, CM_INTERNET_SETTING *setting)\r
173 {\r
174         // 引数チェック\r
175         if(hWnd == NULL || setting == NULL)\r
176         {\r
177                 return;\r
178         }\r
179 \r
180         // チェックをつける\r
181         Check(hWnd, R_DIRECT_TCP,       setting->ProxyType == PROXY_DIRECT);\r
182         Check(hWnd, R_HTTPS,            setting->ProxyType == PROXY_HTTP);\r
183         Check(hWnd, R_SOCKS,            setting->ProxyType == PROXY_SOCKS);\r
184 \r
185         // Proxy 設定\r
186         if(setting->ProxyType != PROXY_DIRECT)\r
187         {\r
188                 StrCpy(o->ProxyName, sizeof(setting->ProxyHostName), setting->ProxyHostName);\r
189                 o->ProxyPort = setting->ProxyPort;\r
190         }\r
191 }\r
192 \r
193 // IE のプロキシ設定を取得する\r
194 void CmGetSystemInternetSetting(CM_INTERNET_SETTING *setting)\r
195 {\r
196         bool use_proxy;\r
197         // 引数チェック\r
198         if (setting == NULL)\r
199         {\r
200                 return;\r
201         }\r
202 \r
203         Zero(setting, sizeof(CM_INTERNET_SETTING));\r
204 \r
205         use_proxy = MsRegReadInt(REG_CURRENT_USER,\r
206                 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",\r
207                 "ProxyEnable");\r
208 \r
209         if (use_proxy)\r
210         {\r
211                 char *str = MsRegReadStr(REG_CURRENT_USER,\r
212                         "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",\r
213                         "ProxyServer");\r
214                 if (str != NULL)\r
215                 {\r
216                         char name[MAX_HOST_NAME_LEN + 1];\r
217                         UINT port;\r
218 \r
219                         if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),\r
220                                 &port, str, "https"))\r
221                         {\r
222                                 setting->ProxyType = PROXY_HTTP;\r
223                                 StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);\r
224                                 setting->ProxyPort = port;\r
225                         }\r
226                         else if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),\r
227                                 &port, str, "http"))\r
228                         {\r
229                                 setting->ProxyType = PROXY_HTTP;\r
230                                 StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);\r
231                                 setting->ProxyPort = port;\r
232                         }\r
233                         else if (CmGetProxyServerNameAndPortFromIeProxyRegStr(name, sizeof(name),\r
234                                 &port, str, "socks"))\r
235                         {\r
236                                 setting->ProxyType = PROXY_SOCKS;\r
237                                 StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), name);\r
238                                 setting->ProxyPort = port;\r
239                         }\r
240                         else\r
241                         {\r
242                                 if (SearchStrEx(str, "=", 0, false) == INFINITE)\r
243                                 {\r
244                                         char *host;\r
245                                         UINT port;\r
246                                         if (ParseHostPort(str, &host, &port, 0))\r
247                                         {\r
248                                                 if (port != 0)\r
249                                                 {\r
250                                                         setting->ProxyType = PROXY_HTTP;\r
251                                                         StrCpy(setting->ProxyHostName, sizeof(setting->ProxyHostName), host);\r
252                                                         setting->ProxyPort = port;\r
253                                                 }\r
254                                                 Free(host);\r
255                                         }\r
256                                 }\r
257                         }\r
258 \r
259                         Free(str);\r
260                 }\r
261         }\r
262 }\r
263 \r
264 // 経由するプロキシ設定で、IE の設定を使用する\r
265 void CmProxyDlgUseForIE(HWND hWnd, CLIENT_OPTION *o)\r
266 {\r
267         CM_INTERNET_SETTING s;\r
268 \r
269         // 引数チェック\r
270         if(hWnd == NULL)\r
271         {\r
272                 return;\r
273         }\r
274 \r
275         Zero(&s, sizeof(s));\r
276         CmGetSystemInternetSetting(&s);\r
277         \r
278         CmProxyDlgSet(hWnd, o, &s);\r
279 }\r
280 \r
281 // スマートカード認証画面のビットマップ ID を決定する\r
282 UINT CmGetSecureBitmapId(char *dest_hostname)\r
283 {\r
284         // 引数チェック\r
285         if (dest_hostname == NULL)\r
286         {\r
287                 return 0;\r
288         }\r
289 \r
290         return 0;\r
291 }\r
292 \r
293 // UAC のウインドウをアクティブにする\r
294 void CmSetUacWindowActive()\r
295 {\r
296         HWND hWnd;\r
297 \r
298         if (MsIsVista() == false)\r
299         {\r
300                 return;\r
301         }\r
302         \r
303         hWnd = FindWindowA("$$$Secure UAP Dummy Window Class For Interim Dialog", NULL);\r
304         if (hWnd == NULL)\r
305         {\r
306                 return;\r
307         }\r
308 \r
309         SwitchToThisWindow(hWnd, true);\r
310 }\r
311 \r
312 // UAC ヘルパースレッド\r
313 void CmUacHelperThread(THREAD *thread, void *param)\r
314 {\r
315         CM_UAC_HELPER *c = (CM_UAC_HELPER *)param;\r
316         // 引数チェック\r
317         if (c == NULL)\r
318         {\r
319                 return;\r
320         }\r
321 \r
322         while (c->Halt == false)\r
323         {\r
324                 CmSetUacWindowActive();\r
325 \r
326                 Wait(c->HaltEvent, 200);\r
327         }\r
328 }\r
329 \r
330 // UAC ヘルパーの開始\r
331 void *CmStartUacHelper()\r
332 {\r
333         CM_UAC_HELPER *c = ZeroMalloc(sizeof(CM_UAC_HELPER));\r
334 \r
335         c->HaltEvent = NewEvent();\r
336         c->Thread = NewThread(CmUacHelperThread, c);\r
337 \r
338         return (void *)c;\r
339 }\r
340 \r
341 // UAC ヘルパーの終了\r
342 void CmStopUacHelper(void *p)\r
343 {\r
344         CM_UAC_HELPER *c = (CM_UAC_HELPER *)p;\r
345         // 引数チェック\r
346         if (c == NULL)\r
347         {\r
348                 return;\r
349         }\r
350 \r
351         c->Halt = true;\r
352         Set(c->HaltEvent);\r
353         WaitThread(c->Thread, INFINITE);\r
354         ReleaseEvent(c->HaltEvent);\r
355         ReleaseThread(c->Thread);\r
356 \r
357         Free(c);\r
358 }\r
359 \r
360 // 簡易接続マネージャのコマンド呼び出し\r
361 void CmEasyDlgOnCommand(HWND hWnd, CM_EASY_DLG *d, WPARAM wParam, LPARAM lParam)\r
362 {\r
363         // 引数チェック\r
364         if (hWnd == NULL || d == NULL)\r
365         {\r
366                 return;\r
367         }\r
368 \r
369         switch (wParam)\r
370         {\r
371         case B_MODE:\r
372                 Command(hWnd, CMD_CM_SETTING);\r
373                 return;\r
374 \r
375         case B_STATUS:\r
376                 Command(hWnd, CMD_STATUS);\r
377                 return;\r
378 \r
379         case IDCANCEL:\r
380                 Close(hWnd);\r
381                 return;\r
382         }\r
383 \r
384         if (wParam == CMD_CONNECT)\r
385         {\r
386                 cm->ConnectStartedFlag = false;\r
387         }\r
388 \r
389         CmMainWindowOnCommandEx(hWnd, wParam, lParam, true);\r
390 \r
391         if (wParam == CMD_CONNECT && cm->ConnectStartedFlag)\r
392         {\r
393                 // 接続を開始することに成功したらウインドウを閉じる\r
394                 Close(hWnd);\r
395         }\r
396 }\r
397 \r
398 // 簡易接続マネージャのキーボード押下\r
399 void CmEasyDlgOnKey(HWND hWnd, CM_EASY_DLG *d, bool ctrl, bool alt, UINT key)\r
400 {\r
401         // 引数チェック\r
402         if (hWnd == NULL)\r
403         {\r
404                 return;\r
405         }\r
406 \r
407         // 単一キー\r
408         switch (key)\r
409         {\r
410         case VK_RETURN:\r
411                 Command(hWnd, IDOK);\r
412                 break;\r
413         case VK_DELETE:\r
414                 // 削除\r
415                 if (IsFocus(hWnd, L_ACCOUNT))\r
416                 {\r
417                         // アカウントリストに関する操作\r
418                         Command(hWnd, CMD_DELETE);\r
419                 }\r
420                 else\r
421                 {\r
422                         // 仮想 LAN カードリストに関する操作\r
423                         Command(hWnd, CMD_DELETE_VLAN);\r
424                 }\r
425                 break;\r
426         case VK_F2:\r
427                 // 名前変更\r
428                 Command(hWnd, CMD_RENAME);\r
429                 break;\r
430         case VK_F5:\r
431                 // 状態更新\r
432                 Command(hWnd, CMD_REFRESH);\r
433                 break;\r
434         }\r
435 \r
436         if (alt)\r
437         {\r
438                 switch (key)\r
439                 {\r
440                 case 'Q':\r
441                         // 閉じる\r
442                         Command(hWnd, CMD_QUIT);\r
443                         break;\r
444                 }\r
445         }\r
446 \r
447         if (ctrl)\r
448         {\r
449                 switch (key)\r
450                 {\r
451                 case 'G':\r
452                         // スマートカードマネージャ\r
453                         Command(hWnd, CMD_SECURE_MANAGER);\r
454                         break;\r
455                 case 'S':\r
456                         // 状態の表示\r
457                         Command(hWnd, CMD_STATUS);\r
458                         break;\r
459                 case 'I':\r
460                         // すべての接続を切断\r
461                         Command(hWnd, CMD_DISCONNECT_ALL);\r
462                         break;\r
463                 case 'D':\r
464                         // 切断\r
465                         Command(hWnd, CMD_DISCONNECT);\r
466                         break;\r
467                 case 'N':\r
468                         // 接続設定の新規作成\r
469                         Command(hWnd, CMD_NEW);\r
470                         break;\r
471                 case 'C':\r
472                         // コピーの作成\r
473                         Command(hWnd, CMD_CLONE);\r
474                         break;\r
475                 case 'T':\r
476                         // スタートアップ接続に設定\r
477                         Command(hWnd, CMD_STARTUP);\r
478                         break;\r
479                 case 'A':\r
480                         // すべて選択\r
481                         Command(hWnd, CMD_SELECT_ALL);\r
482                         break;\r
483                 case 'L':\r
484                         // 新規仮想 LAN カードの作成\r
485                         Command(hWnd, CMD_NEW_VLAN);\r
486                         break;\r
487                 case 'P':\r
488                         // パスワードの設定\r
489                         Command(hWnd, CMD_PASSWORD);\r
490                         break;\r
491                 case 'O':\r
492                         // オプション設定\r
493                         Command(hWnd, CMD_TRAFFIC);\r
494                         break;\r
495                 case 'R':\r
496                         // 証明書管理\r
497                         Command(hWnd, CMD_TRUST);\r
498                         break;\r
499                 case 'Q':\r
500                         // スループット\r
501                         Command(hWnd, CMD_TRAFFIC);\r
502                         break;\r
503                 }\r
504         }\r
505 }\r
506 \r
507 // 簡易接続マネージャのリストビューに対する操作\r
508 void CmEasyDlgOnNotify(HWND hWnd, CM_EASY_DLG *d, NMHDR *n)\r
509 {\r
510         NMLVDISPINFOW *disp_info;\r
511         NMLVKEYDOWN *key;\r
512 \r
513         // 引数チェック\r
514         if (hWnd == NULL || n == NULL)\r
515         {\r
516                 return;\r
517         }\r
518 \r
519         switch (n->idFrom)\r
520         {\r
521         case L_ACCOUNT:\r
522                 switch (n->code)\r
523                 {\r
524                 case LVN_ITEMCHANGED:\r
525                         CmEasyDlgUpdate(hWnd, d);\r
526                         break;\r
527                 case NM_DBLCLK:\r
528                         // ダブルクリック\r
529                         Command(hWnd, CMD_EASY_DBLCLICK);\r
530                         break;\r
531                 case NM_RCLICK:\r
532                         // 右クリック\r
533                         CmAccountListRightClick(hWnd);\r
534                         break;\r
535                 case LVN_ENDLABELEDITW:\r
536                         // 名前の変更\r
537                         disp_info = (NMLVDISPINFOW *)n;\r
538                         if (disp_info->item.pszText != NULL)\r
539                         {\r
540                                 wchar_t *new_name = disp_info->item.pszText;\r
541                                 wchar_t *old_name = LvGetStr(hWnd, L_ACCOUNT, disp_info->item.iItem, 0);\r
542 \r
543                                 if (old_name != NULL)\r
544                                 {\r
545                                         if (UniStrCmp(new_name, old_name) != 0 && UniIsEmptyStr(new_name) == false)\r
546                                         {\r
547                                                 RPC_RENAME_ACCOUNT a;\r
548                                                 Zero(&a, sizeof(a));\r
549                                                 UniStrCpy(a.OldName, sizeof(a.OldName), old_name);\r
550                                                 UniStrCpy(a.NewName, sizeof(a.NewName), new_name);\r
551                                                 if (CALL(hWnd, CcRenameAccount(cm->Client, &a)))\r
552                                                 {\r
553                                                         LvSetItem(hWnd, L_ACCOUNT, disp_info->item.iItem, 0, new_name);\r
554                                                 }\r
555                                         }\r
556 \r
557                                         Free(old_name);\r
558                                 }\r
559                         }\r
560                         break;\r
561                 case LVN_KEYDOWN:\r
562                         // キー押下\r
563                         key = (NMLVKEYDOWN *)n;\r
564                         if (key != NULL)\r
565                         {\r
566                                 bool ctrl, alt;\r
567                                 UINT code = key->wVKey;\r
568                                 ctrl = (GetKeyState(VK_CONTROL) & 0x8000) == 0 ? false : true;\r
569                                 alt = (GetKeyState(VK_MENU) & 0x8000) == 0 ? false : true;\r
570                                 CmEasyDlgOnKey(hWnd, d, ctrl, alt, code);\r
571                         }\r
572                         break;\r
573                 }\r
574                 break;\r
575         }\r
576 }\r
577 \r
578 // 簡易接続マネージャに対して更新通知を送信する\r
579 void CmRefreshEasy()\r
580 {\r
581         if (cm->hEasyWnd == NULL)\r
582         {\r
583                 return;\r
584         }\r
585 \r
586         SendMessage(cm->hEasyWnd, WM_CM_EASY_REFRESH, 0, 0);\r
587 }\r
588 \r
589 // 簡易接続マネージャ初期化\r
590 void CmEasyDlgInit(HWND hWnd, CM_EASY_DLG *d)\r
591 {\r
592         HFONT hFontForList;\r
593         HFONT hFontButton;\r
594         HFONT hFontTitle;\r
595         HFONT hFontInfo;\r
596         HFONT hFontOther;\r
597         UINT i, num, num2, j;\r
598         bool b = false;\r
599         char *font_name = NULL;\r
600         bool font_bold = true;\r
601         // 引数チェック\r
602         if (hWnd == NULL || d == NULL)\r
603         {\r
604                 return;\r
605         }\r
606 \r
607         SetIcon(hWnd, 0, ICO_VPN);\r
608 \r
609         // ウインドウハンドル登録\r
610         cm->hEasyWnd = hWnd;\r
611 \r
612         // 中央に表示\r
613         Center(hWnd);\r
614 \r
615         // アカウントリストの更新\r
616         CmInitAccountListEx(hWnd, true);\r
617 \r
618         // リストのフォント設定\r
619         if (cm->VistaStyle)\r
620         {\r
621                 if (_GETLANG() == 0)\r
622                 {\r
623                         font_name = "Meiryo";\r
624                         font_bold = false;\r
625                 }\r
626                 else if (_GETLANG() == 2)\r
627                 {\r
628                         font_name = "Microsoft YaHei";\r
629                         font_bold = false;\r
630                 }\r
631         }\r
632 \r
633         hFontForList = GetFont(font_name, 14, font_bold, false, false, false);\r
634         hFontButton = GetFont(font_name, 13, font_bold, false, false, false);\r
635         hFontTitle = GetFont(font_name, 14, font_bold, false, false, false);\r
636         hFontInfo = GetFont(font_name, 11, font_bold, false, false, false);\r
637         hFontOther = GetDialogDefaultFont();\r
638 \r
639         if (cm->VistaStyle)\r
640         {\r
641                 hFontOther = GetMeiryoFont();\r
642         }\r
643 \r
644         SetFont(hWnd, L_ACCOUNT, hFontForList);\r
645         SetFont(hWnd, IDOK, hFontButton);\r
646         SetFont(hWnd, S_TITLE, hFontTitle);\r
647         SetFont(hWnd, S_INFO, hFontInfo);\r
648         SetFont(hWnd, B_MODE, hFontOther);\r
649         SetFont(hWnd, IDCANCEL, hFontOther);\r
650 \r
651         CmEasyDlgRefresh(hWnd, d);\r
652 \r
653         num = LvNum(hWnd, L_ACCOUNT);\r
654         num2 = 0;\r
655         j = 0;\r
656         for (i = 0;i < num;i++)\r
657         {\r
658                 wchar_t *str = LvGetStr(hWnd, L_ACCOUNT, i, 1);\r
659 \r
660                 if (str != NULL)\r
661                 {\r
662                         if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)\r
663                         {\r
664                                 num2++;\r
665                                 j = i;\r
666                         }\r
667                         Free(str);\r
668                 }\r
669         }\r
670 \r
671         if (num2 == 1)\r
672         {\r
673                 LvSelect(hWnd, L_ACCOUNT, j);\r
674                 b = true;\r
675         }\r
676 \r
677         if (b == false)\r
678         {\r
679                 if (UniIsEmptyStr(cm->EasyLastSelectedAccountName) == false)\r
680                 {\r
681                         i = LvSearchStr(hWnd, L_ACCOUNT, 0, cm->EasyLastSelectedAccountName);\r
682                         if (i != INFINITE)\r
683                         {\r
684                                 LvSelect(hWnd, L_ACCOUNT, i);\r
685                                 b = true;\r
686                         }\r
687                 }\r
688         }\r
689 \r
690         if (b == false)\r
691         {\r
692                 if (LvNum(hWnd, L_ACCOUNT) != 0)\r
693                 {\r
694                         LvSelect(hWnd, L_ACCOUNT, 0);\r
695                 }\r
696         }\r
697 \r
698         Focus(hWnd, L_ACCOUNT);\r
699 \r
700         CmEasyDlgUpdate(hWnd, d);\r
701 }\r
702 \r
703 // 簡易接続マネージャコントロール更新\r
704 void CmEasyDlgUpdate(HWND hWnd, CM_EASY_DLG *d)\r
705 {\r
706         bool ok = true;\r
707         bool show_status = false;\r
708         wchar_t *button_str = _UU("CM_EASY_CONNECT_BUTTON_1");\r
709         wchar_t *info_str = _UU("CM_EASY_INFO_1");\r
710         wchar_t *title_str = _UU("CM_EASY_TITLE");\r
711         // 引数チェック\r
712         if (hWnd == NULL || d == NULL)\r
713         {\r
714                 return;\r
715         }\r
716 \r
717         if (LvIsSingleSelected(hWnd, L_ACCOUNT) == false)\r
718         {\r
719                 ok = false;\r
720         }\r
721 \r
722         if (ok)\r
723         {\r
724                 UINT i = LvGetSelected(hWnd, L_ACCOUNT);\r
725                 wchar_t *str = LvGetStr(hWnd, L_ACCOUNT, i, 1);\r
726 \r
727                 info_str = _UU("CM_EASY_INFO_2");\r
728 \r
729                 if (str != NULL)\r
730                 {\r
731                         if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)\r
732                         {\r
733                                 button_str = _UU("CM_EASY_CONNECT_BUTTON_2");\r
734                                 show_status = true;\r
735                                 info_str = _UU("CM_EASY_INFO_3");\r
736 \r
737                                 if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0)\r
738                                 {\r
739                                         title_str = _UU("CM_EASY_CONNECTED");\r
740                                 }\r
741                                 else\r
742                                 {\r
743                                         title_str = _UU("CM_EASY_CONNECTING");\r
744                                 }\r
745                         }\r
746                         Free(str);\r
747                 }\r
748         }\r
749 \r
750         SetShow(hWnd, B_STATUS, show_status);\r
751 \r
752         SetText(hWnd, IDOK, button_str);\r
753         SetText(hWnd, S_INFO, info_str);\r
754         SetText(hWnd, S_TITLE, title_str);\r
755 \r
756         SetShow(hWnd, IDOK, ok);\r
757 }\r
758 \r
759 // 簡易接続マネージャ内容更新\r
760 void CmEasyDlgRefresh(HWND hWnd, CM_EASY_DLG *d)\r
761 {\r
762         // 引数チェック\r
763         if (hWnd == NULL || d == NULL)\r
764         {\r
765                 return;\r
766         }\r
767 \r
768         // アカウントリスト更新\r
769         CmRefreshAccountListEx(hWnd, true);\r
770 \r
771         CmEasyDlgUpdate(hWnd, d);\r
772 }\r
773 \r
774 // 簡易接続マネージャのダイアログプロシージャ\r
775 UINT CmEasyDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
776 {\r
777         CM_EASY_DLG *d = (CM_EASY_DLG *)param;\r
778         NMHDR *n;\r
779         UINT i;\r
780         // 引数チェック\r
781         if (hWnd == NULL)\r
782         {\r
783                 return 0;\r
784         }\r
785 \r
786         switch (msg)\r
787         {\r
788         case WM_INITDIALOG:\r
789                 CmEasyDlgInit(hWnd, d);\r
790                 SetTimer(hWnd, 1, 10, NULL);\r
791                 break;\r
792 \r
793         case WM_TIMER:\r
794                 switch (wParam)\r
795                 {\r
796                 case 1:\r
797                         KillTimer(hWnd, 1);\r
798                         SetForegroundWindow(hWnd);\r
799                         SetActiveWindow(hWnd);\r
800                         break;\r
801                 }\r
802                 break;\r
803 \r
804         case WM_CM_EASY_REFRESH:\r
805                 CmEasyDlgRefresh(hWnd, d);\r
806                 break;\r
807 \r
808         case WM_COMMAND:\r
809                 CmEasyDlgOnCommand(hWnd, d, wParam, lParam);\r
810                 break;\r
811 \r
812         case WM_NOTIFY:\r
813                 n = (NMHDR *)lParam;\r
814                 CmEasyDlgOnNotify(hWnd, d, n);\r
815                 break;\r
816 \r
817         case WM_CLOSE:\r
818                 i = LvGetSelected(hWnd, L_ACCOUNT);\r
819                 if (i != INFINITE)\r
820                 {\r
821                         wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, i, 0);\r
822                         if (s != NULL)\r
823                         {\r
824                                 UniStrCpy(cm->EasyLastSelectedAccountName, sizeof(cm->EasyLastSelectedAccountName),\r
825                                         s);\r
826                                 Free(s);\r
827                         }\r
828                 }\r
829                 else\r
830                 {\r
831                         Zero(cm->EasyLastSelectedAccountName, sizeof(cm->EasyLastSelectedAccountName));\r
832                 }\r
833                 EndDialog(hWnd, false);\r
834                 break;\r
835         }\r
836 \r
837         return 0;\r
838 }\r
839 \r
840 // 簡易接続マネージャのウインドウを表示する (遅延タイマで呼び出される)\r
841 void CmMainWindowOnShowEasy(HWND hWnd)\r
842 {\r
843         CM_EASY_DLG d;\r
844 \r
845         Zero(&d, sizeof(d));\r
846 \r
847         if (cm->CmSetting.EasyMode == false)\r
848         {\r
849                 // 簡易モードではない\r
850                 return;\r
851         }\r
852 \r
853         if (cm->hEasyWnd != NULL)\r
854         {\r
855                 // すでに表示されている\r
856                 SetForegroundWindow(cm->hEasyWnd);\r
857                 SetActiveWindow(cm->hEasyWnd);\r
858                 return;\r
859         }\r
860 \r
861         Dialog(NULL, D_CM_EASY, CmEasyDlg, &d);\r
862 \r
863         cm->hEasyWnd = NULL;\r
864 }\r
865 \r
866 // 簡易接続マネージャのウインドウを表示する\r
867 void CmShowEasy()\r
868 {\r
869         SetTimer(cm->hMainWnd, 4, 2, NULL);\r
870 }\r
871 \r
872 // 簡易接続マネージャのウインドウを閉じる\r
873 void CmCloseEasy()\r
874 {\r
875         if (cm->hEasyWnd == NULL)\r
876         {\r
877                 return;\r
878         }\r
879 \r
880         SendMessage(cm->hEasyWnd, WM_CLOSE, 0, 0);\r
881 }\r
882 \r
883 // トレイアイコンのクリック等のメッセージ処理\r
884 void CmMainWindowOnTrayClicked(HWND hWnd, WPARAM wParam, LPARAM lParam)\r
885 {\r
886         bool easymode = cm->CmSetting.EasyMode;\r
887 \r
888         switch (wParam)\r
889         {\r
890         case 1:\r
891                 switch (lParam)\r
892                 {\r
893                 case WM_LBUTTONDOWN:\r
894                 case WM_RBUTTONDOWN:\r
895                         // クリック\r
896                         if (easymode == false)\r
897                         {\r
898                                 if (IsEnable(hWnd, 0))\r
899                                 {\r
900                                         CmShowTrayMenu(hWnd);\r
901                                 }\r
902                                 else\r
903                                 {\r
904                                         CmShowOrHideWindow(hWnd);\r
905                                 }\r
906                         }\r
907                         else\r
908                         {\r
909                                 if (cm->hEasyWnd == NULL || IsEnable(cm->hEasyWnd, 0))\r
910                                 {\r
911                                         CmShowTrayMenu(hWnd);\r
912                                 }\r
913                                 else\r
914                                 {\r
915                                         //CmShowOrHideWindow(hWnd);\r
916                                 }\r
917                         }\r
918                         break;\r
919                 case WM_LBUTTONDBLCLK:\r
920                 case WM_RBUTTONDBLCLK:\r
921                         // ダブルクリック\r
922                         if (easymode == false)\r
923                         {\r
924                                 if (IsEnable(hWnd, 0))\r
925                                 {\r
926                                         CmShowOrHideWindow(hWnd);\r
927                                 }\r
928                         }\r
929                         else\r
930                         {\r
931                                 if (cm->hEasyWnd == NULL)\r
932                                 {\r
933                                         CmShowEasy();\r
934                                 }\r
935                                 else\r
936                                 {\r
937                                         SetForegroundWindow(cm->hEasyWnd);\r
938                                         SetActiveWindow(cm->hEasyWnd);\r
939                                 }\r
940                         }\r
941                         break;\r
942                 }\r
943                 break;\r
944         }\r
945 }\r
946 \r
947 // 動作モードの設定の適用\r
948 void CmApplyCmSetting()\r
949 {\r
950         CM_SETTING a;\r
951         bool changed = false;\r
952 \r
953         if (cm->CmSettingSupported == false)\r
954         {\r
955                 return;\r
956         }\r
957 \r
958         // 現在の vpnclient の設定を取得する\r
959         Zero(&a, sizeof(a));\r
960         CcGetCmSetting(cm->Client, &a);\r
961 \r
962         // 以前の CM_SETTING と比較して変化点があるか調べる\r
963         if (cm->CmSetting.EasyMode != a.EasyMode)\r
964         {\r
965                 changed = true;\r
966         }\r
967         if (cm->CmSetting.LockMode != a.LockMode)\r
968         {\r
969                 changed = true;\r
970         }\r
971 \r
972         Copy(&cm->CmSetting, &a, sizeof(CM_SETTING));\r
973 \r
974         if (changed == false)\r
975         {\r
976                 return;\r
977         }\r
978 \r
979         if (cm->StartupFinished)\r
980         {\r
981                 if (IsShow(cm->hMainWnd, 0) && cm->CmSetting.EasyMode)\r
982                 {\r
983                         // メインウインドウが表示されていれば閉じる\r
984                         Hide(cm->hMainWnd, 0);\r
985                 }\r
986                 else\r
987                 {\r
988                         if (cm->CmSetting.EasyMode == false && IsShow(cm->hMainWnd, 0) == false)\r
989                         {\r
990                                 // 通常モードに復帰した際は、メインウインドウを復元する\r
991                                 if (IsZero(&cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement)) == false)\r
992                                 {\r
993                                         cm->FakeWindowPlacement.flags = cm->FakeWindowPlacement.flags & ~SW_MINIMIZE;\r
994                                         SetWindowPlacement(cm->hMainWnd, &cm->FakeWindowPlacement);\r
995                                         Zero(&cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement));\r
996                                         Hide(cm->hMainWnd, 0);\r
997                                 }\r
998                                 CmShowOrHideWindow(cm->hMainWnd);\r
999                         }\r
1000                 }\r
1001 \r
1002                 Command(cm->hMainWnd, CMD_REFRESH);\r
1003         }\r
1004 \r
1005         if (cm->CmSetting.EasyMode)\r
1006         {\r
1007                 if (cm->StartupFinished == false && cm->StartupMode)\r
1008                 {\r
1009                         // /startup の場合は表示しない\r
1010                 }\r
1011                 else\r
1012                 {\r
1013                         CmShowEasy();\r
1014                 }\r
1015         }\r
1016         else\r
1017         {\r
1018                 CmCloseEasy();\r
1019         }\r
1020 }\r
1021 \r
1022 // 動作モード変更ダイアログ初期化\r
1023 void CmSettingDlgInit(HWND hWnd, CM_SETTING_DLG *d)\r
1024 {\r
1025         CM_SETTING a;\r
1026         // 引数チェック\r
1027         if (hWnd == NULL || d == NULL)\r
1028         {\r
1029                 return;\r
1030         }\r
1031 \r
1032         // 現在の vpnclient の設定を取得する\r
1033         Zero(&a, sizeof(a));\r
1034         CcGetCmSetting(cm->Client, &a);\r
1035 \r
1036         Check(hWnd, R_EASY, a.EasyMode);\r
1037         Check(hWnd, R_NORMAL, a.EasyMode == false);\r
1038 \r
1039         if (a.EasyMode == false)\r
1040         {\r
1041                 Focus(hWnd, R_NORMAL);\r
1042         }\r
1043         else\r
1044         {\r
1045                 Focus(hWnd, R_EASY);\r
1046         }\r
1047 \r
1048         Check(hWnd, R_LOCK, a.LockMode);\r
1049 \r
1050         SetEnable(hWnd, R_EASY, cm->CmEasyModeSupported);\r
1051 \r
1052         if (a.LockMode)\r
1053         {\r
1054                 if (IsZero(a.HashedPassword, sizeof(a.HashedPassword)) == false)\r
1055                 {\r
1056                         // パスワードが設定されている\r
1057                         SetText(hWnd, S_PASSWORD1, _UU("CM_SETTING_PASSWORD"));\r
1058                         Hide(hWnd, S_PASSWORD3);\r
1059                         Hide(hWnd, E_PASSWORD2);\r
1060 \r
1061                         d->CheckPassword = true;\r
1062                         Copy(d->HashedPassword, a.HashedPassword, sizeof(d->HashedPassword));\r
1063                 }\r
1064         }\r
1065 \r
1066         CmSettingDlgUpdate(hWnd, d);\r
1067 }\r
1068 \r
1069 // 動作モード変更ダイアログ更新\r
1070 void CmSettingDlgUpdate(HWND hWnd, CM_SETTING_DLG *d)\r
1071 {\r
1072         bool ok = true;\r
1073         char tmp1[MAX_SIZE], tmp2[MAX_SIZE];\r
1074         // 引数チェック\r
1075         if (hWnd == NULL || d == NULL)\r
1076         {\r
1077                 return;\r
1078         }\r
1079 \r
1080         GetTxtA(hWnd, E_PASSWORD1, tmp1, sizeof(tmp1));\r
1081         GetTxtA(hWnd, E_PASSWORD2, tmp2, sizeof(tmp2));\r
1082 \r
1083         if (d->CheckPassword == false)\r
1084         {\r
1085                 if (IsChecked(hWnd, R_LOCK))\r
1086                 {\r
1087                         if (StrCmp(tmp1, tmp2) != 0)\r
1088                         {\r
1089                                 ok = false;\r
1090                         }\r
1091                 }\r
1092         }\r
1093         else\r
1094         {\r
1095                 bool password_ok = false;\r
1096                 UCHAR hash[SHA1_SIZE];\r
1097 \r
1098                 Hash(hash, tmp1, StrLen(tmp1), true);\r
1099                 if (Cmp(hash, d->HashedPassword, sizeof(hash)) == 0)\r
1100                 {\r
1101                         password_ok = true;\r
1102                 }\r
1103 \r
1104                 if (password_ok == false)\r
1105                 {\r
1106                         Check(hWnd, R_LOCK, true);\r
1107                         Disable(hWnd, R_LOCK);\r
1108                 }\r
1109                 else\r
1110                 {\r
1111                         Enable(hWnd, R_LOCK);\r
1112                 }\r
1113         }\r
1114 \r
1115         SetEnable(hWnd, S_PASSWORD1, IsChecked(hWnd, R_LOCK));\r
1116         SetEnable(hWnd, S_PASSWORD2, IsChecked(hWnd, R_LOCK));\r
1117         SetEnable(hWnd, S_PASSWORD3, IsChecked(hWnd, R_LOCK));\r
1118         SetEnable(hWnd, E_PASSWORD1, IsChecked(hWnd, R_LOCK));\r
1119         SetEnable(hWnd, E_PASSWORD2, IsChecked(hWnd, R_LOCK));\r
1120 \r
1121         SetEnable(hWnd, IDOK, ok);\r
1122 }\r
1123 \r
1124 // 動作モード変更ダイアログ OK\r
1125 void CmSettingDlgOnOk(HWND hWnd, CM_SETTING_DLG *d)\r
1126 {\r
1127         CM_SETTING a;\r
1128         char tmp1[MAX_SIZE], tmp2[MAX_SIZE];\r
1129         // 引数チェック\r
1130         if (hWnd == NULL || d == NULL)\r
1131         {\r
1132                 return;\r
1133         }\r
1134 \r
1135         GetTxtA(hWnd, E_PASSWORD1, tmp1, sizeof(tmp1));\r
1136         GetTxtA(hWnd, E_PASSWORD2, tmp2, sizeof(tmp2));\r
1137 \r
1138         Zero(&a, sizeof(a));\r
1139 \r
1140         a.EasyMode = IsChecked(hWnd, R_EASY);\r
1141         a.LockMode = IsChecked(hWnd, R_LOCK);\r
1142 \r
1143         if (a.LockMode)\r
1144         {\r
1145                 if (d->CheckPassword && IsEnable(hWnd, R_LOCK) == false)\r
1146                 {\r
1147                         Copy(a.HashedPassword, d->HashedPassword, sizeof(a.HashedPassword));\r
1148                 }\r
1149                 else\r
1150                 {\r
1151                         if (StrLen(tmp1) >= 1)\r
1152                         {\r
1153                                 Hash(a.HashedPassword, tmp1, StrLen(tmp1), true);\r
1154                         }\r
1155                 }\r
1156         }\r
1157 \r
1158         CcSetCmSetting(cm->Client, &a);\r
1159 \r
1160         EndDialog(hWnd, true);\r
1161 }\r
1162 \r
1163 // 動作モード変更ダイアログ\r
1164 UINT CmSettingDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
1165 {\r
1166         CM_SETTING_DLG *d = (CM_SETTING_DLG *)param;\r
1167         // 引数チェック\r
1168         if (hWnd == NULL)\r
1169         {\r
1170                 return 0;\r
1171         }\r
1172 \r
1173         switch (msg)\r
1174         {\r
1175         case WM_INITDIALOG:\r
1176                 CmSettingDlgInit(hWnd, d);\r
1177                 break;\r
1178 \r
1179         case WM_COMMAND:\r
1180                 switch (LOWORD(wParam))\r
1181                 {\r
1182                 case R_EASY:\r
1183                 case R_NORMAL:\r
1184                 case R_LOCK:\r
1185                 case E_PASSWORD1:\r
1186                 case E_PASSWORD2:\r
1187                 case IDOK:\r
1188                 case IDCANCEL:\r
1189                         CmSettingDlgUpdate(hWnd, d);\r
1190                         break;\r
1191                 }\r
1192                 switch (wParam)\r
1193                 {\r
1194                 case IDOK:\r
1195                         CmSettingDlgOnOk(hWnd, d);\r
1196                         break;\r
1197 \r
1198                 case IDCANCEL:\r
1199                         Close(hWnd);\r
1200                         break;\r
1201 \r
1202                 case R_LOCK:\r
1203                         if (IsChecked(hWnd, R_LOCK))\r
1204                         {\r
1205                                 if (IsEmpty(hWnd, E_PASSWORD1))\r
1206                                 {\r
1207                                         Focus(hWnd, E_PASSWORD1);\r
1208                                 }\r
1209                         }\r
1210                         break;\r
1211                 }\r
1212                 break;\r
1213 \r
1214         case WM_CLOSE:\r
1215                 EndDialog(hWnd, false);\r
1216                 break;\r
1217         }\r
1218 \r
1219         return 0;\r
1220 }\r
1221 \r
1222 // 動作モード変更\r
1223 bool CmSetting(HWND hWnd)\r
1224 {\r
1225         CM_SETTING_DLG d;\r
1226 \r
1227         Zero(&d, sizeof(d));\r
1228 \r
1229         return Dialog(hWnd, D_CM_SETTING, CmSettingDlg, &d);\r
1230 }\r
1231 \r
1232 // UI Helper の起動の試行スレッド\r
1233 void CmTryToExecUiHelperThread(THREAD *thread, void *param)\r
1234 {\r
1235         // このあたりは急いで実装したのでコードがあまり美しくない。\r
1236         bool first_flag = true;\r
1237 \r
1238         while (cm->TryExecUiHelperHalt == false && cm->WindowsShutdowning == false)\r
1239         {\r
1240                 if (first_flag == false)\r
1241                 {\r
1242                         // 初回以外は少し待つ\r
1243                         Wait(cm->TryExecUiHelperHaltEvent, CM_TRY_EXEC_UI_HELPER_INTERVAL * 2);\r
1244 \r
1245                         if (cm->TryExecUiHelperHalt || cm->WindowsShutdowning)\r
1246                         {\r
1247                                 break;\r
1248                         }\r
1249                 }\r
1250                 first_flag = false;\r
1251 \r
1252                 if (cm->TryExecUiHelperHalt == false && cm->WindowsShutdowning == false)\r
1253                 {\r
1254                         if (cm->TryExecUiHelperProcessHandle == NULL)\r
1255                         {\r
1256                                 CmTryToExecUiHelper();\r
1257                         }\r
1258                 }\r
1259 \r
1260                 if (cm->TryExecUiHelperHalt || cm->WindowsShutdowning)\r
1261                 {\r
1262                         break;\r
1263                 }\r
1264 \r
1265                 if (cm->TryExecUiHelperProcessHandle == NULL)\r
1266                 {\r
1267                         Wait(cm->TryExecUiHelperHaltEvent, CM_TRY_EXEC_UI_HELPER_INTERVAL);\r
1268                 }\r
1269                 else\r
1270                 {\r
1271                         HANDLE handles[2];\r
1272                         handles[0] = cm->TryExecUiHelperProcessHandle;\r
1273                         handles[1] = (HANDLE)cm->TryExecUiHelperHaltEvent->pData;\r
1274                         WaitForMultipleObjects(2, handles, false, CM_TRY_EXEC_UI_HELPER_INTERVAL);\r
1275 \r
1276                         if (WaitForSingleObject(cm->TryExecUiHelperProcessHandle, 0) != WAIT_TIMEOUT)\r
1277                         {\r
1278                                 CloseHandle(cm->TryExecUiHelperProcessHandle);\r
1279                                 cm->TryExecUiHelperProcessHandle = NULL;\r
1280                                 if (cm->TryExecUiHelperHalt || cm->WindowsShutdowning)\r
1281                                 {\r
1282                                         break;\r
1283                                 }\r
1284                                 Wait(cm->TryExecUiHelperHaltEvent, CM_TRY_EXEC_UI_HELPER_INTERVAL * 2);\r
1285                         }\r
1286                 }\r
1287         }\r
1288 }\r
1289 \r
1290 // UI Helper 終了\r
1291 void CmFreeTryToExecUiHelper()\r
1292 {\r
1293         cm->TryExecUiHelperHalt = true;\r
1294         Set(cm->TryExecUiHelperHaltEvent);\r
1295 \r
1296         WaitThread(cm->TryExecUiHelperThread, INFINITE);\r
1297 \r
1298         ReleaseThread(cm->TryExecUiHelperThread);\r
1299         cm->TryExecUiHelperThread = NULL;\r
1300 \r
1301         ReleaseEvent(cm->TryExecUiHelperHaltEvent);\r
1302         cm->TryExecUiHelperHaltEvent = NULL;\r
1303 \r
1304         cm->TryExecUiHelperHalt = false;\r
1305         cm->TryExecUiHelperProcessHandle = NULL;\r
1306 }\r
1307 \r
1308 // UI Helper 起動初期化\r
1309 void CmInitTryToExecUiHelper()\r
1310 {\r
1311         cm->TryExecUiHelperProcessHandle = NULL;\r
1312         cm->TryExecUiHelperHalt = false;\r
1313         cm->TryExecUiHelperHaltEvent = NewEvent();\r
1314         cm->TryExecUiHelperThread = NewThread(CmTryToExecUiHelperThread, NULL);\r
1315 }\r
1316 \r
1317 // UI Helper の起動\r
1318 void *CmExecUiHelperMain()\r
1319 {\r
1320         HANDLE h;\r
1321         wchar_t tmp[MAX_SIZE];\r
1322 \r
1323         UniFormat(tmp, sizeof(tmp), L"%s\\%S", MsGetExeDirNameW(), CiGetVpnClientExeFileName());\r
1324 \r
1325         // 起動\r
1326         h = Win32RunExW(tmp, SVC_ARG_UIHELP_W, false);\r
1327 \r
1328         return (void *)h;\r
1329 }\r
1330 \r
1331 // UI Helper の起動の試行\r
1332 void CmTryToExecUiHelper()\r
1333 {\r
1334         HANDLE h;\r
1335         // 既に起動していないかどうかチェックする\r
1336         if (CnCheckAlreadyExists(false))\r
1337         {\r
1338                 // 既に起動している\r
1339                 return;\r
1340         }\r
1341 \r
1342         h = (HANDLE)CmExecUiHelperMain();\r
1343 \r
1344         if (h != NULL)\r
1345         {\r
1346                 cm->TryExecUiHelperProcessHandle = h;\r
1347         }\r
1348 }\r
1349 \r
1350 // ダイアログ初期化\r
1351 void CmTrafficResultDlgInit(HWND hWnd, TT_RESULT *res)\r
1352 {\r
1353         LVB *ct;\r
1354         wchar_t tmp[MAX_SIZE];\r
1355         wchar_t tmp1[MAX_SIZE];\r
1356         wchar_t tmp2[MAX_SIZE];\r
1357         char str[MAX_SIZE];\r
1358         // 引数チェック\r
1359         if (hWnd == NULL || res == NULL)\r
1360         {\r
1361                 return;\r
1362         }\r
1363 \r
1364         SetIcon(hWnd, 0, ICO_SWITCH);\r
1365 \r
1366         SetFont(hWnd, L_STATUS, GetFont(_SS("DEFAULT_FONT_2"), 10, false, false, false, false));\r
1367 \r
1368         LvInit(hWnd, L_STATUS);\r
1369         LvSetStyle(hWnd, L_STATUS, LVS_EX_GRIDLINES);\r
1370         LvInsertColumn(hWnd, L_STATUS, 0, _UU("TTC_RES_COLUMN_1"), 100);\r
1371         LvInsertColumn(hWnd, L_STATUS, 1, _UU("TTC_RES_COLUMN_2"), 100);\r
1372         LvInsertColumn(hWnd, L_STATUS, 2, _UU("TTC_RES_COLUMN_3"), 100);\r
1373 \r
1374         ct = LvInsertStart();\r
1375 \r
1376         // 測定に使用した時間\r
1377         GetSpanStrMilli(str, sizeof(str), res->Span);\r
1378         StrToUni(tmp, sizeof(tmp), str);\r
1379         LvInsertAdd(ct, ICO_DATETIME, NULL, 3, _UU("TTC_RES_SPAN"), tmp, L"");\r
1380 \r
1381         // Ethernet フレーム用にデータ補正\r
1382         LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_ETHER"), res->Raw ? _UU("SEC_NO") : _UU("SEC_YES"), L"");\r
1383 \r
1384         // ダウンロード方向の通信データ量\r
1385         ToStr3(str, sizeof(str), res->NumBytesDownload);\r
1386         UniFormat(tmp1, sizeof(tmp1), L"%S Bytes", str);\r
1387         ToStrByte1000(str, sizeof(str), res->NumBytesDownload);\r
1388         StrToUni(tmp2, sizeof(tmp2), str);\r
1389         LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BYTES_DOWNLOAD"), tmp1, tmp2);\r
1390 \r
1391         // アップロード方向の通信データ量\r
1392         ToStr3(str, sizeof(str), res->NumBytesUpload);\r
1393         UniFormat(tmp1, sizeof(tmp1), L"%S Bytes", str);\r
1394         ToStrByte1000(str, sizeof(str), res->NumBytesUpload);\r
1395         StrToUni(tmp2, sizeof(tmp2), str);\r
1396         LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BYTES_UPLOAD"), tmp1, tmp2);\r
1397 \r
1398         // 合計通信データ量\r
1399         ToStr3(str, sizeof(str), res->NumBytesTotal);\r
1400         UniFormat(tmp1, sizeof(tmp1), L"%S Bytes", str);\r
1401         ToStrByte1000(str, sizeof(str), res->NumBytesTotal);\r
1402         StrToUni(tmp2, sizeof(tmp2), str);\r
1403         LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BYTES_TOTAL"), tmp1, tmp2);\r
1404 \r
1405         // 中継機器入出力合計スループット算出\r
1406         LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_DOUBLE"), (res->Double == false) ? _UU("SEC_NO") : _UU("SEC_YES"), L"");\r
1407 \r
1408         // ダウンロード方向の平均スループット\r
1409         ToStr3(str, sizeof(str), res->BpsDownload);\r
1410         UniFormat(tmp1, sizeof(tmp1), L"%S bps", str);\r
1411         ToStrByte1000(str, sizeof(str), res->BpsDownload);\r
1412         ReplaceStr(str, sizeof(str), str, "Bytes", "bps");\r
1413         StrToUni(tmp2, sizeof(tmp2), str);\r
1414         LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BPS_DOWNLOAD"), tmp1, tmp2);\r
1415 \r
1416         // アップロード方向の平均スループット\r
1417         ToStr3(str, sizeof(str), res->BpsUpload);\r
1418         UniFormat(tmp1, sizeof(tmp1), L"%S bps", str);\r
1419         ToStrByte1000(str, sizeof(str), res->BpsUpload);\r
1420         ReplaceStr(str, sizeof(str), str, "Bytes", "bps");\r
1421         StrToUni(tmp2, sizeof(tmp2), str);\r
1422         LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BPS_UPLOAD"), tmp1, tmp2);\r
1423 \r
1424         // 合計平均スループット\r
1425         ToStr3(str, sizeof(str), res->BpsTotal);\r
1426         UniFormat(tmp1, sizeof(tmp1), L"%S bps", str);\r
1427         ToStrByte1000(str, sizeof(str), res->BpsTotal);\r
1428         ReplaceStr(str, sizeof(str), str, "Bytes", "bps");\r
1429         StrToUni(tmp2, sizeof(tmp2), str);\r
1430         LvInsertAdd(ct, ICO_INFORMATION, NULL, 3, _UU("TTC_RES_BPS_TOTAL"), tmp1, tmp2);\r
1431 \r
1432         LvInsertEnd(ct, hWnd, L_STATUS);\r
1433 \r
1434         LvAutoSize(hWnd, L_STATUS);\r
1435 }\r
1436 \r
1437 // トラフィック測定結果の表示ダイアログプロシージャ\r
1438 UINT CmTrafficResultDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
1439 {\r
1440         TT_RESULT *r = (TT_RESULT *)param;\r
1441         // 引数チェック\r
1442         if (hWnd == NULL)\r
1443         {\r
1444                 return 0;\r
1445         }\r
1446 \r
1447         switch (msg)\r
1448         {\r
1449         case WM_INITDIALOG:\r
1450                 CmTrafficResultDlgInit(hWnd, r);\r
1451                 break;\r
1452 \r
1453         case WM_COMMAND:\r
1454                 switch (wParam)\r
1455                 {\r
1456                 case IDOK:\r
1457                 case IDCANCEL:\r
1458                         Close(hWnd);\r
1459                         break;\r
1460                 }\r
1461                 break;\r
1462 \r
1463         case WM_CLOSE:\r
1464                 EndDialog(hWnd, 0);\r
1465                 break;\r
1466         }\r
1467 \r
1468         return 0;\r
1469 }\r
1470 \r
1471 // トラフィック測定結果の表示\r
1472 void CmTrafficResult(HWND hWnd, TT_RESULT *r)\r
1473 {\r
1474         // 引数チェック\r
1475         if (r == NULL)\r
1476         {\r
1477                 return;\r
1478         }\r
1479 \r
1480         Dialog(hWnd, D_CM_TRAFFIC_RESULT, CmTrafficResultDlg, r);\r
1481 }\r
1482 \r
1483 // クライアントの終了を待機するスレッド\r
1484 void CmTrafficRunDlgClientWaitThread(THREAD *t, void *param)\r
1485 {\r
1486         CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;\r
1487         TT_RESULT result;\r
1488         UINT ret;\r
1489         // 引数チェック\r
1490         if (t == NULL || param == NULL)\r
1491         {\r
1492                 return;\r
1493         }\r
1494 \r
1495         Zero(&result, sizeof(result));\r
1496         ret = FreeTtc(d->Ttc, &result);\r
1497         d->Ttc = NULL;\r
1498 \r
1499         d->RetCode = ret;\r
1500         Copy(&d->Result, &result, sizeof(TT_RESULT));\r
1501 \r
1502         PostMessage(d->hWnd, WM_APP + 66, 0, 0);\r
1503 }\r
1504 \r
1505 // 文字列の追記\r
1506 void CmTrafficRunDlgAddStr(HWND hWnd, wchar_t *str)\r
1507 {\r
1508         wchar_t *tmp;\r
1509         UINT tmp_size;\r
1510 \r
1511         tmp_size = UniStrSize(str) + 32;\r
1512         tmp = Malloc(tmp_size);\r
1513         UniStrCpy(tmp, tmp_size, str);\r
1514         if (UniEndWith(str, L"\n") == false)\r
1515         {\r
1516                 UniStrCat(tmp, tmp_size, L"\n");\r
1517         }\r
1518 \r
1519         UniReplaceStrEx(tmp, tmp_size, tmp, L"\r\n", L"\n", false);\r
1520         UniReplaceStrEx(tmp, tmp_size, tmp, L"\n", L"\r\n", false);\r
1521 \r
1522         if (MsIsNt())\r
1523         {\r
1524                 SendMsg(hWnd, E_EDIT, EM_SETSEL, 0x7fffffff, 0x7fffffff);\r
1525                 SendMsg(hWnd, E_EDIT, EM_REPLACESEL, false, (LPARAM)tmp);\r
1526         }\r
1527         else\r
1528         {\r
1529                 char *s = CopyUniToStr(tmp);\r
1530                 UINT len;\r
1531 \r
1532                 len = GetWindowTextLength(DlgItem(hWnd, E_EDIT));\r
1533                 SendMsg(hWnd, E_EDIT, EM_SETSEL, 0x7fffffff, 0x7fffffff);\r
1534                 SendMsg(hWnd, E_EDIT, EM_SETSEL, len, len);\r
1535                 SendMsg(hWnd, E_EDIT, EM_REPLACESEL, false, (LPARAM)s);\r
1536                 Free(s);\r
1537         }\r
1538 \r
1539         Free(tmp);\r
1540 }\r
1541 \r
1542 // 文字列の表示\r
1543 void CmTrafficRunDlgPrintProc(void *param, wchar_t *str)\r
1544 {\r
1545         CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;\r
1546         HWND hWnd;\r
1547         // 引数チェック\r
1548         if (param == NULL || str == NULL)\r
1549         {\r
1550                 return;\r
1551         }\r
1552 \r
1553         hWnd = d->hWnd;\r
1554 \r
1555         PostMessage(hWnd, WM_APP + 64, 0, (LPARAM)UniCopyStr(str));\r
1556 }\r
1557 \r
1558 // 測定プログラムの停止用スレッド\r
1559 void CmTrafficRunDlgHaltThread(THREAD *t, void *param)\r
1560 {\r
1561         CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;\r
1562         // 引数チェック\r
1563         if (t == NULL || param == NULL)\r
1564         {\r
1565                 return;\r
1566         }\r
1567 \r
1568         if (d->Setting->ServerMode)\r
1569         {\r
1570                 // サーバーを停止\r
1571                 d->RetCode = FreeTts(d->Tts);\r
1572 \r
1573                 PostMessage(d->hWnd, WM_APP + 65, 0, 0);\r
1574         }\r
1575 }\r
1576 \r
1577 // 測定プログラムを停止する\r
1578 void CmTrafficRunDlgHalt(HWND hWnd, CM_TRAFFIC_DLG *d)\r
1579 {\r
1580         // 引数チェック\r
1581         if (hWnd == NULL || d == NULL)\r
1582         {\r
1583                 return;\r
1584         }\r
1585 \r
1586         if (d->Started == false)\r
1587         {\r
1588                 return;\r
1589         }\r
1590 \r
1591         if (d->Setting->ServerMode)\r
1592         {\r
1593                 if (d->HaltThread == NULL)\r
1594                 {\r
1595                         Disable(hWnd, IDCANCEL);\r
1596                         d->HaltThread = NewThread(CmTrafficRunDlgHaltThread, d);\r
1597                 }\r
1598         }\r
1599         else\r
1600         {\r
1601                 if (d->ClientEndWaitThread != NULL)\r
1602                 {\r
1603                         StopTtc(d->Ttc);\r
1604                 }\r
1605                 else\r
1606                 {\r
1607                         EndDialog(hWnd, 0);\r
1608                 }\r
1609         }\r
1610 }\r
1611 \r
1612 // トラフィック測定の動作を開始する\r
1613 void CmTrafficRunDlgStart(HWND hWnd, CM_TRAFFIC_DLG *d)\r
1614 {\r
1615         // 引数チェック\r
1616         if (hWnd == NULL || d == NULL)\r
1617         {\r
1618                 return;\r
1619         }\r
1620 \r
1621         if (d->Setting->ServerMode)\r
1622         {\r
1623                 // 測定サーバーを開始\r
1624                 d->Tts = NewTts(d->Setting->Port, d, CmTrafficRunDlgPrintProc);\r
1625         }\r
1626         else\r
1627         {\r
1628                 // 測定クライアントを開始\r
1629                 d->Ttc = NewTtc(d->Setting->Host, d->Setting->Port,\r
1630                         d->Setting->NumTcp, d->Setting->Type, d->Setting->Span * 1000ULL,\r
1631                         d->Setting->Double, d->Setting->Raw, CmTrafficRunDlgPrintProc, d);\r
1632 \r
1633                 d->ClientEndWaitThread = NewThread(CmTrafficRunDlgClientWaitThread, d);\r
1634         }\r
1635 \r
1636         d->Started = true;\r
1637 }\r
1638 \r
1639 // トラフィック測定実行ダイアログ初期化\r
1640 void CmTrafficRunDlgInit(HWND hWnd, CM_TRAFFIC_DLG *d)\r
1641 {\r
1642         // 引数チェック\r
1643         if (hWnd == NULL || d == NULL)\r
1644         {\r
1645                 return;\r
1646         }\r
1647 \r
1648         d->hWnd = hWnd;\r
1649 \r
1650         SetIcon(hWnd, 0, ICO_SWITCH);\r
1651         DlgFont(hWnd, S_INFO, 11, false);\r
1652         SetFont(hWnd, E_EDIT, GetFont(_SS("DEFAULT_FONT_2"), 0, false, false,\r
1653                 false, false));\r
1654 \r
1655         Focus(hWnd, IDCANCEL);\r
1656 }\r
1657 \r
1658 // トラフィック測定実行ダイアログプロシージャ\r
1659 UINT CmTrafficRunDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
1660 {\r
1661         CM_TRAFFIC_DLG *d = (CM_TRAFFIC_DLG *)param;\r
1662         wchar_t *s;\r
1663         // 引数チェック\r
1664         if (hWnd == NULL)\r
1665         {\r
1666                 return 0;\r
1667         }\r
1668 \r
1669         switch (msg)\r
1670         {\r
1671         case WM_INITDIALOG:\r
1672                 CmTrafficRunDlgInit(hWnd, d);\r
1673 \r
1674                 SetTimer(hWnd, 1, 10, NULL);\r
1675                 break;\r
1676 \r
1677         case WM_APP + 64:\r
1678                 // 文字列追加\r
1679                 s = (wchar_t *)lParam;\r
1680                 if (s != NULL)\r
1681                 {\r
1682                         CmTrafficRunDlgAddStr(hWnd, s);\r
1683                         Free(s);\r
1684                 }\r
1685                 break;\r
1686 \r
1687         case WM_APP + 65:\r
1688                 // 停止完了\r
1689                 if (d->HaltThread != NULL)\r
1690                 {\r
1691                         WaitThread(d->HaltThread, INFINITE);\r
1692                         ReleaseThread(d->HaltThread);\r
1693                         d->HaltThread = NULL;\r
1694                         EndDialog(hWnd, 0);\r
1695                 }\r
1696                 break;\r
1697 \r
1698         case WM_APP + 66:\r
1699                 // 結果表示\r
1700                 if (d->RetCode == ERR_NO_ERROR)\r
1701                 {\r
1702                         CmTrafficResult(hWnd, &d->Result);\r
1703                 }\r
1704 \r
1705                 if (d->ClientEndWaitThread != NULL)\r
1706                 {\r
1707                         WaitThread(d->ClientEndWaitThread, INFINITE);\r
1708                         ReleaseThread(d->ClientEndWaitThread);\r
1709                         d->ClientEndWaitThread = NULL;\r
1710                 }\r
1711 \r
1712                 if (d->CloseDialogAfter)\r
1713                 {\r
1714                         EndDialog(hWnd, 0);\r
1715                 }\r
1716                 break;\r
1717 \r
1718         case WM_TIMER:\r
1719                 switch (wParam)\r
1720                 {\r
1721                 case 1:\r
1722                         KillTimer(hWnd, 1);\r
1723 \r
1724                         CmTrafficRunDlgStart(hWnd, d);\r
1725                         break;\r
1726                 }\r
1727                 break;\r
1728 \r
1729         case WM_COMMAND:\r
1730                 switch (wParam)\r
1731                 {\r
1732                 case IDOK:\r
1733                 case IDCANCEL:\r
1734                         Close(hWnd);\r
1735                         break;\r
1736                 }\r
1737                 break;\r
1738 \r
1739         case WM_CLOSE:\r
1740                 d->CloseDialogAfter = true;\r
1741                 CmTrafficRunDlgHalt(hWnd, d);\r
1742                 return 1;\r
1743         }\r
1744 \r
1745         return 0;\r
1746 }\r
1747 \r
1748 // トラフィック測定を実行する\r
1749 void CmExecTraffic(HWND hWnd, CM_TRAFFIC *t)\r
1750 {\r
1751         CM_TRAFFIC_DLG d;\r
1752         // 引数チェック\r
1753         if (t == NULL)\r
1754         {\r
1755                 return;\r
1756         }\r
1757 \r
1758         Zero(&d, sizeof(d));\r
1759         d.Setting = t;\r
1760         d.ResultShowEvent = NewEvent();\r
1761 \r
1762         MsSetThreadPriorityHigh();\r
1763         Dialog(hWnd, D_CM_TRAFFIC_RUN, CmTrafficRunDlg, &d);\r
1764         MsRestoreThreadPriority();\r
1765 \r
1766         ReleaseEvent(d.ResultShowEvent);\r
1767 }\r
1768 \r
1769 // レジストリに設定を書き込む\r
1770 void CmTrafficSaveToReg(CM_TRAFFIC *t)\r
1771 {\r
1772         // 引数チェック\r
1773         if (t == NULL)\r
1774         {\r
1775                 return;\r
1776         }\r
1777 \r
1778         MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "ServerMode", t->ServerMode ? 1 : 0);\r
1779         MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Double", t->Double ? 1 : 0);\r
1780         MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Raw", t->Raw ? 1 : 0);\r
1781         MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Port", t->Port);\r
1782         MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "NumTcp", t->NumTcp);\r
1783         MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Type", t->Type);\r
1784         MsRegWriteInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Span", t->Span);\r
1785         MsRegWriteStr(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Host", t->Host);\r
1786 }\r
1787 \r
1788 // レジストリから設定を読み込む\r
1789 bool CmTrafficLoadFromReg(CM_TRAFFIC *t)\r
1790 {\r
1791         char *s;\r
1792         // 引数チェック\r
1793         if (t == NULL)\r
1794         {\r
1795                 return false;\r
1796         }\r
1797 \r
1798         Zero(t, sizeof(CM_TRAFFIC));\r
1799 \r
1800         if (MsRegIsKey(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY) == false)\r
1801         {\r
1802                 return false;\r
1803         }\r
1804 \r
1805         t->Double = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Double") == 0 ? false : true;\r
1806         t->Raw = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Raw") == 0 ? false : true;\r
1807         t->Port = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Port");\r
1808         if (t->Port == 0)\r
1809         {\r
1810                 t->Port = TRAFFIC_DEFAULT_PORT;\r
1811         }\r
1812 \r
1813         s = MsRegReadStr(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Host");\r
1814 \r
1815         if (IsEmptyStr(s) == false)\r
1816         {\r
1817                 Trim(s);\r
1818                 StrCpy(t->Host, sizeof(t->Host), s);\r
1819         }\r
1820 \r
1821         Free(s);\r
1822 \r
1823         t->NumTcp = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "NumTcp");\r
1824         t->NumTcp = MAKESURE(t->NumTcp, 1, TRAFFIC_NUMTCP_MAX);\r
1825         t->Type = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Type");\r
1826 \r
1827         if (t->Type != TRAFFIC_TYPE_DOWNLOAD && t->Type != TRAFFIC_TYPE_UPLOAD &&\r
1828                 t->Type != TRAFFIC_TYPE_FULL)\r
1829         {\r
1830                 t->Type = TRAFFIC_TYPE_FULL;\r
1831         }\r
1832 \r
1833         t->Span = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "Span");\r
1834         if (t->Span == 0)\r
1835         {\r
1836                 t->Span = TRAFFIC_SPAN_DEFAULT;\r
1837         }\r
1838 \r
1839         t->ServerMode = MsRegReadInt(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "ServerMode") == 0 ? false : true;\r
1840 \r
1841         return true;\r
1842 }\r
1843 \r
1844 // デフォルトの設定を取得する\r
1845 void CmTrafficGetDefaultSetting(CM_TRAFFIC *t)\r
1846 {\r
1847         // 引数チェック\r
1848         if (t == NULL)\r
1849         {\r
1850                 return;\r
1851         }\r
1852 \r
1853         Zero(t, sizeof(CM_TRAFFIC));\r
1854 \r
1855         t->Double = false;\r
1856         t->Raw = false;\r
1857         t->Port = TRAFFIC_DEFAULT_PORT;\r
1858         t->NumTcp = TRAFFIC_NUMTCP_DEFAULT;\r
1859         t->Type = TRAFFIC_TYPE_FULL;\r
1860         t->Span = TRAFFIC_SPAN_DEFAULT;\r
1861         t->ServerMode = false;\r
1862 }\r
1863 \r
1864 // 通信スループット測定ツールダイアログ初期化\r
1865 void CmTrafficDlgInit(HWND hWnd)\r
1866 {\r
1867         CM_TRAFFIC t;\r
1868         LIST *c1, *c2;\r
1869         UINT i;\r
1870         // 引数チェック\r
1871         if (hWnd == NULL)\r
1872         {\r
1873                 return;\r
1874         }\r
1875 \r
1876         DlgFont(hWnd, S_8, 9, true);\r
1877         DlgFont(hWnd, S_3, 9, true);\r
1878 \r
1879         Zero(&t, sizeof(t));\r
1880         if (CmTrafficLoadFromReg(&t) == false)\r
1881         {\r
1882                 CmTrafficGetDefaultSetting(&t);\r
1883         }\r
1884 \r
1885         // 設定をダイアログに書き出す\r
1886         Check(hWnd, R_SERVER, t.ServerMode);\r
1887         Check(hWnd, R_CLIENT, t.ServerMode == false);\r
1888 \r
1889         c1 = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "HostCandidate");\r
1890         if (c1 != NULL)\r
1891         {\r
1892                 UINT i;\r
1893 \r
1894                 CbReset(hWnd, C_HOST);\r
1895 \r
1896                 for (i = 0;i < LIST_NUM(c1);i++)\r
1897                 {\r
1898                         CANDIDATE *c = LIST_DATA(c1, i);\r
1899 \r
1900                         CbAddStr(hWnd, C_HOST, c->Str, 0);\r
1901                 }\r
1902 \r
1903                 FreeCandidateList(c1);\r
1904         }\r
1905 \r
1906         if (CbNum(hWnd, C_HOST) == 0)\r
1907         {\r
1908                 CbAddStr(hWnd, C_HOST, L"speed.softether.com", 0);\r
1909         }\r
1910 \r
1911         if (IsEmptyStr(t.Host) == false)\r
1912         {\r
1913                 SetTextA(hWnd, C_HOST, t.Host);\r
1914         }\r
1915 \r
1916         c2 = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "PortCandidate");\r
1917         if (c2 != NULL)\r
1918         {\r
1919                 UINT i;\r
1920 \r
1921                 if (t.Port != 0)\r
1922                 {\r
1923                         wchar_t tmp[32];\r
1924 \r
1925                         UniToStru(tmp, t.Port);\r
1926 \r
1927                         AddCandidate(c2, tmp, 0);\r
1928                 }\r
1929 \r
1930                 CbReset(hWnd, C_PORT);\r
1931 \r
1932                 for (i = 0;i < LIST_NUM(c2);i++)\r
1933                 {\r
1934                         CANDIDATE *c = LIST_DATA(c2, i);\r
1935 \r
1936                         CbAddStr(hWnd, C_PORT, c->Str, 0);\r
1937                 }\r
1938 \r
1939                 FreeCandidateList(c2);\r
1940         }\r
1941 \r
1942         CbReset(hWnd, C_NUM);\r
1943 \r
1944         for (i = 1;i <= TRAFFIC_NUMTCP_MAX;i++)\r
1945         {\r
1946                 wchar_t tmp[32];\r
1947 \r
1948                 UniToStru(tmp, i);\r
1949 \r
1950                 CbAddStr(hWnd, C_NUM, tmp, i);\r
1951         }\r
1952 \r
1953         CbSelect(hWnd, C_NUM, t.NumTcp);\r
1954 \r
1955         Check(hWnd, R_DOWNLOAD, t.Type == TRAFFIC_TYPE_DOWNLOAD);\r
1956         Check(hWnd, R_UPLOAD, t.Type == TRAFFIC_TYPE_UPLOAD);\r
1957         Check(hWnd, R_FULL, t.Type == TRAFFIC_TYPE_FULL);\r
1958 \r
1959         Check(hWnd, R_ETHERNET, t.Raw ? false : true);\r
1960         Check(hWnd, R_DOUBLE, t.Double);\r
1961 \r
1962         SetIntEx(hWnd, E_SPAN, t.Span);\r
1963 \r
1964         CmTrafficDlgUpdate(hWnd);\r
1965 }\r
1966 \r
1967 // ダイアログの内容を構造体に入れる\r
1968 void CmTrafficDlgToStruct(HWND hWnd, CM_TRAFFIC *t)\r
1969 {\r
1970         // 引数チェック\r
1971         if (hWnd == NULL || t == NULL)\r
1972         {\r
1973                 return;\r
1974         }\r
1975 \r
1976         Zero(t, sizeof(CM_TRAFFIC));\r
1977         t->ServerMode = IsChecked(hWnd, R_SERVER);\r
1978         GetTxtA(hWnd, C_HOST, t->Host, sizeof(t->Host));\r
1979         Trim(t->Host);\r
1980 \r
1981         t->Port = GetInt(hWnd, C_PORT);\r
1982         t->NumTcp = CbGetSelect(hWnd, C_NUM);\r
1983         t->Span = GetInt(hWnd, E_SPAN);\r
1984         t->Raw = IsChecked(hWnd, R_ETHERNET) ? false : true;\r
1985         t->Double = IsChecked(hWnd, R_DOUBLE);\r
1986 \r
1987         if (IsChecked(hWnd, R_DOWNLOAD))\r
1988         {\r
1989                 t->Type = TRAFFIC_TYPE_DOWNLOAD;\r
1990         }\r
1991         else if (IsChecked(hWnd, R_UPLOAD))\r
1992         {\r
1993                 t->Type = TRAFFIC_TYPE_UPLOAD;\r
1994         }\r
1995         else\r
1996         {\r
1997                 t->Type = TRAFFIC_TYPE_FULL;\r
1998         }\r
1999 }\r
2000 \r
2001 // 通信スループット測定ツールダイアログ更新\r
2002 bool CmTrafficDlgUpdate(HWND hWnd)\r
2003 {\r
2004         CM_TRAFFIC t;\r
2005         bool ok = true;\r
2006         bool client_only;\r
2007         // 引数チェック\r
2008         if (hWnd == NULL)\r
2009         {\r
2010                 return false;\r
2011         }\r
2012 \r
2013         CmTrafficDlgToStruct(hWnd, &t);\r
2014 \r
2015         client_only = t.ServerMode ? false : true;\r
2016 \r
2017         SetEnable(hWnd, C_HOST, client_only);\r
2018         SetEnable(hWnd, S_5, client_only);\r
2019         SetEnable(hWnd, S_8, client_only);\r
2020         SetEnable(hWnd, S_9, client_only);\r
2021         SetEnable(hWnd, R_DOWNLOAD, client_only);\r
2022         SetEnable(hWnd, R_UPLOAD, client_only);\r
2023         SetEnable(hWnd, R_FULL, client_only);\r
2024         SetEnable(hWnd, S_10, client_only);\r
2025         SetEnable(hWnd, S_11, client_only);\r
2026         SetEnable(hWnd, C_NUM, client_only);\r
2027         SetEnable(hWnd, S_14, client_only);\r
2028         SetEnable(hWnd, S_12, client_only);\r
2029         SetEnable(hWnd, E_SPAN, client_only);\r
2030         SetEnable(hWnd, S_13, client_only);\r
2031         SetEnable(hWnd, R_ETHERNET, client_only);\r
2032         SetEnable(hWnd, R_DOUBLE, client_only);\r
2033 \r
2034         if (t.Port == 0 || t.Port >= 65536)\r
2035         {\r
2036                 ok = false;\r
2037         }\r
2038 \r
2039         if (t.ServerMode == false)\r
2040         {\r
2041                 if (IsEmptyStr(t.Host))\r
2042                 {\r
2043                         ok = false;\r
2044                 }\r
2045 \r
2046                 if (t.NumTcp == 0 || t.NumTcp >= 33)\r
2047                 {\r
2048                         ok = false;\r
2049                 }\r
2050 \r
2051                 if (t.Span == 0)\r
2052                 {\r
2053                         ok = false;\r
2054                 }\r
2055 \r
2056                 if (t.Type == TRAFFIC_TYPE_FULL && ((t.NumTcp % 2) != 0))\r
2057                 {\r
2058                         ok = false;\r
2059                 }\r
2060         }\r
2061 \r
2062         SetEnable(hWnd, IDOK, ok);\r
2063 \r
2064         return ok;\r
2065 }\r
2066 \r
2067 // 通信スループット測定ツールダイアログ OK ボタン\r
2068 void CmTrafficDlgOnOk(HWND hWnd)\r
2069 {\r
2070         CM_TRAFFIC t;\r
2071         LIST *c;\r
2072         // 引数チェック\r
2073         if (hWnd == NULL)\r
2074         {\r
2075                 return;\r
2076         }\r
2077 \r
2078         // 基本データの取得\r
2079         CmTrafficDlgToStruct(hWnd, &t);\r
2080 \r
2081         // レジストリに保存\r
2082         CmTrafficSaveToReg(&t);\r
2083 \r
2084         // サーバー名候補の取得と保存\r
2085         if (IsEmptyStr(t.Host) == false)\r
2086         {\r
2087                 c = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "HostCandidate");\r
2088                 if (c != NULL)\r
2089                 {\r
2090                         wchar_t tmp[MAX_SIZE];\r
2091 \r
2092                         StrToUni(tmp, sizeof(tmp), t.Host);\r
2093                         AddCandidate(c, tmp, 0);\r
2094 \r
2095                         WriteCandidateToReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, c, "HostCandidate");\r
2096 \r
2097                         FreeCandidateList(c);\r
2098                 }\r
2099         }\r
2100 \r
2101         if (t.Port != 0 && t.Port <= 65536)\r
2102         {\r
2103                 // ポート番号候補の取得と保存\r
2104                 c = ReadCandidateFromReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, "PortCandidate");\r
2105                 if (c != NULL)\r
2106                 {\r
2107                         wchar_t tmp[MAX_SIZE];\r
2108 \r
2109                         UniToStru(tmp, t.Port);\r
2110                         AddCandidate(c, tmp, 0);\r
2111 \r
2112                         WriteCandidateToReg(REG_CURRENT_USER, CM_TRAFFIC_REG_KEY, c, "PortCandidate");\r
2113 \r
2114                         FreeCandidateList(c);\r
2115                 }\r
2116         }\r
2117 \r
2118         // 実行\r
2119         CmExecTraffic(hWnd, &t);\r
2120 \r
2121         // ダイアログを更新\r
2122         CmTrafficDlgInit(hWnd);\r
2123 }\r
2124 \r
2125 // 通信スループット測定ツールダイアログプロシージャ\r
2126 UINT CmTrafficDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
2127 {\r
2128         // 引数チェック\r
2129         if (hWnd == NULL)\r
2130         {\r
2131                 return 0;\r
2132         }\r
2133 \r
2134         switch (msg)\r
2135         {\r
2136         case WM_INITDIALOG:\r
2137                 SetIcon(hWnd, 0, ICO_SWITCH);\r
2138                 CmTrafficDlgInit(hWnd);\r
2139                 break;\r
2140 \r
2141         case WM_COMMAND:\r
2142                 switch (LOWORD(wParam))\r
2143                 {\r
2144                 case R_SERVER:\r
2145                 case R_CLIENT:\r
2146                 case C_HOST:\r
2147                 case C_PORT:\r
2148                 case R_DOWNLOAD:\r
2149                 case R_UPLOAD:\r
2150                 case R_FULL:\r
2151                 case C_NUM:\r
2152                 case E_SPAN:\r
2153                 case R_ETHERNET:\r
2154                 case R_DOUBLE:\r
2155                         CmTrafficDlgUpdate(hWnd);\r
2156                         break;\r
2157                 }\r
2158 \r
2159                 switch (wParam)\r
2160                 {\r
2161                 case IDOK:\r
2162                         CmTrafficDlgOnOk(hWnd);\r
2163                         break;\r
2164 \r
2165                 case IDCANCEL:\r
2166                         Close(hWnd);\r
2167                         break;\r
2168                 }\r
2169                 break;\r
2170 \r
2171         case WM_CLOSE:\r
2172                 EndDialog(hWnd, 0);\r
2173                 break;\r
2174         }\r
2175 \r
2176         return 0;\r
2177 }\r
2178 \r
2179 // 通信スループット測定ツール\r
2180 void CmTraffic(HWND hWnd)\r
2181 {\r
2182         Dialog(hWnd, D_CM_TRAFFIC, CmTrafficDlgProc, NULL);\r
2183 }\r
2184 \r
2185 // 古いスタートアップファイルがあれば削除する\r
2186 void CmDeleteOldStartupTrayFile()\r
2187 {\r
2188         char tmp[MAX_SIZE];\r
2189         char *tag = _SS("CM_JAPANESE_ONLY_OLD_STARTUP");\r
2190         if (IsEmptyStr(tag))\r
2191         {\r
2192                 return;\r
2193         }\r
2194 \r
2195         Format(tmp, sizeof(tmp), tag, MsGetCommonStartupDir());\r
2196 \r
2197         FileDelete(tmp);\r
2198 }\r
2199 \r
2200 // PKCS ライセンス確認ダイアログ\r
2201 UINT CmPkcsEulaDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
2202 {\r
2203         UINT id;\r
2204         SECURE_DEVICE *dev;\r
2205         char *name;\r
2206         // 引数チェック\r
2207         if (hWnd == NULL)\r
2208         {\r
2209                 return 0;\r
2210         }\r
2211 \r
2212         switch (msg)\r
2213         {\r
2214         case WM_INITDIALOG:\r
2215                 id = (UINT)param;\r
2216                 dev = GetSecureDevice(id);\r
2217                 if (dev == NULL)\r
2218                 {\r
2219                         EndDialog(hWnd, 0);\r
2220                         return 0;\r
2221                 }\r
2222 \r
2223                 name = dev->ModuleName;\r
2224 \r
2225                 FormatText(hWnd, S_INFO_1, name);\r
2226                 FormatText(hWnd, S_INFO_2, name, name);\r
2227                 FormatText(hWnd, S_INFO_3, name);\r
2228 \r
2229                 break;\r
2230 \r
2231         case WM_COMMAND:\r
2232                 switch (wParam)\r
2233                 {\r
2234                 case IDOK:\r
2235                         EndDialog(hWnd, 1);\r
2236                         break;\r
2237 \r
2238                 case IDCANCEL:\r
2239                         Close(hWnd);\r
2240                         break;\r
2241                 }\r
2242                 break;\r
2243 \r
2244         case WM_CLOSE:\r
2245                 EndDialog(hWnd, 0);\r
2246                 break;\r
2247         }\r
2248 \r
2249         return 0;\r
2250 }\r
2251 \r
2252 // PKCS の DLL の EULA に同意しているかどうかの確認画面\r
2253 bool CmCheckPkcsEula(HWND hWnd, UINT id)\r
2254 {\r
2255         return (Dialog(hWnd, D_CM_PKCSEULA, CmPkcsEulaDlg, (void *)id) == 0) ? false : true;\r
2256 }\r
2257 \r
2258 // コントロール更新\r
2259 void CmSecurePinDlgUpdate(HWND hWnd)\r
2260 {\r
2261         char *tmp1, *tmp2, *tmp3;\r
2262         bool ok = true;\r
2263         // 引数チェック\r
2264         if (hWnd == NULL)\r
2265         {\r
2266                 return;\r
2267         }\r
2268 \r
2269         tmp1 = GetTextA(hWnd, E_PIN1);\r
2270         tmp2 = GetTextA(hWnd, E_PIN2);\r
2271         tmp3 = GetTextA(hWnd, E_PIN3);\r
2272         if (IsEmptyStr(tmp1))\r
2273         {\r
2274                 ok = false;\r
2275         }\r
2276         if (IsEmptyStr(tmp2))\r
2277         {\r
2278                 ok = false;\r
2279         }\r
2280         if (IsEmptyStr(tmp3))\r
2281         {\r
2282                 ok = false;\r
2283         }\r
2284         if (StrCmp(tmp2, tmp3) != 0)\r
2285         {\r
2286                 ok = false;\r
2287         }\r
2288         Free(tmp1);\r
2289         Free(tmp2);\r
2290         Free(tmp3);\r
2291         SetEnable(hWnd, IDOK, ok);\r
2292 }\r
2293 \r
2294 // PIN コード変更ダイアログ\r
2295 UINT CmSecurePinDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
2296 {\r
2297         UINT id = (UINT)param;\r
2298         char *src, *dst;\r
2299         SECURE *s;\r
2300         // 引数チェック\r
2301         if (hWnd == NULL)\r
2302         {\r
2303                 return 0;\r
2304         }\r
2305 \r
2306         switch (msg)\r
2307         {\r
2308         case WM_INITDIALOG:\r
2309                 CmSecurePinDlgUpdate(hWnd);\r
2310                 break;\r
2311 \r
2312         case WM_COMMAND:\r
2313                 switch (LOWORD(wParam))\r
2314                 {\r
2315                 case E_PIN1:\r
2316                 case E_PIN2:\r
2317                 case E_PIN3:\r
2318                         CmSecurePinDlgUpdate(hWnd);\r
2319                         break;\r
2320                 }\r
2321 \r
2322                 switch (wParam)\r
2323                 {\r
2324                 case IDOK:\r
2325                         src = GetTextA(hWnd, E_PIN1);\r
2326                         dst = GetTextA(hWnd, E_PIN3);\r
2327 \r
2328                         Disable(hWnd, IDOK);\r
2329                         Disable(hWnd, IDCANCEL);\r
2330 \r
2331                         s = OpenSec(id);\r
2332                         if (s == NULL)\r
2333                         {\r
2334                                 if (GetSecureDevice(id) != NULL)\r
2335                                 {\r
2336                                         MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),\r
2337                                                 GetSecureDevice(id)->DeviceName);\r
2338                                 }\r
2339                                 else\r
2340                                 {\r
2341                                         MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),\r
2342                                                 "Unknown");\r
2343                                 }\r
2344                         }\r
2345                         else\r
2346                         {\r
2347                                 if (OpenSecSession(s, 0) == false)\r
2348                                 {\r
2349                                         if (GetSecureDevice(id) != NULL)\r
2350                                         {\r
2351                                                 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),\r
2352                                                         GetSecureDevice(id)->DeviceName);\r
2353                                         }\r
2354                                         else\r
2355                                         {\r
2356                                                 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_DEVICE_OPEN_ERR"),\r
2357                                                         "Unknown");\r
2358                                         }\r
2359                                 }\r
2360                                 else\r
2361                                 {\r
2362                                         if (LoginSec(s, src) == false)\r
2363                                         {\r
2364                                                 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_CURRENT_BAD"));\r
2365                                                 FocusEx(hWnd, E_PIN1);\r
2366                                         }\r
2367                                         else\r
2368                                         {\r
2369                                                 if (ChangePin(s, src, dst) == false)\r
2370                                                 {\r
2371                                                         MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SEC_PIN_CHANGE_FAILED"));\r
2372                                                         FocusEx(hWnd, E_PIN1);\r
2373                                                 }\r
2374                                                 else\r
2375                                                 {\r
2376                                                         // PIN コードのキャッシュの消去\r
2377                                                         cached_pin_code_expires = 0;\r
2378                                                         cached_pin_code[0] = 0;\r
2379                                                         MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_PIN_OK"));\r
2380                                                         EndDialog(hWnd, true);\r
2381                                                 }\r
2382 \r
2383                                                 LogoutSec(s);\r
2384                                         }\r
2385 \r
2386                                         CloseSecSession(s);\r
2387                                 }\r
2388                                 CloseSec(s);\r
2389                         }\r
2390 \r
2391                         Enable(hWnd, IDOK);\r
2392                         Enable(hWnd, IDCANCEL);\r
2393 \r
2394                         Free(src);\r
2395                         Free(dst);\r
2396                         break;\r
2397 \r
2398                 case IDCANCEL:\r
2399                         Close(hWnd);\r
2400                         break;\r
2401                 }\r
2402                 break;\r
2403 \r
2404         case WM_CLOSE:\r
2405                 EndDialog(hWnd, false);\r
2406                 break;\r
2407         }\r
2408 \r
2409         return 0;\r
2410 }\r
2411 \r
2412 // PIN コードの変更\r
2413 void CmSecurePin(HWND hWnd, UINT id)\r
2414 {\r
2415         // 引数チェック\r
2416         if (hWnd == NULL || id == 0 || CheckSecureDeviceId(id) == false)\r
2417         {\r
2418                 return;\r
2419         }\r
2420 \r
2421         Dialog(hWnd, D_CM_SECURE_PIN, CmSecurePinDlg, (void *)id);\r
2422 }\r
2423 \r
2424 // オブジェクト種類選択ダイアログ\r
2425 UINT CmSecureTypeDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
2426 {\r
2427         UINT type;\r
2428         // 引数チェック\r
2429         if (hWnd == NULL)\r
2430         {\r
2431                 return 0;\r
2432         }\r
2433 \r
2434         switch (msg)\r
2435         {\r
2436         case WM_INITDIALOG:\r
2437                 type = MsRegReadInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "DefaultImportType");\r
2438                 Check(hWnd, R_DATA, type == SEC_DATA);\r
2439                 Check(hWnd, R_CERT, type == SEC_X);\r
2440                 Check(hWnd, R_KEY, type == SEC_K);\r
2441                 goto UPDATE_CONTROL;\r
2442 \r
2443         case WM_COMMAND:\r
2444                 switch (wParam)\r
2445                 {\r
2446                 case IDOK:\r
2447                         type = SEC_DATA;\r
2448                         if (IsChecked(hWnd, R_CERT))\r
2449                         {\r
2450                                 type = SEC_X;\r
2451                         }\r
2452                         else if (IsChecked(hWnd, R_KEY))\r
2453                         {\r
2454                                 type = SEC_K;\r
2455                         }\r
2456 \r
2457                         MsRegWriteInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "DefaultImportType", type);\r
2458 \r
2459                         EndDialog(hWnd, type);\r
2460                         break;\r
2461 \r
2462                 case IDCANCEL:\r
2463                         Close(hWnd);\r
2464                         break;\r
2465                 case R_CERT:\r
2466                 case R_KEY:\r
2467                 case R_DATA:\r
2468 UPDATE_CONTROL:\r
2469                         SetEnable(hWnd, IDOK, IsChecked(hWnd, R_CERT) || \r
2470                                 IsChecked(hWnd, R_KEY) || \r
2471                                 IsChecked(hWnd, R_DATA));\r
2472                         break;\r
2473                 }\r
2474                 break;\r
2475 \r
2476         case WM_CLOSE:\r
2477                 EndDialog(hWnd, INFINITE);\r
2478                 break;\r
2479         }\r
2480 \r
2481         return 0;\r
2482 }\r
2483 \r
2484 // オブジェクト種類選択\r
2485 UINT CmSecureType(HWND hWnd)\r
2486 {\r
2487         return Dialog(hWnd, D_CM_SECURE_TYPE, CmSecureTypeDlg, NULL);\r
2488 }\r
2489 \r
2490 // ダイアログ初期化\r
2491 void CmSecureManagerDlgInit(HWND hWnd, UINT id)\r
2492 {\r
2493         SECURE_DEVICE *dev;\r
2494         // 引数チェック\r
2495         if (hWnd == NULL || id == 0)\r
2496         {\r
2497                 return;\r
2498         }\r
2499 \r
2500         SetIcon(hWnd, 0, ICO_SECURE);\r
2501 \r
2502         dev = GetSecureDevice(id);\r
2503         if (dev != NULL)\r
2504         {\r
2505                 FormatText(hWnd, S_INFO, dev->DeviceName);\r
2506         }\r
2507 \r
2508         SetFont(hWnd, B_BOLD, Font(0, true));\r
2509 \r
2510         LvInit(hWnd, L_LIST);\r
2511         LvInsertColumn(hWnd, L_LIST, 0, _UU("SEC_MGR_COLUMN1"), 200);\r
2512         LvInsertColumn(hWnd, L_LIST, 1, _UU("SEC_MGR_COLUMN2"), 110);\r
2513 \r
2514         CmSecureManagerDlgUpdate(hWnd, id);\r
2515 }\r
2516 \r
2517 // コントロール更新\r
2518 void CmSecureManagerDlgUpdate(HWND hWnd, UINT id)\r
2519 {\r
2520         bool b = true;\r
2521         bool read_only = IsJPKI(id);\r
2522         // 引数チェック\r
2523         if (hWnd == NULL)\r
2524         {\r
2525                 return;\r
2526         }\r
2527 \r
2528         if (LvIsSingleSelected(hWnd, L_LIST) == false)\r
2529         {\r
2530                 b = false;\r
2531         }\r
2532 \r
2533         SetEnable(hWnd, B_EXPORT, b && ((UINT)LvGetParam(hWnd, L_LIST, LvGetSelected(hWnd, L_LIST)) != SEC_K));\r
2534         SetEnable(hWnd, B_DELETE, b && (read_only == false));\r
2535         SetEnable(hWnd, B_PIN, (read_only == false));\r
2536         SetEnable(hWnd, B_IMPORT, (read_only == false));\r
2537         SetEnable(hWnd, B_NEW_CERT, (read_only == false));\r
2538 }\r
2539 \r
2540 // 内容更新\r
2541 void CmSecureManagerDlgRefresh(HWND hWnd, UINT id)\r
2542 {\r
2543         bool ret;\r
2544         LIST *o;\r
2545         WINUI_SECURE_BATCH batch[] =\r
2546         {\r
2547                 {WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},\r
2548         };\r
2549         // 引数チェック\r
2550         if (hWnd == NULL || id == 0)\r
2551         {\r
2552                 return;\r
2553         }\r
2554 \r
2555         ret = SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0);\r
2556 \r
2557         if (ret == false)\r
2558         {\r
2559                 return;\r
2560         }\r
2561 \r
2562         o = batch[0].EnumList;\r
2563         if (o != NULL)\r
2564         {\r
2565                 CmSecureManagerDlgPrintList(hWnd, o);\r
2566 \r
2567                 FreeEnumSecObject(o);\r
2568         }\r
2569 \r
2570         // コントロール更新\r
2571         CmSecureManagerDlgUpdate(hWnd, id);\r
2572 }\r
2573 \r
2574 // オブジェクト一覧の表示\r
2575 void CmSecureManagerDlgPrintList(HWND hWnd, LIST *o)\r
2576 {\r
2577         CmSecureManagerDlgPrintListEx(hWnd, L_LIST, o, INFINITE);\r
2578 }\r
2579 void CmSecureManagerDlgPrintListEx(HWND hWnd, UINT id, LIST *o, UINT type)\r
2580 {\r
2581         UINT i;\r
2582         LVB *v;\r
2583         // 引数チェック\r
2584         if (hWnd == NULL || o == NULL)\r
2585         {\r
2586                 return;\r
2587         }\r
2588 \r
2589         LvReset(hWnd, id);\r
2590 \r
2591         v = LvInsertStart();\r
2592 \r
2593         for (i = 0;i < LIST_NUM(o);i++)\r
2594         {\r
2595                 UINT icon = ICO_LOG2;\r
2596                 wchar_t tmp1[MAX_SIZE], *tmp2, *tmp3;\r
2597                 SEC_OBJ *obj = LIST_DATA(o, i);\r
2598 \r
2599                 if (type == INFINITE || obj->Type == type)\r
2600                 {\r
2601                         StrToUni(tmp1, sizeof(tmp1), obj->Name);\r
2602                         tmp2 = CmSecureObjTypeToStr(obj->Type);\r
2603                         tmp3 = obj->Private ? _UU("SEC_YES") : _UU("SEC_NO");\r
2604 \r
2605                         if (obj->Type == SEC_X)\r
2606                         {\r
2607                                 icon = ICO_CERT;\r
2608                         }\r
2609                         else if (obj->Type == SEC_K || obj->Type == SEC_P)\r
2610                         {\r
2611                                 icon = ICO_KEY;\r
2612                         }\r
2613 \r
2614                         LvInsertAdd(v, icon, (void *)obj->Type, 2, tmp1, tmp2);\r
2615                 }\r
2616         }\r
2617 \r
2618         LvInsertEnd(v, hWnd, id);\r
2619 }\r
2620 \r
2621 // オブジェクトの種類を文字列にする\r
2622 wchar_t *CmSecureObjTypeToStr(UINT type)\r
2623 {\r
2624         wchar_t *ret = _UU("SEC_TYPE_DATA");\r
2625 \r
2626         if (type == SEC_X)\r
2627         {\r
2628                 ret = _UU("SEC_TYPE_CERT");\r
2629         }\r
2630         else if (type == SEC_K)\r
2631         {\r
2632                 ret = _UU("SEC_TYPE_KEY");\r
2633         }\r
2634         else if (type == SEC_P)\r
2635         {\r
2636                 ret = _UU("SEC_TYPE_PUB");\r
2637         }\r
2638 \r
2639         return ret;\r
2640 }\r
2641 \r
2642 // 新しい証明書を作成して書き込み\r
2643 void CmSecureManagerDlgNewCert(HWND hWnd, UINT id)\r
2644 {\r
2645         X *x;\r
2646         K *k;\r
2647         char default_name[MAX_SIZE];\r
2648         char *object_name;\r
2649         bool ok = false;\r
2650         WINUI_SECURE_BATCH batch[] =\r
2651         {\r
2652                 {WINUI_SECURE_WRITE_CERT, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL},\r
2653                 {WINUI_SECURE_WRITE_KEY, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL},\r
2654                 {WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},\r
2655         };\r
2656         // 引数チェック\r
2657         if (hWnd == NULL || id == 0)\r
2658         {\r
2659                 return;\r
2660         }\r
2661 \r
2662         // 証明書の作成ダイアログ\r
2663         if (SmCreateCert(hWnd, &x, &k, true, NULL) == false)\r
2664         {\r
2665                 return;\r
2666         }\r
2667         // デフォルトの名前を生成する\r
2668         GetPrintNameFromXA(default_name, sizeof(default_name), x);\r
2669         ConvertSafeFileName(default_name, sizeof(default_name), default_name);\r
2670 \r
2671         object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),\r
2672                 _UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_CERT, false, false);\r
2673 \r
2674         if (object_name != NULL)\r
2675         {\r
2676                 // 書き込みと列挙\r
2677                 batch[0].InputX = x;\r
2678                 batch[0].Name = object_name;\r
2679                 batch[1].InputK = k;\r
2680                 batch[1].Name = object_name;\r
2681 \r
2682                 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)\r
2683                 {\r
2684                         // 失敗\r
2685                 }\r
2686                 else\r
2687                 {\r
2688                         ok = true;\r
2689                 }\r
2690 \r
2691                 Free(object_name);\r
2692         }\r
2693 \r
2694         if (ok)\r
2695         {\r
2696                 LIST *o = batch[2].EnumList;\r
2697 \r
2698                 CmSecureManagerDlgPrintList(hWnd, o);\r
2699 \r
2700                 FreeEnumSecObject(o);\r
2701 \r
2702                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_NEW_CERT_IMPORT_OK"));\r
2703         }\r
2704 \r
2705         FreeX(x);\r
2706         FreeK(k);\r
2707 }\r
2708 \r
2709 // インポート\r
2710 void CmSecureManagerDlgImport(HWND hWnd, UINT id)\r
2711 {\r
2712         UINT type;\r
2713         char name[MAX_SIZE];\r
2714         wchar_t tmp2[MAX_SIZE];\r
2715         wchar_t *tmp;\r
2716         wchar_t *filename;\r
2717         BUF *b;\r
2718         K *k;\r
2719         bool ok = false;\r
2720         X *x;\r
2721         WINUI_SECURE_BATCH batch[] =\r
2722         {\r
2723                 {WINUI_SECURE_WRITE_DATA, name, true, NULL, NULL, NULL, NULL, NULL, NULL},\r
2724                 {WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},\r
2725         };\r
2726         // 引数チェック\r
2727         if (hWnd == NULL || id == 0)\r
2728         {\r
2729                 return;\r
2730         }\r
2731 \r
2732         // オブジェクトの種類の選択\r
2733         type = CmSecureType(hWnd);\r
2734 \r
2735         switch (type)\r
2736         {\r
2737         case SEC_DATA:\r
2738                 // データ\r
2739                 tmp = OpenDlg(hWnd, _UU("DLG_ALL_FILES"), _UU("SEC_IMPORT_DATA"));\r
2740                 if (tmp == NULL)\r
2741                 {\r
2742                         return;\r
2743                 }\r
2744 \r
2745                 filename = CopyUniStr(tmp);\r
2746                 Free(tmp);\r
2747 \r
2748                 // ファイル読み込み\r
2749                 b = ReadDumpW(filename);\r
2750                 if (b == NULL)\r
2751                 {\r
2752                         // 読み込み失敗\r
2753                         MsgBox(hWnd, MB_ICONSTOP, _UU("SEC_READ_FAILED"));\r
2754                 }\r
2755                 else\r
2756                 {\r
2757                         if (b->Size > MAX_SEC_DATA_SIZE)\r
2758                         {\r
2759                                 // ファイルサイズが大きすぎる\r
2760                                 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_DATA_TOO_BIG"), MAX_SEC_DATA_SIZE);\r
2761                         }\r
2762                         else\r
2763                         {\r
2764                                 // デフォルトの名前を生成する\r
2765                                 char default_name[MAX_SIZE];\r
2766                                 wchar_t default_name_w[MAX_SIZE];\r
2767                                 char *object_name;\r
2768                                 GetFileNameFromFilePathW(default_name_w, sizeof(default_name_w), filename);\r
2769                                 UniToStr(default_name, sizeof(default_name), default_name_w);\r
2770                                 ConvertSafeFileName(default_name, sizeof(default_name), default_name);\r
2771 \r
2772                                 object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),\r
2773                                         _UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_LOG2, false, false);\r
2774 \r
2775                                 if (object_name != NULL)\r
2776                                 {\r
2777                                         // 書き込みと列挙\r
2778                                         batch[0].InputData = b;\r
2779                                         batch[0].Name = object_name;\r
2780 \r
2781                                         if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)\r
2782                                         {\r
2783                                                 // 失敗\r
2784                                         }\r
2785                                         else\r
2786                                         {\r
2787                                                 ok = true;\r
2788                                         }\r
2789 \r
2790                                         Free(object_name);\r
2791                                 }\r
2792                         }\r
2793 \r
2794                         FreeBuf(b);\r
2795                 }\r
2796 \r
2797                 Free(filename);\r
2798                 break;\r
2799 \r
2800         case SEC_X:\r
2801                 // 証明書読み込み\r
2802                 if (CmLoadXExW(hWnd, &x, tmp2, sizeof(tmp2)))\r
2803                 {\r
2804                         // デフォルトの名前を生成する\r
2805                         char default_name[MAX_SIZE];\r
2806                         wchar_t default_name_w[MAX_PATH];\r
2807                         char *object_name;\r
2808                         GetFileNameFromFilePathW(default_name_w, sizeof(default_name_w), tmp2);\r
2809                         UniToStr(default_name, sizeof(default_name), default_name_w);\r
2810                         ConvertSafeFileName(default_name, sizeof(default_name), default_name);\r
2811 \r
2812                         object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),\r
2813                                 _UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_CERT, false, false);\r
2814 \r
2815                         if (object_name != NULL)\r
2816                         {\r
2817                                 // 書き込みと列挙\r
2818                                 batch[0].Type = WINUI_SECURE_WRITE_CERT;\r
2819                                 batch[0].InputX = x;\r
2820                                 batch[0].Name = object_name;\r
2821 \r
2822                                 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)\r
2823                                 {\r
2824                                         // 失敗\r
2825                                 }\r
2826                                 else\r
2827                                 {\r
2828                                         ok = true;\r
2829                                 }\r
2830 \r
2831                                 Free(object_name);\r
2832                         }\r
2833 \r
2834                         FreeX(x);\r
2835                 }\r
2836 \r
2837                 break;\r
2838 \r
2839         case SEC_K:\r
2840                 // 秘密鍵\r
2841                 if (CmLoadKExW(hWnd, &k, tmp2, sizeof(tmp2)))\r
2842                 {\r
2843                         // デフォルトの名前を生成する\r
2844                         char default_name[MAX_SIZE];\r
2845                         wchar_t default_name_w[MAX_PATH];\r
2846                         char *object_name;\r
2847                         GetFileNameFromFilePathW(default_name_w, sizeof(default_name_w), tmp2);\r
2848                         UniToStr(default_name, sizeof(default_name), default_name_w);\r
2849                         ConvertSafeFileName(default_name, sizeof(default_name), default_name);\r
2850 \r
2851                         object_name = StringDlgA(hWnd, _UU("SEC_OBJECT_NAME_TITLE"),\r
2852                                 _UU("SEC_OBJECT_NAME_INFO"), default_name, ICO_KEY, false, false);\r
2853 \r
2854                         if (object_name != NULL)\r
2855                         {\r
2856                                 // 書き込みと列挙\r
2857                                 batch[0].Type = WINUI_SECURE_WRITE_KEY;\r
2858                                 batch[0].InputK = k;\r
2859                                 batch[0].Name = object_name;\r
2860 \r
2861                                 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)\r
2862                                 {\r
2863                                         // 失敗\r
2864                                 }\r
2865                                 else\r
2866                                 {\r
2867                                         ok = true;\r
2868                                 }\r
2869 \r
2870                                 Free(object_name);\r
2871                         }\r
2872 \r
2873                         FreeK(k);\r
2874                 }\r
2875                 break;\r
2876 \r
2877         default:\r
2878                 // 無効\r
2879                 return;\r
2880         }\r
2881 \r
2882         if (ok)\r
2883         {\r
2884                 LIST *o = batch[1].EnumList;\r
2885 \r
2886                 CmSecureManagerDlgPrintList(hWnd, o);\r
2887 \r
2888                 FreeEnumSecObject(o);\r
2889 \r
2890                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_OBJECT_IMPORT_OK"));\r
2891         }\r
2892 }\r
2893 \r
2894 // オブジェクトのエクスポート\r
2895 void CmSecureManagerDlgExport(HWND hWnd, UINT id)\r
2896 {\r
2897         char name[MAX_SIZE];\r
2898         UINT method = WINUI_SECURE_READ_DATA;\r
2899         char *tmp;\r
2900         UINT type;\r
2901         wchar_t filename[MAX_PATH];\r
2902         wchar_t *uni_tmp;\r
2903         X *x;\r
2904         BUF *b;\r
2905         wchar_t default_name[128];\r
2906         WINUI_SECURE_BATCH batch[] =\r
2907         {\r
2908                 {WINUI_SECURE_READ_DATA, name, true, NULL, NULL, NULL, NULL, NULL, NULL},\r
2909         };\r
2910         UINT i;\r
2911         // 引数チェック\r
2912         if (hWnd == NULL || id == 0)\r
2913         {\r
2914                 return;\r
2915         }\r
2916 \r
2917         i = LvGetSelected(hWnd, L_LIST);\r
2918         if (i == INFINITE)\r
2919         {\r
2920                 return;\r
2921         }\r
2922 \r
2923         tmp = LvGetStrA(hWnd, L_LIST, i, 0);\r
2924         StrCpy(name, sizeof(name), tmp);\r
2925         Free(tmp);\r
2926 \r
2927         type = (UINT)LvGetParam(hWnd, L_LIST, i);\r
2928 \r
2929         switch (type)\r
2930         {\r
2931         case SEC_X:\r
2932                 method = WINUI_SECURE_READ_CERT;\r
2933                 break;\r
2934 \r
2935         default:\r
2936                 method = WINUI_SECURE_READ_DATA;\r
2937                 break;\r
2938         }\r
2939 \r
2940         batch[0].Type = method;\r
2941 \r
2942         // スマートカードの操作を行う\r
2943         if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)\r
2944         {\r
2945                 return;\r
2946         }\r
2947 \r
2948         switch (type)\r
2949         {\r
2950         case SEC_X:\r
2951                 // 証明書\r
2952                 x = batch[0].OutputX;\r
2953 \r
2954                 CertDlg(hWnd, x, NULL, true);\r
2955 \r
2956                 FreeX(x);\r
2957                 break;\r
2958 \r
2959         default:\r
2960                 // ファイル\r
2961                 b = batch[0].OutputData;\r
2962                 StrToUni(default_name, sizeof(default_name), name);\r
2963                 uni_tmp = SaveDlg(hWnd, _UU("DLG_ALL_FILES"), _UU("DLG_SAVE_FILE"), default_name, NULL);\r
2964 \r
2965                 if (uni_tmp != NULL)\r
2966                 {\r
2967                         UniStrCpy(filename, sizeof(filename), uni_tmp);\r
2968 \r
2969                         DumpBufW(b, filename);\r
2970 \r
2971                         Free(uni_tmp);\r
2972 \r
2973                         MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_OBJECT_EXPORT_OK"));\r
2974                 }\r
2975 \r
2976 \r
2977                 FreeBuf(b);\r
2978                 break;\r
2979         }\r
2980 }\r
2981 \r
2982 // オブジェクトの削除\r
2983 void CmSecureManagerDlgDelete(HWND hWnd, UINT id)\r
2984 {\r
2985         char name[MAX_SIZE];\r
2986         UINT method = WINUI_SECURE_DELETE_DATA;\r
2987         char *tmp;\r
2988         UINT type;\r
2989         LIST *o;\r
2990         WINUI_SECURE_BATCH batch[] =\r
2991         {\r
2992                 {WINUI_SECURE_DELETE_OBJECT, name, false, NULL, NULL, NULL, NULL, NULL, NULL},\r
2993                 {WINUI_SECURE_ENUM_OBJECTS, NULL, false, NULL, NULL, NULL, NULL, NULL, NULL},\r
2994         };\r
2995         UINT i;\r
2996         // 引数チェック\r
2997         if (hWnd == NULL || id == 0)\r
2998         {\r
2999                 return;\r
3000         }\r
3001 \r
3002         i = LvGetSelected(hWnd, L_LIST);\r
3003         if (i == INFINITE)\r
3004         {\r
3005                 return;\r
3006         }\r
3007 \r
3008         tmp = LvGetStrA(hWnd, L_LIST, i, 0);\r
3009         StrCpy(name, sizeof(name), tmp);\r
3010         Free(tmp);\r
3011 \r
3012         type = (UINT)LvGetParam(hWnd, L_LIST, i);\r
3013 \r
3014         switch (type)\r
3015         {\r
3016         case SEC_X:\r
3017                 method = WINUI_SECURE_DELETE_CERT;\r
3018                 break;\r
3019 \r
3020         case SEC_K:\r
3021                 method = WINUI_SECURE_DELETE_KEY;\r
3022                 break;\r
3023 \r
3024         default:\r
3025                 method = WINUI_SECURE_DELETE_DATA;\r
3026                 break;\r
3027         }\r
3028 \r
3029         batch[0].Type = method;\r
3030 \r
3031         if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), id, 0) == false)\r
3032         {\r
3033                 return;\r
3034         }\r
3035 \r
3036         o = batch[1].EnumList;\r
3037 \r
3038         CmSecureManagerDlgPrintList(hWnd, o);\r
3039 \r
3040         FreeEnumSecObject(o);\r
3041 }\r
3042 \r
3043 static bool cm_secure_manager_no_new_cert = false;\r
3044 \r
3045 // スマートカードマネージャダイアログ\r
3046 UINT CmSecureManagerDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
3047 {\r
3048         NMHDR *n;\r
3049         UINT id = (UINT)param;\r
3050         // 引数チェック\r
3051         if (hWnd == NULL)\r
3052         {\r
3053                 return 0;\r
3054         }\r
3055 \r
3056         switch (msg)\r
3057         {\r
3058         case WM_INITDIALOG:\r
3059                 CmSecureManagerDlgInit(hWnd, id);\r
3060 \r
3061                 if (cm_secure_manager_no_new_cert)\r
3062                 {\r
3063                         Hide(hWnd, B_NEW_CERT);\r
3064                 }\r
3065 \r
3066                 SetTimer(hWnd, 1, 1, NULL);\r
3067                 break;\r
3068 \r
3069         case WM_COMMAND:\r
3070                 switch (wParam)\r
3071                 {\r
3072                 case B_REFRESH:\r
3073                         CmSecureManagerDlgRefresh(hWnd, id);\r
3074                         break;\r
3075 \r
3076                 case B_IMPORT:\r
3077                         CmSecureManagerDlgImport(hWnd, id);\r
3078                         break;\r
3079 \r
3080                 case B_EXPORT:\r
3081                         CmSecureManagerDlgExport(hWnd, id);\r
3082                         break;\r
3083 \r
3084                 case B_DELETE:\r
3085                         if (MsgBox(hWnd, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2,\r
3086                                 _UU("SEC_DELETE_MSG")) == IDYES)\r
3087                         {\r
3088                                 CmSecureManagerDlgDelete(hWnd, id);\r
3089                         }\r
3090                         break;\r
3091 \r
3092                 case B_NEW_CERT:\r
3093                         CmSecureManagerDlgNewCert(hWnd, id);\r
3094                         break;\r
3095 \r
3096                 case B_PIN:\r
3097                         CmSecurePin(hWnd, id);\r
3098                         break;\r
3099 \r
3100                 case IDCANCEL:\r
3101                         Close(hWnd);\r
3102                         break;\r
3103                 }\r
3104                 break;\r
3105 \r
3106         case WM_TIMER:\r
3107                 switch (wParam)\r
3108                 {\r
3109                 case 1:\r
3110                         KillTimer(hWnd, 1);\r
3111 \r
3112                         CmSecureManagerDlgRefresh(hWnd, id);\r
3113                         break;\r
3114                 }\r
3115                 break;\r
3116 \r
3117         case WM_CLOSE:\r
3118                 EndDialog(hWnd, 0);\r
3119                 break;\r
3120 \r
3121         case WM_NOTIFY:\r
3122                 n = (NMHDR *)lParam;\r
3123                 switch (n->idFrom)\r
3124                 {\r
3125                 case L_LIST:\r
3126                         switch (n->code)\r
3127                         {\r
3128                         case LVN_ITEMCHANGED:\r
3129                                 CmSecureManagerDlgUpdate(hWnd, id);\r
3130                                 break;\r
3131                         }\r
3132                         break;\r
3133                 }\r
3134                 break;\r
3135         }\r
3136 \r
3137         return 0;\r
3138 }\r
3139 \r
3140 // スマートカードマネージャ\r
3141 void CmSecureManager(HWND hWnd, UINT id)\r
3142 {\r
3143         CmSecureManagerEx(hWnd, id, false);\r
3144 }\r
3145 void CmSecureManagerEx(HWND hWnd, UINT id, bool no_new_cert)\r
3146 {\r
3147         // 引数チェック\r
3148         if (hWnd == NULL || id == 0)\r
3149         {\r
3150                 return;\r
3151         }\r
3152 \r
3153         // ID チェック\r
3154         if (CheckSecureDeviceId(id) == false)\r
3155         {\r
3156                 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SEC_INVALID_ID"));\r
3157                 return;\r
3158         }\r
3159 \r
3160         if (no_new_cert)\r
3161         {\r
3162                 cm_secure_manager_no_new_cert = true;\r
3163         }\r
3164         else\r
3165         {\r
3166                 cm_secure_manager_no_new_cert = false;\r
3167         }\r
3168 \r
3169         Dialog(hWnd, D_CM_SECURE_MANAGER, CmSecureManagerDlg, (void *)id);\r
3170 }\r
3171 \r
3172 // クライアント用スマートカードマネージャ\r
3173 void CmClientSecureManager(HWND hWnd)\r
3174 {\r
3175         RPC_USE_SECURE t;\r
3176         UINT id;\r
3177 \r
3178         Zero(&t, sizeof(t));\r
3179         CcGetUseSecure(cm->Client, &t);\r
3180 \r
3181         id = t.DeviceId;\r
3182 \r
3183         if (id == 0 || CheckSecureDeviceId(id) == false)\r
3184         {\r
3185                 id = CmClientSelectSecure(hWnd);\r
3186         }\r
3187 \r
3188         if (id == 0)\r
3189         {\r
3190                 return;\r
3191         }\r
3192 \r
3193         CmSecureManager(hWnd, id);\r
3194 }\r
3195 \r
3196 // ダイアログの初期化\r
3197 void CmSelectSecureDlgInit(HWND hWnd, UINT default_id)\r
3198 {\r
3199         UINT i;\r
3200         LIST *o;\r
3201         LVB *v;\r
3202 \r
3203         SetIcon(hWnd, 0, ICO_SECURE);\r
3204 \r
3205         o = GetSecureDeviceList();\r
3206 \r
3207         LvInit(hWnd, L_LIST);\r
3208         LvInsertColumn(hWnd, L_LIST, 0, _UU("SEC_COLUMN1"), 150);\r
3209         LvInsertColumn(hWnd, L_LIST, 1, _UU("SEC_COLUMN2"), 100);\r
3210         LvInsertColumn(hWnd, L_LIST, 2, _UU("SEC_COLUMN3"), 130);\r
3211         LvInsertColumn(hWnd, L_LIST, 3, _UU("SEC_COLUMN4"), 100);\r
3212 \r
3213         v = LvInsertStart();\r
3214 \r
3215         for (i = 0;i < LIST_NUM(o);i++)\r
3216         {\r
3217                 wchar_t tmp1[MAX_SIZE];\r
3218                 wchar_t *tmp2;\r
3219                 wchar_t tmp3[MAX_SIZE];\r
3220                 wchar_t tmp4[MAX_SIZE];\r
3221                 SECURE_DEVICE *dev = LIST_DATA(o, i);\r
3222 \r
3223                 StrToUni(tmp1, sizeof(tmp1), dev->DeviceName);\r
3224                 tmp2 = (dev->Type == SECURE_IC_CARD) ? _UU("SEC_SMART_CARD") : _UU("SEC_USB_TOKEN");\r
3225                 StrToUni(tmp3, sizeof(tmp3), dev->Manufacturer);\r
3226                 StrToUni(tmp4, sizeof(tmp4), dev->ModuleName);\r
3227 \r
3228                 LvInsertAdd(v, ICO_SECURE, (void *)dev->Id, 4, tmp1, tmp2, tmp3, tmp4);\r
3229         }\r
3230 \r
3231         LvInsertEnd(v, hWnd, L_LIST);\r
3232 \r
3233         if (default_id != 0)\r
3234         {\r
3235                 LvSelect(hWnd, L_LIST, LvSearchParam(hWnd, L_LIST, (void *)default_id));\r
3236         }\r
3237 \r
3238         ReleaseList(o);\r
3239 \r
3240         // コントロール更新\r
3241         CmSelectSecureDlgUpdate(hWnd);\r
3242 }\r
3243 \r
3244 // ダイアログのコントロール更新\r
3245 void CmSelectSecureDlgUpdate(HWND hWnd)\r
3246 {\r
3247         SetEnable(hWnd, IDOK, LvIsSingleSelected(hWnd, L_LIST));\r
3248 }\r
3249 \r
3250 // スマートカード選択ダイアログ\r
3251 UINT CmSelectSecureDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
3252 {\r
3253         UINT default_id = (UINT)param;\r
3254         NMHDR *n = NULL;\r
3255         static UINT old_id;\r
3256         // 引数チェック\r
3257         if (hWnd == NULL)\r
3258         {\r
3259                 return 0;\r
3260         }\r
3261 \r
3262         switch (msg)\r
3263         {\r
3264         case WM_INITDIALOG:\r
3265                 old_id = default_id;\r
3266                 CmSelectSecureDlgInit(hWnd, default_id);\r
3267 \r
3268                 if (LvNum(hWnd, L_LIST) == 0)\r
3269                 {\r
3270                         // 1 つもスマートカードが無い\r
3271                         SetTimer(hWnd, 1, 100, NULL);\r
3272                 }\r
3273                 break;\r
3274 \r
3275         case WM_TIMER:\r
3276                 switch (wParam)\r
3277                 {\r
3278                 case 1:\r
3279                         KillTimer(hWnd, 1);\r
3280 \r
3281                         Disable(hWnd, L_LIST);\r
3282                         MsgBox(hWnd, MB_ICONINFORMATION, _UU("SEC_NO_SECURE_DEVICE"));\r
3283                         break;\r
3284                 }\r
3285                 break;\r
3286 \r
3287         case WM_COMMAND:\r
3288                 switch (wParam)\r
3289                 {\r
3290                 case IDOK:\r
3291                         if (IsEnable(hWnd, IDOK))\r
3292                         {\r
3293                                 UINT i = LvGetSelected(hWnd, L_LIST);\r
3294                                 if (i != INFINITE)\r
3295                                 {\r
3296                                         UINT id = (UINT)LvGetParam(hWnd, L_LIST, i);\r
3297 \r
3298                                         if (old_id != id)\r
3299                                         {\r
3300                                                 if (CmCheckPkcsEula(hWnd, id) == false)\r
3301                                                 {\r
3302                                                         break;\r
3303                                                 }\r
3304                                         }\r
3305                                         EndDialog(hWnd, id);\r
3306                                 }\r
3307                         }\r
3308                         break;\r
3309 \r
3310                 case IDCANCEL:\r
3311                         Close(hWnd);\r
3312                         break;\r
3313                 }\r
3314                 break;\r
3315 \r
3316         case WM_CLOSE:\r
3317                 EndDialog(hWnd, 0);\r
3318                 break;\r
3319 \r
3320         case WM_NOTIFY:\r
3321                 n = (NMHDR *)lParam;\r
3322                 switch (n->idFrom)\r
3323                 {\r
3324                 case L_LIST:\r
3325                         switch (n->code)\r
3326                         {\r
3327                         case LVN_ITEMCHANGED:\r
3328                                 CmSelectSecureDlgUpdate(hWnd);\r
3329                                 break;\r
3330                         case NM_DBLCLK:\r
3331                                 Command(hWnd, IDOK);\r
3332                                 break;\r
3333                         }\r
3334                         break;\r
3335                 }\r
3336                 break;\r
3337         }\r
3338 \r
3339         return 0;\r
3340 }\r
3341 \r
3342 // 使用するスマートカードデバイスの選択\r
3343 UINT CmSelectSecure(HWND hWnd, UINT current_id)\r
3344 {\r
3345         return Dialog(hWnd, D_CM_SELECT_SECURE, CmSelectSecureDlg, (void *)current_id);\r
3346 }\r
3347 \r
3348 // 使用するスマートカードデバイスの選択 (クライアント)\r
3349 UINT CmClientSelectSecure(HWND hWnd)\r
3350 {\r
3351         UINT id;\r
3352         RPC_USE_SECURE t;\r
3353 \r
3354         if (cm->server_name != NULL)\r
3355         {\r
3356                 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("CM_SECURE_MUST_LOCAL"));\r
3357                 return 0;\r
3358         }\r
3359 \r
3360         Zero(&t, sizeof(t));\r
3361         CcGetUseSecure(cm->Client, &t);\r
3362 \r
3363         id = t.DeviceId;\r
3364 \r
3365         id = CmSelectSecure(hWnd, id);\r
3366         if (id != 0)\r
3367         {\r
3368                 Zero(&t, sizeof(t));\r
3369                 t.DeviceId = id;\r
3370 \r
3371                 CALL(hWnd, CcUseSecure(cm->Client, &t));\r
3372 \r
3373                 SmWriteSelectSecureIdReg(id);\r
3374         }\r
3375 \r
3376         return id;\r
3377 }\r
3378 \r
3379 // ショートカット接続\r
3380 void CmConnectShortcut(UCHAR *key)\r
3381 {\r
3382         UINT ret;\r
3383         // 引数チェック\r
3384         if (key == NULL)\r
3385         {\r
3386                 return;\r
3387         }\r
3388 \r
3389         // 接続を試行する\r
3390         ret = CcShortcut(key);\r
3391 \r
3392         if (ret != ERR_NO_ERROR)\r
3393         {\r
3394                 if (ret == ERR_ACCOUNT_ACTIVE)\r
3395                 {\r
3396                         // 現在接続中なので、切断するかどうか問い合わせる\r
3397                         if (MsgBox(NULL, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_SHORTCUT_DISCONNECT")) == IDYES)\r
3398                         {\r
3399                                 // 切断してみる\r
3400                                 ret = CcShortcutDisconnect(key);\r
3401 \r
3402                                 if (ret != ERR_NO_ERROR)\r
3403                                 {\r
3404                                         // エラー\r
3405                                         MsgBox(NULL, MB_ICONEXCLAMATION, GetUniErrorStr(ret));\r
3406                                 }\r
3407                         }\r
3408                 }\r
3409                 else\r
3410                 {\r
3411                         // その他のエラー\r
3412                         MsgBox(NULL, MB_ICONEXCLAMATION, GetUniErrorStr(ret));\r
3413                 }\r
3414         }\r
3415 }\r
3416 \r
3417 // 音声ガイドを再生する\r
3418 void CmVoice(char *name)\r
3419 {\r
3420         UINT i;\r
3421         // 引数チェック\r
3422         if (name == NULL)\r
3423         {\r
3424                 return;\r
3425         }\r
3426 \r
3427         if (cm->DisableVoice)\r
3428         {\r
3429                 return;\r
3430         }\r
3431 \r
3432         for (i = 0;i < sizeof(cm_voice) / sizeof(CM_VOICE);i++)\r
3433         {\r
3434                 if (cm_voice[i].voice_id == cm->VoiceId)\r
3435                 {\r
3436                         char tmp[MAX_SIZE];\r
3437                         Format(tmp, sizeof(tmp), "%s_%s.wav", cm_voice[i].perfix, name);\r
3438                         MsPlaySound(tmp);\r
3439                         return;\r
3440                 }\r
3441         }\r
3442 }\r
3443 \r
3444 // パスワード変更画面更新\r
3445 void CmChangePasswordUpdate(HWND hWnd, CM_CHANGE_PASSWORD *p)\r
3446 {\r
3447         bool ok = true;\r
3448         char *s1, *s2;\r
3449         // 引数チェック\r
3450         if (hWnd == NULL || p == NULL)\r
3451         {\r
3452                 return;\r
3453         }\r
3454 \r
3455         if (IsEmpty(hWnd, E_USERNAME))\r
3456         {\r
3457                 ok = false;\r
3458         }\r
3459 \r
3460         s1 = GetTextA(hWnd, E_NEW_PASSWORD1);\r
3461         s2 = GetTextA(hWnd, E_NEW_PASSWORD2);\r
3462 \r
3463         if (StrCmp(s1, s2) != 0)\r
3464         {\r
3465                 ok = false;\r
3466         }\r
3467 \r
3468         Free(s1);\r
3469         Free(s2);\r
3470 \r
3471         SetEnable(hWnd, IDOK, ok);\r
3472 }\r
3473 \r
3474 // パスワード変更ダイアログプロシージャ\r
3475 UINT CmChangePasswordProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
3476 {\r
3477         CM_CHANGE_PASSWORD *p = (CM_CHANGE_PASSWORD *)param;\r
3478         char username[MAX_USERNAME_LEN + 1];\r
3479         char old_pass[MAX_PASSWORD_LEN + 1];\r
3480         char new_pass[MAX_PASSWORD_LEN + 1];\r
3481         UINT ret;\r
3482         // 引数チェック\r
3483         if (hWnd == NULL)\r
3484         {\r
3485                 return 0;\r
3486         }\r
3487 \r
3488         switch (msg)\r
3489         {\r
3490         case WM_INITDIALOG:\r
3491                 SetTextA(hWnd, E_HUBNAME, p->HubName);\r
3492                 SetTextA(hWnd, E_USERNAME, p->Username);\r
3493                 FormatText(hWnd, S_TITLE, p->ClientOption->Hostname);\r
3494 \r
3495                 if (IsEmpty(hWnd, E_USERNAME))\r
3496                 {\r
3497                         FocusEx(hWnd, E_USERNAME);\r
3498                 }\r
3499                 else\r
3500                 {\r
3501                         FocusEx(hWnd, E_OLD_PASSWORD);\r
3502                 }\r
3503 \r
3504                 CmChangePasswordUpdate(hWnd, p);\r
3505                 break;\r
3506 \r
3507         case WM_COMMAND:\r
3508                 switch (LOWORD(wParam))\r
3509                 {\r
3510                 case E_USERNAME:\r
3511                 case E_OLD_PASSWORD:\r
3512                 case E_NEW_PASSWORD1:\r
3513                 case E_NEW_PASSWORD2:\r
3514                         CmChangePasswordUpdate(hWnd, p);\r
3515                         break;\r
3516                 }\r
3517 \r
3518                 switch (wParam)\r
3519                 {\r
3520                 case IDOK:\r
3521                         GetTxtA(hWnd, E_USERNAME, username, sizeof(username));\r
3522                         GetTxtA(hWnd, E_OLD_PASSWORD, old_pass, sizeof(old_pass));\r
3523                         GetTxtA(hWnd, E_NEW_PASSWORD1, new_pass, sizeof(new_pass));\r
3524 \r
3525                         Disable(hWnd, E_USERNAME);\r
3526                         Disable(hWnd, E_OLD_PASSWORD);\r
3527                         Disable(hWnd, E_NEW_PASSWORD1);\r
3528                         Disable(hWnd, E_NEW_PASSWORD2);\r
3529                         Disable(hWnd, IDOK);\r
3530                         Disable(hWnd, IDCANCEL);\r
3531 \r
3532                         ret = ChangePassword(cm->Cedar, p->ClientOption, p->HubName, username, old_pass, new_pass);\r
3533 \r
3534                         if (ret == ERR_NO_ERROR)\r
3535                         {\r
3536                                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PASSWORD_CHANGED"));\r
3537                                 EndDialog(hWnd, true);\r
3538                         }\r
3539                         else\r
3540                         {\r
3541                                 MsgBox(hWnd, MB_ICONSTOP, _E(ret));\r
3542                                 Enable(hWnd, E_USERNAME);\r
3543                                 Enable(hWnd, E_OLD_PASSWORD);\r
3544                                 Enable(hWnd, E_NEW_PASSWORD1);\r
3545                                 Enable(hWnd, E_NEW_PASSWORD2);\r
3546                                 Enable(hWnd, IDOK);\r
3547                                 Enable(hWnd, IDCANCEL);\r
3548 \r
3549                                 SetTextA(hWnd, E_OLD_PASSWORD, "");\r
3550                                 SetTextA(hWnd, E_NEW_PASSWORD1, "");\r
3551                                 SetTextA(hWnd, E_NEW_PASSWORD2, "");\r
3552 \r
3553                                 Focus(hWnd, E_OLD_PASSWORD);\r
3554                         }\r
3555 \r
3556                         break;\r
3557 \r
3558                 case IDCANCEL:\r
3559                         Close(hWnd);\r
3560                         break;\r
3561 \r
3562                 }\r
3563 \r
3564                 break;\r
3565 \r
3566         case WM_CLOSE:\r
3567                 EndDialog(hWnd, false);\r
3568                 break;\r
3569         }\r
3570 \r
3571         return 0;\r
3572 }\r
3573 \r
3574 // パスワード変更ダイアログ表示\r
3575 void CmChangePassword(HWND hWnd, CLIENT_OPTION *o, char *hubname, char *username)\r
3576 {\r
3577         CM_CHANGE_PASSWORD p;\r
3578         // 引数チェック\r
3579         if (hWnd == NULL || o == NULL || hubname == NULL || username == NULL)\r
3580         {\r
3581                 return;\r
3582         }\r
3583 \r
3584         Zero(&p, sizeof(p));\r
3585         StrCpy(p.Username, sizeof(p.Username), username);\r
3586         StrCpy(p.HubName, sizeof(p.HubName), hubname);\r
3587         p.ClientOption = o;\r
3588 \r
3589         CmVoice("password");\r
3590 \r
3591         Dialog(hWnd, D_CM_CHANGE_PASSWORD, CmChangePasswordProc, &p);\r
3592 }\r
3593 \r
3594 // デスクトップ相違警告メッセージダイアログ初期化\r
3595 void CmDesktopDlgInit(HWND hWnd, wchar_t *account_name)\r
3596 {\r
3597         wchar_t tmp[2048];\r
3598         bool remote = false;\r
3599         bool user_switching = false;\r
3600         bool console_active = false;\r
3601         wchar_t *console_user = NULL;\r
3602         // 引数チェック\r
3603         if (hWnd == NULL)\r
3604         {\r
3605                 return;\r
3606         }\r
3607 \r
3608         FormatText(hWnd, 0, account_name);\r
3609         FormatText(hWnd, S_TITLE, account_name);\r
3610         DlgFont(hWnd, S_TITLE, 11, true);\r
3611         DlgFont(hWnd, S_INFO, 11, true);\r
3612         if (cm->server_name == NULL)\r
3613         {\r
3614                 UniStrCpy(tmp, sizeof(tmp), _UU("CM_DESKTOP_LOCAL_PC"));\r
3615         }\r
3616         else\r
3617         {\r
3618                 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_REMOTE_PC"), cm->server_name);\r
3619         }\r
3620         FormatText(hWnd, S_WARNING, tmp);\r
3621 \r
3622         if (cm->server_name != NULL)\r
3623         {\r
3624                 remote = true;\r
3625         }\r
3626         else\r
3627         {\r
3628                 if (MsIsTerminalServiceInstalled())\r
3629                 {\r
3630                         user_switching = false;\r
3631                 }\r
3632                 else\r
3633                 {\r
3634                         user_switching = true;\r
3635                 }\r
3636 \r
3637                 console_user = MsGetSessionUserName(0);\r
3638 \r
3639                 if (console_user == NULL)\r
3640                 {\r
3641                         console_active = false;\r
3642                 }\r
3643                 else\r
3644                 {\r
3645                         console_active = true;\r
3646                 }\r
3647         }\r
3648 \r
3649         // MSG1\r
3650         if (remote == false)\r
3651         {\r
3652                 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_1"),\r
3653                         user_switching ? _UU("CM_DESKTOP_MSG_LOCAL_SW") : _UU("CM_DESKTOP_MSG_LOCAL_TS"));\r
3654         }\r
3655         else\r
3656         {\r
3657                 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_REMOTE_1"),\r
3658                         cm->server_name);\r
3659         }\r
3660         SetText(hWnd, S_MSG_1, tmp);\r
3661 \r
3662         // MSG2\r
3663         if (remote == false)\r
3664         {\r
3665                 if (console_active)\r
3666                 {\r
3667                         UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_21"),\r
3668                                 console_user, MsGetCurrentTerminalSessionId());\r
3669                 }\r
3670                 else\r
3671                 {\r
3672                         UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_22"),\r
3673                                 MsGetCurrentTerminalSessionId());\r
3674                 }\r
3675         }\r
3676         else\r
3677         {\r
3678                 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_REMOTE_2"), cm->server_name);\r
3679         }\r
3680         SetText(hWnd, S_MSG_2, tmp);\r
3681 \r
3682         // MSG3\r
3683         if (remote == false)\r
3684         {\r
3685                 if (console_active)\r
3686                 {\r
3687                         UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_31"),\r
3688                                 console_user, account_name);\r
3689                 }\r
3690                 else\r
3691                 {\r
3692                         UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_LOCAL_32"),\r
3693                                 account_name);\r
3694                 }\r
3695         }\r
3696         else\r
3697         {\r
3698                 UniFormat(tmp, sizeof(tmp), _UU("CM_DESKTOP_MSG_REMOTE_3"), cm->server_name,\r
3699                         account_name);\r
3700         }\r
3701         SetText(hWnd, S_MSG_3, tmp);\r
3702 \r
3703         if (console_user != NULL)\r
3704         {\r
3705                 Free(console_user);\r
3706         }\r
3707 }\r
3708 \r
3709 // デスクトップ相違警告メッセージダイアログ\r
3710 UINT CmDesktopDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
3711 {\r
3712         wchar_t *account_name = (wchar_t *)param;\r
3713         // 引数チェック\r
3714         if (hWnd == NULL)\r
3715         {\r
3716                 return 0;\r
3717         }\r
3718 \r
3719         switch (msg)\r
3720         {\r
3721         case WM_INITDIALOG:\r
3722                 CmDesktopDlgInit(hWnd, account_name);\r
3723                 break;\r
3724         case WM_COMMAND:\r
3725                 switch (wParam)\r
3726                 {\r
3727                 case IDOK:\r
3728                         EndDialog(hWnd, true);\r
3729                         break;\r
3730                 case IDCANCEL:\r
3731                         Close(hWnd);\r
3732                         break;\r
3733                 }\r
3734                 break;\r
3735         case WM_CLOSE:\r
3736                 EndDialog(hWnd, false);\r
3737                 break;\r
3738         }\r
3739 \r
3740         return 0;\r
3741 }\r
3742 \r
3743 // 必要であればデスクトップが異なる旨の警告メッセージを表示する\r
3744 bool CmWarningDesktop(HWND hWnd, wchar_t *account_name)\r
3745 {\r
3746         // 引数チェック\r
3747         if (hWnd == NULL || account_name == NULL)\r
3748         {\r
3749                 return false;\r
3750         }\r
3751 \r
3752         if (cm->Client->Unix)\r
3753         {\r
3754                 //クライアントが UNIX の場合警告の必要は無い\r
3755                 return true;\r
3756         }\r
3757 \r
3758         if (/*MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled() ||*/ (cm->server_name != NULL))\r
3759         {\r
3760                 if (cm->server_name == NULL)\r
3761                 {\r
3762                         //if (MsGetCurrentTerminalSessionId() == 0)\r
3763                         {\r
3764                                 // 警告の必要は無い\r
3765                                 return true;\r
3766                         }\r
3767                 }\r
3768                 // 警告の必要がある\r
3769                 return Dialog(hWnd, D_CM_DESKTOP, CmDesktopDlgProc, account_name);\r
3770         }\r
3771         else\r
3772         {\r
3773                 // 警告の必要は無い\r
3774                 return true;\r
3775         }\r
3776 }\r
3777 \r
3778 // パスワード設定ダイアログ更新\r
3779 void CmPasswordRefresh(HWND hWnd)\r
3780 {\r
3781         bool ok = true;\r
3782         // 引数チェック\r
3783         if (hWnd == NULL)\r
3784         {\r
3785                 return;\r
3786         }\r
3787 \r
3788         SetEnable(hWnd, E_PASSWORD, IsChecked(hWnd, R_USE_PASSWORD));\r
3789         SetEnable(hWnd, E_PASSWORD2, IsChecked(hWnd, R_USE_PASSWORD));\r
3790         SetEnable(hWnd, IDC_STATIC1, IsChecked(hWnd, R_USE_PASSWORD));\r
3791         SetEnable(hWnd, IDC_STATIC2, IsChecked(hWnd, R_USE_PASSWORD));\r
3792         SetEnable(hWnd, R_REMOTE_ONLY, IsChecked(hWnd, R_USE_PASSWORD));\r
3793 \r
3794         if (IsChecked(hWnd, R_USE_PASSWORD))\r
3795         {\r
3796                 char tmp1[MAX_SIZE];\r
3797                 char tmp2[MAX_SIZE];\r
3798                 if (IsEmpty(hWnd, E_PASSWORD))\r
3799                 {\r
3800                         ok = false;\r
3801                 }\r
3802                 GetTxtA(hWnd, E_PASSWORD, tmp1, sizeof(tmp1));\r
3803                 GetTxtA(hWnd, E_PASSWORD2, tmp2, sizeof(tmp2));\r
3804                 if (StrCmp(tmp1, tmp2) != 0)\r
3805                 {\r
3806                         ok = false;\r
3807                 }\r
3808                 if (StrCmp(tmp1, HIDDEN_PASSWORD) == 0)\r
3809                 {\r
3810                         ok = false;\r
3811                 }\r
3812         }\r
3813 \r
3814         SetEnable(hWnd, IDOK, ok);\r
3815 }\r
3816 \r
3817 // パスワード設定プロシージャ\r
3818 UINT CmPasswordProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
3819 {\r
3820         RPC_CLIENT_PASSWORD_SETTING c;\r
3821         RPC_CLIENT_PASSWORD p;\r
3822         char tmp[MAX_SIZE];\r
3823         // 引数チェック\r
3824         if (hWnd == NULL)\r
3825         {\r
3826                 return 0;\r
3827         }\r
3828 \r
3829         switch (msg)\r
3830         {\r
3831         case WM_INITDIALOG:\r
3832                 // パスワード設定の取得\r
3833                 if (CALL(hWnd, CcGetPasswordSetting(cm->Client, &c)))\r
3834                 {\r
3835                         Check(hWnd, R_USE_PASSWORD, c.IsPasswordPresented);\r
3836                         if (c.IsPasswordPresented)\r
3837                         {\r
3838                                 SetTextA(hWnd, E_PASSWORD, HIDDEN_PASSWORD);\r
3839                                 SetTextA(hWnd, E_PASSWORD2, HIDDEN_PASSWORD);\r
3840                                 FocusEx(hWnd, E_PASSWORD);\r
3841                                 Check(hWnd, R_REMOTE_ONLY, c.PasswordRemoteOnly);\r
3842                         }\r
3843                         else\r
3844                         {\r
3845                                 Focus(hWnd, R_USE_PASSWORD);\r
3846                         }\r
3847                 }\r
3848                 CmPasswordRefresh(hWnd);\r
3849                 break;\r
3850         case WM_COMMAND:\r
3851                 switch (wParam)\r
3852                 {\r
3853                 case R_USE_PASSWORD:\r
3854                         if (IsChecked(hWnd, R_USE_PASSWORD))\r
3855                         {\r
3856                                 FocusEx(hWnd, E_PASSWORD);\r
3857                         }\r
3858                         break;\r
3859                 case IDOK:\r
3860                         GetTxtA(hWnd, E_PASSWORD, tmp, sizeof(tmp));\r
3861                         Zero(&p, sizeof(p));\r
3862                         if (IsChecked(hWnd, R_USE_PASSWORD))\r
3863                         {\r
3864                                 StrCpy(p.Password, sizeof(p.Password), tmp);\r
3865                                 p.PasswordRemoteOnly = IsChecked(hWnd, R_REMOTE_ONLY);\r
3866                         }\r
3867 \r
3868                         if (CALL(hWnd, CcSetPassword(cm->Client, &p)))\r
3869                         {\r
3870                                 if (StrLen(p.Password) > 0)\r
3871                                 {\r
3872                                         MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PASSWORD_SET"));\r
3873                                 }\r
3874                                 else\r
3875                                 {\r
3876                                         MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PASSWORD_REMOVE"));\r
3877                                 }\r
3878                                 EndDialog(hWnd, true);\r
3879                         }\r
3880                         break;\r
3881                 case IDCANCEL:\r
3882                         Close(hWnd);\r
3883                         break;\r
3884                 }\r
3885                 switch (LOWORD(wParam))\r
3886                 {\r
3887                 case R_USE_PASSWORD:\r
3888                 case R_REMOTE_ONLY:\r
3889                 case E_PASSWORD:\r
3890                 case E_PASSWORD2:\r
3891                         CmPasswordRefresh(hWnd);\r
3892                         break;\r
3893                 }\r
3894                 switch (wParam)\r
3895                 {\r
3896                 case R_REMOTE_ONLY:\r
3897                 case R_USE_PASSWORD:\r
3898                         if (IsChecked(hWnd, R_USE_PASSWORD))\r
3899                         {\r
3900                                 FocusEx(hWnd, E_PASSWORD);\r
3901                         }\r
3902                         break;\r
3903                 }\r
3904                 break;\r
3905         case WM_CLOSE:\r
3906                 EndDialog(hWnd, false);\r
3907                 break;\r
3908         }\r
3909 \r
3910         return 0;\r
3911 }\r
3912 \r
3913 // パスワード設定\r
3914 void CmPassword(HWND hWnd)\r
3915 {\r
3916         // 引数チェック\r
3917         if (hWnd == NULL)\r
3918         {\r
3919                 return;\r
3920         }\r
3921 \r
3922         Dialog(hWnd, D_CM_PASSWORD, CmPasswordProc, NULL);\r
3923 }\r
3924 \r
3925 // CA ダイアログ更新\r
3926 void CmTrustDlgUpdate(HWND hWnd)\r
3927 {\r
3928         // 引数チェック\r
3929         if (hWnd == NULL)\r
3930         {\r
3931                 return;\r
3932         }\r
3933 \r
3934         SetEnable(hWnd, B_EXPORT, LvIsSelected(hWnd, L_CERT));\r
3935         SetEnable(hWnd, B_DELETE, LvIsSelected(hWnd, L_CERT) && cm->CmSetting.LockMode == false);\r
3936         SetEnable(hWnd, IDOK, LvIsSelected(hWnd, L_CERT));\r
3937         SetEnable(hWnd, B_IMPORT, cm->CmSetting.LockMode == false);\r
3938 }\r
3939 \r
3940 // 証明書リストの更新\r
3941 void CmTrustDlgRefresh(HWND hWnd)\r
3942 {\r
3943         RPC_CLIENT_ENUM_CA c;\r
3944         // 引数チェック\r
3945         if (hWnd == NULL)\r
3946         {\r
3947                 return;\r
3948         }\r
3949 \r
3950         if (CALL(hWnd, CcEnumCa(cm->Client, &c)))\r
3951         {\r
3952                 UINT i;\r
3953                 LVB *b = LvInsertStart();\r
3954                 for (i = 0;i < c.NumItem;i++)\r
3955                 {\r
3956                         RPC_CLIENT_ENUM_CA_ITEM *cert = c.Items[i];\r
3957                         wchar_t tmp[MAX_SIZE];\r
3958 \r
3959                         GetDateStrEx64(tmp, sizeof(tmp), SystemToLocal64(cert->Expires), NULL);\r
3960                         LvInsertAdd(b, ICO_CERT, (void *)cert->Key, 3,\r
3961                                 cert->SubjectName, cert->IssuerName, tmp);\r
3962                 }\r
3963                 LvInsertEnd(b, hWnd, L_CERT);\r
3964                 CiFreeClientEnumCa(&c);\r
3965         }\r
3966 \r
3967         CmTrustDlgUpdate(hWnd);\r
3968 }\r
3969 \r
3970 // インポート\r
3971 void CmTrustImport(HWND hWnd)\r
3972 {\r
3973         X *x;\r
3974         RPC_CERT c;\r
3975         if (CmLoadXFromFileOrSecureCard(hWnd, &x) == false)\r
3976         {\r
3977                 return;\r
3978         }\r
3979 \r
3980         Zero(&c, sizeof(c));\r
3981         c.x = x;\r
3982 \r
3983         CALL(hWnd, CcAddCa(cm->Client, &c));\r
3984         CmVoice("new_cert");\r
3985 \r
3986         FreeX(c.x);\r
3987         CmTrustDlgRefresh(hWnd);\r
3988 }\r
3989 \r
3990 // エクスポート\r
3991 void CmTrustExport(HWND hWnd)\r
3992 {\r
3993         UINT key;\r
3994         // 引数チェック\r
3995         if (hWnd == NULL)\r
3996         {\r
3997                 return;\r
3998         }\r
3999 \r
4000         key = (UINT)LvGetParam(hWnd, L_CERT, LvGetSelected(hWnd, L_CERT));\r
4001         if (key != INFINITE)\r
4002         {\r
4003                 RPC_GET_CA a;\r
4004                 Zero(&a, sizeof(a));\r
4005                 a.Key = key;\r
4006 \r
4007                 if (CALL(hWnd, CcGetCa(cm->Client, &a)))\r
4008                 {\r
4009                         wchar_t *name;\r
4010                         X *x = CloneX(a.x);\r
4011                         CiFreeGetCa(&a);\r
4012 \r
4013                         // 保存\r
4014                         name = SaveDlg(hWnd, _UU("DLG_CERT_FILES"), _UU("DLG_SAVE_CERT"), NULL, L".cer");\r
4015                         if (name != NULL)\r
4016                         {\r
4017                                 wchar_t str[MAX_SIZE];\r
4018                                 UniStrCpy(str, sizeof(str), name);\r
4019                                 if (XToFileW(x, str, true))\r
4020                                 {\r
4021                                         MsgBox(hWnd, MB_ICONINFORMATION, _UU("DLG_CERT_SAVE_OK"));\r
4022                                 }\r
4023                                 else\r
4024                                 {\r
4025                                         MsgBox(hWnd, MB_ICONSTOP, _UU("DLG_CERT_SAVE_ERROR"));\r
4026                                 }\r
4027                                 Free(name);\r
4028                         }\r
4029                         FreeX(x);\r
4030                 }\r
4031         }\r
4032 }\r
4033 \r
4034 // 表示\r
4035 void CmTrustView(HWND hWnd)\r
4036 {\r
4037         UINT key;\r
4038         // 引数チェック\r
4039         if (hWnd == NULL)\r
4040         {\r
4041                 return;\r
4042         }\r
4043 \r
4044         key = (UINT)LvGetParam(hWnd, L_CERT, LvGetSelected(hWnd, L_CERT));\r
4045         if (key != INFINITE)\r
4046         {\r
4047                 RPC_GET_CA a;\r
4048                 Zero(&a, sizeof(a));\r
4049                 a.Key = key;\r
4050 \r
4051                 if (CALL(hWnd, CcGetCa(cm->Client, &a)))\r
4052                 {\r
4053                         X *x = CloneX(a.x);\r
4054                         X *x_issuer;\r
4055                         CiFreeGetCa(&a);\r
4056 \r
4057                         x_issuer = CmGetIssuer(x);\r
4058                         CertDlg(hWnd, x, x_issuer, true);\r
4059                         FreeX(x);\r
4060                         FreeX(x_issuer);\r
4061                 }\r
4062         }\r
4063 }\r
4064 \r
4065 // CA ダイアログプロシージャ\r
4066 UINT CmTrustDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
4067 {\r
4068         NMHDR *n;\r
4069         UINT index;\r
4070         // 引数チェック\r
4071         if (hWnd == NULL)\r
4072         {\r
4073                 return 0;\r
4074         }\r
4075 \r
4076         switch (msg)\r
4077         {\r
4078         case WM_INITDIALOG:\r
4079                 LvInit(hWnd, L_CERT);\r
4080                 LvInsertColumn(hWnd, L_CERT, 0, _UU("CM_CERT_COLUMN_1"), 190);\r
4081                 LvInsertColumn(hWnd, L_CERT, 1, _UU("CM_CERT_COLUMN_2"), 190);\r
4082                 LvInsertColumn(hWnd, L_CERT, 2, _UU("CM_CERT_COLUMN_3"), 160);\r
4083                 CmTrustDlgRefresh(hWnd);\r
4084                 break;\r
4085         case WM_COMMAND:\r
4086                 switch (wParam)\r
4087                 {\r
4088                 case B_IMPORT:\r
4089                         CmTrustImport(hWnd);\r
4090                         break;\r
4091                 case B_EXPORT:\r
4092                         CmTrustExport(hWnd);\r
4093                         break;\r
4094                 case B_DELETE:\r
4095                         index = LvGetSelected(hWnd, L_CERT);\r
4096                         if (index != INFINITE)\r
4097                         {\r
4098                                 UINT key = (UINT)LvGetParam(hWnd, L_CERT, index);\r
4099                                 if (key != INFINITE)\r
4100                                 {\r
4101                                         if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_CERT_DELETE_MSG")) == IDYES)\r
4102                                         {\r
4103                                                 RPC_CLIENT_DELETE_CA c;\r
4104                                                 Zero(&c, sizeof(c));\r
4105                                                 c.Key = key;\r
4106                                                 if (CALL(hWnd, CcDeleteCa(cm->Client, &c)))\r
4107                                                 {\r
4108                                                         CmTrustDlgRefresh(hWnd);\r
4109                                                 }\r
4110                                         }\r
4111                                 }\r
4112                         }\r
4113                         break;\r
4114                 case IDOK:\r
4115                         if (IsEnable(hWnd, IDOK))\r
4116                         {\r
4117                                 CmTrustView(hWnd);\r
4118                         }\r
4119                         break;\r
4120                 case IDCANCEL:\r
4121                         Close(hWnd);\r
4122                         break;\r
4123                 }\r
4124                 break;\r
4125         case WM_CLOSE:\r
4126                 EndDialog(hWnd, 0);\r
4127                 break;\r
4128         case WM_NOTIFY:\r
4129                 n = (NMHDR *)lParam;\r
4130                 switch (n->idFrom)\r
4131                 {\r
4132                 case L_CERT:\r
4133                         switch (n->code)\r
4134                         {\r
4135                         case LVN_ITEMCHANGED:\r
4136                                 CmTrustDlgUpdate(hWnd);\r
4137                                 break;\r
4138                         case NM_DBLCLK:\r
4139                                 Command(hWnd, IDOK);\r
4140                                 break;\r
4141                         }\r
4142                         break;\r
4143                 }\r
4144                 break;\r
4145         }\r
4146 \r
4147         LvSortHander(hWnd, msg, wParam, lParam, L_CERT);\r
4148 \r
4149         return 0;\r
4150 }\r
4151 \r
4152 // CA ダイアログの表示\r
4153 void CmTrustDlg(HWND hWnd)\r
4154 {\r
4155         Dialog(hWnd, D_CM_TRUST, CmTrustDlgProc, NULL);\r
4156 }\r
4157 \r
4158 // メインウインドウプロシージャ\r
4159 UINT CmMainWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
4160 {\r
4161         NMHDR *n;\r
4162         static UINT taskbar_msg = 0;\r
4163         COPYDATASTRUCT *cpy;\r
4164         // 引数チェック\r
4165         if (hWnd == NULL)\r
4166         {\r
4167                 return 0;\r
4168         }\r
4169 \r
4170         if (taskbar_msg != 0 && msg == taskbar_msg)\r
4171         {\r
4172                 // タスクバーが再生成された\r
4173                 if (cm->TrayInited)\r
4174                 {\r
4175                         MsRestoreIconOnTray();\r
4176                 }\r
4177         }\r
4178 \r
4179         // CmSetForegroundProcessToCnService();\r
4180 \r
4181         switch (msg)\r
4182         {\r
4183         case WM_CM_SETTING_CHANGED_MESSAGE:\r
4184                 // CM_SETTING が変更された\r
4185                 CmApplyCmSetting();\r
4186                 break;\r
4187         case WM_INITDIALOG:\r
4188                 CmMainWindowOnInit(hWnd);\r
4189                 taskbar_msg = RegisterWindowMessage("TaskbarCreated");\r
4190                 CmEndStartupMutex();\r
4191                 break;\r
4192         case WM_SHOWWINDOW:\r
4193 LABEL_SPLASH:\r
4194                 if (cm->SplashHasBeenShown == false)\r
4195                 {\r
4196                         if ((msg == WM_SHOWWINDOW && wParam) || (msg != WM_SHOWWINDOW && IsShow(hWnd, 0)))\r
4197                         {\r
4198                                 if (IsIconic(hWnd) == false)\r
4199                                 {\r
4200                                         SetTimer(hWnd, 5, 100, NULL);\r
4201                                 }\r
4202                         }\r
4203                 }\r
4204                 break;\r
4205         case WM_CM_SHOW:\r
4206                 // 別のプロセスから表示要求を受けた\r
4207                 if (cm->CmSetting.EasyMode == false)\r
4208                 {\r
4209                         ShowWindow(hWnd, SW_SHOWNORMAL);\r
4210                 }\r
4211                 else\r
4212                 {\r
4213                         if (cm->hEasyWnd == NULL)\r
4214                         {\r
4215                                 CmShowEasy();\r
4216                         }\r
4217                         else\r
4218                         {\r
4219                                 SetForegroundWindow(cm->hEasyWnd);\r
4220                                 SetActiveWindow(cm->hEasyWnd);\r
4221                         }\r
4222                 }\r
4223                 break;\r
4224         case WM_COMMAND:\r
4225                 CmMainWindowOnCommand(hWnd, wParam, lParam);\r
4226                 break;\r
4227         case WM_SIZE:\r
4228                 CmMainWindowOnSize(hWnd);\r
4229                 goto LABEL_SPLASH;\r
4230         case WM_CLOSE:\r
4231                 if (cm->CmSetting.EasyMode == false)\r
4232                 {\r
4233                         CmShowOrHideWindow(hWnd);\r
4234                 }\r
4235                 else\r
4236                 {\r
4237                         if (cm->hEasyWnd == NULL)\r
4238                         {\r
4239                                 CmShowEasy();\r
4240                         }\r
4241                         else\r
4242                         {\r
4243                                 SetForegroundWindow(cm->hEasyWnd);\r
4244                                 SetActiveWindow(cm->hEasyWnd);\r
4245                         }\r
4246                 }\r
4247                 return 1;\r
4248         case WM_INITMENUPOPUP:\r
4249                 if (HIWORD(lParam) == false)\r
4250                 {\r
4251                         CmMainWindowOnPopupMenu(hWnd, (HMENU)wParam, LOWORD(lParam));\r
4252                 }\r
4253                 break;\r
4254         case WM_NOTIFY:\r
4255                 n = (NMHDR *)lParam;\r
4256                 if (n->idFrom == L_ACCOUNT && (n->code == LVN_BEGINLABELEDITW || n->code == LVN_BEGINLABELEDITA))\r
4257                 {\r
4258                         wchar_t *tmp = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);\r
4259                         if (tmp != NULL)\r
4260                         {\r
4261                                 if (UniStrCmpi(tmp, _UU("CM_NEW_ICON")) == 0 ||\r
4262                                         UniStrCmpi(tmp, _UU("CM_ASP")) == 0)\r
4263                                 {\r
4264                                         SendMsg(hWnd, L_ACCOUNT, LVM_CANCELEDITLABEL, 0, 0);\r
4265                                         Free(tmp);\r
4266                                         return true;\r
4267                                 }\r
4268                                 Free(tmp);\r
4269                         }\r
4270                 }\r
4271                 CmMainWindowOnNotify(hWnd, (NMHDR *)lParam);\r
4272                 break;\r
4273         case WM_CM_NOTIFY:\r
4274                 CmRefreshVLanList(hWnd);\r
4275                 CmRefreshAccountList(hWnd);\r
4276                 CmRefreshStatusBar(hWnd);\r
4277                 break;\r
4278         case WM_TIMER:\r
4279                 switch (wParam)\r
4280                 {\r
4281                 case 1:\r
4282                         CmSetForegroundProcessToCnService();\r
4283                         break;\r
4284                 case 2:\r
4285                         CmPollingTray(hWnd);\r
4286                         break;\r
4287                 case 3:\r
4288                         KillTimer(hWnd, 3);\r
4289                         Hide(hWnd, 0);\r
4290                         break;\r
4291                 case 4:\r
4292                         KillTimer(hWnd, 4);\r
4293                         CmMainWindowOnShowEasy(hWnd);\r
4294                         break;\r
4295                 case 5:\r
4296                         KillTimer(hWnd, 5);\r
4297                         if (cm->SplashHasBeenShown == false)\r
4298                         {\r
4299                                 cm->SplashHasBeenShown = true;\r
4300 \r
4301                                 ShowSplashEx(hWnd, "UT-VPN Client", 1300, CM_SPLASH_BORDER_COLOR);\r
4302                         }\r
4303                         break;\r
4304                 }\r
4305                 break;\r
4306         case WM_CM_TRAY_MESSAGE:\r
4307                 // タスクトレイのアイコンからのメッセージ\r
4308                 CmMainWindowOnTrayClicked(hWnd, wParam, lParam);\r
4309                 break;\r
4310         case WM_COPYDATA:\r
4311                 cpy = (COPYDATASTRUCT *)lParam;\r
4312                 if (cpy != NULL)\r
4313                 {\r
4314                         if (cpy->dwData == CM_IMPORT_FILENAME_MSG || cpy->dwData == CM_IMPORT_FILENAME_MSG_OVERWRITE)\r
4315                         {\r
4316                                 char *filename = (char *)cpy->lpData;\r
4317 \r
4318                                 if (cm->CmSetting.LockMode == false || cpy->dwData == CM_IMPORT_FILENAME_MSG_OVERWRITE)\r
4319                                 {\r
4320                                         wchar_t fullpath[MAX_PATH];\r
4321 \r
4322                                         if (StrLen(filename) >= 2 && IsFileExists(filename))\r
4323                                         {\r
4324                                                 StrToUni(fullpath, sizeof(fullpath), filename);\r
4325                                         }\r
4326                                         else\r
4327                                         {\r
4328                                                 UniStrCpy(fullpath, sizeof(fullpath), (wchar_t *)filename);\r
4329                                         }\r
4330 \r
4331                                         CmImportAccountMainEx(cm->hEasyWnd ? cm->hEasyWnd : hWnd, fullpath, cpy->dwData == CM_IMPORT_FILENAME_MSG_OVERWRITE);\r
4332                                 }\r
4333                                 else\r
4334                                 {\r
4335                                         MsgBox(cm->hEasyWnd ? cm->hEasyWnd : hWnd, MB_ICONEXCLAMATION | MB_SETFOREGROUND | MB_TOPMOST, _UU("CM_VPN_FILE_IMPORT_NG"));\r
4336                                 }\r
4337                         }\r
4338                 }\r
4339                 break;\r
4340         case WM_QUERYENDSESSION:\r
4341                 // Windows が終了しようとしている\r
4342                 cm->WindowsShutdowning = true;\r
4343                 CmSaveMainWindowPos(hWnd);\r
4344                 SleepThread(256);\r
4345                 break;\r
4346         case WM_ENDSESSION:\r
4347                 // Windows が終了した\r
4348                 _exit(0);\r
4349                 break;\r
4350         }\r
4351 \r
4352         LvSortHander(hWnd, msg, wParam, lParam, L_ACCOUNT);\r
4353         LvSortHander(hWnd, msg, wParam, lParam, L_VLAN);\r
4354 \r
4355         return 0;\r
4356 }\r
4357 \r
4358 // 通知サービスをフォアグラウンドプロセスに指定する\r
4359 void CmSetForegroundProcessToCnService()\r
4360 {\r
4361         if (cm->MenuPopuping)\r
4362         {\r
4363                 return;\r
4364         }\r
4365         if (cm->server_name == NULL)\r
4366         {\r
4367                 if (CnCheckAlreadyExists(false))\r
4368                 {\r
4369                         AllowFGWindow(MsRegReadInt(REG_CURRENT_USER,\r
4370                                 CM_REG_KEY, "NotifyServerProcessId"));\r
4371                 }\r
4372         }\r
4373 }\r
4374 \r
4375 // [最近の接続先] のサブメニューを表示する\r
4376 HMENU CmCreateRecentSubMenu(HWND hWnd, UINT start_id)\r
4377 {\r
4378         HMENU h = NULL;\r
4379         UINT i;\r
4380         RPC_CLIENT_ENUM_ACCOUNT a;\r
4381         LIST *o;\r
4382         bool easy;\r
4383 \r
4384         easy = cm->CmSetting.EasyMode;\r
4385 \r
4386         Zero(&a, sizeof(a));\r
4387 \r
4388         if (CcEnumAccount(cm->Client, &a) == ERR_NO_ERROR)\r
4389         {\r
4390                 o = NewListFast(CiCompareClientAccountEnumItemByLastConnectDateTime);\r
4391 \r
4392                 for (i = 0;i < a.NumItem;i++)\r
4393                 {\r
4394                         RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = a.Items[i];\r
4395 \r
4396                         item->tmp1 = i;\r
4397 \r
4398                         if (item->LastConnectDateTime != 0)\r
4399                         {\r
4400                                 Add(o, item);\r
4401                         }\r
4402                 }\r
4403 \r
4404                 Sort(o);\r
4405 \r
4406                 for (i = 0;i < MIN(LIST_NUM(o), CM_NUM_RECENT);i++)\r
4407                 {\r
4408                         RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = (RPC_CLIENT_ENUM_ACCOUNT_ITEM *)LIST_DATA(o, i);\r
4409                         wchar_t tmp[MAX_PATH];\r
4410                         wchar_t *account_name;\r
4411                         char *server_name;\r
4412                         char *hub_name;\r
4413                         UINT pos;\r
4414 \r
4415                         if (h == NULL)\r
4416                         {\r
4417                                 h = CreatePopupMenu();\r
4418                         }\r
4419 \r
4420                         account_name = item->AccountName;\r
4421                         server_name = item->ServerName;\r
4422                         hub_name = item->HubName;\r
4423 \r
4424                         UniStrCpy(tmp, sizeof(tmp), account_name);\r
4425 \r
4426                         pos = LvSearchStr(hWnd, L_ACCOUNT, 0, account_name);\r
4427                         if (pos != INFINITE)\r
4428                         {\r
4429                                 MsAppendMenu(h, MF_STRING, start_id + pos, tmp);\r
4430                         }\r
4431                 }\r
4432 \r
4433                 ReleaseList(o);\r
4434 \r
4435                 CiFreeClientEnumAccount(&a);\r
4436         }\r
4437 \r
4438         return h;\r
4439 }\r
4440 \r
4441 // タスクトレイの右クリックメニューのサブメニューを表示する\r
4442 HMENU CmCreateTraySubMenu(HWND hWnd, bool flag, UINT start_id)\r
4443 {\r
4444         HMENU h = NULL;\r
4445         UINT i, num;\r
4446         bool easy;\r
4447         // 引数チェック\r
4448         if (hWnd == NULL)\r
4449         {\r
4450                 return NULL;\r
4451         }\r
4452 \r
4453         easy = cm->CmSetting.EasyMode;\r
4454 \r
4455         num = LvNum(hWnd, L_ACCOUNT);\r
4456 \r
4457         for (i = 0;i < num;i++)\r
4458         {\r
4459                 wchar_t *status_str = LvGetStr(hWnd, L_ACCOUNT, i, 1);\r
4460 \r
4461                 if (status_str != NULL)\r
4462                 {\r
4463                         bool b = false;\r
4464                         bool is_account = false;\r
4465 \r
4466                         if (UniStrCmpi(status_str, _UU("CM_ACCOUNT_OFFLINE")) == 0)\r
4467                         {\r
4468                                 if (flag == false)\r
4469                                 {\r
4470                                         b = true;\r
4471                                 }\r
4472 \r
4473                                 is_account = true;\r
4474                         }\r
4475 \r
4476                         if (UniStrCmpi(status_str, _UU("CM_ACCOUNT_ONLINE")) == 0 ||\r
4477                                 UniStrCmpi(status_str, _UU("CM_ACCOUNT_CONNECTING")) == 0)\r
4478                         {\r
4479                                 if (flag == true)\r
4480                                 {\r
4481                                         b = true;\r
4482                                 }\r
4483 \r
4484                                 is_account = true;\r
4485                         }\r
4486 \r
4487                         if (b)\r
4488                         {\r
4489                                 wchar_t tmp[MAX_PATH];\r
4490                                 wchar_t *account_name, *server_name;\r
4491                                 wchar_t *hub_name;\r
4492                                 if (h == NULL)\r
4493                                 {\r
4494                                         h = CreatePopupMenu();\r
4495                                 }\r
4496 \r
4497                                 account_name = LvGetStr(hWnd, L_ACCOUNT, i, 0);\r
4498                                 server_name = LvGetStr(hWnd, L_ACCOUNT, i, 2);\r
4499                                 hub_name = LvGetStr(hWnd, L_ACCOUNT, i, 3);\r
4500 \r
4501                                 if (easy == false)\r
4502                                 {\r
4503                                         UniFormat(tmp, sizeof(tmp), L"%s\t- %s [%s]", account_name, server_name, hub_name);\r
4504                                 }\r
4505                                 else\r
4506                                 {\r
4507                                         UniStrCpy(tmp, sizeof(tmp), account_name);\r
4508                                 }\r
4509 \r
4510                                 MsAppendMenu(h, MF_STRING, start_id + i, tmp);\r
4511 \r
4512                                 Free(account_name);\r
4513                                 Free(server_name);\r
4514                                 Free(hub_name);\r
4515                         }\r
4516 \r
4517                         Free(status_str);\r
4518                 }\r
4519         }\r
4520 \r
4521         return h;\r
4522 }\r
4523 \r
4524 // タスクトレイの右クリックメニューを表示する\r
4525 void CmShowTrayMenu(HWND hWnd)\r
4526 {\r
4527         HMENU h;\r
4528         POINT p;\r
4529         HMENU sub1, sub2, sub3, sub4;\r
4530         bool locked;\r
4531         bool easy;\r
4532         // 引数チェック\r
4533         if (hWnd == NULL)\r
4534         {\r
4535                 return;\r
4536         }\r
4537 \r
4538         cm->MenuPopuping = true;\r
4539 \r
4540         locked = cm->CmSetting.LockMode;\r
4541         easy = cm->CmSetting.EasyMode;\r
4542 \r
4543         // メニューを作成する\r
4544         h = CreatePopupMenu();\r
4545 \r
4546         // キャンセル\r
4547         MsAppendMenu(h, MF_ENABLED | MF_STRING, 100007, _UU("CM_TRAY_MENU_CANCEL"));\r
4548 \r
4549         // セパレータ\r
4550         MsAppendMenu(h, MF_SEPARATOR, 10006, NULL);\r
4551 \r
4552         if (locked == false && easy == false)\r
4553         {\r
4554                 // 新しい接続設定の作成\r
4555                 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_NEW, _UU("CM_TRAY_MENU_NEW"));\r
4556 \r
4557                 // セパレータ\r
4558                 MsAppendMenu(h, MF_SEPARATOR, 10005, NULL);\r
4559         }\r
4560 \r
4561         // 接続メニュー\r
4562         sub1 = CmCreateTraySubMenu(hWnd, false, CM_TRAY_MENU_CONNECT_ID_START);\r
4563         if (sub1 != NULL)\r
4564         {\r
4565                 MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,\r
4566                         (UINT_PTR)sub1, _UU("CM_TRAY_MENU_CONNECT"));\r
4567         }\r
4568 \r
4569         // 切断メニュー\r
4570         sub2 = CmCreateTraySubMenu(hWnd, true, CM_TRAY_MENU_DISCONNECT_ID_START);\r
4571         if (sub2 != NULL)\r
4572         {\r
4573                 MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,\r
4574                         (UINT_PTR)sub2, _UU("CM_TRAY_MENU_DISCONNECT"));\r
4575         }\r
4576 \r
4577         // ステータス表示メニュー\r
4578         sub3 = CmCreateTraySubMenu(hWnd, true, CM_TRAY_MENU_STATUS_ID_START);\r
4579         if (sub3 != NULL)\r
4580         {\r
4581                 MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,\r
4582                         (UINT_PTR)sub3, _UU("CM_TRAY_MENU_STATUS"));\r
4583         }\r
4584 \r
4585         if (sub3 != NULL)\r
4586         {\r
4587                 // すべての接続を切断\r
4588                 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_DISCONNECT_ALL, _UU("CM_TRAY_MENU_DISCONNECT_ALL"));\r
4589         }\r
4590 \r
4591         if (sub1 != NULL || sub2 != NULL || sub3 != NULL)\r
4592         {\r
4593                 // セパレータ\r
4594                 MsAppendMenu(h, MF_SEPARATOR, 10003, NULL);\r
4595         }\r
4596 \r
4597         // 最近接続した VPN サーバーに接続\r
4598         sub4 = CmCreateRecentSubMenu(hWnd, CM_TRAY_MENU_RECENT_ID_START);\r
4599         if (sub4 != NULL)\r
4600         {\r
4601                 MsAppendMenu(h, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,\r
4602                         (UINT_PTR)sub4, _UU("CM_TRAY_MENU_RECENT"));\r
4603                 MsAppendMenu(h, MF_SEPARATOR, 10008, NULL);\r
4604         }\r
4605 \r
4606         if (locked == false && easy == false)\r
4607         {\r
4608                 // 通信スループット測定\r
4609                 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_TRAFFIC, _UU("CM_TRAY_MENU_TRAFFIC"));\r
4610         }\r
4611 \r
4612         if (easy == false)\r
4613         {\r
4614                 // ネットワークデバイス状態\r
4615                 MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_NETIF, _UU("CM_TRAY_MENU_NETIF"));\r
4616         }\r
4617 \r
4618         // バージョン情報\r
4619         MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_ABOUT, _UU("CM_TRAY_MENU_ABOUT"));\r
4620 \r
4621         // セパレータ\r
4622         MsAppendMenu(h, MF_SEPARATOR, 10001, NULL);\r
4623 \r
4624         // 動作モードの変更\r
4625         MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_CM_SETTING, _UU("CM_TRAY_MENU_SETTING"));\r
4626 \r
4627         // セパレータ\r
4628         MsAppendMenu(h, MF_SEPARATOR, 10001, NULL);\r
4629 \r
4630         // アイコンを非表示\r
4631         MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_TRAYICON, _UU("CM_MENU@CMD_TRAYICON"));\r
4632 \r
4633         // セパレータ\r
4634         MsAppendMenu(h, MF_SEPARATOR, 10001, NULL);\r
4635 \r
4636         // 表示または非表示\r
4637         MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_EXIT,\r
4638                 IsHide(hWnd, 0) ? _UU("CM_TRAY_MENU_1_SHOW") : _UU("CM_TRAY_MENU_1_HIDE"));\r
4639 \r
4640         // 終了\r
4641         MsAppendMenu(h, MF_ENABLED | MF_STRING, CMD_QUIT, _UU("CM_TRAY_MENU_2_QUIT"));\r
4642 \r
4643         // メニューを表示する\r
4644         GetCursorPos(&p);\r
4645 \r
4646         SetForegroundWindow(hWnd);\r
4647         TrackPopupMenu(h, TPM_LEFTALIGN, p.x, p.y, 0, hWnd, NULL);\r
4648         PostMessage(hWnd, WM_NULL, 0, 0);\r
4649 \r
4650         if (sub1 != NULL)\r
4651         {\r
4652                 DestroyMenu(sub1);\r
4653         }\r
4654 \r
4655         if (sub2 != NULL)\r
4656         {\r
4657                 DestroyMenu(sub2);\r
4658         }\r
4659 \r
4660         if (sub3 != NULL)\r
4661         {\r
4662                 DestroyMenu(sub3);\r
4663         }\r
4664 \r
4665         DestroyMenu(h);\r
4666 \r
4667         cm->MenuPopuping = false;\r
4668 }\r
4669 \r
4670 // メインウインドウを表示または隠す\r
4671 void CmShowOrHideWindow(HWND hWnd)\r
4672 {\r
4673         // 引数チェック\r
4674         if (hWnd == NULL)\r
4675         {\r
4676                 return;\r
4677         }\r
4678 \r
4679         if (IsHide(hWnd, 0))\r
4680         {\r
4681                 Show(hWnd, 0);\r
4682                 if (IsIconic(hWnd))\r
4683                 {\r
4684                         ShowWindow(hWnd, SW_SHOWNORMAL);\r
4685                 }\r
4686                 SetForegroundWindow(hWnd);\r
4687                 SetActiveWindow(hWnd);\r
4688         }\r
4689         else\r
4690         {\r
4691                 CmSaveMainWindowPos(hWnd);\r
4692                 Hide(hWnd, 0);\r
4693 \r
4694                 if (cm->TrayInited == false)\r
4695                 {\r
4696                         Command(hWnd, CMD_QUIT);\r
4697                         return;\r
4698                 }\r
4699         }\r
4700 }\r
4701 \r
4702 // アカウントリストを右クリックした\r
4703 void CmAccountListRightClick(HWND hWnd)\r
4704 {\r
4705         HMENU h;\r
4706         HMENU parent;\r
4707         UINT i;\r
4708         // 引数チェック\r
4709         if (hWnd == NULL)\r
4710         {\r
4711                 return;\r
4712         }\r
4713 \r
4714         // メニューをロード\r
4715         h = LoadSubMenu(M_MAIN, 0, &parent);\r
4716         if (h == NULL)\r
4717         {\r
4718                 return;\r
4719         }\r
4720 \r
4721         InitMenuInternational(h, "CM_MENU");\r
4722 \r
4723         // ショートカットキーを除去\r
4724         RemoveShortcutKeyStrFromMenu(h);\r
4725 \r
4726         // 終了メニューを削除\r
4727         i = GetMenuItemPos(h, CMD_QUIT);\r
4728         if (i != INFINITE)\r
4729         {\r
4730                 DeleteMenuItem(h, i);\r
4731                 DeleteMenuItem(h, i - 1);\r
4732                 DeleteMenuItem(h, i - 2);\r
4733                 DeleteMenuItem(h, i - 3);\r
4734         }\r
4735 \r
4736         // 有効 / 無効の設定\r
4737         CmMainWindowOnPopupMenu(hWnd, h, INFINITE);\r
4738 \r
4739         if (h != NULL)\r
4740         {\r
4741                 // 選択されているアカウントが接続中かどうか判別する\r
4742                 UINT i = LvGetSelected(hWnd, L_ACCOUNT);\r
4743                 wchar_t *str;\r
4744                 bool is_connected = false;\r
4745                 if (i != INFINITE)\r
4746                 {\r
4747                         str = LvGetStr(hWnd, L_ACCOUNT, i, 1);\r
4748                         if (str != NULL)\r
4749                         {\r
4750                                 if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)\r
4751                                 {\r
4752                                         // 接続中\r
4753                                         is_connected = true;\r
4754                                 }\r
4755                                 Free(str);\r
4756                         }\r
4757                 }\r
4758 \r
4759                 if (i == INFINITE)\r
4760                 {\r
4761                         // 新規作成メニューを太字にする\r
4762                         SetMenuItemBold(h, GetMenuItemPos(h, CMD_NEW), true);\r
4763                 }\r
4764                 else\r
4765                 {\r
4766                         if (is_connected == false)\r
4767                         {\r
4768                                 // 接続メニューを太字にする\r
4769                                 SetMenuItemBold(h, GetMenuItemPos(h, CMD_CONNECT), true);\r
4770                         }\r
4771                         else\r
4772                         {\r
4773                                 // 状況メニューを太字にする\r
4774                                 SetMenuItemBold(h, GetMenuItemPos(h, CMD_STATUS), true);\r
4775                         }\r
4776                 }\r
4777         }\r
4778 \r
4779         // メニューを表示\r
4780         PrintMenu(hWnd, h);\r
4781 \r
4782         DestroyMenu(parent);\r
4783 }\r
4784 \r
4785 // 仮想 LAN カードリストを右クリックした\r
4786 void CmVLanListRightClick(HWND hWnd)\r
4787 {\r
4788         HMENU h;\r
4789         HMENU parent;\r
4790         // 引数チェック\r
4791         if (hWnd == NULL)\r
4792         {\r
4793                 return;\r
4794         }\r
4795 \r
4796         // メニューをロード\r
4797         h = LoadSubMenu(M_MAIN, 3, &parent);\r
4798         if (h == NULL)\r
4799         {\r
4800                 return;\r
4801         }\r
4802 \r
4803         InitMenuInternational(h, "CM_MENU");\r
4804 \r
4805         // ショートカットキーを除去\r
4806         RemoveShortcutKeyStrFromMenu(h);\r
4807 \r
4808         // 有効 / 無効の設定\r
4809         CmMainWindowOnPopupMenu(hWnd, h, INFINITE);\r
4810 \r
4811         if (h != NULL)\r
4812         {\r
4813                 // 選択されているデバイスが有効かどうか調べる\r
4814                 UINT i = LvGetSelected(hWnd, L_VLAN);\r
4815                 wchar_t *str;\r
4816                 bool is_active = false;\r
4817                 if (i != INFINITE)\r
4818                 {\r
4819                         str = LvGetStr(hWnd, L_VLAN, i, 1);\r
4820                         if (str != NULL)\r
4821                         {\r
4822                                 if (UniStrCmpi(str, _UU("CM_VLAN_ENABLED")) == 0)\r
4823                                 {\r
4824                                         // 有効\r
4825                                         is_active = true;\r
4826                                 }\r
4827                                 Free(str);\r
4828                         }\r
4829                 }\r
4830 \r
4831                 if (i == INFINITE)\r
4832                 {\r
4833                         // 新規作成メニューを太字にする\r
4834                         SetMenuItemBold(h, GetMenuItemPos(h, CMD_NEW_VLAN), true);\r
4835                 }\r
4836                 else\r
4837                 {\r
4838                         if (is_active == false)\r
4839                         {\r
4840                                 // 有効化メニューを太字にする\r
4841                                 SetMenuItemBold(h, GetMenuItemPos(h, CMD_ENABLE_VLAN), true);\r
4842                         }\r
4843                         else\r
4844                         {\r
4845                                 // Windows ネットワーク設定メニューを太字にする\r
4846                                 SetMenuItemBold(h, GetMenuItemPos(h, CMD_WINNET), true);\r
4847                         }\r
4848                 }\r
4849         }\r
4850 \r
4851         // メニューを表示\r
4852         PrintMenu(hWnd, h);\r
4853 \r
4854         DestroyMenu(parent);\r
4855 }\r
4856 \r
4857 // メインウインドウへの通知\r
4858 void CmMainWindowOnNotify(HWND hWnd, NMHDR *n)\r
4859 {\r
4860         bool item_vlan;\r
4861         NMLVDISPINFOW *disp_info;\r
4862         NMLVKEYDOWN *key;\r
4863 \r
4864         // 引数チェック\r
4865         if (hWnd == NULL || n == NULL)\r
4866         {\r
4867                 return;\r
4868         }\r
4869 \r
4870         switch (n->idFrom)\r
4871         {\r
4872         case L_ACCOUNT:\r
4873         case L_VLAN:\r
4874                 if (n->idFrom == L_ACCOUNT)\r
4875                 {\r
4876                         item_vlan = false;\r
4877                 }\r
4878                 else\r
4879                 {\r
4880                         item_vlan = true;\r
4881                 }\r
4882 \r
4883                 switch (n->code)\r
4884                 {\r
4885                 case NM_DBLCLK:\r
4886                         // ダブルクリック\r
4887                         CmOnKey(hWnd, false, false, VK_RETURN);\r
4888                         break;\r
4889                 case NM_RCLICK:\r
4890                         // 右クリック\r
4891                         if (item_vlan == false)\r
4892                         {\r
4893                                 CmAccountListRightClick(hWnd);\r
4894                         }\r
4895                         else\r
4896                         {\r
4897                                 CmVLanListRightClick(hWnd);\r
4898                         }\r
4899                         break;\r
4900                 case LVN_ENDLABELEDITW:\r
4901                         // 名前の変更\r
4902                         disp_info = (NMLVDISPINFOW *)n;\r
4903                         if (disp_info->item.pszText != NULL)\r
4904                         {\r
4905                                 wchar_t *new_name = disp_info->item.pszText;\r
4906                                 wchar_t *old_name = LvGetStr(hWnd, L_ACCOUNT, disp_info->item.iItem, 0);\r
4907 \r
4908                                 if (old_name != NULL)\r
4909                                 {\r
4910                                         if (UniStrCmp(new_name, old_name) != 0 && UniIsEmptyStr(new_name) == false)\r
4911                                         {\r
4912                                                 RPC_RENAME_ACCOUNT a;\r
4913                                                 Zero(&a, sizeof(a));\r
4914                                                 UniStrCpy(a.OldName, sizeof(a.OldName), old_name);\r
4915                                                 UniStrCpy(a.NewName, sizeof(a.NewName), new_name);\r
4916                                                 if (CALL(hWnd, CcRenameAccount(cm->Client, &a)))\r
4917                                                 {\r
4918                                                         LvSetItem(hWnd, L_ACCOUNT, disp_info->item.iItem, 0, new_name);\r
4919                                                 }\r
4920                                         }\r
4921 \r
4922                                         Free(old_name);\r
4923                                 }\r
4924                         }\r
4925                         break;\r
4926                 case LVN_KEYDOWN:\r
4927                         // キー押下\r
4928                         key = (NMLVKEYDOWN *)n;\r
4929                         if (key != NULL)\r
4930                         {\r
4931                                 bool ctrl, alt;\r
4932                                 UINT code = key->wVKey;\r
4933                                 ctrl = (GetKeyState(VK_CONTROL) & 0x8000) == 0 ? false : true;\r
4934                                 alt = (GetKeyState(VK_MENU) & 0x8000) == 0 ? false : true;\r
4935                                 CmOnKey(hWnd, ctrl, alt, code);\r
4936                         }\r
4937                         break;\r
4938                 }\r
4939                 break;\r
4940         }\r
4941 }\r
4942 \r
4943 // キーボード押下\r
4944 void CmOnKey(HWND hWnd, bool ctrl, bool alt, UINT key)\r
4945 {\r
4946         // 引数チェック\r
4947         if (hWnd == NULL)\r
4948         {\r
4949                 return;\r
4950         }\r
4951 \r
4952         // 単一キー\r
4953         switch (key)\r
4954         {\r
4955         case VK_RETURN:\r
4956                 Command(hWnd, IDOK);\r
4957                 break;\r
4958         case VK_DELETE:\r
4959                 // 削除\r
4960                 if (IsFocus(hWnd, L_ACCOUNT))\r
4961                 {\r
4962                         // アカウントリストに関する操作\r
4963                         Command(hWnd, CMD_DELETE);\r
4964                 }\r
4965                 else\r
4966                 {\r
4967                         // 仮想 LAN カードリストに関する操作\r
4968                         Command(hWnd, CMD_DELETE_VLAN);\r
4969                 }\r
4970                 break;\r
4971         case VK_F2:\r
4972                 // 名前変更\r
4973                 Command(hWnd, CMD_RENAME);\r
4974                 break;\r
4975         case VK_F5:\r
4976                 // 状態更新\r
4977                 Command(hWnd, CMD_REFRESH);\r
4978                 break;\r
4979         }\r
4980 \r
4981         if (alt)\r
4982         {\r
4983                 switch (key)\r
4984                 {\r
4985                 case 'Q':\r
4986                         // 閉じる\r
4987                         Command(hWnd, CMD_QUIT);\r
4988                         break;\r
4989                 }\r
4990         }\r
4991 \r
4992         if (ctrl)\r
4993         {\r
4994                 switch (key)\r
4995                 {\r
4996                 case 'G':\r
4997                         // スマートカードマネージャ\r
4998                         Command(hWnd, CMD_SECURE_MANAGER);\r
4999                         break;\r
5000                 case 'S':\r
5001                         // 状態の表示\r
5002                         Command(hWnd, CMD_STATUS);\r
5003                         break;\r
5004                 case 'I':\r
5005                         // すべての接続を切断\r
5006                         Command(hWnd, CMD_DISCONNECT_ALL);\r
5007                         break;\r
5008                 case 'D':\r
5009                         // 切断\r
5010                         Command(hWnd, CMD_DISCONNECT);\r
5011                         break;\r
5012                 case 'N':\r
5013                         // 接続設定の新規作成\r
5014                         Command(hWnd, CMD_NEW);\r
5015                         break;\r
5016                 case 'C':\r
5017                         // コピーの作成\r
5018                         Command(hWnd, CMD_CLONE);\r
5019                         break;\r
5020                 case 'T':\r
5021                         // スタートアップ接続に設定\r
5022                         Command(hWnd, CMD_STARTUP);\r
5023                         break;\r
5024                 case 'A':\r
5025                         // すべて選択\r
5026                         Command(hWnd, CMD_SELECT_ALL);\r
5027                         break;\r
5028                 case 'L':\r
5029                         // 新規仮想 LAN カードの作成\r
5030                         Command(hWnd, CMD_NEW_VLAN);\r
5031                         break;\r
5032                 case 'E':\r
5033                         // 仮想 LAN カードの有効化\r
5034                         Command(hWnd, CMD_ENABLE_VLAN);\r
5035                         break;\r
5036                 case 'B':\r
5037                         // 仮想 LAN カードの無効化\r
5038                         Command(hWnd, CMD_DISABLE_VLAN);\r
5039                         break;\r
5040                 case 'U':\r
5041                         // ドライバの再インストール\r
5042                         Command(hWnd, CMD_REINSTALL);\r
5043                         break;\r
5044                 case 'W':\r
5045                         // Windows ネットワーク接続の設定\r
5046                         Command(hWnd, CMD_WINNET);\r
5047                         break;\r
5048                 case 'P':\r
5049                         // パスワードの設定\r
5050                         Command(hWnd, CMD_PASSWORD);\r
5051                         break;\r
5052                 case 'O':\r
5053                         // オプション設定\r
5054                         Command(hWnd, CMD_TRAFFIC);\r
5055                         break;\r
5056                 case 'R':\r
5057                         // 証明書管理\r
5058                         Command(hWnd, CMD_TRUST);\r
5059                         break;\r
5060                 case 'Q':\r
5061                         // スループット\r
5062                         Command(hWnd, CMD_TRAFFIC);\r
5063                         break;\r
5064                 }\r
5065         }\r
5066 }\r
5067 \r
5068 // メインウインドウのコマンド\r
5069 void CmMainWindowOnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)\r
5070 {\r
5071         CmMainWindowOnCommandEx(hWnd, wParam, lParam, false);\r
5072 }\r
5073 void CmMainWindowOnCommandEx(HWND hWnd, WPARAM wParam, LPARAM lParam, bool easy)\r
5074 {\r
5075         wchar_t *tmp;\r
5076         char *name;\r
5077         UINT index;\r
5078         UINT id;\r
5079         bool ctrl, alt;\r
5080         UINT flag = 0;\r
5081         // 引数チェック\r
5082         wchar_t *selected_name = NULL;\r
5083         UINT starter_id = 0;\r
5084         if (hWnd == NULL)\r
5085         {\r
5086                 return;\r
5087         }\r
5088 \r
5089         ctrl = (GetKeyState(VK_CONTROL) & 0x8000) == 0 ? false : true;\r
5090         alt = (GetKeyState(VK_MENU) & 0x8000) == 0 ? false : true;\r
5091 \r
5092         if (wParam == IDOK)\r
5093         {\r
5094                 tmp = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);\r
5095                 if (tmp != NULL)\r
5096                 {\r
5097                         if (UniStrCmpi(tmp, _UU("CM_NEW_ICON")) == 0)\r
5098                         {\r
5099                                 Free(tmp);\r
5100                                 Command(hWnd, CMD_NEW);\r
5101                                 return;\r
5102                         }\r
5103                         if (UniStrCmpi(tmp, _UU("CM_ASP")) == 0)\r
5104                         {\r
5105                                 Free(tmp);\r
5106                                 ShellExecuteA(hWnd, "open", _SS("CM_ASP_URL"), NULL, NULL, SW_SHOW);\r
5107                                 return;\r
5108                         }\r
5109                         Free(tmp);\r
5110                 }\r
5111         }\r
5112 \r
5113         if (CmIsEnabled(hWnd, (UINT)wParam) == false)\r
5114         {\r
5115                 return;\r
5116         }\r
5117 \r
5118         if (CM_TRAY_IS_CONNECT_ID(wParam))\r
5119         {\r
5120                 // 接続要求\r
5121                 starter_id = CM_TRAY_MENU_CONNECT_ID_START;\r
5122                 flag = 1;\r
5123         }\r
5124 \r
5125         if (CM_TRAY_IS_STATUS_ID(wParam))\r
5126         {\r
5127                 // 情報表示要求\r
5128                 starter_id = CM_TRAY_MENU_STATUS_ID_START;\r
5129                 flag = 2;\r
5130         }\r
5131 \r
5132         if (CM_TRAY_IS_DISCONNECT_ID(wParam))\r
5133         {\r
5134                 // 切断要求\r
5135                 starter_id = CM_TRAY_MENU_DISCONNECT_ID_START;\r
5136                 flag = 3;\r
5137         }\r
5138 \r
5139         if (CM_TRAY_IS_RECENT_ID(wParam))\r
5140         {\r
5141                 // 最近の接続先\r
5142                 starter_id = CM_TRAY_MENU_RECENT_ID_START;\r
5143                 flag = 1;\r
5144         }\r
5145 \r
5146         if (starter_id != 0)\r
5147         {\r
5148                 UINT num;\r
5149 \r
5150                 id = (UINT)wParam - starter_id;\r
5151 \r
5152                 num = LvNum(hWnd, L_ACCOUNT);\r
5153 \r
5154                 if (id < num)\r
5155                 {\r
5156                         selected_name = LvGetStr(hWnd, L_ACCOUNT, id, 0);\r
5157 \r
5158                         if (selected_name != NULL)\r
5159                         {\r
5160                                 if (UniStrCmpi(selected_name, _UU("CM_NEW_ICON")) != 0 &&\r
5161                                         UniStrCmpi(selected_name, _UU("CM_ASP")) != 0)\r
5162                                 {\r
5163                                         switch (flag)\r
5164                                         {\r
5165                                         case 1:\r
5166                                                 CmConnect(hWnd, selected_name);\r
5167                                                 break;\r
5168 \r
5169                                         case 2:\r
5170                                                 CmStatus(hWnd, selected_name);\r
5171                                                 break;\r
5172 \r
5173                                         case 3:\r
5174                                                 CmDisconnect(hWnd, selected_name);\r
5175                                                 break;\r
5176                                         }\r
5177                                 }\r
5178                         }\r
5179 \r
5180                         Free(selected_name);\r
5181                 }\r
5182         }\r
5183 \r
5184         switch (wParam)\r
5185         {\r
5186         case IDOK:\r
5187         case CMD_EASY_DBLCLICK:\r
5188                 // 接続またはプロパティ\r
5189                 if (IsFocus(hWnd, L_ACCOUNT) || (hWnd == cm->hEasyWnd))\r
5190                 {\r
5191                         // アカウントリストに関する操作\r
5192                         if (alt == false)\r
5193                         {\r
5194                                 UINT index = LvGetSelected(hWnd, L_ACCOUNT);\r
5195                                 bool b = false;\r
5196                                 if (index != INFINITE)\r
5197                                 {\r
5198                                         wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, index, 1);\r
5199                                         if (s != NULL)\r
5200                                         {\r
5201                                                 if (UniStrCmpi(s, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(s, _UU("CM_ACCOUNT_CONNECTING")) == 0)\r
5202                                                 {\r
5203                                                         b = true;\r
5204                                                 }\r
5205                                                 Free(s);\r
5206                                         }\r
5207                                 }\r
5208 \r
5209                                 if (b == false)\r
5210                                 {\r
5211                                         // 接続\r
5212                                         Command(hWnd, CMD_CONNECT);\r
5213                                 }\r
5214                                 else\r
5215                                 {\r
5216                                         if (hWnd != cm->hEasyWnd || wParam == CMD_EASY_DBLCLICK)\r
5217                                         {\r
5218                                                 // 状況表示\r
5219                                                 Command(hWnd, CMD_STATUS);\r
5220                                         }\r
5221                                         else\r
5222                                         {\r
5223                                                 // 切断\r
5224                                                 Command(hWnd, CMD_DISCONNECT);\r
5225                                         }\r
5226                                 }\r
5227                         }\r
5228                         else\r
5229                         {\r
5230                                 // プロパティ\r
5231                                 Command(hWnd, CMD_PROPERTY);\r
5232                         }\r
5233                 }\r
5234                 else\r
5235                 {\r
5236                         // Windows ネットワーク接続の設定\r
5237                         Command(hWnd, CMD_WINNET);\r
5238                 }\r
5239                 break;\r
5240         case CMD_CONNECT:\r
5241                 // 接続\r
5242                 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);\r
5243                 if (tmp != NULL)\r
5244                 {\r
5245                         CmConnect(hWnd, tmp);\r
5246                         Free(tmp);\r
5247                 }\r
5248                 break;\r
5249         case CMD_STATUS:\r
5250                 // 状態の表示\r
5251                 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);\r
5252                 if (tmp != NULL)\r
5253                 {\r
5254                         CmStatus(hWnd, tmp);\r
5255                         Free(tmp);\r
5256                 }\r
5257                 break;\r
5258         case CMD_DISCONNECT_ALL:\r
5259                 // すべての接続を切断する\r
5260                 CmDisconnectAll(hWnd);\r
5261                 break;\r
5262         case CMD_DISCONNECT:\r
5263                 // 切断\r
5264                 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);\r
5265                 if (tmp != NULL)\r
5266                 {\r
5267                         CmDisconnect(hWnd, tmp);\r
5268                         Free(tmp);\r
5269                 }\r
5270                 break;\r
5271         case CMD_NEW:\r
5272                 // 新規作成\r
5273                 CmNewAccount(hWnd);\r
5274                 break;\r
5275         case CMD_CLONE:\r
5276                 // コピー\r
5277                 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);\r
5278                 if (tmp != NULL)\r
5279                 {\r
5280                         CmCopyAccount(hWnd, tmp);\r
5281                         Free(tmp);\r
5282                 }\r
5283                 break;\r
5284         case CMD_SHORTCUT:\r
5285                 // ショートカット作成\r
5286                 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);\r
5287                 if (tmp != NULL)\r
5288                 {\r
5289                         CmSortcut(hWnd, tmp);\r
5290                         Free(tmp);\r
5291                 }\r
5292                 break;\r
5293         case CMD_EXPORT_ACCOUNT:\r
5294                 // 設定のエクスポート\r
5295                 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);\r
5296                 if (tmp != NULL)\r
5297                 {\r
5298                         CmExportAccount(hWnd, tmp);\r
5299                         Free(tmp);\r
5300                 }\r
5301                 break;\r
5302         case CMD_IMPORT_ACCOUNT:\r
5303                 // 設定のインポート\r
5304                 CmImportAccount(hWnd);\r
5305                 break;\r
5306         case CMD_STARTUP:\r
5307                 // スタートアップ接続に設定\r
5308                 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);\r
5309                 if (tmp != NULL)\r
5310                 {\r
5311                         RPC_CLIENT_DELETE_ACCOUNT c;\r
5312                         Zero(&c, sizeof(c));\r
5313                         UniStrCpy(c.AccountName, sizeof(c.AccountName), tmp);\r
5314                         CALL(hWnd, CcSetStartupAccount(cm->Client, &c));\r
5315                         CmVoice("set_startup");\r
5316                         MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_SET_STARTUP"), tmp);\r
5317                         Free(tmp);\r
5318                 }\r
5319                 break;\r
5320         case CMD_NOSTARTUP:\r
5321                 // スタートアップ接続を解除\r
5322                 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);\r
5323                 if (tmp != NULL)\r
5324                 {\r
5325                         if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2,\r
5326                                 _UU("CM_REMOVE_STARTUP"), tmp) == IDYES)\r
5327                         {\r
5328                                 RPC_CLIENT_DELETE_ACCOUNT c;\r
5329                                 Zero(&c, sizeof(c));\r
5330                                 UniStrCpy(c.AccountName, sizeof(c.AccountName), tmp);\r
5331                                 CALL(hWnd, CcRemoveStartupAccount(cm->Client, &c));\r
5332                                 CmVoice("remove_startup");\r
5333                         }\r
5334                         Free(tmp);\r
5335                 }\r
5336                 break;\r
5337         case CMD_DELETE:\r
5338                 // 削除\r
5339                 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);\r
5340                 if (tmp != NULL)\r
5341                 {\r
5342                         CmDeleteAccount(hWnd, tmp);\r
5343                         Free(tmp);\r
5344                 }\r
5345                 break;\r
5346         case CMD_RENAME:\r
5347                 // 名前の変更\r
5348                 Focus(hWnd, L_ACCOUNT);\r
5349                 LvRename(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT));\r
5350                 break;\r
5351         case CMD_PROPERTY:\r
5352                 // プロパティ\r
5353                 tmp = LvGetStr(hWnd, L_ACCOUNT, LvGetSelected(hWnd, L_ACCOUNT), 0);\r
5354                 if (tmp != NULL)\r
5355                 {\r
5356                         CmEditAccount(hWnd, tmp);\r
5357                         Free(tmp);\r
5358                 }\r
5359                 break;\r
5360         case IDCANCEL:\r
5361         case CMD_EXIT:\r
5362                 // 閉じる\r
5363                 Close(hWnd);\r
5364                 break;\r
5365         case CMD_QUIT:\r
5366                 // 終了\r
5367                 CmMainWindowOnQuit(hWnd);\r
5368                 break;\r
5369         case CMD_SELECT_ALL:\r
5370                 // すべて選択\r
5371                 LvSelectAll(hWnd, L_ACCOUNT);\r
5372                 LvSelectAll(hWnd, L_VLAN);\r
5373                 break;\r
5374         case CMD_SWITCH_SELECT:\r
5375                 // 選択反転\r
5376                 LvSwitchSelect(hWnd, L_ACCOUNT);\r
5377                 LvSwitchSelect(hWnd, L_VLAN);\r
5378                 break;\r
5379         case CMD_GRID:\r
5380                 // 罫線表示\r
5381                 cm->ShowGrid = !cm->ShowGrid;\r
5382                 CmRefreshVLanListEx(hWnd, true);\r
5383                 CmRefreshAccountListEx2(hWnd, false, true);\r
5384                 break;\r
5385         case CMD_STATUSBAR:\r
5386                 // ステータスバー表示\r
5387                 if (cm->HideStatusBar == false)\r
5388                 {\r
5389                         cm->HideStatusBar = true;\r
5390                         Hide(hWnd, S_STATUSBAR);\r
5391                         CmMainWindowOnSize(hWnd);\r
5392                 }\r
5393                 else\r
5394                 {\r
5395                         cm->HideStatusBar = false;\r
5396                         Show(hWnd, S_STATUSBAR);\r
5397                         CmMainWindowOnSize(hWnd);\r
5398                 }\r
5399                 CmSaveMainWindowPos(hWnd);\r
5400                 break;\r
5401         case CMD_VISTASTYLE:\r
5402                 cm->VistaStyle = !cm->VistaStyle;\r
5403                 CmRefreshEx(hWnd, true);\r
5404                 CmSaveMainWindowPos(hWnd);\r
5405                 break;\r
5406         case CMD_TRAYICON:\r
5407                 // トレイアイコン表示\r
5408                 if (cm->HideTrayIcon == false)\r
5409                 {\r
5410                         cm->HideTrayIcon = true;\r
5411                         CmFreeTray(hWnd);\r
5412 \r
5413                         if (IsHide(hWnd, 0))\r
5414                         {\r
5415                                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_TRAY_ICON_RESTORE"));\r
5416                         }\r
5417                 }\r
5418                 else\r
5419                 {\r
5420                         cm->HideTrayIcon = false;\r
5421                         if (cm->server_name == NULL)\r
5422                         {\r
5423                                 CmInitTray(hWnd);\r
5424                         }\r
5425                 }\r
5426                 break;\r
5427         case CMD_SHOWPORT:\r
5428                 // ポート番号を表示\r
5429                 cm->ShowPort = !cm->ShowPort;\r
5430                 CmRefresh(hWnd);\r
5431                 break;\r
5432         case CMD_ICON:\r
5433                 // アイコン表示\r
5434                 if (cm->IconView == false)\r
5435                 {\r
5436                         cm->IconView = true;\r
5437                         CmRefresh(hWnd);\r
5438                 }\r
5439                 break;\r
5440         case CMD_DETAIL:\r
5441                 // 詳細表示\r
5442                 if (cm->IconView)\r
5443                 {\r
5444                         cm->IconView = false;\r
5445                         CmRefresh(hWnd);\r
5446                 }\r
5447                 break;\r
5448         case CMD_REFRESH:\r
5449                 if (easy == false)\r
5450                 {\r
5451                         // 表示更新\r
5452                         LvReset(hWnd, L_ACCOUNT);\r
5453                         LvReset(hWnd, L_VLAN);\r
5454                         CmRefresh(hWnd);\r
5455                 }\r
5456                 break;\r
5457         case CMD_NEW_VLAN:\r
5458                 // 仮想 LAN カード作成\r
5459                 name = CmNewVLanDlg(hWnd);\r
5460                 if (name != NULL)\r
5461                 {\r
5462                         wchar_t tmp[MAX_SIZE];\r
5463                         void *helper = NULL;\r
5464                         RPC_CLIENT_CREATE_VLAN c;\r
5465                         Zero(&c, sizeof(c));\r
5466                         StrCpy(c.DeviceName, sizeof(c.DeviceName), name);\r
5467                         if (MsIsNt() == false)\r
5468                         {\r
5469                                 // ウインドウのタイトルを変更する\r
5470                                 GetTxt(hWnd, 0, tmp, sizeof(tmp));\r
5471                                 SetText(hWnd, 0, _UU("CM_VLAN_INSTALLING"));\r
5472                         }\r
5473                         // 最小化\r
5474                         if (MsIsVista() == false)\r
5475                         {\r
5476                                 ShowWindow(hWnd, SW_SHOWMINIMIZED);\r
5477                         }\r
5478 \r
5479                         if (MsIsVista())\r
5480                         {\r
5481                                 helper = CmStartUacHelper();\r
5482                         }\r
5483 \r
5484                         if (CALL(hWnd, CcCreateVLan(cm->Client, &c)))\r
5485                         {\r
5486                                 CmVoice("new_vlan");\r
5487                         }\r
5488 \r
5489                         CmStopUacHelper(helper);\r
5490 \r
5491                         if (MsIsNt() == false)\r
5492                         {\r
5493                                 // ウインドウのタイトルを戻す\r
5494                                 SetText(hWnd, 0, tmp);\r
5495                         }\r
5496                         // 戻す\r
5497                         if (MsIsVista() == false)\r
5498                         {\r
5499                                 ShowWindow(hWnd, SW_SHOWNORMAL);\r
5500                         }\r
5501                         Free(name);\r
5502                 }\r
5503                 break;\r
5504         case CMD_DELETE_VLAN:\r
5505                 // 仮想 LAN カード削除\r
5506                 index = LvGetSelected(hWnd, L_VLAN);\r
5507                 if (index != INFINITE)\r
5508                 {\r
5509                         if (cm->Client->Win9x == false)\r
5510                         {\r
5511                                 // Windows 2000 以降\r
5512                                 wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);\r
5513                                 if (s != NULL)\r
5514                                 {\r
5515                                         RPC_CLIENT_CREATE_VLAN c;\r
5516                                         char str[MAX_SIZE];\r
5517                                         CmVoice("delete_vlan_1");\r
5518                                         if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_VLAN"), s) == IDYES)\r
5519                                         {\r
5520                                                 Zero(&c, sizeof(c));\r
5521                                                 UniToStr(str, sizeof(str), s);\r
5522                                                 if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))\r
5523                                                 {\r
5524                                                         if (CALL(hWnd, CcDeleteVLan(cm->Client, &c)))\r
5525                                                         {\r
5526                                                                 CmVoice("delete_vlan_2");\r
5527                                                         }\r
5528                                                 }\r
5529                                         }\r
5530                                         Free(s);\r
5531                                 }\r
5532                         }\r
5533                         else\r
5534                         {\r
5535                                 // Windows 9x\r
5536                                 if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("CM_9X_VLAN_UNINSTALL")) == IDYES)\r
5537                                 {\r
5538                                         Run("rundll32.exe", "shell32.dll,Control_RunDLL NETCPL.CPL",\r
5539                                                 false, false);\r
5540                                 }\r
5541                         }\r
5542                 }\r
5543                 break;\r
5544         case CMD_ENABLE_VLAN:\r
5545                 // 仮想 LAN カードの有効化\r
5546                 index = LvGetSelected(hWnd, L_VLAN);\r
5547                 if (index != INFINITE)\r
5548                 {\r
5549                         wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);\r
5550                         if (s != NULL)\r
5551                         {\r
5552                                 RPC_CLIENT_CREATE_VLAN c;\r
5553                                 char str[MAX_SIZE];\r
5554                                 Zero(&c, sizeof(c));\r
5555                                 UniToStr(str, sizeof(str), s);\r
5556                                 if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))\r
5557                                 {\r
5558                                         CALL(hWnd, CcEnableVLan(cm->Client, &c));\r
5559                                 }\r
5560                                 Free(s);\r
5561                         }\r
5562                 }\r
5563                 break;\r
5564         case CMD_DISABLE_VLAN:\r
5565                 // 仮想 LAN カードの無効化\r
5566                 index = LvGetSelected(hWnd, L_VLAN);\r
5567                 if (index != INFINITE)\r
5568                 {\r
5569                         wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);\r
5570                         if (s != NULL)\r
5571                         {\r
5572                                 RPC_CLIENT_CREATE_VLAN c;\r
5573                                 char str[MAX_SIZE];\r
5574                                 Zero(&c, sizeof(c));\r
5575                                 UniToStr(str, sizeof(str), s);\r
5576                                 if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))\r
5577                                 {\r
5578                                         CALL(hWnd, CcDisableVLan(cm->Client, &c));\r
5579                                 }\r
5580                                 Free(s);\r
5581                         }\r
5582                 }\r
5583                 break;\r
5584         case CMD_REINSTALL:\r
5585                 // 仮想 LAN カードの再インストール\r
5586                 index = LvGetSelected(hWnd, L_VLAN);\r
5587                 if (index != INFINITE)\r
5588                 {\r
5589                         wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 0);\r
5590                         if (s != NULL)\r
5591                         {\r
5592                                 RPC_CLIENT_CREATE_VLAN c;\r
5593                                 char str[MAX_SIZE];\r
5594                                 Zero(&c, sizeof(c));\r
5595                                 UniToStr(str, sizeof(str), s);\r
5596                                 if (CmPrintNameToVLanName(c.DeviceName, sizeof(c.DeviceName), str))\r
5597                                 {\r
5598                                         void *helper = NULL;\r
5599 \r
5600                                         if (MsIsVista() == false)\r
5601                                         {\r
5602                                                 ShowWindow(hWnd, SW_SHOWMINIMIZED);\r
5603                                         }\r
5604 \r
5605                                         if (MsIsVista())\r
5606                                         {\r
5607                                                 helper = CmStartUacHelper();\r
5608                                         }\r
5609 \r
5610                                         CALL(hWnd, CcUpgradeVLan(cm->Client, &c));\r
5611 \r
5612                                         CmStopUacHelper(helper);\r
5613 \r
5614                                         if (MsIsVista() == false)\r
5615                                         {\r
5616                                                 ShowWindow(hWnd, SW_SHOWNORMAL);\r
5617                                         }\r
5618                                 }\r
5619                                 Free(s);\r
5620                         }\r
5621                 }\r
5622                 break;\r
5623         case CMD_PASSWORD:\r
5624                 // パスワード設定\r
5625                 CmPassword(hWnd);\r
5626                 break;\r
5627         case CMD_OPTION:\r
5628                 // オプション\r
5629                 CmConfigDlg(hWnd);\r
5630                 break;\r
5631         case CMD_TRUST:\r
5632                 // 証明書管理\r
5633                 CmTrustDlg(hWnd);\r
5634                 break;\r
5635         case CMD_ABOUT:\r
5636                 // バージョン情報\r
5637                 if (IsEnable(hWnd, 0))\r
5638                 {\r
5639                         ShowSplashEx(hWnd, "UT-VPN Client", 0, CM_SPLASH_BORDER_COLOR);\r
5640                 }\r
5641                 break;\r
5642         case CMD_VOIDE_NONE:\r
5643                 cm->DisableVoice = true;\r
5644                 break;\r
5645         case CMD_VOICE_NORMAL:\r
5646                 cm->DisableVoice = false;\r
5647                 cm->VoiceId = VOICE_SSK;\r
5648                 break;\r
5649         case CMD_VOICE_ODD:\r
5650                 if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("CM_EXT_VOICE_MSG")) == IDYES)\r
5651                 {\r
5652                         cm->DisableVoice = false;\r
5653                         cm->VoiceId = VOICE_AHO;\r
5654                 }\r
5655                 break;\r
5656         case CMD_SECURE_MANAGER:\r
5657                 // スマートカードマネージャ\r
5658                 CmClientSecureManager(hWnd);\r
5659                 break;\r
5660         case CMD_SECURE_SELECT:\r
5661                 // スマートカードの選択\r
5662                 CmClientSelectSecure(hWnd);\r
5663                 break;\r
5664         case CMD_NETIF:\r
5665                 // ネットワークデバイスの状態\r
5666                 if (IsEnable(hWnd, 0))\r
5667                 {\r
5668                         UtSpeedMeterEx(hWnd);\r
5669                 }\r
5670                 break;\r
5671         case CMD_TCPIP:\r
5672                 // TCP/IP 最適化ユーティリティ\r
5673                 if (IsEnable(hWnd, 0))\r
5674                 {\r
5675                         ShowTcpIpConfigUtil(hWnd, true);\r
5676                 }\r
5677                 break;\r
5678         case CMD_MMCSS:\r
5679                 // Windows Vista 用最適化ユーティリティ\r
5680                 if (MsIsVista() == false)\r
5681                 {\r
5682                         MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_4"));\r
5683                 }\r
5684                 else\r
5685                 {\r
5686                         if (MsIsAdmin() == false)\r
5687                         {\r
5688                                 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("VISTA_MMCSS_MSG_4"));\r
5689                         }\r
5690                         else\r
5691                         {\r
5692                                 if (MsIsMMCSSNetworkThrottlingEnabled())\r
5693                                 {\r
5694                                         if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("VISTA_MMCSS_MSG")) == IDYES)\r
5695                                         {\r
5696                                                 MsSetMMCSSNetworkThrottlingEnable(false);\r
5697                                                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_5"));\r
5698                                         }\r
5699                                 }\r
5700                                 else\r
5701                                 {\r
5702                                         if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("VISTA_MMCSS_MSG_2")) == IDYES)\r
5703                                         {\r
5704                                                 MsSetMMCSSNetworkThrottlingEnable(true);\r
5705                                                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("VISTA_MMCSS_MSG_6"));\r
5706                                         }\r
5707                                 }\r
5708                         }\r
5709                 }\r
5710                 break;\r
5711         case CMD_TRAFFIC:\r
5712                 // 通信トラフィック測定\r
5713                 if (IsEnable(hWnd, 0))\r
5714                 {\r
5715                         CmTraffic(hWnd);\r
5716                 }\r
5717                 break;\r
5718         case CMD_CM_SETTING:\r
5719                 // 動作モード設定\r
5720                 if (IsEnable(hWnd, 0))\r
5721                 {\r
5722                         if (CmSetting(hWnd))\r
5723                         {\r
5724                                 CmApplyCmSetting();\r
5725                         }\r
5726                 }\r
5727                 break;\r
5728         case CMD_WINNET:\r
5729                 // Windows ネットワークの設定\r
5730                 ShowWindowsNetworkConnectionDialog();\r
5731                 break;\r
5732         }\r
5733 }\r
5734 \r
5735 // オプション設定ダイアログ\r
5736 void CmConfigDlg(HWND hWnd)\r
5737 {\r
5738         // 引数チェック\r
5739         if (hWnd == NULL)\r
5740         {\r
5741                 return;\r
5742         }\r
5743 \r
5744         Dialog(hWnd, D_CM_CONFIG, CmConfigDlgProc, NULL);\r
5745 }\r
5746 \r
5747 // オプション設定ダイアログの初期化\r
5748 void CmConfigDlgInit(HWND hWnd)\r
5749 {\r
5750         bool use_alpha;\r
5751         UINT alpha_value;\r
5752         UINT os;\r
5753         CLIENT_CONFIG c;\r
5754         // 引数チェック\r
5755         if (hWnd == NULL)\r
5756         {\r
5757                 return;\r
5758         }\r
5759 \r
5760         DlgFont(hWnd, S_WARNING, 10, true);\r
5761         DlgFont(hWnd, S_INFO, 10, false);\r
5762 \r
5763         Zero(&c, sizeof(c));\r
5764         if (CALL(hWnd, CcGetClientConfig(cm->Client, &c)) == false)\r
5765         {\r
5766                 EndDialog(hWnd, 0);\r
5767                 return;\r
5768         }\r
5769 \r
5770         Check(hWnd, R_ALLOW_REMOTE_CONFIG, c.AllowRemoteConfig);\r
5771 \r
5772         Check(hWnd, R_USE_KEEP_CONNECT, c.UseKeepConnect);\r
5773         SetTextA(hWnd, E_HOSTNAME, c.KeepConnectHost);\r
5774         SetIntEx(hWnd, E_PORT, c.KeepConnectPort);\r
5775         SetIntEx(hWnd, E_INTERVAL, c.KeepConnectInterval);\r
5776 \r
5777         Check(hWnd, R_TCP, c.KeepConnectProtocol == CONNECTION_TCP);\r
5778         Check(hWnd, R_UDP, c.KeepConnectProtocol == CONNECTION_UDP);\r
5779 \r
5780         use_alpha = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "UseAlpha") == 0 ? false : true;\r
5781         alpha_value = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "AlphaValue");\r
5782         alpha_value = MAKESURE(alpha_value, 0, 100);\r
5783 \r
5784         SetInt(hWnd, E_ALPHA_VALUE, alpha_value == 0 ? 50 : alpha_value);\r
5785         Check(hWnd, R_ALPHA, use_alpha);\r
5786 \r
5787         os = GetOsInfo()->OsType;\r
5788         if (OS_IS_WINDOWS_NT(os) && GET_KETA(os, 100) >= 2)\r
5789         {\r
5790                 Enable(hWnd, R_ALPHA);\r
5791         }\r
5792         else\r
5793         {\r
5794                 Disable(hWnd, R_ALPHA);\r
5795         }\r
5796 \r
5797         CmConfigDlgRefresh(hWnd);\r
5798 }\r
5799 \r
5800 // オプション設定ダイアログの更新\r
5801 void CmConfigDlgRefresh(HWND hWnd)\r
5802 {\r
5803         bool ok = true;\r
5804         bool use_keep_connect;\r
5805         // 引数チェック\r
5806         if (hWnd == NULL)\r
5807         {\r
5808                 return;\r
5809         }\r
5810 \r
5811         use_keep_connect = IsChecked(hWnd, R_USE_KEEP_CONNECT);\r
5812         SetEnable(hWnd, S_HOSTNAME, use_keep_connect);\r
5813         SetEnable(hWnd, S_PORT, use_keep_connect);\r
5814         SetEnable(hWnd, S_INTERVAL, use_keep_connect);\r
5815         SetEnable(hWnd, S_INTERVAL2, use_keep_connect);\r
5816         SetEnable(hWnd, S_PROTOCOL, use_keep_connect);\r
5817         SetEnable(hWnd, S_INFO, use_keep_connect);\r
5818         SetEnable(hWnd, S_INFO2, use_keep_connect);\r
5819         SetEnable(hWnd, E_HOSTNAME, use_keep_connect);\r
5820         SetEnable(hWnd, E_PORT, use_keep_connect);\r
5821         SetEnable(hWnd, E_INTERVAL, use_keep_connect);\r
5822         SetEnable(hWnd, R_TCP, use_keep_connect);\r
5823         SetEnable(hWnd, R_UDP, use_keep_connect);\r
5824 \r
5825         SetEnable(hWnd, S_WARNING, IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG));\r
5826 \r
5827         if (IsChecked(hWnd, R_USE_KEEP_CONNECT))\r
5828         {\r
5829                 if (IsEmpty(hWnd, E_HOSTNAME))\r
5830                 {\r
5831                         ok = false;\r
5832                 }\r
5833                 if (IsChecked(hWnd, R_TCP) == false && IsChecked(hWnd, R_UDP) == false)\r
5834                 {\r
5835                         ok = false;\r
5836                 }\r
5837                 if (GetInt(hWnd, E_PORT) == 0 || GetInt(hWnd, E_PORT) >= 65536)\r
5838                 {\r
5839                         ok = false;\r
5840                 }\r
5841                 if (GetInt(hWnd, E_INTERVAL) == 0)\r
5842                 {\r
5843                         ok = false;\r
5844                 }\r
5845         }\r
5846 \r
5847         if (IsChecked(hWnd, R_ALPHA))\r
5848         {\r
5849                 UINT i = GetInt(hWnd, E_ALPHA_VALUE);\r
5850                 if (i < 20 || i >= 100)\r
5851                 {\r
5852                         ok = false;\r
5853                 }\r
5854                 Enable(hWnd, E_ALPHA_VALUE);\r
5855         }\r
5856         else\r
5857         {\r
5858                 Disable(hWnd, E_ALPHA_VALUE);\r
5859         }\r
5860 \r
5861         SetEnable(hWnd, IDOK, ok);\r
5862 }\r
5863 \r
5864 // オプション設定ダイアログの設定保存\r
5865 void CmConfigDlgOnOk(HWND hWnd)\r
5866 {\r
5867         CLIENT_CONFIG c;\r
5868         // 引数チェック\r
5869         if (hWnd == NULL)\r
5870         {\r
5871                 return;\r
5872         }\r
5873 \r
5874         Zero(&c, sizeof(c));\r
5875         c.AllowRemoteConfig = IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG);\r
5876         c.UseKeepConnect = IsChecked(hWnd, R_USE_KEEP_CONNECT);\r
5877         GetTxtA(hWnd, E_HOSTNAME, c.KeepConnectHost, sizeof(c.KeepConnectHost));\r
5878         c.KeepConnectPort = GetInt(hWnd, E_PORT);\r
5879         c.KeepConnectInterval = GetInt(hWnd, E_INTERVAL);\r
5880         if (IsChecked(hWnd, R_TCP))\r
5881         {\r
5882                 c.KeepConnectProtocol = CONNECTION_TCP;\r
5883         }\r
5884         else if (IsChecked(hWnd, R_UDP))\r
5885         {\r
5886                 c.KeepConnectProtocol = CONNECTION_UDP;\r
5887         }\r
5888         else\r
5889         {\r
5890                 return;\r
5891         }\r
5892 \r
5893         if (c.UseKeepConnect)\r
5894         {\r
5895                 if (c.KeepConnectInterval < KEEP_INTERVAL_MIN || c.KeepConnectInterval > KEEP_INTERVAL_MAX)\r
5896                 {\r
5897                         MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_KEEP_INTERVAL_MSG"),\r
5898                                 KEEP_INTERVAL_MIN, KEEP_INTERVAL_MAX);\r
5899                         FocusEx(hWnd, E_INTERVAL);\r
5900                         return;\r
5901                 }\r
5902         }\r
5903 \r
5904         if (CALL(hWnd, CcSetClientConfig(cm->Client, &c)) == false)\r
5905         {\r
5906                 return;\r
5907         }\r
5908 \r
5909         MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "AlphaValue", GetInt(hWnd, E_ALPHA_VALUE));\r
5910         MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "UseAlpha", IsChecked(hWnd, R_ALPHA));\r
5911 \r
5912         EndDialog(hWnd, true);\r
5913 }\r
5914 \r
5915 // オプション設定ダイアログプロシージャ\r
5916 UINT CmConfigDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
5917 {\r
5918         // 引数チェック\r
5919         if (hWnd == NULL)\r
5920         {\r
5921                 return 0;\r
5922         }\r
5923 \r
5924         switch (msg)\r
5925         {\r
5926         case WM_INITDIALOG:\r
5927                 CmConfigDlgInit(hWnd);\r
5928                 break;\r
5929         case WM_COMMAND:\r
5930                 switch (LOWORD(wParam))\r
5931                 {\r
5932                 case R_ALLOW_REMOTE_CONFIG:\r
5933                 case R_USE_KEEP_CONNECT:\r
5934                 case E_HOSTNAME:\r
5935                 case E_PORT:\r
5936                 case E_INTERVAL:\r
5937                 case R_ALPHA:\r
5938                 case E_ALPHA_VALUE:\r
5939                         CmConfigDlgRefresh(hWnd);\r
5940                         break;\r
5941                 }\r
5942 \r
5943                 switch (wParam)\r
5944                 {\r
5945                 case IDOK:\r
5946                         CmConfigDlgRefresh(hWnd);\r
5947                         CmConfigDlgOnOk(hWnd);\r
5948                         break;\r
5949                 case IDCANCEL:\r
5950                         Close(hWnd);\r
5951                         break;\r
5952                 case R_ALLOW_REMOTE_CONFIG:\r
5953                         if (IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG) == false)\r
5954                         {\r
5955                                 if (cm->server_name != NULL)\r
5956                                 {\r
5957                                         // 現在リモート接続している場合、リモート管理を無効にするように\r
5958                                         // 選択すると警告を表示する\r
5959                                         if (MsgBoxEx(hWnd, MB_ICONEXCLAMATION | MB_DEFBUTTON2 | MB_YESNO, _UU("CM_REMOTE_WARNING"),\r
5960                                                 cm->server_name, cm->server_name) == IDNO)\r
5961                                         {\r
5962                                                 Check(hWnd, R_ALLOW_REMOTE_CONFIG, true);\r
5963                                         }\r
5964                                 }\r
5965                         }\r
5966                         break;\r
5967                 case R_USE_KEEP_CONNECT:\r
5968                         if (IsChecked(hWnd, R_USE_KEEP_CONNECT))\r
5969                         {\r
5970                                 FocusEx(hWnd, E_HOSTNAME);\r
5971                         }\r
5972                         break;\r
5973                 case R_ALPHA:\r
5974                         if (IsChecked(hWnd, R_ALPHA))\r
5975                         {\r
5976                                 FocusEx(hWnd, E_ALPHA_VALUE);\r
5977                         }\r
5978                         break;\r
5979                 }\r
5980                 break;\r
5981         case WM_CLOSE:\r
5982                 EndDialog(hWnd, false);\r
5983                 break;\r
5984         }\r
5985 \r
5986         return 0;\r
5987 }\r
5988 \r
5989 // ショートカット作成\r
5990 void CmSortcut(HWND hWnd, wchar_t *account_name)\r
5991 {\r
5992         wchar_t tmp[MAX_SIZE];\r
5993         CM_ACCOUNT *a;\r
5994         wchar_t *filename;\r
5995         UCHAR key[SHA1_SIZE];\r
5996         // 引数チェック\r
5997         if (hWnd == NULL || account_name == NULL)\r
5998         {\r
5999                 return;\r
6000         }\r
6001 \r
6002         // アカウント情報を取得\r
6003         a = CmGetExistAccountObject(hWnd, account_name);\r
6004         if (a == NULL)\r
6005         {\r
6006                 return;\r
6007         }\r
6008 \r
6009         Copy(key, a->ShortcutKey, SHA1_SIZE);\r
6010 \r
6011         if (IsZero(key, SHA1_SIZE))\r
6012         {\r
6013                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_SHORTCUT_UNSUPPORTED"));\r
6014         }\r
6015         else\r
6016         {\r
6017                 // ファイル名を決定\r
6018                 UniFormat(tmp, sizeof(tmp), L"%s.lnk", account_name);\r
6019                 UniSafeFileName(tmp);\r
6020 \r
6021                 filename = SaveDlg(hWnd, _UU("CM_SHORTCUT_FILE"),\r
6022                         _UU("CM_SHORTCUT_SAVE_TITLE"), tmp, L".uvpn");\r
6023 \r
6024                 if (filename != NULL)\r
6025                 {\r
6026                         char key_str[64];\r
6027                         wchar_t target[MAX_PATH];\r
6028                         wchar_t workdir[MAX_PATH];\r
6029                         wchar_t args[MAX_PATH];\r
6030                         wchar_t comment[MAX_SIZE];\r
6031                         wchar_t icon[MAX_PATH];\r
6032 \r
6033                         BinToStr(key_str, sizeof(key_str), key, SHA1_SIZE);\r
6034 \r
6035                         // ショートカットを作成\r
6036                         UniStrCpy(target, sizeof(target), MsGetExeFileNameW());\r
6037                         UniStrCpy(workdir, sizeof(workdir), MsGetExeDirNameW());\r
6038                         StrToUni(args, sizeof(args), key_str);\r
6039                         UniFormat(comment, sizeof(comment), _UU("CM_SHORTCUT_COMMENT"), account_name);\r
6040                         UniStrCpy(icon, sizeof(icon), MsGetExeFileNameW());\r
6041 \r
6042                         if (CreateLink(tmp, target, workdir, args, comment, icon, 1) == false)\r
6043                         {\r
6044                                 MsgBox(hWnd, MB_ICONSTOP, _UU("CM_SHORTCUT_ERROR"));\r
6045                         }\r
6046 \r
6047                         Free(filename);\r
6048                 }\r
6049         }\r
6050 \r
6051         CmFreeAccountObject(hWnd, a);\r
6052 }\r
6053 \r
6054 // アカウントのエクスポート\r
6055 void CmExportAccount(HWND hWnd, wchar_t *account_name)\r
6056 {\r
6057         wchar_t tmp[MAX_SIZE];\r
6058         CM_ACCOUNT *a;\r
6059         wchar_t *filename;\r
6060         // 引数チェック\r
6061         if (hWnd == NULL || account_name == NULL)\r
6062         {\r
6063                 return;\r
6064         }\r
6065 \r
6066         // アカウント情報を取得\r
6067         a = CmGetExistAccountObject(hWnd, account_name);\r
6068         if (a == NULL)\r
6069         {\r
6070                 return;\r
6071         }\r
6072 \r
6073         // ファイル名を決定\r
6074         UniFormat(tmp, sizeof(tmp), L"%s.uvpn", account_name);\r
6075         UniSafeFileName(tmp);\r
6076 \r
6077         filename = SaveDlg(hWnd, _UU("CM_ACCOUNT_SETTING_FILE"),\r
6078                 _UU("CM_ACCOUNT_SAVE_TITLE"), tmp, L".uvpn");\r
6079 \r
6080         if (filename != NULL)\r
6081         {\r
6082                 RPC_CLIENT_CREATE_ACCOUNT t;\r
6083                 BUF *b;\r
6084                 BUF *b2;\r
6085                 wchar_t tmp[MAX_SIZE];\r
6086                 UCHAR *buf;\r
6087                 UINT buf_size;\r
6088                 UCHAR bom[] = {0xef, 0xbb, 0xbf, };\r
6089 \r
6090                 Zero(&t, sizeof(t));\r
6091                 t.ClientOption = a->ClientOption;\r
6092                 t.ClientAuth = a->ClientAuth;\r
6093                 t.StartupAccount = a->Startup;\r
6094                 t.CheckServerCert = a->CheckServerCert;\r
6095                 t.ServerCert = a->ServerCert;\r
6096                 t.ClientOption->FromAdminPack = false;\r
6097 \r
6098                 b = CiAccountToCfg(&t);\r
6099 \r
6100                 UniStrCpy(tmp, sizeof(tmp), filename);\r
6101                 b2 = NewBuf();\r
6102 \r
6103                 WriteBuf(b2, bom, sizeof(bom));\r
6104 \r
6105                 // ヘッダ部分を付加する\r
6106                 buf_size = CalcUniToUtf8(_UU("CM_ACCOUNT_FILE_BANNER"));\r
6107                 buf = ZeroMalloc(buf_size + 32);\r
6108                 UniToUtf8(buf, buf_size, _UU("CM_ACCOUNT_FILE_BANNER"));\r
6109 \r
6110                 WriteBuf(b2, buf, StrLen((char *)buf));\r
6111                 WriteBuf(b2, b->Buf, b->Size);\r
6112                 SeekBuf(b2, 0, 0);\r
6113 \r
6114                 FreeBuf(b);\r
6115 \r
6116                 if (DumpBufW(b2, tmp) == false)\r
6117                 {\r
6118                         MsgBox(hWnd, MB_ICONSTOP, _UU("CM_FAILED_TO_SAVE_FILE"));\r
6119                 }\r
6120 \r
6121                 Free(filename);\r
6122                 FreeBuf(b2);\r
6123                 Free(buf);\r
6124         }\r
6125 \r
6126         CmFreeAccountObject(hWnd, a);\r
6127 }\r
6128 \r
6129 // アカウントのインポートメイン処理\r
6130 void CmImportAccountMain(HWND hWnd, wchar_t *filename)\r
6131 {\r
6132         CmImportAccountMainEx(hWnd, filename, false);\r
6133 }\r
6134 void CmImportAccountMainEx(HWND hWnd, wchar_t *filename, bool overwrite)\r
6135 {\r
6136         wchar_t name[MAX_SIZE];\r
6137         wchar_t tmp[MAX_SIZE];\r
6138         BUF *b;\r
6139         RPC_CLIENT_CREATE_ACCOUNT *t;\r
6140         // 引数チェック\r
6141         if (hWnd == NULL || filename == NULL)\r
6142         {\r
6143                 return;\r
6144         }\r
6145 \r
6146         UniStrCpy(tmp, sizeof(tmp), filename);\r
6147 \r
6148         b = ReadDumpW(tmp);\r
6149         if (b == NULL)\r
6150         {\r
6151                 MsgBox(hWnd, MB_ICONSTOP, _UU("CM_FAILED_TO_OPEN_FILE"));\r
6152                 return;\r
6153         }\r
6154 \r
6155         t = CiCfgToAccount(b);\r
6156         if (t == NULL)\r
6157         {\r
6158                 FreeBuf(b);\r
6159                 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("CM_ACCOUNT_PARSE_FAILED"));\r
6160                 return;\r
6161         }\r
6162 \r
6163         if (overwrite)\r
6164         {\r
6165                 // すでに同一名が存在する場合は削除する\r
6166                 if (LvSearchStr(hWnd, L_ACCOUNT, 0, t->ClientOption->AccountName) != INFINITE)\r
6167                 {\r
6168                         RPC_CLIENT_DELETE_ACCOUNT d;\r
6169                         RPC_CLIENT_GET_ACCOUNT get;\r
6170                         HWND h = cm->hEasyWnd == NULL ? hWnd : cm->hEasyWnd;\r
6171 \r
6172                         Zero(&d, sizeof(d));\r
6173                         UniStrCpy(d.AccountName, sizeof(d.AccountName), t->ClientOption->AccountName);\r
6174 \r
6175                         Zero(&get, sizeof(get));\r
6176                         UniStrCpy(get.AccountName, sizeof(get.AccountName), t->ClientOption->AccountName);\r
6177                         if (CcGetAccount(cm->Client, &get) == ERR_NO_ERROR)\r
6178                         {\r
6179                                 // すでに存在する同一名のアカウント情報を取得して\r
6180                                 // クライアントオプションのうちいくつかの情報を継承する\r
6181                                 if (get.ClientOption != NULL && get.ClientAuth != NULL)\r
6182                                 {\r
6183                                         CLIENT_OPTION *old_option = get.ClientOption;\r
6184                                         CLIENT_AUTH *old_auth = get.ClientAuth;\r
6185 \r
6186                                         // 接続パラメータの継承\r
6187                                         t->ClientOption->ProxyType = old_option->ProxyType;\r
6188                                         StrCpy(t->ClientOption->ProxyName, sizeof(t->ClientOption->ProxyName),\r
6189                                                 old_option->ProxyName);\r
6190                                         t->ClientOption->ProxyPort = old_option->ProxyPort;\r
6191                                         StrCpy(t->ClientOption->ProxyUsername, sizeof(t->ClientOption->ProxyUsername),\r
6192                                                 old_option->ProxyUsername);\r
6193                                         StrCpy(t->ClientOption->ProxyPassword, sizeof(t->ClientOption->ProxyPassword),\r
6194                                                 old_option->ProxyPassword);\r
6195                                         t->ClientOption->NumRetry = old_option->NumRetry;\r
6196                                         t->ClientOption->RetryInterval = old_option->RetryInterval;\r
6197                                         t->ClientOption->MaxConnection = old_option->MaxConnection;\r
6198                                         t->ClientOption->UseEncrypt = old_option->UseEncrypt;\r
6199                                         t->ClientOption->UseCompress = old_option->UseCompress;\r
6200                                         t->ClientOption->HalfConnection = old_option->HalfConnection;\r
6201                                         t->ClientOption->NoRoutingTracking = old_option->NoRoutingTracking;\r
6202                                         StrCpy(t->ClientOption->DeviceName, sizeof(t->ClientOption->DeviceName),\r
6203                                                 old_option->DeviceName);\r
6204                                         t->ClientOption->AdditionalConnectionInterval = old_option->AdditionalConnectionInterval;\r
6205                                         t->ClientOption->ConnectionDisconnectSpan = old_option->ConnectionDisconnectSpan;\r
6206                                         t->ClientOption->HideStatusWindow = old_option->HideStatusWindow;\r
6207                                         t->ClientOption->RequireMonitorMode = old_option->RequireMonitorMode;\r
6208                                         t->ClientOption->RequireBridgeRoutingMode = old_option->RequireBridgeRoutingMode;\r
6209                                         t->ClientOption->DisableQoS = old_option->DisableQoS;\r
6210                                         t->ClientOption->NoTls1 = old_option->NoTls1;\r
6211 \r
6212                                         // 認証データの継承\r
6213                                         CiFreeClientAuth(t->ClientAuth);\r
6214                                         t->ClientAuth = CopyClientAuth(old_auth);\r
6215 \r
6216                                         // その他の設定\r
6217                                         t->StartupAccount = get.StartupAccount;\r
6218                                         t->CheckServerCert = get.CheckServerCert;\r
6219                                         if (t->ServerCert != NULL)\r
6220                                         {\r
6221                                                 FreeX(t->ServerCert);\r
6222                                         }\r
6223                                         t->ServerCert = NULL;\r
6224                                         if (get.ServerCert != NULL)\r
6225                                         {\r
6226                                                 t->ServerCert = CloneX(get.ServerCert);\r
6227                                         }\r
6228                                         Copy(t->ShortcutKey, get.ShortcutKey, sizeof(t->ShortcutKey));\r
6229                                 }\r
6230 \r
6231                                 CiFreeClientGetAccount(&get);\r
6232                         }\r
6233 \r
6234                         if (CALL(h, CcDeleteAccount(cm->Client, &d)) == false)\r
6235                         {\r
6236                                 CiFreeClientCreateAccount(t);\r
6237                                 Free(t);\r
6238                                 return;\r
6239                         }\r
6240 \r
6241                         CmRefreshAccountList(hWnd);\r
6242                 }\r
6243         }\r
6244 \r
6245         CmGenerateImportName(hWnd, name, sizeof(name), t->ClientOption->AccountName);\r
6246         UniStrCpy(t->ClientOption->AccountName, sizeof(t->ClientOption->AccountName), name);\r
6247 \r
6248         if (overwrite)\r
6249         {\r
6250                 t->ClientOption->FromAdminPack = true;\r
6251         }\r
6252 \r
6253         CALL(hWnd, CcCreateAccount(cm->Client, t));\r
6254 \r
6255         CiFreeClientCreateAccount(t);\r
6256         Free(t);\r
6257 \r
6258         FreeBuf(b);\r
6259 \r
6260         if (overwrite)\r
6261         {\r
6262                 // VPN 接続を開始する\r
6263                 CmConnect(hWnd, name);\r
6264         }\r
6265 \r
6266         //MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_IMPORT_MESSAGE"), filename, name);\r
6267 }\r
6268 \r
6269 // アカウントのインポート\r
6270 void CmImportAccount(HWND hWnd)\r
6271 {\r
6272         wchar_t *filename;\r
6273         wchar_t tmp[MAX_SIZE];\r
6274         // 引数チェック\r
6275         if (hWnd == NULL)\r
6276         {\r
6277                 return;\r
6278         }\r
6279 \r
6280         // ファイルを開く\r
6281         filename = OpenDlg(hWnd, _UU("CM_ACCOUNT_SETTING_FILE"), _UU("CM_ACCOUNT_OPEN_TITLE"));\r
6282         if (filename == NULL)\r
6283         {\r
6284                 return;\r
6285         }\r
6286 \r
6287         UniStrCpy(tmp, sizeof(tmp), filename);\r
6288         Free(filename);\r
6289 \r
6290         CmImportAccountMain(hWnd, tmp);\r
6291 }\r
6292 \r
6293 // アカウントのコピーの作成\r
6294 void CmCopyAccount(HWND hWnd, wchar_t *account_name)\r
6295 {\r
6296         wchar_t tmp[MAX_SIZE];\r
6297         CM_ACCOUNT *a;\r
6298         RPC_CLIENT_CREATE_ACCOUNT c;\r
6299         // 引数チェック\r
6300         if (hWnd == NULL || account_name == NULL)\r
6301         {\r
6302                 return;\r
6303         }\r
6304 \r
6305         CmGenerateCopyName(hWnd, tmp, sizeof(tmp), account_name);\r
6306 \r
6307         // アカウント情報を取得\r
6308         a = CmGetExistAccountObject(hWnd, account_name);\r
6309         if (a == NULL)\r
6310         {\r
6311                 return;\r
6312         }\r
6313 \r
6314         // アカウント名を変更\r
6315         UniStrCpy(a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName), tmp);\r
6316 \r
6317         // 書き込み\r
6318         Zero(&c, sizeof(c));\r
6319         c.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));\r
6320         Copy(c.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));\r
6321         c.ClientAuth = CopyClientAuth(a->ClientAuth);\r
6322         if (a->ServerCert)\r
6323         {\r
6324                 c.ServerCert = CloneX(a->ServerCert);\r
6325         }\r
6326         c.CheckServerCert = a->CheckServerCert;\r
6327         c.StartupAccount = false;               // スタートアップ属性はコピーしない\r
6328 \r
6329         CALL(hWnd, CcCreateAccount(cm->Client, &c));\r
6330         CiFreeClientCreateAccount(&c);\r
6331 \r
6332         CmFreeAccountObject(hWnd, a);\r
6333 }\r
6334 \r
6335 // 仮想 LAN カード名ダイアログ更新\r
6336 void CmNewVLanDlgUpdate(HWND hWnd)\r
6337 {\r
6338         bool ok = true;\r
6339         char tmp[MAX_SIZE];\r
6340         // 引数チェック\r
6341         if (hWnd == NULL)\r
6342         {\r
6343                 return;\r
6344         }\r
6345 \r
6346         GetTxtA(hWnd, E_NAME, tmp, sizeof(tmp));\r
6347         if (IsSafeStr(tmp) == false)\r
6348         {\r
6349                 ok = false;\r
6350         }\r
6351         Trim(tmp);\r
6352         if (StrLen(tmp) == 0)\r
6353         {\r
6354                 ok = false;\r
6355         }\r
6356 \r
6357         SetEnable(hWnd, IDOK, ok);\r
6358 }\r
6359 \r
6360 // 仮想 LAN カード名決定ダイアログプロシージャ\r
6361 UINT CmNewVLanDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
6362 {\r
6363         char *tmp = (char *)param;\r
6364         // 引数チェック\r
6365         if (hWnd == NULL)\r
6366         {\r
6367                 return 0;\r
6368         }\r
6369 \r
6370         switch (msg)\r
6371         {\r
6372         case WM_INITDIALOG:\r
6373                 LimitText(hWnd, E_NAME, cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN);\r
6374                 FormatText(hWnd, S_INFO, cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN);\r
6375                 CmNewVLanDlgUpdate(hWnd);\r
6376                 break;\r
6377 \r
6378         case WM_COMMAND:\r
6379                 switch (wParam)\r
6380                 {\r
6381                 case IDOK:\r
6382                         if (cm->Client->Win9x)\r
6383                         {\r
6384                                 // Windows 9x の場合、確認メッセージを出す\r
6385                                 if (MsgBox(hWnd, MB_ICONQUESTION | MB_OKCANCEL, _UU("CM_9X_VLAN_INSTALL")) == IDCANCEL)\r
6386                                 {\r
6387                                         break;\r
6388                                 }\r
6389                         }\r
6390                         GetTxtA(hWnd, E_NAME, tmp, (cm->Client->Win9x ? MAX_DEVICE_NAME_LEN_9X : MAX_DEVICE_NAME_LEN) + 1);\r
6391                         Trim(tmp);\r
6392                         EndDialog(hWnd, true);\r
6393                         break;\r
6394                 case IDCANCEL:\r
6395                         Close(hWnd);\r
6396                         break;\r
6397                 }\r
6398                 switch (LOWORD(wParam))\r
6399                 {\r
6400                 case E_NAME:\r
6401                         CmNewVLanDlgUpdate(hWnd);\r
6402                         break;\r
6403 \r
6404                 case R_USE_DISCONNECT:\r
6405                         if (IsChecked(hWnd, R_USE_DISCONNECT))\r
6406                         {\r
6407                                 FocusEx(hWnd, E_DISCONNECT_SPAN);\r
6408                         }\r
6409                         break;\r
6410                 }\r
6411                 break;\r
6412 \r
6413         case WM_CLOSE:\r
6414                 EndDialog(hWnd, false);\r
6415                 break;\r
6416         }\r
6417 \r
6418         return 0;\r
6419 }\r
6420 \r
6421 // 新しい仮想 LAN カード名を決定するダイアログ\r
6422 char *CmNewVLanDlg(HWND hWnd)\r
6423 {\r
6424         char tmp[MAX_DEVICE_NAME_LEN + 1];\r
6425 \r
6426         if (Dialog(hWnd, D_CM_NEW_VLAN, CmNewVLanDlgProc, tmp) == false)\r
6427         {\r
6428                 return NULL;\r
6429         }\r
6430 \r
6431         return CopyStr(tmp);\r
6432 }\r
6433 \r
6434 // 詳細設定ダイアログ更新\r
6435 void CmDetailDlgUpdate(HWND hWnd, CM_ACCOUNT *a)\r
6436 {\r
6437         bool ok = true;\r
6438         bool locked;\r
6439         // 引数チェック\r
6440         if (hWnd == NULL || a == NULL)\r
6441         {\r
6442                 return;\r
6443         }\r
6444 \r
6445         locked = a->LockMode;\r
6446 \r
6447         if (a->LinkMode || a->NatMode)\r
6448         {\r
6449                 Disable(hWnd, R_NO_ROUTING);\r
6450         }\r
6451         else\r
6452         {\r
6453                 if (cm->Client->Unix)\r
6454                 {\r
6455                         Disable(hWnd, R_NO_ROUTING);\r
6456                 }\r
6457         }\r
6458 \r
6459         SetEnable(hWnd, E_DISCONNECT_SPAN, IsChecked(hWnd, R_USE_DISCONNECT));\r
6460 \r
6461         SetEnable(hWnd, IDOK, ok);\r
6462 \r
6463         if (locked)\r
6464         {\r
6465                 Disable(hWnd, C_NUM_TCP);\r
6466                 Disable(hWnd, S_STATIC5);\r
6467                 Disable(hWnd, S_STATIC8);\r
6468                 Disable(hWnd, E_INTERVAL);\r
6469                 Disable(hWnd, S_STATIC9);\r
6470                 Disable(hWnd, E_DISCONNECT_SPAN);\r
6471                 Disable(hWnd, S_STATIC10);\r
6472                 Disable(hWnd, S_STATIC11);\r
6473                 Disable(hWnd, R_USE_DISCONNECT);\r
6474                 Disable(hWnd, R_USE_HALF_CONNECTION);\r
6475                 Disable(hWnd, R_DISABLE_QOS);\r
6476                 Disable(hWnd, R_USE_ENCRYPT);\r
6477                 Disable(hWnd, R_USE_COMPRESS);\r
6478                 Disable(hWnd, R_BRIDGE);\r
6479                 Disable(hWnd, R_MONITOR);\r
6480                 Disable(hWnd, R_NO_ROUTING);\r
6481         }\r
6482 }\r
6483 \r
6484 // 詳細設定ダイアログプロシージャ\r
6485 UINT CmDetailDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
6486 {\r
6487         CM_ACCOUNT *a = (CM_ACCOUNT *)param;\r
6488         UINT i;\r
6489         UINT num;\r
6490         wchar_t tmp[MAX_SIZE];\r
6491         // 引数チェック\r
6492         if (hWnd == NULL)\r
6493         {\r
6494                 return 0;\r
6495         }\r
6496 \r
6497         switch (msg)\r
6498         {\r
6499         case WM_INITDIALOG:\r
6500                 // TCP コネクション本数\r
6501                 for (i = 1;i <= MAX_TCP_CONNECTION;i++)\r
6502                 {\r
6503                         UniFormat(tmp, sizeof(tmp), L"%u", i);\r
6504                         CbAddStr(hWnd, C_NUM_TCP, tmp, i);\r
6505                 }\r
6506                 CbSelect(hWnd, C_NUM_TCP, a->ClientOption->MaxConnection);\r
6507 \r
6508                 // コネクション確立間隔\r
6509                 SetInt(hWnd, E_INTERVAL, a->ClientOption->AdditionalConnectionInterval);\r
6510 \r
6511                 // 寿命\r
6512                 SetIntEx(hWnd, E_DISCONNECT_SPAN, a->ClientOption->ConnectionDisconnectSpan);\r
6513                 Check(hWnd, R_USE_DISCONNECT, a->ClientOption->ConnectionDisconnectSpan != 0);\r
6514                 Check(hWnd, R_USE_HALF_CONNECTION, a->ClientOption->HalfConnection);\r
6515                 Check(hWnd, R_USE_ENCRYPT, a->ClientOption->UseEncrypt);\r
6516                 Check(hWnd, R_USE_COMPRESS, a->ClientOption->UseCompress);\r
6517                 Check(hWnd, R_NO_ROUTING, a->ClientOption->NoRoutingTracking);\r
6518                 Check(hWnd, R_DISABLE_QOS, a->ClientOption->DisableQoS);\r
6519 \r
6520                 // 接続モードの選択\r
6521                 if (a->LinkMode == false)\r
6522                 {\r
6523                         Check(hWnd, R_BRIDGE, a->ClientOption->RequireBridgeRoutingMode);\r
6524                         Check(hWnd, R_MONITOR, a->ClientOption->RequireMonitorMode);\r
6525                 }\r
6526                 else\r
6527                 {\r
6528                         Check(hWnd, R_BRIDGE, true);\r
6529                         Check(hWnd, R_MONITOR, false);\r
6530 \r
6531                         SetText(hWnd, S_MODE, _UU("CM_DETAIL_MODE_LINK_STR"));\r
6532                         Disable(hWnd, R_BRIDGE);\r
6533                         Disable(hWnd, R_MONITOR);\r
6534                 }\r
6535 \r
6536                 CmDetailDlgUpdate(hWnd, a);\r
6537                 Focus(hWnd, IDOK);\r
6538                 break;\r
6539         case WM_COMMAND:\r
6540                 switch (wParam)\r
6541                 {\r
6542                 case IDOK:\r
6543                         if (IsChecked(hWnd, R_USE_DISCONNECT) && GetInt(hWnd, E_DISCONNECT_SPAN) == 0)\r
6544                         {\r
6545                                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_NO_DISCONNECT_SPAN"));\r
6546                                 FocusEx(hWnd, E_DISCONNECT_SPAN);\r
6547                                 break;\r
6548                         }\r
6549                         num = GetInt(hWnd, C_NUM_TCP);\r
6550                         if (num == 0)\r
6551                         {\r
6552                                 break;\r
6553                         }\r
6554                         if (num == 1 && IsChecked(hWnd, R_USE_HALF_CONNECTION))\r
6555                         {\r
6556                                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_HALF_MSG"));\r
6557                                 Focus(hWnd, C_NUM_TCP);\r
6558                                 break;\r
6559                         }\r
6560                         if (GetInt(hWnd, E_INTERVAL) < 1)\r
6561                         {\r
6562                                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_TOO_SMALL_INTERVAL"));\r
6563                                 Focus(hWnd, E_INTERVAL);\r
6564                                 break;\r
6565                         }\r
6566 \r
6567                         a->ClientOption->MaxConnection = num;\r
6568                         a->ClientOption->AdditionalConnectionInterval = GetInt(hWnd, E_INTERVAL);\r
6569                         if (IsChecked(hWnd, R_USE_DISCONNECT) == false)\r
6570                         {\r
6571                                 a->ClientOption->ConnectionDisconnectSpan = 0;\r
6572                         }\r
6573                         else\r
6574                         {\r
6575                                 a->ClientOption->ConnectionDisconnectSpan = GetInt(hWnd, E_DISCONNECT_SPAN);\r
6576                         }\r
6577                         a->ClientOption->HalfConnection = IsChecked(hWnd, R_USE_HALF_CONNECTION);\r
6578                         a->ClientOption->UseEncrypt = IsChecked(hWnd, R_USE_ENCRYPT);\r
6579                         a->ClientOption->UseCompress = IsChecked(hWnd, R_USE_COMPRESS);\r
6580                         a->ClientOption->NoRoutingTracking = IsChecked(hWnd, R_NO_ROUTING);\r
6581                         a->ClientOption->DisableQoS = IsChecked(hWnd, R_DISABLE_QOS);\r
6582 \r
6583                         if (a->LinkMode)\r
6584                         {\r
6585                                 a->ClientOption->RequireBridgeRoutingMode = true;\r
6586                                 a->ClientOption->RequireMonitorMode = false;\r
6587                         }\r
6588                         else\r
6589                         {\r
6590                                 a->ClientOption->RequireBridgeRoutingMode = IsChecked(hWnd, R_BRIDGE);\r
6591                                 a->ClientOption->RequireMonitorMode = IsChecked(hWnd, R_MONITOR);\r
6592                         }\r
6593 \r
6594                         EndDialog(hWnd, true);\r
6595 \r
6596                         break;\r
6597                 case IDCANCEL:\r
6598                         Close(hWnd);\r
6599                         break;\r
6600                 }\r
6601                 switch (LOWORD(wParam))\r
6602                 {\r
6603                 case C_NUM_TCP:\r
6604                 case E_INTERVAL:\r
6605                 case E_DISCONNECT_SPAN:\r
6606                 case R_USE_DISCONNECT:\r
6607                 case R_USE_HALF_CONNECTION:\r
6608                         CmDetailDlgUpdate(hWnd, a);\r
6609                         break;\r
6610                 }\r
6611                 break;\r
6612         case WM_CLOSE:\r
6613                 EndDialog(hWnd, false);\r
6614                 break;\r
6615         }\r
6616 \r
6617         return 0;\r
6618 }\r
6619 \r
6620 // 詳細設定ダイアログ\r
6621 bool CmDetailDlg(HWND hWnd, CM_ACCOUNT *a)\r
6622 {\r
6623         // 引数チェック\r
6624         if (hWnd == NULL || a == NULL)\r
6625         {\r
6626                 return false;\r
6627         }\r
6628 \r
6629         return Dialog(hWnd, D_CM_DETAIL, CmDetailDlgProc, a);\r
6630 }\r
6631 \r
6632 // アカウント編集ダイアログプロシージャ更新\r
6633 void CmEditAccountDlgUpdate(HWND hWnd, CM_ACCOUNT *a)\r
6634 {\r
6635         bool ok = true;\r
6636         char str[MAX_SIZE];\r
6637         bool locked;\r
6638         // 引数チェック\r
6639         if (hWnd == NULL || a == NULL)\r
6640         {\r
6641                 return;\r
6642         }\r
6643 \r
6644         locked = a->LockMode;\r
6645 \r
6646         if (a->Inited == false)\r
6647         {\r
6648                 return;\r
6649         }\r
6650 \r
6651         if (a->EditMode)\r
6652         {\r
6653                 Disable(hWnd, E_ACCOUNT_NAME);\r
6654         }\r
6655 \r
6656         // 接続設定名\r
6657         GetTxt(hWnd, E_ACCOUNT_NAME, a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName));\r
6658         UniTrim(a->ClientOption->AccountName);\r
6659 \r
6660         // ホスト名\r
6661         GetTxtA(hWnd, E_HOSTNAME, a->ClientOption->Hostname, sizeof(a->ClientOption->Hostname));\r
6662         Trim(a->ClientOption->Hostname);\r
6663 \r
6664         // ポート番号\r
6665         a->ClientOption->Port = GetInt(hWnd, C_PORT);\r
6666 \r
6667         // HUB 名\r
6668         GetTxtA(hWnd,C_HUBNAME, a->ClientOption->HubName, sizeof(a->ClientOption->HubName));\r
6669 \r
6670         // プロキシの種類\r
6671         a->ClientOption->ProxyType = PROXY_DIRECT;\r
6672         if (IsChecked(hWnd, R_HTTPS))\r
6673         {\r
6674                 a->ClientOption->ProxyType = PROXY_HTTP;\r
6675         }\r
6676         if (IsChecked(hWnd, R_SOCKS))\r
6677         {\r
6678                 a->ClientOption->ProxyType = PROXY_SOCKS;\r
6679         }\r
6680 \r
6681         // サーバー証明書検証\r
6682         a->CheckServerCert = IsChecked(hWnd, R_CHECK_CERT);\r
6683 \r
6684         if (a->NatMode)\r
6685         {\r
6686                 Disable(hWnd, R_CHECK_CERT);\r
6687                 Disable(hWnd, B_TRUST);\r
6688         }\r
6689 \r
6690         if (a->HideTrustCert)\r
6691         {\r
6692                 Disable(hWnd, B_TRUST);\r
6693         }\r
6694 \r
6695         // デバイス名\r
6696         StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName), "");\r
6697         if (LvIsSelected(hWnd, L_VLAN))\r
6698         {\r
6699                 wchar_t *s = LvGetStr(hWnd, L_VLAN, LvGetSelected(hWnd, L_VLAN), 0);\r
6700                 if (s != NULL)\r
6701                 {\r
6702                         char str[MAX_SIZE];\r
6703                         UniToStr(str, sizeof(str), s);\r
6704                         CmPrintNameToVLanName(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName), str);\r
6705                         Free(s);\r
6706                 }\r
6707         }\r
6708 \r
6709         // ユーザー認証\r
6710         a->ClientAuth->AuthType = CbGetSelect(hWnd, C_TYPE);\r
6711         GetTxtA(hWnd, E_USERNAME, a->ClientAuth->Username, sizeof(a->ClientAuth->Username));\r
6712         Trim(a->ClientAuth->Username);\r
6713         switch (a->ClientAuth->AuthType)\r
6714         {\r
6715         case CLIENT_AUTHTYPE_PASSWORD:\r
6716                 // パスワード認証\r
6717                 GetTxtA(hWnd, E_PASSWORD, str, sizeof(str));\r
6718                 if (StrCmp(str, HIDDEN_PASSWORD) != 0)\r
6719                 {\r
6720                         HashPassword(a->ClientAuth->HashedPassword, a->ClientAuth->Username, str);\r
6721                 }\r
6722                 break;\r
6723         case CLIENT_AUTHTYPE_PLAIN_PASSWORD:\r
6724                 // 平文パスワード認証\r
6725                 GetTxtA(hWnd, E_PASSWORD, str, sizeof(str));\r
6726                 if (StrCmp(str, HIDDEN_PASSWORD) != 0)\r
6727                 {\r
6728                         StrCpy(a->ClientAuth->PlainPassword, sizeof(a->ClientAuth->PlainPassword), str);\r
6729                 }\r
6730                 break;\r
6731         }\r
6732 \r
6733         // 再接続オプション\r
6734         if ((a->LinkMode || a->NatMode) || a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)\r
6735         {\r
6736                 Disable(hWnd, R_RETRY);\r
6737         }\r
6738         else\r
6739         {\r
6740                 Enable(hWnd, R_RETRY);\r
6741         }\r
6742 \r
6743         if (IsChecked(hWnd, R_RETRY) == false)\r
6744         {\r
6745                 a->ClientOption->NumRetry = 0;\r
6746         }\r
6747         else\r
6748         {\r
6749                 if (IsChecked(hWnd, R_INFINITE))\r
6750                 {\r
6751                         a->ClientOption->NumRetry = INFINITE;\r
6752                 }\r
6753                 else\r
6754                 {\r
6755                         a->ClientOption->NumRetry = GetInt(hWnd, E_RETRY_NUM);\r
6756                 }\r
6757         }\r
6758         a->ClientOption->RetryInterval = GetInt(hWnd, E_RETRY_SPAN);\r
6759 \r
6760         a->ClientOption->NoTls1 = IsChecked(hWnd, R_NOTLS1);\r
6761 \r
6762         // 情報判定\r
6763         if (UniStrLen(a->ClientOption->AccountName) == 0 && a->NatMode == false)\r
6764         {\r
6765                 ok = false;\r
6766         }\r
6767         if (StrLen(a->ClientOption->Hostname) == 0)\r
6768         {\r
6769                 ok = false;\r
6770         }\r
6771         if (a->ClientOption->Port == 0 || a->ClientOption->Port >= 65536)\r
6772         {\r
6773                 ok = false;\r
6774         }\r
6775         if (StrLen(a->ClientOption->HubName) == 0)\r
6776         {\r
6777                 ok = false;\r
6778         }\r
6779         if (StrLen(a->ClientAuth->Username) == 0)\r
6780         {\r
6781                 ok = false;\r
6782         }\r
6783         if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)\r
6784         {\r
6785                 if (a->ClientAuth->ClientK == NULL || a->ClientAuth->ClientX == NULL)\r
6786                 {\r
6787                         ok = false;\r
6788                 }\r
6789         }\r
6790         if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)\r
6791         {\r
6792                 if (IsEmptyStr(a->ClientAuth->SecurePrivateKeyName) || IsEmptyStr(a->ClientAuth->SecurePublicCertName))\r
6793                 {\r
6794                         ok = false;\r
6795                 }\r
6796         }\r
6797 \r
6798         // 表示更新\r
6799         if (IsChecked(hWnd, R_RETRY) && IsEnable(hWnd, R_RETRY))\r
6800         {\r
6801                 if (a->LinkMode == false && a->NatMode == false)\r
6802                 {\r
6803                         Enable(hWnd, R_INFINITE);\r
6804                         Enable(hWnd, E_RETRY_SPAN);\r
6805                         Enable(hWnd, S_RETRY_SPAN_1);\r
6806                         Enable(hWnd, S_RETRY_SPAN_2);\r
6807                 }\r
6808                 else\r
6809                 {\r
6810                         Disable(hWnd, R_INFINITE);\r
6811                         Disable(hWnd, E_RETRY_SPAN);\r
6812                         Disable(hWnd, S_RETRY_SPAN_1);\r
6813                         Disable(hWnd, S_RETRY_SPAN_2);\r
6814                 }\r
6815                 if (IsChecked(hWnd, R_INFINITE) == false)\r
6816                 {\r
6817                         Enable(hWnd, E_RETRY_NUM);\r
6818                         Enable(hWnd, S_RETRY_NUM_1);\r
6819                         Enable(hWnd, S_RETRY_NUM_2);\r
6820                         if (GetInt(hWnd, E_RETRY_NUM) == 0)\r
6821                         {\r
6822                                 ok = false;\r
6823                         }\r
6824                 }\r
6825                 else\r
6826                 {\r
6827                         Disable(hWnd, E_RETRY_NUM);\r
6828                         Disable(hWnd, S_RETRY_NUM_1);\r
6829                         Disable(hWnd, S_RETRY_NUM_2);\r
6830                 }\r
6831         }\r
6832         else\r
6833         {\r
6834                 Disable(hWnd, E_RETRY_NUM);\r
6835                 Disable(hWnd, E_RETRY_SPAN);\r
6836                 Disable(hWnd, R_INFINITE);\r
6837                 Disable(hWnd, S_RETRY_NUM_1);\r
6838                 Disable(hWnd, S_RETRY_NUM_2);\r
6839                 Disable(hWnd, S_RETRY_SPAN_1);\r
6840                 Disable(hWnd, S_RETRY_SPAN_2);\r
6841         }\r
6842 \r
6843         if (a->NatMode == false)\r
6844         {\r
6845                 if (a->ServerCert == NULL)\r
6846                 {\r
6847                         SetText(hWnd, B_SERVER_CERT, _UU("CM_SERVER_CERT_1"));\r
6848                         Disable(hWnd, B_VIEW_SERVER_CERT);\r
6849                 }\r
6850                 else\r
6851                 {\r
6852                         SetText(hWnd, B_SERVER_CERT, _UU("CM_SERVER_CERT_2"));\r
6853                         Enable(hWnd, B_VIEW_SERVER_CERT);\r
6854                 }\r
6855         }\r
6856         else\r
6857         {\r
6858                 Disable(hWnd, B_VIEW_SERVER_CERT);\r
6859                 Disable(hWnd, B_SERVER_CERT);\r
6860         }\r
6861 \r
6862         if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT || a->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)\r
6863         {\r
6864                 wchar_t tmp[MAX_SIZE * 2];\r
6865                 wchar_t issuer[MAX_SIZE];\r
6866                 wchar_t subject[MAX_SIZE];\r
6867                 wchar_t expires[MAX_SIZE];\r
6868 \r
6869                 SetIcon(hWnd, S_CERT, (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT) ? ICO_CERT : ICO_SECURE);\r
6870 \r
6871                 Hide(hWnd, S_PASSWORD);\r
6872                 Hide(hWnd, E_PASSWORD);\r
6873                 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)\r
6874                 {\r
6875                         if (a->ClientAuth->ClientX != NULL)\r
6876                         {\r
6877                                 Enable(hWnd, B_VIEW_CLIENT_CERT);\r
6878                                 SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_CLIENT_CERT_2"));\r
6879                                 GetPrintNameFromName(issuer, sizeof(issuer), a->ClientAuth->ClientX->issuer_name);\r
6880                                 GetPrintNameFromName(subject, sizeof(subject), a->ClientAuth->ClientX->subject_name);\r
6881                                 GetDateStrEx64(expires, sizeof(expires), SystemToLocal64(a->ClientAuth->ClientX->notAfter), NULL);\r
6882                                 UniFormat(tmp, sizeof(tmp), _UU("CM_CERT_INFO"), subject, issuer, expires);\r
6883                         }\r
6884                         else\r
6885                         {\r
6886                                 Disable(hWnd, B_VIEW_CLIENT_CERT);\r
6887                                 SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_CLIENT_CERT_1"));\r
6888                                 UniStrCpy(tmp, sizeof(tmp), _UU("CM_NO_CERT"));\r
6889                         }\r
6890                         SetText(hWnd, B_VIEW_CLIENT_CERT, _UU("CM_VIEW_CLIENT_CERT"));\r
6891 \r
6892                         Enable(hWnd, B_REGIST_CLIENT_CERT);\r
6893                 }\r
6894                 else\r
6895                 {\r
6896                         if (IsEmptyStr(a->ClientAuth->SecurePrivateKeyName) || IsEmptyStr(a->ClientAuth->SecurePublicCertName))\r
6897                         {\r
6898                                 UniStrCpy(tmp, sizeof(tmp), _UU("CM_NO_SECURE"));\r
6899                         }\r
6900                         else\r
6901                         {\r
6902                                 UniFormat(tmp, sizeof(tmp), _UU("CM_CERT_SECURE_INFO"),\r
6903                                         a->ClientAuth->SecurePublicCertName, a->ClientAuth->SecurePrivateKeyName);\r
6904                         }\r
6905 \r
6906                         SetText(hWnd, B_VIEW_CLIENT_CERT, _UU("CM_SELECT_SECURE_DEVICE"));\r
6907                         SetText(hWnd, B_REGIST_CLIENT_CERT, _UU("CM_SELECT_CERT_INCARD"));\r
6908                         Enable(hWnd, B_VIEW_CLIENT_CERT);\r
6909 \r
6910                         if (SmGetCurrentSecureIdFromReg() == 0)\r
6911                         {\r
6912                                 Disable(hWnd, B_REGIST_CLIENT_CERT);\r
6913                         }\r
6914                         else\r
6915                         {\r
6916                                 Enable(hWnd, B_REGIST_CLIENT_CERT);\r
6917                         }\r
6918                 }\r
6919                 SetText(hWnd, S_CERT_INFO, tmp);\r
6920                 Show(hWnd, S_CERT);\r
6921                 Show(hWnd, S_CERT_INFO);\r
6922                 Show(hWnd, B_VIEW_CLIENT_CERT);\r
6923                 Show(hWnd, B_REGIST_CLIENT_CERT);\r
6924         }\r
6925         else\r
6926         {\r
6927                 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_ANONYMOUS)\r
6928                 {\r
6929                         Hide(hWnd, S_PASSWORD);\r
6930                         Hide(hWnd, E_PASSWORD);\r
6931                 }\r
6932                 else\r
6933                 {\r
6934                         Show(hWnd, S_PASSWORD);\r
6935                         Show(hWnd, E_PASSWORD);\r
6936                 }\r
6937                 Hide(hWnd, S_CERT);\r
6938                 Hide(hWnd, S_CERT_INFO);\r
6939                 Hide(hWnd, B_VIEW_CLIENT_CERT);\r
6940                 Hide(hWnd, B_REGIST_CLIENT_CERT);\r
6941         }\r
6942 \r
6943         if (a->ClientOption->ProxyType != PROXY_DIRECT)\r
6944         {\r
6945                 Enable(hWnd, B_PROXY_CONFIG);\r
6946                 if (StrLen(a->ClientOption->ProxyName) == 0)\r
6947                 {\r
6948                         ok = false;\r
6949                 }\r
6950                 if (a->ClientOption->ProxyPort == 0)\r
6951                 {\r
6952                         ok = false;\r
6953                 }\r
6954         }\r
6955         else\r
6956         {\r
6957                 Disable(hWnd, B_PROXY_CONFIG);\r
6958         }\r
6959 \r
6960         if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PASSWORD)\r
6961         {\r
6962                 bool b = true;\r
6963 \r
6964                 if (ok == false)\r
6965                 {\r
6966                         b = false;\r
6967                 }\r
6968 \r
6969                 if (a->LinkMode == false && a->NatMode == false)\r
6970                 {\r
6971                         SetEnable(hWnd, B_CHANGE_PASSWORD, b);\r
6972                         SetEnable(hWnd, S_CHANGE_PASSWORD, b);\r
6973                         Show(hWnd, B_CHANGE_PASSWORD);\r
6974                         Show(hWnd, S_CHANGE_PASSWORD);\r
6975                 }\r
6976                 else\r
6977                 {\r
6978                         Hide(hWnd, B_CHANGE_PASSWORD);\r
6979                         Hide(hWnd, S_CHANGE_PASSWORD);\r
6980                 }\r
6981         }\r
6982         else\r
6983         {\r
6984                 Hide(hWnd, B_CHANGE_PASSWORD);\r
6985                 Hide(hWnd, S_CHANGE_PASSWORD);\r
6986         }\r
6987 \r
6988         if ((StrLen(a->ClientOption->DeviceName) == 0) && (a->LinkMode == false && a->NatMode == false))\r
6989         {\r
6990                 ok = false;\r
6991         }\r
6992 \r
6993         if (a->LinkMode || a->NatMode)\r
6994         {\r
6995                 Disable(hWnd, L_VLAN);\r
6996         }\r
6997 \r
6998         if (a->EditMode == false)\r
6999         {\r
7000                 char tmp[MAX_SIZE];\r
7001                 GetTxtA(hWnd, E_HOSTNAME, tmp, sizeof(tmp));\r
7002                 Trim(tmp);\r
7003 \r
7004                 if (StartWith(tmp, "127.") || (StrCmpi(tmp, "localhost") == 0))\r
7005                 {\r
7006                         if (a->Flag1 == false)\r
7007                         {\r
7008                                 a->Flag1 = true;\r
7009                                 a->ClientOption->UseEncrypt = a->ClientOption->UseCompress = false;\r
7010                                 a->ClientOption->MaxConnection = 1;\r
7011                         }\r
7012                 }\r
7013         }\r
7014 \r
7015         a->ClientOption->HideStatusWindow = IsChecked(hWnd, R_HIDE);\r
7016         a->ClientOption->HideNicInfoWindow = IsChecked(hWnd, R_HIDE2);\r
7017 \r
7018         if (locked)\r
7019         {\r
7020                 SetEnable(hWnd, E_HOSTNAME, false);\r
7021                 SetEnable(hWnd, C_PORT, false);\r
7022                 SetEnable(hWnd, C_HUBNAME, false);\r
7023                 SetEnable(hWnd, S_STATIC2, false);\r
7024                 SetEnable(hWnd, S_STATIC3, false);\r
7025                 SetEnable(hWnd, S_STATIC4, false);\r
7026                 SetEnable(hWnd, S_STATIC5, false);\r
7027                 SetEnable(hWnd, S_STATIC66, false);\r
7028                 SetEnable(hWnd, S_STATIC7, false);\r
7029                 SetEnable(hWnd, S_STATIC11, false);\r
7030                 SetEnable(hWnd, R_CHECK_CERT, false);\r
7031                 SetEnable(hWnd, B_TRUST, false);\r
7032                 SetEnable(hWnd, B_SERVER_CERT, false);\r
7033                 SetEnable(hWnd, B_VIEW_SERVER_CERT, false);\r
7034                 SetEnable(hWnd, R_RETRY, false);\r
7035                 SetEnable(hWnd, S_RETRY_NUM_1, false);\r
7036                 SetEnable(hWnd, E_RETRY_NUM, false);\r
7037                 SetEnable(hWnd, S_RETRY_NUM_2, false);\r
7038                 SetEnable(hWnd, S_RETRY_SPAN_1, false);\r
7039                 SetEnable(hWnd, E_RETRY_SPAN, false);\r
7040                 SetEnable(hWnd, S_RETRY_SPAN_2, false);\r
7041                 SetEnable(hWnd, R_INFINITE, false);\r
7042         }\r
7043 \r
7044         SetEnable(hWnd, IDOK, ok);\r
7045 }\r
7046 \r
7047 // アカウント編集ダイアログ初期化\r
7048 void CmEditAccountDlgInit(HWND hWnd, CM_ACCOUNT *a)\r
7049 {\r
7050         RPC_CLIENT_ENUM_VLAN v;\r
7051         UINT i;\r
7052         // 引数チェック\r
7053         if (hWnd == NULL || a == NULL)\r
7054         {\r
7055                 return;\r
7056         }\r
7057 \r
7058         if (a->LockMode)\r
7059         {\r
7060                 SetText(hWnd, S_STATIC1, _UU("CM_EASY_ACCOUNT_WARNING"));\r
7061         }\r
7062 \r
7063         // 接続設定名\r
7064         if (a->EditMode || a->NatMode)\r
7065         {\r
7066                 Disable(hWnd, E_ACCOUNT_NAME);\r
7067         }\r
7068 \r
7069         if (a->NatMode || a->LinkMode)\r
7070         {\r
7071                 Hide(hWnd, R_HIDE);\r
7072                 Hide(hWnd, R_HIDE2);\r
7073         }\r
7074 \r
7075         Check(hWnd, R_HIDE, a->ClientOption->HideStatusWindow);\r
7076         Check(hWnd, R_HIDE2, a->ClientOption->HideNicInfoWindow);\r
7077 \r
7078         if (a->NatMode)\r
7079         {\r
7080                 Hide(hWnd, E_ACCOUNT_NAME);\r
7081                 Hide(hWnd, S_ACCOUNT_NAME);\r
7082         }\r
7083 \r
7084         if ((cm != NULL && cm->server_name != NULL) || a->LinkMode)\r
7085         {\r
7086                 Hide(hWnd, B_IE);\r
7087         }\r
7088 \r
7089         SetText(hWnd, E_ACCOUNT_NAME, a->ClientOption->AccountName);\r
7090 \r
7091         // ホスト名\r
7092         SetTextA(hWnd, E_HOSTNAME, a->ClientOption->Hostname);\r
7093         StrCpy(a->old_server_name, sizeof(a->old_server_name), a->ClientOption->Hostname);\r
7094 \r
7095         // ポート番号\r
7096         CbSetHeight(hWnd, C_PORT, 18);\r
7097         CbAddStr(hWnd, C_PORT, _UU("CM_PORT_4"), 0);\r
7098         CbAddStr(hWnd, C_PORT, _UU("CM_PORT_1"), 0);\r
7099         CbAddStr(hWnd, C_PORT, _UU("CM_PORT_2"), 0);\r
7100         CbAddStr(hWnd, C_PORT, _UU("CM_PORT_3"), 0);\r
7101         SetInt(hWnd, C_PORT, a->ClientOption->Port);\r
7102 \r
7103         // 仮想 HUB 名\r
7104         CbSetHeight(hWnd, C_HUBNAME, 18);\r
7105         SetTextA(hWnd, C_HUBNAME, a->ClientOption->HubName);\r
7106 \r
7107         // プロキシの種類\r
7108         Check(hWnd, R_DIRECT_TCP, a->ClientOption->ProxyType == PROXY_DIRECT);\r
7109         Check(hWnd, R_HTTPS, a->ClientOption->ProxyType == PROXY_HTTP);\r
7110         Check(hWnd, R_SOCKS, a->ClientOption->ProxyType == PROXY_SOCKS);\r
7111 \r
7112         // サーバー証明書の検証\r
7113         Check(hWnd, R_CHECK_CERT, a->CheckServerCert);\r
7114 \r
7115         // LAN カード一覧\r
7116         if (a->NatMode == false && a->LinkMode == false)\r
7117         {\r
7118                 Zero(&v, sizeof(v));\r
7119                 CcEnumVLan(cm->Client, &v);\r
7120                 LvInit(hWnd, L_VLAN);\r
7121                 LvInsertColumn(hWnd, L_VLAN, 0, L"DeviceName", 345);\r
7122                 for (i = 0;i < v.NumItem;i++)\r
7123                 {\r
7124                         wchar_t tmp[MAX_SIZE];\r
7125                         char str[MAX_SIZE];\r
7126                         CmVLanNameToPrintName(str, sizeof(str), v.Items[i]->DeviceName);\r
7127                         StrToUni(tmp, sizeof(tmp), str);\r
7128                         LvInsert(hWnd, L_VLAN, ICO_NIC_ONLINE, NULL, 1, tmp);\r
7129                 }\r
7130 //              LvAutoSize(hWnd, L_VLAN);\r
7131 \r
7132                 if (v.NumItem == 1)\r
7133                 {\r
7134                         // 仮想 LAN カードが 1 枚だけのときはそれを最初から選択する\r
7135                         LvSelect(hWnd, L_VLAN, 0);\r
7136                 }\r
7137 \r
7138                 CiFreeClientEnumVLan(&v);\r
7139         }\r
7140 \r
7141         // LAN カードを選択する\r
7142         if (StrLen(a->ClientOption->DeviceName) != 0)\r
7143         {\r
7144                 char str[MAX_SIZE];\r
7145                 wchar_t tmp[MAX_SIZE];\r
7146                 UINT index;\r
7147                 CmVLanNameToPrintName(str, sizeof(str), a->ClientOption->DeviceName);\r
7148                 StrToUni(tmp, sizeof(tmp), str);\r
7149                 index = LvSearchStr(hWnd, L_VLAN, 0, tmp);\r
7150                 if (index != INFINITE)\r
7151                 {\r
7152                         LvSelect(hWnd, L_VLAN, index);\r
7153                 }\r
7154         }\r
7155 \r
7156         // 認証の種類\r
7157         CbSetHeight(hWnd, C_TYPE, 18);\r
7158         CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_0"), CLIENT_AUTHTYPE_ANONYMOUS);\r
7159         CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_1"), CLIENT_AUTHTYPE_PASSWORD);\r
7160         CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_2"), CLIENT_AUTHTYPE_PLAIN_PASSWORD);\r
7161 \r
7162         if (a->HideClientCertAuth == false)\r
7163         {\r
7164                 // HideClientCertAuth が true の場合は証明書認証は利用できない\r
7165                 CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_3"), CLIENT_AUTHTYPE_CERT);\r
7166         }\r
7167 \r
7168         if (a->HideSecureAuth == false)\r
7169         {\r
7170                 // スマートカードを利用した認証\r
7171                 CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_4"), CLIENT_AUTHTYPE_SECURE);\r
7172         }\r
7173 \r
7174         // 認証の選択\r
7175         CbSelect(hWnd, C_TYPE, a->ClientAuth->AuthType);\r
7176 \r
7177         // ユーザー名\r
7178         SetTextA(hWnd, E_USERNAME, a->ClientAuth->Username);\r
7179 \r
7180         // パスワード\r
7181         if (a->EditMode)\r
7182         {\r
7183                 SetTextA(hWnd, E_PASSWORD, HIDDEN_PASSWORD);\r
7184         }\r
7185 \r
7186         // 再接続回数\r
7187         if (a->ClientOption->NumRetry == 0)\r
7188         {\r
7189                 Check(hWnd, R_RETRY, false);\r
7190         }\r
7191         else\r
7192         {\r
7193                 Check(hWnd, R_RETRY, true);\r
7194                 if (a->ClientOption->NumRetry == INFINITE)\r
7195                 {\r
7196                         Check(hWnd, R_INFINITE, true);\r
7197                 }\r
7198                 else\r
7199                 {\r
7200                         Check(hWnd, R_INFINITE, false);\r
7201                         SetInt(hWnd, E_RETRY_NUM, a->ClientOption->NumRetry);\r
7202                 }\r
7203         }\r
7204         SetIntEx(hWnd, E_RETRY_SPAN, a->ClientOption->RetryInterval);\r
7205 \r
7206         Check(hWnd, R_NOTLS1, a->ClientOption->NoTls1);\r
7207 \r
7208         // タイトル\r
7209         if (a->NatMode == false)\r
7210         {\r
7211                 if (a->EditMode == false)\r
7212                 {\r
7213                         SetText(hWnd, 0, _UU("CM_ACCOUNT_TITLE_1"));\r
7214                         FocusEx(hWnd, E_ACCOUNT_NAME);\r
7215                 }\r
7216                 else\r
7217                 {\r
7218                         SetText(hWnd, 0, _UU("CM_ACCOUNT_TITLE_2"));\r
7219                         FormatText(hWnd, 0, a->ClientOption->AccountName);\r
7220                         FocusEx(hWnd, E_HOSTNAME);\r
7221                 }\r
7222         }\r
7223         else\r
7224         {\r
7225                 SetText(hWnd, 0, _UU("NM_ACCOUNT_TITLE"));\r
7226                 FocusEx(hWnd, E_HOSTNAME);\r
7227         }\r
7228 \r
7229         if (a->LinkMode || a->NatMode)\r
7230         {\r
7231                 Hide(hWnd, L_VLAN);\r
7232 \r
7233                 if (a->NatMode == false)\r
7234                 {\r
7235                         SetText(hWnd, S_VLAN_GROUP, _UU("SM_LINK_POLICY_GROUP"));\r
7236                         Show(hWnd, S_POLICY_1);\r
7237                         Show(hWnd, S_POLICY_2);\r
7238                         Show(hWnd, B_POLICY);\r
7239                 }\r
7240                 else\r
7241                 {\r
7242                         Hide(hWnd, S_VLAN_GROUP);\r
7243                         Show(hWnd, S_ROUTER_LOGO);\r
7244                 }\r
7245         }\r
7246 \r
7247         // 表示更新\r
7248         a->Inited = true;\r
7249         CmEditAccountDlgUpdate(hWnd, a);\r
7250 }\r
7251 \r
7252 // アカウント編集ダイアログプロシージャ\r
7253 UINT CmEditAccountDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
7254 {\r
7255         CM_ACCOUNT *a = (CM_ACCOUNT *)param;\r
7256         NMHDR *n;\r
7257         X *x;\r
7258         K *k;\r
7259         // 引数チェック\r
7260         if (hWnd == NULL)\r
7261         {\r
7262                 return 0;\r
7263         }\r
7264 \r
7265         switch (msg)\r
7266         {\r
7267         case WM_INITDIALOG:\r
7268                 CmEditAccountDlgInit(hWnd, a);\r
7269                 if (a->EditMode == false && a->LinkMode == false && a->NatMode == false)\r
7270                 {\r
7271                         SetTimer(hWnd, 1, 100, NULL);\r
7272                 }\r
7273                 break;\r
7274         case WM_TIMER:\r
7275                 switch (wParam)\r
7276                 {\r
7277                 case 1:\r
7278                         {\r
7279                                 CM_INTERNET_SETTING s;\r
7280 \r
7281                                 KillTimer(hWnd, 1);\r
7282 \r
7283                                 Zero(&s, sizeof(s));\r
7284                                 CmGetSystemInternetSetting(&s);\r
7285 \r
7286                                 if (s.ProxyType != PROXY_DIRECT)\r
7287                                 {\r
7288                                         if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO,\r
7289                                                 _UU("CM_WOULDYOULOAD_IE_PROXY"),\r
7290                                                 s.ProxyHostName) == IDYES)\r
7291                                         {\r
7292                                                 Command(hWnd, B_IE);\r
7293                                         }\r
7294                                 }\r
7295                         }\r
7296                         break;\r
7297                 }\r
7298                 break;\r
7299         case WM_COMMAND:\r
7300                 switch (LOWORD(wParam))\r
7301                 {\r
7302                 case E_ACCOUNT_NAME:\r
7303                 case E_HOSTNAME:\r
7304                 case C_PORT:\r
7305                 case C_HUBNAME:\r
7306                 case R_DIRECT_TCP:\r
7307                 case R_HTTPS:\r
7308                 case R_SOCKS:\r
7309                 case R_CHECK_CERT:\r
7310                 case C_TYPE:\r
7311                 case E_USERNAME:\r
7312                 case E_PASSWORD:\r
7313                 case R_RETRY:\r
7314                 case E_RETRY_NUM:\r
7315                 case E_RETRY_SPAN:\r
7316                 case R_INFINITE:\r
7317                         CmEditAccountDlgUpdate(hWnd, a);\r
7318                         break;\r
7319                 }\r
7320                 switch (HIWORD(wParam))\r
7321                 {\r
7322                 case EN_KILLFOCUS:\r
7323                         switch (LOWORD(wParam))\r
7324                         {\r
7325                         case E_HOSTNAME:\r
7326                                 CmEditAccountDlgStartEnumHub(hWnd, a);\r
7327                                 break;\r
7328                         }\r
7329                         break;\r
7330                 case BN_KILLFOCUS:\r
7331                         switch (LOWORD(wParam))\r
7332                         {\r
7333                         case R_DIRECT_TCP:\r
7334                         case R_HTTPS:\r
7335                         case R_SOCKS:\r
7336                                 CmEditAccountDlgStartEnumHub(hWnd, a);\r
7337                                 break;\r
7338                         }\r
7339                         break;\r
7340                 case CBN_KILLFOCUS:\r
7341                         switch (LOWORD(wParam))\r
7342                         {\r
7343                         case C_PORT:\r
7344                                 CmEditAccountDlgStartEnumHub(hWnd, a);\r
7345                                 break;\r
7346                         }\r
7347                         break;\r
7348                 }\r
7349                 if (HIWORD(wParam) == 0)\r
7350                 {\r
7351                         CmEditAccountDlgUpdate(hWnd, a);\r
7352                 }\r
7353                 switch (wParam)\r
7354                 {\r
7355                 case B_POLICY:\r
7356                         // ポリシー\r
7357                         if (a->LinkMode || a->NatMode)\r
7358                         {\r
7359                                 a->Policy.Access = true;\r
7360                                 a->Policy.MonitorPort = false;\r
7361                                 SmPolicyDlgEx2(hWnd, &a->Policy, _UU("SM_LINK_POLICY_CAPTION"), true, a->PolicyVer);\r
7362                                 a->Policy.Access = true;\r
7363                                 a->Policy.MonitorPort = false;\r
7364                         }\r
7365                         break;\r
7366                 case IDOK:\r
7367                         CmEditAccountDlgUpdate(hWnd, a);\r
7368                         CmEditAccountDlgOnOk(hWnd, a);\r
7369                         break;\r
7370                 case IDCANCEL:\r
7371                         Close(hWnd);\r
7372                         break;\r
7373                 case B_PROXY_CONFIG:\r
7374                         // プロキシ設定\r
7375                         if (CmProxyDlg(hWnd, a->ClientOption))\r
7376                         {\r
7377                                 UINT n = GetInt(hWnd, C_PORT);\r
7378                                 if (a->ClientOption->ProxyType == PROXY_HTTP &&\r
7379                                         n != 443)\r
7380                                 {\r
7381                                         // HTTP プロキシ経由の設定になっていて接続先が 443 番ポート\r
7382                                         // 以外のポートである場合は警告を表示する\r
7383                                         if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("CM_HTTP_PROXY_WARNING"), n) == IDYES)\r
7384                                         {\r
7385                                                 // ポート番号を 443 に変更する\r
7386                                                 SetText(hWnd, C_PORT, _UU("CM_PORT_2"));\r
7387                                         }\r
7388                                 }\r
7389                                 CmEditAccountDlgStartEnumHub(hWnd, a);\r
7390                                 CmEditAccountDlgUpdate(hWnd, a);\r
7391                         }\r
7392                         break;\r
7393                 case B_IE:\r
7394                         // IE の設定を使用する\r
7395                         if(cm->server_name == NULL)\r
7396                         {\r
7397                                 CmProxyDlgUseForIE(hWnd, a->ClientOption);\r
7398                                 CmEditAccountDlgUpdate(hWnd, a);\r
7399                                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PROXY_FROM_IE"));\r
7400                         }\r
7401                         break;\r
7402                 case B_TRUST:\r
7403                         // CA\r
7404                         if (a->LinkMode == false)\r
7405                         {\r
7406                                 CmTrustDlg(hWnd);\r
7407                         }\r
7408                         else\r
7409                         {\r
7410                                 SmCaDlg(hWnd, a->Hub);\r
7411                         }\r
7412                         break;\r
7413                 case B_SERVER_CERT:\r
7414                         // サーバー証明書登録 / 削除\r
7415                         if (a->ServerCert == NULL)\r
7416                         {\r
7417                                 if (CmLoadXFromFileOrSecureCard(hWnd, &x))\r
7418                                 {\r
7419                                         a->ServerCert = x;\r
7420                                         CmEditAccountDlgUpdate(hWnd, a);\r
7421                                 }\r
7422                         }\r
7423                         else\r
7424                         {\r
7425                                 if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_SERVER_CERT")) == IDYES)\r
7426                                 {\r
7427                                         FreeX(a->ServerCert);\r
7428                                         a->ServerCert = NULL;\r
7429                                         CmEditAccountDlgUpdate(hWnd, a);\r
7430                                 }\r
7431                         }\r
7432                         break;\r
7433                 case B_VIEW_SERVER_CERT:\r
7434                         // サーバー証明書表示\r
7435                         if (a->ServerCert != NULL)\r
7436                         {\r
7437                                 X *issuer = CmGetIssuer(a->ServerCert);\r
7438                                 CertDlg(hWnd, a->ServerCert, issuer, true);\r
7439                                 FreeX(issuer);\r
7440                         }\r
7441                         break;\r
7442                 case B_VIEW_CLIENT_CERT:\r
7443                         if (a->ClientAuth->AuthType != CLIENT_AUTHTYPE_SECURE)\r
7444                         {\r
7445                                 // クライアント証明書表示\r
7446                                 if (a->ClientAuth->ClientX != NULL)\r
7447                                 {\r
7448                                         X *issuer = CmGetIssuer(a->ClientAuth->ClientX);\r
7449                                         CertDlg(hWnd, a->ClientAuth->ClientX, issuer, true);\r
7450                                         FreeX(issuer);\r
7451                                 }\r
7452                         }\r
7453                         else\r
7454                         {\r
7455                                 UINT id;\r
7456                                 // スマートカードの種類の選択\r
7457                                 SmSelectSecureId(hWnd);\r
7458                                 id = SmGetCurrentSecureIdFromReg();\r
7459                                 if (id != 0)\r
7460                                 {\r
7461                                         if (cm->server_name == NULL)\r
7462                                         {\r
7463                                                 RPC_USE_SECURE t;\r
7464 \r
7465                                                 Zero(&t, sizeof(t));\r
7466                                                 t.DeviceId = id;\r
7467                                                 CcUseSecure(cm->Client, &t);\r
7468                                         }\r
7469                                 }\r
7470                                 CmEditAccountDlgUpdate(hWnd, a);\r
7471                         }\r
7472                         break;\r
7473                 case B_REGIST_CLIENT_CERT:\r
7474                         if (a->ClientAuth->AuthType != CLIENT_AUTHTYPE_SECURE)\r
7475                         {\r
7476                                 // クライアント証明書登録 / 削除\r
7477                                 if (a->ClientAuth->ClientX == NULL)\r
7478                                 {\r
7479                                         if (CmLoadXAndK(hWnd, &x, &k))\r
7480                                         {\r
7481                                                 a->ClientAuth->ClientX = x;\r
7482                                                 a->ClientAuth->ClientK = k;\r
7483                                                 CmEditAccountDlgUpdate(hWnd, a);\r
7484                                         }\r
7485                                 }\r
7486                                 else\r
7487                                 {\r
7488                                         if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_CLIENT_CERT")) == IDYES)\r
7489                                         {\r
7490                                                 FreeX(a->ClientAuth->ClientX);\r
7491                                                 FreeK(a->ClientAuth->ClientK);\r
7492                                                 a->ClientAuth->ClientX = NULL;\r
7493                                                 a->ClientAuth->ClientK = NULL;\r
7494                                                 CmEditAccountDlgUpdate(hWnd, a);\r
7495                                         }\r
7496                                 }\r
7497                         }\r
7498                         else\r
7499                         {\r
7500                                 char cert[MAX_SECURE_DEVICE_FILE_LEN + 1], priv[MAX_SECURE_DEVICE_FILE_LEN + 1];\r
7501 \r
7502                                 // スマートカード内証明書の選択\r
7503                                 if (SmSelectKeyPairEx(hWnd, cert, sizeof(cert), priv, sizeof(priv), CmGetSecureBitmapId(a->ClientOption->Hostname)))\r
7504                                 {\r
7505                                         StrCpy(a->ClientAuth->SecurePublicCertName, sizeof(a->ClientAuth->SecurePublicCertName), cert);\r
7506                                         StrCpy(a->ClientAuth->SecurePrivateKeyName, sizeof(a->ClientAuth->SecurePrivateKeyName), priv);\r
7507                                         CmEditAccountDlgUpdate(hWnd, a);\r
7508                                 }\r
7509                         }\r
7510                         break;\r
7511                 case B_DETAIL:\r
7512                         // 高度な通信設定\r
7513                         if (CmDetailDlg(hWnd, a))\r
7514                         {\r
7515                                 CmEditAccountDlgUpdate(hWnd, a);\r
7516                         }\r
7517                         break;\r
7518                 case B_CHANGE_PASSWORD:\r
7519                         // パスワードの変更\r
7520                         CmChangePassword(hWnd, a->ClientOption, a->ClientOption->HubName,\r
7521                                 a->ClientAuth->Username);\r
7522                         break;\r
7523                 }\r
7524                 break;\r
7525         case WM_CLOSE:\r
7526                 EndDialog(hWnd, false);\r
7527                 break;\r
7528         case WM_NOTIFY:\r
7529                 n = (NMHDR *)lParam;\r
7530                 switch (n->idFrom)\r
7531                 {\r
7532                 case L_VLAN:\r
7533                         switch (n->code)\r
7534                         {\r
7535                         case LVN_ITEMCHANGED:\r
7536                                 CmEditAccountDlgUpdate(hWnd, a);\r
7537                                 break;\r
7538                         }\r
7539                         break;\r
7540                 }\r
7541                 break;\r
7542         }\r
7543 \r
7544         return 0;\r
7545 }\r
7546 \r
7547 // プロキシサーバー設定更新\r
7548 void CmProxyDlgUpdate(HWND hWnd, CLIENT_OPTION *a)\r
7549 {\r
7550         bool ok = true;\r
7551         // 引数チェック\r
7552         if (hWnd == NULL || a == NULL)\r
7553         {\r
7554                 return;\r
7555         }\r
7556 \r
7557         if (IsEmpty(hWnd, E_HOSTNAME))\r
7558         {\r
7559                 ok = false;\r
7560         }\r
7561         if (GetInt(hWnd, C_PORT) == 0)\r
7562         {\r
7563                 ok = false;\r
7564         }\r
7565 \r
7566         SetEnable(hWnd, IDOK, ok);\r
7567 }\r
7568 \r
7569 // プロキシサーバー設定ダイアログc\r
7570 UINT CmProxyDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
7571 {\r
7572         CLIENT_OPTION *a = (CLIENT_OPTION *)param;\r
7573         // 引数チェック\r
7574         if (hWnd == NULL)\r
7575         {\r
7576                 return 0;\r
7577         }\r
7578 \r
7579         switch (msg)\r
7580         {\r
7581         case WM_INITDIALOG:\r
7582                 SetTextA(hWnd, E_HOSTNAME, a->ProxyName);\r
7583                 CbSetHeight(hWnd, C_PORT, 18);\r
7584                 CbAddStr(hWnd, C_PORT, L"8080", 0);\r
7585                 CbAddStr(hWnd, C_PORT, L"1080", 0);\r
7586                 CbAddStr(hWnd, C_PORT, L"80", 0);\r
7587                 CbAddStr(hWnd, C_PORT, L"3128", 0);\r
7588                 CbAddStr(hWnd, C_PORT, L"443", 0);\r
7589                 CbAddStr(hWnd, C_PORT, L"9821", 0);\r
7590                 CbAddStr(hWnd, C_PORT, L"9801", 0);\r
7591                 SetIntEx(hWnd, C_PORT, a->ProxyPort);\r
7592                 SetTextA(hWnd, E_USERNAME, a->ProxyUsername);\r
7593                 SetTextA(hWnd, E_PASSWORD, a->ProxyPassword);\r
7594                 if (a->ProxyPort == 0)\r
7595                 {\r
7596                         if (a->ProxyType == PROXY_HTTP)\r
7597                         {\r
7598                                 SetInt(hWnd, C_PORT, 8080);\r
7599                         }\r
7600                         else\r
7601                         {\r
7602                                 SetInt(hWnd, C_PORT, 1080);\r
7603                         }\r
7604                 }\r
7605                 CmProxyDlgUpdate(hWnd, a);\r
7606                 break;\r
7607         case WM_COMMAND:\r
7608                 switch (LOWORD(wParam))\r
7609                 {\r
7610                 case E_HOSTNAME:\r
7611                 case C_PORT:\r
7612                 case E_USERNAME:\r
7613                 case E_PASSWORD:\r
7614                         CmProxyDlgUpdate(hWnd, a);\r
7615                         break;\r
7616                 }\r
7617 \r
7618                 switch (wParam)\r
7619                 {\r
7620                 case IDOK:\r
7621                         GetTxtA(hWnd, E_HOSTNAME, a->ProxyName, sizeof(a->ProxyName));\r
7622                         GetTxtA(hWnd, E_USERNAME, a->ProxyUsername, sizeof(a->ProxyUsername));\r
7623                         GetTxtA(hWnd, E_PASSWORD, a->ProxyPassword, sizeof(a->ProxyPassword));\r
7624                         a->ProxyPort = GetInt(hWnd, C_PORT);\r
7625                         EndDialog(hWnd, true);\r
7626                         break;\r
7627                 case IDCANCEL:\r
7628                         Close(hWnd);\r
7629                         break;\r
7630                 }\r
7631                 break;\r
7632         case WM_CLOSE:\r
7633                 EndDialog(hWnd, false);\r
7634                 break;\r
7635         }\r
7636 \r
7637         return 0;\r
7638 }\r
7639 \r
7640 // プロキシサーバー設定\r
7641 bool CmProxyDlg(HWND hWnd, CLIENT_OPTION *a)\r
7642 {\r
7643         // 引数チェック\r
7644         if (a == NULL)\r
7645         {\r
7646                 return false;\r
7647         }\r
7648 \r
7649         return Dialog(hWnd, D_CM_PROXY, CmProxyDlgProc, a);\r
7650 }\r
7651 \r
7652 // 指定した証明書の署名者がわかれば取得する\r
7653 X *CmGetIssuer(X *x)\r
7654 {\r
7655         RPC_GET_ISSUER a;\r
7656         X *ret;\r
7657         // 引数チェック\r
7658         if (x == NULL)\r
7659         {\r
7660                 return NULL;\r
7661         }\r
7662 \r
7663         Zero(&a, sizeof(a));\r
7664         a.x = CloneX(x);\r
7665         if (CALLEX(cm->hMainWnd, CcGetIssuer(cm->Client, &a)) == 0)\r
7666         {\r
7667                 ret = CloneX(a.issuer_x);\r
7668         }\r
7669         else\r
7670         {\r
7671                 ret = NULL;\r
7672         }\r
7673 \r
7674         CiFreeGetIssuer(&a);\r
7675 \r
7676         return ret;\r
7677 }\r
7678 \r
7679 // ダイアログ初期化\r
7680 void CmLoadXFromFileOrSecureCardDlgInit(HWND hWnd, CM_LOADX *p)\r
7681 {\r
7682         UINT current;\r
7683         // 引数チェック\r
7684         if (hWnd == NULL || p == NULL)\r
7685         {\r
7686                 return;\r
7687         }\r
7688 \r
7689         current = MsRegReadInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "CertLoadSource");\r
7690 \r
7691         Check(hWnd, R_FROM_FILE, current == 0);\r
7692         Check(hWnd, R_FROM_SECURE, current != 0);\r
7693 \r
7694         SetFont(hWnd, S_INFO, Font(0, true));\r
7695 \r
7696         CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);\r
7697 }\r
7698 \r
7699 // ダイアログコントロール更新\r
7700 void CmLoadXFromFileOrSecureCardDlgUpdate(HWND hWnd, CM_LOADX *p)\r
7701 {\r
7702         SECURE_DEVICE *dev;\r
7703         wchar_t tmp[MAX_SIZE];\r
7704         bool ok = true;\r
7705         // 引数チェック\r
7706         if (hWnd == NULL || p == NULL)\r
7707         {\r
7708                 return;\r
7709         }\r
7710 \r
7711         dev = GetSecureDevice(SmGetCurrentSecureIdFromReg());\r
7712         if (dev == NULL)\r
7713         {\r
7714                 UniStrCpy(tmp, sizeof(tmp), _UU("SEC_CURRENT_NO_DEVICE"));\r
7715         }\r
7716         else\r
7717         {\r
7718                 UniFormat(tmp, sizeof(tmp), _UU("SEC_CURRENT_DEVICE"), dev->DeviceName);\r
7719         }\r
7720 \r
7721         SetText(hWnd, S_INFO, tmp);\r
7722 \r
7723         if (IsChecked(hWnd, R_FROM_SECURE))\r
7724         {\r
7725                 if (dev == NULL)\r
7726                 {\r
7727                         ok = false;\r
7728                 }\r
7729         }\r
7730 \r
7731         SetEnable(hWnd, IDOK, ok);\r
7732         SetEnable(hWnd, B_SELECT, IsChecked(hWnd, R_FROM_SECURE));\r
7733         SetEnable(hWnd, S_CERT, IsChecked(hWnd, R_FROM_SECURE));\r
7734         SetEnable(hWnd, S_FILE, IsChecked(hWnd, R_FROM_FILE));\r
7735 }\r
7736 \r
7737 // 証明書読み込み選択ダイアログプロシージャ\r
7738 UINT CmLoadXFromFileOrSecureCardDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
7739 {\r
7740         CM_LOADX *p = (CM_LOADX *)param;\r
7741         X *x;\r
7742         UINT current;\r
7743         // 引数チェック\r
7744         if (hWnd == NULL)\r
7745         {\r
7746                 return 0;\r
7747         }\r
7748 \r
7749         switch (msg)\r
7750         {\r
7751         case WM_INITDIALOG:\r
7752                 CmLoadXFromFileOrSecureCardDlgInit(hWnd, p);\r
7753                 break;\r
7754 \r
7755         case WM_COMMAND:\r
7756                 switch (wParam)\r
7757                 {\r
7758                 case IDOK:\r
7759                         current = (IsChecked(hWnd, R_FROM_FILE)) ? 0 : 1;\r
7760                         MsRegWriteInt(REG_CURRENT_USER, SECURE_MANAGER_KEY, "CertLoadSource", current);\r
7761 \r
7762                         if (current == 0)\r
7763                         {\r
7764                                 // ファイルから\r
7765                                 if (CmLoadX(hWnd, &x))\r
7766                                 {\r
7767                                         p->x = x;\r
7768                                         EndDialog(hWnd, true);\r
7769                                 }\r
7770                         }\r
7771                         else\r
7772                         {\r
7773                                 // スマートカードから\r
7774                                 char name[MAX_SIZE];\r
7775 \r
7776                                 // カード内の証明書名を選択\r
7777                                 if (SmSelectKeyPair(hWnd, name, sizeof(name), NULL, 0))\r
7778                                 {\r
7779                                         // 読み込み\r
7780                                         WINUI_SECURE_BATCH batch[] =\r
7781                                         {\r
7782                                                 {WINUI_SECURE_READ_CERT, name, true, NULL, NULL, NULL, NULL, NULL, NULL},\r
7783                                         };\r
7784 \r
7785                                         // 読み込み実行\r
7786                                         if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), SmGetCurrentSecureIdFromReg(), 0))\r
7787                                         {\r
7788                                                 // 成功\r
7789                                                 p->x = batch[0].OutputX;\r
7790                                                 EndDialog(hWnd, true);\r
7791                                         }\r
7792                                 }\r
7793                         }\r
7794                         break;\r
7795 \r
7796                 case IDCANCEL:\r
7797                         Close(hWnd);\r
7798                         break;\r
7799 \r
7800                 case R_FROM_FILE:\r
7801                         CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);\r
7802                         break;\r
7803 \r
7804                 case R_FROM_SECURE:\r
7805                         CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);\r
7806                         break;\r
7807 \r
7808                 case B_SELECT:\r
7809                         SmSelectSecureId(hWnd);\r
7810                         CmLoadXFromFileOrSecureCardDlgUpdate(hWnd, p);\r
7811                         break;\r
7812                 }\r
7813                 break;\r
7814 \r
7815         case WM_CLOSE:\r
7816                 EndDialog(hWnd, false);\r
7817                 break;\r
7818         }\r
7819 \r
7820         return 0;\r
7821 }\r
7822 \r
7823 // 証明書をスマートカードかファイルから読み込む\r
7824 bool CmLoadXFromFileOrSecureCard(HWND hWnd, X **x)\r
7825 {\r
7826         CM_LOADX p;\r
7827         // 引数チェック\r
7828         if (x == NULL)\r
7829         {\r
7830                 return false;\r
7831         }\r
7832 \r
7833         Zero(&p, sizeof(p));\r
7834         if (Dialog(hWnd, D_CM_LOAD_X, CmLoadXFromFileOrSecureCardDlgProc, &p) == false)\r
7835         {\r
7836                 return false;\r
7837         }\r
7838 \r
7839         *x = p.x;\r
7840 \r
7841         return true;\r
7842 }\r
7843 \r
7844 // 証明書を読み込む\r
7845 bool CmLoadX(HWND hWnd, X **x)\r
7846 {\r
7847         return CmLoadXEx(hWnd, x, NULL, 0);\r
7848 }\r
7849 bool CmLoadXEx(HWND hWnd, X **x, char *filename, UINT size)\r
7850 {\r
7851         wchar_t *filename_w = CopyStrToUni(filename);\r
7852         bool ret;\r
7853 \r
7854         ret = CmLoadXExW(hWnd, x, filename_w, size);\r
7855 \r
7856         Free(filename_w);\r
7857 \r
7858         return ret;\r
7859 }\r
7860 bool CmLoadXExW(HWND hWnd, X **x, wchar_t *filename, UINT size)\r
7861 {\r
7862         wchar_t *s;\r
7863         bool is_p12;\r
7864         wchar_t tmp[MAX_SIZE];\r
7865         K *k;\r
7866         // 引数チェック\r
7867         if (x == NULL)\r
7868         {\r
7869                 return false;\r
7870         }\r
7871 \r
7872         // 証明書を読み込む\r
7873         s = OpenDlg(hWnd, _UU("DLG_CERT_OR_P12_FILTER"), _UU("DLG_OPEN_CERT"));\r
7874         if (s == NULL)\r
7875         {\r
7876                 return false;\r
7877         }\r
7878         UniStrCpy(tmp, sizeof(tmp), s);\r
7879         if (filename != NULL)\r
7880         {\r
7881                 UniStrCpy(filename, size, tmp);\r
7882         }\r
7883         Free(s);\r
7884         if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))\r
7885         {\r
7886                 is_p12 = true;\r
7887         }\r
7888         else\r
7889         {\r
7890                 is_p12 = false;\r
7891         }\r
7892 \r
7893         if (is_p12)\r
7894         {\r
7895                 // PKCS#12 の処理\r
7896                 BUF *b = ReadDumpW(tmp);\r
7897                 P12 *p12;\r
7898                 if (b == NULL)\r
7899                 {\r
7900                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);\r
7901                         return false;\r
7902                 }\r
7903                 p12 = BufToP12(b);\r
7904                 if (p12 == NULL)\r
7905                 {\r
7906                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);\r
7907                         FreeBuf(b);\r
7908                         return false;\r
7909                 }\r
7910                 if (IsEncryptedP12(p12) == false)\r
7911                 {\r
7912                         if (ParseP12(p12, x, &k, NULL) == false)\r
7913                         {\r
7914                                 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);\r
7915                                 FreeP12(p12);\r
7916                                 FreeBuf(b);\r
7917                                 return false;\r
7918                         }\r
7919                 }\r
7920                 else\r
7921                 {\r
7922                         char password[MAX_SIZE];\r
7923                         if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)\r
7924                         {\r
7925                                 FreeP12(p12);\r
7926                                 FreeBuf(b);\r
7927                                 return false;\r
7928                         }\r
7929                         else\r
7930                         {\r
7931                                 if (ParseP12(p12, x, &k, password) == false)\r
7932                                 {\r
7933                                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);\r
7934                                         FreeP12(p12);\r
7935                                         FreeBuf(b);\r
7936                                         return false;\r
7937                                 }\r
7938                         }\r
7939                 }\r
7940                 FreeP12(p12);\r
7941                 FreeBuf(b);\r
7942                 FreeK(k);\r
7943                 return true;\r
7944         }\r
7945         else\r
7946         {\r
7947                 // X509 の処理\r
7948                 BUF *b = ReadDumpW(tmp);\r
7949                 X *x509;\r
7950                 if (b == NULL)\r
7951                 {\r
7952                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);\r
7953                         return false;\r
7954                 }\r
7955 \r
7956                 x509 = BufToX(b, IsBase64(b));\r
7957                 FreeBuf(b);\r
7958                 if (x509 == NULL)\r
7959                 {\r
7960                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_X509_W"), tmp);\r
7961                         return false;\r
7962                 }\r
7963 \r
7964                 *x = x509;\r
7965                 return true;\r
7966         }\r
7967 }\r
7968 \r
7969 // 秘密鍵を読み込む\r
7970 bool CmLoadK(HWND hWnd, K **k)\r
7971 {\r
7972         return CmLoadKEx(hWnd, k, NULL, 0);\r
7973 }\r
7974 bool CmLoadKEx(HWND hWnd, K **k, char *filename, UINT size)\r
7975 {\r
7976         wchar_t *filename_w = CopyStrToUni(filename);\r
7977         bool ret;\r
7978 \r
7979         ret = CmLoadKExW(hWnd, k, filename_w, size);\r
7980 \r
7981         Free(filename_w);\r
7982 \r
7983         return ret;\r
7984 }\r
7985 bool CmLoadKExW(HWND hWnd, K **k, wchar_t *filename, UINT size)\r
7986 {\r
7987         wchar_t *s;\r
7988         bool is_p12;\r
7989         wchar_t tmp[MAX_SIZE];\r
7990         // 引数チェック\r
7991         if (k == NULL)\r
7992         {\r
7993                 return false;\r
7994         }\r
7995 \r
7996         // 証明書を読み込む\r
7997         s = OpenDlg(hWnd, _UU("DLG_KEY_OR_P12_FILTER"), _UU("DLG_OPEN_KEY"));\r
7998         if (s == NULL)\r
7999         {\r
8000                 return false;\r
8001         }\r
8002         UniStrCpy(tmp, sizeof(tmp), s);\r
8003         Free(s);\r
8004         if (filename != NULL)\r
8005         {\r
8006                 UniStrCpy(filename, size, tmp);\r
8007         }\r
8008         if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))\r
8009         {\r
8010                 is_p12 = true;\r
8011         }\r
8012         else\r
8013         {\r
8014                 is_p12 = false;\r
8015         }\r
8016 \r
8017         if (is_p12)\r
8018         {\r
8019                 // PKCS#12 の処理\r
8020                 BUF *b = ReadDumpW(tmp);\r
8021                 P12 *p12;\r
8022                 if (b == NULL)\r
8023                 {\r
8024                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);\r
8025                         return false;\r
8026                 }\r
8027                 p12 = BufToP12(b);\r
8028                 if (p12 == NULL)\r
8029                 {\r
8030                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);\r
8031                         FreeBuf(b);\r
8032                         return false;\r
8033                 }\r
8034                 if (IsEncryptedP12(p12) == false)\r
8035                 {\r
8036                         X *x;\r
8037                         if (ParseP12(p12, &x, k, NULL) == false)\r
8038                         {\r
8039                                 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);\r
8040                                 FreeP12(p12);\r
8041                                 FreeBuf(b);\r
8042                                 return false;\r
8043                         }\r
8044 \r
8045                         FreeX(x);\r
8046                 }\r
8047                 else\r
8048                 {\r
8049                         char password[MAX_SIZE];\r
8050                         if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)\r
8051                         {\r
8052                                 FreeP12(p12);\r
8053                                 FreeBuf(b);\r
8054                                 return false;\r
8055                         }\r
8056                         else\r
8057                         {\r
8058                                 X *x;\r
8059                                 if (ParseP12(p12, &x, k, password) == false)\r
8060                                 {\r
8061                                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);\r
8062                                         FreeP12(p12);\r
8063                                         FreeBuf(b);\r
8064                                         return false;\r
8065                                 }\r
8066 \r
8067                                 FreeX(x);\r
8068                         }\r
8069                 }\r
8070                 FreeP12(p12);\r
8071                 FreeBuf(b);\r
8072                 return true;\r
8073         }\r
8074         else\r
8075         {\r
8076                 // 秘密鍵の処理\r
8077                 BUF *b = ReadDumpW(tmp);\r
8078                 K *key;\r
8079                 if (b == NULL)\r
8080                 {\r
8081                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);\r
8082                         return false;\r
8083                 }\r
8084 \r
8085                 if (IsEncryptedK(b, true) == false)\r
8086                 {\r
8087                         key = BufToK(b, true, IsBase64(b), NULL);\r
8088                 }\r
8089                 else\r
8090                 {\r
8091                         char pass[MAX_SIZE];\r
8092                         if (PassphraseDlg(hWnd, pass, sizeof(pass), b, false) == false)\r
8093                         {\r
8094                                 FreeBuf(b);\r
8095                                 return false;\r
8096                         }\r
8097                         key = BufToK(b, true, IsBase64(b), pass);\r
8098                 }\r
8099 \r
8100                 if (key == NULL)\r
8101                 {\r
8102                         FreeBuf(b);\r
8103                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_KEY_W"), tmp);\r
8104                         return false;\r
8105                 }\r
8106 \r
8107                 FreeBuf(b);\r
8108                 *k = key;\r
8109                 return true;\r
8110         }\r
8111 }\r
8112 \r
8113 // 証明書と秘密鍵のセットを読み込む\r
8114 bool CmLoadXAndK(HWND hWnd, X **x, K **k)\r
8115 {\r
8116         wchar_t *s;\r
8117         bool is_p12;\r
8118         wchar_t tmp[MAX_SIZE];\r
8119         // 引数チェック\r
8120         if (x == NULL || k == NULL)\r
8121         {\r
8122                 return false;\r
8123         }\r
8124 START_FIRST:\r
8125 \r
8126         // 証明書を読み込む\r
8127         s = OpenDlg(hWnd, _UU("DLG_CERT_OR_P12_FILTER"), _UU("DLG_OPEN_CERT"));\r
8128         if (s == NULL)\r
8129         {\r
8130                 return false;\r
8131         }\r
8132         UniStrCpy(tmp, sizeof(tmp), s);\r
8133         Free(s);\r
8134         if (UniEndWith(tmp, L".p12") || UniEndWith(tmp, L".pfx"))\r
8135         {\r
8136                 is_p12 = true;\r
8137         }\r
8138         else\r
8139         {\r
8140                 is_p12 = false;\r
8141         }\r
8142 \r
8143         if (is_p12)\r
8144         {\r
8145                 // PKCS#12 の処理\r
8146                 BUF *b = ReadDumpW(tmp);\r
8147                 P12 *p12;\r
8148                 if (b == NULL)\r
8149                 {\r
8150                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);\r
8151                         return false;\r
8152                 }\r
8153                 p12 = BufToP12(b);\r
8154                 if (p12 == NULL)\r
8155                 {\r
8156                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);\r
8157                         FreeBuf(b);\r
8158                         return false;\r
8159                 }\r
8160                 if (IsEncryptedP12(p12) == false)\r
8161                 {\r
8162                         if (ParseP12(p12, x, k, NULL) == false)\r
8163                         {\r
8164                                 MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);\r
8165                                 FreeP12(p12);\r
8166                                 FreeBuf(b);\r
8167                                 return false;\r
8168                         }\r
8169                 }\r
8170                 else\r
8171                 {\r
8172                         char password[MAX_SIZE];\r
8173                         if (PassphraseDlg(hWnd, password, sizeof(password), b, true) == false)\r
8174                         {\r
8175                                 FreeP12(p12);\r
8176                                 FreeBuf(b);\r
8177                                 return false;\r
8178                         }\r
8179                         else\r
8180                         {\r
8181                                 if (ParseP12(p12, x, k, password) == false)\r
8182                                 {\r
8183                                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);\r
8184                                         FreeP12(p12);\r
8185                                         FreeBuf(b);\r
8186                                         return false;\r
8187                                 }\r
8188                         }\r
8189                 }\r
8190                 if (CheckXandK(*x, *k) == false)\r
8191                 {\r
8192                         FreeX(*x);\r
8193                         FreeK(*k);\r
8194                         FreeP12(p12);\r
8195                         FreeBuf(b);\r
8196                         if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)\r
8197                         {\r
8198                                 goto START_FIRST;\r
8199                         }\r
8200                         return false;\r
8201                 }\r
8202                 FreeP12(p12);\r
8203                 FreeBuf(b);\r
8204                 return true;\r
8205         }\r
8206         else\r
8207         {\r
8208                 // X509 の処理\r
8209                 BUF *b = ReadDumpW(tmp);\r
8210                 X *x509;\r
8211                 K *key;\r
8212                 if (b == NULL)\r
8213                 {\r
8214                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);\r
8215                         return false;\r
8216                 }\r
8217 \r
8218                 x509 = BufToX(b, IsBase64(b));\r
8219                 FreeBuf(b);\r
8220                 if (x509 == NULL)\r
8221                 {\r
8222                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_X509_W"), tmp);\r
8223                         return false;\r
8224                 }\r
8225 \r
8226                 // 秘密鍵を読み込む\r
8227                 s = OpenDlg(hWnd, _UU("DLG_KEY_FILTER"), _UU("DLG_OPEN_KEY_WITH_CERT"));\r
8228                 if (s == NULL)\r
8229                 {\r
8230                         FreeX(x509);\r
8231                         return false;\r
8232                 }\r
8233                 UniStrCpy(tmp, sizeof(tmp), s);\r
8234                 Free(s);\r
8235 \r
8236                 b = ReadDumpW(tmp);\r
8237                 if (b == NULL)\r
8238                 {\r
8239                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);\r
8240                         FreeX(x509);\r
8241                         return false;\r
8242                 }\r
8243 \r
8244                 if (IsEncryptedK(b, true) == false)\r
8245                 {\r
8246                         key = BufToK(b, true, IsBase64(b), NULL);\r
8247                 }\r
8248                 else\r
8249                 {\r
8250                         char pass[MAX_SIZE];\r
8251                         if (PassphraseDlg(hWnd, pass, sizeof(pass), b, false) == false)\r
8252                         {\r
8253                                 FreeBuf(b);\r
8254                                 FreeX(x509);\r
8255                                 return false;\r
8256                         }\r
8257                         key = BufToK(b, true, IsBase64(b), pass);\r
8258                 }\r
8259 \r
8260                 if (key == NULL)\r
8261                 {\r
8262                         FreeBuf(b);\r
8263                         FreeX(x509);\r
8264                         MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_KEY_W"), tmp);\r
8265                         return false;\r
8266                 }\r
8267 \r
8268                 if (CheckXandK(x509, key) == false)\r
8269                 {\r
8270                         FreeBuf(b);\r
8271                         FreeX(x509);\r
8272                         FreeK(key);\r
8273                         if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)\r
8274                         {\r
8275                                 goto START_FIRST;\r
8276                         }\r
8277                         return false;\r
8278                 }\r
8279 \r
8280                 FreeBuf(b);\r
8281                 *x = x509;\r
8282                 *k = key;\r
8283                 return true;\r
8284         }\r
8285 }\r
8286 \r
8287 // 仮想 HUB 列挙開始\r
8288 void CmEditAccountDlgStartEnumHub(HWND hWnd, CM_ACCOUNT *a)\r
8289 {\r
8290         char server_name[MAX_HOST_NAME_LEN + 1];\r
8291         UINT old_proxy_type;\r
8292         // 引数チェック\r
8293         if (hWnd == NULL || a == NULL)\r
8294         {\r
8295                 return;\r
8296         }\r
8297 \r
8298         if (StrLen(a->ClientOption->Hostname) == 0)\r
8299         {\r
8300                 return;\r
8301         }\r
8302         if (a->ClientOption->Port == 0)\r
8303         {\r
8304                 return;\r
8305         }\r
8306         if (a->ClientOption->ProxyType != PROXY_DIRECT &&\r
8307                 (StrLen(a->ClientOption->ProxyName) == 0 ||\r
8308                 a->ClientOption->ProxyPort == 0))\r
8309         {\r
8310                 return;\r
8311         }\r
8312 \r
8313         if (StrCmpi(server_name, a->old_server_name) == 0)\r
8314         {\r
8315                 if (CbNum(hWnd, C_HUBNAME) != 0)\r
8316                 {\r
8317                         return;\r
8318                 }\r
8319         }\r
8320         else\r
8321         {\r
8322                 StrCpy(a->old_server_name, sizeof(a->old_server_name), server_name);\r
8323                 CbReset(hWnd, C_HUBNAME);\r
8324         }\r
8325 \r
8326         old_proxy_type = a->ClientOption->ProxyType;\r
8327 \r
8328         if (IsChecked(hWnd, R_DIRECT_TCP))\r
8329         {\r
8330                 a->ClientOption->ProxyType = PROXY_DIRECT;\r
8331         }\r
8332         if (IsChecked(hWnd, R_HTTPS))\r
8333         {\r
8334                 a->ClientOption->ProxyType = PROXY_HTTP;\r
8335         }\r
8336         if (IsChecked(hWnd, R_SOCKS))\r
8337         {\r
8338                 a->ClientOption->ProxyType = PROXY_SOCKS;\r
8339         }\r
8340 \r
8341         CmEnumHubStart(hWnd, a->ClientOption);\r
8342 \r
8343         a->ClientOption->ProxyType = old_proxy_type;\r
8344 }\r
8345 \r
8346 // [OK] ボタン\r
8347 void CmEditAccountDlgOnOk(HWND hWnd, CM_ACCOUNT *a)\r
8348 {\r
8349         RPC_CLIENT_CREATE_ACCOUNT c;\r
8350         bool b;\r
8351         // 引数チェック\r
8352         if (hWnd == NULL || a == NULL)\r
8353         {\r
8354                 return;\r
8355         }\r
8356         if (a->ClientOption->NumRetry != 0 && a->ClientOption->RetryInterval < 5)\r
8357         {\r
8358                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_RETRY_INTERVAL_ERROR"));\r
8359                 FocusEx(hWnd, E_RETRY_SPAN);\r
8360                 return;\r
8361         }\r
8362 \r
8363         CmEditAccountDlgUpdate(hWnd, a);\r
8364 \r
8365         if (a->LinkMode == false && a->NatMode == false)\r
8366         {\r
8367                 // アカウントを保存\r
8368                 Zero(&c, sizeof(c));\r
8369                 c.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));\r
8370                 Copy(c.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));\r
8371                 c.ClientAuth = CopyClientAuth(a->ClientAuth);\r
8372                 c.CheckServerCert = a->CheckServerCert;\r
8373                 if (a->ServerCert != NULL)\r
8374                 {\r
8375                         c.ServerCert = CloneX(a->ServerCert);\r
8376                 }\r
8377                 c.StartupAccount = a->Startup;\r
8378 \r
8379                 if (a->EditMode == false)\r
8380                 {\r
8381                         b = CALL(hWnd, CcCreateAccount(cm->Client, &c));\r
8382                 }\r
8383                 else\r
8384                 {\r
8385                         b = CALL(hWnd, CcSetAccount(cm->Client, &c));\r
8386                 }\r
8387 \r
8388                 CiFreeClientCreateAccount(&c);\r
8389 \r
8390                 // 現在このアカウントが動作中かどうかチェック\r
8391                 if (b)\r
8392                 {\r
8393                         RPC_CLIENT_GET_CONNECTION_STATUS st;\r
8394                         Zero(&st, sizeof(st));\r
8395                         UniStrCpy(st.AccountName, sizeof(st.AccountName), a->ClientOption->AccountName);\r
8396                         if (CALL(hWnd, CcGetAccountStatus(cm->Client, &st)))\r
8397                         {\r
8398                                 if (st.Active)\r
8399                                 {\r
8400                                         MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("CM_CURRENT_ACTIVE"),\r
8401                                                 st.AccountName);\r
8402                                 }\r
8403                         }\r
8404                 }\r
8405 \r
8406                 if (b)\r
8407                 {\r
8408                         EndDialog(hWnd, true);\r
8409                 }\r
8410         }\r
8411         else\r
8412         {\r
8413                 if (a->LinkMode)\r
8414                 {\r
8415                         // リンクモード\r
8416                         RPC_CREATE_LINK t;\r
8417 \r
8418                         Zero(&t, sizeof(t));\r
8419                         StrCpy(t.HubName, sizeof(t.HubName), a->Hub->HubName);\r
8420                         t.Online = a->OnlineFlag;\r
8421                         Copy(&t.Policy, &a->Policy, sizeof(POLICY));\r
8422                         t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));\r
8423                         Copy(t.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));\r
8424                         t.ClientAuth = CopyClientAuth(a->ClientAuth);\r
8425                         t.CheckServerCert = a->CheckServerCert;\r
8426                         t.ServerCert = CloneX(a->ServerCert);\r
8427 \r
8428                         // カスケード接続の設定を保存\r
8429                         if (a->EditMode)\r
8430                         {\r
8431                                 if (CALL(hWnd, ScSetLink(a->Hub->Rpc, &t)))\r
8432                                 {\r
8433                                         if (a->OnlineFlag)\r
8434                                         {\r
8435                                                 MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("SM_LINK_SAVE_ONLINE"), a->ClientOption->AccountName);\r
8436                                         }\r
8437                                         EndDialog(hWnd, true);\r
8438                                 }\r
8439                         }\r
8440                         else\r
8441                         {\r
8442                                 if (CALL(hWnd, ScCreateLink(a->Hub->Rpc, &t)))\r
8443                                 {\r
8444                                         if (a->Link_ConnectNow)\r
8445                                         {\r
8446                                                 RPC_LINK tt;\r
8447 \r
8448                                                 Zero(&tt, sizeof(tt));\r
8449                                                 UniStrCpy(tt.AccountName, sizeof(tt.AccountName), a->ClientOption->AccountName);\r
8450                                                 StrCpy(tt.HubName, sizeof(tt.HubName), a->Hub->HubName);\r
8451 \r
8452                                                 CALL(hWnd, ScSetLinkOnline(a->Hub->Rpc, &tt));\r
8453                                         }\r
8454                                         EndDialog(hWnd, true);\r
8455                                 }\r
8456                         }\r
8457 \r
8458                         FreeRpcCreateLink(&t);\r
8459                 }\r
8460                 else\r
8461                 {\r
8462                         // NAT モード\r
8463                         RPC_CREATE_LINK t;\r
8464                         Zero(&t, sizeof(t));\r
8465 \r
8466                         t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));\r
8467                         Copy(t.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));\r
8468                         t.ClientAuth = CopyClientAuth(a->ClientAuth);\r
8469 \r
8470                         if (CALL(hWnd, NcSetClientConfig(a->Rpc, &t)))\r
8471                         {\r
8472                                 EndDialog(hWnd, true);\r
8473                         }\r
8474 \r
8475                         FreeRpcCreateLink(&t);\r
8476                 }\r
8477         }\r
8478 }\r
8479 \r
8480 // アカウント編集ダイアログの表示\r
8481 bool CmEditAccountDlg(HWND hWnd, CM_ACCOUNT *a)\r
8482 {\r
8483         // 引数チェック\r
8484         if (hWnd == NULL || a == NULL)\r
8485         {\r
8486                 return false;\r
8487         }\r
8488 \r
8489         return Dialog(hWnd, D_CM_ACCOUNT, CmEditAccountDlgProc, a);\r
8490 }\r
8491 \r
8492 // アカウント編集\r
8493 void CmEditAccount(HWND hWnd, wchar_t *account_name)\r
8494 {\r
8495         CM_ACCOUNT *a;\r
8496         // 引数チェック\r
8497         if (hWnd == NULL || account_name == NULL)\r
8498         {\r
8499                 return;\r
8500         }\r
8501 \r
8502         a = CmGetExistAccountObject(hWnd, account_name);\r
8503         if (a == NULL)\r
8504         {\r
8505                 return;\r
8506         }\r
8507 \r
8508         CmVoice("input_config");\r
8509         if (CmEditAccountDlg(hWnd, a))\r
8510         {\r
8511                 CmVoice("set_config");\r
8512         }\r
8513 \r
8514         CmFreeAccountObject(hWnd, a);\r
8515 }\r
8516 \r
8517 // アカウント作成\r
8518 void CmNewAccount(HWND hWnd)\r
8519 {\r
8520         CM_ACCOUNT *a;\r
8521         RPC_CLIENT_ENUM_VLAN t;\r
8522         UINT num_vlan = 0;\r
8523         // 引数チェック\r
8524         if (hWnd == NULL)\r
8525         {\r
8526                 return;\r
8527         }\r
8528 \r
8529         if (IsEnable(hWnd, 0) == false)\r
8530         {\r
8531                 return;\r
8532         }\r
8533 \r
8534         Zero(&t, sizeof(t));\r
8535         if (CcEnumVLan(cm->Client, &t) == ERR_NO_ERROR)\r
8536         {\r
8537                 num_vlan = t.NumItem;\r
8538 \r
8539                 CiFreeClientEnumVLan(&t);\r
8540         }\r
8541 \r
8542         if (num_vlan == 0)\r
8543         {\r
8544                 if (MsgBox(hWnd, MB_ICONINFORMATION | MB_YESNO, _UU("CM_NO_VLAN")) == IDNO)\r
8545                 {\r
8546                         return;\r
8547                 }\r
8548                 else\r
8549                 {\r
8550                         if (cm->server_name == NULL)\r
8551                         {\r
8552                                 Command(hWnd, CMD_NEW_VLAN);\r
8553                                 return;\r
8554                         }\r
8555                         else\r
8556                         {\r
8557                                 MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_VLAN_REMOTE_ERROR"));\r
8558                         }\r
8559                         return;\r
8560                 }\r
8561         }\r
8562 \r
8563         a = CmCreateNewAccountObject(hWnd);\r
8564         if (a == NULL)\r
8565         {\r
8566                 return;\r
8567         }\r
8568 \r
8569         CmVoice("input_config");\r
8570         if (CmEditAccountDlg(hWnd, a))\r
8571         {\r
8572                 CmVoice("new_config");\r
8573         }\r
8574 \r
8575         CmFreeAccountObject(hWnd, a);\r
8576 }\r
8577 \r
8578 // アカウントオブジェクトの解放\r
8579 void CmFreeAccountObject(HWND hWnd, CM_ACCOUNT *a)\r
8580 {\r
8581         // 引数チェック\r
8582         if (hWnd == NULL || a == NULL)\r
8583         {\r
8584                 return;\r
8585         }\r
8586 \r
8587         Free(a->ClientOption);\r
8588         CiFreeClientAuth(a->ClientAuth);\r
8589         if (a->ServerCert != NULL)\r
8590         {\r
8591                 FreeX(a->ServerCert);\r
8592         }\r
8593         Free(a);\r
8594 }\r
8595 \r
8596 // 既存のアカウントオブジェクトの取得\r
8597 CM_ACCOUNT *CmGetExistAccountObject(HWND hWnd, wchar_t *account_name)\r
8598 {\r
8599         RPC_CLIENT_GET_ACCOUNT c;\r
8600         CM_ACCOUNT *a;\r
8601         // 引数チェック\r
8602         if (hWnd == NULL)\r
8603         {\r
8604                 return NULL;\r
8605         }\r
8606 \r
8607         Zero(&c, sizeof(c));\r
8608         UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);\r
8609         if (CALL(hWnd, CcGetAccount(cm->Client, &c)) == false)\r
8610         {\r
8611                 return NULL;\r
8612         }\r
8613 \r
8614         a = ZeroMalloc(sizeof(CM_ACCOUNT));\r
8615         a->EditMode = true;\r
8616         a->CheckServerCert = c.CheckServerCert;\r
8617         a->Startup = c.StartupAccount;\r
8618         if (c.ServerCert != NULL)\r
8619         {\r
8620                 a->ServerCert = CloneX(c.ServerCert);\r
8621         }\r
8622         a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));\r
8623         Copy(a->ClientOption, c.ClientOption, sizeof(CLIENT_OPTION));\r
8624         a->ClientAuth = CopyClientAuth(c.ClientAuth);\r
8625         Copy(a->ShortcutKey, c.ShortcutKey, SHA1_SIZE);\r
8626         CiFreeClientGetAccount(&c);\r
8627 \r
8628         a->LockMode = cm->CmSetting.LockMode;\r
8629 \r
8630         return a;\r
8631 }\r
8632 \r
8633 // 新しいアカウントオブジェクトの作成\r
8634 CM_ACCOUNT *CmCreateNewAccountObject(HWND hWnd)\r
8635 {\r
8636         CM_ACCOUNT *a;\r
8637         // 引数チェック\r
8638         if (hWnd == NULL)\r
8639         {\r
8640                 return NULL;\r
8641         }\r
8642 \r
8643         a = ZeroMalloc(sizeof(CM_ACCOUNT));\r
8644         a->EditMode = false;\r
8645         a->CheckServerCert = false;\r
8646         a->Startup = false;\r
8647         a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));\r
8648 \r
8649         // クライアントオプションの初期化\r
8650         CmGenerateNewAccountName(hWnd, a->ClientOption->AccountName, sizeof(a->ClientOption->AccountName));\r
8651         a->ClientOption->Port = 443;    // デフォルトポート番号\r
8652         a->ClientOption->NumRetry = INFINITE;\r
8653         a->ClientOption->RetryInterval = 15;\r
8654         a->ClientOption->MaxConnection = 1;\r
8655         a->ClientOption->HalfConnection = false;\r
8656         a->ClientOption->UseEncrypt = true;\r
8657         a->ClientOption->AdditionalConnectionInterval = 1;\r
8658 \r
8659         if (cm->Client->Unix)\r
8660         {\r
8661                 a->ClientOption->NoRoutingTracking = true;\r
8662         }\r
8663 \r
8664         a->ClientAuth = ZeroMalloc(sizeof(CLIENT_AUTH));\r
8665 \r
8666         // パスワード認証\r
8667         a->ClientAuth->AuthType = CLIENT_AUTHTYPE_PASSWORD;\r
8668 \r
8669         return a;\r
8670 }\r
8671 \r
8672 // インポート名の作成\r
8673 void CmGenerateImportName(HWND hWnd, wchar_t *name, UINT size, wchar_t *old_name)\r
8674 {\r
8675         UINT i;\r
8676         // 引数チェック\r
8677         if (name == NULL || hWnd == NULL)\r
8678         {\r
8679                 return;\r
8680         }\r
8681 \r
8682         for (i = 1;;i++)\r
8683         {\r
8684                 wchar_t tmp[MAX_SIZE];\r
8685                 if (i == 1)\r
8686                 {\r
8687                         UniFormat(tmp, sizeof(tmp), _UU("CM_IMPORT_NAME_1"), old_name);\r
8688                 }\r
8689                 else\r
8690                 {\r
8691                         UniFormat(tmp, sizeof(tmp), _UU("CM_IMPORT_NAME_2"), old_name, i);\r
8692                 }\r
8693 \r
8694                 if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)\r
8695                 {\r
8696                         UniStrCpy(name, size, tmp);\r
8697                         return;\r
8698                 }\r
8699         }\r
8700 }\r
8701 \r
8702 // コピー名の作成\r
8703 void CmGenerateCopyName(HWND hWnd, wchar_t *name, UINT size, wchar_t *old_name)\r
8704 {\r
8705         UINT i;\r
8706         // 引数チェック\r
8707         if (name == NULL || hWnd == NULL)\r
8708         {\r
8709                 return;\r
8710         }\r
8711 \r
8712         for (i = 1;;i++)\r
8713         {\r
8714                 wchar_t tmp[MAX_SIZE];\r
8715                 if (i == 1)\r
8716                 {\r
8717                         UniFormat(tmp, sizeof(tmp), _UU("CM_COPY_NAME_1"), old_name);\r
8718                 }\r
8719                 else\r
8720                 {\r
8721                         UniFormat(tmp, sizeof(tmp), _UU("CM_COPY_NAME_2"), i, old_name);\r
8722                 }\r
8723 \r
8724                 if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)\r
8725                 {\r
8726                         UniStrCpy(name, size, tmp);\r
8727                         return;\r
8728                 }\r
8729         }\r
8730 }\r
8731 \r
8732 // 新しいアカウント名の作成\r
8733 void CmGenerateNewAccountName(HWND hWnd, wchar_t *name, UINT size)\r
8734 {\r
8735         UINT i;\r
8736         // 引数チェック\r
8737         if (name == NULL || hWnd == NULL)\r
8738         {\r
8739                 return;\r
8740         }\r
8741 \r
8742         for (i = 1;;i++)\r
8743         {\r
8744                 wchar_t tmp[MAX_SIZE];\r
8745                 if (i == 1)\r
8746                 {\r
8747                         UniFormat(tmp, sizeof(tmp), _UU("CM_NEW_ACCOUNT_NAME_1"));\r
8748                 }\r
8749                 else\r
8750                 {\r
8751                         UniFormat(tmp, sizeof(tmp), _UU("CM_NEW_ACCOUNT_NAME_2"), i);\r
8752                 }\r
8753 \r
8754                 if (LvSearchStr(hWnd, L_ACCOUNT, 0, tmp) == INFINITE)\r
8755                 {\r
8756                         UniStrCpy(name, size, tmp);\r
8757                         return;\r
8758                 }\r
8759         }\r
8760 }\r
8761 \r
8762 // ポリシー一覧を表示する\r
8763 void CmPolicyDlgPrint(HWND hWnd, CM_POLICY *p)\r
8764 {\r
8765         CmPolicyDlgPrintEx(hWnd, p, false);\r
8766 }\r
8767 void CmPolicyDlgPrintEx(HWND hWnd, CM_POLICY *p, bool cascade_mode)\r
8768 {\r
8769         CmPolicyDlgPrintEx2(hWnd, p, cascade_mode, POLICY_CURRENT_VERSION);\r
8770 }\r
8771 void CmPolicyDlgPrintEx2(HWND hWnd, CM_POLICY *p, bool cascade_mode, bool ver)\r
8772 {\r
8773         POLICY *pol;\r
8774         UINT i;\r
8775         LVB *b;\r
8776         // 引数チェック\r
8777         if (hWnd == NULL || p == NULL)\r
8778         {\r
8779                 return;\r
8780         }\r
8781 \r
8782         pol = p->Policy;\r
8783 \r
8784         b = LvInsertStart();\r
8785 \r
8786         for (i = 0;i < NUM_POLICY_ITEM;i++)\r
8787         {\r
8788                 wchar_t tmp[MAX_SIZE];\r
8789 \r
8790                 if (cascade_mode)\r
8791                 {\r
8792                         if (PolicyIsSupportedForCascade(i) == false)\r
8793                         {\r
8794                                 continue;\r
8795                         }\r
8796                 }\r
8797 \r
8798                 if (IS_POLICY_FOR_CURRENT_VER(i, ver))\r
8799                 {\r
8800                         if (policy_item[i].TypeInt == false)\r
8801                         {\r
8802                                 // bool 型\r
8803                                 UniStrCpy(tmp, sizeof(tmp), POLICY_BOOL(pol, i) ? _UU("POL_BOOL_ENABLE") : (p->Extension ? _UU("POL_BOOL_DISABLE_EX") : _UU("POL_BOOL_DISABLE")));\r
8804                         }\r
8805                         else\r
8806                         {\r
8807                                 // int 型\r
8808                                 if (policy_item[i].AllowZero && POLICY_INT(pol, i) == 0)\r
8809                                 {\r
8810                                         UniStrCpy(tmp, sizeof(tmp), _UU("POL_INT_ZERO"));\r
8811                                 }\r
8812                                 else\r
8813                                 {\r
8814                                         UniFormat(tmp, sizeof(tmp), _UU(policy_item[i].FormatStr), POLICY_INT(pol, i));\r
8815                                 }\r
8816                         }\r
8817 \r
8818                         LvInsertAdd(b, ICO_MACHINE, (void *)i, 2, GetPolicyTitle(i), tmp);\r
8819                 }\r
8820         }\r
8821 \r
8822         LvInsertEnd(b, hWnd, L_POLICY);\r
8823 }\r
8824 \r
8825 // ポリシー一覧ダイアログ\r
8826 UINT CmPolicyDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
8827 {\r
8828         CM_POLICY *p = (CM_POLICY *)param;\r
8829         NMHDR *n;\r
8830         // 引数チェック\r
8831         if (hWnd == NULL)\r
8832         {\r
8833                 return 0;\r
8834         }\r
8835 \r
8836         switch (msg)\r
8837         {\r
8838         case WM_INITDIALOG:\r
8839                 FormatText(hWnd, 0, p->AccountName);\r
8840                 FormatText(hWnd, S_TITLE, p->AccountName);\r
8841                 p->hWnd = hWnd;\r
8842                 if (p->CmStatus != NULL)\r
8843                 {\r
8844                         p->CmStatus->hWndPolicy = hWnd;\r
8845                 }\r
8846 \r
8847                 // カラム初期化\r
8848                 LvInit(hWnd, L_POLICY);\r
8849                 LvInsertColumn(hWnd, L_POLICY, 0, _UU("POL_TITLE_STR"), 375);\r
8850                 LvInsertColumn(hWnd, L_POLICY, 1, _UU("POL_VALUE_STR"), 100);\r
8851 \r
8852                 // 表示\r
8853                 CmPolicyDlgPrint(hWnd, p);\r
8854 \r
8855                 // 1 つ目を選択\r
8856                 LvSelect(hWnd, L_POLICY, 0);\r
8857                 break;\r
8858 \r
8859         case WM_COMMAND:\r
8860                 switch (wParam)\r
8861                 {\r
8862                 case IDOK:\r
8863                 case IDCANCEL:\r
8864                         Close(hWnd);\r
8865                         break;\r
8866                 }\r
8867                 break;\r
8868 \r
8869         case WM_NOTIFY:\r
8870                 n = (NMHDR *)lParam;\r
8871                 switch (n->idFrom)\r
8872                 {\r
8873                 case L_POLICY:\r
8874                         switch (n->code)\r
8875                         {\r
8876                         case LVN_ITEMCHANGED:\r
8877                                 // 選択変更\r
8878                                 if (LvIsSelected(hWnd, L_POLICY) == false)\r
8879                                 {\r
8880                                         SetText(hWnd, S_DESCRIPTION, L"");\r
8881                                 }\r
8882                                 else\r
8883                                 {\r
8884                                         UINT index = LvGetSelected(hWnd, L_POLICY);\r
8885                                         UINT id = (UINT)LvGetParam(hWnd, L_POLICY, index);\r
8886                                         if (id < NUM_POLICY_ITEM)\r
8887                                         {\r
8888                                                 SetText(hWnd, S_DESCRIPTION, GetPolicyDescription(id));\r
8889                                         }\r
8890                                 }\r
8891                                 break;\r
8892                         }\r
8893                         break;\r
8894                 }\r
8895                 break;\r
8896 \r
8897         case WM_CLOSE:\r
8898                 EndDialog(hWnd, 0);\r
8899                 break;\r
8900         }\r
8901 \r
8902         LvSortHander(hWnd, msg, wParam, lParam, L_POLICY);\r
8903 \r
8904         return 0;\r
8905 }\r
8906 \r
8907 // ポリシー一覧ダイアログの表示\r
8908 void CmPolicyDlg(HWND hWnd, CM_STATUS *st)\r
8909 {\r
8910         RPC_CLIENT_GET_CONNECTION_STATUS s;\r
8911         POLICY *policy;\r
8912         CM_POLICY cp;\r
8913         // 引数チェック\r
8914         if (hWnd == NULL || st == NULL)\r
8915         {\r
8916                 return;\r
8917         }\r
8918 \r
8919         // ポリシーの取得\r
8920         Zero(&s, sizeof(s));\r
8921         UniStrCpy(s.AccountName, sizeof(s.AccountName), st->AccountName);\r
8922         if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)\r
8923         {\r
8924                 return;\r
8925         }\r
8926         if (s.Active == false)\r
8927         {\r
8928                 return;\r
8929         }\r
8930 \r
8931         policy = &s.Policy;\r
8932 \r
8933         Zero(&cp, sizeof(cp));\r
8934         UniStrCpy(cp.AccountName, sizeof(cp.AccountName), st->AccountName);\r
8935         cp.Policy = policy;\r
8936         cp.CmStatus = st;\r
8937 \r
8938         Dialog(hWnd, D_CM_POLICY, CmPolicyDlgProc, &cp);\r
8939 \r
8940         st->hWndPolicy = NULL;\r
8941 \r
8942         CiFreeClientGetConnectionStatus(&s);\r
8943 }\r
8944 \r
8945 // 証明書の表示\r
8946 void CmStatusDlgPrintCert(HWND hWnd, CM_STATUS *st, bool server)\r
8947 {\r
8948         RPC_CLIENT_GET_CONNECTION_STATUS s;\r
8949         X *x, *issuer;\r
8950         // 引数チェック\r
8951         if (hWnd == NULL || st == NULL)\r
8952         {\r
8953                 return;\r
8954         }\r
8955 \r
8956         // 最新情報を取得する\r
8957         Zero(&s, sizeof(s));\r
8958         UniStrCpy(s.AccountName, sizeof(s.AccountName), st->AccountName);\r
8959         if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)\r
8960         {\r
8961                 Close(hWnd);\r
8962                 return;\r
8963         }\r
8964 \r
8965         if (s.Active == false)\r
8966         {\r
8967                 // 接続切断\r
8968                 Close(hWnd);\r
8969                 return;\r
8970         }\r
8971 \r
8972         if (server == false)\r
8973         {\r
8974                 // クライアント証明書の表示\r
8975                 x = s.ClientX;\r
8976         }\r
8977         else\r
8978         {\r
8979                 // サーバー証明書の表示\r
8980                 x = s.ServerX;\r
8981         }\r
8982 \r
8983         cm->WindowCount++;\r
8984         issuer = CmGetIssuer(x);\r
8985         CertDlg(hWnd, x, issuer, true);\r
8986         FreeX(issuer);\r
8987         cm->WindowCount--;\r
8988 \r
8989         CiFreeClientGetConnectionStatus(&s);\r
8990 }\r
8991 \r
8992 // ステータスダイアログの情報を表示\r
8993 void CmStatusDlgPrint(HWND hWnd, CM_STATUS *cmst)\r
8994 {\r
8995         RPC_CLIENT_GET_CONNECTION_STATUS s;\r
8996         LVB *b;\r
8997         // 引数チェック\r
8998         if (hWnd == NULL || cmst == NULL)\r
8999         {\r
9000                 return;\r
9001         }\r
9002 \r
9003         // 最新情報を取得する\r
9004         Zero(&s, sizeof(s));\r
9005         UniStrCpy(s.AccountName, sizeof(s.AccountName), cmst->AccountName);\r
9006         if (CALL(hWnd, CcGetAccountStatus(cm->Client, &s)) == false)\r
9007         {\r
9008                 Close(hWnd);\r
9009                 return;\r
9010         }\r
9011 \r
9012         if (s.Active == false)\r
9013         {\r
9014                 // 接続切断\r
9015                 Close(hWnd);\r
9016                 return;\r
9017         }\r
9018 \r
9019         // ステータスダイアログのリストボックスにステータスを表示する\r
9020         b = LvInsertStart();\r
9021         CmPrintStatusToListView(b, &s);\r
9022         LvInsertEnd(b, hWnd, L_STATUS);\r
9023 \r
9024         LvAutoSize(hWnd, L_STATUS);\r
9025 \r
9026         SetEnable(hWnd, B_POLICY, s.Connected);\r
9027 \r
9028         SetEnable(hWnd, B_SERVER_CERT, s.ServerX != NULL);\r
9029         SetEnable(hWnd, B_CLIENT_CERT, s.ClientX != NULL);\r
9030 \r
9031         CiFreeClientGetConnectionStatus(&s);\r
9032 }\r
9033 \r
9034 // ステータスダイアログのリストボックスにステータスを表示する\r
9035 void CmPrintStatusToListView(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s)\r
9036 {\r
9037         CmPrintStatusToListViewEx(b, s, false);\r
9038 }\r
9039 void CmPrintStatusToListViewEx(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s, bool server_mode)\r
9040 {\r
9041         wchar_t tmp[MAX_SIZE];\r
9042         char str[MAX_SIZE];\r
9043         char vv[128];\r
9044         // 引数チェック\r
9045         if (b == NULL || s == NULL)\r
9046         {\r
9047                 return;\r
9048         }\r
9049 \r
9050         if (server_mode == false)\r
9051         {\r
9052                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_ACCOUNT_NAME"), s->AccountName);\r
9053 \r
9054                 if (s->Connected == false)\r
9055                 {\r
9056                         wchar_t *st = _UU("CM_ST_CONNECTED_FALSE");\r
9057                         switch (s->SessionStatus)\r
9058                         {\r
9059                         case CLIENT_STATUS_CONNECTING:\r
9060                                 st = _UU("CM_ST_CONNECTING");\r
9061                                 break;\r
9062                         case CLIENT_STATUS_NEGOTIATION:\r
9063                                 st = _UU("CM_ST_NEGOTIATION");\r
9064                                 break;\r
9065                         case CLIENT_STATUS_AUTH:\r
9066                                 st = _UU("CM_ST_AUTH");\r
9067                                 break;\r
9068                         case CLIENT_STATUS_ESTABLISHED:\r
9069                                 st = _UU("CM_ST_ESTABLISHED");\r
9070                                 break;\r
9071                         case CLIENT_STATUS_RETRY:\r
9072                                 st = _UU("CM_ST_RETRY");\r
9073                                 break;\r
9074                         case CLIENT_STATUS_IDLE:\r
9075                                 st = _UU("CM_ST_IDLE");\r
9076                                 break;\r
9077                         }\r
9078                         LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CONNECTED"), st);\r
9079                 }\r
9080                 else\r
9081                 {\r
9082                         LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CONNECTED"), _UU("CM_ST_CONNECTED_TRUE"));\r
9083                 }\r
9084         }\r
9085 \r
9086         if (s->Connected)\r
9087         {\r
9088                 if (s->VLanId == 0)\r
9089                 {\r
9090                         UniStrCpy(tmp, sizeof(tmp), _UU("CM_ST_NO_VLAN"));\r
9091                 }\r
9092                 else\r
9093                 {\r
9094                         UniToStru(tmp, s->VLanId);\r
9095                 }\r
9096 \r
9097                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_VLAN_ID"), tmp);\r
9098 \r
9099                 if (server_mode == false)\r
9100                 {\r
9101                         StrToUni(tmp, sizeof(tmp), s->ServerName);\r
9102                         LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_NAME"), tmp);\r
9103 \r
9104                         UniFormat(tmp, sizeof(tmp), _UU("CM_ST_PORT_TCP"), s->ServerPort);\r
9105                         LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_PORT"), tmp);\r
9106                 }\r
9107 \r
9108                 StrToUni(tmp, sizeof(tmp), s->ServerProductName);\r
9109                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_NAME"), tmp);\r
9110 \r
9111                 UniFormat(tmp, sizeof(tmp), L"%u.%02u", s->ServerProductVer / 100, s->ServerProductVer % 100);\r
9112                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_VER"), tmp);\r
9113                 UniFormat(tmp, sizeof(tmp), L"Build %u", s->ServerProductBuild);\r
9114                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SERVER_P_BUILD"), tmp);\r
9115         }\r
9116 \r
9117         GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->StartTime), NULL);\r
9118         LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_START_TIME"), tmp);\r
9119         GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->FirstConnectionEstablisiedTime), NULL);\r
9120         LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_FIRST_ESTAB_TIME"), s->FirstConnectionEstablisiedTime == 0 ? _UU("CM_ST_NONE") : tmp);\r
9121 \r
9122         if (s->Connected)\r
9123         {\r
9124                 GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->CurrentConnectionEstablishTime), NULL);\r
9125                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CURR_ESTAB_TIME"), tmp);\r
9126         }\r
9127 \r
9128         if (server_mode == false)\r
9129         {\r
9130                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_STR"), s->NumConnectionsEatablished);\r
9131                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_ESTABLISHED"), tmp);\r
9132         }\r
9133 \r
9134         if (s->Connected)\r
9135         {\r
9136                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_HALF_CONNECTION"), s->HalfConnection ? _UU("CM_ST_HALF_TRUE") : _UU("CM_ST_HALF_FALSE"));\r
9137 \r
9138                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_QOS"), s->QoS ? _UU("CM_ST_QOS_TRUE") : _UU("CM_ST_QOS_FALSE"));\r
9139 \r
9140                 UniFormat(tmp, sizeof(tmp), L"%u", s->NumTcpConnections);\r
9141                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_TCP"), tmp);\r
9142 \r
9143                 if (s->HalfConnection)\r
9144                 {\r
9145                         UniFormat(tmp, sizeof(tmp), L"%u", s->NumTcpConnectionsUpload);\r
9146                         LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_TCP_UPLOAD"), tmp);\r
9147                         UniFormat(tmp, sizeof(tmp), L"%u", s->NumTcpConnectionsDownload);\r
9148                         LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_NUM_TCP_DOWNLOAD"), tmp);\r
9149                 }\r
9150 \r
9151                 UniFormat(tmp, sizeof(tmp), L"%u", s->MaxTcpConnections);\r
9152                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_MAX_TCP"), tmp);\r
9153 \r
9154                 if (s->UseEncrypt == false)\r
9155                 {\r
9156                         UniStrCpy(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_FALSE"));\r
9157                 }\r
9158                 else\r
9159                 {\r
9160                         if (StrLen(s->CipherName) != 0)\r
9161                         {\r
9162                                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_TRUE"), s->CipherName);\r
9163                         }\r
9164                         else\r
9165                         {\r
9166                                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_TRUE2"));\r
9167                         }\r
9168                 }\r
9169                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_USE_ENCRYPT"), tmp);\r
9170 \r
9171                 if (s->UseCompress)\r
9172                 {\r
9173                         UINT percent = 0;\r
9174                         if ((s->TotalRecvSize + s->TotalSendSize) > 0)\r
9175                         {\r
9176                                 percent = (UINT)((UINT64)100 - (UINT64)(s->TotalRecvSizeReal + s->TotalSendSizeReal) * (UINT64)100 /\r
9177                                         (s->TotalRecvSize + s->TotalSendSize));\r
9178                                 percent = MAKESURE(percent, 0, 100);\r
9179                         }\r
9180 \r
9181                         UniFormat(tmp, sizeof(tmp), _UU("CM_ST_COMPRESS_TRUE"), percent);\r
9182                 }\r
9183                 else\r
9184                 {\r
9185                         UniStrCpy(tmp, sizeof(tmp), _UU("CM_ST_COMPRESS_FALSE"));\r
9186                 }\r
9187                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_USE_COMPRESS"), tmp);\r
9188 \r
9189                 StrToUni(tmp, sizeof(tmp), s->SessionName);\r
9190                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SESSION_NAME"), tmp);\r
9191 \r
9192                 StrToUni(tmp, sizeof(tmp), s->ConnectionName);\r
9193                 if (UniStrCmpi(tmp, L"INITING") != 0)\r
9194                 {\r
9195                         LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_CONNECTION_NAME"), tmp);\r
9196                 }\r
9197 \r
9198                 BinToStr(str, sizeof(str), s->SessionKey, sizeof(s->SessionKey));\r
9199                 StrToUni(tmp, sizeof(tmp), str);\r
9200                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SESSION_KEY"), tmp);\r
9201 \r
9202                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_BRIDGE_MODE"), s->IsBridgeMode ? _UU("CM_ST_YES") : _UU("CM_ST_NO"));\r
9203 \r
9204                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_MONITOR_MODE"), s->IsMonitorMode ? _UU("CM_ST_YES") : _UU("CM_ST_NO"));\r
9205 \r
9206                 ToStr3(vv, sizeof(vv), s->TotalSendSize);\r
9207                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);\r
9208                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_SIZE"), tmp);\r
9209 \r
9210                 ToStr3(vv, sizeof(vv), s->TotalRecvSize);\r
9211                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);\r
9212                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_SIZE"), tmp);\r
9213 \r
9214                 ToStr3(vv, sizeof(vv), s->Traffic.Send.UnicastCount);\r
9215                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);\r
9216                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_UCAST_NUM"), tmp);\r
9217 \r
9218                 ToStr3(vv, sizeof(vv), s->Traffic.Send.UnicastBytes);\r
9219                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);\r
9220                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_UCAST_SIZE"), tmp);\r
9221 \r
9222                 ToStr3(vv, sizeof(vv), s->Traffic.Send.BroadcastCount);\r
9223                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);\r
9224                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_BCAST_NUM"), tmp);\r
9225 \r
9226                 ToStr3(vv, sizeof(vv), s->Traffic.Send.BroadcastBytes);\r
9227                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);\r
9228                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_SEND_BCAST_SIZE"), tmp);\r
9229 \r
9230                 ToStr3(vv, sizeof(vv), s->Traffic.Recv.UnicastCount);\r
9231                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);\r
9232                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_UCAST_NUM"), tmp);\r
9233 \r
9234                 ToStr3(vv, sizeof(vv), s->Traffic.Recv.UnicastBytes);\r
9235                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);\r
9236                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_UCAST_SIZE"), tmp);\r
9237 \r
9238                 ToStr3(vv, sizeof(vv), s->Traffic.Recv.BroadcastCount);\r
9239                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_NUM_PACKET_STR"), vv);\r
9240                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_BCAST_NUM"), tmp);\r
9241 \r
9242                 ToStr3(vv, sizeof(vv), s->Traffic.Recv.BroadcastBytes);\r
9243                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_SIZE_BYTE_STR"), vv);\r
9244                 LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_RECV_BCAST_SIZE"), tmp);\r
9245         }\r
9246 }\r
9247 \r
9248 // ステータスダイアログプロシージャ\r
9249 UINT CmStatusDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
9250 {\r
9251         wchar_t tmp[MAX_SIZE];\r
9252         CM_STATUS *s = (CM_STATUS *)param;\r
9253         // 引数チェック\r
9254         if (hWnd == NULL)\r
9255         {\r
9256                 return 0;\r
9257         }\r
9258 \r
9259         switch (msg)\r
9260         {\r
9261         case WM_INITDIALOG:\r
9262                 SetIcon(hWnd, 0, ICO_TOWER);\r
9263                 UniFormat(tmp, sizeof(tmp), _UU("CM_ST_TITLE"), s->AccountName);\r
9264                 SetText(hWnd, 0, tmp);\r
9265                 FormatText(hWnd, S_TITLE, s->AccountName);\r
9266                 DlgFont(hWnd, S_TITLE, 0, 1);\r
9267 \r
9268                 Add(cm->StatusWindowList, hWnd);\r
9269 \r
9270                 SetTimer(hWnd, 1, 500, NULL);\r
9271 \r
9272                 LvInitEx(hWnd, L_STATUS, true);\r
9273                 ListView_SetImageList(DlgItem(hWnd, L_STATUS), NULL, LVSIL_NORMAL);\r
9274                 ListView_SetImageList(DlgItem(hWnd, L_STATUS), NULL, LVSIL_SMALL);\r
9275                 LvInsertColumn(hWnd, L_STATUS, 0, _UU("CM_ST_COLUMN_1"), 160);\r
9276                 LvInsertColumn(hWnd, L_STATUS, 1, _UU("CM_ST_COLUMN_2"), 270);\r
9277 \r
9278                 CmStatusDlgPrint(hWnd, s);\r
9279 \r
9280                 break;\r
9281         case WM_TIMER:\r
9282                 switch (wParam)\r
9283                 {\r
9284                 case 1:\r
9285                         KillTimer(hWnd, 1);\r
9286                         CmStatusDlgPrint(hWnd, s);\r
9287                         SetTimer(hWnd, 1, 500, NULL);\r
9288                         break;\r
9289                 }\r
9290                 break;\r
9291         case WM_COMMAND:\r
9292                 switch (wParam)\r
9293                 {\r
9294                 case IDOK:\r
9295                 case IDCANCEL:\r
9296                         // 閉じる\r
9297                         Close(hWnd);\r
9298                         break;\r
9299                 case B_POLICY:\r
9300                         // ポリシー表示\r
9301                         CmPolicyDlg(hWnd, s);\r
9302                         break;\r
9303                 case B_SERVER_CERT:\r
9304                         CmStatusDlgPrintCert(hWnd, s, true);\r
9305                         break;\r
9306                 case B_CLIENT_CERT:\r
9307                         CmStatusDlgPrintCert(hWnd, s, false);\r
9308                         break;\r
9309                 }\r
9310                 break;\r
9311         case WM_CLOSE:\r
9312                 Delete(cm->StatusWindowList, hWnd);\r
9313                 if (s->hWndPolicy != NULL)\r
9314                 {\r
9315                         EndDialog(s->hWndPolicy, false);\r
9316                         s->hWndPolicy = NULL;\r
9317                 }\r
9318                 EndDialog(hWnd, false);\r
9319                 break;\r
9320         }\r
9321 \r
9322         return 0;\r
9323 }\r
9324 \r
9325 // ステータスダイアログの表示\r
9326 void CmStatusDlg(HWND hWnd, wchar_t *account_name)\r
9327 {\r
9328         CM_STATUS *s;\r
9329         // 引数チェック\r
9330         if (hWnd == NULL || account_name == NULL)\r
9331         {\r
9332                 return;\r
9333         }\r
9334 \r
9335         s = ZeroMalloc(sizeof(CM_STATUS));\r
9336         UniStrCpy(s->AccountName, sizeof(s->AccountName), account_name);\r
9337 \r
9338         Dialog(hWnd, D_CONNECTION_STATUS, CmStatusDlgProc, s);\r
9339 \r
9340         Free(s);\r
9341 }\r
9342 \r
9343 // ステータスの表示\r
9344 void CmStatus(HWND hWnd, wchar_t *account_name)\r
9345 {\r
9346         UINT i;\r
9347         wchar_t tmp[MAX_SIZE];\r
9348         // 引数チェック\r
9349         if (hWnd == NULL || account_name == NULL)\r
9350         {\r
9351                 return;\r
9352         }\r
9353 \r
9354         UniFormat(tmp, sizeof(tmp), _UU("CM_ST_TITLE"), account_name);\r
9355 \r
9356         for (i = 0;i < LIST_NUM(cm->StatusWindowList);i++)\r
9357         {\r
9358                 HWND h = LIST_DATA(cm->StatusWindowList, i);\r
9359                 if (h != NULL)\r
9360                 {\r
9361                         wchar_t tmp2[MAX_SIZE];\r
9362                         if (GetTxt(h, 0, tmp2, sizeof(tmp2)))\r
9363                         {\r
9364                                 if (UniStrCmpi(tmp2, tmp) == 0)\r
9365                                 {\r
9366                                         SetActiveWindow(h);\r
9367                                         return;\r
9368                                 }\r
9369                         }\r
9370                 }\r
9371         }\r
9372 \r
9373         CmStatusDlg(hWnd, account_name);\r
9374 }\r
9375 \r
9376 // 削除\r
9377 void CmDeleteAccount(HWND hWnd, wchar_t *account_name)\r
9378 {\r
9379         RPC_CLIENT_DELETE_ACCOUNT c;\r
9380         // 引数チェック\r
9381         if (hWnd == NULL || account_name == NULL)\r
9382         {\r
9383                 return;\r
9384         }\r
9385         Zero(&c, sizeof(c));\r
9386         UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);\r
9387 \r
9388         CmVoice("delete_config_1");\r
9389         if (MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DELETE_ACCOUNT_MSG"), account_name)\r
9390                 == IDNO)\r
9391         {\r
9392                 return;\r
9393         }\r
9394 \r
9395         CALL(hWnd, CcDeleteAccount(cm->Client, &c));\r
9396         CmVoice("delete_config_2");\r
9397 }\r
9398 \r
9399 // 切断\r
9400 void CmDisconnect(HWND hWnd, wchar_t *account_name)\r
9401 {\r
9402         RPC_CLIENT_CONNECT c;\r
9403         // 引数チェック\r
9404         if (hWnd == NULL || account_name == NULL)\r
9405         {\r
9406                 return;\r
9407         }\r
9408 \r
9409         Zero(&c, sizeof(c));\r
9410         UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);\r
9411 \r
9412         cm->PositiveDisconnectFlag = true;\r
9413 \r
9414         CALL(hWnd, CcDisconnect(cm->Client, &c));\r
9415 }\r
9416 \r
9417 // 宣伝ウインドウの表示\r
9418 void SmShowPublicVpnServerHtml(HWND hWnd)\r
9419 {\r
9420         char *langstr = _SS("LANGSTR");\r
9421 \r
9422         if(StrCmpi(langstr, "Japanese") == 0)\r
9423         {\r
9424                 ShowHtml(hWnd, PUBLIC_SERVER_HTML, PUBLIC_SERVER_TAG);\r
9425         }\r
9426         else\r
9427         {\r
9428                 ShowHtml(hWnd, PUBLIC_SERVER_HTML_EN, PUBLIC_SERVER_TAG);\r
9429         }\r
9430 }\r
9431 \r
9432 // 接続\r
9433 void CmConnect(HWND hWnd, wchar_t *account_name)\r
9434 {\r
9435         RPC_CLIENT_CONNECT c;\r
9436         UINT i;\r
9437         // 引数チェック\r
9438         if (hWnd == NULL || account_name == NULL)\r
9439         {\r
9440                 return;\r
9441         }\r
9442 \r
9443         if (IsEnable(hWnd, 0) == false)\r
9444         {\r
9445                 return;\r
9446         }\r
9447 \r
9448         if (hWnd == cm->hMainWnd)\r
9449         {\r
9450                 if (LvNum(hWnd, L_VLAN) == 0 && cm->Client->Win9x)\r
9451                 {\r
9452                         if (MsgBox(hWnd, MB_ICONINFORMATION | MB_YESNO, _UU("CM_NO_VLAN_2")) == IDNO)\r
9453                         {\r
9454                                 return;\r
9455                         }\r
9456                         else\r
9457                         {\r
9458                                 if (cm->server_name == NULL)\r
9459                                 {\r
9460                                         Command(hWnd, CMD_NEW_VLAN);\r
9461                                         return;\r
9462                                 }\r
9463                                 else\r
9464                                 {\r
9465                                         MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_VLAN_REMOTE_ERROR"));\r
9466                                 }\r
9467                                 return;\r
9468                         }\r
9469                 }\r
9470         }\r
9471 \r
9472         // 警告を表示 (必要な場合)\r
9473         if (CmWarningDesktop(hWnd, account_name) == false)\r
9474         {\r
9475                 return;\r
9476         }\r
9477 \r
9478         if (cm->server_name == NULL)\r
9479         {\r
9480                 if (cm->BadProcessChecked == false)\r
9481                 {\r
9482                         cm->BadProcessChecked = true;\r
9483 \r
9484                         CheckBadProcesses(hWnd);\r
9485                 }\r
9486         }\r
9487 \r
9488         if (cm->server_name == NULL)\r
9489         {\r
9490                 // Windows バージョンチェック\r
9491                 RPC_WINVER winver;\r
9492                 wchar_t winver_msg_client[3800];\r
9493 \r
9494                 GetWinVer(&winver);\r
9495                 Zero(winver_msg_client, sizeof(winver_msg_client));\r
9496 \r
9497                 if (IsSupportedWinVer(&winver) == false)\r
9498                 {\r
9499                         SYSTEMTIME st;\r
9500 \r
9501                         LocalTime(&st);\r
9502 \r
9503                         UniFormat(winver_msg_client, sizeof(winver_msg_client), _UU("WINVER_ERROR_FORMAT"),\r
9504                                 _UU("WINVER_ERROR_PC_LOCAL"),\r
9505                                 winver.Title,\r
9506                                 _UU("WINVER_ERROR_VPNCLIENT"),\r
9507                                 SUPPORTED_WINDOWS_LIST,\r
9508                                 _UU("WINVER_ERROR_PC_LOCAL"),\r
9509                                 _UU("WINVER_ERROR_VPNCLIENT"),\r
9510                                 _UU("WINVER_ERROR_VPNCLIENT"),\r
9511                                 _UU("WINVER_ERROR_VPNCLIENT"),\r
9512                                 st.wYear, st.wMonth);\r
9513                 }\r
9514 \r
9515                 if (UniIsEmptyStr(winver_msg_client) == false)\r
9516                 {\r
9517                         OnceMsgEx(hWnd, _UU("WINVER_TITLE"), winver_msg_client,\r
9518                                 true, ICO_WARNING, NULL);\r
9519                 }\r
9520         }\r
9521 \r
9522         i = LvSearchStr(hWnd, L_ACCOUNT, 0, account_name);\r
9523         if (i != INFINITE)\r
9524         {\r
9525                 wchar_t *tmp = LvGetStr(hWnd, L_ACCOUNT, i, 2);\r
9526                 if (tmp != NULL)\r
9527                 {\r
9528                         wchar_t tag[MAX_SIZE];\r
9529                         StrToUni(tag, sizeof(tag), PUBLIC_SERVER_NAME);\r
9530 \r
9531                         if (UniSearchStrEx(tmp, tag, 0, false) != INFINITE)\r
9532                         {\r
9533                                 SmShowPublicVpnServerHtml(hWnd);\r
9534                         }\r
9535 \r
9536                         Free(tmp);\r
9537                 }\r
9538         }\r
9539 \r
9540         Zero(&c, sizeof(c));\r
9541         UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);\r
9542 \r
9543         CmSetForegroundProcessToCnService();\r
9544 \r
9545         if (CALL(hWnd, CcConnect(cm->Client, &c)))\r
9546         {\r
9547                 cm->ConnectStartedFlag = true;\r
9548         }\r
9549 }\r
9550 \r
9551 // 指定されたメニュー項目を太字にするかどうか判断する\r
9552 bool CmIsBold(UINT id)\r
9553 {\r
9554         return false;\r
9555 }\r
9556 \r
9557 // 指定されたメニュー項目を有効にするかどうか判断する\r
9558 bool CmIsEnabled(HWND hWnd, UINT id)\r
9559 {\r
9560         UINT index;\r
9561         wchar_t *name;\r
9562         bool locked = false;\r
9563         // 引数チェック\r
9564         if (hWnd == NULL)\r
9565         {\r
9566                 return false;\r
9567         }\r
9568 \r
9569         locked = cm->CmSetting.LockMode;\r
9570 \r
9571         if (locked)\r
9572         {\r
9573                 switch (id)\r
9574                 {\r
9575                 case CMD_NEW:\r
9576                 case CMD_CLONE:\r
9577                 case CMD_IMPORT_ACCOUNT:\r
9578                 case CMD_DELETE:\r
9579                 case CMD_TCPIP:\r
9580                 case CMD_OPTION:\r
9581                 case CMD_VOIDE_NONE:\r
9582                 case CMD_VOICE_NORMAL:\r
9583                 case CMD_VOICE_ODD:\r
9584                 case CMD_STARTUP:\r
9585                 case CMD_NOSTARTUP:\r
9586                 case CMD_TRAFFIC:\r
9587                 case CMD_MMCSS:\r
9588                         return false;\r
9589                 case CMD_NEW_VLAN:\r
9590                 case CMD_ENABLE_VLAN:\r
9591                 case CMD_DISABLE_VLAN:\r
9592                 case CMD_DELETE_VLAN:\r
9593                 case CMD_REINSTALL:\r
9594                 case CMD_WINNET:\r
9595                         if (cm->CmEasyModeSupported)\r
9596                         {\r
9597                                 return false;\r
9598                         }\r
9599                 }\r
9600         }\r
9601 \r
9602         switch (id)\r
9603         {\r
9604         case CMD_SHOWPORT:\r
9605         case CMD_GRID:\r
9606                 if (cm->IconView)\r
9607                 {\r
9608                         return false;\r
9609                 }\r
9610                 return true;\r
9611         case CMD_TCPIP:\r
9612                 if (MsIsTcpConfigSupported() == false)\r
9613                 {\r
9614                         return false;\r
9615                 }\r
9616                 return cm->server_name != NULL ? false : true;\r
9617         case CMD_MMCSS:\r
9618                 if (MsIsVista() == false || IsEmptyStr(cm->server_name) == false)\r
9619                 {\r
9620                         return false;\r
9621                 }\r
9622                 if (OS_IS_SERVER(GetOsType()))\r
9623                 {\r
9624                         return false;\r
9625                 }\r
9626                 return true;\r
9627         case CMD_TRAYICON:\r
9628         case CMD_TRAFFIC:\r
9629                 return (cm->server_name == NULL);\r
9630         case CMD_NETIF:\r
9631                 if (MsIsNt() == false)\r
9632                 {\r
9633                         return false;\r
9634                 }\r
9635                 return (cm->server_name == NULL);\r
9636         case CMD_CM_SETTING:\r
9637                 return cm->CmSettingSupported;\r
9638         case CMD_CONNECT:\r
9639         case CMD_DISCONNECT:\r
9640         case CMD_STATUS:\r
9641         case CMD_RENAME:\r
9642         case CMD_DELETE:\r
9643                 if (LvIsMultiMasked(hWnd, L_ACCOUNT))\r
9644                 {\r
9645                         return false;\r
9646                 }\r
9647                 if (LvIsSelected(hWnd, L_ACCOUNT) == false)\r
9648                 {\r
9649                         return false;\r
9650                 }\r
9651                 else\r
9652                 {\r
9653                         // 選択されているアカウントが接続中かどうか判別する\r
9654                         UINT i = LvGetSelected(hWnd, L_ACCOUNT);\r
9655                         wchar_t *str = LvGetStr(hWnd, L_ACCOUNT, i, 1);\r
9656                         wchar_t *name = LvGetStr(hWnd, L_ACCOUNT, i, 0);\r
9657                         bool is_connected = false;\r
9658                         if (str != NULL)\r
9659                         {\r
9660                                 if (UniStrCmpi(str, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(str, _UU("CM_ACCOUNT_CONNECTING")) == 0)\r
9661                                 {\r
9662                                         is_connected = true;\r
9663                                 }\r
9664                                 Free(str);\r
9665                         }\r
9666                         if (name != NULL)\r
9667                         {\r
9668                                 if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_ASP")) == 0)\r
9669                                 {\r
9670                                         Free(name);\r
9671                                         return false;\r
9672                                 }\r
9673                                 Free(name);\r
9674                         }\r
9675                         if (id == CMD_CONNECT || id == CMD_RENAME || id == CMD_DELETE)\r
9676                         {\r
9677                                 return !is_connected;\r
9678                         }\r
9679                         else\r
9680                         {\r
9681                                 return is_connected;\r
9682                         }\r
9683                 }\r
9684                 break;\r
9685         case CMD_DISCONNECT_ALL:\r
9686                 if (CmGetNumConnected(hWnd) == 0)\r
9687                 {\r
9688                         return false;\r
9689                 }\r
9690                 else\r
9691                 {\r
9692                         return true;\r
9693                 }\r
9694         case CMD_SHORTCUT:\r
9695                 // ショートカットの作成\r
9696                 if (cm->Client->Rpc->Sock->RemoteIP.addr[0] != 127)\r
9697                 {\r
9698                         return false;\r
9699                 }\r
9700         case CMD_EXPORT_ACCOUNT:\r
9701                 if (LvIsMultiMasked(hWnd, L_ACCOUNT))\r
9702                 {\r
9703                         return false;\r
9704                 }\r
9705                 name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);\r
9706                 if (name != NULL)\r
9707                 {\r
9708                         if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_ASP")) == 0)\r
9709                         {\r
9710                                 Free(name);\r
9711                                 return false;\r
9712                         }\r
9713                         Free(name);\r
9714                 }\r
9715                 return LvIsSelected(hWnd, L_ACCOUNT);\r
9716         case CMD_CLONE:\r
9717                 if (LvIsMultiMasked(hWnd, L_ACCOUNT))\r
9718                 {\r
9719                         return false;\r
9720                 }\r
9721                 name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);\r
9722                 if (name != NULL)\r
9723                 {\r
9724                         if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_ASP")) == 0)\r
9725                         {\r
9726                                 Free(name);\r
9727                                 return false;\r
9728                         }\r
9729                         Free(name);\r
9730                 }\r
9731                 return LvIsSelected(hWnd, L_ACCOUNT);\r
9732         case CMD_STARTUP:\r
9733         case CMD_NOSTARTUP:\r
9734                 name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);\r
9735                 if (name != NULL)\r
9736                 {\r
9737                         if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_ASP")) == 0)\r
9738                         {\r
9739                                 Free(name);\r
9740                                 return false;\r
9741                         }\r
9742                         Free(name);\r
9743                 }\r
9744                 if (LvIsMultiMasked(hWnd, L_ACCOUNT))\r
9745                 {\r
9746                         return false;\r
9747                 }\r
9748                 if (LvIsSelected(hWnd, L_ACCOUNT) == false)\r
9749                 {\r
9750                         return false;\r
9751                 }\r
9752                 else\r
9753                 {\r
9754                         // 選択されているアカウントがスタートアップアカウントかどうか判別する\r
9755                         UINT i = LvGetSelected(hWnd, L_ACCOUNT);\r
9756                         bool is_startup = (bool)LvGetParam(hWnd, L_ACCOUNT, i);\r
9757                         if (id == CMD_STARTUP)\r
9758                         {\r
9759                                 return !is_startup;\r
9760                         }\r
9761                         else\r
9762                         {\r
9763                                 return is_startup;\r
9764                         }\r
9765                 }\r
9766                 break;\r
9767         case CMD_NEW_VLAN:\r
9768                 if (cm->Client->Unix == false && cm->Client->Win9x == false)\r
9769                 {\r
9770                         if (cm->server_name != NULL)\r
9771                         {\r
9772                                 return false;\r
9773                         }\r
9774                 }\r
9775                 if (cm->Client->Win9x)\r
9776                 {\r
9777                         if (LvNum(hWnd, L_VLAN) >= 1)\r
9778                         {\r
9779                                 // Win9x では 2 枚以上の仮想 LAN カードをインストールできない\r
9780                                 return false;\r
9781                         }\r
9782                 }\r
9783                 break;\r
9784         case CMD_PROPERTY:\r
9785                 name = LvGetSelectedStr(hWnd, L_ACCOUNT, 0);\r
9786                 if (name != NULL)\r
9787                 {\r
9788                         if (UniStrCmpi(name, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(name, _UU("CM_ASP")) == 0)\r
9789                         {\r
9790                                 Free(name);\r
9791                                 return false;\r
9792                         }\r
9793                         Free(name);\r
9794                 }\r
9795                 if (LvIsMultiMasked(hWnd, L_ACCOUNT))\r
9796                 {\r
9797                         return false;\r
9798                 }\r
9799                 return LvIsSelected(hWnd, L_ACCOUNT);\r
9800         case CMD_DELETE_VLAN:\r
9801                 if (LvIsMultiMasked(hWnd, L_VLAN))\r
9802                 {\r
9803                         return false;\r
9804                 }\r
9805                 return LvIsSelected(hWnd, L_VLAN);\r
9806         case CMD_ENABLE_VLAN:\r
9807                 if (cm->Client->Win9x)\r
9808                 {\r
9809                         return false;\r
9810                 }\r
9811                 if (LvIsMultiMasked(hWnd, L_VLAN))\r
9812                 {\r
9813                         return false;\r
9814                 }\r
9815                 index = LvGetSelected(hWnd, L_VLAN);\r
9816                 if (index == INFINITE)\r
9817                 {\r
9818                         return false;\r
9819                 }\r
9820                 else\r
9821                 {\r
9822                         wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 1);\r
9823                         if (s != NULL)\r
9824                         {\r
9825                                 if (UniStrCmpi(s, _UU("CM_VLAN_DISABLED")) == 0)\r
9826                                 {\r
9827                                         Free(s);\r
9828                                         return true;\r
9829                                 }\r
9830                                 Free(s);\r
9831                         }\r
9832                         return false;\r
9833                 }\r
9834                 break;\r
9835         case CMD_DISABLE_VLAN:\r
9836                 if (cm->Client->Win9x)\r
9837                 {\r
9838                         return false;\r
9839                 }\r
9840                 if (LvIsMultiMasked(hWnd, L_VLAN))\r
9841                 {\r
9842                         return false;\r
9843                 }\r
9844                 index = LvGetSelected(hWnd, L_VLAN);\r
9845                 if (index == INFINITE)\r
9846                 {\r
9847                         return false;\r
9848                 }\r
9849                 else\r
9850                 {\r
9851                         wchar_t *s = LvGetStr(hWnd, L_VLAN, index, 1);\r
9852                         if (s != NULL)\r
9853                         {\r
9854                                 if (UniStrCmpi(s, _UU("CM_VLAN_ENABLED")) == 0)\r
9855                                 {\r
9856                                         Free(s);\r
9857                                         return true;\r
9858                                 }\r
9859                                 Free(s);\r
9860                         }\r
9861                         return false;\r
9862                 }\r
9863                 break;\r
9864         case CMD_REINSTALL:\r
9865                 if (cm->server_name != NULL)\r
9866                 {\r
9867                         return false;\r
9868                 }\r
9869                 if (cm->Client->Win9x || cm->Client->Unix)\r
9870                 {\r
9871                         // Win9x と UNIX 系では仮想 LAN カードのアップグレード不可\r
9872                         return false;\r
9873                 }\r
9874                 if (LvIsMultiMasked(hWnd, L_VLAN))\r
9875                 {\r
9876                         return false;\r
9877                 }\r
9878                 return LvIsSelected(hWnd, L_VLAN);\r
9879         case CMD_WINNET:\r
9880                 {\r
9881                         UINT os_type = GetOsInfo()->OsType;\r
9882 \r
9883                         if (OS_IS_WINDOWS_NT(os_type) && GET_KETA(os_type, 100) >= 2)\r
9884                         {\r
9885                                 if (cm->server_name != NULL)\r
9886                                 {\r
9887                                         return false;\r
9888                                 }\r
9889 \r
9890                                 return true;\r
9891                         }\r
9892                         else\r
9893                         {\r
9894                                 return false;\r
9895                         }\r
9896                 }\r
9897                 break;\r
9898         case CMD_EXIT:\r
9899                 return cm->TrayInited;\r
9900         }\r
9901         return true;\r
9902 }\r
9903 \r
9904 // VLAN デバイス名を表示名に変換\r
9905 void CmVLanNameToPrintName(char *str, UINT size, char *name)\r
9906 {\r
9907         // 引数チェック\r
9908         if (str == NULL || name == NULL)\r
9909         {\r
9910                 return;\r
9911         }\r
9912 \r
9913         Format(str, size, VLAN_ADAPTER_NAME_TAG, name);\r
9914 }\r
9915 \r
9916 // 表示名を VLAN デバイス名に変換\r
9917 bool CmPrintNameToVLanName(char *name, UINT size, char *str)\r
9918 {\r
9919         // 引数チェック\r
9920         if (name == NULL || str == NULL)\r
9921         {\r
9922                 return false;\r
9923         }\r
9924 \r
9925         if (StartWith(str, VLAN_ADAPTER_NAME))\r
9926         {\r
9927                 if (StrLen(str) < (StrLen(VLAN_ADAPTER_NAME) + 3))\r
9928                 {\r
9929                         return false;\r
9930                 }\r
9931 \r
9932                 StrCpy(name, size, str + StrLen(VLAN_ADAPTER_NAME) + 3);\r
9933 \r
9934                 return true;\r
9935         }\r
9936 \r
9937         return false;\r
9938 }\r
9939 \r
9940 // アカウントリストの初期化\r
9941 void CmInitAccountList(HWND hWnd)\r
9942 {\r
9943         CmInitAccountListEx(hWnd, false);\r
9944 }\r
9945 void CmInitAccountListEx(HWND hWnd, bool easy)\r
9946 {\r
9947         UINT width[5];\r
9948         BUF *b;\r
9949         // 引数チェック\r
9950         if (hWnd == NULL)\r
9951         {\r
9952                 return;\r
9953         }\r
9954 \r
9955         // 設定読み込み\r
9956         b = MsRegReadBin(REG_CURRENT_USER, CM_REG_KEY, "AccountListColumnWidth");\r
9957         if ((b != NULL) && (b->Size == sizeof(width)))\r
9958         {\r
9959                 Copy(width, b->Buf, sizeof(width));\r
9960         }\r
9961         else if ((b != NULL) && (b->Size == (sizeof(width) - sizeof(UINT))))\r
9962         {\r
9963                 // 旧バージョンからの移行\r
9964                 Zero(width, sizeof(width));\r
9965                 Copy(width, b->Buf, sizeof(width) - sizeof(UINT));\r
9966                 width[4] = width[3];\r
9967                 width[3] = 0;\r
9968         }\r
9969         else\r
9970         {\r
9971                 Zero(width, sizeof(width));\r
9972         }\r
9973         FreeBuf(b);\r
9974 \r
9975         LvInitEx2(hWnd, L_ACCOUNT, false, easy);\r
9976 \r
9977 //      LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_TRACKSELECT);\r
9978 \r
9979         // カラムの初期化\r
9980         if (easy == false)\r
9981         {\r
9982                 LvInsertColumn(hWnd, L_ACCOUNT, 0, _UU("CM_ACCOUNT_COLUMN_1"), width[0] == 0 ? 215 : width[0]);\r
9983                 LvInsertColumn(hWnd, L_ACCOUNT, 1, _UU("CM_ACCOUNT_COLUMN_2"), width[1] == 0 ? 80 : width[1]);\r
9984                 LvInsertColumn(hWnd, L_ACCOUNT, 2, _UU("CM_ACCOUNT_COLUMN_3"), width[2] == 0 ? 220 : width[2]);\r
9985                 LvInsertColumn(hWnd, L_ACCOUNT, 3, _UU("CM_ACCOUNT_COLUMN_3_2"), width[3] == 0 ? 90 : width[3]);\r
9986                 LvInsertColumn(hWnd, L_ACCOUNT, 4, _UU("CM_ACCOUNT_COLUMN_4"), (width[4] == 0 || width[4] == 250) ? 120 : width[4]);\r
9987 \r
9988                 //LvSetBkImage(hWnd, L_ACCOUNT, "|ClientBack2.bmp");\r
9989         }\r
9990         else\r
9991         {\r
9992                 LvInsertColumn(hWnd, L_ACCOUNT, 0, _UU("CM_ACCOUNT_COLUMN_1"), 345);\r
9993                 LvInsertColumn(hWnd, L_ACCOUNT, 1, _UU("CM_ACCOUNT_COLUMN_2"), 140);\r
9994                 LvInsertColumn(hWnd, L_ACCOUNT, 2, _UU("CM_ACCOUNT_COLUMN_3"), 0);\r
9995                 LvInsertColumn(hWnd, L_ACCOUNT, 3, _UU("CM_ACCOUNT_COLUMN_3_2"), 0);\r
9996                 LvInsertColumn(hWnd, L_ACCOUNT, 4, _UU("CM_ACCOUNT_COLUMN_4"), 0);\r
9997         }\r
9998 \r
9999 }\r
10000 \r
10001 // アカウントリストの解放\r
10002 void CmSaveAccountListPos(HWND hWnd)\r
10003 {\r
10004         UINT width[5];\r
10005         UINT i;\r
10006         // 引数チェック\r
10007         if (hWnd == NULL)\r
10008         {\r
10009                 return;\r
10010         }\r
10011 \r
10012         for (i = 0;i < 5;i++)\r
10013         {\r
10014                 width[i] = LvGetColumnWidth(hWnd, L_ACCOUNT, i);\r
10015         }\r
10016 \r
10017         MsRegWriteBin(REG_CURRENT_USER, CM_REG_KEY, "AccountListColumnWidth", width, sizeof(width));\r
10018 }\r
10019 \r
10020 // VLAN リストの初期化\r
10021 void CmInitVLanList(HWND hWnd)\r
10022 {\r
10023         UINT width[4];\r
10024         BUF *b;\r
10025         // 引数チェック\r
10026         if (hWnd == NULL)\r
10027         {\r
10028                 return;\r
10029         }\r
10030 \r
10031         // 設定読み込み\r
10032         b = MsRegReadBin(REG_CURRENT_USER, CM_REG_KEY, "VLanListColumnWidth");\r
10033         if ((b != NULL) && (b->Size == sizeof(width)))\r
10034         {\r
10035                 Copy(width, b->Buf, sizeof(width));\r
10036         }\r
10037         else\r
10038         {\r
10039                 Zero(width, sizeof(width));\r
10040         }\r
10041         FreeBuf(b);\r
10042 \r
10043         LvInit(hWnd, L_VLAN);\r
10044 \r
10045 //      LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_TRACKSELECT);\r
10046 \r
10047         // カラムの初期化\r
10048         LvInsertColumn(hWnd, L_VLAN, 0, _UU("CM_VLAN_COLUMN_1"), width[0] == 0 ? 310 : width[0]);\r
10049         LvInsertColumn(hWnd, L_VLAN, 1, _UU("CM_VLAN_COLUMN_2"), width[1] == 0 ? 120 : width[1]);\r
10050         LvInsertColumn(hWnd, L_VLAN, 2, _UU("CM_VLAN_COLUMN_3"), width[2] == 0 ? 175 : width[2]);\r
10051         LvInsertColumn(hWnd, L_VLAN, 3, _UU("CM_VLAN_COLUMN_4"), width[3] == 0 ? 120 : width[3]);\r
10052 \r
10053         // 背景イメージ\r
10054         LvSetBkImage(hWnd, L_VLAN, "|ClientBack2.bmp");\r
10055 }\r
10056 \r
10057 // VLAN リストの解放\r
10058 void CmSaveVLanListPos(HWND hWnd)\r
10059 {\r
10060         UINT width[4];\r
10061         UINT i;\r
10062         // 引数チェック\r
10063         if (hWnd == NULL)\r
10064         {\r
10065                 return;\r
10066         }\r
10067 \r
10068         for (i = 0;i < 4;i++)\r
10069         {\r
10070                 width[i] = LvGetColumnWidth(hWnd, L_VLAN, i);\r
10071         }\r
10072 \r
10073         MsRegWriteBin(REG_CURRENT_USER, CM_REG_KEY, "VLanListColumnWidth", width, sizeof(width));\r
10074 }\r
10075 \r
10076 // アカウントリストの更新\r
10077 void CmRefreshAccountList(HWND hWnd)\r
10078 {\r
10079         CmRefreshAccountListEx(hWnd, false);\r
10080         CmRefreshEasy();\r
10081 }\r
10082 void CmRefreshAccountListEx(HWND hWnd, bool easy)\r
10083 {\r
10084         CmRefreshAccountListEx2(hWnd, easy, false);\r
10085 }\r
10086 void CmRefreshAccountListEx2(HWND hWnd, bool easy, bool style_changed)\r
10087 {\r
10088         UINT num = 0;\r
10089         RPC_CLIENT_ENUM_ACCOUNT a;\r
10090         UINT num_connecting = 0, num_connected = 0;\r
10091         wchar_t tmp[MAX_SIZE];\r
10092         wchar_t new_inserted_item[MAX_ACCOUNT_NAME_LEN + 1];\r
10093         bool select_new_insteted_item = true;\r
10094         // 引数チェック\r
10095         if (hWnd == NULL)\r
10096         {\r
10097                 return;\r
10098         }\r
10099 \r
10100         // アイコン / 詳細表示の切り替え\r
10101         LvSetView(hWnd, L_ACCOUNT, cm->IconView == false || easy);\r
10102 \r
10103         // グリッド表示\r
10104         if (cm->ShowGrid || easy)\r
10105         {\r
10106                 LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_GRIDLINES);\r
10107         }\r
10108         else\r
10109         {\r
10110                 LvRemoveStyle(hWnd, L_ACCOUNT, LVS_EX_GRIDLINES);\r
10111         }\r
10112 \r
10113         if (style_changed)\r
10114         {\r
10115                 // フォントの変更\r
10116                 if (easy == false)\r
10117                 {\r
10118                         if (cm->VistaStyle)\r
10119                         {\r
10120                                 SetFontMeiryo(hWnd, L_ACCOUNT);\r
10121                         }\r
10122                         else\r
10123                         {\r
10124                                 SetFontDefault(hWnd, L_ACCOUNT);\r
10125                         }\r
10126 \r
10127                         if (cm->VistaStyle && (cm->IconView == false))\r
10128                         {\r
10129                                 LvSetStyle(hWnd, L_ACCOUNT, LVS_EX_FULLROWSELECT);\r
10130                         }\r
10131                         else\r
10132                         {\r
10133                                 LvRemoveStyle(hWnd, L_ACCOUNT, LVS_EX_FULLROWSELECT);\r
10134                         }\r
10135                 }\r
10136         }\r
10137 \r
10138         Zero(new_inserted_item, sizeof(new_inserted_item));\r
10139 \r
10140         if (LvNum(hWnd, L_ACCOUNT) == 0)\r
10141         {\r
10142                 select_new_insteted_item = false;\r
10143         }\r
10144 \r
10145         // アカウントリストの列挙\r
10146         if (CALL(hWnd, CcEnumAccount(cm->Client, &a)))\r
10147         {\r
10148                 UINT i;\r
10149                 LVB *b = LvInsertStart();\r
10150 \r
10151                 if (cm->CmSetting.LockMode == false && (easy == false))\r
10152                 {\r
10153                         // 特別なアイコン\r
10154                         LvInsertAdd(b, ICO_NEW, NULL, 4, _UU("CM_NEW_ICON"), L"", L"", L"");\r
10155                         LvInsertAdd(b, ICO_INTERNET, NULL, 4, _UU("CM_ASP"), L"", L"", L"");\r
10156                 }\r
10157 \r
10158                 for (i = 0;i < a.NumItem;i++)\r
10159                 {\r
10160                         RPC_CLIENT_ENUM_ACCOUNT_ITEM *t = a.Items[i];\r
10161                         UINT icon;\r
10162                         wchar_t tmp[MAX_SIZE];\r
10163                         wchar_t tmp2[MAX_SIZE];\r
10164                         char tmp3[MAX_SIZE];\r
10165                         wchar_t tmp4[MAX_SIZE];\r
10166                         IP ip;\r
10167                         char ip_str[MAX_SIZE];\r
10168 \r
10169                         // IPv6 アドレスの場合の特別処理\r
10170                         if (StrToIP6(&ip, t->ServerName) && StartWith(t->ServerName, "[") == false)\r
10171                         {\r
10172                                 Format(ip_str, sizeof(ip_str),\r
10173                                         "[%s]", t->ServerName);\r
10174                         }\r
10175                         else\r
10176                         {\r
10177                                 StrCpy(ip_str, sizeof(ip_str), t->ServerName);\r
10178                         }\r
10179 \r
10180                         // アイコンの決定\r
10181                         if (t->Active == false)\r
10182                         {\r
10183                                 if (t->StartupAccount == false)\r
10184                                 {\r
10185                                         icon = ICO_SERVER_OFFLINE;\r
10186                                 }\r
10187                                 else\r
10188                                 {\r
10189                                         icon = ICO_SERVER_OFFLINE_EX;\r
10190                                 }\r
10191                         }\r
10192                         else\r
10193                         {\r
10194                                 num++;\r
10195                                 if (t->StartupAccount == false)\r
10196                                 {\r
10197                                         icon = ICO_SERVER_ONLINE;\r
10198                                 }\r
10199                                 else\r
10200                                 {\r
10201                                         icon = ICO_SERVER_ONLINE_EX;\r
10202                                 }\r
10203                         }\r
10204 \r
10205                         // 追加\r
10206                         if (easy == false)\r
10207                         {\r
10208                                 //CmVLanNameToPrintName(tmp3, sizeof(tmp3), t->DeviceName);\r
10209                                 StrCpy(tmp3, sizeof(tmp3), t->DeviceName);\r
10210                                 StrToUni(tmp, sizeof(tmp), tmp3);\r
10211                         }\r
10212                         else\r
10213                         {\r
10214                                 StrToUni(tmp, sizeof(tmp), t->DeviceName);\r
10215                         }\r
10216 \r
10217                         if (t->Port == 0 || cm->ShowPort == false)\r
10218                         {\r
10219                                 // ポート番号不明\r
10220                                 UniFormat(tmp2, sizeof(tmp2), L"%S (%s)", ip_str, CmGetProtocolName(t->ProxyType));\r
10221                         }\r
10222                         else\r
10223                         {\r
10224                                 // ポート番号併記\r
10225                                 UniFormat(tmp2, sizeof(tmp2), L"%S:%u (%s)", ip_str, t->Port, CmGetProtocolName(t->ProxyType));\r
10226                         }\r
10227 \r
10228                         if (LvSearchStr(hWnd, L_ACCOUNT, 0, t->AccountName) == INFINITE)\r
10229                         {\r
10230                                 UniStrCpy(new_inserted_item, sizeof(new_inserted_item), t->AccountName);\r
10231                         }\r
10232 \r
10233                         // 仮想 HUB 名\r
10234                         StrToUni(tmp4, sizeof(tmp4), t->HubName);\r
10235 \r
10236                         if (easy == false)\r
10237                         {\r
10238                                 LvInsertAdd(b, icon, (void *)t->StartupAccount, 5, t->AccountName,\r
10239                                         t->Active == false ? _UU("CM_ACCOUNT_OFFLINE") :\r
10240                                         (t->Connected ? _UU("CM_ACCOUNT_ONLINE") : _UU("CM_ACCOUNT_CONNECTING")),\r
10241                                         tmp2, tmp4,\r
10242                                         tmp);\r
10243                         }\r
10244                         else\r
10245                         {\r
10246                                 LvInsertAdd(b, icon, (void *)t->StartupAccount, 5, t->AccountName,\r
10247                                         t->Active == false ? _UU("CM_ACCOUNT_OFFLINE") :\r
10248                                         (t->Connected ? _UU("CM_ACCOUNT_ONLINE") : _UU("CM_ACCOUNT_CONNECTING")),\r
10249                                         tmp2, tmp4,\r
10250                                         tmp);\r
10251                         }\r
10252 \r
10253                         if (t->Active)\r
10254                         {\r
10255                                 if (t->Connected)\r
10256                                 {\r
10257                                         num_connected++;\r
10258                                 }\r
10259                                 else\r
10260                                 {\r
10261                                         num_connecting++;\r
10262                                 }\r
10263                         }\r
10264                 }\r
10265 \r
10266                 LvInsertEnd(b, hWnd, L_ACCOUNT);\r
10267 \r
10268                 CiFreeClientEnumAccount(&a);\r
10269 \r
10270                 if (select_new_insteted_item)\r
10271                 {\r
10272                         if (UniStrLen(new_inserted_item) >= 1)\r
10273                         {\r
10274                                 LvSelect(hWnd, L_ACCOUNT, INFINITE);\r
10275                                 LvSelect(hWnd, L_ACCOUNT, LvSearchStr(hWnd, L_ACCOUNT, 0, new_inserted_item));\r
10276                         }\r
10277                 }\r
10278         }\r
10279 \r
10280         if (easy == false)\r
10281         {\r
10282                 // 音声ガイドのため、新しく接続されたり、切断されたりした場合を検出する\r
10283                 if (cm->UpdateConnectedNumFlag == false)\r
10284                 {\r
10285                         cm->UpdateConnectedNumFlag = true;\r
10286                         cm->OldConnectedNum = num;\r
10287                 }\r
10288                 else\r
10289                 {\r
10290                         if (cm->OldConnectedNum != num)\r
10291                         {\r
10292                                 if (cm->OldConnectedNum < num)\r
10293                                 {\r
10294                                         CmVoice("connect");\r
10295                                 }\r
10296                                 else\r
10297                                 {\r
10298                                         CmVoice("disconnect");\r
10299 \r
10300                                         if (cm->CmSetting.EasyMode && cm->PositiveDisconnectFlag == false)\r
10301                                         {\r
10302                                                 CmShowEasy();\r
10303                                         }\r
10304 \r
10305                                         cm->PositiveDisconnectFlag = false;\r
10306                                 }\r
10307                                 cm->OldConnectedNum = num;\r
10308                         }\r
10309                 }\r
10310 \r
10311                 if (num_connecting == 0 && num_connected == 0)\r
10312                 {\r
10313                         // 接続中も接続完了も無し\r
10314                         UniStrCpy(tmp, sizeof(tmp), _UU("CM_TRAY_NOT_CONNECTED"));\r
10315                 }\r
10316                 else if (num_connected == 0)\r
10317                 {\r
10318                         // 接続中だけ有り\r
10319                         UniFormat(tmp, sizeof(tmp), _UU("CM_TRAY_CONNECTED_1"), num_connecting);\r
10320                 }\r
10321                 else if (num_connecting == 0)\r
10322                 {\r
10323                         // 接続完了だけ有り\r
10324                         UniFormat(tmp, sizeof(tmp), _UU("CM_TRAY_CONNECTED_2"), num_connected);\r
10325                 }\r
10326                 else\r
10327                 {\r
10328                         // 両方有り\r
10329                         UniFormat(tmp, sizeof(tmp), _UU("CM_TRAY_CONNECTED_0"), num_connected, num_connecting);\r
10330                 }\r
10331 \r
10332                 if (num_connecting == 0 && num_connected == 0)\r
10333                 {\r
10334                         cm->TrayAnimation = false;\r
10335                         cm->TraySpeedAnimation = false;\r
10336                 }\r
10337                 else\r
10338                 {\r
10339                         cm->TrayAnimation = true;\r
10340 \r
10341                         if (num_connecting == 0)\r
10342                         {\r
10343                                 cm->TraySpeedAnimation = false;\r
10344                         }\r
10345                         else\r
10346                         {\r
10347                                 cm->TraySpeedAnimation = true;\r
10348                         }\r
10349                 }\r
10350 \r
10351                 CmChangeTrayString(hWnd, tmp);\r
10352         }\r
10353 \r
10354         Refresh(hWnd);\r
10355 \r
10356         //ジャンプリストを更新\r
10357         CmUpdateJumpList(0);\r
10358 }\r
10359 \r
10360 // VLAN リストの更新\r
10361 void CmRefreshVLanList(HWND hWnd)\r
10362 {\r
10363         CmRefreshVLanListEx(hWnd, false);\r
10364 }\r
10365 void CmRefreshVLanListEx(HWND hWnd, bool style_changed)\r
10366 {\r
10367         RPC_CLIENT_ENUM_VLAN e;\r
10368         // 引数チェック\r
10369         if (hWnd == NULL)\r
10370         {\r
10371                 return;\r
10372         }\r
10373 \r
10374         LvSetView(hWnd, L_VLAN, cm->IconView == false);\r
10375 \r
10376         // グリッド表示\r
10377         if (cm->ShowGrid)\r
10378         {\r
10379                 LvSetStyle(hWnd, L_VLAN, LVS_EX_GRIDLINES);\r
10380         }\r
10381         else\r
10382         {\r
10383                 LvRemoveStyle(hWnd, L_VLAN, LVS_EX_GRIDLINES);\r
10384         }\r
10385 \r
10386         if (style_changed)\r
10387         {\r
10388                 // フォントの変更\r
10389                 if (cm->VistaStyle)\r
10390                 {\r
10391                         SetFontMeiryo(hWnd, L_VLAN);\r
10392                 }\r
10393                 else\r
10394                 {\r
10395                         SetFontDefault(hWnd, L_VLAN);\r
10396                 }\r
10397 \r
10398                 if (cm->VistaStyle && (cm->IconView == false))\r
10399                 {\r
10400                         LvSetStyle(hWnd, L_VLAN, LVS_EX_FULLROWSELECT);\r
10401                 }\r
10402                 else\r
10403                 {\r
10404                         LvRemoveStyle(hWnd, L_VLAN, LVS_EX_FULLROWSELECT);\r
10405                 }\r
10406         }\r
10407 \r
10408         // 列挙\r
10409         Zero(&e, sizeof(e));\r
10410         if (CALL(hWnd, CcEnumVLan(cm->Client, &e)))\r
10411         {\r
10412                 LVB *b = LvInsertStart();\r
10413                 UINT i;\r
10414                 for (i = 0;i < e.NumItem;i++)\r
10415                 {\r
10416                         wchar_t name[MAX_SIZE];\r
10417                         wchar_t mac[MAX_SIZE];\r
10418                         wchar_t ver[MAX_SIZE];\r
10419                         char str[MAX_SIZE];\r
10420                         wchar_t *status;\r
10421                         RPC_CLIENT_ENUM_VLAN_ITEM *v = e.Items[i];\r
10422 \r
10423                         // デバイス名\r
10424                         CmVLanNameToPrintName(str, sizeof(str), v->DeviceName);\r
10425                         StrToUni(name, sizeof(name), str);\r
10426 \r
10427                         // 状態\r
10428                         status = v->Enabled ? _UU("CM_VLAN_ENABLED") : _UU("CM_VLAN_DISABLED");\r
10429 \r
10430                         // MAC アドレス\r
10431                         StrToUni(mac, sizeof(mac), v->MacAddress);\r
10432 \r
10433                         // バージョン\r
10434                         StrToUni(ver, sizeof(ver), v->Version);\r
10435 \r
10436                         LvInsertAdd(b, v->Enabled ? ICO_NIC_ONLINE : ICO_NIC_OFFLINE, NULL, 4,\r
10437                                 name, status, mac, ver);\r
10438                 }\r
10439                 LvInsertEnd(b, hWnd, L_VLAN);\r
10440 \r
10441                 CiFreeClientEnumVLan(&e);\r
10442         }\r
10443 }\r
10444 \r
10445 // プロトコル名文字列を取得\r
10446 wchar_t *CmGetProtocolName(UINT n)\r
10447 {\r
10448         return GetProtocolName(n);\r
10449 }\r
10450 \r
10451 // 表示更新\r
10452 void CmRefresh(HWND hWnd)\r
10453 {\r
10454         CmRefreshEx(hWnd, false);\r
10455 }\r
10456 void CmRefreshEx(HWND hWnd, bool style_changed)\r
10457 {\r
10458         // 引数チェック\r
10459         if (hWnd == NULL)\r
10460         {\r
10461                 return;\r
10462         }\r
10463 \r
10464         // サイズ更新\r
10465         CmMainWindowOnSize(hWnd);\r
10466 \r
10467         // VLAN リストの更新\r
10468         CmRefreshVLanListEx(hWnd, style_changed);\r
10469 \r
10470         // アカウントリストの更新\r
10471         CmRefreshAccountListEx2(hWnd, false, style_changed);\r
10472 \r
10473         // ステータスバーの更新\r
10474         CmRefreshStatusBar(hWnd);\r
10475 }\r
10476 \r
10477 // 指定されたメニュー項目をチェックするかどうか判断する\r
10478 bool CmIsChecked(UINT id)\r
10479 {\r
10480         switch (id)\r
10481         {\r
10482         case CMD_TRAYICON:\r
10483                 return cm->HideTrayIcon == false;\r
10484         case CMD_STATUSBAR:\r
10485                 return cm->HideStatusBar == false;\r
10486         case CMD_VISTASTYLE:\r
10487                 return cm->VistaStyle;\r
10488         case CMD_ICON:\r
10489                 return cm->IconView;\r
10490         case CMD_DETAIL:\r
10491                 return cm->IconView == false;\r
10492         case CMD_GRID:\r
10493                 return cm->ShowGrid;\r
10494         case CMD_VOIDE_NONE:\r
10495                 return cm->DisableVoice;\r
10496         case CMD_SHOWPORT:\r
10497                 return cm->ShowPort;\r
10498         case CMD_VOICE_NORMAL:\r
10499                 if (cm->DisableVoice)\r
10500                 {\r
10501                         return false;\r
10502                 }\r
10503                 else\r
10504                 {\r
10505                         return cm->VoiceId == VOICE_SSK;\r
10506                 }\r
10507         case CMD_VOICE_ODD:\r
10508                 if (cm->DisableVoice)\r
10509                 {\r
10510                         return false;\r
10511                 }\r
10512                 else\r
10513                 {\r
10514                         return cm->VoiceId == VOICE_AHO;\r
10515                 }\r
10516         }\r
10517         return false;\r
10518 }\r
10519 \r
10520 // メニューがポップアップされた\r
10521 void CmMainWindowOnPopupMenu(HWND hWnd, HMENU hMenu, UINT pos)\r
10522 {\r
10523         UINT num_menu, i, id;\r
10524         // 引数チェック\r
10525         if (hWnd == NULL || hMenu == NULL)\r
10526         {\r
10527                 return;\r
10528         }\r
10529 \r
10530         num_menu = GetMenuItemCount(hMenu);\r
10531         for (i = 0;i < num_menu;i++)\r
10532         {\r
10533                 id = GetMenuItemID(hMenu, i);\r
10534 \r
10535                 if (id != INFINITE)\r
10536                 {\r
10537                         bool enable_flag = CmIsEnabled(hWnd, id);\r
10538                         bool checked_flag = CmIsChecked(id);\r
10539                         bool bold_flag = CmIsBold(id);\r
10540                         MENUITEMINFO info;\r
10541 \r
10542                         Zero(&info, sizeof(info));\r
10543                         info.cbSize = sizeof(info);\r
10544                         info.fMask = MIIM_STATE;\r
10545                         info.fState = (enable_flag ? MFS_ENABLED : MFS_DISABLED) |\r
10546                                 (checked_flag ? MFS_CHECKED : MFS_UNCHECKED) |\r
10547                                 (bold_flag ? MFS_DEFAULT : 0);\r
10548 \r
10549                         if (id == CMD_ICON || id == CMD_DETAIL || id == CMD_VOIDE_NONE ||\r
10550                                 id == CMD_VOICE_NORMAL || id == CMD_VOICE_ODD)\r
10551                         {\r
10552                                 info.fMask |= MIIM_FTYPE;\r
10553                                 info.fType = MFT_RADIOCHECK;\r
10554                         }\r
10555 \r
10556                         SetMenuItemInfo(hMenu, id, false, &info);\r
10557                 }\r
10558 \r
10559                 if (id == CMD_RECENT)\r
10560                 {\r
10561                         HMENU sub = CmCreateRecentSubMenu(hWnd, CM_TRAY_MENU_RECENT_ID_START);\r
10562 \r
10563                         if (sub != NULL)\r
10564                         {\r
10565                                 DeleteMenu(hMenu, i, MF_BYPOSITION);\r
10566                                 MsInsertMenu(hMenu, i, MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING,\r
10567                                         (UINT_PTR)sub, _UU("CM_TRAY_MENU_RECENT"));\r
10568                         }\r
10569                         else\r
10570                         {\r
10571                                 MENUITEMINFO info;\r
10572 \r
10573                                 Zero(&info, sizeof(info));\r
10574                                 info.cbSize = sizeof(info);\r
10575                                 info.fMask = MIIM_STATE;\r
10576                                 info.fState = MFS_DISABLED;\r
10577 \r
10578                                 SetMenuItemInfo(hMenu, id, false, &info);\r
10579                         }\r
10580                 }\r
10581         }\r
10582 }\r
10583 \r
10584 // メインウインドウタイトルの設定\r
10585 wchar_t *CmGenerateMainWindowTitle()\r
10586 {\r
10587         wchar_t tmp[MAX_SIZE];\r
10588         if (cm->server_name == NULL)\r
10589         {\r
10590                 UniFormat(tmp, sizeof(tmp), L"%s", _UU("CM_TITLE"));\r
10591         }\r
10592         else\r
10593         {\r
10594                 UniFormat(tmp, sizeof(tmp), L"%s - %S", _UU("CM_TITLE"), cm->server_name);\r
10595         }\r
10596 \r
10597         return CopyUniStr(tmp);\r
10598 }\r
10599 \r
10600 // タスクトレイの初期化\r
10601 void CmInitTray(HWND hWnd)\r
10602 {\r
10603         // 引数チェック\r
10604         if (hWnd == NULL)\r
10605         {\r
10606                 return;\r
10607         }\r
10608 \r
10609         if (cm->server_name != NULL)\r
10610         {\r
10611                 return;\r
10612         }\r
10613 \r
10614         if (cm->TrayInited)\r
10615         {\r
10616                 return;\r
10617         }\r
10618 \r
10619         MsShowIconOnTray(hWnd, LoadSmallIcon(CmGetTrayIconId(false, 0)), _UU("CM_TRAY_INITING"), WM_CM_TRAY_MESSAGE);\r
10620 \r
10621         cm->TrayInited = true;\r
10622         cm->TrayAnimation = false;\r
10623 \r
10624         SetTimer(hWnd, 2, CM_TRAY_ANIMATION_INTERVAL / 4, NULL);\r
10625 }\r
10626 \r
10627 // タスクトレイの文字列の変更\r
10628 void CmChangeTrayString(HWND hWnd, wchar_t *str)\r
10629 {\r
10630         // 引数チェック\r
10631         if (hWnd == NULL || str == NULL)\r
10632         {\r
10633                 return;\r
10634         }\r
10635         if (cm->TrayInited == false)\r
10636         {\r
10637                 return;\r
10638         }\r
10639 \r
10640         MsChangeIconOnTray(NULL, str);\r
10641 }\r
10642 \r
10643 // タスクトレイの解放\r
10644 void CmFreeTray(HWND hWnd)\r
10645 {\r
10646         // 引数チェック\r
10647         if (hWnd == NULL)\r
10648         {\r
10649                 return;\r
10650         }\r
10651 \r
10652         if (cm->TrayInited == false)\r
10653         {\r
10654                 return;\r
10655         }\r
10656 \r
10657         MsHideIconOnTray();\r
10658 \r
10659         cm->TrayInited = false;\r
10660 }\r
10661 void CmFreeTrayExternal(void *hWnd)\r
10662 {\r
10663         CmFreeTray((HWND)hWnd);\r
10664 }\r
10665 \r
10666 // タスクトレイに対する定期的な処理\r
10667 void CmPollingTray(HWND hWnd)\r
10668 {\r
10669         UINT interval;\r
10670         // 引数チェック\r
10671         if (hWnd == NULL)\r
10672         {\r
10673                 return;\r
10674         }\r
10675 \r
10676         if (cm->TrayInited == false)\r
10677         {\r
10678                 return;\r
10679         }\r
10680 \r
10681         MsChangeIconOnTray(LoadSmallIcon(CmGetTrayIconId(cm->TrayAnimation, cm->TrayAnimationCounter)),\r
10682                 NULL);\r
10683 \r
10684         cm->TrayAnimationCounter++;\r
10685 \r
10686         KillTimer(hWnd, 2);\r
10687         interval = CM_TRAY_ANIMATION_INTERVAL / 4;\r
10688         if (cm->TraySpeedAnimation)\r
10689         {\r
10690                 interval /= 4;\r
10691         }\r
10692         SetTimer(hWnd, 2, interval, NULL);\r
10693 }\r
10694 \r
10695 // アニメーション用のタスクトレイのアイコン ID の取得\r
10696 UINT CmGetTrayIconId(bool animation, UINT animation_counter)\r
10697 {\r
10698         if (animation == false)\r
10699         {\r
10700                 return ICO_TRAY0;\r
10701         }\r
10702         else\r
10703         {\r
10704                 switch (animation_counter % 4)\r
10705                 {\r
10706                 case 0:\r
10707                         return ICO_TRAY1;\r
10708 \r
10709                 case 1:\r
10710                         return ICO_TRAY2;\r
10711 \r
10712                 case 2:\r
10713                         return ICO_TRAY3;\r
10714 \r
10715                 default:\r
10716                         return ICO_TRAY4;\r
10717                 }\r
10718         }\r
10719 }\r
10720 \r
10721 // メインウインドウの初期化\r
10722 void CmMainWindowOnInit(HWND hWnd)\r
10723 {\r
10724         wchar_t *s;\r
10725         BUF *b;\r
10726         bool startup_mode = cm->StartupMode;\r
10727         CM_SETTING a;\r
10728         bool fake = false;\r
10729         // 引数チェック\r
10730         if (hWnd == NULL)\r
10731         {\r
10732                 return;\r
10733         }\r
10734 \r
10735         // リストのフォント設定\r
10736         SetFontMeiryo(hWnd, L_ACCOUNT);\r
10737         SetFontMeiryo(hWnd, L_VLAN);\r
10738 \r
10739         // 現在の vpnclient の設定を取得する\r
10740         Zero(&a, sizeof(a));\r
10741         CcGetCmSetting(cm->Client, &a);\r
10742 \r
10743         if (a.EasyMode)\r
10744         {\r
10745                 fake = true;\r
10746         }\r
10747 \r
10748         InitMenuInternational(GetMenu(hWnd), "CM_MENU");\r
10749 \r
10750         cm->HideStatusBar = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "HideStatusBar");\r
10751         cm->HideTrayIcon = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "HideTrayIcon");\r
10752         cm->IconView = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "IconView");\r
10753         cm->ShowGrid = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "ShowGrid");\r
10754 \r
10755         if (MsRegIsValue(REG_CURRENT_USER, CM_REG_KEY, "VistaStyle"))\r
10756         {\r
10757                 cm->VistaStyle = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "VistaStyle");\r
10758         }\r
10759         else\r
10760         {\r
10761                 cm->VistaStyle = MsIsVista();\r
10762         }\r
10763 \r
10764         if (MsRegIsValue(REG_CURRENT_USER, CM_REG_KEY, "ShowPort"))\r
10765         {\r
10766                 cm->ShowPort = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "ShowPort");\r
10767         }\r
10768         else\r
10769         {\r
10770                 cm->ShowPort = false;\r
10771         }\r
10772 \r
10773         if (MsRegIsValue(REG_CURRENT_USER, CM_REG_KEY, "DisableVoice"))\r
10774         {\r
10775                 cm->DisableVoice = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "DisableVoice");\r
10776         }\r
10777         else\r
10778         {\r
10779                 cm->DisableVoice = true;\r
10780         }\r
10781         cm->VoiceId = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "VoiceId");\r
10782 \r
10783         cm->StatusWindowList = NewList(NULL);\r
10784 \r
10785         SetIcon(hWnd, 0, ICO_VPN);\r
10786 \r
10787         s = CmGenerateMainWindowTitle();\r
10788         SetText(hWnd, 0, s);\r
10789         Free(s);\r
10790 \r
10791         // ウインドウ位置の初期化\r
10792         b = MsRegReadBin(REG_CURRENT_USER, CM_REG_KEY, "WindowPlacement");\r
10793         if (b != NULL && b->Size == sizeof(WINDOWPLACEMENT))\r
10794         {\r
10795                 // ウインドウ位置を復元\r
10796                 WINDOWPLACEMENT *p;\r
10797                 p = ZeroMalloc(b->Size);\r
10798                 Copy(p, b->Buf, b->Size);\r
10799 \r
10800                 if (startup_mode)\r
10801                 {\r
10802                         p->showCmd = SW_SHOWMINIMIZED;\r
10803                 }\r
10804 \r
10805                 if (fake)\r
10806                 {\r
10807                         Copy(&cm->FakeWindowPlacement, p, sizeof(WINDOWPLACEMENT));\r
10808                 }\r
10809                 else\r
10810                 {\r
10811                         SetWindowPlacement(hWnd, p);\r
10812                 }\r
10813                 Free(p);\r
10814         }\r
10815         else\r
10816         {\r
10817                 // ウインドウ位置を初期化\r
10818                 SetWindowPos(hWnd, NULL, 0, 0, CM_DEFAULT_WIDTH, CM_DEFAULT_HEIGHT, SWP_NOREDRAW);\r
10819                 Center(hWnd);\r
10820                 if (startup_mode)\r
10821                 {\r
10822                         ShowWindow(hWnd, SW_SHOWMINIMIZED);\r
10823                 }\r
10824 \r
10825                 if (fake)\r
10826                 {\r
10827                         WINDOWPLACEMENT p;\r
10828 \r
10829                         Zero(&p, sizeof(p));\r
10830                         p.length = sizeof(p);\r
10831                         GetWindowPlacement(hWnd, &p);\r
10832                         Copy(&cm->FakeWindowPlacement, &p, sizeof(WINDOWPLACEMENT));\r
10833                 }\r
10834         }\r
10835         FreeBuf(b);\r
10836 \r
10837         if (fake)\r
10838         {\r
10839                 SetWindowPos(hWnd, NULL, -200, -200, 100, 100,\r
10840                         SWP_NOREDRAW | SWP_SHOWWINDOW);\r
10841         }\r
10842 \r
10843         // ステータスバー関係の初期化\r
10844         cm->hMainWnd = hWnd;\r
10845         cm->hStatusBar = CreateStatusWindowW(WS_CHILD |\r
10846                 (cm->HideStatusBar == false ? WS_VISIBLE : 0),\r
10847                 _UU("CM_TITLE"),\r
10848                 hWnd, S_STATUSBAR);\r
10849 \r
10850         UniStrCpy(cm->StatudBar1, sizeof(cm->StatudBar1), _UU("CM_TITLE"));\r
10851         UniStrCpy(cm->StatudBar2, sizeof(cm->StatudBar2), _UU("CM_CONN_NO"));\r
10852         UniFormat(cm->StatudBar3, sizeof(cm->StatudBar3), _UU("CM_PRODUCT_NAME"), CEDAR_BUILD);\r
10853 \r
10854         cm->Icon2 = LoadSmallIcon(ICO_SERVER_OFFLINE);\r
10855         cm->Icon3 = LoadSmallIcon(ICO_VPN);\r
10856 \r
10857         // アカウントリストの初期化\r
10858         CmInitAccountList(hWnd);\r
10859 \r
10860         // VLAN リストの初期化\r
10861         CmInitVLanList(hWnd);\r
10862 \r
10863         // 表示更新\r
10864         CmRefreshEx(hWnd, true);\r
10865 \r
10866         // 通知クライアントのスレッドを開始\r
10867         CmInitNotifyClientThread();\r
10868 \r
10869         // タイマー設定\r
10870         SetTimer(hWnd, 1, 128, NULL);\r
10871 \r
10872         // タスクトレイの初期化\r
10873         if (cm->server_name == NULL)\r
10874         {\r
10875                 if (cm->HideTrayIcon == false)\r
10876                 {\r
10877                         CmInitTray(hWnd);\r
10878                 }\r
10879         }\r
10880 \r
10881         CmVoice("start");\r
10882 \r
10883         if (startup_mode || a.EasyMode)\r
10884         {\r
10885                 SetTimer(hWnd, 3, 1, NULL);\r
10886         }\r
10887 \r
10888         if (cm->import_file_name != NULL)\r
10889         {\r
10890                 // 引数として指定されたファイルをインポートする\r
10891                 CmSendImportMessage(hWnd, cm->import_file_name, cm->CmSettingInitialFlag == CM_SETTING_INIT_NONE ? CM_IMPORT_FILENAME_MSG : CM_IMPORT_FILENAME_MSG_OVERWRITE);\r
10892                 /*if (a.LockMode == false)\r
10893                 {\r
10894                         CmImportAccountMainEx(hWnd, cm->import_file_name, cm->CmSettingInitialFlag != CM_SETTING_INIT_NONE);\r
10895                 }\r
10896                 else\r
10897                 {\r
10898                         MsgBox(cm->hEasyWnd ? cm->hEasyWnd : hWnd, MB_ICONEXCLAMATION, _UU("CM_VPN_FILE_IMPORT_NG"));\r
10899                 }*/\r
10900         }\r
10901 \r
10902         // CM_SETTING の適用\r
10903         CmApplyCmSetting();\r
10904 \r
10905         cm->StartupFinished = true;\r
10906 }\r
10907 \r
10908 // 通知クライアントのスレッドを開始\r
10909 void CmInitNotifyClientThread()\r
10910 {\r
10911         cm->NotifyClient = CcConnectNotify(cm->Client);\r
10912         if (cm->NotifyClient == false)\r
10913         {\r
10914                 Close(cm->hMainWnd);\r
10915                 exit(0);\r
10916         }\r
10917         cm->NotifyClientThread = NewThread(CmNotifyClientThread, NULL);\r
10918 }\r
10919 \r
10920 // 通知クライアントスレッド\r
10921 void CmNotifyClientThread(THREAD *thread, void *param)\r
10922 {\r
10923         NOTIFY_CLIENT *nc;\r
10924         // 引数チェック\r
10925         if (thread == NULL)\r
10926         {\r
10927                 return;\r
10928         }\r
10929 \r
10930         nc = cm->NotifyClient;\r
10931 \r
10932         // 次の通知を待機する\r
10933         while (cm->Halt == false)\r
10934         {\r
10935                 if (CcWaitNotify(nc))\r
10936                 {\r
10937                         // メッセージ送信\r
10938                         PostMessage(cm->hMainWnd, WM_CM_NOTIFY, 0, 0);\r
10939                 }\r
10940                 else\r
10941                 {\r
10942                         // 切断された\r
10943                         if (cm->Halt == false)\r
10944                         {\r
10945                                 if (cm != NULL)\r
10946                                 {\r
10947                                         CmFreeTrayExternal((void *)cm->hMainWnd);\r
10948                                 }\r
10949                                 CncExit();\r
10950                                 exit(0);\r
10951                         }\r
10952                         break;\r
10953                 }\r
10954         }\r
10955 }\r
10956 \r
10957 // 通知クライアントのスレッドを終了\r
10958 void CmFreeNotifyClientThread()\r
10959 {\r
10960         cm->Halt = true;\r
10961 \r
10962         // 切断\r
10963         CcStopNotify(cm->NotifyClient);\r
10964 \r
10965         // スレッド終了を待機する\r
10966         WaitThread(cm->NotifyClientThread, INFINITE);\r
10967 \r
10968         // コネクション終了\r
10969         CcDisconnectNotify(cm->NotifyClient);\r
10970         ReleaseThread(cm->NotifyClientThread);\r
10971 }\r
10972 \r
10973 // メインウインドウのサイズ変更\r
10974 void CmMainWindowOnSize(HWND hWnd)\r
10975 {\r
10976         RECT r;\r
10977         UINT client_width, client_height;\r
10978         UINT status_height;\r
10979         // 引数チェック\r
10980         if (hWnd == NULL)\r
10981         {\r
10982                 return;\r
10983         }\r
10984 \r
10985         // メインウインドウのクライアント領域のサイズを取得する\r
10986         GetClientRect(hWnd, &r);\r
10987         client_width = MAX(r.right - r.left, 0);\r
10988         client_height = MAX(r.bottom - r.top, 0);\r
10989 \r
10990         SendMsg(hWnd, S_STATUSBAR, WM_SIZE, 0, 0);\r
10991 \r
10992         // ステータスバーのサイズを取得する\r
10993         GetWindowRect(DlgItem(hWnd, S_STATUSBAR), &r);\r
10994         status_height = MAX(r.bottom - r.top, 0);\r
10995 \r
10996         if (cm->HideStatusBar == false)\r
10997         {\r
10998                 client_height = MAX(client_height - status_height, 0);\r
10999         }\r
11000 \r
11001         MoveWindow(DlgItem(hWnd, L_ACCOUNT), 0, 0, client_width, client_height * 3 / 5 - 3, true);\r
11002         MoveWindow(DlgItem(hWnd, L_VLAN), 0, client_height * 3 / 5, client_width, client_height * 2 / 5, true);\r
11003 \r
11004         // ステータスバーの再描画\r
11005         CmRedrawStatusBar(hWnd);\r
11006 }\r
11007 \r
11008 // 現在接続中のアカウントをすべて切断する\r
11009 void CmDisconnectAll(HWND hWnd)\r
11010 {\r
11011         UINT i, num;\r
11012         LIST *o;\r
11013         // 引数チェック\r
11014         if (hWnd == NULL)\r
11015         {\r
11016                 return;\r
11017         }\r
11018 \r
11019         // 警告を表示する\r
11020         num = CmGetNumConnected(hWnd);\r
11021         if (num == 0)\r
11022         {\r
11023                 return;\r
11024         }\r
11025 \r
11026         if (MsgBoxEx(hWnd, MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2, _UU("CM_DISCONNECT_ALL"), num) == IDNO)\r
11027         {\r
11028                 return;\r
11029         }\r
11030 \r
11031         cm->PositiveDisconnectFlag = true;\r
11032 \r
11033         // 接続中のリストを作成する\r
11034         o = NewListFast(NULL);\r
11035 \r
11036         num = LvNum(hWnd, L_ACCOUNT);\r
11037         for (i = 0;i < num;i++)\r
11038         {\r
11039                 wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, i, 1);\r
11040                 if (s != NULL)\r
11041                 {\r
11042                         if (UniStrCmpi(s, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(s, _UU("CM_ACCOUNT_CONNECTING")) == 0)\r
11043                         {\r
11044                                 Add(o, LvGetStr(hWnd, L_ACCOUNT, i, 0));\r
11045                         }\r
11046                         Free(s);\r
11047                 }\r
11048         }\r
11049 \r
11050         for (i = 0;i < LIST_NUM(o);i++)\r
11051         {\r
11052                 wchar_t *s = LIST_DATA(o, i);\r
11053                 if (s != NULL)\r
11054                 {\r
11055                         CmDisconnect(hWnd, s);\r
11056                         Free(s);\r
11057                 }\r
11058         }\r
11059 \r
11060         ReleaseList(o);\r
11061 }\r
11062 \r
11063 // 現在接続中の接続設定数を取得する\r
11064 UINT CmGetNumConnected(HWND hWnd)\r
11065 {\r
11066         UINT i, num, num_active;\r
11067         // 引数チェック\r
11068         if (hWnd == NULL)\r
11069         {\r
11070                 return 0;\r
11071         }\r
11072 \r
11073         num_active = 0;\r
11074         num = LvNum(hWnd, L_ACCOUNT);\r
11075         for (i = 0;i < num;i++)\r
11076         {\r
11077                 wchar_t *s = LvGetStr(hWnd, L_ACCOUNT, i, 1);\r
11078                 if (s != NULL)\r
11079                 {\r
11080                         if (UniStrCmpi(s, _UU("CM_ACCOUNT_ONLINE")) == 0 || UniStrCmpi(s, _UU("CM_ACCOUNT_CONNECTING")) == 0)\r
11081                         {\r
11082                                 num_active++;\r
11083                         }\r
11084                         Free(s);\r
11085                 }\r
11086         }\r
11087 \r
11088         return num_active;\r
11089 }\r
11090 \r
11091 // ステータスバー情報を更新\r
11092 void CmRefreshStatusBar(HWND hWnd)\r
11093 {\r
11094         UINT num_active = CmGetNumConnected(hWnd);\r
11095         // 引数チェック\r
11096         if (hWnd == NULL)\r
11097         {\r
11098                 return;\r
11099         }\r
11100 \r
11101         if (num_active == 0)\r
11102         {\r
11103                 UniStrCpy(cm->StatudBar2, sizeof(cm->StatudBar2), _UU("CM_CONN_NO"));\r
11104                 cm->Icon2 = LoadSmallIcon(ICO_SERVER_OFFLINE);\r
11105         }\r
11106         else\r
11107         {\r
11108                 UniFormat(cm->StatudBar2, sizeof(cm->StatudBar2), _UU("CM_NUM_CONN_COUNT"), num_active);\r
11109                 cm->Icon2 = LoadSmallIcon(ICO_SERVER_ONLINE);\r
11110         }\r
11111 \r
11112         CmRedrawStatusBar(hWnd);\r
11113 }\r
11114 \r
11115 // ステータスバーの再描画\r
11116 void CmRedrawStatusBar(HWND hWnd)\r
11117 {\r
11118         HWND h;\r
11119         RECT r;\r
11120         int width;\r
11121         int x1, x2, x3;\r
11122         int xx[3];\r
11123         wchar_t tmp[MAX_SIZE];\r
11124         HICON icon;\r
11125         // 引数チェック\r
11126         if (hWnd == NULL)\r
11127         {\r
11128                 return;\r
11129         }\r
11130 \r
11131         h = cm->hStatusBar;\r
11132 \r
11133         // ステータスバーの横幅を取得\r
11134         GetWindowRect(h, &r);\r
11135         width = MAX(r.right - r.left, 0);\r
11136         x2 = 180;\r
11137         x3 = 245;\r
11138         x1 = MAX(width - x2 - x3, 0);\r
11139 \r
11140         // 3 つの部分に分割する\r
11141         xx[0] = x1;\r
11142         xx[1] = x2 + x1;\r
11143         xx[2] = x3 + x2 + x1;\r
11144         SendMsg(h, 0, SB_SETPARTS, 3, (LPARAM)xx);\r
11145 \r
11146         // アイコンを設定\r
11147         icon = (HICON)SendMsg(h, 0, SB_GETICON, 1, 0);\r
11148         if (icon != cm->Icon2)\r
11149         {\r
11150                 SendMsg(h, 0, SB_SETICON, 1, (LPARAM)cm->Icon2);\r
11151         }\r
11152 \r
11153         icon = (HICON)SendMsg(h, 0, SB_GETICON, 2, 0);\r
11154         if (icon != cm->Icon3)\r
11155         {\r
11156                 SendMsg(h, 0, SB_SETICON, 2, (LPARAM)cm->Icon3);\r
11157         }\r
11158 \r
11159         // 文字列を設定\r
11160         SendMsg(h, 0, SB_GETTEXTW, 0, (LPARAM)tmp);\r
11161         if (UniStrCmp(tmp, cm->StatudBar1))\r
11162         {\r
11163                 SendMsg(h, 0, SB_SETTEXTW, 0, (LPARAM)cm->StatudBar1);\r
11164         }\r
11165 \r
11166         SendMsg(h, 0, SB_GETTEXTW, 1, (LPARAM)tmp);\r
11167         if (UniStrCmp(tmp, cm->StatudBar2))\r
11168         {\r
11169                 SendMsg(h, 0, SB_SETTEXTW, 1, (LPARAM)cm->StatudBar2);\r
11170         }\r
11171 \r
11172         SendMsg(h, 0, SB_GETTEXTW, 2, (LPARAM)tmp);\r
11173         if (UniStrCmp(tmp, cm->StatudBar3))\r
11174         {\r
11175                 SendMsg(h, 0, SB_SETTEXTW, 2, (LPARAM)cm->StatudBar3);\r
11176         }\r
11177 }\r
11178 \r
11179 // メインウインドウの位置情報を保存する\r
11180 void CmSaveMainWindowPos(HWND hWnd)\r
11181 {\r
11182         WINDOWPLACEMENT p;\r
11183         // 引数チェック\r
11184         if (hWnd == NULL)\r
11185         {\r
11186                 return;\r
11187         }\r
11188 \r
11189         // 設定の保存\r
11190         MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "HideStatusBar", cm->HideStatusBar);\r
11191         MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "HideTrayIcon", cm->HideTrayIcon);\r
11192         MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "IconView", cm->IconView);\r
11193         MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "ShowGrid", cm->ShowGrid);\r
11194         MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "DisableVoice", cm->DisableVoice);\r
11195         MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "VoiceId", cm->VoiceId);\r
11196         MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "VistaStyle", cm->VistaStyle);\r
11197         MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY, "ShowPort", cm->ShowPort);\r
11198 \r
11199         // ウインドウ位置の保存\r
11200         Zero(&p, sizeof(p));\r
11201         p.length = sizeof(p);\r
11202         GetWindowPlacement(hWnd, &p);\r
11203 \r
11204         if (IsZero(&cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement)) == false)\r
11205         {\r
11206                 Copy(&p, &cm->FakeWindowPlacement, sizeof(cm->FakeWindowPlacement));\r
11207         }\r
11208 \r
11209         MsRegWriteBin(REG_CURRENT_USER, CM_REG_KEY, "WindowPlacement", &p, sizeof(p));\r
11210 \r
11211         CmSaveAccountListPos(hWnd);\r
11212         CmSaveVLanListPos(hWnd);\r
11213 }\r
11214 \r
11215 // メインウインドウを閉じる\r
11216 void CmMainWindowOnQuit(HWND hWnd)\r
11217 {\r
11218         UINT i;\r
11219         // 引数チェック\r
11220         if (hWnd == NULL)\r
11221         {\r
11222                 return;\r
11223         }\r
11224 \r
11225         if (cm->TrayInited)\r
11226         {\r
11227                 if (MsgBox(hWnd, MB_YESNO | MB_ICONQUESTION,\r
11228                         _UU("CM_EXIT_MESSAGE")) == IDNO)\r
11229                 {\r
11230                         return;\r
11231                 }\r
11232         }\r
11233 \r
11234         if (cm->OnCloseDispatched)\r
11235         {\r
11236                 return;\r
11237         }\r
11238         cm->OnCloseDispatched = true;\r
11239 \r
11240         CmCloseEasy();\r
11241 \r
11242         // トレイを解放\r
11243         CmFreeTray(hWnd);\r
11244 \r
11245         // メインウインドウの位置情報を保存する\r
11246         CmSaveMainWindowPos(hWnd);\r
11247 \r
11248         // ステータスウインドウを閉じる\r
11249         for (i = 0;i < LIST_NUM(cm->StatusWindowList);i++)\r
11250         {\r
11251                 HWND h = LIST_DATA(cm->StatusWindowList, i);\r
11252                 //EndDialog(h, 0);\r
11253                 PostMessage(h, WM_CLOSE, 0, 0);\r
11254         }\r
11255 \r
11256         ReleaseList(cm->StatusWindowList);\r
11257         cm->StatusWindowList = NULL;\r
11258 \r
11259         if (cm->WindowCount != 0)\r
11260         {\r
11261                 // 強制終了\r
11262                 exit(0);\r
11263         }\r
11264 \r
11265         // 閉じる\r
11266         CmFreeNotifyClientThread();\r
11267 \r
11268         EndDialog(hWnd, false);\r
11269 }\r
11270 \r
11271 // 起動時に使用する mutex を開始\r
11272 bool CmStartStartupMutex()\r
11273 {\r
11274         INSTANCE *o = NewSingleInstance(STARTUP_MUTEX_NAME);\r
11275 \r
11276         if (o == NULL)\r
11277         {\r
11278                 return false;\r
11279         }\r
11280 \r
11281         cm->StartupMutex = o;\r
11282 \r
11283         return true;\r
11284 }\r
11285 \r
11286 // 起動時に使用する mutex を解放\r
11287 void CmEndStartupMutex()\r
11288 {\r
11289         if (cm->StartupMutex != NULL)\r
11290         {\r
11291                 FreeSingleInstance(cm->StartupMutex);\r
11292 \r
11293                 cm->StartupMutex = NULL;\r
11294         }\r
11295 }\r
11296 \r
11297 // メインウインドウ\r
11298 void MainCMWindow()\r
11299 {\r
11300         HWND h;\r
11301         wchar_t *s;\r
11302         CM_SETTING a;\r
11303 \r
11304         if (CmStartStartupMutex() == false)\r
11305         {\r
11306                 return;\r
11307         }\r
11308 \r
11309         s = CmGenerateMainWindowTitle();\r
11310         h = SearchWindow(s);\r
11311         Free(s);\r
11312 \r
11313         Zero(&a, sizeof(a));\r
11314         CcGetCmSetting(cm->Client, &a);\r
11315         if (cm->server_name != NULL && a.EasyMode)\r
11316         {\r
11317                 CmEndStartupMutex();\r
11318                 MsgBox(NULL, MB_ICONEXCLAMATION, _UU("CM_EASY_MODE_NOT_ON_REMOTE"));\r
11319                 return;\r
11320         }\r
11321 \r
11322         // 動作モードの変更\r
11323         if (cm->CmSettingSupported)\r
11324         {\r
11325                 if (cm->CmSettingInitialFlag == CM_SETTING_INIT_SELECT)\r
11326                 {\r
11327                         if (h != NULL)\r
11328                         {\r
11329                                 CmEndStartupMutex();\r
11330                         }\r
11331 \r
11332                         // 選択画面を表示\r
11333                         CmSetting(NULL);\r
11334 \r
11335                         if (h != NULL)\r
11336                         {\r
11337                                 goto SEND_MESSAGES;\r
11338                         }\r
11339                         else\r
11340                         {\r
11341                                 return;\r
11342                         }\r
11343                 }\r
11344                 else if ((cm->CmSettingInitialFlag == CM_SETTING_INIT_EASY && cm->CmEasyModeSupported) || cm->CmSettingInitialFlag == CM_SETTING_INIT_NORMAL)\r
11345                 {\r
11346                         // 状態遷移\r
11347                         CM_SETTING a;\r
11348 \r
11349                         Zero(&a, sizeof(a));\r
11350                         CcGetCmSetting(cm->Client, &a);\r
11351 \r
11352                         if (cm->CmSettingInitialFlag == CM_SETTING_INIT_EASY)\r
11353                         {\r
11354                                 a.EasyMode = true;\r
11355                         }\r
11356                         else\r
11357                         {\r
11358                                 a.EasyMode = false;\r
11359                         }\r
11360 \r
11361                         CcSetCmSetting(cm->Client, &a);\r
11362                 }\r
11363         }\r
11364 \r
11365         if (h == NULL)\r
11366         {\r
11367                 // 他に同じタイトルのウインドウが無いのでウインドウを作成する\r
11368                 if (cm->server_name == NULL)\r
11369                 {\r
11370                         CmInitTryToExecUiHelper();\r
11371                         CnWaitForCnServiceReady();\r
11372                 }\r
11373                 Dialog(NULL, D_CM_MAIN, CmMainWindowProc, NULL);\r
11374                 CmFreeTryToExecUiHelper();\r
11375         }\r
11376         else\r
11377         {\r
11378 SEND_MESSAGES:\r
11379                 CmEndStartupMutex();\r
11380 \r
11381                 // すでに同じタイトルのウインドウが存在する場合はそれをアクティブにして\r
11382                 // 自分自身は終了する\r
11383                 SetForegroundWindow(h);\r
11384                 SendMessage(h, WM_CM_SHOW, 0, 0);\r
11385                 SetForegroundWindow(h);\r
11386 \r
11387                 if (cm->CmSettingInitialFlag != CM_SETTING_INIT_NONE)\r
11388                 {\r
11389                         // CM_SETTING が変更されたのでそれを通知する\r
11390                         SendMessage(h, WM_CM_SETTING_CHANGED_MESSAGE, 0, 0);\r
11391                 }\r
11392 \r
11393                 if (cm->import_file_name != NULL)\r
11394                 {\r
11395                         UINT msg;\r
11396                         if (cm->CmSettingInitialFlag == CM_SETTING_INIT_NONE)\r
11397                         {\r
11398                                 msg = CM_IMPORT_FILENAME_MSG;\r
11399                         }\r
11400                         else\r
11401                         {\r
11402                                 msg = CM_IMPORT_FILENAME_MSG_OVERWRITE;\r
11403                         }\r
11404 \r
11405                         CmSendImportMessage(h, cm->import_file_name, msg);\r
11406                 }\r
11407         }\r
11408 \r
11409         CmEndStartupMutex();\r
11410 }\r
11411 \r
11412 // インポートメッセージの送信\r
11413 void CmSendImportMessage(HWND hWnd, wchar_t *filename, UINT msg)\r
11414 {\r
11415         COPYDATASTRUCT cpy;\r
11416         // 引数チェック\r
11417         if (hWnd == NULL || filename == NULL)\r
11418         {\r
11419                 return;\r
11420         }\r
11421 \r
11422         // インポートすべきファイルを指定する\r
11423         Zero(&cpy, sizeof(cpy));\r
11424 \r
11425         cpy.cbData = UniStrSize(filename);\r
11426         cpy.lpData = filename;\r
11427         cpy.dwData = msg;\r
11428 \r
11429         SendMessage(hWnd, WM_COPYDATA, 0, (LPARAM)&cpy);\r
11430 }\r
11431 \r
11432 // ログインダイアログ\r
11433 UINT CmLoginDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)\r
11434 {\r
11435         // 引数チェック\r
11436         wchar_t server_name[MAX_SIZE];\r
11437         char password[MAX_PASSWORD_LEN + 1];\r
11438         bool bad_pass;\r
11439         if (hWnd == NULL)\r
11440         {\r
11441                 return 0;\r
11442         }\r
11443 \r
11444         switch (msg)\r
11445         {\r
11446         case WM_INITDIALOG:\r
11447                 if (cm->server_name != NULL)\r
11448                 {\r
11449                         StrToUni(server_name, sizeof(server_name), cm->server_name);\r
11450                 }\r
11451                 else\r
11452                 {\r
11453                         UniStrCpy(server_name, sizeof(server_name), _UU("CM_PW_LOCALMACHINE"));\r
11454                 }\r
11455                 FormatText(hWnd, S_TITLE, server_name);\r
11456                 break;\r
11457 \r
11458         case WM_COMMAND:\r
11459                 switch (wParam)\r
11460                 {\r
11461                 case IDOK:\r
11462                         if (cm->server_name != NULL)\r
11463                         {\r
11464                                 StrToUni(server_name, sizeof(server_name), cm->server_name);\r
11465                         }\r
11466                         else\r
11467                         {\r
11468                                 UniStrCpy(server_name, sizeof(server_name), _UU("CM_PW_LOCALMACHINE"));\r
11469                         }\r
11470                         GetTxtA(hWnd, E_PASSWORD, password, sizeof(password));\r
11471                         cm->Client = CcConnectRpc(cm->server_name == NULL ? "127.0.0.1" : cm->server_name,\r
11472                                 password, &bad_pass, NULL, 0);\r
11473                         if (cm->Client == NULL)\r
11474                         {\r
11475                                 MsgBox(hWnd, MB_ICONSTOP, _UU("CM_BAD_PASSWORD"));\r
11476                                 FocusEx(hWnd, E_PASSWORD);\r
11477                         }\r
11478                         else\r
11479                         {\r
11480                                 EndDialog(hWnd, true);\r
11481                         }\r
11482                         break;\r
11483                 case IDCANCEL:\r
11484                         Close(hWnd);\r
11485                         break;\r
11486                 }\r
11487                 break;\r
11488 \r
11489         case WM_CLOSE:\r
11490                 EndDialog(hWnd, false);\r
11491                 break;\r
11492         }\r
11493 \r
11494         return 0;\r
11495 }\r
11496 \r
11497 // ログイン\r
11498 bool LoginCM()\r
11499 {\r
11500         // まず空のパスワードでログインを試みる\r
11501         bool bad_pass, no_remote;\r
11502         wchar_t server_name[MAX_SIZE];\r
11503         RPC_CLIENT_VERSION a;\r
11504 \r
11505 RETRY:\r
11506         if (cm->server_name != NULL)\r
11507         {\r
11508                 StrToUni(server_name, sizeof(server_name), cm->server_name);\r
11509         }\r
11510         else\r
11511         {\r
11512                 UniStrCpy(server_name, sizeof(server_name), _UU("CM_PW_LOCALMACHINE"));\r
11513         }\r
11514 \r
11515         // 接続試行\r
11516         if ((cm->Client = CcConnectRpc(\r
11517                 cm->server_name == NULL ? "localhost" : cm->server_name,\r
11518                 "", &bad_pass, &no_remote, cm->StartupMode == false ? 0 : 60000)) == NULL)\r
11519         {\r
11520                 if (no_remote)\r
11521                 {\r
11522                         // リモート接続が拒否された\r
11523                         if (MsgBoxEx(NULL, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("CM_NO_REMOTE"), server_name) == IDRETRY)\r
11524                         {\r
11525                                 // 再試行\r
11526                                 goto RETRY;\r
11527                         }\r
11528                         else\r
11529                         {\r
11530                                 return false;\r
11531                         }\r
11532                 }\r
11533                 else if (bad_pass)\r
11534                 {\r
11535                         if (Dialog(NULL, D_CM_LOGIN, CmLoginDlgProc, NULL) == false)\r
11536                         {\r
11537                                 return false;\r
11538                         }\r
11539                 }\r
11540                 else\r
11541                 {\r
11542                         // 接続失敗\r
11543                         if (cm->StartupMode == false && MsgBoxEx(NULL, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("CM_CONNECT_FAILED"), server_name) == IDRETRY)\r
11544                         {\r
11545                                 // 再試行\r
11546                                 goto RETRY;\r
11547                         }\r
11548                         else\r
11549                         {\r
11550                                 return false;\r
11551                         }\r
11552                 }\r
11553         }\r
11554 \r
11555         Zero(&a, sizeof(a));\r
11556         CcGetClientVersion(cm->Client, &a);\r
11557         if (a.ClientBuildInt >= 5192)\r
11558         {\r
11559                 cm->CmSettingSupported = true;\r
11560                 cm->CmEasyModeSupported = true;\r
11561                 if (OS_IS_WINDOWS_9X(a.OsType))\r
11562                 {\r
11563                         cm->CmEasyModeSupported = false;\r
11564                 }\r
11565         }\r
11566 \r
11567         return true;\r
11568 }\r
11569 \r
11570 // メイン処理\r
11571 void MainCM()\r
11572 {\r
11573         // 引数に /remote があればリモート接続の画面を出す\r
11574         char *cmdline = GetCommandLineStr();\r
11575 \r
11576         if (StrCmpi(cmdline, "/remote") == 0)\r
11577         {\r
11578                 char *hostname = RemoteDlg(NULL, CM_REG_KEY, ICO_VPN, _UU("CM_TITLE"), _UU("CM_REMOTE_TITLE"), NULL);\r
11579                 if (hostname == NULL)\r
11580                 {\r
11581                         return;\r
11582                 }\r
11583                 if (cm->server_name != NULL)\r
11584                 {\r
11585                         Free(cm->server_name);\r
11586                 }\r
11587                 cm->server_name = NULL;\r
11588                 if (StrCmpi(hostname, "localhost") != 0 && StrCmpi(hostname, "127.0.0.1") != 0 )\r
11589                 {\r
11590                         cm->server_name = hostname;\r
11591                 }\r
11592         }\r
11593 \r
11594         if (StrCmpi(cmdline, "/startup") == 0)\r
11595         {\r
11596                 // スタートアップモード\r
11597                 cm->StartupMode = true;\r
11598         }\r
11599 \r
11600         Free(cmdline);\r
11601 \r
11602         if (IsZero(cm->ShortcutKey, SHA1_SIZE) == false)\r
11603         {\r
11604                 //if (MsGetCurrentTerminalSessionId() == 0)\r
11605                 {\r
11606                         // ショートカット接続の開始\r
11607                         CmConnectShortcut(cm->ShortcutKey);\r
11608                 }/*\r
11609                 else\r
11610                 {\r
11611                         MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("CM_SHORTCUT_DESKTOP_MSG"),\r
11612                                 MsGetCurrentTerminalSessionId());\r
11613                 }*/\r
11614                 return;\r
11615         }\r
11616 \r
11617         // ログイン\r
11618         if (LoginCM() == false)\r
11619         {\r
11620                 return;\r
11621         }\r
11622 \r
11623         //ジャンプリストの更新\r
11624         CmUpdateJumpList(0);\r
11625 \r
11626         // メインウインドウ\r
11627         MainCMWindow();\r
11628 \r
11629         // ログアウト\r
11630         LogoutCM();\r
11631 }\r
11632 \r
11633 // ログアウト\r
11634 void LogoutCM()\r
11635 {\r
11636         if (cm->Client != NULL)\r
11637         {\r
11638                 CcDisconnectRpc(cm->Client);\r
11639         }\r
11640 }\r
11641 \r
11642 // クライアント接続マネージャ起動関数\r
11643 void CMExec()\r
11644 {\r
11645         // 初期化\r
11646         InitCM();\r
11647 \r
11648         // メイン処理\r
11649         MainCM();\r
11650 \r
11651         // 解放\r
11652         FreeCM();\r
11653 }\r
11654 \r
11655 // HUB 列挙スレッド\r
11656 void CmEnumHubThread(THREAD *t, void *param)\r
11657 {\r
11658         CM_ENUM_HUB *e = (CM_ENUM_HUB *)param;\r
11659         HWND hWnd;\r
11660         // 引数チェック\r
11661         if (t == NULL || param == NULL)\r
11662         {\r
11663                 return;\r
11664         }\r
11665 \r
11666         e->Thread = t;\r
11667         hWnd = e->hWnd;\r
11668         LockList(cm->EnumHubList);\r
11669         {\r
11670                 Add(cm->EnumHubList, e);\r
11671         }\r
11672         UnlockList(cm->EnumHubList);\r
11673 \r
11674         // スレッド初期化完了\r
11675         NoticeThreadInit(t);\r
11676 \r
11677         // セッション作成\r
11678         e->Session = NewRpcSession(cm->Cedar, e->ClientOption);\r
11679         if (e->Session)\r
11680         {\r
11681                 // HUB の列挙\r
11682                 e->Hub = EnumHub(e->Session);\r
11683 \r
11684                 if (e->Hub != NULL)\r
11685                 {\r
11686                         // 列挙完了\r
11687                         // コンボボックスに追加する\r
11688                         if (CbNum(hWnd, C_HUBNAME) == 0)\r
11689                         {\r
11690                                 UINT i;\r
11691                                 wchar_t tmp[MAX_SIZE];\r
11692                                 for (i = 0;i < e->Hub->NumTokens;i++)\r
11693                                 {\r
11694                                         StrToUni(tmp, sizeof(tmp), e->Hub->Token[i]);\r
11695                                         CbAddStr(hWnd, C_HUBNAME, tmp, 0);\r
11696                                 }\r
11697                         }\r
11698 \r
11699                         // メモリ解放\r
11700                         FreeToken(e->Hub);\r
11701                 }\r
11702 \r
11703                 // セッション解放\r
11704                 ReleaseSession(e->Session);\r
11705         }\r
11706 \r
11707         LockList(cm->EnumHubList);\r
11708         {\r
11709                 Delete(cm->EnumHubList, e);\r
11710         }\r
11711         UnlockList(cm->EnumHubList);\r
11712 \r
11713         Free(e->ClientOption);\r
11714         Free(e);\r
11715 }\r
11716 \r
11717 // HUB 列挙の開始\r
11718 void CmEnumHubStart(HWND hWnd, CLIENT_OPTION *o)\r
11719 {\r
11720         CM_ENUM_HUB *e;\r
11721         THREAD *t;\r
11722         // 引数チェック\r
11723         if (hWnd == NULL || o == NULL)\r
11724         {\r
11725                 return;\r
11726         }\r
11727 \r
11728         if (StrLen(o->Hostname) == 0 ||\r
11729                 o->Port == 0)\r
11730         {\r
11731                 return;\r
11732         }\r
11733 \r
11734         if (o->ProxyType != PROXY_DIRECT)\r
11735         {\r
11736                 if (StrLen(o->ProxyName) == 0 ||\r
11737                         o->ProxyPort == 0)\r
11738                 {\r
11739                         return;\r
11740                 }\r
11741         }\r
11742 \r
11743         if (LvNum(hWnd, C_HUBNAME) != 0)\r
11744         {\r
11745                 return;\r
11746         }\r
11747 \r
11748         e = ZeroMalloc(sizeof(CM_ENUM_HUB));\r
11749         e->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));\r
11750         e->hWnd = hWnd;\r
11751         Copy(e->ClientOption, o, sizeof(CLIENT_OPTION));\r
11752 \r
11753         t = NewThread(CmEnumHubThread, e);\r
11754         WaitThreadInit(t);\r
11755         ReleaseThread(t);\r
11756 }\r
11757 \r
11758 // HUB 列挙処理の初期化\r
11759 void CmInitEnumHub()\r
11760 {\r
11761         cm->EnumHubList = NewList(NULL);\r
11762 }\r
11763 \r
11764 // HUB 列挙処理の解放\r
11765 void CmFreeEnumHub()\r
11766 {\r
11767         LIST *o;\r
11768         UINT i;\r
11769         if (cm->EnumHubList == NULL)\r
11770         {\r
11771                 return;\r
11772         }\r
11773 \r
11774         o = NewList(NULL);\r
11775         LockList(cm->EnumHubList);\r
11776         {\r
11777                 UINT i;\r
11778                 for (i = 0;i < LIST_NUM(cm->EnumHubList);i++)\r
11779                 {\r
11780                         CM_ENUM_HUB *e = LIST_DATA(cm->EnumHubList, i);\r
11781                         Add(o, e->Thread);\r
11782                         AddRef(e->Thread->ref);\r
11783                 }\r
11784         }\r
11785         UnlockList(cm->EnumHubList);\r
11786 \r
11787         for (i = 0;i < LIST_NUM(o);i++)\r
11788         {\r
11789                 THREAD *t = LIST_DATA(o, i);\r
11790                 WaitThread(t, INFINITE);\r
11791                 ReleaseThread(t);\r
11792         }\r
11793         ReleaseList(o);\r
11794 \r
11795         ReleaseList(cm->EnumHubList);\r
11796 }\r
11797 \r
11798 // クライアント接続マネージャの初期化\r
11799 #define APPID L"SoftEther.SoftEther UT-VPN Client"\r
11800 \r
11801 void InitCM()\r
11802 {\r
11803         UNI_TOKEN_LIST *ut;\r
11804         if (cm != NULL)\r
11805         {\r
11806                 return;\r
11807         }\r
11808 \r
11809         //Set Application ID\r
11810         if(JL_SetCurrentProcessExplicitAppUserModelID(APPID) != S_OK)\r
11811         {\r
11812         }\r
11813 \r
11814         CmDeleteOldStartupTrayFile();\r
11815 \r
11816         MsSetShutdownParameters(0x4ff, SHUTDOWN_NORETRY);\r
11817 \r
11818         // メモリ確保\r
11819         cm = ZeroMalloc(sizeof(CM));\r
11820 \r
11821         // コマンドライン引数が設定されている場合はサーバー名として取り扱う\r
11822         ut = GetCommandLineUniToken();\r
11823 \r
11824         if (ut->NumTokens >= 1)\r
11825         {\r
11826                 if (UniStrLen(ut->Token[0]) != 0)\r
11827                 {\r
11828                         if (UniStrCmpi(ut->Token[0], L"cm") != 0 && ut->Token[0][0] != L'/')\r
11829                         {\r
11830                                 BUF *b = UniStrToBin(ut->Token[0]);\r
11831                                 if (b->Size == SHA1_SIZE)\r
11832                                 {\r
11833                                         // 接続設定のショートカットキーとして扱う\r
11834                                         Copy(cm->ShortcutKey, b->Buf, SHA1_SIZE);\r
11835                                 }\r
11836                                 else\r
11837                                 {\r
11838                                         if (UniEndWith(ut->Token[0], L".uvpn") == false)\r
11839                                         {\r
11840                                                 // サーバー名として扱う\r
11841                                                 cm->server_name = CopyUniToStr(ut->Token[0]);\r
11842                                         }\r
11843                                         else\r
11844                                         {\r
11845                                                 // インポートファイル名として扱う\r
11846                                                 cm->import_file_name = CopyUniStr(ut->Token[0]);\r
11847                                         }\r
11848                                 }\r
11849                                 FreeBuf(b);\r
11850                         }\r
11851                         else if (UniStrCmpi(ut->Token[0], L"/easy") == 0)\r
11852                         {\r
11853                                 // 簡易モード\r
11854                                 if (ut->NumTokens >= 2)\r
11855                                 {\r
11856                                         // インポートすべき接続設定が指定されている\r
11857                                         cm->import_file_name = CopyUniStr(ut->Token[1]);\r
11858                                 }\r
11859 \r
11860                                 cm->CmSettingInitialFlag = CM_SETTING_INIT_EASY;\r
11861                         }\r
11862                         else if (UniStrCmpi(ut->Token[0], L"/normal") == 0)\r
11863                         {\r
11864                                 // 通常モード\r
11865                                 if (ut->NumTokens >= 2)\r
11866                                 {\r
11867                                         // インポートすべき接続設定が指定されている\r
11868                                         cm->import_file_name = CopyUniStr(ut->Token[1]);\r
11869                                 }\r
11870 \r
11871                                 cm->CmSettingInitialFlag = CM_SETTING_INIT_NORMAL;\r
11872                         }\r
11873                         else if (UniStrCmpi(ut->Token[0], L"/select") == 0)\r
11874                         {\r
11875                                 // 選択画面\r
11876                                 cm->CmSettingInitialFlag = CM_SETTING_INIT_SELECT;\r
11877                         }\r
11878                 }\r
11879         }\r
11880 \r
11881         UniFreeToken(ut);\r
11882 \r
11883         InitWinUi(_UU("CM_TITLE"), _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE"));\r
11884 \r
11885         // アルファブレンディング関係\r
11886         UseAlpha = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "UseAlpha");\r
11887         AlphaValue = MsRegReadInt(REG_CURRENT_USER, CM_REG_KEY, "AlphaValue");\r
11888 \r
11889         cm->Cedar = NewCedar(NULL, NULL);\r
11890         CmInitEnumHub();\r
11891 }\r
11892 \r
11893 // クライアント接続マネージャの終了\r
11894 void FreeCM()\r
11895 {\r
11896         if (cm == NULL)\r
11897         {\r
11898                 return;\r
11899         }\r
11900 \r
11901         CmFreeEnumHub();\r
11902         ReleaseCedar(cm->Cedar);\r
11903 \r
11904         FreeWinUi();\r
11905 \r
11906         // メモリ解放\r
11907         if (cm->server_name != NULL)\r
11908         {\r
11909                 Free(cm->server_name);\r
11910         }\r
11911         Free(cm);\r
11912         cm = NULL;\r
11913 }\r
11914 \r
11915 \r
11916 \r
11917 //////////////////////////////////////////////////////////////////////////\r
11918 //JumpList ToDo\r
11919 // By Takao Ito\r
11920 void *CmUpdateJumpList(UINT start_id)\r
11921 {\r
11922         HMENU h = NULL;\r
11923         UINT i;\r
11924         RPC_CLIENT_ENUM_ACCOUNT a;\r
11925         LIST *o;\r
11926         bool easy;\r
11927 \r
11928         JL_PCustomDestinationList pcdl;\r
11929         JL_PObjectCollection poc;\r
11930         JL_PShellLink shell;\r
11931         JL_PObjectArray poaRemoved;\r
11932 \r
11933         HRESULT hr;\r
11934 \r
11935         if (cm->server_name != NULL)\r
11936         {\r
11937                 // 外部 PC の場合は利用しない\r
11938                 return NULL;\r
11939         }\r
11940 \r
11941         //試しに追加\r
11942         if(SUCCEEDED(JL_CreateCustomDestinationList(&pcdl,APPID)))\r
11943         {\r
11944 \r
11945                 JL_DeleteJumpList(pcdl,APPID);\r
11946 \r
11947                 easy = cm->CmSetting.EasyMode;\r
11948 \r
11949                 Zero(&a, sizeof(a));\r
11950 \r
11951                 \r
11952                 if (CcEnumAccount(cm->Client, &a) == ERR_NO_ERROR)\r
11953                 {\r
11954                         o = NewListFast(CiCompareClientAccountEnumItemByLastConnectDateTime);\r
11955 \r
11956                         for (i = 0;i < a.NumItem;i++)\r
11957                         {\r
11958                                 RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = a.Items[i];\r
11959 \r
11960                                 item->tmp1 = i;\r
11961 \r
11962                                 if (item->LastConnectDateTime != 0)\r
11963                                 {\r
11964                                         Add(o, item);\r
11965                                 }\r
11966                         }\r
11967 \r
11968                         Sort(o);\r
11969 \r
11970                         if(LIST_NUM(o) > 0)\r
11971                         {\r
11972 \r
11973                                 if(SUCCEEDED(JL_BeginList(pcdl, &poaRemoved)))\r
11974                                 {\r
11975 \r
11976 \r
11977                                         //コレクションの作成\r
11978                                         if(SUCCEEDED(JL_CreateObjectCollection(&poc)))\r
11979                                         {\r
11980 \r
11981                                                 for (i = 0;i < MIN(LIST_NUM(o), CM_NUM_RECENT);i++)\r
11982                                                 {\r
11983 \r
11984                                                         RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = (RPC_CLIENT_ENUM_ACCOUNT_ITEM *)LIST_DATA(o, i);\r
11985 //                                                      wchar_t tmp[MAX_PATH];\r
11986                                                         wchar_t *account_name;\r
11987                                                         char *server_name;\r
11988                                                         char *hub_name;\r
11989 //                                                      CM_ACCOUNT *a;\r
11990                                                         UCHAR key[SHA1_SIZE];\r
11991                                                         RPC_CLIENT_GET_ACCOUNT c;\r
11992 \r
11993 \r
11994                                                         account_name = item->AccountName;\r
11995                                                         server_name = item->ServerName;\r
11996                                                         hub_name = item->HubName;\r
11997 \r
11998 \r
11999 \r
12000                                                         //\r
12001                                                         //a = CmGetExistAccountObject(hWnd, account_name);\r
12002 \r
12003 \r
12004                                                         //if (a == NULL)\r
12005                                                         //{\r
12006                                                         //continue;\r
12007                                                         //}\r
12008 \r
12009                                                         //Copy(key, a->ShortcutKey, SHA1_SIZE);\r
12010                                                         //\r
12011 \r
12012                                                         Zero(&c, sizeof(c));\r
12013                                                         UniStrCpy(c.AccountName, sizeof(c.AccountName), account_name);\r
12014                                                         if (CALL(NULL, CcGetAccount(cm->Client, &c)) == false)\r
12015                                                         {\r
12016                                                                 break;\r
12017                                                         }\r
12018 \r
12019                                                         Copy(key, c.ShortcutKey, SHA1_SIZE);\r
12020 \r
12021                                                         if (IsZero(key, SHA1_SIZE))\r
12022                                                         {\r
12023                                                                 //MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_SHORTCUT_UNSUPPORTED"));\r
12024                                                         }\r
12025                                                         else\r
12026                                                         {\r
12027 \r
12028                                                                 //wchar_t target[MAX_PATH];\r
12029                                                                 ////wchar_t workdir[MAX_PATH];\r
12030                                                                 //wchar_t args[MAX_PATH];\r
12031                                                                 ////wchar_t comment[MAX_SIZE];\r
12032                                                                 //wchar_t icon[MAX_PATH];\r
12033 \r
12034                                                                 char key_str[64];\r
12035                                                                 wchar_t target[MAX_PATH];\r
12036                                                                 //wchar_t workdir[MAX_PATH];\r
12037                                                                 wchar_t args[MAX_PATH];\r
12038                                                                 wchar_t commentW[MAX_SIZE];\r
12039                                                                 wchar_t icon[MAX_PATH];\r
12040                                                                 int iconNum;\r
12041 \r
12042                                                                 //char icon = "C:\\Server.ico";\r
12043 \r
12044                                                                 BinToStr(key_str, sizeof(key_str), key, SHA1_SIZE);\r
12045                                                                 UniStrCpy(target, sizeof(target), MsGetExeFileNameW());\r
12046                                                                 StrToUni(args, sizeof(args), key_str);\r
12047                                                                 UniStrCpy(icon, sizeof(icon), MsGetExeFileNameW());\r
12048                                                                 UniFormat(commentW, sizeof(commentW), _UU("CM_SHORTCUT_COMMENT"), account_name);\r
12049 \r
12050                                                                 if(item->Connected)\r
12051                                                                 {\r
12052                                                                         iconNum = 1;\r
12053                                                                 }\r
12054                                                                 else\r
12055                                                                 {\r
12056                                                                         iconNum = 2;\r
12057                                                                 }\r
12058 \r
12059                                                                 hr = JL_CreateShellLink(\r
12060                                                                         target,\r
12061                                                                         args,\r
12062                                                                         account_name,\r
12063                                                                         icon,iconNum,\r
12064                                                                         commentW,\r
12065                                                                         &shell);\r
12066 \r
12067                                                                 if(SUCCEEDED(hr))\r
12068                                                                 {\r
12069 \r
12070                                                                         if(SUCCEEDED(JL_ObjectCollectionAddShellLink(poc, shell)))\r
12071                                                                         {\r
12072                                                                                 //Print("Add JumpList %d c:%s\n",i, comment);\r
12073                                                                                 //wprintf(comment);\r
12074                                                                         }\r
12075                                                                         JL_ReleaseShellLink(shell);\r
12076                                                                 }\r
12077                                                         }\r
12078 \r
12079                                                         CiFreeClientGetAccount(&c);\r
12080                                                 }\r
12081 \r
12082                                                 hr = JL_AddCategoryToList(pcdl,poc,_UU("CM_JUMPLIST_RCCONNECT"),poaRemoved);\r
12083 \r
12084                                                 if(SUCCEEDED(hr))\r
12085                                                 {\r
12086                                                         //wprintf(L"AddCategory\n");\r
12087 \r
12088                                                         hr = JL_CommitList(pcdl);\r
12089                                                         if(SUCCEEDED(hr))\r
12090                                                         {\r
12091                                                                 //wprintf(L"JumpList Commit\n");\r
12092                                                         }\r
12093                                                 }\r
12094                                                 else\r
12095                                                 {\r
12096                                                         //wprintf(L"Erro JumpList AddCategory %x\n", hr);\r
12097                                                 }\r
12098 \r
12099                                                 //リリース\r
12100                                                 JL_ReleaseObjectCollection(poc);\r
12101                                         }\r
12102                                 }\r
12103 \r
12104                         }\r
12105 \r
12106 \r
12107                         ReleaseList(o);\r
12108 \r
12109                         CiFreeClientEnumAccount(&a);\r
12110                 }\r
12111 \r
12112                 \r
12113 \r
12114 \r
12115                 /*\r
12116                         JL_BeginList(pcdl, &poaRemoved);\r
12117 \r
12118                         JL_CreateObjectCollection(&poc);\r
12119 \r
12120                         //てしゅと\r
12121                         for (i = 0; i < 5; i++)\r
12122                         {\r
12123 \r
12124                                 JL_CreateShellLink(\r
12125                                         "",\r
12126                                         "",\r
12127                                         L"せつぞく",\r
12128                                         NULL,0,\r
12129                                         NULL,\r
12130                                         &shell);\r
12131                                 JL_ObjectCollectionAddShellLink(poc, shell);\r
12132 \r
12133                                 JL_ReleaseShellLink(shell);\r
12134 \r
12135                         }\r
12136 \r
12137                         JL_AddCategoryToList(pcdl,poc,_UU("CM_JUMPLIST_RCCONNECT"),poaRemoved);\r
12138                         JL_CommitList(pcdl);\r
12139                         JL_ReleaseObjectCollection(poc);\r
12140 \r
12141                 JL_ReleaseCustomDestinationList(pcdl);\r
12142                 */\r
12143 \r
12144         }\r
12145 \r
12146         return h;\r
12147 }\r
12148 \r
12149 \r
12150 \r
12151 #endif  // WIN32\r
12152 \r
12153 \r