1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Cedar Communication Module
3 //
4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
5 //
6 // Copyright (c) Daiyuu Nobori.
7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
8 // Copyright (c) SoftEther Corporation.
9 // Copyright (c) all contributors on SoftEther VPN project in GitHub.
10 //
11 // All Rights Reserved.
12 //
13 // http://www.softether.org/
14 //
15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
17 //
18 // License: The Apache License, Version 2.0
19 // https://www.apache.org/licenses/LICENSE-2.0
20 //
21 // DISCLAIMER
22 // ==========
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 //
32 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
33 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
34 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
35 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
36 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
37 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
38 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
39 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
40 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
41 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
42 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
43 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
44 // LAW OR COURT RULE.
45 //
46 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
47 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
48 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
49 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
50 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
51 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
52 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
53 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
54 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
55 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
56 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
57 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
58 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
59 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
60 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
61 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
62 // STATEMENT FOR WARNING AND DISCLAIMER.
63 //
64 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
65 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
66 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
67 //
68 //
69 // SOURCE CODE CONTRIBUTION
70 // ------------------------
71 //
72 // Your contribution to SoftEther VPN Project is much appreciated.
73 // Please send patches to us through GitHub.
74 // Read the SoftEther VPN Patch Acceptance Policy in advance:
75 // http://www.softether.org/5-download/src/9.patch
76 //
77 //
78 // DEAR SECURITY EXPERTS
79 // ---------------------
80 //
81 // If you find a bug or a security vulnerability please kindly inform us
82 // about the problem immediately so that we can fix the security problem
83 // to protect a lot of users around the world as soon as possible.
84 //
85 // Our e-mail address for security reports is:
86 // softether-vpn-security [at] softether.org
87 //
88 // Please note that the above e-mail address is not a technical support
89 // inquiry address. If you need technical assistance, please visit
90 // http://www.softether.org/ and ask your question on the users forum.
91 //
92 // Thank you for your cooperation.
93 //
94 //
95 // NO MEMORY OR RESOURCE LEAKS
96 // ---------------------------
97 //
98 // The memory-leaks and resource-leaks verification under the stress
99 // test has been passed before release this source code.
100
101
102 // WinUi.c
103 // User interface code for Win32
104
105 #include <GlobalConst.h>
106
107 #ifdef WIN32
108
109 #define WINUI_C
110
111 #define _WIN32_WINNT 0x0502
112 #define WINVER 0x0502
113 #include <winsock2.h>
114 #include <windows.h>
115 #include <wincrypt.h>
116 #include <wininet.h>
117 #include <Iphlpapi.h>
118 #include <shlobj.h>
119 #include <commctrl.h>
120 #include <Dbghelp.h>
121 #include <stdio.h>
122 #include <stdlib.h>
123 #include <string.h>
124 #include <wchar.h>
125 #include <stdarg.h>
126 #include <time.h>
127 #include <errno.h>
128 #include <Mayaqua/Mayaqua.h>
129 #include <Cedar/Cedar.h>
130 #include "../PenCore/resource.h"
131
132 char cached_pin_code[MAX_SIZE] = {0};
133 UINT64 cached_pin_code_expires = 0;
134
135 static HINSTANCE hDll = NULL;
136 static wchar_t *title_bar = NULL;
137 static char *font_name = NULL;
138 static UINT font_size = 9;
139 static HIMAGELIST large_image_list = NULL, small_image_list = NULL;
140 static LIST *icon_list = NULL;
141 static HINSTANCE hMsHtml = NULL;
142 static UINT init_winui_counter = 0;
143 static HDC hCommonDC = NULL;
144 static LOCK *lock_common_dc = NULL;
145
146 bool UseAlpha = false;
147 UINT AlphaValue = 100;
148
149 static THREAD *led_thread = NULL;
150 static bool thread_stop = false;
151 static bool g_led_special = false;
152 static bool g_tcpip_topmost = false;
153 static DWORD tls_current_wizard = 0xFFFFFFFF;
154
155 #define WINUI_PSM_SHOWWIZBUTTONS (WM_USER + 138)
156 #define WINUI_PropSheet_ShowWizButtons(hDlg, dwFlag, dwButton) \
157 PSTMSG(hDlg, WINUI_PSM_SHOWWIZBUTTONS, (WPARAM)(dwFlag), (LPARAM)(dwButton))
158
159 typedef struct _WINUI_SHSTOCKICONINFO
160 {
161 DWORD cbSize;
162 HICON hIcon;
163 int iSysImageIndex;
164 int iIcon;
165 WCHAR szPath[MAX_PATH];
166 } WINUI_SHSTOCKICONINFO;
167
168 // Get whether the current process is foreground
IsThisProcessForeground()169 bool IsThisProcessForeground()
170 {
171 HWND hWnd = GetForegroundWindow();
172 DWORD proc_id, thread_id;
173
174 if (hWnd == NULL)
175 {
176 return false;
177 }
178
179 proc_id = 0;
180 thread_id = GetWindowThreadProcessId(hWnd, &proc_id);
181
182 if (proc_id == MsGetCurrentProcessId())
183 {
184 return true;
185 }
186
187 return false;
188 }
IsThisProcessForegroundForUpdateUi(UPDATE_CLIENT * c,void * p)189 bool IsThisProcessForegroundForUpdateUi(UPDATE_CLIENT *c, void *p)
190 {
191 return IsThisProcessForeground();
192 }
193
194 // Update notification screen dialog procedure
UpdateConfigDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)195 UINT UpdateConfigDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
196 {
197 WINUI_UPDATE *u = (WINUI_UPDATE *)param;
198 UPDATE_CLIENT_SETTING s;
199
200 switch (msg)
201 {
202 case WM_INITDIALOG:
203 SetTimer(hWnd, 1, 100, NULL);
204
205 LoadUpdateUiSetting(u, &s);
206
207 Check(hWnd, S_ENABLE, s.DisableCheck == false);
208 Check(hWnd, S_DISBLE, s.DisableCheck);
209
210 DlgFont(hWnd, S_TITLE, 10, true);
211 FormatText(hWnd, S_TITLE, u->SoftwareTitle);
212 FormatText(hWnd, S_INFO, u->SoftwareTitle);
213 break;
214
215 case WM_TIMER:
216 switch (wParam)
217 {
218 case 1:
219 if (u->UpdateClient->HaltFlag)
220 {
221 goto LABEL_CLOSE;
222 }
223 break;
224 }
225 break;
226
227 case WM_COMMAND:
228 switch (wParam)
229 {
230 case IDCANCEL:
231 Close(hWnd);
232 break;
233 }
234 break;
235
236 case WM_CLOSE:
237 LABEL_CLOSE:
238 LoadUpdateUiSetting(u, &s);
239
240 s.DisableCheck = IsChecked(hWnd, S_DISBLE);
241
242 if (s.DisableCheck)
243 {
244 s.LatestIgnoreBuild = 0;
245 }
246
247 SaveUpdateUiSetting(u, &s);
248
249 SetUpdateClientSetting(u->UpdateClient, &s);
250
251 EndDialog(hWnd, !s.DisableCheck);
252
253 break;
254 }
255
256 return 0;
257 }
258
259 // Show the update notification setting screen
ConfigUpdateUi(WINUI_UPDATE * u,HWND hWnd)260 bool ConfigUpdateUi(WINUI_UPDATE *u, HWND hWnd)
261 {
262 // Validate arguments
263 if (u == NULL)
264 {
265 return false;
266 }
267
268 return Dialog(hWnd, D_UPDATE_CONFIG, UpdateConfigDlgProc, u);
269 }
270
271 // Update notification dialog procedure
UpdateNoticeDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)272 UINT UpdateNoticeDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
273 {
274 WINUI_UPDATE_DLG_PARAM *p = (WINUI_UPDATE_DLG_PARAM *)param;
275 WINUI_UPDATE *u = NULL;
276 UPDATE_CLIENT_SETTING s;
277 char date_current[64];
278 char date_latest[64];
279 wchar_t date_current_str[128];
280 wchar_t date_latest_str[128];
281 char *font_name = NULL;
282
283 if (p != NULL)
284 {
285 u = p->Update;
286 }
287
288 switch (msg)
289 {
290 case WM_INITDIALOG:
291 Zero(date_current_str, sizeof(date_current_str));
292 Zero(date_latest_str, sizeof(date_latest_str));
293
294 GetDateStr64(date_current, sizeof(date_current), u->CurrentDate);
295 if (u->CurrentDate != 0)
296 {
297 UniFormat(date_current_str, sizeof(date_current_str), _UU("DLG_UPDATE_DATE"), date_current);
298 }
299
300 GetDateStr64(date_latest, sizeof(date_latest), p->LatestDate);
301 if (p->LatestDate != 0)
302 {
303 UniFormat(date_latest_str, sizeof(date_latest_str), _UU("DLG_UPDATE_DATE"), date_latest);
304 }
305
306 FormatText(hWnd, 0, u->UpdateClient->SoftwareTitle);
307 FormatText(hWnd, S_INFO, u->UpdateClient->SoftwareTitle);
308 SetText(hWnd, S_PRODUCT_STR, u->UpdateClient->SoftwareTitle);
309
310 FormatText(hWnd, S_CURRENT_STR, u->CurrentVer / 100, u->CurrentVer % 100, u->CurrentBuild, date_current_str);
311 FormatText(hWnd, S_LATEST_STR, p->LatestVer, date_latest_str);
312
313 if (MsIsWindows7())
314 {
315 if (_GETLANG() == 0)
316 {
317 font_name = GetMeiryoFontName();
318 }
319 else if (_GETLANG() == 2)
320 {
321 font_name = "Microsoft YaHei";
322 }
323 }
324
325 SetFont(hWnd, S_INFO, GetFont(font_name, 11, false, false, false, false));
326 SetFont(hWnd, IDOK, GetFont(font_name, 0, true, false, false, false));
327 SetFont(hWnd, IDCANCEL, GetFont(font_name, 0, false, false, false, false));
328 SetFont(hWnd, S_PRODUCT_STR, GetFont(font_name, 10, true, false, false, false));
329 SetFont(hWnd, S_CURRENT_STR, GetFont(font_name, 10, true, false, false, false));
330 SetFont(hWnd, S_LATEST_STR, GetFont(font_name, 10, true, false, false, false));
331
332 SetFont(hWnd, S_PRODUCT, GetFont(font_name, 0, false, false, false, false));
333 SetFont(hWnd, S_CURRENT, GetFont(font_name, 0, false, false, false, false));
334 SetFont(hWnd, S_LATEST, GetFont(font_name, 0, false, false, false, false));
335 SetFont(hWnd, B_CONFIG, GetFont(font_name, 0, false, false, false, false));
336
337 SetTimer(hWnd, 1, 100, NULL);
338
339 //MessageBeep(MB_ICONASTERISK);
340 break;
341
342 case WM_COMMAND:
343 switch (wParam)
344 {
345 case IDOK: // Web View
346 OnceMsgEx(hWnd, NULL, _UU("DLG_UPDATE_HINT"), true, ICO_INTERNET, (bool *)p->halt_flag);
347
348 ShellExecuteA(hWnd, "open", p->Url, NULL, NULL, SW_SHOWNORMAL);
349 SleepThread(250);
350
351 // Ignore the update notification of this version for future
352 LoadUpdateUiSetting(u, &s);
353 s.LatestIgnoreBuild = p->LatestBuild;
354 SaveUpdateUiSetting(u, &s);
355
356 EndDialog(hWnd, 1);
357 break;
358
359 case IDCANCEL: // Ignore this version
360 LoadUpdateUiSetting(u, &s);
361 s.LatestIgnoreBuild = p->LatestBuild;
362 SaveUpdateUiSetting(u, &s);
363 Close(hWnd);
364 break;
365
366 case B_CONFIG: // Show the notification settings screen
367 p->IsInConfigDialog = true;
368
369 if (ConfigUpdateUi(u, hWnd) == false)
370 {
371 // Decided not to notify any more as a result of setting
372 Close(hWnd);
373 }
374
375 p->IsInConfigDialog = false;
376 break;
377 }
378 break;
379
380 case WM_TIMER:
381 switch (wParam)
382 {
383 case 1:
384 if (p->IsInConfigDialog == false)
385 {
386 if (*(p->halt_flag))
387 {
388 // Close the screen forcibly
389 EndDialog(hWnd, 0);
390 }
391 }
392 break;
393 }
394 break;
395
396 case WM_CLOSE: // Close
397 EndDialog(hWnd, 0);
398 break;
399 }
400
401 return 0;
402 }
403
404 // Update notification dialog
UpdateNotifyProcUi(UPDATE_CLIENT * c,UINT latest_build,UINT64 latest_date,char * latest_ver,char * url,volatile bool * halt_flag,void * param)405 void UpdateNotifyProcUi(UPDATE_CLIENT *c, UINT latest_build, UINT64 latest_date, char *latest_ver, char *url, volatile bool *halt_flag, void *param)
406 {
407 WINUI_UPDATE *u = (WINUI_UPDATE *)param;
408 WINUI_UPDATE_DLG_PARAM p;
409 // Validate arguments
410 if (c == NULL || latest_build == 0 || latest_date == 0 || latest_ver == NULL || url == NULL || halt_flag == NULL || param == NULL)
411 {
412 return;
413 }
414
415 if (u->UseSuppressFlag)
416 {
417 // Check the suppress flag
418 if (MsRegReadIntEx2(REG_LOCAL_MACHINE, PROTO_SUPPRESS_CLIENT_UPDATE_NOTIFICATION_REGKEY,
419 PROTO_SUPPRESS_CLIENT_UPDATE_NOTIFICATION_REGVALUE, false, true))
420 {
421 // Supress the dialog
422 return;
423 }
424 }
425
426 if (u->CurrentlyDisabled)
427 {
428 // Hide
429 return;
430 }
431
432 // Show the update screen
433 Zero(&p, sizeof(p));
434
435 p.Update = u;
436 p.LatestBuild = latest_build;
437 p.LatestDate = latest_date;
438 p.LatestVer = latest_ver;
439 p.Url = url;
440 p.halt_flag = halt_flag;
441
442 Dialog(NULL, D_UPDATE_NOTICE, UpdateNoticeDlgProc, &p);
443 }
444
445 // Initialize the update notification
InitUpdateUi(wchar_t * title,char * name,char * family_name,UINT64 current_date,UINT current_build,UINT current_ver,char * client_id,bool use_suppress_flag)446 WINUI_UPDATE *InitUpdateUi(wchar_t *title, char *name, char *family_name, UINT64 current_date, UINT current_build, UINT current_ver, char *client_id, bool use_suppress_flag)
447 {
448 WINUI_UPDATE *u;
449 UPDATE_CLIENT_SETTING s;
450 LANGLIST t;
451 // Validate arguments
452 if (title == NULL || name == NULL || current_build == 0 || current_ver == 0)
453 {
454 return NULL;
455 }
456 if (MsIsWine())
457 {
458 return false;
459 }
460 if (IsEmptyStr(family_name))
461 {
462 family_name = UPDATE_FAMILY_NAME;
463 }
464
465 u = ZeroMalloc(sizeof(WINUI_UPDATE));
466
467 StrCpy(u->ClientId, sizeof(u->ClientId), client_id);
468 UniStrCpy(u->SoftwareTitle, sizeof(u->SoftwareTitle), title);
469 StrCpy(u->SoftwareName, sizeof(u->SoftwareName), name);
470 u->CurrentDate = current_date;
471 u->CurrentBuild = current_build;
472 u->CurrentVer = current_ver;
473 u->UseSuppressFlag = use_suppress_flag;
474
475 Format(u->RegKey, sizeof(u->RegKey), WINUI_UPDATE_REGKEY, u->SoftwareName);
476
477 Zero(&s, sizeof(s));
478 LoadUpdateUiSetting(u, &s);
479
480 Zero(&t, sizeof(t));
481 GetCurrentLang(&t);
482
483 u->UpdateClient = NewUpdateClient(UpdateNotifyProcUi, IsThisProcessForegroundForUpdateUi, u, family_name, u->SoftwareName, u->SoftwareTitle,
484 u->CurrentBuild, u->CurrentDate, t.Name, &s, client_id);
485
486 if (u->UpdateClient == NULL)
487 {
488 Free(u);
489 return NULL;
490 }
491
492 return u;
493 }
494
495 // Disable the update notification UI
DisableUpdateUi(WINUI_UPDATE * u)496 void DisableUpdateUi(WINUI_UPDATE *u)
497 {
498 // Validate arguments
499 if (u == NULL)
500 {
501 return;
502 }
503
504 u->CurrentlyDisabled = true;
505 }
506
507 // Release the update notification
FreeUpdateUi(WINUI_UPDATE * u)508 void FreeUpdateUi(WINUI_UPDATE *u)
509 {
510 // Validate arguments
511 if (u == NULL)
512 {
513 return;
514 }
515
516 if (u->UpdateClient != NULL)
517 {
518 FreeUpdateClient(u->UpdateClient);
519 }
520
521 Free(u);
522 }
523
524 // Read the current settings from the registry
LoadUpdateUiSetting(WINUI_UPDATE * u,UPDATE_CLIENT_SETTING * s)525 void LoadUpdateUiSetting(WINUI_UPDATE *u, UPDATE_CLIENT_SETTING *s)
526 {
527 Zero(s, sizeof(UPDATE_CLIENT_SETTING));
528 // Validate arguments
529 if (u == NULL || s == NULL)
530 {
531 return;
532 }
533
534 s->DisableCheck = MsRegReadInt(REG_CURRENT_USER, u->RegKey, "DisableCheck");
535 s->LatestIgnoreBuild = MsRegReadInt(REG_CURRENT_USER, u->RegKey, "LatestIgnoreBuild");
536 }
537
538 // Write the current settings to the registry
SaveUpdateUiSetting(WINUI_UPDATE * u,UPDATE_CLIENT_SETTING * s)539 void SaveUpdateUiSetting(WINUI_UPDATE *u, UPDATE_CLIENT_SETTING *s)
540 {
541 // Validate arguments
542 if (u == NULL || s == NULL)
543 {
544 return;
545 }
546
547 MsRegWriteInt(REG_CURRENT_USER, u->RegKey, "DisableCheck", s->DisableCheck);
548 MsRegWriteInt(REG_CURRENT_USER, u->RegKey, "LatestIgnoreBuild", s->LatestIgnoreBuild);
549 }
550
551 // Set the UAC icon to the control in the dialog
SetUacIcon(HWND hWnd,UINT id)552 void SetUacIcon(HWND hWnd, UINT id)
553 {
554 static HINSTANCE hShell32 = NULL;
555 static HRESULT (__stdcall *_SHGetStockIconInfo)(UINT siid, UINT uFlags, void *psii) = NULL;
556 bool ok = false;
557 // Validate arguments
558 if (hWnd == NULL)
559 {
560 return;
561 }
562
563 if (MsIsVista() == false)
564 {
565 goto LABEL_FAILED;
566 }
567
568 if (hShell32 == NULL)
569 {
570 hShell32 = LoadLibraryA("shell32.dll");
571 }
572
573 if (hShell32 != NULL)
574 {
575 if (_SHGetStockIconInfo == NULL)
576 {
577 _SHGetStockIconInfo = (HRESULT (__stdcall *)(UINT,UINT,void *))GetProcAddress(hShell32, "SHGetStockIconInfo");
578 }
579 }
580
581 if (_SHGetStockIconInfo != NULL)
582 {
583 WINUI_SHSTOCKICONINFO sii;
584
585 Zero(&sii, sizeof(sii));
586
587 sii.cbSize = sizeof(sii);
588 if (_SHGetStockIconInfo(77, 0x000000100 | 0x000000001, &sii) == S_OK)
589 {
590 SendMessage(DlgItem(hWnd, id), STM_SETICON, (WPARAM)sii.hIcon, 0);
591
592 ok = true;
593 }
594 }
595
596 if (ok)
597 {
598 return;
599 }
600
601 LABEL_FAILED:
602
603 Hide(hWnd, id);
604 }
605
606 // Procedure of the wizard page
WizardPageDefDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)607 UINT CALLBACK WizardPageDefDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
608 {
609 DIALOG_PARAM *dp = (DIALOG_PARAM *)GetParam(hWnd);
610 WIZARD_PAGE *wizard_page = NULL;
611 WIZARD *wizard = NULL;
612 UINT ret_value = 0;
613 bool do_not_send_msg = false;
614
615 if (dp != NULL)
616 {
617 wizard_page = dp->wizard_page;
618 wizard = wizard_page->Wizard;
619 }
620
621 switch (msg)
622 {
623 case WM_INITDIALOG:
624 {
625 PROPSHEETPAGEW_V3 *t = (PROPSHEETPAGEW_V3 *)lParam;
626 dp = (DIALOG_PARAM *)t->lParam;
627 wizard_page = dp->wizard_page;
628 wizard = wizard_page->Wizard;
629
630 wizard->hWndWizard = GetParent(hWnd);
631 wizard_page->hWndPage = hWnd;
632
633 SetParam(hWnd, dp);
634
635 InitDialogInternational(hWnd, dp);
636 }
637 break;
638
639 case WM_CTLCOLORBTN:
640 case WM_CTLCOLORDLG:
641 case WM_CTLCOLOREDIT:
642 case WM_CTLCOLORLISTBOX:
643 case WM_CTLCOLORMSGBOX:
644 case WM_CTLCOLORSCROLLBAR:
645 case WM_CTLCOLORSTATIC:
646 return (UINT)GetStockObject(WHITE_BRUSH);
647 break;
648
649 case WM_NOTIFY:
650 {
651 NMHDR *pnmh = (NMHDR *)lParam;
652 UINT ret = 0;
653 UINT next_page = INFINITE;
654
655 switch (pnmh->code)
656 {
657 case PSN_SETACTIVE: // Activate
658 SetWizardButton(wizard_page, true, true, true, false);
659 dp->wizard_proc(hWnd, WM_WIZ_SHOW, 0, 0, wizard, wizard_page, wizard->Param);
660 break;
661
662 case PSN_KILLACTIVE: // Deactivate
663 dp->wizard_proc(hWnd, WM_WIZ_HIDE, 0, 0, wizard, wizard_page, wizard->Param);
664 break;
665
666 case PSN_WIZNEXT: // Determine the destination of [Next] button
667 ret = dp->wizard_proc(hWnd, WM_WIZ_NEXT, 0, 0, wizard, wizard_page, wizard->Param);
668 do_not_send_msg = true;
669
670 if (ret == 0)
671 {
672 SetWindowLong(hWnd, DWLP_MSGRESULT, -1);
673 }
674 else
675 {
676 SetWindowLong(hWnd, DWLP_MSGRESULT, ret);
677 }
678
679 ret_value = 1;
680 break;
681
682 case PSN_WIZBACK: // Determine the destination of [back] button
683 ret = dp->wizard_proc(hWnd, WM_WIZ_BACK, 0, 0, wizard, wizard_page, wizard->Param);
684 do_not_send_msg = true;
685
686 if (ret == 0)
687 {
688 SetWindowLong(hWnd, DWLP_MSGRESULT, -1);
689 }
690 else
691 {
692 SetWindowLong(hWnd, DWLP_MSGRESULT, ret);
693 }
694
695 ret_value = 1;
696 break;
697
698 case PSN_QUERYCANCEL: // Determine the process of the [Cancel] button
699 if (dp->wizard_page->EnableClose == false)
700 {
701 SetWindowLong(hWnd, DWLP_MSGRESULT, 1);
702 }
703 else
704 {
705
706 ret = dp->wizard_proc(hWnd, WM_WIZ_CLOSE, 0, 0, wizard, wizard_page, wizard->Param);
707
708 if (ret == 0)
709 {
710 if (IsEmptyUniStr(wizard->CloseConfirmMsg) == false &&
711 MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, wizard->CloseConfirmMsg) == IDNO)
712 {
713 ret = 1;
714 }
715 }
716
717 if (ret == 0)
718 {
719 SetWindowLong(hWnd, DWLP_MSGRESULT, 0);
720 }
721 else
722 {
723 SetWindowLong(hWnd, DWLP_MSGRESULT, 1);
724 }
725 }
726 ret_value = 1;
727 do_not_send_msg = true;
728 break;
729 }
730 break;
731 }
732 }
733
734 if (do_not_send_msg == false)
735 {
736 if (dp != NULL)
737 {
738 UINT ret = dp->wizard_proc(hWnd, msg, wParam, lParam, wizard, wizard_page, wizard->Param);
739
740 if (ret != 0)
741 {
742 ret_value = ret;
743 }
744 }
745 }
746
747 if (msg == WM_INITDIALOG)
748 {
749 if (wizard->SetCenterFlag == false)
750 {
751 wizard->SetCenterFlag = true;
752
753 Center(wizard->hWndWizard);
754 }
755
756 SetForegroundWindow(wizard->hWndWizard);
757 SetActiveWindow(wizard->hWndWizard);
758 }
759
760 return ret_value;
761 }
762
763 // Button setting of the wizard
SetWizardButton(WIZARD_PAGE * p,bool enable_next,bool enable_back,bool enable_close,bool is_finish)764 void SetWizardButton(WIZARD_PAGE *p, bool enable_next, bool enable_back, bool enable_close, bool is_finish)
765 {
766 SetWizardButtonEx(p, enable_next, enable_back, enable_close, is_finish, false);
767 }
SetWizardButtonEx(WIZARD_PAGE * p,bool enable_next,bool enable_back,bool enable_close,bool is_finish,bool shield_icon)768 void SetWizardButtonEx(WIZARD_PAGE *p, bool enable_next, bool enable_back, bool enable_close, bool is_finish, bool shield_icon)
769 {
770 DWORD flags = 0;
771 DWORD flags2 = 0;
772 DWORD flags3 = 0;
773 // Validate arguments
774 if (p == NULL)
775 {
776 return;
777 }
778
779 p->EnableNext = enable_next;
780 p->EnableBack = enable_back;
781 p->EnableClose = enable_close;
782 p->IsFinish = is_finish;
783
784 if (is_finish == false)
785 {
786 if (p->EnableNext)
787 {
788 flags |= PSWIZB_NEXT;
789 flags2 |= PSWIZB_NEXT;
790
791 if (shield_icon)
792 {
793 if (p->Wizard->IsAreoStyle)
794 {
795 if (MsIsAdmin() == false)
796 {
797 flags3 |= PSWIZBF_ELEVATIONREQUIRED;
798 }
799 }
800 }
801 }
802 }
803 else
804 {
805 if (p->EnableNext)
806 {
807 flags |= PSWIZB_FINISH;
808 flags2 |= PSWIZB_FINISH;
809 }
810 else
811 {
812 flags |= PSWIZB_DISABLEDFINISH;
813 flags2 |= PSWIZB_FINISH;
814 }
815 }
816
817 if (p->EnableBack)
818 {
819 flags |= PSWIZB_BACK;
820 flags2 |= PSWIZB_BACK;
821 }
822
823 if (p->EnableClose)
824 {
825 flags2 |= 0x00000010;
826 }
827
828 PostMessage(p->Wizard->hWndWizard, PSM_SETWIZBUTTONS, flags3, flags);
829
830 SetEnable(p->Wizard->hWndWizard, IDCANCEL, p->EnableClose);
831
832 WINUI_PropSheet_ShowWizButtons(p->Wizard->hWndWizard,
833 flags2, PSWIZB_BACK | PSWIZB_NEXT | PSWIZB_FINISH | 0x00000010);
834
835 if (p->EnableClose)
836 {
837 EnableClose(p->Wizard->hWndWizard);
838 }
839 else
840 {
841 DisableClose(p->Wizard->hWndWizard);
842 }
843 }
844
WizardCustomizedWindowProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)845 LRESULT CALLBACK WizardCustomizedWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
846 {
847 WIZARD *wizard = (WIZARD *)TlsGetValue(tls_current_wizard);
848
849 if (wizard != NULL)
850 {
851 switch (msg)
852 {
853 case WM_CTLCOLORBTN:
854 case WM_CTLCOLORDLG:
855 case WM_CTLCOLOREDIT:
856 case WM_CTLCOLORLISTBOX:
857 case WM_CTLCOLORMSGBOX:
858 case WM_CTLCOLORSCROLLBAR:
859 case WM_CTLCOLORSTATIC:
860 return (UINT)GetStockObject(WHITE_BRUSH);
861 break;
862 }
863
864 if (MsIsNt())
865 {
866 return CallWindowProcW(wizard->OriginalWindowProc, hWnd, msg, wParam, lParam);
867 }
868 else
869 {
870 return CallWindowProcA(wizard->OriginalWindowProc, hWnd, msg, wParam, lParam);
871 }
872 }
873 else
874 {
875 return 0;
876 }
877 }
878
879 // Procedure of the wizard
WizardDlgProc(HWND hWnd,UINT msg,LPARAM lParam)880 UINT CALLBACK WizardDlgProc(HWND hWnd, UINT msg, LPARAM lParam)
881 {
882 WIZARD *wizard = (WIZARD *)TlsGetValue(tls_current_wizard);
883 switch (msg)
884 {
885 case PSCB_INITIALIZED:
886 if (wizard != NULL)
887 {
888 if (wizard->hWndWizard != NULL)
889 {
890 wizard->hWndWizard = hWnd;
891 }
892
893 if (wizard->ReplaceWindowProcFlag == false)
894 {
895 wizard->ReplaceWindowProcFlag = true;
896
897 if (MsIsNt())
898 {
899 wizard->OriginalWindowProc = (void *)GetWindowLongPtrW(hWnd, GWLP_WNDPROC);
900 }
901 else
902 {
903 wizard->OriginalWindowProc = (void *)GetWindowLongPtrA(hWnd, GWLP_WNDPROC);
904 }
905
906 if (wizard->OriginalWindowProc != NULL)
907 {
908 if (MsIsNt())
909 {
910 SetWindowLongPtrW(hWnd, GWLP_WNDPROC, (LONG_PTR)WizardCustomizedWindowProc);
911 }
912 else
913 {
914 SetWindowLongPtrA(hWnd, GWLP_WNDPROC, (LONG_PTR)WizardCustomizedWindowProc);
915 }
916 }
917 }
918 }
919 break;
920 }
921
922 return 0;
923 }
924
925 // Jump to another wizard page
JumpWizard(WIZARD_PAGE * p,UINT next_id)926 void JumpWizard(WIZARD_PAGE *p, UINT next_id)
927 {
928 // Validate arguments
929 if (p == NULL || next_id == 0)
930 {
931 return;
932 }
933
934 PropSheet_SetCurSelByID(p->Wizard->hWndWizard, next_id);
935 }
936
937 // Close the wizard
CloseWizard(WIZARD_PAGE * p)938 void CloseWizard(WIZARD_PAGE *p)
939 {
940 // Validate arguments
941 if (p == NULL)
942 {
943 return;
944 }
945
946 p->Wizard->CloseConfirmMsg = NULL;
947 SetWizardButton(p, false, false, true, false);
948
949 if (p->Wizard->IsAreoStyle)
950 {
951 PropSheet_PressButton(p->hWndPage, PSBTN_CANCEL);
952 }
953 else
954 {
955 Close(p->Wizard->hWndWizard);
956 }
957 }
958
959 // Show the wizard
ShowWizard(HWND hWndParent,WIZARD * w,UINT start_id)960 void ShowWizard(HWND hWndParent, WIZARD *w, UINT start_id)
961 {
962 void **pages_array;
963 UINT num_pages;
964 UINT i;
965 PROPSHEETHEADERW_V2 h;
966 WIZARD_PAGE *start_page;
967 // Validate arguments
968 if (w == NULL)
969 {
970 return;
971 }
972
973 num_pages = LIST_NUM(w->Pages);
974 pages_array = ZeroMalloc(sizeof(void *) * num_pages);
975
976 for (i = 0;i < num_pages;i++)
977 {
978 WIZARD_PAGE *p = LIST_DATA(w->Pages, i);
979
980 pages_array[i] = CreateWizardPageInstance(w, p);
981
982 p->Index = i;
983 }
984
985 Zero(&h, sizeof(h));
986 h.dwSize = sizeof(PROPSHEETHEADERW_V2);
987 h.dwFlags = PSH_WIZARD97 | PSH_HEADER | PSH_USEICONID | PSH_USECALLBACK;
988
989 if (MsIsVista() == false)
990 {
991 // Aero Wizard is unavailable in pre-Vista
992 w->IsAreoStyle = false;
993 }
994
995 if (MsIsAeroColor() == false)
996 {
997 // Aero Wizard can not be used If the color of Aero is disabled
998 // even in Vista or later (if the background color is not white)
999 w->IsAreoStyle = false;
1000 }
1001
1002 if (MsIsWindows10())
1003 {
1004 // Windows 10 Icon Bug: Disable Aero Style!
1005 w->IsAreoStyle = false;
1006 }
1007
1008 if (w->IsAreoStyle)
1009 {
1010 // Aero Wizard
1011 h.dwFlags = PSH_WIZARD | 0x00004000 | PSH_HEADER | PSH_USEICONID | PSH_USECALLBACK;
1012 }
1013
1014 h.hInstance = hDll;
1015 h.pszIcon = MAKEINTRESOURCEW(w->Icon);
1016 h.hwndParent = hWndParent;
1017 h.nPages = num_pages;
1018 h.phpage = (HPROPSHEETPAGE *)pages_array;
1019 h.pszbmHeader = MAKEINTRESOURCEW(w->Bitmap);
1020 h.pszCaption = w->Caption;
1021 h.pfnCallback = WizardDlgProc;
1022
1023 start_page = GetWizardPage(w, start_id);
1024 if (start_page != NULL)
1025 {
1026 h.nStartPage = start_page->Index;
1027 }
1028
1029 w->hWndParent = hWndParent;
1030 w->hWndWizard = NULL;
1031 w->SetCenterFlag = false;
1032
1033 TlsSetValue(tls_current_wizard, w);
1034
1035 PropertySheetW(&h);
1036
1037 TlsSetValue(tls_current_wizard, NULL);
1038
1039 Free(pages_array);
1040 }
1041
1042 // Create an instance of the wizard page
CreateWizardPageInstance(WIZARD * w,WIZARD_PAGE * p)1043 void *CreateWizardPageInstance(WIZARD *w, WIZARD_PAGE *p)
1044 {
1045 PROPSHEETPAGEW_V3 t;
1046 // Validate arguments
1047 if (w == NULL || p == NULL)
1048 {
1049 return NULL;
1050 }
1051
1052 Zero(&t, sizeof(t));
1053 t.dwSize = sizeof(PROPSHEETPAGEW_V3);
1054 t.dwFlags = PSP_USETITLE | PSP_USEHEADERTITLE;// | PSP_USEHEADERSUBTITLE;
1055 t.hInstance = hDll;
1056 t.pszTemplate = MAKEINTRESOURCEW(p->Id);
1057 t.pfnDlgProc = (DLGPROC)WizardPageDefDlgProc;
1058 t.pszHeaderTitle = p->Title;
1059 t.pszTitle = w->Caption;
1060
1061 if (p->DialogParam != NULL)
1062 {
1063 FreeBitmapList(p->DialogParam->BitmapList);
1064 Free(p->DialogParam);
1065 }
1066
1067 p->DialogParam = ZeroMalloc(sizeof(DIALOG_PARAM));
1068
1069 p->DialogParam->BitmapList = NewBitmapList();
1070 p->DialogParam->wizard = w;
1071 p->DialogParam->wizard_page = p;
1072 p->DialogParam->wizard_proc = p->Proc;
1073 p->DialogParam->param = w->Param;
1074 p->DialogParam->white = false;
1075 p->DialogParam->meiryo = false;
1076
1077 t.lParam = (LPARAM)p->DialogParam;
1078
1079 return CreatePropertySheetPageW(&t);
1080 }
1081
1082 // Create a new wizard
NewWizard(UINT icon,UINT bitmap,wchar_t * caption,void * param)1083 WIZARD *NewWizard(UINT icon, UINT bitmap, wchar_t *caption, void *param)
1084 {
1085 WIZARD *w = ZeroMalloc(sizeof(WIZARD));
1086
1087 w->Icon = icon;
1088 w->Pages = NewList(NULL);
1089 w->Param = param;
1090 w->Bitmap = bitmap;
1091 w->Caption = CopyUniStr(caption);
1092
1093 return w;
1094 }
1095
1096 // Release the wizard
FreeWizard(WIZARD * w)1097 void FreeWizard(WIZARD *w)
1098 {
1099 UINT i;
1100 // Validate arguments
1101 if (w == NULL)
1102 {
1103 return;
1104 }
1105
1106 for (i = 0;i < LIST_NUM(w->Pages);i++)
1107 {
1108 WIZARD_PAGE *p = LIST_DATA(w->Pages, i);
1109
1110 FreeWizardPage(p);
1111 }
1112
1113 ReleaseList(w->Pages);
1114
1115 Free(w->Caption);
1116
1117 Free(w);
1118 }
1119
1120 // Get the index page of the wizard
GetWizardPageIndex(WIZARD * w,UINT id)1121 UINT GetWizardPageIndex(WIZARD *w, UINT id)
1122 {
1123 WIZARD_PAGE *p;
1124 // Validate arguments
1125 if (w == NULL || id == 0)
1126 {
1127 return INFINITE;
1128 }
1129
1130 p = GetWizardPage(w, id);
1131 if (p == NULL)
1132 {
1133 return INFINITE;
1134 }
1135
1136 return p->Index;
1137 }
1138
1139 // Get the wizard page
GetWizardPage(WIZARD * w,UINT id)1140 WIZARD_PAGE *GetWizardPage(WIZARD *w, UINT id)
1141 {
1142 UINT i;
1143 // Validate arguments
1144 if (w == NULL || id == 0)
1145 {
1146 return NULL;
1147 }
1148
1149 for (i = 0;i < LIST_NUM(w->Pages);i++)
1150 {
1151 WIZARD_PAGE *p = LIST_DATA(w->Pages, i);
1152
1153 if (p->Id == id)
1154 {
1155 return p;
1156 }
1157 }
1158
1159 return NULL;
1160 }
1161
1162 // Add a wizard page
AddWizardPage(WIZARD * w,WIZARD_PAGE * p)1163 void AddWizardPage(WIZARD *w, WIZARD_PAGE *p)
1164 {
1165 // Validate arguments
1166 if (w == NULL || p == NULL)
1167 {
1168 return;
1169 }
1170
1171 Add(w->Pages, p);
1172
1173 p->Wizard = w;
1174 }
1175
1176 // Create a new wizard page
NewWizardPage(UINT id,WINUI_WIZARD_PROC * proc,wchar_t * title)1177 WIZARD_PAGE *NewWizardPage(UINT id, WINUI_WIZARD_PROC *proc, wchar_t *title)
1178 {
1179 WIZARD_PAGE *p;
1180 // Validate arguments
1181 if (id == 0 || proc == NULL)
1182 {
1183 return NULL;
1184 }
1185
1186 p = ZeroMalloc(sizeof(WIZARD_PAGE));
1187 p->Id = id;
1188 p->Proc = proc;
1189 p->Title = CopyUniStr(title);
1190
1191 return p;
1192 }
1193
1194 // Release the wizard page
FreeWizardPage(WIZARD_PAGE * p)1195 void FreeWizardPage(WIZARD_PAGE *p)
1196 {
1197 // Validate arguments
1198 if (p == NULL)
1199 {
1200 return;
1201 }
1202
1203 if (p->DialogParam != NULL)
1204 {
1205 FreeBitmapList(p->DialogParam->BitmapList);
1206 Free(p->DialogParam);
1207 }
1208
1209 Free(p->Title);
1210
1211 Free(p);
1212 }
1213
1214 // NIC information dialog procedure
NicInfoProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)1215 UINT NicInfoProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
1216 {
1217 UI_NICINFO *info = (UI_NICINFO *)param;
1218
1219 switch (msg)
1220 {
1221 case WM_INITDIALOG:
1222 NicInfoInit(hWnd, info);
1223
1224 SetTimer(hWnd, 1, 50, NULL);
1225 break;
1226
1227 case WM_TIMER:
1228 switch (wParam)
1229 {
1230 case 1:
1231 KillTimer(hWnd, 1);
1232
1233 NicInfoOnTimer(hWnd, info);
1234
1235 SetTimer(hWnd, 1, 50, NULL);
1236 break;
1237
1238 case 2:
1239 KillTimer(hWnd, 2);
1240 Close(hWnd);
1241 break;
1242 }
1243 break;
1244
1245 case WM_COMMAND:
1246 switch (wParam)
1247 {
1248 case IDOK:
1249 case IDCANCEL:
1250 Close(hWnd);
1251 break;
1252 }
1253 break;
1254
1255 case WM_CLOSE:
1256 KillTimer(hWnd, 1);
1257 KillTimer(hWnd, 2);
1258 EndDialog(hWnd, 0);
1259 break;
1260 }
1261
1262 return 0;
1263 }
NicInfoCloseAfterTime(HWND hWnd,UI_NICINFO * info,UINT tick)1264 void NicInfoCloseAfterTime(HWND hWnd, UI_NICINFO *info, UINT tick)
1265 {
1266 UINT64 now;
1267 UINT64 closetime;
1268 // Validate arguments
1269 if (hWnd == NULL || info == NULL)
1270 {
1271 return;
1272 }
1273
1274 now = Tick64();
1275 closetime = now + (UINT64)tick;
1276
1277 if (info->CloseAfterTime == 0 || info->CloseAfterTime >= closetime)
1278 {
1279 info->CloseAfterTime = closetime;
1280 KillTimer(hWnd, 2);
1281 SetTimer(hWnd, 2, tick, NULL);
1282 }
1283 }
NicInfoShowStatus(HWND hWnd,UI_NICINFO * info,wchar_t * msg1,wchar_t * msg2,UINT icon,bool animate)1284 void NicInfoShowStatus(HWND hWnd, UI_NICINFO *info, wchar_t *msg1, wchar_t *msg2, UINT icon, bool animate)
1285 {
1286 // Validate arguments
1287 if (hWnd == NULL || info == NULL)
1288 {
1289 return;
1290 }
1291 if (icon == 0)
1292 {
1293 icon = ICO_TEST;
1294 }
1295 if (msg1 == NULL)
1296 {
1297 msg1 = L"";
1298 }
1299 if (msg2 == NULL)
1300 {
1301 msg2 = L"";
1302 }
1303
1304 if (info->CurrentIcon != icon)
1305 {
1306 SetIcon(hWnd, S_ICON, icon);
1307 info->CurrentIcon = icon;
1308 }
1309
1310 SetText(hWnd, S_STATUS1, msg1);
1311 SetText(hWnd, S_STATUS2, msg2);
1312
1313 SetShow(hWnd, P_BAR, animate && MsIsWinXPOrWinVista());
1314 }
NicInfoRefresh(HWND hWnd,UI_NICINFO * info)1315 void NicInfoRefresh(HWND hWnd, UI_NICINFO *info)
1316 {
1317 MS_ADAPTER *a;
1318 IP ip;
1319 char ip_str[MAX_SIZE];
1320 char title[MAX_SIZE];
1321 UINT i;
1322 wchar_t tmp[MAX_SIZE];
1323 bool has_ip = false;
1324 // Validate arguments
1325 if (hWnd == NULL || info == NULL)
1326 {
1327 return;
1328 }
1329
1330 Format(title, sizeof(title), VLAN_ADAPTER_NAME_TAG, info->NicName);
1331
1332 a = MsGetAdapter(title);
1333 if (a == NULL)
1334 {
1335 Close(hWnd);
1336 return;
1337 }
1338
1339 // Check whether an IP address is assigned
1340 Zero(&ip, sizeof(ip));
1341 for (i = 0;i < MAX_MS_ADAPTER_IP_ADDRESS;i++)
1342 {
1343 if (IsZeroIP(&a->IpAddresses[i]) == false)
1344 {
1345 Copy(&ip, &a->IpAddresses[i], sizeof(IP));
1346
1347 if (!(ip.addr[0] == 169 && ip.addr[1] == 254))
1348 {
1349 has_ip = true;
1350 }
1351 }
1352 }
1353 IPToStr(ip_str, sizeof(ip_str), &ip);
1354
1355 if (has_ip == false)
1356 {
1357 if (a->UseDhcp)
1358 {
1359 NicInfoShowStatus(hWnd, info, _UU("NICINFO_1"), _UU("NICINFO_1_1"), ICO_NIC_OFFLINE, true);
1360 }
1361 else
1362 {
1363 NicInfoShowStatus(hWnd, info, _UU("NICINFO_1"), _UU("NICINFO_1_2"), ICO_NIC_OFFLINE, true);
1364 }
1365 }
1366 else
1367 {
1368 if (a->UseDhcp)
1369 {
1370 UniFormat(tmp, sizeof(tmp), _UU("NICINFO_2_1"), ip_str);
1371 NicInfoShowStatus(hWnd, info, _UU("NICINFO_2"), tmp, ICO_NIC_ONLINE, false);
1372 }
1373 else
1374 {
1375 UniFormat(tmp, sizeof(tmp), _UU("NICINFO_3_1"), ip_str);
1376 NicInfoShowStatus(hWnd, info, _UU("NICINFO_3"), tmp, ICO_NIC_ONLINE, false);
1377 }
1378
1379 NicInfoCloseAfterTime(hWnd, info, NICINFO_AUTOCLOSE_TIME_2);
1380 }
1381
1382 MsFreeAdapter(a);
1383 }
NicInfoInit(HWND hWnd,UI_NICINFO * info)1384 void NicInfoInit(HWND hWnd, UI_NICINFO *info)
1385 {
1386 // Validate arguments
1387 if (hWnd == NULL || info == NULL)
1388 {
1389 return;
1390 }
1391
1392 if (MsIsWinXPOrWinVista())
1393 {
1394 // Show a progress bar for Windows XP or later
1395 SendMsg(hWnd, P_BAR, PBM_SETMARQUEE, TRUE, 150);
1396 SetStyle(hWnd, P_BAR, PBS_MARQUEE);
1397 }
1398
1399 DlgFont(hWnd, S_STATUS1, 9, false);
1400 DlgFont(hWnd, S_STATUS2, 11, false);
1401
1402 SetIcon(hWnd, 0, ICO_NIC_ONLINE);
1403
1404 FormatText(hWnd, 0, info->NicName);
1405
1406 NicInfoRefresh(hWnd, info);
1407
1408 NicInfoCloseAfterTime(hWnd, info, NICINFO_AUTOCLOSE_TIME_1);
1409 }
NicInfoOnTimer(HWND hWnd,UI_NICINFO * info)1410 void NicInfoOnTimer(HWND hWnd, UI_NICINFO *info)
1411 {
1412 // Validate arguments
1413 if (hWnd == NULL || info == NULL)
1414 {
1415 return;
1416 }
1417
1418 if (info->Halt)
1419 {
1420 Close(hWnd);
1421 return;
1422 }
1423
1424 if (info->RouteChange != NULL &&
1425 IsRouteChanged(info->RouteChange) == false)
1426 {
1427 return;
1428 }
1429
1430 NicInfoRefresh(hWnd, info);
1431 }
1432
1433 // Show the NIC information dialog
NicInfo(UI_NICINFO * info)1434 void NicInfo(UI_NICINFO *info)
1435 {
1436 // Validate arguments
1437 if (info == NULL)
1438 {
1439 return;
1440 }
1441
1442 info->RouteChange = NewRouteChange();
1443
1444 DialogEx2(NULL, D_NICINFO, NicInfoProc, info, true, true);
1445
1446 FreeRouteChange(info->RouteChange);
1447 info->RouteChange = NULL;
1448 }
1449
1450 // TCP connection thread
WinConnectDlgThread(THREAD * thread,void * param)1451 void WinConnectDlgThread(THREAD *thread, void *param)
1452 {
1453 SOCK *s;
1454 WINCONNECT_DLG_DATA *d = (WINCONNECT_DLG_DATA *)param;
1455 UINT nat_t_error_code;
1456 char *nat_t_svc_name = NULL;
1457 // Validate arguments
1458 if (d == NULL || thread == NULL)
1459 {
1460 return;
1461 }
1462
1463 // Socket connection
1464 if (IsEmptyStr(d->nat_t_svc_name) == false)
1465 {
1466 nat_t_svc_name = d->nat_t_svc_name;
1467 }
1468
1469 s = ConnectEx3(d->hostname, d->port, d->timeout, &d->cancel, nat_t_svc_name, &nat_t_error_code, d->try_start_ssl, d->ssl_no_tls, false);
1470
1471 d->ret_sock = s;
1472 d->nat_t_error_code = nat_t_error_code;
1473
1474 PostMessageA(d->hWnd, WM_APP + 68, 0, 0);
1475 }
1476
1477 // TCP connection dialog procedure
WinConnectDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)1478 UINT WinConnectDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
1479 {
1480 WINCONNECT_DLG_DATA *d = (WINCONNECT_DLG_DATA *)param;
1481 // Validate arguments
1482 if (hWnd == NULL || d == NULL)
1483 {
1484 return 0;
1485 }
1486
1487 switch (msg)
1488 {
1489 case WM_INITDIALOG:
1490 // UI setting
1491 CenterParent(hWnd);
1492 SetText(hWnd, 0, d->caption);
1493 SetText(hWnd, S_INFO, d->info);
1494 SetIcon(hWnd, S_ICON, d->icon_id);
1495 d->hWnd = hWnd;
1496
1497 if (MsIsWinXPOrWinVista())
1498 {
1499 // Show a progress bar for Windows XP or later
1500 SendMsg(hWnd, IDC_PROGRESS1, PBM_SETMARQUEE, TRUE, 100);
1501 SetStyle(hWnd, IDC_PROGRESS1, PBS_MARQUEE);
1502 }
1503 else
1504 {
1505 // Hide the progress bar in the case of pre-Windows 2000
1506 Hide(hWnd, IDC_PROGRESS1);
1507 }
1508
1509 // Create a thread
1510 d->thread = NewThread(WinConnectDlgThread, d);
1511 break;
1512
1513 case WM_COMMAND:
1514 switch (wParam)
1515 {
1516 case IDCANCEL:
1517 Close(hWnd);
1518 break;
1519 }
1520 break;
1521
1522 case WM_APP + 68:
1523 case WM_CLOSE:
1524 if (d->cancel == false)
1525 {
1526 d->cancel = true;
1527 Disable(hWnd, IDCANCEL);
1528 if (d->ret_sock == NULL)
1529 {
1530 SetText(hWnd, S_INFO, _UU("CONNECTDLG_CANCELING"));
1531 }
1532 DoEvents(hWnd);
1533 Refresh(hWnd);
1534 WaitThread(d->thread, INFINITE);
1535 ReleaseThread(d->thread);
1536 EndDialog(hWnd, 0);
1537 }
1538 break;
1539 }
1540
1541 return 0;
1542 }
1543
1544 // TCP connection with showing the UI
WinConnectEx2(HWND hWnd,char * server,UINT port,UINT timeout,UINT icon_id,wchar_t * caption,wchar_t * info,bool try_start_ssl,bool ssl_no_tls)1545 SOCK *WinConnectEx2(HWND hWnd, char *server, UINT port, UINT timeout, UINT icon_id, wchar_t *caption, wchar_t *info, bool try_start_ssl, bool ssl_no_tls)
1546 {
1547 return WinConnectEx3(hWnd, server, port, timeout, icon_id, caption, info, NULL, false, try_start_ssl, ssl_no_tls);
1548 }
WinConnectEx3(HWND hWnd,char * server,UINT port,UINT timeout,UINT icon_id,wchar_t * caption,wchar_t * info,UINT * nat_t_error_code,char * nat_t_svc_name,bool try_start_ssl,bool ssl_no_tls)1549 SOCK *WinConnectEx3(HWND hWnd, char *server, UINT port, UINT timeout, UINT icon_id, wchar_t *caption, wchar_t *info, UINT *nat_t_error_code, char *nat_t_svc_name, bool try_start_ssl, bool ssl_no_tls)
1550 {
1551 wchar_t tmp[MAX_SIZE];
1552 wchar_t tmp2[MAX_SIZE];
1553 WINCONNECT_DLG_DATA d;
1554 // Validate arguments
1555 if (server == NULL || port == 0)
1556 {
1557 return NULL;
1558 }
1559 if (icon_id == 0)
1560 {
1561 icon_id = ICO_USER_ADMIN;
1562 }
1563 if (caption == NULL)
1564 {
1565 if (hWnd == NULL)
1566 {
1567 caption = _UU("CONNECTDLG_CAPTION");
1568 }
1569 else
1570 {
1571 GetTxt(hWnd, 0, tmp2, sizeof(tmp2));
1572 caption = tmp2;
1573 }
1574 }
1575 if (info == NULL)
1576 {
1577 UniFormat(tmp, sizeof(tmp), _UU("CONNECTDLG_MESSAGE"), server, port);
1578
1579 info = tmp;
1580 }
1581
1582 Zero(&d, sizeof(d));
1583
1584 d.try_start_ssl = try_start_ssl;
1585 d.ssl_no_tls = ssl_no_tls;
1586 d.cancel = false;
1587 d.caption = caption;
1588 d.icon_id = icon_id;
1589 d.info = info;
1590 d.timeout = timeout;
1591 d.hostname = server;
1592 d.port = port;
1593 StrCpy(d.nat_t_svc_name, sizeof(d.nat_t_svc_name), nat_t_svc_name);
1594
1595 Dialog(hWnd, D_CONNECT, WinConnectDlgProc, &d);
1596
1597 if (nat_t_error_code != NULL)
1598 {
1599 *nat_t_error_code = d.nat_t_error_code;
1600 }
1601
1602 return d.ret_sock;
1603 }
1604
1605 // Show the Windows Network Setup screen
ShowWindowsNetworkConnectionDialog()1606 bool ShowWindowsNetworkConnectionDialog()
1607 {
1608 wchar_t exe_name[MAX_SIZE];
1609 void *proc;
1610
1611 CombinePathW(exe_name, sizeof(exe_name), MsGetSystem32DirW(), L"control.exe");
1612
1613 proc = Win32RunEx2W(exe_name, L"netconnections", false, NULL);
1614
1615 if (proc == NULL)
1616 {
1617 return false;
1618 }
1619
1620 Win32CloseProcess(proc);
1621
1622 return true;
1623 }
1624
1625 // Get the best Meiryo font name for the current OS
GetMeiryoFontName()1626 char *GetMeiryoFontName()
1627 {
1628 if (MsIsWindows7())
1629 {
1630 return "Meiryo UI";
1631 }
1632 else
1633 {
1634 if (MsIsVista())
1635 {
1636 return "Meiryo";
1637 }
1638 else
1639 {
1640 return "MS UI Gothic";
1641 }
1642 }
1643 }
1644
1645 // Get the Meiryo font
GetMeiryoFont()1646 HFONT GetMeiryoFont()
1647 {
1648 return GetMeiryoFontEx(0);
1649 }
GetMeiryoFontEx(UINT font_size)1650 HFONT GetMeiryoFontEx(UINT font_size)
1651 {
1652 return GetMeiryoFontEx2(font_size, false);
1653 }
GetMeiryoFontEx2(UINT font_size,bool bold)1654 HFONT GetMeiryoFontEx2(UINT font_size, bool bold)
1655 {
1656 if (_GETLANG() == 0)
1657 {
1658 return GetFont(GetMeiryoFontName(), font_size, bold, false, false, false);
1659 }
1660 else if (_GETLANG() == 2)
1661 {
1662 return GetFont("Microsoft YaHei", font_size, bold, false, false, false);
1663 }
1664 else
1665 {
1666 return GetFont(NULL, font_size, bold, false, false, false);
1667 }
1668 }
1669
1670 // Set font to Meiryo
SetFontMeiryo(HWND hWnd,UINT id,UINT font_size)1671 void SetFontMeiryo(HWND hWnd, UINT id, UINT font_size)
1672 {
1673 SetFont(hWnd, id, GetMeiryoFontEx(font_size));
1674 }
1675
1676 // Set as the default font
SetFontDefault(HWND hWnd,UINT id)1677 void SetFontDefault(HWND hWnd, UINT id)
1678 {
1679 SetFont(hWnd, id, GetDialogDefaultFont());
1680 }
1681
1682 // Display the warning messages about bad process
ShowBadProcessWarning(HWND hWnd,BAD_PROCESS * bad)1683 void ShowBadProcessWarning(HWND hWnd, BAD_PROCESS *bad)
1684 {
1685 wchar_t title[MAX_SIZE];
1686 wchar_t message[8192];
1687 // Validate arguments
1688 if (bad == NULL)
1689 {
1690 return;
1691 }
1692
1693 UniFormat(title, sizeof(title), _UU("BAD_PROCESS_TITLE"), bad->Title);
1694 UniFormat(message, sizeof(message), _UU("BAD_PROCESS_MESSAGE"),
1695 bad->Title, bad->Title, bad->Title, bad->Title);
1696
1697 OnceMsg(hWnd, title, message, true, ICO_WARNING);
1698 }
1699
1700 // If there is process which is included in incompatible anti-virus software list, show appropriate
CheckBadProcesses(HWND hWnd)1701 bool CheckBadProcesses(HWND hWnd)
1702 {
1703 bool ret = true;
1704 UINT i;
1705 LIST *o;
1706
1707 o = MsGetProcessList();
1708
1709 for (i = 0;i < LIST_NUM(o);i++)
1710 {
1711 MS_PROCESS *p = LIST_DATA(o, i);
1712 char exe[MAX_PATH];
1713 BAD_PROCESS *bad;
1714
1715 GetFileNameFromFilePath(exe, sizeof(exe), p->ExeFilename);
1716
1717 bad = IsBadProcess(exe);
1718
1719 if (bad != NULL)
1720 {
1721 // Display the message because a bad process have been found
1722 ret = false;
1723
1724 ShowBadProcessWarning(hWnd, bad);
1725 }
1726 }
1727
1728 MsFreeProcessList(o);
1729
1730 return ret;
1731 }
1732
1733 // Search whether the specified process name is the appropriate to a bad process
IsBadProcess(char * exe)1734 BAD_PROCESS *IsBadProcess(char *exe)
1735 {
1736 UINT i;
1737 // Validate arguments
1738 if (exe == NULL)
1739 {
1740 return NULL;
1741 }
1742
1743 for (i = 0;i < num_bad_processes;i++)
1744 {
1745 BAD_PROCESS *bad = &bad_processes[i];
1746
1747 if (StrCmpi(bad->ExeName, exe) == 0)
1748 {
1749 return bad;
1750 }
1751 }
1752
1753 return NULL;
1754 }
1755
1756 // Message display procedure
OnceMsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)1757 UINT OnceMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
1758 {
1759 ONCEMSG_DLG *d = (ONCEMSG_DLG *)param;
1760 // Validate arguments
1761 if (hWnd == NULL)
1762 {
1763 return 0;
1764 }
1765
1766 switch (msg)
1767 {
1768 case WM_INITDIALOG:
1769 SetText(hWnd, 0, d->Title);
1770 SetText(hWnd, E_TEXT, d->Message);
1771 SetShow(hWnd, C_DONTSHOWAGAIN, d->ShowCheckbox);
1772 //DisableClose(hWnd);
1773 Focus(hWnd, IDCANCEL);
1774 if (d->Icon != 0)
1775 {
1776 SetIcon(hWnd, 0, d->Icon);
1777 }
1778
1779 if (MsIsVista())
1780 {
1781 SetFont(hWnd, E_TEXT, GetMeiryoFont());
1782 }
1783 else
1784 {
1785 DlgFont(hWnd, E_TEXT, 11, false);
1786 }
1787
1788 SetTimer(hWnd, 1, 50, NULL);
1789 break;
1790
1791 case WM_TIMER:
1792 switch (wParam)
1793 {
1794 case 1:
1795 if (*d->halt)
1796 {
1797 Close(hWnd);
1798 }
1799 break;
1800 }
1801 break;
1802
1803 case WM_COMMAND:
1804 switch (wParam)
1805 {
1806 case IDOK:
1807 case IDCANCEL:
1808 Close(hWnd);
1809 break;
1810 }
1811 break;
1812
1813 case WM_CLOSE:
1814 KillTimer(hWnd, 1);
1815 d->Checked = IsChecked(hWnd, C_DONTSHOWAGAIN);
1816 EndDialog(hWnd, 0);
1817 break;
1818 }
1819
1820 return 0;
1821 }
1822
1823 // Show a message
OnceMsg(HWND hWnd,wchar_t * title,wchar_t * message,bool show_checkbox,UINT icon)1824 void OnceMsg(HWND hWnd, wchar_t *title, wchar_t *message, bool show_checkbox, UINT icon)
1825 {
1826 OnceMsgEx(hWnd, title, message, show_checkbox, icon, NULL);
1827 }
OnceMsgEx(HWND hWnd,wchar_t * title,wchar_t * message,bool show_checkbox,UINT icon,bool * halt)1828 void OnceMsgEx(HWND hWnd, wchar_t *title, wchar_t *message, bool show_checkbox, UINT icon, bool *halt)
1829 {
1830 ONCEMSG_DLG d;
1831 UINT hash;
1832 char valuename[MAX_PATH];
1833 bool b_dummy = false;
1834 // Validate arguments
1835 if (title == NULL)
1836 {
1837 title = title_bar;
1838 }
1839 if (message == NULL)
1840 {
1841 message = L"message";
1842 }
1843 if (halt == NULL)
1844 {
1845 halt = &b_dummy;
1846 }
1847
1848 Zero(&d, sizeof(d));
1849 d.Message = message;
1850 d.Title = title;
1851 d.ShowCheckbox = show_checkbox;
1852 d.Icon = icon;
1853 d.halt = halt;
1854
1855 hash = GetOnceMsgHash(title, message);
1856 Format(valuename, sizeof(valuename), ONCE_MSG_REGVALUE, hash);
1857
1858 if (MsRegReadInt(REG_CURRENT_USER, ONCE_MSG_REGKEY, valuename) == 0)
1859 {
1860 switch (icon)
1861 {
1862 case ICO_WARNING:
1863 MessageBeep(MB_ICONEXCLAMATION);
1864 break;
1865
1866 case ICO_INFORMATION:
1867 MessageBeep(MB_ICONASTERISK);
1868 break;
1869 }
1870
1871 Dialog(hWnd, D_ONCEMSG, OnceMsgProc, &d);
1872
1873 if (show_checkbox)
1874 {
1875 if (d.Checked)
1876 {
1877 MsRegWriteInt(REG_CURRENT_USER, ONCE_MSG_REGKEY, valuename, 1);
1878 }
1879 }
1880 }
1881 }
1882
1883 // Get the message hash
GetOnceMsgHash(wchar_t * title,wchar_t * message)1884 UINT GetOnceMsgHash(wchar_t *title, wchar_t *message)
1885 {
1886 BUF *b;
1887 UCHAR hash[SHA1_SIZE];
1888 UINT ret;
1889 // Validate arguments
1890 if (title == NULL)
1891 {
1892 title = title_bar;
1893 }
1894 if (message == NULL)
1895 {
1896 message = L"message";
1897 }
1898
1899 b = NewBuf();
1900 // 2013.5.19: Exclude the title from the hash calculation
1901 //WriteBuf(b, title, UniStrSize(title));
1902 WriteBuf(b, message, UniStrSize(message));
1903 HashSha1(hash, b->Buf, b->Size);
1904 FreeBuf(b);
1905
1906 Copy(&ret, hash, sizeof(UINT));
1907
1908 return ret;
1909 }
1910
1911 // Set a theme for Windows Vista
InitVistaWindowTheme(HWND hWnd)1912 void InitVistaWindowTheme(HWND hWnd)
1913 {
1914 static HINSTANCE hInstDll = NULL;
1915 HRESULT (WINAPI *_SetWindowTheme)(HWND, LPCWSTR, LPCWSTR) = NULL;
1916
1917 if (MsIsVista() == false)
1918 {
1919 return;
1920 }
1921
1922 if (hInstDll == NULL)
1923 {
1924 hInstDll = LoadLibraryA("uxtheme.dll");
1925 }
1926
1927 if (hInstDll == NULL)
1928 {
1929 return;
1930 }
1931
1932 if (_SetWindowTheme == NULL)
1933 {
1934 _SetWindowTheme = (HRESULT (WINAPI *)(HWND,LPCWSTR,LPCWSTR))GetProcAddress(hInstDll, "SetWindowTheme");
1935 }
1936
1937 if (_SetWindowTheme == NULL)
1938 {
1939 return;
1940 }
1941
1942 _SetWindowTheme(hWnd, L"explorer", NULL);
1943 }
1944
1945 // Register all applications to be registered in the Windows firewall
1946 // that may be present in the current directory
RegistWindowsFirewallAll()1947 void RegistWindowsFirewallAll()
1948 {
1949 char exedir[MAX_SIZE];
1950
1951 GetExeDir(exedir, sizeof(exedir));
1952
1953 RegistWindowsFirewallAllEx(exedir);
1954 }
RegistWindowsFirewallAllEx(char * dir)1955 void RegistWindowsFirewallAllEx(char *dir)
1956 {
1957 MsRegistWindowsFirewallEx2(CEDAR_CLIENT_STR, "vpnclient.exe", dir);
1958 MsRegistWindowsFirewallEx2(CEDAR_CLIENT_STR, "vpnclient_x64.exe", dir);
1959
1960 MsRegistWindowsFirewallEx2(CEDAR_CLIENT_MANAGER_STR, "vpncmgr.exe", dir);
1961 MsRegistWindowsFirewallEx2(CEDAR_CLIENT_MANAGER_STR, "vpncmgr_x64.exe", dir);
1962
1963 MsRegistWindowsFirewallEx2(CEDAR_MANAGER_STR, "vpnsmgr.exe", dir);
1964 MsRegistWindowsFirewallEx2(CEDAR_MANAGER_STR, "vpnsmgr_x64.exe", dir);
1965
1966 MsRegistWindowsFirewallEx2(CEDAR_SERVER_STR, "vpnserver.exe", dir);
1967 MsRegistWindowsFirewallEx2(CEDAR_SERVER_STR, "vpnserver_x64.exe", dir);
1968
1969 MsRegistWindowsFirewallEx2(CEDAR_BRIDGE_STR, "vpnbridge.exe", dir);
1970 MsRegistWindowsFirewallEx2(CEDAR_BRIDGE_STR, "vpnbridge_x64.exe", dir);
1971
1972 MsRegistWindowsFirewallEx2(CEDAR_CUI_STR, "vpncmd.exe", dir);
1973 MsRegistWindowsFirewallEx2(CEDAR_CUI_STR, "vpncmd_x64.exe", dir);
1974
1975 MsRegistWindowsFirewallEx2(CEDAR_PRODUCT_STR, "ham.exe", dir);
1976 MsRegistWindowsFirewallEx2(CEDAR_PRODUCT_STR, "ham_x64.exe", dir);
1977 }
1978
1979 // Check whether the notification service is already running
Win32CnCheckAlreadyExists(bool lock)1980 bool Win32CnCheckAlreadyExists(bool lock)
1981 {
1982 char tmp[MAX_SIZE];
1983 HANDLE hMutex;
1984
1985 HashInstanceNameLocal(tmp, sizeof(tmp), CLIENT_NOTIFY_SERVICE_INSTANCENAME);
1986
1987 hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, tmp);
1988 if (hMutex != NULL)
1989 {
1990 CloseHandle(hMutex);
1991 return true;
1992 }
1993
1994 if (lock == false)
1995 {
1996 return false;
1997 }
1998
1999 hMutex = CreateMutex(NULL, FALSE, tmp);
2000 if (hMutex == NULL)
2001 {
2002 CloseHandle(hMutex);
2003 return true;
2004 }
2005
2006 return false;
2007 }
2008
2009 // Get whether it is set to not display the dialog about the free version
IsRegistedToDontShowFreeEditionDialog(char * server_name)2010 bool IsRegistedToDontShowFreeEditionDialog(char *server_name)
2011 {
2012 // Validate arguments
2013 if (server_name == NULL)
2014 {
2015 return false;
2016 }
2017
2018 if (MsRegReadInt(REG_LOCAL_MACHINE, FREE_REGKEY, server_name) != 0)
2019 {
2020 return true;
2021 }
2022
2023 if (MsRegWriteInt(REG_LOCAL_MACHINE, FREE_REGKEY, "__test__", 1) == false)
2024 {
2025 return true;
2026 }
2027
2028 MsRegDeleteValue(REG_LOCAL_MACHINE, FREE_REGKEY, "__test__");
2029
2030 return false;
2031 }
2032
2033 // Set in the registry not to show a dialog about the free version
RegistToDontShowFreeEditionDialog(char * server_name)2034 void RegistToDontShowFreeEditionDialog(char *server_name)
2035 {
2036 // Validate arguments
2037 if (server_name == NULL)
2038 {
2039 return;
2040 }
2041
2042 MsRegWriteInt(REG_LOCAL_MACHINE, FREE_REGKEY, server_name, 1);
2043 }
2044
2045 // Free Edition dialog procedure
FreeInfoDialogProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)2046 UINT FreeInfoDialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
2047 {
2048 FREEINFO *info = (FREEINFO *)param;
2049 // Validate arguments
2050 if (hWnd == NULL)
2051 {
2052 return 0;
2053 }
2054
2055 switch (msg)
2056 {
2057 case WM_INITDIALOG:
2058 SetIcon(hWnd, 0, ICO_HUB);
2059 Top(hWnd);
2060 info->hWnd = hWnd;
2061 Set(info->Event);
2062 FormatText(hWnd, S_INFO_2, info->ServerName);
2063 DlgFont(hWnd, S_INFO_1, 13, true);
2064 DlgFont(hWnd, S_INFO_3, 13, false);
2065 DlgFont(hWnd, B_HIDE, 10, true);
2066 break;
2067
2068 case WM_COMMAND:
2069 switch (wParam)
2070 {
2071 case IDOK:
2072 case IDCANCEL:
2073 if (IsChecked(hWnd, B_HIDE))
2074 {
2075 RegistToDontShowFreeEditionDialog(info->ServerName);
2076 }
2077
2078 Close(hWnd);
2079 break;
2080 }
2081 break;
2082
2083 case WM_CLOSE:
2084 EndDialog(hWnd, 0);
2085 break;
2086 }
2087
2088 return 0;
2089 }
2090
2091 // Display the dialog about the Free Edition
ShowFreeInfoDialog(HWND hWnd,FREEINFO * info)2092 void ShowFreeInfoDialog(HWND hWnd, FREEINFO *info)
2093 {
2094 // Validate arguments
2095 if (info == NULL)
2096 {
2097 return;
2098 }
2099
2100 Dialog(hWnd, D_FREEINFO, FreeInfoDialogProc, info);
2101 Set(info->Event);
2102 }
2103
2104 // Free Edition dialog thread
FreeInfoThread(THREAD * thread,void * param)2105 void FreeInfoThread(THREAD *thread, void *param)
2106 {
2107 FREEINFO *info = (FREEINFO *)param;
2108 // Validate arguments
2109 if (thread == NULL || info == NULL)
2110 {
2111 return;
2112 }
2113
2114 ShowFreeInfoDialog(NULL, info);
2115 }
2116
2117 // Start the Free Edition Announcement dialog
StartFreeInfoDlg(char * server_name)2118 FREEINFO *StartFreeInfoDlg(char *server_name)
2119 {
2120 FREEINFO *info;
2121
2122 if (IsRegistedToDontShowFreeEditionDialog(server_name))
2123 {
2124 return NULL;
2125 }
2126
2127 info = ZeroMalloc(sizeof(FREEINFO));
2128
2129 StrCpy(info->ServerName, sizeof(info->ServerName), server_name);
2130 info->Event = NewEvent();
2131
2132 info->Thread = NewThread(FreeInfoThread, info);
2133 Wait(info->Event, INFINITE);
2134 ReleaseEvent(info->Event);
2135 info->Event = NULL;
2136
2137 return info;
2138 }
2139
2140 // End the Free Edition Announcement dialog
EndFreeInfoDlg(FREEINFO * info)2141 void EndFreeInfoDlg(FREEINFO *info)
2142 {
2143 // Validate arguments
2144 if (info == NULL)
2145 {
2146 return;
2147 }
2148
2149 SendMsg(info->hWnd, 0, WM_CLOSE, 0, 0);
2150 WaitThread(info->Thread, INFINITE);
2151 ReleaseThread(info->Thread);
2152
2153 Free(info);
2154 }
2155
2156 // Execute a EXE in the hamcore
ExecuteHamcoreExe(char * name)2157 bool ExecuteHamcoreExe(char *name)
2158 {
2159 BUF *b;
2160 wchar_t tmp[MAX_PATH];
2161 char tmp2[MAX_PATH];
2162 UCHAR hash[MD5_SIZE];
2163 // Validate arguments
2164 if (name == NULL)
2165 {
2166 return false;
2167 }
2168
2169 b = ReadDump(name);
2170 if (b == NULL)
2171 {
2172 return false;
2173 }
2174
2175 Hash(hash, name, StrLen(name), false);
2176 BinToStr(tmp2, sizeof(tmp2), hash, sizeof(hash));
2177 UniFormat(tmp, sizeof(tmp), L"%s\\tmp_%S.exe", MsGetMyTempDirW(), tmp2);
2178 SeekBuf(b, 0, 0);
2179 DumpBufW(b, tmp);
2180
2181 FreeBuf(b);
2182
2183 return RunW(tmp, NULL, false, false);
2184 }
2185
2186 // Show the Easter Egg
ShowEasterEgg(HWND hWnd)2187 void ShowEasterEgg(HWND hWnd)
2188 {
2189 }
2190
KakushiThread(THREAD * thread,void * param)2191 void KakushiThread(THREAD *thread, void *param)
2192 {
2193 KAKUSHI *k;
2194 // Validate arguments
2195 if (thread == NULL || param == NULL)
2196 {
2197 return;
2198 }
2199
2200 k = (KAKUSHI *)param;
2201
2202 k->Thread = thread;
2203 AddRef(k->Thread->ref);
2204 NoticeThreadInit(thread);
2205
2206 Dialog(NULL, D_CM_KAKUSHI, KakushiDlgProc, k);
2207 k->hWnd = NULL;
2208 }
2209
InitKakushi()2210 KAKUSHI *InitKakushi()
2211 {
2212 THREAD *t;
2213 KAKUSHI *k = ZeroMalloc(sizeof(KAKUSHI));
2214
2215 t = NewThread(KakushiThread, k);
2216
2217 WaitThreadInit(t);
2218 ReleaseThread(t);
2219
2220 return k;
2221 }
2222
KakushiDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)2223 UINT KakushiDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
2224 {
2225 KAKUSHI *k = (KAKUSHI *)param;
2226 UINT64 now;
2227 bool b;
2228 if (hWnd == NULL)
2229 {
2230 return 0;
2231 }
2232
2233 switch (msg)
2234 {
2235 case WM_INITDIALOG:
2236 SetText(hWnd, S_INFO, _UU("CM_VLAN_CREATING"));
2237
2238 b = false;
2239
2240 if (MsIsVista())
2241 {
2242 if (_GETLANG() == 0)
2243 {
2244 SetFont(hWnd, S_INFO, GetFont(GetMeiryoFontName(), 11, false, false, false, false));
2245 b = true;
2246 }
2247 else if (_GETLANG() == 2)
2248 {
2249 SetFont(hWnd, S_INFO, GetFont("Microsoft YaHei", 11, false, false, false, false));
2250 b = true;
2251 }
2252 }
2253
2254 if (b == false)
2255 {
2256 DlgFont(hWnd, S_INFO, 11, false);
2257 }
2258
2259 SetTimer(hWnd, 1, 50, NULL);
2260 k->hWnd = hWnd;
2261
2262 k->Span = 20 * 1000;
2263 k->StartTick = Tick64();
2264
2265 SetRange(hWnd, P_PROGRESS, 0, (UINT)k->Span);
2266
2267 case WM_APP + 9821:
2268 now = Tick64();
2269
2270 if (((k->StartTick + k->Span) <= now) || k->Halt)
2271 {
2272 EndDialog(hWnd, 0);
2273 break;
2274 }
2275
2276 SetPos(hWnd, P_PROGRESS, (UINT)(now - k->StartTick));
2277 break;
2278
2279 case WM_TIMER:
2280 switch (wParam)
2281 {
2282 case 1:
2283 AllowSetForegroundWindow(ASFW_ANY);
2284 SetForegroundWindow(hWnd);
2285 SetActiveWindow(hWnd);
2286
2287 now = Tick64();
2288
2289 if (((k->StartTick + k->Span) <= now) || k->Halt)
2290 {
2291 EndDialog(hWnd, 0);
2292 break;
2293 }
2294
2295 SetPos(hWnd, P_PROGRESS, (UINT)(now - k->StartTick));
2296 break;
2297 }
2298 break;
2299
2300 case WM_CLOSE:
2301 return 1;
2302 }
2303
2304 return 0;
2305 }
2306
2307 // Release the Kakushi screen
FreeKakushi(KAKUSHI * k)2308 void FreeKakushi(KAKUSHI *k)
2309 {
2310 // Validate arguments
2311 if (k == NULL)
2312 {
2313 return;
2314 }
2315
2316 k->Halt = true;
2317
2318 if (k->hWnd != NULL)
2319 {
2320 PostMessage(k->hWnd, WM_APP + 9821, 0, 0);
2321 }
2322
2323 WaitThread(k->Thread, INFINITE);
2324 ReleaseThread(k->Thread);
2325
2326 Free(k);
2327 }
2328
2329 // TCP/IP optimization selection dialog procedure
TcpMsgDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)2330 UINT TcpMsgDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
2331 {
2332 UINT ret;
2333 // Validate arguments
2334 if (hWnd == NULL)
2335 {
2336 return 0;
2337 }
2338
2339 switch (msg)
2340 {
2341 case WM_INITDIALOG:
2342 SetIcon(hWnd, 0, ICO_SETUP);
2343 //DlgFont(hWnd, R_OPTIMIZE, 0, true);
2344
2345 Check(hWnd, R_NO, true);
2346
2347 if (g_tcpip_topmost)
2348 {
2349 Top(hWnd);
2350 }
2351
2352 break;
2353
2354 case WM_COMMAND:
2355 switch (wParam)
2356 {
2357 case IDOK:
2358 ret = 1;
2359 if (IsChecked(hWnd, R_MANUAL))
2360 {
2361 ret = 2;
2362 }
2363 else if (IsChecked(hWnd, R_NO))
2364 {
2365 ret = 0;
2366 }
2367
2368 EndDialog(hWnd, ret);
2369 break;
2370 }
2371 break;
2372
2373 case WM_CLOSE:
2374 return 1;
2375 }
2376
2377 return 0;
2378 }
2379
2380 // Initialize the dialog
TcpIpDlgInit(HWND hWnd)2381 void TcpIpDlgInit(HWND hWnd)
2382 {
2383 MS_TCP tcp;
2384
2385 SetIcon(hWnd, 0, ICO_SETUP);
2386
2387 MsGetTcpConfig(&tcp);
2388
2389 Check(hWnd, R_RECV_DISABLE, tcp.RecvWindowSize == 0);
2390 Check(hWnd, R_RECV_ENABLE, tcp.RecvWindowSize != 0);
2391 SetInt(hWnd, E_RECV, tcp.RecvWindowSize != 0 ? tcp.RecvWindowSize : DEFAULT_TCP_MAX_WINDOW_SIZE_RECV);
2392
2393 Check(hWnd, R_SEND_DISABLE, tcp.SendWindowSize == 0);
2394 Check(hWnd, R_SEND_ENABLE, tcp.SendWindowSize != 0);
2395 SetInt(hWnd, E_SEND, tcp.SendWindowSize != 0 ? tcp.SendWindowSize : DEFAULT_TCP_MAX_WINDOW_SIZE_SEND);
2396
2397 TcpIpDlgUpdate(hWnd);
2398
2399 Top(hWnd);
2400 }
2401
2402 // Update the dialog
TcpIpDlgUpdate(HWND hWnd)2403 void TcpIpDlgUpdate(HWND hWnd)
2404 {
2405 bool ok = true;
2406
2407 SetEnable(hWnd, E_RECV, IsChecked(hWnd, R_RECV_ENABLE));
2408 SetEnable(hWnd, S_RECV, IsChecked(hWnd, R_RECV_ENABLE));
2409 SetEnable(hWnd, E_SEND, IsChecked(hWnd, R_SEND_ENABLE));
2410 SetEnable(hWnd, S_SEND, IsChecked(hWnd, R_SEND_ENABLE));
2411
2412 if (IsChecked(hWnd, R_RECV_ENABLE) && GetInt(hWnd, E_RECV) < 1454)
2413 {
2414 ok = false;
2415 }
2416
2417 if (IsChecked(hWnd, R_SEND_ENABLE) && GetInt(hWnd, E_SEND) < 1454)
2418 {
2419 ok = false;
2420 }
2421
2422 SetEnable(hWnd, IDOK, ok);
2423 }
2424
2425 // TCP/IP dialog procedure
TcpIpDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)2426 UINT TcpIpDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
2427 {
2428 MS_TCP tcp, old;
2429 // Validate arguments
2430 if (hWnd == NULL)
2431 {
2432 return 0;
2433 }
2434
2435 switch (msg)
2436 {
2437 case WM_INITDIALOG:
2438 TcpIpDlgInit(hWnd);
2439
2440 if (g_tcpip_topmost)
2441 {
2442 Top(hWnd);
2443 }
2444
2445 break;
2446
2447 case WM_COMMAND:
2448 switch (LOWORD(wParam))
2449 {
2450 case R_RECV_DISABLE:
2451 case R_RECV_ENABLE:
2452 case R_SEND_DISABLE:
2453 case R_SEND_ENABLE:
2454 case E_RECV:
2455 case E_SEND:
2456 TcpIpDlgUpdate(hWnd);
2457 break;
2458 }
2459
2460 switch (wParam)
2461 {
2462 case IDOK:
2463 Zero(&tcp, sizeof(tcp));
2464
2465 if (IsChecked(hWnd, R_RECV_ENABLE))
2466 {
2467 tcp.RecvWindowSize = GetInt(hWnd, E_RECV);
2468 }
2469
2470 if (IsChecked(hWnd, R_SEND_ENABLE))
2471 {
2472 tcp.SendWindowSize = GetInt(hWnd, E_SEND);
2473 }
2474
2475 MsGetTcpConfig(&old);
2476
2477 MsSetTcpConfig(&tcp);
2478 MsSaveTcpConfigReg(&tcp);
2479
2480 EndDialog(hWnd, true);
2481 break;
2482
2483 case IDCANCEL:
2484 Close(hWnd);
2485 break;
2486
2487 case R_RECV_ENABLE:
2488 FocusEx(hWnd, E_RECV);
2489 break;
2490
2491 case R_SEND_ENABLE:
2492 FocusEx(hWnd, E_SEND);
2493 break;
2494
2495 case B_RECV:
2496 SetInt(hWnd, E_RECV, DEFAULT_TCP_MAX_WINDOW_SIZE_RECV);
2497 Check(hWnd, R_RECV_DISABLE, false);
2498 Check(hWnd, R_RECV_ENABLE, true);
2499 TcpIpDlgUpdate(hWnd);
2500 FocusEx(hWnd, E_RECV);
2501 break;
2502
2503 case B_SEND:
2504 SetInt(hWnd, E_SEND, DEFAULT_TCP_MAX_WINDOW_SIZE_SEND);
2505 Check(hWnd, R_SEND_DISABLE, false);
2506 Check(hWnd, R_SEND_ENABLE, true);
2507 TcpIpDlgUpdate(hWnd);
2508 FocusEx(hWnd, E_SEND);
2509 break;
2510
2511 case B_DELETE:
2512 Zero(&tcp, sizeof(tcp));
2513 MsSetTcpConfig(&tcp);
2514 MsDeleteTcpConfigReg();
2515 EndDialog(hWnd, 0);
2516 break;
2517 }
2518 break;
2519
2520 case WM_CLOSE:
2521 EndDialog(hWnd, false);
2522 break;
2523 }
2524
2525 return 0;
2526 }
2527
2528 // Warning dialog about 64-bit
Cpu64DlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)2529 UINT Cpu64DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
2530 {
2531 switch (msg)
2532 {
2533 case WM_INITDIALOG:
2534 SetIcon(hWnd, 0, ICO_WARNING);
2535 DlgFont(hWnd, S_BOLD, 9, true);
2536 SetTimer(hWnd, 1, 30 * 1000, NULL);
2537 break;
2538
2539 case WM_TIMER:
2540 switch (wParam)
2541 {
2542 case 1:
2543 KillTimer(hWnd, 1);
2544 Command(hWnd, IDOK);
2545 break;
2546 }
2547
2548 break;
2549
2550 case WM_COMMAND:
2551 switch (wParam)
2552 {
2553 case IDOK:
2554 case IDCANCEL:
2555 Close(hWnd);
2556 break;
2557 }
2558 break;
2559
2560 case WM_CLOSE:
2561 EndDialog(hWnd, 0);
2562 break;
2563 }
2564
2565 return 0;
2566 }
2567
2568 // Display a warning dialog about 64-bit
ShowCpu64Warning()2569 void ShowCpu64Warning()
2570 {
2571 Dialog(NULL, D_CPU64_WARNING, Cpu64DlgProc, NULL);
2572 }
2573
2574 // Show the TCP/IP configuration utility
ShowTcpIpConfigUtil(HWND hWnd,bool util_mode)2575 void ShowTcpIpConfigUtil(HWND hWnd, bool util_mode)
2576 {
2577 if (MsIsTcpConfigSupported() == false)
2578 {
2579 if (util_mode)
2580 {
2581 // Show a message that is not supported by the current OS
2582 if (MsIsAdmin() == false)
2583 {
2584 MsgBox(hWnd, MB_ICONINFORMATION, _UU("TCPOPT_NOT_ADMIN"));
2585 }
2586 else
2587 {
2588 MsgBox(hWnd, MB_ICONINFORMATION, _UU("TCPOPT_NOT_SUPPORTED"));
2589 }
2590 }
2591 return;
2592 }
2593
2594 if (util_mode == false)
2595 {
2596 // Exit immediately by start the vpncmd
2597 wchar_t tmp[MAX_PATH];
2598 wchar_t exedir[MAX_PATH];
2599 HANDLE h;
2600
2601 GetExeDirW(exedir, sizeof(exedir));
2602
2603 if (IsX64())
2604 {
2605 UniFormat(tmp, sizeof(tmp), L"%s\\vpncmd_x64.exe", exedir);
2606 }
2607 else if (IsIA64())
2608 {
2609 UniFormat(tmp, sizeof(tmp), L"%s\\vpncmd_ia64.exe", exedir);
2610 }
2611 else
2612 {
2613 UniFormat(tmp, sizeof(tmp), L"%s\\vpncmd.exe", exedir);
2614 }
2615
2616 if (IsFileW(tmp))
2617 {
2618 RunW(tmp, L"/tool /cmd:exit", true, false);
2619 }
2620
2621 // Disable the task off-loading by netsh
2622 if (MsIsVista())
2623 {
2624 DIRLIST *dl;
2625 UINT i;
2626 bool b = false;
2627
2628 dl = EnumDirW(exedir);
2629
2630 for (i = 0;i < dl->NumFiles;i++)
2631 {
2632 if (UniInStr(dl->File[i]->FileNameW, L"vpnbridge") ||
2633 UniInStr(dl->File[i]->FileNameW, L"vpnserver"))
2634 {
2635 b = true;
2636 }
2637 }
2638
2639 FreeDir(dl);
2640
2641 if (b)
2642 {
2643 // Disable the off-loading
2644 MsDisableNetworkOffloadingEtc();
2645 }
2646 }
2647
2648 // Windows Firewall registration
2649 RegistWindowsFirewallAll();
2650
2651 SleepThread(1000);
2652
2653 // Start vpnclient.exe /uihelp
2654 h = CmExecUiHelperMain();
2655 if (h != NULL)
2656 {
2657 CloseHandle(h);
2658 }
2659
2660 if (Is64() == false)
2661 {
2662 if (MsIs64BitWindows())
2663 {
2664 // Show a warning message if a 32-bit version is used in 64-bit Windows
2665 ShowCpu64Warning();
2666 }
2667 }
2668
2669 if (MsIsAdmin())
2670 {
2671 if (MsIsVista())
2672 {
2673 // If installing on Windows Vista,
2674 // dispel the network limitation of MMCSS
2675 if (MsIsMMCSSNetworkThrottlingEnabled())
2676 {
2677 MsSetMMCSSNetworkThrottlingEnable(false);
2678 }
2679 }
2680 }
2681 }
2682
2683 if (util_mode == false && MsIsShouldShowTcpConfigApp() == false)
2684 {
2685 return;
2686 }
2687
2688 if (util_mode == false)
2689 {
2690 // 2006.07.04 nobori
2691 // I decided not to show TCP/IP optimization utility in the installer
2692 return;
2693 }
2694
2695 g_tcpip_topmost = util_mode ? false : true;
2696
2697 if (util_mode == false)
2698 {
2699 UINT ret = Dialog(hWnd, D_TCP_MSG, TcpMsgDlgProc, NULL);
2700
2701 if (ret == 0)
2702 {
2703 MS_TCP tcp;
2704
2705 Zero(&tcp, sizeof(tcp));
2706 MsGetTcpConfig(&tcp);
2707 MsSaveTcpConfigReg(&tcp);
2708 return;
2709 }
2710 else if (ret == 1)
2711 {
2712 MS_TCP tcp;
2713
2714 Zero(&tcp, sizeof(tcp));
2715
2716 tcp.RecvWindowSize = DEFAULT_TCP_MAX_WINDOW_SIZE_RECV;
2717 tcp.SendWindowSize = DEFAULT_TCP_MAX_WINDOW_SIZE_SEND;
2718 MsSetTcpConfig(&tcp);
2719 MsSaveTcpConfigReg(&tcp);
2720
2721 return;
2722 }
2723 }
2724
2725 Dialog(hWnd, D_TCP, TcpIpDlgProc, NULL);
2726 }
2727
2728 // Internationalization of menu (Unicode)
InitMenuInternationalUni(HMENU hMenu,char * prefix)2729 void InitMenuInternationalUni(HMENU hMenu, char *prefix)
2730 {
2731 UINT i, num;
2732 // Validate arguments
2733 if (hMenu == NULL || prefix == NULL)
2734 {
2735 return;
2736 }
2737
2738 // Get the number of items in the menu
2739 num = GetMenuItemCount(hMenu);
2740
2741 // Enumerate the menu items
2742 for (i = 0;i < num;i++)
2743 {
2744 HMENU hSubMenu = GetSubMenu(hMenu, i);
2745 MENUITEMINFOW info;
2746 wchar_t tmp[MAX_SIZE];
2747
2748 if (hSubMenu != NULL)
2749 {
2750 // If there is a sub-menu, call it recursively
2751 InitMenuInternational(hSubMenu, prefix);
2752 }
2753
2754 // Get the menu item
2755 Zero(&info, sizeof(info));
2756 info.cbSize = sizeof(info);
2757 info.cch = sizeof(tmp);
2758 info.dwTypeData = tmp;
2759 info.fMask = MIIM_STRING;
2760 Zero(tmp, sizeof(tmp));
2761
2762 if (GetMenuItemInfoW(hMenu, i, true, &info))
2763 {
2764 if (tmp[0] == L'@')
2765 {
2766 char name[256];
2767 wchar_t *ret;
2768
2769 Format(name, sizeof(name), "%s@%S", prefix, &tmp[1]);
2770
2771 ret = _UU(name);
2772 if (UniIsEmptyStr(ret) == false)
2773 {
2774 UniStrCpy(tmp, sizeof(tmp), ret);
2775 info.cch = UniStrLen(tmp);
2776
2777 SetMenuItemInfoW(hMenu, i, true, &info);
2778 }
2779 }
2780 }
2781 }
2782 }
2783
2784 // Internationalization of menu
InitMenuInternational(HMENU hMenu,char * prefix)2785 void InitMenuInternational(HMENU hMenu, char *prefix)
2786 {
2787 UINT i, num;
2788 // Validate arguments
2789 if (hMenu == NULL || prefix == NULL)
2790 {
2791 return;
2792 }
2793
2794 if (MsIsNt())
2795 {
2796 InitMenuInternationalUni(hMenu, prefix);
2797 return;
2798 }
2799
2800 // Get the number of items in the menu
2801 num = GetMenuItemCount(hMenu);
2802
2803 // Enumerate the menu items
2804 for (i = 0;i < num;i++)
2805 {
2806 HMENU hSubMenu = GetSubMenu(hMenu, i);
2807 MENUITEMINFO info;
2808 char tmp[MAX_SIZE];
2809
2810 if (hSubMenu != NULL)
2811 {
2812 // If there is a sub-menu, call it recursively
2813 InitMenuInternational(hSubMenu, prefix);
2814 }
2815
2816 // Get the menu item
2817 Zero(&info, sizeof(info));
2818 info.cbSize = sizeof(info);
2819 info.cch = sizeof(tmp);
2820 info.dwTypeData = tmp;
2821 info.fMask = MIIM_STRING;
2822 Zero(tmp, sizeof(tmp));
2823
2824 if (GetMenuItemInfo(hMenu, i, true, &info))
2825 {
2826 if (tmp[0] == '@')
2827 {
2828 char name[256];
2829 char *ret;
2830
2831 Format(name, sizeof(name), "%s@%s", prefix, &tmp[1]);
2832
2833 ret = _SS(name);
2834 if (IsEmptyStr(ret) == false)
2835 {
2836 StrCpy(tmp, sizeof(tmp), ret);
2837 info.cch = StrLen(tmp);
2838
2839 SetMenuItemInfo(hMenu, i, true, &info);
2840 }
2841 }
2842 }
2843 }
2844 }
2845
2846 // Get the default font for the dialog box
GetDialogDefaultFont()2847 HFONT GetDialogDefaultFont()
2848 {
2849 return GetDialogDefaultFontEx(false);
2850 }
GetDialogDefaultFontEx(bool meiryo)2851 HFONT GetDialogDefaultFontEx(bool meiryo)
2852 {
2853 char *default_font_name = _SS("DEFAULT_FONT");
2854 UINT default_font_size = _II("DEFAULT_FONT_SIZE");
2855 char *win7_font = _SS("DEFAULT_FONT_WIN7");
2856
2857 if (meiryo)
2858 {
2859 if (_GETLANG() == 2)
2860 {
2861 default_font_name = "Microsoft YaHei";
2862 }
2863 else
2864 {
2865 default_font_name = GetMeiryoFontName();
2866 }
2867 }
2868
2869 if (MsIsWindows7())
2870 {
2871 if (IsEmptyStr(win7_font) == false)
2872 {
2873 default_font_name = win7_font;
2874 }
2875
2876 if (GetTextScalingFactor() >= 1.44)
2877 {
2878 // Use a substitute font in the case of high-DPI in Windows 7 and later
2879 char *alternative_font = _SS("DEFAULT_FONT_HIGHDPI");
2880
2881 if (IsEmptyStr(alternative_font) == false)
2882 {
2883 default_font_name = alternative_font;
2884 }
2885 }
2886 }
2887
2888 if (IsEmptyStr(default_font_name))
2889 {
2890 default_font_name = font_name;
2891 }
2892
2893 if (default_font_size == 0)
2894 {
2895 default_font_size = 9;
2896 }
2897
2898 return GetFont(default_font_name, default_font_size, false, false, false, false);
2899 }
2900
2901 // Get the adjustment scale between the control size and the window size
GetWindowAndControlSizeResizeScale(HWND hWnd,bool * need_resize,double * factor_x,double * factor_y)2902 void GetWindowAndControlSizeResizeScale(HWND hWnd, bool *need_resize, double *factor_x, double *factor_y)
2903 {
2904 UINT dlgfont_x, dlgfont_y;
2905 HFONT hDlgFont;
2906 // Validate arguments
2907 if (hWnd == NULL || need_resize == NULL || factor_x == NULL || factor_y == NULL)
2908 {
2909 return;
2910 }
2911
2912 *need_resize = true;
2913
2914 // Get the font of the current window
2915 hDlgFont = (HFONT)SendMsg(hWnd, 0, WM_GETFONT, 0, 0);
2916
2917 // Get the width and height of the font of the current window
2918 CalcFontSize(hDlgFont, &dlgfont_x, &dlgfont_y);
2919
2920 if ((dlgfont_x == WINUI_DEFAULT_DIALOG_UNIT_X) &&
2921 (dlgfont_y == WINUI_DEFAULT_DIALOG_UNIT_Y))
2922 {
2923 // There is no need to adjust
2924 *need_resize = false;
2925 *factor_x = 1.0;
2926 *factor_y = 1.0;
2927 return;
2928 }
2929
2930 // Calculate the adjustment amount
2931 *factor_x = (double)dlgfont_x / (double)WINUI_DEFAULT_DIALOG_UNIT_X;
2932 *factor_y = (double)dlgfont_y / (double)WINUI_DEFAULT_DIALOG_UNIT_Y;
2933 }
2934
2935 // Adjust the control size and window size
AdjustWindowAndControlSize(HWND hWnd,bool * need_resize,double * factor_x,double * factor_y)2936 void AdjustWindowAndControlSize(HWND hWnd, bool *need_resize, double *factor_x, double *factor_y)
2937 {
2938 HFONT hDlgFont;
2939 UINT dlgfont_x, dlgfont_y;
2940 RECT rect, rect2;
2941 LIST *o;
2942 UINT i;
2943 // Validate arguments
2944 if (hWnd == NULL || need_resize == NULL || factor_x == NULL || factor_y == NULL)
2945 {
2946 return;
2947 }
2948
2949 *need_resize = true;
2950
2951 // Get the font of the current window
2952 hDlgFont = (HFONT)SendMsg(hWnd, 0, WM_GETFONT, 0, 0);
2953
2954 // Get the width and height of the font of the current window
2955 CalcFontSize(hDlgFont, &dlgfont_x, &dlgfont_y);
2956
2957 if ((dlgfont_x == WINUI_DEFAULT_DIALOG_UNIT_X) &&
2958 (dlgfont_y == WINUI_DEFAULT_DIALOG_UNIT_Y))
2959 {
2960 // There is no need to adjust
2961 *need_resize = false;
2962 *factor_x = 1.0;
2963 *factor_y = 1.0;
2964 //Debug("// There is no need to adjust\n");
2965 return;
2966 }
2967
2968 // Calculate the adjustment amount
2969 *factor_x = (double)dlgfont_x / (double)WINUI_DEFAULT_DIALOG_UNIT_X;
2970 *factor_y = (double)dlgfont_y / (double)WINUI_DEFAULT_DIALOG_UNIT_Y;
2971 //Debug("Factors: %f %f\n", *factor_x, *factor_y);
2972
2973 if (MsIsVista())
2974 {
2975 // In Windows Vista or later, trust the size expansion by the OS to follow this (not adjusted)
2976 return;
2977 }
2978
2979 // Adjust the size of the window
2980 if (GetWindowRect(hWnd, &rect))
2981 {
2982 if (GetClientRect(hWnd, &rect2))
2983 {
2984 UINT width = rect2.right - rect2.left;
2985 UINT height = rect2.bottom - rect2.top;
2986
2987 AdjustDialogXY(&width, &height, dlgfont_x, dlgfont_y);
2988
2989 width += (rect.right - rect.left) - (rect2.right - rect2.left);
2990 height += (rect.bottom - rect.top) - (rect2.bottom - rect2.top);
2991
2992 if (true)
2993 {
2994 HWND hParent = GetParent(hWnd);
2995
2996 if (hParent != NULL)
2997 {
2998 RECT r;
2999
3000 Zero(&r, sizeof(r));
3001
3002 if (GetWindowRect(hParent, &r))
3003 {
3004 RECT r2;
3005
3006 rect.top = r.top + GetSystemMetrics(SM_CYCAPTION);
3007
3008 Zero(&r2, sizeof(r2));
3009 if (SystemParametersInfo(SPI_GETWORKAREA, 0, &r2, 0))
3010 {
3011 if (r2.bottom < (rect.top + (int)height))
3012 {
3013 rect.top -= (rect.top + (int)height) - r2.bottom;
3014
3015 if (rect.top < 0)
3016 {
3017 rect.top = 0;
3018 }
3019 }
3020 }
3021 }
3022 }
3023 }
3024
3025 MoveWindow(hWnd, rect.left, rect.top, width, height, false);
3026 }
3027 }
3028
3029 // Enumerate the child windows
3030 o = EnumAllChildWindowEx(hWnd, false, true, true);
3031
3032 for (i = 0;i < LIST_NUM(o);i++)
3033 {
3034 // Adjust the size of the child window
3035 HWND h = *((HWND *)LIST_DATA(o, i));
3036 HWND hWndParent = GetParent(h);
3037 RECT current_rect;
3038 char class_name[MAX_PATH];
3039 bool is_image = false;
3040
3041 // Get the class name
3042 Zero(class_name, sizeof(class_name));
3043 GetClassNameA(h, class_name, sizeof(class_name));
3044
3045 if (StrCmpi(class_name, "static") == 0)
3046 {
3047 if (SendMsg(h, 0, STM_GETIMAGE, IMAGE_BITMAP, 0) != 0 ||
3048 SendMsg(h, 0, STM_GETIMAGE, IMAGE_ICON, 0) != 0 ||
3049 SendMsg(h, 0, STM_GETICON, 0, 0) != 0)
3050 {
3051 is_image = true;
3052 }
3053 }
3054
3055 // Get the position
3056 if (GetWindowRect(h, ¤t_rect))
3057 {
3058 // Convert to client coordinates
3059 POINT p1, p2;
3060
3061 p1.x = current_rect.left;
3062 p1.y = current_rect.top;
3063
3064 p2.x = current_rect.right;
3065 p2.y = current_rect.bottom;
3066
3067 ScreenToClient(hWndParent, &p1);
3068 ScreenToClient(hWndParent, &p2);
3069
3070 // Adjust the position
3071 AdjustDialogXY(&p1.x, &p1.y, dlgfont_x, dlgfont_y);
3072 AdjustDialogXY(&p2.x, &p2.y, dlgfont_x, dlgfont_y);
3073
3074 if (is_image)
3075 {
3076 p2.x = p1.x + (current_rect.right - current_rect.left);
3077 p2.y = p1.y + (current_rect.bottom - current_rect.top);
3078 }
3079
3080 // Move
3081 MoveWindow(h, p1.x, p1.y, p2.x - p1.x, p2.y - p1.y, false);
3082 }
3083 }
3084
3085 FreeWindowList(o);
3086 }
3087
3088 // Adjust the values of x and y according to the font
AdjustDialogXY(UINT * x,UINT * y,UINT dlgfont_x,UINT dlgfont_y)3089 void AdjustDialogXY(UINT *x, UINT *y, UINT dlgfont_x, UINT dlgfont_y)
3090 {
3091 if (x != NULL)
3092 {
3093 *x = (UINT)(((double)*x) * (double)WINUI_DEFAULT_DIALOG_UNIT_X / (double)dlgfont_x);
3094 }
3095
3096 if (y != NULL)
3097 {
3098 *y = (UINT)(((double)*y) * (double)WINUI_DEFAULT_DIALOG_UNIT_Y / (double)dlgfont_y);
3099 }
3100 }
3101
3102 // Internationalizing process for the dialog box
InitDialogInternational(HWND hWnd,void * pparam)3103 void InitDialogInternational(HWND hWnd, void *pparam)
3104 {
3105 LIST *o;
3106 UINT i;
3107 bool is_managed_dialog = false;
3108 char caption[MAX_PATH];
3109 char *dialog_name;
3110 DIALOG_PARAM *param = (DIALOG_PARAM *)pparam;
3111 HDC hDC;
3112 bool need_resize = false;
3113 double factor_x = 0.0, factor_y = 0.0;
3114 // Validate arguments
3115 if (hWnd == NULL || param == NULL)
3116 {
3117 return;
3118 }
3119
3120 hDC = CreateCompatibleDC(NULL);
3121
3122 AdjustWindowAndControlSize(hWnd, &need_resize, &factor_x, &factor_y);
3123
3124 GetTxtA(hWnd, 0, caption, sizeof(caption));
3125 if (caption[0] == '@')
3126 {
3127 dialog_name = &caption[1];
3128
3129 is_managed_dialog = true;
3130 }
3131
3132 // Enumerate all window handles
3133 o = EnumAllChildWindow(hWnd);
3134
3135 for (i = 0;i < LIST_NUM(o);i++)
3136 {
3137 HWND hControl = *((HWND *)LIST_DATA(o, i));
3138
3139 if (hControl != NULL)
3140 {
3141 bool set_font = true;
3142 HFONT hFont = GetDialogDefaultFontEx(param && ((DIALOG_PARAM *)param)->meiryo);
3143
3144 if (MsIsWine())
3145 {
3146 char classname[MAX_PATH];
3147 char parent_classname[MAX_PATH];
3148 HWND hParent = GetParent(hControl);
3149
3150 Zero(classname, sizeof(classname));
3151 Zero(parent_classname, sizeof(parent_classname));
3152
3153 GetClassNameA(hControl, classname, sizeof(classname));
3154
3155 if (hParent != NULL)
3156 {
3157 GetClassNameA(hParent, parent_classname, sizeof(parent_classname));
3158 }
3159
3160 if (StrCmpi(classname, "edit") == 0)
3161 {
3162 set_font = false;
3163 }
3164
3165 if (StrCmpi(classname, "combobox") == 0)
3166 {
3167 set_font = false;
3168 }
3169
3170 if (StrCmpi(classname, "syslistview32") == 0)
3171 {
3172 set_font = false;
3173 }
3174
3175 if (StrCmpi(classname, "sysheader32") == 0)
3176 {
3177 set_font = false;
3178 }
3179
3180 if (StrCmpi(parent_classname, "SysIPAddress32") == 0 ||
3181 StrCmpi(classname, "SysIPAddress32") == 0)
3182 {
3183 set_font = true;
3184 hFont = GetFont("Tahoma", 8, false, false, false, false);
3185 }
3186 }
3187
3188 if (set_font)
3189 {
3190 SetFont(hControl, 0, hFont);
3191 }
3192
3193 if (MsIsVista())
3194 {
3195 char classname[MAX_PATH];
3196 GetClassNameA(hControl, classname, sizeof(classname));
3197
3198 if (StrCmpi(classname, "syslistview32") == 0)
3199 {
3200 InitVistaWindowTheme(hControl);
3201 }
3202 }
3203
3204 if (is_managed_dialog)
3205 {
3206 char str[MAX_PATH];
3207
3208 GetTxtA(hControl, 0, str, sizeof(str));
3209 if (str[0] == '@')
3210 {
3211 char *control_name = &str[1];
3212 char tmp[MAX_PATH];
3213 wchar_t *ret;
3214
3215 StrCpy(tmp, sizeof(tmp), dialog_name);
3216 StrCat(tmp, sizeof(tmp), "@");
3217
3218 if (hWnd == hControl)
3219 {
3220 StrCat(tmp, sizeof(tmp), "CAPTION");
3221 }
3222 else
3223 {
3224 StrCat(tmp, sizeof(tmp), control_name);
3225 }
3226
3227 ret = _UU(tmp);
3228
3229 if (ret != NULL && UniIsEmptyStr(ret) == false)
3230 {
3231 SetText(hControl, 0, ret);
3232 }
3233 }
3234 }
3235 }
3236 }
3237
3238 FreeWindowList(o);
3239
3240 if (MsIsVista() && need_resize)
3241 {
3242 // Since the window size is changed automatically by the OS by the dpi setting
3243 // in Windows Vista or later, a static (bitmap) control needs to be expanded
3244 // by anticipating the size after changing
3245
3246 // Enumerate all child window (not recursive)
3247 o = EnumAllChildWindowEx(hWnd, true, false, true);
3248
3249 for (i = 0;i < LIST_NUM(o);i++)
3250 {
3251 HWND hControl = *((HWND *)LIST_DATA(o, i));
3252
3253 if (hControl != NULL)
3254 {
3255 char class_name[MAX_SIZE];
3256
3257 Zero(class_name, sizeof(class_name));
3258 GetClassNameA(hControl, class_name, sizeof(class_name));
3259
3260 if (StrCmpi(class_name, "static") == 0)
3261 {
3262 UINT style = GetStyle(hControl, 0);
3263
3264 if (style & SS_BITMAP)
3265 {
3266 // Get the Bitmap
3267 HBITMAP hBitmap = (HBITMAP)SendMessage(hControl, STM_GETIMAGE, IMAGE_BITMAP, 0);
3268
3269 if (hBitmap != NULL)
3270 {
3271 // Get the size of this bitmap
3272 UINT src_x;
3273 UINT src_y;
3274
3275 if (GetBitmapSize(hBitmap, &src_x, &src_y))
3276 {
3277 RECT ctl_rect;
3278
3279 Zero(&ctl_rect, sizeof(ctl_rect));
3280
3281 if (GetWindowRect(hControl, &ctl_rect))
3282 {
3283 // Use the smaller magnification of the height and the width
3284 //double scale_factor = 1.5;
3285 double scale_factor = MIN(factor_x, factor_y);
3286 UINT dst_x = (UINT)((double)src_x * scale_factor);
3287 UINT dst_y = (UINT)((double)src_y * scale_factor);
3288
3289 HBITMAP hDst = ResizeBitmap(hBitmap, src_x, src_y, dst_x, dst_y);
3290
3291 if (hDst != NULL)
3292 {
3293 Add(param->BitmapList, hDst);
3294
3295 SendMessage(hControl, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hDst);
3296 }
3297 }
3298 }
3299 }
3300 }
3301 }
3302 }
3303 }
3304
3305 FreeWindowList(o);
3306 }
3307
3308 DeleteDC(hDC);
3309 }
3310
3311 // Get the size of the bitmap
GetBitmapSize(void * bmp,UINT * x,UINT * y)3312 bool GetBitmapSize(void *bmp, UINT *x, UINT *y)
3313 {
3314 BITMAP info;
3315 // Validate arguments
3316 if (bmp == NULL || x == NULL || y == NULL)
3317 {
3318 return false;
3319 }
3320
3321 Zero(&info, sizeof(info));
3322 if (GetObject((HANDLE)bmp, sizeof(info), &info) == 0)
3323 {
3324 return false;
3325 }
3326
3327 *x = info.bmWidth;
3328 *y = info.bmHeight;
3329
3330 return true;
3331 }
3332
3333 // Resize the bitmap
ResizeBitmap(HBITMAP hSrc,UINT src_x,UINT src_y,UINT dst_x,UINT dst_y)3334 HBITMAP ResizeBitmap(HBITMAP hSrc, UINT src_x, UINT src_y, UINT dst_x, UINT dst_y)
3335 {
3336 HDC hMemDC;
3337 HDC hSrcDC;
3338 HBITMAP ret = NULL;
3339 BITMAPINFOHEADER h;
3340 BITMAPINFO bi;
3341 UCHAR *data = NULL;
3342 // Validate arguments
3343 if (hSrc == NULL)
3344 {
3345 return NULL;
3346 }
3347
3348 hSrcDC = CreateCompatibleDC(NULL);
3349 if (hSrcDC != NULL)
3350 {
3351 HBITMAP hOld = SelectObject(hSrcDC, hSrc);
3352
3353 if (hOld != NULL)
3354 {
3355 hMemDC = CreateCompatibleDC(NULL);
3356
3357 if (hMemDC != NULL)
3358 {
3359 HBITMAP hOld;
3360 HBITMAP srcHbitMap;
3361 UCHAR* srcData;
3362 CT_RectF_c destRect;
3363 CT_RectF_c srcRect;
3364
3365 Zero(&h, sizeof(h));
3366 h.biSize = sizeof(h);
3367 h.biWidth = src_x;
3368 h.biHeight = src_y;
3369 h.biPlanes = 1;
3370 h.biBitCount = 32;
3371 h.biXPelsPerMeter = 2834;
3372 h.biYPelsPerMeter = 2834;
3373 h.biCompression = BI_RGB;
3374
3375 // Copy once the transfer source
3376 Zero(&bi, sizeof(bi));
3377 Copy(&bi.bmiHeader, &h, sizeof(BITMAPINFOHEADER));
3378 srcHbitMap = CreateDIBSection(hMemDC, &bi, DIB_RGB_COLORS, &srcData, NULL, 0);
3379
3380 hOld = SelectObject(hMemDC, srcHbitMap);
3381
3382 BitBlt(hMemDC,0,0,src_x,src_y,hSrcDC,0,0, SRCCOPY);
3383
3384 GdiFlush();
3385
3386
3387
3388 // Generate a resized version
3389 if(src_x != dst_x || src_y != dst_y)
3390 {
3391 h.biWidth = dst_x;
3392 h.biHeight = dst_y;
3393 Zero(&bi, sizeof(bi));
3394 Copy(&bi.bmiHeader, &h, sizeof(BITMAPINFOHEADER));
3395
3396 ret = CreateDIBSection(hMemDC, &bi, DIB_RGB_COLORS, &data, NULL, 0);
3397
3398 if(srcData != NULL && data != NULL)
3399 {
3400 destRect.X = 0; destRect.Y = 0;
3401 destRect.Width = (float)dst_x; destRect.Height = (float)dst_y;
3402 srcRect = destRect;
3403 srcRect.Width = (float)src_x; srcRect.Height = (float)src_y;
3404
3405 CT_DrawImage((UCHAR*)data, destRect, dst_x,dst_y,
3406 (UCHAR*)srcData, srcRect,src_x, src_y);
3407 }
3408
3409 if(srcHbitMap != NULL)
3410 {
3411 DeleteObject(srcHbitMap);
3412 }
3413 }
3414 else
3415 {
3416 ret = srcHbitMap;
3417 }
3418
3419 SelectObject(hMemDC, hOld);
3420
3421 DeleteDC(hMemDC);
3422 }
3423
3424 SelectObject(hSrcDC, hOld);
3425 }
3426
3427 DeleteDC(hSrcDC);
3428 }
3429
3430 return ret;
3431 }
3432
3433 // Initialize the bitmap list
NewBitmapList()3434 LIST *NewBitmapList()
3435 {
3436 LIST *o = NewListFast(NULL);
3437
3438 return o;
3439 }
3440
3441 // Release the bitmap list
FreeBitmapList(LIST * o)3442 void FreeBitmapList(LIST *o)
3443 {
3444 UINT i;
3445 // Validate arguments
3446 if (o == NULL)
3447 {
3448 return;
3449 }
3450
3451 for (i = 0;i < LIST_NUM(o);i++)
3452 {
3453 HBITMAP *h = LIST_DATA(o, i);
3454
3455 DeleteObject(h);
3456 }
3457
3458 ReleaseList(o);
3459 }
3460
3461 // Child window enumeration procedure
3462 // Initialize the dialog
StringDlgInit(HWND hWnd,STRING_DLG * s)3463 void StringDlgInit(HWND hWnd, STRING_DLG *s)
3464 {
3465 // Validate arguments
3466 if (hWnd == NULL || s == NULL)
3467 {
3468 return;
3469 }
3470
3471 SetText(hWnd, E_STRING, s->String);
3472
3473 SetIcon(hWnd, S_ICON, s->Icon);
3474 SetText(hWnd, S_INFO, s->Info);
3475 SetText(hWnd, 0, s->Title);
3476
3477 FocusEx(hWnd, E_STRING);
3478
3479 StringDlgUpdate(hWnd, s);
3480 }
3481
3482 // Update the dialog control
StringDlgUpdate(HWND hWnd,STRING_DLG * s)3483 void StringDlgUpdate(HWND hWnd, STRING_DLG *s)
3484 {
3485 wchar_t *tmp;
3486 bool b = true;
3487 // Validate arguments
3488 if (hWnd == NULL || s == NULL)
3489 {
3490 return;
3491 }
3492
3493 tmp = GetText(hWnd, E_STRING);
3494
3495 if (tmp != NULL)
3496 {
3497 if (s->AllowEmpty == false)
3498 {
3499 if (UniIsEmptyStr(tmp))
3500 {
3501 b = false;
3502 }
3503 }
3504
3505 if (s->AllowUnsafe == false)
3506 {
3507 if (IsSafeUniStr(tmp) == false)
3508 {
3509 b = false;
3510 }
3511 }
3512
3513 Free(tmp);
3514 }
3515
3516 SetEnable(hWnd, IDOK, b);
3517 }
3518
3519 // String dialog procedure
StringDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)3520 UINT StringDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
3521 {
3522 STRING_DLG *s = (STRING_DLG *)param;
3523 // Validate arguments
3524 if (hWnd == NULL)
3525 {
3526 return 0;
3527 }
3528
3529 switch (msg)
3530 {
3531 case WM_INITDIALOG:
3532 StringDlgInit(hWnd, s);
3533 break;
3534
3535 case WM_COMMAND:
3536 switch (LOWORD(wParam))
3537 {
3538 case E_STRING:
3539 StringDlgUpdate(hWnd, s);
3540 break;
3541 }
3542
3543 switch (wParam)
3544 {
3545 case IDOK:
3546 GetTxt(hWnd, E_STRING, s->String, sizeof(s->String));
3547 EndDialog(hWnd, true);
3548 break;
3549
3550 case IDCANCEL:
3551 Close(hWnd);
3552 break;
3553 }
3554 break;
3555
3556 case WM_CLOSE:
3557 EndDialog(hWnd, false);
3558 break;
3559 }
3560
3561 return 0;
3562 }
3563
3564 // Show the string dialog
StringDlg(HWND hWnd,wchar_t * title,wchar_t * info,wchar_t * def,UINT icon,bool allow_empty,bool allow_unsafe)3565 wchar_t *StringDlg(HWND hWnd, wchar_t *title, wchar_t *info, wchar_t *def, UINT icon, bool allow_empty, bool allow_unsafe)
3566 {
3567 STRING_DLG s;
3568 // Validate arguments
3569 if (title == NULL)
3570 {
3571 title = _UU("DLG_STRING_DEFTITLE");
3572 }
3573 if (info == NULL)
3574 {
3575 info = _UU("DLG_STRING_DEFINFO");
3576 }
3577 if (def == NULL)
3578 {
3579 def = L"";
3580 }
3581 if (icon == 0)
3582 {
3583 icon = ICO_NULL;
3584 }
3585
3586 Zero(&s, sizeof(s));
3587 s.Icon = icon;
3588 s.Info = info;
3589 s.Title = title;
3590 s.Icon = icon;
3591 UniStrCpy(s.String, sizeof(s.String), def);
3592 s.AllowEmpty = allow_empty;
3593 s.AllowUnsafe = allow_unsafe;
3594
3595 if (Dialog(hWnd, D_STRING, StringDlgProc, &s) == false)
3596 {
3597 return NULL;
3598 }
3599 else
3600 {
3601 return CopyUniStr(s.String);
3602 }
3603 }
StringDlgA(HWND hWnd,wchar_t * title,wchar_t * info,char * def,UINT icon,bool allow_empty,bool allow_unsafe)3604 char *StringDlgA(HWND hWnd, wchar_t *title, wchar_t *info, char *def, UINT icon, bool allow_empty, bool allow_unsafe)
3605 {
3606 wchar_t unidef[MAX_SIZE];
3607 wchar_t *tmp;
3608 char *ret;
3609 if (def == NULL)
3610 {
3611 def = "";
3612 }
3613
3614 StrToUni(unidef, sizeof(unidef), def);
3615
3616 tmp = StringDlg(hWnd, title, info, unidef, icon, allow_empty, allow_unsafe);
3617 if (tmp == NULL)
3618 {
3619 return NULL;
3620 }
3621
3622 ret = CopyUniToStr(tmp);
3623 Free(tmp);
3624
3625 return ret;
3626 }
3627
3628 // Draw frame
LedDrawRect(LED * d)3629 void LedDrawRect(LED *d)
3630 {
3631 RECT r;
3632 // Validate arguments
3633 if (d == NULL)
3634 {
3635 return;
3636 }
3637
3638 SetRect(&r, 0, 0, LED_WIDTH, LED_HEIGHT);
3639 FrameRect(d->hDC, &r, GetStockObject(WHITE_BRUSH));
3640 }
3641
3642 // Restarting dialog
Win9xRebootDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)3643 UINT Win9xRebootDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
3644 {
3645 WIN9X_REBOOT_DLG *d = (WIN9X_REBOOT_DLG *)param;
3646 UINT64 now;
3647 wchar_t tmp[MAX_PATH];
3648 // Validate arguments
3649 if (hWnd == NULL)
3650 {
3651 return 0;
3652 }
3653
3654 switch (msg)
3655 {
3656 case WM_INITDIALOG:
3657 d->StartTime = Tick64();
3658 SetRange(hWnd, P_PROGRESS, 0, d->TotalTime);
3659 SetTimer(hWnd, 1, 100, NULL);
3660 goto UPDATE;
3661
3662 case WM_TIMER:
3663 switch (wParam)
3664 {
3665 case 1:
3666 UPDATE:
3667 now = Tick64();
3668 if ((d->StartTime + (UINT64)d->TotalTime) <= now)
3669 {
3670 KillTimer(hWnd, 1);
3671 UniStrCpy(tmp, sizeof(tmp), _UU("DLG_REBOOT_INFO_2"));
3672 SetText(hWnd, S_INFO, tmp);
3673 if (MsShutdown(true, false) == false)
3674 {
3675 MsgBox(hWnd, MB_ICONSTOP, _UU("DLG_REBOOT_ERROR"));
3676 }
3677 EndDialog(hWnd, 0);
3678 }
3679 else
3680 {
3681 SetPos(hWnd, P_PROGRESS, (UINT)(now - d->StartTime));
3682 UniFormat(tmp, sizeof(tmp), _UU("DLG_REBOOT_INFO"),
3683 (UINT)((UINT64)d->TotalTime - (now - d->StartTime)) / 1000 + 1);
3684 SetText(hWnd, S_INFO, tmp);
3685 }
3686
3687 break;
3688 }
3689 break;
3690 }
3691 return 0;
3692 }
3693
3694 // Restarting thread
Win9xRebootThread(THREAD * t,void * p)3695 void Win9xRebootThread(THREAD *t, void *p)
3696 {
3697 // Validate arguments
3698 if (t == NULL)
3699 {
3700 return;
3701 }
3702
3703 Win9xReboot(NULL);
3704 }
3705
3706 // Restart automatically
Win9xReboot(HWND hWnd)3707 void Win9xReboot(HWND hWnd)
3708 {
3709 WIN9X_REBOOT_DLG d;
3710
3711 Zero(&d, sizeof(d));
3712 d.TotalTime = 10 * 1000;
3713
3714 Dialog(hWnd, D_WIN9X_REBOOT, Win9xRebootDlgProc, &d);
3715 }
3716
3717 // Show a text file
ShowTextFile(HWND hWnd,char * filename,wchar_t * caption,UINT icon)3718 void ShowTextFile(HWND hWnd, char *filename, wchar_t *caption, UINT icon)
3719 {
3720 BUF *b;
3721 wchar_t *str;
3722 // Validate arguments
3723 if (filename == NULL || caption == NULL)
3724 {
3725 return;
3726 }
3727 if (icon == 0)
3728 {
3729 icon = ICO_NULL;
3730 }
3731
3732 // Read the text file
3733 b = ReadDump(filename);
3734 if (b == NULL)
3735 {
3736 return;
3737 }
3738
3739 SeekBufToEnd(b);
3740 WriteBufChar(b, 0);
3741
3742 str = CopyUtfToUni(b->Buf);
3743
3744 OnceMsg(hWnd, caption, str, false, icon);
3745
3746 FreeBuf(b);
3747 Free(str);
3748 }
3749
3750 // Initialize the version information
AboutDlgInit(HWND hWnd,WINUI_ABOUT * a)3751 void AboutDlgInit(HWND hWnd, WINUI_ABOUT *a)
3752 {
3753 wchar_t tmp[MAX_SIZE];
3754 // Validate arguments
3755 if (hWnd == NULL || a == NULL)
3756 {
3757 return;
3758 }
3759
3760 SetIcon(hWnd, 0, ICO_INFORMATION);
3761
3762 UniFormat(tmp, sizeof(tmp), _UU("ABOUT_CAPTION"), a->ProductName);
3763 SetText(hWnd, 0, tmp);
3764
3765 SetFont(hWnd, S_INFO1, GetFont("Arial", 12, false, false, false, false));
3766 FormatText(hWnd, S_INFO1, CEDAR_VER / 100, CEDAR_VER / 100, CEDAR_VER % 100, CEDAR_BUILD);
3767
3768 SetFont(hWnd, S_INFO2, GetFont("Arial", 8, false, false, false, false));
3769 FormatText(hWnd, S_INFO2, BUILD_DATE_Y, a->Cedar->BuildInfo);
3770
3771 SetFont(hWnd, S_INFO3, GetFont("Arial", 7, false, false, false, false));
3772
3773 if (MsIsWine())
3774 {
3775 Disable(hWnd, B_LANGUAGE);
3776 }
3777
3778 //DlgFont(hWnd, S_INFO4, 8, false);
3779
3780 SetShow(hWnd, B_UPDATE_CONFIG, (a->Update != NULL));
3781
3782 Show(hWnd, B_AUTHORS);
3783 }
3784
3785 // Version information procedure
AboutDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)3786 UINT AboutDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
3787 {
3788 WINUI_ABOUT *a = (WINUI_ABOUT *)param;
3789 char tmp[MAX_PATH];
3790 LANGLIST t;
3791 // Validate arguments
3792 if (hWnd == NULL)
3793 {
3794 return 0;
3795 }
3796
3797 switch (msg)
3798 {
3799 case WM_INITDIALOG:
3800 AboutDlgInit(hWnd, a);
3801 break;
3802
3803 case WM_COMMAND:
3804 switch (wParam)
3805 {
3806 case IDOK:
3807 case IDCANCEL:
3808 if ((GetKeyState(VK_SHIFT) & 0x8000) &&
3809 (GetKeyState(VK_CONTROL) & 0x8000) &&
3810 (GetKeyState(VK_MENU) & 0x8000))
3811 {
3812 ShowEasterEgg(hWnd);
3813 }
3814 EndDialog(hWnd, true);
3815 break;
3816 case B_WEB:
3817 ShellExecute(hWnd, "open", _SS("SE_COMPANY_URL"), NULL, NULL, SW_SHOW);
3818 break;
3819 case B_EULA:
3820 ShowTextFile(hWnd, "|eula.txt", _UU("SW_EULA_TITLE"), ICO_LOG);
3821 break;
3822 case B_IMPORTANT:
3823 GetCurrentLang(&t);
3824 Format(tmp, sizeof(tmp), "|warning_%s.txt", t.Name);
3825 ShowTextFile(hWnd, tmp, _UU("SW_WARNING_TITLE"), ICO_LOG);
3826 break;
3827 case B_LEGAL:
3828 ShowTextFile(hWnd, "|legal.txt", _UU("DLG_ABOUT_LEGAL"), ICO_LOG);
3829 break;
3830 case B_UPDATE_CONFIG:
3831 ConfigUpdateUi(a->Update, hWnd);
3832 break;
3833 case B_AUTHORS:
3834 ShowTextFile(hWnd, "|authors.txt", _UU("DLG_ABOUT_AUTHORS"), ICO_ZURUHAM);
3835 break;
3836 case B_LANGUAGE:
3837 // Language settings
3838 if (true)
3839 {
3840 wchar_t path[MAX_SIZE];
3841
3842 CombinePathW(path, sizeof(path), MsGetExeDirNameW(), L"vpnsetup.exe");
3843
3844 if (IsFileExistsW(path))
3845 {
3846 // with Installer
3847 if (MsExecuteW(path, L"/language:yes") == false)
3848 {
3849 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SW_CHILD_PROCESS_ERROR"));
3850 }
3851 }
3852 else
3853 {
3854 // without Installer
3855 CombinePathW(path, sizeof(path), MsGetExeDirNameW(), L"lang.config");
3856 if (MsExecuteW(path, L"") == false)
3857 {
3858 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("SW_CHILD_PROCESS_ERROR"));
3859 }
3860 }
3861 }
3862 break;
3863 }
3864 break;
3865
3866 case WM_CLOSE:
3867 EndDialog(hWnd, false);
3868 break;
3869 }
3870
3871 return 0;
3872 }
3873
3874 // Version information
About(HWND hWnd,CEDAR * cedar,wchar_t * product_name)3875 void About(HWND hWnd, CEDAR *cedar, wchar_t *product_name)
3876 {
3877 AboutEx(hWnd, cedar, product_name, NULL);
3878 }
AboutEx(HWND hWnd,CEDAR * cedar,wchar_t * product_name,WINUI_UPDATE * u)3879 void AboutEx(HWND hWnd, CEDAR *cedar, wchar_t *product_name, WINUI_UPDATE *u)
3880 {
3881 WINUI_ABOUT a;
3882 // Validate arguments
3883 if (cedar == NULL || product_name == NULL)
3884 {
3885 return;
3886 }
3887
3888 Zero(&a, sizeof(a));
3889 a.Cedar = cedar;
3890 a.ProductName = product_name;
3891 a.Update = u;
3892
3893 Dialog(hWnd, D_ABOUT, AboutDlgProc, &a);
3894 }
3895
3896 // Test
UiTest()3897 void UiTest()
3898 {
3899 }
3900
3901 // Examine the number of fields that an IP address is entered
IpGetFilledNum(HWND hWnd,UINT id)3902 UINT IpGetFilledNum(HWND hWnd, UINT id)
3903 {
3904 UINT ret;
3905 DWORD value;
3906 // Validate arguments
3907 if (hWnd == NULL)
3908 {
3909 return 0;
3910 }
3911
3912 ret = SendMsg(hWnd, id, IPM_GETADDRESS, 0, (LPARAM)&value);
3913
3914 return ret;
3915 }
3916
3917 // Examine whether an IP address has been entered
IpIsFilled(HWND hWnd,UINT id)3918 bool IpIsFilled(HWND hWnd, UINT id)
3919 {
3920 UINT ret;
3921 DWORD value;
3922 // Validate arguments
3923 if (hWnd == NULL)
3924 {
3925 return 0;
3926 }
3927
3928 ret = SendMsg(hWnd, id, IPM_GETADDRESS, 0, (LPARAM)&value);
3929
3930 if (ret != 4)
3931 {
3932 return false;
3933 }
3934 else
3935 {
3936 return true;
3937 }
3938 }
3939
3940 // Clear the IP address
IpClear(HWND hWnd,UINT id)3941 void IpClear(HWND hWnd, UINT id)
3942 {
3943 // Validate arguments
3944 if (hWnd == NULL)
3945 {
3946 return;
3947 }
3948
3949 SendMsg(hWnd, id, IPM_CLEARADDRESS, 0, 0);
3950 }
3951
3952 // Get an IP address
IpGet(HWND hWnd,UINT id)3953 UINT IpGet(HWND hWnd, UINT id)
3954 {
3955 UINT ret;
3956 DWORD value;
3957 // Validate arguments
3958 if (hWnd == NULL)
3959 {
3960 return 0;
3961 }
3962
3963 ret = SendMsg(hWnd, id, IPM_GETADDRESS, 0, (LPARAM)&value);
3964
3965 if (ret != 4)
3966 {
3967 return 0;
3968 }
3969 else
3970 {
3971 return Endian32((UINT)value);
3972 }
3973 }
3974
3975 // Set the IP addresses
IpSet(HWND hWnd,UINT id,UINT ip)3976 void IpSet(HWND hWnd, UINT id, UINT ip)
3977 {
3978 // Validate arguments
3979 if (hWnd == NULL)
3980 {
3981 return;
3982 }
3983
3984 SendMsg(hWnd, id, IPM_SETADDRESS, 0, Endian32(ip));
3985 }
3986
3987 // Write the candidates to the registry
WriteCandidateToReg(UINT root,char * key,LIST * o,char * name)3988 void WriteCandidateToReg(UINT root, char *key, LIST *o, char *name)
3989 {
3990 BUF *b;
3991 // Validate arguments
3992 if (key == NULL || o == NULL || name == NULL)
3993 {
3994 return;
3995 }
3996
3997 b = CandidateToBuf(o);
3998 if (b == NULL)
3999 {
4000 return;
4001 }
4002
4003 MsRegWriteBin(root, key, name, b->Buf, b->Size);
4004
4005 FreeBuf(b);
4006 }
4007
4008 // Read the candidates from the registry
ReadCandidateFromReg(UINT root,char * key,char * name)4009 LIST *ReadCandidateFromReg(UINT root, char *key, char *name)
4010 {
4011 BUF *b;
4012 // Validate arguments
4013 if (key == NULL || name == NULL)
4014 {
4015 return NULL;
4016 }
4017
4018 b = MsRegReadBin(root, key, name);
4019 if (b == NULL)
4020 {
4021 return NewCandidateList();
4022 }
4023 else
4024 {
4025 LIST *o = BufToCandidate(b);
4026 FreeBuf(b);
4027
4028 return o;
4029 }
4030 }
4031
4032 // initialize the remote connection dialog
RemoteDlgInit(HWND hWnd,WINUI_REMOTE * r)4033 void RemoteDlgInit(HWND hWnd, WINUI_REMOTE *r)
4034 {
4035 LIST *o;
4036 UINT i;
4037 // Validate arguments
4038 if (hWnd == NULL || r == NULL)
4039 {
4040 return;
4041 }
4042
4043 SetIcon(hWnd, 0, r->Icon);
4044
4045 SetText(hWnd, 0, r->Caption);
4046 SetText(hWnd, S_TITLE, r->Title);
4047 SetIcon(hWnd, S_ICON, r->Icon);
4048
4049 // Read candidates
4050 o = ReadCandidateFromReg(REG_CURRENT_USER, r->RegKeyName, "RemoteHostCandidate");
4051 r->CandidateList = o;
4052
4053 // Show the candidates
4054 for (i = 0;i < LIST_NUM(o);i++)
4055 {
4056 CANDIDATE *c = LIST_DATA(o, i);
4057 CbAddStr(hWnd, C_HOSTNAME, c->Str, 0);
4058 }
4059
4060 if (r->DefaultHostname != NULL)
4061 {
4062 SetTextA(hWnd, C_HOSTNAME, r->DefaultHostname);
4063 }
4064
4065 FocusEx(hWnd, C_HOSTNAME);
4066
4067 RemoteDlgRefresh(hWnd, r);
4068 }
4069
4070 // Remote connection dialog update
RemoteDlgRefresh(HWND hWnd,WINUI_REMOTE * r)4071 void RemoteDlgRefresh(HWND hWnd, WINUI_REMOTE *r)
4072 {
4073 char *s;
4074 bool ok = true;
4075 bool localhost_mode = false;
4076 // Validate arguments
4077 if (hWnd == NULL || r == NULL)
4078 {
4079 return;
4080 }
4081
4082 s = GetTextA(hWnd, C_HOSTNAME);
4083 if (s != NULL)
4084 {
4085 Trim(s);
4086 if (StrCmpi(s, "localhost") == 0 || StartWith(s, "127."))
4087 {
4088 localhost_mode = true;
4089 }
4090 Free(s);
4091 }
4092
4093 if (localhost_mode == false)
4094 {
4095 Enable(hWnd, C_HOSTNAME);
4096 Enable(hWnd, S_HOSTNAME);
4097 Check(hWnd, R_LOCAL, false);
4098 }
4099 else
4100 {
4101 if (r->Title != _UU("NM_CONNECT_TITLE"))
4102 {
4103 Disable(hWnd, C_HOSTNAME);
4104 Disable(hWnd, S_HOSTNAME);
4105 }
4106 Check(hWnd, R_LOCAL, true);
4107 SetTextA(hWnd, C_HOSTNAME, "localhost");
4108
4109 if (r->flag1 == false)
4110 {
4111 Focus(hWnd, IDOK);
4112 }
4113 }
4114
4115 if (IsEmpty(hWnd, C_HOSTNAME))
4116 {
4117 ok = false;
4118 }
4119
4120 SetEnable(hWnd, IDOK, ok);
4121
4122 r->flag1 = true;
4123 }
4124
4125 // Remote connection dialog OK button
RemoteDlgOnOk(HWND hWnd,WINUI_REMOTE * r)4126 void RemoteDlgOnOk(HWND hWnd, WINUI_REMOTE *r)
4127 {
4128 char *hostname;
4129 wchar_t *s;
4130 LIST *o;
4131 // Validate arguments
4132 if (hWnd == NULL || r == NULL)
4133 {
4134 return;
4135 }
4136
4137 // Get the entered host name
4138 hostname = GetTextA(hWnd, C_HOSTNAME);
4139 if (hostname == NULL)
4140 {
4141 return;
4142 }
4143 Trim(hostname);
4144
4145 // Add a candidate
4146 o = r->CandidateList;
4147 s = CopyStrToUni(hostname);
4148 AddCandidate(o, s, 64);
4149 Free(s);
4150
4151 // Write the candidates
4152 WriteCandidateToReg(REG_CURRENT_USER, r->RegKeyName, o, "RemoteHostCandidate");
4153 FreeCandidateList(o);
4154
4155 r->Hostname = hostname;
4156
4157 EndDialog(hWnd, true);
4158 }
4159
4160 // Remote connection dialog procedure
RemoteDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)4161 UINT RemoteDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
4162 {
4163 WINUI_REMOTE *r = (WINUI_REMOTE *)param;
4164 // Validate arguments
4165 if (hWnd == NULL)
4166 {
4167 return 0;
4168 }
4169
4170 switch (msg)
4171 {
4172 case WM_INITDIALOG:
4173 RemoteDlgInit(hWnd, r);
4174 SetTimer(hWnd, 1, 100, NULL);
4175 break;
4176 case WM_TIMER:
4177 switch (wParam)
4178 {
4179 case 1:
4180 KillTimer(hWnd, 1);
4181 RemoteDlgRefresh(hWnd, r);
4182 SetTimer(hWnd, 1, 100, NULL);
4183 break;
4184 }
4185 break;
4186 case WM_COMMAND:
4187 switch (wParam)
4188 {
4189 case R_LOCAL:
4190 if (IsChecked(hWnd, R_LOCAL) == false)
4191 {
4192 SetTextA(hWnd, C_HOSTNAME, "");
4193 RemoteDlgRefresh(hWnd, r);
4194 FocusEx(hWnd, C_HOSTNAME);
4195 }
4196 else
4197 {
4198 SetTextA(hWnd, C_HOSTNAME, "localhost");
4199 RemoteDlgRefresh(hWnd, r);
4200 Focus(hWnd, IDOK);
4201 }
4202 break;
4203 case IDCANCEL:
4204 Close(hWnd);
4205 break;
4206 case IDOK:
4207 RemoteDlgOnOk(hWnd, r);
4208 break;
4209 }
4210 switch (LOWORD(wParam))
4211 {
4212 case R_LOCAL:
4213 case C_HOSTNAME:
4214 RemoteDlgRefresh(hWnd, r);
4215 break;
4216 }
4217 break;
4218 case WM_CLOSE:
4219 FreeCandidateList(r->CandidateList);
4220 EndDialog(hWnd, false);
4221 break;
4222 }
4223
4224 return 0;
4225 }
4226
4227 // Remote connection dialog
RemoteDlg(HWND hWnd,char * regkey,UINT icon,wchar_t * caption,wchar_t * title,char * default_host)4228 char *RemoteDlg(HWND hWnd, char *regkey, UINT icon, wchar_t *caption, wchar_t *title, char *default_host)
4229 {
4230 WINUI_REMOTE r;
4231 // Validate arguments
4232 if (regkey == NULL)
4233 {
4234 regkey = "Software\\" GC_REG_COMPANY_NAME "\\" CEDAR_PRODUCT_STR " VPN\\WinUI Common Module";
4235 }
4236 if (caption == NULL)
4237 {
4238 caption = _UU("REMOTE_DEF_CAPTION");
4239 }
4240 if (title == NULL)
4241 {
4242 title = _UU("REMOTE_DEF_TITLE");
4243 }
4244 if (icon == 0)
4245 {
4246 icon = ICO_INTERNET;
4247 }
4248
4249 Zero(&r, sizeof(r));
4250 r.RegKeyName = regkey;
4251 r.Caption = caption;
4252 r.Title = title;
4253 r.Icon = icon;
4254 r.DefaultHostname = default_host;
4255
4256 if (Dialog(hWnd, D_REMOTE, RemoteDlgProc, &r) == false)
4257 {
4258 return NULL;
4259 }
4260
4261 return r.Hostname;
4262 }
4263
4264 // Window Searching procedure
SearchWindowEnumProc(HWND hWnd,LPARAM lParam)4265 bool CALLBACK SearchWindowEnumProc(HWND hWnd, LPARAM lParam)
4266 {
4267 if (hWnd != NULL && lParam != 0)
4268 {
4269 wchar_t *s = GetText(hWnd, 0);
4270 SEARCH_WINDOW_PARAM *p = (SEARCH_WINDOW_PARAM *)lParam;
4271 if (s != NULL)
4272 {
4273 if (UniStrCmpi(p->caption, s) == 0)
4274 {
4275 p->hWndFound = hWnd;
4276 }
4277 Free(s);
4278 }
4279 }
4280 return true;
4281 }
4282
4283 // Search for the window
SearchWindow(wchar_t * caption)4284 HWND SearchWindow(wchar_t *caption)
4285 {
4286 SEARCH_WINDOW_PARAM p;
4287 // Validate arguments
4288 if (caption == NULL)
4289 {
4290 return NULL;
4291 }
4292
4293 Zero(&p, sizeof(p));
4294 p.caption = caption;
4295 p.hWndFound = NULL;
4296
4297 EnumWindows(SearchWindowEnumProc, (LPARAM)&p);
4298
4299 return p.hWndFound;
4300 }
4301
4302 // Allow for the specified process to become the foreground window
AllowFGWindow(UINT process_id)4303 void AllowFGWindow(UINT process_id)
4304 {
4305 if (process_id == 0)
4306 {
4307 return;
4308 }
4309
4310 if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType) &&
4311 GET_KETA(GetOsInfo()->OsType, 100) >= 2)
4312 {
4313 AllowSetForegroundWindow(process_id);
4314 }
4315 }
4316
4317 // Rename the item
LvRename(HWND hWnd,UINT id,UINT pos)4318 void LvRename(HWND hWnd, UINT id, UINT pos)
4319 {
4320 // Validate arguments
4321 if (hWnd == NULL || pos == INFINITE)
4322 {
4323 return;
4324 }
4325
4326 ListView_EditLabel(DlgItem(hWnd, id), pos);
4327 }
4328
4329 // Show the menu
PrintMenu(HWND hWnd,HMENU hMenu)4330 void PrintMenu(HWND hWnd, HMENU hMenu)
4331 {
4332 POINT p;
4333 // Validate arguments
4334 if (hMenu == NULL || hWnd == NULL)
4335 {
4336 return;
4337 }
4338
4339 GetCursorPos(&p);
4340
4341 TrackPopupMenu(hMenu, TPM_LEFTALIGN, p.x, p.y, 0, hWnd, NULL);
4342 }
4343
4344 // Remove a shortcut string from the menu
RemoveShortcutKeyStrFromMenu(HMENU hMenu)4345 void RemoveShortcutKeyStrFromMenu(HMENU hMenu)
4346 {
4347 UINT i, num;
4348 // Validate arguments
4349 if (hMenu == NULL)
4350 {
4351 return;
4352 }
4353
4354 num = GetMenuNum(hMenu);
4355 for (i = 0;i < num;i++)
4356 {
4357 wchar_t *str = GetMenuStr(hMenu, i);
4358 if (str != NULL)
4359 {
4360 UINT j, len;
4361 len = UniStrLen(str);
4362 for (j = 0;j < len;j++)
4363 {
4364 if (str[j] == L'\t')
4365 {
4366 str[j] = 0;
4367 }
4368 }
4369 SetMenuStr(hMenu, i, str);
4370 Free(str);
4371 }
4372 }
4373 }
4374
4375 // Get the number of items in the menu
GetMenuNum(HMENU hMenu)4376 UINT GetMenuNum(HMENU hMenu)
4377 {
4378 UINT ret;
4379 // Validate arguments
4380 if (hMenu == NULL)
4381 {
4382 return 0;
4383 }
4384
4385 ret = GetMenuItemCount(hMenu);
4386 if (ret == INFINITE)
4387 {
4388 return 0;
4389 }
4390 else
4391 {
4392 return ret;
4393 }
4394 }
4395
4396 // Set the string into the menu
SetMenuStr(HMENU hMenu,UINT pos,wchar_t * str)4397 void SetMenuStr(HMENU hMenu, UINT pos, wchar_t *str)
4398 {
4399 MENUITEMINFOW info;
4400 // Validate arguments
4401 if (hMenu == NULL || pos == INFINITE || str == NULL)
4402 {
4403 return;
4404 }
4405
4406 if (MsIsNt() == false)
4407 {
4408 char *s = CopyUniToStr(str);
4409 SetMenuStrA(hMenu, pos, s);
4410 Free(s);
4411 return;
4412 }
4413
4414 Zero(&info, sizeof(info));
4415 info.cbSize = sizeof(info);
4416 info.fMask = MIIM_STRING;
4417 info.dwTypeData = str;
4418 SetMenuItemInfoW(hMenu, pos, true, &info);
4419 }
SetMenuStrA(HMENU hMenu,UINT pos,char * str)4420 void SetMenuStrA(HMENU hMenu, UINT pos, char *str)
4421 {
4422 MENUITEMINFOA info;
4423 // Validate arguments
4424 if (hMenu == NULL || pos == INFINITE || str == NULL)
4425 {
4426 return;
4427 }
4428
4429 Zero(&info, sizeof(info));
4430 info.cbSize = sizeof(info);
4431 info.fMask = MIIM_STRING;
4432 info.dwTypeData = str;
4433 SetMenuItemInfoA(hMenu, pos, true, &info);
4434 }
4435
4436 // Get a string in the menu
GetMenuStr(HMENU hMenu,UINT pos)4437 wchar_t *GetMenuStr(HMENU hMenu, UINT pos)
4438 {
4439 wchar_t tmp[MAX_SIZE];
4440 // Validate arguments
4441 if (hMenu == NULL || pos == INFINITE)
4442 {
4443 return NULL;
4444 }
4445 if (MsIsNt() == false)
4446 {
4447 char *s = GetMenuStrA(hMenu, pos);
4448 if (s == NULL)
4449 {
4450 return NULL;
4451 }
4452 else
4453 {
4454 wchar_t *ret = CopyStrToUni(s);
4455 Free(s);
4456 return ret;
4457 }
4458 }
4459
4460 if (GetMenuStringW(hMenu, pos, tmp, sizeof(tmp), MF_BYPOSITION) == 0)
4461 {
4462 return NULL;
4463 }
4464
4465 return UniCopyStr(tmp);
4466 }
GetMenuStrA(HMENU hMenu,UINT pos)4467 char *GetMenuStrA(HMENU hMenu, UINT pos)
4468 {
4469 char tmp[MAX_SIZE];
4470 // Validate arguments
4471 if (hMenu == NULL || pos == INFINITE)
4472 {
4473 return NULL;
4474 }
4475
4476 if (GetMenuString(hMenu, pos, tmp, sizeof(tmp), MF_BYPOSITION) == 0)
4477 {
4478 return NULL;
4479 }
4480
4481 return CopyStr(tmp);
4482 }
4483
4484 // Bold the menu item
SetMenuItemBold(HMENU hMenu,UINT pos,bool bold)4485 void SetMenuItemBold(HMENU hMenu, UINT pos, bool bold)
4486 {
4487 MENUITEMINFO info;
4488 // Validate arguments
4489 if (hMenu == NULL || pos == INFINITE)
4490 {
4491 return;
4492 }
4493
4494 Zero(&info, sizeof(info));
4495 info.cbSize = sizeof(info);
4496 info.fMask = MIIM_STATE;
4497
4498 if (GetMenuItemInfo(hMenu, pos, true, &info) == false)
4499 {
4500 return;
4501 }
4502
4503 if (bold)
4504 {
4505 info.fState |= MFS_DEFAULT;
4506 }
4507 else
4508 {
4509 info.fState = info.fState & ~MFS_DEFAULT;
4510 }
4511
4512 SetMenuItemInfo(hMenu, pos, true, &info);
4513 }
4514
4515 // Enable / disable the menu item
SetMenuItemEnable(HMENU hMenu,UINT pos,bool enable)4516 void SetMenuItemEnable(HMENU hMenu, UINT pos, bool enable)
4517 {
4518 MENUITEMINFO info;
4519 // Validate arguments
4520 if (hMenu == NULL || pos == INFINITE)
4521 {
4522 return;
4523 }
4524
4525 Zero(&info, sizeof(info));
4526 info.cbSize = sizeof(info);
4527 info.fMask = MIIM_STATE;
4528
4529 if (GetMenuItemInfo(hMenu, pos, true, &info) == false)
4530 {
4531 return;
4532 }
4533
4534 if (enable)
4535 {
4536 info.fState |= MFS_ENABLED;
4537 info.fState = info.fState & ~MFS_DISABLED;
4538 }
4539 else
4540 {
4541 info.fState |= MFS_DISABLED;
4542 info.fState = info.fState & ~MFS_ENABLED;
4543 }
4544
4545 SetMenuItemInfo(hMenu, pos, true, &info);
4546 }
4547
4548 // Remove a menu item
DeleteMenuItem(HMENU hMenu,UINT pos)4549 void DeleteMenuItem(HMENU hMenu, UINT pos)
4550 {
4551 // Validate arguments
4552 if (hMenu == NULL || pos == INFINITE)
4553 {
4554 return;
4555 }
4556
4557 DeleteMenu(hMenu, pos, MF_BYPOSITION);
4558 }
4559
4560 // Get the position from the ID in the menu
GetMenuItemPos(HMENU hMenu,UINT id)4561 UINT GetMenuItemPos(HMENU hMenu, UINT id)
4562 {
4563 UINT num, i;
4564 // Validate arguments
4565 if (hMenu == NULL)
4566 {
4567 return INFINITE;
4568 }
4569
4570 num = GetMenuItemCount(hMenu);
4571 if (num == INFINITE)
4572 {
4573 return INFINITE;
4574 }
4575
4576 for (i = 0;i < num;i++)
4577 {
4578 if (GetMenuItemID(hMenu, i) == id)
4579 {
4580 return i;
4581 }
4582 }
4583
4584 return INFINITE;
4585 }
4586
4587 // Get a sub-menu
LoadSubMenu(UINT menu_id,UINT pos,HMENU * parent_menu)4588 HMENU LoadSubMenu(UINT menu_id, UINT pos, HMENU *parent_menu)
4589 {
4590 HMENU h = LoadMenu(hDll, MAKEINTRESOURCE(menu_id));
4591 HMENU ret;
4592 if (h == NULL)
4593 {
4594 return NULL;
4595 }
4596
4597 ret = GetSubMenu(h, pos);
4598
4599 if (parent_menu != NULL)
4600 {
4601 *parent_menu = h;
4602 }
4603
4604 return ret;
4605 }
4606
4607 // Get the DLL of the user interface
GetUiDll()4608 HINSTANCE GetUiDll()
4609 {
4610 return hDll;
4611 }
4612
4613 // Connection Error dialog procedure
ConnectErrorDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)4614 UINT ConnectErrorDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
4615 {
4616 UI_CONNECTERROR_DLG *p = (UI_CONNECTERROR_DLG *)param;
4617 wchar_t tmp[1024];
4618 // Validate arguments
4619 if (hWnd == NULL)
4620 {
4621 return 0;
4622 }
4623
4624 switch (msg)
4625 {
4626 case WM_INITDIALOG:
4627 if (p->Err == ERR_DISCONNECTED || p->Err == ERR_SESSION_TIMEOUT)
4628 {
4629 // Message indicating that the connection has been disconnected
4630 SetText(hWnd, S_TITLE, _UU("ERRDLG_DISCONNECTED_MSG"));
4631 }
4632 if (p->HideWindow)
4633 {
4634 Hide(hWnd, R_HIDE);
4635 }
4636 FormatText(hWnd, 0, p->AccountName);
4637 FormatText(hWnd, S_TITLE, p->ServerName);
4638 UniFormat(tmp, sizeof(tmp), _UU("ERRDLG_ERRMSG"), p->Err, _E(p->Err));
4639 SetText(hWnd, E_ERROR, tmp);
4640
4641 SetIcon(hWnd, 0, ICO_SERVER_OFFLINE);
4642
4643 if (p->RetryIntervalSec == 0)
4644 {
4645 SetText(hWnd, S_COUNTDOWN, _UU("ERRDLG_INFORMATION"));
4646 Hide(hWnd, P_PROGRESS);
4647 Hide(hWnd, S_RETRYINFO);
4648 }
4649 else
4650 {
4651 if (p->RetryLimit != INFINITE)
4652 {
4653 UniFormat(tmp, sizeof(tmp), _UU("ERRDLG_RETRY_INFO_1"), p->CurrentRetryCount, p->RetryLimit);
4654 }
4655 else
4656 {
4657 UniFormat(tmp, sizeof(tmp), _UU("ERRDLG_RETRY_INFO_2"), p->CurrentRetryCount);
4658 }
4659 SetText(hWnd, S_RETRYINFO, tmp);
4660 SetRange(hWnd, P_PROGRESS, 0, p->RetryIntervalSec);
4661 SetPos(hWnd, P_PROGRESS, 0);
4662 SetTimer(hWnd, 1, 10, NULL);
4663 p->StartTick = Tick64();
4664 }
4665 SetTimer(hWnd, 2, 10, NULL);
4666 Focus(hWnd, IDOK);
4667 break;
4668 case WM_TIMER:
4669 switch (wParam)
4670 {
4671 case 1:
4672 if (p->RetryIntervalSec != 0)
4673 {
4674 UINT64 start, end, now;
4675 now = Tick64();
4676 start = p->StartTick;
4677 end = start + (UINT64)p->RetryIntervalSec;
4678
4679 if (end > now)
4680 {
4681 SetPos(hWnd, P_PROGRESS, (UINT)(now - start));
4682 UniFormat(tmp, sizeof(tmp), _UU("ERRDLG_RETRYCOUNT"), ((UINT)(end - now)) / 1000);
4683 SetText(hWnd, S_COUNTDOWN, tmp);
4684 }
4685 else
4686 {
4687 Command(hWnd, IDOK);
4688 }
4689 }
4690 break;
4691 case 2:
4692 if (p->CancelEvent != NULL)
4693 {
4694 if (WaitForSingleObject((HANDLE)p->CancelEvent->pData, 0) != WAIT_TIMEOUT)
4695 {
4696 // Forced Cancel
4697 Close(hWnd);
4698 }
4699 }
4700 break;
4701 }
4702 break;
4703 case WM_COMMAND:
4704 switch (LOWORD(wParam))
4705 {
4706 case R_HIDE:
4707 p->HideWindow = IsChecked(hWnd, R_HIDE);
4708 break;
4709 }
4710 switch (wParam)
4711 {
4712 case IDOK:
4713 EndDialog(hWnd, true);
4714 break;
4715 case IDCANCEL:
4716 Close(hWnd);
4717 break;
4718 }
4719 break;
4720 case WM_CLOSE:
4721 EndDialog(hWnd, false);
4722 break;
4723 }
4724
4725 return 0;
4726 }
4727
4728 // Show the connection error dialog
ConnectErrorDlg(UI_CONNECTERROR_DLG * p)4729 bool ConnectErrorDlg(UI_CONNECTERROR_DLG *p)
4730 {
4731 // Validate arguments
4732 if (p == NULL)
4733 {
4734 return false;
4735 }
4736
4737 return DialogEx2(NULL, D_CONNECTERROR, ConnectErrorDlgProc, p, true, true);
4738 }
4739
4740 // Display the contents of the certificate
PrintCheckCertInfo(HWND hWnd,UI_CHECKCERT * p)4741 void PrintCheckCertInfo(HWND hWnd, UI_CHECKCERT *p)
4742 {
4743 wchar_t tmp[MAX_SIZE];
4744 char tmp2[MAX_SIZE];
4745 UCHAR md5[MD5_SIZE];
4746 UCHAR sha1[SHA1_SIZE];
4747 X *x;
4748 // Validate arguments
4749 if (hWnd == NULL || p == NULL)
4750 {
4751 return;
4752 }
4753
4754 x = p->x;
4755
4756 GetAllNameFromNameEx(tmp, sizeof(tmp), x->subject_name);
4757 SetText(hWnd, E_SUBJECT, tmp);
4758
4759 GetAllNameFromNameEx(tmp, sizeof(tmp), x->issuer_name);
4760 SetText(hWnd, E_ISSUER, tmp);
4761
4762 GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(x->notAfter), NULL);
4763 SetText(hWnd, E_EXPIRES, tmp);
4764
4765 GetXDigest(x, md5, false);
4766 BinToStr(tmp2, sizeof(tmp2), md5, sizeof(md5));
4767 SetTextA(hWnd, E_MD5, tmp2);
4768
4769 GetXDigest(x, sha1, true);
4770 BinToStr(tmp2, sizeof(tmp2), sha1, sizeof(sha1));
4771 SetTextA(hWnd, E_SHA1, tmp2);
4772
4773 SetFont(hWnd, E_MD5, GetFont("Arial", 8, false, false, false, false));
4774 SetFont(hWnd, E_SHA1, GetFont("Arial", 8, false, false, false, false));
4775 }
4776
4777 // Warn that the certificate is different
ShowDlgDiffWarning(HWND hWnd,UI_CHECKCERT * p)4778 void ShowDlgDiffWarning(HWND hWnd, UI_CHECKCERT *p)
4779 {
4780 UCHAR sha1_new[SHA1_SIZE], sha1_old[SHA1_SIZE];
4781 UCHAR md5_new[MD5_SIZE], md5_old[MD5_SIZE];
4782 char sha1_new_str[MAX_SIZE], sha1_old_str[MAX_SIZE];
4783 char md5_new_str[MAX_SIZE], md5_old_str[MAX_SIZE];
4784 // Validate arguments
4785 if (hWnd == NULL || p == NULL || p->x == NULL || p->old_x == NULL)
4786 {
4787 return;
4788 }
4789
4790 GetXDigest(p->x, sha1_new, true);
4791 GetXDigest(p->x, md5_new, false);
4792
4793 GetXDigest(p->old_x, sha1_old, true);
4794 GetXDigest(p->old_x, md5_old, false);
4795
4796 BinToStrEx(sha1_new_str, sizeof(sha1_new_str), sha1_new, sizeof(sha1_new));
4797 BinToStrEx(md5_new_str, sizeof(md5_new_str), md5_new, sizeof(md5_new));
4798 BinToStrEx(sha1_old_str, sizeof(sha1_old_str), sha1_old, sizeof(sha1_old));
4799 BinToStrEx(md5_old_str, sizeof(md5_old_str), md5_old, sizeof(md5_old));
4800
4801 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("CC_DANGEROUS_MSG"),
4802 p->ServerName, md5_old_str, sha1_old_str, md5_new_str, sha1_new_str);
4803 }
4804
4805 // [OK] button is pressed
CheckCertDialogOnOk(HWND hWnd,UI_CHECKCERT * p)4806 void CheckCertDialogOnOk(HWND hWnd, UI_CHECKCERT *p)
4807 {
4808 UCHAR sha1_new[SHA1_SIZE];
4809 UCHAR md5_new[MD5_SIZE];
4810 char sha1_new_str[MAX_SIZE];
4811 char md5_new_str[MAX_SIZE];
4812 UINT ret;
4813 // Validate arguments
4814 if (hWnd == NULL || p == NULL)
4815 {
4816 return;
4817 }
4818
4819 GetXDigest(p->x, sha1_new, true);
4820 GetXDigest(p->x, md5_new, false);
4821 BinToStrEx(sha1_new_str, sizeof(sha1_new_str), sha1_new, sizeof(sha1_new));
4822 BinToStrEx(md5_new_str, sizeof(md5_new_str), md5_new, sizeof(md5_new));
4823
4824 ret = MsgBoxEx(hWnd, MB_ICONQUESTION | MB_YESNOCANCEL | MB_DEFBUTTON2,
4825 _UU("CC_WARNING_MSG"),
4826 p->AccountName, sha1_new_str, md5_new_str);
4827
4828 if (ret == IDYES)
4829 {
4830 p->SaveServerCert = true;
4831 }
4832
4833 if (ret == IDCANCEL)
4834 {
4835 return;
4836 }
4837
4838 p->Ok = true;
4839 EndDialog(hWnd, true);
4840 }
4841
4842 // Certificate dialog procedure
CheckCertDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)4843 UINT CheckCertDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
4844 {
4845 UI_CHECKCERT *p = (UI_CHECKCERT *)param;
4846 // Validate arguments
4847 if (hWnd == NULL || param == NULL)
4848 {
4849 return 0;
4850 }
4851
4852 switch (msg)
4853 {
4854 case WM_INITDIALOG:
4855 FormatText(hWnd, 0, p->AccountName);
4856 FormatText(hWnd, S_TITLE, p->ServerName);
4857 FormatText(hWnd, S_MSG1, p->ServerName);
4858
4859 PrintCheckCertInfo(hWnd, p);
4860
4861 Focus(hWnd, IDCANCEL);
4862
4863 SetIcon(hWnd, 0, ICO_WARNING);
4864
4865 if (p->DiffWarning)
4866 {
4867 SetTimer(hWnd, 1, 1, NULL);
4868 }
4869
4870 SetTimer(hWnd, 2, 100, NULL);
4871
4872 break;
4873 case WM_TIMER:
4874 switch (wParam)
4875 {
4876 case 1:
4877 KillTimer(hWnd, 1);
4878 ShowDlgDiffWarning(hWnd, p);
4879 break;
4880 case 2:
4881 if ((p->Session != NULL && p->Session->Halt) ||
4882 (p->Halt))
4883 {
4884 p->Ok = false;
4885 EndDialog(hWnd, false);
4886 }
4887 break;
4888 }
4889 break;
4890 case WM_COMMAND:
4891 switch (wParam)
4892 {
4893 case B_SHOW:
4894 CertDlg(hWnd, p->x, p->parent_x, false);
4895 break;
4896 case IDOK:
4897 CheckCertDialogOnOk(hWnd, p);
4898 break;
4899 case IDCANCEL:
4900 Close(hWnd);
4901 break;
4902 }
4903 break;
4904 case WM_CLOSE:
4905 p->Ok = false;
4906 EndDialog(hWnd, false);
4907 break;
4908 }
4909
4910 return 0;
4911 }
4912
4913 // Certificate Check dialog
CheckCertDlg(UI_CHECKCERT * p)4914 void CheckCertDlg(UI_CHECKCERT *p)
4915 {
4916 // Validate arguments
4917 if (p == NULL)
4918 {
4919 return;
4920 }
4921
4922 Dialog(NULL, D_CHECKCERT, CheckCertDlgProc, p);
4923 }
4924
4925 // Get the image list ID from the icon ID
GetIcon(UINT icon_id)4926 UINT GetIcon(UINT icon_id)
4927 {
4928 IMAGELIST_ICON *c, t;
4929 t.id = icon_id;
4930
4931 c = Search(icon_list, &t);
4932 if (c == NULL)
4933 {
4934 if (icon_id != ICO_NULL)
4935 {
4936 return GetIcon(ICO_NULL);
4937 }
4938 else
4939 {
4940 return INFINITE;
4941 }
4942 }
4943 else
4944 {
4945 return c->Index;
4946 }
4947 }
4948
4949 // Load an icon for the image list
LoadIconForImageList(UINT id)4950 IMAGELIST_ICON *LoadIconForImageList(UINT id)
4951 {
4952 IMAGELIST_ICON *ret = ZeroMalloc(sizeof(IMAGELIST_ICON));
4953 HICON small_icon, large_icon;
4954
4955 ret->id = id;
4956
4957 large_icon = LoadLargeIcon(id);
4958 if (large_icon == NULL)
4959 {
4960 large_icon = LoadSmallIcon(id);
4961 }
4962
4963 small_icon = LoadSmallIcon(id);
4964 if (small_icon == NULL)
4965 {
4966 small_icon = LoadLargeIcon(id);
4967 }
4968
4969 ret->hSmallImage = small_icon;
4970 ret->hLargeImage = large_icon;
4971 ret->Index = ImageList_AddIcon(large_image_list, large_icon);
4972 ImageList_AddIcon(small_image_list, small_icon);
4973
4974 return ret;
4975 }
4976
4977 // Comparison of the image list icons
CompareImageListIcon(void * p1,void * p2)4978 int CompareImageListIcon(void *p1, void *p2)
4979 {
4980 IMAGELIST_ICON *c1, *c2;
4981 if (p1 == NULL || p2 == NULL)
4982 {
4983 return 0;
4984 }
4985 c1 = *(IMAGELIST_ICON **)p1;
4986 c2 = *(IMAGELIST_ICON **)p2;
4987 if (c1 == NULL || c2 == NULL)
4988 {
4989 return 0;
4990 }
4991
4992 if (c1->id > c2->id)
4993 {
4994 return 1;
4995 }
4996 else if (c1->id < c2->id)
4997 {
4998 return -1;
4999 }
5000 else
5001 {
5002 return 0;
5003 }
5004 }
5005
5006 // Initialize thr image list
InitImageList()5007 void InitImageList()
5008 {
5009 large_image_list = ImageList_Create(32, 32, ILC_COLOR32 | ILC_MASK, 1, 0);
5010 ImageList_SetBkColor(large_image_list, RGB(255, 255, 255));
5011 small_image_list = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 1, 0);
5012 ImageList_SetBkColor(small_image_list, RGB(255, 255, 255));
5013 icon_list = NewList(CompareImageListIcon);
5014
5015 // Enumeration
5016 EnumResourceNames(hDll, RT_GROUP_ICON, EnumResNameProc, 0);
5017 }
5018
5019 // Icon resource enumeration procedure
EnumResNameProc(HMODULE hModule,LPCTSTR lpszType,LPTSTR lpszName,LONG_PTR lParam)5020 BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam)
5021 {
5022 if (IS_INTRESOURCE(lpszName))
5023 {
5024 UINT icon_id = (UINT)lpszName;
5025 IMAGELIST_ICON *img = LoadIconForImageList(icon_id);
5026
5027 Add(icon_list, img);
5028 }
5029
5030 return TRUE;
5031 }
5032
5033 // Release the image list
FreeImageList()5034 void FreeImageList()
5035 {
5036 UINT i;
5037 ImageList_Destroy(large_image_list);
5038 ImageList_Destroy(small_image_list);
5039 large_image_list = small_image_list = NULL;
5040
5041 for (i = 0;i < LIST_NUM(icon_list);i++)
5042 {
5043 IMAGELIST_ICON *c = LIST_DATA(icon_list, i);
5044 Free(c);
5045 }
5046
5047 ReleaseList(icon_list);
5048 icon_list = NULL;
5049 }
5050
5051 // Get the width of the column of the list view
LvGetColumnWidth(HWND hWnd,UINT id,UINT index)5052 UINT LvGetColumnWidth(HWND hWnd, UINT id, UINT index)
5053 {
5054 return (UINT)((double)ListView_GetColumnWidth(DlgItem(hWnd, id), index) / GetTextScalingFactor());
5055 }
5056
5057 // Insert the column into the list view
LvInsertColumn(HWND hWnd,UINT id,UINT index,wchar_t * str,UINT width)5058 void LvInsertColumn(HWND hWnd, UINT id, UINT index, wchar_t *str, UINT width)
5059 {
5060 LVCOLUMNW c;
5061 // Validate arguments
5062 if (hWnd == NULL || str == NULL)
5063 {
5064 return;
5065 }
5066
5067 width = (UINT)((double)width * GetTextScalingFactor());
5068
5069 Zero(&c, sizeof(c));
5070 c.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
5071
5072 c.pszText = str;
5073 c.iSubItem = index;
5074 c.cx = width;
5075
5076 SendMsg(hWnd, id, LVM_INSERTCOLUMNW, index, (LPARAM)&c);
5077 }
5078
5079 // Remove all items from list view
LvReset(HWND hWnd,UINT id)5080 void LvReset(HWND hWnd, UINT id)
5081 {
5082 // Validate arguments
5083 if (hWnd == NULL)
5084 {
5085 return;
5086 }
5087
5088 ListView_DeleteAllItems(DlgItem(hWnd, id));
5089 }
5090
5091 // Initialize the list view
LvInitEx(HWND hWnd,UINT id,bool no_image)5092 void LvInitEx(HWND hWnd, UINT id, bool no_image)
5093 {
5094 LvInitEx2(hWnd, id, no_image, false);
5095 }
LvInitEx2(HWND hWnd,UINT id,bool no_image,bool large_icon)5096 void LvInitEx2(HWND hWnd, UINT id, bool no_image, bool large_icon)
5097 {
5098 // Validate arguments
5099 if (hWnd == NULL)
5100 {
5101 return;
5102 }
5103
5104 ListView_SetUnicodeFormat(DlgItem(hWnd, id), true);
5105
5106 if (no_image == false)
5107 {
5108 ListView_SetImageList(DlgItem(hWnd, id), large_image_list, LVSIL_NORMAL);
5109 ListView_SetImageList(DlgItem(hWnd, id), large_icon ? large_image_list : small_image_list, LVSIL_SMALL);
5110 }
5111
5112 ListView_SetExtendedListViewStyle(DlgItem(hWnd, id), LVS_EX_FULLROWSELECT);
5113
5114 if (MsIsVista())
5115 {
5116 LvSetStyle(hWnd, id, LVS_EX_DOUBLEBUFFER);
5117 }
5118 }
LvInit(HWND hWnd,UINT id)5119 void LvInit(HWND hWnd, UINT id)
5120 {
5121 LvInitEx(hWnd, id, false);
5122 }
5123
5124 // Adding batch complete (high-speed)
LvInsertEnd(LVB * b,HWND hWnd,UINT id)5125 void LvInsertEnd(LVB *b, HWND hWnd, UINT id)
5126 {
5127 LvInsertEndEx(b, hWnd, id, false);
5128 }
LvInsertEndEx(LVB * b,HWND hWnd,UINT id,bool force_reset)5129 void LvInsertEndEx(LVB *b, HWND hWnd, UINT id, bool force_reset)
5130 {
5131 UINT i, num;
5132 LIST *new_list, *exist_list;
5133 wchar_t *last_selected = NULL;
5134 // Validate arguments
5135 if (b == NULL || hWnd == NULL)
5136 {
5137 return;
5138 }
5139
5140 new_list = NewListFast(CompareUniStr);
5141
5142 for (i = 0;i < LIST_NUM(b->ItemList);i++)
5143 {
5144 LVB_ITEM *t = LIST_DATA(b->ItemList, i);
5145 Add(new_list, t->Strings[0]);
5146 }
5147
5148 Sort(new_list);
5149
5150 if ((LIST_NUM(b->ItemList) >= LV_INSERT_RESET_ALL_ITEM_MIN) || force_reset)
5151 {
5152 last_selected = LvGetFocusedStr(hWnd, id, 0);
5153 LvReset(hWnd, id);
5154 }
5155
5156 exist_list = NewListFast(CompareUniStr);
5157
5158 num = LvNum(hWnd, id);
5159
5160 // Delete the items which isn't contained in the batch list of existing items
5161 for (i = 0;i < num;i++)
5162 {
5163 bool exists = false;
5164 wchar_t *s = LvGetStr(hWnd, id, i, 0);
5165 if (Search(new_list, s) != NULL)
5166 {
5167 exists = true;
5168 }
5169 if (exists == false)
5170 {
5171 // Remove items that don't exist in the batch list of the adding plan from the list view
5172 LvDeleteItem(hWnd, id, i);
5173 num = LvNum(hWnd, id);
5174 i--;
5175 Free(s);
5176 }
5177 else
5178 {
5179 Add(exist_list, s);
5180 }
5181 }
5182
5183 Sort(exist_list);
5184
5185 // Add items in the batch one by one
5186 for (i = 0;i < LIST_NUM(b->ItemList);i++)
5187 {
5188 LVB_ITEM *t = LIST_DATA(b->ItemList, i);
5189 UINT index;
5190 UINT j;
5191 bool exists = false;
5192
5193 if (Search(exist_list, t->Strings[0]) != NULL)
5194 {
5195 index = LvSearchStr(hWnd, id, 0, t->Strings[0]);
5196 }
5197 else
5198 {
5199 index = INFINITE;
5200 }
5201
5202 if (index != INFINITE)
5203 {
5204 UINT j;
5205 // If an item with the string same to adding item already exists,
5206 // update instead of adding
5207 for (j = 0;j < t->NumStrings;j++)
5208 {
5209 LvSetItem(hWnd, id, index, j, t->Strings[j]);
5210 }
5211 LvSetItemImageByImageListId(hWnd, id, index, t->Image);
5212 LvSetItemParam(hWnd, id, index, t->Param);
5213 }
5214 else
5215 {
5216 // Add newly
5217 UINT index = INFINITE;
5218 UINT j;
5219 for (j = 0;j < t->NumStrings;j++)
5220 {
5221 if (j == 0)
5222 {
5223 index = LvInsertItemByImageListId(hWnd, id, t->Image, t->Param, t->Strings[j]);
5224 }
5225 else
5226 {
5227 LvSetItem(hWnd, id, index, j, t->Strings[j]);
5228 }
5229 }
5230 }
5231
5232 // Release the memory
5233 for (j = 0;j < t->NumStrings;j++)
5234 {
5235 Free(t->Strings[j]);
5236 }
5237 Free(t->Strings);
5238 Free(t);
5239 }
5240
5241 // Release the list
5242 ReleaseList(b->ItemList);
5243
5244 // Release the memory
5245 Free(b);
5246
5247 ReleaseList(new_list);
5248
5249 for (i = 0;i < LIST_NUM(exist_list);i++)
5250 {
5251 Free(LIST_DATA(exist_list, i));
5252 }
5253 ReleaseList(exist_list);
5254
5255 if (last_selected != NULL)
5256 {
5257 UINT pos = LvSearchStr(hWnd, id, 0, last_selected);
5258
5259 if (pos != INFINITE)
5260 {
5261 LvSelect(hWnd, id, pos);
5262 }
5263
5264 Free(last_selected);
5265 }
5266 }
5267
5268 // Get the number of columns of the list view
LvGetColumnNum(HWND hWnd,UINT id)5269 UINT LvGetColumnNum(HWND hWnd, UINT id)
5270 {
5271 UINT i;
5272 LVCOLUMN c;
5273 if (hWnd == NULL)
5274 {
5275 return 0;
5276 }
5277
5278 for (i = 0;;i++)
5279 {
5280 Zero(&c, sizeof(c));
5281 c.mask = LVCF_SUBITEM;
5282 if (ListView_GetColumn(DlgItem(hWnd, id), i, &c) == false)
5283 {
5284 break;
5285 }
5286 }
5287
5288 return i;
5289 }
5290
5291 // List-view sort function
LvSortProc(LPARAM param1,LPARAM param2,LPARAM sort_param)5292 int CALLBACK LvSortProc(LPARAM param1, LPARAM param2, LPARAM sort_param)
5293 {
5294 WINUI_LV_SORT *sort = (WINUI_LV_SORT *)sort_param;
5295 HWND hWnd;
5296 UINT id;
5297 UINT i1, i2;
5298 int ret = 0;
5299 wchar_t *s1, *s2;
5300 if (sort == NULL)
5301 {
5302 return 0;
5303 }
5304
5305 hWnd = sort->hWnd;
5306 id = sort->id;
5307
5308 if (hWnd == NULL)
5309 {
5310 return 0;
5311 }
5312
5313 i1 = (UINT)param1;
5314 i2 = (UINT)param2;
5315
5316 s1 = LvGetStr(hWnd, id, i1, sort->subitem);
5317 if (s1 == NULL)
5318 {
5319 return 0;
5320 }
5321
5322 s2 = LvGetStr(hWnd, id, i2, sort->subitem);
5323 if (s2 == NULL)
5324 {
5325 Free(s1);
5326 return 0;
5327 }
5328
5329 if (sort->numeric == false)
5330 {
5331 if (UniStrCmpi(s1, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(s1, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(s1, _UU("CM_VGC_LINK")) == 0)
5332 {
5333 ret = -1;
5334 }
5335 else if (UniStrCmpi(s2, _UU("CM_NEW_ICON")) == 0 || UniStrCmpi(s2, _UU("CM_VGC_ICON")) == 0 || UniStrCmpi(s1, _UU("CM_VGC_LINK")) == 0)
5336 {
5337 ret = 1;
5338 }
5339 else
5340 {
5341 ret = UniStrCmpi(s1, s2);
5342 }
5343 }
5344 else
5345 {
5346 UINT64 v1, v2;
5347 v1 = UniToInt64(s1);
5348 v2 = UniToInt64(s2);
5349 if (v1 > v2)
5350 {
5351 ret = 1;
5352 }
5353 else if (v1 < v2)
5354 {
5355 ret = -1;
5356 }
5357 else
5358 {
5359 ret = 0;
5360 }
5361 }
5362
5363 Free(s1);
5364 Free(s2);
5365
5366 if (sort->desc)
5367 {
5368 ret = -ret;
5369 }
5370
5371 return ret;
5372 }
5373
5374 // Standard handler
LvStandardHandler(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,UINT id)5375 void LvStandardHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT id)
5376 {
5377 NMHDR *n;
5378 NMLVKEYDOWN *key;
5379 // Validate arguments
5380 if (hWnd == NULL)
5381 {
5382 return;
5383 }
5384
5385 LvSortHander(hWnd, msg, wParam, lParam, id);
5386
5387 switch (msg)
5388 {
5389 case WM_NOTIFY:
5390 n = (NMHDR *)lParam;
5391 if (n->idFrom == id)
5392 {
5393 switch (n->code)
5394 {
5395 case NM_DBLCLK:
5396 Command(hWnd, IDOK);
5397 break;
5398 case LVN_KEYDOWN:
5399 key = (NMLVKEYDOWN *)n;
5400 if (key != NULL)
5401 {
5402 UINT code = key->wVKey;
5403 switch (code)
5404 {
5405 case VK_DELETE:
5406 Command(hWnd, B_DELETE);
5407 break;
5408
5409 case VK_RETURN:
5410 Command(hWnd, IDOK);
5411 break;
5412
5413 case VK_F5:
5414 Command(hWnd, B_REFRESH);
5415 break;
5416 }
5417 }
5418 break;
5419 }
5420 }
5421 break;
5422 }
5423 }
5424
5425 // Sort header handler
LvSortHander(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,UINT id)5426 void LvSortHander(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT id)
5427 {
5428 NMHDR *nmhdr;
5429 UINT subitem;
5430 bool desc;
5431 // Validate arguments
5432 if (hWnd == NULL)
5433 {
5434 return;
5435 }
5436
5437 switch (msg)
5438 {
5439 case WM_NOTIFY:
5440 nmhdr = (NMHDR *)lParam;
5441
5442 if (nmhdr != NULL)
5443 {
5444 if (nmhdr->idFrom == id)
5445 {
5446 NMLISTVIEW *v;
5447 switch (nmhdr->code)
5448 {
5449 case LVN_COLUMNCLICK:
5450 desc = false;
5451 v = (NMLISTVIEW *)lParam;
5452 subitem = v->iSubItem;
5453
5454 if ((GetStyle(hWnd, id) & LVS_SORTDESCENDING) == 0)
5455 {
5456 desc = true;
5457 SetStyle(hWnd, id, LVS_SORTDESCENDING);
5458 RemoveStyle(hWnd, id, LVS_SORTASCENDING);
5459 }
5460 else
5461 {
5462 SetStyle(hWnd, id, LVS_SORTASCENDING);
5463 RemoveStyle(hWnd, id, LVS_SORTDESCENDING);
5464 }
5465
5466 LvSort(hWnd, id, subitem, desc);
5467 break;
5468 }
5469 }
5470 }
5471 break;
5472 }
5473 }
5474
5475 // Do sort
LvSort(HWND hWnd,UINT id,UINT subitem,bool desc)5476 void LvSort(HWND hWnd, UINT id, UINT subitem, bool desc)
5477 {
5478 UINT i, num;
5479 bool numeric = true;
5480 wchar_t na[2] = {0xff0d, 0x0, };
5481 // Validate arguments
5482 if (hWnd == NULL)
5483 {
5484 return;
5485 }
5486
5487 num = LvNum(hWnd, id);
5488 for (i = 0;i < num;i++)
5489 {
5490 wchar_t *s = LvGetStr(hWnd, id, i, subitem);
5491 if (s != NULL)
5492 {
5493 if (UniIsNum(s) == false && UniStrCmp(s, na) != 0)
5494 {
5495 numeric = false;
5496 Free(s);
5497 break;
5498 }
5499 Free(s);
5500 }
5501 else
5502 {
5503 numeric = false;
5504 break;
5505 }
5506 }
5507
5508 LvSortEx(hWnd, id, subitem, desc, numeric);
5509 }
5510
LvSortEx(HWND hWnd,UINT id,UINT subitem,bool desc,bool numeric)5511 void LvSortEx(HWND hWnd, UINT id, UINT subitem, bool desc, bool numeric)
5512 {
5513 WINUI_LV_SORT s;
5514 // Validate arguments
5515 if (hWnd == NULL)
5516 {
5517 return;
5518 }
5519 if (subitem >= LvGetColumnNum(hWnd, id))
5520 {
5521 return;
5522 }
5523
5524 Zero(&s, sizeof(s));
5525 s.desc = desc;
5526 s.numeric = numeric;
5527 s.id = id;
5528 s.hWnd = hWnd;
5529 s.subitem = subitem;
5530
5531 ListView_SortItemsEx(DlgItem(hWnd, id), LvSortProc, (LPARAM)&s);
5532 }
5533
5534 // Add an item to adding batch
LvInsertAdd(LVB * b,UINT icon,void * param,UINT num_str,...)5535 void LvInsertAdd(LVB *b, UINT icon, void *param, UINT num_str, ...)
5536 {
5537 UINT i;
5538 va_list va;
5539 UINT index = 0;
5540 LVB_ITEM *t;
5541 // Validate arguments
5542 if (b == NULL || num_str == 0)
5543 {
5544 return;
5545 }
5546
5547 t = ZeroMalloc(sizeof(LVB_ITEM));
5548
5549 va_start(va, num_str);
5550
5551 t->Strings = (wchar_t **)ZeroMalloc(sizeof(wchar_t *) * num_str);
5552 t->NumStrings = num_str;
5553
5554 for (i = 0;i < num_str;i++)
5555 {
5556 wchar_t *s = va_arg(va, wchar_t *);
5557
5558 t->Strings[i] = UniCopyStr(s);
5559 }
5560
5561 t->Param = param;
5562 t->Image = GetIcon(icon);
5563
5564 Add(b->ItemList, t);
5565
5566 va_end(va);
5567 }
5568
5569 // Start the item adding batch
LvInsertStart()5570 LVB *LvInsertStart()
5571 {
5572 LVB *b = ZeroMalloc(sizeof(LVB));
5573 b->ItemList = NewListFast(NULL);
5574
5575 return b;
5576 }
5577
5578 // Add items to the list view
LvInsert(HWND hWnd,UINT id,UINT icon,void * param,UINT num_str,...)5579 void LvInsert(HWND hWnd, UINT id, UINT icon, void *param, UINT num_str, ...)
5580 {
5581 UINT i;
5582 va_list va;
5583 UINT index = 0;
5584 // Validate arguments
5585 if (hWnd == NULL)
5586 {
5587 return;
5588 }
5589
5590 va_start(va, num_str);
5591
5592 for (i = 0;i < num_str;i++)
5593 {
5594 wchar_t *s = va_arg(va, wchar_t *);
5595 if (i == 0)
5596 {
5597 index = LvInsertItem(hWnd, id, icon, param, s);
5598 }
5599 else
5600 {
5601 LvSetItem(hWnd, id, index, i, s);
5602 }
5603 }
5604
5605 va_end(va);
5606 }
5607
5608 // Adjust the item size automatically
LvAutoSize(HWND hWnd,UINT id)5609 void LvAutoSize(HWND hWnd, UINT id)
5610 {
5611 UINT i;
5612 // Validate arguments
5613 if (hWnd == NULL)
5614 {
5615 return;
5616 }
5617
5618 i = 0;
5619 while (true)
5620 {
5621 if (ListView_SetColumnWidth(DlgItem(hWnd, id), i, LVSCW_AUTOSIZE) == false)
5622 {
5623 break;
5624 }
5625 i++;
5626 }
5627 }
5628
5629 // Add an item
LvInsertItem(HWND hWnd,UINT id,UINT icon,void * param,wchar_t * str)5630 UINT LvInsertItem(HWND hWnd, UINT id, UINT icon, void *param, wchar_t *str)
5631 {
5632 return LvInsertItemByImageListId(hWnd, id, GetIcon(icon), param, str);
5633 }
LvInsertItemByImageListId(HWND hWnd,UINT id,UINT image,void * param,wchar_t * str)5634 UINT LvInsertItemByImageListId(HWND hWnd, UINT id, UINT image, void *param, wchar_t *str)
5635 {
5636 LVITEMW t;
5637 // Validate arguments
5638 if (hWnd == NULL || str == NULL)
5639 {
5640 return INFINITE;
5641 }
5642 if (MsIsNt() == false)
5643 {
5644 char *s = CopyUniToStr(str);
5645 UINT ret;
5646 ret = LvInsertItemByImageListIdA(hWnd, id, image, param, s);
5647 Free(s);
5648 return ret;
5649 }
5650
5651 Zero(&t, sizeof(t));
5652 t.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_TEXT;
5653 t.pszText = str;
5654 t.iImage = image;
5655 t.lParam = (LPARAM)param;
5656 t.iItem = LvNum(hWnd, id);
5657
5658 return SendMsg(hWnd, id, LVM_INSERTITEMW, 0, (LPARAM)&t);
5659 }
LvInsertItemByImageListIdA(HWND hWnd,UINT id,UINT image,void * param,char * str)5660 UINT LvInsertItemByImageListIdA(HWND hWnd, UINT id, UINT image, void *param, char *str)
5661 {
5662 LVITEM t;
5663 // Validate arguments
5664 if (hWnd == NULL || str == NULL)
5665 {
5666 return INFINITE;
5667 }
5668
5669 Zero(&t, sizeof(t));
5670 t.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_TEXT;
5671 t.pszText = str;
5672 t.iImage = image;
5673 t.lParam = (LPARAM)param;
5674 t.iItem = LvNum(hWnd, id);
5675
5676 return SendMsg(hWnd, id, LVM_INSERTITEM, 0, (LPARAM)&t);
5677 }
5678
5679 // Change the image
LvSetItemImage(HWND hWnd,UINT id,UINT index,UINT icon)5680 void LvSetItemImage(HWND hWnd, UINT id, UINT index, UINT icon)
5681 {
5682 LvSetItemImageByImageListId(hWnd, id, index, GetIcon(icon));
5683 }
LvSetItemImageByImageListId(HWND hWnd,UINT id,UINT index,UINT image)5684 void LvSetItemImageByImageListId(HWND hWnd, UINT id, UINT index, UINT image)
5685 {
5686 LVITEM t;
5687 // Validate arguments
5688 if (hWnd == NULL)
5689 {
5690 return;
5691 }
5692
5693 Zero(&t, sizeof(t));
5694 t.mask = LVIF_IMAGE;
5695 t.iImage = image;
5696 t.iItem = index;
5697
5698 SendMsg(hWnd, id, LVM_SETITEM, 0, (LPARAM)&t);
5699 }
5700
5701 // Set the parameters of the item
LvSetItemParam(HWND hWnd,UINT id,UINT index,void * param)5702 void LvSetItemParam(HWND hWnd, UINT id, UINT index, void *param)
5703 {
5704 LvSetItemParamEx(hWnd, id, index, 0, param);
5705 }
LvSetItemParamEx(HWND hWnd,UINT id,UINT index,UINT subitem,void * param)5706 void LvSetItemParamEx(HWND hWnd, UINT id, UINT index, UINT subitem, void *param)
5707 {
5708 LVITEM t;
5709 // Validate arguments
5710 if (hWnd == NULL)
5711 {
5712 return;
5713 }
5714
5715 Zero(&t, sizeof(t));
5716 t.mask = LVIF_PARAM;
5717 t.iItem = index;
5718 t.iSubItem = subitem;
5719 t.lParam = (LPARAM)param;
5720
5721 SendMsg(hWnd, id, LVM_SETITEM, 0, (LPARAM)&t);
5722 }
5723
5724 // Set the item
LvSetItem(HWND hWnd,UINT id,UINT index,UINT pos,wchar_t * str)5725 void LvSetItem(HWND hWnd, UINT id, UINT index, UINT pos, wchar_t *str)
5726 {
5727 LVITEMW t;
5728 wchar_t *old_str;
5729 // Validate arguments
5730 if (hWnd == NULL || str == NULL)
5731 {
5732 return;
5733 }
5734 if (MsIsNt() == false)
5735 {
5736 char *s = CopyUniToStr(str);
5737 LvSetItemA(hWnd, id, index, pos, s);
5738 Free(s);
5739 return;
5740 }
5741
5742 Zero(&t, sizeof(t));
5743 t.mask = LVIF_TEXT;
5744 t.pszText = str;
5745 t.iItem = index;
5746 t.iSubItem = pos;
5747
5748 old_str = LvGetStr(hWnd, id, index, pos);
5749
5750 if (UniStrCmp(old_str, str) != 0)
5751 {
5752 SendMsg(hWnd, id, LVM_SETITEMW, 0, (LPARAM)&t);
5753 }
5754
5755 Free(old_str);
5756 }
LvSetItemA(HWND hWnd,UINT id,UINT index,UINT pos,char * str)5757 void LvSetItemA(HWND hWnd, UINT id, UINT index, UINT pos, char *str)
5758 {
5759 LVITEM t;
5760 wchar_t *old_str;
5761 char *old_str_2;
5762 // Validate arguments
5763 if (hWnd == NULL || str == NULL)
5764 {
5765 return;
5766 }
5767
5768 Zero(&t, sizeof(t));
5769 t.mask = LVIF_TEXT;
5770 t.pszText = str;
5771 t.iItem = index;
5772 t.iSubItem = pos;
5773
5774 old_str = LvGetStr(hWnd, id, index, pos);
5775 old_str_2 = CopyUniToStr(old_str);
5776
5777 if (StrCmp(old_str_2, str) != 0)
5778 {
5779 SendMsg(hWnd, id, LVM_SETITEM, 0, (LPARAM)&t);
5780 }
5781
5782 Free(old_str_2);
5783 Free(old_str);
5784 }
5785
5786 // Set the view of the list box
LvSetView(HWND hWnd,UINT id,bool details)5787 void LvSetView(HWND hWnd, UINT id, bool details)
5788 {
5789 // Validate arguments
5790 if (hWnd == NULL)
5791 {
5792 return;
5793 }
5794
5795 if (details)
5796 {
5797 RemoveStyle(hWnd, id, LVS_ICON);
5798 SetStyle(hWnd, id, LVS_REPORT);
5799 }
5800 else
5801 {
5802 RemoveStyle(hWnd, id, LVS_REPORT);
5803 SetStyle(hWnd, id, LVS_ICON);
5804 }
5805 }
5806
5807 // Ensure that the specified item is visible
LvShow(HWND hWnd,UINT id,UINT index)5808 void LvShow(HWND hWnd, UINT id, UINT index)
5809 {
5810 // Validate arguments
5811 if (hWnd == NULL)
5812 {
5813 return;
5814 }
5815
5816 ListView_EnsureVisible(DlgItem(hWnd, id), index, false);
5817 }
5818
5819 // Get whether there is currently selected item
LvIsSelected(HWND hWnd,UINT id)5820 bool LvIsSelected(HWND hWnd, UINT id)
5821 {
5822 // Validate arguments
5823 if (hWnd == NULL)
5824 {
5825 return false;
5826 }
5827
5828 if (LvGetSelected(hWnd, id) == INFINITE)
5829 {
5830 return false;
5831 }
5832
5833 return true;
5834 }
5835
5836 // Get the currently selected item
LvGetFocused(HWND hWnd,UINT id)5837 UINT LvGetFocused(HWND hWnd, UINT id)
5838 {
5839 // Validate arguments
5840 if (hWnd == NULL)
5841 {
5842 return INFINITE;
5843 }
5844
5845 return ListView_GetNextItem(DlgItem(hWnd, id), -1, LVNI_FOCUSED);
5846 }
5847
5848 // Get the parameter of the currently selected item
LvGetSelectedParam(HWND hWnd,UINT id)5849 void *LvGetSelectedParam(HWND hWnd, UINT id)
5850 {
5851 UINT index;
5852 // Validate arguments
5853 if (hWnd == NULL)
5854 {
5855 return NULL;
5856 }
5857
5858 index = LvGetSelected(hWnd, id);
5859
5860 if (index == INFINITE)
5861 {
5862 return NULL;
5863 }
5864
5865 return LvGetParam(hWnd, id, index);
5866 }
5867
5868 // Get a string that is currently selected
LvGetFocusedStr(HWND hWnd,UINT id,UINT pos)5869 wchar_t *LvGetFocusedStr(HWND hWnd, UINT id, UINT pos)
5870 {
5871 UINT i;
5872 // Validate arguments
5873 if (hWnd == NULL)
5874 {
5875 return NULL;
5876 }
5877
5878 i = LvGetFocused(hWnd, id);
5879 if (i == INFINITE)
5880 {
5881 return NULL;
5882 }
5883
5884 return LvGetStr(hWnd, id, i, pos);
5885 }
5886
5887 // Get the currently selected item
LvGetSelected(HWND hWnd,UINT id)5888 UINT LvGetSelected(HWND hWnd, UINT id)
5889 {
5890 // Validate arguments
5891 if (hWnd == NULL)
5892 {
5893 return INFINITE;
5894 }
5895
5896 return ListView_GetNextItem(DlgItem(hWnd, id), -1, LVNI_FOCUSED | LVNI_SELECTED);
5897 }
5898
5899 // Get a string that is currently selected
LvGetSelectedStr(HWND hWnd,UINT id,UINT pos)5900 wchar_t *LvGetSelectedStr(HWND hWnd, UINT id, UINT pos)
5901 {
5902 UINT i;
5903 // Validate arguments
5904 if (hWnd == NULL)
5905 {
5906 return NULL;
5907 }
5908
5909 i = LvGetSelected(hWnd, id);
5910 if (i == INFINITE)
5911 {
5912 return NULL;
5913 }
5914
5915 return LvGetStr(hWnd, id, i, pos);
5916 }
LvGetSelectedStrA(HWND hWnd,UINT id,UINT pos)5917 char *LvGetSelectedStrA(HWND hWnd, UINT id, UINT pos)
5918 {
5919 char *ret;
5920 wchar_t *tmp = LvGetSelectedStr(hWnd, id, pos);
5921 if (tmp == NULL)
5922 {
5923 return NULL;
5924 }
5925 ret = CopyUniToStr(tmp);
5926 Free(tmp);
5927 return ret;
5928 }
5929
5930 // Get whether two or more items are masked
LvIsMultiMasked(HWND hWnd,UINT id)5931 bool LvIsMultiMasked(HWND hWnd, UINT id)
5932 {
5933 UINT i;
5934 // Validate arguments
5935 if (hWnd == NULL)
5936 {
5937 return false;
5938 }
5939
5940 i = INFINITE;
5941 i = LvGetNextMasked(hWnd, id, i);
5942 if (i != INFINITE)
5943 {
5944 if (LvGetNextMasked(hWnd, id, i) != INFINITE)
5945 {
5946 return true;
5947 }
5948 }
5949
5950 return false;
5951 }
5952
5953 // Examine whether just only one item is selected
LvIsSingleSelected(HWND hWnd,UINT id)5954 bool LvIsSingleSelected(HWND hWnd, UINT id)
5955 {
5956 return LvIsSelected(hWnd, id) && (LvIsMultiMasked(hWnd, id) == false);
5957 }
5958
5959 // Get whether there are items that are currently masked
LvIsMasked(HWND hWnd,UINT id)5960 bool LvIsMasked(HWND hWnd, UINT id)
5961 {
5962 // Validate arguments
5963 if (hWnd == NULL)
5964 {
5965 return false;
5966 }
5967
5968 if (LvGetNextMasked(hWnd, id, INFINITE) == INFINITE)
5969 {
5970 return false;
5971 }
5972
5973 return true;
5974 }
5975
5976 // Get the number of items that are currently masked
LvGetMaskedNum(HWND hWnd,UINT id)5977 UINT LvGetMaskedNum(HWND hWnd, UINT id)
5978 {
5979 UINT i = INFINITE;
5980 UINT num = 0;
5981 // Validate arguments
5982 if (hWnd == NULL)
5983 {
5984 return 0;
5985 }
5986
5987 while (true)
5988 {
5989 i = LvGetNextMasked(hWnd, id, i);
5990 if (i == INFINITE)
5991 {
5992 break;
5993 }
5994
5995 num++;
5996 }
5997
5998 return num;
5999 }
6000
6001 // Get the items that is currently masked
LvGetNextMasked(HWND hWnd,UINT id,UINT start)6002 UINT LvGetNextMasked(HWND hWnd, UINT id, UINT start)
6003 {
6004 // Validate arguments
6005 if (hWnd == NULL)
6006 {
6007 return INFINITE;
6008 }
6009
6010 return ListView_GetNextItem(DlgItem(hWnd, id), start, LVNI_SELECTED);
6011 }
6012
6013 // Search an item with the specified string
LvSearchStr_(HWND hWnd,UINT id,UINT pos,wchar_t * str)6014 UINT LvSearchStr_(HWND hWnd, UINT id, UINT pos, wchar_t *str)
6015 {
6016 UINT ret;
6017 LVFINDINFOW t;
6018 // Validate arguments
6019 if (hWnd == NULL || str == NULL)
6020 {
6021 return INFINITE;
6022 }
6023
6024 Zero(&t, sizeof(t));
6025 t.flags = LVFI_STRING;
6026 t.psz = str;
6027 t.vkDirection = VK_DOWN;
6028
6029 ret = SendMsg(hWnd, id, LVM_FINDITEMW, -1, (LPARAM)&t);
6030
6031 return ret;
6032 }
6033
6034 // Search an item with the specified string
LvSearchStr(HWND hWnd,UINT id,UINT pos,wchar_t * str)6035 UINT LvSearchStr(HWND hWnd, UINT id, UINT pos, wchar_t *str)
6036 {
6037 UINT i, num;
6038 // Validate arguments
6039 if (hWnd == NULL || str == NULL)
6040 {
6041 return INFINITE;
6042 }
6043
6044 num = LvNum(hWnd, id);
6045
6046 for (i = 0;i < num;i++)
6047 {
6048 wchar_t *s = LvGetStr(hWnd, id, i, pos);
6049 if (s != NULL)
6050 {
6051 if (UniStrCmpi(s, str) == 0)
6052 {
6053 Free(s);
6054 return i;
6055 }
6056 else
6057 {
6058 Free(s);
6059 }
6060 }
6061 }
6062
6063 return INFINITE;
6064 }
LvSearchStrA(HWND hWnd,UINT id,UINT pos,char * str)6065 UINT LvSearchStrA(HWND hWnd, UINT id, UINT pos, char *str)
6066 {
6067 wchar_t *tmp = CopyStrToUni(str);
6068 UINT ret = LvSearchStr(hWnd, id, pos, tmp);
6069 Free(tmp);
6070 return ret;
6071 }
6072
6073 // Search for item that have a specified param
LvSearchParam(HWND hWnd,UINT id,void * param)6074 UINT LvSearchParam(HWND hWnd, UINT id, void *param)
6075 {
6076 UINT i, num;
6077 // Validate arguments
6078 if (hWnd == NULL)
6079 {
6080 return INFINITE;
6081 }
6082
6083 num = LvNum(hWnd, id);
6084
6085 for (i = 0;i < num;i++)
6086 {
6087 if (LvGetParam(hWnd, id, i) == param)
6088 {
6089 return i;
6090 }
6091 }
6092
6093 return INFINITE;
6094 }
6095
6096 // Get the number of items
LvNum(HWND hWnd,UINT id)6097 UINT LvNum(HWND hWnd, UINT id)
6098 {
6099 // Validate arguments
6100 if (hWnd == NULL)
6101 {
6102 return 0;
6103 }
6104
6105 return ListView_GetItemCount(DlgItem(hWnd, id));
6106 }
6107
6108 // Remove an item
LvDeleteItem(HWND hWnd,UINT id,UINT index)6109 void LvDeleteItem(HWND hWnd, UINT id, UINT index)
6110 {
6111 UINT i;
6112 // Validate arguments
6113 if (hWnd == NULL)
6114 {
6115 return;
6116 }
6117
6118 ListView_DeleteItem(DlgItem(hWnd, id), index);
6119
6120 i = LvGetSelected(hWnd, id);
6121 if (i != INFINITE)
6122 {
6123 LvSelect(hWnd, id, i);
6124 }
6125 }
6126
6127 // Get the data from the item
LvGetParam(HWND hWnd,UINT id,UINT index)6128 void *LvGetParam(HWND hWnd, UINT id, UINT index)
6129 {
6130 return LvGetParamEx(hWnd, id, index, 0);
6131 }
LvGetParamEx(HWND hWnd,UINT id,UINT index,UINT subitem)6132 void *LvGetParamEx(HWND hWnd, UINT id, UINT index, UINT subitem)
6133 {
6134 LVITEM t;
6135 // Validate arguments
6136 if (hWnd == NULL)
6137 {
6138 return NULL;
6139 }
6140 if (index == INFINITE)
6141 {
6142 return NULL;
6143 }
6144
6145 Zero(&t, sizeof(t));
6146 t.mask = LVIF_PARAM;
6147 t.iItem = index;
6148 t.iSubItem = subitem;
6149
6150 if (ListView_GetItem(DlgItem(hWnd, id), &t) == false)
6151 {
6152 return NULL;
6153 }
6154
6155 return (void *)t.lParam;
6156 }
6157
6158 // Get the string of item
LvGetStr(HWND hWnd,UINT id,UINT index,UINT pos)6159 wchar_t *LvGetStr(HWND hWnd, UINT id, UINT index, UINT pos)
6160 {
6161 wchar_t *tmp;
6162 UINT size;
6163 LVITEMW t;
6164 // Validate arguments
6165 if (hWnd == NULL)
6166 {
6167 return NULL;
6168 }
6169 if (MsIsNt() == false)
6170 {
6171 char *s = LvGetStrA(hWnd, id, index, pos);
6172 if (s == NULL)
6173 {
6174 return NULL;
6175 }
6176 else
6177 {
6178 wchar_t *ret = CopyStrToUni(s);
6179 Free(s);
6180
6181 return ret;
6182 }
6183 }
6184
6185 size = 65536;
6186 tmp = Malloc(size);
6187
6188 Zero(&t, sizeof(t));
6189 t.mask = LVIF_TEXT;
6190 t.iItem = index;
6191 t.iSubItem = pos;
6192 t.pszText = tmp;
6193 t.cchTextMax = size;
6194
6195 if (SendMsg(hWnd, id, LVM_GETITEMTEXTW, index, (LPARAM)&t) <= 0)
6196 {
6197 Free(tmp);
6198 return UniCopyStr(L"");
6199 }
6200 else
6201 {
6202 wchar_t *ret = UniCopyStr(tmp);
6203 Free(tmp);
6204 return ret;
6205 }
6206 }
LvGetStrA(HWND hWnd,UINT id,UINT index,UINT pos)6207 char *LvGetStrA(HWND hWnd, UINT id, UINT index, UINT pos)
6208 {
6209 char *tmp;
6210 UINT size;
6211 LVITEM t;
6212 // Validate arguments
6213 if (hWnd == NULL)
6214 {
6215 return NULL;
6216 }
6217
6218 size = 65536;
6219 tmp = Malloc(size);
6220
6221 Zero(&t, sizeof(t));
6222 t.mask = LVIF_TEXT;
6223 t.iItem = index;
6224 t.iSubItem = pos;
6225 t.pszText = tmp;
6226 t.cchTextMax = size;
6227
6228 if (SendMsg(hWnd, id, LVM_GETITEMTEXT, index, (LPARAM)&t) <= 0)
6229 {
6230 Free(tmp);
6231 return CopyStr("");
6232 }
6233 else
6234 {
6235 char *ret = CopyStr(tmp);
6236 Free(tmp);
6237 return ret;
6238 }
6239 }
6240
6241 // Set the style
LvSetStyle(HWND hWnd,UINT id,UINT style)6242 void LvSetStyle(HWND hWnd, UINT id, UINT style)
6243 {
6244 // Validate arguments
6245 if (hWnd == NULL)
6246 {
6247 return;
6248 }
6249
6250 if ((ListView_GetExtendedListViewStyle(DlgItem(hWnd, id)) & style) == 0)
6251 {
6252 ListView_SetExtendedListViewStyleEx(DlgItem(hWnd, id), style, style);
6253 }
6254 }
6255
6256 // Remove the style
LvRemoveStyle(HWND hWnd,UINT id,UINT style)6257 void LvRemoveStyle(HWND hWnd, UINT id, UINT style)
6258 {
6259 // Validate arguments
6260 if (hWnd == NULL)
6261 {
6262 return;
6263 }
6264
6265 if ((ListView_GetExtendedListViewStyle(DlgItem(hWnd, id)) & style) != 0)
6266 {
6267 ListView_SetExtendedListViewStyleEx(DlgItem(hWnd, id), style, 0);
6268 }
6269 }
6270
6271 // Invert the selection of items
LvSwitchSelect(HWND hWnd,UINT id)6272 void LvSwitchSelect(HWND hWnd, UINT id)
6273 {
6274 UINT i, num;
6275 bool *states;
6276 // Validate arguments
6277 if (hWnd == NULL)
6278 {
6279 return;
6280 }
6281
6282 num = LvNum(hWnd, id);
6283 states = ZeroMalloc(sizeof(bool) * num);
6284
6285 i = INFINITE;
6286 while (true)
6287 {
6288 i = LvGetNextMasked(hWnd, id, i);
6289 if (i == INFINITE)
6290 {
6291 break;
6292 }
6293
6294 states[i] = true;
6295 }
6296
6297 for (i = 0;i < num;i++)
6298 {
6299 if (states[i] == false)
6300 {
6301 ListView_SetItemState(DlgItem(hWnd, id), i, LVIS_SELECTED, LVIS_SELECTED);
6302 }
6303 else
6304 {
6305 ListView_SetItemState(DlgItem(hWnd, id), i, 0, LVIS_SELECTED);
6306 }
6307 }
6308
6309 Free(states);
6310 }
6311
6312 // Select all items
LvSelectAll(HWND hWnd,UINT id)6313 void LvSelectAll(HWND hWnd, UINT id)
6314 {
6315 UINT i, num;
6316 // Validate arguments
6317 if (hWnd == NULL)
6318 {
6319 return;
6320 }
6321
6322 num = LvNum(hWnd, id);
6323 for (i = 0;i < num;i++)
6324 {
6325 ListView_SetItemState(DlgItem(hWnd, id), i, LVIS_SELECTED, LVIS_SELECTED);
6326 }
6327 }
6328
6329 // Select the item by specifying the parameter
LvSelectByParam(HWND hWnd,UINT id,void * param)6330 void LvSelectByParam(HWND hWnd, UINT id, void *param)
6331 {
6332 UINT index;
6333 // Validate arguments
6334 if (hWnd == NULL || param == NULL)
6335 {
6336 return;
6337 }
6338
6339 index = LvSearchParam(hWnd, id, param);
6340 if (index == INFINITE)
6341 {
6342 return;
6343 }
6344
6345 LvSelect(hWnd, id, index);
6346 }
6347
6348 // Select an item
LvSelect(HWND hWnd,UINT id,UINT index)6349 void LvSelect(HWND hWnd, UINT id, UINT index)
6350 {
6351 // Validate arguments
6352 if (hWnd == NULL)
6353 {
6354 return;
6355 }
6356
6357 if (index == INFINITE)
6358 {
6359 UINT i, num;
6360 // Deselect all
6361 num = LvNum(hWnd, id);
6362 for (i = 0;i < num;i++)
6363 {
6364 ListView_SetItemState(DlgItem(hWnd, id), i, 0, LVIS_SELECTED);
6365 }
6366 }
6367 else
6368 {
6369 // Select
6370 ListView_SetItemState(DlgItem(hWnd, id), index, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
6371 ListView_EnsureVisible(DlgItem(hWnd, id), index, true);
6372 }
6373 }
6374
6375 // Show the certificate information
PrintCertInfo(HWND hWnd,CERT_DLG * p)6376 void PrintCertInfo(HWND hWnd, CERT_DLG *p)
6377 {
6378 X *x;
6379 char *serial_tmp;
6380 UINT serial_size;
6381 wchar_t *wchar_tmp;
6382 wchar_t tmp[1024 * 5];
6383 UCHAR md5[MD5_SIZE];
6384 UCHAR sha1[SHA1_SIZE];
6385 char *s_tmp;
6386 K *k;
6387 // Validate arguments
6388 if (p == NULL || hWnd == NULL)
6389 {
6390 return;
6391 }
6392
6393 x = p->x;
6394
6395 // Serial number
6396 if (x->serial != NULL)
6397 {
6398 serial_size = x->serial->size * 3 + 1;
6399 serial_tmp = ZeroMalloc(serial_size);
6400 BinToStrEx(serial_tmp, serial_size, x->serial->data, x->serial->size);
6401 wchar_tmp = CopyStrToUni(serial_tmp);
6402 Free(serial_tmp);
6403 }
6404 else
6405 {
6406 wchar_tmp = CopyUniStr(_UU("CERT_NO_SERIAL"));
6407 }
6408 LvInsert(hWnd, L_CERTINFO, ICO_CERT, NULL, 2, _UU("CERT_SERIAL"), wchar_tmp);
6409
6410 // Issuer
6411 GetAllNameFromName(tmp, sizeof(tmp), x->issuer_name);
6412 LvInsert(hWnd, L_CERTINFO, ICO_CERT, NULL, 2, _UU("CERT_ISSUER"), tmp);
6413
6414 // Subject
6415 GetAllNameFromName(tmp, sizeof(tmp), x->subject_name);
6416 LvInsert(hWnd, L_CERTINFO, ICO_CERT, NULL, 2, _UU("CERT_SUBJECT"), tmp);
6417
6418 // Not available before
6419 GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(x->notBefore), NULL);
6420 LvInsert(hWnd, L_CERTINFO, ICO_CERT, NULL, 2, _UU("CERT_NOT_BEFORE"), tmp);
6421
6422 // Not available after
6423 GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(x->notAfter), NULL);
6424 LvInsert(hWnd, L_CERTINFO, ICO_CERT, NULL, 2, _UU("CERT_NOT_AFTER"), tmp);
6425
6426 // Number of bits
6427 if (x->is_compatible_bit)
6428 {
6429 UniFormat(tmp, sizeof(tmp), _UU("CERT_BITS_FORMAT"), x->bits);
6430 LvInsert(hWnd, L_CERTINFO, ICO_CERT, NULL, 2, _UU("CERT_BITS"), tmp);
6431 }
6432
6433 // Public key
6434 k = GetKFromX(x);
6435 if (k != NULL)
6436 {
6437 BUF *b = KToBuf(k, false, NULL);
6438 s_tmp = CopyBinToStrEx(b->Buf, b->Size);
6439 StrToUni(tmp, sizeof(tmp), s_tmp);
6440 Free(s_tmp);
6441 LvInsert(hWnd, L_CERTINFO, ICO_KEY, NULL, 2, _UU("CERT_PUBLIC_KEY"), tmp);
6442 FreeBuf(b);
6443 }
6444 FreeK(k);
6445
6446 GetXDigest(x, md5, false);
6447 GetXDigest(x, sha1, true);
6448
6449 // Digest (MD5)
6450 s_tmp = CopyBinToStrEx(md5, sizeof(md5));
6451 StrToUni(tmp, sizeof(tmp), s_tmp);
6452 Free(s_tmp);
6453 LvInsert(hWnd, L_CERTINFO, ICO_KEY, NULL, 2, _UU("CERT_DIGEST_MD5"), tmp);
6454
6455 // Digest (SHA-1)
6456 s_tmp = CopyBinToStrEx(sha1, sizeof(sha1));
6457 StrToUni(tmp, sizeof(tmp), s_tmp);
6458 Free(s_tmp);
6459 LvInsert(hWnd, L_CERTINFO, ICO_KEY, NULL, 2, _UU("CERT_DIGEST_SHA1"), tmp);
6460
6461 Free(wchar_tmp);
6462
6463 LvSelect(hWnd, L_CERTINFO, 0);
6464 }
6465
6466 // Update the display
CertDlgUpdate(HWND hWnd,CERT_DLG * p)6467 void CertDlgUpdate(HWND hWnd, CERT_DLG *p)
6468 {
6469 // Validate arguments
6470 if (hWnd == NULL || p == NULL)
6471 {
6472 return;
6473 }
6474
6475 if (LvIsSelected(hWnd, L_CERTINFO) == false)
6476 {
6477 SetText(hWnd, E_DETAIL, L"");
6478 }
6479 else
6480 {
6481 UINT i = LvGetSelected(hWnd, L_CERTINFO);
6482 wchar_t *tmp = LvGetStr(hWnd, L_CERTINFO, i, 1);
6483 SetText(hWnd, E_DETAIL, tmp);
6484 Free(tmp);
6485 }
6486 }
6487
6488 // Save the certificate
CertDlgSave(HWND hWnd,CERT_DLG * p)6489 void CertDlgSave(HWND hWnd, CERT_DLG *p)
6490 {
6491 wchar_t *name;
6492 X *x;
6493 // Validate arguments
6494 if (hWnd == NULL || p == NULL)
6495 {
6496 return;
6497 }
6498
6499 // Save to a file
6500 name = SaveDlg(hWnd, _UU("DLG_CERT_FILES"), _UU("DLG_SAVE_CERT"), NULL, L".cer");
6501 x = p->x;
6502 if (name != NULL)
6503 {
6504 wchar_t str[MAX_SIZE];
6505 UniStrCpy(str, sizeof(str), name);
6506 if (XToFileW(x, str, true))
6507 {
6508 MsgBox(hWnd, MB_ICONINFORMATION, _UU("DLG_CERT_SAVE_OK"));
6509 }
6510 else
6511 {
6512 MsgBox(hWnd, MB_ICONSTOP, _UU("DLG_CERT_SAVE_ERROR"));
6513 }
6514 Free(name);
6515 }
6516 }
6517
6518 // Certificate display dialog procedure
CertDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)6519 UINT CertDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
6520 {
6521 CERT_DLG *p = (CERT_DLG *)param;
6522 X *x;
6523 wchar_t tmp[MAX_SIZE];
6524 NMHDR *n;
6525 // Validate arguments
6526 if (hWnd == NULL)
6527 {
6528 return 0;
6529 }
6530
6531 switch (msg)
6532 {
6533 case WM_INITDIALOG:
6534 SetIcon(hWnd, 0, ICO_CERT);
6535 x = p->x;
6536 GetAllNameFromNameEx(tmp, sizeof(tmp), x->subject_name);
6537 SetText(hWnd, E_SUBJECT, tmp);
6538 GetAllNameFromNameEx(tmp, sizeof(tmp), x->issuer_name);
6539 SetText(hWnd, E_ISSUER, tmp);
6540 GetDateStrEx64(tmp, sizeof(tmp), SystemToLocal64(x->notAfter), NULL);
6541 SetText(hWnd, E_EXPIRES, tmp);
6542 SetFont(hWnd, E_SUBJECT, Font(0, 1));
6543 SetFont(hWnd, E_ISSUER, Font(0, 1));
6544 SetFont(hWnd, E_EXPIRES, Font(0, 1));
6545 SetIcon(hWnd, B_PARENT, ICO_CERT);
6546 if (x->root_cert)
6547 {
6548 // Root certificate
6549 Hide(hWnd, S_WARNING_ICON);
6550 SetText(hWnd, S_PARENT, _UU("CERT_ROOT"));
6551 Hide(hWnd, B_PARENT);
6552 Hide(hWnd, S_PARENT_BUTTON_STR);
6553 }
6554 else if (p->issuer_x != NULL)
6555 {
6556 // Parent certificate exists
6557 Hide(hWnd, S_WARNING_ICON);
6558 }
6559 else
6560 {
6561 // There is no parent certificate
6562 Hide(hWnd, S_CERT_ICON);
6563 Hide(hWnd, B_PARENT);
6564 Hide(hWnd, S_PARENT_BUTTON_STR);
6565 SetText(hWnd, S_PARENT, _UU("CERT_NOT_FOUND"));
6566 if (p->ManagerMode)
6567 {
6568 Hide(hWnd, IDC_STATIC1);
6569 Hide(hWnd, S_PARENT);
6570 Hide(hWnd, S_WARNING_ICON);
6571 Hide(hWnd, S_CERT_ICON);
6572 Hide(hWnd, B_PARENT);
6573 Hide(hWnd, S_PARENT_BUTTON_STR);
6574 }
6575 }
6576
6577
6578 LvInit(hWnd, L_CERTINFO);
6579 LvInsertColumn(hWnd, L_CERTINFO, 0, _UU("CERT_LV_C1"), 130);
6580 LvInsertColumn(hWnd, L_CERTINFO, 1, _UU("CERT_LV_C2"), 250);
6581
6582 PrintCertInfo(hWnd, p);
6583 Focus(hWnd, L_CERTINFO);
6584
6585 CertDlgUpdate(hWnd, p);
6586
6587 if (p->ManagerMode)
6588 {
6589 Show(hWnd, B_SAVE);
6590 }
6591 else
6592 {
6593 // Hide for security
6594 Hide(hWnd, B_SAVE);
6595 }
6596
6597 break;
6598 case WM_COMMAND:
6599 switch (wParam)
6600 {
6601 case IDOK:
6602 case IDCANCEL:
6603 Close(hWnd);
6604 break;
6605 case B_PARENT:
6606 CertDlg(hWnd, p->issuer_x, NULL, p->ManagerMode);
6607 break;
6608 case B_SAVE:
6609 // Save to the file
6610 CertDlgSave(hWnd, p);
6611 break;
6612 }
6613 break;
6614 case WM_CLOSE:
6615 EndDialog(hWnd, false);
6616 break;
6617 case WM_NOTIFY:
6618 n = (NMHDR *)lParam;
6619 switch (n->idFrom)
6620 {
6621 case L_CERTINFO:
6622 switch (n->code)
6623 {
6624 case LVN_ITEMCHANGED:
6625 CertDlgUpdate(hWnd, p);
6626 break;
6627 }
6628 break;
6629 }
6630 break;
6631 }
6632
6633 LvSortHander(hWnd, msg, wParam, lParam, L_CERTINFO);
6634
6635 return 0;
6636 }
6637
6638 // Certificate display dialog
CertDlg(HWND hWnd,X * x,X * issuer_x,bool manager)6639 void CertDlg(HWND hWnd, X *x, X *issuer_x, bool manager)
6640 {
6641 CERT_DLG p;
6642 // Validate arguments
6643 if (x == NULL)
6644 {
6645 return;
6646 }
6647
6648 Zero(&p, sizeof(p));
6649 p.x = x;
6650 if (CompareX(x, issuer_x) == false)
6651 {
6652 p.issuer_x = issuer_x;
6653 }
6654 p.ManagerMode = manager;
6655 Dialog(hWnd, D_CERT, CertDlgProc, &p);
6656 }
6657
6658 // Status window dialog
StatusPrinterWindowDlg(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)6659 UINT StatusPrinterWindowDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
6660 {
6661 STATUS_WINDOW_PARAM *p = (STATUS_WINDOW_PARAM *)param;
6662 PACK *pack;
6663 // Validate arguments
6664 if (hWnd == NULL)
6665 {
6666 return 0;
6667 }
6668
6669 switch (msg)
6670 {
6671 case WM_INITDIALOG:
6672 // Initialize
6673 SetIcon(hWnd, 0, ICO_SERVER_ONLINE);
6674 RemoveExStyle(hWnd, 0, WS_EX_APPWINDOW);
6675 p->hWnd = hWnd;
6676 NoticeThreadInit(p->Thread);
6677 FormatText(hWnd, 0, p->AccountName);
6678 break;
6679
6680 case WM_COMMAND:
6681 switch (wParam)
6682 {
6683 case IDOK:
6684 case IDCANCEL:
6685 // Cancel button
6686 Close(hWnd);
6687 break;
6688 }
6689
6690 break;
6691
6692 case WM_APP + 1:
6693 // Set a string
6694 SetText(hWnd, S_STATUS, (wchar_t *)lParam);
6695 break;
6696
6697 case WM_APP + 2:
6698 // Close this window
6699 EndDialog(hWnd, false);
6700 break;
6701
6702 case WM_CLOSE:
6703 // End the session
6704 pack = NewPack();
6705 SendPack(p->Sock, pack);
6706 EndDialog(hWnd, false);
6707 break;
6708 }
6709
6710 return 0;
6711 }
6712
6713 // Status window control thread
StatusPrinterWindowThread(THREAD * thread,void * param)6714 void StatusPrinterWindowThread(THREAD *thread, void *param)
6715 {
6716 STATUS_WINDOW_PARAM *p = (STATUS_WINDOW_PARAM *)param;
6717 // Validate arguments
6718 if (thread == NULL || param == NULL)
6719 {
6720 return;
6721 }
6722
6723 p->Thread = thread;
6724 DialogEx2(NULL, D_STATUS, StatusPrinterWindowDlg, p, true, true);
6725
6726 Free(p);
6727 }
6728
6729 // Show a message in the status window
StatusPrinterWindowPrint(STATUS_WINDOW * sw,wchar_t * str)6730 void StatusPrinterWindowPrint(STATUS_WINDOW *sw, wchar_t *str)
6731 {
6732 // Validate arguments
6733 if (sw == NULL)
6734 {
6735 return;
6736 }
6737
6738 SendMessage(sw->hWnd, WM_APP + 1, 0, (LPARAM)str);
6739 }
6740
6741 // End and release the status window
StatusPrinterWindowStop(STATUS_WINDOW * sw)6742 void StatusPrinterWindowStop(STATUS_WINDOW *sw)
6743 {
6744 // Validate arguments
6745 if (sw == NULL)
6746 {
6747 return;
6748 }
6749
6750 // Send stop message
6751 SendMessage(sw->hWnd, WM_APP + 2, 0, 0);
6752
6753 // Wait until the thread terminates
6754 WaitThread(sw->Thread, INFINITE);
6755
6756 // Release the memory
6757 ReleaseThread(sw->Thread);
6758 Free(sw);
6759 }
6760
6761 // Initialize the status window
StatusPrinterWindowStart(SOCK * s,wchar_t * account_name)6762 STATUS_WINDOW *StatusPrinterWindowStart(SOCK *s, wchar_t *account_name)
6763 {
6764 STATUS_WINDOW_PARAM *p;
6765 STATUS_WINDOW *sw;
6766 THREAD *t;
6767 // Validate arguments
6768 if (s == NULL || account_name == NULL)
6769 {
6770 return NULL;
6771 }
6772
6773 p = ZeroMalloc(sizeof(STATUS_WINDOW_PARAM));
6774 p->Sock = s;
6775 UniStrCpy(p->AccountName, sizeof(p->AccountName), account_name);
6776
6777 // Create a thread
6778 t = NewThread(StatusPrinterWindowThread, p);
6779 WaitThreadInit(t);
6780
6781 sw = ZeroMalloc(sizeof(STATUS_WINDOW));
6782 sw->hWnd = p->hWnd;
6783 sw->Thread = t;
6784
6785 return sw;
6786 }
6787
6788 // Get the string
LbGetStr(HWND hWnd,UINT id)6789 wchar_t *LbGetStr(HWND hWnd, UINT id)
6790 {
6791 // Validate arguments
6792 if (hWnd == NULL)
6793 {
6794 return NULL;
6795 }
6796
6797 return GetText(hWnd, id);
6798 }
6799
6800 // String search
LbFindStr(HWND hWnd,UINT id,wchar_t * str)6801 UINT LbFindStr(HWND hWnd, UINT id, wchar_t *str)
6802 {
6803 UINT ret;
6804 // Validate arguments
6805 if (hWnd == NULL || str == NULL)
6806 {
6807 return INFINITE;
6808 }
6809
6810 ret = SendMsg(hWnd, id, LB_FINDSTRING, -1, (LPARAM)str);
6811
6812 return ret;
6813 }
6814
6815 // Get the number of items
LbNum(HWND hWnd,UINT id)6816 UINT LbNum(HWND hWnd, UINT id)
6817 {
6818 // Validate arguments
6819 if (hWnd == NULL)
6820 {
6821 return INFINITE;
6822 }
6823
6824 return SendMsg(hWnd, id, LB_GETCOUNT, 0, 0);
6825 }
6826
6827 // Add a string
LbAddStr(HWND hWnd,UINT id,wchar_t * str,UINT data)6828 UINT LbAddStr(HWND hWnd, UINT id, wchar_t *str, UINT data)
6829 {
6830 UINT ret;
6831
6832 if (MsIsNt() == false)
6833 {
6834 char *s = CopyUniToStr(str);
6835 ret = LbAddStrA(hWnd, id, s, data);
6836 Free(s);
6837 return ret;
6838 }
6839
6840 // Validate arguments
6841 if (hWnd == NULL || str == NULL)
6842 {
6843 return INFINITE;
6844 }
6845
6846 ret = SendMsg(hWnd, id, LB_ADDSTRING, 0, (LPARAM)str);
6847 SendMsg(hWnd, id, LB_SETITEMDATA, ret, (LPARAM)data);
6848
6849 if (LbNum(hWnd, id) == 1)
6850 {
6851 LbSelectIndex(hWnd, id, 0);
6852 }
6853
6854 return ret;
6855 }
LbAddStrA(HWND hWnd,UINT id,char * str,UINT data)6856 UINT LbAddStrA(HWND hWnd, UINT id, char *str, UINT data)
6857 {
6858 UINT ret;
6859 // Validate arguments
6860 if (hWnd == NULL || str == NULL)
6861 {
6862 return INFINITE;
6863 }
6864
6865 ret = SendMsg(hWnd, id, LB_ADDSTRING, 0, (LPARAM)str);
6866 SendMsg(hWnd, id, LB_SETITEMDATA, ret, (LPARAM)data);
6867
6868 if (LbNum(hWnd, id) == 1)
6869 {
6870 LbSelectIndex(hWnd, id, 0);
6871 }
6872
6873 return ret;
6874 }
6875
6876 // Insert a string
LbInsertStr(HWND hWnd,UINT id,UINT index,wchar_t * str,UINT data)6877 UINT LbInsertStr(HWND hWnd, UINT id, UINT index, wchar_t *str, UINT data)
6878 {
6879 UINT ret;
6880
6881 if (MsIsNt() == false)
6882 {
6883 char *s = CopyUniToStr(str);
6884 ret = LbInsertStrA(hWnd, id, index, s, data);
6885 Free(s);
6886 return ret;
6887 }
6888
6889 // Validate arguments
6890 if (hWnd == NULL || str == NULL)
6891 {
6892 return INFINITE;
6893 }
6894
6895 ret = SendMsg(hWnd, id, LB_INSERTSTRING, index, (LPARAM)str);
6896 SendMsg(hWnd, id, LB_SETITEMDATA, ret, (LPARAM)data);
6897
6898 if (LbNum(hWnd, id) == 1)
6899 {
6900 LbSelect(hWnd, id, 0);
6901 }
6902
6903 return ret;
6904 }
LbInsertStrA(HWND hWnd,UINT id,UINT index,char * str,UINT data)6905 UINT LbInsertStrA(HWND hWnd, UINT id, UINT index, char *str, UINT data)
6906 {
6907 UINT ret;
6908 // Validate arguments
6909 if (hWnd == NULL || str == NULL)
6910 {
6911 return INFINITE;
6912 }
6913
6914 ret = SendMsg(hWnd, id, LB_INSERTSTRING, index, (LPARAM)str);
6915 SendMsg(hWnd, id, LB_SETITEMDATA, ret, (LPARAM)data);
6916
6917 if (LbNum(hWnd, id) == 1)
6918 {
6919 LbSelect(hWnd, id, 0);
6920 }
6921
6922 return ret;
6923 }
6924
6925 // Remove all
LbReset(HWND hWnd,UINT id)6926 void LbReset(HWND hWnd, UINT id)
6927 {
6928 // Validate arguments
6929 if (hWnd == NULL)
6930 {
6931 return;
6932 }
6933
6934 SendMsg(hWnd, id, LB_RESETCONTENT, 0, 0);
6935 }
6936
6937 // Select by specifying the index
LbSelectIndex(HWND hWnd,UINT id,UINT index)6938 void LbSelectIndex(HWND hWnd, UINT id, UINT index)
6939 {
6940 // Validate arguments
6941 if (hWnd == NULL)
6942 {
6943 return;
6944 }
6945
6946 SendMsg(hWnd, id, LB_SETCURSEL, index, 0);
6947 }
6948
6949 // Get the data
LbGetData(HWND hWnd,UINT id,UINT index)6950 UINT LbGetData(HWND hWnd, UINT id, UINT index)
6951 {
6952 // Validate arguments
6953 if (hWnd == NULL || index == INFINITE)
6954 {
6955 return INFINITE;
6956 }
6957
6958 return SendMsg(hWnd, id, LB_GETITEMDATA, index, 0);
6959 }
6960
6961 // Search for the data
LbFindData(HWND hWnd,UINT id,UINT data)6962 UINT LbFindData(HWND hWnd, UINT id, UINT data)
6963 {
6964 UINT i, num;
6965 // Validate arguments
6966 if (hWnd == NULL)
6967 {
6968 return INFINITE;
6969 }
6970
6971 num = LbNum(hWnd, id);
6972 if (num == INFINITE)
6973 {
6974 return INFINITE;
6975 }
6976
6977 for (i = 0;i < num;i++)
6978 {
6979 if (LbGetData(hWnd, id, i) == data)
6980 {
6981 return i;
6982 }
6983 }
6984
6985 return INFINITE;
6986 }
6987
6988 // Set the height of the item
LbSetHeight(HWND hWnd,UINT id,UINT value)6989 void LbSetHeight(HWND hWnd, UINT id, UINT value)
6990 {
6991 // Validate arguments
6992 if (hWnd == NULL)
6993 {
6994 return;
6995 }
6996
6997 SendMsg(hWnd, id, LB_SETITEMHEIGHT, 0, (UINT)(GetTextScalingFactor() * (double)value));
6998 }
6999
7000 // Search by specifying the data
LbSelect(HWND hWnd,UINT id,int data)7001 void LbSelect(HWND hWnd, UINT id, int data)
7002 {
7003 UINT index;
7004 // Validate arguments
7005 if (hWnd == NULL)
7006 {
7007 return;
7008 }
7009
7010 if (data == INFINITE)
7011 {
7012 // Get the first item
7013 LbSelectIndex(hWnd, id, 0);
7014 return;
7015 }
7016
7017 index = LbFindData(hWnd, id, data);
7018 if (index == INFINITE)
7019 {
7020 // Can not be found
7021 return;
7022 }
7023
7024 // Select
7025 LbSelectIndex(hWnd, id, index);
7026 }
7027
7028 // Get the currently selected item
LbGetSelectIndex(HWND hWnd,UINT id)7029 UINT LbGetSelectIndex(HWND hWnd, UINT id)
7030 {
7031 // Validate arguments
7032 if (hWnd == NULL)
7033 {
7034 return INFINITE;
7035 }
7036
7037 return SendMsg(hWnd, id, LB_GETCURSEL, 0, 0);
7038 }
7039
7040 // Get the value that is currently selected
LbGetSelect(HWND hWnd,UINT id)7041 UINT LbGetSelect(HWND hWnd, UINT id)
7042 {
7043 UINT index;
7044 // Validate arguments
7045 if (hWnd == NULL)
7046 {
7047 return INFINITE;
7048 }
7049
7050 index = LbGetSelectIndex(hWnd, id);
7051 if (index == INFINITE)
7052 {
7053 return INFINITE;
7054 }
7055
7056 return LbGetData(hWnd, id, index);
7057 }
7058
7059 // Password input dialog state change
PasswordDlgProcChange(HWND hWnd,UI_PASSWORD_DLG * p)7060 void PasswordDlgProcChange(HWND hWnd, UI_PASSWORD_DLG *p)
7061 {
7062 bool b;
7063 // Validate arguments
7064 if (hWnd == NULL || p == NULL)
7065 {
7066 return;
7067 }
7068
7069 b = true;
7070 if (IsEmpty(hWnd, E_USERNAME))
7071 {
7072 b = false;
7073 }
7074
7075 SetEnable(hWnd, IDOK, b);
7076
7077 p->StartTick = Tick64();
7078 if (p->RetryIntervalSec)
7079 {
7080 KillTimer(hWnd, 1);
7081 Hide(hWnd, P_PROGRESS);
7082 Hide(hWnd, S_COUNTDOWN);
7083 }
7084 }
7085
7086 // Get the string
CbGetStr(HWND hWnd,UINT id)7087 wchar_t *CbGetStr(HWND hWnd, UINT id)
7088 {
7089 // Validate arguments
7090 if (hWnd == NULL)
7091 {
7092 return NULL;
7093 }
7094
7095 return GetText(hWnd, id);
7096 }
7097
7098 // String search
CbFindStr(HWND hWnd,UINT id,wchar_t * str)7099 UINT CbFindStr(HWND hWnd, UINT id, wchar_t *str)
7100 {
7101 UINT ret;
7102 if (MsIsNt() == false)
7103 {
7104 char *tmp = CopyUniToStr(str);
7105 ret = CbFindStr9xA(hWnd, id, tmp);
7106 Free(tmp);
7107 return ret;
7108 }
7109 // Validate arguments
7110 if (hWnd == NULL || str == NULL)
7111 {
7112 return INFINITE;
7113 }
7114
7115 ret = SendMsg(hWnd, id, CB_FINDSTRINGEXACT, -1, (LPARAM)str);
7116
7117 return ret;
7118 }
CbFindStr9xA(HWND hWnd,UINT id,char * str)7119 UINT CbFindStr9xA(HWND hWnd, UINT id, char *str)
7120 {
7121 UINT ret;
7122 // Validate arguments
7123 if (hWnd == NULL || str == NULL)
7124 {
7125 return INFINITE;
7126 }
7127
7128 ret = SendMsg(hWnd, id, CB_FINDSTRINGEXACT, -1, (LPARAM)str);
7129
7130 return ret;
7131 }
7132
7133 // Get the number of items
CbNum(HWND hWnd,UINT id)7134 UINT CbNum(HWND hWnd, UINT id)
7135 {
7136 // Validate arguments
7137 if (hWnd == NULL)
7138 {
7139 return INFINITE;
7140 }
7141
7142 return SendMsg(hWnd, id, CB_GETCOUNT, 0, 0);
7143 }
7144
7145 // Add a string
CbAddStrA(HWND hWnd,UINT id,char * str,UINT data)7146 UINT CbAddStrA(HWND hWnd, UINT id, char *str, UINT data)
7147 {
7148 wchar_t *tmp;
7149 UINT ret;
7150 // Validate arguments
7151 if (hWnd == NULL || str == NULL)
7152 {
7153 return INFINITE;
7154 }
7155 tmp = CopyStrToUni(str);
7156 ret = CbAddStr(hWnd, id, tmp, data);
7157 Free(tmp);
7158 return ret;
7159 }
CbAddStr(HWND hWnd,UINT id,wchar_t * str,UINT data)7160 UINT CbAddStr(HWND hWnd, UINT id, wchar_t *str, UINT data)
7161 {
7162 UINT ret;
7163 if (MsIsNt() == false)
7164 {
7165 char *s = CopyUniToStr(str);
7166 ret = CbAddStr9xA(hWnd, id, s, data);
7167 Free(s);
7168 return ret;
7169 }
7170 // Validate arguments
7171 if (hWnd == NULL || str == NULL)
7172 {
7173 return INFINITE;
7174 }
7175
7176 ret = SendMsg(hWnd, id, CB_ADDSTRING, 0, (LPARAM)str);
7177 SendMsg(hWnd, id, CB_SETITEMDATA, ret, (LPARAM)data);
7178
7179 if (CbNum(hWnd, id) == 1)
7180 {
7181 wchar_t tmp[MAX_SIZE];
7182 GetTxt(hWnd, id, tmp, sizeof(tmp));
7183 if (UniStrLen(tmp) == 0)
7184 {
7185 CbSelectIndex(hWnd, id, 0);
7186 }
7187 }
7188
7189 return ret;
7190 }
CbAddStr9xA(HWND hWnd,UINT id,char * str,UINT data)7191 UINT CbAddStr9xA(HWND hWnd, UINT id, char *str, UINT data)
7192 {
7193 UINT ret;
7194 // Validate arguments
7195 if (hWnd == NULL || str == NULL)
7196 {
7197 return INFINITE;
7198 }
7199
7200 ret = SendMsg(hWnd, id, CB_ADDSTRING, 0, (LPARAM)str);
7201 SendMsg(hWnd, id, CB_SETITEMDATA, ret, (LPARAM)data);
7202
7203 if (CbNum(hWnd, id) == 1)
7204 {
7205 wchar_t tmp[MAX_SIZE];
7206 GetTxt(hWnd, id, tmp, sizeof(tmp));
7207 if (UniStrLen(tmp) == 0)
7208 {
7209 CbSelectIndex(hWnd, id, 0);
7210 }
7211 }
7212
7213 return ret;
7214 }
7215
7216 // Insert a string
CbInsertStrA(HWND hWnd,UINT id,UINT index,char * str,UINT data)7217 UINT CbInsertStrA(HWND hWnd, UINT id, UINT index, char *str, UINT data)
7218 {
7219 wchar_t *tmp;
7220 UINT ret;
7221 // Validate arguments
7222 if (hWnd == NULL || str == NULL)
7223 {
7224 return INFINITE;
7225 }
7226 tmp = CopyStrToUni(str);
7227 ret = CbInsertStr(hWnd, id, index, tmp, data);
7228 Free(tmp);
7229 return ret;
7230 }
CbInsertStr(HWND hWnd,UINT id,UINT index,wchar_t * str,UINT data)7231 UINT CbInsertStr(HWND hWnd, UINT id, UINT index, wchar_t *str, UINT data)
7232 {
7233 UINT ret;
7234 // Validate arguments
7235 if (hWnd == NULL || str == NULL)
7236 {
7237 return INFINITE;
7238 }
7239
7240 if (MsIsNt() == false)
7241 {
7242 char *s = CopyUniToStr(str);
7243 ret = CbInsertStr9xA(hWnd, id, index, s, data);
7244 Free(s);
7245 return ret;
7246 }
7247
7248 ret = SendMsg(hWnd, id, CB_INSERTSTRING, index, (LPARAM)str);
7249 SendMsg(hWnd, id, CB_SETITEMDATA, ret, (LPARAM)data);
7250
7251 if (CbNum(hWnd, id) == 1)
7252 {
7253 CbSelect(hWnd, id, 0);
7254 }
7255
7256 return ret;
7257 }
CbInsertStr9xA(HWND hWnd,UINT id,UINT index,char * str,UINT data)7258 UINT CbInsertStr9xA(HWND hWnd, UINT id, UINT index, char *str, UINT data)
7259 {
7260 UINT ret;
7261 // Validate arguments
7262 if (hWnd == NULL || str == NULL)
7263 {
7264 return INFINITE;
7265 }
7266
7267 ret = SendMsg(hWnd, id, CB_INSERTSTRING, index, (LPARAM)str);
7268 SendMsg(hWnd, id, CB_SETITEMDATA, ret, (LPARAM)data);
7269
7270 if (CbNum(hWnd, id) == 1)
7271 {
7272 CbSelect(hWnd, id, 0);
7273 }
7274
7275 return ret;
7276 }
7277
7278 // Remove all
CbReset(HWND hWnd,UINT id)7279 void CbReset(HWND hWnd, UINT id)
7280 {
7281 wchar_t *s;
7282 // Validate arguments
7283 if (hWnd == NULL)
7284 {
7285 return;
7286 }
7287
7288 s = GetText(hWnd, id);
7289
7290 SendMsg(hWnd, id, CB_RESETCONTENT, 0, 0);
7291
7292 if (s != NULL)
7293 {
7294 SetText(hWnd, id, s);
7295 Free(s);
7296 }
7297 }
7298
7299 // Select by specifying the index
CbSelectIndex(HWND hWnd,UINT id,UINT index)7300 void CbSelectIndex(HWND hWnd, UINT id, UINT index)
7301 {
7302 // Validate arguments
7303 if (hWnd == NULL)
7304 {
7305 return;
7306 }
7307
7308 SendMsg(hWnd, id, CB_SETCURSEL, index, 0);
7309 }
7310
7311 // Get the data
CbGetData(HWND hWnd,UINT id,UINT index)7312 UINT CbGetData(HWND hWnd, UINT id, UINT index)
7313 {
7314 // Validate arguments
7315 if (hWnd == NULL || index == INFINITE)
7316 {
7317 return INFINITE;
7318 }
7319
7320 return SendMsg(hWnd, id, CB_GETITEMDATA, index, 0);
7321 }
7322
7323 // Search for the data
CbFindData(HWND hWnd,UINT id,UINT data)7324 UINT CbFindData(HWND hWnd, UINT id, UINT data)
7325 {
7326 UINT i, num;
7327 // Validate arguments
7328 if (hWnd == NULL)
7329 {
7330 return INFINITE;
7331 }
7332
7333 num = CbNum(hWnd, id);
7334 if (num == INFINITE)
7335 {
7336 return INFINITE;
7337 }
7338
7339 for (i = 0;i < num;i++)
7340 {
7341 if (CbGetData(hWnd, id, i) == data)
7342 {
7343 return i;
7344 }
7345 }
7346
7347 return INFINITE;
7348 }
7349
7350 // Set the height of the item
CbSetHeight(HWND hWnd,UINT id,UINT value)7351 void CbSetHeight(HWND hWnd, UINT id, UINT value)
7352 {
7353 // Validate arguments
7354 if (hWnd == NULL)
7355 {
7356 return;
7357 }
7358
7359 SendMsg(hWnd, id, CB_SETITEMHEIGHT, 0, (UINT)(GetTextScalingFactor() * (double)value));
7360 }
7361
7362 // Search by specifying the data
CbSelect(HWND hWnd,UINT id,int data)7363 void CbSelect(HWND hWnd, UINT id, int data)
7364 {
7365 UINT index;
7366 // Validate arguments
7367 if (hWnd == NULL)
7368 {
7369 return;
7370 }
7371
7372 if (data == INFINITE)
7373 {
7374 // Get the first item
7375 CbSelectIndex(hWnd, id, 0);
7376 return;
7377 }
7378
7379 index = CbFindData(hWnd, id, data);
7380 if (index == INFINITE)
7381 {
7382 // Can not be found
7383 return;
7384 }
7385
7386 // Select
7387 CbSelectIndex(hWnd, id, index);
7388 }
7389
7390 // Get the currently selected item
CbGetSelectIndex(HWND hWnd,UINT id)7391 UINT CbGetSelectIndex(HWND hWnd, UINT id)
7392 {
7393 // Validate arguments
7394 if (hWnd == NULL)
7395 {
7396 return INFINITE;
7397 }
7398
7399 return SendMsg(hWnd, id, CB_GETCURSEL, 0, 0);
7400 }
7401
7402 // Get the value that is currently selected
CbGetSelect(HWND hWnd,UINT id)7403 UINT CbGetSelect(HWND hWnd, UINT id)
7404 {
7405 UINT index;
7406 // Validate arguments
7407 if (hWnd == NULL)
7408 {
7409 return INFINITE;
7410 }
7411
7412 index = CbGetSelectIndex(hWnd, id);
7413 if (index == INFINITE)
7414 {
7415 return INFINITE;
7416 }
7417
7418 return CbGetData(hWnd, id, index);
7419 }
7420
7421 // OK button is pressed
PasswordDlgOnOk(HWND hWnd,UI_PASSWORD_DLG * p)7422 void PasswordDlgOnOk(HWND hWnd, UI_PASSWORD_DLG *p)
7423 {
7424 // Validate arguments
7425 if (hWnd == NULL || p == NULL)
7426 {
7427 return;
7428 }
7429
7430 GetTxtA(hWnd, E_USERNAME, p->Username, sizeof(p->Username));
7431 GetTxtA(hWnd, E_PASSWORD, p->Password, sizeof(p->Password));
7432 p->Type = CbGetSelect(hWnd, C_TYPE);
7433
7434 if (p->ShowNoSavePassword)
7435 {
7436 p->NoSavePassword = IsChecked(hWnd, R_NO_SAVE_PASSWORD);
7437 }
7438
7439 EndDialog(hWnd, true);
7440 }
7441
7442 // Password input dialog procedure
PasswordDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)7443 UINT PasswordDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
7444 {
7445 UI_PASSWORD_DLG *p = (UI_PASSWORD_DLG *)param;
7446 // Validate arguments
7447 if (hWnd == NULL)
7448 {
7449 return 0;
7450 }
7451
7452 switch (msg)
7453 {
7454 case WM_INITDIALOG:
7455 SetIcon(hWnd, 0, ICO_KEY);
7456 CbSetHeight(hWnd, C_TYPE, 18);
7457 if (p->ServerName != NULL)
7458 {
7459 FormatText(hWnd, 0, p->ServerName);
7460 }
7461 else
7462 {
7463 SetText(hWnd, 0, _UU("PW_LOGIN_DLG_TITLE"));
7464 }
7465
7466 if (p->ProxyServer == false)
7467 {
7468 FormatText(hWnd, S_TITLE, p->ServerName == NULL ? "" : p->ServerName);
7469 }
7470 else
7471 {
7472 wchar_t tmp[MAX_SIZE];
7473 UniFormat(tmp, sizeof(tmp), _UU("PW_MSG_PROXY"), p->ServerName == NULL ? "" : p->ServerName);
7474 SetText(hWnd, S_TITLE, tmp);
7475 }
7476
7477 // Enumerate the connection methods
7478 SendMsg(hWnd, C_TYPE, CBEM_SETUNICODEFORMAT, true, 0);
7479
7480 if (StrCmpi(p->Username, WINUI_PASSWORD_NULL_USERNAME) != 0)
7481 {
7482 SetTextA(hWnd, E_USERNAME, p->Username);
7483 SetTextA(hWnd, E_PASSWORD, p->Password);
7484 }
7485 else
7486 {
7487 p->RetryIntervalSec = 0;
7488 SetTextA(hWnd, E_USERNAME, "");
7489 SetTextA(hWnd, E_PASSWORD, "");
7490 }
7491
7492 if (p->AdminMode == false)
7493 {
7494 if (p->ProxyServer == false)
7495 {
7496 CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_1"), CLIENT_AUTHTYPE_PASSWORD);
7497 CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_2"), CLIENT_AUTHTYPE_PLAIN_PASSWORD);
7498 }
7499 else
7500 {
7501 CbAddStr(hWnd, C_TYPE, _UU("PW_TYPE_PROXY"), 0);
7502 Disable(hWnd, C_TYPE);
7503 }
7504
7505 CbSelect(hWnd, C_TYPE, p->Type);
7506 }
7507 else
7508 {
7509 CbAddStr(hWnd, C_TYPE, _UU("SM_PASSWORD_TYPE_STR"), 0);
7510 Disable(hWnd, C_TYPE);
7511 SetTextA(hWnd, E_USERNAME, "Administrator");
7512 Disable(hWnd, E_USERNAME);
7513 }
7514
7515 if (IsEmpty(hWnd, E_USERNAME))
7516 {
7517 FocusEx(hWnd, E_USERNAME);
7518 }
7519 else
7520 {
7521 FocusEx(hWnd, E_PASSWORD);
7522 }
7523 LimitText(hWnd, E_USERNAME, MAX_USERNAME_LEN);
7524 LimitText(hWnd, E_PASSWORD, MAX_PASSWORD_LEN);
7525
7526 PasswordDlgProcChange(hWnd, p);
7527
7528 if (p->RetryIntervalSec != 0)
7529 {
7530 SetTimer(hWnd, 1, 50, NULL);
7531 FormatText(hWnd, S_COUNTDOWN, p->RetryIntervalSec);
7532 Show(hWnd, S_COUNTDOWN);
7533 Show(hWnd, P_PROGRESS);
7534 SetRange(hWnd, P_PROGRESS, 0, p->RetryIntervalSec * 1000);
7535 }
7536 else
7537 {
7538 Hide(hWnd, S_COUNTDOWN);
7539 Hide(hWnd, P_PROGRESS);
7540 }
7541
7542 if (p->ShowNoSavePassword)
7543 {
7544 Show(hWnd, R_NO_SAVE_PASSWORD);
7545 Check(hWnd, R_NO_SAVE_PASSWORD, p->NoSavePassword);
7546 }
7547 else
7548 {
7549 Hide(hWnd, R_NO_SAVE_PASSWORD);
7550 }
7551
7552 p->StartTick = Tick64();
7553
7554 if (p->CancelEvent != NULL)
7555 {
7556 SetTimer(hWnd, 2, 50, NULL);
7557 }
7558
7559 break;
7560
7561 case WM_CLOSE:
7562 EndDialog(hWnd, false);
7563 break;
7564
7565 case WM_TIMER:
7566 switch (wParam)
7567 {
7568 case 1:
7569 if (p->RetryIntervalSec != 0)
7570 {
7571 wchar_t tmp[MAX_SIZE];
7572 UINT64 end, now, start;
7573 start = p->StartTick;
7574 end = p->StartTick + (UINT64)(p->RetryIntervalSec * 1000);
7575 now = Tick64();
7576
7577 if (now <= end)
7578 {
7579 UniFormat(tmp, sizeof(tmp), _UU("PW_RETRYCOUNT"), (UINT)((end - now) / 1000));
7580 SetText(hWnd, S_COUNTDOWN, tmp);
7581 SetPos(hWnd, P_PROGRESS, (UINT)(now - start));
7582 }
7583 else
7584 {
7585 EndDialog(hWnd, true);
7586 }
7587 }
7588 break;
7589
7590 case 2:
7591 if (p->CancelEvent != NULL)
7592 {
7593 // Wait for the end event
7594 HANDLE hEvent = (HANDLE)p->CancelEvent->pData;
7595 UINT ret = WaitForSingleObject(hEvent, 0);
7596 if (ret != WAIT_TIMEOUT)
7597 {
7598 // Forced termination event is set
7599 Close(hWnd);
7600 }
7601 }
7602 break;
7603 }
7604 break;
7605
7606 case WM_COMMAND:
7607 switch (wParam)
7608 {
7609 case IDOK:
7610 PasswordDlgOnOk(hWnd, p);
7611 break;
7612 case IDCANCEL:
7613 Close(hWnd);
7614 break;
7615 }
7616 switch (HIWORD(wParam))
7617 {
7618 case EN_CHANGE:
7619 switch (LOWORD(wParam))
7620 {
7621 case E_USERNAME:
7622 case E_PASSWORD:
7623 PasswordDlgProcChange(hWnd, p);
7624 break;
7625 }
7626 break;
7627 case CBN_SELCHANGE:
7628 switch (LOWORD(wParam))
7629 {
7630 case C_TYPE:
7631 PasswordDlgProcChange(hWnd, p);
7632 if (IsEmpty(hWnd, E_USERNAME))
7633 {
7634 FocusEx(hWnd, E_USERNAME);
7635 }
7636 else
7637 {
7638 FocusEx(hWnd, E_PASSWORD);
7639 }
7640 break;
7641 }
7642 break;
7643 }
7644 break;
7645 }
7646
7647 return 0;
7648 }
7649
7650 // Set the position of the progress bar
SetPos(HWND hWnd,UINT id,UINT pos)7651 void SetPos(HWND hWnd, UINT id, UINT pos)
7652 {
7653 // Validate arguments
7654 if (hWnd == NULL)
7655 {
7656 return;
7657 }
7658
7659 SendMsg(hWnd, id, PBM_SETPOS, pos, 0);
7660 }
7661
7662 // Set the range of the progress bar
SetRange(HWND hWnd,UINT id,UINT start,UINT end)7663 void SetRange(HWND hWnd, UINT id, UINT start, UINT end)
7664 {
7665 // Validate arguments
7666 if (hWnd == NULL)
7667 {
7668 return;
7669 }
7670
7671 SendMsg(hWnd, id, PBM_SETRANGE32, start, end);
7672 }
7673
7674 // Password input dialog
PasswordDlg(HWND hWnd,UI_PASSWORD_DLG * p)7675 bool PasswordDlg(HWND hWnd, UI_PASSWORD_DLG *p)
7676 {
7677 // Validate arguments
7678 if (p == NULL)
7679 {
7680 return false;
7681 }
7682
7683 p->StartTick = Tick64();
7684
7685 return Dialog(hWnd, D_PASSWORD, PasswordDlgProc, p);
7686 }
7687
7688 // Passphrase input dialog
PassphraseDlg(HWND hWnd,char * pass,UINT pass_size,BUF * buf,bool p12)7689 bool PassphraseDlg(HWND hWnd, char *pass, UINT pass_size, BUF *buf, bool p12)
7690 {
7691 PASSPHRASE_DLG p;
7692 // Validate arguments
7693 if (pass == NULL || buf == NULL)
7694 {
7695 return false;
7696 }
7697
7698 Zero(&p, sizeof(PASSPHRASE_DLG));
7699
7700 p.buf = buf;
7701 p.p12 = p12;
7702
7703 // Examine whether it is encrypted first
7704 if (p12 == false)
7705 {
7706 // Secret key
7707 if (IsEncryptedK(buf, true) == false)
7708 {
7709 // Unencrypted
7710 StrCpy(pass, pass_size, "");
7711 return true;
7712 }
7713 }
7714 else
7715 {
7716 // PKCS#12
7717 P12 *p12 = BufToP12(buf);
7718 if (p12 == NULL)
7719 {
7720 // It is in unknown format, but not encrypted
7721 StrCpy(pass, pass_size, "");
7722 return true;
7723 }
7724
7725 if (IsEncryptedP12(p12) == false)
7726 {
7727 // Unencrypted
7728 StrCpy(pass, pass_size, "");
7729 FreeP12(p12);
7730 return true;
7731 }
7732 FreeP12(p12);
7733 }
7734
7735 // Show the dialog
7736 if (Dialog(hWnd, D_PASSPHRASE, PassphraseDlgProc, &p) == false)
7737 {
7738 // Cancel
7739 return false;
7740 }
7741
7742 StrCpy(pass, pass_size, p.pass);
7743
7744 return true;
7745 }
7746
7747 // WM_COMMAND handler
PassphraseDlgProcCommand(HWND hWnd,PASSPHRASE_DLG * p)7748 void PassphraseDlgProcCommand(HWND hWnd, PASSPHRASE_DLG *p)
7749 {
7750 char *pass;
7751 bool ok;
7752 // Validate arguments
7753 if (hWnd == NULL || p == NULL)
7754 {
7755 return;
7756 }
7757
7758 pass = GetTextA(hWnd, E_PASSPHRASE);
7759 if (pass == NULL)
7760 {
7761 return;
7762 }
7763
7764 ok = false;
7765
7766 if (p->p12 == false)
7767 {
7768 K *k;
7769 k = BufToK(p->buf, true, true, pass);
7770 if (k != NULL)
7771 {
7772 ok = true;
7773 FreeK(k);
7774 }
7775 }
7776 else
7777 {
7778 X *x;
7779 K *k;
7780 P12 *p12;
7781 p12 = BufToP12(p->buf);
7782 if (p12 != NULL)
7783 {
7784 if (ParseP12(p12, &x, &k, pass))
7785 {
7786 FreeX(x);
7787 FreeK(k);
7788 ok = true;
7789 }
7790 FreeP12(p12);
7791 }
7792 }
7793
7794 Free(pass);
7795
7796 SetEnable(hWnd, IDOK, ok);
7797 }
7798
7799 // Passphrase input dialog procedure
PassphraseDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)7800 UINT PassphraseDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
7801 {
7802 PASSPHRASE_DLG *p = (PASSPHRASE_DLG *)param;
7803 // Validate arguments
7804 if (hWnd == NULL)
7805 {
7806 return 0;
7807 }
7808
7809 switch (msg)
7810 {
7811 case WM_INITDIALOG:
7812 PassphraseDlgProcCommand(hWnd, p);
7813 break;
7814
7815 case WM_COMMAND:
7816 switch (wParam)
7817 {
7818 case IDOK:
7819 GetTxtA(hWnd, E_PASSPHRASE, p->pass, sizeof(p->pass));
7820 EndDialog(hWnd, true);
7821 break;
7822
7823 case IDCANCEL:
7824 Close(hWnd);
7825 break;
7826 }
7827
7828 switch (LOWORD(wParam))
7829 {
7830 case E_PASSPHRASE:
7831 PassphraseDlgProcCommand(hWnd, p);
7832 break;
7833 }
7834 break;
7835
7836 case WM_CLOSE:
7837 EndDialog(hWnd, false);
7838 break;
7839 }
7840
7841 return 0;
7842 }
7843
7844 // PKCS utility
PkcsUtil()7845 void PkcsUtil()
7846 {
7847 InitWinUi(_UU("PKCS_UTIL_TITLE"), _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE"));
7848 Dialog(NULL, D_PKCSUTIL, PkcsUtilProc, NULL);
7849 FreeWinUi();
7850 }
7851
7852 // PKCS writing
PkcsUtilWrite(HWND hWnd)7853 void PkcsUtilWrite(HWND hWnd)
7854 {
7855 wchar_t *filename;
7856 BUF *in_buf;
7857 char filename_ansi[MAX_SIZE];
7858 char pass[MAX_SIZE];
7859 // Validate arguments
7860 if (hWnd == NULL)
7861 {
7862 return;
7863 }
7864
7865 filename = OpenDlg(hWnd, _UU("DLG_PKCS12_FILTER"), _UU("PKCS_UTIL_SAVEDLG_TITLE"));
7866 if (filename == NULL)
7867 {
7868 return;
7869 }
7870
7871 UniToStr(filename_ansi, sizeof(filename_ansi), filename);
7872
7873 in_buf = ReadDump(filename_ansi);
7874
7875 if (in_buf == NULL)
7876 {
7877 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("PKCS_UTIL_READ_ERROR"), filename);
7878 }
7879 else
7880 {
7881 if (PassphraseDlg(hWnd, pass, sizeof(pass), in_buf, true))
7882 {
7883 P12 *p12 = BufToP12(in_buf);
7884 if (p12 == NULL)
7885 {
7886 MsgBox(hWnd, MB_ICONEXCLAMATION, _UU("PKCS_UTIL_BAD_FILE"));
7887 }
7888 else
7889 {
7890 X *x = NULL;
7891 K *k = NULL;
7892 BUF *b;
7893 ParseP12(p12, &x, &k, pass);
7894 FreeP12(p12);
7895 p12 = NewP12(x, k, NULL);
7896 FreeX(x);
7897 FreeK(k);
7898 b = P12ToBuf(p12);
7899 FreeP12(p12);
7900 if (b != NULL)
7901 {
7902 // Batch processing
7903 WINUI_SECURE_BATCH batch[] =
7904 {
7905 {WINUI_SECURE_WRITE_DATA, _SS("PKCS_UTIL_SECA_FILENAME"), false,
7906 b, NULL, NULL, NULL, NULL, NULL},
7907 };
7908
7909 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), 2, 0))
7910 {
7911 MsgBoxEx(hWnd, MB_ICONINFORMATION, _UU("PKCS_UTIL_WRITE_OK_MSG"), filename);
7912 }
7913 }
7914 FreeBuf(b);
7915 }
7916 }
7917
7918 FreeBuf(in_buf);
7919 }
7920
7921 Free(filename);
7922 }
7923
7924 // PKCS erase
PkcsUtilErase(HWND hWnd)7925 void PkcsUtilErase(HWND hWnd)
7926 {
7927 // Validate arguments
7928 if (hWnd == NULL)
7929 {
7930 return;
7931 }
7932
7933 if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2,
7934 _UU("PKCS_MAKE_SURE")) == IDYES)
7935 {
7936 // Batch processing
7937 WINUI_SECURE_BATCH batch[] =
7938 {
7939 {WINUI_SECURE_DELETE_OBJECT, _SS("PKCS_UTIL_SECA_FILENAME"), false,
7940 NULL, NULL, NULL, NULL, NULL, NULL},
7941 };
7942
7943 if (SecureDeviceWindow(hWnd, batch, sizeof(batch) / sizeof(batch[0]), 2, 0))
7944 {
7945 MsgBox(hWnd, MB_ICONINFORMATION, _UU("PKCS_UTIL_DELETE_OK_MSG"));
7946 }
7947 }
7948 }
7949
7950 // PKCS Utility dialog
PkcsUtilProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)7951 UINT PkcsUtilProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
7952 {
7953 // Validate arguments
7954 if (hWnd == NULL)
7955 {
7956 return 0;
7957 }
7958
7959 switch (msg)
7960 {
7961 case WM_INITDIALOG:
7962 DlgFont(hWnd, S_TITLE, 12, true);
7963 SetIcon(hWnd, 0, ICO_CERT);
7964 SetFont(hWnd, S_COPYRIGHT, GetFont("Arial", 8, false, false, false, false));
7965 break;
7966
7967 case WM_COMMAND:
7968 switch (wParam)
7969 {
7970 case B_WRITE:
7971 PkcsUtilWrite(hWnd);
7972 break;
7973
7974 case B_ERASE:
7975 PkcsUtilErase(hWnd);
7976 break;
7977
7978 case IDCANCEL:
7979 Close(hWnd);
7980 break;
7981 }
7982
7983 break;
7984
7985 case WM_CLOSE:
7986 EndDialog(hWnd, 0);
7987 break;
7988 }
7989
7990 return 0;
7991 }
7992
7993 // [Save File] dialog
SaveDlg(HWND hWnd,wchar_t * filter,wchar_t * title,wchar_t * default_name,wchar_t * default_ext)7994 wchar_t *SaveDlg(HWND hWnd, wchar_t *filter, wchar_t *title, wchar_t *default_name, wchar_t *default_ext)
7995 {
7996 wchar_t *filter_str;
7997 wchar_t tmp[MAX_SIZE];
7998 OPENFILENAMEW o;
7999
8000 if (MsIsNt() == false)
8001 {
8002 char *ret, *s1, *s2, *s3, *s4;
8003 wchar_t *wr;
8004 s1 = CopyUniToStr(filter);
8005 s2 = CopyUniToStr(title);
8006 s3 = CopyUniToStr(default_name);
8007 s4 = CopyUniToStr(default_ext);
8008 ret = SaveDlgA(hWnd, s1, s2, s3, s4);
8009 Free(s1);
8010 Free(s2);
8011 Free(s3);
8012 Free(s4);
8013 wr = CopyStrToUni(ret);
8014 Free(ret);
8015 return wr;
8016 }
8017
8018 // Validate arguments
8019 if (filter == NULL)
8020 {
8021 filter = _UU("DLG_ALL_FILES");
8022 }
8023
8024 filter_str = MakeFilter(filter);
8025
8026 Zero(&o, sizeof(o));
8027 Zero(tmp, sizeof(tmp));
8028
8029 if (default_name != NULL)
8030 {
8031 UniStrCpy(tmp, sizeof(tmp), default_name);
8032 }
8033
8034 o.lStructSize = sizeof(o);
8035
8036 if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType) || (OS_IS_WINDOWS_NT(GetOsInfo()->OsType) && GET_KETA(GetOsInfo()->OsType, 100) <= 1))
8037 {
8038 o.lStructSize = OPENFILENAME_SIZE_VERSION_400W;
8039 }
8040
8041 o.hwndOwner = hWnd;
8042 o.hInstance = GetModuleHandle(NULL);
8043 o.lpstrFile = tmp;
8044 o.lpstrTitle = title;
8045 o.lpstrFilter = filter_str;
8046 o.nMaxFile = sizeof(tmp);
8047 o.Flags = OFN_OVERWRITEPROMPT;
8048 o.lpstrDefExt = default_ext;
8049
8050 if (GetSaveFileNameW(&o) == false)
8051 {
8052 Free(filter_str);
8053 return NULL;
8054 }
8055
8056 Free(filter_str);
8057
8058 return UniCopyStr(tmp);
8059 }
SaveDlgA(HWND hWnd,char * filter,char * title,char * default_name,char * default_ext)8060 char *SaveDlgA(HWND hWnd, char *filter, char *title, char *default_name, char *default_ext)
8061 {
8062 char *filter_str;
8063 char tmp[MAX_SIZE];
8064 OPENFILENAME o;
8065 // Validate arguments
8066 if (filter == NULL)
8067 {
8068 filter = _SS("DLG_ALL_FILES");
8069 }
8070
8071 filter_str = MakeFilterA(filter);
8072
8073 Zero(&o, sizeof(o));
8074 Zero(tmp, sizeof(tmp));
8075
8076 if (default_name != NULL)
8077 {
8078 StrCpy(tmp, sizeof(tmp), default_name);
8079 }
8080
8081 o.lStructSize = sizeof(o);
8082
8083 if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType) || (OS_IS_WINDOWS_NT(GetOsInfo()->OsType) && GET_KETA(GetOsInfo()->OsType, 100) <= 1))
8084 {
8085 o.lStructSize = OPENFILENAME_SIZE_VERSION_400A;
8086 }
8087
8088 o.hwndOwner = hWnd;
8089 o.hInstance = GetModuleHandle(NULL);
8090 o.lpstrFile = tmp;
8091 o.lpstrTitle = title;
8092 o.lpstrFilter = filter_str;
8093 o.nMaxFile = sizeof(tmp);
8094 o.Flags = OFN_OVERWRITEPROMPT;
8095 o.lpstrDefExt = default_ext;
8096
8097 if (GetSaveFileName(&o) == false)
8098 {
8099 Free(filter_str);
8100 return NULL;
8101 }
8102
8103 Free(filter_str);
8104
8105 return CopyStr(tmp);
8106 }
8107
8108 // [Open File] dialog
OpenDlg(HWND hWnd,wchar_t * filter,wchar_t * title)8109 wchar_t *OpenDlg(HWND hWnd, wchar_t *filter, wchar_t *title)
8110 {
8111 wchar_t *filter_str;
8112 wchar_t tmp[MAX_SIZE];
8113 OPENFILENAMEW o;
8114
8115 if (MsIsNt() == false)
8116 {
8117 char *ret;
8118 char *filter_a;
8119 char *title_a;
8120 wchar_t *w;
8121 filter_a = CopyUniToStr(filter);
8122 title_a = CopyUniToStr(title);
8123 ret = OpenDlgA(hWnd, filter_a, title_a);
8124 Free(filter_a);
8125 Free(title_a);
8126 w = CopyStrToUni(ret);
8127 Free(ret);
8128 return w;
8129 }
8130
8131 // Validate arguments
8132 if (filter == NULL)
8133 {
8134 filter = _UU("DLG_ALL_FILES");
8135 }
8136
8137 filter_str = MakeFilter(filter);
8138
8139 Zero(&o, sizeof(OPENFILENAMEW));
8140 Zero(tmp, sizeof(tmp));
8141
8142 o.lStructSize = sizeof(o);
8143
8144
8145 if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType) || (OS_IS_WINDOWS_NT(GetOsInfo()->OsType) && GET_KETA(GetOsInfo()->OsType, 100) <= 1))
8146 {
8147 o.lStructSize = OPENFILENAME_SIZE_VERSION_400W;
8148 }
8149
8150
8151 o.hwndOwner = hWnd;
8152 o.hInstance = GetModuleHandle(NULL);
8153 o.lpstrFilter = filter_str;
8154 o.lpstrFile = tmp;
8155 o.nMaxFile = sizeof(tmp);
8156 o.lpstrTitle = title;
8157 o.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
8158
8159 if (GetOpenFileNameW(&o) == false)
8160 {
8161 Free(filter_str);
8162 return NULL;
8163 }
8164
8165 Free(filter_str);
8166
8167 return UniCopyStr(tmp);
8168 }
OpenDlgA(HWND hWnd,char * filter,char * title)8169 char *OpenDlgA(HWND hWnd, char *filter, char *title)
8170 {
8171 char *filter_str;
8172 char tmp[MAX_SIZE];
8173 OPENFILENAME o;
8174 // Validate arguments
8175 if (filter == NULL)
8176 {
8177 filter = _SS("DLG_ALL_FILES");
8178 }
8179
8180 filter_str = MakeFilterA(filter);
8181
8182 Zero(&o, sizeof(OPENFILENAME));
8183 Zero(tmp, sizeof(tmp));
8184
8185 o.lStructSize = sizeof(o);
8186
8187 if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType) || (OS_IS_WINDOWS_NT(GetOsInfo()->OsType) && GET_KETA(GetOsInfo()->OsType, 100) <= 1))
8188 {
8189 o.lStructSize = OPENFILENAME_SIZE_VERSION_400A;
8190 }
8191
8192 o.hwndOwner = hWnd;
8193 o.hInstance = GetModuleHandle(NULL);
8194 o.lpstrFilter = filter_str;
8195 o.lpstrFile = tmp;
8196 o.nMaxFile = sizeof(tmp);
8197 o.lpstrTitle = title;
8198 o.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
8199
8200 if (GetOpenFileName(&o) == false)
8201 {
8202 Free(filter_str);
8203 return NULL;
8204 }
8205
8206 Free(filter_str);
8207
8208 return CopyStr(tmp);
8209 }
8210
8211 // Generate the filter string
MakeFilter(wchar_t * str)8212 wchar_t *MakeFilter(wchar_t *str)
8213 {
8214 UINT i;
8215 wchar_t *ret;
8216 // Validate arguments
8217 if (str == NULL)
8218 {
8219 return NULL;
8220 }
8221
8222 ret = ZeroMalloc(UniStrSize(str) + 32);
8223
8224 for (i = 0;i < UniStrLen(str);i++)
8225 {
8226 if (str[i] == L'|')
8227 {
8228 ret[i] = L'\0';
8229 }
8230 else
8231 {
8232 ret[i] = str[i];
8233 }
8234 }
8235
8236 return ret;
8237 }
MakeFilterA(char * str)8238 char *MakeFilterA(char *str)
8239 {
8240 UINT i;
8241 char *ret;
8242 // Validate arguments
8243 if (str == NULL)
8244 {
8245 return NULL;
8246 }
8247
8248 ret = ZeroMalloc(StrSize(str) + 32);
8249
8250 for (i = 0;i < StrLen(str);i++)
8251 {
8252 if (str[i] == '|')
8253 {
8254 ret[i] = '\0';
8255 }
8256 else
8257 {
8258 ret[i] = str[i];
8259 }
8260 }
8261
8262 return ret;
8263 }
8264
8265 // Execution of batch
ExecuteSecureDeviceBatch(HWND hWnd,SECURE * sec,SECURE_DEVICE_THREAD * p,SECURE_DEVICE * dev,WINUI_SECURE_BATCH * batch)8266 bool ExecuteSecureDeviceBatch(HWND hWnd, SECURE *sec, SECURE_DEVICE_THREAD *p, SECURE_DEVICE *dev, WINUI_SECURE_BATCH *batch)
8267 {
8268 LIST *o;
8269 void *buf;
8270 UINT size = 10 * 1024; // Maximum size of the data
8271 UINT type = INFINITE;
8272 // Validate arguments
8273 if (hWnd == NULL || p == NULL || dev == NULL || batch == NULL || sec == NULL)
8274 {
8275 return false;
8276 }
8277
8278 switch (batch->Type)
8279 {
8280 case WINUI_SECURE_DELETE_CERT:
8281 type = SEC_X;
8282 goto DELETE_OBJECT;
8283
8284 case WINUI_SECURE_DELETE_KEY:
8285 type = SEC_K;
8286 goto DELETE_OBJECT;
8287
8288 case WINUI_SECURE_DELETE_DATA:
8289 type = SEC_DATA;
8290 goto DELETE_OBJECT;
8291
8292 case WINUI_SECURE_DELETE_OBJECT:
8293 // Delete the object
8294 DELETE_OBJECT:
8295 SetText(hWnd, S_STATUS, _UU("SEC_DELETE"));
8296 if (DeleteSecObjectByName(sec, batch->Name, type) == false)
8297 {
8298 p->ErrorMessage = UniCopyStr(_UU("SEC_ERROR_DELETE"));
8299 return false;
8300 }
8301 break;
8302
8303 case WINUI_SECURE_ENUM_OBJECTS:
8304 // Enumerate objects
8305 SetText(hWnd, S_STATUS, _UU("SEC_ENUM"));
8306 o = EnumSecObject(sec);
8307 if (o == NULL)
8308 {
8309 p->ErrorMessage = UniCopyStr(_UU("SEC_ERROR_ENUM"));
8310 return false;
8311 }
8312
8313 batch->EnumList = o;
8314 break;
8315
8316 case WINUI_SECURE_WRITE_DATA:
8317 // Write the data
8318 SetText(hWnd, S_STATUS, _UU("SEC_WRITE_DATA"));
8319 if (WriteSecData(sec, batch->Private, batch->Name, batch->InputData->Buf, batch->InputData->Size) == false)
8320 {
8321 p->ErrorMessage = UniCopyStr(dev->Type != SECURE_USB_TOKEN ?
8322 _UU("SEC_ERROR_WRITE_1") : _UU("SEC_ERROR_WRITE_2"));
8323 return false;
8324 }
8325 break;
8326
8327 case WINUI_SECURE_READ_DATA:
8328 // Read the data
8329 SetText(hWnd, S_STATUS, _UU("SEC_READ_DATA"));
8330 buf = MallocEx(size, true);
8331 size = ReadSecData(sec, batch->Name, buf, size);
8332 if (size == 0)
8333 {
8334 Free(buf);
8335 p->ErrorMessage = UniCopyStr(dev->Type != SECURE_USB_TOKEN ?
8336 _UU("SEC_ERROR_NOT_FOUND_1") : _UU("SEC_ERROR_NOT_FOUND_2"));
8337 return false;
8338 }
8339 batch->OutputData = NewBuf();
8340 WriteBuf(batch->OutputData, buf, size);
8341 SeekBuf(batch->OutputData, 0, 0);
8342 Free(buf);
8343 break;
8344
8345 case WINUI_SECURE_WRITE_CERT:
8346 // Write the certificate
8347 SetText(hWnd, S_STATUS, _UU("SEC_WRITE_CERT"));
8348 if (WriteSecCert(sec, batch->Private, batch->Name, batch->InputX) == false)
8349 {
8350 p->ErrorMessage = UniCopyStr(dev->Type != SECURE_USB_TOKEN ?
8351 _UU("SEC_ERROR_WRITE_1") : _UU("SEC_ERROR_WRITE_2"));
8352 return false;
8353 }
8354 break;
8355
8356 case WINUI_SECURE_READ_CERT:
8357 // Read the certificate
8358 SetText(hWnd, S_STATUS, _UU("SEC_READ_CERT"));
8359 batch->OutputX = ReadSecCert(sec, batch->Name);
8360 if (batch->OutputX == NULL)
8361 {
8362 p->ErrorMessage = UniCopyStr(dev->Type != SECURE_USB_TOKEN ?
8363 _UU("SEC_ERROR_NOT_FOUND_1") : _UU("SEC_ERROR_NOT_FOUND_2"));
8364 return false;
8365 }
8366 break;
8367
8368 case WINUI_SECURE_WRITE_KEY:
8369 // Write the secret key
8370 SetText(hWnd, S_STATUS, _UU("SEC_WRITE_KEY"));
8371 if (WriteSecKey(sec, batch->Private, batch->Name, batch->InputK) == false)
8372 {
8373 p->ErrorMessage = UniCopyStr(dev->Type != SECURE_USB_TOKEN ?
8374 _UU("SEC_ERROR_WRITE_1") : _UU("SEC_ERROR_WRITE_2"));
8375 return false;
8376 }
8377 break;
8378
8379 case WINUI_SECURE_SIGN_WITH_KEY:
8380 // Signature
8381 SetText(hWnd, S_STATUS, _UU("SEC_SIGN"));
8382 if (SignSec(sec, batch->Name, batch->OutputSign, batch->InputData->Buf, batch->InputData->Size) == false)
8383 {
8384 p->ErrorMessage = UniCopyStr(dev->Type != SECURE_USB_TOKEN ?
8385 _UU("SEC_ERROR_SIGN_1") : _UU("SEC_ERROR_SIGN_2"));
8386 return false;
8387 }
8388 break;
8389 }
8390
8391 return true;
8392 }
8393
8394 // Run the secure device operations as a batch job
SecureDeviceBatch(HWND hWnd,SECURE * sec,SECURE_DEVICE_THREAD * p,SECURE_DEVICE * dev)8395 void SecureDeviceBatch(HWND hWnd, SECURE *sec, SECURE_DEVICE_THREAD *p, SECURE_DEVICE *dev)
8396 {
8397 UINT i;
8398 // Validate arguments
8399 if (hWnd == NULL || p == NULL || dev == NULL || sec == NULL)
8400 {
8401 return;
8402 }
8403
8404 // Sequential processing
8405 for (i = 0;i < p->w->num_batch;i++)
8406 {
8407 WINUI_SECURE_BATCH *batch = &p->w->batch[i];
8408
8409 if (ExecuteSecureDeviceBatch(hWnd, sec, p, dev, batch) == false)
8410 {
8411 // If fail even one, abort immediately
8412 return;
8413 }
8414 }
8415
8416 // All batch job succeeded
8417 p->Succeed = true;
8418 }
8419
8420 // Thread to perform a secure device operation
SecureDeviceThread(THREAD * t,void * param)8421 void SecureDeviceThread(THREAD *t, void *param)
8422 {
8423 SECURE *sec;
8424 SECURE_DEVICE_THREAD *p = (SECURE_DEVICE_THREAD *)param;
8425 SECURE_DEVICE *dev;
8426 HWND hWnd;
8427 // Validate arguments
8428 if (t == NULL || param == NULL)
8429 {
8430 return;
8431 }
8432
8433 p->Succeed = false;
8434 p->ErrorMessage = NULL;
8435
8436 hWnd = p->hWnd;
8437
8438 // Open the device
8439 dev = GetSecureDevice(p->w->device_id);
8440 SetText(hWnd, S_STATUS, _UU("SEC_OPENING"));
8441 sec = OpenSec(p->w->device_id);
8442 if (sec == NULL)
8443 {
8444 // Device open failure
8445 if (p->w->device_id != 9)
8446 {
8447 p->ErrorMessage = CopyUniFormat(_UU("SEC_ERROR_OPEN_DEVICE"), dev->DeviceName);
8448 }
8449 else
8450 {
8451 p->ErrorMessage = CopyUniFormat(_UU("SEC_ERROR_OPEN_DEVICEEX"), dev->DeviceName);
8452 }
8453 }
8454 else
8455 {
8456 // Open the session
8457 SetText(hWnd, S_STATUS, _UU("SEC_OPEN_SESSION"));
8458 if (OpenSecSession(sec, 0) == false)
8459 {
8460 // Session initialization failure
8461 p->ErrorMessage = CopyUniFormat(_UU("SEC_ERROR_OPEN_SESSION"), dev->DeviceName);
8462 }
8463 else
8464 {
8465 // Login
8466 SetText(hWnd, S_STATUS, _UU("SEC_LOGIN"));
8467 if (LoginSec(sec, p->pin) == false)
8468 {
8469 // Login failure
8470 p->ErrorMessage =UniCopyStr(_UU("SEC_ERROR_LOGIN"));
8471 }
8472 else
8473 {
8474 // Batch processing main
8475 SetText(hWnd, S_STATUS, _UU("SEC_INIT_BATCH"));
8476 SecureDeviceBatch(hWnd, sec, p, dev);
8477
8478 // Logout
8479 SetText(hWnd, S_STATUS, _UU("SEC_LOGOUT"));
8480 LogoutSec(sec);
8481 }
8482
8483 // Close the session
8484 SetText(hWnd, S_STATUS, _UU("SEC_CLOSE_SESSION"));
8485 CloseSecSession(sec);
8486 }
8487
8488 // Close the device
8489 SetText(hWnd, S_STATUS, _UU("SEC_CLOSING"));
8490 CloseSec(sec);
8491 }
8492
8493 if (p->Succeed)
8494 {
8495 // If successful, show the message for 150ms (service)
8496 SetText(hWnd, S_STATUS, _UU("SEC_FINISHED"));
8497 SleepThread(150);
8498 }
8499
8500 SendMessage(p->hWnd, WM_APP + 1, 0, 0);
8501 }
8502
8503 // Start a secure device operation
StartSecureDevice(HWND hWnd,SECURE_DEVICE_WINDOW * w)8504 void StartSecureDevice(HWND hWnd, SECURE_DEVICE_WINDOW *w)
8505 {
8506 SECURE_DEVICE_THREAD *p;
8507 // Validate arguments
8508 if (hWnd == NULL || w == NULL)
8509 {
8510 return;
8511 }
8512
8513 // Disable the control
8514 EnableSecureDeviceWindowControls(hWnd, false);
8515
8516 // Start the thread
8517 p = ZeroMalloc(sizeof(SECURE_DEVICE_THREAD));
8518 p->w = w;
8519 p->hWnd = hWnd;
8520 w->p = p;
8521 p->pin = GetTextA(hWnd, E_PIN);
8522 ReleaseThread(NewThread(SecureDeviceThread, p));
8523 }
8524
8525 // Enable or disable the control of the secure device operation window
EnableSecureDeviceWindowControls(HWND hWnd,bool enable)8526 void EnableSecureDeviceWindowControls(HWND hWnd, bool enable)
8527 {
8528 // Validate arguments
8529 if (hWnd == NULL)
8530 {
8531 return;
8532 }
8533
8534 if (enable)
8535 {
8536 Show(hWnd, S_PIN_CODE);
8537 Show(hWnd, E_PIN);
8538 Show(hWnd, S_WARNING);
8539 }
8540 else
8541 {
8542 Hide(hWnd, S_PIN_CODE);
8543 Hide(hWnd, E_PIN);
8544 Hide(hWnd, S_WARNING);
8545 }
8546
8547 SetEnable(hWnd, IDOK, enable);
8548 SetEnable(hWnd, IDCANCEL, enable);
8549 SetEnable(hWnd, S_TITLE, enable);
8550 SetEnable(hWnd, S_DEVICE_INFO, enable);
8551 SetEnable(hWnd, S_INSERT_SECURE, enable);
8552
8553 if (enable == false)
8554 {
8555 DisableClose(hWnd);
8556 SetText(hWnd, S_STATUS, L"");
8557 Show(hWnd, S_STATUS);
8558 PlayAvi(hWnd, A_PROGRESS, true);
8559 }
8560 else
8561 {
8562 EnableClose(hWnd);
8563 SetText(hWnd, S_STATUS, L"");
8564 Hide(hWnd, S_STATUS);
8565 StopAvi(hWnd, A_PROGRESS);
8566 }
8567 }
8568
8569 // Secure device operation window procedure
SecureDeviceWindowProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,void * param)8570 UINT SecureDeviceWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
8571 {
8572 SECURE_DEVICE_WINDOW *w = (SECURE_DEVICE_WINDOW *)param;
8573 SECURE_DEVICE *dev = GetSecureDevice(w->device_id);
8574
8575 switch (msg)
8576 {
8577 case WM_INITDIALOG:
8578 if (dev == NULL)
8579 {
8580 MsgBoxEx(hWnd, MB_ICONEXCLAMATION, _UU("SEC_ERROR_INVALID_ID"), w->device_id);
8581 EndDialog(hWnd, 0);
8582 break;
8583 }
8584
8585 if (IsJPKI(dev->Id))
8586 {
8587 // Juki card
8588 Hide(hWnd, S_IMAGE);
8589 Show(hWnd, S_IMAGE2);
8590 Hide(hWnd, S_IMAGE_TSUKUBA);
8591 }
8592 else
8593 {
8594 // Regular card
8595 Hide(hWnd, S_IMAGE2);
8596
8597 if (w->BitmapId != 0)
8598 {
8599 // For University of Tsukuba
8600 Hide(hWnd, S_IMAGE);
8601 Show(hWnd, S_IMAGE_TSUKUBA);
8602 }
8603 else
8604 {
8605 // For general use
8606 Show(hWnd, S_IMAGE);
8607 Hide(hWnd, S_IMAGE_TSUKUBA);
8608 }
8609 }
8610
8611 FormatText(hWnd, 0, dev->Type != SECURE_USB_TOKEN ? _UU("SEC_SMART_CARD") : _UU("SEC_USB_TOKEN"),
8612 dev->DeviceName);
8613 FormatText(hWnd, S_TITLE, dev->DeviceName);
8614 FormatText(hWnd, S_INSERT_SECURE,
8615 dev->Type != SECURE_USB_TOKEN ? _UU("SEC_INIT_MSG_1") : _UU("SEC_INIT_MSG_2"));
8616 FormatText(hWnd, S_DEVICE_INFO,
8617 dev->DeviceName, dev->Manufacturer, dev->ModuleName);
8618
8619 DlgFont(hWnd, S_SOFTWARE_TITLE, 11, 0);
8620 SetText(hWnd, S_SOFTWARE_TITLE, title_bar);
8621
8622 DlgFont(hWnd, S_TITLE, 14, true);
8623 DlgFont(hWnd, S_DEVICE_INFO, 11, false);
8624 DlgFont(hWnd, S_STATUS, 13, true);
8625 EnableSecureDeviceWindowControls(hWnd, true);
8626 OpenAvi(hWnd, A_PROGRESS, AVI_PROGRESS);
8627
8628 SetIcon(hWnd, 0, ICO_KEY);
8629
8630 // Initial PIN
8631 if ((w->default_pin != NULL && StrLen(w->default_pin) != 0) || (cached_pin_code_expires >= Tick64()))
8632 {
8633 if (w->default_pin != NULL && StrLen(w->default_pin) != 0)
8634 {
8635 SetTextA(hWnd, E_PIN, w->default_pin);
8636 }
8637 else
8638 {
8639 SetTextA(hWnd, E_PIN, cached_pin_code);
8640 }
8641 SetTimer(hWnd, 1, 1, NULL);
8642 }
8643
8644 break;
8645
8646 case WM_TIMER:
8647 switch (wParam)
8648 {
8649 case 1:
8650 KillTimer(hWnd, 1);
8651 Command(hWnd, IDOK);
8652 break;
8653 }
8654 break;
8655
8656 case WM_COMMAND:
8657 switch (wParam)
8658 {
8659 case IDOK:
8660 StartSecureDevice(hWnd, w);
8661 break;
8662
8663 case IDCANCEL:
8664 Close(hWnd);
8665 break;
8666 }
8667 break;
8668
8669 case WM_CLOSE:
8670 if (IsEnable(hWnd, IDCANCEL))
8671 {
8672 CloseAvi(hWnd, A_PROGRESS);
8673 EndDialog(hWnd, false);
8674 }
8675 break;
8676
8677 case WM_APP + 1:
8678 // There is a response from the thread
8679 if (w->p != NULL)
8680 {
8681 if (w->p->Succeed)
8682 {
8683 // Success
8684 if (w->default_pin != NULL)
8685 {
8686 StrCpy(w->default_pin, 128, w->p->pin);
8687 }
8688 StrCpy(cached_pin_code, sizeof(cached_pin_code), w->p->pin);
8689 cached_pin_code_expires = Tick64() + (UINT64)WINUI_SECUREDEVICE_PIN_CACHE_TIME;
8690 Free(w->p->pin);
8691 Free(w->p);
8692 EndDialog(hWnd, true);
8693 }
8694 else
8695 {
8696 // Failure
8697 cached_pin_code_expires = 0;
8698 EnableSecureDeviceWindowControls(hWnd, true);
8699 FocusEx(hWnd, E_PIN);
8700 MsgBox(hWnd, MB_ICONEXCLAMATION, w->p->ErrorMessage);
8701 Free(w->p->pin);
8702 Free(w->p->ErrorMessage);
8703 Free(w->p);
8704 }
8705 }
8706 break;
8707 }
8708
8709 return 0;
8710 }
8711
8712 // Send a WM_COMMAND
Command(HWND hWnd,UINT id)8713 void Command(HWND hWnd, UINT id)
8714 {
8715 SendMessage(hWnd, WM_COMMAND, id, 0);
8716 }
8717
8718 // Show the secure device window
SecureDeviceWindow(HWND hWnd,WINUI_SECURE_BATCH * batch,UINT num_batch,UINT device_id,UINT bitmap_id)8719 bool SecureDeviceWindow(HWND hWnd, WINUI_SECURE_BATCH *batch, UINT num_batch, UINT device_id, UINT bitmap_id)
8720 {
8721 SECURE_DEVICE_WINDOW w;
8722 UINT i;
8723 // Validate arguments
8724 if (batch == NULL || num_batch == 0 || device_id == 0)
8725 {
8726 return false;
8727 }
8728
8729 // Initialize the success flag
8730 for (i = 0;i < num_batch;i++)
8731 {
8732 batch[i].Succeed = false;
8733 }
8734
8735 Zero(&w, sizeof(w));
8736 w.batch = batch;
8737 w.device_id = device_id;
8738 w.num_batch = num_batch;
8739 w.BitmapId = bitmap_id;
8740
8741 // Open a dialog
8742 return (bool)Dialog(hWnd, D_SECURE, SecureDeviceWindowProc, &w);
8743 }
8744
8745 // Stop playing the AVI
StopAvi(HWND hWnd,UINT id)8746 void StopAvi(HWND hWnd, UINT id)
8747 {
8748 // Validate arguments
8749 if (hWnd == NULL)
8750 {
8751 return;
8752 }
8753
8754 Animate_Stop(DlgItem(hWnd, id));
8755 Hide(hWnd, id);
8756 }
8757
8758 // Play an AVI
PlayAvi(HWND hWnd,UINT id,bool repeat)8759 void PlayAvi(HWND hWnd, UINT id, bool repeat)
8760 {
8761 // Validate arguments
8762 if (hWnd == NULL)
8763 {
8764 return;
8765 }
8766
8767 Show(hWnd, id);
8768 Animate_Play(DlgItem(hWnd, id), 0, -1, (repeat ? -1 : 0));
8769 }
8770
8771 // Close the AVI file
CloseAvi(HWND hWnd,UINT id)8772 void CloseAvi(HWND hWnd, UINT id)
8773 {
8774 // Validate arguments
8775 if (hWnd == NULL)
8776 {
8777 return;
8778 }
8779
8780 StopAvi(hWnd, id);
8781 Animate_Close(DlgItem(hWnd, id));
8782 }
8783
8784 // Open an AVI file
OpenAvi(HWND hWnd,UINT id,UINT avi_id)8785 void OpenAvi(HWND hWnd, UINT id, UINT avi_id)
8786 {
8787 // Validate arguments
8788 if (hWnd == NULL || avi_id == 0)
8789 {
8790 return;
8791 }
8792
8793 Hide(hWnd, id);
8794 Animate_OpenEx(DlgItem(hWnd, id), hDll, MAKEINTRESOURCE(avi_id));
8795 }
8796
8797 // Set the font to the control
DlgFont(HWND hWnd,UINT id,UINT size,UINT bold)8798 void DlgFont(HWND hWnd, UINT id, UINT size, UINT bold)
8799 {
8800 DIALOG_PARAM *param = (DIALOG_PARAM *)GetParam(hWnd);
8801
8802 if (param == NULL || param->meiryo == false)
8803 {
8804 SetFont(hWnd, id, Font(size, bold));
8805 }
8806 else
8807 {
8808 SetFont(hWnd, id, GetFont((_GETLANG() == 2 ? "Microsoft YaHei" : GetMeiryoFontName()), size, bold, false, false, false));
8809 }
8810 }
8811
8812 // Generate a standard font
Font(UINT size,UINT bold)8813 HFONT Font(UINT size, UINT bold)
8814 {
8815 return GetFont(NULL, size, bold, false, false, false);
8816 }
8817
8818 // Dialog procedure for internal management
InternalDialogProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)8819 UINT CALLBACK InternalDialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
8820 {
8821 DIALOG_PARAM *param = (DIALOG_PARAM *)GetParam(hWnd);
8822 void *app_param = NULL;
8823 bool white_flag = false;
8824 UINT ret;
8825 // Validate arguments
8826 if (hWnd == NULL)
8827 {
8828 return 0;
8829 }
8830
8831 if (msg == WM_INITDIALOG)
8832 {
8833 DoEvents(hWnd);
8834 }
8835
8836 if (param == NULL)
8837 {
8838 if (msg == WM_INITDIALOG)
8839 {
8840 param = (void *)lParam;
8841 InitDialogInternational(hWnd, param);
8842 }
8843 }
8844 if (param != NULL)
8845 {
8846 app_param = param->param;
8847 white_flag = param->white;
8848 }
8849
8850 ret = DlgProc(hWnd, msg, wParam, lParam, white_flag);
8851 if (ret != 0)
8852 {
8853 return ret;
8854 }
8855
8856 ret = 0;
8857
8858 if (param != NULL)
8859 {
8860 if (param->proc != NULL)
8861 {
8862 ret = param->proc(hWnd, msg, wParam, lParam, app_param);
8863 }
8864 else
8865 {
8866 if (msg == WM_CLOSE)
8867 {
8868 EndDialog(hWnd, 0);
8869 }
8870 else if (msg == WM_COMMAND && (wParam == IDOK || wParam == IDCANCEL))
8871 {
8872 Close(hWnd);
8873 }
8874 }
8875 }
8876
8877 if (msg == WM_INITDIALOG)
8878 {
8879 SetForegroundWindow(hWnd);
8880 SetActiveWindow(hWnd);
8881 }
8882
8883 return ret;
8884 }
8885
8886 // Show a dialog box
Dialog(HWND hWnd,UINT id,WINUI_DIALOG_PROC * proc,void * param)8887 UINT Dialog(HWND hWnd, UINT id, WINUI_DIALOG_PROC *proc, void *param)
8888 {
8889 bool white = true;
8890
8891 return DialogEx(hWnd, id, proc, param, white);
8892 }
DialogEx(HWND hWnd,UINT id,WINUI_DIALOG_PROC * proc,void * param,bool white)8893 UINT DialogEx(HWND hWnd, UINT id, WINUI_DIALOG_PROC *proc, void *param, bool white)
8894 {
8895 return DialogEx2(hWnd, id, proc, param, white, false);
8896 }
DialogEx2(HWND hWnd,UINT id,WINUI_DIALOG_PROC * proc,void * param,bool white,bool meiryo)8897 UINT DialogEx2(HWND hWnd, UINT id, WINUI_DIALOG_PROC *proc, void *param, bool white, bool meiryo)
8898 {
8899 UINT ret;
8900 DIALOG_PARAM p;
8901 // Validate arguments
8902 if (id == 0)
8903 {
8904 return 0;
8905 }
8906
8907 Zero(&p, sizeof(p));
8908 p.param = param;
8909 p.white = white;
8910 p.proc = proc;
8911
8912 p.BitmapList = NewBitmapList();
8913
8914 if (MsIsVista())
8915 {
8916 p.meiryo = meiryo;
8917 }
8918
8919 ret = DialogInternal(hWnd, id, InternalDialogProc, &p);
8920
8921 FreeBitmapList(p.BitmapList);
8922
8923 return ret;
8924 }
8925
8926 // Create a modeless dialog
DialogCreateEx(HWND hWnd,UINT id,WINUI_DIALOG_PROC * proc,void * param,bool white)8927 HWND DialogCreateEx(HWND hWnd, UINT id, WINUI_DIALOG_PROC *proc, void *param, bool white)
8928 {
8929 HWND ret = NULL;
8930 DIALOG_PARAM p;
8931 // Validate arguments
8932 if (id == 0)
8933 {
8934 return 0;
8935 }
8936
8937 Zero(&p, sizeof(p));
8938 p.param = param;
8939 p.white = white;
8940 p.proc = proc;
8941
8942 if (MsIsNt() == false)
8943 {
8944 // Win9x
8945 ret = CreateDialogParamA(hDll, MAKEINTRESOURCEA(id), hWnd,
8946 (DLGPROC)proc, (LPARAM)param);
8947 }
8948 else
8949 {
8950 // WinNT
8951 ret = CreateDialogParamW(hDll, MAKEINTRESOURCEW(id), hWnd,
8952 (DLGPROC)proc, (LPARAM)param);
8953 }
8954
8955 return ret;
8956 }
8957
8958 // Set the bitmap to the button
SetBitmap(HWND hWnd,UINT id,UINT bmp_id)8959 void SetBitmap(HWND hWnd, UINT id, UINT bmp_id)
8960 {
8961 HBITMAP bmp;
8962 char *class_name;
8963 DIALOG_PARAM *dialog_param = NULL;
8964 bool need_resize = 0;
8965 double resize_x = 1.0;
8966 double resize_y = 1.0;
8967 bool add_to_free_list = false;
8968 // Validate arguments
8969 if (hWnd == NULL)
8970 {
8971 return;
8972 }
8973
8974 bmp = LoadImage(hDll, MAKEINTRESOURCE(bmp_id), IMAGE_BITMAP, 0, 0, (MsIsNt() ? LR_SHARED : 0) | LR_VGACOLOR);
8975 if (bmp == NULL)
8976 {
8977 return;
8978 }
8979
8980 dialog_param = GetParam(hWnd);
8981
8982 // Determine the need for resizing
8983 if (dialog_param)
8984 {
8985 if (MsIsVista())
8986 {
8987 GetWindowAndControlSizeResizeScale(hWnd, &need_resize, &resize_x, &resize_y);
8988
8989 if (need_resize)
8990 {
8991 // Resize
8992 UINT src_x, src_y, dst_x, dst_y;
8993
8994 if (GetBitmapSize(bmp, &src_x, &src_y))
8995 {
8996 HBITMAP new_bmp;
8997 double scale_factor = MIN(resize_x, resize_y);
8998
8999 dst_x = (UINT)((double)src_x * scale_factor);
9000 dst_y = (UINT)((double)src_y * scale_factor);
9001
9002 new_bmp = ResizeBitmap(bmp, src_x, src_y, dst_x, dst_y);
9003
9004 if (new_bmp != NULL)
9005 {
9006 bmp = new_bmp;
9007
9008 add_to_free_list = true;
9009 }
9010 }
9011 }
9012 }
9013 }
9014
9015 class_name = GetClassA(hWnd, id);
9016
9017 if (StrCmpi(class_name, "Static") != 0)
9018 {
9019 SendMsg(hWnd, id, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)bmp);
9020 }
9021 else
9022 {
9023 SendMsg(hWnd, id, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)bmp);
9024 }
9025
9026 Free(class_name);
9027
9028 if (add_to_free_list)
9029 {
9030 Add(dialog_param->BitmapList, bmp);
9031 }
9032 }
9033
9034 // Initialize the icon cache
InitIconCache()9035 void InitIconCache()
9036 {
9037 if (icon_cache_list != NULL)
9038 {
9039 return;
9040 }
9041
9042 icon_cache_list = NewList(NULL);
9043 }
9044
9045 // Release the icon cache
FreeIconCache()9046 void FreeIconCache()
9047 {
9048 UINT i;
9049 if (icon_cache_list == NULL)
9050 {
9051 return;
9052 }
9053
9054 for (i = 0;i < LIST_NUM(icon_cache_list);i++)
9055 {
9056 ICON_CACHE *c = LIST_DATA(icon_cache_list, i);
9057 DestroyIcon(c->hIcon);
9058 Free(c);
9059 }
9060
9061 ReleaseList(icon_cache_list);
9062 icon_cache_list = NULL;
9063 }
9064
9065 // Get the Icon
LoadIconEx(UINT id,bool small_icon)9066 HICON LoadIconEx(UINT id, bool small_icon)
9067 {
9068 HICON h = NULL;
9069 UINT i;
9070 if (icon_cache_list == NULL)
9071 {
9072 return small_icon == false ? LoadLargeIconInner(id) : LoadSmallIconInner(id);
9073 }
9074
9075 LockList(icon_cache_list);
9076 {
9077 for (i = 0;i < LIST_NUM(icon_cache_list);i++)
9078 {
9079 ICON_CACHE *c = LIST_DATA(icon_cache_list, i);
9080 if (c->id == id && c->small_icon == small_icon)
9081 {
9082 h = c->hIcon;
9083 break;
9084 }
9085 }
9086
9087 if (h == NULL)
9088 {
9089 h = small_icon == false ? LoadLargeIconInner(id) : LoadSmallIconInner(id);
9090 if (h != NULL)
9091 {
9092 ICON_CACHE *c = ZeroMalloc(sizeof(ICON_CACHE));
9093 c->hIcon = h;
9094 c->id = id;
9095 c->small_icon = small_icon;
9096 Add(icon_cache_list, c);
9097 }
9098 }
9099 }
9100 UnlockList(icon_cache_list);
9101
9102 return h;
9103 }
9104
9105 // Get a large Icon
LoadLargeIcon(UINT id)9106 HICON LoadLargeIcon(UINT id)
9107 {
9108 return LoadIconEx(id, false);
9109 }
9110
9111 // Get a small icon
LoadSmallIcon(UINT id)9112 HICON LoadSmallIcon(UINT id)
9113 {
9114 return LoadIconEx(id, true);
9115 }
9116
9117 // Get a large icon
LoadLargeIconInner(UINT id)9118 HICON LoadLargeIconInner(UINT id)
9119 {
9120 HICON ret;
9121 ret = LoadImage(hDll, MAKEINTRESOURCE(id), IMAGE_ICON, 32, 32, 0);
9122 if (ret == NULL)
9123 {
9124 ret = LoadImage(hDll, MAKEINTRESOURCE(id), IMAGE_ICON, 32, 32, LR_VGACOLOR);
9125 if (ret == NULL)
9126 {
9127 ret = LoadImage(hDll, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, 0);
9128 if (ret == NULL)
9129 {
9130 ret = LoadImage(hDll, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_VGACOLOR);
9131 if (ret == NULL)
9132 {
9133 ret = LoadIcon(hDll, MAKEINTRESOURCE(id));
9134 }
9135 }
9136 }
9137 }
9138 return ret;
9139 }
9140
9141 // Get a small icon
LoadSmallIconInner(UINT id)9142 HICON LoadSmallIconInner(UINT id)
9143 {
9144 HICON ret;
9145 ret = LoadImage(hDll, MAKEINTRESOURCE(id), IMAGE_ICON, 16, 16, 0);
9146 if (ret == NULL)
9147 {
9148 ret = LoadImage(hDll, MAKEINTRESOURCE(id), IMAGE_ICON, 16, 16, LR_VGACOLOR);
9149 if (ret == NULL)
9150 {
9151 ret = LoadImage(hDll, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, 0);
9152 if (ret == NULL)
9153 {
9154 ret = LoadImage(hDll, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_VGACOLOR);
9155 if (ret == NULL)
9156 {
9157 ret = LoadLargeIconInner(id);
9158 }
9159 }
9160 }
9161 }
9162 return ret;
9163 }
9164
9165 // Set the icon to the button or window
SetIcon(HWND hWnd,UINT id,UINT icon_id)9166 void SetIcon(HWND hWnd, UINT id, UINT icon_id)
9167 {
9168 HICON icon1, icon2;
9169 // Validate arguments
9170 if (hWnd == NULL)
9171 {
9172 return;
9173 }
9174
9175 icon1 = LoadLargeIcon(icon_id);
9176 if (icon1 == NULL)
9177 {
9178 return;
9179 }
9180
9181 if (id == 0)
9182 {
9183 SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)icon1);
9184 icon2 = LoadSmallIcon(icon_id);
9185 if (icon2 == NULL)
9186 {
9187 icon2 = icon1;
9188 }
9189 SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)icon2);
9190 }
9191 else
9192 {
9193 bool is_btn = true;
9194 wchar_t *s = GetClass(hWnd, id);
9195 if (s != NULL)
9196 {
9197 if (UniStrCmpi(s, L"Static") == 0)
9198 {
9199 is_btn = false;
9200 }
9201 Free(s);
9202 }
9203
9204 if (is_btn)
9205 {
9206 SendMsg(hWnd, id, BM_SETIMAGE, IMAGE_ICON, (LPARAM)icon1);
9207 }
9208 else
9209 {
9210 SendMsg(hWnd, id, STM_SETICON, (WPARAM)icon1, 0);
9211 }
9212 }
9213 }
9214
9215 // Check whether the radio button is checked
IsChecked(HWND hWnd,UINT id)9216 bool IsChecked(HWND hWnd, UINT id)
9217 {
9218 // Validate arguments
9219 if (hWnd == NULL)
9220 {
9221 return false;
9222 }
9223
9224 return IsDlgButtonChecked(hWnd, id) == BST_CHECKED ? true : false;
9225 }
9226
9227 // Check the radio button
Check(HWND hWnd,UINT id,bool b)9228 void Check(HWND hWnd, UINT id, bool b)
9229 {
9230 // Validate arguments
9231 if (hWnd == NULL)
9232 {
9233 return;
9234 }
9235
9236 if ((!(!IsChecked(hWnd, id))) != (!(!b)))
9237 {
9238 CheckDlgButton(hWnd, id, b ? BST_CHECKED : BST_UNCHECKED);
9239 }
9240 }
9241
9242 // Confirm that the character size of the text-box is less than or equal to specified size
CheckTextSize(HWND hWnd,UINT id,UINT size,bool unicode)9243 bool CheckTextSize(HWND hWnd, UINT id, UINT size, bool unicode)
9244 {
9245 // Validate arguments
9246 if (hWnd == NULL)
9247 {
9248 return false;
9249 }
9250
9251 if (GetTextSize(hWnd, id, unicode) <= size)
9252 {
9253 return true;
9254 }
9255 else
9256 {
9257 return false;
9258 }
9259 }
9260
9261 // Confirm that a length of the string in the text-box is less than or equal to the specified size
CheckTextLen(HWND hWnd,UINT id,UINT len,bool unicode)9262 bool CheckTextLen(HWND hWnd, UINT id, UINT len, bool unicode)
9263 {
9264 // Validate arguments
9265 if (hWnd == NULL)
9266 {
9267 return false;
9268 }
9269
9270 if (GetTextLen(hWnd, id, unicode) <= len)
9271 {
9272 return true;
9273 }
9274 else
9275 {
9276 return false;
9277 }
9278 }
9279
9280 // Limit the number of characters that can be entered into the text-box
LimitText(HWND hWnd,UINT id,UINT count)9281 void LimitText(HWND hWnd, UINT id, UINT count)
9282 {
9283 // Validate arguments
9284 if (hWnd == NULL)
9285 {
9286 return;
9287 }
9288
9289 SendMsg(hWnd, id, EM_LIMITTEXT, count, 0);
9290 }
9291
9292 // Font settings
SetFont(HWND hWnd,UINT id,HFONT hFont)9293 void SetFont(HWND hWnd, UINT id, HFONT hFont)
9294 {
9295 SetFontEx(hWnd, id, hFont, false);
9296 }
SetFontEx(HWND hWnd,UINT id,HFONT hFont,bool no_adjust_font_size)9297 void SetFontEx(HWND hWnd, UINT id, HFONT hFont, bool no_adjust_font_size)
9298 {
9299 // Validate arguments
9300 if (hWnd == NULL || hFont == NULL)
9301 {
9302 return;
9303 }
9304
9305 SendMessage(DlgItem(hWnd, id), WM_SETFONT, (WPARAM)hFont, true);
9306
9307 if (no_adjust_font_size == false)
9308 {
9309 AdjustFontSize(hWnd, id);
9310 }
9311 }
9312
9313 // Get the font size
GetFontSize(HFONT hFont,UINT * x,UINT * y)9314 bool GetFontSize(HFONT hFont, UINT *x, UINT *y)
9315 {
9316 bool ret = false;
9317 UINT xx = 0;
9318 UINT yy = 0;
9319
9320 // Search for the font handle
9321 LockList(font_list);
9322 {
9323 UINT i;
9324
9325 for (i = 0;i < LIST_NUM(font_list);i++)
9326 {
9327 FONT *f = LIST_DATA(font_list, i);
9328
9329 if (f->hFont == hFont)
9330 {
9331 xx = f->x;
9332 yy = f->y;
9333
9334 ret = true;
9335 break;
9336 }
9337 }
9338 }
9339 UnlockList(font_list);
9340
9341 if (ret == false)
9342 {
9343 ret = CalcFontSize(hFont, &xx, &yy);
9344 }
9345
9346 if (xx == 0 || yy == 0)
9347 {
9348 xx = 8;
9349 yy = 16;
9350 }
9351
9352 if (x != NULL)
9353 {
9354 *x = xx;
9355 }
9356
9357 if (y != NULL)
9358 {
9359 *y = yy;
9360 }
9361
9362 return ret;
9363 }
9364
9365 // Calculate the font size
CalcFontSize(HFONT hFont,UINT * x,UINT * y)9366 bool CalcFontSize(HFONT hFont, UINT *x, UINT *y)
9367 {
9368 UINT xx = 0, yy = 0;
9369 TEXTMETRIC tm;
9370 SIZE sz;
9371 bool ret = false;
9372 HDC hDC;
9373
9374 hDC = CreateCompatibleDC(NULL);
9375
9376 SelectObject(hDC, hFont);
9377
9378 Zero(&tm, sizeof(tm));
9379 Zero(&sz, sizeof(sz));
9380
9381 if (GetTextMetrics(hDC, &tm))
9382 {
9383 xx = tm.tmAveCharWidth;
9384 yy = tm.tmHeight;
9385
9386 ret = true;
9387
9388 if (GetTextExtentPoint32(hDC,
9389 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
9390 52, &sz))
9391 {
9392 xx = (sz.cx / 26 + 1) / 2;
9393 }
9394 }
9395
9396 if (x != NULL)
9397 {
9398 *x = xx;
9399 }
9400
9401 if (y != NULL)
9402 {
9403 *y = yy;
9404 }
9405
9406 DeleteDC(hDC);
9407
9408 return ret;
9409 }
9410
9411 // Get the font magnification
GetTextScalingFactor()9412 double GetTextScalingFactor()
9413 {
9414 static int cached_dpi = 0;
9415 double ret = 1.0;
9416
9417 if (MsIsVista() == false)
9418 {
9419 // It's always 1.0 in Windows XP or earlier
9420 return 1.0;
9421 }
9422
9423 if (cached_dpi == 0)
9424 {
9425 HDC hDC = CreateCompatibleDC(NULL);
9426
9427 if (hDC != NULL)
9428 {
9429 cached_dpi = GetDeviceCaps(hDC, LOGPIXELSY);
9430
9431 DeleteDC(hDC);
9432 }
9433 }
9434
9435 if (cached_dpi != 0)
9436 {
9437 ret = (double)cached_dpi / 96.0;
9438
9439 if (ret < 0)
9440 {
9441 ret = -ret;
9442 }
9443 }
9444
9445 return ret;
9446 }
9447
9448 // Get the parameters of the font that was created in the past
GetFontParam(HFONT hFont,struct FONT * f)9449 bool GetFontParam(HFONT hFont, struct FONT *f)
9450 {
9451 bool ret = false;
9452 // Validate arguments
9453 if (hFont == NULL || f == NULL)
9454 {
9455 return false;
9456 }
9457
9458 // Search for the existing font
9459 LockList(font_list);
9460 {
9461 UINT i;
9462
9463 for (i = 0;i < LIST_NUM(font_list);i++)
9464 {
9465 FONT *n = LIST_DATA(font_list, i);
9466
9467 if (n->hFont == hFont)
9468 {
9469 Copy(f, n, sizeof(FONT));
9470
9471 ret = true;
9472
9473 break;
9474 }
9475 }
9476 }
9477 UnlockList(font_list);
9478
9479 return ret;
9480 }
9481
9482 // Get the font
GetFont(char * name,UINT size,bool bold,bool italic,bool underline,bool strikeout)9483 HFONT GetFont(char *name, UINT size, bool bold, bool italic, bool underline, bool strikeout)
9484 {
9485 HFONT hFont;
9486 HDC hDC;
9487 // Validate arguments
9488 if (name == NULL)
9489 {
9490 name = font_name;
9491 }
9492 if (size == 0)
9493 {
9494 size = font_size;
9495 if (size == 0)
9496 {
9497 size = 9;
9498 }
9499 }
9500
9501 // Search for the existing font
9502 LockList(font_list);
9503 {
9504 FONT *f, t;
9505 DWORD font_quality = ANTIALIASED_QUALITY;
9506 OS_INFO *os = GetOsInfo();
9507 UINT x = 0;
9508 UINT y = 0;
9509 int rotate = 0;
9510 UINT dpi;
9511
9512 Zero(&t, sizeof(t));
9513 t.Bold = bold;
9514 t.Italic = italic;
9515 t.Size = size;
9516 t.StrikeOut = strikeout;
9517 t.UnderLine = underline;
9518 t.Name = CopyStr(name);
9519 f = Search(font_list, &t);
9520 Free(t.Name);
9521
9522 if (f != NULL)
9523 {
9524 // Font is found
9525 UnlockList(font_list);
9526 return f->hFont;
9527 }
9528
9529 // Create a new font
9530 hDC = CreateCompatibleDC(NULL);
9531
9532 // Specify the ClearType in Windows XP or later
9533 if (OS_IS_WINDOWS_NT(os->OsType) && GET_KETA(os->OsType, 100) >= 3)
9534 {
9535 font_quality = CLEARTYPE_NATURAL_QUALITY;
9536 rotate = 3600;
9537 }
9538
9539 if (MsIsVista())
9540 {
9541 dpi = GetDeviceCaps(hDC, LOGPIXELSY);
9542 }
9543 else
9544 {
9545 dpi = 96;
9546 }
9547
9548 // Create a font
9549 hFont = CreateFontA(-MulDiv(size, dpi, 72),
9550 0, rotate, rotate, (bold == false ? 500 : FW_BOLD),
9551 italic, underline, strikeout, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
9552 CLIP_DEFAULT_PRECIS, font_quality, DEFAULT_PITCH, name);
9553
9554 if (hFont == NULL)
9555 {
9556 // Failure
9557 DeleteDC(hDC);
9558 UnlockList(font_list);
9559
9560 return NULL;
9561 }
9562
9563 CalcFontSize(hFont, &x, &y);
9564
9565 // Add to the table
9566 f = ZeroMalloc(sizeof(FONT));
9567 f->Bold = bold;
9568 f->hFont = hFont;
9569 f->Italic = italic;
9570 f->Name = CopyStr(name);
9571 f->Size = size;
9572 f->StrikeOut = strikeout;
9573 f->UnderLine = underline;
9574 f->x = x;
9575 f->y = y;
9576
9577 Insert(font_list, f);
9578
9579 DeleteDC(hDC);
9580 }
9581 UnlockList(font_list);
9582
9583 return hFont;
9584 }
9585
9586 // Comparison of the font
CompareFont(void * p1,void * p2)9587 int CompareFont(void *p1, void *p2)
9588 {
9589 FONT *f1, *f2;
9590 UINT r;
9591 if (p1 == NULL || p2 == NULL)
9592 {
9593 return 0;
9594 }
9595 f1 = *(FONT **)p1;
9596 f2 = *(FONT **)p2;
9597 if (f1 == NULL || f2 == NULL)
9598 {
9599 return 0;
9600 }
9601 r = StrCmpi(f1->Name, f2->Name);
9602 if (r != 0)
9603 {
9604 return r;
9605 }
9606 else
9607 {
9608 if (f1->Bold > f2->Bold)
9609 {
9610 return 1;
9611 }
9612 else if (f1->Bold < f2->Bold)
9613 {
9614 return -1;
9615 }
9616 else if (f1->Italic > f2->Italic)
9617 {
9618 return 1;
9619 }
9620 else if (f1->Italic < f2->Italic)
9621 {
9622 return -1;
9623 }
9624 else if (f1->Size > f2->Size)
9625 {
9626 return 1;
9627 }
9628 else if (f1->Size < f2->Size)
9629 {
9630 return -1;
9631 }
9632 else if (f1->StrikeOut > f2->StrikeOut)
9633 {
9634 return 1;
9635 }
9636 else if (f1->StrikeOut < f2->StrikeOut)
9637 {
9638 return -1;
9639 }
9640 else if (f1->UnderLine > f2->UnderLine)
9641 {
9642 return 1;
9643 }
9644 else if (f1->UnderLine < f2->UnderLine)
9645 {
9646 return -1;
9647 }
9648 else
9649 {
9650 return 0;
9651 }
9652 }
9653 }
9654
9655 // Initialize the font
InitFont()9656 void InitFont()
9657 {
9658 if (font_list != NULL)
9659 {
9660 return;
9661 }
9662 font_list = NewList(CompareFont);
9663 }
9664
9665 // Release the font
FreeFont()9666 void FreeFont()
9667 {
9668 UINT i;
9669 if (font_list == NULL)
9670 {
9671 return;
9672 }
9673 for (i = 0;i < LIST_NUM(font_list);i++)
9674 {
9675 FONT *f = LIST_DATA(font_list, i);
9676 Free(f->Name);
9677 DeleteObject((HGDIOBJ)f->hFont);
9678 Free(f);
9679 }
9680 ReleaseList(font_list);
9681 font_list = NULL;
9682 }
9683
9684 // Show a button to close the window
EnableClose(HWND hWnd)9685 void EnableClose(HWND hWnd)
9686 {
9687 HMENU h;
9688 // Validate arguments
9689 if (hWnd == NULL)
9690 {
9691 return;
9692 }
9693
9694 h = GetSystemMenu(hWnd, false);
9695 EnableMenuItem(h, SC_CLOSE, MF_ENABLED);
9696 DrawMenuBar(hWnd);
9697 }
9698
9699 // Hide the button to close the window
DisableClose(HWND hWnd)9700 void DisableClose(HWND hWnd)
9701 {
9702 HMENU h;
9703 // Validate arguments
9704 if (hWnd == NULL)
9705 {
9706 return;
9707 }
9708
9709 h = GetSystemMenu(hWnd, false);
9710 EnableMenuItem(h, SC_CLOSE, MF_GRAYED);
9711 DrawMenuBar(hWnd);
9712 }
9713
9714 // Move to the center of the parent window
CenterParent(HWND hWnd)9715 void CenterParent(HWND hWnd)
9716 {
9717 RECT rp;
9718 RECT r;
9719 HWND hWndParent = GetParent(hWnd);
9720 int win_x, win_y;
9721 int x, y;
9722
9723 if (hWndParent == NULL || IsHide(hWndParent, 0) || IsIconic(hWndParent))
9724 {
9725 Center(hWnd);
9726 return;
9727 }
9728
9729 if (GetWindowRect(hWndParent, &rp) == false)
9730 {
9731 Center(hWnd);
9732 return;
9733 }
9734
9735 GetWindowRect(hWnd, &r);
9736
9737 win_x = r.right - r.left;
9738 win_y = r.bottom - r.top;
9739
9740 x = (rp.right - rp.left - win_x) / 2 + rp.left;
9741 y = (rp.bottom - rp.top - win_y) / 2 + rp.top;
9742
9743 x = MAX(x, 0);
9744 y = MAX(y, 0);
9745
9746 SetWindowPos(hWnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
9747 }
9748
9749 // Get the coordinates of the client region of the window
GetWindowClientRect(HWND hWnd,struct tagRECT * rect)9750 void GetWindowClientRect(HWND hWnd, struct tagRECT *rect)
9751 {
9752 RECT r1, r2;
9753 HWND hParent;
9754 WINDOWINFO info;
9755 Zero(rect, sizeof(RECT));
9756 // Validate arguments
9757 if (hWnd == NULL || rect == NULL)
9758 {
9759 return;
9760 }
9761
9762 hParent = GetParent(hWnd);
9763 if (hParent == NULL)
9764 {
9765 return;
9766 }
9767
9768 Zero(&info, sizeof(info));
9769 info.cbSize = sizeof(WINDOWINFO);
9770
9771 if (GetWindowInfo(hParent, &info) == false)
9772 {
9773 return;
9774 }
9775
9776 if (GetWindowRect(hWnd, &r1) == false ||
9777 GetWindowRect(hParent, &r2) == false)
9778 {
9779 return;
9780 }
9781
9782 rect->left = r1.left - r2.left - (info.rcClient.left - info.rcWindow.left);
9783 rect->right = r1.right - r2.left - (info.rcClient.left - info.rcWindow.left);
9784 rect->top = r1.top - r2.top - (info.rcClient.top - info.rcWindow.top);
9785 rect->bottom = r1.bottom - r2.top - (info.rcClient.top - info.rcWindow.top);
9786 }
9787
9788 // Move the window to the center
Center(HWND hWnd)9789 void Center(HWND hWnd)
9790 {
9791 RECT screen;
9792 RECT win;
9793 UINT x, y;
9794 UINT win_x, win_y;
9795 // Validate arguments
9796 if (hWnd == NULL)
9797 {
9798 return;
9799 }
9800
9801 if (SystemParametersInfo(SPI_GETWORKAREA, 0, &screen, 0) == false)
9802 {
9803 return;
9804 }
9805
9806 GetWindowRect(hWnd, &win);
9807 win_x = win.right - win.left;
9808 win_y = win.bottom - win.top;
9809
9810 if (win_x < (UINT)(screen.right - screen.left))
9811 {
9812 x = (screen.right - screen.left - win_x) / 2;
9813 }
9814 else
9815 {
9816 x = 0;
9817 }
9818
9819 if (win_y < (UINT)(screen.bottom - screen.top))
9820 {
9821 y = (screen.bottom - screen.top - win_y) / 2;
9822 }
9823 else
9824 {
9825 y = 0;
9826 }
9827
9828 SetWindowPos(hWnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
9829 }
9830
9831 // Move the window to the center 2
Center2(HWND hWnd)9832 void Center2(HWND hWnd)
9833 {
9834 RECT screen;
9835 RECT win;
9836 UINT x, y;
9837 UINT win_x, win_y;
9838 // Validate arguments
9839 if (hWnd == NULL)
9840 {
9841 return;
9842 }
9843
9844 if (SystemParametersInfo(SPI_GETWORKAREA, 0, &screen, 0) == false)
9845 {
9846 return;
9847 }
9848
9849 GetWindowRect(hWnd, &win);
9850 win_x = win.right - win.left;
9851 win_y = win.bottom - win.top;
9852
9853 if (win_x < (UINT)(screen.right - screen.left))
9854 {
9855 x = (screen.right - screen.left - win_x) / 2;
9856 }
9857 else
9858 {
9859 x = 0;
9860 }
9861
9862 if (win_y < (UINT)(screen.bottom - screen.top))
9863 {
9864 y = (screen.bottom - screen.top - win_y) / 4;
9865 }
9866 else
9867 {
9868 y = 0;
9869 }
9870
9871 SetWindowPos(hWnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
9872 }
9873
9874 // Get the size of the monitor
GetMonitorSize(UINT * width,UINT * height)9875 void GetMonitorSize(UINT *width, UINT *height)
9876 {
9877 // Validate arguments
9878 if (width == NULL || height == NULL)
9879 {
9880 return;
9881 }
9882
9883 *width = GetSystemMetrics(SM_CXSCREEN);
9884 *height = GetSystemMetrics(SM_CYSCREEN);
9885 }
9886
9887 // Format the string in the window
FormatText(HWND hWnd,UINT id,...)9888 void FormatText(HWND hWnd, UINT id, ...)
9889 {
9890 va_list args;
9891 wchar_t *buf;
9892 UINT size;
9893 wchar_t *str;
9894 // Validate arguments
9895 if (hWnd == NULL)
9896 {
9897 return;
9898 }
9899
9900 str = GetText(hWnd, id);
9901 if (str == NULL)
9902 {
9903 return;
9904 }
9905
9906 size = MAX(UniStrSize(str) * 10, MAX_SIZE * 10);
9907 buf = MallocEx(size, true);
9908
9909 va_start(args, id);
9910 UniFormatArgs(buf, size, str, args);
9911
9912 SetText(hWnd, id, buf);
9913
9914 Free(buf);
9915
9916 Free(str);
9917 va_end(args);
9918 }
FormatTextA(HWND hWnd,UINT id,...)9919 void FormatTextA(HWND hWnd, UINT id, ...)
9920 {
9921 va_list args;
9922 char *buf;
9923 UINT size;
9924 char *str;
9925 // Validate arguments
9926 if (hWnd == NULL)
9927 {
9928 return;
9929 }
9930
9931 str = GetTextA(hWnd, id);
9932 if (str == NULL)
9933 {
9934 return;
9935 }
9936
9937 size = MAX(StrSize(str) * 10, MAX_SIZE * 10);
9938 buf = MallocEx(size, true);
9939
9940 va_start(args, id);
9941 FormatArgs(buf, size, str, args);
9942
9943 SetTextA(hWnd, id, buf);
9944
9945 Free(buf);
9946
9947 Free(str);
9948 va_end(args);
9949 }
9950
9951 // Set a variable-length argument string to the window
SetTextEx(HWND hWnd,UINT id,wchar_t * str,...)9952 void SetTextEx(HWND hWnd, UINT id, wchar_t *str, ...)
9953 {
9954 va_list args;
9955 wchar_t *buf;
9956 UINT size;
9957 // Validate arguments
9958 if (str == NULL || hWnd == NULL)
9959 {
9960 return;
9961 }
9962
9963 size = MAX(UniStrSize(str) * 10, MAX_SIZE * 10);
9964 buf = MallocEx(size, true);
9965
9966 va_start(args, str);
9967 UniFormatArgs(buf, size, str, args);
9968
9969 SetText(hWnd, id, buf);
9970
9971 Free(buf);
9972 va_end(args);
9973 }
SetTextExA(HWND hWnd,UINT id,char * str,...)9974 void SetTextExA(HWND hWnd, UINT id, char *str, ...)
9975 {
9976 va_list args;
9977 char *buf;
9978 UINT size;
9979 // Validate arguments
9980 if (str == NULL || hWnd == NULL)
9981 {
9982 return;
9983 }
9984
9985 size = MAX(StrSize(str) * 10, MAX_SIZE * 10);
9986 buf = MallocEx(size, true);
9987
9988 va_start(args, str);
9989 FormatArgs(buf, size, str, args);
9990
9991 SetTextA(hWnd, id, buf);
9992
9993 Free(buf);
9994 va_end(args);
9995 }
9996
9997 // Show the variable-length message box
MsgBoxEx(HWND hWnd,UINT flag,wchar_t * msg,...)9998 UINT MsgBoxEx(HWND hWnd, UINT flag, wchar_t *msg, ...)
9999 {
10000 va_list args;
10001 wchar_t *buf;
10002 UINT size;
10003 UINT ret;
10004 // Validate arguments
10005 if (msg == NULL)
10006 {
10007 msg = L"MessageBox";
10008 }
10009
10010 size = MAX(UniStrSize(msg) * 10, MAX_SIZE * 10);
10011 buf = MallocEx(size, true);
10012
10013 va_start(args, msg);
10014 UniFormatArgs(buf, size, msg, args);
10015
10016 ret = MsgBox(hWnd, flag, buf);
10017 Free(buf);
10018 va_end(args);
10019
10020 return ret;
10021 }
10022
10023 // Show the message box
MsgBox(HWND hWnd,UINT flag,wchar_t * msg)10024 UINT MsgBox(HWND hWnd, UINT flag, wchar_t *msg)
10025 {
10026 UINT ret;
10027 wchar_t *title;
10028 // Validate arguments
10029 if (msg == NULL)
10030 {
10031 msg = L"MessageBox";
10032 }
10033
10034 if (title_bar != NULL)
10035 {
10036 title = CopyUniStr(title_bar);
10037 }
10038 else
10039 {
10040 title = CopyStrToUni(CEDAR_PRODUCT_STR);
10041 }
10042
10043 if (hWnd)
10044 {
10045 // Raise the message box to top-level if the parent window is the top-level window
10046 if (GetExStyle(hWnd, 0) & WS_EX_TOPMOST)
10047 {
10048 flag |= MB_SYSTEMMODAL;
10049 }
10050 }
10051
10052 ret = MessageBoxW(hWnd, msg, title, flag);
10053
10054 Free(title);
10055
10056 return ret;
10057 }
10058
10059 // Create a dialog (internal)
DialogInternal(HWND hWnd,UINT id,DIALOG_PROC * proc,void * param)10060 UINT DialogInternal(HWND hWnd, UINT id, DIALOG_PROC *proc, void *param)
10061 {
10062 // Validate arguments
10063 if (proc == NULL)
10064 {
10065 return 0;
10066 }
10067
10068 if (MsIsNt() == false)
10069 {
10070 // Win9x
10071 return (UINT)DialogBoxParam(hDll, MAKEINTRESOURCE(id), hWnd, (DLGPROC)proc, (LPARAM)param);
10072 }
10073 else
10074 {
10075 // WinNT
10076 return (UINT)DialogBoxParamW(hDll, MAKEINTRESOURCEW(id), hWnd, (DLGPROC)proc, (LPARAM)param);
10077 }
10078 }
10079
10080 // Notice that the system configuration has been updated
NoticeSettingChange()10081 void NoticeSettingChange()
10082 {
10083 PostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0);
10084 DoEvents(NULL);
10085 }
10086
10087 // Dialog box procedure managed by WinUi
DlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,bool white_color)10088 UINT DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, bool white_color)
10089 {
10090 void *param;
10091 HWND hWndParent;
10092 // Validate arguments
10093 if (hWnd == NULL)
10094 {
10095 return 0;
10096 }
10097
10098 switch (msg)
10099 {
10100 case WM_INITDIALOG:
10101 if (true)
10102 {
10103 RECT rect1;
10104
10105 SetRect(&rect1, 0, 0, 100, 100);
10106 MapDialogRect(hWnd, &rect1);
10107 Debug("%u %u %u %u\n", rect1.left, rect1.right, rect1.top, rect1.bottom);
10108 }
10109
10110 param = (void *)lParam;
10111 SetParam(hWnd, param);
10112
10113 // Examine whether the parent window exists
10114 hWndParent = GetParent(hWnd);
10115 if (hWndParent == NULL || IsShow(hWndParent, 0) == false)
10116 {
10117 // Place in the center if parent does not exist
10118 Center(hWnd);
10119 }
10120
10121 if (UseAlpha)
10122 {
10123 UINT os_type = GetOsInfo()->OsType;
10124 if (OS_IS_WINDOWS_NT(os_type) && GET_KETA(os_type, 100) >= 2)
10125 {
10126 bool (WINAPI *_SetLayeredWindowAttributes)(HWND, COLORREF, BYTE, DWORD);
10127 HINSTANCE hInst;
10128
10129 hInst = LoadLibrary("user32.dll");
10130 _SetLayeredWindowAttributes =
10131 (bool (__stdcall *)(HWND,COLORREF,BYTE,DWORD))
10132 GetProcAddress(hInst, "SetLayeredWindowAttributes");
10133
10134 if (_SetLayeredWindowAttributes != NULL)
10135 {
10136 // Only available on Windows 2000 or later
10137 SetExStyle(hWnd, 0, WS_EX_LAYERED);
10138 _SetLayeredWindowAttributes(hWnd, 0, AlphaValue * 255 / 100, LWA_ALPHA);
10139 }
10140 }
10141 }
10142
10143 break;
10144
10145 case WM_CTLCOLORBTN:
10146 case WM_CTLCOLORDLG:
10147 case WM_CTLCOLOREDIT:
10148 case WM_CTLCOLORLISTBOX:
10149 case WM_CTLCOLORMSGBOX:
10150 case WM_CTLCOLORSCROLLBAR:
10151 case WM_CTLCOLORSTATIC:
10152 if (white_color)
10153 {
10154 return (UINT)GetStockObject(WHITE_BRUSH);
10155 }
10156 break;
10157 }
10158
10159 return 0;
10160 }
10161
10162 // Set the parameters of the dialog box
SetParam(HWND hWnd,void * param)10163 void SetParam(HWND hWnd, void *param)
10164 {
10165 // Validate arguments
10166 if (hWnd == NULL)
10167 {
10168 return;
10169 }
10170
10171 SetWindowLongPtr(hWnd, DWLP_USER, (LONG_PTR)param);
10172 }
10173
10174 // Get the parameters of the dialog box
GetParam(HWND hWnd)10175 void *GetParam(HWND hWnd)
10176 {
10177 void *ret;
10178 // Validate arguments
10179 if (hWnd == NULL)
10180 {
10181 return NULL;
10182 }
10183
10184 ret = (void *)GetWindowLongPtr(hWnd, DWLP_USER);
10185 return ret;
10186 }
10187
10188 // Relieve the window from foreground
NoTop(HWND hWnd)10189 void NoTop(HWND hWnd)
10190 {
10191 // Validate arguments
10192 if (hWnd == NULL)
10193 {
10194 return;
10195 }
10196
10197 SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
10198 }
10199
10200 // Show the windows as foreground
Top(HWND hWnd)10201 void Top(HWND hWnd)
10202 {
10203 // Validate arguments
10204 if (hWnd == NULL)
10205 {
10206 return;
10207 }
10208
10209 SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
10210 }
10211
10212 // Hide the window
Hide(HWND hWnd,UINT id)10213 void Hide(HWND hWnd, UINT id)
10214 {
10215 // Validate arguments
10216 if (hWnd == NULL)
10217 {
10218 return;
10219 }
10220
10221 if (IsShow(hWnd, id))
10222 {
10223 ShowWindow(DlgItem(hWnd, id), SW_HIDE);
10224 }
10225 }
10226
10227 // Show the window
Show(HWND hWnd,UINT id)10228 void Show(HWND hWnd, UINT id)
10229 {
10230 // Validate arguments
10231 if (hWnd == NULL)
10232 {
10233 return;
10234 }
10235
10236 if (IsHide(hWnd, id))
10237 {
10238 ShowWindow(DlgItem(hWnd, id), SW_SHOW);
10239 }
10240 }
10241
10242 // Change the display settings
SetShow(HWND hWnd,UINT id,bool b)10243 void SetShow(HWND hWnd, UINT id, bool b)
10244 {
10245 // Validate arguments
10246 if (hWnd == NULL)
10247 {
10248 return;
10249 }
10250
10251 if (b)
10252 {
10253 Show(hWnd, id);
10254 }
10255 else
10256 {
10257 Hide(hWnd, id);
10258 }
10259 }
10260
10261 // Get whether the window is shown
IsShow(HWND hWnd,UINT id)10262 bool IsShow(HWND hWnd, UINT id)
10263 {
10264 return IsHide(hWnd, id) ? false : true;
10265 }
10266
10267 // Get whether the window is hidden
IsHide(HWND hWnd,UINT id)10268 bool IsHide(HWND hWnd, UINT id)
10269 {
10270 // Validate arguments
10271 if (hWnd == NULL)
10272 {
10273 return true;
10274 }
10275
10276 if (GetStyle(hWnd, id) & WS_VISIBLE)
10277 {
10278 return false;
10279 }
10280 else
10281 {
10282 return true;
10283 }
10284 }
10285
10286 // Remove the window style
RemoveExStyle(HWND hWnd,UINT id,UINT style)10287 void RemoveExStyle(HWND hWnd, UINT id, UINT style)
10288 {
10289 UINT old;
10290 // Validate arguments
10291 if (hWnd == NULL)
10292 {
10293 return;
10294 }
10295
10296 old = GetExStyle(hWnd, id);
10297 if ((old & style) == 0)
10298 {
10299 return;
10300 }
10301
10302 SetWindowLong(DlgItem(hWnd, id), GWL_EXSTYLE, old & ~style);
10303 Refresh(DlgItem(hWnd, id));
10304 }
10305
10306 // Set the window style
SetExStyle(HWND hWnd,UINT id,UINT style)10307 void SetExStyle(HWND hWnd, UINT id, UINT style)
10308 {
10309 UINT old;
10310 // Validate arguments
10311 if (hWnd == NULL)
10312 {
10313 return;
10314 }
10315
10316 old = GetExStyle(hWnd, id);
10317 if (old & style)
10318 {
10319 return;
10320 }
10321
10322 SetWindowLong(DlgItem(hWnd, id), GWL_EXSTYLE, old | style);
10323 Refresh(DlgItem(hWnd, id));
10324 }
10325
10326 // Get the window style
GetExStyle(HWND hWnd,UINT id)10327 UINT GetExStyle(HWND hWnd, UINT id)
10328 {
10329 // Validate arguments
10330 if (hWnd == NULL)
10331 {
10332 return 0;
10333 }
10334
10335 return GetWindowLong(DlgItem(hWnd, id), GWL_EXSTYLE);
10336 }
10337
10338 // Remove the window style
RemoveStyle(HWND hWnd,UINT id,UINT style)10339 void RemoveStyle(HWND hWnd, UINT id, UINT style)
10340 {
10341 UINT old;
10342 // Validate arguments
10343 if (hWnd == NULL)
10344 {
10345 return;
10346 }
10347
10348 old = GetStyle(hWnd, id);
10349 if ((old & style) == 0)
10350 {
10351 return;
10352 }
10353
10354 SetWindowLong(DlgItem(hWnd, id), GWL_STYLE, old & ~style);
10355 Refresh(DlgItem(hWnd, id));
10356 }
10357
10358 // Set the window style
SetStyle(HWND hWnd,UINT id,UINT style)10359 void SetStyle(HWND hWnd, UINT id, UINT style)
10360 {
10361 UINT old;
10362 // Validate arguments
10363 if (hWnd == NULL)
10364 {
10365 return;
10366 }
10367
10368 old = GetStyle(hWnd, id);
10369 if (old & style)
10370 {
10371 return;
10372 }
10373
10374 SetWindowLong(DlgItem(hWnd, id), GWL_STYLE, old | style);
10375 Refresh(DlgItem(hWnd, id));
10376 }
10377
10378 // Get the window style
GetStyle(HWND hWnd,UINT id)10379 UINT GetStyle(HWND hWnd, UINT id)
10380 {
10381 // Validate arguments
10382 if (hWnd == NULL)
10383 {
10384 return 0;
10385 }
10386
10387 return GetWindowLong(DlgItem(hWnd, id), GWL_STYLE);
10388 }
10389
10390 // Get the number of bytes of the text
GetTextSize(HWND hWnd,UINT id,bool unicode)10391 UINT GetTextSize(HWND hWnd, UINT id, bool unicode)
10392 {
10393 UINT len;
10394 // Validate arguments
10395 if (hWnd == NULL)
10396 {
10397 return 0;
10398 }
10399
10400 len = GetTextLen(hWnd, id, unicode);
10401
10402 return len + (unicode ? 2 : 1);
10403 }
10404
10405 // Get the number of characters in the text
GetTextLen(HWND hWnd,UINT id,bool unicode)10406 UINT GetTextLen(HWND hWnd, UINT id, bool unicode)
10407 {
10408 wchar_t *s;
10409 UINT ret;
10410 // Validate arguments
10411 if (hWnd == NULL)
10412 {
10413 return 0;
10414 }
10415
10416 s = GetText(hWnd, id);
10417 if (s == NULL)
10418 {
10419 return 0;
10420 }
10421
10422 if (unicode)
10423 {
10424 ret = UniStrLen(s);
10425 }
10426 else
10427 {
10428 char *tmp = CopyUniToStr(s);
10429 ret = StrLen(tmp);
10430 Free(tmp);
10431 }
10432
10433 Free(s);
10434
10435 return ret;
10436 }
10437
10438 // Check whether the text is blank
IsEmpty(HWND hWnd,UINT id)10439 bool IsEmpty(HWND hWnd, UINT id)
10440 {
10441 bool ret;
10442 wchar_t *s;
10443 // Validate arguments
10444 if (hWnd == NULL)
10445 {
10446 return true;
10447 }
10448
10449 s = GetText(hWnd, id);
10450
10451 UniTrim(s);
10452 if (UniStrLen(s) == 0)
10453 {
10454 ret = true;
10455 }
10456 else
10457 {
10458 ret = false;
10459 }
10460
10461 Free(s);
10462
10463 return ret;
10464 }
10465
10466 // Get the window class
GetClass(HWND hWnd,UINT id)10467 wchar_t *GetClass(HWND hWnd, UINT id)
10468 {
10469 wchar_t tmp[MAX_SIZE];
10470
10471 if (MsIsNt() == false)
10472 {
10473 wchar_t *ret;
10474 char *s;
10475 s = GetClassA(hWnd, id);
10476 ret = CopyStrToUni(s);
10477 Free(s);
10478 return ret;
10479 }
10480
10481 // Validate arguments
10482 if (hWnd == NULL)
10483 {
10484 return CopyUniStr(L"");
10485 }
10486
10487 GetClassNameW(DlgItem(hWnd, id), tmp, sizeof(tmp));
10488
10489 return UniCopyStr(tmp);
10490 }
GetClassA(HWND hWnd,UINT id)10491 char *GetClassA(HWND hWnd, UINT id)
10492 {
10493 char tmp[MAX_SIZE];
10494 // Validate arguments
10495 if (hWnd == NULL)
10496 {
10497 return CopyStr("");
10498 }
10499
10500 GetClassName(DlgItem(hWnd, id), tmp, sizeof(tmp));
10501
10502 return CopyStr(tmp);
10503 }
10504
10505 // Transmit a message to the control
SendMsg(HWND hWnd,UINT id,UINT msg,WPARAM wParam,LPARAM lParam)10506 UINT SendMsg(HWND hWnd, UINT id, UINT msg, WPARAM wParam, LPARAM lParam)
10507 {
10508 // Validate arguments
10509 if (hWnd == NULL)
10510 {
10511 return 0;
10512 }
10513
10514 if (MsIsNt())
10515 {
10516 return (UINT)SendMessageW(DlgItem(hWnd, id), msg, wParam, lParam);
10517 }
10518 else
10519 {
10520 return (UINT)SendMessageA(DlgItem(hWnd, id), msg, wParam, lParam);
10521 }
10522 }
10523
10524 // Move the cursor to the right edge of the text in the EDIT
SetCursorOnRight(HWND hWnd,UINT id)10525 void SetCursorOnRight(HWND hWnd, UINT id)
10526 {
10527 wchar_t *class_name;
10528 // Validate arguments
10529 if (hWnd == NULL)
10530 {
10531 return;
10532 }
10533
10534 class_name = GetClass(hWnd, id);
10535
10536 if (class_name != NULL)
10537 {
10538 if (UniStrCmpi(class_name, L"edit") == 0)
10539 {
10540 wchar_t *str = GetText(hWnd, id);
10541
10542 if (str != NULL)
10543 {
10544 UINT len = UniStrLen(str);
10545
10546 SendMsg(hWnd, id, EM_SETSEL, len, len);
10547
10548 Free(str);
10549 }
10550 }
10551 Free(class_name);
10552 }
10553 }
10554
10555 // Select entire the text in the EDIT
SelectEdit(HWND hWnd,UINT id)10556 void SelectEdit(HWND hWnd, UINT id)
10557 {
10558 wchar_t *class_name;
10559
10560 // Validate arguments
10561 if (hWnd == NULL)
10562 {
10563 return;
10564 }
10565
10566 class_name = GetClass(hWnd, id);
10567
10568 if (class_name != NULL)
10569 {
10570 if (UniStrCmpi(class_name, L"edit") == 0)
10571 {
10572 SendMsg(hWnd, id, EM_SETSEL, 0, -1);
10573 }
10574 Free(class_name);
10575 }
10576 }
10577
10578 // Deselect the text of EDIT
UnselectEdit(HWND hWnd,UINT id)10579 void UnselectEdit(HWND hWnd, UINT id)
10580 {
10581 wchar_t *class_name;
10582
10583 // Validate arguments
10584 if (hWnd == NULL)
10585 {
10586 return;
10587 }
10588
10589 class_name = GetClass(hWnd, id);
10590
10591 if (class_name != NULL)
10592 {
10593 if (UniStrCmpi(class_name, L"edit") == 0)
10594 {
10595 SendMsg(hWnd, id, EM_SETSEL, -1, 0);
10596 }
10597 Free(class_name);
10598 }
10599 }
10600
10601 // Select all by setting the focus to the EDIT
FocusEx(HWND hWnd,UINT id)10602 void FocusEx(HWND hWnd, UINT id)
10603 {
10604 // Validate arguments
10605 if (hWnd == NULL)
10606 {
10607 return;
10608 }
10609
10610 if (IsEnable(hWnd, id) == false || IsShow(hWnd, id) == false)
10611 {
10612 return;
10613 }
10614
10615 SelectEdit(hWnd, id);
10616
10617 Focus(hWnd, id);
10618 }
10619
10620 // Get whether the specified window has focus
IsFocus(HWND hWnd,UINT id)10621 bool IsFocus(HWND hWnd, UINT id)
10622 {
10623 // Validate arguments
10624 if (hWnd == NULL)
10625 {
10626 return false;
10627 }
10628
10629 if (GetFocus() == DlgItem(hWnd, id))
10630 {
10631 return true;
10632 }
10633
10634 return false;
10635 }
10636
10637 // Set the focus
Focus(HWND hWnd,UINT id)10638 void Focus(HWND hWnd, UINT id)
10639 {
10640 // Validate arguments
10641 if (hWnd == NULL)
10642 {
10643 return;
10644 }
10645
10646 if (IsEnable(hWnd, id) == false || IsShow(hWnd, id) == false)
10647 {
10648 return;
10649 }
10650
10651 SetFocus(DlgItem(hWnd, id));
10652 }
10653
10654 // Set the value of the int type
SetInt(HWND hWnd,UINT id,UINT value)10655 void SetInt(HWND hWnd, UINT id, UINT value)
10656 {
10657 wchar_t tmp[MAX_SIZE];
10658 // Validate arguments
10659 if (hWnd == NULL)
10660 {
10661 return;
10662 }
10663
10664 UniToStru(tmp, value);
10665 SetText(hWnd, id, tmp);
10666 }
SetIntEx(HWND hWnd,UINT id,UINT value)10667 void SetIntEx(HWND hWnd, UINT id, UINT value)
10668 {
10669 // Validate arguments
10670 if (hWnd == NULL)
10671 {
10672 return;
10673 }
10674
10675 if (value == 0)
10676 {
10677 // Leave blank in the case of 0
10678 SetText(hWnd, id, L"");
10679 }
10680 else
10681 {
10682 SetInt(hWnd, id, value);
10683 }
10684 }
10685
10686 // Get the value of the int type
GetInt(HWND hWnd,UINT id)10687 UINT GetInt(HWND hWnd, UINT id)
10688 {
10689 wchar_t *s;
10690 UINT ret;
10691 // Validate arguments
10692 if (hWnd == NULL)
10693 {
10694 return 0;
10695 }
10696
10697 s = GetText(hWnd, id);
10698 if (s == NULL)
10699 {
10700 return 0;
10701 }
10702
10703 ret = UniToInt(s);
10704 Free(s);
10705
10706 return ret;
10707 }
10708
10709 // Update the window appearance
Refresh(HWND hWnd)10710 void Refresh(HWND hWnd)
10711 {
10712 HWND parent;
10713 // Validate arguments
10714 if (hWnd == NULL)
10715 {
10716 return;
10717 }
10718
10719 DoEvents(hWnd);
10720 UpdateWindow(hWnd);
10721 DoEvents(hWnd);
10722
10723 parent = GetParent(hWnd);
10724 if (parent != NULL)
10725 {
10726 Refresh(parent);
10727 }
10728 }
10729
10730 // Handle the event
DoEvents(HWND hWnd)10731 void DoEvents(HWND hWnd)
10732 {
10733 MSG msg;
10734
10735 if (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
10736 {
10737 TranslateMessage(&msg);
10738 DispatchMessage(&msg);
10739 }
10740 UpdateWindow(hWnd);
10741
10742 if (hWnd)
10743 {
10744 DoEvents(NULL);
10745 }
10746 }
10747
10748 // Close the window
Close(HWND hWnd)10749 void Close(HWND hWnd)
10750 {
10751 // Validate arguments
10752 if (hWnd == NULL)
10753 {
10754 return;
10755 }
10756
10757 SendMessage(hWnd, WM_CLOSE, 0, 0);
10758 }
10759
10760 // Disable the window
Disable(HWND hWnd,UINT id)10761 void Disable(HWND hWnd, UINT id)
10762 {
10763 SetEnable(hWnd, id, false);
10764 }
10765
10766 // Enable the window
Enable(HWND hWnd,UINT id)10767 void Enable(HWND hWnd, UINT id)
10768 {
10769 SetEnable(hWnd, id, true);
10770 }
10771
10772 // Set the enabled state of a window
SetEnable(HWND hWnd,UINT id,bool b)10773 void SetEnable(HWND hWnd, UINT id, bool b)
10774 {
10775 // Validate arguments
10776 if (hWnd == NULL)
10777 {
10778 return;
10779 }
10780
10781 if (b == false)
10782 {
10783 if (IsEnable(hWnd, id))
10784 {
10785 if (id != 0 && IsFocus(hWnd, id))
10786 {
10787 Focus(hWnd, IDCANCEL);
10788 Focus(hWnd, IDOK);
10789 }
10790 EnableWindow(DlgItem(hWnd, id), false);
10791 Refresh(DlgItem(hWnd, id));
10792 }
10793 }
10794 else
10795 {
10796 if (IsDisable(hWnd, id))
10797 {
10798 EnableWindow(DlgItem(hWnd, id), true);
10799 Refresh(DlgItem(hWnd, id));
10800 }
10801 }
10802 }
10803
10804 // Examine whether the window is disabled
IsDisable(HWND hWnd,UINT id)10805 bool IsDisable(HWND hWnd, UINT id)
10806 {
10807 return IsEnable(hWnd, id) ? false : true;
10808 }
10809
10810 // Examine whether the window is enabled
IsEnable(HWND hWnd,UINT id)10811 bool IsEnable(HWND hWnd, UINT id)
10812 {
10813 // Validate arguments
10814 if (hWnd == NULL)
10815 {
10816 return false;
10817 }
10818
10819 return IsWindowEnabled(DlgItem(hWnd, id));
10820 }
10821
10822 static LOCK *winui_debug_lock = NULL;
10823
10824 // Initialize the debug function
WinUiDebugInit()10825 void WinUiDebugInit()
10826 {
10827 winui_debug_lock = NewLock();
10828 }
10829
10830 // Release the debug function
WinUiDebugFree()10831 void WinUiDebugFree()
10832 {
10833 DeleteLock(winui_debug_lock);
10834 }
10835
10836 // Write a string to the debug file
WinUiDebug(wchar_t * str)10837 void WinUiDebug(wchar_t *str)
10838 {
10839 wchar_t tmp[1024];
10840 char dtstr[256];
10841 char *buf;
10842 wchar_t exename[MAX_PATH];
10843 UINT tid;
10844 // Validate arguments
10845 if (str == NULL)
10846 {
10847 return;
10848 }
10849
10850 tid = GetCurrentThreadId();
10851
10852 GetExeNameW(exename, sizeof(exename));
10853 GetFileNameFromFilePathW(exename, sizeof(exename), exename);
10854
10855 GetDateTimeStrMilli64(dtstr, sizeof(dtstr), LocalTime64());
10856
10857 UniFormat(tmp, sizeof(tmp), L"[%S] (%s:%u) %s\r\n", dtstr, exename, tid, str);
10858
10859 buf = CopyUniToUtf(tmp);
10860
10861 Lock(winui_debug_lock);
10862 {
10863 IO *o = FileOpenEx(WINUI_DEBUG_TEXT, true, true);
10864 if (o == NULL)
10865 {
10866 o = FileCreate(WINUI_DEBUG_TEXT);
10867 }
10868
10869 if (o != NULL)
10870 {
10871 UINT size = FileSize(o);
10872
10873 FileSeek(o, FILE_BEGIN, size);
10874
10875 FileWrite(o, buf, StrLen(buf));
10876 FileFlush(o);
10877
10878 FileClose(o);
10879 }
10880 }
10881 Unlock(winui_debug_lock);
10882
10883 Free(buf);
10884 }
10885
10886 // If the control protrude by large font size, adjust into appropriate size
AdjustFontSize(HWND hWnd,UINT id)10887 void AdjustFontSize(HWND hWnd, UINT id)
10888 {
10889 char class_name[MAX_PATH];
10890 UINT style;
10891 UINT format = 0;
10892 HFONT current_font;
10893 FONT font;
10894 wchar_t *text;
10895 RECT rect;
10896 UINT width, height;
10897 HFONT new_font = NULL;
10898 UINT old_font_size;
10899 UINT style1;
10900 // Validate arguments
10901 if (hWnd == NULL)
10902 {
10903 return;
10904 }
10905
10906 hWnd = DlgItem(hWnd, id);
10907
10908 if (GetClassNameA(hWnd, class_name, sizeof(class_name)) == 0)
10909 {
10910 return;
10911 }
10912
10913 if (StrCmpi(class_name, "static") != 0)
10914 {
10915 return;
10916 }
10917
10918 style = GetStyle(hWnd, 0);
10919
10920 if ((style & SS_ENDELLIPSIS) || (style & SS_PATHELLIPSIS))
10921 {
10922 return;
10923 }
10924
10925 style1 = style & 0x0F;
10926
10927 // Create a format for DrawText
10928 if (style1 == SS_RIGHT)
10929 {
10930 // Right justification
10931 format |= DT_RIGHT;
10932 }
10933 else if (style1 == SS_CENTER)
10934 {
10935 // Center justification
10936 format |= DT_CENTER;
10937 }
10938 else if (style1 == SS_LEFT)
10939 {
10940 // Left justification
10941 format |= DT_LEFT;
10942 }
10943 else
10944 {
10945 // Others
10946 return;
10947 }
10948
10949 if (style & DT_NOPREFIX)
10950 {
10951 // Without prefix
10952 format |= DT_NOPREFIX;
10953 }
10954
10955 // Get the font parameters currently set
10956 current_font = (HFONT)SendMessageA(hWnd, WM_GETFONT, 0, 0);
10957 if (current_font == NULL)
10958 {
10959 return;
10960 }
10961
10962 Zero(&font, sizeof(font));
10963 if (GetFontParam(current_font, &font) == false)
10964 {
10965 return;
10966 }
10967
10968 // Get the size of the static area
10969 Zero(&rect, sizeof(rect));
10970 if (GetWindowRect(hWnd, &rect) == false)
10971 {
10972 return;
10973 }
10974
10975 // Get the text that is currently set
10976 text = GetText(hWnd, 0);
10977 if (text == NULL)
10978 {
10979 return;
10980 }
10981
10982 if (IsEmptyUniStr(text))
10983 {
10984 Free(text);
10985 return;
10986 }
10987
10988 width = GET_ABS(rect.right - rect.left);
10989 height = GET_ABS(rect.bottom - rect.top);
10990
10991 new_font = NULL;
10992 old_font_size = font.Size;
10993
10994 // Try to gradually reduce the font size until drawing succeeds
10995 while (font.Size != 0)
10996 {
10997 // Drawing test
10998 bool aborted = false;
10999
11000 if (IsFontFitInRect(&font, width, height, text, format, &aborted))
11001 {
11002 // Drawing success
11003 if (old_font_size != font.Size)
11004 {
11005 // Font size is changed
11006 new_font = GetFont(font.Name, font.Size, font.Bold, font.Italic, font.UnderLine, font.StrikeOut);
11007 }
11008 break;
11009 }
11010 else
11011 {
11012 if (aborted)
11013 {
11014 // Fatal error
11015 break;
11016 }
11017 }
11018
11019 font.Size--;
11020
11021 if (font.Size == 1)
11022 {
11023 // Not supposed to become a font size like this. Fatal error
11024 break;
11025 }
11026 }
11027
11028 Free(text);
11029
11030 if (new_font != NULL)
11031 {
11032 // Change the font size
11033 SetFontEx(hWnd, 0, new_font, true);
11034 }
11035 }
11036
11037 // Check whether the specified string can be drawn in the specified area with the specified font
IsFontFitInRect(struct FONT * f,UINT width,UINT height,wchar_t * text,UINT format,bool * aborted)11038 bool IsFontFitInRect(struct FONT *f, UINT width, UINT height, wchar_t *text, UINT format, bool *aborted)
11039 {
11040 RECT r;
11041 int i;
11042 bool dummy_bool;
11043 UINT new_height;
11044 HFONT hCreatedFont, hOldFont;
11045 // Validate arguments
11046 if (f == NULL || text == NULL)
11047 {
11048 return false;
11049 }
11050 if (aborted == NULL)
11051 {
11052 aborted = &dummy_bool;
11053 }
11054
11055 format |= DT_CALCRECT | DT_WORDBREAK;
11056
11057 *aborted = false;
11058
11059 // Create a font
11060 hCreatedFont = GetFont(f->Name, f->Size, f->Bold, f->Italic, f->UnderLine, f->StrikeOut);
11061 if (hCreatedFont == NULL)
11062 {
11063 *aborted = true;
11064 return false;
11065 }
11066
11067 Lock(lock_common_dc);
11068 {
11069 hOldFont = SelectObject(hCommonDC, hCreatedFont);
11070
11071 Zero(&r, sizeof(r));
11072 r.left = r.top = 0;
11073 r.right = width;
11074 r.bottom = height;
11075
11076 if (MsIsNt())
11077 {
11078 i = DrawTextW(hCommonDC, text, -1, &r, format);
11079 }
11080 else
11081 {
11082 char *a = CopyUniToStr(text);
11083
11084 i = DrawTextA(hCommonDC, a, -1, &r, format);
11085
11086 Free(a);
11087 }
11088
11089 SelectObject(hCommonDC, hOldFont);
11090 }
11091 Unlock(lock_common_dc);
11092
11093 if (i == 0)
11094 {
11095 *aborted = true;
11096 return false;
11097 }
11098
11099 new_height = GET_ABS(r.bottom - r.top);
11100
11101 if (new_height > height)
11102 {
11103 return false;
11104 }
11105
11106 return true;
11107 }
11108
11109 // Set a text string
SetText(HWND hWnd,UINT id,wchar_t * str)11110 void SetText(HWND hWnd, UINT id, wchar_t *str)
11111 {
11112 // Validate arguments
11113 if (hWnd == NULL || str == NULL)
11114 {
11115 return;
11116 }
11117
11118 SetTextInner(hWnd, id, str);
11119 }
SetTextInner(HWND hWnd,UINT id,wchar_t * str)11120 void SetTextInner(HWND hWnd, UINT id, wchar_t *str)
11121 {
11122 wchar_t *old;
11123 // Validate arguments
11124 if (hWnd == NULL || str == NULL)
11125 {
11126 return;
11127 }
11128
11129 // Get the old string
11130 old = GetText(hWnd, id);
11131 if (UniStrCmp(str, old) == 0)
11132 {
11133 // Identity
11134 Free(old);
11135 return;
11136 }
11137
11138 Free(old);
11139
11140 if (MsIsNt())
11141 {
11142 SetWindowTextW(DlgItem(hWnd, id), str);
11143 }
11144 else
11145 {
11146 char *tmp = CopyUniToStr(str);
11147
11148 if (MsIsNt() == false && StrLen(tmp) >= 32000)
11149 {
11150 // Truncate to less than 32k
11151 tmp[32000] = 0;
11152 }
11153
11154 SetWindowTextA(DlgItem(hWnd, id), tmp);
11155 Free(tmp);
11156 }
11157
11158 AdjustFontSize(hWnd, id);
11159
11160 if (id != 0)
11161 {
11162 Refresh(DlgItem(hWnd, id));
11163 }
11164 }
SetTextA(HWND hWnd,UINT id,char * str)11165 void SetTextA(HWND hWnd, UINT id, char *str)
11166 {
11167 wchar_t *s;
11168 // Validate arguments
11169 if (hWnd == NULL || str == NULL)
11170 {
11171 return;
11172 }
11173
11174 s = CopyStrToUni(str);
11175 if (s == NULL)
11176 {
11177 return;
11178 }
11179
11180 SetText(hWnd, id, s);
11181
11182 Free(s);
11183 }
11184
11185 // Get the text string to the buffer
GetTxt(HWND hWnd,UINT id,wchar_t * str,UINT size)11186 bool GetTxt(HWND hWnd, UINT id, wchar_t *str, UINT size)
11187 {
11188 wchar_t *s;
11189 // Validate arguments
11190 if (hWnd == NULL || str == NULL)
11191 {
11192 return false;
11193 }
11194
11195 s = GetText(hWnd, id);
11196 if (s == NULL)
11197 {
11198 UniStrCpy(str, size, L"");
11199 return false;
11200 }
11201
11202 UniStrCpy(str, size, s);
11203 Free(s);
11204
11205 return true;
11206 }
GetTxtA(HWND hWnd,UINT id,char * str,UINT size)11207 bool GetTxtA(HWND hWnd, UINT id, char *str, UINT size)
11208 {
11209 char *s;
11210 // Validate arguments
11211 if (hWnd == NULL || str == NULL)
11212 {
11213 return false;
11214 }
11215
11216 s = GetTextA(hWnd, id);
11217 if (s == NULL)
11218 {
11219 StrCpy(str, size, "");
11220 return false;
11221 }
11222
11223 StrCpy(str, size, s);
11224 Free(s);
11225
11226 return true;
11227 }
11228
11229 // Get the text string
GetText(HWND hWnd,UINT id)11230 wchar_t *GetText(HWND hWnd, UINT id)
11231 {
11232 wchar_t *ret;
11233 UINT size, len;
11234 // Validate arguments
11235 if (hWnd == NULL)
11236 {
11237 return NULL;
11238 }
11239
11240 if (MsIsNt() == false)
11241 {
11242 char *s = GetTextA(hWnd, id);
11243 ret = CopyStrToUni(s);
11244 Free(s);
11245
11246 return ret;
11247 }
11248
11249 len = GetWindowTextLengthW(DlgItem(hWnd, id));
11250 if (len == 0)
11251 {
11252 return CopyUniStr(L"");
11253 }
11254
11255 size = (len + 1) * 2;
11256 ret = ZeroMallocEx(size, true);
11257
11258 GetWindowTextW(DlgItem(hWnd, id), ret, size);
11259
11260 return ret;
11261 }
GetTextA(HWND hWnd,UINT id)11262 char *GetTextA(HWND hWnd, UINT id)
11263 {
11264 char *ret;
11265 UINT size, len;
11266 // Validate arguments
11267 if (hWnd == NULL)
11268 {
11269 return NULL;
11270 }
11271
11272 len = GetWindowTextLengthA(DlgItem(hWnd, id));
11273 if (len == 0)
11274 {
11275 return CopyStr("");
11276 }
11277
11278 size = len + 1;
11279 ret = ZeroMallocEx(size, true);
11280
11281 GetWindowTextA(DlgItem(hWnd, id), ret, size);
11282
11283 return ret;
11284 }
11285
11286 // Get the item in the dialog
DlgItem(HWND hWnd,UINT id)11287 HWND DlgItem(HWND hWnd, UINT id)
11288 {
11289 // Validate arguments
11290 if (hWnd == NULL)
11291 {
11292 return NULL;
11293 }
11294
11295 if (id == 0)
11296 {
11297 return hWnd;
11298 }
11299 else
11300 {
11301 return GetDlgItem(hWnd, id);
11302 }
11303 }
11304
11305 // Set the title
SetWinUiTitle(wchar_t * title)11306 void SetWinUiTitle(wchar_t *title)
11307 {
11308 // Validate arguments
11309 if (title == NULL)
11310 {
11311 return;
11312 }
11313
11314 Free(title_bar);
11315 title_bar = CopyUniStr(title);
11316 }
11317
11318 // Initialize the WinUi
InitWinUi(wchar_t * software_name,char * font,UINT fontsize)11319 void InitWinUi(wchar_t *software_name, char *font, UINT fontsize)
11320 {
11321 if (tls_current_wizard == 0xffffffff)
11322 {
11323 tls_current_wizard = TlsAlloc();
11324 }
11325
11326 if ((init_winui_counter++) != 0)
11327 {
11328 return;
11329 }
11330
11331 if (hDll != NULL)
11332 {
11333 return;
11334 }
11335
11336 WinUiDebugInit();
11337
11338 if (MayaquaIsMinimalMode() == false)
11339 {
11340 if (Is64())
11341 {
11342 hDll = MsLoadLibraryAsDataFile(MsGetPenCoreDllFileName());
11343 }
11344 else
11345 {
11346 hDll = MsLoadLibrary(MsGetPenCoreDllFileName());
11347 }
11348
11349 if (hDll == NULL)
11350 {
11351 Alert(PENCORE_DLL_NAME " not found. "CEDAR_PRODUCT_STR " VPN couldn't start.\r\n\r\n"
11352 "Please reinstall all files with "CEDAR_PRODUCT_STR " VPN Installer.",
11353 NULL);
11354 exit(0);
11355 }
11356 }
11357 else
11358 {
11359 hDll = LoadLibrary(MsGetExeFileName());
11360
11361 if (hDll == NULL)
11362 {
11363 Alert("MsLoadLibrary() Error.",
11364 NULL);
11365 exit(0);
11366 }
11367 }
11368
11369 if (software_name != NULL)
11370 {
11371 title_bar = CopyUniStr(software_name);
11372 }
11373 else
11374 {
11375 title_bar = CopyUniStr(CEDAR_PRODUCT_STR_W L" VPN");
11376 }
11377
11378 if (font != NULL)
11379 {
11380 font_name = CopyStr(font);
11381 }
11382 else
11383 {
11384 font_name = CopyStr(_SS("DEFAULT_FONT"));
11385 }
11386
11387 if (MsIsWindows7())
11388 {
11389 char *win7_font = _SS("DEFAULT_FONT_WIN7");
11390
11391 if (IsEmptyStr(win7_font) == false)
11392 {
11393 Free(font_name);
11394 font_name = CopyStr(win7_font);
11395 }
11396
11397 if (GetTextScalingFactor() >= 1.44)
11398 {
11399 // Use a substitute font in the case of high-DPI in Windows 7 and later
11400 char *alternative_font = _SS("DEFAULT_FONT_HIGHDPI");
11401
11402 if (IsEmptyStr(alternative_font) == false)
11403 {
11404 Free(font_name);
11405 font_name = CopyStr(alternative_font);
11406 }
11407 }
11408 }
11409
11410 if (fontsize != 0)
11411 {
11412 font_size = fontsize;
11413 }
11414 else
11415 {
11416 font_size = _II("DEFAULT_FONT_SIZE");
11417 if (font_size == 0)
11418 {
11419 font_size = 9;
11420 }
11421 }
11422
11423 lock_common_dc = NewLock();
11424
11425 hCommonDC = CreateCompatibleDC(NULL);
11426
11427 InitIconCache();
11428
11429 InitFont();
11430
11431 InitImageList();
11432 }
11433
11434 // Release the WinUi
FreeWinUi()11435 void FreeWinUi()
11436 {
11437 if ((--init_winui_counter) != 0)
11438 {
11439 return;
11440 }
11441
11442 if (hDll == NULL)
11443 {
11444 return;
11445 }
11446
11447 FreeImageList();
11448
11449 FreeFont();
11450
11451 FreeIconCache();
11452
11453 FreeLibrary(hDll);
11454 hDll = NULL;
11455
11456 Free(title_bar);
11457 title_bar = NULL;
11458
11459 Free(font_name);
11460 font_name = NULL;
11461
11462 WinUiDebugFree();
11463
11464 if (hCommonDC != NULL)
11465 {
11466 DeleteDC(hCommonDC);
11467 hCommonDC = NULL;
11468 }
11469
11470 DeleteLock(lock_common_dc);
11471 lock_common_dc = NULL;
11472 }
11473
11474 #endif // WIN32
11475