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