Try the blindingly-obvious fix for the hidden-controls-are-still-
[u/mdw/putty] / windlg.c
1 #include <windows.h>
2 #include <commctrl.h>
3 #include <commdlg.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #include "ssh.h"
8 #include "putty.h"
9 #include "winstuff.h"
10 #include "win_res.h"
11 #include "storage.h"
12
13 static char **events = NULL;
14 static int nevents = 0, negsize = 0;
15
16 static HWND logbox = NULL, abtbox = NULL;
17
18 static int readytogo;
19
20 void force_normal(HWND hwnd)
21 {
22 static int recurse = 0;
23
24 WINDOWPLACEMENT wp;
25
26 if(recurse) return;
27 recurse = 1;
28
29 wp.length = sizeof(wp);
30 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED)
31 {
32 wp.showCmd = SW_SHOWNORMAL;
33 SetWindowPlacement(hwnd, &wp);
34 }
35 recurse = 0;
36 }
37
38 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
39 BOOL ok;
40 int n;
41 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
42 if (ok)
43 *result = n;
44 }
45
46 static int CALLBACK LogProc (HWND hwnd, UINT msg,
47 WPARAM wParam, LPARAM lParam) {
48 int i;
49
50 switch (msg) {
51 case WM_INITDIALOG:
52 for (i=0; i<nevents; i++)
53 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
54 0, (LPARAM)events[i]);
55 return 1;
56 case WM_COMMAND:
57 switch (LOWORD(wParam)) {
58 case IDOK:
59 logbox = NULL;
60 DestroyWindow (hwnd);
61 return 0;
62 case IDN_COPY:
63 if (HIWORD(wParam) == BN_CLICKED ||
64 HIWORD(wParam) == BN_DOUBLECLICKED) {
65 int selcount;
66 int *selitems;
67 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
68 LB_GETSELCOUNT, 0, 0);
69 selitems = smalloc(selcount * sizeof(int));
70 if (selitems) {
71 int count = SendDlgItemMessage(hwnd, IDN_LIST,
72 LB_GETSELITEMS,
73 selcount, (LPARAM)selitems);
74 int i;
75 int size;
76 char *clipdata;
77 static unsigned char sel_nl[] = SEL_NL;
78
79 if (count == 0) { /* can't copy zero stuff */
80 MessageBeep(0);
81 break;
82 }
83
84 size = 0;
85 for (i = 0; i < count; i++)
86 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
87
88 clipdata = smalloc(size);
89 if (clipdata) {
90 char *p = clipdata;
91 for (i = 0; i < count; i++) {
92 char *q = events[selitems[i]];
93 int qlen = strlen(q);
94 memcpy(p, q, qlen);
95 p += qlen;
96 memcpy(p, sel_nl, sizeof(sel_nl));
97 p += sizeof(sel_nl);
98 }
99 write_clip(clipdata, size, TRUE);
100 sfree(clipdata);
101 }
102 sfree(selitems);
103
104 for (i = 0; i < nevents; i++)
105 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
106 FALSE, i);
107 }
108 }
109 return 0;
110 }
111 return 0;
112 case WM_CLOSE:
113 logbox = NULL;
114 DestroyWindow (hwnd);
115 return 0;
116 }
117 return 0;
118 }
119
120 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
121 WPARAM wParam, LPARAM lParam) {
122 switch (msg) {
123 case WM_INITDIALOG:
124 return 1;
125 case WM_COMMAND:
126 switch (LOWORD(wParam)) {
127 case IDOK:
128 EndDialog(hwnd, 1);
129 return 0;
130 }
131 return 0;
132 case WM_CLOSE:
133 EndDialog(hwnd, 1);
134 return 0;
135 }
136 return 0;
137 }
138
139 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
140 WPARAM wParam, LPARAM lParam) {
141 switch (msg) {
142 case WM_INITDIALOG:
143 SetDlgItemText (hwnd, IDA_VERSION, ver);
144 return 1;
145 case WM_COMMAND:
146 switch (LOWORD(wParam)) {
147 case IDOK:
148 abtbox = NULL;
149 DestroyWindow (hwnd);
150 return 0;
151 case IDA_LICENCE:
152 EnableWindow(hwnd, 0);
153 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
154 NULL, LicenceProc);
155 EnableWindow(hwnd, 1);
156 SetActiveWindow(hwnd);
157 return 0;
158 }
159 return 0;
160 case WM_CLOSE:
161 abtbox = NULL;
162 DestroyWindow (hwnd);
163 return 0;
164 }
165 return 0;
166 }
167
168 /*
169 * Null dialog procedure.
170 */
171 static int CALLBACK NullDlgProc (HWND hwnd, UINT msg,
172 WPARAM wParam, LPARAM lParam) {
173 return 0;
174 }
175
176 static char savedsession[2048];
177
178 enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
179
180 sessionpanelstart,
181 IDC_TITLE_SESSION,
182 IDC_BOX_SESSION1, IDC_BOXT_SESSION1,
183 IDC_BOX_SESSION2, IDC_BOXT_SESSION2,
184 IDC_BOX_SESSION3,
185 IDC_HOSTSTATIC,
186 IDC_HOST,
187 IDC_PORTSTATIC,
188 IDC_PORT,
189 IDC_PROTSTATIC,
190 IDC_PROTRAW,
191 IDC_PROTTELNET,
192 IDC_PROTRLOGIN,
193 IDC_PROTSSH,
194 IDC_SESSSTATIC,
195 IDC_SESSEDIT,
196 IDC_SESSLIST,
197 IDC_SESSLOAD,
198 IDC_SESSSAVE,
199 IDC_SESSDEL,
200 IDC_CLOSEEXIT,
201 sessionpanelend,
202
203 keyboardpanelstart,
204 IDC_TITLE_KEYBOARD,
205 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1,
206 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2,
207 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3,
208 IDC_DELSTATIC,
209 IDC_DEL008,
210 IDC_DEL127,
211 IDC_HOMESTATIC,
212 IDC_HOMETILDE,
213 IDC_HOMERXVT,
214 IDC_FUNCSTATIC,
215 IDC_FUNCTILDE,
216 IDC_FUNCLINUX,
217 IDC_FUNCXTERM,
218 IDC_FUNCVT400,
219 IDC_KPSTATIC,
220 IDC_KPNORMAL,
221 IDC_KPAPPLIC,
222 IDC_KPNH,
223 IDC_NOAPPLICK,
224 IDC_NOAPPLICC,
225 IDC_CURSTATIC,
226 IDC_CURNORMAL,
227 IDC_CURAPPLIC,
228 IDC_COMPOSEKEY,
229 keyboardpanelend,
230
231 terminalpanelstart,
232 IDC_TITLE_TERMINAL,
233 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1,
234 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2,
235 IDC_WRAPMODE,
236 IDC_DECOM,
237 IDC_LFHASCR,
238 IDC_BEEP,
239 IDC_BCE,
240 IDC_BLINKTEXT,
241 IDC_LDISCTERM,
242 IDC_LSTATSTATIC,
243 IDC_LSTATOFF,
244 IDC_LSTATASCII,
245 IDC_LSTATRAW,
246 IDC_LGFSTATIC,
247 IDC_LGFEDIT,
248 IDC_LGFBUTTON,
249 terminalpanelend,
250
251 windowpanelstart,
252 IDC_TITLE_WINDOW,
253 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1,
254 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2,
255 IDC_BOX_WINDOW3,
256 IDC_ROWSSTATIC,
257 IDC_ROWSEDIT,
258 IDC_COLSSTATIC,
259 IDC_COLSEDIT,
260 IDC_LOCKSIZE,
261 IDC_SCROLLBAR,
262 IDC_CLOSEWARN,
263 IDC_SAVESTATIC,
264 IDC_SAVEEDIT,
265 IDC_ALTF4,
266 IDC_ALTSPACE,
267 IDC_ALTONLY,
268 IDC_SCROLLKEY,
269 IDC_SCROLLDISP,
270 IDC_ALWAYSONTOP,
271 windowpanelend,
272
273 appearancepanelstart,
274 IDC_TITLE_APPEARANCE,
275 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1,
276 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2,
277 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3,
278 IDC_CURSORSTATIC,
279 IDC_CURBLOCK,
280 IDC_CURUNDER,
281 IDC_CURVERT,
282 IDC_BLINKCUR,
283 IDC_FONTSTATIC,
284 IDC_CHOOSEFONT,
285 IDC_WINTITLE,
286 IDC_WINEDIT,
287 IDC_WINNAME,
288 appearancepanelend,
289
290 connectionpanelstart,
291 IDC_TITLE_CONNECTION,
292 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1,
293 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2,
294 IDC_TTSTATIC,
295 IDC_TTEDIT,
296 IDC_LOGSTATIC,
297 IDC_LOGEDIT,
298 IDC_PINGSTATIC,
299 IDC_PINGEDIT,
300 connectionpanelend,
301
302 telnetpanelstart,
303 IDC_TITLE_TELNET,
304 IDC_BOX_TELNET1, IDC_BOXT_TELNET1,
305 IDC_BOX_TELNET2, IDC_BOXT_TELNET2,
306 IDC_TSSTATIC,
307 IDC_TSEDIT,
308 IDC_ENVSTATIC,
309 IDC_VARSTATIC,
310 IDC_VAREDIT,
311 IDC_VALSTATIC,
312 IDC_VALEDIT,
313 IDC_ENVLIST,
314 IDC_ENVADD,
315 IDC_ENVREMOVE,
316 IDC_EMSTATIC,
317 IDC_EMBSD,
318 IDC_EMRFC,
319 telnetpanelend,
320
321 rloginpanelstart,
322 IDC_TITLE_RLOGIN,
323 IDC_BOX_RLOGIN1, IDC_BOXT_RLOGIN1,
324 IDC_BOX_RLOGIN2, IDC_BOXT_RLOGIN2,
325 IDC_R_TSSTATIC,
326 IDC_R_TSEDIT,
327 IDC_RLLUSERSTATIC,
328 IDC_RLLUSEREDIT,
329 rloginpanelend,
330
331 sshpanelstart,
332 IDC_TITLE_SSH,
333 IDC_BOX_SSH1, IDC_BOXT_SSH1,
334 IDC_BOX_SSH2, IDC_BOXT_SSH2,
335 IDC_BOX_SSH3, IDC_BOXT_SSH3,
336 IDC_NOPTY,
337 IDC_CIPHERSTATIC,
338 IDC_CIPHER3DES,
339 IDC_CIPHERBLOWF,
340 IDC_CIPHERDES,
341 IDC_BUGGYMAC,
342 IDC_AUTHTIS,
343 IDC_PKSTATIC,
344 IDC_PKEDIT,
345 IDC_PKBUTTON,
346 IDC_SSHPROTSTATIC,
347 IDC_SSHPROT1,
348 IDC_SSHPROT2,
349 IDC_AGENTFWD,
350 IDC_CMDSTATIC,
351 IDC_CMDEDIT,
352 IDC_COMPRESS,
353 sshpanelend,
354
355 selectionpanelstart,
356 IDC_TITLE_SELECTION,
357 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1,
358 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2,
359 IDC_MBSTATIC,
360 IDC_MBWINDOWS,
361 IDC_MBXTERM,
362 IDC_CCSTATIC,
363 IDC_CCLIST,
364 IDC_CCSET,
365 IDC_CCSTATIC2,
366 IDC_CCEDIT,
367 selectionpanelend,
368
369 colourspanelstart,
370 IDC_TITLE_COLOURS,
371 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1,
372 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2,
373 IDC_BOLDCOLOUR,
374 IDC_PALETTE,
375 IDC_COLOURSTATIC,
376 IDC_COLOURLIST,
377 IDC_RSTATIC,
378 IDC_GSTATIC,
379 IDC_BSTATIC,
380 IDC_RVALUE,
381 IDC_GVALUE,
382 IDC_BVALUE,
383 IDC_CHANGE,
384 colourspanelend,
385
386 translationpanelstart,
387 IDC_TITLE_TRANSLATION,
388 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1,
389 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2,
390 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3,
391 IDC_XLATSTATIC,
392 IDC_NOXLAT,
393 IDC_KOI8WIN1251,
394 IDC_88592WIN1250,
395 IDC_88592CP852,
396 IDC_CAPSLOCKCYR,
397 IDC_VTSTATIC,
398 IDC_VTXWINDOWS,
399 IDC_VTOEMANSI,
400 IDC_VTOEMONLY,
401 IDC_VTPOORMAN,
402 translationpanelend,
403
404 tunnelspanelstart,
405 IDC_BOX_TUNNELS, IDC_BOXT_TUNNELS,
406 IDC_X11_FORWARD,
407 IDC_X11_DISPSTATIC,
408 IDC_X11_DISPLAY,
409 tunnelspanelend,
410
411 controlendvalue
412 };
413
414 static const char *const colours[] = {
415 "Default Foreground", "Default Bold Foreground",
416 "Default Background", "Default Bold Background",
417 "Cursor Text", "Cursor Colour",
418 "ANSI Black", "ANSI Black Bold",
419 "ANSI Red", "ANSI Red Bold",
420 "ANSI Green", "ANSI Green Bold",
421 "ANSI Yellow", "ANSI Yellow Bold",
422 "ANSI Blue", "ANSI Blue Bold",
423 "ANSI Magenta", "ANSI Magenta Bold",
424 "ANSI Cyan", "ANSI Cyan Bold",
425 "ANSI White", "ANSI White Bold"
426 };
427 static const int permcolour[] = {
428 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
429 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
430 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
431 };
432
433 static void fmtfont (char *buf) {
434 sprintf (buf, "Font: %s, ", cfg.font);
435 if (cfg.fontisbold)
436 strcat(buf, "bold, ");
437 if (cfg.fontheight == 0)
438 strcat (buf, "default height");
439 else
440 sprintf (buf+strlen(buf), "%d-%s",
441 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
442 (cfg.fontheight < 0 ? "pixel" : "point"));
443 }
444
445 static void init_dlg_ctrls(HWND hwnd) {
446 int i;
447 char fontstatic[256];
448
449 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
450 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
451 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
452 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
453 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
454 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET :
455 cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW );
456 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
457
458 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
459 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
460 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
461 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
462 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
463 cfg.funky_type == 0 ? IDC_FUNCTILDE :
464 cfg.funky_type == 1 ? IDC_FUNCLINUX :
465 cfg.funky_type == 2 ? IDC_FUNCXTERM :
466 cfg.funky_type == 3 ? IDC_FUNCVT400 :
467 IDC_FUNCTILDE );
468 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
469 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
470 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
471 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
472 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
473 cfg.nethack_keypad ? IDC_KPNH :
474 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
475 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
476 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
477 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
478 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
479 CheckDlgButton (hwnd, IDC_LDISCTERM, cfg.ldisc_term);
480 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
481 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
482 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
483
484 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
485 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
486 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
487 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
488 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
489 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
490 fmtfont (fontstatic);
491 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
492 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
493 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
494 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
495
496 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
497 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
498 CheckRadioButton (hwnd, IDC_CURBLOCK, IDC_CURVERT,
499 cfg.cursor_type==0 ? IDC_CURBLOCK :
500 cfg.cursor_type==1 ? IDC_CURUNDER : IDC_CURVERT);
501 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
502 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
503 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
504 CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit);
505 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
506
507 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
508 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
509 SetDlgItemText (hwnd, IDC_R_TSEDIT, cfg.termspeed);
510 SetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername);
511 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
512 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
513 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
514 cfg.logtype == 0 ? IDC_LSTATOFF :
515 cfg.logtype == 1 ? IDC_LSTATASCII :
516 IDC_LSTATRAW);
517 {
518 char *p = cfg.environmt;
519 while (*p) {
520 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
521 (LPARAM) p);
522 p += strlen(p)+1;
523 }
524 }
525 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
526 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
527
528 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
529 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
530 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
531 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
532 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
533 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
534 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
535 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
536 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
537 IDC_CIPHER3DES);
538 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
539 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
540 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
541 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
542 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
543
544 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
545 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
546 {
547 static int tabs[4] = {25, 61, 96, 128};
548 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
549 (LPARAM) tabs);
550 }
551 for (i=0; i<256; i++) {
552 char str[100];
553 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
554 (i>=0x21 && i != 0x7F) ? i : ' ',
555 cfg.wordness[i]);
556 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
557 (LPARAM) str);
558 }
559
560 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
561 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
562 {
563 int i, n;
564 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
565 for (i=n; i-- >0 ;)
566 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
567 LB_DELETESTRING, i, 0);
568 for (i=0; i<22; i++)
569 if (cfg.bold_colour || permcolour[i])
570 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
571 (LPARAM) colours[i]);
572 }
573 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
574 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
575 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
576 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
577
578 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
579 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
580 cfg.xlat_88592cp852 ? IDC_88592CP852 :
581 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
582 IDC_NOXLAT);
583 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
584 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
585 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
586 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
587 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
588 IDC_VTPOORMAN);
589
590 CheckDlgButton (hwnd, IDC_X11_FORWARD, cfg.x11_forward);
591 SetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display);
592 }
593
594 static void hide(HWND hwnd, int hide, int minid, int maxid) {
595 int i;
596 for (i = minid; i < maxid; i++) {
597 HWND ctl = GetDlgItem(hwnd, i);
598 if (ctl) {
599 if (!hide)
600 EnableWindow(ctl, 1);
601 ShowWindow(ctl, hide ? SW_HIDE : SW_SHOW);
602 if (hide)
603 EnableWindow(ctl, 0);
604 }
605 }
606 }
607
608 struct treeview_faff {
609 HWND treeview;
610 HTREEITEM lastat[4];
611 };
612
613 static HTREEITEM treeview_insert(struct treeview_faff *faff,
614 int level, char *text) {
615 TVINSERTSTRUCT ins;
616 int i;
617 HTREEITEM newitem;
618 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
619 ins.hInsertAfter = faff->lastat[level];
620 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
621 #define INSITEM DUMMYUNIONNAME.item
622 #else
623 #define INSITEM item
624 #endif
625 ins.INSITEM.mask = TVIF_TEXT;
626 ins.INSITEM.pszText = text;
627 newitem = TreeView_InsertItem(faff->treeview, &ins);
628 if (level > 0)
629 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
630 faff->lastat[level] = newitem;
631 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
632 return newitem;
633 }
634
635 /*
636 * This _huge_ function is the configuration box.
637 */
638 static int GenericMainDlgProc (HWND hwnd, UINT msg,
639 WPARAM wParam, LPARAM lParam,
640 int dlgtype) {
641 HWND hw, treeview;
642 struct treeview_faff tvfaff;
643 HTREEITEM hsession;
644 OPENFILENAME of;
645 char filename[sizeof(cfg.keyfile)];
646 CHOOSEFONT cf;
647 LOGFONT lf;
648 char fontstatic[256];
649 char portname[32];
650 struct servent * service;
651 int i;
652
653 switch (msg) {
654 case WM_INITDIALOG:
655 readytogo = 0;
656 SetWindowLong(hwnd, GWL_USERDATA, 0);
657 /*
658 * Centre the window.
659 */
660 { /* centre the window */
661 RECT rs, rd;
662
663 hw = GetDesktopWindow();
664 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
665 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
666 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
667 rd.right-rd.left, rd.bottom-rd.top, TRUE);
668 }
669
670 /*
671 * Create the tree view.
672 */
673 {
674 RECT r;
675 WPARAM font;
676 HWND tvstatic;
677
678 r.left = 3; r.right = r.left + 75;
679 r.top = 3; r.bottom = r.top + 10;
680 MapDialogRect(hwnd, &r);
681 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
682 WS_CHILD | WS_VISIBLE,
683 r.left, r.top,
684 r.right-r.left, r.bottom-r.top,
685 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
686 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
687 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
688
689 r.left = 3; r.right = r.left + 75;
690 r.top = 13; r.bottom = r.top + 206;
691 MapDialogRect(hwnd, &r);
692 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
693 WS_CHILD | WS_VISIBLE |
694 WS_TABSTOP | TVS_HASLINES |
695 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
696 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
697 r.left, r.top,
698 r.right-r.left, r.bottom-r.top,
699 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
700 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
701 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
702 tvfaff.treeview = treeview;
703 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
704 }
705
706 /*
707 * Create the various panelfuls of controls.
708 */
709
710 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
711 {
712 struct ctlpos cp;
713 ctlposinit(&cp, hwnd, 80, 3, 13);
714 bartitle(&cp, "Basic options for your PuTTY session",
715 IDC_TITLE_SESSION);
716 if (dlgtype == 0) {
717 beginbox(&cp, "Specify your connection by host name",
718 IDC_BOX_SESSION1, IDC_BOXT_SESSION1);
719 multiedit(&cp,
720 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
721 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
722 if (backends[3].backend == NULL) {
723 /* this is PuTTYtel, so only two protocols available */
724 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
725 "&Raw", IDC_PROTRAW,
726 "&Telnet", IDC_PROTTELNET,
727 "R&login", IDC_PROTRLOGIN, NULL);
728 } else {
729 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
730 "&Raw", IDC_PROTRAW,
731 "&Telnet", IDC_PROTTELNET,
732 "R&login", IDC_PROTRLOGIN,
733 #ifdef FWHACK
734 "SS&H/hack",
735 #else
736 "SS&H",
737 #endif
738 IDC_PROTSSH, NULL);
739 }
740 endbox(&cp);
741 beginbox(&cp, "Load, save or delete a stored session",
742 IDC_BOX_SESSION2, IDC_BOXT_SESSION2);
743 sesssaver(&cp, "Sav&ed Sessions",
744 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
745 "&Load", IDC_SESSLOAD,
746 "&Save", IDC_SESSSAVE,
747 "&Delete", IDC_SESSDEL, NULL);
748 endbox(&cp);
749 }
750 beginbox(&cp, NULL, IDC_BOX_SESSION3, 0);
751 checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT);
752 endbox(&cp);
753
754 hsession = treeview_insert(&tvfaff, 0, "Session");
755 }
756
757 /* The Terminal panel. Accelerators used: [acgo] &dflbenuw */
758 {
759 struct ctlpos cp;
760 ctlposinit(&cp, hwnd, 80, 3, 13);
761 bartitle(&cp, "Options controlling the terminal emulation",
762 IDC_TITLE_TERMINAL);
763 beginbox(&cp, "Set various terminal options",
764 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1);
765 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
766 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
767 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
768 checkbox(&cp, "&Beep enabled", IDC_BEEP);
769 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
770 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
771 checkbox(&cp, "&Use local terminal line discipline", IDC_LDISCTERM);
772 endbox(&cp);
773
774 beginbox(&cp, "Control session logging",
775 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2);
776 radiobig(&cp,
777 "Session logging:", IDC_LSTATSTATIC,
778 "Logging turned &off completely", IDC_LSTATOFF,
779 "Log printable output only", IDC_LSTATASCII,
780 "Log all session output", IDC_LSTATRAW, NULL);
781 editbutton(&cp, "Log &file name:",
782 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
783 IDC_LGFBUTTON);
784 endbox(&cp);
785
786 treeview_insert(&tvfaff, 0, "Terminal");
787 }
788
789 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmietu */
790 {
791 struct ctlpos cp;
792 ctlposinit(&cp, hwnd, 80, 3, 13);
793 bartitle(&cp, "Options controlling the effects of keys",
794 IDC_TITLE_KEYBOARD);
795 beginbox(&cp, "Change the sequences sent by:",
796 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1);
797 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
798 "Control-&H", IDC_DEL008,
799 "Control-&? (127)", IDC_DEL127, NULL);
800 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
801 "&Standard", IDC_HOMETILDE,
802 "&rxvt", IDC_HOMERXVT, NULL);
803 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
804 "ESC[n&~", IDC_FUNCTILDE,
805 "&Linux", IDC_FUNCLINUX,
806 "&Xterm R6", IDC_FUNCXTERM,
807 "&VT400", IDC_FUNCVT400, NULL);
808 endbox(&cp);
809 beginbox(&cp, "Application keypad settings:",
810 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2);
811 checkbox(&cp,
812 "Application c&ursor keys totally disabled",
813 IDC_NOAPPLICC);
814 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
815 "&Normal", IDC_CURNORMAL,
816 "A&pplication", IDC_CURAPPLIC, NULL);
817 checkbox(&cp,
818 "Application ke&ypad keys totally disabled",
819 IDC_NOAPPLICK);
820 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
821 "Nor&mal", IDC_KPNORMAL,
822 "Appl&ication", IDC_KPAPPLIC,
823 "N&etHack", IDC_KPNH, NULL);
824 endbox(&cp);
825 beginbox(&cp, "Enable extra keyboard features:",
826 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3);
827 checkbox(&cp, "Application and AltGr ac&t as Compose key",
828 IDC_COMPOSEKEY);
829 endbox(&cp);
830
831 treeview_insert(&tvfaff, 1, "Keyboard");
832 }
833
834 /* The Window panel. Accelerators used: [acgo] bsdkw4ylpt */
835 {
836 struct ctlpos cp;
837 ctlposinit(&cp, hwnd, 80, 3, 13);
838 bartitle(&cp, "Options controlling PuTTY's window",
839 IDC_TITLE_WINDOW);
840 beginbox(&cp, "Set the size of the window",
841 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1);
842 multiedit(&cp,
843 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
844 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
845 NULL);
846 checkbox(&cp, "Loc&k window size against resizing", IDC_LOCKSIZE);
847 endbox(&cp);
848 beginbox(&cp, "Control the scrollback in the window",
849 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2);
850 staticedit(&cp, "Lines of &scrollback",
851 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
852 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
853 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
854 checkbox(&cp, "Reset scrollback on dis&play activity",
855 IDC_SCROLLDISP);
856 endbox(&cp);
857 beginbox(&cp, NULL, IDC_BOX_WINDOW3, 0);
858 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
859 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
860 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
861 checkbox(&cp, "System menu appears on A&LT alone", IDC_ALTONLY);
862 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
863 endbox(&cp);
864
865 treeview_insert(&tvfaff, 0, "Window");
866 }
867
868 /* The Appearance panel. Accelerators used: [acgo] rmkhtibluv */
869 {
870 struct ctlpos cp;
871 ctlposinit(&cp, hwnd, 80, 3, 13);
872 bartitle(&cp, "Options controlling PuTTY's appearance",
873 IDC_TITLE_APPEARANCE);
874 beginbox(&cp, "Adjust the use of the cursor",
875 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1);
876 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
877 "B&lock", IDC_CURBLOCK,
878 "&Underline", IDC_CURUNDER,
879 "&Vertical line", IDC_CURVERT,
880 NULL);
881 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
882 endbox(&cp);
883 beginbox(&cp, "Set the font used in the terminal window",
884 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2);
885 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
886 endbox(&cp);
887 beginbox(&cp, "Adjust the use of the window title",
888 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3);
889 multiedit(&cp,
890 "Window &title:", IDC_WINTITLE,
891 IDC_WINEDIT, 100, NULL);
892 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
893 endbox(&cp);
894
895 treeview_insert(&tvfaff, 1, "Appearance");
896 }
897
898 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
899 {
900 struct ctlpos cp;
901 ctlposinit(&cp, hwnd, 80, 3, 13);
902 bartitle(&cp, "Options controlling character set translation",
903 IDC_TITLE_TRANSLATION);
904 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
905 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1);
906 radiobig(&cp,
907 "Handling of line drawing characters:", IDC_VTSTATIC,
908 "Font has &XWindows encoding", IDC_VTXWINDOWS,
909 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
910 "Use font in O&EM mode only", IDC_VTOEMONLY,
911 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
912 IDC_VTPOORMAN, NULL);
913 endbox(&cp);
914 beginbox(&cp, "Enable character set translation on received data",
915 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2);
916 radiobig(&cp,
917 "Character set translation:", IDC_XLATSTATIC,
918 "&None", IDC_NOXLAT,
919 "&KOI8 / Win-1251", IDC_KOI8WIN1251,
920 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250,
921 "&ISO-8859-2 / CP852", IDC_88592CP852, NULL);
922 endbox(&cp);
923 beginbox(&cp, "Enable character set translation on input data",
924 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3);
925 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
926 IDC_CAPSLOCKCYR);
927 endbox(&cp);
928
929 treeview_insert(&tvfaff, 1, "Translation");
930 }
931
932 /* The Selection panel. Accelerators used: [acgo] wxst */
933 {
934 struct ctlpos cp;
935 ctlposinit(&cp, hwnd, 80, 3, 13);
936 bartitle(&cp, "Options controlling copy and paste",
937 IDC_TITLE_SELECTION);
938 beginbox(&cp, "Control which mouse button does which thing",
939 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1);
940 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
941 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
942 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
943 NULL);
944 endbox(&cp);
945 beginbox(&cp, "Control the select-one-word-at-a-time mode",
946 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2);
947 charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST,
948 "&Set", IDC_CCSET, IDC_CCEDIT,
949 "&to class", IDC_CCSTATIC2);
950 endbox(&cp);
951
952 treeview_insert(&tvfaff, 1, "Selection");
953 }
954
955 /* The Colours panel. Accelerators used: [acgo] blum */
956 {
957 struct ctlpos cp;
958 ctlposinit(&cp, hwnd, 80, 3, 13);
959 bartitle(&cp, "Options controlling use of colours",
960 IDC_TITLE_COLOURS);
961 beginbox(&cp, "General options for colour usage",
962 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1);
963 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
964 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
965 endbox(&cp);
966 beginbox(&cp, "Adjust the precise colours PuTTY displays",
967 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2);
968 colouredit(&cp, "Select a colo&ur and then click to modify it:",
969 IDC_COLOURSTATIC, IDC_COLOURLIST,
970 "&Modify...", IDC_CHANGE,
971 "Red:", IDC_RSTATIC, IDC_RVALUE,
972 "Green:", IDC_GSTATIC, IDC_GVALUE,
973 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
974 endbox(&cp);
975
976 treeview_insert(&tvfaff, 1, "Colours");
977 }
978
979 /* The Connection panel. Accelerators used: [acgo] tuk */
980 {
981 struct ctlpos cp;
982 ctlposinit(&cp, hwnd, 80, 3, 13);
983 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
984 if (dlgtype == 0) {
985 beginbox(&cp, "Data to send to the server",
986 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1);
987 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
988 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
989 endbox(&cp);
990 }
991 beginbox(&cp, "Sending of null packets to keep session active",
992 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2);
993 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
994 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
995 endbox(&cp);
996
997 treeview_insert(&tvfaff, 0, "Connection");
998 }
999
1000 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
1001 {
1002 struct ctlpos cp;
1003 ctlposinit(&cp, hwnd, 80, 3, 13);
1004 if (dlgtype == 0) {
1005 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
1006 beginbox(&cp, "Data to send to the server",
1007 IDC_BOX_TELNET1, IDC_BOXT_TELNET1);
1008 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
1009 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1010 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
1011 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
1012 IDC_ENVLIST,
1013 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1014 endbox(&cp);
1015 beginbox(&cp, "Telnet protocol adjustments",
1016 IDC_BOX_TELNET2, IDC_BOXT_TELNET2);
1017 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
1018 "&BSD (commonplace)", IDC_EMBSD,
1019 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1020 endbox(&cp);
1021
1022 treeview_insert(&tvfaff, 1, "Telnet");
1023 }
1024 }
1025
1026
1027 /* The Rlogin Panel */
1028 {
1029 struct ctlpos cp;
1030 ctlposinit(&cp, hwnd, 80, 3, 13);
1031 if (dlgtype == 0) {
1032 bartitle(&cp, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN);
1033 beginbox(&cp, "Data to send to the server",
1034 IDC_BOX_RLOGIN1, IDC_BOXT_RLOGIN1);
1035 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC, IDC_R_TSEDIT, 50);
1036 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC, IDC_RLLUSEREDIT, 50);
1037 endbox(&cp);
1038
1039 treeview_insert(&tvfaff, 1, "Rlogin");
1040 }
1041 }
1042
1043 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
1044 if (backends[3].backend != NULL) {
1045 struct ctlpos cp;
1046 ctlposinit(&cp, hwnd, 80, 3, 13);
1047 if (dlgtype == 0) {
1048 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
1049 beginbox(&cp, "Data to send to the server",
1050 IDC_BOX_SSH1, IDC_BOXT_SSH1);
1051 multiedit(&cp,
1052 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1053 NULL);
1054 endbox(&cp);
1055 beginbox(&cp, "Authentication options",
1056 IDC_BOX_SSH2, IDC_BOXT_SSH2);
1057 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1058 IDC_AUTHTIS);
1059 checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD);
1060 editbutton(&cp, "Private &key file for authentication:",
1061 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
1062 endbox(&cp);
1063 beginbox(&cp, "Protocol options",
1064 IDC_BOX_SSH3, IDC_BOXT_SSH3);
1065 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1066 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1067 radioline(&cp, "Preferred SSH protocol version:",
1068 IDC_SSHPROTSTATIC, 2,
1069 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1070 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
1071 "&3DES", IDC_CIPHER3DES,
1072 "&Blowfish", IDC_CIPHERBLOWF,
1073 "&DES", IDC_CIPHERDES, NULL);
1074 checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1075 IDC_BUGGYMAC);
1076 endbox(&cp);
1077
1078 treeview_insert(&tvfaff, 1, "SSH");
1079 }
1080 }
1081 /* The Tunnels panel. Accelerators used: [acgo] ex */
1082 {
1083 struct ctlpos tp;
1084 ctlposinit(&tp, hwnd, 80, 3, 13);
1085 if (dlgtype == 0) {
1086 beginbox(&tp, "X11 forwarding options",
1087 IDC_BOX_TUNNELS, IDC_BOXT_TUNNELS);
1088 checkbox(&tp, "&Enable X11 forwarding",
1089 IDC_X11_FORWARD);
1090 multiedit(&tp, "&X display location", IDC_X11_DISPSTATIC,
1091 IDC_X11_DISPLAY, 50, NULL);
1092 endbox(&tp);
1093
1094 treeview_insert(&tvfaff, 2, "Tunnels");
1095 }
1096 }
1097
1098 init_dlg_ctrls(hwnd);
1099 for (i = 0; i < nsessions; i++)
1100 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1101 0, (LPARAM) (sessions[i]));
1102
1103 /*
1104 * Hide all the controls to start with.
1105 */
1106 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1107
1108 /*
1109 * Put the treeview selection on to the Session panel. This
1110 * should also cause unhiding of the relevant controls.
1111 */
1112 TreeView_SelectItem(treeview, hsession);
1113
1114 /*
1115 * Set focus into the first available control.
1116 */
1117 {
1118 HWND ctl;
1119 ctl = GetDlgItem(hwnd, IDC_HOST);
1120 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1121 SetFocus(ctl);
1122 }
1123
1124 SetWindowLong(hwnd, GWL_USERDATA, 1);
1125 return 0;
1126 case WM_LBUTTONUP:
1127 /*
1128 * Button release should trigger WM_OK if there was a
1129 * previous double click on the session list.
1130 */
1131 ReleaseCapture();
1132 if (readytogo)
1133 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1134 break;
1135 case WM_NOTIFY:
1136 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1137 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1138 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1139 TVITEM item;
1140 char buffer[64];
1141 item.hItem = i;
1142 item.pszText = buffer;
1143 item.cchTextMax = sizeof(buffer);
1144 item.mask = TVIF_TEXT;
1145 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1146 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1147 if (!strcmp(buffer, "Session"))
1148 hide(hwnd, FALSE, sessionpanelstart, sessionpanelend);
1149 if (!strcmp(buffer, "Keyboard"))
1150 hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend);
1151 if (!strcmp(buffer, "Terminal"))
1152 hide(hwnd, FALSE, terminalpanelstart, terminalpanelend);
1153 if (!strcmp(buffer, "Window"))
1154 hide(hwnd, FALSE, windowpanelstart, windowpanelend);
1155 if (!strcmp(buffer, "Appearance"))
1156 hide(hwnd, FALSE, appearancepanelstart, appearancepanelend);
1157 if (!strcmp(buffer, "Tunnels"))
1158 hide(hwnd, FALSE, tunnelspanelstart, tunnelspanelend);
1159 if (!strcmp(buffer, "Connection"))
1160 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
1161 if (!strcmp(buffer, "Telnet"))
1162 hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
1163 if (!strcmp(buffer, "Rlogin"))
1164 hide(hwnd, FALSE, rloginpanelstart, rloginpanelend);
1165 if (!strcmp(buffer, "SSH"))
1166 hide(hwnd, FALSE, sshpanelstart, sshpanelend);
1167 if (!strcmp(buffer, "Selection"))
1168 hide(hwnd, FALSE, selectionpanelstart, selectionpanelend);
1169 if (!strcmp(buffer, "Colours"))
1170 hide(hwnd, FALSE, colourspanelstart, colourspanelend);
1171 if (!strcmp(buffer, "Translation"))
1172 hide(hwnd, FALSE, translationpanelstart, translationpanelend);
1173
1174 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1175 return 0;
1176 }
1177 break;
1178 case WM_COMMAND:
1179 /*
1180 * Only process WM_COMMAND once the dialog is fully formed.
1181 */
1182 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1183 case IDOK:
1184 if (*cfg.host)
1185 EndDialog (hwnd, 1);
1186 else
1187 MessageBeep (0);
1188 return 0;
1189 case IDCANCEL:
1190 EndDialog (hwnd, 0);
1191 return 0;
1192 case IDC_PROTTELNET:
1193 case IDC_PROTRLOGIN:
1194 case IDC_PROTSSH:
1195 case IDC_PROTRAW:
1196 if (HIWORD(wParam) == BN_CLICKED ||
1197 HIWORD(wParam) == BN_DOUBLECLICKED) {
1198 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1199 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1200 int k = IsDlgButtonChecked (hwnd, IDC_PROTRLOGIN);
1201 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN : PROT_RAW ;
1202 if ((cfg.protocol == PROT_SSH && cfg.port != 22) ||
1203 (cfg.protocol == PROT_TELNET && cfg.port != 23) ||
1204 (cfg.protocol == PROT_RLOGIN && cfg.port != 513)) {
1205 cfg.port = i ? 22 : j ? 23 : 513;
1206 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1207 }
1208 }
1209 break;
1210 case IDC_HOST:
1211 if (HIWORD(wParam) == EN_CHANGE)
1212 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1213 sizeof(cfg.host)-1);
1214 break;
1215 case IDC_PORT:
1216 if (HIWORD(wParam) == EN_CHANGE) {
1217 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1218 if (isdigit(portname[0]))
1219 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1220 else {
1221 service = getservbyname(portname, NULL);
1222 if (service) cfg.port = ntohs(service->s_port);
1223 else cfg.port = 0;
1224 }
1225 }
1226 break;
1227 case IDC_SESSEDIT:
1228 if (HIWORD(wParam) == EN_CHANGE) {
1229 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1230 (WPARAM) -1, 0);
1231 GetDlgItemText (hwnd, IDC_SESSEDIT,
1232 savedsession, sizeof(savedsession)-1);
1233 savedsession[sizeof(savedsession)-1] = '\0';
1234 }
1235 break;
1236 case IDC_SESSSAVE:
1237 if (HIWORD(wParam) == BN_CLICKED ||
1238 HIWORD(wParam) == BN_DOUBLECLICKED) {
1239 /*
1240 * Save a session
1241 */
1242 char str[2048];
1243 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1244 if (!*str) {
1245 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1246 LB_GETCURSEL, 0, 0);
1247 if (n == LB_ERR) {
1248 MessageBeep(0);
1249 break;
1250 }
1251 strcpy (str, sessions[n]);
1252 }
1253 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1254 get_sesslist (FALSE);
1255 get_sesslist (TRUE);
1256 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1257 0, 0);
1258 for (i = 0; i < nsessions; i++)
1259 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1260 0, (LPARAM) (sessions[i]));
1261 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1262 (WPARAM) -1, 0);
1263 }
1264 break;
1265 case IDC_SESSLIST:
1266 case IDC_SESSLOAD:
1267 if (LOWORD(wParam) == IDC_SESSLOAD &&
1268 HIWORD(wParam) != BN_CLICKED &&
1269 HIWORD(wParam) != BN_DOUBLECLICKED)
1270 break;
1271 if (LOWORD(wParam) == IDC_SESSLIST &&
1272 HIWORD(wParam) != LBN_DBLCLK)
1273 break;
1274 {
1275 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1276 LB_GETCURSEL, 0, 0);
1277 int isdef;
1278 if (n == LB_ERR) {
1279 MessageBeep(0);
1280 break;
1281 }
1282 isdef = !strcmp(sessions[n], "Default Settings");
1283 load_settings (sessions[n], !isdef, &cfg);
1284 init_dlg_ctrls(hwnd);
1285 if (!isdef)
1286 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1287 else
1288 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1289 }
1290 if (LOWORD(wParam) == IDC_SESSLIST) {
1291 /*
1292 * A double-click on a saved session should
1293 * actually start the session, not just load it.
1294 * Unless it's Default Settings or some other
1295 * host-less set of saved settings.
1296 */
1297 if (*cfg.host) {
1298 readytogo = TRUE;
1299 SetCapture(hwnd);
1300 }
1301 }
1302 break;
1303 case IDC_SESSDEL:
1304 if (HIWORD(wParam) == BN_CLICKED ||
1305 HIWORD(wParam) == BN_DOUBLECLICKED) {
1306 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1307 LB_GETCURSEL, 0, 0);
1308 if (n == LB_ERR || n == 0) {
1309 MessageBeep(0);
1310 break;
1311 }
1312 del_settings(sessions[n]);
1313 get_sesslist (FALSE);
1314 get_sesslist (TRUE);
1315 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1316 0, 0);
1317 for (i = 0; i < nsessions; i++)
1318 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1319 0, (LPARAM) (sessions[i]));
1320 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1321 (WPARAM) -1, 0);
1322 }
1323 case IDC_PINGEDIT:
1324 if (HIWORD(wParam) == EN_CHANGE)
1325 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1326 break;
1327 case IDC_DEL008:
1328 case IDC_DEL127:
1329 if (HIWORD(wParam) == BN_CLICKED ||
1330 HIWORD(wParam) == BN_DOUBLECLICKED)
1331 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1332 break;
1333 case IDC_HOMETILDE:
1334 case IDC_HOMERXVT:
1335 if (HIWORD(wParam) == BN_CLICKED ||
1336 HIWORD(wParam) == BN_DOUBLECLICKED)
1337 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1338 break;
1339 case IDC_FUNCXTERM:
1340 if (HIWORD(wParam) == BN_CLICKED ||
1341 HIWORD(wParam) == BN_DOUBLECLICKED)
1342 cfg.funky_type = 2;
1343 break;
1344 case IDC_FUNCVT400:
1345 if (HIWORD(wParam) == BN_CLICKED ||
1346 HIWORD(wParam) == BN_DOUBLECLICKED)
1347 cfg.funky_type = 3;
1348 break;
1349 case IDC_FUNCTILDE:
1350 case IDC_FUNCLINUX:
1351 if (HIWORD(wParam) == BN_CLICKED ||
1352 HIWORD(wParam) == BN_DOUBLECLICKED)
1353 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1354 break;
1355 case IDC_KPNORMAL:
1356 case IDC_KPAPPLIC:
1357 if (HIWORD(wParam) == BN_CLICKED ||
1358 HIWORD(wParam) == BN_DOUBLECLICKED) {
1359 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1360 cfg.nethack_keypad = FALSE;
1361 }
1362 break;
1363 case IDC_KPNH:
1364 if (HIWORD(wParam) == BN_CLICKED ||
1365 HIWORD(wParam) == BN_DOUBLECLICKED) {
1366 cfg.app_keypad = FALSE;
1367 cfg.nethack_keypad = TRUE;
1368 }
1369 break;
1370 case IDC_CURNORMAL:
1371 case IDC_CURAPPLIC:
1372 if (HIWORD(wParam) == BN_CLICKED ||
1373 HIWORD(wParam) == BN_DOUBLECLICKED)
1374 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1375 break;
1376 case IDC_NOAPPLICC:
1377 if (HIWORD(wParam) == BN_CLICKED ||
1378 HIWORD(wParam) == BN_DOUBLECLICKED)
1379 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1380 break;
1381 case IDC_NOAPPLICK:
1382 if (HIWORD(wParam) == BN_CLICKED ||
1383 HIWORD(wParam) == BN_DOUBLECLICKED)
1384 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1385 break;
1386 case IDC_ALTF4:
1387 if (HIWORD(wParam) == BN_CLICKED ||
1388 HIWORD(wParam) == BN_DOUBLECLICKED)
1389 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1390 break;
1391 case IDC_ALTSPACE:
1392 if (HIWORD(wParam) == BN_CLICKED ||
1393 HIWORD(wParam) == BN_DOUBLECLICKED)
1394 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1395 break;
1396 case IDC_ALTONLY:
1397 if (HIWORD(wParam) == BN_CLICKED ||
1398 HIWORD(wParam) == BN_DOUBLECLICKED)
1399 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1400 break;
1401 case IDC_LDISCTERM:
1402 if (HIWORD(wParam) == BN_CLICKED ||
1403 HIWORD(wParam) == BN_DOUBLECLICKED)
1404 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM);
1405 break;
1406 case IDC_ALWAYSONTOP:
1407 if (HIWORD(wParam) == BN_CLICKED ||
1408 HIWORD(wParam) == BN_DOUBLECLICKED)
1409 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1410 break;
1411 case IDC_SCROLLKEY:
1412 if (HIWORD(wParam) == BN_CLICKED ||
1413 HIWORD(wParam) == BN_DOUBLECLICKED)
1414 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1415 break;
1416 case IDC_SCROLLDISP:
1417 if (HIWORD(wParam) == BN_CLICKED ||
1418 HIWORD(wParam) == BN_DOUBLECLICKED)
1419 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1420 break;
1421 case IDC_COMPOSEKEY:
1422 if (HIWORD(wParam) == BN_CLICKED ||
1423 HIWORD(wParam) == BN_DOUBLECLICKED)
1424 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1425 break;
1426 case IDC_WRAPMODE:
1427 if (HIWORD(wParam) == BN_CLICKED ||
1428 HIWORD(wParam) == BN_DOUBLECLICKED)
1429 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1430 break;
1431 case IDC_DECOM:
1432 if (HIWORD(wParam) == BN_CLICKED ||
1433 HIWORD(wParam) == BN_DOUBLECLICKED)
1434 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1435 break;
1436 case IDC_LFHASCR:
1437 if (HIWORD(wParam) == BN_CLICKED ||
1438 HIWORD(wParam) == BN_DOUBLECLICKED)
1439 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1440 break;
1441 case IDC_ROWSEDIT:
1442 if (HIWORD(wParam) == EN_CHANGE)
1443 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1444 break;
1445 case IDC_COLSEDIT:
1446 if (HIWORD(wParam) == EN_CHANGE)
1447 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1448 break;
1449 case IDC_SAVEEDIT:
1450 if (HIWORD(wParam) == EN_CHANGE)
1451 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1452 break;
1453 case IDC_CHOOSEFONT:
1454 lf.lfHeight = cfg.fontheight;
1455 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1456 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1457 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1458 lf.lfCharSet = cfg.fontcharset;
1459 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1460 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1461 lf.lfQuality = DEFAULT_QUALITY;
1462 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1463 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1464 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1465
1466 cf.lStructSize = sizeof(cf);
1467 cf.hwndOwner = hwnd;
1468 cf.lpLogFont = &lf;
1469 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1470 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1471
1472 if (ChooseFont (&cf)) {
1473 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1474 cfg.font[sizeof(cfg.font)-1] = '\0';
1475 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1476 cfg.fontcharset = lf.lfCharSet;
1477 cfg.fontheight = lf.lfHeight;
1478 fmtfont (fontstatic);
1479 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1480 }
1481 break;
1482 case IDC_BEEP:
1483 if (HIWORD(wParam) == BN_CLICKED ||
1484 HIWORD(wParam) == BN_DOUBLECLICKED)
1485 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1486 break;
1487 case IDC_BLINKTEXT:
1488 if (HIWORD(wParam) == BN_CLICKED ||
1489 HIWORD(wParam) == BN_DOUBLECLICKED)
1490 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1491 break;
1492 case IDC_BCE:
1493 if (HIWORD(wParam) == BN_CLICKED ||
1494 HIWORD(wParam) == BN_DOUBLECLICKED)
1495 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1496 break;
1497 case IDC_WINNAME:
1498 if (HIWORD(wParam) == BN_CLICKED ||
1499 HIWORD(wParam) == BN_DOUBLECLICKED)
1500 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1501 break;
1502 case IDC_CURBLOCK:
1503 if (HIWORD(wParam) == BN_CLICKED ||
1504 HIWORD(wParam) == BN_DOUBLECLICKED)
1505 cfg.cursor_type = 0;
1506 break;
1507 case IDC_CURUNDER:
1508 if (HIWORD(wParam) == BN_CLICKED ||
1509 HIWORD(wParam) == BN_DOUBLECLICKED)
1510 cfg.cursor_type = 1;
1511 break;
1512 case IDC_CURVERT:
1513 if (HIWORD(wParam) == BN_CLICKED ||
1514 HIWORD(wParam) == BN_DOUBLECLICKED)
1515 cfg.cursor_type = 2;
1516 break;
1517 case IDC_BLINKCUR:
1518 if (HIWORD(wParam) == BN_CLICKED ||
1519 HIWORD(wParam) == BN_DOUBLECLICKED)
1520 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1521 break;
1522 case IDC_SCROLLBAR:
1523 if (HIWORD(wParam) == BN_CLICKED ||
1524 HIWORD(wParam) == BN_DOUBLECLICKED)
1525 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1526 break;
1527 case IDC_LOCKSIZE:
1528 if (HIWORD(wParam) == BN_CLICKED ||
1529 HIWORD(wParam) == BN_DOUBLECLICKED)
1530 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1531 break;
1532 case IDC_WINEDIT:
1533 if (HIWORD(wParam) == EN_CHANGE)
1534 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1535 sizeof(cfg.wintitle)-1);
1536 break;
1537 case IDC_CLOSEEXIT:
1538 if (HIWORD(wParam) == BN_CLICKED ||
1539 HIWORD(wParam) == BN_DOUBLECLICKED)
1540 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
1541 break;
1542 case IDC_CLOSEWARN:
1543 if (HIWORD(wParam) == BN_CLICKED ||
1544 HIWORD(wParam) == BN_DOUBLECLICKED)
1545 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1546 break;
1547 case IDC_TTEDIT:
1548 if (HIWORD(wParam) == EN_CHANGE)
1549 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1550 sizeof(cfg.termtype)-1);
1551 break;
1552 case IDC_LGFEDIT:
1553 if (HIWORD(wParam) == EN_CHANGE)
1554 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1555 sizeof(cfg.logfilename)-1);
1556 break;
1557 case IDC_LGFBUTTON:
1558 memset(&of, 0, sizeof(of));
1559 #ifdef OPENFILENAME_SIZE_VERSION_400
1560 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1561 #else
1562 of.lStructSize = sizeof(of);
1563 #endif
1564 of.hwndOwner = hwnd;
1565 of.lpstrFilter = "All Files\0*\0\0\0";
1566 of.lpstrCustomFilter = NULL;
1567 of.nFilterIndex = 1;
1568 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1569 of.nMaxFile = sizeof(filename);
1570 of.lpstrFileTitle = NULL;
1571 of.lpstrInitialDir = NULL;
1572 of.lpstrTitle = "Select session log file";
1573 of.Flags = 0;
1574 if (GetSaveFileName(&of)) {
1575 strcpy(cfg.keyfile, filename);
1576 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.keyfile);
1577 }
1578 break;
1579 case IDC_LSTATOFF:
1580 case IDC_LSTATASCII:
1581 case IDC_LSTATRAW:
1582 if (HIWORD(wParam) == BN_CLICKED ||
1583 HIWORD(wParam) == BN_DOUBLECLICKED) {
1584 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1585 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1586 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1587 }
1588 break;
1589 case IDC_TSEDIT:
1590 case IDC_R_TSEDIT:
1591 if (HIWORD(wParam) == EN_CHANGE)
1592 GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed,
1593 sizeof(cfg.termspeed)-1);
1594 break;
1595 case IDC_LOGEDIT:
1596 if (HIWORD(wParam) == EN_CHANGE)
1597 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1598 sizeof(cfg.username)-1);
1599 break;
1600 case IDC_RLLUSEREDIT:
1601 if (HIWORD(wParam) == EN_CHANGE)
1602 GetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername,
1603 sizeof(cfg.localusername)-1);
1604 break;
1605 case IDC_EMBSD:
1606 case IDC_EMRFC:
1607 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1608 break;
1609 case IDC_ENVADD:
1610 if (HIWORD(wParam) == BN_CLICKED ||
1611 HIWORD(wParam) == BN_DOUBLECLICKED) {
1612 char str[sizeof(cfg.environmt)];
1613 char *p;
1614 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1615 if (!*str) {
1616 MessageBeep(0);
1617 break;
1618 }
1619 p = str + strlen(str);
1620 *p++ = '\t';
1621 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1622 if (!*p) {
1623 MessageBeep(0);
1624 break;
1625 }
1626 p = cfg.environmt;
1627 while (*p) {
1628 while (*p) p++;
1629 p++;
1630 }
1631 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1632 strcpy (p, str);
1633 p[strlen(str)+1] = '\0';
1634 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1635 0, (LPARAM)str);
1636 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1637 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1638 } else {
1639 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1640 MB_OK | MB_ICONERROR);
1641 }
1642 }
1643 break;
1644 case IDC_ENVREMOVE:
1645 if (HIWORD(wParam) != BN_CLICKED &&
1646 HIWORD(wParam) != BN_DOUBLECLICKED)
1647 break;
1648 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1649 if (i == LB_ERR)
1650 MessageBeep (0);
1651 else {
1652 char *p, *q;
1653
1654 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1655 i, 0);
1656 p = cfg.environmt;
1657 while (i > 0) {
1658 if (!*p)
1659 goto disaster;
1660 while (*p) p++;
1661 p++;
1662 i--;
1663 }
1664 q = p;
1665 if (!*p)
1666 goto disaster;
1667 while (*p) p++;
1668 p++;
1669 while (*p) {
1670 while (*p)
1671 *q++ = *p++;
1672 *q++ = *p++;
1673 }
1674 *q = '\0';
1675 disaster:;
1676 }
1677 break;
1678 case IDC_NOPTY:
1679 if (HIWORD(wParam) == BN_CLICKED ||
1680 HIWORD(wParam) == BN_DOUBLECLICKED)
1681 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1682 break;
1683 case IDC_COMPRESS:
1684 if (HIWORD(wParam) == BN_CLICKED ||
1685 HIWORD(wParam) == BN_DOUBLECLICKED)
1686 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1687 break;
1688 case IDC_BUGGYMAC:
1689 if (HIWORD(wParam) == BN_CLICKED ||
1690 HIWORD(wParam) == BN_DOUBLECLICKED)
1691 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1692 break;
1693 case IDC_AGENTFWD:
1694 if (HIWORD(wParam) == BN_CLICKED ||
1695 HIWORD(wParam) == BN_DOUBLECLICKED)
1696 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1697 break;
1698 case IDC_CIPHER3DES:
1699 case IDC_CIPHERBLOWF:
1700 case IDC_CIPHERDES:
1701 if (HIWORD(wParam) == BN_CLICKED ||
1702 HIWORD(wParam) == BN_DOUBLECLICKED) {
1703 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1704 cfg.cipher = CIPHER_3DES;
1705 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1706 cfg.cipher = CIPHER_BLOWFISH;
1707 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1708 cfg.cipher = CIPHER_DES;
1709 }
1710 break;
1711 case IDC_SSHPROT1:
1712 case IDC_SSHPROT2:
1713 if (HIWORD(wParam) == BN_CLICKED ||
1714 HIWORD(wParam) == BN_DOUBLECLICKED) {
1715 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1716 cfg.sshprot = 1;
1717 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1718 cfg.sshprot = 2;
1719 }
1720 break;
1721 case IDC_AUTHTIS:
1722 if (HIWORD(wParam) == BN_CLICKED ||
1723 HIWORD(wParam) == BN_DOUBLECLICKED)
1724 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1725 break;
1726 case IDC_PKEDIT:
1727 if (HIWORD(wParam) == EN_CHANGE)
1728 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1729 sizeof(cfg.keyfile)-1);
1730 break;
1731 case IDC_CMDEDIT:
1732 if (HIWORD(wParam) == EN_CHANGE)
1733 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1734 sizeof(cfg.remote_cmd)-1);
1735 break;
1736 case IDC_PKBUTTON:
1737 memset(&of, 0, sizeof(of));
1738 #ifdef OPENFILENAME_SIZE_VERSION_400
1739 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1740 #else
1741 of.lStructSize = sizeof(of);
1742 #endif
1743 of.hwndOwner = hwnd;
1744 of.lpstrFilter = "All Files\0*\0\0\0";
1745 of.lpstrCustomFilter = NULL;
1746 of.nFilterIndex = 1;
1747 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1748 of.nMaxFile = sizeof(filename);
1749 of.lpstrFileTitle = NULL;
1750 of.lpstrInitialDir = NULL;
1751 of.lpstrTitle = "Select Public Key File";
1752 of.Flags = 0;
1753 if (GetOpenFileName(&of)) {
1754 strcpy(cfg.keyfile, filename);
1755 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1756 }
1757 break;
1758 case IDC_MBWINDOWS:
1759 case IDC_MBXTERM:
1760 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1761 break;
1762 case IDC_CCSET:
1763 {
1764 BOOL ok;
1765 int i;
1766 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1767
1768 if (!ok)
1769 MessageBeep (0);
1770 else {
1771 for (i=0; i<256; i++)
1772 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1773 i, 0)) {
1774 char str[100];
1775 cfg.wordness[i] = n;
1776 SendDlgItemMessage (hwnd, IDC_CCLIST,
1777 LB_DELETESTRING, i, 0);
1778 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1779 (i>=0x21 && i != 0x7F) ? i : ' ',
1780 cfg.wordness[i]);
1781 SendDlgItemMessage (hwnd, IDC_CCLIST,
1782 LB_INSERTSTRING, i,
1783 (LPARAM)str);
1784 }
1785 }
1786 }
1787 break;
1788 case IDC_BOLDCOLOUR:
1789 if (HIWORD(wParam) == BN_CLICKED ||
1790 HIWORD(wParam) == BN_DOUBLECLICKED) {
1791 int n, i;
1792 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1793 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1794 if (n != 12+10*cfg.bold_colour) {
1795 for (i=n; i-- >0 ;)
1796 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1797 LB_DELETESTRING, i, 0);
1798 for (i=0; i<22; i++)
1799 if (cfg.bold_colour || permcolour[i])
1800 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1801 LB_ADDSTRING, 0,
1802 (LPARAM) colours[i]);
1803 }
1804 }
1805 break;
1806 case IDC_PALETTE:
1807 if (HIWORD(wParam) == BN_CLICKED ||
1808 HIWORD(wParam) == BN_DOUBLECLICKED)
1809 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1810 break;
1811 case IDC_COLOURLIST:
1812 if (HIWORD(wParam) == LBN_DBLCLK ||
1813 HIWORD(wParam) == LBN_SELCHANGE) {
1814 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1815 0, 0);
1816 if (!cfg.bold_colour)
1817 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1818 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1819 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1820 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1821 }
1822 break;
1823 case IDC_CHANGE:
1824 if (HIWORD(wParam) == BN_CLICKED ||
1825 HIWORD(wParam) == BN_DOUBLECLICKED) {
1826 static CHOOSECOLOR cc;
1827 static DWORD custom[16] = {0}; /* zero initialisers */
1828 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1829 0, 0);
1830 if (!cfg.bold_colour)
1831 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1832 cc.lStructSize = sizeof(cc);
1833 cc.hwndOwner = hwnd;
1834 cc.hInstance = (HWND)hinst;
1835 cc.lpCustColors = custom;
1836 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1837 cfg.colours[i][2]);
1838 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1839 if (ChooseColor(&cc)) {
1840 cfg.colours[i][0] =
1841 (unsigned char) (cc.rgbResult & 0xFF);
1842 cfg.colours[i][1] =
1843 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1844 cfg.colours[i][2] =
1845 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1846 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1847 FALSE);
1848 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1849 FALSE);
1850 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1851 FALSE);
1852 }
1853 }
1854 break;
1855 case IDC_NOXLAT:
1856 case IDC_KOI8WIN1251:
1857 case IDC_88592WIN1250:
1858 case IDC_88592CP852:
1859 cfg.xlat_enablekoiwin =
1860 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1861 cfg.xlat_88592w1250 =
1862 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1863 cfg.xlat_88592cp852 =
1864 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1865 break;
1866 case IDC_CAPSLOCKCYR:
1867 if (HIWORD(wParam) == BN_CLICKED ||
1868 HIWORD(wParam) == BN_DOUBLECLICKED) {
1869 cfg.xlat_capslockcyr =
1870 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1871 }
1872 break;
1873 case IDC_VTXWINDOWS:
1874 case IDC_VTOEMANSI:
1875 case IDC_VTOEMONLY:
1876 case IDC_VTPOORMAN:
1877 cfg.vtmode =
1878 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1879 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1880 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1881 VT_POORMAN);
1882 break;
1883 case IDC_X11_FORWARD:
1884 if (HIWORD(wParam) == BN_CLICKED ||
1885 HIWORD(wParam) == BN_DOUBLECLICKED)
1886 cfg.x11_forward = IsDlgButtonChecked (hwnd, IDC_X11_FORWARD);
1887 break;
1888 case IDC_X11_DISPLAY:
1889 if (HIWORD(wParam) == EN_CHANGE)
1890 GetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display,
1891 sizeof(cfg.x11_display)-1);
1892 break;
1893 }
1894 return 0;
1895 case WM_CLOSE:
1896 EndDialog (hwnd, 0);
1897 return 0;
1898
1899 /* Grrr Explorer will maximize Dialogs! */
1900 case WM_SIZE:
1901 if (wParam == SIZE_MAXIMIZED)
1902 force_normal(hwnd);
1903 return 0;
1904 }
1905 return 0;
1906 }
1907
1908 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1909 WPARAM wParam, LPARAM lParam) {
1910 static HWND page = NULL;
1911
1912 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1913 }
1914 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
1915 EnableWindow(hwnd, 0);
1916 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1917 GetParent(hwnd), AboutProc);
1918 EnableWindow(hwnd, 1);
1919 SetActiveWindow(hwnd);
1920 }
1921 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
1922 }
1923
1924 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1925 WPARAM wParam, LPARAM lParam) {
1926 static HWND page;
1927 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
1928 }
1929
1930 void defuse_showwindow(void) {
1931 /*
1932 * Work around the fact that the app's first call to ShowWindow
1933 * will ignore the default in favour of the shell-provided
1934 * setting.
1935 */
1936 {
1937 HWND hwnd;
1938 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1939 NULL, NullDlgProc);
1940 ShowWindow(hwnd, SW_HIDE);
1941 DestroyWindow(hwnd);
1942 }
1943 }
1944
1945 int do_config (void) {
1946 int ret;
1947
1948 get_sesslist(TRUE);
1949 savedsession[0] = '\0';
1950 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1951 get_sesslist(FALSE);
1952
1953 return ret;
1954 }
1955
1956 int do_reconfig (HWND hwnd) {
1957 Config backup_cfg;
1958 int ret;
1959
1960 backup_cfg = cfg; /* structure copy */
1961 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1962 if (!ret)
1963 cfg = backup_cfg; /* structure copy */
1964
1965 return ret;
1966 }
1967
1968 void logevent (char *string) {
1969 if (nevents >= negsize) {
1970 negsize += 64;
1971 events = srealloc (events, negsize * sizeof(*events));
1972 }
1973 events[nevents] = smalloc(1+strlen(string));
1974 strcpy (events[nevents], string);
1975 nevents++;
1976 if (logbox) {
1977 int count;
1978 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1979 0, (LPARAM)string);
1980 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1981 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
1982 }
1983 }
1984
1985 void showeventlog (HWND hwnd) {
1986 if (!logbox) {
1987 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1988 hwnd, LogProc);
1989 ShowWindow (logbox, SW_SHOWNORMAL);
1990 }
1991 }
1992
1993 void showabout (HWND hwnd) {
1994 if (!abtbox) {
1995 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1996 hwnd, AboutProc);
1997 ShowWindow (abtbox, SW_SHOWNORMAL);
1998 }
1999 }
2000
2001 void verify_ssh_host_key(char *host, int port, char *keytype,
2002 char *keystr, char *fingerprint) {
2003 int ret;
2004
2005 static const char absentmsg[] =
2006 "The server's host key is not cached in the registry. You\n"
2007 "have no guarantee that the server is the computer you\n"
2008 "think it is.\n"
2009 "The server's key fingerprint is:\n"
2010 "%s\n"
2011 "If you trust this host, hit Yes to add the key to\n"
2012 "PuTTY's cache and carry on connecting.\n"
2013 "If you do not trust this host, hit No to abandon the\n"
2014 "connection.\n";
2015
2016 static const char wrongmsg[] =
2017 "WARNING - POTENTIAL SECURITY BREACH!\n"
2018 "\n"
2019 "The server's host key does not match the one PuTTY has\n"
2020 "cached in the registry. This means that either the\n"
2021 "server administrator has changed the host key, or you\n"
2022 "have actually connected to another computer pretending\n"
2023 "to be the server.\n"
2024 "The new key fingerprint is:\n"
2025 "%s\n"
2026 "If you were expecting this change and trust the new key,\n"
2027 "hit Yes to update PuTTY's cache and continue connecting.\n"
2028 "If you want to carry on connecting but without updating\n"
2029 "the cache, hit No.\n"
2030 "If you want to abandon the connection completely, hit\n"
2031 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2032 "choice.\n";
2033
2034 static const char mbtitle[] = "PuTTY Security Alert";
2035
2036
2037 char message[160+ /* sensible fingerprint max size */
2038 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2039 sizeof(absentmsg) : sizeof(wrongmsg))];
2040
2041 /*
2042 * Verify the key against the registry.
2043 */
2044 ret = verify_host_key(host, port, keytype, keystr);
2045
2046 if (ret == 0) /* success - key matched OK */
2047 return;
2048 if (ret == 2) { /* key was different */
2049 int mbret;
2050 sprintf(message, wrongmsg, fingerprint);
2051 mbret = MessageBox(NULL, message, mbtitle,
2052 MB_ICONWARNING | MB_YESNOCANCEL);
2053 if (mbret == IDYES)
2054 store_host_key(host, port, keytype, keystr);
2055 if (mbret == IDCANCEL)
2056 exit(0);
2057 }
2058 if (ret == 1) { /* key was absent */
2059 int mbret;
2060 sprintf(message, absentmsg, fingerprint);
2061 mbret = MessageBox(NULL, message, mbtitle,
2062 MB_ICONWARNING | MB_YESNO);
2063 if (mbret == IDNO)
2064 exit(0);
2065 store_host_key(host, port, keytype, keystr);
2066 }
2067 }
2068
2069 /*
2070 * Ask whether to wipe a session log file before writing to it.
2071 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2072 */
2073 int askappend(char *filename) {
2074 static const char mbtitle[] = "PuTTY Log to File";
2075 static const char msgtemplate[] =
2076 "The session log file \"%.*s\" already exists.\n"
2077 "You can overwrite it with a new session log,\n"
2078 "append your session log to the end of it,\n"
2079 "or disable session logging for this session.\n"
2080 "Hit Yes to wipe the file, No to append to it,\n"
2081 "or Cancel to disable logging.";
2082 char message[sizeof(msgtemplate) + FILENAME_MAX];
2083 int mbret;
2084 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2085
2086 mbret = MessageBox(NULL, message, mbtitle,
2087 MB_ICONQUESTION | MB_YESNOCANCEL);
2088 if (mbret == IDYES)
2089 return 2;
2090 else if (mbret == IDNO)
2091 return 1;
2092 else
2093 return 0;
2094 }