15 static char **events
= NULL
;
16 static int nevents
= 0, negsize
= 0;
19 static int sesslist_has_focus
;
21 static struct prefslist cipherlist
;
23 void force_normal(HWND hwnd
)
25 static int recurse
= 0;
33 wp
.length
= sizeof(wp
);
34 if (GetWindowPlacement(hwnd
, &wp
) && wp
.showCmd
== SW_SHOWMAXIMIZED
) {
35 wp
.showCmd
= SW_SHOWNORMAL
;
36 SetWindowPlacement(hwnd
, &wp
);
41 static void MyGetDlgItemInt(HWND hwnd
, int id
, int *result
)
45 n
= GetDlgItemInt(hwnd
, id
, &ok
, FALSE
);
50 static void MyGetDlgItemFlt(HWND hwnd
, int id
, int *result
, int scale
)
54 ok
= GetDlgItemText(hwnd
, id
, text
, sizeof(text
) - 1);
56 *result
= (int) (scale
* atof(text
));
59 static void MySetDlgItemFlt(HWND hwnd
, int id
, double value
)
62 sprintf(text
, "%g", value
);
63 SetDlgItemText(hwnd
, id
, text
);
66 static int CALLBACK
LogProc(HWND hwnd
, UINT msg
,
67 WPARAM wParam
, LPARAM lParam
)
74 static int tabs
[4] = { 78, 108 };
75 SendDlgItemMessage(hwnd
, IDN_LIST
, LB_SETTABSTOPS
, 2,
78 for (i
= 0; i
< nevents
; i
++)
79 SendDlgItemMessage(hwnd
, IDN_LIST
, LB_ADDSTRING
,
80 0, (LPARAM
) events
[i
]);
83 switch (LOWORD(wParam
)) {
87 SetActiveWindow(GetParent(hwnd
));
91 if (HIWORD(wParam
) == BN_CLICKED
||
92 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
95 selcount
= SendDlgItemMessage(hwnd
, IDN_LIST
,
96 LB_GETSELCOUNT
, 0, 0);
97 if (selcount
== 0) { /* don't even try to copy zero items */
102 selitems
= smalloc(selcount
* sizeof(int));
104 int count
= SendDlgItemMessage(hwnd
, IDN_LIST
,
111 static unsigned char sel_nl
[] = SEL_NL
;
113 if (count
== 0) { /* can't copy zero stuff */
119 for (i
= 0; i
< count
; i
++)
121 strlen(events
[selitems
[i
]]) + sizeof(sel_nl
);
123 clipdata
= smalloc(size
);
126 for (i
= 0; i
< count
; i
++) {
127 char *q
= events
[selitems
[i
]];
128 int qlen
= strlen(q
);
131 memcpy(p
, sel_nl
, sizeof(sel_nl
));
134 write_aclip(clipdata
, size
, TRUE
);
139 for (i
= 0; i
< nevents
; i
++)
140 SendDlgItemMessage(hwnd
, IDN_LIST
, LB_SETSEL
,
149 SetActiveWindow(GetParent(hwnd
));
156 static int CALLBACK
LicenceProc(HWND hwnd
, UINT msg
,
157 WPARAM wParam
, LPARAM lParam
)
163 switch (LOWORD(wParam
)) {
176 static int CALLBACK
AboutProc(HWND hwnd
, UINT msg
,
177 WPARAM wParam
, LPARAM lParam
)
181 SetDlgItemText(hwnd
, IDA_VERSION
, ver
);
184 switch (LOWORD(wParam
)) {
187 EndDialog(hwnd
, TRUE
);
190 EnableWindow(hwnd
, 0);
191 DialogBox(hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
193 EnableWindow(hwnd
, 1);
194 SetActiveWindow(hwnd
);
198 /* Load web browser */
199 ShellExecute(hwnd
, "open",
200 "http://www.chiark.greenend.org.uk/~sgtatham/putty/",
201 0, 0, SW_SHOWDEFAULT
);
206 EndDialog(hwnd
, TRUE
);
213 * Null dialog procedure.
215 static int CALLBACK
NullDlgProc(HWND hwnd
, UINT msg
,
216 WPARAM wParam
, LPARAM lParam
)
221 static char savedsession
[2048];
224 IDC_ABOUT
, IDCX_TVSTATIC
, IDCX_TREEVIEW
, controlstartvalue
,
370 appearancepanelstart
,
371 IDC_TITLE_APPEARANCE
,
391 connectionpanelstart
,
392 IDC_TITLE_CONNECTION
,
500 translationpanelstart
,
501 IDC_TITLE_TRANSLATION
,
502 IDC_BOX_TRANSLATION1
,
503 IDC_BOX_TRANSLATION2
,
539 static const char *const colours
[] = {
540 "Default Foreground", "Default Bold Foreground",
541 "Default Background", "Default Bold Background",
542 "Cursor Text", "Cursor Colour",
543 "ANSI Black", "ANSI Black Bold",
544 "ANSI Red", "ANSI Red Bold",
545 "ANSI Green", "ANSI Green Bold",
546 "ANSI Yellow", "ANSI Yellow Bold",
547 "ANSI Blue", "ANSI Blue Bold",
548 "ANSI Magenta", "ANSI Magenta Bold",
549 "ANSI Cyan", "ANSI Cyan Bold",
550 "ANSI White", "ANSI White Bold"
552 static const int permcolour
[] = {
553 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
554 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
555 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
558 static void fmtfont(char *buf
)
560 sprintf(buf
, "Font: %s, ", cfg
.font
);
562 strcat(buf
, "bold, ");
563 if (cfg
.fontheight
== 0)
564 strcat(buf
, "default height");
566 sprintf(buf
+ strlen(buf
), "%d-point",
567 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
));
570 /* 2nd arg: NZ => don't redraw session list (use when loading
572 static void init_dlg_ctrls(HWND hwnd
, int keepsess
)
575 char fontstatic
[256];
577 SetDlgItemText(hwnd
, IDC_HOST
, cfg
.host
);
578 SetDlgItemText(hwnd
, IDC_SESSEDIT
, savedsession
);
581 n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_GETCOUNT
, 0, 0);
582 for (i
= n
; i
-- > 0;)
583 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_DELETESTRING
, i
, 0);
584 for (i
= 0; i
< nsessions
; i
++)
585 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
586 0, (LPARAM
) (sessions
[i
]));
588 SetDlgItemInt(hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
589 CheckRadioButton(hwnd
, IDC_PROTRAW
, IDC_PROTSSH
,
590 cfg
.protocol
== PROT_SSH ? IDC_PROTSSH
:
591 cfg
.protocol
== PROT_TELNET ? IDC_PROTTELNET
:
593 PROT_RLOGIN ? IDC_PROTRLOGIN
: IDC_PROTRAW
);
594 SetDlgItemInt(hwnd
, IDC_PINGEDIT
, cfg
.ping_interval
, FALSE
);
596 CheckRadioButton(hwnd
, IDC_DEL008
, IDC_DEL127
,
597 cfg
.bksp_is_delete ? IDC_DEL127
: IDC_DEL008
);
598 CheckRadioButton(hwnd
, IDC_HOMETILDE
, IDC_HOMERXVT
,
599 cfg
.rxvt_homeend ? IDC_HOMERXVT
: IDC_HOMETILDE
);
600 CheckRadioButton(hwnd
, IDC_FUNCTILDE
, IDC_FUNCSCO
,
601 cfg
.funky_type
== 0 ? IDC_FUNCTILDE
:
602 cfg
.funky_type
== 1 ? IDC_FUNCLINUX
:
603 cfg
.funky_type
== 2 ? IDC_FUNCXTERM
:
604 cfg
.funky_type
== 3 ? IDC_FUNCVT400
:
605 cfg
.funky_type
== 4 ? IDC_FUNCVT100P
:
606 cfg
.funky_type
== 5 ? IDC_FUNCSCO
: IDC_FUNCTILDE
);
607 CheckDlgButton(hwnd
, IDC_NOAPPLICC
, cfg
.no_applic_c
);
608 CheckDlgButton(hwnd
, IDC_NOAPPLICK
, cfg
.no_applic_k
);
609 CheckRadioButton(hwnd
, IDC_CURNORMAL
, IDC_CURAPPLIC
,
610 cfg
.app_cursor ? IDC_CURAPPLIC
: IDC_CURNORMAL
);
611 CheckRadioButton(hwnd
, IDC_KPNORMAL
, IDC_KPNH
,
612 cfg
.nethack_keypad ? IDC_KPNH
:
613 cfg
.app_keypad ? IDC_KPAPPLIC
: IDC_KPNORMAL
);
614 CheckDlgButton(hwnd
, IDC_ALTF4
, cfg
.alt_f4
);
615 CheckDlgButton(hwnd
, IDC_ALTSPACE
, cfg
.alt_space
);
616 CheckDlgButton(hwnd
, IDC_ALTONLY
, cfg
.alt_only
);
617 CheckDlgButton(hwnd
, IDC_COMPOSEKEY
, cfg
.compose_key
);
618 CheckDlgButton(hwnd
, IDC_CTRLALTKEYS
, cfg
.ctrlaltkeys
);
619 CheckDlgButton(hwnd
, IDC_TELNETKEY
, cfg
.telnet_keyboard
);
620 CheckRadioButton(hwnd
, IDC_ECHOBACKEND
, IDC_ECHONO
,
621 cfg
.localecho
== LD_BACKEND ? IDC_ECHOBACKEND
:
622 cfg
.localecho
== LD_YES ? IDC_ECHOYES
: IDC_ECHONO
);
623 CheckRadioButton(hwnd
, IDC_EDITBACKEND
, IDC_EDITNO
,
624 cfg
.localedit
== LD_BACKEND ? IDC_EDITBACKEND
:
625 cfg
.localedit
== LD_YES ? IDC_EDITYES
: IDC_EDITNO
);
626 SetDlgItemText(hwnd
, IDC_ANSWEREDIT
, cfg
.answerback
);
627 CheckDlgButton(hwnd
, IDC_ALWAYSONTOP
, cfg
.alwaysontop
);
628 CheckDlgButton(hwnd
, IDC_SCROLLKEY
, cfg
.scroll_on_key
);
629 CheckDlgButton(hwnd
, IDC_SCROLLDISP
, cfg
.scroll_on_disp
);
631 CheckDlgButton(hwnd
, IDC_WRAPMODE
, cfg
.wrap_mode
);
632 CheckDlgButton(hwnd
, IDC_DECOM
, cfg
.dec_om
);
633 CheckDlgButton(hwnd
, IDC_LFHASCR
, cfg
.lfhascr
);
634 SetDlgItemInt(hwnd
, IDC_ROWSEDIT
, cfg
.height
, FALSE
);
635 SetDlgItemInt(hwnd
, IDC_COLSEDIT
, cfg
.width
, FALSE
);
636 SetDlgItemInt(hwnd
, IDC_SAVEEDIT
, cfg
.savelines
, FALSE
);
638 SetDlgItemText(hwnd
, IDC_FONTSTATIC
, fontstatic
);
639 CheckRadioButton(hwnd
, IDC_BELL_DISABLED
, IDC_BELL_VISUAL
,
640 cfg
.beep
== BELL_DISABLED ? IDC_BELL_DISABLED
:
641 cfg
.beep
== BELL_DEFAULT ? IDC_BELL_DEFAULT
:
642 cfg
.beep
== BELL_WAVEFILE ? IDC_BELL_WAVEFILE
:
644 BELL_VISUAL ? IDC_BELL_VISUAL
: IDC_BELL_DEFAULT
);
645 CheckRadioButton(hwnd
, IDC_B_IND_DISABLED
, IDC_B_IND_STEADY
,
647 B_IND_DISABLED ? IDC_B_IND_DISABLED
: cfg
.beep_ind
==
648 B_IND_FLASH ? IDC_B_IND_FLASH
: cfg
.beep_ind
==
649 B_IND_STEADY ? IDC_B_IND_STEADY
: IDC_B_IND_DISABLED
);
650 SetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
, cfg
.bell_wavefile
);
651 CheckDlgButton(hwnd
, IDC_BELLOVL
, cfg
.bellovl
);
652 SetDlgItemInt(hwnd
, IDC_BELLOVLN
, cfg
.bellovl_n
, FALSE
);
653 MySetDlgItemFlt(hwnd
, IDC_BELLOVLT
, cfg
.bellovl_t
/ 1000.0);
654 MySetDlgItemFlt(hwnd
, IDC_BELLOVLS
, cfg
.bellovl_s
/ 1000.0);
656 CheckDlgButton(hwnd
, IDC_BCE
, cfg
.bce
);
657 CheckDlgButton(hwnd
, IDC_BLINKTEXT
, cfg
.blinktext
);
659 SetDlgItemText(hwnd
, IDC_WINEDIT
, cfg
.wintitle
);
660 CheckDlgButton(hwnd
, IDC_WINNAME
, cfg
.win_name_always
);
661 CheckDlgButton(hwnd
, IDC_HIDEMOUSE
, cfg
.hide_mouseptr
);
662 CheckDlgButton(hwnd
, IDC_SUNKENEDGE
, cfg
.sunken_edge
);
663 CheckRadioButton(hwnd
, IDC_CURBLOCK
, IDC_CURVERT
,
664 cfg
.cursor_type
== 0 ? IDC_CURBLOCK
:
665 cfg
.cursor_type
== 1 ? IDC_CURUNDER
: IDC_CURVERT
);
666 CheckDlgButton(hwnd
, IDC_BLINKCUR
, cfg
.blink_cur
);
667 CheckDlgButton(hwnd
, IDC_SCROLLBAR
, cfg
.scrollbar
);
668 CheckDlgButton(hwnd
, IDC_LOCKSIZE
, cfg
.locksize
);
669 CheckRadioButton(hwnd
, IDC_COEALWAYS
, IDC_COENORMAL
,
670 cfg
.close_on_exit
== COE_NORMAL ? IDC_COENORMAL
:
672 COE_NEVER ? IDC_COENEVER
: IDC_COEALWAYS
);
673 CheckDlgButton(hwnd
, IDC_CLOSEWARN
, cfg
.warn_on_close
);
675 SetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
);
676 SetDlgItemText(hwnd
, IDC_TSEDIT
, cfg
.termspeed
);
677 SetDlgItemText(hwnd
, IDC_R_TSEDIT
, cfg
.termspeed
);
678 SetDlgItemText(hwnd
, IDC_RLLUSEREDIT
, cfg
.localusername
);
679 SetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
);
680 SetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
);
681 CheckRadioButton(hwnd
, IDC_LSTATOFF
, IDC_LSTATRAW
,
682 cfg
.logtype
== 0 ? IDC_LSTATOFF
:
683 cfg
.logtype
== 1 ? IDC_LSTATASCII
: IDC_LSTATRAW
);
684 CheckRadioButton(hwnd
, IDC_LSTATXOVR
, IDC_LSTATXASK
,
685 cfg
.logxfovr
== LGXF_OVR ? IDC_LSTATXOVR
:
686 cfg
.logxfovr
== LGXF_ASK ? IDC_LSTATXASK
:
689 char *p
= cfg
.environmt
;
690 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_RESETCONTENT
, 0, 0);
692 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_ADDSTRING
, 0,
698 SendDlgItemMessage(hwnd
, IDC_PFWDLIST
, LB_ADDSTRING
, 0,
703 CheckRadioButton(hwnd
, IDC_EMBSD
, IDC_EMRFC
,
704 cfg
.rfc_environ ? IDC_EMRFC
: IDC_EMBSD
);
705 CheckRadioButton(hwnd
, IDC_TPASSIVE
, IDC_TACTIVE
,
706 cfg
.passive_telnet ? IDC_TPASSIVE
: IDC_TACTIVE
);
708 SetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
);
709 SetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
);
710 CheckDlgButton(hwnd
, IDC_NOPTY
, cfg
.nopty
);
711 CheckDlgButton(hwnd
, IDC_COMPRESS
, cfg
.compression
);
712 CheckDlgButton(hwnd
, IDC_BUGGYMAC
, cfg
.buggymac
);
713 CheckDlgButton(hwnd
, IDC_AGENTFWD
, cfg
.agentfwd
);
714 CheckRadioButton(hwnd
, IDC_SSHPROT1
, IDC_SSHPROT2
,
715 cfg
.sshprot
== 1 ? IDC_SSHPROT1
: IDC_SSHPROT2
);
716 CheckDlgButton(hwnd
, IDC_AUTHTIS
, cfg
.try_tis_auth
);
717 SetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
718 SetDlgItemText(hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
);
722 static const struct { char *s
; int c
; } ciphers
[] = {
723 { "3DES", CIPHER_3DES
},
724 { "Blowfish", CIPHER_BLOWFISH
},
725 { "DES (SSH 1 only)", CIPHER_DES
},
726 { "AES (SSH 2 only)", CIPHER_AES
},
727 { "-- warn below here --", CIPHER_WARN
}
730 /* Set up the "selected ciphers" box. */
731 /* (cipherlist assumed to contain all ciphers) */
732 SendDlgItemMessage(hwnd
, IDC_CIPHERLIST
, LB_RESETCONTENT
, 0, 0);
733 for (i
= 0; i
< CIPHER_MAX
; i
++) {
734 int c
= cfg
.ssh_cipherlist
[i
];
737 for (j
= 0; j
< (sizeof ciphers
) / (sizeof ciphers
[0]); j
++) {
738 if (ciphers
[j
].c
== c
) {
743 pos
= SendDlgItemMessage(hwnd
, IDC_CIPHERLIST
, LB_ADDSTRING
,
745 SendDlgItemMessage(hwnd
, IDC_CIPHERLIST
, LB_SETITEMDATA
,
752 CheckRadioButton(hwnd
, IDC_MBWINDOWS
, IDC_MBXTERM
,
753 cfg
.mouse_is_xterm ? IDC_MBXTERM
: IDC_MBWINDOWS
);
754 CheckDlgButton(hwnd
, IDC_MOUSEOVERRIDE
, cfg
.mouse_override
);
755 CheckDlgButton(hwnd
, IDC_RAWCNP
, cfg
.rawcnp
);
757 static int tabs
[4] = { 25, 61, 96, 128 };
758 SendDlgItemMessage(hwnd
, IDC_CCLIST
, LB_SETTABSTOPS
, 4,
761 for (i
= 0; i
< 128; i
++) {
763 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
764 (i
>= 0x21 && i
!= 0x7F) ? i
: ' ', cfg
.wordness
[i
]);
765 SendDlgItemMessage(hwnd
, IDC_CCLIST
, LB_ADDSTRING
, 0,
769 CheckDlgButton(hwnd
, IDC_BOLDCOLOUR
, cfg
.bold_colour
);
770 CheckDlgButton(hwnd
, IDC_PALETTE
, cfg
.try_palette
);
773 n
= SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_GETCOUNT
, 0, 0);
774 for (i
= n
; i
-- > 0;)
775 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
776 LB_DELETESTRING
, i
, 0);
777 for (i
= 0; i
< 22; i
++)
778 if (cfg
.bold_colour
|| permcolour
[i
])
779 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_ADDSTRING
, 0,
780 (LPARAM
) colours
[i
]);
782 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_SETCURSEL
, 0, 0);
783 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[0][0], FALSE
);
784 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[0][1], FALSE
);
785 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[0][2], FALSE
);
790 strcpy(cfg
.line_codepage
, cp_name(decode_codepage(cfg
.line_codepage
)));
791 SendDlgItemMessage(hwnd
, IDC_CODEPAGE
, CB_RESETCONTENT
, 0, 0);
792 for (i
= 0; (cp
= cp_enumerate(i
)) != NULL
; i
++) {
793 SendDlgItemMessage(hwnd
, IDC_CODEPAGE
, CB_ADDSTRING
,
796 SetDlgItemText(hwnd
, IDC_CODEPAGE
, cfg
.line_codepage
);
799 CheckRadioButton(hwnd
, IDC_VTXWINDOWS
, IDC_VTUNICODE
,
800 cfg
.vtmode
== VT_XWINDOWS ? IDC_VTXWINDOWS
:
801 cfg
.vtmode
== VT_OEMANSI ? IDC_VTOEMANSI
:
802 cfg
.vtmode
== VT_OEMONLY ? IDC_VTOEMONLY
:
803 cfg
.vtmode
== VT_UNICODE ? IDC_VTUNICODE
:
806 CheckDlgButton(hwnd
, IDC_X11_FORWARD
, cfg
.x11_forward
);
807 SetDlgItemText(hwnd
, IDC_X11_DISPLAY
, cfg
.x11_display
);
809 CheckDlgButton(hwnd
, IDC_LPORT_ALL
, cfg
.lport_acceptall
);
810 CheckRadioButton(hwnd
, IDC_PFWDLOCAL
, IDC_PFWDREMOTE
, IDC_PFWDLOCAL
);
813 struct treeview_faff
{
818 static HTREEITEM
treeview_insert(struct treeview_faff
*faff
,
819 int level
, char *text
)
824 ins
.hParent
= (level
> 0 ? faff
->lastat
[level
- 1] : TVI_ROOT
);
825 ins
.hInsertAfter
= faff
->lastat
[level
];
826 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
827 #define INSITEM DUMMYUNIONNAME.item
831 ins
.INSITEM
.mask
= TVIF_TEXT
;
832 ins
.INSITEM
.pszText
= text
;
833 newitem
= TreeView_InsertItem(faff
->treeview
, &ins
);
835 TreeView_Expand(faff
->treeview
, faff
->lastat
[level
- 1],
837 faff
->lastat
[level
] = newitem
;
838 for (i
= level
+ 1; i
< 4; i
++)
839 faff
->lastat
[i
] = NULL
;
844 * Create the panelfuls of controls in the configuration box.
846 static void create_controls(HWND hwnd
, int dlgtype
, int panel
)
848 if (panel
== sessionpanelstart
) {
849 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
851 ctlposinit(&cp
, hwnd
, 80, 3, 13);
852 bartitle(&cp
, "Basic options for your PuTTY session",
855 beginbox(&cp
, "Specify your connection by host name or IP address",
858 "Host &Name (or IP address)",
859 IDC_HOSTSTATIC
, IDC_HOST
, 75,
860 "&Port", IDC_PORTSTATIC
, IDC_PORT
, 25, NULL
);
861 if (backends
[3].backend
== NULL
) {
862 /* this is PuTTYtel, so only three protocols available */
863 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 3,
865 "&Telnet", IDC_PROTTELNET
,
866 "Rlog&in", IDC_PROTRLOGIN
, NULL
);
868 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 4,
870 "&Telnet", IDC_PROTTELNET
,
871 "Rlog&in", IDC_PROTRLOGIN
,
880 beginbox(&cp
, "Load, save or delete a stored session",
882 sesssaver(&cp
, "Sav&ed Sessions",
883 IDC_SESSSTATIC
, IDC_SESSEDIT
, IDC_SESSLIST
,
884 "&Load", IDC_SESSLOAD
,
885 "&Save", IDC_SESSSAVE
, "&Delete", IDC_SESSDEL
, NULL
);
888 beginbox(&cp
, NULL
, IDC_BOX_SESSION3
);
889 radioline(&cp
, "Close &window on exit:", IDC_CLOSEEXIT
, 4,
890 "Always", IDC_COEALWAYS
,
891 "Never", IDC_COENEVER
,
892 "Only on clean exit", IDC_COENORMAL
, NULL
);
896 if (panel
== loggingpanelstart
) {
897 /* The Logging panel. Accelerators used: [acgo] tplfwe */
899 ctlposinit(&cp
, hwnd
, 80, 3, 13);
900 bartitle(&cp
, "Options controlling session logging",
902 beginbox(&cp
, NULL
, IDC_BOX_LOGGING1
);
904 "Session logging:", IDC_LSTATSTATIC
,
905 "Logging &turned off completely", IDC_LSTATOFF
,
906 "Log &printable output only", IDC_LSTATASCII
,
907 "&Log all session output", IDC_LSTATRAW
, NULL
);
908 editbutton(&cp
, "Log &file name:",
909 IDC_LGFSTATIC
, IDC_LGFEDIT
, "Bro&wse...",
911 statictext(&cp
, "(Log file name can contain &&Y, &&M, &&D for date,"
912 " &&T for time, and &&H for host name)", 2, IDC_LGFEXPLAIN
);
914 "What to do if the log file already &exists:",
915 IDC_LSTATXIST
, "Always overwrite it", IDC_LSTATXOVR
,
916 "Always append to the end of it", IDC_LSTATXAPN
,
917 "Ask the user every time", IDC_LSTATXASK
, NULL
);
921 if (panel
== terminalpanelstart
) {
922 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
924 ctlposinit(&cp
, hwnd
, 80, 3, 13);
925 bartitle(&cp
, "Options controlling the terminal emulation",
927 beginbox(&cp
, "Set various terminal options", IDC_BOX_TERMINAL1
);
928 checkbox(&cp
, "Auto &wrap mode initially on", IDC_WRAPMODE
);
929 checkbox(&cp
, "&DEC Origin Mode initially on", IDC_DECOM
);
930 checkbox(&cp
, "Implicit CR in every &LF", IDC_LFHASCR
);
931 checkbox(&cp
, "Use background colour to &erase screen", IDC_BCE
);
932 checkbox(&cp
, "Enable bli&nking text", IDC_BLINKTEXT
);
934 "An&swerback to ^E:", IDC_ANSWERBACK
,
935 IDC_ANSWEREDIT
, 100, NULL
);
938 beginbox(&cp
, "Line discipline options", IDC_BOX_TERMINAL2
);
939 radioline(&cp
, "Local ec&ho:", IDC_ECHOSTATIC
, 3,
940 "Auto", IDC_ECHOBACKEND
,
941 "Force on", IDC_ECHOYES
, "Force off", IDC_ECHONO
, NULL
);
942 radioline(&cp
, "Local line edi&ting:", IDC_EDITSTATIC
, 3,
943 "Auto", IDC_EDITBACKEND
,
944 "Force on", IDC_EDITYES
, "Force off", IDC_EDITNO
, NULL
);
948 if (panel
== bellpanelstart
) {
949 /* The Bell panel. Accelerators used: [acgo] bdsm wit */
951 ctlposinit(&cp
, hwnd
, 80, 3, 13);
952 bartitle(&cp
, "Options controlling the terminal bell",
954 beginbox(&cp
, "Set the style of bell", IDC_BOX_BELL1
);
956 "Action to happen when a &bell occurs:", IDC_BELLSTATIC
,
957 "None (bell disabled)", IDC_BELL_DISABLED
,
958 "Play Windows Default Sound", IDC_BELL_DEFAULT
,
959 "Play a custom sound file", IDC_BELL_WAVEFILE
,
960 "Visual bell (flash window)", IDC_BELL_VISUAL
, NULL
);
961 editbutton(&cp
, "Custom sound file to play as a bell:",
962 IDC_BELL_WAVESTATIC
, IDC_BELL_WAVEEDIT
,
963 "Bro&wse...", IDC_BELL_WAVEBROWSE
);
964 radioline(&cp
, "Taskbar/caption &indication on bell:",
965 IDC_B_IND_STATIC
, 3, "Disabled", IDC_B_IND_DISABLED
,
966 "Flashing", IDC_B_IND_FLASH
, "Steady", IDC_B_IND_STEADY
,
969 beginbox(&cp
, "Control the bell overload behaviour",
971 checkbox(&cp
, "Bell is temporarily &disabled when over-used",
973 staticedit(&cp
, "Over-use means this &many bells...",
974 IDC_BELLOVLNSTATIC
, IDC_BELLOVLN
, 20);
975 staticedit(&cp
, "... in &this many seconds",
976 IDC_BELLOVLTSTATIC
, IDC_BELLOVLT
, 20);
978 "The bell is re-enabled after a few seconds of silence.",
979 1, IDC_BELLOVLEXPLAIN
);
980 staticedit(&cp
, "Seconds of &silence required", IDC_BELLOVLSSTATIC
,
985 if (panel
== keyboardpanelstart
) {
986 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
988 ctlposinit(&cp
, hwnd
, 80, 3, 13);
990 bartitle(&cp, "Options controlling the effects of keys",
993 beginbox(&cp
, "Change the sequences sent by:", IDC_BOX_KEYBOARD1
);
994 radioline(&cp
, "The &Backspace key", IDC_DELSTATIC
, 2,
995 "Control-H", IDC_DEL008
,
996 "Control-? (127)", IDC_DEL127
, NULL
);
997 radioline(&cp
, "The &Home and End keys", IDC_HOMESTATIC
, 2,
998 "Standard", IDC_HOMETILDE
, "rxvt", IDC_HOMERXVT
, NULL
);
999 radioline(&cp
, "The &Function keys and keypad", IDC_FUNCSTATIC
, 3,
1000 "ESC[n~", IDC_FUNCTILDE
,
1001 "Linux", IDC_FUNCLINUX
,
1002 "Xterm R6", IDC_FUNCXTERM
,
1003 "VT400", IDC_FUNCVT400
,
1004 "VT100+", IDC_FUNCVT100P
, "SCO", IDC_FUNCSCO
, NULL
);
1006 beginbox(&cp
, "Application keypad settings:", IDC_BOX_KEYBOARD2
);
1008 "Application c&ursor keys totally disabled",
1010 radioline(&cp
, "Initial state of cu&rsor keys:", IDC_CURSTATIC
, 2,
1011 "Normal", IDC_CURNORMAL
,
1012 "Application", IDC_CURAPPLIC
, NULL
);
1014 "Application ke&ypad keys totally disabled",
1016 radioline(&cp
, "Initial state of &numeric keypad:", IDC_KPSTATIC
,
1017 3, "Normal", IDC_KPNORMAL
, "Application", IDC_KPAPPLIC
,
1018 "NetHack", IDC_KPNH
, NULL
);
1020 beginbox(&cp
, "Enable extra keyboard features:",
1022 checkbox(&cp
, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY
);
1023 checkbox(&cp
, "Control-Alt is &different from AltGr",
1028 if (panel
== windowpanelstart
) {
1029 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
1031 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1032 bartitle(&cp
, "Options controlling PuTTY's window",
1034 beginbox(&cp
, "Set the size of the window", IDC_BOX_WINDOW1
);
1036 "&Rows", IDC_ROWSSTATIC
, IDC_ROWSEDIT
, 50,
1037 "Colu&mns", IDC_COLSSTATIC
, IDC_COLSEDIT
, 50, NULL
);
1038 checkbox(&cp
, "Lock window size against resi&zing", IDC_LOCKSIZE
);
1040 beginbox(&cp
, "Control the scrollback in the window",
1042 staticedit(&cp
, "Lines of &scrollback",
1043 IDC_SAVESTATIC
, IDC_SAVEEDIT
, 50);
1044 checkbox(&cp
, "&Display scrollbar", IDC_SCROLLBAR
);
1045 checkbox(&cp
, "Reset scrollback on &keypress", IDC_SCROLLKEY
);
1046 checkbox(&cp
, "Reset scrollback on dis&play activity",
1049 beginbox(&cp
, NULL
, IDC_BOX_WINDOW3
);
1050 checkbox(&cp
, "&Warn before closing window", IDC_CLOSEWARN
);
1051 checkbox(&cp
, "Window closes on ALT-F&4", IDC_ALTF4
);
1052 checkbox(&cp
, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE
);
1053 checkbox(&cp
, "System menu appears on A< alone", IDC_ALTONLY
);
1054 checkbox(&cp
, "Ensure window is always on &top", IDC_ALWAYSONTOP
);
1058 if (panel
== appearancepanelstart
) {
1059 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
1061 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1062 bartitle(&cp
, "Options controlling PuTTY's appearance",
1063 IDC_TITLE_APPEARANCE
);
1064 beginbox(&cp
, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1
);
1065 radioline(&cp
, "Cursor appearance:", IDC_CURSORSTATIC
, 3,
1066 "B&lock", IDC_CURBLOCK
,
1067 "&Underline", IDC_CURUNDER
,
1068 "&Vertical line", IDC_CURVERT
, NULL
);
1069 checkbox(&cp
, "Cursor &blinks", IDC_BLINKCUR
);
1071 beginbox(&cp
, "Set the font used in the terminal window",
1072 IDC_BOX_APPEARANCE2
);
1073 staticbtn(&cp
, "", IDC_FONTSTATIC
, "C&hange...", IDC_CHOOSEFONT
);
1075 beginbox(&cp
, "Adjust the use of the window title",
1076 IDC_BOX_APPEARANCE3
);
1078 "Window &title:", IDC_WINTITLE
, IDC_WINEDIT
, 100, NULL
);
1079 checkbox(&cp
, "Avoid ever using &icon title", IDC_WINNAME
);
1081 beginbox(&cp
, "Adjust the use of the mouse pointer",
1082 IDC_BOX_APPEARANCE4
);
1083 checkbox(&cp
, "Hide mouse &pointer when typing in window",
1086 beginbox(&cp
, "Adjust the window border", IDC_BOX_APPEARANCE5
);
1087 checkbox(&cp
, "&Sunken-edge border (slightly thicker)",
1092 if (panel
== translationpanelstart
) {
1093 /* The Translation panel. Accelerators used: [acgo] xbep t s */
1095 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1096 bartitle(&cp
, "Options controlling character set translation",
1097 IDC_TITLE_TRANSLATION
);
1098 beginbox(&cp
, "Character set translation on received data",
1099 IDC_BOX_TRANSLATION2
);
1100 combobox(&cp
, "Received data assumed to be in which character set:",
1101 IDC_CODEPAGESTATIC
, IDC_CODEPAGE
);
1103 beginbox(&cp
, "Adjust how PuTTY displays line drawing characters",
1104 IDC_BOX_TRANSLATION1
);
1106 "Handling of line drawing characters:", IDC_VTSTATIC
,
1107 "Font has &XWindows encoding", IDC_VTXWINDOWS
,
1108 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI
,
1109 "Use font in O&EM mode only", IDC_VTOEMONLY
,
1110 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1111 IDC_VTPOORMAN
, "&Unicode mode", IDC_VTUNICODE
, NULL
);
1115 if (panel
== selectionpanelstart
) {
1116 /* The Selection panel. Accelerators used: [acgo] d wxp hst */
1118 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1119 bartitle(&cp
, "Options controlling copy and paste",
1120 IDC_TITLE_SELECTION
);
1121 beginbox(&cp
, "Translation of pasted characters",
1122 IDC_BOX_SELECTION1
);
1124 "&Don't translate line drawing chars into +, - and |",
1127 beginbox(&cp
, "Control which mouse button does which thing",
1128 IDC_BOX_SELECTION2
);
1129 radiobig(&cp
, "Action of mouse buttons:", IDC_MBSTATIC
,
1130 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS
,
1131 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM
,
1134 "Shift overrides a&pplication's use of mouse",
1137 beginbox(&cp
, "Control the select-one-word-at-a-time mode",
1138 IDC_BOX_SELECTION3
);
1139 charclass(&cp
, "C&haracter classes:", IDC_CCSTATIC
, IDC_CCLIST
,
1140 "&Set", IDC_CCSET
, IDC_CCEDIT
,
1141 "&to class", IDC_CCSTATIC2
);
1145 if (panel
== colourspanelstart
) {
1146 /* The Colours panel. Accelerators used: [acgo] blum */
1148 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1149 bartitle(&cp
, "Options controlling use of colours",
1151 beginbox(&cp
, "General options for colour usage",
1153 checkbox(&cp
, "&Bolded text is a different colour",
1155 checkbox(&cp
, "Attempt to use &logical palettes", IDC_PALETTE
);
1157 beginbox(&cp
, "Adjust the precise colours PuTTY displays",
1159 colouredit(&cp
, "Select a colo&ur and then click to modify it:",
1160 IDC_COLOURSTATIC
, IDC_COLOURLIST
,
1161 "&Modify...", IDC_CHANGE
,
1162 "Red:", IDC_RSTATIC
, IDC_RVALUE
,
1163 "Green:", IDC_GSTATIC
, IDC_GVALUE
,
1164 "Blue:", IDC_BSTATIC
, IDC_BVALUE
, NULL
);
1168 if (panel
== connectionpanelstart
) {
1169 /* The Connection panel. Accelerators used: [acgo] tuk */
1171 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1172 bartitle(&cp
, "Options controlling the connection",
1173 IDC_TITLE_CONNECTION
);
1175 beginbox(&cp
, "Data to send to the server",
1176 IDC_BOX_CONNECTION1
);
1177 staticedit(&cp
, "Terminal-&type string", IDC_TTSTATIC
,
1179 staticedit(&cp
, "Auto-login &username", IDC_LOGSTATIC
,
1183 beginbox(&cp
, "Adjust telnet session.", IDC_BOX_CONNECTION1
);
1184 checkbox(&cp
, "Keyboard sends telnet Backspace and Interrupt",
1188 beginbox(&cp
, "Sending of null packets to keep session active",
1189 IDC_BOX_CONNECTION2
);
1190 staticedit(&cp
, "Seconds between &keepalives (0 to turn off)",
1191 IDC_PINGSTATIC
, IDC_PINGEDIT
, 20);
1195 if (panel
== telnetpanelstart
) {
1196 /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
1198 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1200 bartitle(&cp
, "Options controlling Telnet connections",
1202 beginbox(&cp
, "Data to send to the server", IDC_BOX_TELNET1
);
1203 staticedit(&cp
, "Terminal-&speed string", IDC_TSSTATIC
,
1205 envsetter(&cp
, "Environment variables:", IDC_ENVSTATIC
,
1206 "&Variable", IDC_VARSTATIC
, IDC_VAREDIT
, "Va&lue",
1207 IDC_VALSTATIC
, IDC_VALEDIT
, IDC_ENVLIST
, "A&dd",
1208 IDC_ENVADD
, "&Remove", IDC_ENVREMOVE
);
1210 beginbox(&cp
, "Telnet protocol adjustments", IDC_BOX_TELNET2
);
1211 radioline(&cp
, "Handling of OLD_ENVIRON ambiguity:",
1212 IDC_EMSTATIC
, 2, "&BSD (commonplace)", IDC_EMBSD
,
1213 "R&FC 1408 (unusual)", IDC_EMRFC
, NULL
);
1214 radioline(&cp
, "&Telnet negotiation mode:", IDC_ACTSTATIC
, 2,
1215 "Passive", IDC_TPASSIVE
, "Active",
1217 checkbox(&cp
, "&Keyboard sends telnet Backspace and Interrupt",
1223 if (panel
== rloginpanelstart
) {
1224 /* The Rlogin panel. Accelerators used: [acgo] sl */
1226 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1228 bartitle(&cp
, "Options controlling Rlogin connections",
1230 beginbox(&cp
, "Data to send to the server", IDC_BOX_RLOGIN1
);
1231 staticedit(&cp
, "Terminal-&speed string", IDC_R_TSSTATIC
,
1233 staticedit(&cp
, "&Local username:", IDC_RLLUSERSTATIC
,
1234 IDC_RLLUSEREDIT
, 50);
1239 if (panel
== sshpanelstart
) {
1240 /* The SSH panel. Accelerators used: [acgo] r pe12i sud */
1242 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1244 bartitle(&cp
, "Options controlling SSH connections",
1246 beginbox(&cp
, "Data to send to the server", IDC_BOX_SSH1
);
1248 "&Remote command:", IDC_CMDSTATIC
, IDC_CMDEDIT
, 100,
1251 beginbox(&cp
, "Protocol options", IDC_BOX_SSH2
);
1252 checkbox(&cp
, "Don't allocate a &pseudo-terminal", IDC_NOPTY
);
1253 checkbox(&cp
, "Enable compr&ession", IDC_COMPRESS
);
1254 radioline(&cp
, "Preferred SSH protocol version:",
1255 IDC_SSHPROTSTATIC
, 2,
1256 "&1", IDC_SSHPROT1
, "&2", IDC_SSHPROT2
, NULL
);
1257 checkbox(&cp
, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1260 beginbox(&cp
, "Encryption options", IDC_BOX_SSH3
);
1261 prefslist(&cipherlist
, &cp
, "Encryption cipher &selection policy:",
1262 IDC_CIPHERSTATIC2
, IDC_CIPHERLIST
, IDC_CIPHERUP
,
1268 if (panel
== sshauthpanelstart
) {
1269 /* The SSH authentication panel. Accelerators used: [acgo] m fkw */
1271 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1273 bartitle(&cp
, "Options controlling SSH authentication",
1275 beginbox(&cp
, "Authentication methods",
1277 checkbox(&cp
, "Atte&mpt TIS or CryptoCard authentication",
1280 beginbox(&cp
, "Authentication parameters",
1282 checkbox(&cp
, "Allow agent &forwarding", IDC_AGENTFWD
);
1283 editbutton(&cp
, "Private &key file for authentication:",
1284 IDC_PKSTATIC
, IDC_PKEDIT
, "Bro&wse...",
1290 if (panel
== tunnelspanelstart
) {
1291 /* The Tunnels panel. Accelerators used: [acgo] deilmrstx */
1293 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1295 bartitle(&cp
, "Options controlling SSH tunnelling",
1297 beginbox(&cp
, "X11 forwarding", IDC_BOX_TUNNELS1
);
1298 checkbox(&cp
, "&Enable X11 forwarding", IDC_X11_FORWARD
);
1299 multiedit(&cp
, "&X display location", IDC_X11_DISPSTATIC
,
1300 IDC_X11_DISPLAY
, 50, NULL
);
1302 beginbox(&cp
, "Port forwarding", IDC_BOX_TUNNELS2
);
1303 checkbox(&cp
, "Local ports accept connections from o&ther hosts", IDC_LPORT_ALL
);
1304 staticbtn(&cp
, "Forwarded ports:", IDC_PFWDSTATIC
,
1305 "&Remove", IDC_PFWDREMOVE
);
1306 fwdsetter(&cp
, IDC_PFWDLIST
,
1307 "Add new forwarded port:", IDC_PFWDSTATIC2
,
1308 "&Source port", IDC_SPORTSTATIC
, IDC_SPORTEDIT
,
1309 "Dest&ination", IDC_DPORTSTATIC
, IDC_DPORTEDIT
,
1310 "A&dd", IDC_PFWDADD
);
1311 bareradioline(&cp
, 2,
1312 "&Local", IDC_PFWDLOCAL
, "Re&mote", IDC_PFWDREMOTE
, NULL
);
1320 * Helper function to load the session selected in SESSLIST
1321 * if any, as this is done in more than one place in
1322 * GenericMainDlgProc(). 0 => failure.
1324 static int load_selected_session(HWND hwnd
)
1326 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1327 LB_GETCURSEL
, 0, 0);
1333 isdef
= !strcmp(sessions
[n
], "Default Settings");
1334 load_settings(sessions
[n
], !isdef
, &cfg
);
1335 init_dlg_ctrls(hwnd
, TRUE
);
1337 SetDlgItemText(hwnd
, IDC_SESSEDIT
, sessions
[n
]);
1339 SetDlgItemText(hwnd
, IDC_SESSEDIT
, "");
1340 /* Restore the selection, which will have been clobbered by
1341 * SESSEDIT handling. */
1342 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
, n
, 0);
1347 * This function is the configuration box.
1349 static int GenericMainDlgProc(HWND hwnd
, UINT msg
,
1350 WPARAM wParam
, LPARAM lParam
, int dlgtype
)
1353 struct treeview_faff tvfaff
;
1356 char filename
[sizeof(cfg
.keyfile
)];
1359 char fontstatic
[256];
1361 struct servent
*service
;
1363 static UINT draglistmsg
= WM_NULL
;
1368 SetWindowLong(hwnd
, GWL_USERDATA
, 0);
1369 SendMessage(hwnd
, WM_SETICON
, (WPARAM
) ICON_BIG
,
1370 (LPARAM
) LoadIcon(hinst
, MAKEINTRESOURCE(IDI_CFGICON
)));
1372 * Centre the window.
1374 { /* centre the window */
1377 hw
= GetDesktopWindow();
1378 if (GetWindowRect(hw
, &rs
) && GetWindowRect(hwnd
, &rd
))
1380 (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
) / 2,
1381 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
) / 2,
1382 rd
.right
- rd
.left
, rd
.bottom
- rd
.top
, TRUE
);
1386 * Create the tree view.
1394 r
.right
= r
.left
+ 75;
1396 r
.bottom
= r
.top
+ 10;
1397 MapDialogRect(hwnd
, &r
);
1398 tvstatic
= CreateWindowEx(0, "STATIC", "Cate&gory:",
1399 WS_CHILD
| WS_VISIBLE
,
1401 r
.right
- r
.left
, r
.bottom
- r
.top
,
1402 hwnd
, (HMENU
) IDCX_TVSTATIC
, hinst
,
1404 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
1405 SendMessage(tvstatic
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
1408 r
.right
= r
.left
+ 75;
1410 r
.bottom
= r
.top
+ 206;
1411 MapDialogRect(hwnd
, &r
);
1412 treeview
= CreateWindowEx(WS_EX_CLIENTEDGE
, WC_TREEVIEW
, "",
1413 WS_CHILD
| WS_VISIBLE
|
1414 WS_TABSTOP
| TVS_HASLINES
|
1415 TVS_DISABLEDRAGDROP
| TVS_HASBUTTONS
1417 TVS_SHOWSELALWAYS
, r
.left
, r
.top
,
1418 r
.right
- r
.left
, r
.bottom
- r
.top
,
1419 hwnd
, (HMENU
) IDCX_TREEVIEW
, hinst
,
1421 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
1422 SendMessage(treeview
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
1423 tvfaff
.treeview
= treeview
;
1424 memset(tvfaff
.lastat
, 0, sizeof(tvfaff
.lastat
));
1428 * Set up the tree view contents.
1430 hsession
= treeview_insert(&tvfaff
, 0, "Session");
1431 treeview_insert(&tvfaff
, 1, "Logging");
1432 treeview_insert(&tvfaff
, 0, "Terminal");
1433 treeview_insert(&tvfaff
, 1, "Keyboard");
1434 treeview_insert(&tvfaff
, 1, "Bell");
1435 treeview_insert(&tvfaff
, 0, "Window");
1436 treeview_insert(&tvfaff
, 1, "Appearance");
1437 treeview_insert(&tvfaff
, 1, "Translation");
1438 treeview_insert(&tvfaff
, 1, "Selection");
1439 treeview_insert(&tvfaff
, 1, "Colours");
1440 treeview_insert(&tvfaff
, 0, "Connection");
1442 treeview_insert(&tvfaff
, 1, "Telnet");
1443 treeview_insert(&tvfaff
, 1, "Rlogin");
1444 if (backends
[3].backend
!= NULL
) {
1445 treeview_insert(&tvfaff
, 1, "SSH");
1446 /* XXX long name is ugly */
1447 /* XXX make it closed by default? */
1448 treeview_insert(&tvfaff
, 2, "Auth");
1449 treeview_insert(&tvfaff
, 2, "Tunnels");
1454 * Put the treeview selection on to the Session panel. This
1455 * should also cause creation of the relevant controls.
1457 TreeView_SelectItem(treeview
, hsession
);
1460 * Set focus into the first available control.
1464 ctl
= GetDlgItem(hwnd
, IDC_HOST
);
1466 ctl
= GetDlgItem(hwnd
, IDC_CLOSEEXIT
);
1470 SetWindowLong(hwnd
, GWL_USERDATA
, 1);
1471 sesslist_has_focus
= 0;
1475 * Button release should trigger WM_OK if there was a
1476 * previous double click on the session list.
1480 SendMessage(hwnd
, WM_COMMAND
, IDOK
, 0);
1483 if (LOWORD(wParam
) == IDCX_TREEVIEW
&&
1484 ((LPNMHDR
) lParam
)->code
== TVN_SELCHANGED
) {
1486 TreeView_GetSelection(((LPNMHDR
) lParam
)->hwndFrom
);
1491 SendMessage (hwnd
, WM_SETREDRAW
, FALSE
, 0);
1494 item
.pszText
= buffer
;
1495 item
.cchTextMax
= sizeof(buffer
);
1496 item
.mask
= TVIF_TEXT
;
1497 TreeView_GetItem(((LPNMHDR
) lParam
)->hwndFrom
, &item
);
1498 for (j
= controlstartvalue
; j
< controlendvalue
; j
++) {
1499 HWND item
= GetDlgItem(hwnd
, j
);
1501 DestroyWindow(item
);
1503 if (!strcmp(buffer
, "Session"))
1504 create_controls(hwnd
, dlgtype
, sessionpanelstart
);
1505 if (!strcmp(buffer
, "Logging"))
1506 create_controls(hwnd
, dlgtype
, loggingpanelstart
);
1507 if (!strcmp(buffer
, "Keyboard"))
1508 create_controls(hwnd
, dlgtype
, keyboardpanelstart
);
1509 if (!strcmp(buffer
, "Terminal"))
1510 create_controls(hwnd
, dlgtype
, terminalpanelstart
);
1511 if (!strcmp(buffer
, "Bell"))
1512 create_controls(hwnd
, dlgtype
, bellpanelstart
);
1513 if (!strcmp(buffer
, "Window"))
1514 create_controls(hwnd
, dlgtype
, windowpanelstart
);
1515 if (!strcmp(buffer
, "Appearance"))
1516 create_controls(hwnd
, dlgtype
, appearancepanelstart
);
1517 if (!strcmp(buffer
, "Tunnels"))
1518 create_controls(hwnd
, dlgtype
, tunnelspanelstart
);
1519 if (!strcmp(buffer
, "Connection"))
1520 create_controls(hwnd
, dlgtype
, connectionpanelstart
);
1521 if (!strcmp(buffer
, "Telnet"))
1522 create_controls(hwnd
, dlgtype
, telnetpanelstart
);
1523 if (!strcmp(buffer
, "Rlogin"))
1524 create_controls(hwnd
, dlgtype
, rloginpanelstart
);
1525 if (!strcmp(buffer
, "SSH"))
1526 create_controls(hwnd
, dlgtype
, sshpanelstart
);
1527 if (!strcmp(buffer
, "Auth"))
1528 create_controls(hwnd
, dlgtype
, sshauthpanelstart
);
1529 if (!strcmp(buffer
, "Selection"))
1530 create_controls(hwnd
, dlgtype
, selectionpanelstart
);
1531 if (!strcmp(buffer
, "Colours"))
1532 create_controls(hwnd
, dlgtype
, colourspanelstart
);
1533 if (!strcmp(buffer
, "Translation"))
1534 create_controls(hwnd
, dlgtype
, translationpanelstart
);
1536 init_dlg_ctrls(hwnd
, FALSE
);
1538 SendMessage (hwnd
, WM_SETREDRAW
, TRUE
, 0);
1539 InvalidateRect (hwnd
, NULL
, TRUE
);
1541 SetFocus(((LPNMHDR
) lParam
)->hwndFrom
); /* ensure focus stays */
1547 * Only process WM_COMMAND once the dialog is fully formed.
1549 if (GetWindowLong(hwnd
, GWL_USERDATA
) == 1)
1550 switch (LOWORD(wParam
)) {
1552 /* Behaviour of the "Open" button is different if the
1553 * session list has focus, *unless* the user just
1554 * double-clicked... */
1555 if (sesslist_has_focus
&& !readytogo
) {
1556 if (!load_selected_session(hwnd
)) {
1561 /* If at this point we have a valid session, go! */
1570 case IDC_PROTTELNET
:
1571 case IDC_PROTRLOGIN
:
1574 if (HIWORD(wParam
) == BN_CLICKED
||
1575 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1576 int i
= IsDlgButtonChecked(hwnd
, IDC_PROTSSH
);
1577 int j
= IsDlgButtonChecked(hwnd
, IDC_PROTTELNET
);
1578 int k
= IsDlgButtonChecked(hwnd
, IDC_PROTRLOGIN
);
1580 i ? PROT_SSH
: j ? PROT_TELNET
: k ? PROT_RLOGIN
:
1582 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
!= 22)
1583 || (cfg
.protocol
== PROT_TELNET
&& cfg
.port
!= 23)
1584 || (cfg
.protocol
== PROT_RLOGIN
1585 && cfg
.port
!= 513)) {
1586 cfg
.port
= i ?
22 : j ?
23 : 513;
1587 SetDlgItemInt(hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
1592 if (HIWORD(wParam
) == EN_CHANGE
)
1593 GetDlgItemText(hwnd
, IDC_HOST
, cfg
.host
,
1594 sizeof(cfg
.host
) - 1);
1597 if (HIWORD(wParam
) == EN_CHANGE
) {
1598 GetDlgItemText(hwnd
, IDC_PORT
, portname
, 31);
1599 if (isdigit(portname
[0]))
1600 MyGetDlgItemInt(hwnd
, IDC_PORT
, &cfg
.port
);
1602 service
= getservbyname(portname
, NULL
);
1604 cfg
.port
= ntohs(service
->s_port
);
1611 if (HIWORD(wParam
) == EN_CHANGE
) {
1612 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1614 GetDlgItemText(hwnd
, IDC_SESSEDIT
,
1615 savedsession
, sizeof(savedsession
) - 1);
1616 savedsession
[sizeof(savedsession
) - 1] = '\0';
1620 if (HIWORD(wParam
) == BN_CLICKED
||
1621 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1626 GetDlgItemText(hwnd
, IDC_SESSEDIT
, str
,
1629 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1630 LB_GETCURSEL
, 0, 0);
1635 strcpy(str
, sessions
[n
]);
1637 save_settings(str
, !!strcmp(str
, "Default Settings"),
1639 get_sesslist(FALSE
);
1641 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, WM_SETREDRAW
,
1643 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1645 for (i
= 0; i
< nsessions
; i
++)
1646 SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1648 (LPARAM
) (sessions
[i
]));
1649 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1651 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, WM_SETREDRAW
,
1653 InvalidateRect(GetDlgItem(hwnd
, IDC_SESSLIST
), NULL
,
1659 if (LOWORD(wParam
) == IDC_SESSLIST
) {
1660 if (HIWORD(wParam
) == LBN_SETFOCUS
)
1661 sesslist_has_focus
= 1;
1662 else if (HIWORD(wParam
) == LBN_KILLFOCUS
)
1663 sesslist_has_focus
= 0;
1665 if (LOWORD(wParam
) == IDC_SESSLOAD
&&
1666 HIWORD(wParam
) != BN_CLICKED
&&
1667 HIWORD(wParam
) != BN_DOUBLECLICKED
) break;
1668 if (LOWORD(wParam
) == IDC_SESSLIST
&&
1669 HIWORD(wParam
) != LBN_DBLCLK
) break;
1670 /* Load the session selected in SESSLIST. */
1671 if (load_selected_session(hwnd
) &&
1672 LOWORD(wParam
) == IDC_SESSLIST
) {
1674 * A double-click on a saved session should
1675 * actually start the session, not just load it.
1676 * Unless it's Default Settings or some other
1677 * host-less set of saved settings.
1686 if (HIWORD(wParam
) == BN_CLICKED
||
1687 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1688 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1689 LB_GETCURSEL
, 0, 0);
1690 if (n
== LB_ERR
|| n
== 0) {
1694 del_settings(sessions
[n
]);
1695 get_sesslist(FALSE
);
1697 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, WM_SETREDRAW
,
1699 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1701 for (i
= 0; i
< nsessions
; i
++)
1702 SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1704 (LPARAM
) (sessions
[i
]));
1705 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1707 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, WM_SETREDRAW
,
1709 InvalidateRect(GetDlgItem(hwnd
, IDC_SESSLIST
), NULL
,
1713 if (HIWORD(wParam
) == EN_CHANGE
)
1714 MyGetDlgItemInt(hwnd
, IDC_PINGEDIT
,
1715 &cfg
.ping_interval
);
1719 if (HIWORD(wParam
) == BN_CLICKED
||
1720 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1721 cfg
.bksp_is_delete
=
1722 IsDlgButtonChecked(hwnd
, IDC_DEL127
);
1726 if (HIWORD(wParam
) == BN_CLICKED
||
1727 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1729 IsDlgButtonChecked(hwnd
, IDC_HOMERXVT
);
1735 case IDC_FUNCVT100P
:
1737 if (HIWORD(wParam
) == BN_CLICKED
||
1738 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1739 switch (LOWORD(wParam
)) {
1752 case IDC_FUNCVT100P
:
1762 if (HIWORD(wParam
) == BN_CLICKED
||
1763 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1765 IsDlgButtonChecked(hwnd
, IDC_KPAPPLIC
);
1766 cfg
.nethack_keypad
= FALSE
;
1770 if (HIWORD(wParam
) == BN_CLICKED
||
1771 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1772 cfg
.app_keypad
= FALSE
;
1773 cfg
.nethack_keypad
= TRUE
;
1778 if (HIWORD(wParam
) == BN_CLICKED
||
1779 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1781 IsDlgButtonChecked(hwnd
, IDC_CURAPPLIC
);
1784 if (HIWORD(wParam
) == BN_CLICKED
||
1785 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1787 IsDlgButtonChecked(hwnd
, IDC_NOAPPLICC
);
1790 if (HIWORD(wParam
) == BN_CLICKED
||
1791 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1793 IsDlgButtonChecked(hwnd
, IDC_NOAPPLICK
);
1796 if (HIWORD(wParam
) == BN_CLICKED
||
1797 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1798 cfg
.alt_f4
= IsDlgButtonChecked(hwnd
, IDC_ALTF4
);
1801 if (HIWORD(wParam
) == BN_CLICKED
||
1802 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1804 IsDlgButtonChecked(hwnd
, IDC_ALTSPACE
);
1807 if (HIWORD(wParam
) == BN_CLICKED
||
1808 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1810 IsDlgButtonChecked(hwnd
, IDC_ALTONLY
);
1812 case IDC_ECHOBACKEND
:
1815 if (HIWORD(wParam
) == BN_CLICKED
||
1816 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1817 if (LOWORD(wParam
) == IDC_ECHOBACKEND
)
1818 cfg
.localecho
= LD_BACKEND
;
1819 if (LOWORD(wParam
) == IDC_ECHOYES
)
1820 cfg
.localecho
= LD_YES
;
1821 if (LOWORD(wParam
) == IDC_ECHONO
)
1822 cfg
.localecho
= LD_NO
;
1825 case IDC_EDITBACKEND
:
1828 if (HIWORD(wParam
) == BN_CLICKED
||
1829 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1830 if (LOWORD(wParam
) == IDC_EDITBACKEND
)
1831 cfg
.localedit
= LD_BACKEND
;
1832 if (LOWORD(wParam
) == IDC_EDITYES
)
1833 cfg
.localedit
= LD_YES
;
1834 if (LOWORD(wParam
) == IDC_EDITNO
)
1835 cfg
.localedit
= LD_NO
;
1838 case IDC_ANSWEREDIT
:
1839 if (HIWORD(wParam
) == EN_CHANGE
)
1840 GetDlgItemText(hwnd
, IDC_ANSWEREDIT
, cfg
.answerback
,
1841 sizeof(cfg
.answerback
) - 1);
1843 case IDC_ALWAYSONTOP
:
1844 if (HIWORD(wParam
) == BN_CLICKED
||
1845 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1847 IsDlgButtonChecked(hwnd
, IDC_ALWAYSONTOP
);
1850 if (HIWORD(wParam
) == BN_CLICKED
||
1851 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1853 IsDlgButtonChecked(hwnd
, IDC_SCROLLKEY
);
1855 case IDC_SCROLLDISP
:
1856 if (HIWORD(wParam
) == BN_CLICKED
||
1857 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1858 cfg
.scroll_on_disp
=
1859 IsDlgButtonChecked(hwnd
, IDC_SCROLLDISP
);
1861 case IDC_COMPOSEKEY
:
1862 if (HIWORD(wParam
) == BN_CLICKED
||
1863 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1865 IsDlgButtonChecked(hwnd
, IDC_COMPOSEKEY
);
1867 case IDC_CTRLALTKEYS
:
1868 if (HIWORD(wParam
) == BN_CLICKED
||
1869 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1871 IsDlgButtonChecked(hwnd
, IDC_CTRLALTKEYS
);
1874 if (HIWORD(wParam
) == BN_CLICKED
||
1875 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1876 cfg
.telnet_keyboard
=
1877 IsDlgButtonChecked(hwnd
, IDC_TELNETKEY
);
1880 if (HIWORD(wParam
) == BN_CLICKED
||
1881 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1883 IsDlgButtonChecked(hwnd
, IDC_WRAPMODE
);
1886 if (HIWORD(wParam
) == BN_CLICKED
||
1887 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1888 cfg
.dec_om
= IsDlgButtonChecked(hwnd
, IDC_DECOM
);
1891 if (HIWORD(wParam
) == BN_CLICKED
||
1892 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1894 IsDlgButtonChecked(hwnd
, IDC_LFHASCR
);
1897 if (HIWORD(wParam
) == EN_CHANGE
)
1898 MyGetDlgItemInt(hwnd
, IDC_ROWSEDIT
, &cfg
.height
);
1901 if (HIWORD(wParam
) == EN_CHANGE
)
1902 MyGetDlgItemInt(hwnd
, IDC_COLSEDIT
, &cfg
.width
);
1905 if (HIWORD(wParam
) == EN_CHANGE
)
1906 MyGetDlgItemInt(hwnd
, IDC_SAVEEDIT
, &cfg
.savelines
);
1908 case IDC_CHOOSEFONT
:
1911 lf
.lfHeight
= -MulDiv(cfg
.fontheight
,
1912 GetDeviceCaps(hdc
, LOGPIXELSY
),
1916 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
1917 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
1918 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
1919 lf
.lfCharSet
= cfg
.fontcharset
;
1920 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1921 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1922 lf
.lfQuality
= DEFAULT_QUALITY
;
1923 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
1924 strncpy(lf
.lfFaceName
, cfg
.font
,
1925 sizeof(lf
.lfFaceName
) - 1);
1926 lf
.lfFaceName
[sizeof(lf
.lfFaceName
) - 1] = '\0';
1928 cf
.lStructSize
= sizeof(cf
);
1929 cf
.hwndOwner
= hwnd
;
1931 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
1932 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
1934 if (ChooseFont(&cf
)) {
1935 strncpy(cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
) - 1);
1936 cfg
.font
[sizeof(cfg
.font
) - 1] = '\0';
1937 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
1938 cfg
.fontcharset
= lf
.lfCharSet
;
1939 cfg
.fontheight
= cf
.iPointSize
/ 10;
1940 fmtfont(fontstatic
);
1941 SetDlgItemText(hwnd
, IDC_FONTSTATIC
, fontstatic
);
1944 case IDC_BELL_DISABLED
:
1945 case IDC_BELL_DEFAULT
:
1946 case IDC_BELL_WAVEFILE
:
1947 case IDC_BELL_VISUAL
:
1948 if (HIWORD(wParam
) == BN_CLICKED
||
1949 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1950 if (LOWORD(wParam
) == IDC_BELL_DISABLED
)
1951 cfg
.beep
= BELL_DISABLED
;
1952 if (LOWORD(wParam
) == IDC_BELL_DEFAULT
)
1953 cfg
.beep
= BELL_DEFAULT
;
1954 if (LOWORD(wParam
) == IDC_BELL_WAVEFILE
)
1955 cfg
.beep
= BELL_WAVEFILE
;
1956 if (LOWORD(wParam
) == IDC_BELL_VISUAL
)
1957 cfg
.beep
= BELL_VISUAL
;
1960 case IDC_B_IND_DISABLED
:
1961 case IDC_B_IND_FLASH
:
1962 case IDC_B_IND_STEADY
:
1963 if (HIWORD(wParam
) == BN_CLICKED
||
1964 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1965 if (LOWORD(wParam
) == IDC_B_IND_DISABLED
)
1966 cfg
.beep_ind
= B_IND_DISABLED
;
1967 if (LOWORD(wParam
) == IDC_B_IND_FLASH
)
1968 cfg
.beep_ind
= B_IND_FLASH
;
1969 if (LOWORD(wParam
) == IDC_B_IND_STEADY
)
1970 cfg
.beep_ind
= B_IND_STEADY
;
1973 case IDC_BELL_WAVEBROWSE
:
1974 memset(&of
, 0, sizeof(of
));
1975 #ifdef OPENFILENAME_SIZE_VERSION_400
1976 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1978 of
.lStructSize
= sizeof(of
);
1980 of
.hwndOwner
= hwnd
;
1981 of
.lpstrFilter
= "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1982 of
.lpstrCustomFilter
= NULL
;
1983 of
.nFilterIndex
= 1;
1984 of
.lpstrFile
= filename
;
1985 strcpy(filename
, cfg
.bell_wavefile
);
1986 of
.nMaxFile
= sizeof(filename
);
1987 of
.lpstrFileTitle
= NULL
;
1988 of
.lpstrInitialDir
= NULL
;
1989 of
.lpstrTitle
= "Select Bell Sound File";
1991 if (GetOpenFileName(&of
)) {
1992 strcpy(cfg
.bell_wavefile
, filename
);
1993 SetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
,
1997 case IDC_BELL_WAVEEDIT
:
1998 if (HIWORD(wParam
) == EN_CHANGE
)
1999 GetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
,
2001 sizeof(cfg
.bell_wavefile
) - 1);
2004 if (HIWORD(wParam
) == BN_CLICKED
||
2005 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2007 IsDlgButtonChecked(hwnd
, IDC_BELLOVL
);
2010 if (HIWORD(wParam
) == EN_CHANGE
)
2011 MyGetDlgItemInt(hwnd
, IDC_BELLOVLN
, &cfg
.bellovl_n
);
2014 if (HIWORD(wParam
) == EN_CHANGE
)
2015 MyGetDlgItemFlt(hwnd
, IDC_BELLOVLT
, &cfg
.bellovl_t
,
2019 if (HIWORD(wParam
) == EN_CHANGE
)
2020 MyGetDlgItemFlt(hwnd
, IDC_BELLOVLS
, &cfg
.bellovl_s
,
2024 if (HIWORD(wParam
) == BN_CLICKED
||
2025 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2027 IsDlgButtonChecked(hwnd
, IDC_BLINKTEXT
);
2030 if (HIWORD(wParam
) == BN_CLICKED
||
2031 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2032 cfg
.bce
= IsDlgButtonChecked(hwnd
, IDC_BCE
);
2035 if (HIWORD(wParam
) == BN_CLICKED
||
2036 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2037 cfg
.win_name_always
=
2038 IsDlgButtonChecked(hwnd
, IDC_WINNAME
);
2041 if (HIWORD(wParam
) == BN_CLICKED
||
2042 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2044 IsDlgButtonChecked(hwnd
, IDC_HIDEMOUSE
);
2046 case IDC_SUNKENEDGE
:
2047 if (HIWORD(wParam
) == BN_CLICKED
||
2048 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2050 IsDlgButtonChecked(hwnd
, IDC_SUNKENEDGE
);
2053 if (HIWORD(wParam
) == BN_CLICKED
||
2054 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2055 cfg
.cursor_type
= 0;
2058 if (HIWORD(wParam
) == BN_CLICKED
||
2059 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2060 cfg
.cursor_type
= 1;
2063 if (HIWORD(wParam
) == BN_CLICKED
||
2064 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2065 cfg
.cursor_type
= 2;
2068 if (HIWORD(wParam
) == BN_CLICKED
||
2069 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2071 IsDlgButtonChecked(hwnd
, IDC_BLINKCUR
);
2074 if (HIWORD(wParam
) == BN_CLICKED
||
2075 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2077 IsDlgButtonChecked(hwnd
, IDC_SCROLLBAR
);
2080 if (HIWORD(wParam
) == BN_CLICKED
||
2081 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2083 IsDlgButtonChecked(hwnd
, IDC_LOCKSIZE
);
2086 if (HIWORD(wParam
) == EN_CHANGE
)
2087 GetDlgItemText(hwnd
, IDC_WINEDIT
, cfg
.wintitle
,
2088 sizeof(cfg
.wintitle
) - 1);
2093 if (HIWORD(wParam
) == BN_CLICKED
||
2094 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2096 IsDlgButtonChecked(hwnd
,
2097 IDC_COEALWAYS
) ? COE_ALWAYS
:
2098 IsDlgButtonChecked(hwnd
,
2099 IDC_COENEVER
) ? COE_NEVER
:
2104 if (HIWORD(wParam
) == BN_CLICKED
||
2105 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2107 IsDlgButtonChecked(hwnd
, IDC_CLOSEWARN
);
2110 if (HIWORD(wParam
) == EN_CHANGE
)
2111 GetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
,
2112 sizeof(cfg
.termtype
) - 1);
2115 if (HIWORD(wParam
) == EN_CHANGE
)
2116 GetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
,
2117 sizeof(cfg
.logfilename
) - 1);
2120 memset(&of
, 0, sizeof(of
));
2121 #ifdef OPENFILENAME_SIZE_VERSION_400
2122 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
2124 of
.lStructSize
= sizeof(of
);
2126 of
.hwndOwner
= hwnd
;
2127 of
.lpstrFilter
= "All Files\0*\0\0\0";
2128 of
.lpstrCustomFilter
= NULL
;
2129 of
.nFilterIndex
= 1;
2130 of
.lpstrFile
= filename
;
2131 strcpy(filename
, cfg
.logfilename
);
2132 of
.nMaxFile
= sizeof(filename
);
2133 of
.lpstrFileTitle
= NULL
;
2134 of
.lpstrInitialDir
= NULL
;
2135 of
.lpstrTitle
= "Select session log file";
2137 if (GetSaveFileName(&of
)) {
2138 strcpy(cfg
.logfilename
, filename
);
2139 SetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
);
2143 case IDC_LSTATASCII
:
2145 if (HIWORD(wParam
) == BN_CLICKED
||
2146 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2147 if (IsDlgButtonChecked(hwnd
, IDC_LSTATOFF
))
2149 if (IsDlgButtonChecked(hwnd
, IDC_LSTATASCII
))
2151 if (IsDlgButtonChecked(hwnd
, IDC_LSTATRAW
))
2158 if (HIWORD(wParam
) == BN_CLICKED
||
2159 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2160 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXASK
))
2161 cfg
.logxfovr
= LGXF_ASK
;
2162 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXAPN
))
2163 cfg
.logxfovr
= LGXF_APN
;
2164 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXOVR
))
2165 cfg
.logxfovr
= LGXF_OVR
;
2170 if (HIWORD(wParam
) == EN_CHANGE
)
2171 GetDlgItemText(hwnd
, LOWORD(wParam
), cfg
.termspeed
,
2172 sizeof(cfg
.termspeed
) - 1);
2175 if (HIWORD(wParam
) == EN_CHANGE
)
2176 GetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
,
2177 sizeof(cfg
.username
) - 1);
2179 case IDC_RLLUSEREDIT
:
2180 if (HIWORD(wParam
) == EN_CHANGE
)
2181 GetDlgItemText(hwnd
, IDC_RLLUSEREDIT
,
2183 sizeof(cfg
.localusername
) - 1);
2187 cfg
.rfc_environ
= IsDlgButtonChecked(hwnd
, IDC_EMRFC
);
2191 cfg
.passive_telnet
=
2192 IsDlgButtonChecked(hwnd
, IDC_TPASSIVE
);
2195 if (HIWORD(wParam
) == BN_CLICKED
||
2196 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2197 char str
[sizeof(cfg
.environmt
)];
2199 GetDlgItemText(hwnd
, IDC_VAREDIT
, str
,
2205 p
= str
+ strlen(str
);
2207 GetDlgItemText(hwnd
, IDC_VALEDIT
, p
,
2208 sizeof(str
) - 1 - (p
- str
));
2219 if ((p
- cfg
.environmt
) + strlen(str
) + 2 <
2220 sizeof(cfg
.environmt
)) {
2222 p
[strlen(str
) + 1] = '\0';
2223 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_ADDSTRING
,
2225 SetDlgItemText(hwnd
, IDC_VAREDIT
, "");
2226 SetDlgItemText(hwnd
, IDC_VALEDIT
, "");
2228 MessageBox(hwnd
, "Environment too big",
2229 "PuTTY Error", MB_OK
| MB_ICONERROR
);
2234 if (HIWORD(wParam
) != BN_CLICKED
&&
2235 HIWORD(wParam
) != BN_DOUBLECLICKED
) break;
2237 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_GETCURSEL
, 0,
2244 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_DELETESTRING
,
2271 if (HIWORD(wParam
) == BN_CLICKED
||
2272 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2273 cfg
.nopty
= IsDlgButtonChecked(hwnd
, IDC_NOPTY
);
2276 if (HIWORD(wParam
) == BN_CLICKED
||
2277 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2279 IsDlgButtonChecked(hwnd
, IDC_COMPRESS
);
2282 if (HIWORD(wParam
) == BN_CLICKED
||
2283 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2285 IsDlgButtonChecked(hwnd
, IDC_BUGGYMAC
);
2288 if (HIWORD(wParam
) == BN_CLICKED
||
2289 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2291 IsDlgButtonChecked(hwnd
, IDC_AGENTFWD
);
2293 case IDC_CIPHERLIST
:
2296 handle_prefslist(&cipherlist
,
2297 cfg
.ssh_cipherlist
, CIPHER_MAX
,
2298 0, hwnd
, wParam
, lParam
);
2302 if (HIWORD(wParam
) == BN_CLICKED
||
2303 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2304 if (IsDlgButtonChecked(hwnd
, IDC_SSHPROT1
))
2306 else if (IsDlgButtonChecked(hwnd
, IDC_SSHPROT2
))
2311 if (HIWORD(wParam
) == BN_CLICKED
||
2312 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2314 IsDlgButtonChecked(hwnd
, IDC_AUTHTIS
);
2317 if (HIWORD(wParam
) == EN_CHANGE
)
2318 GetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
,
2319 sizeof(cfg
.keyfile
) - 1);
2322 if (HIWORD(wParam
) == EN_CHANGE
)
2323 GetDlgItemText(hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
,
2324 sizeof(cfg
.remote_cmd
) - 1);
2327 memset(&of
, 0, sizeof(of
));
2328 #ifdef OPENFILENAME_SIZE_VERSION_400
2329 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
2331 of
.lStructSize
= sizeof(of
);
2333 of
.hwndOwner
= hwnd
;
2334 of
.lpstrFilter
= "All Files\0*\0\0\0";
2335 of
.lpstrCustomFilter
= NULL
;
2336 of
.nFilterIndex
= 1;
2337 of
.lpstrFile
= filename
;
2338 strcpy(filename
, cfg
.keyfile
);
2339 of
.nMaxFile
= sizeof(filename
);
2340 of
.lpstrFileTitle
= NULL
;
2341 of
.lpstrInitialDir
= NULL
;
2342 of
.lpstrTitle
= "Select Public Key File";
2344 if (GetOpenFileName(&of
)) {
2345 strcpy(cfg
.keyfile
, filename
);
2346 SetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
2350 cfg
.rawcnp
= IsDlgButtonChecked(hwnd
, IDC_RAWCNP
);
2354 cfg
.mouse_is_xterm
= IsDlgButtonChecked(hwnd
, IDC_MBXTERM
);
2356 case IDC_MOUSEOVERRIDE
:
2357 cfg
.mouse_override
= IsDlgButtonChecked(hwnd
, IDC_MOUSEOVERRIDE
);
2363 int n
= GetDlgItemInt(hwnd
, IDC_CCEDIT
, &ok
, FALSE
);
2368 for (i
= 0; i
< 128; i
++)
2369 if (SendDlgItemMessage
2370 (hwnd
, IDC_CCLIST
, LB_GETSEL
, i
, 0)) {
2372 cfg
.wordness
[i
] = n
;
2373 SendDlgItemMessage(hwnd
, IDC_CCLIST
,
2374 LB_DELETESTRING
, i
, 0);
2375 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
2376 (i
>= 0x21 && i
!= 0x7F) ? i
: ' ',
2378 SendDlgItemMessage(hwnd
, IDC_CCLIST
,
2385 case IDC_BOLDCOLOUR
:
2386 if (HIWORD(wParam
) == BN_CLICKED
||
2387 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2390 IsDlgButtonChecked(hwnd
, IDC_BOLDCOLOUR
);
2391 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, WM_SETREDRAW
,
2394 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2396 if (n
!= 12 + 10 * cfg
.bold_colour
) {
2397 for (i
= n
; i
-- > 0;)
2398 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2399 LB_DELETESTRING
, i
, 0);
2400 for (i
= 0; i
< 22; i
++)
2401 if (cfg
.bold_colour
|| permcolour
[i
])
2402 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2404 (LPARAM
) colours
[i
]);
2406 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, WM_SETREDRAW
,
2408 InvalidateRect(GetDlgItem(hwnd
, IDC_COLOURLIST
), NULL
,
2413 if (HIWORD(wParam
) == BN_CLICKED
||
2414 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2416 IsDlgButtonChecked(hwnd
, IDC_PALETTE
);
2418 case IDC_COLOURLIST
:
2419 if (HIWORD(wParam
) == LBN_DBLCLK
||
2420 HIWORD(wParam
) == LBN_SELCHANGE
) {
2422 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2425 if (!cfg
.bold_colour
)
2426 i
= (i
< 3 ? i
* 2 : i
== 3 ?
5 : i
* 2 - 2);
2427 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
2429 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
2431 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
2436 if (HIWORD(wParam
) == BN_CLICKED
||
2437 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2438 static CHOOSECOLOR cc
;
2439 static DWORD custom
[16] = { 0 }; /* zero initialisers */
2441 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2444 if (!cfg
.bold_colour
)
2445 i
= (i
< 3 ? i
* 2 : i
== 3 ?
5 : i
* 2 - 2);
2446 cc
.lStructSize
= sizeof(cc
);
2447 cc
.hwndOwner
= hwnd
;
2448 cc
.hInstance
= (HWND
) hinst
;
2449 cc
.lpCustColors
= custom
;
2451 RGB(cfg
.colours
[i
][0], cfg
.colours
[i
][1],
2453 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
2454 if (ChooseColor(&cc
)) {
2456 (unsigned char) (cc
.rgbResult
& 0xFF);
2458 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
2460 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
2461 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
2463 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
2465 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
2471 if (HIWORD(wParam
) == CBN_SELCHANGE
) {
2472 int index
= SendDlgItemMessage(hwnd
, IDC_CODEPAGE
,
2473 CB_GETCURSEL
, 0, 0);
2474 SendDlgItemMessage(hwnd
, IDC_CODEPAGE
, CB_GETLBTEXT
,
2475 index
, (LPARAM
)cfg
.line_codepage
);
2476 } else if (HIWORD(wParam
) == CBN_EDITCHANGE
) {
2477 GetDlgItemText(hwnd
, IDC_CODEPAGE
, cfg
.line_codepage
,
2478 sizeof(cfg
.line_codepage
) - 1);
2479 } else if (HIWORD(wParam
) == CBN_KILLFOCUS
) {
2480 strcpy(cfg
.line_codepage
,
2481 cp_name(decode_codepage(cfg
.line_codepage
)));
2482 SetDlgItemText(hwnd
, IDC_CODEPAGE
, cfg
.line_codepage
);
2485 case IDC_VTXWINDOWS
:
2491 (IsDlgButtonChecked(hwnd
, IDC_VTXWINDOWS
) ? VT_XWINDOWS
2492 : IsDlgButtonChecked(hwnd
,
2493 IDC_VTOEMANSI
) ? VT_OEMANSI
:
2494 IsDlgButtonChecked(hwnd
,
2495 IDC_VTOEMONLY
) ? VT_OEMONLY
:
2496 IsDlgButtonChecked(hwnd
,
2497 IDC_VTUNICODE
) ? VT_UNICODE
:
2500 case IDC_X11_FORWARD
:
2501 if (HIWORD(wParam
) == BN_CLICKED
||
2502 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2504 IsDlgButtonChecked(hwnd
, IDC_X11_FORWARD
);
2507 if (HIWORD(wParam
) == BN_CLICKED
||
2508 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2509 cfg
.lport_acceptall
=
2510 IsDlgButtonChecked(hwnd
, IDC_LPORT_ALL
);
2512 case IDC_X11_DISPLAY
:
2513 if (HIWORD(wParam
) == EN_CHANGE
)
2514 GetDlgItemText(hwnd
, IDC_X11_DISPLAY
, cfg
.x11_display
,
2515 sizeof(cfg
.x11_display
) - 1);
2518 if (HIWORD(wParam
) == BN_CLICKED
||
2519 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2520 char str
[sizeof(cfg
.portfwd
)];
2522 if (IsDlgButtonChecked(hwnd
, IDC_PFWDLOCAL
))
2526 GetDlgItemText(hwnd
, IDC_SPORTEDIT
, str
+1,
2530 "You need to specify a source port number",
2531 "PuTTY Error", MB_OK
| MB_ICONERROR
);
2534 p
= str
+ strlen(str
);
2536 GetDlgItemText(hwnd
, IDC_DPORTEDIT
, p
,
2537 sizeof(str
) - 1 - (p
- str
));
2538 if (!*p
|| !strchr(p
, ':')) {
2540 "You need to specify a destination address\n"
2541 "in the form \"host.name:port\"",
2542 "PuTTY Error", MB_OK
| MB_ICONERROR
);
2551 if ((p
- cfg
.portfwd
) + strlen(str
) + 2 <
2552 sizeof(cfg
.portfwd
)) {
2554 p
[strlen(str
) + 1] = '\0';
2555 SendDlgItemMessage(hwnd
, IDC_PFWDLIST
, LB_ADDSTRING
,
2557 SetDlgItemText(hwnd
, IDC_SPORTEDIT
, "");
2558 SetDlgItemText(hwnd
, IDC_DPORTEDIT
, "");
2560 MessageBox(hwnd
, "Too many forwardings",
2561 "PuTTY Error", MB_OK
| MB_ICONERROR
);
2565 case IDC_PFWDREMOVE
:
2566 if (HIWORD(wParam
) != BN_CLICKED
&&
2567 HIWORD(wParam
) != BN_DOUBLECLICKED
) break;
2568 i
= SendDlgItemMessage(hwnd
, IDC_PFWDLIST
,
2569 LB_GETCURSEL
, 0, 0);
2575 SendDlgItemMessage(hwnd
, IDC_PFWDLIST
, LB_DELETESTRING
,
2607 /* Grrr Explorer will maximize Dialogs! */
2609 if (wParam
== SIZE_MAXIMIZED
)
2615 * Handle application-defined messages eg. DragListBox
2617 /* First find out what the number is (once). */
2618 if (draglistmsg
== WM_NULL
)
2619 draglistmsg
= RegisterWindowMessage (DRAGLISTMSGSTRING
);
2621 if (msg
== draglistmsg
) {
2622 /* Only process once dialog is fully formed. */
2623 if (GetWindowLong(hwnd
, GWL_USERDATA
) == 1) switch (LOWORD(wParam
)) {
2624 case IDC_CIPHERLIST
:
2625 return handle_prefslist(&cipherlist
,
2626 cfg
.ssh_cipherlist
, CIPHER_MAX
,
2627 1, hwnd
, wParam
, lParam
);
2636 static int CALLBACK
MainDlgProc(HWND hwnd
, UINT msg
,
2637 WPARAM wParam
, LPARAM lParam
)
2639 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
2641 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDCX_ABOUT
) {
2642 EnableWindow(hwnd
, 0);
2643 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hwnd
, AboutProc
);
2644 EnableWindow(hwnd
, 1);
2645 SetActiveWindow(hwnd
);
2647 return GenericMainDlgProc(hwnd
, msg
, wParam
, lParam
, 0);
2650 static int CALLBACK
ReconfDlgProc(HWND hwnd
, UINT msg
,
2651 WPARAM wParam
, LPARAM lParam
)
2653 return GenericMainDlgProc(hwnd
, msg
, wParam
, lParam
, 1);
2656 void defuse_showwindow(void)
2659 * Work around the fact that the app's first call to ShowWindow
2660 * will ignore the default in favour of the shell-provided
2665 hwnd
= CreateDialog(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
2667 ShowWindow(hwnd
, SW_HIDE
);
2668 SetActiveWindow(hwnd
);
2669 DestroyWindow(hwnd
);
2678 savedsession
[0] = '\0';
2680 DialogBox(hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
2681 get_sesslist(FALSE
);
2686 int do_reconfig(HWND hwnd
)
2691 backup_cfg
= cfg
; /* structure copy */
2693 DialogBox(hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
2695 cfg
= backup_cfg
; /* structure copy */
2700 void logevent(char *string
)
2705 if (nevents
>= negsize
) {
2707 events
= srealloc(events
, negsize
* sizeof(*events
));
2711 strftime(timebuf
, sizeof(timebuf
), "%Y-%m-%d %H:%M:%S\t",
2714 events
[nevents
] = smalloc(strlen(timebuf
) + strlen(string
) + 1);
2715 strcpy(events
[nevents
], timebuf
);
2716 strcat(events
[nevents
], string
);
2719 SendDlgItemMessage(logbox
, IDN_LIST
, LB_ADDSTRING
,
2720 0, (LPARAM
) events
[nevents
]);
2721 count
= SendDlgItemMessage(logbox
, IDN_LIST
, LB_GETCOUNT
, 0, 0);
2722 SendDlgItemMessage(logbox
, IDN_LIST
, LB_SETTOPINDEX
, count
- 1, 0);
2727 void showeventlog(HWND hwnd
)
2730 logbox
= CreateDialog(hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
2732 ShowWindow(logbox
, SW_SHOWNORMAL
);
2734 SetActiveWindow(logbox
);
2737 void showabout(HWND hwnd
)
2739 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hwnd
, AboutProc
);
2742 void verify_ssh_host_key(char *host
, int port
, char *keytype
,
2743 char *keystr
, char *fingerprint
)
2747 static const char absentmsg
[] =
2748 "The server's host key is not cached in the registry. You\n"
2749 "have no guarantee that the server is the computer you\n"
2751 "The server's key fingerprint is:\n"
2753 "If you trust this host, hit Yes to add the key to\n"
2754 "PuTTY's cache and carry on connecting.\n"
2755 "If you want to carry on connecting just once, without\n"
2756 "adding the key to the cache, hit No.\n"
2757 "If you do not trust this host, hit Cancel to abandon the\n"
2760 static const char wrongmsg
[] =
2761 "WARNING - POTENTIAL SECURITY BREACH!\n"
2763 "The server's host key does not match the one PuTTY has\n"
2764 "cached in the registry. This means that either the\n"
2765 "server administrator has changed the host key, or you\n"
2766 "have actually connected to another computer pretending\n"
2767 "to be the server.\n"
2768 "The new key fingerprint is:\n"
2770 "If you were expecting this change and trust the new key,\n"
2771 "hit Yes to update PuTTY's cache and continue connecting.\n"
2772 "If you want to carry on connecting but without updating\n"
2773 "the cache, hit No.\n"
2774 "If you want to abandon the connection completely, hit\n"
2775 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2777 static const char mbtitle
[] = "PuTTY Security Alert";
2780 /* sensible fingerprint max size */
2781 (sizeof(absentmsg
) > sizeof(wrongmsg
) ?
2782 sizeof(absentmsg
) : sizeof(wrongmsg
))];
2785 * Verify the key against the registry.
2787 ret
= verify_host_key(host
, port
, keytype
, keystr
);
2789 if (ret
== 0) /* success - key matched OK */
2791 if (ret
== 2) { /* key was different */
2793 sprintf(message
, wrongmsg
, fingerprint
);
2794 mbret
= MessageBox(NULL
, message
, mbtitle
,
2795 MB_ICONWARNING
| MB_YESNOCANCEL
);
2797 store_host_key(host
, port
, keytype
, keystr
);
2798 if (mbret
== IDCANCEL
)
2801 if (ret
== 1) { /* key was absent */
2803 sprintf(message
, absentmsg
, fingerprint
);
2804 mbret
= MessageBox(NULL
, message
, mbtitle
,
2805 MB_ICONWARNING
| MB_YESNOCANCEL
);
2807 store_host_key(host
, port
, keytype
, keystr
);
2808 if (mbret
== IDCANCEL
)
2814 * Ask whether the selected cipher is acceptable (since it was
2815 * below the configured 'warn' threshold).
2816 * cs: 0 = both ways, 1 = client->server, 2 = server->client
2818 void askcipher(char *ciphername
, int cs
)
2820 static const char mbtitle
[] = "PuTTY Security Alert";
2821 static const char msg
[] =
2822 "The first %.35scipher supported by the server\n"
2823 "is %.64s, which is below the configured\n"
2824 "warning threshold.\n"
2825 "Do you want to continue with this connection?\n";
2826 /* guessed cipher name + type max length */
2827 char message
[100 + sizeof(msg
)];
2830 sprintf(message
, msg
,
2832 (cs
== 1) ?
"client-to-server " :
2833 "server-to-client ",
2835 mbret
= MessageBox(NULL
, message
, mbtitle
,
2836 MB_ICONWARNING
| MB_YESNO
);
2844 * Ask whether to wipe a session log file before writing to it.
2845 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2847 int askappend(char *filename
)
2849 static const char mbtitle
[] = "PuTTY Log to File";
2850 static const char msgtemplate
[] =
2851 "The session log file \"%.*s\" already exists.\n"
2852 "You can overwrite it with a new session log,\n"
2853 "append your session log to the end of it,\n"
2854 "or disable session logging for this session.\n"
2855 "Hit Yes to wipe the file, No to append to it,\n"
2856 "or Cancel to disable logging.";
2857 char message
[sizeof(msgtemplate
) + FILENAME_MAX
];
2859 if (cfg
.logxfovr
!= LGXF_ASK
) {
2860 return ((cfg
.logxfovr
== LGXF_OVR
) ?
2 : 1);
2862 sprintf(message
, msgtemplate
, FILENAME_MAX
, filename
);
2864 mbret
= MessageBox(NULL
, message
, mbtitle
,
2865 MB_ICONQUESTION
| MB_YESNOCANCEL
);
2868 else if (mbret
== IDNO
)