13 static char **events = NULL;
14 static int nevents = 0, negsize = 0;
18 void force_normal(HWND hwnd)
20 static int recurse = 0;
27 wp.length = sizeof(wp);
28 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED)
30 wp.showCmd = SW_SHOWNORMAL;
31 SetWindowPlacement(hwnd, &wp);
36 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
39 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
44 static int CALLBACK LogProc (HWND hwnd, UINT msg,
45 WPARAM wParam, LPARAM lParam) {
50 for (i=0; i<nevents; i++)
51 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
52 0, (LPARAM)events[i]);
55 switch (LOWORD(wParam)) {
59 SetActiveWindow(GetParent(hwnd));
63 if (HIWORD(wParam) == BN_CLICKED ||
64 HIWORD(wParam) == BN_DOUBLECLICKED) {
67 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
68 LB_GETSELCOUNT, 0, 0);
69 if (selcount == 0) { /* don't even try to copy zero items */
74 selitems = smalloc(selcount * sizeof(int));
76 int count = SendDlgItemMessage(hwnd, IDN_LIST,
78 selcount, (LPARAM)selitems);
82 static unsigned char sel_nl[] = SEL_NL;
84 if (count == 0) { /* can't copy zero stuff */
90 for (i = 0; i < count; i++)
91 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
93 clipdata = smalloc(size);
96 for (i = 0; i < count; i++) {
97 char *q = events[selitems[i]];
101 memcpy(p, sel_nl, sizeof(sel_nl));
104 write_clip(clipdata, size, TRUE);
109 for (i = 0; i < nevents; i++)
110 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
119 SetActiveWindow(GetParent(hwnd));
120 DestroyWindow (hwnd);
126 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
127 WPARAM wParam, LPARAM lParam) {
132 switch (LOWORD(wParam)) {
145 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
146 WPARAM wParam, LPARAM lParam) {
149 SetDlgItemText (hwnd, IDA_VERSION, ver);
152 switch (LOWORD(wParam)) {
155 EndDialog(hwnd, TRUE);
158 EnableWindow(hwnd, 0);
159 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
161 EnableWindow(hwnd, 1);
162 SetActiveWindow(hwnd);
167 EndDialog(hwnd, TRUE);
174 * Null dialog procedure.
176 static int CALLBACK NullDlgProc (HWND hwnd, UINT msg,
177 WPARAM wParam, LPARAM lParam) {
181 static char savedsession[2048];
183 enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
289 appearancepanelstart,
290 IDC_TITLE_APPEARANCE,
308 connectionpanelstart,
309 IDC_TITLE_CONNECTION,
404 translationpanelstart,
405 IDC_TITLE_TRANSLATION,
406 IDC_BOX_TRANSLATION1,
407 IDC_BOX_TRANSLATION2,
408 IDC_BOX_TRANSLATION3,
433 static const char *const colours[] = {
434 "Default Foreground", "Default Bold Foreground",
435 "Default Background", "Default Bold Background",
436 "Cursor Text", "Cursor Colour",
437 "ANSI Black", "ANSI Black Bold",
438 "ANSI Red", "ANSI Red Bold",
439 "ANSI Green", "ANSI Green Bold",
440 "ANSI Yellow", "ANSI Yellow Bold",
441 "ANSI Blue", "ANSI Blue Bold",
442 "ANSI Magenta", "ANSI Magenta Bold",
443 "ANSI Cyan", "ANSI Cyan Bold",
444 "ANSI White", "ANSI White Bold"
446 static const int permcolour[] = {
447 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
448 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
449 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
452 static void fmtfont (char *buf) {
453 sprintf (buf, "Font: %s, ", cfg.font);
455 strcat(buf, "bold, ");
456 if (cfg.fontheight == 0)
457 strcat (buf, "default height");
459 sprintf (buf+strlen(buf), "%d-%s",
460 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
461 (cfg.fontheight < 0 ? "pixel" : "point"));
464 static void init_dlg_ctrls(HWND hwnd) {
466 char fontstatic[256];
468 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
469 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
472 n = SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
474 SendDlgItemMessage (hwnd, IDC_SESSLIST,
475 LB_DELETESTRING, i, 0);
476 for (i = 0; i < nsessions; i++)
477 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
478 0, (LPARAM) (sessions[i]));
480 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
481 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
482 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
483 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET :
484 cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW );
485 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
487 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
488 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
489 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
490 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
491 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
492 cfg.funky_type == 0 ? IDC_FUNCTILDE :
493 cfg.funky_type == 1 ? IDC_FUNCLINUX :
494 cfg.funky_type == 2 ? IDC_FUNCXTERM :
495 cfg.funky_type == 3 ? IDC_FUNCVT400 :
497 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
498 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
499 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
500 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
501 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
502 cfg.nethack_keypad ? IDC_KPNH :
503 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
504 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
505 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
506 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
507 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
508 CheckRadioButton (hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
509 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND:
510 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
511 CheckRadioButton (hwnd, IDC_EDITBACKEND, IDC_EDITNO,
512 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND:
513 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
514 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
515 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
516 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
518 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
519 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
520 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
521 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
522 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
523 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
524 fmtfont (fontstatic);
525 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
526 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
527 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
528 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
530 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
531 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
532 CheckDlgButton (hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
533 CheckRadioButton (hwnd, IDC_CURBLOCK, IDC_CURVERT,
534 cfg.cursor_type==0 ? IDC_CURBLOCK :
535 cfg.cursor_type==1 ? IDC_CURUNDER : IDC_CURVERT);
536 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
537 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
538 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
539 CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit);
540 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
542 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
543 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
544 SetDlgItemText (hwnd, IDC_R_TSEDIT, cfg.termspeed);
545 SetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername);
546 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
547 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
548 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
549 cfg.logtype == 0 ? IDC_LSTATOFF :
550 cfg.logtype == 1 ? IDC_LSTATASCII :
553 char *p = cfg.environmt;
555 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
560 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
561 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
563 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
564 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
565 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
566 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
567 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
568 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
569 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
570 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
571 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
573 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
574 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
575 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
576 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
577 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
579 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
580 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
582 static int tabs[4] = {25, 61, 96, 128};
583 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
586 for (i=0; i<256; i++) {
588 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
589 (i>=0x21 && i != 0x7F) ? i : ' ',
591 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
595 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
596 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
599 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
601 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
602 LB_DELETESTRING, i, 0);
604 if (cfg.bold_colour || permcolour[i])
605 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
606 (LPARAM) colours[i]);
608 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
609 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
610 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
611 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
613 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
614 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
615 cfg.xlat_88592cp852 ? IDC_88592CP852 :
616 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
618 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
619 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
620 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
621 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
622 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
625 CheckDlgButton (hwnd, IDC_X11_FORWARD, cfg.x11_forward);
626 SetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display);
629 struct treeview_faff {
634 static HTREEITEM treeview_insert(struct treeview_faff *faff,
635 int level, char *text) {
639 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
640 ins.hInsertAfter = faff->lastat[level];
641 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
642 #define INSITEM DUMMYUNIONNAME.item
646 ins.INSITEM.mask = TVIF_TEXT;
647 ins.INSITEM.pszText = text;
648 newitem = TreeView_InsertItem(faff->treeview, &ins);
650 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
651 faff->lastat[level] = newitem;
652 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
657 * Create the panelfuls of controls in the configuration box.
659 static void create_controls(HWND hwnd, int dlgtype, int panel) {
660 if (panel == sessionpanelstart) {
661 /* The Session panel. Accelerators used: [acgo] nprtih elsd x */
663 ctlposinit(&cp, hwnd, 80, 3, 13);
664 bartitle(&cp, "Basic options for your PuTTY session",
667 beginbox(&cp, "Specify your connection by host name",
670 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
671 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
672 if (backends[3].backend == NULL) {
673 /* this is PuTTYtel, so only three protocols available */
674 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
676 "&Telnet", IDC_PROTTELNET,
677 "Rlog&in", IDC_PROTRLOGIN, NULL);
679 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
681 "&Telnet", IDC_PROTTELNET,
682 "Rlog&in", IDC_PROTRLOGIN,
691 beginbox(&cp, "Load, save or delete a stored session",
693 sesssaver(&cp, "Sav&ed Sessions",
694 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
695 "&Load", IDC_SESSLOAD,
696 "&Save", IDC_SESSSAVE,
697 "&Delete", IDC_SESSDEL, NULL);
700 beginbox(&cp, NULL, IDC_BOX_SESSION3);
701 checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT);
705 if (panel == loggingpanelstart) {
706 /* The Logging panel. Accelerators used: [acgo] tplfw */
708 ctlposinit(&cp, hwnd, 80, 3, 13);
709 bartitle(&cp, "Options controlling session logging",
711 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
713 "Session logging:", IDC_LSTATSTATIC,
714 "Logging &turned off completely", IDC_LSTATOFF,
715 "Log &printable output only", IDC_LSTATASCII,
716 "&Log all session output", IDC_LSTATRAW, NULL);
717 editbutton(&cp, "Log &file name:",
718 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
723 if (panel == terminalpanelstart) {
724 /* The Terminal panel. Accelerators used: [acgo] wdlben ht */
726 ctlposinit(&cp, hwnd, 80, 3, 13);
727 bartitle(&cp, "Options controlling the terminal emulation",
729 beginbox(&cp, "Set various terminal options",
731 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
732 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
733 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
734 checkbox(&cp, "&Beep enabled", IDC_BEEP);
735 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
736 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
739 beginbox(&cp, "Line discipline options",
741 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
742 "Auto", IDC_ECHOBACKEND,
743 "Force on", IDC_ECHOYES,
744 "Force off", IDC_ECHONO, NULL);
745 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
746 "Auto", IDC_EDITBACKEND,
747 "Force on", IDC_EDITYES,
748 "Force off", IDC_EDITNO, NULL);
752 if (panel == keyboardpanelstart) {
753 /* The Keyboard panel. Accelerators used: [acgo] h?sr~lxv unpymie t */
755 ctlposinit(&cp, hwnd, 80, 3, 13);
756 bartitle(&cp, "Options controlling the effects of keys",
758 beginbox(&cp, "Change the sequences sent by:",
760 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
761 "Control-&H", IDC_DEL008,
762 "Control-&? (127)", IDC_DEL127, NULL);
763 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
764 "&Standard", IDC_HOMETILDE,
765 "&rxvt", IDC_HOMERXVT, NULL);
766 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
767 "ESC[n&~", IDC_FUNCTILDE,
768 "&Linux", IDC_FUNCLINUX,
769 "&Xterm R6", IDC_FUNCXTERM,
770 "&VT400", IDC_FUNCVT400, NULL);
772 beginbox(&cp, "Application keypad settings:",
775 "Application c&ursor keys totally disabled",
777 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
778 "&Normal", IDC_CURNORMAL,
779 "A&pplication", IDC_CURAPPLIC, NULL);
781 "Application ke&ypad keys totally disabled",
783 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
784 "Nor&mal", IDC_KPNORMAL,
785 "Appl&ication", IDC_KPAPPLIC,
786 "N&etHack", IDC_KPNH, NULL);
788 beginbox(&cp, "Enable extra keyboard features:",
790 checkbox(&cp, "Application and AltGr ac&t as Compose key",
795 if (panel == windowpanelstart) {
796 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
798 ctlposinit(&cp, hwnd, 80, 3, 13);
799 bartitle(&cp, "Options controlling PuTTY's window",
801 beginbox(&cp, "Set the size of the window",
804 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
805 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
807 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
809 beginbox(&cp, "Control the scrollback in the window",
811 staticedit(&cp, "Lines of &scrollback",
812 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
813 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
814 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
815 checkbox(&cp, "Reset scrollback on dis&play activity",
818 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
819 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
820 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
821 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
822 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
823 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
827 if (panel == appearancepanelstart) {
828 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p */
830 ctlposinit(&cp, hwnd, 80, 3, 13);
831 bartitle(&cp, "Options controlling PuTTY's appearance",
832 IDC_TITLE_APPEARANCE);
833 beginbox(&cp, "Adjust the use of the cursor",
834 IDC_BOX_APPEARANCE1);
835 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
836 "B&lock", IDC_CURBLOCK,
837 "&Underline", IDC_CURUNDER,
838 "&Vertical line", IDC_CURVERT,
840 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
842 beginbox(&cp, "Set the font used in the terminal window",
843 IDC_BOX_APPEARANCE2);
844 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
846 beginbox(&cp, "Adjust the use of the window title",
847 IDC_BOX_APPEARANCE3);
849 "Window &title:", IDC_WINTITLE,
850 IDC_WINEDIT, 100, NULL);
851 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
853 beginbox(&cp, "Adjust the use of the mouse pointer",
854 IDC_BOX_APPEARANCE4);
855 checkbox(&cp, "Hide mouse &pointer when typing in window",
860 if (panel == translationpanelstart) {
861 /* The Translation panel. Accelerators used: [acgo] xbep t s */
863 ctlposinit(&cp, hwnd, 80, 3, 13);
864 bartitle(&cp, "Options controlling character set translation",
865 IDC_TITLE_TRANSLATION);
866 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
867 IDC_BOX_TRANSLATION1);
869 "Handling of line drawing characters:", IDC_VTSTATIC,
870 "Font has &XWindows encoding", IDC_VTXWINDOWS,
871 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
872 "Use font in O&EM mode only", IDC_VTOEMONLY,
873 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
874 IDC_VTPOORMAN, NULL);
876 beginbox(&cp, "Enable character set translation on received data",
877 IDC_BOX_TRANSLATION2);
879 "Character set &translation:", IDC_XLATSTATIC,
881 "KOI8 / Win-1251", IDC_KOI8WIN1251,
882 "ISO-8859-2 / Win-1250", IDC_88592WIN1250,
883 "ISO-8859-2 / CP852", IDC_88592CP852, NULL);
885 beginbox(&cp, "Enable character set translation on input data",
886 IDC_BOX_TRANSLATION3);
887 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
892 if (panel == selectionpanelstart) {
893 /* The Selection panel. Accelerators used: [acgo] wx hst */
895 ctlposinit(&cp, hwnd, 80, 3, 13);
896 bartitle(&cp, "Options controlling copy and paste",
897 IDC_TITLE_SELECTION);
898 beginbox(&cp, "Control which mouse button does which thing",
900 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
901 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
902 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
905 beginbox(&cp, "Control the select-one-word-at-a-time mode",
907 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
908 "&Set", IDC_CCSET, IDC_CCEDIT,
909 "&to class", IDC_CCSTATIC2);
913 if (panel == colourspanelstart) {
914 /* The Colours panel. Accelerators used: [acgo] blum */
916 ctlposinit(&cp, hwnd, 80, 3, 13);
917 bartitle(&cp, "Options controlling use of colours",
919 beginbox(&cp, "General options for colour usage",
921 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
922 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
924 beginbox(&cp, "Adjust the precise colours PuTTY displays",
926 colouredit(&cp, "Select a colo&ur and then click to modify it:",
927 IDC_COLOURSTATIC, IDC_COLOURLIST,
928 "&Modify...", IDC_CHANGE,
929 "Red:", IDC_RSTATIC, IDC_RVALUE,
930 "Green:", IDC_GSTATIC, IDC_GVALUE,
931 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
935 if (panel == connectionpanelstart) {
936 /* The Connection panel. Accelerators used: [acgo] tuk */
938 ctlposinit(&cp, hwnd, 80, 3, 13);
939 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
941 beginbox(&cp, "Data to send to the server",
942 IDC_BOX_CONNECTION1);
943 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
944 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
947 beginbox(&cp, "Sending of null packets to keep session active",
948 IDC_BOX_CONNECTION2);
949 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
950 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
954 if (panel == telnetpanelstart) {
955 /* The Telnet panel. Accelerators used: [acgo] svldr bf */
957 ctlposinit(&cp, hwnd, 80, 3, 13);
959 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
960 beginbox(&cp, "Data to send to the server",
962 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
963 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
964 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
965 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
967 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
969 beginbox(&cp, "Telnet protocol adjustments",
971 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
972 "&BSD (commonplace)", IDC_EMBSD,
973 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
978 if (panel == rloginpanelstart) {
979 /* The Rlogin panel. Accelerators used: [acgo] sl */
981 ctlposinit(&cp, hwnd, 80, 3, 13);
983 bartitle(&cp, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN);
984 beginbox(&cp, "Data to send to the server",
986 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC, IDC_R_TSEDIT, 50);
987 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC, IDC_RLLUSEREDIT, 50);
992 if (panel == sshpanelstart) {
993 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bd i */
995 ctlposinit(&cp, hwnd, 80, 3, 13);
997 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
998 beginbox(&cp, "Data to send to the server",
1001 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1004 beginbox(&cp, "Authentication options",
1006 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1008 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1009 editbutton(&cp, "Private &key file for authentication:",
1010 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
1012 beginbox(&cp, "Protocol options",
1014 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1015 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1016 radioline(&cp, "Preferred SSH protocol version:",
1017 IDC_SSHPROTSTATIC, 2,
1018 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1019 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
1020 "&3DES", IDC_CIPHER3DES,
1021 "&Blowfish", IDC_CIPHERBLOWF,
1022 "&DES", IDC_CIPHERDES, NULL);
1023 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1029 if (panel == tunnelspanelstart) {
1030 /* The Tunnels panel. Accelerators used: [acgo] ex */
1032 ctlposinit(&cp, hwnd, 80, 3, 13);
1034 bartitle(&cp, "Options controlling SSH tunnelling",
1036 beginbox(&cp, "X11 forwarding options",
1038 checkbox(&cp, "&Enable X11 forwarding",
1040 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1041 IDC_X11_DISPLAY, 50, NULL);
1048 * This function is the configuration box.
1050 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1051 WPARAM wParam, LPARAM lParam,
1054 struct treeview_faff tvfaff;
1057 char filename[sizeof(cfg.keyfile)];
1060 char fontstatic[256];
1062 struct servent * service;
1068 SetWindowLong(hwnd, GWL_USERDATA, 0);
1070 * Centre the window.
1072 { /* centre the window */
1075 hw = GetDesktopWindow();
1076 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1077 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1078 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1079 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1083 * Create the tree view.
1090 r.left = 3; r.right = r.left + 75;
1091 r.top = 3; r.bottom = r.top + 10;
1092 MapDialogRect(hwnd, &r);
1093 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1094 WS_CHILD | WS_VISIBLE,
1096 r.right-r.left, r.bottom-r.top,
1097 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
1098 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1099 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1101 r.left = 3; r.right = r.left + 75;
1102 r.top = 13; r.bottom = r.top + 206;
1103 MapDialogRect(hwnd, &r);
1104 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1105 WS_CHILD | WS_VISIBLE |
1106 WS_TABSTOP | TVS_HASLINES |
1107 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
1108 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
1110 r.right-r.left, r.bottom-r.top,
1111 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
1112 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1113 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1114 tvfaff.treeview = treeview;
1115 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1119 * Set up the tree view contents.
1121 hsession = treeview_insert(&tvfaff, 0, "Session");
1122 treeview_insert(&tvfaff, 1, "Logging");
1123 treeview_insert(&tvfaff, 0, "Terminal");
1124 treeview_insert(&tvfaff, 1, "Keyboard");
1125 treeview_insert(&tvfaff, 0, "Window");
1126 treeview_insert(&tvfaff, 1, "Appearance");
1127 treeview_insert(&tvfaff, 1, "Translation");
1128 treeview_insert(&tvfaff, 1, "Selection");
1129 treeview_insert(&tvfaff, 1, "Colours");
1130 treeview_insert(&tvfaff, 0, "Connection");
1132 treeview_insert(&tvfaff, 1, "Telnet");
1133 treeview_insert(&tvfaff, 1, "Rlogin");
1134 if (backends[3].backend != NULL) {
1135 treeview_insert(&tvfaff, 1, "SSH");
1136 treeview_insert(&tvfaff, 2, "Tunnels");
1141 * Put the treeview selection on to the Session panel. This
1142 * should also cause creation of the relevant controls.
1144 TreeView_SelectItem(treeview, hsession);
1147 * Set focus into the first available control.
1151 ctl = GetDlgItem(hwnd, IDC_HOST);
1152 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1156 SetWindowLong(hwnd, GWL_USERDATA, 1);
1160 * Button release should trigger WM_OK if there was a
1161 * previous double click on the session list.
1165 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1168 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1169 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1170 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1175 item.pszText = buffer;
1176 item.cchTextMax = sizeof(buffer);
1177 item.mask = TVIF_TEXT;
1178 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1179 for (j = controlstartvalue; j < controlendvalue; j++) {
1180 HWND item = GetDlgItem(hwnd, j);
1182 DestroyWindow(item);
1184 if (!strcmp(buffer, "Session"))
1185 create_controls(hwnd, dlgtype, sessionpanelstart);
1186 if (!strcmp(buffer, "Logging"))
1187 create_controls(hwnd, dlgtype, loggingpanelstart);
1188 if (!strcmp(buffer, "Keyboard"))
1189 create_controls(hwnd, dlgtype, keyboardpanelstart);
1190 if (!strcmp(buffer, "Terminal"))
1191 create_controls(hwnd, dlgtype, terminalpanelstart);
1192 if (!strcmp(buffer, "Window"))
1193 create_controls(hwnd, dlgtype, windowpanelstart);
1194 if (!strcmp(buffer, "Appearance"))
1195 create_controls(hwnd, dlgtype, appearancepanelstart);
1196 if (!strcmp(buffer, "Tunnels"))
1197 create_controls(hwnd, dlgtype, tunnelspanelstart);
1198 if (!strcmp(buffer, "Connection"))
1199 create_controls(hwnd, dlgtype, connectionpanelstart);
1200 if (!strcmp(buffer, "Telnet"))
1201 create_controls(hwnd, dlgtype, telnetpanelstart);
1202 if (!strcmp(buffer, "Rlogin"))
1203 create_controls(hwnd, dlgtype, rloginpanelstart);
1204 if (!strcmp(buffer, "SSH"))
1205 create_controls(hwnd, dlgtype, sshpanelstart);
1206 if (!strcmp(buffer, "Selection"))
1207 create_controls(hwnd, dlgtype, selectionpanelstart);
1208 if (!strcmp(buffer, "Colours"))
1209 create_controls(hwnd, dlgtype, colourspanelstart);
1210 if (!strcmp(buffer, "Translation"))
1211 create_controls(hwnd, dlgtype, translationpanelstart);
1213 init_dlg_ctrls(hwnd);
1215 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1221 * Only process WM_COMMAND once the dialog is fully formed.
1223 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1226 EndDialog (hwnd, 1);
1231 EndDialog (hwnd, 0);
1233 case IDC_PROTTELNET:
1234 case IDC_PROTRLOGIN:
1237 if (HIWORD(wParam) == BN_CLICKED ||
1238 HIWORD(wParam) == BN_DOUBLECLICKED) {
1239 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1240 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1241 int k = IsDlgButtonChecked (hwnd, IDC_PROTRLOGIN);
1242 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN : PROT_RAW ;
1243 if ((cfg.protocol == PROT_SSH && cfg.port != 22) ||
1244 (cfg.protocol == PROT_TELNET && cfg.port != 23) ||
1245 (cfg.protocol == PROT_RLOGIN && cfg.port != 513)) {
1246 cfg.port = i ? 22 : j ? 23 : 513;
1247 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1252 if (HIWORD(wParam) == EN_CHANGE)
1253 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1254 sizeof(cfg.host)-1);
1257 if (HIWORD(wParam) == EN_CHANGE) {
1258 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1259 if (isdigit(portname[0]))
1260 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1262 service = getservbyname(portname, NULL);
1263 if (service) cfg.port = ntohs(service->s_port);
1269 if (HIWORD(wParam) == EN_CHANGE) {
1270 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1272 GetDlgItemText (hwnd, IDC_SESSEDIT,
1273 savedsession, sizeof(savedsession)-1);
1274 savedsession[sizeof(savedsession)-1] = '\0';
1278 if (HIWORD(wParam) == BN_CLICKED ||
1279 HIWORD(wParam) == BN_DOUBLECLICKED) {
1284 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1286 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1287 LB_GETCURSEL, 0, 0);
1292 strcpy (str, sessions[n]);
1294 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1295 get_sesslist (FALSE);
1296 get_sesslist (TRUE);
1297 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1299 for (i = 0; i < nsessions; i++)
1300 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1301 0, (LPARAM) (sessions[i]));
1302 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1308 if (LOWORD(wParam) == IDC_SESSLOAD &&
1309 HIWORD(wParam) != BN_CLICKED &&
1310 HIWORD(wParam) != BN_DOUBLECLICKED)
1312 if (LOWORD(wParam) == IDC_SESSLIST &&
1313 HIWORD(wParam) != LBN_DBLCLK)
1316 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1317 LB_GETCURSEL, 0, 0);
1323 isdef = !strcmp(sessions[n], "Default Settings");
1324 load_settings (sessions[n], !isdef, &cfg);
1325 init_dlg_ctrls(hwnd);
1327 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1329 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1331 if (LOWORD(wParam) == IDC_SESSLIST) {
1333 * A double-click on a saved session should
1334 * actually start the session, not just load it.
1335 * Unless it's Default Settings or some other
1336 * host-less set of saved settings.
1345 if (HIWORD(wParam) == BN_CLICKED ||
1346 HIWORD(wParam) == BN_DOUBLECLICKED) {
1347 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1348 LB_GETCURSEL, 0, 0);
1349 if (n == LB_ERR || n == 0) {
1353 del_settings(sessions[n]);
1354 get_sesslist (FALSE);
1355 get_sesslist (TRUE);
1356 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1358 for (i = 0; i < nsessions; i++)
1359 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1360 0, (LPARAM) (sessions[i]));
1361 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1365 if (HIWORD(wParam) == EN_CHANGE)
1366 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1370 if (HIWORD(wParam) == BN_CLICKED ||
1371 HIWORD(wParam) == BN_DOUBLECLICKED)
1372 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1376 if (HIWORD(wParam) == BN_CLICKED ||
1377 HIWORD(wParam) == BN_DOUBLECLICKED)
1378 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1381 if (HIWORD(wParam) == BN_CLICKED ||
1382 HIWORD(wParam) == BN_DOUBLECLICKED)
1386 if (HIWORD(wParam) == BN_CLICKED ||
1387 HIWORD(wParam) == BN_DOUBLECLICKED)
1392 if (HIWORD(wParam) == BN_CLICKED ||
1393 HIWORD(wParam) == BN_DOUBLECLICKED)
1394 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1398 if (HIWORD(wParam) == BN_CLICKED ||
1399 HIWORD(wParam) == BN_DOUBLECLICKED) {
1400 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1401 cfg.nethack_keypad = FALSE;
1405 if (HIWORD(wParam) == BN_CLICKED ||
1406 HIWORD(wParam) == BN_DOUBLECLICKED) {
1407 cfg.app_keypad = FALSE;
1408 cfg.nethack_keypad = TRUE;
1413 if (HIWORD(wParam) == BN_CLICKED ||
1414 HIWORD(wParam) == BN_DOUBLECLICKED)
1415 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1418 if (HIWORD(wParam) == BN_CLICKED ||
1419 HIWORD(wParam) == BN_DOUBLECLICKED)
1420 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1423 if (HIWORD(wParam) == BN_CLICKED ||
1424 HIWORD(wParam) == BN_DOUBLECLICKED)
1425 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1428 if (HIWORD(wParam) == BN_CLICKED ||
1429 HIWORD(wParam) == BN_DOUBLECLICKED)
1430 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1433 if (HIWORD(wParam) == BN_CLICKED ||
1434 HIWORD(wParam) == BN_DOUBLECLICKED)
1435 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1438 if (HIWORD(wParam) == BN_CLICKED ||
1439 HIWORD(wParam) == BN_DOUBLECLICKED)
1440 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1442 case IDC_ECHOBACKEND:
1445 if (HIWORD(wParam) == BN_CLICKED ||
1446 HIWORD(wParam) == BN_DOUBLECLICKED) {
1447 if (LOWORD(wParam)==IDC_ECHOBACKEND) cfg.localecho=LD_BACKEND;
1448 if (LOWORD(wParam)==IDC_ECHOYES) cfg.localecho=LD_YES;
1449 if (LOWORD(wParam)==IDC_ECHONO) cfg.localecho=LD_NO;
1452 case IDC_EDITBACKEND:
1455 if (HIWORD(wParam) == BN_CLICKED ||
1456 HIWORD(wParam) == BN_DOUBLECLICKED) {
1457 if (LOWORD(wParam)==IDC_EDITBACKEND) cfg.localedit=LD_BACKEND;
1458 if (LOWORD(wParam)==IDC_EDITYES) cfg.localedit=LD_YES;
1459 if (LOWORD(wParam)==IDC_EDITNO) cfg.localedit=LD_NO;
1462 case IDC_ALWAYSONTOP:
1463 if (HIWORD(wParam) == BN_CLICKED ||
1464 HIWORD(wParam) == BN_DOUBLECLICKED)
1465 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1468 if (HIWORD(wParam) == BN_CLICKED ||
1469 HIWORD(wParam) == BN_DOUBLECLICKED)
1470 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1472 case IDC_SCROLLDISP:
1473 if (HIWORD(wParam) == BN_CLICKED ||
1474 HIWORD(wParam) == BN_DOUBLECLICKED)
1475 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1477 case IDC_COMPOSEKEY:
1478 if (HIWORD(wParam) == BN_CLICKED ||
1479 HIWORD(wParam) == BN_DOUBLECLICKED)
1480 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1483 if (HIWORD(wParam) == BN_CLICKED ||
1484 HIWORD(wParam) == BN_DOUBLECLICKED)
1485 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1488 if (HIWORD(wParam) == BN_CLICKED ||
1489 HIWORD(wParam) == BN_DOUBLECLICKED)
1490 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1493 if (HIWORD(wParam) == BN_CLICKED ||
1494 HIWORD(wParam) == BN_DOUBLECLICKED)
1495 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1498 if (HIWORD(wParam) == EN_CHANGE)
1499 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1502 if (HIWORD(wParam) == EN_CHANGE)
1503 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1506 if (HIWORD(wParam) == EN_CHANGE)
1507 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1509 case IDC_CHOOSEFONT:
1510 lf.lfHeight = cfg.fontheight;
1511 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1512 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1513 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1514 lf.lfCharSet = cfg.fontcharset;
1515 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1516 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1517 lf.lfQuality = DEFAULT_QUALITY;
1518 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1519 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1520 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1522 cf.lStructSize = sizeof(cf);
1523 cf.hwndOwner = hwnd;
1525 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1526 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1528 if (ChooseFont (&cf)) {
1529 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1530 cfg.font[sizeof(cfg.font)-1] = '\0';
1531 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1532 cfg.fontcharset = lf.lfCharSet;
1533 cfg.fontheight = lf.lfHeight;
1534 fmtfont (fontstatic);
1535 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1539 if (HIWORD(wParam) == BN_CLICKED ||
1540 HIWORD(wParam) == BN_DOUBLECLICKED)
1541 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1544 if (HIWORD(wParam) == BN_CLICKED ||
1545 HIWORD(wParam) == BN_DOUBLECLICKED)
1546 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1549 if (HIWORD(wParam) == BN_CLICKED ||
1550 HIWORD(wParam) == BN_DOUBLECLICKED)
1551 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1554 if (HIWORD(wParam) == BN_CLICKED ||
1555 HIWORD(wParam) == BN_DOUBLECLICKED)
1556 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1559 if (HIWORD(wParam) == BN_CLICKED ||
1560 HIWORD(wParam) == BN_DOUBLECLICKED)
1561 cfg.hide_mouseptr = IsDlgButtonChecked (hwnd, IDC_HIDEMOUSE);
1564 if (HIWORD(wParam) == BN_CLICKED ||
1565 HIWORD(wParam) == BN_DOUBLECLICKED)
1566 cfg.cursor_type = 0;
1569 if (HIWORD(wParam) == BN_CLICKED ||
1570 HIWORD(wParam) == BN_DOUBLECLICKED)
1571 cfg.cursor_type = 1;
1574 if (HIWORD(wParam) == BN_CLICKED ||
1575 HIWORD(wParam) == BN_DOUBLECLICKED)
1576 cfg.cursor_type = 2;
1579 if (HIWORD(wParam) == BN_CLICKED ||
1580 HIWORD(wParam) == BN_DOUBLECLICKED)
1581 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1584 if (HIWORD(wParam) == BN_CLICKED ||
1585 HIWORD(wParam) == BN_DOUBLECLICKED)
1586 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1589 if (HIWORD(wParam) == BN_CLICKED ||
1590 HIWORD(wParam) == BN_DOUBLECLICKED)
1591 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1594 if (HIWORD(wParam) == EN_CHANGE)
1595 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1596 sizeof(cfg.wintitle)-1);
1599 if (HIWORD(wParam) == BN_CLICKED ||
1600 HIWORD(wParam) == BN_DOUBLECLICKED)
1601 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
1604 if (HIWORD(wParam) == BN_CLICKED ||
1605 HIWORD(wParam) == BN_DOUBLECLICKED)
1606 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1609 if (HIWORD(wParam) == EN_CHANGE)
1610 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1611 sizeof(cfg.termtype)-1);
1614 if (HIWORD(wParam) == EN_CHANGE)
1615 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1616 sizeof(cfg.logfilename)-1);
1619 memset(&of, 0, sizeof(of));
1620 #ifdef OPENFILENAME_SIZE_VERSION_400
1621 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1623 of.lStructSize = sizeof(of);
1625 of.hwndOwner = hwnd;
1626 of.lpstrFilter = "All Files\0*\0\0\0";
1627 of.lpstrCustomFilter = NULL;
1628 of.nFilterIndex = 1;
1629 of.lpstrFile = filename; strcpy(filename, cfg.logfilename);
1630 of.nMaxFile = sizeof(filename);
1631 of.lpstrFileTitle = NULL;
1632 of.lpstrInitialDir = NULL;
1633 of.lpstrTitle = "Select session log file";
1635 if (GetSaveFileName(&of)) {
1636 strcpy(cfg.logfilename, filename);
1637 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
1641 case IDC_LSTATASCII:
1643 if (HIWORD(wParam) == BN_CLICKED ||
1644 HIWORD(wParam) == BN_DOUBLECLICKED) {
1645 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1646 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1647 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1652 if (HIWORD(wParam) == EN_CHANGE)
1653 GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed,
1654 sizeof(cfg.termspeed)-1);
1657 if (HIWORD(wParam) == EN_CHANGE)
1658 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1659 sizeof(cfg.username)-1);
1661 case IDC_RLLUSEREDIT:
1662 if (HIWORD(wParam) == EN_CHANGE)
1663 GetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername,
1664 sizeof(cfg.localusername)-1);
1668 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1671 if (HIWORD(wParam) == BN_CLICKED ||
1672 HIWORD(wParam) == BN_DOUBLECLICKED) {
1673 char str[sizeof(cfg.environmt)];
1675 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1680 p = str + strlen(str);
1682 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1692 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1694 p[strlen(str)+1] = '\0';
1695 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1697 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1698 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1700 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1701 MB_OK | MB_ICONERROR);
1706 if (HIWORD(wParam) != BN_CLICKED &&
1707 HIWORD(wParam) != BN_DOUBLECLICKED)
1709 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1715 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1740 if (HIWORD(wParam) == BN_CLICKED ||
1741 HIWORD(wParam) == BN_DOUBLECLICKED)
1742 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1745 if (HIWORD(wParam) == BN_CLICKED ||
1746 HIWORD(wParam) == BN_DOUBLECLICKED)
1747 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1750 if (HIWORD(wParam) == BN_CLICKED ||
1751 HIWORD(wParam) == BN_DOUBLECLICKED)
1752 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1755 if (HIWORD(wParam) == BN_CLICKED ||
1756 HIWORD(wParam) == BN_DOUBLECLICKED)
1757 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1759 case IDC_CIPHER3DES:
1760 case IDC_CIPHERBLOWF:
1762 if (HIWORD(wParam) == BN_CLICKED ||
1763 HIWORD(wParam) == BN_DOUBLECLICKED) {
1764 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1765 cfg.cipher = CIPHER_3DES;
1766 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1767 cfg.cipher = CIPHER_BLOWFISH;
1768 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1769 cfg.cipher = CIPHER_DES;
1774 if (HIWORD(wParam) == BN_CLICKED ||
1775 HIWORD(wParam) == BN_DOUBLECLICKED) {
1776 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1778 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1783 if (HIWORD(wParam) == BN_CLICKED ||
1784 HIWORD(wParam) == BN_DOUBLECLICKED)
1785 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1788 if (HIWORD(wParam) == EN_CHANGE)
1789 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1790 sizeof(cfg.keyfile)-1);
1793 if (HIWORD(wParam) == EN_CHANGE)
1794 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1795 sizeof(cfg.remote_cmd)-1);
1798 memset(&of, 0, sizeof(of));
1799 #ifdef OPENFILENAME_SIZE_VERSION_400
1800 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1802 of.lStructSize = sizeof(of);
1804 of.hwndOwner = hwnd;
1805 of.lpstrFilter = "All Files\0*\0\0\0";
1806 of.lpstrCustomFilter = NULL;
1807 of.nFilterIndex = 1;
1808 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1809 of.nMaxFile = sizeof(filename);
1810 of.lpstrFileTitle = NULL;
1811 of.lpstrInitialDir = NULL;
1812 of.lpstrTitle = "Select Public Key File";
1814 if (GetOpenFileName(&of)) {
1815 strcpy(cfg.keyfile, filename);
1816 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1821 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1827 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1832 for (i=0; i<256; i++)
1833 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1836 cfg.wordness[i] = n;
1837 SendDlgItemMessage (hwnd, IDC_CCLIST,
1838 LB_DELETESTRING, i, 0);
1839 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1840 (i>=0x21 && i != 0x7F) ? i : ' ',
1842 SendDlgItemMessage (hwnd, IDC_CCLIST,
1849 case IDC_BOLDCOLOUR:
1850 if (HIWORD(wParam) == BN_CLICKED ||
1851 HIWORD(wParam) == BN_DOUBLECLICKED) {
1853 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1854 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1855 if (n != 12+10*cfg.bold_colour) {
1857 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1858 LB_DELETESTRING, i, 0);
1859 for (i=0; i<22; i++)
1860 if (cfg.bold_colour || permcolour[i])
1861 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1863 (LPARAM) colours[i]);
1868 if (HIWORD(wParam) == BN_CLICKED ||
1869 HIWORD(wParam) == BN_DOUBLECLICKED)
1870 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1872 case IDC_COLOURLIST:
1873 if (HIWORD(wParam) == LBN_DBLCLK ||
1874 HIWORD(wParam) == LBN_SELCHANGE) {
1875 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1877 if (!cfg.bold_colour)
1878 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1879 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1880 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1881 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1885 if (HIWORD(wParam) == BN_CLICKED ||
1886 HIWORD(wParam) == BN_DOUBLECLICKED) {
1887 static CHOOSECOLOR cc;
1888 static DWORD custom[16] = {0}; /* zero initialisers */
1889 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1891 if (!cfg.bold_colour)
1892 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1893 cc.lStructSize = sizeof(cc);
1894 cc.hwndOwner = hwnd;
1895 cc.hInstance = (HWND)hinst;
1896 cc.lpCustColors = custom;
1897 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1899 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1900 if (ChooseColor(&cc)) {
1902 (unsigned char) (cc.rgbResult & 0xFF);
1904 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1906 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1907 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1909 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1911 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1917 case IDC_KOI8WIN1251:
1918 case IDC_88592WIN1250:
1919 case IDC_88592CP852:
1920 cfg.xlat_enablekoiwin =
1921 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1922 cfg.xlat_88592w1250 =
1923 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1924 cfg.xlat_88592cp852 =
1925 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1927 case IDC_CAPSLOCKCYR:
1928 if (HIWORD(wParam) == BN_CLICKED ||
1929 HIWORD(wParam) == BN_DOUBLECLICKED) {
1930 cfg.xlat_capslockcyr =
1931 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1934 case IDC_VTXWINDOWS:
1939 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1940 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1941 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1944 case IDC_X11_FORWARD:
1945 if (HIWORD(wParam) == BN_CLICKED ||
1946 HIWORD(wParam) == BN_DOUBLECLICKED)
1947 cfg.x11_forward = IsDlgButtonChecked (hwnd, IDC_X11_FORWARD);
1949 case IDC_X11_DISPLAY:
1950 if (HIWORD(wParam) == EN_CHANGE)
1951 GetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display,
1952 sizeof(cfg.x11_display)-1);
1957 EndDialog (hwnd, 0);
1960 /* Grrr Explorer will maximize Dialogs! */
1962 if (wParam == SIZE_MAXIMIZED)
1969 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1970 WPARAM wParam, LPARAM lParam) {
1971 static HWND page = NULL;
1973 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1975 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
1976 EnableWindow(hwnd, 0);
1977 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1978 GetParent(hwnd), AboutProc);
1979 EnableWindow(hwnd, 1);
1980 SetActiveWindow(hwnd);
1982 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
1985 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1986 WPARAM wParam, LPARAM lParam) {
1988 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
1991 void defuse_showwindow(void) {
1993 * Work around the fact that the app's first call to ShowWindow
1994 * will ignore the default in favour of the shell-provided
1999 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2001 ShowWindow(hwnd, SW_HIDE);
2002 DestroyWindow(hwnd);
2006 int do_config (void) {
2010 savedsession[0] = '\0';
2011 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2012 get_sesslist(FALSE);
2017 int do_reconfig (HWND hwnd) {
2021 backup_cfg = cfg; /* structure copy */
2022 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2024 cfg = backup_cfg; /* structure copy */
2029 void logevent (char *string) {
2030 if (nevents >= negsize) {
2032 events = srealloc (events, negsize * sizeof(*events));
2034 events[nevents] = smalloc(1+strlen(string));
2035 strcpy (events[nevents], string);
2039 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
2041 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2042 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
2046 void showeventlog (HWND hwnd) {
2048 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2050 ShowWindow (logbox, SW_SHOWNORMAL);
2052 SetActiveWindow(logbox);
2055 void showabout (HWND hwnd) {
2056 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),hwnd, AboutProc);
2059 void verify_ssh_host_key(char *host, int port, char *keytype,
2060 char *keystr, char *fingerprint) {
2063 static const char absentmsg[] =
2064 "The server's host key is not cached in the registry. You\n"
2065 "have no guarantee that the server is the computer you\n"
2067 "The server's key fingerprint is:\n"
2069 "If you trust this host, hit Yes to add the key to\n"
2070 "PuTTY's cache and carry on connecting.\n"
2071 "If you do not trust this host, hit No to abandon the\n"
2074 static const char wrongmsg[] =
2075 "WARNING - POTENTIAL SECURITY BREACH!\n"
2077 "The server's host key does not match the one PuTTY has\n"
2078 "cached in the registry. This means that either the\n"
2079 "server administrator has changed the host key, or you\n"
2080 "have actually connected to another computer pretending\n"
2081 "to be the server.\n"
2082 "The new key fingerprint is:\n"
2084 "If you were expecting this change and trust the new key,\n"
2085 "hit Yes to update PuTTY's cache and continue connecting.\n"
2086 "If you want to carry on connecting but without updating\n"
2087 "the cache, hit No.\n"
2088 "If you want to abandon the connection completely, hit\n"
2089 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2092 static const char mbtitle[] = "PuTTY Security Alert";
2095 char message[160+ /* sensible fingerprint max size */
2096 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2097 sizeof(absentmsg) : sizeof(wrongmsg))];
2100 * Verify the key against the registry.
2102 ret = verify_host_key(host, port, keytype, keystr);
2104 if (ret == 0) /* success - key matched OK */
2106 if (ret == 2) { /* key was different */
2108 sprintf(message, wrongmsg, fingerprint);
2109 mbret = MessageBox(NULL, message, mbtitle,
2110 MB_ICONWARNING | MB_YESNOCANCEL);
2112 store_host_key(host, port, keytype, keystr);
2113 if (mbret == IDCANCEL)
2116 if (ret == 1) { /* key was absent */
2118 sprintf(message, absentmsg, fingerprint);
2119 mbret = MessageBox(NULL, message, mbtitle,
2120 MB_ICONWARNING | MB_YESNO);
2123 store_host_key(host, port, keytype, keystr);
2128 * Ask whether to wipe a session log file before writing to it.
2129 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2131 int askappend(char *filename) {
2132 static const char mbtitle[] = "PuTTY Log to File";
2133 static const char msgtemplate[] =
2134 "The session log file \"%.*s\" already exists.\n"
2135 "You can overwrite it with a new session log,\n"
2136 "append your session log to the end of it,\n"
2137 "or disable session logging for this session.\n"
2138 "Hit Yes to wipe the file, No to append to it,\n"
2139 "or Cancel to disable logging.";
2140 char message[sizeof(msgtemplate) + FILENAME_MAX];
2142 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2144 mbret = MessageBox(NULL, message, mbtitle,
2145 MB_ICONQUESTION | MB_YESNOCANCEL);
2148 else if (mbret == IDNO)