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,
417 translationpanelstart,
418 IDC_TITLE_TRANSLATION,
419 IDC_BOX_TRANSLATION1,
420 IDC_BOX_TRANSLATION2,
421 IDC_BOX_TRANSLATION3,
446 static const char *const colours[] = {
447 "Default Foreground", "Default Bold Foreground",
448 "Default Background", "Default Bold Background",
449 "Cursor Text", "Cursor Colour",
450 "ANSI Black", "ANSI Black Bold",
451 "ANSI Red", "ANSI Red Bold",
452 "ANSI Green", "ANSI Green Bold",
453 "ANSI Yellow", "ANSI Yellow Bold",
454 "ANSI Blue", "ANSI Blue Bold",
455 "ANSI Magenta", "ANSI Magenta Bold",
456 "ANSI Cyan", "ANSI Cyan Bold",
457 "ANSI White", "ANSI White Bold"
459 static const int permcolour[] = {
460 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
461 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
462 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
465 static void fmtfont (char *buf) {
466 sprintf (buf, "Font: %s, ", cfg.font);
468 strcat(buf, "bold, ");
469 if (cfg.fontheight == 0)
470 strcat (buf, "default height");
472 sprintf (buf+strlen(buf), "%d-point",
473 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
476 static void init_dlg_ctrls(HWND hwnd) {
478 char fontstatic[256];
480 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
481 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
484 n = SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
486 SendDlgItemMessage (hwnd, IDC_SESSLIST,
487 LB_DELETESTRING, i, 0);
488 for (i = 0; i < nsessions; i++)
489 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
490 0, (LPARAM) (sessions[i]));
492 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
493 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
494 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
495 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET :
496 cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW );
497 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
499 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
500 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
501 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
502 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
503 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
504 cfg.funky_type == 0 ? IDC_FUNCTILDE :
505 cfg.funky_type == 1 ? IDC_FUNCLINUX :
506 cfg.funky_type == 2 ? IDC_FUNCXTERM :
507 cfg.funky_type == 3 ? IDC_FUNCVT400 :
509 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
510 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
511 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
512 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
513 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
514 cfg.nethack_keypad ? IDC_KPNH :
515 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
516 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
517 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
518 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
519 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
520 CheckRadioButton (hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
521 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND:
522 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
523 CheckRadioButton (hwnd, IDC_EDITBACKEND, IDC_EDITNO,
524 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND:
525 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
526 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
527 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
528 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
530 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
531 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
532 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
533 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
534 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
535 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
536 fmtfont (fontstatic);
537 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
538 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
539 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
540 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
542 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
543 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
544 CheckDlgButton (hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
545 CheckRadioButton (hwnd, IDC_CURBLOCK, IDC_CURVERT,
546 cfg.cursor_type==0 ? IDC_CURBLOCK :
547 cfg.cursor_type==1 ? IDC_CURUNDER : IDC_CURVERT);
548 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
549 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
550 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
551 CheckRadioButton (hwnd, IDC_COEALWAYS, IDC_COENORMAL,
552 cfg.close_on_exit==COE_NORMAL ? IDC_COENORMAL :
553 cfg.close_on_exit==COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
554 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
556 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
557 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
558 SetDlgItemText (hwnd, IDC_R_TSEDIT, cfg.termspeed);
559 SetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername);
560 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
561 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
562 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
563 cfg.logtype == 0 ? IDC_LSTATOFF :
564 cfg.logtype == 1 ? IDC_LSTATASCII :
567 char *p = cfg.environmt;
569 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
574 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
575 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
577 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
578 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
579 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
580 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
581 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
582 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
583 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERAES,
584 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
585 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
586 cfg.cipher == CIPHER_AES ? IDC_CIPHERAES :
588 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
589 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
590 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
591 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
592 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
594 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
595 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
596 CheckDlgButton (hwnd, IDC_RAWCNP, cfg.rawcnp);
598 static int tabs[4] = {25, 61, 96, 128};
599 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
602 for (i=0; i<256; i++) {
604 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
605 (i>=0x21 && i != 0x7F) ? i : ' ',
607 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
611 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
612 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
615 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
617 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
618 LB_DELETESTRING, i, 0);
620 if (cfg.bold_colour || permcolour[i])
621 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
622 (LPARAM) colours[i]);
624 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
625 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
626 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
627 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
629 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
630 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
631 cfg.xlat_88592cp852 ? IDC_88592CP852 :
632 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
634 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
635 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
636 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
637 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
638 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
641 CheckDlgButton (hwnd, IDC_X11_FORWARD, cfg.x11_forward);
642 SetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display);
645 struct treeview_faff {
650 static HTREEITEM treeview_insert(struct treeview_faff *faff,
651 int level, char *text) {
655 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
656 ins.hInsertAfter = faff->lastat[level];
657 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
658 #define INSITEM DUMMYUNIONNAME.item
662 ins.INSITEM.mask = TVIF_TEXT;
663 ins.INSITEM.pszText = text;
664 newitem = TreeView_InsertItem(faff->treeview, &ins);
666 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
667 faff->lastat[level] = newitem;
668 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
673 * Create the panelfuls of controls in the configuration box.
675 static void create_controls(HWND hwnd, int dlgtype, int panel) {
676 if (panel == sessionpanelstart) {
677 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
679 ctlposinit(&cp, hwnd, 80, 3, 13);
680 bartitle(&cp, "Basic options for your PuTTY session",
683 beginbox(&cp, "Specify your connection by host name",
686 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
687 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
688 if (backends[3].backend == NULL) {
689 /* this is PuTTYtel, so only three protocols available */
690 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
692 "&Telnet", IDC_PROTTELNET,
693 "Rlog&in", IDC_PROTRLOGIN, NULL);
695 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
697 "&Telnet", IDC_PROTTELNET,
698 "Rlog&in", IDC_PROTRLOGIN,
707 beginbox(&cp, "Load, save or delete a stored session",
709 sesssaver(&cp, "Sav&ed Sessions",
710 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
711 "&Load", IDC_SESSLOAD,
712 "&Save", IDC_SESSSAVE,
713 "&Delete", IDC_SESSDEL, NULL);
716 beginbox(&cp, NULL, IDC_BOX_SESSION3);
717 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
718 "Always", IDC_COEALWAYS,
719 "Never", IDC_COENEVER,
720 "Only on clean exit", IDC_COENORMAL, NULL);
724 if (panel == loggingpanelstart) {
725 /* The Logging panel. Accelerators used: [acgo] tplfw */
727 ctlposinit(&cp, hwnd, 80, 3, 13);
728 bartitle(&cp, "Options controlling session logging",
730 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
732 "Session logging:", IDC_LSTATSTATIC,
733 "Logging &turned off completely", IDC_LSTATOFF,
734 "Log &printable output only", IDC_LSTATASCII,
735 "&Log all session output", IDC_LSTATRAW, NULL);
736 editbutton(&cp, "Log &file name:",
737 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
742 if (panel == terminalpanelstart) {
743 /* The Terminal panel. Accelerators used: [acgo] wdlben ht */
745 ctlposinit(&cp, hwnd, 80, 3, 13);
746 bartitle(&cp, "Options controlling the terminal emulation",
748 beginbox(&cp, "Set various terminal options",
750 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
751 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
752 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
753 checkbox(&cp, "&Beep enabled", IDC_BEEP);
754 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
755 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
758 beginbox(&cp, "Line discipline options",
760 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
761 "Auto", IDC_ECHOBACKEND,
762 "Force on", IDC_ECHOYES,
763 "Force off", IDC_ECHONO, NULL);
764 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
765 "Auto", IDC_EDITBACKEND,
766 "Force on", IDC_EDITYES,
767 "Force off", IDC_EDITNO, NULL);
771 if (panel == keyboardpanelstart) {
772 /* The Keyboard panel. Accelerators used: [acgo] h?sr~lxv unpymie t */
774 ctlposinit(&cp, hwnd, 80, 3, 13);
775 bartitle(&cp, "Options controlling the effects of keys",
777 beginbox(&cp, "Change the sequences sent by:",
779 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
780 "Control-&H", IDC_DEL008,
781 "Control-&? (127)", IDC_DEL127, NULL);
782 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
783 "&Standard", IDC_HOMETILDE,
784 "&rxvt", IDC_HOMERXVT, NULL);
785 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
786 "ESC[n&~", IDC_FUNCTILDE,
787 "&Linux", IDC_FUNCLINUX,
788 "&Xterm R6", IDC_FUNCXTERM,
789 "&VT400", IDC_FUNCVT400, NULL);
791 beginbox(&cp, "Application keypad settings:",
794 "Application c&ursor keys totally disabled",
796 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
797 "&Normal", IDC_CURNORMAL,
798 "A&pplication", IDC_CURAPPLIC, NULL);
800 "Application ke&ypad keys totally disabled",
802 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
803 "Nor&mal", IDC_KPNORMAL,
804 "Appl&ication", IDC_KPAPPLIC,
805 "N&etHack", IDC_KPNH, NULL);
807 beginbox(&cp, "Enable extra keyboard features:",
809 checkbox(&cp, "Application and AltGr ac&t as Compose key",
814 if (panel == windowpanelstart) {
815 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
817 ctlposinit(&cp, hwnd, 80, 3, 13);
818 bartitle(&cp, "Options controlling PuTTY's window",
820 beginbox(&cp, "Set the size of the window",
823 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
824 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
826 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
828 beginbox(&cp, "Control the scrollback in the window",
830 staticedit(&cp, "Lines of &scrollback",
831 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
832 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
833 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
834 checkbox(&cp, "Reset scrollback on dis&play activity",
837 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
838 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
839 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
840 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
841 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
842 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
846 if (panel == appearancepanelstart) {
847 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p */
849 ctlposinit(&cp, hwnd, 80, 3, 13);
850 bartitle(&cp, "Options controlling PuTTY's appearance",
851 IDC_TITLE_APPEARANCE);
852 beginbox(&cp, "Adjust the use of the cursor",
853 IDC_BOX_APPEARANCE1);
854 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
855 "B&lock", IDC_CURBLOCK,
856 "&Underline", IDC_CURUNDER,
857 "&Vertical line", IDC_CURVERT,
859 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
861 beginbox(&cp, "Set the font used in the terminal window",
862 IDC_BOX_APPEARANCE2);
863 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
865 beginbox(&cp, "Adjust the use of the window title",
866 IDC_BOX_APPEARANCE3);
868 "Window &title:", IDC_WINTITLE,
869 IDC_WINEDIT, 100, NULL);
870 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
872 beginbox(&cp, "Adjust the use of the mouse pointer",
873 IDC_BOX_APPEARANCE4);
874 checkbox(&cp, "Hide mouse &pointer when typing in window",
879 if (panel == translationpanelstart) {
880 /* The Translation panel. Accelerators used: [acgo] xbep t s */
882 ctlposinit(&cp, hwnd, 80, 3, 13);
883 bartitle(&cp, "Options controlling character set translation",
884 IDC_TITLE_TRANSLATION);
885 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
886 IDC_BOX_TRANSLATION1);
888 "Handling of line drawing characters:", IDC_VTSTATIC,
889 "Font has &XWindows encoding", IDC_VTXWINDOWS,
890 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
891 "Use font in O&EM mode only", IDC_VTOEMONLY,
892 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
893 IDC_VTPOORMAN, NULL);
895 beginbox(&cp, "Enable character set translation on received data",
896 IDC_BOX_TRANSLATION2);
898 "Character set &translation:", IDC_XLATSTATIC,
900 "KOI8 / Win-1251", IDC_KOI8WIN1251,
901 "ISO-8859-2 / Win-1250", IDC_88592WIN1250,
902 "ISO-8859-2 / CP852", IDC_88592CP852, NULL);
904 beginbox(&cp, "Enable character set translation on input data",
905 IDC_BOX_TRANSLATION3);
906 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
911 if (panel == selectionpanelstart) {
912 /* The Selection panel. Accelerators used: [acgo] d wx hst */
914 ctlposinit(&cp, hwnd, 80, 3, 13);
915 bartitle(&cp, "Options controlling copy and paste",
916 IDC_TITLE_SELECTION);
917 beginbox(&cp, "Translation of pasted characters",
919 checkbox(&cp, "&Don't translate line drawing chars into +, - and |",
922 beginbox(&cp, "Control which mouse button does which thing",
924 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
925 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
926 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
929 beginbox(&cp, "Control the select-one-word-at-a-time mode",
931 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
932 "&Set", IDC_CCSET, IDC_CCEDIT,
933 "&to class", IDC_CCSTATIC2);
937 if (panel == colourspanelstart) {
938 /* The Colours panel. Accelerators used: [acgo] blum */
940 ctlposinit(&cp, hwnd, 80, 3, 13);
941 bartitle(&cp, "Options controlling use of colours",
943 beginbox(&cp, "General options for colour usage",
945 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
946 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
948 beginbox(&cp, "Adjust the precise colours PuTTY displays",
950 colouredit(&cp, "Select a colo&ur and then click to modify it:",
951 IDC_COLOURSTATIC, IDC_COLOURLIST,
952 "&Modify...", IDC_CHANGE,
953 "Red:", IDC_RSTATIC, IDC_RVALUE,
954 "Green:", IDC_GSTATIC, IDC_GVALUE,
955 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
959 if (panel == connectionpanelstart) {
960 /* The Connection panel. Accelerators used: [acgo] tuk */
962 ctlposinit(&cp, hwnd, 80, 3, 13);
963 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
965 beginbox(&cp, "Data to send to the server",
966 IDC_BOX_CONNECTION1);
967 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
968 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
971 beginbox(&cp, "Sending of null packets to keep session active",
972 IDC_BOX_CONNECTION2);
973 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
974 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
978 if (panel == telnetpanelstart) {
979 /* The Telnet panel. Accelerators used: [acgo] svldr bf */
981 ctlposinit(&cp, hwnd, 80, 3, 13);
983 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
984 beginbox(&cp, "Data to send to the server",
986 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
987 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
988 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
989 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
991 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
993 beginbox(&cp, "Telnet protocol adjustments",
995 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
996 "&BSD (commonplace)", IDC_EMBSD,
997 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1002 if (panel == rloginpanelstart) {
1003 /* The Rlogin panel. Accelerators used: [acgo] sl */
1005 ctlposinit(&cp, hwnd, 80, 3, 13);
1007 bartitle(&cp, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN);
1008 beginbox(&cp, "Data to send to the server",
1010 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC, IDC_R_TSEDIT, 50);
1011 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC, IDC_RLLUSEREDIT, 50);
1016 if (panel == sshpanelstart) {
1017 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1019 ctlposinit(&cp, hwnd, 80, 3, 13);
1021 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
1022 beginbox(&cp, "Data to send to the server",
1025 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1028 beginbox(&cp, "Authentication options",
1030 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1032 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1033 editbutton(&cp, "Private &key file for authentication:",
1034 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
1036 beginbox(&cp, "Protocol options",
1038 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1039 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1040 radioline(&cp, "Preferred SSH protocol version:",
1041 IDC_SSHPROTSTATIC, 2,
1042 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1043 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 4,
1044 "&3DES", IDC_CIPHER3DES,
1045 "&Blowfish", IDC_CIPHERBLOWF,
1046 "&DES", IDC_CIPHERDES,
1047 "AE&S", IDC_CIPHERAES,
1049 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1055 if (panel == tunnelspanelstart) {
1056 /* The Tunnels panel. Accelerators used: [acgo] ex */
1058 ctlposinit(&cp, hwnd, 80, 3, 13);
1060 bartitle(&cp, "Options controlling SSH tunnelling",
1062 beginbox(&cp, "X11 forwarding options",
1064 checkbox(&cp, "&Enable X11 forwarding",
1066 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1067 IDC_X11_DISPLAY, 50, NULL);
1074 * This function is the configuration box.
1076 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1077 WPARAM wParam, LPARAM lParam,
1080 struct treeview_faff tvfaff;
1083 char filename[sizeof(cfg.keyfile)];
1086 char fontstatic[256];
1088 struct servent * service;
1094 SetWindowLong(hwnd, GWL_USERDATA, 0);
1096 * Centre the window.
1098 { /* centre the window */
1101 hw = GetDesktopWindow();
1102 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1103 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1104 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1105 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1109 * Create the tree view.
1116 r.left = 3; r.right = r.left + 75;
1117 r.top = 3; r.bottom = r.top + 10;
1118 MapDialogRect(hwnd, &r);
1119 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1120 WS_CHILD | WS_VISIBLE,
1122 r.right-r.left, r.bottom-r.top,
1123 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
1124 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1125 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1127 r.left = 3; r.right = r.left + 75;
1128 r.top = 13; r.bottom = r.top + 206;
1129 MapDialogRect(hwnd, &r);
1130 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1131 WS_CHILD | WS_VISIBLE |
1132 WS_TABSTOP | TVS_HASLINES |
1133 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
1134 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
1136 r.right-r.left, r.bottom-r.top,
1137 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
1138 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1139 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1140 tvfaff.treeview = treeview;
1141 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1145 * Set up the tree view contents.
1147 hsession = treeview_insert(&tvfaff, 0, "Session");
1148 treeview_insert(&tvfaff, 1, "Logging");
1149 treeview_insert(&tvfaff, 0, "Terminal");
1150 treeview_insert(&tvfaff, 1, "Keyboard");
1151 treeview_insert(&tvfaff, 0, "Window");
1152 treeview_insert(&tvfaff, 1, "Appearance");
1153 treeview_insert(&tvfaff, 1, "Translation");
1154 treeview_insert(&tvfaff, 1, "Selection");
1155 treeview_insert(&tvfaff, 1, "Colours");
1156 treeview_insert(&tvfaff, 0, "Connection");
1158 treeview_insert(&tvfaff, 1, "Telnet");
1159 treeview_insert(&tvfaff, 1, "Rlogin");
1160 if (backends[3].backend != NULL) {
1161 treeview_insert(&tvfaff, 1, "SSH");
1162 treeview_insert(&tvfaff, 2, "Tunnels");
1167 * Put the treeview selection on to the Session panel. This
1168 * should also cause creation of the relevant controls.
1170 TreeView_SelectItem(treeview, hsession);
1173 * Set focus into the first available control.
1177 ctl = GetDlgItem(hwnd, IDC_HOST);
1178 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1182 SetWindowLong(hwnd, GWL_USERDATA, 1);
1186 * Button release should trigger WM_OK if there was a
1187 * previous double click on the session list.
1191 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1194 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1195 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1196 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1201 item.pszText = buffer;
1202 item.cchTextMax = sizeof(buffer);
1203 item.mask = TVIF_TEXT;
1204 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1205 for (j = controlstartvalue; j < controlendvalue; j++) {
1206 HWND item = GetDlgItem(hwnd, j);
1208 DestroyWindow(item);
1210 if (!strcmp(buffer, "Session"))
1211 create_controls(hwnd, dlgtype, sessionpanelstart);
1212 if (!strcmp(buffer, "Logging"))
1213 create_controls(hwnd, dlgtype, loggingpanelstart);
1214 if (!strcmp(buffer, "Keyboard"))
1215 create_controls(hwnd, dlgtype, keyboardpanelstart);
1216 if (!strcmp(buffer, "Terminal"))
1217 create_controls(hwnd, dlgtype, terminalpanelstart);
1218 if (!strcmp(buffer, "Window"))
1219 create_controls(hwnd, dlgtype, windowpanelstart);
1220 if (!strcmp(buffer, "Appearance"))
1221 create_controls(hwnd, dlgtype, appearancepanelstart);
1222 if (!strcmp(buffer, "Tunnels"))
1223 create_controls(hwnd, dlgtype, tunnelspanelstart);
1224 if (!strcmp(buffer, "Connection"))
1225 create_controls(hwnd, dlgtype, connectionpanelstart);
1226 if (!strcmp(buffer, "Telnet"))
1227 create_controls(hwnd, dlgtype, telnetpanelstart);
1228 if (!strcmp(buffer, "Rlogin"))
1229 create_controls(hwnd, dlgtype, rloginpanelstart);
1230 if (!strcmp(buffer, "SSH"))
1231 create_controls(hwnd, dlgtype, sshpanelstart);
1232 if (!strcmp(buffer, "Selection"))
1233 create_controls(hwnd, dlgtype, selectionpanelstart);
1234 if (!strcmp(buffer, "Colours"))
1235 create_controls(hwnd, dlgtype, colourspanelstart);
1236 if (!strcmp(buffer, "Translation"))
1237 create_controls(hwnd, dlgtype, translationpanelstart);
1239 init_dlg_ctrls(hwnd);
1241 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1247 * Only process WM_COMMAND once the dialog is fully formed.
1249 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1252 EndDialog (hwnd, 1);
1257 EndDialog (hwnd, 0);
1259 case IDC_PROTTELNET:
1260 case IDC_PROTRLOGIN:
1263 if (HIWORD(wParam) == BN_CLICKED ||
1264 HIWORD(wParam) == BN_DOUBLECLICKED) {
1265 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1266 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1267 int k = IsDlgButtonChecked (hwnd, IDC_PROTRLOGIN);
1268 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN : PROT_RAW ;
1269 if ((cfg.protocol == PROT_SSH && cfg.port != 22) ||
1270 (cfg.protocol == PROT_TELNET && cfg.port != 23) ||
1271 (cfg.protocol == PROT_RLOGIN && cfg.port != 513)) {
1272 cfg.port = i ? 22 : j ? 23 : 513;
1273 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1278 if (HIWORD(wParam) == EN_CHANGE)
1279 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1280 sizeof(cfg.host)-1);
1283 if (HIWORD(wParam) == EN_CHANGE) {
1284 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1285 if (isdigit(portname[0]))
1286 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1288 service = getservbyname(portname, NULL);
1289 if (service) cfg.port = ntohs(service->s_port);
1295 if (HIWORD(wParam) == EN_CHANGE) {
1296 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1298 GetDlgItemText (hwnd, IDC_SESSEDIT,
1299 savedsession, sizeof(savedsession)-1);
1300 savedsession[sizeof(savedsession)-1] = '\0';
1304 if (HIWORD(wParam) == BN_CLICKED ||
1305 HIWORD(wParam) == BN_DOUBLECLICKED) {
1310 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1312 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1313 LB_GETCURSEL, 0, 0);
1318 strcpy (str, sessions[n]);
1320 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1321 get_sesslist (FALSE);
1322 get_sesslist (TRUE);
1323 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1325 for (i = 0; i < nsessions; i++)
1326 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1327 0, (LPARAM) (sessions[i]));
1328 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1334 if (LOWORD(wParam) == IDC_SESSLOAD &&
1335 HIWORD(wParam) != BN_CLICKED &&
1336 HIWORD(wParam) != BN_DOUBLECLICKED)
1338 if (LOWORD(wParam) == IDC_SESSLIST &&
1339 HIWORD(wParam) != LBN_DBLCLK)
1342 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1343 LB_GETCURSEL, 0, 0);
1349 isdef = !strcmp(sessions[n], "Default Settings");
1350 load_settings (sessions[n], !isdef, &cfg);
1351 init_dlg_ctrls(hwnd);
1353 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1355 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1357 if (LOWORD(wParam) == IDC_SESSLIST) {
1359 * A double-click on a saved session should
1360 * actually start the session, not just load it.
1361 * Unless it's Default Settings or some other
1362 * host-less set of saved settings.
1371 if (HIWORD(wParam) == BN_CLICKED ||
1372 HIWORD(wParam) == BN_DOUBLECLICKED) {
1373 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1374 LB_GETCURSEL, 0, 0);
1375 if (n == LB_ERR || n == 0) {
1379 del_settings(sessions[n]);
1380 get_sesslist (FALSE);
1381 get_sesslist (TRUE);
1382 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1384 for (i = 0; i < nsessions; i++)
1385 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1386 0, (LPARAM) (sessions[i]));
1387 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1391 if (HIWORD(wParam) == EN_CHANGE)
1392 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1396 if (HIWORD(wParam) == BN_CLICKED ||
1397 HIWORD(wParam) == BN_DOUBLECLICKED)
1398 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1402 if (HIWORD(wParam) == BN_CLICKED ||
1403 HIWORD(wParam) == BN_DOUBLECLICKED)
1404 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1407 if (HIWORD(wParam) == BN_CLICKED ||
1408 HIWORD(wParam) == BN_DOUBLECLICKED)
1412 if (HIWORD(wParam) == BN_CLICKED ||
1413 HIWORD(wParam) == BN_DOUBLECLICKED)
1418 if (HIWORD(wParam) == BN_CLICKED ||
1419 HIWORD(wParam) == BN_DOUBLECLICKED)
1420 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1424 if (HIWORD(wParam) == BN_CLICKED ||
1425 HIWORD(wParam) == BN_DOUBLECLICKED) {
1426 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1427 cfg.nethack_keypad = FALSE;
1431 if (HIWORD(wParam) == BN_CLICKED ||
1432 HIWORD(wParam) == BN_DOUBLECLICKED) {
1433 cfg.app_keypad = FALSE;
1434 cfg.nethack_keypad = TRUE;
1439 if (HIWORD(wParam) == BN_CLICKED ||
1440 HIWORD(wParam) == BN_DOUBLECLICKED)
1441 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1444 if (HIWORD(wParam) == BN_CLICKED ||
1445 HIWORD(wParam) == BN_DOUBLECLICKED)
1446 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1449 if (HIWORD(wParam) == BN_CLICKED ||
1450 HIWORD(wParam) == BN_DOUBLECLICKED)
1451 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1454 if (HIWORD(wParam) == BN_CLICKED ||
1455 HIWORD(wParam) == BN_DOUBLECLICKED)
1456 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1459 if (HIWORD(wParam) == BN_CLICKED ||
1460 HIWORD(wParam) == BN_DOUBLECLICKED)
1461 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1464 if (HIWORD(wParam) == BN_CLICKED ||
1465 HIWORD(wParam) == BN_DOUBLECLICKED)
1466 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1468 case IDC_ECHOBACKEND:
1471 if (HIWORD(wParam) == BN_CLICKED ||
1472 HIWORD(wParam) == BN_DOUBLECLICKED) {
1473 if (LOWORD(wParam)==IDC_ECHOBACKEND) cfg.localecho=LD_BACKEND;
1474 if (LOWORD(wParam)==IDC_ECHOYES) cfg.localecho=LD_YES;
1475 if (LOWORD(wParam)==IDC_ECHONO) cfg.localecho=LD_NO;
1478 case IDC_EDITBACKEND:
1481 if (HIWORD(wParam) == BN_CLICKED ||
1482 HIWORD(wParam) == BN_DOUBLECLICKED) {
1483 if (LOWORD(wParam)==IDC_EDITBACKEND) cfg.localedit=LD_BACKEND;
1484 if (LOWORD(wParam)==IDC_EDITYES) cfg.localedit=LD_YES;
1485 if (LOWORD(wParam)==IDC_EDITNO) cfg.localedit=LD_NO;
1488 case IDC_ALWAYSONTOP:
1489 if (HIWORD(wParam) == BN_CLICKED ||
1490 HIWORD(wParam) == BN_DOUBLECLICKED)
1491 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1494 if (HIWORD(wParam) == BN_CLICKED ||
1495 HIWORD(wParam) == BN_DOUBLECLICKED)
1496 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1498 case IDC_SCROLLDISP:
1499 if (HIWORD(wParam) == BN_CLICKED ||
1500 HIWORD(wParam) == BN_DOUBLECLICKED)
1501 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1503 case IDC_COMPOSEKEY:
1504 if (HIWORD(wParam) == BN_CLICKED ||
1505 HIWORD(wParam) == BN_DOUBLECLICKED)
1506 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1509 if (HIWORD(wParam) == BN_CLICKED ||
1510 HIWORD(wParam) == BN_DOUBLECLICKED)
1511 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1514 if (HIWORD(wParam) == BN_CLICKED ||
1515 HIWORD(wParam) == BN_DOUBLECLICKED)
1516 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1519 if (HIWORD(wParam) == BN_CLICKED ||
1520 HIWORD(wParam) == BN_DOUBLECLICKED)
1521 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1524 if (HIWORD(wParam) == EN_CHANGE)
1525 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1528 if (HIWORD(wParam) == EN_CHANGE)
1529 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1532 if (HIWORD(wParam) == EN_CHANGE)
1533 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1535 case IDC_CHOOSEFONT:
1536 lf.lfHeight = cfg.fontheight;
1537 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1538 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1539 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1540 lf.lfCharSet = cfg.fontcharset;
1541 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1542 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1543 lf.lfQuality = DEFAULT_QUALITY;
1544 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1545 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1546 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1548 cf.lStructSize = sizeof(cf);
1549 cf.hwndOwner = hwnd;
1551 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1552 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1554 if (ChooseFont (&cf)) {
1555 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1556 cfg.font[sizeof(cfg.font)-1] = '\0';
1557 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1558 cfg.fontcharset = lf.lfCharSet;
1559 cfg.fontheight = cf.iPointSize / 10;
1560 fmtfont (fontstatic);
1561 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1565 if (HIWORD(wParam) == BN_CLICKED ||
1566 HIWORD(wParam) == BN_DOUBLECLICKED)
1567 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1570 if (HIWORD(wParam) == BN_CLICKED ||
1571 HIWORD(wParam) == BN_DOUBLECLICKED)
1572 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1575 if (HIWORD(wParam) == BN_CLICKED ||
1576 HIWORD(wParam) == BN_DOUBLECLICKED)
1577 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1580 if (HIWORD(wParam) == BN_CLICKED ||
1581 HIWORD(wParam) == BN_DOUBLECLICKED)
1582 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1585 if (HIWORD(wParam) == BN_CLICKED ||
1586 HIWORD(wParam) == BN_DOUBLECLICKED)
1587 cfg.hide_mouseptr = IsDlgButtonChecked (hwnd, IDC_HIDEMOUSE);
1590 if (HIWORD(wParam) == BN_CLICKED ||
1591 HIWORD(wParam) == BN_DOUBLECLICKED)
1592 cfg.cursor_type = 0;
1595 if (HIWORD(wParam) == BN_CLICKED ||
1596 HIWORD(wParam) == BN_DOUBLECLICKED)
1597 cfg.cursor_type = 1;
1600 if (HIWORD(wParam) == BN_CLICKED ||
1601 HIWORD(wParam) == BN_DOUBLECLICKED)
1602 cfg.cursor_type = 2;
1605 if (HIWORD(wParam) == BN_CLICKED ||
1606 HIWORD(wParam) == BN_DOUBLECLICKED)
1607 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1610 if (HIWORD(wParam) == BN_CLICKED ||
1611 HIWORD(wParam) == BN_DOUBLECLICKED)
1612 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1615 if (HIWORD(wParam) == BN_CLICKED ||
1616 HIWORD(wParam) == BN_DOUBLECLICKED)
1617 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1620 if (HIWORD(wParam) == EN_CHANGE)
1621 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1622 sizeof(cfg.wintitle)-1);
1627 if (HIWORD(wParam) == BN_CLICKED ||
1628 HIWORD(wParam) == BN_DOUBLECLICKED) {
1629 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_COEALWAYS) ? COE_ALWAYS :
1630 IsDlgButtonChecked (hwnd, IDC_COENEVER) ? COE_NEVER :
1635 if (HIWORD(wParam) == BN_CLICKED ||
1636 HIWORD(wParam) == BN_DOUBLECLICKED)
1637 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1640 if (HIWORD(wParam) == EN_CHANGE)
1641 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1642 sizeof(cfg.termtype)-1);
1645 if (HIWORD(wParam) == EN_CHANGE)
1646 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1647 sizeof(cfg.logfilename)-1);
1650 memset(&of, 0, sizeof(of));
1651 #ifdef OPENFILENAME_SIZE_VERSION_400
1652 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1654 of.lStructSize = sizeof(of);
1656 of.hwndOwner = hwnd;
1657 of.lpstrFilter = "All Files\0*\0\0\0";
1658 of.lpstrCustomFilter = NULL;
1659 of.nFilterIndex = 1;
1660 of.lpstrFile = filename; strcpy(filename, cfg.logfilename);
1661 of.nMaxFile = sizeof(filename);
1662 of.lpstrFileTitle = NULL;
1663 of.lpstrInitialDir = NULL;
1664 of.lpstrTitle = "Select session log file";
1666 if (GetSaveFileName(&of)) {
1667 strcpy(cfg.logfilename, filename);
1668 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
1672 case IDC_LSTATASCII:
1674 if (HIWORD(wParam) == BN_CLICKED ||
1675 HIWORD(wParam) == BN_DOUBLECLICKED) {
1676 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1677 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1678 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1683 if (HIWORD(wParam) == EN_CHANGE)
1684 GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed,
1685 sizeof(cfg.termspeed)-1);
1688 if (HIWORD(wParam) == EN_CHANGE)
1689 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1690 sizeof(cfg.username)-1);
1692 case IDC_RLLUSEREDIT:
1693 if (HIWORD(wParam) == EN_CHANGE)
1694 GetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername,
1695 sizeof(cfg.localusername)-1);
1699 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1702 if (HIWORD(wParam) == BN_CLICKED ||
1703 HIWORD(wParam) == BN_DOUBLECLICKED) {
1704 char str[sizeof(cfg.environmt)];
1706 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1711 p = str + strlen(str);
1713 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1723 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1725 p[strlen(str)+1] = '\0';
1726 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1728 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1729 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1731 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1732 MB_OK | MB_ICONERROR);
1737 if (HIWORD(wParam) != BN_CLICKED &&
1738 HIWORD(wParam) != BN_DOUBLECLICKED)
1740 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1746 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1771 if (HIWORD(wParam) == BN_CLICKED ||
1772 HIWORD(wParam) == BN_DOUBLECLICKED)
1773 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1776 if (HIWORD(wParam) == BN_CLICKED ||
1777 HIWORD(wParam) == BN_DOUBLECLICKED)
1778 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1781 if (HIWORD(wParam) == BN_CLICKED ||
1782 HIWORD(wParam) == BN_DOUBLECLICKED)
1783 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1786 if (HIWORD(wParam) == BN_CLICKED ||
1787 HIWORD(wParam) == BN_DOUBLECLICKED)
1788 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1790 case IDC_CIPHER3DES:
1791 case IDC_CIPHERBLOWF:
1794 if (HIWORD(wParam) == BN_CLICKED ||
1795 HIWORD(wParam) == BN_DOUBLECLICKED) {
1796 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1797 cfg.cipher = CIPHER_3DES;
1798 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1799 cfg.cipher = CIPHER_BLOWFISH;
1800 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1801 cfg.cipher = CIPHER_DES;
1802 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERAES))
1803 cfg.cipher = CIPHER_AES;
1808 if (HIWORD(wParam) == BN_CLICKED ||
1809 HIWORD(wParam) == BN_DOUBLECLICKED) {
1810 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1812 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1817 if (HIWORD(wParam) == BN_CLICKED ||
1818 HIWORD(wParam) == BN_DOUBLECLICKED)
1819 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1822 if (HIWORD(wParam) == EN_CHANGE)
1823 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1824 sizeof(cfg.keyfile)-1);
1827 if (HIWORD(wParam) == EN_CHANGE)
1828 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1829 sizeof(cfg.remote_cmd)-1);
1832 memset(&of, 0, sizeof(of));
1833 #ifdef OPENFILENAME_SIZE_VERSION_400
1834 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1836 of.lStructSize = sizeof(of);
1838 of.hwndOwner = hwnd;
1839 of.lpstrFilter = "All Files\0*\0\0\0";
1840 of.lpstrCustomFilter = NULL;
1841 of.nFilterIndex = 1;
1842 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1843 of.nMaxFile = sizeof(filename);
1844 of.lpstrFileTitle = NULL;
1845 of.lpstrInitialDir = NULL;
1846 of.lpstrTitle = "Select Public Key File";
1848 if (GetOpenFileName(&of)) {
1849 strcpy(cfg.keyfile, filename);
1850 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1854 cfg.rawcnp = IsDlgButtonChecked (hwnd, IDC_RAWCNP);
1857 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1863 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1868 for (i=0; i<256; i++)
1869 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1872 cfg.wordness[i] = n;
1873 SendDlgItemMessage (hwnd, IDC_CCLIST,
1874 LB_DELETESTRING, i, 0);
1875 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1876 (i>=0x21 && i != 0x7F) ? i : ' ',
1878 SendDlgItemMessage (hwnd, IDC_CCLIST,
1885 case IDC_BOLDCOLOUR:
1886 if (HIWORD(wParam) == BN_CLICKED ||
1887 HIWORD(wParam) == BN_DOUBLECLICKED) {
1889 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1890 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1891 if (n != 12+10*cfg.bold_colour) {
1893 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1894 LB_DELETESTRING, i, 0);
1895 for (i=0; i<22; i++)
1896 if (cfg.bold_colour || permcolour[i])
1897 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1899 (LPARAM) colours[i]);
1904 if (HIWORD(wParam) == BN_CLICKED ||
1905 HIWORD(wParam) == BN_DOUBLECLICKED)
1906 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1908 case IDC_COLOURLIST:
1909 if (HIWORD(wParam) == LBN_DBLCLK ||
1910 HIWORD(wParam) == LBN_SELCHANGE) {
1911 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1913 if (!cfg.bold_colour)
1914 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1915 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1916 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1917 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1921 if (HIWORD(wParam) == BN_CLICKED ||
1922 HIWORD(wParam) == BN_DOUBLECLICKED) {
1923 static CHOOSECOLOR cc;
1924 static DWORD custom[16] = {0}; /* zero initialisers */
1925 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1927 if (!cfg.bold_colour)
1928 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1929 cc.lStructSize = sizeof(cc);
1930 cc.hwndOwner = hwnd;
1931 cc.hInstance = (HWND)hinst;
1932 cc.lpCustColors = custom;
1933 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1935 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1936 if (ChooseColor(&cc)) {
1938 (unsigned char) (cc.rgbResult & 0xFF);
1940 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1942 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1943 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1945 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1947 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1953 case IDC_KOI8WIN1251:
1954 case IDC_88592WIN1250:
1955 case IDC_88592CP852:
1956 cfg.xlat_enablekoiwin =
1957 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1958 cfg.xlat_88592w1250 =
1959 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1960 cfg.xlat_88592cp852 =
1961 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1963 case IDC_CAPSLOCKCYR:
1964 if (HIWORD(wParam) == BN_CLICKED ||
1965 HIWORD(wParam) == BN_DOUBLECLICKED) {
1966 cfg.xlat_capslockcyr =
1967 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1970 case IDC_VTXWINDOWS:
1975 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1976 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1977 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1980 case IDC_X11_FORWARD:
1981 if (HIWORD(wParam) == BN_CLICKED ||
1982 HIWORD(wParam) == BN_DOUBLECLICKED)
1983 cfg.x11_forward = IsDlgButtonChecked (hwnd, IDC_X11_FORWARD);
1985 case IDC_X11_DISPLAY:
1986 if (HIWORD(wParam) == EN_CHANGE)
1987 GetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display,
1988 sizeof(cfg.x11_display)-1);
1993 EndDialog (hwnd, 0);
1996 /* Grrr Explorer will maximize Dialogs! */
1998 if (wParam == SIZE_MAXIMIZED)
2005 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
2006 WPARAM wParam, LPARAM lParam) {
2007 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2009 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2010 EnableWindow(hwnd, 0);
2011 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2012 GetParent(hwnd), AboutProc);
2013 EnableWindow(hwnd, 1);
2014 SetActiveWindow(hwnd);
2016 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
2019 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
2020 WPARAM wParam, LPARAM lParam) {
2021 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
2024 void defuse_showwindow(void) {
2026 * Work around the fact that the app's first call to ShowWindow
2027 * will ignore the default in favour of the shell-provided
2032 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2034 ShowWindow(hwnd, SW_HIDE);
2035 DestroyWindow(hwnd);
2039 int do_config (void) {
2043 savedsession[0] = '\0';
2044 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2045 get_sesslist(FALSE);
2050 int do_reconfig (HWND hwnd) {
2054 backup_cfg = cfg; /* structure copy */
2055 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2057 cfg = backup_cfg; /* structure copy */
2062 void logevent (char *string) {
2066 if (nevents >= negsize) {
2068 events = srealloc (events, negsize * sizeof(*events));
2072 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t", localtime(&t));
2074 events[nevents] = smalloc(strlen(timebuf)+strlen(string)+1);
2075 strcpy(events[nevents], timebuf);
2076 strcat(events[nevents], string);
2079 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
2080 0, (LPARAM)events[nevents]);
2081 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2082 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
2087 void showeventlog (HWND hwnd) {
2089 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2091 ShowWindow (logbox, SW_SHOWNORMAL);
2093 SetActiveWindow(logbox);
2096 void showabout (HWND hwnd) {
2097 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),hwnd, AboutProc);
2100 void verify_ssh_host_key(char *host, int port, char *keytype,
2101 char *keystr, char *fingerprint) {
2104 static const char absentmsg[] =
2105 "The server's host key is not cached in the registry. You\n"
2106 "have no guarantee that the server is the computer you\n"
2108 "The server's key fingerprint is:\n"
2110 "If you trust this host, hit Yes to add the key to\n"
2111 "PuTTY's cache and carry on connecting.\n"
2112 "If you do not trust this host, hit No to abandon the\n"
2115 static const char wrongmsg[] =
2116 "WARNING - POTENTIAL SECURITY BREACH!\n"
2118 "The server's host key does not match the one PuTTY has\n"
2119 "cached in the registry. This means that either the\n"
2120 "server administrator has changed the host key, or you\n"
2121 "have actually connected to another computer pretending\n"
2122 "to be the server.\n"
2123 "The new key fingerprint is:\n"
2125 "If you were expecting this change and trust the new key,\n"
2126 "hit Yes to update PuTTY's cache and continue connecting.\n"
2127 "If you want to carry on connecting but without updating\n"
2128 "the cache, hit No.\n"
2129 "If you want to abandon the connection completely, hit\n"
2130 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2133 static const char mbtitle[] = "PuTTY Security Alert";
2136 char message[160+ /* sensible fingerprint max size */
2137 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2138 sizeof(absentmsg) : sizeof(wrongmsg))];
2141 * Verify the key against the registry.
2143 ret = verify_host_key(host, port, keytype, keystr);
2145 if (ret == 0) /* success - key matched OK */
2147 if (ret == 2) { /* key was different */
2149 sprintf(message, wrongmsg, fingerprint);
2150 mbret = MessageBox(NULL, message, mbtitle,
2151 MB_ICONWARNING | MB_YESNOCANCEL);
2153 store_host_key(host, port, keytype, keystr);
2154 if (mbret == IDCANCEL)
2157 if (ret == 1) { /* key was absent */
2159 sprintf(message, absentmsg, fingerprint);
2160 mbret = MessageBox(NULL, message, mbtitle,
2161 MB_ICONWARNING | MB_YESNO);
2164 store_host_key(host, port, keytype, keystr);
2169 * Ask whether to wipe a session log file before writing to it.
2170 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2172 int askappend(char *filename) {
2173 static const char mbtitle[] = "PuTTY Log to File";
2174 static const char msgtemplate[] =
2175 "The session log file \"%.*s\" already exists.\n"
2176 "You can overwrite it with a new session log,\n"
2177 "append your session log to the end of it,\n"
2178 "or disable session logging for this session.\n"
2179 "Hit Yes to wipe the file, No to append to it,\n"
2180 "or Cancel to disable logging.";
2181 char message[sizeof(msgtemplate) + FILENAME_MAX];
2183 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2185 mbret = MessageBox(NULL, message, mbtitle,
2186 MB_ICONQUESTION | MB_YESNOCANCEL);
2189 else if (mbret == IDNO)