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,
309 appearancepanelstart,
310 IDC_TITLE_APPEARANCE,
328 connectionpanelstart,
329 IDC_TITLE_CONNECTION,
427 translationpanelstart,
428 IDC_TITLE_TRANSLATION,
429 IDC_BOX_TRANSLATION1,
430 IDC_BOX_TRANSLATION2,
431 IDC_BOX_TRANSLATION3,
456 static const char *const colours[] = {
457 "Default Foreground", "Default Bold Foreground",
458 "Default Background", "Default Bold Background",
459 "Cursor Text", "Cursor Colour",
460 "ANSI Black", "ANSI Black Bold",
461 "ANSI Red", "ANSI Red Bold",
462 "ANSI Green", "ANSI Green Bold",
463 "ANSI Yellow", "ANSI Yellow Bold",
464 "ANSI Blue", "ANSI Blue Bold",
465 "ANSI Magenta", "ANSI Magenta Bold",
466 "ANSI Cyan", "ANSI Cyan Bold",
467 "ANSI White", "ANSI White Bold"
469 static const int permcolour[] = {
470 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
471 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
472 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
475 static void fmtfont (char *buf) {
476 sprintf (buf, "Font: %s, ", cfg.font);
478 strcat(buf, "bold, ");
479 if (cfg.fontheight == 0)
480 strcat (buf, "default height");
482 sprintf (buf+strlen(buf), "%d-point",
483 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
486 static void init_dlg_ctrls(HWND hwnd) {
488 char fontstatic[256];
490 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
491 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
494 n = SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
496 SendDlgItemMessage (hwnd, IDC_SESSLIST,
497 LB_DELETESTRING, i, 0);
498 for (i = 0; i < nsessions; i++)
499 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
500 0, (LPARAM) (sessions[i]));
502 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
503 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
504 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
505 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET :
506 cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW );
507 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
509 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
510 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
511 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
512 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
513 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
514 cfg.funky_type == 0 ? IDC_FUNCTILDE :
515 cfg.funky_type == 1 ? IDC_FUNCLINUX :
516 cfg.funky_type == 2 ? IDC_FUNCXTERM :
517 cfg.funky_type == 3 ? IDC_FUNCVT400 :
519 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
520 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
521 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
522 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
523 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
524 cfg.nethack_keypad ? IDC_KPNH :
525 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
526 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
527 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
528 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
529 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
530 CheckDlgButton (hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
531 CheckRadioButton (hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
532 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND:
533 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
534 CheckRadioButton (hwnd, IDC_EDITBACKEND, IDC_EDITNO,
535 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND:
536 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
537 SetDlgItemText (hwnd, IDC_ANSWEREDIT, cfg.answerback);
538 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
539 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
540 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
542 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
543 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
544 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
545 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
546 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
547 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
548 fmtfont (fontstatic);
549 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
550 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
551 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
552 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
554 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
555 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
556 CheckDlgButton (hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
557 CheckRadioButton (hwnd, IDC_CURBLOCK, IDC_CURVERT,
558 cfg.cursor_type==0 ? IDC_CURBLOCK :
559 cfg.cursor_type==1 ? IDC_CURUNDER : IDC_CURVERT);
560 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
561 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
562 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
563 CheckRadioButton (hwnd, IDC_COEALWAYS, IDC_COENORMAL,
564 cfg.close_on_exit==COE_NORMAL ? IDC_COENORMAL :
565 cfg.close_on_exit==COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
566 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
568 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
569 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
570 SetDlgItemText (hwnd, IDC_R_TSEDIT, cfg.termspeed);
571 SetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername);
572 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
573 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
574 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
575 cfg.logtype == 0 ? IDC_LSTATOFF :
576 cfg.logtype == 1 ? IDC_LSTATASCII :
579 char *p = cfg.environmt;
581 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
586 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
587 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
589 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
590 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
591 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
592 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
593 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
594 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
595 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERAES,
596 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
597 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
598 cfg.cipher == CIPHER_AES ? IDC_CIPHERAES :
600 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
601 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
602 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
603 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
604 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
606 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
607 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
608 CheckDlgButton (hwnd, IDC_RAWCNP, cfg.rawcnp);
610 static int tabs[4] = {25, 61, 96, 128};
611 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
614 for (i=0; i<256; i++) {
616 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
617 (i>=0x21 && i != 0x7F) ? i : ' ',
619 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
623 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
624 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
627 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
629 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
630 LB_DELETESTRING, i, 0);
632 if (cfg.bold_colour || permcolour[i])
633 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
634 (LPARAM) colours[i]);
636 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
637 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
638 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
639 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
641 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
642 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
643 cfg.xlat_88592cp852 ? IDC_88592CP852 :
644 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
646 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
647 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
648 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
649 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
650 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
653 CheckDlgButton (hwnd, IDC_X11_FORWARD, cfg.x11_forward);
654 SetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display);
657 struct treeview_faff {
662 static HTREEITEM treeview_insert(struct treeview_faff *faff,
663 int level, char *text) {
667 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
668 ins.hInsertAfter = faff->lastat[level];
669 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
670 #define INSITEM DUMMYUNIONNAME.item
674 ins.INSITEM.mask = TVIF_TEXT;
675 ins.INSITEM.pszText = text;
676 newitem = TreeView_InsertItem(faff->treeview, &ins);
678 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
679 faff->lastat[level] = newitem;
680 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
685 * Create the panelfuls of controls in the configuration box.
687 static void create_controls(HWND hwnd, int dlgtype, int panel) {
688 if (panel == sessionpanelstart) {
689 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
691 ctlposinit(&cp, hwnd, 80, 3, 13);
692 bartitle(&cp, "Basic options for your PuTTY session",
695 beginbox(&cp, "Specify your connection by host name",
698 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
699 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
700 if (backends[3].backend == NULL) {
701 /* this is PuTTYtel, so only three protocols available */
702 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
704 "&Telnet", IDC_PROTTELNET,
705 "Rlog&in", IDC_PROTRLOGIN, NULL);
707 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
709 "&Telnet", IDC_PROTTELNET,
710 "Rlog&in", IDC_PROTRLOGIN,
719 beginbox(&cp, "Load, save or delete a stored session",
721 sesssaver(&cp, "Sav&ed Sessions",
722 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
723 "&Load", IDC_SESSLOAD,
724 "&Save", IDC_SESSSAVE,
725 "&Delete", IDC_SESSDEL, NULL);
728 beginbox(&cp, NULL, IDC_BOX_SESSION3);
729 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
730 "Always", IDC_COEALWAYS,
731 "Never", IDC_COENEVER,
732 "Only on clean exit", IDC_COENORMAL, NULL);
736 if (panel == loggingpanelstart) {
737 /* The Logging panel. Accelerators used: [acgo] tplfw */
739 ctlposinit(&cp, hwnd, 80, 3, 13);
740 bartitle(&cp, "Options controlling session logging",
742 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
744 "Session logging:", IDC_LSTATSTATIC,
745 "Logging &turned off completely", IDC_LSTATOFF,
746 "Log &printable output only", IDC_LSTATASCII,
747 "&Log all session output", IDC_LSTATRAW, NULL);
748 editbutton(&cp, "Log &file name:",
749 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
754 if (panel == terminalpanelstart) {
755 /* The Terminal panel. Accelerators used: [acgo] wdlben hts */
757 ctlposinit(&cp, hwnd, 80, 3, 13);
758 bartitle(&cp, "Options controlling the terminal emulation",
760 beginbox(&cp, "Set various terminal options",
762 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
763 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
764 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
765 checkbox(&cp, "&Beep enabled", IDC_BEEP);
766 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
767 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
769 "An&swerback to ^E:", IDC_ANSWERBACK,
770 IDC_ANSWEREDIT, 100, NULL);
773 beginbox(&cp, "Line discipline options",
775 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
776 "Auto", IDC_ECHOBACKEND,
777 "Force on", IDC_ECHOYES,
778 "Force off", IDC_ECHONO, NULL);
779 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
780 "Auto", IDC_EDITBACKEND,
781 "Force on", IDC_EDITYES,
782 "Force off", IDC_EDITNO, NULL);
786 if (panel == keyboardpanelstart) {
787 /* The Keyboard panel. Accelerators used: [acgo] h?sr~lxvunpymietd */
789 ctlposinit(&cp, hwnd, 80, 3, 13);
790 bartitle(&cp, "Options controlling the effects of keys",
792 beginbox(&cp, "Change the sequences sent by:",
794 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
795 "Control-&H", IDC_DEL008,
796 "Control-&? (127)", IDC_DEL127, NULL);
797 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
798 "&Standard", IDC_HOMETILDE,
799 "&rxvt", IDC_HOMERXVT, NULL);
800 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
801 "ESC[n&~", IDC_FUNCTILDE,
802 "&Linux", IDC_FUNCLINUX,
803 "&Xterm R6", IDC_FUNCXTERM,
804 "&VT400", IDC_FUNCVT400, NULL);
806 beginbox(&cp, "Application keypad settings:",
809 "Application c&ursor keys totally disabled",
811 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
812 "&Normal", IDC_CURNORMAL,
813 "A&pplication", IDC_CURAPPLIC, NULL);
815 "Application ke&ypad keys totally disabled",
817 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
818 "Nor&mal", IDC_KPNORMAL,
819 "Appl&ication", IDC_KPAPPLIC,
820 "N&etHack", IDC_KPNH, NULL);
822 beginbox(&cp, "Enable extra keyboard features:",
824 checkbox(&cp, "AltGr ac&ts as Compose key",
826 checkbox(&cp, "Control-Alt is &different from AltGr",
831 if (panel == windowpanelstart) {
832 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
834 ctlposinit(&cp, hwnd, 80, 3, 13);
835 bartitle(&cp, "Options controlling PuTTY's window",
837 beginbox(&cp, "Set the size of the window",
840 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
841 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
843 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
845 beginbox(&cp, "Control the scrollback in the window",
847 staticedit(&cp, "Lines of &scrollback",
848 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
849 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
850 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
851 checkbox(&cp, "Reset scrollback on dis&play activity",
854 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
855 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
856 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
857 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
858 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
859 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
863 if (panel == appearancepanelstart) {
864 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p */
866 ctlposinit(&cp, hwnd, 80, 3, 13);
867 bartitle(&cp, "Options controlling PuTTY's appearance",
868 IDC_TITLE_APPEARANCE);
869 beginbox(&cp, "Adjust the use of the cursor",
870 IDC_BOX_APPEARANCE1);
871 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
872 "B&lock", IDC_CURBLOCK,
873 "&Underline", IDC_CURUNDER,
874 "&Vertical line", IDC_CURVERT,
876 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
878 beginbox(&cp, "Set the font used in the terminal window",
879 IDC_BOX_APPEARANCE2);
880 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
882 beginbox(&cp, "Adjust the use of the window title",
883 IDC_BOX_APPEARANCE3);
885 "Window &title:", IDC_WINTITLE,
886 IDC_WINEDIT, 100, NULL);
887 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
889 beginbox(&cp, "Adjust the use of the mouse pointer",
890 IDC_BOX_APPEARANCE4);
891 checkbox(&cp, "Hide mouse &pointer when typing in window",
896 if (panel == translationpanelstart) {
897 /* The Translation panel. Accelerators used: [acgo] xbep t s */
899 ctlposinit(&cp, hwnd, 80, 3, 13);
900 bartitle(&cp, "Options controlling character set translation",
901 IDC_TITLE_TRANSLATION);
902 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
903 IDC_BOX_TRANSLATION1);
905 "Handling of line drawing characters:", IDC_VTSTATIC,
906 "Font has &XWindows encoding", IDC_VTXWINDOWS,
907 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
908 "Use font in O&EM mode only", IDC_VTOEMONLY,
909 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
910 IDC_VTPOORMAN, NULL);
912 beginbox(&cp, "Enable character set translation on received data",
913 IDC_BOX_TRANSLATION2);
915 "Character set &translation:", IDC_XLATSTATIC,
917 "KOI8 / Win-1251", IDC_KOI8WIN1251,
918 "ISO-8859-2 / Win-1250", IDC_88592WIN1250,
919 "ISO-8859-2 / CP852", IDC_88592CP852, NULL);
921 beginbox(&cp, "Enable character set translation on input data",
922 IDC_BOX_TRANSLATION3);
923 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
928 if (panel == selectionpanelstart) {
929 /* The Selection panel. Accelerators used: [acgo] d wx hst */
931 ctlposinit(&cp, hwnd, 80, 3, 13);
932 bartitle(&cp, "Options controlling copy and paste",
933 IDC_TITLE_SELECTION);
934 beginbox(&cp, "Translation of pasted characters",
936 checkbox(&cp, "&Don't translate line drawing chars into +, - and |",
939 beginbox(&cp, "Control which mouse button does which thing",
941 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
942 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
943 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
946 beginbox(&cp, "Control the select-one-word-at-a-time mode",
948 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
949 "&Set", IDC_CCSET, IDC_CCEDIT,
950 "&to class", IDC_CCSTATIC2);
954 if (panel == colourspanelstart) {
955 /* The Colours panel. Accelerators used: [acgo] blum */
957 ctlposinit(&cp, hwnd, 80, 3, 13);
958 bartitle(&cp, "Options controlling use of colours",
960 beginbox(&cp, "General options for colour usage",
962 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
963 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
965 beginbox(&cp, "Adjust the precise colours PuTTY displays",
967 colouredit(&cp, "Select a colo&ur and then click to modify it:",
968 IDC_COLOURSTATIC, IDC_COLOURLIST,
969 "&Modify...", IDC_CHANGE,
970 "Red:", IDC_RSTATIC, IDC_RVALUE,
971 "Green:", IDC_GSTATIC, IDC_GVALUE,
972 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
976 if (panel == connectionpanelstart) {
977 /* The Connection panel. Accelerators used: [acgo] tuk */
979 ctlposinit(&cp, hwnd, 80, 3, 13);
980 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
982 beginbox(&cp, "Data to send to the server",
983 IDC_BOX_CONNECTION1);
984 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
985 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
988 beginbox(&cp, "Sending of null packets to keep session active",
989 IDC_BOX_CONNECTION2);
990 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
991 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
995 if (panel == telnetpanelstart) {
996 /* The Telnet panel. Accelerators used: [acgo] svldr bf */
998 ctlposinit(&cp, hwnd, 80, 3, 13);
1000 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
1001 beginbox(&cp, "Data to send to the server",
1003 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
1004 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1005 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
1006 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
1008 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1010 beginbox(&cp, "Telnet protocol adjustments",
1012 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
1013 "&BSD (commonplace)", IDC_EMBSD,
1014 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1019 if (panel == rloginpanelstart) {
1020 /* The Rlogin panel. Accelerators used: [acgo] sl */
1022 ctlposinit(&cp, hwnd, 80, 3, 13);
1024 bartitle(&cp, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN);
1025 beginbox(&cp, "Data to send to the server",
1027 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC, IDC_R_TSEDIT, 50);
1028 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC, IDC_RLLUSEREDIT, 50);
1033 if (panel == sshpanelstart) {
1034 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1036 ctlposinit(&cp, hwnd, 80, 3, 13);
1038 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
1039 beginbox(&cp, "Data to send to the server",
1042 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1045 beginbox(&cp, "Authentication options",
1047 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1049 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1050 editbutton(&cp, "Private &key file for authentication:",
1051 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
1053 beginbox(&cp, "Protocol options",
1055 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1056 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1057 radioline(&cp, "Preferred SSH protocol version:",
1058 IDC_SSHPROTSTATIC, 2,
1059 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1060 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 4,
1061 "&3DES", IDC_CIPHER3DES,
1062 "&Blowfish", IDC_CIPHERBLOWF,
1063 "&DES", IDC_CIPHERDES,
1064 "AE&S", IDC_CIPHERAES,
1066 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1072 if (panel == tunnelspanelstart) {
1073 /* The Tunnels panel. Accelerators used: [acgo] ex */
1075 ctlposinit(&cp, hwnd, 80, 3, 13);
1077 bartitle(&cp, "Options controlling SSH tunnelling",
1079 beginbox(&cp, "X11 forwarding options",
1081 checkbox(&cp, "&Enable X11 forwarding",
1083 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1084 IDC_X11_DISPLAY, 50, NULL);
1091 * This function is the configuration box.
1093 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1094 WPARAM wParam, LPARAM lParam,
1097 struct treeview_faff tvfaff;
1100 char filename[sizeof(cfg.keyfile)];
1103 char fontstatic[256];
1105 struct servent * service;
1111 SetWindowLong(hwnd, GWL_USERDATA, 0);
1113 * Centre the window.
1115 { /* centre the window */
1118 hw = GetDesktopWindow();
1119 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1120 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1121 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1122 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1126 * Create the tree view.
1133 r.left = 3; r.right = r.left + 75;
1134 r.top = 3; r.bottom = r.top + 10;
1135 MapDialogRect(hwnd, &r);
1136 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1137 WS_CHILD | WS_VISIBLE,
1139 r.right-r.left, r.bottom-r.top,
1140 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
1141 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1142 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1144 r.left = 3; r.right = r.left + 75;
1145 r.top = 13; r.bottom = r.top + 206;
1146 MapDialogRect(hwnd, &r);
1147 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1148 WS_CHILD | WS_VISIBLE |
1149 WS_TABSTOP | TVS_HASLINES |
1150 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
1151 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
1153 r.right-r.left, r.bottom-r.top,
1154 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
1155 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1156 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1157 tvfaff.treeview = treeview;
1158 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1162 * Set up the tree view contents.
1164 hsession = treeview_insert(&tvfaff, 0, "Session");
1165 treeview_insert(&tvfaff, 1, "Logging");
1166 treeview_insert(&tvfaff, 0, "Terminal");
1167 treeview_insert(&tvfaff, 1, "Keyboard");
1168 treeview_insert(&tvfaff, 0, "Window");
1169 treeview_insert(&tvfaff, 1, "Appearance");
1170 treeview_insert(&tvfaff, 1, "Translation");
1171 treeview_insert(&tvfaff, 1, "Selection");
1172 treeview_insert(&tvfaff, 1, "Colours");
1173 treeview_insert(&tvfaff, 0, "Connection");
1175 treeview_insert(&tvfaff, 1, "Telnet");
1176 treeview_insert(&tvfaff, 1, "Rlogin");
1177 if (backends[3].backend != NULL) {
1178 treeview_insert(&tvfaff, 1, "SSH");
1179 treeview_insert(&tvfaff, 2, "Tunnels");
1184 * Put the treeview selection on to the Session panel. This
1185 * should also cause creation of the relevant controls.
1187 TreeView_SelectItem(treeview, hsession);
1190 * Set focus into the first available control.
1194 ctl = GetDlgItem(hwnd, IDC_HOST);
1195 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1199 SetWindowLong(hwnd, GWL_USERDATA, 1);
1203 * Button release should trigger WM_OK if there was a
1204 * previous double click on the session list.
1208 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1211 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1212 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1213 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1218 item.pszText = buffer;
1219 item.cchTextMax = sizeof(buffer);
1220 item.mask = TVIF_TEXT;
1221 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1222 for (j = controlstartvalue; j < controlendvalue; j++) {
1223 HWND item = GetDlgItem(hwnd, j);
1225 DestroyWindow(item);
1227 if (!strcmp(buffer, "Session"))
1228 create_controls(hwnd, dlgtype, sessionpanelstart);
1229 if (!strcmp(buffer, "Logging"))
1230 create_controls(hwnd, dlgtype, loggingpanelstart);
1231 if (!strcmp(buffer, "Keyboard"))
1232 create_controls(hwnd, dlgtype, keyboardpanelstart);
1233 if (!strcmp(buffer, "Terminal"))
1234 create_controls(hwnd, dlgtype, terminalpanelstart);
1235 if (!strcmp(buffer, "Window"))
1236 create_controls(hwnd, dlgtype, windowpanelstart);
1237 if (!strcmp(buffer, "Appearance"))
1238 create_controls(hwnd, dlgtype, appearancepanelstart);
1239 if (!strcmp(buffer, "Tunnels"))
1240 create_controls(hwnd, dlgtype, tunnelspanelstart);
1241 if (!strcmp(buffer, "Connection"))
1242 create_controls(hwnd, dlgtype, connectionpanelstart);
1243 if (!strcmp(buffer, "Telnet"))
1244 create_controls(hwnd, dlgtype, telnetpanelstart);
1245 if (!strcmp(buffer, "Rlogin"))
1246 create_controls(hwnd, dlgtype, rloginpanelstart);
1247 if (!strcmp(buffer, "SSH"))
1248 create_controls(hwnd, dlgtype, sshpanelstart);
1249 if (!strcmp(buffer, "Selection"))
1250 create_controls(hwnd, dlgtype, selectionpanelstart);
1251 if (!strcmp(buffer, "Colours"))
1252 create_controls(hwnd, dlgtype, colourspanelstart);
1253 if (!strcmp(buffer, "Translation"))
1254 create_controls(hwnd, dlgtype, translationpanelstart);
1256 init_dlg_ctrls(hwnd);
1258 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1264 * Only process WM_COMMAND once the dialog is fully formed.
1266 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1269 EndDialog (hwnd, 1);
1274 EndDialog (hwnd, 0);
1276 case IDC_PROTTELNET:
1277 case IDC_PROTRLOGIN:
1280 if (HIWORD(wParam) == BN_CLICKED ||
1281 HIWORD(wParam) == BN_DOUBLECLICKED) {
1282 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1283 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1284 int k = IsDlgButtonChecked (hwnd, IDC_PROTRLOGIN);
1285 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN : PROT_RAW ;
1286 if ((cfg.protocol == PROT_SSH && cfg.port != 22) ||
1287 (cfg.protocol == PROT_TELNET && cfg.port != 23) ||
1288 (cfg.protocol == PROT_RLOGIN && cfg.port != 513)) {
1289 cfg.port = i ? 22 : j ? 23 : 513;
1290 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1295 if (HIWORD(wParam) == EN_CHANGE)
1296 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1297 sizeof(cfg.host)-1);
1300 if (HIWORD(wParam) == EN_CHANGE) {
1301 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1302 if (isdigit(portname[0]))
1303 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1305 service = getservbyname(portname, NULL);
1306 if (service) cfg.port = ntohs(service->s_port);
1312 if (HIWORD(wParam) == EN_CHANGE) {
1313 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1315 GetDlgItemText (hwnd, IDC_SESSEDIT,
1316 savedsession, sizeof(savedsession)-1);
1317 savedsession[sizeof(savedsession)-1] = '\0';
1321 if (HIWORD(wParam) == BN_CLICKED ||
1322 HIWORD(wParam) == BN_DOUBLECLICKED) {
1327 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1329 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1330 LB_GETCURSEL, 0, 0);
1335 strcpy (str, sessions[n]);
1337 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1338 get_sesslist (FALSE);
1339 get_sesslist (TRUE);
1340 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1342 for (i = 0; i < nsessions; i++)
1343 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1344 0, (LPARAM) (sessions[i]));
1345 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1351 if (LOWORD(wParam) == IDC_SESSLOAD &&
1352 HIWORD(wParam) != BN_CLICKED &&
1353 HIWORD(wParam) != BN_DOUBLECLICKED)
1355 if (LOWORD(wParam) == IDC_SESSLIST &&
1356 HIWORD(wParam) != LBN_DBLCLK)
1359 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1360 LB_GETCURSEL, 0, 0);
1366 isdef = !strcmp(sessions[n], "Default Settings");
1367 load_settings (sessions[n], !isdef, &cfg);
1368 init_dlg_ctrls(hwnd);
1370 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1372 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1374 if (LOWORD(wParam) == IDC_SESSLIST) {
1376 * A double-click on a saved session should
1377 * actually start the session, not just load it.
1378 * Unless it's Default Settings or some other
1379 * host-less set of saved settings.
1388 if (HIWORD(wParam) == BN_CLICKED ||
1389 HIWORD(wParam) == BN_DOUBLECLICKED) {
1390 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1391 LB_GETCURSEL, 0, 0);
1392 if (n == LB_ERR || n == 0) {
1396 del_settings(sessions[n]);
1397 get_sesslist (FALSE);
1398 get_sesslist (TRUE);
1399 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1401 for (i = 0; i < nsessions; i++)
1402 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1403 0, (LPARAM) (sessions[i]));
1404 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1408 if (HIWORD(wParam) == EN_CHANGE)
1409 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1413 if (HIWORD(wParam) == BN_CLICKED ||
1414 HIWORD(wParam) == BN_DOUBLECLICKED)
1415 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1419 if (HIWORD(wParam) == BN_CLICKED ||
1420 HIWORD(wParam) == BN_DOUBLECLICKED)
1421 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1424 if (HIWORD(wParam) == BN_CLICKED ||
1425 HIWORD(wParam) == BN_DOUBLECLICKED)
1429 if (HIWORD(wParam) == BN_CLICKED ||
1430 HIWORD(wParam) == BN_DOUBLECLICKED)
1435 if (HIWORD(wParam) == BN_CLICKED ||
1436 HIWORD(wParam) == BN_DOUBLECLICKED)
1437 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1441 if (HIWORD(wParam) == BN_CLICKED ||
1442 HIWORD(wParam) == BN_DOUBLECLICKED) {
1443 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1444 cfg.nethack_keypad = FALSE;
1448 if (HIWORD(wParam) == BN_CLICKED ||
1449 HIWORD(wParam) == BN_DOUBLECLICKED) {
1450 cfg.app_keypad = FALSE;
1451 cfg.nethack_keypad = TRUE;
1456 if (HIWORD(wParam) == BN_CLICKED ||
1457 HIWORD(wParam) == BN_DOUBLECLICKED)
1458 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1461 if (HIWORD(wParam) == BN_CLICKED ||
1462 HIWORD(wParam) == BN_DOUBLECLICKED)
1463 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1466 if (HIWORD(wParam) == BN_CLICKED ||
1467 HIWORD(wParam) == BN_DOUBLECLICKED)
1468 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1471 if (HIWORD(wParam) == BN_CLICKED ||
1472 HIWORD(wParam) == BN_DOUBLECLICKED)
1473 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1476 if (HIWORD(wParam) == BN_CLICKED ||
1477 HIWORD(wParam) == BN_DOUBLECLICKED)
1478 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1481 if (HIWORD(wParam) == BN_CLICKED ||
1482 HIWORD(wParam) == BN_DOUBLECLICKED)
1483 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1485 case IDC_ECHOBACKEND:
1488 if (HIWORD(wParam) == BN_CLICKED ||
1489 HIWORD(wParam) == BN_DOUBLECLICKED) {
1490 if (LOWORD(wParam)==IDC_ECHOBACKEND) cfg.localecho=LD_BACKEND;
1491 if (LOWORD(wParam)==IDC_ECHOYES) cfg.localecho=LD_YES;
1492 if (LOWORD(wParam)==IDC_ECHONO) cfg.localecho=LD_NO;
1495 case IDC_EDITBACKEND:
1498 if (HIWORD(wParam) == BN_CLICKED ||
1499 HIWORD(wParam) == BN_DOUBLECLICKED) {
1500 if (LOWORD(wParam)==IDC_EDITBACKEND) cfg.localedit=LD_BACKEND;
1501 if (LOWORD(wParam)==IDC_EDITYES) cfg.localedit=LD_YES;
1502 if (LOWORD(wParam)==IDC_EDITNO) cfg.localedit=LD_NO;
1505 case IDC_ANSWEREDIT:
1506 if (HIWORD(wParam) == EN_CHANGE)
1507 GetDlgItemText (hwnd, IDC_ANSWEREDIT, cfg.answerback,
1508 sizeof(cfg.answerback)-1);
1510 case IDC_ALWAYSONTOP:
1511 if (HIWORD(wParam) == BN_CLICKED ||
1512 HIWORD(wParam) == BN_DOUBLECLICKED)
1513 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1516 if (HIWORD(wParam) == BN_CLICKED ||
1517 HIWORD(wParam) == BN_DOUBLECLICKED)
1518 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1520 case IDC_SCROLLDISP:
1521 if (HIWORD(wParam) == BN_CLICKED ||
1522 HIWORD(wParam) == BN_DOUBLECLICKED)
1523 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1525 case IDC_COMPOSEKEY:
1526 if (HIWORD(wParam) == BN_CLICKED ||
1527 HIWORD(wParam) == BN_DOUBLECLICKED)
1528 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1530 case IDC_CTRLALTKEYS:
1531 if (HIWORD(wParam) == BN_CLICKED ||
1532 HIWORD(wParam) == BN_DOUBLECLICKED)
1533 cfg.ctrlaltkeys = IsDlgButtonChecked (hwnd, IDC_CTRLALTKEYS);
1536 if (HIWORD(wParam) == BN_CLICKED ||
1537 HIWORD(wParam) == BN_DOUBLECLICKED)
1538 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1541 if (HIWORD(wParam) == BN_CLICKED ||
1542 HIWORD(wParam) == BN_DOUBLECLICKED)
1543 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1546 if (HIWORD(wParam) == BN_CLICKED ||
1547 HIWORD(wParam) == BN_DOUBLECLICKED)
1548 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1551 if (HIWORD(wParam) == EN_CHANGE)
1552 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1555 if (HIWORD(wParam) == EN_CHANGE)
1556 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1559 if (HIWORD(wParam) == EN_CHANGE)
1560 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1562 case IDC_CHOOSEFONT:
1563 lf.lfHeight = cfg.fontheight;
1564 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1565 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1566 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1567 lf.lfCharSet = cfg.fontcharset;
1568 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1569 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1570 lf.lfQuality = DEFAULT_QUALITY;
1571 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1572 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1573 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1575 cf.lStructSize = sizeof(cf);
1576 cf.hwndOwner = hwnd;
1578 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1579 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1581 if (ChooseFont (&cf)) {
1582 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1583 cfg.font[sizeof(cfg.font)-1] = '\0';
1584 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1585 cfg.fontcharset = lf.lfCharSet;
1586 cfg.fontheight = cf.iPointSize / 10;
1587 fmtfont (fontstatic);
1588 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1592 if (HIWORD(wParam) == BN_CLICKED ||
1593 HIWORD(wParam) == BN_DOUBLECLICKED)
1594 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1597 if (HIWORD(wParam) == BN_CLICKED ||
1598 HIWORD(wParam) == BN_DOUBLECLICKED)
1599 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1602 if (HIWORD(wParam) == BN_CLICKED ||
1603 HIWORD(wParam) == BN_DOUBLECLICKED)
1604 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1607 if (HIWORD(wParam) == BN_CLICKED ||
1608 HIWORD(wParam) == BN_DOUBLECLICKED)
1609 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1612 if (HIWORD(wParam) == BN_CLICKED ||
1613 HIWORD(wParam) == BN_DOUBLECLICKED)
1614 cfg.hide_mouseptr = IsDlgButtonChecked (hwnd, IDC_HIDEMOUSE);
1617 if (HIWORD(wParam) == BN_CLICKED ||
1618 HIWORD(wParam) == BN_DOUBLECLICKED)
1619 cfg.cursor_type = 0;
1622 if (HIWORD(wParam) == BN_CLICKED ||
1623 HIWORD(wParam) == BN_DOUBLECLICKED)
1624 cfg.cursor_type = 1;
1627 if (HIWORD(wParam) == BN_CLICKED ||
1628 HIWORD(wParam) == BN_DOUBLECLICKED)
1629 cfg.cursor_type = 2;
1632 if (HIWORD(wParam) == BN_CLICKED ||
1633 HIWORD(wParam) == BN_DOUBLECLICKED)
1634 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1637 if (HIWORD(wParam) == BN_CLICKED ||
1638 HIWORD(wParam) == BN_DOUBLECLICKED)
1639 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1642 if (HIWORD(wParam) == BN_CLICKED ||
1643 HIWORD(wParam) == BN_DOUBLECLICKED)
1644 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1647 if (HIWORD(wParam) == EN_CHANGE)
1648 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1649 sizeof(cfg.wintitle)-1);
1654 if (HIWORD(wParam) == BN_CLICKED ||
1655 HIWORD(wParam) == BN_DOUBLECLICKED) {
1656 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_COEALWAYS) ? COE_ALWAYS :
1657 IsDlgButtonChecked (hwnd, IDC_COENEVER) ? COE_NEVER :
1662 if (HIWORD(wParam) == BN_CLICKED ||
1663 HIWORD(wParam) == BN_DOUBLECLICKED)
1664 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1667 if (HIWORD(wParam) == EN_CHANGE)
1668 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1669 sizeof(cfg.termtype)-1);
1672 if (HIWORD(wParam) == EN_CHANGE)
1673 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1674 sizeof(cfg.logfilename)-1);
1677 memset(&of, 0, sizeof(of));
1678 #ifdef OPENFILENAME_SIZE_VERSION_400
1679 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1681 of.lStructSize = sizeof(of);
1683 of.hwndOwner = hwnd;
1684 of.lpstrFilter = "All Files\0*\0\0\0";
1685 of.lpstrCustomFilter = NULL;
1686 of.nFilterIndex = 1;
1687 of.lpstrFile = filename; strcpy(filename, cfg.logfilename);
1688 of.nMaxFile = sizeof(filename);
1689 of.lpstrFileTitle = NULL;
1690 of.lpstrInitialDir = NULL;
1691 of.lpstrTitle = "Select session log file";
1693 if (GetSaveFileName(&of)) {
1694 strcpy(cfg.logfilename, filename);
1695 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
1699 case IDC_LSTATASCII:
1701 if (HIWORD(wParam) == BN_CLICKED ||
1702 HIWORD(wParam) == BN_DOUBLECLICKED) {
1703 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1704 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1705 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1710 if (HIWORD(wParam) == EN_CHANGE)
1711 GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed,
1712 sizeof(cfg.termspeed)-1);
1715 if (HIWORD(wParam) == EN_CHANGE)
1716 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1717 sizeof(cfg.username)-1);
1719 case IDC_RLLUSEREDIT:
1720 if (HIWORD(wParam) == EN_CHANGE)
1721 GetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername,
1722 sizeof(cfg.localusername)-1);
1726 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1729 if (HIWORD(wParam) == BN_CLICKED ||
1730 HIWORD(wParam) == BN_DOUBLECLICKED) {
1731 char str[sizeof(cfg.environmt)];
1733 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1738 p = str + strlen(str);
1740 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1750 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1752 p[strlen(str)+1] = '\0';
1753 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1755 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1756 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1758 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1759 MB_OK | MB_ICONERROR);
1764 if (HIWORD(wParam) != BN_CLICKED &&
1765 HIWORD(wParam) != BN_DOUBLECLICKED)
1767 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1773 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1798 if (HIWORD(wParam) == BN_CLICKED ||
1799 HIWORD(wParam) == BN_DOUBLECLICKED)
1800 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1803 if (HIWORD(wParam) == BN_CLICKED ||
1804 HIWORD(wParam) == BN_DOUBLECLICKED)
1805 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1808 if (HIWORD(wParam) == BN_CLICKED ||
1809 HIWORD(wParam) == BN_DOUBLECLICKED)
1810 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1813 if (HIWORD(wParam) == BN_CLICKED ||
1814 HIWORD(wParam) == BN_DOUBLECLICKED)
1815 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1817 case IDC_CIPHER3DES:
1818 case IDC_CIPHERBLOWF:
1821 if (HIWORD(wParam) == BN_CLICKED ||
1822 HIWORD(wParam) == BN_DOUBLECLICKED) {
1823 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1824 cfg.cipher = CIPHER_3DES;
1825 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1826 cfg.cipher = CIPHER_BLOWFISH;
1827 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1828 cfg.cipher = CIPHER_DES;
1829 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERAES))
1830 cfg.cipher = CIPHER_AES;
1835 if (HIWORD(wParam) == BN_CLICKED ||
1836 HIWORD(wParam) == BN_DOUBLECLICKED) {
1837 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1839 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1844 if (HIWORD(wParam) == BN_CLICKED ||
1845 HIWORD(wParam) == BN_DOUBLECLICKED)
1846 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1849 if (HIWORD(wParam) == EN_CHANGE)
1850 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1851 sizeof(cfg.keyfile)-1);
1854 if (HIWORD(wParam) == EN_CHANGE)
1855 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1856 sizeof(cfg.remote_cmd)-1);
1859 memset(&of, 0, sizeof(of));
1860 #ifdef OPENFILENAME_SIZE_VERSION_400
1861 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1863 of.lStructSize = sizeof(of);
1865 of.hwndOwner = hwnd;
1866 of.lpstrFilter = "All Files\0*\0\0\0";
1867 of.lpstrCustomFilter = NULL;
1868 of.nFilterIndex = 1;
1869 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1870 of.nMaxFile = sizeof(filename);
1871 of.lpstrFileTitle = NULL;
1872 of.lpstrInitialDir = NULL;
1873 of.lpstrTitle = "Select Public Key File";
1875 if (GetOpenFileName(&of)) {
1876 strcpy(cfg.keyfile, filename);
1877 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1881 cfg.rawcnp = IsDlgButtonChecked (hwnd, IDC_RAWCNP);
1884 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1890 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1895 for (i=0; i<256; i++)
1896 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1899 cfg.wordness[i] = n;
1900 SendDlgItemMessage (hwnd, IDC_CCLIST,
1901 LB_DELETESTRING, i, 0);
1902 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1903 (i>=0x21 && i != 0x7F) ? i : ' ',
1905 SendDlgItemMessage (hwnd, IDC_CCLIST,
1912 case IDC_BOLDCOLOUR:
1913 if (HIWORD(wParam) == BN_CLICKED ||
1914 HIWORD(wParam) == BN_DOUBLECLICKED) {
1916 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1917 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1918 if (n != 12+10*cfg.bold_colour) {
1920 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1921 LB_DELETESTRING, i, 0);
1922 for (i=0; i<22; i++)
1923 if (cfg.bold_colour || permcolour[i])
1924 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1926 (LPARAM) colours[i]);
1931 if (HIWORD(wParam) == BN_CLICKED ||
1932 HIWORD(wParam) == BN_DOUBLECLICKED)
1933 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1935 case IDC_COLOURLIST:
1936 if (HIWORD(wParam) == LBN_DBLCLK ||
1937 HIWORD(wParam) == LBN_SELCHANGE) {
1938 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1940 if (!cfg.bold_colour)
1941 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1942 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1943 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1944 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1948 if (HIWORD(wParam) == BN_CLICKED ||
1949 HIWORD(wParam) == BN_DOUBLECLICKED) {
1950 static CHOOSECOLOR cc;
1951 static DWORD custom[16] = {0}; /* zero initialisers */
1952 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1954 if (!cfg.bold_colour)
1955 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1956 cc.lStructSize = sizeof(cc);
1957 cc.hwndOwner = hwnd;
1958 cc.hInstance = (HWND)hinst;
1959 cc.lpCustColors = custom;
1960 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1962 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1963 if (ChooseColor(&cc)) {
1965 (unsigned char) (cc.rgbResult & 0xFF);
1967 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1969 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1970 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1972 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1974 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1980 case IDC_KOI8WIN1251:
1981 case IDC_88592WIN1250:
1982 case IDC_88592CP852:
1983 cfg.xlat_enablekoiwin =
1984 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1985 cfg.xlat_88592w1250 =
1986 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1987 cfg.xlat_88592cp852 =
1988 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1990 case IDC_CAPSLOCKCYR:
1991 if (HIWORD(wParam) == BN_CLICKED ||
1992 HIWORD(wParam) == BN_DOUBLECLICKED) {
1993 cfg.xlat_capslockcyr =
1994 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1997 case IDC_VTXWINDOWS:
2002 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
2003 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
2004 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
2007 case IDC_X11_FORWARD:
2008 if (HIWORD(wParam) == BN_CLICKED ||
2009 HIWORD(wParam) == BN_DOUBLECLICKED)
2010 cfg.x11_forward = IsDlgButtonChecked (hwnd, IDC_X11_FORWARD);
2012 case IDC_X11_DISPLAY:
2013 if (HIWORD(wParam) == EN_CHANGE)
2014 GetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2015 sizeof(cfg.x11_display)-1);
2020 EndDialog (hwnd, 0);
2023 /* Grrr Explorer will maximize Dialogs! */
2025 if (wParam == SIZE_MAXIMIZED)
2032 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
2033 WPARAM wParam, LPARAM lParam) {
2034 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2036 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2037 EnableWindow(hwnd, 0);
2038 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2039 GetParent(hwnd), AboutProc);
2040 EnableWindow(hwnd, 1);
2041 SetActiveWindow(hwnd);
2043 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
2046 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
2047 WPARAM wParam, LPARAM lParam) {
2048 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
2051 void defuse_showwindow(void) {
2053 * Work around the fact that the app's first call to ShowWindow
2054 * will ignore the default in favour of the shell-provided
2059 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2061 ShowWindow(hwnd, SW_HIDE);
2062 DestroyWindow(hwnd);
2066 int do_config (void) {
2070 savedsession[0] = '\0';
2071 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2072 get_sesslist(FALSE);
2077 int do_reconfig (HWND hwnd) {
2081 backup_cfg = cfg; /* structure copy */
2082 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2084 cfg = backup_cfg; /* structure copy */
2089 void logevent (char *string) {
2093 if (nevents >= negsize) {
2095 events = srealloc (events, negsize * sizeof(*events));
2099 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t", localtime(&t));
2101 events[nevents] = smalloc(strlen(timebuf)+strlen(string)+1);
2102 strcpy(events[nevents], timebuf);
2103 strcat(events[nevents], string);
2106 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
2107 0, (LPARAM)events[nevents]);
2108 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2109 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
2114 void showeventlog (HWND hwnd) {
2116 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2118 ShowWindow (logbox, SW_SHOWNORMAL);
2120 SetActiveWindow(logbox);
2123 void showabout (HWND hwnd) {
2124 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),hwnd, AboutProc);
2127 void verify_ssh_host_key(char *host, int port, char *keytype,
2128 char *keystr, char *fingerprint) {
2131 static const char absentmsg[] =
2132 "The server's host key is not cached in the registry. You\n"
2133 "have no guarantee that the server is the computer you\n"
2135 "The server's key fingerprint is:\n"
2137 "If you trust this host, hit Yes to add the key to\n"
2138 "PuTTY's cache and carry on connecting.\n"
2139 "If you do not trust this host, hit No to abandon the\n"
2142 static const char wrongmsg[] =
2143 "WARNING - POTENTIAL SECURITY BREACH!\n"
2145 "The server's host key does not match the one PuTTY has\n"
2146 "cached in the registry. This means that either the\n"
2147 "server administrator has changed the host key, or you\n"
2148 "have actually connected to another computer pretending\n"
2149 "to be the server.\n"
2150 "The new key fingerprint is:\n"
2152 "If you were expecting this change and trust the new key,\n"
2153 "hit Yes to update PuTTY's cache and continue connecting.\n"
2154 "If you want to carry on connecting but without updating\n"
2155 "the cache, hit No.\n"
2156 "If you want to abandon the connection completely, hit\n"
2157 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2160 static const char mbtitle[] = "PuTTY Security Alert";
2163 char message[160+ /* sensible fingerprint max size */
2164 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2165 sizeof(absentmsg) : sizeof(wrongmsg))];
2168 * Verify the key against the registry.
2170 ret = verify_host_key(host, port, keytype, keystr);
2172 if (ret == 0) /* success - key matched OK */
2174 if (ret == 2) { /* key was different */
2176 sprintf(message, wrongmsg, fingerprint);
2177 mbret = MessageBox(NULL, message, mbtitle,
2178 MB_ICONWARNING | MB_YESNOCANCEL);
2180 store_host_key(host, port, keytype, keystr);
2181 if (mbret == IDCANCEL)
2184 if (ret == 1) { /* key was absent */
2186 sprintf(message, absentmsg, fingerprint);
2187 mbret = MessageBox(NULL, message, mbtitle,
2188 MB_ICONWARNING | MB_YESNO);
2191 store_host_key(host, port, keytype, keystr);
2196 * Ask whether to wipe a session log file before writing to it.
2197 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2199 int askappend(char *filename) {
2200 static const char mbtitle[] = "PuTTY Log to File";
2201 static const char msgtemplate[] =
2202 "The session log file \"%.*s\" already exists.\n"
2203 "You can overwrite it with a new session log,\n"
2204 "append your session log to the end of it,\n"
2205 "or disable session logging for this session.\n"
2206 "Hit Yes to wipe the file, No to append to it,\n"
2207 "or Cancel to disable logging.";
2208 char message[sizeof(msgtemplate) + FILENAME_MAX];
2210 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2212 mbret = MessageBox(NULL, message, mbtitle,
2213 MB_ICONQUESTION | MB_YESNOCANCEL);
2216 else if (mbret == IDNO)