]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - windlg.c
Add another bug workaround, this one for old OpenSSH (<2.3) servers
[PuTTY.git] / windlg.c
1 #include <windows.h>
2 #include <commctrl.h>
3 #include <commdlg.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <ctype.h>
7 #include <time.h>
8
9 #include "ssh.h"
10 #include "putty.h"
11 #include "winstuff.h"
12 #include "win_res.h"
13 #include "storage.h"
14
15 #ifdef MSVC4
16 #define TVINSERTSTRUCT  TV_INSERTSTRUCT
17 #define TVITEM          TV_ITEM
18 #define ICON_BIG        1
19 #endif
20
21 static char **events = NULL;
22 static int nevents = 0, negsize = 0;
23
24 static int readytogo;
25 static int sesslist_has_focus;
26 static int requested_help;
27
28 static struct prefslist cipherlist;
29
30 extern Config cfg;                     /* defined in window.c */
31
32 struct sesslist sesslist;              /* exported to window.c */
33
34 #define PRINTER_DISABLED_STRING "None (printing disabled)"
35
36 void force_normal(HWND hwnd)
37 {
38     static int recurse = 0;
39
40     WINDOWPLACEMENT wp;
41
42     if (recurse)
43         return;
44     recurse = 1;
45
46     wp.length = sizeof(wp);
47     if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
48         wp.showCmd = SW_SHOWNORMAL;
49         SetWindowPlacement(hwnd, &wp);
50     }
51     recurse = 0;
52 }
53
54 static void MyGetDlgItemInt(HWND hwnd, int id, int *result)
55 {
56     BOOL ok;
57     int n;
58     n = GetDlgItemInt(hwnd, id, &ok, FALSE);
59     if (ok)
60         *result = n;
61 }
62
63 static void MyGetDlgItemFlt(HWND hwnd, int id, int *result, int scale)
64 {
65     char text[80];
66     BOOL ok;
67     ok = GetDlgItemText(hwnd, id, text, sizeof(text) - 1);
68     if (ok && text[0])
69         *result = (int) (scale * atof(text));
70 }
71
72 static void MySetDlgItemFlt(HWND hwnd, int id, double value)
73 {
74     char text[80];
75     sprintf(text, "%g", value);
76     SetDlgItemText(hwnd, id, text);
77 }
78
79 static int CALLBACK LogProc(HWND hwnd, UINT msg,
80                             WPARAM wParam, LPARAM lParam)
81 {
82     int i;
83
84     switch (msg) {
85       case WM_INITDIALOG:
86         {
87             static int tabs[4] = { 78, 108 };
88             SendDlgItemMessage(hwnd, IDN_LIST, LB_SETTABSTOPS, 2,
89                                (LPARAM) tabs);
90         }
91         for (i = 0; i < nevents; i++)
92             SendDlgItemMessage(hwnd, IDN_LIST, LB_ADDSTRING,
93                                0, (LPARAM) events[i]);
94         return 1;
95       case WM_COMMAND:
96         switch (LOWORD(wParam)) {
97           case IDOK:
98           case IDCANCEL:
99             logbox = NULL;
100             SetActiveWindow(GetParent(hwnd));
101             DestroyWindow(hwnd);
102             return 0;
103           case IDN_COPY:
104             if (HIWORD(wParam) == BN_CLICKED ||
105                 HIWORD(wParam) == BN_DOUBLECLICKED) {
106                 int selcount;
107                 int *selitems;
108                 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
109                                               LB_GETSELCOUNT, 0, 0);
110                 if (selcount == 0) {   /* don't even try to copy zero items */
111                     MessageBeep(0);
112                     break;
113                 }
114
115                 selitems = smalloc(selcount * sizeof(int));
116                 if (selitems) {
117                     int count = SendDlgItemMessage(hwnd, IDN_LIST,
118                                                    LB_GETSELITEMS,
119                                                    selcount,
120                                                    (LPARAM) selitems);
121                     int i;
122                     int size;
123                     char *clipdata;
124                     static unsigned char sel_nl[] = SEL_NL;
125
126                     if (count == 0) {  /* can't copy zero stuff */
127                         MessageBeep(0);
128                         break;
129                     }
130
131                     size = 0;
132                     for (i = 0; i < count; i++)
133                         size +=
134                             strlen(events[selitems[i]]) + sizeof(sel_nl);
135
136                     clipdata = smalloc(size);
137                     if (clipdata) {
138                         char *p = clipdata;
139                         for (i = 0; i < count; i++) {
140                             char *q = events[selitems[i]];
141                             int qlen = strlen(q);
142                             memcpy(p, q, qlen);
143                             p += qlen;
144                             memcpy(p, sel_nl, sizeof(sel_nl));
145                             p += sizeof(sel_nl);
146                         }
147                         write_aclip(NULL, clipdata, size, TRUE);
148                         sfree(clipdata);
149                     }
150                     sfree(selitems);
151
152                     for (i = 0; i < nevents; i++)
153                         SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
154                                            FALSE, i);
155                 }
156             }
157             return 0;
158         }
159         return 0;
160       case WM_CLOSE:
161         logbox = NULL;
162         SetActiveWindow(GetParent(hwnd));
163         DestroyWindow(hwnd);
164         return 0;
165     }
166     return 0;
167 }
168
169 static int CALLBACK LicenceProc(HWND hwnd, UINT msg,
170                                 WPARAM wParam, LPARAM lParam)
171 {
172     switch (msg) {
173       case WM_INITDIALOG:
174         return 1;
175       case WM_COMMAND:
176         switch (LOWORD(wParam)) {
177           case IDOK:
178             EndDialog(hwnd, 1);
179             return 0;
180         }
181         return 0;
182       case WM_CLOSE:
183         EndDialog(hwnd, 1);
184         return 0;
185     }
186     return 0;
187 }
188
189 static int CALLBACK AboutProc(HWND hwnd, UINT msg,
190                               WPARAM wParam, LPARAM lParam)
191 {
192     switch (msg) {
193       case WM_INITDIALOG:
194         SetDlgItemText(hwnd, IDA_VERSION, ver);
195         return 1;
196       case WM_COMMAND:
197         switch (LOWORD(wParam)) {
198           case IDOK:
199           case IDCANCEL:
200             EndDialog(hwnd, TRUE);
201             return 0;
202           case IDA_LICENCE:
203             EnableWindow(hwnd, 0);
204             DialogBox(hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
205                       NULL, LicenceProc);
206             EnableWindow(hwnd, 1);
207             SetActiveWindow(hwnd);
208             return 0;
209
210           case IDA_WEB:
211             /* Load web browser */
212             ShellExecute(hwnd, "open",
213                          "http://www.chiark.greenend.org.uk/~sgtatham/putty/",
214                          0, 0, SW_SHOWDEFAULT);
215             return 0;
216         }
217         return 0;
218       case WM_CLOSE:
219         EndDialog(hwnd, TRUE);
220         return 0;
221     }
222     return 0;
223 }
224
225 /*
226  * Null dialog procedure.
227  */
228 static int CALLBACK NullDlgProc(HWND hwnd, UINT msg,
229                                 WPARAM wParam, LPARAM lParam)
230 {
231     return 0;
232 }
233
234 static char savedsession[2048];
235
236 enum { IDCX_ABOUT =
237         IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
238
239     sessionpanelstart,
240     IDC_TITLE_SESSION,
241     IDC_BOX_SESSION1,
242     IDC_BOX_SESSION2,
243     IDC_BOX_SESSION3,
244     IDC_HOSTSTATIC,
245     IDC_HOST,
246     IDC_PORTSTATIC,
247     IDC_PORT,
248     IDC_PROTSTATIC,
249     IDC_PROTRAW,
250     IDC_PROTTELNET,
251     IDC_PROTRLOGIN,
252     IDC_PROTSSH,
253     IDC_SESSSTATIC,
254     IDC_SESSEDIT,
255     IDC_SESSLIST,
256     IDC_SESSLOAD,
257     IDC_SESSSAVE,
258     IDC_SESSDEL,
259     IDC_CLOSEEXIT,
260     IDC_COEALWAYS,
261     IDC_COENEVER,
262     IDC_COENORMAL,
263     sessionpanelend,
264
265     loggingpanelstart,
266     IDC_TITLE_LOGGING,
267     IDC_BOX_LOGGING1,
268     IDC_LSTATSTATIC,
269     IDC_LSTATOFF,
270     IDC_LSTATASCII,
271     IDC_LSTATRAW,
272     IDC_LSTATPACKET,
273     IDC_LGFSTATIC,
274     IDC_LGFEDIT,
275     IDC_LGFBUTTON,
276     IDC_LGFEXPLAIN,
277     IDC_LSTATXIST,
278     IDC_LSTATXOVR,
279     IDC_LSTATXAPN,
280     IDC_LSTATXASK,
281     loggingpanelend,
282
283     keyboardpanelstart,
284     IDC_TITLE_KEYBOARD,
285     IDC_BOX_KEYBOARD1,
286     IDC_BOX_KEYBOARD2,
287     IDC_BOX_KEYBOARD3,
288     IDC_DELSTATIC,
289     IDC_DEL008,
290     IDC_DEL127,
291     IDC_HOMESTATIC,
292     IDC_HOMETILDE,
293     IDC_HOMERXVT,
294     IDC_FUNCSTATIC,
295     IDC_FUNCTILDE,
296     IDC_FUNCLINUX,
297     IDC_FUNCXTERM,
298     IDC_FUNCVT400,
299     IDC_FUNCVT100P,
300     IDC_FUNCSCO,
301     IDC_KPSTATIC,
302     IDC_KPNORMAL,
303     IDC_KPAPPLIC,
304     IDC_KPNH,
305     IDC_CURSTATIC,
306     IDC_CURNORMAL,
307     IDC_CURAPPLIC,
308     IDC_COMPOSEKEY,
309     IDC_CTRLALTKEYS,
310     keyboardpanelend,
311
312     terminalpanelstart,
313     IDC_TITLE_TERMINAL,
314     IDC_BOX_TERMINAL1,
315     IDC_BOX_TERMINAL2,
316     IDC_BOX_TERMINAL3,
317     IDC_WRAPMODE,
318     IDC_DECOM,
319     IDC_LFHASCR,
320     IDC_BCE,
321     IDC_BLINKTEXT,
322     IDC_ANSWERBACK,
323     IDC_ANSWEREDIT,
324     IDC_ECHOSTATIC,
325     IDC_ECHOBACKEND,
326     IDC_ECHOYES,
327     IDC_ECHONO,
328     IDC_EDITSTATIC,
329     IDC_EDITBACKEND,
330     IDC_EDITYES,
331     IDC_EDITNO,
332     IDC_PRINTERSTATIC,
333     IDC_PRINTER,
334     terminalpanelend,
335
336     featurespanelstart,
337     IDC_TITLE_FEATURES,
338     IDC_BOX_FEATURES1,
339     IDC_NOAPPLICK,
340     IDC_NOAPPLICC,
341     IDC_NOMOUSEREP,
342     IDC_NORESIZE,
343     IDC_NOALTSCREEN,
344     IDC_NOWINTITLE,
345     IDC_NODBACKSPACE,
346     IDC_NOCHARSET,
347     featurespanelend,
348
349     bellpanelstart,
350     IDC_TITLE_BELL,
351     IDC_BOX_BELL1,
352     IDC_BOX_BELL2,
353     IDC_BELLSTATIC,
354     IDC_BELL_DISABLED,
355     IDC_BELL_DEFAULT,
356     IDC_BELL_WAVEFILE,
357     IDC_BELL_VISUAL,
358     IDC_BELL_WAVESTATIC,
359     IDC_BELL_WAVEEDIT,
360     IDC_BELL_WAVEBROWSE,
361     IDC_B_IND_STATIC,
362     IDC_B_IND_DISABLED,
363     IDC_B_IND_FLASH,
364     IDC_B_IND_STEADY,
365     IDC_BELLOVL,
366     IDC_BELLOVLNSTATIC,
367     IDC_BELLOVLN,
368     IDC_BELLOVLTSTATIC,
369     IDC_BELLOVLT,
370     IDC_BELLOVLEXPLAIN,
371     IDC_BELLOVLSSTATIC,
372     IDC_BELLOVLS,
373     bellpanelend,
374
375     windowpanelstart,
376     IDC_TITLE_WINDOW,
377     IDC_BOX_WINDOW1,
378     IDC_BOX_WINDOW2,
379     IDC_BOX_WINDOW3,
380     IDC_ROWSSTATIC,
381     IDC_ROWSEDIT,
382     IDC_COLSSTATIC,
383     IDC_COLSEDIT,
384     IDC_RESIZESTATIC,
385     IDC_RESIZETERM,
386     IDC_RESIZEFONT,
387     IDC_RESIZENONE,
388     IDC_RESIZEEITHER,
389     IDC_SCROLLBAR,
390     IDC_SCROLLBARFULLSCREEN,
391     IDC_SAVESTATIC,
392     IDC_SAVEEDIT,
393     IDC_SCROLLKEY,
394     IDC_SCROLLDISP,
395     windowpanelend,
396
397     behaviourpanelstart,
398     IDC_TITLE_BEHAVIOUR,
399     IDC_BOX_BEHAVIOUR1,
400     IDC_CLOSEWARN,
401     IDC_ALTF4,
402     IDC_ALTSPACE,
403     IDC_ALTONLY,
404     IDC_ALWAYSONTOP,
405     IDC_FULLSCREENONALTENTER,
406     behaviourpanelend,
407
408     appearancepanelstart,
409     IDC_TITLE_APPEARANCE,
410     IDC_BOX_APPEARANCE1,
411     IDC_BOX_APPEARANCE2,
412     IDC_BOX_APPEARANCE3,
413     IDC_BOX_APPEARANCE4,
414     IDC_BOX_APPEARANCE5,
415     IDC_CURSORSTATIC,
416     IDC_CURBLOCK,
417     IDC_CURUNDER,
418     IDC_CURVERT,
419     IDC_BLINKCUR,
420     IDC_FONTSTATIC,
421     IDC_CHOOSEFONT,
422     IDC_WINTITLE,
423     IDC_WINEDIT,
424     IDC_WINNAME,
425     IDC_HIDEMOUSE,
426     IDC_SUNKENEDGE,
427     IDC_WINBSTATIC,
428     IDC_WINBEDIT,
429     appearancepanelend,
430
431     connectionpanelstart,
432     IDC_TITLE_CONNECTION,
433     IDC_BOX_CONNECTION1,
434     IDC_BOX_CONNECTION2,
435     IDC_BOX_CONNECTION3,
436     IDC_TTSTATIC,
437     IDC_TTEDIT,
438     IDC_LOGSTATIC,
439     IDC_LOGEDIT,
440     IDC_PINGSTATIC,
441     IDC_PINGEDIT,
442     IDC_NODELAY,
443     connectionpanelend,
444
445     proxypanelstart,
446     IDC_TITLE_PROXY,
447     IDC_BOX_PROXY1,
448     IDC_PROXYTYPESTATIC,
449     IDC_PROXYTYPENONE,
450     IDC_PROXYTYPEHTTP,
451     IDC_PROXYTYPESOCKS,
452     IDC_PROXYTYPETELNET,
453     IDC_PROXYHOSTSTATIC,
454     IDC_PROXYHOSTEDIT,
455     IDC_PROXYPORTSTATIC,
456     IDC_PROXYPORTEDIT,
457     IDC_PROXYEXCLUDESTATIC,
458     IDC_PROXYEXCLUDEEDIT,
459     IDC_PROXYLOCALHOST,
460     IDC_PROXYDNSSTATIC,
461     IDC_PROXYDNSNO,
462     IDC_PROXYDNSAUTO,
463     IDC_PROXYDNSYES,
464     IDC_PROXYUSERSTATIC,
465     IDC_PROXYUSEREDIT,
466     IDC_PROXYPASSSTATIC,
467     IDC_PROXYPASSEDIT,
468     IDC_BOX_PROXY2,
469     IDC_PROXYTELNETCMDSTATIC,
470     IDC_PROXYTELNETCMDEDIT,
471     IDC_PROXYSOCKSVERSTATIC,
472     IDC_PROXYSOCKSVER5,
473     IDC_PROXYSOCKSVER4,
474     proxypanelend,
475
476     telnetpanelstart,
477     IDC_TITLE_TELNET,
478     IDC_BOX_TELNET1,
479     IDC_BOX_TELNET2,
480     IDC_TSSTATIC,
481     IDC_TSEDIT,
482     IDC_ENVSTATIC,
483     IDC_VARSTATIC,
484     IDC_VAREDIT,
485     IDC_VALSTATIC,
486     IDC_VALEDIT,
487     IDC_ENVLIST,
488     IDC_ENVADD,
489     IDC_ENVREMOVE,
490     IDC_EMSTATIC,
491     IDC_EMBSD,
492     IDC_EMRFC,
493     IDC_ACTSTATIC,
494     IDC_TPASSIVE,
495     IDC_TACTIVE,
496     IDC_TELNETKEY,
497     IDC_TELNETRET,
498     telnetpanelend,
499
500     rloginpanelstart,
501     IDC_TITLE_RLOGIN,
502     IDC_BOX_RLOGIN1,
503     IDC_BOX_RLOGIN2,
504     IDC_R_TSSTATIC,
505     IDC_R_TSEDIT,
506     IDC_RLLUSERSTATIC,
507     IDC_RLLUSEREDIT,
508     rloginpanelend,
509
510     sshpanelstart,
511     IDC_TITLE_SSH,
512     IDC_BOX_SSH1,
513     IDC_BOX_SSH2,
514     IDC_BOX_SSH3,
515     IDC_NOPTY,
516     IDC_BOX_SSHCIPHER,
517     IDC_CIPHERSTATIC2,
518     IDC_CIPHERLIST,
519     IDC_CIPHERUP,
520     IDC_CIPHERDN,
521     IDC_SSH2DES,
522     IDC_SSHPROTSTATIC,
523     IDC_SSHPROT1ONLY,
524     IDC_SSHPROT1,
525     IDC_SSHPROT2,
526     IDC_SSHPROT2ONLY,
527     IDC_CMDSTATIC,
528     IDC_CMDEDIT,
529     IDC_COMPRESS,
530     sshpanelend,
531
532     sshauthpanelstart,
533     IDC_TITLE_SSHAUTH,
534     IDC_BOX_SSHAUTH1,
535     IDC_BOX_SSHAUTH2,
536     IDC_PKSTATIC,
537     IDC_PKEDIT,
538     IDC_PKBUTTON,
539     IDC_AGENTFWD,
540     IDC_CHANGEUSER,
541     IDC_AUTHTIS,
542     IDC_AUTHKI,
543     sshauthpanelend,
544
545     sshbugspanelstart,
546     IDC_TITLE_SSHBUGS,
547     IDC_BOX_SSHBUGS1,
548     IDC_BUGS_IGNORE1,
549     IDC_BUGD_IGNORE1,
550     IDC_BUGS_PLAINPW1,
551     IDC_BUGD_PLAINPW1,
552     IDC_BUGS_RSA1,
553     IDC_BUGD_RSA1,
554     IDC_BUGS_HMAC2,
555     IDC_BUGD_HMAC2,
556     IDC_BUGS_DERIVEKEY2,
557     IDC_BUGD_DERIVEKEY2,
558     IDC_BUGS_RSAPAD2,
559     IDC_BUGD_RSAPAD2,
560     IDC_BUGS_DHGEX2,
561     IDC_BUGD_DHGEX2,
562     IDC_BUGS_PKSESSID2,
563     IDC_BUGD_PKSESSID2,
564     sshbugspanelend,
565
566     selectionpanelstart,
567     IDC_TITLE_SELECTION,
568     IDC_BOX_SELECTION1,
569     IDC_BOX_SELECTION2,
570     IDC_BOX_SELECTION3,
571     IDC_MBSTATIC,
572     IDC_MBWINDOWS,
573     IDC_MBXTERM,
574     IDC_MOUSEOVERRIDE,
575     IDC_SELTYPESTATIC,
576     IDC_SELTYPELEX,
577     IDC_SELTYPERECT,
578     IDC_CCSTATIC,
579     IDC_CCLIST,
580     IDC_CCSET,
581     IDC_CCSTATIC2,
582     IDC_CCEDIT,
583     IDC_RAWCNP,
584     IDC_RTFPASTE,
585     selectionpanelend,
586
587     colourspanelstart,
588     IDC_TITLE_COLOURS,
589     IDC_BOX_COLOURS1,
590     IDC_BOX_COLOURS2,
591     IDC_BOLDCOLOUR,
592     IDC_PALETTE,
593     IDC_COLOURSTATIC,
594     IDC_COLOURLIST,
595     IDC_RSTATIC,
596     IDC_GSTATIC,
597     IDC_BSTATIC,
598     IDC_RVALUE,
599     IDC_GVALUE,
600     IDC_BVALUE,
601     IDC_CHANGE,
602     colourspanelend,
603
604     translationpanelstart,
605     IDC_TITLE_TRANSLATION,
606     IDC_BOX_TRANSLATION1,
607     IDC_BOX_TRANSLATION2,
608     IDC_BOX_TRANSLATION3,
609     IDC_CODEPAGESTATIC,
610     IDC_CODEPAGE,
611     IDC_CAPSLOCKCYR,
612     IDC_VTSTATIC,
613     IDC_VTXWINDOWS,
614     IDC_VTOEMANSI,
615     IDC_VTOEMONLY,
616     IDC_VTPOORMAN,
617     IDC_VTUNICODE,
618     translationpanelend,
619
620     tunnelspanelstart,
621     IDC_TITLE_TUNNELS,
622     IDC_BOX_TUNNELS1,
623     IDC_BOX_TUNNELS2,
624     IDC_X11_FORWARD,
625     IDC_X11_DISPSTATIC,
626     IDC_X11_DISPLAY,
627     IDC_X11AUTHSTATIC,
628     IDC_X11MIT,
629     IDC_X11XDM,
630     IDC_LPORT_ALL,
631     IDC_RPORT_ALL,
632     IDC_PFWDSTATIC,
633     IDC_PFWDSTATIC2,
634     IDC_PFWDREMOVE,
635     IDC_PFWDLIST,
636     IDC_PFWDADD,
637     IDC_SPORTSTATIC,
638     IDC_SPORTEDIT,
639     IDC_DPORTSTATIC,
640     IDC_DPORTEDIT,
641     IDC_PFWDLOCAL,
642     IDC_PFWDREMOTE,
643
644     tunnelspanelend,
645
646     controlendvalue
647 };
648
649 static const char *const colours[] = {
650     "Default Foreground", "Default Bold Foreground",
651     "Default Background", "Default Bold Background",
652     "Cursor Text", "Cursor Colour",
653     "ANSI Black", "ANSI Black Bold",
654     "ANSI Red", "ANSI Red Bold",
655     "ANSI Green", "ANSI Green Bold",
656     "ANSI Yellow", "ANSI Yellow Bold",
657     "ANSI Blue", "ANSI Blue Bold",
658     "ANSI Magenta", "ANSI Magenta Bold",
659     "ANSI Cyan", "ANSI Cyan Bold",
660     "ANSI White", "ANSI White Bold"
661 };
662
663 static void fmtfont(char *buf)
664 {
665     sprintf(buf, "Font: %s, ", cfg.font.name);
666     if (cfg.font.isbold)
667         strcat(buf, "bold, ");
668     if (cfg.font.height == 0)
669         strcat(buf, "default height");
670     else
671         sprintf(buf + strlen(buf), "%d-point",
672                 (cfg.font.height < 0 ? -cfg.font.height : cfg.font.height));
673 }
674
675 char *help_context_cmd(int id)
676 {
677     switch (id) {
678       case IDC_HOSTSTATIC:
679       case IDC_HOST:
680       case IDC_PORTSTATIC:
681       case IDC_PORT:
682       case IDC_PROTSTATIC:
683       case IDC_PROTRAW:
684       case IDC_PROTTELNET:
685       case IDC_PROTRLOGIN:
686       case IDC_PROTSSH:
687         return "JI(`',`session.hostname')";
688       case IDC_SESSSTATIC:
689       case IDC_SESSEDIT:
690       case IDC_SESSLIST:
691       case IDC_SESSLOAD:
692       case IDC_SESSSAVE:
693       case IDC_SESSDEL:
694         return "JI(`',`session.saved')";
695       case IDC_CLOSEEXIT:
696       case IDC_COEALWAYS:
697       case IDC_COENEVER:
698       case IDC_COENORMAL:
699         return "JI(`',`session.coe')";
700       case IDC_LSTATSTATIC:
701       case IDC_LSTATOFF:
702       case IDC_LSTATASCII:
703       case IDC_LSTATRAW:
704       case IDC_LSTATPACKET:
705         return "JI(`',`logging.main')";
706       case IDC_LGFSTATIC:
707       case IDC_LGFEDIT:
708       case IDC_LGFBUTTON:
709       case IDC_LGFEXPLAIN:
710         return "JI(`',`logging.filename')";
711       case IDC_LSTATXIST:
712       case IDC_LSTATXOVR:
713       case IDC_LSTATXAPN:
714       case IDC_LSTATXASK:
715         return "JI(`',`logging.exists')";
716
717       case IDC_DELSTATIC:
718       case IDC_DEL008:
719       case IDC_DEL127:
720         return "JI(`',`keyboard.backspace')";
721       case IDC_HOMESTATIC:
722       case IDC_HOMETILDE:
723       case IDC_HOMERXVT:
724         return "JI(`',`keyboard.homeend')";
725       case IDC_FUNCSTATIC:
726       case IDC_FUNCTILDE:
727       case IDC_FUNCLINUX:
728       case IDC_FUNCXTERM:
729       case IDC_FUNCVT400:
730       case IDC_FUNCVT100P:
731       case IDC_FUNCSCO:
732         return "JI(`',`keyboard.funkeys')";
733       case IDC_KPSTATIC:
734       case IDC_KPNORMAL:
735       case IDC_KPAPPLIC:
736         return "JI(`',`keyboard.appkeypad')";
737       case IDC_CURSTATIC:
738       case IDC_CURNORMAL:
739       case IDC_CURAPPLIC:
740         return "JI(`',`keyboard.appcursor')";
741       case IDC_KPNH:
742         return "JI(`',`keyboard.nethack')";
743       case IDC_COMPOSEKEY:
744         return "JI(`',`keyboard.compose')";
745       case IDC_CTRLALTKEYS:
746         return "JI(`',`keyboard.ctrlalt')";
747
748       case IDC_NOAPPLICK:
749       case IDC_NOAPPLICC:
750         return "JI(`',`features.application')";
751       case IDC_NOMOUSEREP:
752         return "JI(`',`features.mouse')";
753       case IDC_NORESIZE:
754         return "JI(`',`features.resize')";
755       case IDC_NOALTSCREEN:
756         return "JI(`',`features.altscreen')";
757       case IDC_NOWINTITLE:
758         return "JI(`',`features.retitle')";
759       case IDC_NODBACKSPACE:
760         return "JI(`',`features.dbackspace')";
761       case IDC_NOCHARSET:
762         return "JI(`',`features.charset')";
763
764       case IDC_WRAPMODE:
765         return "JI(`',`terminal.autowrap')";
766       case IDC_DECOM:
767         return "JI(`',`terminal.decom')";
768       case IDC_LFHASCR:
769         return "JI(`',`terminal.lfhascr')";
770       case IDC_BCE:
771         return "JI(`',`terminal.bce')";
772       case IDC_BLINKTEXT:
773         return "JI(`',`terminal.blink')";
774       case IDC_ANSWERBACK:
775       case IDC_ANSWEREDIT:
776         return "JI(`',`terminal.answerback')";
777       case IDC_ECHOSTATIC:
778       case IDC_ECHOBACKEND:
779       case IDC_ECHOYES:
780       case IDC_ECHONO:
781         return "JI(`',`terminal.localecho')";
782       case IDC_EDITSTATIC:
783       case IDC_EDITBACKEND:
784       case IDC_EDITYES:
785       case IDC_EDITNO:
786         return "JI(`',`terminal.localedit')";
787       case IDC_PRINTERSTATIC:
788       case IDC_PRINTER:
789         return "JI(`',`terminal.printing')";
790
791       case IDC_BELLSTATIC:
792       case IDC_BELL_DISABLED:
793       case IDC_BELL_DEFAULT:
794       case IDC_BELL_WAVEFILE:
795       case IDC_BELL_VISUAL:
796       case IDC_BELL_WAVESTATIC:
797       case IDC_BELL_WAVEEDIT:
798       case IDC_BELL_WAVEBROWSE:
799         return "JI(`',`bell.style')";
800       case IDC_B_IND_STATIC:
801       case IDC_B_IND_DISABLED:
802       case IDC_B_IND_FLASH:
803       case IDC_B_IND_STEADY:
804         return "JI(`',`bell.taskbar')";
805       case IDC_BELLOVL:
806       case IDC_BELLOVLNSTATIC:
807       case IDC_BELLOVLN:
808       case IDC_BELLOVLTSTATIC:
809       case IDC_BELLOVLT:
810       case IDC_BELLOVLEXPLAIN:
811       case IDC_BELLOVLSSTATIC:
812       case IDC_BELLOVLS:
813         return "JI(`',`bell.overload')";
814
815       case IDC_ROWSSTATIC:
816       case IDC_ROWSEDIT:
817       case IDC_COLSSTATIC:
818       case IDC_COLSEDIT:
819         return "JI(`',`window.size')";
820       case IDC_RESIZESTATIC:
821       case IDC_RESIZETERM:
822       case IDC_RESIZEFONT:
823       case IDC_RESIZENONE:
824       case IDC_RESIZEEITHER:
825         return "JI(`',`window.resize')";
826       case IDC_SCROLLBAR:
827       case IDC_SCROLLBARFULLSCREEN:
828       case IDC_SAVESTATIC:
829       case IDC_SAVEEDIT:
830       case IDC_SCROLLKEY:
831       case IDC_SCROLLDISP:
832         return "JI(`',`window.scrollback')";
833
834       case IDC_CLOSEWARN:
835         return "JI(`',`behaviour.closewarn')";
836       case IDC_ALTF4:
837         return "JI(`',`behaviour.altf4')";
838       case IDC_ALTSPACE:
839         return "JI(`',`behaviour.altspace')";
840       case IDC_ALTONLY:
841         return "JI(`',`behaviour.altonly')";
842       case IDC_ALWAYSONTOP:
843         return "JI(`',`behaviour.alwaysontop')";
844       case IDC_FULLSCREENONALTENTER:
845         return "JI(`',`behaviour.altenter')";
846
847       case IDC_CURSORSTATIC:
848       case IDC_CURBLOCK:
849       case IDC_CURUNDER:
850       case IDC_CURVERT:
851       case IDC_BLINKCUR:
852         return "JI(`',`appearance.cursor')";
853       case IDC_FONTSTATIC:
854       case IDC_CHOOSEFONT:
855         return "JI(`',`appearance.font')";
856       case IDC_WINTITLE:
857       case IDC_WINEDIT:
858       case IDC_WINNAME:
859         return "JI(`',`appearance.title')";
860       case IDC_HIDEMOUSE:
861         return "JI(`',`appearance.hidemouse')";
862       case IDC_SUNKENEDGE:
863       case IDC_WINBSTATIC:
864       case IDC_WINBEDIT:
865         return "JI(`',`appearance.border')";
866
867       case IDC_TTSTATIC:
868       case IDC_TTEDIT:
869         return "JI(`',`connection.termtype')";
870       case IDC_LOGSTATIC:
871       case IDC_LOGEDIT:
872         return "JI(`',`connection.username')";
873       case IDC_PINGSTATIC:
874       case IDC_PINGEDIT:
875         return "JI(`',`connection.keepalive')";
876       case IDC_NODELAY:
877         return "JI(`',`connection.nodelay')";
878
879       case IDC_PROXYTYPESTATIC:
880       case IDC_PROXYTYPENONE:
881       case IDC_PROXYTYPEHTTP:
882       case IDC_PROXYTYPESOCKS:
883       case IDC_PROXYTYPETELNET:
884         return "JI(`',`proxy.type')";
885       case IDC_PROXYHOSTSTATIC:
886       case IDC_PROXYHOSTEDIT:
887       case IDC_PROXYPORTSTATIC:
888       case IDC_PROXYPORTEDIT:
889         return "JI(`',`proxy.main')";
890       case IDC_PROXYEXCLUDESTATIC:
891       case IDC_PROXYEXCLUDEEDIT:
892       case IDC_PROXYLOCALHOST:
893         return "JI(`',`proxy.exclude')";
894       case IDC_PROXYDNSSTATIC:
895       case IDC_PROXYDNSNO:
896       case IDC_PROXYDNSAUTO:
897       case IDC_PROXYDNSYES:
898         return "JI(`',`proxy.dns')";
899       case IDC_PROXYUSERSTATIC:
900       case IDC_PROXYUSEREDIT:
901       case IDC_PROXYPASSSTATIC:
902       case IDC_PROXYPASSEDIT:
903         return "JI(`',`proxy.auth')";
904       case IDC_PROXYTELNETCMDSTATIC:
905       case IDC_PROXYTELNETCMDEDIT:
906         return "JI(`',`proxy.command')";
907       case IDC_PROXYSOCKSVERSTATIC:
908       case IDC_PROXYSOCKSVER5:
909       case IDC_PROXYSOCKSVER4:
910         return "JI(`',`proxy.socksver')";
911
912       case IDC_TSSTATIC:
913       case IDC_TSEDIT:
914         return "JI(`',`telnet.termspeed')";
915       case IDC_ENVSTATIC:
916       case IDC_VARSTATIC:
917       case IDC_VAREDIT:
918       case IDC_VALSTATIC:
919       case IDC_VALEDIT:
920       case IDC_ENVLIST:
921       case IDC_ENVADD:
922       case IDC_ENVREMOVE:
923         return "JI(`',`telnet.environ')";
924       case IDC_EMSTATIC:
925       case IDC_EMBSD:
926       case IDC_EMRFC:
927         return "JI(`',`telnet.oldenviron')";
928       case IDC_ACTSTATIC:
929       case IDC_TPASSIVE:
930       case IDC_TACTIVE:
931         return "JI(`',`telnet.passive')";
932       case IDC_TELNETKEY:
933         return "JI(`',`telnet.specialkeys')";
934       case IDC_TELNETRET:
935         return "JI(`',`telnet.newline')";
936
937       case IDC_R_TSSTATIC:
938       case IDC_R_TSEDIT:
939         return "JI(`',`rlogin.termspeed')";
940       case IDC_RLLUSERSTATIC:
941       case IDC_RLLUSEREDIT:
942         return "JI(`',`rlogin.localuser')";
943
944       case IDC_NOPTY:
945         return "JI(`',`ssh.nopty')";
946       case IDC_CIPHERSTATIC2:
947       case IDC_CIPHERLIST:
948       case IDC_CIPHERUP:
949       case IDC_CIPHERDN:
950       case IDC_SSH2DES:
951         return "JI(`',`ssh.ciphers')";
952       case IDC_SSHPROTSTATIC:
953       case IDC_SSHPROT1ONLY:
954       case IDC_SSHPROT1:
955       case IDC_SSHPROT2:
956       case IDC_SSHPROT2ONLY:
957         return "JI(`',`ssh.protocol')";
958       case IDC_CMDSTATIC:
959       case IDC_CMDEDIT:
960         return "JI(`',`ssh.command')";
961       case IDC_COMPRESS:
962         return "JI(`',`ssh.compress')";
963
964       case IDC_PKSTATIC:
965       case IDC_PKEDIT:
966       case IDC_PKBUTTON:
967         return "JI(`',`ssh.auth.privkey')";
968       case IDC_AGENTFWD:
969         return "JI(`',`ssh.auth.agentfwd')";
970       case IDC_CHANGEUSER:
971         return "JI(`',`ssh.auth.changeuser')";
972       case IDC_AUTHTIS:
973         return "JI(`',`ssh.auth.tis')";
974       case IDC_AUTHKI:
975         return "JI(`',`ssh.auth.ki')";
976
977       case IDC_MBSTATIC:
978       case IDC_MBWINDOWS:
979       case IDC_MBXTERM:
980         return "JI(`',`selection.buttons')";
981       case IDC_MOUSEOVERRIDE:
982         return "JI(`',`selection.shiftdrag')";
983       case IDC_SELTYPESTATIC:
984       case IDC_SELTYPELEX:
985       case IDC_SELTYPERECT:
986         return "JI(`',`selection.rect')";
987       case IDC_CCSTATIC:
988       case IDC_CCLIST:
989       case IDC_CCSET:
990       case IDC_CCSTATIC2:
991       case IDC_CCEDIT:
992         return "JI(`',`selection.charclasses')";
993       case IDC_RAWCNP:
994         return "JI(`',`selection.linedraw')";
995       case IDC_RTFPASTE:
996         return "JI(`',`selection.rtf')";
997
998       case IDC_BOLDCOLOUR:
999         return "JI(`',`colours.bold')";
1000       case IDC_PALETTE:
1001         return "JI(`',`colours.logpal')";
1002       case IDC_COLOURSTATIC:
1003       case IDC_COLOURLIST:
1004       case IDC_RSTATIC:
1005       case IDC_GSTATIC:
1006       case IDC_BSTATIC:
1007       case IDC_RVALUE:
1008       case IDC_GVALUE:
1009       case IDC_BVALUE:
1010       case IDC_CHANGE:
1011         return "JI(`',`colours.config')";
1012
1013       case IDC_CODEPAGESTATIC:
1014       case IDC_CODEPAGE:
1015         return "JI(`',`translation.codepage')";
1016       case IDC_CAPSLOCKCYR:
1017         return "JI(`',`translation.cyrillic')";
1018       case IDC_VTSTATIC:
1019       case IDC_VTXWINDOWS:
1020       case IDC_VTOEMANSI:
1021       case IDC_VTOEMONLY:
1022       case IDC_VTPOORMAN:
1023       case IDC_VTUNICODE:
1024         return "JI(`',`translation.linedraw')";
1025
1026       case IDC_X11_FORWARD:
1027       case IDC_X11_DISPSTATIC:
1028       case IDC_X11_DISPLAY:
1029         return "JI(`',`ssh.tunnels.x11')";
1030       case IDC_X11AUTHSTATIC:
1031       case IDC_X11MIT:
1032       case IDC_X11XDM:
1033         return "JI(`',`ssh.tunnels.x11auth')";
1034       case IDC_PFWDSTATIC:
1035       case IDC_PFWDSTATIC2:
1036       case IDC_PFWDREMOVE:
1037       case IDC_PFWDLIST:
1038       case IDC_PFWDADD:
1039       case IDC_SPORTSTATIC:
1040       case IDC_SPORTEDIT:
1041       case IDC_DPORTSTATIC:
1042       case IDC_DPORTEDIT:
1043       case IDC_PFWDLOCAL:
1044       case IDC_PFWDREMOTE:
1045         return "JI(`',`ssh.tunnels.portfwd')";
1046       case IDC_LPORT_ALL:
1047       case IDC_RPORT_ALL:
1048         return "JI(`',`ssh.tunnels.portfwd.localhost')";
1049
1050       case IDC_BUGS_IGNORE1:
1051       case IDC_BUGD_IGNORE1:
1052         return "JI(`',`ssh.bugs.ignore1')";
1053       case IDC_BUGS_PLAINPW1:
1054       case IDC_BUGD_PLAINPW1:
1055         return "JI(`',`ssh.bugs.plainpw1')";
1056       case IDC_BUGS_RSA1:
1057       case IDC_BUGD_RSA1:
1058         return "JI(`',`ssh.bugs.rsa1')";
1059       case IDC_BUGS_HMAC2:
1060       case IDC_BUGD_HMAC2:
1061         return "JI(`',`ssh.bugs.hmac2')";
1062       case IDC_BUGS_DERIVEKEY2:
1063       case IDC_BUGD_DERIVEKEY2:
1064         return "JI(`',`ssh.bugs.derivekey2')";
1065       case IDC_BUGS_RSAPAD2:
1066       case IDC_BUGD_RSAPAD2:
1067         return "JI(`',`ssh.bugs.rsapad2')";
1068       case IDC_BUGS_DHGEX2:
1069       case IDC_BUGD_DHGEX2:
1070         return "JI(`',`ssh.bugs.dhgex2')";
1071       case IDC_BUGS_PKSESSID2:
1072       case IDC_BUGD_PKSESSID2:
1073         return "JI(`',`ssh.bugs.pksessid2')";
1074
1075       default:
1076         return NULL;
1077     }
1078 }
1079
1080 /* 2nd arg: NZ => don't redraw session list (use when loading
1081  * a new session) */
1082 static void init_dlg_ctrls(HWND hwnd, int keepsess)
1083 {
1084     int i;
1085     char fontstatic[256];
1086
1087     SetDlgItemText(hwnd, IDC_HOST, cfg.host);
1088     SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession);
1089     if (!keepsess) {
1090         int i, n;
1091         n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
1092         for (i = n; i-- > 0;)
1093             SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_DELETESTRING, i, 0);
1094         for (i = 0; i < sesslist.nsessions; i++)
1095             SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_ADDSTRING,
1096                                0, (LPARAM) (sesslist.sessions[i]));
1097     }
1098     SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
1099     CheckRadioButton(hwnd, IDC_PROTRAW, IDC_PROTSSH,
1100                      cfg.protocol == PROT_SSH ? IDC_PROTSSH :
1101                      cfg.protocol == PROT_TELNET ? IDC_PROTTELNET :
1102                      cfg.protocol ==
1103                      PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
1104     SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
1105     CheckDlgButton(hwnd, IDC_NODELAY, cfg.tcp_nodelay);
1106
1107     CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
1108                      cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
1109     CheckRadioButton(hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
1110                      cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
1111     CheckRadioButton(hwnd, IDC_FUNCTILDE, IDC_FUNCSCO,
1112                      cfg.funky_type == 0 ? IDC_FUNCTILDE :
1113                      cfg.funky_type == 1 ? IDC_FUNCLINUX :
1114                      cfg.funky_type == 2 ? IDC_FUNCXTERM :
1115                      cfg.funky_type == 3 ? IDC_FUNCVT400 :
1116                      cfg.funky_type == 4 ? IDC_FUNCVT100P :
1117                      cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
1118     CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
1119     CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
1120     CheckDlgButton(hwnd, IDC_NOMOUSEREP, cfg.no_mouse_rep);
1121     CheckDlgButton(hwnd, IDC_NORESIZE, cfg.no_remote_resize);
1122     CheckDlgButton(hwnd, IDC_NOALTSCREEN, cfg.no_alt_screen);
1123     CheckDlgButton(hwnd, IDC_NOWINTITLE, cfg.no_remote_wintitle);
1124     CheckDlgButton(hwnd, IDC_NODBACKSPACE, cfg.no_dbackspace);
1125     CheckDlgButton(hwnd, IDC_NOCHARSET, cfg.no_remote_charset);
1126     CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
1127                      cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
1128     CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
1129                      cfg.nethack_keypad ? IDC_KPNH :
1130                      cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
1131     CheckDlgButton(hwnd, IDC_ALTF4, cfg.alt_f4);
1132     CheckDlgButton(hwnd, IDC_ALTSPACE, cfg.alt_space);
1133     CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only);
1134     CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
1135     CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
1136     CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard);
1137     CheckDlgButton(hwnd, IDC_TELNETRET, cfg.telnet_newline);
1138     CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
1139                      cfg.localecho == AUTO ? IDC_ECHOBACKEND :
1140                      cfg.localecho == FORCE_ON ? IDC_ECHOYES : IDC_ECHONO);
1141     CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
1142                      cfg.localedit == AUTO ? IDC_EDITBACKEND :
1143                      cfg.localedit == FORCE_ON ? IDC_EDITYES : IDC_EDITNO);
1144     SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
1145     CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
1146     CheckDlgButton(hwnd, IDC_FULLSCREENONALTENTER, cfg.fullscreenonaltenter);
1147     CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
1148     CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
1149
1150     CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
1151     CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
1152     CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
1153     SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
1154     SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
1155     SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
1156     fmtfont(fontstatic);
1157     SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
1158     CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
1159                      cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
1160                      cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
1161                      cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
1162                      cfg.beep ==
1163                      BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
1164     CheckRadioButton(hwnd, IDC_B_IND_DISABLED, IDC_B_IND_STEADY,
1165                      cfg.beep_ind ==
1166                      B_IND_DISABLED ? IDC_B_IND_DISABLED : cfg.beep_ind ==
1167                      B_IND_FLASH ? IDC_B_IND_FLASH : cfg.beep_ind ==
1168                      B_IND_STEADY ? IDC_B_IND_STEADY : IDC_B_IND_DISABLED);
1169     SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile.path);
1170     CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
1171     SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
1172     MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
1173     MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
1174
1175     CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
1176     CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
1177
1178     SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
1179     CheckDlgButton(hwnd, IDC_WINNAME, !cfg.win_name_always);
1180     CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
1181     CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
1182     SetDlgItemInt(hwnd, IDC_WINBEDIT, cfg.window_border, FALSE);
1183     CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
1184                      cfg.cursor_type == 0 ? IDC_CURBLOCK :
1185                      cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
1186     CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
1187     CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
1188     CheckDlgButton(hwnd, IDC_SCROLLBARFULLSCREEN, cfg.scrollbar_in_fullscreen);
1189     CheckRadioButton(hwnd, IDC_RESIZETERM, IDC_RESIZEEITHER,
1190                      cfg.resize_action == RESIZE_TERM ? IDC_RESIZETERM :
1191                      cfg.resize_action == RESIZE_FONT ? IDC_RESIZEFONT :
1192                      cfg.resize_action == RESIZE_EITHER ? IDC_RESIZEEITHER :
1193                      IDC_RESIZENONE);
1194     CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
1195                      cfg.close_on_exit == AUTO ? IDC_COENORMAL :
1196                      cfg.close_on_exit ==
1197                      FORCE_OFF ? IDC_COENEVER : IDC_COEALWAYS);
1198     CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
1199
1200     SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
1201     SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
1202     SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
1203     SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
1204     SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
1205     SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename.path);
1206     CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATPACKET,
1207                      cfg.logtype == LGTYP_NONE ? IDC_LSTATOFF :
1208                      cfg.logtype == LGTYP_ASCII ? IDC_LSTATASCII :
1209                      cfg.logtype == LGTYP_DEBUG ? IDC_LSTATRAW :
1210                      IDC_LSTATPACKET);
1211     CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
1212                      cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
1213                      cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
1214                      IDC_LSTATXAPN);
1215     {
1216         char *p = cfg.environmt;
1217         SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_RESETCONTENT, 0, 0);
1218         while (*p) {
1219             SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
1220                                (LPARAM) p);
1221             p += strlen(p) + 1;
1222         }
1223         p = cfg.portfwd;
1224         while (*p) {
1225             SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING, 0,
1226                                (LPARAM) p);
1227             p += strlen(p) + 1;
1228         }
1229     }
1230     CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
1231                      cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
1232     CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE,
1233                      cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE);
1234
1235     SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
1236     SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
1237     CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
1238     CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
1239     CheckDlgButton(hwnd, IDC_SSH2DES, cfg.ssh2_des_cbc);
1240     CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
1241     CheckDlgButton(hwnd, IDC_CHANGEUSER, cfg.change_username);
1242     CheckRadioButton(hwnd, IDC_SSHPROT1ONLY, IDC_SSHPROT2ONLY,
1243                      cfg.sshprot == 1 ? IDC_SSHPROT1 :
1244                      cfg.sshprot == 2 ? IDC_SSHPROT2 :
1245                      cfg.sshprot == 3 ? IDC_SSHPROT2ONLY : IDC_SSHPROT1ONLY);
1246     CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
1247     CheckDlgButton(hwnd, IDC_AUTHKI, cfg.try_ki_auth);
1248     SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile.path);
1249     SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
1250
1251     {
1252         int i;
1253         static const struct { char *s; int c; } ciphers[] = {
1254             { "3DES",                   CIPHER_3DES },
1255             { "Blowfish",               CIPHER_BLOWFISH },
1256             { "DES",                    CIPHER_DES },
1257             { "AES (SSH 2 only)",       CIPHER_AES },
1258             { "-- warn below here --",  CIPHER_WARN }
1259         };
1260
1261         /* Set up the "selected ciphers" box. */
1262         /* (cipherlist assumed to contain all ciphers) */
1263         SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_RESETCONTENT, 0, 0);
1264         for (i = 0; i < CIPHER_MAX; i++) {
1265             int c = cfg.ssh_cipherlist[i];
1266             int j, pos;
1267             char *cstr = NULL;
1268             for (j = 0; j < (sizeof ciphers) / (sizeof ciphers[0]); j++) {
1269                 if (ciphers[j].c == c) {
1270                     cstr = ciphers[j].s;
1271                     break;
1272                 }
1273             }
1274             pos = SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_ADDSTRING,
1275                                      0, (LPARAM) cstr);
1276             SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_SETITEMDATA,
1277                                pos, (LPARAM) c);
1278         }
1279
1280     }
1281
1282     CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
1283                      cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
1284     CheckRadioButton(hwnd, IDC_SELTYPELEX, IDC_SELTYPERECT,
1285                      cfg.rect_select == 0 ? IDC_SELTYPELEX : IDC_SELTYPERECT);
1286     CheckDlgButton(hwnd, IDC_MOUSEOVERRIDE, cfg.mouse_override);
1287     CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
1288     CheckDlgButton(hwnd, IDC_RTFPASTE, cfg.rtf_paste);
1289     {
1290         static int tabs[4] = { 25, 61, 96, 128 };
1291         SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
1292                            (LPARAM) tabs);
1293     }
1294     for (i = 0; i < 128; i++) {
1295         char str[100];
1296         sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1297                 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
1298         SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
1299                            (LPARAM) str);
1300     }
1301
1302     CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
1303     CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
1304     {
1305         int i, n;
1306         n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1307         for (i = n; i-- > 0;)
1308             SendDlgItemMessage(hwnd, IDC_COLOURLIST,
1309                                LB_DELETESTRING, i, 0);
1310         for (i = 0; i < 22; i++)
1311             SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
1312                                (LPARAM) colours[i]);
1313     }
1314     SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
1315     SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
1316     SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
1317     SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
1318
1319     {
1320         int i;
1321         char *cp;
1322         strcpy(cfg.line_codepage, cp_name(decode_codepage(cfg.line_codepage)));
1323         SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_RESETCONTENT, 0, 0);
1324         CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
1325         for (i = 0; (cp = cp_enumerate(i)) != NULL; i++) {
1326             SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_ADDSTRING,
1327                                0, (LPARAM) cp);
1328         }
1329         SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
1330     }
1331
1332     {
1333         int i, nprinters;
1334         printer_enum *pe;
1335         pe = printer_start_enum(&nprinters);
1336         SendDlgItemMessage(hwnd, IDC_PRINTER, CB_RESETCONTENT, 0, 0);
1337         SendDlgItemMessage(hwnd, IDC_PRINTER, CB_ADDSTRING,
1338                            0, (LPARAM) PRINTER_DISABLED_STRING);
1339         for (i = 0; i < nprinters; i++) {
1340             char *printer_name = printer_get_name(pe, i);
1341             SendDlgItemMessage(hwnd, IDC_PRINTER, CB_ADDSTRING,
1342                                0, (LPARAM) printer_name);
1343         }
1344         printer_finish_enum(pe);
1345         SetDlgItemText(hwnd, IDC_PRINTER,
1346                        *cfg.printer ? cfg.printer : PRINTER_DISABLED_STRING);
1347     }
1348
1349     CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
1350                      cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
1351                      cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
1352                      cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
1353                      cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE :
1354                      IDC_VTPOORMAN);
1355
1356     CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
1357     SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
1358     CheckRadioButton(hwnd, IDC_X11MIT, IDC_X11XDM,
1359                      cfg.x11_auth == X11_MIT ? IDC_X11MIT : IDC_X11XDM);
1360
1361     CheckDlgButton(hwnd, IDC_LPORT_ALL, cfg.lport_acceptall);
1362     CheckDlgButton(hwnd, IDC_RPORT_ALL, cfg.rport_acceptall);
1363     CheckRadioButton(hwnd, IDC_PFWDLOCAL, IDC_PFWDREMOTE, IDC_PFWDLOCAL);
1364
1365     /* proxy config */
1366     CheckRadioButton(hwnd, IDC_PROXYTYPENONE, IDC_PROXYTYPETELNET,
1367                      cfg.proxy_type == PROXY_HTTP ? IDC_PROXYTYPEHTTP :
1368                      cfg.proxy_type == PROXY_SOCKS ? IDC_PROXYTYPESOCKS :
1369                      cfg.proxy_type == PROXY_TELNET ? IDC_PROXYTYPETELNET : IDC_PROXYTYPENONE);
1370     SetDlgItemText(hwnd, IDC_PROXYHOSTEDIT, cfg.proxy_host);
1371     SetDlgItemInt(hwnd, IDC_PROXYPORTEDIT, cfg.proxy_port, FALSE);
1372     SetDlgItemText(hwnd, IDC_PROXYEXCLUDEEDIT, cfg.proxy_exclude_list);
1373     CheckDlgButton(hwnd, IDC_PROXYLOCALHOST, cfg.even_proxy_localhost);
1374     CheckRadioButton(hwnd, IDC_PROXYDNSNO, IDC_PROXYDNSYES,
1375                      cfg.proxy_dns == FORCE_OFF ? IDC_PROXYDNSNO :
1376                      cfg.proxy_dns == FORCE_ON ? IDC_PROXYDNSYES :
1377                      IDC_PROXYDNSAUTO);
1378     SetDlgItemText(hwnd, IDC_PROXYTELNETCMDEDIT, cfg.proxy_telnet_command);
1379     SetDlgItemText(hwnd, IDC_PROXYUSEREDIT, cfg.proxy_username);
1380     SetDlgItemText(hwnd, IDC_PROXYPASSEDIT, cfg.proxy_password);
1381     CheckRadioButton(hwnd, IDC_PROXYSOCKSVER5, IDC_PROXYSOCKSVER4,
1382                      cfg.proxy_socks_version == 4 ? IDC_PROXYSOCKSVER4 : IDC_PROXYSOCKSVER5);
1383
1384     /* SSH bugs config */
1385     SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_RESETCONTENT, 0, 0);
1386     SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_ADDSTRING, 0, (LPARAM)"Auto");
1387     SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_ADDSTRING, 0, (LPARAM)"Off");
1388     SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_ADDSTRING, 0, (LPARAM)"On");
1389     SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_SETCURSEL,
1390                        cfg.sshbug_ignore1 == FORCE_ON ? 2 :
1391                        cfg.sshbug_ignore1 == FORCE_OFF ? 1 : 0, 0);
1392     SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_RESETCONTENT, 0, 0);
1393     SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_ADDSTRING, 0, (LPARAM)"Auto");
1394     SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_ADDSTRING, 0, (LPARAM)"Off");
1395     SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_ADDSTRING, 0, (LPARAM)"On");
1396     SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_SETCURSEL,
1397                        cfg.sshbug_plainpw1 == FORCE_ON ? 2 :
1398                        cfg.sshbug_plainpw1 == FORCE_OFF ? 1 : 0, 0);
1399     SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_RESETCONTENT, 0, 0);
1400     SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_ADDSTRING, 0, (LPARAM)"Auto");
1401     SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_ADDSTRING, 0, (LPARAM)"Off");
1402     SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_ADDSTRING, 0, (LPARAM)"On");
1403     SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_SETCURSEL,
1404                        cfg.sshbug_rsa1 == FORCE_ON ? 2 :
1405                        cfg.sshbug_rsa1 == FORCE_OFF ? 1 : 0, 0);
1406     SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_RESETCONTENT, 0, 0);
1407     SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_ADDSTRING, 0, (LPARAM)"Auto");
1408     SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_ADDSTRING, 0, (LPARAM)"Off");
1409     SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_ADDSTRING, 0, (LPARAM)"On");
1410     SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_SETCURSEL,
1411                        cfg.sshbug_hmac2 == FORCE_ON ? 2 :
1412                        cfg.sshbug_hmac2 == FORCE_OFF ? 1 : 0, 0);
1413     SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_RESETCONTENT, 0, 0);
1414     SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_ADDSTRING, 0, (LPARAM)"Auto");
1415     SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_ADDSTRING, 0, (LPARAM)"Off");
1416     SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_ADDSTRING, 0, (LPARAM)"On");
1417     SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_SETCURSEL,
1418                        cfg.sshbug_derivekey2 == FORCE_ON ? 2 :
1419                        cfg.sshbug_derivekey2 == FORCE_OFF ? 1 : 0, 0);
1420     SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_RESETCONTENT, 0, 0);
1421     SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_ADDSTRING, 0, (LPARAM)"Auto");
1422     SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_ADDSTRING, 0, (LPARAM)"Off");
1423     SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_ADDSTRING, 0, (LPARAM)"On");
1424     SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_SETCURSEL,
1425                        cfg.sshbug_rsapad2 == FORCE_ON ? 2 :
1426                        cfg.sshbug_rsapad2 == FORCE_OFF ? 1 : 0, 0);
1427     SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_RESETCONTENT, 0, 0);
1428     SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_ADDSTRING, 0, (LPARAM)"Auto");
1429     SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_ADDSTRING, 0, (LPARAM)"Off");
1430     SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_ADDSTRING, 0, (LPARAM)"On");
1431     SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_SETCURSEL,
1432                        cfg.sshbug_dhgex2 == FORCE_ON ? 2 :
1433                        cfg.sshbug_dhgex2 == FORCE_OFF ? 1 : 0, 0);
1434     SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_RESETCONTENT, 0, 0);
1435     SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_ADDSTRING, 0, (LPARAM)"Auto");
1436     SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_ADDSTRING, 0, (LPARAM)"Off");
1437     SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_ADDSTRING, 0, (LPARAM)"On");
1438     SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_SETCURSEL,
1439                        cfg.sshbug_pksessid2 == FORCE_ON ? 2 :
1440                        cfg.sshbug_pksessid2 == FORCE_OFF ? 1 : 0, 0);
1441 }
1442
1443 struct treeview_faff {
1444     HWND treeview;
1445     HTREEITEM lastat[4];
1446 };
1447
1448 static HTREEITEM treeview_insert(struct treeview_faff *faff,
1449                                  int level, char *text)
1450 {
1451     TVINSERTSTRUCT ins;
1452     int i;
1453     HTREEITEM newitem;
1454     ins.hParent = (level > 0 ? faff->lastat[level - 1] : TVI_ROOT);
1455     ins.hInsertAfter = faff->lastat[level];
1456 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
1457 #define INSITEM DUMMYUNIONNAME.item
1458 #else
1459 #define INSITEM item
1460 #endif
1461     ins.INSITEM.mask = TVIF_TEXT;
1462     ins.INSITEM.pszText = text;
1463     newitem = TreeView_InsertItem(faff->treeview, &ins);
1464     if (level > 0)
1465         TreeView_Expand(faff->treeview, faff->lastat[level - 1],
1466                         TVE_EXPAND);
1467     faff->lastat[level] = newitem;
1468     for (i = level + 1; i < 4; i++)
1469         faff->lastat[i] = NULL;
1470     return newitem;
1471 }
1472
1473 /*
1474  * Create the panelfuls of controls in the configuration box.
1475  */
1476 static void create_controls(HWND hwnd, int dlgtype, int panel)
1477 {
1478     if (panel == sessionpanelstart) {
1479         /* The Session panel. Accelerators used: [acgoh] nprtis elvd w */
1480         struct ctlpos cp;
1481         ctlposinit(&cp, hwnd, 80, 3, 13);
1482         bartitle(&cp, "Basic options for your PuTTY session",
1483                  IDC_TITLE_SESSION);
1484         if (dlgtype == 0) {
1485             beginbox(&cp, "Specify your connection by host name or IP address",
1486                      IDC_BOX_SESSION1);
1487             multiedit(&cp,
1488                       "Host &Name (or IP address)",
1489                       IDC_HOSTSTATIC, IDC_HOST, 75,
1490                       "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
1491             if (backends[3].backend == NULL) {
1492                 /* this is PuTTYtel, so only three protocols available */
1493                 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
1494                           "&Raw", IDC_PROTRAW,
1495                           "&Telnet", IDC_PROTTELNET,
1496                           "Rlog&in", IDC_PROTRLOGIN, NULL);
1497             } else {
1498                 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
1499                           "&Raw", IDC_PROTRAW,
1500                           "&Telnet", IDC_PROTTELNET,
1501                           "Rlog&in", IDC_PROTRLOGIN,
1502 #ifdef FWHACK
1503                           "&SSH/hack",
1504 #else
1505                           "&SSH",
1506 #endif
1507                           IDC_PROTSSH, NULL);
1508             }
1509             endbox(&cp);
1510             beginbox(&cp, "Load, save or delete a stored session",
1511                      IDC_BOX_SESSION2);
1512             sesssaver(&cp, "Sav&ed Sessions",
1513                       IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
1514                       "&Load", IDC_SESSLOAD,
1515                       "Sa&ve", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
1516             endbox(&cp);
1517         }
1518         beginbox(&cp, NULL, IDC_BOX_SESSION3);
1519         radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
1520                   "Always", IDC_COEALWAYS,
1521                   "Never", IDC_COENEVER,
1522                   "Only on clean exit", IDC_COENORMAL, NULL);
1523         endbox(&cp);
1524     }
1525
1526     if (panel == loggingpanelstart) {
1527         /* The Logging panel. Accelerators used: [acgoh] tplsfwe */
1528         struct ctlpos cp;
1529         ctlposinit(&cp, hwnd, 80, 3, 13);
1530         bartitle(&cp, "Options controlling session logging",
1531                  IDC_TITLE_LOGGING);
1532         beginbox(&cp, NULL, IDC_BOX_LOGGING1);
1533         radiobig(&cp,
1534                  "Session logging:", IDC_LSTATSTATIC,
1535                  "Logging &turned off completely", IDC_LSTATOFF,
1536                  "Log &printable output only", IDC_LSTATASCII,
1537                  "&Log all session output", IDC_LSTATRAW,
1538                  "Log &SSH packet data", IDC_LSTATPACKET,
1539                  NULL);
1540         editbutton(&cp, "Log &file name:",
1541                    IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
1542                    IDC_LGFBUTTON);
1543         statictext(&cp, "(Log file name can contain &&Y, &&M, &&D for date,"
1544                    " &&T for time, and &&H for host name)", 2, IDC_LGFEXPLAIN);
1545         radiobig(&cp,
1546                  "What to do if the log file already &exists:",
1547                  IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
1548                  "Always append to the end of it", IDC_LSTATXAPN,
1549                  "Ask the user every time", IDC_LSTATXASK, NULL);
1550         endbox(&cp);
1551     }
1552
1553     if (panel == terminalpanelstart) {
1554         /* The Terminal panel. Accelerators used: [acgoh] wdren lts p */
1555         struct ctlpos cp;
1556         ctlposinit(&cp, hwnd, 80, 3, 13);
1557         bartitle(&cp, "Options controlling the terminal emulation",
1558                  IDC_TITLE_TERMINAL);
1559         beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
1560         checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
1561         checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
1562         checkbox(&cp, "Implicit C&R in every LF", IDC_LFHASCR);
1563         checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
1564         checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
1565         multiedit(&cp,
1566                   "An&swerback to ^E:", IDC_ANSWERBACK,
1567                   IDC_ANSWEREDIT, 100, NULL);
1568         endbox(&cp);
1569
1570         beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
1571         radioline(&cp, "&Local echo:", IDC_ECHOSTATIC, 3,
1572                   "Auto", IDC_ECHOBACKEND,
1573                   "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
1574         radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
1575                   "Auto", IDC_EDITBACKEND,
1576                   "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
1577         endbox(&cp);
1578
1579         beginbox(&cp, "Remote-controlled printing", IDC_BOX_TERMINAL3);
1580         combobox(&cp, "&Printer to send ANSI printer output to:",
1581                  IDC_PRINTERSTATIC, IDC_PRINTER);
1582         endbox(&cp);
1583     }
1584
1585     if (panel == featurespanelstart) {
1586         /* The Features panel. Accelerators used: [acgoh] ukswtbrx */
1587         struct ctlpos cp;
1588         ctlposinit(&cp, hwnd, 80, 3, 13);
1589         bartitle(&cp, "Enabling and disabling advanced terminal features ",
1590                  IDC_TITLE_FEATURES);
1591         beginbox(&cp, NULL, IDC_BOX_FEATURES1);
1592         checkbox(&cp, "Disable application c&ursor keys mode", IDC_NOAPPLICC);
1593         checkbox(&cp, "Disable application &keypad mode", IDC_NOAPPLICK);
1594         checkbox(&cp, "Disable &xterm-style mouse reporting", IDC_NOMOUSEREP);
1595         checkbox(&cp, "Disable remote-controlled terminal re&sizing",
1596                  IDC_NORESIZE);
1597         checkbox(&cp, "Disable s&witching to alternate terminal screen",
1598                  IDC_NOALTSCREEN);
1599         checkbox(&cp, "Disable remote-controlled window &title changing",
1600                  IDC_NOWINTITLE);
1601         checkbox(&cp, "Disable destructive &backspace on server sending ^?",
1602                  IDC_NODBACKSPACE);
1603         checkbox(&cp, "Disable remote-controlled cha&racter set configuration",
1604                  IDC_NOCHARSET);
1605         endbox(&cp);
1606     }
1607
1608     if (panel == bellpanelstart) {
1609         /* The Bell panel. Accelerators used: [acgoh] bdsm wit */
1610         struct ctlpos cp;
1611         ctlposinit(&cp, hwnd, 80, 3, 13);
1612         bartitle(&cp, "Options controlling the terminal bell",
1613                  IDC_TITLE_BELL);
1614         beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
1615         radiobig(&cp,
1616                  "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
1617                  "None (bell disabled)", IDC_BELL_DISABLED,
1618                  "Play Windows Default Sound", IDC_BELL_DEFAULT,
1619                  "Play a custom sound file", IDC_BELL_WAVEFILE,
1620                  "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
1621         editbutton(&cp, "Custom sound file to play as a bell:",
1622                    IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
1623                    "Bro&wse...", IDC_BELL_WAVEBROWSE);
1624         radioline(&cp, "Taskbar/caption &indication on bell:",
1625                   IDC_B_IND_STATIC, 3, "Disabled", IDC_B_IND_DISABLED,
1626                   "Flashing", IDC_B_IND_FLASH, "Steady", IDC_B_IND_STEADY,
1627                   NULL);
1628         endbox(&cp);
1629         beginbox(&cp, "Control the bell overload behaviour",
1630                  IDC_BOX_BELL2);
1631         checkbox(&cp, "Bell is temporarily &disabled when over-used",
1632                  IDC_BELLOVL);
1633         staticedit(&cp, "Over-use means this &many bells...",
1634                    IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
1635         staticedit(&cp, "... in &this many seconds",
1636                    IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
1637         statictext(&cp,
1638                    "The bell is re-enabled after a few seconds of silence.",
1639                    1, IDC_BELLOVLEXPLAIN);
1640         staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
1641                    IDC_BELLOVLS, 20);
1642         endbox(&cp);
1643     }
1644
1645     if (panel == keyboardpanelstart) {
1646         /* The Keyboard panel. Accelerators used: [acgoh] bef rntd */
1647         struct ctlpos cp;
1648         ctlposinit(&cp, hwnd, 80, 3, 13);
1649         bartitle(&cp, "Options controlling the effects of keys",
1650                  IDC_TITLE_KEYBOARD);
1651         beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
1652         radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
1653                   "Control-H", IDC_DEL008,
1654                   "Control-? (127)", IDC_DEL127, NULL);
1655         radioline(&cp, "The Home and &End keys", IDC_HOMESTATIC, 2,
1656                   "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
1657         radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
1658                   "ESC[n~", IDC_FUNCTILDE,
1659                   "Linux", IDC_FUNCLINUX,
1660                   "Xterm R6", IDC_FUNCXTERM,
1661                   "VT400", IDC_FUNCVT400,
1662                   "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
1663         endbox(&cp);
1664         beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
1665         radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
1666                   "Normal", IDC_CURNORMAL,
1667                   "Application", IDC_CURAPPLIC, NULL);
1668         radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
1669                   3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
1670                   "NetHack", IDC_KPNH, NULL);
1671         endbox(&cp);
1672         beginbox(&cp, "Enable extra keyboard features:",
1673                  IDC_BOX_KEYBOARD3);
1674         checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
1675         checkbox(&cp, "Control-Alt is &different from AltGr",
1676                  IDC_CTRLALTKEYS);
1677         endbox(&cp);
1678     }
1679
1680     if (panel == windowpanelstart) {
1681         /* The Window panel. Accelerators used: [acgoh] rmz sdikp */
1682         struct ctlpos cp;
1683         ctlposinit(&cp, hwnd, 80, 3, 13);
1684         bartitle(&cp, "Options controlling PuTTY's window",
1685                  IDC_TITLE_WINDOW);
1686         beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
1687         multiedit(&cp,
1688                   "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
1689                   "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
1690         radiobig(&cp, "When window is resi&zed:", IDC_RESIZESTATIC,
1691                  "Change the number of rows and columns", IDC_RESIZETERM,
1692                  "Change the size of the font", IDC_RESIZEFONT,
1693                  "Change font size only when maximised", IDC_RESIZEEITHER,
1694                  "Forbid resizing completely", IDC_RESIZENONE, NULL);
1695         endbox(&cp);
1696         beginbox(&cp, "Control the scrollback in the window",
1697                  IDC_BOX_WINDOW2);
1698         staticedit(&cp, "Lines of &scrollback",
1699                    IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
1700         checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
1701         checkbox(&cp, "D&isplay scrollbar in full screen mode", IDC_SCROLLBARFULLSCREEN);
1702         checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
1703         checkbox(&cp, "Reset scrollback on dis&play activity",
1704                  IDC_SCROLLDISP);
1705         endbox(&cp);
1706     }
1707
1708     if (panel == appearancepanelstart) {
1709         /* The Appearance panel. Accelerators used: [acgoh] luvb n ti p s */
1710         struct ctlpos cp;
1711         ctlposinit(&cp, hwnd, 80, 3, 13);
1712         bartitle(&cp, "Configure the appearance of PuTTY's window",
1713                  IDC_TITLE_APPEARANCE);
1714         beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
1715         radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
1716                   "B&lock", IDC_CURBLOCK,
1717                   "&Underline", IDC_CURUNDER,
1718                   "&Vertical line", IDC_CURVERT, NULL);
1719         checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
1720         endbox(&cp);
1721         beginbox(&cp, "Set the font used in the terminal window",
1722                  IDC_BOX_APPEARANCE2);
1723         staticbtn(&cp, "", IDC_FONTSTATIC, "Cha&nge...", IDC_CHOOSEFONT);
1724         endbox(&cp);
1725         beginbox(&cp, "Adjust the use of the window title",
1726                  IDC_BOX_APPEARANCE3);
1727         multiedit(&cp,
1728                   "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
1729         checkbox(&cp, "Separate window and &icon titles", IDC_WINNAME);
1730         endbox(&cp);
1731         beginbox(&cp, "Adjust the use of the mouse pointer",
1732                  IDC_BOX_APPEARANCE4);
1733         checkbox(&cp, "Hide mouse &pointer when typing in window",
1734                  IDC_HIDEMOUSE);
1735         endbox(&cp);
1736         beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
1737         checkbox(&cp, "&Sunken-edge border (slightly thicker)",
1738                  IDC_SUNKENEDGE);
1739         staticedit(&cp, "Gap between text and window edge",
1740                    IDC_WINBSTATIC, IDC_WINBEDIT, 20);
1741         endbox(&cp);
1742     }
1743
1744     if (panel == behaviourpanelstart) {
1745         /* The Behaviour panel. Accelerators used: [acgoh] w4yltf */
1746         struct ctlpos cp;
1747         ctlposinit(&cp, hwnd, 80, 3, 13);
1748         bartitle(&cp, "Configure the behaviour of PuTTY's window",
1749                  IDC_TITLE_WINDOW);
1750         beginbox(&cp, NULL, IDC_BOX_BEHAVIOUR1);
1751         checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
1752         checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
1753         checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
1754         checkbox(&cp, "System menu appears on A&LT alone", IDC_ALTONLY);
1755         checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
1756         checkbox(&cp, "&Full screen on Alt-Enter", IDC_FULLSCREENONALTENTER);
1757         endbox(&cp);
1758     }
1759
1760     if (panel == translationpanelstart) {
1761         /* The Translation panel. Accelerators used: [acgoh] rxbepus */
1762         struct ctlpos cp;
1763         ctlposinit(&cp, hwnd, 80, 3, 13);
1764         bartitle(&cp, "Options controlling character set translation",
1765                  IDC_TITLE_TRANSLATION);
1766         beginbox(&cp, "Character set translation on received data",
1767                  IDC_BOX_TRANSLATION1);
1768         combobox(&cp, "&Received data assumed to be in which character set:",
1769                  IDC_CODEPAGESTATIC, IDC_CODEPAGE);
1770         endbox(&cp);
1771         beginbox(&cp, "Enable character set translation on input data",
1772                  IDC_BOX_TRANSLATION2);
1773         checkbox(&cp, "Cap&s Lock acts as Cyrillic switch",
1774                  IDC_CAPSLOCKCYR);
1775         endbox(&cp);
1776         beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
1777                  IDC_BOX_TRANSLATION3);
1778         radiobig(&cp,
1779                  "Handling of line drawing characters:", IDC_VTSTATIC,
1780                  "Font has &XWindows encoding", IDC_VTXWINDOWS,
1781                  "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
1782                  "Use font in O&EM mode only", IDC_VTOEMONLY,
1783                  "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1784                  IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL);
1785         endbox(&cp);
1786     }
1787
1788     if (panel == selectionpanelstart) {
1789         /* The Selection panel. Accelerators used: [acgoh] df wxp est nr */
1790         struct ctlpos cp;
1791         ctlposinit(&cp, hwnd, 80, 3, 13);
1792         bartitle(&cp, "Options controlling copy and paste",
1793                  IDC_TITLE_SELECTION);
1794         beginbox(&cp, "Translation of pasted characters",
1795                  IDC_BOX_SELECTION1);
1796         checkbox(&cp,
1797                  "&Don't translate line drawing chars into +, - and |",
1798                  IDC_RAWCNP);
1799         checkbox(&cp,
1800                  "Paste to clipboard in RT&F as well as plain text",
1801                  IDC_RTFPASTE);
1802         endbox(&cp);
1803         beginbox(&cp, "Control which mouse button does which thing",
1804                  IDC_BOX_SELECTION2);
1805         radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1806                  "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1807                  "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1808                  NULL);
1809         checkbox(&cp,
1810                  "Shift overrides a&pplication's use of mouse",
1811                  IDC_MOUSEOVERRIDE);
1812         radioline(&cp,
1813                   "Default selection mode (Alt+drag does the other one):",
1814                   IDC_SELTYPESTATIC, 2,
1815                   "&Normal", IDC_SELTYPELEX,
1816                   "&Rectangular block", IDC_SELTYPERECT, NULL);
1817         endbox(&cp);
1818         beginbox(&cp, "Control the select-one-word-at-a-time mode",
1819                  IDC_BOX_SELECTION3);
1820         charclass(&cp, "Charact&er classes:", IDC_CCSTATIC, IDC_CCLIST,
1821                   "&Set", IDC_CCSET, IDC_CCEDIT,
1822                   "&to class", IDC_CCSTATIC2);
1823         endbox(&cp);
1824     }
1825
1826     if (panel == colourspanelstart) {
1827         /* The Colours panel. Accelerators used: [acgoh] blum */
1828         struct ctlpos cp;
1829         ctlposinit(&cp, hwnd, 80, 3, 13);
1830         bartitle(&cp, "Options controlling use of colours",
1831                  IDC_TITLE_COLOURS);
1832         beginbox(&cp, "General options for colour usage",
1833                  IDC_BOX_COLOURS1);
1834         checkbox(&cp, "&Bolded text is a different colour",
1835                  IDC_BOLDCOLOUR);
1836         checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1837         endbox(&cp);
1838         beginbox(&cp, "Adjust the precise colours PuTTY displays",
1839                  IDC_BOX_COLOURS2);
1840         colouredit(&cp, "Select a colo&ur and then click to modify it:",
1841                    IDC_COLOURSTATIC, IDC_COLOURLIST,
1842                    "&Modify...", IDC_CHANGE,
1843                    "Red:", IDC_RSTATIC, IDC_RVALUE,
1844                    "Green:", IDC_GSTATIC, IDC_GVALUE,
1845                    "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1846         endbox(&cp);
1847     }
1848
1849     if (panel == connectionpanelstart) {
1850         /* The Connection panel. Accelerators used: [acgoh] tukn */
1851         struct ctlpos cp;
1852         ctlposinit(&cp, hwnd, 80, 3, 13);
1853         bartitle(&cp, "Options controlling the connection",
1854                  IDC_TITLE_CONNECTION);
1855         if (dlgtype == 0) {
1856             beginbox(&cp, "Data to send to the server",
1857                      IDC_BOX_CONNECTION1);
1858             staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1859                        IDC_TTEDIT, 50);
1860             staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1861                        IDC_LOGEDIT, 50);
1862             endbox(&cp);
1863         } else {
1864             beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
1865             checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
1866                      IDC_TELNETKEY);
1867             checkbox(&cp, "Return key sends telnet New Line instead of ^M",
1868                      IDC_TELNETRET);
1869             endbox(&cp);
1870         }
1871         beginbox(&cp, "Sending of null packets to keep session active",
1872                  IDC_BOX_CONNECTION2);
1873         staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1874                    IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1875         endbox(&cp);
1876         if (dlgtype == 0) {
1877             beginbox(&cp, "Low-level TCP connection options",
1878                      IDC_BOX_CONNECTION3);
1879             checkbox(&cp, "Disable &Nagle's algorithm (TCP_NODELAY option)",
1880                      IDC_NODELAY);
1881             endbox(&cp);
1882         }
1883     }
1884
1885     if (panel == proxypanelstart) {
1886         /* The Proxy panel. Accelerators used: [acgoh] ntslypeuwmvxd */
1887         struct ctlpos cp;
1888         ctlposinit(&cp, hwnd, 80, 3, 13);
1889         if (dlgtype == 0) {
1890             bartitle(&cp, "Options controlling proxy usage",
1891                      IDC_TITLE_PROXY);
1892             beginbox(&cp, "Proxy basics", IDC_BOX_PROXY1);
1893             radioline(&cp, "Proxy type:", IDC_PROXYTYPESTATIC, 4,
1894                       "&None", IDC_PROXYTYPENONE,
1895                       "H&TTP", IDC_PROXYTYPEHTTP,
1896                       "&SOCKS", IDC_PROXYTYPESOCKS,
1897                       "Te&lnet", IDC_PROXYTYPETELNET, NULL);
1898             multiedit(&cp,
1899                       "Prox&y Host", IDC_PROXYHOSTSTATIC, IDC_PROXYHOSTEDIT, 80,
1900                       "&Port", IDC_PROXYPORTSTATIC, IDC_PROXYPORTEDIT, 20, NULL);
1901             multiedit(&cp,
1902                       "&Exclude Hosts/IPs", IDC_PROXYEXCLUDESTATIC,
1903                       IDC_PROXYEXCLUDEEDIT, 100, NULL);
1904             checkbox(&cp, "Consider pro&xying local host connections",
1905                      IDC_PROXYLOCALHOST);
1906             radioline(&cp, "Do &DNS name lookup at proxy end:",
1907                       IDC_PROXYDNSSTATIC, 3,
1908                       "No", IDC_PROXYDNSNO,
1909                       "Auto", IDC_PROXYDNSAUTO,
1910                       "Yes", IDC_PROXYDNSYES, NULL);
1911             staticedit(&cp, "&Username", IDC_PROXYUSERSTATIC,
1912                        IDC_PROXYUSEREDIT, 60);
1913             staticpassedit(&cp, "Pass&word", IDC_PROXYPASSSTATIC,
1914                            IDC_PROXYPASSEDIT, 60);
1915             endbox(&cp);
1916             beginbox(&cp, "Misc. proxy settings", IDC_BOX_PROXY2);
1917             multiedit(&cp,
1918                       "Telnet co&mmand", IDC_PROXYTELNETCMDSTATIC,
1919                       IDC_PROXYTELNETCMDEDIT, 100, NULL);
1920             radioline(&cp, "SOCKS &Version", IDC_PROXYSOCKSVERSTATIC,
1921                       2, "Version 5", IDC_PROXYSOCKSVER5, "Version 4",
1922                       IDC_PROXYSOCKSVER4, NULL);
1923             endbox(&cp);
1924         }
1925     }
1926
1927     if (panel == telnetpanelstart) {
1928         /* The Telnet panel. Accelerators used: [acgoh] svldr bftk */
1929         struct ctlpos cp;
1930         ctlposinit(&cp, hwnd, 80, 3, 13);
1931         if (dlgtype == 0) {
1932             bartitle(&cp, "Options controlling Telnet connections",
1933                      IDC_TITLE_TELNET);
1934             beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1935             staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1936                        IDC_TSEDIT, 50);
1937             envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1938                       "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1939                       IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1940                       IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1941             endbox(&cp);
1942             beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1943             radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1944                       IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1945                       "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1946             radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2,
1947                       "Passive", IDC_TPASSIVE, "Active",
1948                       IDC_TACTIVE, NULL);
1949             checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
1950                      IDC_TELNETKEY);
1951             checkbox(&cp, "Return key sends telnet New Line instead of ^M",
1952                      IDC_TELNETRET);
1953             endbox(&cp);
1954         }
1955     }
1956
1957     if (panel == rloginpanelstart) {
1958         /* The Rlogin panel. Accelerators used: [acgoh] sl */
1959         struct ctlpos cp;
1960         ctlposinit(&cp, hwnd, 80, 3, 13);
1961         if (dlgtype == 0) {
1962             bartitle(&cp, "Options controlling Rlogin connections",
1963                      IDC_TITLE_RLOGIN);
1964             beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1965             staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1966                        IDC_R_TSEDIT, 50);
1967             staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1968                        IDC_RLLUSEREDIT, 50);
1969             endbox(&cp);
1970         }
1971     }
1972
1973     if (panel == sshpanelstart) {
1974         /* The SSH panel. Accelerators used: [acgoh] r pel12n sud i */
1975         struct ctlpos cp;
1976         ctlposinit(&cp, hwnd, 80, 3, 13);
1977         if (dlgtype == 0) {
1978             bartitle(&cp, "Options controlling SSH connections",
1979                      IDC_TITLE_SSH);
1980             beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1981             multiedit(&cp,
1982                       "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1983                       NULL);
1984             endbox(&cp);
1985             beginbox(&cp, "Protocol options", IDC_BOX_SSH2);
1986             checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1987             checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1988             radioline(&cp, "Preferred SSH protocol version:",
1989                       IDC_SSHPROTSTATIC, 4,
1990                       "1 on&ly", IDC_SSHPROT1ONLY,
1991                       "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2,
1992                       "2 o&nly", IDC_SSHPROT2ONLY, NULL);
1993             endbox(&cp);
1994             beginbox(&cp, "Encryption options", IDC_BOX_SSH3);
1995             /* Adds accelerators: ud */
1996             prefslist(&cipherlist, &cp, "Encryption cipher &selection policy:",
1997                       IDC_CIPHERSTATIC2, IDC_CIPHERLIST, IDC_CIPHERUP,
1998                       IDC_CIPHERDN);
1999             checkbox(&cp, "Enable non-standard use of s&ingle-DES in SSH 2",
2000                      IDC_SSH2DES);
2001             endbox(&cp);
2002         }
2003     }
2004
2005     if (panel == sshauthpanelstart) {
2006         /* The SSH authentication panel. Accelerators used: [acgoh] m fkiuw */
2007         struct ctlpos cp;
2008         ctlposinit(&cp, hwnd, 80, 3, 13);
2009         if (dlgtype == 0) {
2010             bartitle(&cp, "Options controlling SSH authentication",
2011                      IDC_TITLE_SSHAUTH);
2012             beginbox(&cp, "Authentication methods",
2013                      IDC_BOX_SSHAUTH1);
2014             checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication (SSH1)",
2015                      IDC_AUTHTIS);
2016             checkbox(&cp, "Attempt \"keyboard-&interactive\" authentication"
2017                      " (SSH2)", IDC_AUTHKI);
2018             endbox(&cp);
2019             beginbox(&cp, "Authentication parameters",
2020                      IDC_BOX_SSHAUTH2);
2021             checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
2022             checkbox(&cp, "Allow attempted changes of &username in SSH2",
2023                      IDC_CHANGEUSER);
2024             editbutton(&cp, "Private &key file for authentication:",
2025                        IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
2026                        IDC_PKBUTTON);
2027             endbox(&cp);
2028         }
2029     }
2030
2031     if (panel == sshbugspanelstart) {
2032         /* The SSH bugs panel. Accelerators used: [acgoh] isrmepd */
2033         struct ctlpos cp;
2034         ctlposinit(&cp, hwnd, 80, 3, 13);
2035         if (dlgtype == 0) {
2036             bartitle(&cp, "Workarounds for SSH server bugs",
2037                      IDC_TITLE_SSHBUGS);
2038             beginbox(&cp, "Detection of known bugs in SSH servers",
2039                      IDC_BOX_SSHBUGS1);
2040             staticddl(&cp, "Chokes on SSH1 &ignore messages",
2041                       IDC_BUGS_IGNORE1, IDC_BUGD_IGNORE1, 20);
2042             staticddl(&cp, "Refuses all SSH1 pa&ssword camouflage",
2043                       IDC_BUGS_PLAINPW1, IDC_BUGD_PLAINPW1, 20);
2044             staticddl(&cp, "Chokes on SSH1 &RSA authentication",
2045                       IDC_BUGS_RSA1, IDC_BUGD_RSA1, 20);
2046             staticddl(&cp, "Miscomputes SSH2 H&MAC keys",
2047                       IDC_BUGS_HMAC2, IDC_BUGD_HMAC2, 20);
2048             staticddl(&cp, "Miscomputes SSH2 &encryption keys",
2049                       IDC_BUGS_DERIVEKEY2, IDC_BUGD_DERIVEKEY2, 20);
2050             staticddl(&cp, "Requires &padding on SSH2 RSA signatures",
2051                       IDC_BUGS_RSAPAD2, IDC_BUGD_RSAPAD2, 20);
2052             staticddl(&cp, "Chokes on &Diffie-Hellman group exchange",
2053                       IDC_BUGS_DHGEX2, IDC_BUGD_DHGEX2, 20);
2054             staticddl(&cp, "Misuses the sessio&n ID in PK auth",
2055                       IDC_BUGS_PKSESSID2, IDC_BUGD_PKSESSID2, 20);
2056             endbox(&cp);
2057         }
2058     }
2059
2060     if (panel == tunnelspanelstart) {
2061         /* The Tunnels panel. Accelerators used: [acgoh] exu tprsdilm */
2062         struct ctlpos cp;
2063         ctlposinit(&cp, hwnd, 80, 3, 13);
2064         if (dlgtype == 0) {
2065             bartitle(&cp, "Options controlling SSH tunnelling",
2066                      IDC_TITLE_TUNNELS);
2067             beginbox(&cp, "X11 forwarding", IDC_BOX_TUNNELS1);
2068             checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
2069             staticedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
2070                       IDC_X11_DISPLAY, 50);
2071             radioline(&cp, "Remote X11 a&uthentication protocol",
2072                       IDC_X11AUTHSTATIC, 2,
2073                       "MIT-Magic-Cookie-1", IDC_X11MIT,
2074                       "XDM-Authorization-1", IDC_X11XDM, NULL);
2075             endbox(&cp);
2076             beginbox(&cp, "Port forwarding", IDC_BOX_TUNNELS2);
2077             checkbox(&cp, "Local ports accept connections from o&ther hosts",
2078                      IDC_LPORT_ALL);
2079             checkbox(&cp, "Remote &ports do the same (SSH v2 only)",
2080                      IDC_RPORT_ALL);
2081             staticbtn(&cp, "Forwarded ports:", IDC_PFWDSTATIC,
2082                       "&Remove", IDC_PFWDREMOVE);
2083             fwdsetter(&cp, IDC_PFWDLIST,
2084                       "Add new forwarded port:", IDC_PFWDSTATIC2,
2085                       "&Source port", IDC_SPORTSTATIC, IDC_SPORTEDIT,
2086                       "Dest&ination", IDC_DPORTSTATIC, IDC_DPORTEDIT,
2087                       "A&dd", IDC_PFWDADD,
2088                       "&Local", IDC_PFWDLOCAL,
2089                       "Re&mote", IDC_PFWDREMOTE);
2090             endbox(&cp);
2091
2092         }
2093     }
2094 }
2095
2096 /* 
2097  * Helper function to load the session selected in SESSLIST
2098  * if any, as this is done in more than one place in
2099  * GenericMainDlgProc(). 0 => failure.
2100  */
2101 static int load_selected_session(HWND hwnd)
2102 {
2103     int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
2104                                LB_GETCURSEL, 0, 0);
2105     int isdef;
2106     if (n == LB_ERR) {
2107         MessageBeep(0);
2108         return 0;
2109     }
2110     isdef = !strcmp(sesslist.sessions[n], "Default Settings");
2111     load_settings(sesslist.sessions[n], !isdef, &cfg);
2112     init_dlg_ctrls(hwnd, TRUE);
2113     if (!isdef)
2114         SetDlgItemText(hwnd, IDC_SESSEDIT, sesslist.sessions[n]);
2115     else
2116         SetDlgItemText(hwnd, IDC_SESSEDIT, "");
2117     /* Restore the selection, which will have been clobbered by
2118      * SESSEDIT handling. */
2119     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0);
2120     return 1;
2121 }
2122
2123 /*
2124  * This function is the configuration box.
2125  */
2126 static int GenericMainDlgProc(HWND hwnd, UINT msg,
2127                               WPARAM wParam, LPARAM lParam, int dlgtype)
2128 {
2129     HWND hw, treeview;
2130     struct treeview_faff tvfaff;
2131     HTREEITEM hsession;
2132     OPENFILENAME of;
2133     char filename[sizeof(cfg.keyfile.path)];
2134     CHOOSEFONT cf;
2135     LOGFONT lf;
2136     char fontstatic[256];
2137     char portname[32];
2138     struct servent *service;
2139     int i;
2140     static UINT draglistmsg = WM_NULL;
2141
2142     switch (msg) {
2143       case WM_INITDIALOG:
2144         readytogo = 0;
2145         SetWindowLong(hwnd, GWL_USERDATA, 0);
2146         if (help_path)
2147             SetWindowLong(hwnd, GWL_EXSTYLE,
2148                           GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
2149         else {
2150             HWND item = GetDlgItem(hwnd, IDC_HELPBTN);
2151             if (item)
2152                 DestroyWindow(item);
2153         }
2154         requested_help = FALSE;
2155         SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
2156                     (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
2157         /*
2158          * Centre the window.
2159          */
2160         {                              /* centre the window */
2161             RECT rs, rd;
2162
2163             hw = GetDesktopWindow();
2164             if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
2165                 MoveWindow(hwnd,
2166                            (rs.right + rs.left + rd.left - rd.right) / 2,
2167                            (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
2168                            rd.right - rd.left, rd.bottom - rd.top, TRUE);
2169         }
2170
2171         /*
2172          * Create the tree view.
2173          */
2174         {
2175             RECT r;
2176             WPARAM font;
2177             HWND tvstatic;
2178
2179             r.left = 3;
2180             r.right = r.left + 75;
2181             r.top = 3;
2182             r.bottom = r.top + 10;
2183             MapDialogRect(hwnd, &r);
2184             tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
2185                                       WS_CHILD | WS_VISIBLE,
2186                                       r.left, r.top,
2187                                       r.right - r.left, r.bottom - r.top,
2188                                       hwnd, (HMENU) IDCX_TVSTATIC, hinst,
2189                                       NULL);
2190             font = SendMessage(hwnd, WM_GETFONT, 0, 0);
2191             SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
2192
2193             r.left = 3;
2194             r.right = r.left + 75;
2195             r.top = 13;
2196             r.bottom = r.top + 219;
2197             MapDialogRect(hwnd, &r);
2198             treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
2199                                       WS_CHILD | WS_VISIBLE |
2200                                       WS_TABSTOP | TVS_HASLINES |
2201                                       TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
2202                                       | TVS_LINESATROOT |
2203                                       TVS_SHOWSELALWAYS, r.left, r.top,
2204                                       r.right - r.left, r.bottom - r.top,
2205                                       hwnd, (HMENU) IDCX_TREEVIEW, hinst,
2206                                       NULL);
2207             font = SendMessage(hwnd, WM_GETFONT, 0, 0);
2208             SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
2209             tvfaff.treeview = treeview;
2210             memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
2211         }
2212
2213         /*
2214          * Set up the tree view contents.
2215          */
2216         hsession = treeview_insert(&tvfaff, 0, "Session");
2217         treeview_insert(&tvfaff, 1, "Logging");
2218         treeview_insert(&tvfaff, 0, "Terminal");
2219         treeview_insert(&tvfaff, 1, "Keyboard");
2220         treeview_insert(&tvfaff, 1, "Bell");
2221         treeview_insert(&tvfaff, 1, "Features");
2222         treeview_insert(&tvfaff, 0, "Window");
2223         treeview_insert(&tvfaff, 1, "Appearance");
2224         treeview_insert(&tvfaff, 1, "Behaviour");
2225         treeview_insert(&tvfaff, 1, "Translation");
2226         treeview_insert(&tvfaff, 1, "Selection");
2227         treeview_insert(&tvfaff, 1, "Colours");
2228         treeview_insert(&tvfaff, 0, "Connection");
2229         if (dlgtype == 0) {
2230             treeview_insert(&tvfaff, 1, "Proxy");
2231             treeview_insert(&tvfaff, 1, "Telnet");
2232             treeview_insert(&tvfaff, 1, "Rlogin");
2233             if (backends[3].backend != NULL) {
2234                 treeview_insert(&tvfaff, 1, "SSH");
2235                 /* XXX long name is ugly */
2236                 /* XXX make it closed by default? */
2237                 treeview_insert(&tvfaff, 2, "Auth");
2238                 treeview_insert(&tvfaff, 2, "Tunnels");
2239                 treeview_insert(&tvfaff, 2, "Bugs");
2240             }
2241         }
2242
2243         /*
2244          * Put the treeview selection on to the Session panel. This
2245          * should also cause creation of the relevant controls.
2246          */
2247         TreeView_SelectItem(treeview, hsession);
2248
2249         /*
2250          * Set focus into the first available control.
2251          */
2252         {
2253             HWND ctl;
2254             ctl = GetDlgItem(hwnd, IDC_HOST);
2255             if (!ctl)
2256                 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
2257             SetFocus(ctl);
2258         }
2259
2260         SetWindowLong(hwnd, GWL_USERDATA, 1);
2261         sesslist_has_focus = 0;
2262         return 0;
2263       case WM_LBUTTONUP:
2264         /*
2265          * Button release should trigger WM_OK if there was a
2266          * previous double click on the session list.
2267          */
2268         ReleaseCapture();
2269         if (readytogo)
2270             SendMessage(hwnd, WM_COMMAND, IDOK, 0);
2271         break;
2272       case WM_NOTIFY:
2273         if (LOWORD(wParam) == IDCX_TREEVIEW &&
2274             ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
2275             HTREEITEM i =
2276                 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
2277             TVITEM item;
2278             int j;
2279             char buffer[64];
2280  
2281             SendMessage (hwnd, WM_SETREDRAW, FALSE, 0);
2282  
2283             item.hItem = i;
2284             item.pszText = buffer;
2285             item.cchTextMax = sizeof(buffer);
2286             item.mask = TVIF_TEXT;
2287             TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
2288             for (j = controlstartvalue; j < controlendvalue; j++) {
2289                 HWND item = GetDlgItem(hwnd, j);
2290                 if (item)
2291                     DestroyWindow(item);
2292             }
2293             if (!strcmp(buffer, "Session"))
2294                 create_controls(hwnd, dlgtype, sessionpanelstart);
2295             if (!strcmp(buffer, "Logging"))
2296                 create_controls(hwnd, dlgtype, loggingpanelstart);
2297             if (!strcmp(buffer, "Keyboard"))
2298                 create_controls(hwnd, dlgtype, keyboardpanelstart);
2299             if (!strcmp(buffer, "Terminal"))
2300                 create_controls(hwnd, dlgtype, terminalpanelstart);
2301             if (!strcmp(buffer, "Bell"))
2302                 create_controls(hwnd, dlgtype, bellpanelstart);
2303             if (!strcmp(buffer, "Features"))
2304                 create_controls(hwnd, dlgtype, featurespanelstart);
2305             if (!strcmp(buffer, "Window"))
2306                 create_controls(hwnd, dlgtype, windowpanelstart);
2307             if (!strcmp(buffer, "Appearance"))
2308                 create_controls(hwnd, dlgtype, appearancepanelstart);
2309             if (!strcmp(buffer, "Behaviour"))
2310                 create_controls(hwnd, dlgtype, behaviourpanelstart);
2311             if (!strcmp(buffer, "Tunnels"))
2312                 create_controls(hwnd, dlgtype, tunnelspanelstart);
2313             if (!strcmp(buffer, "Connection"))
2314                 create_controls(hwnd, dlgtype, connectionpanelstart);
2315             if (!strcmp(buffer, "Proxy"))
2316                 create_controls(hwnd, dlgtype, proxypanelstart);
2317             if (!strcmp(buffer, "Telnet"))
2318                 create_controls(hwnd, dlgtype, telnetpanelstart);
2319             if (!strcmp(buffer, "Rlogin"))
2320                 create_controls(hwnd, dlgtype, rloginpanelstart);
2321             if (!strcmp(buffer, "SSH"))
2322                 create_controls(hwnd, dlgtype, sshpanelstart);
2323             if (!strcmp(buffer, "Auth"))
2324                 create_controls(hwnd, dlgtype, sshauthpanelstart);
2325             if (!strcmp(buffer, "Bugs"))
2326                 create_controls(hwnd, dlgtype, sshbugspanelstart);
2327             if (!strcmp(buffer, "Selection"))
2328                 create_controls(hwnd, dlgtype, selectionpanelstart);
2329             if (!strcmp(buffer, "Colours"))
2330                 create_controls(hwnd, dlgtype, colourspanelstart);
2331             if (!strcmp(buffer, "Translation"))
2332                 create_controls(hwnd, dlgtype, translationpanelstart);
2333
2334             init_dlg_ctrls(hwnd, FALSE);
2335  
2336             SendMessage (hwnd, WM_SETREDRAW, TRUE, 0);
2337             InvalidateRect (hwnd, NULL, TRUE);
2338
2339             SetFocus(((LPNMHDR) lParam)->hwndFrom);     /* ensure focus stays */
2340             return 0;
2341         }
2342         break;
2343       case WM_COMMAND:
2344         /*
2345          * Only process WM_COMMAND once the dialog is fully formed.
2346          */
2347         if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
2348             switch (LOWORD(wParam)) {
2349               case IDOK:
2350                 /* Behaviour of the "Open" button is different if the
2351                  * session list has focus, *unless* the user just
2352                  * double-clicked... */
2353                 if (sesslist_has_focus && !readytogo) {
2354                     if (!load_selected_session(hwnd)) {
2355                         MessageBeep(0);
2356                         return 0;
2357                     }
2358                 }
2359                 /* If at this point we have a valid session, go! */
2360                 if (*cfg.host) {
2361                     if (requested_help) {
2362                         WinHelp(hwnd, help_path, HELP_QUIT, 0);
2363                         requested_help = FALSE;
2364                     }
2365                     EndDialog(hwnd, 1);
2366                 } else
2367                     MessageBeep(0);
2368                 return 0;
2369               case IDC_HELPBTN:
2370                 if (HIWORD(wParam) == BN_CLICKED ||
2371                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2372                     if (help_path) {
2373                         WinHelp(hwnd, help_path,
2374                                 help_has_contents ? HELP_FINDER : HELP_CONTENTS,
2375                                 0);
2376                         requested_help = TRUE;
2377                     }
2378                 }
2379                 break;
2380               case IDCANCEL:
2381                 if (requested_help) {
2382                     WinHelp(hwnd, help_path, HELP_QUIT, 0);
2383                     requested_help = FALSE;
2384                 }
2385                 EndDialog(hwnd, 0);
2386                 return 0;
2387               case IDC_PROTTELNET:
2388               case IDC_PROTRLOGIN:
2389               case IDC_PROTSSH:
2390               case IDC_PROTRAW:
2391                 if (HIWORD(wParam) == BN_CLICKED ||
2392                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2393                     int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
2394                     int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
2395                     int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
2396                     cfg.protocol =
2397                         i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
2398                         PROT_RAW;
2399                     /*
2400                      * When switching using the arrow keys, we
2401                      * appear to get two of these messages, both
2402                      * mentioning the target button in
2403                      * LOWORD(wParam), but one of them called while
2404                      * the previous button is still checked. This
2405                      * causes an unnecessary reset of the port
2406                      * number field, which we fix by ensuring here
2407                      * that the button selected is indeed the one
2408                      * checked.
2409                      */
2410                     if (IsDlgButtonChecked(hwnd, LOWORD(wParam)) &&
2411                         ((cfg.protocol == PROT_SSH && cfg.port != 22)
2412                          || (cfg.protocol == PROT_TELNET && cfg.port != 23)
2413                          || (cfg.protocol == PROT_RLOGIN
2414                              && cfg.port != 513))) {
2415                         cfg.port = i ? 22 : j ? 23 : 513;
2416                         SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
2417                     }
2418                 }
2419                 break;
2420               case IDC_HOST:
2421                 if (HIWORD(wParam) == EN_CHANGE)
2422                     GetDlgItemText(hwnd, IDC_HOST, cfg.host,
2423                                    sizeof(cfg.host) - 1);
2424                 break;
2425               case IDC_PORT:
2426                 if (HIWORD(wParam) == EN_CHANGE) {
2427                     GetDlgItemText(hwnd, IDC_PORT, portname, 31);
2428                     if (isdigit(portname[0]))
2429                         MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
2430                     else {
2431                         service = getservbyname(portname, NULL);
2432                         if (service)
2433                             cfg.port = ntohs(service->s_port);
2434                         else
2435                             cfg.port = 0;
2436                     }
2437                 }
2438                 break;
2439               case IDC_SESSEDIT:
2440                 if (HIWORD(wParam) == EN_CHANGE) {
2441                     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2442                                        (WPARAM) - 1, 0);
2443                     GetDlgItemText(hwnd, IDC_SESSEDIT,
2444                                    savedsession, sizeof(savedsession) - 1);
2445                     savedsession[sizeof(savedsession) - 1] = '\0';
2446                 }
2447                 break;
2448               case IDC_SESSSAVE:
2449                 if (HIWORD(wParam) == BN_CLICKED ||
2450                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2451                     /*
2452                      * Save a session
2453                      */
2454                     char str[2048];
2455                     GetDlgItemText(hwnd, IDC_SESSEDIT, str,
2456                                    sizeof(str) - 1);
2457                     if (!*str) {
2458                         int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
2459                                                    LB_GETCURSEL, 0, 0);
2460                         if (n == LB_ERR) {
2461                             MessageBeep(0);
2462                             break;
2463                         }
2464                         strcpy(str, sesslist.sessions[n]);
2465                     }
2466                     save_settings(str, !!strcmp(str, "Default Settings"),
2467                                   &cfg);
2468                     get_sesslist(&sesslist, FALSE);
2469                     get_sesslist(&sesslist, TRUE);
2470                     SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2471                                        FALSE, 0);
2472                     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
2473                                        0, 0);
2474                     for (i = 0; i < sesslist.nsessions; i++)
2475                         SendDlgItemMessage(hwnd, IDC_SESSLIST,
2476                                            LB_ADDSTRING, 0,
2477                                            (LPARAM) (sesslist.sessions[i]));
2478                     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2479                                        (WPARAM) - 1, 0);
2480                     SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2481                                        TRUE, 0);
2482                     InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
2483                                    TRUE);
2484                 }
2485                 break;
2486               case IDC_SESSLIST:
2487               case IDC_SESSLOAD:
2488                 if (LOWORD(wParam) == IDC_SESSLIST) {
2489                     if (HIWORD(wParam) == LBN_SETFOCUS)
2490                         sesslist_has_focus = 1;
2491                     else if (HIWORD(wParam) == LBN_KILLFOCUS)
2492                         sesslist_has_focus = 0;
2493                 }
2494                 if (LOWORD(wParam) == IDC_SESSLOAD &&
2495                     HIWORD(wParam) != BN_CLICKED &&
2496                     HIWORD(wParam) != BN_DOUBLECLICKED) break;
2497                 if (LOWORD(wParam) == IDC_SESSLIST &&
2498                     HIWORD(wParam) != LBN_DBLCLK) break;
2499                 /* Load the session selected in SESSLIST. */
2500                 if (load_selected_session(hwnd) &&
2501                     LOWORD(wParam) == IDC_SESSLIST) {
2502                     /*
2503                      * A double-click on a saved session should
2504                      * actually start the session, not just load it.
2505                      * Unless it's Default Settings or some other
2506                      * host-less set of saved settings.
2507                      */
2508                     if (*cfg.host) {
2509                         readytogo = TRUE;
2510                         SetCapture(hwnd);
2511                     }
2512                 }
2513                 break;
2514               case IDC_SESSDEL:
2515                 if (HIWORD(wParam) == BN_CLICKED ||
2516                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2517                     int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
2518                                                LB_GETCURSEL, 0, 0);
2519                     if (n == LB_ERR || n == 0) {
2520                         MessageBeep(0);
2521                         break;
2522                     }
2523                     del_settings(sesslist.sessions[n]);
2524                     get_sesslist(&sesslist, FALSE);
2525                     get_sesslist(&sesslist, TRUE);
2526                     SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2527                                        FALSE, 0);
2528                     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
2529                                        0, 0);
2530                     for (i = 0; i < sesslist.nsessions; i++)
2531                         SendDlgItemMessage(hwnd, IDC_SESSLIST,
2532                                            LB_ADDSTRING, 0,
2533                                            (LPARAM) (sesslist.sessions[i]));
2534                     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2535                                        (WPARAM) - 1, 0);
2536                     SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2537                                        TRUE, 0);
2538                     InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
2539                                    TRUE);
2540                 }
2541               case IDC_PINGEDIT:
2542                 if (HIWORD(wParam) == EN_CHANGE)
2543                     MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
2544                                     &cfg.ping_interval);
2545                 break;
2546               case IDC_NODELAY:
2547                 if (HIWORD(wParam) == BN_CLICKED ||
2548                     HIWORD(wParam) == BN_DOUBLECLICKED)
2549                         cfg.tcp_nodelay =
2550                         IsDlgButtonChecked(hwnd, IDC_NODELAY);
2551                 break;
2552               case IDC_DEL008:
2553               case IDC_DEL127:
2554                 if (HIWORD(wParam) == BN_CLICKED ||
2555                     HIWORD(wParam) == BN_DOUBLECLICKED)
2556                         cfg.bksp_is_delete =
2557                         IsDlgButtonChecked(hwnd, IDC_DEL127);
2558                 break;
2559               case IDC_HOMETILDE:
2560               case IDC_HOMERXVT:
2561                 if (HIWORD(wParam) == BN_CLICKED ||
2562                     HIWORD(wParam) == BN_DOUBLECLICKED)
2563                         cfg.rxvt_homeend =
2564                         IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
2565                 break;
2566               case IDC_FUNCTILDE:
2567               case IDC_FUNCLINUX:
2568               case IDC_FUNCXTERM:
2569               case IDC_FUNCVT400:
2570               case IDC_FUNCVT100P:
2571               case IDC_FUNCSCO:
2572                 if (HIWORD(wParam) == BN_CLICKED ||
2573                     HIWORD(wParam) == BN_DOUBLECLICKED)
2574                         switch (LOWORD(wParam)) {
2575                       case IDC_FUNCTILDE:
2576                         cfg.funky_type = 0;
2577                         break;
2578                       case IDC_FUNCLINUX:
2579                         cfg.funky_type = 1;
2580                         break;
2581                       case IDC_FUNCXTERM:
2582                         cfg.funky_type = 2;
2583                         break;
2584                       case IDC_FUNCVT400:
2585                         cfg.funky_type = 3;
2586                         break;
2587                       case IDC_FUNCVT100P:
2588                         cfg.funky_type = 4;
2589                         break;
2590                       case IDC_FUNCSCO:
2591                         cfg.funky_type = 5;
2592                         break;
2593                     }
2594                 break;
2595               case IDC_KPNORMAL:
2596               case IDC_KPAPPLIC:
2597                 if (HIWORD(wParam) == BN_CLICKED ||
2598                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2599                     cfg.app_keypad =
2600                         IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
2601                     cfg.nethack_keypad = FALSE;
2602                 }
2603                 break;
2604               case IDC_KPNH:
2605                 if (HIWORD(wParam) == BN_CLICKED ||
2606                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2607                     cfg.app_keypad = FALSE;
2608                     cfg.nethack_keypad = TRUE;
2609                 }
2610                 break;
2611               case IDC_CURNORMAL:
2612               case IDC_CURAPPLIC:
2613                 if (HIWORD(wParam) == BN_CLICKED ||
2614                     HIWORD(wParam) == BN_DOUBLECLICKED)
2615                         cfg.app_cursor =
2616                         IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
2617                 break;
2618               case IDC_NOAPPLICC:
2619                 if (HIWORD(wParam) == BN_CLICKED ||
2620                     HIWORD(wParam) == BN_DOUBLECLICKED)
2621                         cfg.no_applic_c =
2622                         IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
2623                 break;
2624               case IDC_NOAPPLICK:
2625                 if (HIWORD(wParam) == BN_CLICKED ||
2626                     HIWORD(wParam) == BN_DOUBLECLICKED)
2627                         cfg.no_applic_k =
2628                         IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
2629                 break;
2630               case IDC_NOMOUSEREP:
2631                 if (HIWORD(wParam) == BN_CLICKED ||
2632                     HIWORD(wParam) == BN_DOUBLECLICKED)
2633                         cfg.no_mouse_rep =
2634                         IsDlgButtonChecked(hwnd, IDC_NOMOUSEREP);
2635                 break;
2636               case IDC_NORESIZE:
2637                 if (HIWORD(wParam) == BN_CLICKED ||
2638                     HIWORD(wParam) == BN_DOUBLECLICKED)
2639                         cfg.no_remote_resize =
2640                         IsDlgButtonChecked(hwnd, IDC_NORESIZE);
2641                 break;
2642               case IDC_NOALTSCREEN:
2643                 if (HIWORD(wParam) == BN_CLICKED ||
2644                     HIWORD(wParam) == BN_DOUBLECLICKED)
2645                         cfg.no_alt_screen =
2646                         IsDlgButtonChecked(hwnd, IDC_NOALTSCREEN);
2647                 break;
2648               case IDC_NOWINTITLE:
2649                 if (HIWORD(wParam) == BN_CLICKED ||
2650                     HIWORD(wParam) == BN_DOUBLECLICKED)
2651                         cfg.no_remote_wintitle =
2652                         IsDlgButtonChecked(hwnd, IDC_NOWINTITLE);
2653                 break;
2654               case IDC_NODBACKSPACE:
2655                 if (HIWORD(wParam) == BN_CLICKED ||
2656                     HIWORD(wParam) == BN_DOUBLECLICKED)
2657                         cfg.no_dbackspace =
2658                         IsDlgButtonChecked(hwnd, IDC_NODBACKSPACE);
2659                 break;
2660               case IDC_NOCHARSET:
2661                 if (HIWORD(wParam) == BN_CLICKED ||
2662                     HIWORD(wParam) == BN_DOUBLECLICKED)
2663                         cfg.no_remote_charset =
2664                         IsDlgButtonChecked(hwnd, IDC_NOCHARSET);
2665                 break;
2666               case IDC_ALTF4:
2667                 if (HIWORD(wParam) == BN_CLICKED ||
2668                     HIWORD(wParam) == BN_DOUBLECLICKED)
2669                         cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
2670                 break;
2671               case IDC_ALTSPACE:
2672                 if (HIWORD(wParam) == BN_CLICKED ||
2673                     HIWORD(wParam) == BN_DOUBLECLICKED)
2674                         cfg.alt_space =
2675                         IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
2676                 break;
2677               case IDC_ALTONLY:
2678                 if (HIWORD(wParam) == BN_CLICKED ||
2679                     HIWORD(wParam) == BN_DOUBLECLICKED)
2680                         cfg.alt_only =
2681                         IsDlgButtonChecked(hwnd, IDC_ALTONLY);
2682                 break;
2683               case IDC_ECHOBACKEND:
2684               case IDC_ECHOYES:
2685               case IDC_ECHONO:
2686                 if (HIWORD(wParam) == BN_CLICKED ||
2687                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2688                     if (LOWORD(wParam) == IDC_ECHOBACKEND)
2689                         cfg.localecho = AUTO;
2690                     if (LOWORD(wParam) == IDC_ECHOYES)
2691                         cfg.localecho = FORCE_ON;
2692                     if (LOWORD(wParam) == IDC_ECHONO)
2693                         cfg.localecho = FORCE_OFF;
2694                 }
2695                 break;
2696               case IDC_EDITBACKEND:
2697               case IDC_EDITYES:
2698               case IDC_EDITNO:
2699                 if (HIWORD(wParam) == BN_CLICKED ||
2700                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2701                     if (LOWORD(wParam) == IDC_EDITBACKEND)
2702                         cfg.localedit = AUTO;
2703                     if (LOWORD(wParam) == IDC_EDITYES)
2704                         cfg.localedit = FORCE_ON;
2705                     if (LOWORD(wParam) == IDC_EDITNO)
2706                         cfg.localedit = FORCE_OFF;
2707                 }
2708                 break;
2709               case IDC_ANSWEREDIT:
2710                 if (HIWORD(wParam) == EN_CHANGE)
2711                     GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
2712                                    sizeof(cfg.answerback) - 1);
2713                 break;
2714               case IDC_ALWAYSONTOP:
2715                 if (HIWORD(wParam) == BN_CLICKED ||
2716                     HIWORD(wParam) == BN_DOUBLECLICKED)
2717                         cfg.alwaysontop =
2718                         IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
2719                 break;
2720               case IDC_FULLSCREENONALTENTER:
2721                 if (HIWORD(wParam) == BN_CLICKED ||
2722                     HIWORD(wParam) == BN_DOUBLECLICKED)
2723                         cfg.fullscreenonaltenter =
2724                         IsDlgButtonChecked(hwnd, IDC_FULLSCREENONALTENTER);
2725                 break;
2726               case IDC_SCROLLKEY:
2727                 if (HIWORD(wParam) == BN_CLICKED ||
2728                     HIWORD(wParam) == BN_DOUBLECLICKED)
2729                         cfg.scroll_on_key =
2730                         IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
2731                 break;
2732               case IDC_SCROLLDISP:
2733                 if (HIWORD(wParam) == BN_CLICKED ||
2734                     HIWORD(wParam) == BN_DOUBLECLICKED)
2735                         cfg.scroll_on_disp =
2736                         IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
2737                 break;
2738               case IDC_COMPOSEKEY:
2739                 if (HIWORD(wParam) == BN_CLICKED ||
2740                     HIWORD(wParam) == BN_DOUBLECLICKED)
2741                         cfg.compose_key =
2742                         IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
2743                 break;
2744               case IDC_CTRLALTKEYS:
2745                 if (HIWORD(wParam) == BN_CLICKED ||
2746                     HIWORD(wParam) == BN_DOUBLECLICKED)
2747                         cfg.ctrlaltkeys =
2748                         IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
2749                 break;
2750               case IDC_TELNETKEY:
2751                 if (HIWORD(wParam) == BN_CLICKED ||
2752                     HIWORD(wParam) == BN_DOUBLECLICKED)
2753                         cfg.telnet_keyboard =
2754                         IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
2755                 break;
2756               case IDC_TELNETRET:
2757                 if (HIWORD(wParam) == BN_CLICKED ||
2758                     HIWORD(wParam) == BN_DOUBLECLICKED)
2759                         cfg.telnet_newline =
2760                         IsDlgButtonChecked(hwnd, IDC_TELNETRET);
2761                 break;
2762               case IDC_WRAPMODE:
2763                 if (HIWORD(wParam) == BN_CLICKED ||
2764                     HIWORD(wParam) == BN_DOUBLECLICKED)
2765                         cfg.wrap_mode =
2766                         IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
2767                 break;
2768               case IDC_DECOM:
2769                 if (HIWORD(wParam) == BN_CLICKED ||
2770                     HIWORD(wParam) == BN_DOUBLECLICKED)
2771                         cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
2772                 break;
2773               case IDC_LFHASCR:
2774                 if (HIWORD(wParam) == BN_CLICKED ||
2775                     HIWORD(wParam) == BN_DOUBLECLICKED)
2776                         cfg.lfhascr =
2777                         IsDlgButtonChecked(hwnd, IDC_LFHASCR);
2778                 break;
2779               case IDC_ROWSEDIT:
2780                 if (HIWORD(wParam) == EN_CHANGE)
2781                     MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
2782                 break;
2783               case IDC_COLSEDIT:
2784                 if (HIWORD(wParam) == EN_CHANGE)
2785                     MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
2786                 break;
2787               case IDC_SAVEEDIT:
2788                 if (HIWORD(wParam) == EN_CHANGE)
2789                     MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
2790                 break;
2791               case IDC_CHOOSEFONT:
2792                 {
2793                     HDC hdc = GetDC(0);
2794                     lf.lfHeight = -MulDiv(cfg.font.height,
2795                                           GetDeviceCaps(hdc, LOGPIXELSY),
2796                                           72);
2797                     ReleaseDC(0, hdc);
2798                 }
2799                 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
2800                 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
2801                 lf.lfWeight = (cfg.font.isbold ? FW_BOLD : 0);
2802                 lf.lfCharSet = cfg.font.charset;
2803                 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
2804                 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
2805                 lf.lfQuality = DEFAULT_QUALITY;
2806                 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
2807                 strncpy(lf.lfFaceName, cfg.font.name,
2808                         sizeof(lf.lfFaceName) - 1);
2809                 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
2810
2811                 cf.lStructSize = sizeof(cf);
2812                 cf.hwndOwner = hwnd;
2813                 cf.lpLogFont = &lf;
2814                 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
2815                     CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
2816
2817                 if (ChooseFont(&cf)) {
2818                     strncpy(cfg.font.name, lf.lfFaceName,
2819                             sizeof(cfg.font.name) - 1);
2820                     cfg.font.name[sizeof(cfg.font.name) - 1] = '\0';
2821                     cfg.font.isbold = (lf.lfWeight == FW_BOLD);
2822                     cfg.font.charset = lf.lfCharSet;
2823                     cfg.font.height = cf.iPointSize / 10;
2824                     fmtfont(fontstatic);
2825                     SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
2826                 }
2827                 break;
2828               case IDC_BELL_DISABLED:
2829               case IDC_BELL_DEFAULT:
2830               case IDC_BELL_WAVEFILE:
2831               case IDC_BELL_VISUAL:
2832                 if (HIWORD(wParam) == BN_CLICKED ||
2833                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2834                     if (LOWORD(wParam) == IDC_BELL_DISABLED)
2835                         cfg.beep = BELL_DISABLED;
2836                     if (LOWORD(wParam) == IDC_BELL_DEFAULT)
2837                         cfg.beep = BELL_DEFAULT;
2838                     if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
2839                         cfg.beep = BELL_WAVEFILE;
2840                     if (LOWORD(wParam) == IDC_BELL_VISUAL)
2841                         cfg.beep = BELL_VISUAL;
2842                 }
2843                 break;
2844               case IDC_B_IND_DISABLED:
2845               case IDC_B_IND_FLASH:
2846               case IDC_B_IND_STEADY:
2847                 if (HIWORD(wParam) == BN_CLICKED ||
2848                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2849                     if (LOWORD(wParam) == IDC_B_IND_DISABLED)
2850                         cfg.beep_ind = B_IND_DISABLED;
2851                     if (LOWORD(wParam) == IDC_B_IND_FLASH)
2852                         cfg.beep_ind = B_IND_FLASH;
2853                     if (LOWORD(wParam) == IDC_B_IND_STEADY)
2854                         cfg.beep_ind = B_IND_STEADY;
2855                 }
2856                 break;
2857               case IDC_BELL_WAVEBROWSE:
2858                 memset(&of, 0, sizeof(of));
2859 #ifdef OPENFILENAME_SIZE_VERSION_400
2860                 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2861 #else
2862                 of.lStructSize = sizeof(of);
2863 #endif
2864                 of.hwndOwner = hwnd;
2865                 of.lpstrFilter = "Wave Files (*.wav)\0*.WAV\0"
2866                     "All Files (*.*)\0*\0\0\0";
2867                 of.lpstrCustomFilter = NULL;
2868                 of.nFilterIndex = 1;
2869                 of.lpstrFile = filename;
2870                 strcpy(filename, cfg.bell_wavefile.path);
2871                 of.nMaxFile = sizeof(filename);
2872                 of.lpstrFileTitle = NULL;
2873                 of.lpstrInitialDir = NULL;
2874                 of.lpstrTitle = "Select Bell Sound File";
2875                 of.Flags = 0;
2876                 if (GetOpenFileName(&of)) {
2877                     strcpy(cfg.bell_wavefile.path, filename);
2878                     SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2879                                    cfg.bell_wavefile.path);
2880                 }
2881                 break;
2882               case IDC_BELL_WAVEEDIT:
2883                 if (HIWORD(wParam) == EN_CHANGE)
2884                     GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2885                                    cfg.bell_wavefile.path,
2886                                    sizeof(cfg.bell_wavefile.path) - 1);
2887                 break;
2888               case IDC_BELLOVL:
2889                 if (HIWORD(wParam) == BN_CLICKED ||
2890                     HIWORD(wParam) == BN_DOUBLECLICKED)
2891                         cfg.bellovl =
2892                         IsDlgButtonChecked(hwnd, IDC_BELLOVL);
2893                 break;
2894               case IDC_BELLOVLN:
2895                 if (HIWORD(wParam) == EN_CHANGE)
2896                     MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
2897                 break;
2898               case IDC_BELLOVLT:
2899                 if (HIWORD(wParam) == EN_CHANGE)
2900                     MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
2901                                     1000);
2902                 break;
2903               case IDC_BELLOVLS:
2904                 if (HIWORD(wParam) == EN_CHANGE)
2905                     MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
2906                                     1000);
2907                 break;
2908               case IDC_BLINKTEXT:
2909                 if (HIWORD(wParam) == BN_CLICKED ||
2910                     HIWORD(wParam) == BN_DOUBLECLICKED)
2911                         cfg.blinktext =
2912                         IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
2913                 break;
2914               case IDC_BCE:
2915                 if (HIWORD(wParam) == BN_CLICKED ||
2916                     HIWORD(wParam) == BN_DOUBLECLICKED)
2917                         cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
2918                 break;
2919               case IDC_WINNAME:
2920                 if (HIWORD(wParam) == BN_CLICKED ||
2921                     HIWORD(wParam) == BN_DOUBLECLICKED)
2922                         cfg.win_name_always =
2923                         !IsDlgButtonChecked(hwnd, IDC_WINNAME);
2924                 break;
2925               case IDC_HIDEMOUSE:
2926                 if (HIWORD(wParam) == BN_CLICKED ||
2927                     HIWORD(wParam) == BN_DOUBLECLICKED)
2928                         cfg.hide_mouseptr =
2929                         IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
2930                 break;
2931               case IDC_SUNKENEDGE:
2932                 if (HIWORD(wParam) == BN_CLICKED ||
2933                     HIWORD(wParam) == BN_DOUBLECLICKED)
2934                         cfg.sunken_edge =
2935                         IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
2936                 break;
2937               case IDC_WINBEDIT:
2938                 if (HIWORD(wParam) == EN_CHANGE)
2939                     MyGetDlgItemInt(hwnd, IDC_WINBEDIT,
2940                                     &cfg.window_border);
2941                 if (cfg.window_border > 32)
2942                     cfg.window_border = 32;
2943                 break;
2944               case IDC_CURBLOCK:
2945                 if (HIWORD(wParam) == BN_CLICKED ||
2946                     HIWORD(wParam) == BN_DOUBLECLICKED)
2947                         cfg.cursor_type = 0;
2948                 break;
2949               case IDC_CURUNDER:
2950                 if (HIWORD(wParam) == BN_CLICKED ||
2951                     HIWORD(wParam) == BN_DOUBLECLICKED)
2952                         cfg.cursor_type = 1;
2953                 break;
2954               case IDC_CURVERT:
2955                 if (HIWORD(wParam) == BN_CLICKED ||
2956                     HIWORD(wParam) == BN_DOUBLECLICKED)
2957                         cfg.cursor_type = 2;
2958                 break;
2959               case IDC_BLINKCUR:
2960                 if (HIWORD(wParam) == BN_CLICKED ||
2961                     HIWORD(wParam) == BN_DOUBLECLICKED)
2962                         cfg.blink_cur =
2963                         IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
2964                 break;
2965               case IDC_SCROLLBAR:
2966                 if (HIWORD(wParam) == BN_CLICKED ||
2967                     HIWORD(wParam) == BN_DOUBLECLICKED)
2968                         cfg.scrollbar =
2969                         IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
2970                 break;
2971               case IDC_SCROLLBARFULLSCREEN:
2972                 if (HIWORD(wParam) == BN_CLICKED ||
2973                     HIWORD(wParam) == BN_DOUBLECLICKED)
2974                     cfg.scrollbar_in_fullscreen =
2975                     IsDlgButtonChecked(hwnd, IDC_SCROLLBARFULLSCREEN);
2976                 break;
2977               case IDC_RESIZETERM:
2978               case IDC_RESIZEFONT:
2979               case IDC_RESIZENONE:
2980               case IDC_RESIZEEITHER:
2981                 if (HIWORD(wParam) == BN_CLICKED ||
2982                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2983                     cfg.resize_action =
2984                         IsDlgButtonChecked(hwnd,
2985                                            IDC_RESIZETERM) ? RESIZE_TERM :
2986                         IsDlgButtonChecked(hwnd,
2987                                            IDC_RESIZEFONT) ? RESIZE_FONT :
2988                         IsDlgButtonChecked(hwnd,
2989                                            IDC_RESIZEEITHER) ? RESIZE_EITHER :
2990                         RESIZE_DISABLED;
2991                 }
2992                 break;
2993               case IDC_WINEDIT:
2994                 if (HIWORD(wParam) == EN_CHANGE)
2995                     GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
2996                                    sizeof(cfg.wintitle) - 1);
2997                 break;
2998               case IDC_COEALWAYS:
2999               case IDC_COENEVER:
3000               case IDC_COENORMAL:
3001                 if (HIWORD(wParam) == BN_CLICKED ||
3002                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3003                     cfg.close_on_exit =
3004                         IsDlgButtonChecked(hwnd,
3005                                            IDC_COEALWAYS) ? FORCE_ON :
3006                         IsDlgButtonChecked(hwnd,
3007                                            IDC_COENEVER) ? FORCE_OFF :
3008                         AUTO;
3009                 }
3010                 break;
3011               case IDC_CLOSEWARN:
3012                 if (HIWORD(wParam) == BN_CLICKED ||
3013                     HIWORD(wParam) == BN_DOUBLECLICKED)
3014                         cfg.warn_on_close =
3015                         IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
3016                 break;
3017               case IDC_TTEDIT:
3018                 if (HIWORD(wParam) == EN_CHANGE)
3019                     GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
3020                                    sizeof(cfg.termtype) - 1);
3021                 break;
3022
3023                 /* proxy config */
3024               case IDC_PROXYHOSTEDIT:
3025                 if (HIWORD(wParam) == EN_CHANGE)
3026                     GetDlgItemText(hwnd, IDC_PROXYHOSTEDIT, cfg.proxy_host, 
3027                                    sizeof(cfg.proxy_host) - 1);
3028                 break;
3029               case IDC_PROXYPORTEDIT:
3030                 if (HIWORD(wParam) == EN_CHANGE) {
3031                     GetDlgItemText(hwnd, IDC_PROXYPORTEDIT, portname, 31);
3032                     if (isdigit(portname[0]))
3033                         MyGetDlgItemInt(hwnd, IDC_PROXYPORTEDIT, &cfg.proxy_port);
3034                     else {
3035                         service = getservbyname(portname, NULL);
3036                         if (service)
3037                             cfg.proxy_port = ntohs(service->s_port);
3038                         else
3039                             cfg.proxy_port = 0;
3040                     }
3041                 }
3042                 break;
3043               case IDC_PROXYEXCLUDEEDIT:
3044                 if (HIWORD(wParam) == EN_CHANGE)
3045                     GetDlgItemText(hwnd, IDC_PROXYEXCLUDEEDIT,
3046                                    cfg.proxy_exclude_list,
3047                                    sizeof(cfg.proxy_exclude_list) - 1);
3048                 break;
3049               case IDC_PROXYUSEREDIT:
3050                 if (HIWORD(wParam) == EN_CHANGE)
3051                     GetDlgItemText(hwnd, IDC_PROXYUSEREDIT,
3052                                    cfg.proxy_username, 
3053                                    sizeof(cfg.proxy_username) - 1);
3054                 break;
3055               case IDC_PROXYPASSEDIT:
3056                 if (HIWORD(wParam) == EN_CHANGE)
3057                     GetDlgItemText(hwnd, IDC_PROXYPASSEDIT,
3058                                    cfg.proxy_password, 
3059                                    sizeof(cfg.proxy_password) - 1);
3060                 break;
3061               case IDC_PROXYTELNETCMDEDIT:
3062                 if (HIWORD(wParam) == EN_CHANGE)
3063                     GetDlgItemText(hwnd, IDC_PROXYTELNETCMDEDIT,
3064                                    cfg.proxy_telnet_command,
3065                                    sizeof(cfg.proxy_telnet_command) - 1);
3066                 break;
3067               case IDC_PROXYSOCKSVER5:
3068               case IDC_PROXYSOCKSVER4:
3069                 if (HIWORD(wParam) == BN_CLICKED ||
3070                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3071                     cfg.proxy_socks_version =
3072                         IsDlgButtonChecked(hwnd, IDC_PROXYSOCKSVER4) ? 4 : 5;
3073                 }
3074                 break;
3075               case IDC_PROXYLOCALHOST:
3076                 if (HIWORD(wParam) == BN_CLICKED ||
3077                     HIWORD(wParam) == BN_DOUBLECLICKED)
3078                     cfg.even_proxy_localhost =
3079                     IsDlgButtonChecked(hwnd, IDC_PROXYLOCALHOST);
3080                 break;
3081               case IDC_PROXYDNSNO:
3082               case IDC_PROXYDNSAUTO:
3083               case IDC_PROXYDNSYES:
3084                 if (HIWORD(wParam) == BN_CLICKED ||
3085                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3086                     cfg.proxy_dns =
3087                         IsDlgButtonChecked(hwnd, IDC_PROXYDNSNO) ? FORCE_OFF :
3088                         IsDlgButtonChecked(hwnd, IDC_PROXYDNSYES) ? FORCE_ON :
3089                         AUTO;
3090                 }
3091                 break;
3092               case IDC_PROXYTYPENONE:
3093               case IDC_PROXYTYPEHTTP:
3094               case IDC_PROXYTYPESOCKS:
3095               case IDC_PROXYTYPETELNET:
3096                 if (HIWORD(wParam) == BN_CLICKED ||
3097                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3098                     cfg.proxy_type =
3099                         IsDlgButtonChecked(hwnd, IDC_PROXYTYPEHTTP) ? PROXY_HTTP :
3100                         IsDlgButtonChecked(hwnd, IDC_PROXYTYPESOCKS) ? PROXY_SOCKS :
3101                         IsDlgButtonChecked(hwnd, IDC_PROXYTYPETELNET) ? PROXY_TELNET :
3102                         PROXY_NONE;
3103                 }
3104                 break;
3105
3106               case IDC_LGFEDIT:
3107                 if (HIWORD(wParam) == EN_CHANGE)
3108                     GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename.path,
3109                                    sizeof(cfg.logfilename.path) - 1);
3110                 break;
3111               case IDC_LGFBUTTON:
3112                 memset(&of, 0, sizeof(of));
3113 #ifdef OPENFILENAME_SIZE_VERSION_400
3114                 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
3115 #else
3116                 of.lStructSize = sizeof(of);
3117 #endif
3118                 of.hwndOwner = hwnd;
3119                 of.lpstrFilter = "All Files (*.*)\0*\0\0\0";
3120                 of.lpstrCustomFilter = NULL;
3121                 of.nFilterIndex = 1;
3122                 of.lpstrFile = filename;
3123                 strcpy(filename, cfg.logfilename.path);
3124                 of.nMaxFile = sizeof(filename);
3125                 of.lpstrFileTitle = NULL;
3126                 of.lpstrInitialDir = NULL;
3127                 of.lpstrTitle = "Select session log file";
3128                 of.Flags = 0;
3129                 if (GetSaveFileName(&of)) {
3130                     strcpy(cfg.logfilename.path, filename);
3131                     SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename.path);
3132                 }
3133                 break;
3134               case IDC_LSTATOFF:
3135               case IDC_LSTATASCII:
3136               case IDC_LSTATRAW:
3137               case IDC_LSTATPACKET:
3138                 if (HIWORD(wParam) == BN_CLICKED ||
3139                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3140                     if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
3141                         cfg.logtype = LGTYP_NONE;
3142                     if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
3143                         cfg.logtype = LGTYP_ASCII;
3144                     if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
3145                         cfg.logtype = LGTYP_DEBUG;
3146                     if (IsDlgButtonChecked(hwnd, IDC_LSTATPACKET))
3147                         cfg.logtype = LGTYP_PACKETS;
3148                 }
3149                 break;
3150               case IDC_LSTATXASK:
3151               case IDC_LSTATXAPN:
3152               case IDC_LSTATXOVR:
3153                 if (HIWORD(wParam) == BN_CLICKED ||
3154                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3155                     if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
3156                         cfg.logxfovr = LGXF_ASK;
3157                     if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
3158                         cfg.logxfovr = LGXF_APN;
3159                     if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
3160                         cfg.logxfovr = LGXF_OVR;
3161                 }
3162                 break;
3163               case IDC_TSEDIT:
3164               case IDC_R_TSEDIT:
3165                 if (HIWORD(wParam) == EN_CHANGE)
3166                     GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
3167                                    sizeof(cfg.termspeed) - 1);
3168                 break;
3169               case IDC_LOGEDIT:
3170                 if (HIWORD(wParam) == EN_CHANGE)
3171                     GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
3172                                    sizeof(cfg.username) - 1);
3173                 break;
3174               case IDC_RLLUSEREDIT:
3175                 if (HIWORD(wParam) == EN_CHANGE)
3176                     GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
3177                                    cfg.localusername,
3178                                    sizeof(cfg.localusername) - 1);
3179                 break;
3180               case IDC_EMBSD:
3181               case IDC_EMRFC:
3182                 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
3183                 break;
3184               case IDC_TPASSIVE:
3185               case IDC_TACTIVE:
3186                 cfg.passive_telnet =
3187                     IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
3188                 break;
3189               case IDC_ENVADD:
3190                 if (HIWORD(wParam) == BN_CLICKED ||
3191                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3192                     char str[sizeof(cfg.environmt)];
3193                     char *p;
3194                     GetDlgItemText(hwnd, IDC_VAREDIT, str,
3195                                    sizeof(str) - 1);
3196                     if (!*str) {
3197                         MessageBeep(0);
3198                         break;
3199                     }
3200                     p = str + strlen(str);
3201                     *p++ = '\t';
3202                     GetDlgItemText(hwnd, IDC_VALEDIT, p,
3203                                    sizeof(str) - 1 - (p - str));
3204                     if (!*p) {
3205                         MessageBeep(0);
3206                         break;
3207                     }
3208                     p = cfg.environmt;
3209                     while (*p) {
3210                         while (*p)
3211                             p++;
3212                         p++;
3213                     }
3214                     if ((p - cfg.environmt) + strlen(str) + 2 <
3215                         sizeof(cfg.environmt)) {
3216                         strcpy(p, str);
3217                         p[strlen(str) + 1] = '\0';
3218                         SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
3219                                            0, (LPARAM) str);
3220                         SetDlgItemText(hwnd, IDC_VAREDIT, "");
3221                         SetDlgItemText(hwnd, IDC_VALEDIT, "");
3222                     } else {
3223                         MessageBox(hwnd, "Environment too big",
3224                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3225                     }
3226                 }
3227                 break;
3228               case IDC_ENVREMOVE:
3229                 if (HIWORD(wParam) != BN_CLICKED &&
3230                     HIWORD(wParam) != BN_DOUBLECLICKED) break;
3231                 i =
3232                     SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
3233                                        0);
3234                 if (i == LB_ERR)
3235                     MessageBeep(0);
3236                 else {
3237                     char *p, *q;
3238
3239                     SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
3240                                        i, 0);
3241                     p = cfg.environmt;
3242                     while (i > 0) {
3243                         if (!*p)
3244                             goto disaster;
3245                         while (*p)
3246                             p++;
3247                         p++;
3248                         i--;
3249                     }
3250                     q = p;
3251                     if (!*p)
3252                         goto disaster;
3253                     while (*p)
3254                         p++;
3255                     p++;
3256                     while (*p) {
3257                         while (*p)
3258                             *q++ = *p++;
3259                         *q++ = *p++;
3260                     }
3261                     *q = '\0';
3262                   disaster:;
3263                 }
3264                 break;
3265               case IDC_NOPTY:
3266                 if (HIWORD(wParam) == BN_CLICKED ||
3267                     HIWORD(wParam) == BN_DOUBLECLICKED)
3268                         cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
3269                 break;
3270               case IDC_COMPRESS:
3271                 if (HIWORD(wParam) == BN_CLICKED ||
3272                     HIWORD(wParam) == BN_DOUBLECLICKED)
3273                         cfg.compression =
3274                         IsDlgButtonChecked(hwnd, IDC_COMPRESS);
3275                 break;
3276               case IDC_SSH2DES:
3277                 if (HIWORD(wParam) == BN_CLICKED ||
3278                     HIWORD(wParam) == BN_DOUBLECLICKED)
3279                         cfg.ssh2_des_cbc =
3280                         IsDlgButtonChecked(hwnd, IDC_SSH2DES);
3281                 break;
3282               case IDC_AGENTFWD:
3283                 if (HIWORD(wParam) == BN_CLICKED ||
3284                     HIWORD(wParam) == BN_DOUBLECLICKED)
3285                         cfg.agentfwd =
3286                         IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
3287                 break;
3288               case IDC_CHANGEUSER:
3289                 if (HIWORD(wParam) == BN_CLICKED ||
3290                     HIWORD(wParam) == BN_DOUBLECLICKED)
3291                         cfg.change_username =
3292                         IsDlgButtonChecked(hwnd, IDC_CHANGEUSER);
3293                 break;
3294               case IDC_CIPHERLIST:
3295               case IDC_CIPHERUP:
3296               case IDC_CIPHERDN:
3297                 handle_prefslist(&cipherlist,
3298                                  cfg.ssh_cipherlist, CIPHER_MAX,
3299                                  0, hwnd, wParam, lParam);
3300                 break;
3301               case IDC_SSHPROT1ONLY:
3302               case IDC_SSHPROT1:
3303               case IDC_SSHPROT2:
3304               case IDC_SSHPROT2ONLY:
3305                 if (HIWORD(wParam) == BN_CLICKED ||
3306                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3307                     if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1ONLY))
3308                         cfg.sshprot = 0;
3309                     if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
3310                         cfg.sshprot = 1;
3311                     else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
3312                         cfg.sshprot = 2;
3313                     else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2ONLY))
3314                         cfg.sshprot = 3;
3315                 }
3316                 break;
3317               case IDC_AUTHTIS:
3318                 if (HIWORD(wParam) == BN_CLICKED ||
3319                     HIWORD(wParam) == BN_DOUBLECLICKED)
3320                         cfg.try_tis_auth =
3321                         IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
3322                 break;
3323               case IDC_AUTHKI:
3324                 if (HIWORD(wParam) == BN_CLICKED ||
3325                     HIWORD(wParam) == BN_DOUBLECLICKED)
3326                         cfg.try_ki_auth =
3327                         IsDlgButtonChecked(hwnd, IDC_AUTHKI);
3328                 break;
3329               case IDC_PKEDIT:
3330                 if (HIWORD(wParam) == EN_CHANGE)
3331                     GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile.path,
3332                                    sizeof(cfg.keyfile.path) - 1);
3333                 break;
3334               case IDC_CMDEDIT:
3335                 if (HIWORD(wParam) == EN_CHANGE)
3336                     GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
3337                                    sizeof(cfg.remote_cmd) - 1);
3338                 break;
3339               case IDC_PKBUTTON:
3340                 memset(&of, 0, sizeof(of));
3341 #ifdef OPENFILENAME_SIZE_VERSION_400
3342                 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
3343 #else
3344                 of.lStructSize = sizeof(of);
3345 #endif
3346                 of.hwndOwner = hwnd;
3347                 of.lpstrFilter = "PuTTY Private Key Files (*.ppk)\0*.ppk\0"
3348                     "All Files (*.*)\0*\0\0\0";
3349                 of.lpstrCustomFilter = NULL;
3350                 of.nFilterIndex = 1;
3351                 of.lpstrFile = filename;
3352                 strcpy(filename, cfg.keyfile.path);
3353                 of.nMaxFile = sizeof(filename);
3354                 of.lpstrFileTitle = NULL;
3355                 of.lpstrInitialDir = NULL;
3356                 of.lpstrTitle = "Select Private Key File";
3357                 of.Flags = 0;
3358                 if (GetOpenFileName(&of)) {
3359                     strcpy(cfg.keyfile.path, filename);
3360                     SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile.path);
3361                 }
3362                 break;
3363               case IDC_RAWCNP:
3364                 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
3365                 break;
3366               case IDC_RTFPASTE:
3367                 cfg.rtf_paste = IsDlgButtonChecked(hwnd, IDC_RTFPASTE);
3368                 break;
3369               case IDC_MBWINDOWS:
3370               case IDC_MBXTERM:
3371                 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
3372                 break;
3373               case IDC_SELTYPELEX:
3374               case IDC_SELTYPERECT:
3375                 cfg.rect_select = IsDlgButtonChecked(hwnd, IDC_SELTYPERECT);
3376                 break;
3377               case IDC_MOUSEOVERRIDE:
3378                 cfg.mouse_override = IsDlgButtonChecked(hwnd, IDC_MOUSEOVERRIDE);
3379                 break;
3380               case IDC_CCSET:
3381                 {
3382                     BOOL ok;
3383                     int i;
3384                     int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
3385
3386                     if (!ok)
3387                         MessageBeep(0);
3388                     else {
3389                         for (i = 0; i < 128; i++)
3390                             if (SendDlgItemMessage
3391                                 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
3392                                 char str[100];
3393                                 cfg.wordness[i] = n;
3394                                 SendDlgItemMessage(hwnd, IDC_CCLIST,
3395                                                    LB_DELETESTRING, i, 0);
3396                                 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
3397                                         (i >= 0x21 && i != 0x7F) ? i : ' ',
3398                                         cfg.wordness[i]);
3399                                 SendDlgItemMessage(hwnd, IDC_CCLIST,
3400                                                    LB_INSERTSTRING, i,
3401                                                    (LPARAM) str);
3402                             }
3403                     }
3404                 }
3405                 break;
3406               case IDC_BOLDCOLOUR:
3407                 if (HIWORD(wParam) == BN_CLICKED ||
3408                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3409                     int n, i;
3410                     cfg.bold_colour =
3411                         IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
3412                 }
3413                 break;
3414               case IDC_PALETTE:
3415                 if (HIWORD(wParam) == BN_CLICKED ||
3416                     HIWORD(wParam) == BN_DOUBLECLICKED)
3417                         cfg.try_palette =
3418                         IsDlgButtonChecked(hwnd, IDC_PALETTE);
3419                 break;
3420               case IDC_COLOURLIST:
3421                 if (HIWORD(wParam) == LBN_DBLCLK ||
3422                     HIWORD(wParam) == LBN_SELCHANGE) {
3423                     int i =
3424                         SendDlgItemMessage(hwnd, IDC_COLOURLIST,
3425                                            LB_GETCURSEL,
3426                                            0, 0);
3427                     if (!cfg.bold_colour)
3428                         i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
3429                     SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
3430                                   FALSE);
3431                     SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
3432                                   FALSE);
3433                     SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
3434                                   FALSE);
3435                 }
3436                 break;
3437               case IDC_CHANGE:
3438                 if (HIWORD(wParam) == BN_CLICKED ||
3439                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3440                     static CHOOSECOLOR cc;
3441                     static DWORD custom[16] = { 0 };    /* zero initialisers */
3442                     int i =
3443                         SendDlgItemMessage(hwnd, IDC_COLOURLIST,
3444                                            LB_GETCURSEL,
3445                                            0, 0);
3446                     if (!cfg.bold_colour)
3447                         i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
3448                     cc.lStructSize = sizeof(cc);
3449                     cc.hwndOwner = hwnd;
3450                     cc.hInstance = (HWND) hinst;
3451                     cc.lpCustColors = custom;
3452                     cc.rgbResult =
3453                         RGB(cfg.colours[i][0], cfg.colours[i][1],
3454                             cfg.colours[i][2]);
3455                     cc.Flags = CC_FULLOPEN | CC_RGBINIT;
3456                     if (ChooseColor(&cc)) {
3457                         cfg.colours[i][0] =
3458                             (unsigned char) (cc.rgbResult & 0xFF);
3459                         cfg.colours[i][1] =
3460                             (unsigned char) (cc.rgbResult >> 8) & 0xFF;
3461                         cfg.colours[i][2] =
3462                             (unsigned char) (cc.rgbResult >> 16) & 0xFF;
3463                         SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
3464                                       FALSE);
3465                         SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
3466                                       FALSE);
3467                         SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
3468                                       FALSE);
3469                     }
3470                 }
3471                 break;
3472               case IDC_CODEPAGE:
3473                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3474                     int index = SendDlgItemMessage(hwnd, IDC_CODEPAGE,
3475                                                    CB_GETCURSEL, 0, 0);
3476                     SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_GETLBTEXT,
3477                                        index, (LPARAM)cfg.line_codepage);
3478                 } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
3479                     GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
3480                                    sizeof(cfg.line_codepage) - 1);
3481                 } else if (HIWORD(wParam) == CBN_KILLFOCUS) {
3482                     strcpy(cfg.line_codepage,
3483                            cp_name(decode_codepage(cfg.line_codepage)));
3484                     SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
3485                 }
3486                 break;
3487               case IDC_PRINTER:
3488                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3489                     int index = SendDlgItemMessage(hwnd, IDC_PRINTER,
3490                                                    CB_GETCURSEL, 0, 0);
3491                     SendDlgItemMessage(hwnd, IDC_PRINTER, CB_GETLBTEXT,
3492                                        index, (LPARAM)cfg.printer);
3493                 } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
3494                     GetDlgItemText(hwnd, IDC_PRINTER, cfg.printer,
3495                                    sizeof(cfg.printer) - 1);
3496                 }
3497                 if (!strcmp(cfg.printer, PRINTER_DISABLED_STRING))
3498                     *cfg.printer = '\0';
3499                 break;
3500               case IDC_CAPSLOCKCYR:
3501                 if (HIWORD(wParam) == BN_CLICKED ||
3502                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3503                     cfg.xlat_capslockcyr =
3504                         IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
3505                 }
3506                 break;
3507               case IDC_VTXWINDOWS:
3508               case IDC_VTOEMANSI:
3509               case IDC_VTOEMONLY:
3510               case IDC_VTPOORMAN:
3511               case IDC_VTUNICODE:
3512                 cfg.vtmode =
3513                     (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
3514                      : IsDlgButtonChecked(hwnd,
3515                                           IDC_VTOEMANSI) ? VT_OEMANSI :
3516                      IsDlgButtonChecked(hwnd,
3517                                         IDC_VTOEMONLY) ? VT_OEMONLY :
3518                      IsDlgButtonChecked(hwnd,
3519                                         IDC_VTUNICODE) ? VT_UNICODE :
3520                      VT_POORMAN);
3521                 break;
3522               case IDC_X11_FORWARD:
3523                 if (HIWORD(wParam) == BN_CLICKED ||
3524                     HIWORD(wParam) == BN_DOUBLECLICKED)
3525                     cfg.x11_forward =
3526                     IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
3527                 break;
3528               case IDC_LPORT_ALL:
3529                 if (HIWORD(wParam) == BN_CLICKED ||
3530                     HIWORD(wParam) == BN_DOUBLECLICKED)
3531                     cfg.lport_acceptall =
3532                     IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
3533                 break;
3534               case IDC_RPORT_ALL:
3535                 if (HIWORD(wParam) == BN_CLICKED ||
3536                     HIWORD(wParam) == BN_DOUBLECLICKED)
3537                     cfg.rport_acceptall =
3538                     IsDlgButtonChecked(hwnd, IDC_RPORT_ALL);
3539                 break;
3540               case IDC_X11_DISPLAY:
3541                 if (HIWORD(wParam) == EN_CHANGE)
3542                     GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
3543                                    sizeof(cfg.x11_display) - 1);
3544                 break;
3545               case IDC_X11MIT:
3546               case IDC_X11XDM:
3547                 if (HIWORD(wParam) == BN_CLICKED ||
3548                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3549                     if (IsDlgButtonChecked(hwnd, IDC_X11MIT))
3550                         cfg.x11_auth = X11_MIT;
3551                     else if (IsDlgButtonChecked(hwnd, IDC_X11XDM))
3552                         cfg.x11_auth = X11_XDM;
3553                 }
3554                 break;
3555               case IDC_PFWDADD:
3556                 if (HIWORD(wParam) == BN_CLICKED ||
3557                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3558                     char str[sizeof(cfg.portfwd)];
3559                     char *p;
3560                     if (IsDlgButtonChecked(hwnd, IDC_PFWDLOCAL))
3561                         str[0] = 'L';
3562                     else
3563                         str[0] = 'R';
3564                     GetDlgItemText(hwnd, IDC_SPORTEDIT, str+1,
3565                                    sizeof(str) - 2);
3566                     if (!str[1]) {
3567                         MessageBox(hwnd,
3568                                    "You need to specify a source port number",
3569                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3570                         break;
3571                     }
3572                     p = str + strlen(str);
3573                     *p++ = '\t';
3574                     GetDlgItemText(hwnd, IDC_DPORTEDIT, p,
3575                                    sizeof(str) - 1 - (p - str));
3576                     if (!*p || !strchr(p, ':')) {
3577                         MessageBox(hwnd,
3578                                    "You need to specify a destination address\n"
3579                                    "in the form \"host.name:port\"",
3580                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3581                         break;
3582                     }
3583                     p = cfg.portfwd;
3584                     while (*p) {
3585                         while (*p)
3586                             p++;
3587                         p++;
3588                     }
3589                     if ((p - cfg.portfwd) + strlen(str) + 2 <
3590                         sizeof(cfg.portfwd)) {
3591                         strcpy(p, str);
3592                         p[strlen(str) + 1] = '\0';
3593                         SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING,
3594                                            0, (LPARAM) str);
3595                         SetDlgItemText(hwnd, IDC_SPORTEDIT, "");
3596                         SetDlgItemText(hwnd, IDC_DPORTEDIT, "");
3597                     } else {
3598                         MessageBox(hwnd, "Too many forwardings",
3599                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3600                     }
3601                 }
3602                 break;
3603               case IDC_PFWDREMOVE:
3604                 if (HIWORD(wParam) != BN_CLICKED &&
3605                     HIWORD(wParam) != BN_DOUBLECLICKED) break;
3606                 i = SendDlgItemMessage(hwnd, IDC_PFWDLIST,
3607                                        LB_GETCURSEL, 0, 0);
3608                 if (i == LB_ERR)
3609                     MessageBeep(0);
3610                 else {
3611                     char *p, *q;
3612
3613                     SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_DELETESTRING,
3614                                        i, 0);
3615                     p = cfg.portfwd;
3616                     while (i > 0) {
3617                         if (!*p)
3618                             goto disaster2;
3619                         while (*p)
3620                             p++;
3621                         p++;
3622                         i--;
3623                     }
3624                     q = p;
3625                     if (!*p)
3626                         goto disaster2;
3627                     while (*p)
3628                         p++;
3629                     p++;
3630                     while (*p) {
3631                         while (*p)
3632                             *q++ = *p++;
3633                         *q++ = *p++;
3634                     }
3635                     *q = '\0';
3636                   disaster2:;
3637                 }
3638                 break;
3639               case IDC_BUGD_IGNORE1:
3640                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3641                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1,
3642                                                    CB_GETCURSEL, 0, 0);
3643                     cfg.sshbug_ignore1 = (index == 0 ? AUTO :
3644                                           index == 1 ? FORCE_OFF : FORCE_ON);
3645                 }
3646                 break;
3647               case IDC_BUGD_PLAINPW1:
3648                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3649                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1,
3650                                                    CB_GETCURSEL, 0, 0);
3651                     cfg.sshbug_plainpw1 = (index == 0 ? AUTO :
3652                                            index == 1 ? FORCE_OFF : FORCE_ON);
3653                 }
3654                 break;
3655               case IDC_BUGD_RSA1:
3656                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3657                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_RSA1,
3658                                                    CB_GETCURSEL, 0, 0);
3659                     cfg.sshbug_rsa1 = (index == 0 ? AUTO :
3660                                        index == 1 ? FORCE_OFF : FORCE_ON);
3661                 }
3662                 break;
3663               case IDC_BUGD_HMAC2:
3664                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3665                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2,
3666                                                    CB_GETCURSEL, 0, 0);
3667                     cfg.sshbug_hmac2 = (index == 0 ? AUTO :
3668                                         index == 1 ? FORCE_OFF : FORCE_ON);
3669                 }
3670                 break;
3671               case IDC_BUGD_DERIVEKEY2:
3672                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3673                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2,
3674                                                    CB_GETCURSEL, 0, 0);
3675                     cfg.sshbug_derivekey2 = (index == 0 ? AUTO :
3676                                              index == 1 ? FORCE_OFF:FORCE_ON);
3677                 }
3678                 break;
3679               case IDC_BUGD_RSAPAD2:
3680                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3681                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2,
3682                                                    CB_GETCURSEL, 0, 0);
3683                     cfg.sshbug_rsapad2 = (index == 0 ? AUTO :
3684                                           index == 1 ? FORCE_OFF : FORCE_ON);
3685                 }
3686                 break;
3687               case IDC_BUGD_DHGEX2:
3688                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3689                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2,
3690                                                    CB_GETCURSEL, 0, 0);
3691                     cfg.sshbug_dhgex2 = (index == 0 ? AUTO :
3692                                          index == 1 ? FORCE_OFF : FORCE_ON);
3693                 }
3694                 break;
3695               case IDC_BUGD_PKSESSID2:
3696                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3697                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2,
3698                                                    CB_GETCURSEL, 0, 0);
3699                     cfg.sshbug_pksessid2 = (index == 0 ? AUTO :
3700                                             index == 1 ? FORCE_OFF : FORCE_ON);
3701                 }
3702                 break;
3703             }
3704         return 0;
3705       case WM_HELP:
3706         if (help_path) {
3707             int id = ((LPHELPINFO)lParam)->iCtrlId;
3708             char *cmd = help_context_cmd(id);
3709             if (cmd) {
3710                 WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
3711                 requested_help = TRUE;
3712             } else {
3713                 MessageBeep(0);
3714             }
3715         }
3716         break;
3717       case WM_CLOSE:
3718         if (requested_help) {
3719             WinHelp(hwnd, help_path, HELP_QUIT, 0);
3720             requested_help = FALSE;
3721         }
3722         EndDialog(hwnd, 0);
3723         return 0;
3724
3725         /* Grrr Explorer will maximize Dialogs! */
3726       case WM_SIZE:
3727         if (wParam == SIZE_MAXIMIZED)
3728             force_normal(hwnd);
3729         return 0;
3730
3731       default:
3732         /*
3733          * Handle application-defined messages eg. DragListBox
3734          */
3735         /* First find out what the number is (once). */
3736         if (draglistmsg == WM_NULL)
3737             draglistmsg = RegisterWindowMessage (DRAGLISTMSGSTRING);
3738
3739         if (msg == draglistmsg) {
3740             /* Only process once dialog is fully formed. */
3741             if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
3742               case IDC_CIPHERLIST:
3743                 return handle_prefslist(&cipherlist,
3744                                         cfg.ssh_cipherlist, CIPHER_MAX,
3745                                         1, hwnd, wParam, lParam);
3746             }
3747         }
3748         return 0;
3749
3750     }
3751     return 0;
3752 }
3753
3754 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
3755                                 WPARAM wParam, LPARAM lParam)
3756 {
3757     if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
3758     }
3759     if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
3760         EnableWindow(hwnd, 0);
3761         DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
3762         EnableWindow(hwnd, 1);
3763         SetActiveWindow(hwnd);
3764     }
3765     return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
3766 }
3767
3768 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
3769                                   WPARAM wParam, LPARAM lParam)
3770 {
3771     return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
3772 }
3773
3774 void defuse_showwindow(void)
3775 {
3776     /*
3777      * Work around the fact that the app's first call to ShowWindow
3778      * will ignore the default in favour of the shell-provided
3779      * setting.
3780      */
3781     {
3782         HWND hwnd;
3783         hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
3784                             NULL, NullDlgProc);
3785         ShowWindow(hwnd, SW_HIDE);
3786         SetActiveWindow(hwnd);
3787         DestroyWindow(hwnd);
3788     }
3789 }
3790
3791 int do_config(void)
3792 {
3793     int ret;
3794
3795     get_sesslist(&sesslist, TRUE);
3796     savedsession[0] = '\0';
3797     ret =
3798         DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
3799     get_sesslist(&sesslist, FALSE);
3800
3801     return ret;
3802 }
3803
3804 int do_reconfig(HWND hwnd)
3805 {
3806     Config backup_cfg;
3807     int ret;
3808
3809     backup_cfg = cfg;                  /* structure copy */
3810     ret =
3811         DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
3812     if (!ret)
3813         cfg = backup_cfg;              /* structure copy */
3814
3815     return ret;
3816 }
3817
3818 void logevent(void *frontend, char *string)
3819 {
3820     char timebuf[40];
3821     time_t t;
3822
3823     log_eventlog(logctx, string);
3824
3825     if (nevents >= negsize) {
3826         negsize += 64;
3827         events = srealloc(events, negsize * sizeof(*events));
3828     }
3829
3830     time(&t);
3831     strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
3832              localtime(&t));
3833
3834     events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
3835     strcpy(events[nevents], timebuf);
3836     strcat(events[nevents], string);
3837     if (logbox) {
3838         int count;
3839         SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
3840                            0, (LPARAM) events[nevents]);
3841         count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
3842         SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
3843     }
3844     nevents++;
3845 }
3846
3847 void showeventlog(HWND hwnd)
3848 {
3849     if (!logbox) {
3850         logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
3851                               hwnd, LogProc);
3852         ShowWindow(logbox, SW_SHOWNORMAL);
3853     }
3854     SetActiveWindow(logbox);
3855 }
3856
3857 void showabout(HWND hwnd)
3858 {
3859     DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
3860 }
3861
3862 void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
3863                          char *keystr, char *fingerprint)
3864 {
3865     int ret;
3866
3867     static const char absentmsg[] =
3868         "The server's host key is not cached in the registry. You\n"
3869         "have no guarantee that the server is the computer you\n"
3870         "think it is.\n"
3871         "The server's key fingerprint is:\n"
3872         "%s\n"
3873         "If you trust this host, hit Yes to add the key to\n"
3874         "PuTTY's cache and carry on connecting.\n"
3875         "If you want to carry on connecting just once, without\n"
3876         "adding the key to the cache, hit No.\n"
3877         "If you do not trust this host, hit Cancel to abandon the\n"
3878         "connection.\n";
3879
3880     static const char wrongmsg[] =
3881         "WARNING - POTENTIAL SECURITY BREACH!\n"
3882         "\n"
3883         "The server's host key does not match the one PuTTY has\n"
3884         "cached in the registry. This means that either the\n"
3885         "server administrator has changed the host key, or you\n"
3886         "have actually connected to another computer pretending\n"
3887         "to be the server.\n"
3888         "The new key fingerprint is:\n"
3889         "%s\n"
3890         "If you were expecting this change and trust the new key,\n"
3891         "hit Yes to update PuTTY's cache and continue connecting.\n"
3892         "If you want to carry on connecting but without updating\n"
3893         "the cache, hit No.\n"
3894         "If you want to abandon the connection completely, hit\n"
3895         "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
3896
3897     static const char mbtitle[] = "PuTTY Security Alert";
3898
3899     char message[160 +
3900         /* sensible fingerprint max size */
3901         (sizeof(absentmsg) > sizeof(wrongmsg) ?
3902          sizeof(absentmsg) : sizeof(wrongmsg))];
3903
3904     /*
3905      * Verify the key against the registry.
3906      */
3907     ret = verify_host_key(host, port, keytype, keystr);
3908
3909     if (ret == 0)                      /* success - key matched OK */
3910         return;
3911     if (ret == 2) {                    /* key was different */
3912         int mbret;
3913         sprintf(message, wrongmsg, fingerprint);
3914         mbret = MessageBox(NULL, message, mbtitle,
3915                            MB_ICONWARNING | MB_YESNOCANCEL);
3916         if (mbret == IDYES)
3917             store_host_key(host, port, keytype, keystr);
3918         if (mbret == IDCANCEL)
3919             cleanup_exit(0);
3920     }
3921     if (ret == 1) {                    /* key was absent */
3922         int mbret;
3923         sprintf(message, absentmsg, fingerprint);
3924         mbret = MessageBox(NULL, message, mbtitle,
3925                            MB_ICONWARNING | MB_YESNOCANCEL);
3926         if (mbret == IDYES)
3927             store_host_key(host, port, keytype, keystr);
3928         if (mbret == IDCANCEL)
3929             cleanup_exit(0);
3930     }
3931 }
3932
3933 /*
3934  * Ask whether the selected cipher is acceptable (since it was
3935  * below the configured 'warn' threshold).
3936  * cs: 0 = both ways, 1 = client->server, 2 = server->client
3937  */
3938 void askcipher(void *frontend, char *ciphername, int cs)
3939 {
3940     static const char mbtitle[] = "PuTTY Security Alert";
3941     static const char msg[] =
3942         "The first %.35scipher supported by the server\n"
3943         "is %.64s, which is below the configured\n"
3944         "warning threshold.\n"
3945         "Do you want to continue with this connection?\n";
3946     /* guessed cipher name + type max length */
3947     char message[100 + sizeof(msg)];
3948     int mbret;
3949
3950     sprintf(message, msg,
3951             (cs == 0) ? "" :
3952             (cs == 1) ? "client-to-server " :
3953                         "server-to-client ",
3954             ciphername);
3955     mbret = MessageBox(NULL, message, mbtitle,
3956                        MB_ICONWARNING | MB_YESNO);
3957     if (mbret == IDYES)
3958         return;
3959     else
3960         cleanup_exit(0);
3961 }
3962
3963 /*
3964  * Ask whether to wipe a session log file before writing to it.
3965  * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
3966  */
3967 int askappend(void *frontend, Filename filename)
3968 {
3969     static const char mbtitle[] = "PuTTY Log to File";
3970     static const char msgtemplate[] =
3971         "The session log file \"%.*s\" already exists.\n"
3972         "You can overwrite it with a new session log,\n"
3973         "append your session log to the end of it,\n"
3974         "or disable session logging for this session.\n"
3975         "Hit Yes to wipe the file, No to append to it,\n"
3976         "or Cancel to disable logging.";
3977     char message[sizeof(msgtemplate) + FILENAME_MAX];
3978     int mbret;
3979
3980     sprintf(message, msgtemplate, FILENAME_MAX, filename.path);
3981
3982     mbret = MessageBox(NULL, message, mbtitle,
3983                        MB_ICONQUESTION | MB_YESNOCANCEL);
3984     if (mbret == IDYES)
3985         return 2;
3986     else if (mbret == IDNO)
3987         return 1;
3988     else
3989         return 0;
3990 }
3991
3992 /*
3993  * Warn about the obsolescent key file format.
3994  * 
3995  * Uniquely among these functions, this one does _not_ expect a
3996  * frontend handle. This means that if PuTTY is ported to a
3997  * platform which requires frontend handles, this function will be
3998  * an anomaly. Fortunately, the problem it addresses will not have
3999  * been present on that platform, so it can plausibly be
4000  * implemented as an empty function.
4001  */
4002 void old_keyfile_warning(void)
4003 {
4004     static const char mbtitle[] = "PuTTY Key File Warning";
4005     static const char message[] =
4006         "You are loading an SSH 2 private key which has an\n"
4007         "old version of the file format. This means your key\n"
4008         "file is not fully tamperproof. Future versions of\n"
4009         "PuTTY may stop supporting this private key format,\n"
4010         "so we recommend you convert your key to the new\n"
4011         "format.\n"
4012         "\n"
4013         "You can perform this conversion by loading the key\n"
4014         "into PuTTYgen and then saving it again.";
4015
4016     MessageBox(NULL, message, mbtitle, MB_OK);
4017 }