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-point",
471 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
474 static void init_dlg_ctrls(HWND hwnd) {
476 char fontstatic[256];
478 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
479 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
482 n = SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
484 SendDlgItemMessage (hwnd, IDC_SESSLIST,
485 LB_DELETESTRING, i, 0);
486 for (i = 0; i < nsessions; i++)
487 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
488 0, (LPARAM) (sessions[i]));
490 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
491 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
492 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
493 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET :
494 cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW );
495 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
497 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
498 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
499 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
500 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
501 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
502 cfg.funky_type == 0 ? IDC_FUNCTILDE :
503 cfg.funky_type == 1 ? IDC_FUNCLINUX :
504 cfg.funky_type == 2 ? IDC_FUNCXTERM :
505 cfg.funky_type == 3 ? IDC_FUNCVT400 :
507 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
508 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
509 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
510 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
511 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
512 cfg.nethack_keypad ? IDC_KPNH :
513 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
514 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
515 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
516 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
517 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
518 CheckRadioButton (hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
519 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND:
520 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
521 CheckRadioButton (hwnd, IDC_EDITBACKEND, IDC_EDITNO,
522 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND:
523 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
524 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
525 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
526 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
528 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
529 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
530 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
531 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
532 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
533 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
534 fmtfont (fontstatic);
535 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
536 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
537 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
538 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
540 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
541 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
542 CheckDlgButton (hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
543 CheckRadioButton (hwnd, IDC_CURBLOCK, IDC_CURVERT,
544 cfg.cursor_type==0 ? IDC_CURBLOCK :
545 cfg.cursor_type==1 ? IDC_CURUNDER : IDC_CURVERT);
546 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
547 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
548 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
549 CheckRadioButton (hwnd, IDC_COEALWAYS, IDC_COENORMAL,
550 cfg.close_on_exit==COE_NORMAL ? IDC_COENORMAL :
551 cfg.close_on_exit==COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
552 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
554 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
555 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
556 SetDlgItemText (hwnd, IDC_R_TSEDIT, cfg.termspeed);
557 SetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername);
558 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
559 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
560 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
561 cfg.logtype == 0 ? IDC_LSTATOFF :
562 cfg.logtype == 1 ? IDC_LSTATASCII :
565 char *p = cfg.environmt;
567 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
572 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
573 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
575 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
576 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
577 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
578 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
579 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
580 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
581 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERAES,
582 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
583 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
584 cfg.cipher == CIPHER_AES ? IDC_CIPHERAES :
586 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
587 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
588 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
589 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
590 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
592 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
593 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
595 static int tabs[4] = {25, 61, 96, 128};
596 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
599 for (i=0; i<256; i++) {
601 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
602 (i>=0x21 && i != 0x7F) ? i : ' ',
604 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
608 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
609 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
612 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
614 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
615 LB_DELETESTRING, i, 0);
617 if (cfg.bold_colour || permcolour[i])
618 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
619 (LPARAM) colours[i]);
621 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
622 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
623 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
624 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
626 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
627 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
628 cfg.xlat_88592cp852 ? IDC_88592CP852 :
629 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
631 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
632 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
633 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
634 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
635 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
638 CheckDlgButton (hwnd, IDC_X11_FORWARD, cfg.x11_forward);
639 SetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display);
642 struct treeview_faff {
647 static HTREEITEM treeview_insert(struct treeview_faff *faff,
648 int level, char *text) {
652 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
653 ins.hInsertAfter = faff->lastat[level];
654 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
655 #define INSITEM DUMMYUNIONNAME.item
659 ins.INSITEM.mask = TVIF_TEXT;
660 ins.INSITEM.pszText = text;
661 newitem = TreeView_InsertItem(faff->treeview, &ins);
663 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
664 faff->lastat[level] = newitem;
665 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
670 * Create the panelfuls of controls in the configuration box.
672 static void create_controls(HWND hwnd, int dlgtype, int panel) {
673 if (panel == sessionpanelstart) {
674 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
676 ctlposinit(&cp, hwnd, 80, 3, 13);
677 bartitle(&cp, "Basic options for your PuTTY session",
680 beginbox(&cp, "Specify your connection by host name",
683 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
684 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
685 if (backends[3].backend == NULL) {
686 /* this is PuTTYtel, so only three protocols available */
687 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
689 "&Telnet", IDC_PROTTELNET,
690 "Rlog&in", IDC_PROTRLOGIN, NULL);
692 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
694 "&Telnet", IDC_PROTTELNET,
695 "Rlog&in", IDC_PROTRLOGIN,
704 beginbox(&cp, "Load, save or delete a stored session",
706 sesssaver(&cp, "Sav&ed Sessions",
707 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
708 "&Load", IDC_SESSLOAD,
709 "&Save", IDC_SESSSAVE,
710 "&Delete", IDC_SESSDEL, NULL);
713 beginbox(&cp, NULL, IDC_BOX_SESSION3);
714 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
715 "Always", IDC_COEALWAYS,
716 "Never", IDC_COENEVER,
717 "Only on clean exit", IDC_COENORMAL, NULL);
721 if (panel == loggingpanelstart) {
722 /* The Logging panel. Accelerators used: [acgo] tplfw */
724 ctlposinit(&cp, hwnd, 80, 3, 13);
725 bartitle(&cp, "Options controlling session logging",
727 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
729 "Session logging:", IDC_LSTATSTATIC,
730 "Logging &turned off completely", IDC_LSTATOFF,
731 "Log &printable output only", IDC_LSTATASCII,
732 "&Log all session output", IDC_LSTATRAW, NULL);
733 editbutton(&cp, "Log &file name:",
734 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
739 if (panel == terminalpanelstart) {
740 /* The Terminal panel. Accelerators used: [acgo] wdlben ht */
742 ctlposinit(&cp, hwnd, 80, 3, 13);
743 bartitle(&cp, "Options controlling the terminal emulation",
745 beginbox(&cp, "Set various terminal options",
747 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
748 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
749 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
750 checkbox(&cp, "&Beep enabled", IDC_BEEP);
751 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
752 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
755 beginbox(&cp, "Line discipline options",
757 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
758 "Auto", IDC_ECHOBACKEND,
759 "Force on", IDC_ECHOYES,
760 "Force off", IDC_ECHONO, NULL);
761 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
762 "Auto", IDC_EDITBACKEND,
763 "Force on", IDC_EDITYES,
764 "Force off", IDC_EDITNO, NULL);
768 if (panel == keyboardpanelstart) {
769 /* The Keyboard panel. Accelerators used: [acgo] h?sr~lxv unpymie t */
771 ctlposinit(&cp, hwnd, 80, 3, 13);
772 bartitle(&cp, "Options controlling the effects of keys",
774 beginbox(&cp, "Change the sequences sent by:",
776 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
777 "Control-&H", IDC_DEL008,
778 "Control-&? (127)", IDC_DEL127, NULL);
779 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
780 "&Standard", IDC_HOMETILDE,
781 "&rxvt", IDC_HOMERXVT, NULL);
782 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
783 "ESC[n&~", IDC_FUNCTILDE,
784 "&Linux", IDC_FUNCLINUX,
785 "&Xterm R6", IDC_FUNCXTERM,
786 "&VT400", IDC_FUNCVT400, NULL);
788 beginbox(&cp, "Application keypad settings:",
791 "Application c&ursor keys totally disabled",
793 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
794 "&Normal", IDC_CURNORMAL,
795 "A&pplication", IDC_CURAPPLIC, NULL);
797 "Application ke&ypad keys totally disabled",
799 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
800 "Nor&mal", IDC_KPNORMAL,
801 "Appl&ication", IDC_KPAPPLIC,
802 "N&etHack", IDC_KPNH, NULL);
804 beginbox(&cp, "Enable extra keyboard features:",
806 checkbox(&cp, "Application and AltGr ac&t as Compose key",
811 if (panel == windowpanelstart) {
812 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
814 ctlposinit(&cp, hwnd, 80, 3, 13);
815 bartitle(&cp, "Options controlling PuTTY's window",
817 beginbox(&cp, "Set the size of the window",
820 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
821 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
823 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
825 beginbox(&cp, "Control the scrollback in the window",
827 staticedit(&cp, "Lines of &scrollback",
828 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
829 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
830 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
831 checkbox(&cp, "Reset scrollback on dis&play activity",
834 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
835 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
836 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
837 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
838 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
839 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
843 if (panel == appearancepanelstart) {
844 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p */
846 ctlposinit(&cp, hwnd, 80, 3, 13);
847 bartitle(&cp, "Options controlling PuTTY's appearance",
848 IDC_TITLE_APPEARANCE);
849 beginbox(&cp, "Adjust the use of the cursor",
850 IDC_BOX_APPEARANCE1);
851 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
852 "B&lock", IDC_CURBLOCK,
853 "&Underline", IDC_CURUNDER,
854 "&Vertical line", IDC_CURVERT,
856 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
858 beginbox(&cp, "Set the font used in the terminal window",
859 IDC_BOX_APPEARANCE2);
860 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
862 beginbox(&cp, "Adjust the use of the window title",
863 IDC_BOX_APPEARANCE3);
865 "Window &title:", IDC_WINTITLE,
866 IDC_WINEDIT, 100, NULL);
867 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
869 beginbox(&cp, "Adjust the use of the mouse pointer",
870 IDC_BOX_APPEARANCE4);
871 checkbox(&cp, "Hide mouse &pointer when typing in window",
876 if (panel == translationpanelstart) {
877 /* The Translation panel. Accelerators used: [acgo] xbep t s */
879 ctlposinit(&cp, hwnd, 80, 3, 13);
880 bartitle(&cp, "Options controlling character set translation",
881 IDC_TITLE_TRANSLATION);
882 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
883 IDC_BOX_TRANSLATION1);
885 "Handling of line drawing characters:", IDC_VTSTATIC,
886 "Font has &XWindows encoding", IDC_VTXWINDOWS,
887 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
888 "Use font in O&EM mode only", IDC_VTOEMONLY,
889 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
890 IDC_VTPOORMAN, NULL);
892 beginbox(&cp, "Enable character set translation on received data",
893 IDC_BOX_TRANSLATION2);
895 "Character set &translation:", IDC_XLATSTATIC,
897 "KOI8 / Win-1251", IDC_KOI8WIN1251,
898 "ISO-8859-2 / Win-1250", IDC_88592WIN1250,
899 "ISO-8859-2 / CP852", IDC_88592CP852, NULL);
901 beginbox(&cp, "Enable character set translation on input data",
902 IDC_BOX_TRANSLATION3);
903 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
908 if (panel == selectionpanelstart) {
909 /* The Selection panel. Accelerators used: [acgo] wx hst */
911 ctlposinit(&cp, hwnd, 80, 3, 13);
912 bartitle(&cp, "Options controlling copy and paste",
913 IDC_TITLE_SELECTION);
914 beginbox(&cp, "Control which mouse button does which thing",
916 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
917 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
918 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
921 beginbox(&cp, "Control the select-one-word-at-a-time mode",
923 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
924 "&Set", IDC_CCSET, IDC_CCEDIT,
925 "&to class", IDC_CCSTATIC2);
929 if (panel == colourspanelstart) {
930 /* The Colours panel. Accelerators used: [acgo] blum */
932 ctlposinit(&cp, hwnd, 80, 3, 13);
933 bartitle(&cp, "Options controlling use of colours",
935 beginbox(&cp, "General options for colour usage",
937 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
938 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
940 beginbox(&cp, "Adjust the precise colours PuTTY displays",
942 colouredit(&cp, "Select a colo&ur and then click to modify it:",
943 IDC_COLOURSTATIC, IDC_COLOURLIST,
944 "&Modify...", IDC_CHANGE,
945 "Red:", IDC_RSTATIC, IDC_RVALUE,
946 "Green:", IDC_GSTATIC, IDC_GVALUE,
947 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
951 if (panel == connectionpanelstart) {
952 /* The Connection panel. Accelerators used: [acgo] tuk */
954 ctlposinit(&cp, hwnd, 80, 3, 13);
955 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
957 beginbox(&cp, "Data to send to the server",
958 IDC_BOX_CONNECTION1);
959 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
960 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
963 beginbox(&cp, "Sending of null packets to keep session active",
964 IDC_BOX_CONNECTION2);
965 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
966 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
970 if (panel == telnetpanelstart) {
971 /* The Telnet panel. Accelerators used: [acgo] svldr bf */
973 ctlposinit(&cp, hwnd, 80, 3, 13);
975 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
976 beginbox(&cp, "Data to send to the server",
978 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
979 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
980 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
981 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
983 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
985 beginbox(&cp, "Telnet protocol adjustments",
987 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
988 "&BSD (commonplace)", IDC_EMBSD,
989 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
994 if (panel == rloginpanelstart) {
995 /* The Rlogin panel. Accelerators used: [acgo] sl */
997 ctlposinit(&cp, hwnd, 80, 3, 13);
999 bartitle(&cp, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN);
1000 beginbox(&cp, "Data to send to the server",
1002 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC, IDC_R_TSEDIT, 50);
1003 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC, IDC_RLLUSEREDIT, 50);
1008 if (panel == sshpanelstart) {
1009 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1011 ctlposinit(&cp, hwnd, 80, 3, 13);
1013 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
1014 beginbox(&cp, "Data to send to the server",
1017 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1020 beginbox(&cp, "Authentication options",
1022 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1024 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1025 editbutton(&cp, "Private &key file for authentication:",
1026 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
1028 beginbox(&cp, "Protocol options",
1030 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1031 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1032 radioline(&cp, "Preferred SSH protocol version:",
1033 IDC_SSHPROTSTATIC, 2,
1034 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1035 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 4,
1036 "&3DES", IDC_CIPHER3DES,
1037 "&Blowfish", IDC_CIPHERBLOWF,
1038 "&DES", IDC_CIPHERDES,
1039 "AE&S", IDC_CIPHERAES,
1041 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1047 if (panel == tunnelspanelstart) {
1048 /* The Tunnels panel. Accelerators used: [acgo] ex */
1050 ctlposinit(&cp, hwnd, 80, 3, 13);
1052 bartitle(&cp, "Options controlling SSH tunnelling",
1054 beginbox(&cp, "X11 forwarding options",
1056 checkbox(&cp, "&Enable X11 forwarding",
1058 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1059 IDC_X11_DISPLAY, 50, NULL);
1066 * This function is the configuration box.
1068 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1069 WPARAM wParam, LPARAM lParam,
1072 struct treeview_faff tvfaff;
1075 char filename[sizeof(cfg.keyfile)];
1078 char fontstatic[256];
1080 struct servent * service;
1086 SetWindowLong(hwnd, GWL_USERDATA, 0);
1088 * Centre the window.
1090 { /* centre the window */
1093 hw = GetDesktopWindow();
1094 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1095 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1096 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1097 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1101 * Create the tree view.
1108 r.left = 3; r.right = r.left + 75;
1109 r.top = 3; r.bottom = r.top + 10;
1110 MapDialogRect(hwnd, &r);
1111 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1112 WS_CHILD | WS_VISIBLE,
1114 r.right-r.left, r.bottom-r.top,
1115 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
1116 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1117 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1119 r.left = 3; r.right = r.left + 75;
1120 r.top = 13; r.bottom = r.top + 206;
1121 MapDialogRect(hwnd, &r);
1122 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1123 WS_CHILD | WS_VISIBLE |
1124 WS_TABSTOP | TVS_HASLINES |
1125 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
1126 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
1128 r.right-r.left, r.bottom-r.top,
1129 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
1130 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1131 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1132 tvfaff.treeview = treeview;
1133 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1137 * Set up the tree view contents.
1139 hsession = treeview_insert(&tvfaff, 0, "Session");
1140 treeview_insert(&tvfaff, 1, "Logging");
1141 treeview_insert(&tvfaff, 0, "Terminal");
1142 treeview_insert(&tvfaff, 1, "Keyboard");
1143 treeview_insert(&tvfaff, 0, "Window");
1144 treeview_insert(&tvfaff, 1, "Appearance");
1145 treeview_insert(&tvfaff, 1, "Translation");
1146 treeview_insert(&tvfaff, 1, "Selection");
1147 treeview_insert(&tvfaff, 1, "Colours");
1148 treeview_insert(&tvfaff, 0, "Connection");
1150 treeview_insert(&tvfaff, 1, "Telnet");
1151 treeview_insert(&tvfaff, 1, "Rlogin");
1152 if (backends[3].backend != NULL) {
1153 treeview_insert(&tvfaff, 1, "SSH");
1154 treeview_insert(&tvfaff, 2, "Tunnels");
1159 * Put the treeview selection on to the Session panel. This
1160 * should also cause creation of the relevant controls.
1162 TreeView_SelectItem(treeview, hsession);
1165 * Set focus into the first available control.
1169 ctl = GetDlgItem(hwnd, IDC_HOST);
1170 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1174 SetWindowLong(hwnd, GWL_USERDATA, 1);
1178 * Button release should trigger WM_OK if there was a
1179 * previous double click on the session list.
1183 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1186 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1187 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1188 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1193 item.pszText = buffer;
1194 item.cchTextMax = sizeof(buffer);
1195 item.mask = TVIF_TEXT;
1196 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1197 for (j = controlstartvalue; j < controlendvalue; j++) {
1198 HWND item = GetDlgItem(hwnd, j);
1200 DestroyWindow(item);
1202 if (!strcmp(buffer, "Session"))
1203 create_controls(hwnd, dlgtype, sessionpanelstart);
1204 if (!strcmp(buffer, "Logging"))
1205 create_controls(hwnd, dlgtype, loggingpanelstart);
1206 if (!strcmp(buffer, "Keyboard"))
1207 create_controls(hwnd, dlgtype, keyboardpanelstart);
1208 if (!strcmp(buffer, "Terminal"))
1209 create_controls(hwnd, dlgtype, terminalpanelstart);
1210 if (!strcmp(buffer, "Window"))
1211 create_controls(hwnd, dlgtype, windowpanelstart);
1212 if (!strcmp(buffer, "Appearance"))
1213 create_controls(hwnd, dlgtype, appearancepanelstart);
1214 if (!strcmp(buffer, "Tunnels"))
1215 create_controls(hwnd, dlgtype, tunnelspanelstart);
1216 if (!strcmp(buffer, "Connection"))
1217 create_controls(hwnd, dlgtype, connectionpanelstart);
1218 if (!strcmp(buffer, "Telnet"))
1219 create_controls(hwnd, dlgtype, telnetpanelstart);
1220 if (!strcmp(buffer, "Rlogin"))
1221 create_controls(hwnd, dlgtype, rloginpanelstart);
1222 if (!strcmp(buffer, "SSH"))
1223 create_controls(hwnd, dlgtype, sshpanelstart);
1224 if (!strcmp(buffer, "Selection"))
1225 create_controls(hwnd, dlgtype, selectionpanelstart);
1226 if (!strcmp(buffer, "Colours"))
1227 create_controls(hwnd, dlgtype, colourspanelstart);
1228 if (!strcmp(buffer, "Translation"))
1229 create_controls(hwnd, dlgtype, translationpanelstart);
1231 init_dlg_ctrls(hwnd);
1233 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1239 * Only process WM_COMMAND once the dialog is fully formed.
1241 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1244 EndDialog (hwnd, 1);
1249 EndDialog (hwnd, 0);
1251 case IDC_PROTTELNET:
1252 case IDC_PROTRLOGIN:
1255 if (HIWORD(wParam) == BN_CLICKED ||
1256 HIWORD(wParam) == BN_DOUBLECLICKED) {
1257 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1258 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1259 int k = IsDlgButtonChecked (hwnd, IDC_PROTRLOGIN);
1260 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN : PROT_RAW ;
1261 if ((cfg.protocol == PROT_SSH && cfg.port != 22) ||
1262 (cfg.protocol == PROT_TELNET && cfg.port != 23) ||
1263 (cfg.protocol == PROT_RLOGIN && cfg.port != 513)) {
1264 cfg.port = i ? 22 : j ? 23 : 513;
1265 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1270 if (HIWORD(wParam) == EN_CHANGE)
1271 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1272 sizeof(cfg.host)-1);
1275 if (HIWORD(wParam) == EN_CHANGE) {
1276 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1277 if (isdigit(portname[0]))
1278 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1280 service = getservbyname(portname, NULL);
1281 if (service) cfg.port = ntohs(service->s_port);
1287 if (HIWORD(wParam) == EN_CHANGE) {
1288 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1290 GetDlgItemText (hwnd, IDC_SESSEDIT,
1291 savedsession, sizeof(savedsession)-1);
1292 savedsession[sizeof(savedsession)-1] = '\0';
1296 if (HIWORD(wParam) == BN_CLICKED ||
1297 HIWORD(wParam) == BN_DOUBLECLICKED) {
1302 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1304 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1305 LB_GETCURSEL, 0, 0);
1310 strcpy (str, sessions[n]);
1312 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1313 get_sesslist (FALSE);
1314 get_sesslist (TRUE);
1315 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1317 for (i = 0; i < nsessions; i++)
1318 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1319 0, (LPARAM) (sessions[i]));
1320 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1326 if (LOWORD(wParam) == IDC_SESSLOAD &&
1327 HIWORD(wParam) != BN_CLICKED &&
1328 HIWORD(wParam) != BN_DOUBLECLICKED)
1330 if (LOWORD(wParam) == IDC_SESSLIST &&
1331 HIWORD(wParam) != LBN_DBLCLK)
1334 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1335 LB_GETCURSEL, 0, 0);
1341 isdef = !strcmp(sessions[n], "Default Settings");
1342 load_settings (sessions[n], !isdef, &cfg);
1343 init_dlg_ctrls(hwnd);
1345 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1347 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1349 if (LOWORD(wParam) == IDC_SESSLIST) {
1351 * A double-click on a saved session should
1352 * actually start the session, not just load it.
1353 * Unless it's Default Settings or some other
1354 * host-less set of saved settings.
1363 if (HIWORD(wParam) == BN_CLICKED ||
1364 HIWORD(wParam) == BN_DOUBLECLICKED) {
1365 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1366 LB_GETCURSEL, 0, 0);
1367 if (n == LB_ERR || n == 0) {
1371 del_settings(sessions[n]);
1372 get_sesslist (FALSE);
1373 get_sesslist (TRUE);
1374 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1376 for (i = 0; i < nsessions; i++)
1377 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1378 0, (LPARAM) (sessions[i]));
1379 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1383 if (HIWORD(wParam) == EN_CHANGE)
1384 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1388 if (HIWORD(wParam) == BN_CLICKED ||
1389 HIWORD(wParam) == BN_DOUBLECLICKED)
1390 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1394 if (HIWORD(wParam) == BN_CLICKED ||
1395 HIWORD(wParam) == BN_DOUBLECLICKED)
1396 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1399 if (HIWORD(wParam) == BN_CLICKED ||
1400 HIWORD(wParam) == BN_DOUBLECLICKED)
1404 if (HIWORD(wParam) == BN_CLICKED ||
1405 HIWORD(wParam) == BN_DOUBLECLICKED)
1410 if (HIWORD(wParam) == BN_CLICKED ||
1411 HIWORD(wParam) == BN_DOUBLECLICKED)
1412 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1416 if (HIWORD(wParam) == BN_CLICKED ||
1417 HIWORD(wParam) == BN_DOUBLECLICKED) {
1418 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1419 cfg.nethack_keypad = FALSE;
1423 if (HIWORD(wParam) == BN_CLICKED ||
1424 HIWORD(wParam) == BN_DOUBLECLICKED) {
1425 cfg.app_keypad = FALSE;
1426 cfg.nethack_keypad = TRUE;
1431 if (HIWORD(wParam) == BN_CLICKED ||
1432 HIWORD(wParam) == BN_DOUBLECLICKED)
1433 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1436 if (HIWORD(wParam) == BN_CLICKED ||
1437 HIWORD(wParam) == BN_DOUBLECLICKED)
1438 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1441 if (HIWORD(wParam) == BN_CLICKED ||
1442 HIWORD(wParam) == BN_DOUBLECLICKED)
1443 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1446 if (HIWORD(wParam) == BN_CLICKED ||
1447 HIWORD(wParam) == BN_DOUBLECLICKED)
1448 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1451 if (HIWORD(wParam) == BN_CLICKED ||
1452 HIWORD(wParam) == BN_DOUBLECLICKED)
1453 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1456 if (HIWORD(wParam) == BN_CLICKED ||
1457 HIWORD(wParam) == BN_DOUBLECLICKED)
1458 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1460 case IDC_ECHOBACKEND:
1463 if (HIWORD(wParam) == BN_CLICKED ||
1464 HIWORD(wParam) == BN_DOUBLECLICKED) {
1465 if (LOWORD(wParam)==IDC_ECHOBACKEND) cfg.localecho=LD_BACKEND;
1466 if (LOWORD(wParam)==IDC_ECHOYES) cfg.localecho=LD_YES;
1467 if (LOWORD(wParam)==IDC_ECHONO) cfg.localecho=LD_NO;
1470 case IDC_EDITBACKEND:
1473 if (HIWORD(wParam) == BN_CLICKED ||
1474 HIWORD(wParam) == BN_DOUBLECLICKED) {
1475 if (LOWORD(wParam)==IDC_EDITBACKEND) cfg.localedit=LD_BACKEND;
1476 if (LOWORD(wParam)==IDC_EDITYES) cfg.localedit=LD_YES;
1477 if (LOWORD(wParam)==IDC_EDITNO) cfg.localedit=LD_NO;
1480 case IDC_ALWAYSONTOP:
1481 if (HIWORD(wParam) == BN_CLICKED ||
1482 HIWORD(wParam) == BN_DOUBLECLICKED)
1483 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1486 if (HIWORD(wParam) == BN_CLICKED ||
1487 HIWORD(wParam) == BN_DOUBLECLICKED)
1488 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1490 case IDC_SCROLLDISP:
1491 if (HIWORD(wParam) == BN_CLICKED ||
1492 HIWORD(wParam) == BN_DOUBLECLICKED)
1493 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1495 case IDC_COMPOSEKEY:
1496 if (HIWORD(wParam) == BN_CLICKED ||
1497 HIWORD(wParam) == BN_DOUBLECLICKED)
1498 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1501 if (HIWORD(wParam) == BN_CLICKED ||
1502 HIWORD(wParam) == BN_DOUBLECLICKED)
1503 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1506 if (HIWORD(wParam) == BN_CLICKED ||
1507 HIWORD(wParam) == BN_DOUBLECLICKED)
1508 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1511 if (HIWORD(wParam) == BN_CLICKED ||
1512 HIWORD(wParam) == BN_DOUBLECLICKED)
1513 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1516 if (HIWORD(wParam) == EN_CHANGE)
1517 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1520 if (HIWORD(wParam) == EN_CHANGE)
1521 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1524 if (HIWORD(wParam) == EN_CHANGE)
1525 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1527 case IDC_CHOOSEFONT:
1528 lf.lfHeight = cfg.fontheight;
1529 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1530 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1531 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1532 lf.lfCharSet = cfg.fontcharset;
1533 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1534 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1535 lf.lfQuality = DEFAULT_QUALITY;
1536 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1537 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1538 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1540 cf.lStructSize = sizeof(cf);
1541 cf.hwndOwner = hwnd;
1543 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1544 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1546 if (ChooseFont (&cf)) {
1547 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1548 cfg.font[sizeof(cfg.font)-1] = '\0';
1549 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1550 cfg.fontcharset = lf.lfCharSet;
1551 cfg.fontheight = cf.iPointSize / 10;
1552 fmtfont (fontstatic);
1553 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1557 if (HIWORD(wParam) == BN_CLICKED ||
1558 HIWORD(wParam) == BN_DOUBLECLICKED)
1559 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1562 if (HIWORD(wParam) == BN_CLICKED ||
1563 HIWORD(wParam) == BN_DOUBLECLICKED)
1564 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1567 if (HIWORD(wParam) == BN_CLICKED ||
1568 HIWORD(wParam) == BN_DOUBLECLICKED)
1569 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1572 if (HIWORD(wParam) == BN_CLICKED ||
1573 HIWORD(wParam) == BN_DOUBLECLICKED)
1574 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1577 if (HIWORD(wParam) == BN_CLICKED ||
1578 HIWORD(wParam) == BN_DOUBLECLICKED)
1579 cfg.hide_mouseptr = IsDlgButtonChecked (hwnd, IDC_HIDEMOUSE);
1582 if (HIWORD(wParam) == BN_CLICKED ||
1583 HIWORD(wParam) == BN_DOUBLECLICKED)
1584 cfg.cursor_type = 0;
1587 if (HIWORD(wParam) == BN_CLICKED ||
1588 HIWORD(wParam) == BN_DOUBLECLICKED)
1589 cfg.cursor_type = 1;
1592 if (HIWORD(wParam) == BN_CLICKED ||
1593 HIWORD(wParam) == BN_DOUBLECLICKED)
1594 cfg.cursor_type = 2;
1597 if (HIWORD(wParam) == BN_CLICKED ||
1598 HIWORD(wParam) == BN_DOUBLECLICKED)
1599 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1602 if (HIWORD(wParam) == BN_CLICKED ||
1603 HIWORD(wParam) == BN_DOUBLECLICKED)
1604 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1607 if (HIWORD(wParam) == BN_CLICKED ||
1608 HIWORD(wParam) == BN_DOUBLECLICKED)
1609 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1612 if (HIWORD(wParam) == EN_CHANGE)
1613 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1614 sizeof(cfg.wintitle)-1);
1619 if (HIWORD(wParam) == BN_CLICKED ||
1620 HIWORD(wParam) == BN_DOUBLECLICKED) {
1621 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_COEALWAYS) ? COE_ALWAYS :
1622 IsDlgButtonChecked (hwnd, IDC_COENEVER) ? COE_NEVER :
1627 if (HIWORD(wParam) == BN_CLICKED ||
1628 HIWORD(wParam) == BN_DOUBLECLICKED)
1629 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1632 if (HIWORD(wParam) == EN_CHANGE)
1633 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1634 sizeof(cfg.termtype)-1);
1637 if (HIWORD(wParam) == EN_CHANGE)
1638 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1639 sizeof(cfg.logfilename)-1);
1642 memset(&of, 0, sizeof(of));
1643 #ifdef OPENFILENAME_SIZE_VERSION_400
1644 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1646 of.lStructSize = sizeof(of);
1648 of.hwndOwner = hwnd;
1649 of.lpstrFilter = "All Files\0*\0\0\0";
1650 of.lpstrCustomFilter = NULL;
1651 of.nFilterIndex = 1;
1652 of.lpstrFile = filename; strcpy(filename, cfg.logfilename);
1653 of.nMaxFile = sizeof(filename);
1654 of.lpstrFileTitle = NULL;
1655 of.lpstrInitialDir = NULL;
1656 of.lpstrTitle = "Select session log file";
1658 if (GetSaveFileName(&of)) {
1659 strcpy(cfg.logfilename, filename);
1660 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
1664 case IDC_LSTATASCII:
1666 if (HIWORD(wParam) == BN_CLICKED ||
1667 HIWORD(wParam) == BN_DOUBLECLICKED) {
1668 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1669 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1670 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1675 if (HIWORD(wParam) == EN_CHANGE)
1676 GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed,
1677 sizeof(cfg.termspeed)-1);
1680 if (HIWORD(wParam) == EN_CHANGE)
1681 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1682 sizeof(cfg.username)-1);
1684 case IDC_RLLUSEREDIT:
1685 if (HIWORD(wParam) == EN_CHANGE)
1686 GetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername,
1687 sizeof(cfg.localusername)-1);
1691 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1694 if (HIWORD(wParam) == BN_CLICKED ||
1695 HIWORD(wParam) == BN_DOUBLECLICKED) {
1696 char str[sizeof(cfg.environmt)];
1698 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1703 p = str + strlen(str);
1705 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1715 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1717 p[strlen(str)+1] = '\0';
1718 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1720 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1721 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1723 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1724 MB_OK | MB_ICONERROR);
1729 if (HIWORD(wParam) != BN_CLICKED &&
1730 HIWORD(wParam) != BN_DOUBLECLICKED)
1732 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1738 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1763 if (HIWORD(wParam) == BN_CLICKED ||
1764 HIWORD(wParam) == BN_DOUBLECLICKED)
1765 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1768 if (HIWORD(wParam) == BN_CLICKED ||
1769 HIWORD(wParam) == BN_DOUBLECLICKED)
1770 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1773 if (HIWORD(wParam) == BN_CLICKED ||
1774 HIWORD(wParam) == BN_DOUBLECLICKED)
1775 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1778 if (HIWORD(wParam) == BN_CLICKED ||
1779 HIWORD(wParam) == BN_DOUBLECLICKED)
1780 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1782 case IDC_CIPHER3DES:
1783 case IDC_CIPHERBLOWF:
1786 if (HIWORD(wParam) == BN_CLICKED ||
1787 HIWORD(wParam) == BN_DOUBLECLICKED) {
1788 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1789 cfg.cipher = CIPHER_3DES;
1790 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1791 cfg.cipher = CIPHER_BLOWFISH;
1792 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1793 cfg.cipher = CIPHER_DES;
1794 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERAES))
1795 cfg.cipher = CIPHER_AES;
1800 if (HIWORD(wParam) == BN_CLICKED ||
1801 HIWORD(wParam) == BN_DOUBLECLICKED) {
1802 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1804 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1809 if (HIWORD(wParam) == BN_CLICKED ||
1810 HIWORD(wParam) == BN_DOUBLECLICKED)
1811 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1814 if (HIWORD(wParam) == EN_CHANGE)
1815 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1816 sizeof(cfg.keyfile)-1);
1819 if (HIWORD(wParam) == EN_CHANGE)
1820 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1821 sizeof(cfg.remote_cmd)-1);
1824 memset(&of, 0, sizeof(of));
1825 #ifdef OPENFILENAME_SIZE_VERSION_400
1826 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1828 of.lStructSize = sizeof(of);
1830 of.hwndOwner = hwnd;
1831 of.lpstrFilter = "All Files\0*\0\0\0";
1832 of.lpstrCustomFilter = NULL;
1833 of.nFilterIndex = 1;
1834 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1835 of.nMaxFile = sizeof(filename);
1836 of.lpstrFileTitle = NULL;
1837 of.lpstrInitialDir = NULL;
1838 of.lpstrTitle = "Select Public Key File";
1840 if (GetOpenFileName(&of)) {
1841 strcpy(cfg.keyfile, filename);
1842 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1847 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1853 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1858 for (i=0; i<256; i++)
1859 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1862 cfg.wordness[i] = n;
1863 SendDlgItemMessage (hwnd, IDC_CCLIST,
1864 LB_DELETESTRING, i, 0);
1865 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1866 (i>=0x21 && i != 0x7F) ? i : ' ',
1868 SendDlgItemMessage (hwnd, IDC_CCLIST,
1875 case IDC_BOLDCOLOUR:
1876 if (HIWORD(wParam) == BN_CLICKED ||
1877 HIWORD(wParam) == BN_DOUBLECLICKED) {
1879 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1880 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1881 if (n != 12+10*cfg.bold_colour) {
1883 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1884 LB_DELETESTRING, i, 0);
1885 for (i=0; i<22; i++)
1886 if (cfg.bold_colour || permcolour[i])
1887 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1889 (LPARAM) colours[i]);
1894 if (HIWORD(wParam) == BN_CLICKED ||
1895 HIWORD(wParam) == BN_DOUBLECLICKED)
1896 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1898 case IDC_COLOURLIST:
1899 if (HIWORD(wParam) == LBN_DBLCLK ||
1900 HIWORD(wParam) == LBN_SELCHANGE) {
1901 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1903 if (!cfg.bold_colour)
1904 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1905 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1906 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1907 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1911 if (HIWORD(wParam) == BN_CLICKED ||
1912 HIWORD(wParam) == BN_DOUBLECLICKED) {
1913 static CHOOSECOLOR cc;
1914 static DWORD custom[16] = {0}; /* zero initialisers */
1915 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1917 if (!cfg.bold_colour)
1918 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1919 cc.lStructSize = sizeof(cc);
1920 cc.hwndOwner = hwnd;
1921 cc.hInstance = (HWND)hinst;
1922 cc.lpCustColors = custom;
1923 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1925 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1926 if (ChooseColor(&cc)) {
1928 (unsigned char) (cc.rgbResult & 0xFF);
1930 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1932 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1933 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1935 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1937 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1943 case IDC_KOI8WIN1251:
1944 case IDC_88592WIN1250:
1945 case IDC_88592CP852:
1946 cfg.xlat_enablekoiwin =
1947 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1948 cfg.xlat_88592w1250 =
1949 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1950 cfg.xlat_88592cp852 =
1951 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1953 case IDC_CAPSLOCKCYR:
1954 if (HIWORD(wParam) == BN_CLICKED ||
1955 HIWORD(wParam) == BN_DOUBLECLICKED) {
1956 cfg.xlat_capslockcyr =
1957 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1960 case IDC_VTXWINDOWS:
1965 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1966 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1967 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1970 case IDC_X11_FORWARD:
1971 if (HIWORD(wParam) == BN_CLICKED ||
1972 HIWORD(wParam) == BN_DOUBLECLICKED)
1973 cfg.x11_forward = IsDlgButtonChecked (hwnd, IDC_X11_FORWARD);
1975 case IDC_X11_DISPLAY:
1976 if (HIWORD(wParam) == EN_CHANGE)
1977 GetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display,
1978 sizeof(cfg.x11_display)-1);
1983 EndDialog (hwnd, 0);
1986 /* Grrr Explorer will maximize Dialogs! */
1988 if (wParam == SIZE_MAXIMIZED)
1995 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1996 WPARAM wParam, LPARAM lParam) {
1997 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1999 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2000 EnableWindow(hwnd, 0);
2001 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2002 GetParent(hwnd), AboutProc);
2003 EnableWindow(hwnd, 1);
2004 SetActiveWindow(hwnd);
2006 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
2009 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
2010 WPARAM wParam, LPARAM lParam) {
2011 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
2014 void defuse_showwindow(void) {
2016 * Work around the fact that the app's first call to ShowWindow
2017 * will ignore the default in favour of the shell-provided
2022 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2024 ShowWindow(hwnd, SW_HIDE);
2025 DestroyWindow(hwnd);
2029 int do_config (void) {
2033 savedsession[0] = '\0';
2034 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2035 get_sesslist(FALSE);
2040 int do_reconfig (HWND hwnd) {
2044 backup_cfg = cfg; /* structure copy */
2045 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2047 cfg = backup_cfg; /* structure copy */
2052 void logevent (char *string) {
2056 if (nevents >= negsize) {
2058 events = srealloc (events, negsize * sizeof(*events));
2062 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t", localtime(&t));
2064 events[nevents] = smalloc(strlen(timebuf)+strlen(string)+1);
2065 strcpy(events[nevents], timebuf);
2066 strcat(events[nevents], string);
2069 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
2070 0, (LPARAM)events[nevents]);
2071 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2072 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
2077 void showeventlog (HWND hwnd) {
2079 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2081 ShowWindow (logbox, SW_SHOWNORMAL);
2083 SetActiveWindow(logbox);
2086 void showabout (HWND hwnd) {
2087 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),hwnd, AboutProc);
2090 void verify_ssh_host_key(char *host, int port, char *keytype,
2091 char *keystr, char *fingerprint) {
2094 static const char absentmsg[] =
2095 "The server's host key is not cached in the registry. You\n"
2096 "have no guarantee that the server is the computer you\n"
2098 "The server's key fingerprint is:\n"
2100 "If you trust this host, hit Yes to add the key to\n"
2101 "PuTTY's cache and carry on connecting.\n"
2102 "If you do not trust this host, hit No to abandon the\n"
2105 static const char wrongmsg[] =
2106 "WARNING - POTENTIAL SECURITY BREACH!\n"
2108 "The server's host key does not match the one PuTTY has\n"
2109 "cached in the registry. This means that either the\n"
2110 "server administrator has changed the host key, or you\n"
2111 "have actually connected to another computer pretending\n"
2112 "to be the server.\n"
2113 "The new key fingerprint is:\n"
2115 "If you were expecting this change and trust the new key,\n"
2116 "hit Yes to update PuTTY's cache and continue connecting.\n"
2117 "If you want to carry on connecting but without updating\n"
2118 "the cache, hit No.\n"
2119 "If you want to abandon the connection completely, hit\n"
2120 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2123 static const char mbtitle[] = "PuTTY Security Alert";
2126 char message[160+ /* sensible fingerprint max size */
2127 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2128 sizeof(absentmsg) : sizeof(wrongmsg))];
2131 * Verify the key against the registry.
2133 ret = verify_host_key(host, port, keytype, keystr);
2135 if (ret == 0) /* success - key matched OK */
2137 if (ret == 2) { /* key was different */
2139 sprintf(message, wrongmsg, fingerprint);
2140 mbret = MessageBox(NULL, message, mbtitle,
2141 MB_ICONWARNING | MB_YESNOCANCEL);
2143 store_host_key(host, port, keytype, keystr);
2144 if (mbret == IDCANCEL)
2147 if (ret == 1) { /* key was absent */
2149 sprintf(message, absentmsg, fingerprint);
2150 mbret = MessageBox(NULL, message, mbtitle,
2151 MB_ICONWARNING | MB_YESNO);
2154 store_host_key(host, port, keytype, keystr);
2159 * Ask whether to wipe a session log file before writing to it.
2160 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2162 int askappend(char *filename) {
2163 static const char mbtitle[] = "PuTTY Log to File";
2164 static const char msgtemplate[] =
2165 "The session log file \"%.*s\" already exists.\n"
2166 "You can overwrite it with a new session log,\n"
2167 "append your session log to the end of it,\n"
2168 "or disable session logging for this session.\n"
2169 "Hit Yes to wipe the file, No to append to it,\n"
2170 "or Cancel to disable logging.";
2171 char message[sizeof(msgtemplate) + FILENAME_MAX];
2173 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2175 mbret = MessageBox(NULL, message, mbtitle,
2176 MB_ICONQUESTION | MB_YESNOCANCEL);
2179 else if (mbret == IDNO)