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);
173 /* Load web browser */
174 ShellExecute(hwnd, "open",
175 "http://www.chiark.greenend.org.uk/~sgtatham/putty/",
176 0, 0, SW_SHOWDEFAULT);
181 EndDialog(hwnd, TRUE);
188 * Null dialog procedure.
190 static int CALLBACK NullDlgProc (HWND hwnd, UINT msg,
191 WPARAM wParam, LPARAM lParam) {
195 static char savedsession[2048];
197 enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
308 appearancepanelstart,
309 IDC_TITLE_APPEARANCE,
327 connectionpanelstart,
328 IDC_TITLE_CONNECTION,
426 translationpanelstart,
427 IDC_TITLE_TRANSLATION,
428 IDC_BOX_TRANSLATION1,
429 IDC_BOX_TRANSLATION2,
430 IDC_BOX_TRANSLATION3,
455 static const char *const colours[] = {
456 "Default Foreground", "Default Bold Foreground",
457 "Default Background", "Default Bold Background",
458 "Cursor Text", "Cursor Colour",
459 "ANSI Black", "ANSI Black Bold",
460 "ANSI Red", "ANSI Red Bold",
461 "ANSI Green", "ANSI Green Bold",
462 "ANSI Yellow", "ANSI Yellow Bold",
463 "ANSI Blue", "ANSI Blue Bold",
464 "ANSI Magenta", "ANSI Magenta Bold",
465 "ANSI Cyan", "ANSI Cyan Bold",
466 "ANSI White", "ANSI White Bold"
468 static const int permcolour[] = {
469 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
470 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
471 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
474 static void fmtfont (char *buf) {
475 sprintf (buf, "Font: %s, ", cfg.font);
477 strcat(buf, "bold, ");
478 if (cfg.fontheight == 0)
479 strcat (buf, "default height");
481 sprintf (buf+strlen(buf), "%d-point",
482 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
485 static void init_dlg_ctrls(HWND hwnd) {
487 char fontstatic[256];
489 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
490 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
493 n = SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
495 SendDlgItemMessage (hwnd, IDC_SESSLIST,
496 LB_DELETESTRING, i, 0);
497 for (i = 0; i < nsessions; i++)
498 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
499 0, (LPARAM) (sessions[i]));
501 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
502 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
503 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
504 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET :
505 cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW );
506 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
508 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
509 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
510 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
511 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
512 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
513 cfg.funky_type == 0 ? IDC_FUNCTILDE :
514 cfg.funky_type == 1 ? IDC_FUNCLINUX :
515 cfg.funky_type == 2 ? IDC_FUNCXTERM :
516 cfg.funky_type == 3 ? IDC_FUNCVT400 :
518 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
519 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
520 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
521 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
522 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
523 cfg.nethack_keypad ? IDC_KPNH :
524 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
525 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
526 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
527 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
528 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
529 CheckRadioButton (hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
530 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND:
531 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
532 CheckRadioButton (hwnd, IDC_EDITBACKEND, IDC_EDITNO,
533 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND:
534 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
535 SetDlgItemText (hwnd, IDC_ANSWEREDIT, cfg.answerback);
536 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
537 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
538 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
540 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
541 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
542 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
543 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
544 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
545 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
546 fmtfont (fontstatic);
547 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
548 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
549 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
550 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
552 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
553 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
554 CheckDlgButton (hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
555 CheckRadioButton (hwnd, IDC_CURBLOCK, IDC_CURVERT,
556 cfg.cursor_type==0 ? IDC_CURBLOCK :
557 cfg.cursor_type==1 ? IDC_CURUNDER : IDC_CURVERT);
558 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
559 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
560 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
561 CheckRadioButton (hwnd, IDC_COEALWAYS, IDC_COENORMAL,
562 cfg.close_on_exit==COE_NORMAL ? IDC_COENORMAL :
563 cfg.close_on_exit==COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
564 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
566 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
567 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
568 SetDlgItemText (hwnd, IDC_R_TSEDIT, cfg.termspeed);
569 SetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername);
570 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
571 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
572 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
573 cfg.logtype == 0 ? IDC_LSTATOFF :
574 cfg.logtype == 1 ? IDC_LSTATASCII :
577 char *p = cfg.environmt;
579 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
584 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
585 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
587 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
588 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
589 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
590 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
591 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
592 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
593 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERAES,
594 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
595 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
596 cfg.cipher == CIPHER_AES ? IDC_CIPHERAES :
598 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
599 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
600 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
601 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
602 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
604 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
605 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
606 CheckDlgButton (hwnd, IDC_RAWCNP, cfg.rawcnp);
608 static int tabs[4] = {25, 61, 96, 128};
609 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
612 for (i=0; i<256; i++) {
614 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
615 (i>=0x21 && i != 0x7F) ? i : ' ',
617 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
621 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
622 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
625 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
627 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
628 LB_DELETESTRING, i, 0);
630 if (cfg.bold_colour || permcolour[i])
631 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
632 (LPARAM) colours[i]);
634 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
635 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
636 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
637 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
639 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
640 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
641 cfg.xlat_88592cp852 ? IDC_88592CP852 :
642 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
644 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
645 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
646 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
647 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
648 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
651 CheckDlgButton (hwnd, IDC_X11_FORWARD, cfg.x11_forward);
652 SetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display);
655 struct treeview_faff {
660 static HTREEITEM treeview_insert(struct treeview_faff *faff,
661 int level, char *text) {
665 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
666 ins.hInsertAfter = faff->lastat[level];
667 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
668 #define INSITEM DUMMYUNIONNAME.item
672 ins.INSITEM.mask = TVIF_TEXT;
673 ins.INSITEM.pszText = text;
674 newitem = TreeView_InsertItem(faff->treeview, &ins);
676 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
677 faff->lastat[level] = newitem;
678 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
683 * Create the panelfuls of controls in the configuration box.
685 static void create_controls(HWND hwnd, int dlgtype, int panel) {
686 if (panel == sessionpanelstart) {
687 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
689 ctlposinit(&cp, hwnd, 80, 3, 13);
690 bartitle(&cp, "Basic options for your PuTTY session",
693 beginbox(&cp, "Specify your connection by host name",
696 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
697 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
698 if (backends[3].backend == NULL) {
699 /* this is PuTTYtel, so only three protocols available */
700 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
702 "&Telnet", IDC_PROTTELNET,
703 "Rlog&in", IDC_PROTRLOGIN, NULL);
705 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
707 "&Telnet", IDC_PROTTELNET,
708 "Rlog&in", IDC_PROTRLOGIN,
717 beginbox(&cp, "Load, save or delete a stored session",
719 sesssaver(&cp, "Sav&ed Sessions",
720 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
721 "&Load", IDC_SESSLOAD,
722 "&Save", IDC_SESSSAVE,
723 "&Delete", IDC_SESSDEL, NULL);
726 beginbox(&cp, NULL, IDC_BOX_SESSION3);
727 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
728 "Always", IDC_COEALWAYS,
729 "Never", IDC_COENEVER,
730 "Only on clean exit", IDC_COENORMAL, NULL);
734 if (panel == loggingpanelstart) {
735 /* The Logging panel. Accelerators used: [acgo] tplfw */
737 ctlposinit(&cp, hwnd, 80, 3, 13);
738 bartitle(&cp, "Options controlling session logging",
740 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
742 "Session logging:", IDC_LSTATSTATIC,
743 "Logging &turned off completely", IDC_LSTATOFF,
744 "Log &printable output only", IDC_LSTATASCII,
745 "&Log all session output", IDC_LSTATRAW, NULL);
746 editbutton(&cp, "Log &file name:",
747 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
752 if (panel == terminalpanelstart) {
753 /* The Terminal panel. Accelerators used: [acgo] wdlben hts */
755 ctlposinit(&cp, hwnd, 80, 3, 13);
756 bartitle(&cp, "Options controlling the terminal emulation",
758 beginbox(&cp, "Set various terminal options",
760 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
761 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
762 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
763 checkbox(&cp, "&Beep enabled", IDC_BEEP);
764 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
765 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
767 "An&swerback to ^E:", IDC_ANSWERBACK,
768 IDC_ANSWEREDIT, 100, NULL);
771 beginbox(&cp, "Line discipline options",
773 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
774 "Auto", IDC_ECHOBACKEND,
775 "Force on", IDC_ECHOYES,
776 "Force off", IDC_ECHONO, NULL);
777 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
778 "Auto", IDC_EDITBACKEND,
779 "Force on", IDC_EDITYES,
780 "Force off", IDC_EDITNO, NULL);
784 if (panel == keyboardpanelstart) {
785 /* The Keyboard panel. Accelerators used: [acgo] h?sr~lxv unpymie t */
787 ctlposinit(&cp, hwnd, 80, 3, 13);
788 bartitle(&cp, "Options controlling the effects of keys",
790 beginbox(&cp, "Change the sequences sent by:",
792 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
793 "Control-&H", IDC_DEL008,
794 "Control-&? (127)", IDC_DEL127, NULL);
795 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
796 "&Standard", IDC_HOMETILDE,
797 "&rxvt", IDC_HOMERXVT, NULL);
798 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
799 "ESC[n&~", IDC_FUNCTILDE,
800 "&Linux", IDC_FUNCLINUX,
801 "&Xterm R6", IDC_FUNCXTERM,
802 "&VT400", IDC_FUNCVT400, NULL);
804 beginbox(&cp, "Application keypad settings:",
807 "Application c&ursor keys totally disabled",
809 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
810 "&Normal", IDC_CURNORMAL,
811 "A&pplication", IDC_CURAPPLIC, NULL);
813 "Application ke&ypad keys totally disabled",
815 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
816 "Nor&mal", IDC_KPNORMAL,
817 "Appl&ication", IDC_KPAPPLIC,
818 "N&etHack", IDC_KPNH, NULL);
820 beginbox(&cp, "Enable extra keyboard features:",
822 checkbox(&cp, "Application and AltGr ac&t as Compose key",
827 if (panel == windowpanelstart) {
828 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
830 ctlposinit(&cp, hwnd, 80, 3, 13);
831 bartitle(&cp, "Options controlling PuTTY's window",
833 beginbox(&cp, "Set the size of the window",
836 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
837 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
839 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
841 beginbox(&cp, "Control the scrollback in the window",
843 staticedit(&cp, "Lines of &scrollback",
844 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
845 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
846 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
847 checkbox(&cp, "Reset scrollback on dis&play activity",
850 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
851 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
852 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
853 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
854 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
855 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
859 if (panel == appearancepanelstart) {
860 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p */
862 ctlposinit(&cp, hwnd, 80, 3, 13);
863 bartitle(&cp, "Options controlling PuTTY's appearance",
864 IDC_TITLE_APPEARANCE);
865 beginbox(&cp, "Adjust the use of the cursor",
866 IDC_BOX_APPEARANCE1);
867 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
868 "B&lock", IDC_CURBLOCK,
869 "&Underline", IDC_CURUNDER,
870 "&Vertical line", IDC_CURVERT,
872 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
874 beginbox(&cp, "Set the font used in the terminal window",
875 IDC_BOX_APPEARANCE2);
876 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
878 beginbox(&cp, "Adjust the use of the window title",
879 IDC_BOX_APPEARANCE3);
881 "Window &title:", IDC_WINTITLE,
882 IDC_WINEDIT, 100, NULL);
883 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
885 beginbox(&cp, "Adjust the use of the mouse pointer",
886 IDC_BOX_APPEARANCE4);
887 checkbox(&cp, "Hide mouse &pointer when typing in window",
892 if (panel == translationpanelstart) {
893 /* The Translation panel. Accelerators used: [acgo] xbep t s */
895 ctlposinit(&cp, hwnd, 80, 3, 13);
896 bartitle(&cp, "Options controlling character set translation",
897 IDC_TITLE_TRANSLATION);
898 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
899 IDC_BOX_TRANSLATION1);
901 "Handling of line drawing characters:", IDC_VTSTATIC,
902 "Font has &XWindows encoding", IDC_VTXWINDOWS,
903 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
904 "Use font in O&EM mode only", IDC_VTOEMONLY,
905 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
906 IDC_VTPOORMAN, NULL);
908 beginbox(&cp, "Enable character set translation on received data",
909 IDC_BOX_TRANSLATION2);
911 "Character set &translation:", IDC_XLATSTATIC,
913 "KOI8 / Win-1251", IDC_KOI8WIN1251,
914 "ISO-8859-2 / Win-1250", IDC_88592WIN1250,
915 "ISO-8859-2 / CP852", IDC_88592CP852, NULL);
917 beginbox(&cp, "Enable character set translation on input data",
918 IDC_BOX_TRANSLATION3);
919 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
924 if (panel == selectionpanelstart) {
925 /* The Selection panel. Accelerators used: [acgo] d wx hst */
927 ctlposinit(&cp, hwnd, 80, 3, 13);
928 bartitle(&cp, "Options controlling copy and paste",
929 IDC_TITLE_SELECTION);
930 beginbox(&cp, "Translation of pasted characters",
932 checkbox(&cp, "&Don't translate line drawing chars into +, - and |",
935 beginbox(&cp, "Control which mouse button does which thing",
937 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
938 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
939 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
942 beginbox(&cp, "Control the select-one-word-at-a-time mode",
944 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
945 "&Set", IDC_CCSET, IDC_CCEDIT,
946 "&to class", IDC_CCSTATIC2);
950 if (panel == colourspanelstart) {
951 /* The Colours panel. Accelerators used: [acgo] blum */
953 ctlposinit(&cp, hwnd, 80, 3, 13);
954 bartitle(&cp, "Options controlling use of colours",
956 beginbox(&cp, "General options for colour usage",
958 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
959 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
961 beginbox(&cp, "Adjust the precise colours PuTTY displays",
963 colouredit(&cp, "Select a colo&ur and then click to modify it:",
964 IDC_COLOURSTATIC, IDC_COLOURLIST,
965 "&Modify...", IDC_CHANGE,
966 "Red:", IDC_RSTATIC, IDC_RVALUE,
967 "Green:", IDC_GSTATIC, IDC_GVALUE,
968 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
972 if (panel == connectionpanelstart) {
973 /* The Connection panel. Accelerators used: [acgo] tuk */
975 ctlposinit(&cp, hwnd, 80, 3, 13);
976 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
978 beginbox(&cp, "Data to send to the server",
979 IDC_BOX_CONNECTION1);
980 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
981 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
984 beginbox(&cp, "Sending of null packets to keep session active",
985 IDC_BOX_CONNECTION2);
986 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
987 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
991 if (panel == telnetpanelstart) {
992 /* The Telnet panel. Accelerators used: [acgo] svldr bf */
994 ctlposinit(&cp, hwnd, 80, 3, 13);
996 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
997 beginbox(&cp, "Data to send to the server",
999 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
1000 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1001 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
1002 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
1004 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1006 beginbox(&cp, "Telnet protocol adjustments",
1008 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
1009 "&BSD (commonplace)", IDC_EMBSD,
1010 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1015 if (panel == rloginpanelstart) {
1016 /* The Rlogin panel. Accelerators used: [acgo] sl */
1018 ctlposinit(&cp, hwnd, 80, 3, 13);
1020 bartitle(&cp, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN);
1021 beginbox(&cp, "Data to send to the server",
1023 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC, IDC_R_TSEDIT, 50);
1024 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC, IDC_RLLUSEREDIT, 50);
1029 if (panel == sshpanelstart) {
1030 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1032 ctlposinit(&cp, hwnd, 80, 3, 13);
1034 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
1035 beginbox(&cp, "Data to send to the server",
1038 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1041 beginbox(&cp, "Authentication options",
1043 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1045 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1046 editbutton(&cp, "Private &key file for authentication:",
1047 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
1049 beginbox(&cp, "Protocol options",
1051 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1052 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1053 radioline(&cp, "Preferred SSH protocol version:",
1054 IDC_SSHPROTSTATIC, 2,
1055 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1056 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 4,
1057 "&3DES", IDC_CIPHER3DES,
1058 "&Blowfish", IDC_CIPHERBLOWF,
1059 "&DES", IDC_CIPHERDES,
1060 "AE&S", IDC_CIPHERAES,
1062 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1068 if (panel == tunnelspanelstart) {
1069 /* The Tunnels panel. Accelerators used: [acgo] ex */
1071 ctlposinit(&cp, hwnd, 80, 3, 13);
1073 bartitle(&cp, "Options controlling SSH tunnelling",
1075 beginbox(&cp, "X11 forwarding options",
1077 checkbox(&cp, "&Enable X11 forwarding",
1079 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1080 IDC_X11_DISPLAY, 50, NULL);
1087 * This function is the configuration box.
1089 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1090 WPARAM wParam, LPARAM lParam,
1093 struct treeview_faff tvfaff;
1096 char filename[sizeof(cfg.keyfile)];
1099 char fontstatic[256];
1101 struct servent * service;
1107 SetWindowLong(hwnd, GWL_USERDATA, 0);
1109 * Centre the window.
1111 { /* centre the window */
1114 hw = GetDesktopWindow();
1115 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1116 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1117 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1118 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1122 * Create the tree view.
1129 r.left = 3; r.right = r.left + 75;
1130 r.top = 3; r.bottom = r.top + 10;
1131 MapDialogRect(hwnd, &r);
1132 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1133 WS_CHILD | WS_VISIBLE,
1135 r.right-r.left, r.bottom-r.top,
1136 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
1137 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1138 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1140 r.left = 3; r.right = r.left + 75;
1141 r.top = 13; r.bottom = r.top + 206;
1142 MapDialogRect(hwnd, &r);
1143 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1144 WS_CHILD | WS_VISIBLE |
1145 WS_TABSTOP | TVS_HASLINES |
1146 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
1147 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
1149 r.right-r.left, r.bottom-r.top,
1150 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
1151 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1152 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1153 tvfaff.treeview = treeview;
1154 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1158 * Set up the tree view contents.
1160 hsession = treeview_insert(&tvfaff, 0, "Session");
1161 treeview_insert(&tvfaff, 1, "Logging");
1162 treeview_insert(&tvfaff, 0, "Terminal");
1163 treeview_insert(&tvfaff, 1, "Keyboard");
1164 treeview_insert(&tvfaff, 0, "Window");
1165 treeview_insert(&tvfaff, 1, "Appearance");
1166 treeview_insert(&tvfaff, 1, "Translation");
1167 treeview_insert(&tvfaff, 1, "Selection");
1168 treeview_insert(&tvfaff, 1, "Colours");
1169 treeview_insert(&tvfaff, 0, "Connection");
1171 treeview_insert(&tvfaff, 1, "Telnet");
1172 treeview_insert(&tvfaff, 1, "Rlogin");
1173 if (backends[3].backend != NULL) {
1174 treeview_insert(&tvfaff, 1, "SSH");
1175 treeview_insert(&tvfaff, 2, "Tunnels");
1180 * Put the treeview selection on to the Session panel. This
1181 * should also cause creation of the relevant controls.
1183 TreeView_SelectItem(treeview, hsession);
1186 * Set focus into the first available control.
1190 ctl = GetDlgItem(hwnd, IDC_HOST);
1191 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1195 SetWindowLong(hwnd, GWL_USERDATA, 1);
1199 * Button release should trigger WM_OK if there was a
1200 * previous double click on the session list.
1204 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1207 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1208 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1209 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1214 item.pszText = buffer;
1215 item.cchTextMax = sizeof(buffer);
1216 item.mask = TVIF_TEXT;
1217 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1218 for (j = controlstartvalue; j < controlendvalue; j++) {
1219 HWND item = GetDlgItem(hwnd, j);
1221 DestroyWindow(item);
1223 if (!strcmp(buffer, "Session"))
1224 create_controls(hwnd, dlgtype, sessionpanelstart);
1225 if (!strcmp(buffer, "Logging"))
1226 create_controls(hwnd, dlgtype, loggingpanelstart);
1227 if (!strcmp(buffer, "Keyboard"))
1228 create_controls(hwnd, dlgtype, keyboardpanelstart);
1229 if (!strcmp(buffer, "Terminal"))
1230 create_controls(hwnd, dlgtype, terminalpanelstart);
1231 if (!strcmp(buffer, "Window"))
1232 create_controls(hwnd, dlgtype, windowpanelstart);
1233 if (!strcmp(buffer, "Appearance"))
1234 create_controls(hwnd, dlgtype, appearancepanelstart);
1235 if (!strcmp(buffer, "Tunnels"))
1236 create_controls(hwnd, dlgtype, tunnelspanelstart);
1237 if (!strcmp(buffer, "Connection"))
1238 create_controls(hwnd, dlgtype, connectionpanelstart);
1239 if (!strcmp(buffer, "Telnet"))
1240 create_controls(hwnd, dlgtype, telnetpanelstart);
1241 if (!strcmp(buffer, "Rlogin"))
1242 create_controls(hwnd, dlgtype, rloginpanelstart);
1243 if (!strcmp(buffer, "SSH"))
1244 create_controls(hwnd, dlgtype, sshpanelstart);
1245 if (!strcmp(buffer, "Selection"))
1246 create_controls(hwnd, dlgtype, selectionpanelstart);
1247 if (!strcmp(buffer, "Colours"))
1248 create_controls(hwnd, dlgtype, colourspanelstart);
1249 if (!strcmp(buffer, "Translation"))
1250 create_controls(hwnd, dlgtype, translationpanelstart);
1252 init_dlg_ctrls(hwnd);
1254 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1260 * Only process WM_COMMAND once the dialog is fully formed.
1262 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1265 EndDialog (hwnd, 1);
1270 EndDialog (hwnd, 0);
1272 case IDC_PROTTELNET:
1273 case IDC_PROTRLOGIN:
1276 if (HIWORD(wParam) == BN_CLICKED ||
1277 HIWORD(wParam) == BN_DOUBLECLICKED) {
1278 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1279 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1280 int k = IsDlgButtonChecked (hwnd, IDC_PROTRLOGIN);
1281 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN : PROT_RAW ;
1282 if ((cfg.protocol == PROT_SSH && cfg.port != 22) ||
1283 (cfg.protocol == PROT_TELNET && cfg.port != 23) ||
1284 (cfg.protocol == PROT_RLOGIN && cfg.port != 513)) {
1285 cfg.port = i ? 22 : j ? 23 : 513;
1286 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1291 if (HIWORD(wParam) == EN_CHANGE)
1292 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1293 sizeof(cfg.host)-1);
1296 if (HIWORD(wParam) == EN_CHANGE) {
1297 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1298 if (isdigit(portname[0]))
1299 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1301 service = getservbyname(portname, NULL);
1302 if (service) cfg.port = ntohs(service->s_port);
1308 if (HIWORD(wParam) == EN_CHANGE) {
1309 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1311 GetDlgItemText (hwnd, IDC_SESSEDIT,
1312 savedsession, sizeof(savedsession)-1);
1313 savedsession[sizeof(savedsession)-1] = '\0';
1317 if (HIWORD(wParam) == BN_CLICKED ||
1318 HIWORD(wParam) == BN_DOUBLECLICKED) {
1323 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1325 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1326 LB_GETCURSEL, 0, 0);
1331 strcpy (str, sessions[n]);
1333 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1334 get_sesslist (FALSE);
1335 get_sesslist (TRUE);
1336 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1338 for (i = 0; i < nsessions; i++)
1339 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1340 0, (LPARAM) (sessions[i]));
1341 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1347 if (LOWORD(wParam) == IDC_SESSLOAD &&
1348 HIWORD(wParam) != BN_CLICKED &&
1349 HIWORD(wParam) != BN_DOUBLECLICKED)
1351 if (LOWORD(wParam) == IDC_SESSLIST &&
1352 HIWORD(wParam) != LBN_DBLCLK)
1355 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1356 LB_GETCURSEL, 0, 0);
1362 isdef = !strcmp(sessions[n], "Default Settings");
1363 load_settings (sessions[n], !isdef, &cfg);
1364 init_dlg_ctrls(hwnd);
1366 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1368 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1370 if (LOWORD(wParam) == IDC_SESSLIST) {
1372 * A double-click on a saved session should
1373 * actually start the session, not just load it.
1374 * Unless it's Default Settings or some other
1375 * host-less set of saved settings.
1384 if (HIWORD(wParam) == BN_CLICKED ||
1385 HIWORD(wParam) == BN_DOUBLECLICKED) {
1386 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1387 LB_GETCURSEL, 0, 0);
1388 if (n == LB_ERR || n == 0) {
1392 del_settings(sessions[n]);
1393 get_sesslist (FALSE);
1394 get_sesslist (TRUE);
1395 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1397 for (i = 0; i < nsessions; i++)
1398 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1399 0, (LPARAM) (sessions[i]));
1400 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1404 if (HIWORD(wParam) == EN_CHANGE)
1405 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1409 if (HIWORD(wParam) == BN_CLICKED ||
1410 HIWORD(wParam) == BN_DOUBLECLICKED)
1411 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1415 if (HIWORD(wParam) == BN_CLICKED ||
1416 HIWORD(wParam) == BN_DOUBLECLICKED)
1417 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1420 if (HIWORD(wParam) == BN_CLICKED ||
1421 HIWORD(wParam) == BN_DOUBLECLICKED)
1425 if (HIWORD(wParam) == BN_CLICKED ||
1426 HIWORD(wParam) == BN_DOUBLECLICKED)
1431 if (HIWORD(wParam) == BN_CLICKED ||
1432 HIWORD(wParam) == BN_DOUBLECLICKED)
1433 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1437 if (HIWORD(wParam) == BN_CLICKED ||
1438 HIWORD(wParam) == BN_DOUBLECLICKED) {
1439 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1440 cfg.nethack_keypad = FALSE;
1444 if (HIWORD(wParam) == BN_CLICKED ||
1445 HIWORD(wParam) == BN_DOUBLECLICKED) {
1446 cfg.app_keypad = FALSE;
1447 cfg.nethack_keypad = TRUE;
1452 if (HIWORD(wParam) == BN_CLICKED ||
1453 HIWORD(wParam) == BN_DOUBLECLICKED)
1454 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1457 if (HIWORD(wParam) == BN_CLICKED ||
1458 HIWORD(wParam) == BN_DOUBLECLICKED)
1459 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1462 if (HIWORD(wParam) == BN_CLICKED ||
1463 HIWORD(wParam) == BN_DOUBLECLICKED)
1464 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1467 if (HIWORD(wParam) == BN_CLICKED ||
1468 HIWORD(wParam) == BN_DOUBLECLICKED)
1469 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1472 if (HIWORD(wParam) == BN_CLICKED ||
1473 HIWORD(wParam) == BN_DOUBLECLICKED)
1474 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1477 if (HIWORD(wParam) == BN_CLICKED ||
1478 HIWORD(wParam) == BN_DOUBLECLICKED)
1479 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1481 case IDC_ECHOBACKEND:
1484 if (HIWORD(wParam) == BN_CLICKED ||
1485 HIWORD(wParam) == BN_DOUBLECLICKED) {
1486 if (LOWORD(wParam)==IDC_ECHOBACKEND) cfg.localecho=LD_BACKEND;
1487 if (LOWORD(wParam)==IDC_ECHOYES) cfg.localecho=LD_YES;
1488 if (LOWORD(wParam)==IDC_ECHONO) cfg.localecho=LD_NO;
1491 case IDC_EDITBACKEND:
1494 if (HIWORD(wParam) == BN_CLICKED ||
1495 HIWORD(wParam) == BN_DOUBLECLICKED) {
1496 if (LOWORD(wParam)==IDC_EDITBACKEND) cfg.localedit=LD_BACKEND;
1497 if (LOWORD(wParam)==IDC_EDITYES) cfg.localedit=LD_YES;
1498 if (LOWORD(wParam)==IDC_EDITNO) cfg.localedit=LD_NO;
1501 case IDC_ANSWEREDIT:
1502 if (HIWORD(wParam) == EN_CHANGE)
1503 GetDlgItemText (hwnd, IDC_ANSWEREDIT, cfg.answerback,
1504 sizeof(cfg.answerback)-1);
1506 case IDC_ALWAYSONTOP:
1507 if (HIWORD(wParam) == BN_CLICKED ||
1508 HIWORD(wParam) == BN_DOUBLECLICKED)
1509 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1512 if (HIWORD(wParam) == BN_CLICKED ||
1513 HIWORD(wParam) == BN_DOUBLECLICKED)
1514 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1516 case IDC_SCROLLDISP:
1517 if (HIWORD(wParam) == BN_CLICKED ||
1518 HIWORD(wParam) == BN_DOUBLECLICKED)
1519 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1521 case IDC_COMPOSEKEY:
1522 if (HIWORD(wParam) == BN_CLICKED ||
1523 HIWORD(wParam) == BN_DOUBLECLICKED)
1524 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1527 if (HIWORD(wParam) == BN_CLICKED ||
1528 HIWORD(wParam) == BN_DOUBLECLICKED)
1529 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1532 if (HIWORD(wParam) == BN_CLICKED ||
1533 HIWORD(wParam) == BN_DOUBLECLICKED)
1534 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1537 if (HIWORD(wParam) == BN_CLICKED ||
1538 HIWORD(wParam) == BN_DOUBLECLICKED)
1539 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1542 if (HIWORD(wParam) == EN_CHANGE)
1543 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1546 if (HIWORD(wParam) == EN_CHANGE)
1547 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1550 if (HIWORD(wParam) == EN_CHANGE)
1551 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1553 case IDC_CHOOSEFONT:
1554 lf.lfHeight = cfg.fontheight;
1555 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1556 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1557 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1558 lf.lfCharSet = cfg.fontcharset;
1559 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1560 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1561 lf.lfQuality = DEFAULT_QUALITY;
1562 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1563 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1564 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1566 cf.lStructSize = sizeof(cf);
1567 cf.hwndOwner = hwnd;
1569 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1570 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1572 if (ChooseFont (&cf)) {
1573 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1574 cfg.font[sizeof(cfg.font)-1] = '\0';
1575 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1576 cfg.fontcharset = lf.lfCharSet;
1577 cfg.fontheight = cf.iPointSize / 10;
1578 fmtfont (fontstatic);
1579 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1583 if (HIWORD(wParam) == BN_CLICKED ||
1584 HIWORD(wParam) == BN_DOUBLECLICKED)
1585 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1588 if (HIWORD(wParam) == BN_CLICKED ||
1589 HIWORD(wParam) == BN_DOUBLECLICKED)
1590 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1593 if (HIWORD(wParam) == BN_CLICKED ||
1594 HIWORD(wParam) == BN_DOUBLECLICKED)
1595 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1598 if (HIWORD(wParam) == BN_CLICKED ||
1599 HIWORD(wParam) == BN_DOUBLECLICKED)
1600 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1603 if (HIWORD(wParam) == BN_CLICKED ||
1604 HIWORD(wParam) == BN_DOUBLECLICKED)
1605 cfg.hide_mouseptr = IsDlgButtonChecked (hwnd, IDC_HIDEMOUSE);
1608 if (HIWORD(wParam) == BN_CLICKED ||
1609 HIWORD(wParam) == BN_DOUBLECLICKED)
1610 cfg.cursor_type = 0;
1613 if (HIWORD(wParam) == BN_CLICKED ||
1614 HIWORD(wParam) == BN_DOUBLECLICKED)
1615 cfg.cursor_type = 1;
1618 if (HIWORD(wParam) == BN_CLICKED ||
1619 HIWORD(wParam) == BN_DOUBLECLICKED)
1620 cfg.cursor_type = 2;
1623 if (HIWORD(wParam) == BN_CLICKED ||
1624 HIWORD(wParam) == BN_DOUBLECLICKED)
1625 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1628 if (HIWORD(wParam) == BN_CLICKED ||
1629 HIWORD(wParam) == BN_DOUBLECLICKED)
1630 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1633 if (HIWORD(wParam) == BN_CLICKED ||
1634 HIWORD(wParam) == BN_DOUBLECLICKED)
1635 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1638 if (HIWORD(wParam) == EN_CHANGE)
1639 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1640 sizeof(cfg.wintitle)-1);
1645 if (HIWORD(wParam) == BN_CLICKED ||
1646 HIWORD(wParam) == BN_DOUBLECLICKED) {
1647 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_COEALWAYS) ? COE_ALWAYS :
1648 IsDlgButtonChecked (hwnd, IDC_COENEVER) ? COE_NEVER :
1653 if (HIWORD(wParam) == BN_CLICKED ||
1654 HIWORD(wParam) == BN_DOUBLECLICKED)
1655 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1658 if (HIWORD(wParam) == EN_CHANGE)
1659 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1660 sizeof(cfg.termtype)-1);
1663 if (HIWORD(wParam) == EN_CHANGE)
1664 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1665 sizeof(cfg.logfilename)-1);
1668 memset(&of, 0, sizeof(of));
1669 #ifdef OPENFILENAME_SIZE_VERSION_400
1670 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1672 of.lStructSize = sizeof(of);
1674 of.hwndOwner = hwnd;
1675 of.lpstrFilter = "All Files\0*\0\0\0";
1676 of.lpstrCustomFilter = NULL;
1677 of.nFilterIndex = 1;
1678 of.lpstrFile = filename; strcpy(filename, cfg.logfilename);
1679 of.nMaxFile = sizeof(filename);
1680 of.lpstrFileTitle = NULL;
1681 of.lpstrInitialDir = NULL;
1682 of.lpstrTitle = "Select session log file";
1684 if (GetSaveFileName(&of)) {
1685 strcpy(cfg.logfilename, filename);
1686 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
1690 case IDC_LSTATASCII:
1692 if (HIWORD(wParam) == BN_CLICKED ||
1693 HIWORD(wParam) == BN_DOUBLECLICKED) {
1694 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1695 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1696 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1701 if (HIWORD(wParam) == EN_CHANGE)
1702 GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed,
1703 sizeof(cfg.termspeed)-1);
1706 if (HIWORD(wParam) == EN_CHANGE)
1707 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1708 sizeof(cfg.username)-1);
1710 case IDC_RLLUSEREDIT:
1711 if (HIWORD(wParam) == EN_CHANGE)
1712 GetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername,
1713 sizeof(cfg.localusername)-1);
1717 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1720 if (HIWORD(wParam) == BN_CLICKED ||
1721 HIWORD(wParam) == BN_DOUBLECLICKED) {
1722 char str[sizeof(cfg.environmt)];
1724 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1729 p = str + strlen(str);
1731 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1741 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1743 p[strlen(str)+1] = '\0';
1744 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1746 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1747 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1749 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1750 MB_OK | MB_ICONERROR);
1755 if (HIWORD(wParam) != BN_CLICKED &&
1756 HIWORD(wParam) != BN_DOUBLECLICKED)
1758 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1764 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1789 if (HIWORD(wParam) == BN_CLICKED ||
1790 HIWORD(wParam) == BN_DOUBLECLICKED)
1791 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1794 if (HIWORD(wParam) == BN_CLICKED ||
1795 HIWORD(wParam) == BN_DOUBLECLICKED)
1796 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1799 if (HIWORD(wParam) == BN_CLICKED ||
1800 HIWORD(wParam) == BN_DOUBLECLICKED)
1801 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1804 if (HIWORD(wParam) == BN_CLICKED ||
1805 HIWORD(wParam) == BN_DOUBLECLICKED)
1806 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1808 case IDC_CIPHER3DES:
1809 case IDC_CIPHERBLOWF:
1812 if (HIWORD(wParam) == BN_CLICKED ||
1813 HIWORD(wParam) == BN_DOUBLECLICKED) {
1814 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1815 cfg.cipher = CIPHER_3DES;
1816 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1817 cfg.cipher = CIPHER_BLOWFISH;
1818 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1819 cfg.cipher = CIPHER_DES;
1820 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERAES))
1821 cfg.cipher = CIPHER_AES;
1826 if (HIWORD(wParam) == BN_CLICKED ||
1827 HIWORD(wParam) == BN_DOUBLECLICKED) {
1828 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1830 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1835 if (HIWORD(wParam) == BN_CLICKED ||
1836 HIWORD(wParam) == BN_DOUBLECLICKED)
1837 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1840 if (HIWORD(wParam) == EN_CHANGE)
1841 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1842 sizeof(cfg.keyfile)-1);
1845 if (HIWORD(wParam) == EN_CHANGE)
1846 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1847 sizeof(cfg.remote_cmd)-1);
1850 memset(&of, 0, sizeof(of));
1851 #ifdef OPENFILENAME_SIZE_VERSION_400
1852 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1854 of.lStructSize = sizeof(of);
1856 of.hwndOwner = hwnd;
1857 of.lpstrFilter = "All Files\0*\0\0\0";
1858 of.lpstrCustomFilter = NULL;
1859 of.nFilterIndex = 1;
1860 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1861 of.nMaxFile = sizeof(filename);
1862 of.lpstrFileTitle = NULL;
1863 of.lpstrInitialDir = NULL;
1864 of.lpstrTitle = "Select Public Key File";
1866 if (GetOpenFileName(&of)) {
1867 strcpy(cfg.keyfile, filename);
1868 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1872 cfg.rawcnp = IsDlgButtonChecked (hwnd, IDC_RAWCNP);
1875 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1881 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1886 for (i=0; i<256; i++)
1887 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1890 cfg.wordness[i] = n;
1891 SendDlgItemMessage (hwnd, IDC_CCLIST,
1892 LB_DELETESTRING, i, 0);
1893 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1894 (i>=0x21 && i != 0x7F) ? i : ' ',
1896 SendDlgItemMessage (hwnd, IDC_CCLIST,
1903 case IDC_BOLDCOLOUR:
1904 if (HIWORD(wParam) == BN_CLICKED ||
1905 HIWORD(wParam) == BN_DOUBLECLICKED) {
1907 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1908 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1909 if (n != 12+10*cfg.bold_colour) {
1911 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1912 LB_DELETESTRING, i, 0);
1913 for (i=0; i<22; i++)
1914 if (cfg.bold_colour || permcolour[i])
1915 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1917 (LPARAM) colours[i]);
1922 if (HIWORD(wParam) == BN_CLICKED ||
1923 HIWORD(wParam) == BN_DOUBLECLICKED)
1924 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1926 case IDC_COLOURLIST:
1927 if (HIWORD(wParam) == LBN_DBLCLK ||
1928 HIWORD(wParam) == LBN_SELCHANGE) {
1929 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1931 if (!cfg.bold_colour)
1932 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1933 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1934 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1935 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1939 if (HIWORD(wParam) == BN_CLICKED ||
1940 HIWORD(wParam) == BN_DOUBLECLICKED) {
1941 static CHOOSECOLOR cc;
1942 static DWORD custom[16] = {0}; /* zero initialisers */
1943 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1945 if (!cfg.bold_colour)
1946 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1947 cc.lStructSize = sizeof(cc);
1948 cc.hwndOwner = hwnd;
1949 cc.hInstance = (HWND)hinst;
1950 cc.lpCustColors = custom;
1951 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1953 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1954 if (ChooseColor(&cc)) {
1956 (unsigned char) (cc.rgbResult & 0xFF);
1958 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1960 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1961 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1963 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1965 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1971 case IDC_KOI8WIN1251:
1972 case IDC_88592WIN1250:
1973 case IDC_88592CP852:
1974 cfg.xlat_enablekoiwin =
1975 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1976 cfg.xlat_88592w1250 =
1977 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1978 cfg.xlat_88592cp852 =
1979 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1981 case IDC_CAPSLOCKCYR:
1982 if (HIWORD(wParam) == BN_CLICKED ||
1983 HIWORD(wParam) == BN_DOUBLECLICKED) {
1984 cfg.xlat_capslockcyr =
1985 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1988 case IDC_VTXWINDOWS:
1993 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1994 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1995 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1998 case IDC_X11_FORWARD:
1999 if (HIWORD(wParam) == BN_CLICKED ||
2000 HIWORD(wParam) == BN_DOUBLECLICKED)
2001 cfg.x11_forward = IsDlgButtonChecked (hwnd, IDC_X11_FORWARD);
2003 case IDC_X11_DISPLAY:
2004 if (HIWORD(wParam) == EN_CHANGE)
2005 GetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2006 sizeof(cfg.x11_display)-1);
2011 EndDialog (hwnd, 0);
2014 /* Grrr Explorer will maximize Dialogs! */
2016 if (wParam == SIZE_MAXIMIZED)
2023 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
2024 WPARAM wParam, LPARAM lParam) {
2025 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2027 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2028 EnableWindow(hwnd, 0);
2029 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2030 GetParent(hwnd), AboutProc);
2031 EnableWindow(hwnd, 1);
2032 SetActiveWindow(hwnd);
2034 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
2037 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
2038 WPARAM wParam, LPARAM lParam) {
2039 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
2042 void defuse_showwindow(void) {
2044 * Work around the fact that the app's first call to ShowWindow
2045 * will ignore the default in favour of the shell-provided
2050 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2052 ShowWindow(hwnd, SW_HIDE);
2053 DestroyWindow(hwnd);
2057 int do_config (void) {
2061 savedsession[0] = '\0';
2062 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2063 get_sesslist(FALSE);
2068 int do_reconfig (HWND hwnd) {
2072 backup_cfg = cfg; /* structure copy */
2073 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2075 cfg = backup_cfg; /* structure copy */
2080 void logevent (char *string) {
2084 if (nevents >= negsize) {
2086 events = srealloc (events, negsize * sizeof(*events));
2090 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t", localtime(&t));
2092 events[nevents] = smalloc(strlen(timebuf)+strlen(string)+1);
2093 strcpy(events[nevents], timebuf);
2094 strcat(events[nevents], string);
2097 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
2098 0, (LPARAM)events[nevents]);
2099 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2100 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
2105 void showeventlog (HWND hwnd) {
2107 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2109 ShowWindow (logbox, SW_SHOWNORMAL);
2111 SetActiveWindow(logbox);
2114 void showabout (HWND hwnd) {
2115 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),hwnd, AboutProc);
2118 void verify_ssh_host_key(char *host, int port, char *keytype,
2119 char *keystr, char *fingerprint) {
2122 static const char absentmsg[] =
2123 "The server's host key is not cached in the registry. You\n"
2124 "have no guarantee that the server is the computer you\n"
2126 "The server's key fingerprint is:\n"
2128 "If you trust this host, hit Yes to add the key to\n"
2129 "PuTTY's cache and carry on connecting.\n"
2130 "If you do not trust this host, hit No to abandon the\n"
2133 static const char wrongmsg[] =
2134 "WARNING - POTENTIAL SECURITY BREACH!\n"
2136 "The server's host key does not match the one PuTTY has\n"
2137 "cached in the registry. This means that either the\n"
2138 "server administrator has changed the host key, or you\n"
2139 "have actually connected to another computer pretending\n"
2140 "to be the server.\n"
2141 "The new key fingerprint is:\n"
2143 "If you were expecting this change and trust the new key,\n"
2144 "hit Yes to update PuTTY's cache and continue connecting.\n"
2145 "If you want to carry on connecting but without updating\n"
2146 "the cache, hit No.\n"
2147 "If you want to abandon the connection completely, hit\n"
2148 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2151 static const char mbtitle[] = "PuTTY Security Alert";
2154 char message[160+ /* sensible fingerprint max size */
2155 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2156 sizeof(absentmsg) : sizeof(wrongmsg))];
2159 * Verify the key against the registry.
2161 ret = verify_host_key(host, port, keytype, keystr);
2163 if (ret == 0) /* success - key matched OK */
2165 if (ret == 2) { /* key was different */
2167 sprintf(message, wrongmsg, fingerprint);
2168 mbret = MessageBox(NULL, message, mbtitle,
2169 MB_ICONWARNING | MB_YESNOCANCEL);
2171 store_host_key(host, port, keytype, keystr);
2172 if (mbret == IDCANCEL)
2175 if (ret == 1) { /* key was absent */
2177 sprintf(message, absentmsg, fingerprint);
2178 mbret = MessageBox(NULL, message, mbtitle,
2179 MB_ICONWARNING | MB_YESNO);
2182 store_host_key(host, port, keytype, keystr);
2187 * Ask whether to wipe a session log file before writing to it.
2188 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2190 int askappend(char *filename) {
2191 static const char mbtitle[] = "PuTTY Log to File";
2192 static const char msgtemplate[] =
2193 "The session log file \"%.*s\" already exists.\n"
2194 "You can overwrite it with a new session log,\n"
2195 "append your session log to the end of it,\n"
2196 "or disable session logging for this session.\n"
2197 "Hit Yes to wipe the file, No to append to it,\n"
2198 "or Cancel to disable logging.";
2199 char message[sizeof(msgtemplate) + FILENAME_MAX];
2201 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2203 mbret = MessageBox(NULL, message, mbtitle,
2204 MB_ICONQUESTION | MB_YESNOCANCEL);
2207 else if (mbret == IDNO)