15 static char **events = NULL;
16 static int nevents = 0, negsize = 0;
20 void force_normal(HWND hwnd)
22 static int recurse = 0;
29 wp.length = sizeof(wp);
30 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED)
32 wp.showCmd = SW_SHOWNORMAL;
33 SetWindowPlacement(hwnd, &wp);
38 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
41 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
46 static int CALLBACK LogProc (HWND hwnd, UINT msg,
47 WPARAM wParam, LPARAM lParam) {
53 static int tabs[4] = {78, 108};
54 SendDlgItemMessage (hwnd, IDN_LIST, LB_SETTABSTOPS, 2,
57 for (i=0; i<nevents; i++)
58 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
59 0, (LPARAM)events[i]);
62 switch (LOWORD(wParam)) {
66 SetActiveWindow(GetParent(hwnd));
70 if (HIWORD(wParam) == BN_CLICKED ||
71 HIWORD(wParam) == BN_DOUBLECLICKED) {
74 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
75 LB_GETSELCOUNT, 0, 0);
76 if (selcount == 0) { /* don't even try to copy zero items */
81 selitems = smalloc(selcount * sizeof(int));
83 int count = SendDlgItemMessage(hwnd, IDN_LIST,
85 selcount, (LPARAM)selitems);
89 static unsigned char sel_nl[] = SEL_NL;
91 if (count == 0) { /* can't copy zero stuff */
97 for (i = 0; i < count; i++)
98 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
100 clipdata = smalloc(size);
103 for (i = 0; i < count; i++) {
104 char *q = events[selitems[i]];
105 int qlen = strlen(q);
108 memcpy(p, sel_nl, sizeof(sel_nl));
111 write_clip(clipdata, size, TRUE);
116 for (i = 0; i < nevents; i++)
117 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
126 SetActiveWindow(GetParent(hwnd));
127 DestroyWindow (hwnd);
133 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
134 WPARAM wParam, LPARAM lParam) {
139 switch (LOWORD(wParam)) {
152 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
153 WPARAM wParam, LPARAM lParam) {
156 SetDlgItemText (hwnd, IDA_VERSION, ver);
159 switch (LOWORD(wParam)) {
162 EndDialog(hwnd, TRUE);
165 EnableWindow(hwnd, 0);
166 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
168 EnableWindow(hwnd, 1);
169 SetActiveWindow(hwnd);
174 EndDialog(hwnd, TRUE);
181 * Null dialog procedure.
183 static int CALLBACK NullDlgProc (HWND hwnd, UINT msg,
184 WPARAM wParam, LPARAM lParam) {
188 static char savedsession[2048];
190 enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
299 appearancepanelstart,
300 IDC_TITLE_APPEARANCE,
318 connectionpanelstart,
319 IDC_TITLE_CONNECTION,
415 translationpanelstart,
416 IDC_TITLE_TRANSLATION,
417 IDC_BOX_TRANSLATION1,
418 IDC_BOX_TRANSLATION2,
419 IDC_BOX_TRANSLATION3,
444 static const char *const colours[] = {
445 "Default Foreground", "Default Bold Foreground",
446 "Default Background", "Default Bold Background",
447 "Cursor Text", "Cursor Colour",
448 "ANSI Black", "ANSI Black Bold",
449 "ANSI Red", "ANSI Red Bold",
450 "ANSI Green", "ANSI Green Bold",
451 "ANSI Yellow", "ANSI Yellow Bold",
452 "ANSI Blue", "ANSI Blue Bold",
453 "ANSI Magenta", "ANSI Magenta Bold",
454 "ANSI Cyan", "ANSI Cyan Bold",
455 "ANSI White", "ANSI White Bold"
457 static const int permcolour[] = {
458 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
459 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
460 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
463 static void fmtfont (char *buf) {
464 sprintf (buf, "Font: %s, ", cfg.font);
466 strcat(buf, "bold, ");
467 if (cfg.fontheight == 0)
468 strcat (buf, "default height");
470 sprintf (buf+strlen(buf), "%d-%s",
471 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
472 (cfg.fontheight < 0 ? "pixel" : "point"));
475 static void init_dlg_ctrls(HWND hwnd) {
477 char fontstatic[256];
479 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
480 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
483 n = SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
485 SendDlgItemMessage (hwnd, IDC_SESSLIST,
486 LB_DELETESTRING, i, 0);
487 for (i = 0; i < nsessions; i++)
488 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
489 0, (LPARAM) (sessions[i]));
491 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
492 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
493 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
494 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET :
495 cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW );
496 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
498 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
499 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
500 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
501 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
502 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
503 cfg.funky_type == 0 ? IDC_FUNCTILDE :
504 cfg.funky_type == 1 ? IDC_FUNCLINUX :
505 cfg.funky_type == 2 ? IDC_FUNCXTERM :
506 cfg.funky_type == 3 ? IDC_FUNCVT400 :
508 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
509 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
510 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
511 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
512 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
513 cfg.nethack_keypad ? IDC_KPNH :
514 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
515 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
516 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
517 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
518 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
519 CheckRadioButton (hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
520 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND:
521 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
522 CheckRadioButton (hwnd, IDC_EDITBACKEND, IDC_EDITNO,
523 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND:
524 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
525 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
526 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
527 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
529 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
530 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
531 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
532 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
533 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
534 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
535 fmtfont (fontstatic);
536 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
537 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
538 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
539 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
541 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
542 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
543 CheckDlgButton (hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
544 CheckRadioButton (hwnd, IDC_CURBLOCK, IDC_CURVERT,
545 cfg.cursor_type==0 ? IDC_CURBLOCK :
546 cfg.cursor_type==1 ? IDC_CURUNDER : IDC_CURVERT);
547 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
548 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
549 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
550 CheckRadioButton (hwnd, IDC_COEALWAYS, IDC_COENORMAL,
551 cfg.close_on_exit==COE_NORMAL ? IDC_COENORMAL :
552 cfg.close_on_exit==COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
553 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
555 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
556 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
557 SetDlgItemText (hwnd, IDC_R_TSEDIT, cfg.termspeed);
558 SetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername);
559 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
560 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
561 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
562 cfg.logtype == 0 ? IDC_LSTATOFF :
563 cfg.logtype == 1 ? IDC_LSTATASCII :
566 char *p = cfg.environmt;
568 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
573 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
574 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
576 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
577 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
578 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
579 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
580 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
581 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
582 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERAES,
583 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
584 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
585 cfg.cipher == CIPHER_AES ? IDC_CIPHERAES :
587 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
588 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
589 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
590 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
591 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
593 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
594 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
596 static int tabs[4] = {25, 61, 96, 128};
597 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
600 for (i=0; i<256; i++) {
602 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
603 (i>=0x21 && i != 0x7F) ? i : ' ',
605 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
609 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
610 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
613 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
615 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
616 LB_DELETESTRING, i, 0);
618 if (cfg.bold_colour || permcolour[i])
619 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
620 (LPARAM) colours[i]);
622 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
623 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
624 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
625 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
627 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
628 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
629 cfg.xlat_88592cp852 ? IDC_88592CP852 :
630 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
632 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
633 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
634 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
635 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
636 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
639 CheckDlgButton (hwnd, IDC_X11_FORWARD, cfg.x11_forward);
640 SetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display);
643 struct treeview_faff {
648 static HTREEITEM treeview_insert(struct treeview_faff *faff,
649 int level, char *text) {
653 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
654 ins.hInsertAfter = faff->lastat[level];
655 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
656 #define INSITEM DUMMYUNIONNAME.item
660 ins.INSITEM.mask = TVIF_TEXT;
661 ins.INSITEM.pszText = text;
662 newitem = TreeView_InsertItem(faff->treeview, &ins);
664 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
665 faff->lastat[level] = newitem;
666 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
671 * Create the panelfuls of controls in the configuration box.
673 static void create_controls(HWND hwnd, int dlgtype, int panel) {
674 if (panel == sessionpanelstart) {
675 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
677 ctlposinit(&cp, hwnd, 80, 3, 13);
678 bartitle(&cp, "Basic options for your PuTTY session",
681 beginbox(&cp, "Specify your connection by host name",
684 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
685 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
686 if (backends[3].backend == NULL) {
687 /* this is PuTTYtel, so only three protocols available */
688 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
690 "&Telnet", IDC_PROTTELNET,
691 "Rlog&in", IDC_PROTRLOGIN, NULL);
693 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
695 "&Telnet", IDC_PROTTELNET,
696 "Rlog&in", IDC_PROTRLOGIN,
705 beginbox(&cp, "Load, save or delete a stored session",
707 sesssaver(&cp, "Sav&ed Sessions",
708 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
709 "&Load", IDC_SESSLOAD,
710 "&Save", IDC_SESSSAVE,
711 "&Delete", IDC_SESSDEL, NULL);
714 beginbox(&cp, NULL, IDC_BOX_SESSION3);
715 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
716 "Always", IDC_COEALWAYS,
717 "Never", IDC_COENEVER,
718 "Only on clean exit", IDC_COENORMAL, NULL);
722 if (panel == loggingpanelstart) {
723 /* The Logging panel. Accelerators used: [acgo] tplfw */
725 ctlposinit(&cp, hwnd, 80, 3, 13);
726 bartitle(&cp, "Options controlling session logging",
728 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
730 "Session logging:", IDC_LSTATSTATIC,
731 "Logging &turned off completely", IDC_LSTATOFF,
732 "Log &printable output only", IDC_LSTATASCII,
733 "&Log all session output", IDC_LSTATRAW, NULL);
734 editbutton(&cp, "Log &file name:",
735 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
740 if (panel == terminalpanelstart) {
741 /* The Terminal panel. Accelerators used: [acgo] wdlben ht */
743 ctlposinit(&cp, hwnd, 80, 3, 13);
744 bartitle(&cp, "Options controlling the terminal emulation",
746 beginbox(&cp, "Set various terminal options",
748 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
749 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
750 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
751 checkbox(&cp, "&Beep enabled", IDC_BEEP);
752 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
753 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
756 beginbox(&cp, "Line discipline options",
758 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
759 "Auto", IDC_ECHOBACKEND,
760 "Force on", IDC_ECHOYES,
761 "Force off", IDC_ECHONO, NULL);
762 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
763 "Auto", IDC_EDITBACKEND,
764 "Force on", IDC_EDITYES,
765 "Force off", IDC_EDITNO, NULL);
769 if (panel == keyboardpanelstart) {
770 /* The Keyboard panel. Accelerators used: [acgo] h?sr~lxv unpymie t */
772 ctlposinit(&cp, hwnd, 80, 3, 13);
773 bartitle(&cp, "Options controlling the effects of keys",
775 beginbox(&cp, "Change the sequences sent by:",
777 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
778 "Control-&H", IDC_DEL008,
779 "Control-&? (127)", IDC_DEL127, NULL);
780 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
781 "&Standard", IDC_HOMETILDE,
782 "&rxvt", IDC_HOMERXVT, NULL);
783 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
784 "ESC[n&~", IDC_FUNCTILDE,
785 "&Linux", IDC_FUNCLINUX,
786 "&Xterm R6", IDC_FUNCXTERM,
787 "&VT400", IDC_FUNCVT400, NULL);
789 beginbox(&cp, "Application keypad settings:",
792 "Application c&ursor keys totally disabled",
794 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
795 "&Normal", IDC_CURNORMAL,
796 "A&pplication", IDC_CURAPPLIC, NULL);
798 "Application ke&ypad keys totally disabled",
800 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
801 "Nor&mal", IDC_KPNORMAL,
802 "Appl&ication", IDC_KPAPPLIC,
803 "N&etHack", IDC_KPNH, NULL);
805 beginbox(&cp, "Enable extra keyboard features:",
807 checkbox(&cp, "Application and AltGr ac&t as Compose key",
812 if (panel == windowpanelstart) {
813 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
815 ctlposinit(&cp, hwnd, 80, 3, 13);
816 bartitle(&cp, "Options controlling PuTTY's window",
818 beginbox(&cp, "Set the size of the window",
821 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
822 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
824 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
826 beginbox(&cp, "Control the scrollback in the window",
828 staticedit(&cp, "Lines of &scrollback",
829 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
830 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
831 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
832 checkbox(&cp, "Reset scrollback on dis&play activity",
835 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
836 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
837 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
838 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
839 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
840 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
844 if (panel == appearancepanelstart) {
845 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p */
847 ctlposinit(&cp, hwnd, 80, 3, 13);
848 bartitle(&cp, "Options controlling PuTTY's appearance",
849 IDC_TITLE_APPEARANCE);
850 beginbox(&cp, "Adjust the use of the cursor",
851 IDC_BOX_APPEARANCE1);
852 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
853 "B&lock", IDC_CURBLOCK,
854 "&Underline", IDC_CURUNDER,
855 "&Vertical line", IDC_CURVERT,
857 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
859 beginbox(&cp, "Set the font used in the terminal window",
860 IDC_BOX_APPEARANCE2);
861 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
863 beginbox(&cp, "Adjust the use of the window title",
864 IDC_BOX_APPEARANCE3);
866 "Window &title:", IDC_WINTITLE,
867 IDC_WINEDIT, 100, NULL);
868 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
870 beginbox(&cp, "Adjust the use of the mouse pointer",
871 IDC_BOX_APPEARANCE4);
872 checkbox(&cp, "Hide mouse &pointer when typing in window",
877 if (panel == translationpanelstart) {
878 /* The Translation panel. Accelerators used: [acgo] xbep t s */
880 ctlposinit(&cp, hwnd, 80, 3, 13);
881 bartitle(&cp, "Options controlling character set translation",
882 IDC_TITLE_TRANSLATION);
883 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
884 IDC_BOX_TRANSLATION1);
886 "Handling of line drawing characters:", IDC_VTSTATIC,
887 "Font has &XWindows encoding", IDC_VTXWINDOWS,
888 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
889 "Use font in O&EM mode only", IDC_VTOEMONLY,
890 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
891 IDC_VTPOORMAN, NULL);
893 beginbox(&cp, "Enable character set translation on received data",
894 IDC_BOX_TRANSLATION2);
896 "Character set &translation:", IDC_XLATSTATIC,
898 "KOI8 / Win-1251", IDC_KOI8WIN1251,
899 "ISO-8859-2 / Win-1250", IDC_88592WIN1250,
900 "ISO-8859-2 / CP852", IDC_88592CP852, NULL);
902 beginbox(&cp, "Enable character set translation on input data",
903 IDC_BOX_TRANSLATION3);
904 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
909 if (panel == selectionpanelstart) {
910 /* The Selection panel. Accelerators used: [acgo] wx hst */
912 ctlposinit(&cp, hwnd, 80, 3, 13);
913 bartitle(&cp, "Options controlling copy and paste",
914 IDC_TITLE_SELECTION);
915 beginbox(&cp, "Control which mouse button does which thing",
917 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
918 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
919 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
922 beginbox(&cp, "Control the select-one-word-at-a-time mode",
924 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
925 "&Set", IDC_CCSET, IDC_CCEDIT,
926 "&to class", IDC_CCSTATIC2);
930 if (panel == colourspanelstart) {
931 /* The Colours panel. Accelerators used: [acgo] blum */
933 ctlposinit(&cp, hwnd, 80, 3, 13);
934 bartitle(&cp, "Options controlling use of colours",
936 beginbox(&cp, "General options for colour usage",
938 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
939 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
941 beginbox(&cp, "Adjust the precise colours PuTTY displays",
943 colouredit(&cp, "Select a colo&ur and then click to modify it:",
944 IDC_COLOURSTATIC, IDC_COLOURLIST,
945 "&Modify...", IDC_CHANGE,
946 "Red:", IDC_RSTATIC, IDC_RVALUE,
947 "Green:", IDC_GSTATIC, IDC_GVALUE,
948 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
952 if (panel == connectionpanelstart) {
953 /* The Connection panel. Accelerators used: [acgo] tuk */
955 ctlposinit(&cp, hwnd, 80, 3, 13);
956 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
958 beginbox(&cp, "Data to send to the server",
959 IDC_BOX_CONNECTION1);
960 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
961 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
964 beginbox(&cp, "Sending of null packets to keep session active",
965 IDC_BOX_CONNECTION2);
966 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
967 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
971 if (panel == telnetpanelstart) {
972 /* The Telnet panel. Accelerators used: [acgo] svldr bf */
974 ctlposinit(&cp, hwnd, 80, 3, 13);
976 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
977 beginbox(&cp, "Data to send to the server",
979 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
980 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
981 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
982 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
984 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
986 beginbox(&cp, "Telnet protocol adjustments",
988 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
989 "&BSD (commonplace)", IDC_EMBSD,
990 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
995 if (panel == rloginpanelstart) {
996 /* The Rlogin panel. Accelerators used: [acgo] sl */
998 ctlposinit(&cp, hwnd, 80, 3, 13);
1000 bartitle(&cp, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN);
1001 beginbox(&cp, "Data to send to the server",
1003 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC, IDC_R_TSEDIT, 50);
1004 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC, IDC_RLLUSEREDIT, 50);
1009 if (panel == sshpanelstart) {
1010 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bd i */
1012 ctlposinit(&cp, hwnd, 80, 3, 13);
1014 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
1015 beginbox(&cp, "Data to send to the server",
1018 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1021 beginbox(&cp, "Authentication options",
1023 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1025 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1026 editbutton(&cp, "Private &key file for authentication:",
1027 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
1029 beginbox(&cp, "Protocol options",
1031 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1032 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1033 radioline(&cp, "Preferred SSH protocol version:",
1034 IDC_SSHPROTSTATIC, 2,
1035 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1036 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 4,
1037 "&3DES", IDC_CIPHER3DES,
1038 "&Blowfish", IDC_CIPHERBLOWF,
1039 "&DES", IDC_CIPHERDES,
1040 "&AES", IDC_CIPHERAES,
1042 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1048 if (panel == tunnelspanelstart) {
1049 /* The Tunnels panel. Accelerators used: [acgo] ex */
1051 ctlposinit(&cp, hwnd, 80, 3, 13);
1053 bartitle(&cp, "Options controlling SSH tunnelling",
1055 beginbox(&cp, "X11 forwarding options",
1057 checkbox(&cp, "&Enable X11 forwarding",
1059 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1060 IDC_X11_DISPLAY, 50, NULL);
1067 * This function is the configuration box.
1069 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1070 WPARAM wParam, LPARAM lParam,
1073 struct treeview_faff tvfaff;
1076 char filename[sizeof(cfg.keyfile)];
1079 char fontstatic[256];
1081 struct servent * service;
1087 SetWindowLong(hwnd, GWL_USERDATA, 0);
1089 * Centre the window.
1091 { /* centre the window */
1094 hw = GetDesktopWindow();
1095 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1096 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1097 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1098 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1102 * Create the tree view.
1109 r.left = 3; r.right = r.left + 75;
1110 r.top = 3; r.bottom = r.top + 10;
1111 MapDialogRect(hwnd, &r);
1112 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1113 WS_CHILD | WS_VISIBLE,
1115 r.right-r.left, r.bottom-r.top,
1116 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
1117 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1118 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1120 r.left = 3; r.right = r.left + 75;
1121 r.top = 13; r.bottom = r.top + 206;
1122 MapDialogRect(hwnd, &r);
1123 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1124 WS_CHILD | WS_VISIBLE |
1125 WS_TABSTOP | TVS_HASLINES |
1126 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
1127 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
1129 r.right-r.left, r.bottom-r.top,
1130 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
1131 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1132 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1133 tvfaff.treeview = treeview;
1134 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1138 * Set up the tree view contents.
1140 hsession = treeview_insert(&tvfaff, 0, "Session");
1141 treeview_insert(&tvfaff, 1, "Logging");
1142 treeview_insert(&tvfaff, 0, "Terminal");
1143 treeview_insert(&tvfaff, 1, "Keyboard");
1144 treeview_insert(&tvfaff, 0, "Window");
1145 treeview_insert(&tvfaff, 1, "Appearance");
1146 treeview_insert(&tvfaff, 1, "Translation");
1147 treeview_insert(&tvfaff, 1, "Selection");
1148 treeview_insert(&tvfaff, 1, "Colours");
1149 treeview_insert(&tvfaff, 0, "Connection");
1151 treeview_insert(&tvfaff, 1, "Telnet");
1152 treeview_insert(&tvfaff, 1, "Rlogin");
1153 if (backends[3].backend != NULL) {
1154 treeview_insert(&tvfaff, 1, "SSH");
1155 treeview_insert(&tvfaff, 2, "Tunnels");
1160 * Put the treeview selection on to the Session panel. This
1161 * should also cause creation of the relevant controls.
1163 TreeView_SelectItem(treeview, hsession);
1166 * Set focus into the first available control.
1170 ctl = GetDlgItem(hwnd, IDC_HOST);
1171 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1175 SetWindowLong(hwnd, GWL_USERDATA, 1);
1179 * Button release should trigger WM_OK if there was a
1180 * previous double click on the session list.
1184 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1187 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1188 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1189 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1194 item.pszText = buffer;
1195 item.cchTextMax = sizeof(buffer);
1196 item.mask = TVIF_TEXT;
1197 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1198 for (j = controlstartvalue; j < controlendvalue; j++) {
1199 HWND item = GetDlgItem(hwnd, j);
1201 DestroyWindow(item);
1203 if (!strcmp(buffer, "Session"))
1204 create_controls(hwnd, dlgtype, sessionpanelstart);
1205 if (!strcmp(buffer, "Logging"))
1206 create_controls(hwnd, dlgtype, loggingpanelstart);
1207 if (!strcmp(buffer, "Keyboard"))
1208 create_controls(hwnd, dlgtype, keyboardpanelstart);
1209 if (!strcmp(buffer, "Terminal"))
1210 create_controls(hwnd, dlgtype, terminalpanelstart);
1211 if (!strcmp(buffer, "Window"))
1212 create_controls(hwnd, dlgtype, windowpanelstart);
1213 if (!strcmp(buffer, "Appearance"))
1214 create_controls(hwnd, dlgtype, appearancepanelstart);
1215 if (!strcmp(buffer, "Tunnels"))
1216 create_controls(hwnd, dlgtype, tunnelspanelstart);
1217 if (!strcmp(buffer, "Connection"))
1218 create_controls(hwnd, dlgtype, connectionpanelstart);
1219 if (!strcmp(buffer, "Telnet"))
1220 create_controls(hwnd, dlgtype, telnetpanelstart);
1221 if (!strcmp(buffer, "Rlogin"))
1222 create_controls(hwnd, dlgtype, rloginpanelstart);
1223 if (!strcmp(buffer, "SSH"))
1224 create_controls(hwnd, dlgtype, sshpanelstart);
1225 if (!strcmp(buffer, "Selection"))
1226 create_controls(hwnd, dlgtype, selectionpanelstart);
1227 if (!strcmp(buffer, "Colours"))
1228 create_controls(hwnd, dlgtype, colourspanelstart);
1229 if (!strcmp(buffer, "Translation"))
1230 create_controls(hwnd, dlgtype, translationpanelstart);
1232 init_dlg_ctrls(hwnd);
1234 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1240 * Only process WM_COMMAND once the dialog is fully formed.
1242 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1245 EndDialog (hwnd, 1);
1250 EndDialog (hwnd, 0);
1252 case IDC_PROTTELNET:
1253 case IDC_PROTRLOGIN:
1256 if (HIWORD(wParam) == BN_CLICKED ||
1257 HIWORD(wParam) == BN_DOUBLECLICKED) {
1258 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1259 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1260 int k = IsDlgButtonChecked (hwnd, IDC_PROTRLOGIN);
1261 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN : PROT_RAW ;
1262 if ((cfg.protocol == PROT_SSH && cfg.port != 22) ||
1263 (cfg.protocol == PROT_TELNET && cfg.port != 23) ||
1264 (cfg.protocol == PROT_RLOGIN && cfg.port != 513)) {
1265 cfg.port = i ? 22 : j ? 23 : 513;
1266 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1271 if (HIWORD(wParam) == EN_CHANGE)
1272 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1273 sizeof(cfg.host)-1);
1276 if (HIWORD(wParam) == EN_CHANGE) {
1277 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1278 if (isdigit(portname[0]))
1279 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1281 service = getservbyname(portname, NULL);
1282 if (service) cfg.port = ntohs(service->s_port);
1288 if (HIWORD(wParam) == EN_CHANGE) {
1289 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1291 GetDlgItemText (hwnd, IDC_SESSEDIT,
1292 savedsession, sizeof(savedsession)-1);
1293 savedsession[sizeof(savedsession)-1] = '\0';
1297 if (HIWORD(wParam) == BN_CLICKED ||
1298 HIWORD(wParam) == BN_DOUBLECLICKED) {
1303 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1305 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1306 LB_GETCURSEL, 0, 0);
1311 strcpy (str, sessions[n]);
1313 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1314 get_sesslist (FALSE);
1315 get_sesslist (TRUE);
1316 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1318 for (i = 0; i < nsessions; i++)
1319 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1320 0, (LPARAM) (sessions[i]));
1321 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1327 if (LOWORD(wParam) == IDC_SESSLOAD &&
1328 HIWORD(wParam) != BN_CLICKED &&
1329 HIWORD(wParam) != BN_DOUBLECLICKED)
1331 if (LOWORD(wParam) == IDC_SESSLIST &&
1332 HIWORD(wParam) != LBN_DBLCLK)
1335 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1336 LB_GETCURSEL, 0, 0);
1342 isdef = !strcmp(sessions[n], "Default Settings");
1343 load_settings (sessions[n], !isdef, &cfg);
1344 init_dlg_ctrls(hwnd);
1346 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1348 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1350 if (LOWORD(wParam) == IDC_SESSLIST) {
1352 * A double-click on a saved session should
1353 * actually start the session, not just load it.
1354 * Unless it's Default Settings or some other
1355 * host-less set of saved settings.
1364 if (HIWORD(wParam) == BN_CLICKED ||
1365 HIWORD(wParam) == BN_DOUBLECLICKED) {
1366 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1367 LB_GETCURSEL, 0, 0);
1368 if (n == LB_ERR || n == 0) {
1372 del_settings(sessions[n]);
1373 get_sesslist (FALSE);
1374 get_sesslist (TRUE);
1375 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1377 for (i = 0; i < nsessions; i++)
1378 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1379 0, (LPARAM) (sessions[i]));
1380 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1384 if (HIWORD(wParam) == EN_CHANGE)
1385 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1389 if (HIWORD(wParam) == BN_CLICKED ||
1390 HIWORD(wParam) == BN_DOUBLECLICKED)
1391 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1395 if (HIWORD(wParam) == BN_CLICKED ||
1396 HIWORD(wParam) == BN_DOUBLECLICKED)
1397 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1400 if (HIWORD(wParam) == BN_CLICKED ||
1401 HIWORD(wParam) == BN_DOUBLECLICKED)
1405 if (HIWORD(wParam) == BN_CLICKED ||
1406 HIWORD(wParam) == BN_DOUBLECLICKED)
1411 if (HIWORD(wParam) == BN_CLICKED ||
1412 HIWORD(wParam) == BN_DOUBLECLICKED)
1413 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1417 if (HIWORD(wParam) == BN_CLICKED ||
1418 HIWORD(wParam) == BN_DOUBLECLICKED) {
1419 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1420 cfg.nethack_keypad = FALSE;
1424 if (HIWORD(wParam) == BN_CLICKED ||
1425 HIWORD(wParam) == BN_DOUBLECLICKED) {
1426 cfg.app_keypad = FALSE;
1427 cfg.nethack_keypad = TRUE;
1432 if (HIWORD(wParam) == BN_CLICKED ||
1433 HIWORD(wParam) == BN_DOUBLECLICKED)
1434 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1437 if (HIWORD(wParam) == BN_CLICKED ||
1438 HIWORD(wParam) == BN_DOUBLECLICKED)
1439 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1442 if (HIWORD(wParam) == BN_CLICKED ||
1443 HIWORD(wParam) == BN_DOUBLECLICKED)
1444 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1447 if (HIWORD(wParam) == BN_CLICKED ||
1448 HIWORD(wParam) == BN_DOUBLECLICKED)
1449 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1452 if (HIWORD(wParam) == BN_CLICKED ||
1453 HIWORD(wParam) == BN_DOUBLECLICKED)
1454 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1457 if (HIWORD(wParam) == BN_CLICKED ||
1458 HIWORD(wParam) == BN_DOUBLECLICKED)
1459 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1461 case IDC_ECHOBACKEND:
1464 if (HIWORD(wParam) == BN_CLICKED ||
1465 HIWORD(wParam) == BN_DOUBLECLICKED) {
1466 if (LOWORD(wParam)==IDC_ECHOBACKEND) cfg.localecho=LD_BACKEND;
1467 if (LOWORD(wParam)==IDC_ECHOYES) cfg.localecho=LD_YES;
1468 if (LOWORD(wParam)==IDC_ECHONO) cfg.localecho=LD_NO;
1471 case IDC_EDITBACKEND:
1474 if (HIWORD(wParam) == BN_CLICKED ||
1475 HIWORD(wParam) == BN_DOUBLECLICKED) {
1476 if (LOWORD(wParam)==IDC_EDITBACKEND) cfg.localedit=LD_BACKEND;
1477 if (LOWORD(wParam)==IDC_EDITYES) cfg.localedit=LD_YES;
1478 if (LOWORD(wParam)==IDC_EDITNO) cfg.localedit=LD_NO;
1481 case IDC_ALWAYSONTOP:
1482 if (HIWORD(wParam) == BN_CLICKED ||
1483 HIWORD(wParam) == BN_DOUBLECLICKED)
1484 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1487 if (HIWORD(wParam) == BN_CLICKED ||
1488 HIWORD(wParam) == BN_DOUBLECLICKED)
1489 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1491 case IDC_SCROLLDISP:
1492 if (HIWORD(wParam) == BN_CLICKED ||
1493 HIWORD(wParam) == BN_DOUBLECLICKED)
1494 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1496 case IDC_COMPOSEKEY:
1497 if (HIWORD(wParam) == BN_CLICKED ||
1498 HIWORD(wParam) == BN_DOUBLECLICKED)
1499 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1502 if (HIWORD(wParam) == BN_CLICKED ||
1503 HIWORD(wParam) == BN_DOUBLECLICKED)
1504 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1507 if (HIWORD(wParam) == BN_CLICKED ||
1508 HIWORD(wParam) == BN_DOUBLECLICKED)
1509 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1512 if (HIWORD(wParam) == BN_CLICKED ||
1513 HIWORD(wParam) == BN_DOUBLECLICKED)
1514 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1517 if (HIWORD(wParam) == EN_CHANGE)
1518 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1521 if (HIWORD(wParam) == EN_CHANGE)
1522 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1525 if (HIWORD(wParam) == EN_CHANGE)
1526 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1528 case IDC_CHOOSEFONT:
1529 lf.lfHeight = cfg.fontheight;
1530 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1531 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1532 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1533 lf.lfCharSet = cfg.fontcharset;
1534 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1535 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1536 lf.lfQuality = DEFAULT_QUALITY;
1537 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1538 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1539 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1541 cf.lStructSize = sizeof(cf);
1542 cf.hwndOwner = hwnd;
1544 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1545 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1547 if (ChooseFont (&cf)) {
1548 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1549 cfg.font[sizeof(cfg.font)-1] = '\0';
1550 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1551 cfg.fontcharset = lf.lfCharSet;
1552 cfg.fontheight = lf.lfHeight;
1553 fmtfont (fontstatic);
1554 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1558 if (HIWORD(wParam) == BN_CLICKED ||
1559 HIWORD(wParam) == BN_DOUBLECLICKED)
1560 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1563 if (HIWORD(wParam) == BN_CLICKED ||
1564 HIWORD(wParam) == BN_DOUBLECLICKED)
1565 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1568 if (HIWORD(wParam) == BN_CLICKED ||
1569 HIWORD(wParam) == BN_DOUBLECLICKED)
1570 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1573 if (HIWORD(wParam) == BN_CLICKED ||
1574 HIWORD(wParam) == BN_DOUBLECLICKED)
1575 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1578 if (HIWORD(wParam) == BN_CLICKED ||
1579 HIWORD(wParam) == BN_DOUBLECLICKED)
1580 cfg.hide_mouseptr = IsDlgButtonChecked (hwnd, IDC_HIDEMOUSE);
1583 if (HIWORD(wParam) == BN_CLICKED ||
1584 HIWORD(wParam) == BN_DOUBLECLICKED)
1585 cfg.cursor_type = 0;
1588 if (HIWORD(wParam) == BN_CLICKED ||
1589 HIWORD(wParam) == BN_DOUBLECLICKED)
1590 cfg.cursor_type = 1;
1593 if (HIWORD(wParam) == BN_CLICKED ||
1594 HIWORD(wParam) == BN_DOUBLECLICKED)
1595 cfg.cursor_type = 2;
1598 if (HIWORD(wParam) == BN_CLICKED ||
1599 HIWORD(wParam) == BN_DOUBLECLICKED)
1600 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1603 if (HIWORD(wParam) == BN_CLICKED ||
1604 HIWORD(wParam) == BN_DOUBLECLICKED)
1605 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1608 if (HIWORD(wParam) == BN_CLICKED ||
1609 HIWORD(wParam) == BN_DOUBLECLICKED)
1610 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1613 if (HIWORD(wParam) == EN_CHANGE)
1614 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1615 sizeof(cfg.wintitle)-1);
1620 if (HIWORD(wParam) == BN_CLICKED ||
1621 HIWORD(wParam) == BN_DOUBLECLICKED) {
1622 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_COEALWAYS) ? COE_ALWAYS :
1623 IsDlgButtonChecked (hwnd, IDC_COENEVER) ? COE_NEVER :
1628 if (HIWORD(wParam) == BN_CLICKED ||
1629 HIWORD(wParam) == BN_DOUBLECLICKED)
1630 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1633 if (HIWORD(wParam) == EN_CHANGE)
1634 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1635 sizeof(cfg.termtype)-1);
1638 if (HIWORD(wParam) == EN_CHANGE)
1639 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1640 sizeof(cfg.logfilename)-1);
1643 memset(&of, 0, sizeof(of));
1644 #ifdef OPENFILENAME_SIZE_VERSION_400
1645 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1647 of.lStructSize = sizeof(of);
1649 of.hwndOwner = hwnd;
1650 of.lpstrFilter = "All Files\0*\0\0\0";
1651 of.lpstrCustomFilter = NULL;
1652 of.nFilterIndex = 1;
1653 of.lpstrFile = filename; strcpy(filename, cfg.logfilename);
1654 of.nMaxFile = sizeof(filename);
1655 of.lpstrFileTitle = NULL;
1656 of.lpstrInitialDir = NULL;
1657 of.lpstrTitle = "Select session log file";
1659 if (GetSaveFileName(&of)) {
1660 strcpy(cfg.logfilename, filename);
1661 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
1665 case IDC_LSTATASCII:
1667 if (HIWORD(wParam) == BN_CLICKED ||
1668 HIWORD(wParam) == BN_DOUBLECLICKED) {
1669 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1670 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1671 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1676 if (HIWORD(wParam) == EN_CHANGE)
1677 GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed,
1678 sizeof(cfg.termspeed)-1);
1681 if (HIWORD(wParam) == EN_CHANGE)
1682 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1683 sizeof(cfg.username)-1);
1685 case IDC_RLLUSEREDIT:
1686 if (HIWORD(wParam) == EN_CHANGE)
1687 GetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername,
1688 sizeof(cfg.localusername)-1);
1692 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1695 if (HIWORD(wParam) == BN_CLICKED ||
1696 HIWORD(wParam) == BN_DOUBLECLICKED) {
1697 char str[sizeof(cfg.environmt)];
1699 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1704 p = str + strlen(str);
1706 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1716 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1718 p[strlen(str)+1] = '\0';
1719 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1721 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1722 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1724 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1725 MB_OK | MB_ICONERROR);
1730 if (HIWORD(wParam) != BN_CLICKED &&
1731 HIWORD(wParam) != BN_DOUBLECLICKED)
1733 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1739 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1764 if (HIWORD(wParam) == BN_CLICKED ||
1765 HIWORD(wParam) == BN_DOUBLECLICKED)
1766 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1769 if (HIWORD(wParam) == BN_CLICKED ||
1770 HIWORD(wParam) == BN_DOUBLECLICKED)
1771 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1774 if (HIWORD(wParam) == BN_CLICKED ||
1775 HIWORD(wParam) == BN_DOUBLECLICKED)
1776 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1779 if (HIWORD(wParam) == BN_CLICKED ||
1780 HIWORD(wParam) == BN_DOUBLECLICKED)
1781 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1783 case IDC_CIPHER3DES:
1784 case IDC_CIPHERBLOWF:
1787 if (HIWORD(wParam) == BN_CLICKED ||
1788 HIWORD(wParam) == BN_DOUBLECLICKED) {
1789 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1790 cfg.cipher = CIPHER_3DES;
1791 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1792 cfg.cipher = CIPHER_BLOWFISH;
1793 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1794 cfg.cipher = CIPHER_DES;
1795 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERAES))
1796 cfg.cipher = CIPHER_AES;
1801 if (HIWORD(wParam) == BN_CLICKED ||
1802 HIWORD(wParam) == BN_DOUBLECLICKED) {
1803 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1805 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1810 if (HIWORD(wParam) == BN_CLICKED ||
1811 HIWORD(wParam) == BN_DOUBLECLICKED)
1812 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1815 if (HIWORD(wParam) == EN_CHANGE)
1816 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1817 sizeof(cfg.keyfile)-1);
1820 if (HIWORD(wParam) == EN_CHANGE)
1821 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1822 sizeof(cfg.remote_cmd)-1);
1825 memset(&of, 0, sizeof(of));
1826 #ifdef OPENFILENAME_SIZE_VERSION_400
1827 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1829 of.lStructSize = sizeof(of);
1831 of.hwndOwner = hwnd;
1832 of.lpstrFilter = "All Files\0*\0\0\0";
1833 of.lpstrCustomFilter = NULL;
1834 of.nFilterIndex = 1;
1835 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1836 of.nMaxFile = sizeof(filename);
1837 of.lpstrFileTitle = NULL;
1838 of.lpstrInitialDir = NULL;
1839 of.lpstrTitle = "Select Public Key File";
1841 if (GetOpenFileName(&of)) {
1842 strcpy(cfg.keyfile, filename);
1843 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1848 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1854 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1859 for (i=0; i<256; i++)
1860 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1863 cfg.wordness[i] = n;
1864 SendDlgItemMessage (hwnd, IDC_CCLIST,
1865 LB_DELETESTRING, i, 0);
1866 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1867 (i>=0x21 && i != 0x7F) ? i : ' ',
1869 SendDlgItemMessage (hwnd, IDC_CCLIST,
1876 case IDC_BOLDCOLOUR:
1877 if (HIWORD(wParam) == BN_CLICKED ||
1878 HIWORD(wParam) == BN_DOUBLECLICKED) {
1880 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1881 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1882 if (n != 12+10*cfg.bold_colour) {
1884 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1885 LB_DELETESTRING, i, 0);
1886 for (i=0; i<22; i++)
1887 if (cfg.bold_colour || permcolour[i])
1888 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1890 (LPARAM) colours[i]);
1895 if (HIWORD(wParam) == BN_CLICKED ||
1896 HIWORD(wParam) == BN_DOUBLECLICKED)
1897 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1899 case IDC_COLOURLIST:
1900 if (HIWORD(wParam) == LBN_DBLCLK ||
1901 HIWORD(wParam) == LBN_SELCHANGE) {
1902 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1904 if (!cfg.bold_colour)
1905 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1906 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1907 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1908 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1912 if (HIWORD(wParam) == BN_CLICKED ||
1913 HIWORD(wParam) == BN_DOUBLECLICKED) {
1914 static CHOOSECOLOR cc;
1915 static DWORD custom[16] = {0}; /* zero initialisers */
1916 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1918 if (!cfg.bold_colour)
1919 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1920 cc.lStructSize = sizeof(cc);
1921 cc.hwndOwner = hwnd;
1922 cc.hInstance = (HWND)hinst;
1923 cc.lpCustColors = custom;
1924 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1926 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1927 if (ChooseColor(&cc)) {
1929 (unsigned char) (cc.rgbResult & 0xFF);
1931 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1933 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1934 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1936 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1938 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1944 case IDC_KOI8WIN1251:
1945 case IDC_88592WIN1250:
1946 case IDC_88592CP852:
1947 cfg.xlat_enablekoiwin =
1948 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1949 cfg.xlat_88592w1250 =
1950 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1951 cfg.xlat_88592cp852 =
1952 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1954 case IDC_CAPSLOCKCYR:
1955 if (HIWORD(wParam) == BN_CLICKED ||
1956 HIWORD(wParam) == BN_DOUBLECLICKED) {
1957 cfg.xlat_capslockcyr =
1958 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1961 case IDC_VTXWINDOWS:
1966 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1967 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1968 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1971 case IDC_X11_FORWARD:
1972 if (HIWORD(wParam) == BN_CLICKED ||
1973 HIWORD(wParam) == BN_DOUBLECLICKED)
1974 cfg.x11_forward = IsDlgButtonChecked (hwnd, IDC_X11_FORWARD);
1976 case IDC_X11_DISPLAY:
1977 if (HIWORD(wParam) == EN_CHANGE)
1978 GetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display,
1979 sizeof(cfg.x11_display)-1);
1984 EndDialog (hwnd, 0);
1987 /* Grrr Explorer will maximize Dialogs! */
1989 if (wParam == SIZE_MAXIMIZED)
1996 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1997 WPARAM wParam, LPARAM lParam) {
1998 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2000 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2001 EnableWindow(hwnd, 0);
2002 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2003 GetParent(hwnd), AboutProc);
2004 EnableWindow(hwnd, 1);
2005 SetActiveWindow(hwnd);
2007 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
2010 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
2011 WPARAM wParam, LPARAM lParam) {
2012 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
2015 void defuse_showwindow(void) {
2017 * Work around the fact that the app's first call to ShowWindow
2018 * will ignore the default in favour of the shell-provided
2023 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2025 ShowWindow(hwnd, SW_HIDE);
2026 DestroyWindow(hwnd);
2030 int do_config (void) {
2034 savedsession[0] = '\0';
2035 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2036 get_sesslist(FALSE);
2041 int do_reconfig (HWND hwnd) {
2045 backup_cfg = cfg; /* structure copy */
2046 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2048 cfg = backup_cfg; /* structure copy */
2053 void logevent (char *string) {
2057 if (nevents >= negsize) {
2059 events = srealloc (events, negsize * sizeof(*events));
2063 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t", localtime(&t));
2065 events[nevents] = smalloc(strlen(timebuf)+strlen(string)+1);
2066 strcpy(events[nevents], timebuf);
2067 strcat(events[nevents], string);
2070 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
2071 0, (LPARAM)events[nevents]);
2072 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2073 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
2078 void showeventlog (HWND hwnd) {
2080 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2082 ShowWindow (logbox, SW_SHOWNORMAL);
2084 SetActiveWindow(logbox);
2087 void showabout (HWND hwnd) {
2088 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),hwnd, AboutProc);
2091 void verify_ssh_host_key(char *host, int port, char *keytype,
2092 char *keystr, char *fingerprint) {
2095 static const char absentmsg[] =
2096 "The server's host key is not cached in the registry. You\n"
2097 "have no guarantee that the server is the computer you\n"
2099 "The server's key fingerprint is:\n"
2101 "If you trust this host, hit Yes to add the key to\n"
2102 "PuTTY's cache and carry on connecting.\n"
2103 "If you do not trust this host, hit No to abandon the\n"
2106 static const char wrongmsg[] =
2107 "WARNING - POTENTIAL SECURITY BREACH!\n"
2109 "The server's host key does not match the one PuTTY has\n"
2110 "cached in the registry. This means that either the\n"
2111 "server administrator has changed the host key, or you\n"
2112 "have actually connected to another computer pretending\n"
2113 "to be the server.\n"
2114 "The new key fingerprint is:\n"
2116 "If you were expecting this change and trust the new key,\n"
2117 "hit Yes to update PuTTY's cache and continue connecting.\n"
2118 "If you want to carry on connecting but without updating\n"
2119 "the cache, hit No.\n"
2120 "If you want to abandon the connection completely, hit\n"
2121 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2124 static const char mbtitle[] = "PuTTY Security Alert";
2127 char message[160+ /* sensible fingerprint max size */
2128 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2129 sizeof(absentmsg) : sizeof(wrongmsg))];
2132 * Verify the key against the registry.
2134 ret = verify_host_key(host, port, keytype, keystr);
2136 if (ret == 0) /* success - key matched OK */
2138 if (ret == 2) { /* key was different */
2140 sprintf(message, wrongmsg, fingerprint);
2141 mbret = MessageBox(NULL, message, mbtitle,
2142 MB_ICONWARNING | MB_YESNOCANCEL);
2144 store_host_key(host, port, keytype, keystr);
2145 if (mbret == IDCANCEL)
2148 if (ret == 1) { /* key was absent */
2150 sprintf(message, absentmsg, fingerprint);
2151 mbret = MessageBox(NULL, message, mbtitle,
2152 MB_ICONWARNING | MB_YESNO);
2155 store_host_key(host, port, keytype, keystr);
2160 * Ask whether to wipe a session log file before writing to it.
2161 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2163 int askappend(char *filename) {
2164 static const char mbtitle[] = "PuTTY Log to File";
2165 static const char msgtemplate[] =
2166 "The session log file \"%.*s\" already exists.\n"
2167 "You can overwrite it with a new session log,\n"
2168 "append your session log to the end of it,\n"
2169 "or disable session logging for this session.\n"
2170 "Hit Yes to wipe the file, No to append to it,\n"
2171 "or Cancel to disable logging.";
2172 char message[sizeof(msgtemplate) + FILENAME_MAX];
2174 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2176 mbret = MessageBox(NULL, message, mbtitle,
2177 MB_ICONQUESTION | MB_YESNOCANCEL);
2180 else if (mbret == IDNO)