Yet more global-removal. The static variables in logging.c are now
[u/mdw/putty] / windlg.c
index 706a68f..5040a24 100644 (file)
--- a/windlg.c
+++ b/windlg.c
 #include "win_res.h"
 #include "storage.h"
 
+#ifdef MSVC4
+#define TVINSERTSTRUCT  TV_INSERTSTRUCT
+#define TVITEM          TV_ITEM
+#define ICON_BIG        1
+#endif
+
 static char **events = NULL;
 static int nevents = 0, negsize = 0;
 
 static int readytogo;
 static int sesslist_has_focus;
+static int requested_help;
 
 static struct prefslist cipherlist;
 
+#define PRINTER_DISABLED_STRING "None (printing disabled)"
+
 void force_normal(HWND hwnd)
 {
     static int recurse = 0;
@@ -131,7 +140,7 @@ static int CALLBACK LogProc(HWND hwnd, UINT msg,
                            memcpy(p, sel_nl, sizeof(sel_nl));
                            p += sizeof(sel_nl);
                        }
-                       write_aclip(clipdata, size, TRUE);
+                       write_aclip(NULL, clipdata, size, TRUE);
                        sfree(clipdata);
                    }
                    sfree(selitems);
@@ -256,6 +265,7 @@ enum { IDCX_ABOUT =
     IDC_LSTATOFF,
     IDC_LSTATASCII,
     IDC_LSTATRAW,
+    IDC_LSTATPACKET,
     IDC_LGFSTATIC,
     IDC_LGFEDIT,
     IDC_LGFBUTTON,
@@ -288,20 +298,18 @@ enum { IDCX_ABOUT =
     IDC_KPNORMAL,
     IDC_KPAPPLIC,
     IDC_KPNH,
-    IDC_NOAPPLICK,
-    IDC_NOAPPLICC,
     IDC_CURSTATIC,
     IDC_CURNORMAL,
     IDC_CURAPPLIC,
     IDC_COMPOSEKEY,
     IDC_CTRLALTKEYS,
-    IDC_TELNETKEY,
     keyboardpanelend,
 
     terminalpanelstart,
     IDC_TITLE_TERMINAL,
     IDC_BOX_TERMINAL1,
     IDC_BOX_TERMINAL2,
+    IDC_BOX_TERMINAL3,
     IDC_WRAPMODE,
     IDC_DECOM,
     IDC_LFHASCR,
@@ -317,8 +325,23 @@ enum { IDCX_ABOUT =
     IDC_EDITBACKEND,
     IDC_EDITYES,
     IDC_EDITNO,
+    IDC_PRINTERSTATIC,
+    IDC_PRINTER,
     terminalpanelend,
 
+    featurespanelstart,
+    IDC_TITLE_FEATURES,
+    IDC_BOX_FEATURES1,
+    IDC_NOAPPLICK,
+    IDC_NOAPPLICC,
+    IDC_NOMOUSEREP,
+    IDC_NORESIZE,
+    IDC_NOALTSCREEN,
+    IDC_NOWINTITLE,
+    IDC_NODBACKSPACE,
+    IDC_NOCHARSET,
+    featurespanelend,
+
     bellpanelstart,
     IDC_TITLE_BELL,
     IDC_BOX_BELL1,
@@ -358,19 +381,25 @@ enum { IDCX_ABOUT =
     IDC_RESIZETERM,
     IDC_RESIZEFONT,
     IDC_RESIZENONE,
+    IDC_RESIZEEITHER,
     IDC_SCROLLBAR,
     IDC_SCROLLBARFULLSCREEN,
-    IDC_CLOSEWARN,
     IDC_SAVESTATIC,
     IDC_SAVEEDIT,
+    IDC_SCROLLKEY,
+    IDC_SCROLLDISP,
+    windowpanelend,
+
+    behaviourpanelstart,
+    IDC_TITLE_BEHAVIOUR,
+    IDC_BOX_BEHAVIOUR1,
+    IDC_CLOSEWARN,
     IDC_ALTF4,
     IDC_ALTSPACE,
     IDC_ALTONLY,
-    IDC_SCROLLKEY,
-    IDC_SCROLLDISP,
     IDC_ALWAYSONTOP,
     IDC_FULLSCREENONALTENTER,
-    windowpanelend,
+    behaviourpanelend,
 
     appearancepanelstart,
     IDC_TITLE_APPEARANCE,
@@ -399,14 +428,42 @@ enum { IDCX_ABOUT =
     IDC_TITLE_CONNECTION,
     IDC_BOX_CONNECTION1,
     IDC_BOX_CONNECTION2,
+    IDC_BOX_CONNECTION3,
     IDC_TTSTATIC,
     IDC_TTEDIT,
     IDC_LOGSTATIC,
     IDC_LOGEDIT,
     IDC_PINGSTATIC,
     IDC_PINGEDIT,
+    IDC_NODELAY,
     connectionpanelend,
 
+    proxypanelstart,
+    IDC_TITLE_PROXY,
+    IDC_BOX_PROXY1,
+    IDC_PROXYTYPESTATIC,
+    IDC_PROXYTYPENONE,
+    IDC_PROXYTYPEHTTP,
+    IDC_PROXYTYPESOCKS,
+    IDC_PROXYTYPETELNET,
+    IDC_PROXYHOSTSTATIC,
+    IDC_PROXYHOSTEDIT,
+    IDC_PROXYPORTSTATIC,
+    IDC_PROXYPORTEDIT,
+    IDC_PROXYEXCLUDESTATIC,
+    IDC_PROXYEXCLUDEEDIT,
+    IDC_PROXYUSERSTATIC,
+    IDC_PROXYUSEREDIT,
+    IDC_PROXYPASSSTATIC,
+    IDC_PROXYPASSEDIT,
+    IDC_BOX_PROXY2,
+    IDC_PROXYTELNETCMDSTATIC,
+    IDC_PROXYTELNETCMDEDIT,
+    IDC_PROXYSOCKSVERSTATIC,
+    IDC_PROXYSOCKSVER5,
+    IDC_PROXYSOCKSVER4,
+    proxypanelend,
+
     telnetpanelstart,
     IDC_TITLE_TELNET,
     IDC_BOX_TELNET1,
@@ -427,6 +484,8 @@ enum { IDCX_ABOUT =
     IDC_ACTSTATIC,
     IDC_TPASSIVE,
     IDC_TACTIVE,
+    IDC_TELNETKEY,
+    IDC_TELNETRET,
     telnetpanelend,
 
     rloginpanelstart,
@@ -450,10 +509,12 @@ enum { IDCX_ABOUT =
     IDC_CIPHERLIST,
     IDC_CIPHERUP,
     IDC_CIPHERDN,
-    IDC_BUGGYMAC,
+    IDC_SSH2DES,
     IDC_SSHPROTSTATIC,
+    IDC_SSHPROT1ONLY,
     IDC_SSHPROT1,
     IDC_SSHPROT2,
+    IDC_SSHPROT2ONLY,
     IDC_CMDSTATIC,
     IDC_CMDEDIT,
     IDC_COMPRESS,
@@ -467,9 +528,30 @@ enum { IDCX_ABOUT =
     IDC_PKEDIT,
     IDC_PKBUTTON,
     IDC_AGENTFWD,
+    IDC_CHANGEUSER,
     IDC_AUTHTIS,
+    IDC_AUTHKI,
     sshauthpanelend,
 
+    sshbugspanelstart,
+    IDC_TITLE_SSHBUGS,
+    IDC_BOX_SSHBUGS1,
+    IDC_BUGS_IGNORE1,
+    IDC_BUGD_IGNORE1,
+    IDC_BUGS_PLAINPW1,
+    IDC_BUGD_PLAINPW1,
+    IDC_BUGS_RSA1,
+    IDC_BUGD_RSA1,
+    IDC_BUGS_HMAC2,
+    IDC_BUGD_HMAC2,
+    IDC_BUGS_DERIVEKEY2,
+    IDC_BUGD_DERIVEKEY2,
+    IDC_BUGS_RSAPAD2,
+    IDC_BUGD_RSAPAD2,
+    IDC_BUGS_DHGEX2,
+    IDC_BUGD_DHGEX2,
+    sshbugspanelend,
+
     selectionpanelstart,
     IDC_TITLE_SELECTION,
     IDC_BOX_SELECTION1,
@@ -488,6 +570,7 @@ enum { IDCX_ABOUT =
     IDC_CCSTATIC2,
     IDC_CCEDIT,
     IDC_RAWCNP,
+    IDC_RTFPASTE,
     selectionpanelend,
 
     colourspanelstart,
@@ -531,6 +614,7 @@ enum { IDCX_ABOUT =
     IDC_X11_DISPSTATIC,
     IDC_X11_DISPLAY,
     IDC_LPORT_ALL,
+    IDC_RPORT_ALL,
     IDC_PFWDSTATIC,
     IDC_PFWDSTATIC2,
     IDC_PFWDREMOVE,
@@ -579,6 +663,398 @@ static void fmtfont(char *buf)
                (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
 }
 
+char *help_context_cmd(int id)
+{
+    switch (id) {
+      case IDC_HOSTSTATIC:
+      case IDC_HOST:
+      case IDC_PORTSTATIC:
+      case IDC_PORT:
+      case IDC_PROTSTATIC:
+      case IDC_PROTRAW:
+      case IDC_PROTTELNET:
+      case IDC_PROTRLOGIN:
+      case IDC_PROTSSH:
+        return "JI(`',`session.hostname')";
+      case IDC_SESSSTATIC:
+      case IDC_SESSEDIT:
+      case IDC_SESSLIST:
+      case IDC_SESSLOAD:
+      case IDC_SESSSAVE:
+      case IDC_SESSDEL:
+        return "JI(`',`session.saved')";
+      case IDC_CLOSEEXIT:
+      case IDC_COEALWAYS:
+      case IDC_COENEVER:
+      case IDC_COENORMAL:
+        return "JI(`',`session.coe')";
+      case IDC_LSTATSTATIC:
+      case IDC_LSTATOFF:
+      case IDC_LSTATASCII:
+      case IDC_LSTATRAW:
+      case IDC_LSTATPACKET:
+        return "JI(`',`logging.main')";
+      case IDC_LGFSTATIC:
+      case IDC_LGFEDIT:
+      case IDC_LGFBUTTON:
+      case IDC_LGFEXPLAIN:
+        return "JI(`',`logging.filename')";
+      case IDC_LSTATXIST:
+      case IDC_LSTATXOVR:
+      case IDC_LSTATXAPN:
+      case IDC_LSTATXASK:
+        return "JI(`',`logging.exists')";
+
+      case IDC_DELSTATIC:
+      case IDC_DEL008:
+      case IDC_DEL127:
+        return "JI(`',`keyboard.backspace')";
+      case IDC_HOMESTATIC:
+      case IDC_HOMETILDE:
+      case IDC_HOMERXVT:
+        return "JI(`',`keyboard.homeend')";
+      case IDC_FUNCSTATIC:
+      case IDC_FUNCTILDE:
+      case IDC_FUNCLINUX:
+      case IDC_FUNCXTERM:
+      case IDC_FUNCVT400:
+      case IDC_FUNCVT100P:
+      case IDC_FUNCSCO:
+        return "JI(`',`keyboard.funkeys')";
+      case IDC_KPSTATIC:
+      case IDC_KPNORMAL:
+      case IDC_KPAPPLIC:
+        return "JI(`',`keyboard.appkeypad')";
+      case IDC_CURSTATIC:
+      case IDC_CURNORMAL:
+      case IDC_CURAPPLIC:
+        return "JI(`',`keyboard.appcursor')";
+      case IDC_KPNH:
+        return "JI(`',`keyboard.nethack')";
+      case IDC_COMPOSEKEY:
+        return "JI(`',`keyboard.compose')";
+      case IDC_CTRLALTKEYS:
+        return "JI(`',`keyboard.ctrlalt')";
+
+      case IDC_NOAPPLICK:
+      case IDC_NOAPPLICC:
+        return "JI(`',`features.application')";
+      case IDC_NOMOUSEREP:
+        return "JI(`',`features.mouse')";
+      case IDC_NORESIZE:
+        return "JI(`',`features.resize')";
+      case IDC_NOALTSCREEN:
+        return "JI(`',`features.altscreen')";
+      case IDC_NOWINTITLE:
+        return "JI(`',`features.retitle')";
+      case IDC_NODBACKSPACE:
+        return "JI(`',`features.dbackspace')";
+      case IDC_NOCHARSET:
+        return "JI(`',`features.charset')";
+
+      case IDC_WRAPMODE:
+        return "JI(`',`terminal.autowrap')";
+      case IDC_DECOM:
+        return "JI(`',`terminal.decom')";
+      case IDC_LFHASCR:
+        return "JI(`',`terminal.lfhascr')";
+      case IDC_BCE:
+        return "JI(`',`terminal.bce')";
+      case IDC_BLINKTEXT:
+        return "JI(`',`terminal.blink')";
+      case IDC_ANSWERBACK:
+      case IDC_ANSWEREDIT:
+        return "JI(`',`terminal.answerback')";
+      case IDC_ECHOSTATIC:
+      case IDC_ECHOBACKEND:
+      case IDC_ECHOYES:
+      case IDC_ECHONO:
+        return "JI(`',`terminal.localecho')";
+      case IDC_EDITSTATIC:
+      case IDC_EDITBACKEND:
+      case IDC_EDITYES:
+      case IDC_EDITNO:
+        return "JI(`',`terminal.localedit')";
+      case IDC_PRINTERSTATIC:
+      case IDC_PRINTER:
+       return "JI(`',`terminal.printing')";
+
+      case IDC_BELLSTATIC:
+      case IDC_BELL_DISABLED:
+      case IDC_BELL_DEFAULT:
+      case IDC_BELL_WAVEFILE:
+      case IDC_BELL_VISUAL:
+      case IDC_BELL_WAVESTATIC:
+      case IDC_BELL_WAVEEDIT:
+      case IDC_BELL_WAVEBROWSE:
+        return "JI(`',`bell.style')";
+      case IDC_B_IND_STATIC:
+      case IDC_B_IND_DISABLED:
+      case IDC_B_IND_FLASH:
+      case IDC_B_IND_STEADY:
+        return "JI(`',`bell.taskbar')";
+      case IDC_BELLOVL:
+      case IDC_BELLOVLNSTATIC:
+      case IDC_BELLOVLN:
+      case IDC_BELLOVLTSTATIC:
+      case IDC_BELLOVLT:
+      case IDC_BELLOVLEXPLAIN:
+      case IDC_BELLOVLSSTATIC:
+      case IDC_BELLOVLS:
+        return "JI(`',`bell.overload')";
+
+      case IDC_ROWSSTATIC:
+      case IDC_ROWSEDIT:
+      case IDC_COLSSTATIC:
+      case IDC_COLSEDIT:
+        return "JI(`',`window.size')";
+      case IDC_RESIZESTATIC:
+      case IDC_RESIZETERM:
+      case IDC_RESIZEFONT:
+      case IDC_RESIZENONE:
+      case IDC_RESIZEEITHER:
+        return "JI(`',`window.resize')";
+      case IDC_SCROLLBAR:
+      case IDC_SCROLLBARFULLSCREEN:
+      case IDC_SAVESTATIC:
+      case IDC_SAVEEDIT:
+      case IDC_SCROLLKEY:
+      case IDC_SCROLLDISP:
+        return "JI(`',`window.scrollback')";
+
+      case IDC_CLOSEWARN:
+        return "JI(`',`behaviour.closewarn')";
+      case IDC_ALTF4:
+        return "JI(`',`behaviour.altf4')";
+      case IDC_ALTSPACE:
+        return "JI(`',`behaviour.altspace')";
+      case IDC_ALTONLY:
+        return "JI(`',`behaviour.altonly')";
+      case IDC_ALWAYSONTOP:
+        return "JI(`',`behaviour.alwaysontop')";
+      case IDC_FULLSCREENONALTENTER:
+        return "JI(`',`behaviour.altenter')";
+
+      case IDC_CURSORSTATIC:
+      case IDC_CURBLOCK:
+      case IDC_CURUNDER:
+      case IDC_CURVERT:
+      case IDC_BLINKCUR:
+        return "JI(`',`appearance.cursor')";
+      case IDC_FONTSTATIC:
+      case IDC_CHOOSEFONT:
+        return "JI(`',`appearance.font')";
+      case IDC_WINTITLE:
+      case IDC_WINEDIT:
+      case IDC_WINNAME:
+        return "JI(`',`appearance.title')";
+      case IDC_HIDEMOUSE:
+        return "JI(`',`appearance.hidemouse')";
+      case IDC_SUNKENEDGE:
+      case IDC_WINBSTATIC:
+      case IDC_WINBEDIT:
+        return "JI(`',`appearance.border')";
+
+      case IDC_TTSTATIC:
+      case IDC_TTEDIT:
+        return "JI(`',`connection.termtype')";
+      case IDC_LOGSTATIC:
+      case IDC_LOGEDIT:
+        return "JI(`',`connection.username')";
+      case IDC_PINGSTATIC:
+      case IDC_PINGEDIT:
+        return "JI(`',`connection.keepalive')";
+      case IDC_NODELAY:
+        return "JI(`',`connection.nodelay')";
+
+      case IDC_PROXYTYPESTATIC:
+      case IDC_PROXYTYPENONE:
+      case IDC_PROXYTYPEHTTP:
+      case IDC_PROXYTYPESOCKS:
+      case IDC_PROXYTYPETELNET:
+        return "JI(`',`proxy.type')";
+      case IDC_PROXYHOSTSTATIC:
+      case IDC_PROXYHOSTEDIT:
+      case IDC_PROXYPORTSTATIC:
+      case IDC_PROXYPORTEDIT:
+        return "JI(`',`proxy.main')";
+      case IDC_PROXYEXCLUDESTATIC:
+      case IDC_PROXYEXCLUDEEDIT:
+        return "JI(`',`proxy.exclude')";
+      case IDC_PROXYUSERSTATIC:
+      case IDC_PROXYUSEREDIT:
+      case IDC_PROXYPASSSTATIC:
+      case IDC_PROXYPASSEDIT:
+        return "JI(`',`proxy.auth')";
+      case IDC_PROXYTELNETCMDSTATIC:
+      case IDC_PROXYTELNETCMDEDIT:
+        return "JI(`',`proxy.command')";
+      case IDC_PROXYSOCKSVERSTATIC:
+      case IDC_PROXYSOCKSVER5:
+      case IDC_PROXYSOCKSVER4:
+        return "JI(`',`proxy.socksver')";
+
+      case IDC_TSSTATIC:
+      case IDC_TSEDIT:
+        return "JI(`',`telnet.termspeed')";
+      case IDC_ENVSTATIC:
+      case IDC_VARSTATIC:
+      case IDC_VAREDIT:
+      case IDC_VALSTATIC:
+      case IDC_VALEDIT:
+      case IDC_ENVLIST:
+      case IDC_ENVADD:
+      case IDC_ENVREMOVE:
+        return "JI(`',`telnet.environ')";
+      case IDC_EMSTATIC:
+      case IDC_EMBSD:
+      case IDC_EMRFC:
+        return "JI(`',`telnet.oldenviron')";
+      case IDC_ACTSTATIC:
+      case IDC_TPASSIVE:
+      case IDC_TACTIVE:
+        return "JI(`',`telnet.passive')";
+      case IDC_TELNETKEY:
+        return "JI(`',`telnet.specialkeys')";
+      case IDC_TELNETRET:
+        return "JI(`',`telnet.newline')";
+
+      case IDC_R_TSSTATIC:
+      case IDC_R_TSEDIT:
+        return "JI(`',`rlogin.termspeed')";
+      case IDC_RLLUSERSTATIC:
+      case IDC_RLLUSEREDIT:
+        return "JI(`',`rlogin.localuser')";
+
+      case IDC_NOPTY:
+        return "JI(`',`ssh.nopty')";
+      case IDC_CIPHERSTATIC2:
+      case IDC_CIPHERLIST:
+      case IDC_CIPHERUP:
+      case IDC_CIPHERDN:
+      case IDC_SSH2DES:
+        return "JI(`',`ssh.ciphers')";
+      case IDC_SSHPROTSTATIC:
+      case IDC_SSHPROT1ONLY:
+      case IDC_SSHPROT1:
+      case IDC_SSHPROT2:
+      case IDC_SSHPROT2ONLY:
+        return "JI(`',`ssh.protocol')";
+      case IDC_CMDSTATIC:
+      case IDC_CMDEDIT:
+        return "JI(`',`ssh.command')";
+      case IDC_COMPRESS:
+        return "JI(`',`ssh.compress')";
+
+      case IDC_PKSTATIC:
+      case IDC_PKEDIT:
+      case IDC_PKBUTTON:
+        return "JI(`',`ssh.auth.privkey')";
+      case IDC_AGENTFWD:
+        return "JI(`',`ssh.auth.agentfwd')";
+      case IDC_CHANGEUSER:
+        return "JI(`',`ssh.auth.changeuser')";
+      case IDC_AUTHTIS:
+        return "JI(`',`ssh.auth.tis')";
+      case IDC_AUTHKI:
+        return "JI(`',`ssh.auth.ki')";
+
+      case IDC_MBSTATIC:
+      case IDC_MBWINDOWS:
+      case IDC_MBXTERM:
+        return "JI(`',`selection.buttons')";
+      case IDC_MOUSEOVERRIDE:
+        return "JI(`',`selection.shiftdrag')";
+      case IDC_SELTYPESTATIC:
+      case IDC_SELTYPELEX:
+      case IDC_SELTYPERECT:
+        return "JI(`',`selection.rect')";
+      case IDC_CCSTATIC:
+      case IDC_CCLIST:
+      case IDC_CCSET:
+      case IDC_CCSTATIC2:
+      case IDC_CCEDIT:
+        return "JI(`',`selection.charclasses')";
+      case IDC_RAWCNP:
+        return "JI(`',`selection.linedraw')";
+      case IDC_RTFPASTE:
+        return "JI(`',`selection.rtf')";
+
+      case IDC_BOLDCOLOUR:
+        return "JI(`',`colours.bold')";
+      case IDC_PALETTE:
+        return "JI(`',`colours.logpal')";
+      case IDC_COLOURSTATIC:
+      case IDC_COLOURLIST:
+      case IDC_RSTATIC:
+      case IDC_GSTATIC:
+      case IDC_BSTATIC:
+      case IDC_RVALUE:
+      case IDC_GVALUE:
+      case IDC_BVALUE:
+      case IDC_CHANGE:
+        return "JI(`',`colours.config')";
+
+      case IDC_CODEPAGESTATIC:
+      case IDC_CODEPAGE:
+        return "JI(`',`translation.codepage')";
+      case IDC_CAPSLOCKCYR:
+        return "JI(`',`translation.cyrillic')";
+      case IDC_VTSTATIC:
+      case IDC_VTXWINDOWS:
+      case IDC_VTOEMANSI:
+      case IDC_VTOEMONLY:
+      case IDC_VTPOORMAN:
+      case IDC_VTUNICODE:
+        return "JI(`',`translation.linedraw')";
+
+      case IDC_X11_FORWARD:
+      case IDC_X11_DISPSTATIC:
+      case IDC_X11_DISPLAY:
+        return "JI(`',`ssh.tunnels.x11')";
+      case IDC_PFWDSTATIC:
+      case IDC_PFWDSTATIC2:
+      case IDC_PFWDREMOVE:
+      case IDC_PFWDLIST:
+      case IDC_PFWDADD:
+      case IDC_SPORTSTATIC:
+      case IDC_SPORTEDIT:
+      case IDC_DPORTSTATIC:
+      case IDC_DPORTEDIT:
+      case IDC_PFWDLOCAL:
+      case IDC_PFWDREMOTE:
+        return "JI(`',`ssh.tunnels.portfwd')";
+      case IDC_LPORT_ALL:
+      case IDC_RPORT_ALL:
+        return "JI(`',`ssh.tunnels.portfwd.localhost')";
+
+      case IDC_BUGS_IGNORE1:
+      case IDC_BUGD_IGNORE1:
+       return "JI(`',`ssh.bugs.ignore1')";
+      case IDC_BUGS_PLAINPW1:
+      case IDC_BUGD_PLAINPW1:
+       return "JI(`',`ssh.bugs.plainpw1')";
+      case IDC_BUGS_RSA1:
+      case IDC_BUGD_RSA1:
+       return "JI(`',`ssh.bugs.rsa1')";
+      case IDC_BUGS_HMAC2:
+      case IDC_BUGD_HMAC2:
+       return "JI(`',`ssh.bugs.hmac2')";
+      case IDC_BUGS_DERIVEKEY2:
+      case IDC_BUGD_DERIVEKEY2:
+       return "JI(`',`ssh.bugs.derivekey2')";
+      case IDC_BUGS_RSAPAD2:
+      case IDC_BUGD_RSAPAD2:
+       return "JI(`',`ssh.bugs.rsapad2')";
+      case IDC_BUGS_DHGEX2:
+      case IDC_BUGD_DHGEX2:
+       return "JI(`',`ssh.bugs.dhgex2')";
+
+      default:
+        return NULL;
+    }
+}
+
 /* 2nd arg: NZ => don't redraw session list (use when loading
  * a new session) */
 static void init_dlg_ctrls(HWND hwnd, int keepsess)
@@ -604,6 +1080,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
                     cfg.protocol ==
                     PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
     SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
+    CheckDlgButton(hwnd, IDC_NODELAY, cfg.tcp_nodelay);
 
     CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
                     cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
@@ -618,6 +1095,12 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
                     cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
     CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
     CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
+    CheckDlgButton(hwnd, IDC_NOMOUSEREP, cfg.no_mouse_rep);
+    CheckDlgButton(hwnd, IDC_NORESIZE, cfg.no_remote_resize);
+    CheckDlgButton(hwnd, IDC_NOALTSCREEN, cfg.no_alt_screen);
+    CheckDlgButton(hwnd, IDC_NOWINTITLE, cfg.no_remote_wintitle);
+    CheckDlgButton(hwnd, IDC_NODBACKSPACE, cfg.no_dbackspace);
+    CheckDlgButton(hwnd, IDC_NOCHARSET, cfg.no_remote_charset);
     CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
                     cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
     CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
@@ -629,6 +1112,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
     CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
     CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
     CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard);
+    CheckDlgButton(hwnd, IDC_TELNETRET, cfg.telnet_newline);
     CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
                     cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
                     cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
@@ -680,9 +1164,10 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
     CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
     CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
     CheckDlgButton(hwnd, IDC_SCROLLBARFULLSCREEN, cfg.scrollbar_in_fullscreen);
-    CheckRadioButton(hwnd, IDC_RESIZETERM, IDC_RESIZENONE,
+    CheckRadioButton(hwnd, IDC_RESIZETERM, IDC_RESIZEEITHER,
                     cfg.resize_action == RESIZE_TERM ? IDC_RESIZETERM :
                     cfg.resize_action == RESIZE_FONT ? IDC_RESIZEFONT :
+                    cfg.resize_action == RESIZE_EITHER ? IDC_RESIZEEITHER :
                     IDC_RESIZENONE);
     CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
                     cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
@@ -696,9 +1181,11 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
     SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
     SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
     SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
-    CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
-                    cfg.logtype == 0 ? IDC_LSTATOFF :
-                    cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
+    CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATPACKET,
+                    cfg.logtype == LGTYP_NONE ? IDC_LSTATOFF :
+                    cfg.logtype == LGTYP_ASCII ? IDC_LSTATASCII :
+                    cfg.logtype == LGTYP_DEBUG ? IDC_LSTATRAW :
+                    IDC_LSTATPACKET);
     CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
                     cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
                     cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
@@ -727,11 +1214,15 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
     SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
     CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
     CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
-    CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
+    CheckDlgButton(hwnd, IDC_SSH2DES, cfg.ssh2_des_cbc);
     CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
-    CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
-                    cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
+    CheckDlgButton(hwnd, IDC_CHANGEUSER, cfg.change_username);
+    CheckRadioButton(hwnd, IDC_SSHPROT1ONLY, IDC_SSHPROT2ONLY,
+                    cfg.sshprot == 1 ? IDC_SSHPROT1 :
+                    cfg.sshprot == 2 ? IDC_SSHPROT2 :
+                    cfg.sshprot == 3 ? IDC_SSHPROT2ONLY : IDC_SSHPROT1ONLY);
     CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
+    CheckDlgButton(hwnd, IDC_AUTHKI, cfg.try_ki_auth);
     SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
     SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
 
@@ -740,7 +1231,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
        static const struct { char *s; int c; } ciphers[] = {
            { "3DES",                   CIPHER_3DES },
            { "Blowfish",               CIPHER_BLOWFISH },
-           { "DES (SSH 1 only)",       CIPHER_DES },
+           { "DES",                    CIPHER_DES },
            { "AES (SSH 2 only)",       CIPHER_AES },
            { "-- warn below here --",  CIPHER_WARN }
        };
@@ -772,6 +1263,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
                     cfg.rect_select == 0 ? IDC_SELTYPELEX : IDC_SELTYPERECT);
     CheckDlgButton(hwnd, IDC_MOUSEOVERRIDE, cfg.mouse_override);
     CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
+    CheckDlgButton(hwnd, IDC_RTFPASTE, cfg.rtf_paste);
     {
        static int tabs[4] = { 25, 61, 96, 128 };
        SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
@@ -815,7 +1307,24 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
        }
        SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
     }
-    
+
+    {
+       int i, nprinters;
+       printer_enum *pe;
+       pe = printer_start_enum(&nprinters);
+       SendDlgItemMessage(hwnd, IDC_PRINTER, CB_RESETCONTENT, 0, 0);
+       SendDlgItemMessage(hwnd, IDC_PRINTER, CB_ADDSTRING,
+                          0, (LPARAM) PRINTER_DISABLED_STRING);
+       for (i = 0; i < nprinters; i++) {
+           char *printer_name = printer_get_name(pe, i);
+           SendDlgItemMessage(hwnd, IDC_PRINTER, CB_ADDSTRING,
+                              0, (LPARAM) printer_name);
+       }
+       printer_finish_enum(pe);
+       SetDlgItemText(hwnd, IDC_PRINTER,
+                      *cfg.printer ? cfg.printer : PRINTER_DISABLED_STRING);
+    }
+
     CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
                     cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
                     cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
@@ -827,7 +1336,73 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
     SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
 
     CheckDlgButton(hwnd, IDC_LPORT_ALL, cfg.lport_acceptall);
+    CheckDlgButton(hwnd, IDC_RPORT_ALL, cfg.rport_acceptall);
     CheckRadioButton(hwnd, IDC_PFWDLOCAL, IDC_PFWDREMOTE, IDC_PFWDLOCAL);
+
+    /* proxy config */
+    CheckRadioButton(hwnd, IDC_PROXYTYPENONE, IDC_PROXYTYPETELNET,
+                    cfg.proxy_type == PROXY_HTTP ? IDC_PROXYTYPEHTTP :
+                    cfg.proxy_type == PROXY_SOCKS ? IDC_PROXYTYPESOCKS :
+                    cfg.proxy_type == PROXY_TELNET ? IDC_PROXYTYPETELNET : IDC_PROXYTYPENONE);
+    SetDlgItemText(hwnd, IDC_PROXYHOSTEDIT, cfg.proxy_host);
+    SetDlgItemInt(hwnd, IDC_PROXYPORTEDIT, cfg.proxy_port, FALSE);
+    SetDlgItemText(hwnd, IDC_PROXYEXCLUDEEDIT, cfg.proxy_exclude_list);
+    SetDlgItemText(hwnd, IDC_PROXYTELNETCMDEDIT, cfg.proxy_telnet_command);
+    SetDlgItemText(hwnd, IDC_PROXYUSEREDIT, cfg.proxy_username);
+    SetDlgItemText(hwnd, IDC_PROXYPASSEDIT, cfg.proxy_password);
+    CheckRadioButton(hwnd, IDC_PROXYSOCKSVER5, IDC_PROXYSOCKSVER4,
+                    cfg.proxy_socks_version == 4 ? IDC_PROXYSOCKSVER4 : IDC_PROXYSOCKSVER5);
+
+    /* SSH bugs config */
+    SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_RESETCONTENT, 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_ADDSTRING, 0, (LPARAM)"Auto");
+    SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_ADDSTRING, 0, (LPARAM)"Off");
+    SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_ADDSTRING, 0, (LPARAM)"On");
+    SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_SETCURSEL,
+                      cfg.sshbug_ignore1 == BUG_ON ? 2 :
+                      cfg.sshbug_ignore1 == BUG_OFF ? 1 : 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_RESETCONTENT, 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_ADDSTRING, 0, (LPARAM)"Auto");
+    SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_ADDSTRING, 0, (LPARAM)"Off");
+    SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_ADDSTRING, 0, (LPARAM)"On");
+    SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_SETCURSEL,
+                      cfg.sshbug_plainpw1 == BUG_ON ? 2 :
+                      cfg.sshbug_plainpw1 == BUG_OFF ? 1 : 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_RESETCONTENT, 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_ADDSTRING, 0, (LPARAM)"Auto");
+    SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_ADDSTRING, 0, (LPARAM)"Off");
+    SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_ADDSTRING, 0, (LPARAM)"On");
+    SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_SETCURSEL,
+                      cfg.sshbug_rsa1 == BUG_ON ? 2 :
+                      cfg.sshbug_rsa1 == BUG_OFF ? 1 : 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_RESETCONTENT, 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_ADDSTRING, 0, (LPARAM)"Auto");
+    SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_ADDSTRING, 0, (LPARAM)"Off");
+    SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_ADDSTRING, 0, (LPARAM)"On");
+    SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_SETCURSEL,
+                      cfg.sshbug_hmac2 == BUG_ON ? 2 :
+                      cfg.sshbug_hmac2 == BUG_OFF ? 1 : 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_RESETCONTENT, 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_ADDSTRING, 0, (LPARAM)"Auto");
+    SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_ADDSTRING, 0, (LPARAM)"Off");
+    SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_ADDSTRING, 0, (LPARAM)"On");
+    SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_SETCURSEL,
+                      cfg.sshbug_derivekey2 == BUG_ON ? 2 :
+                      cfg.sshbug_derivekey2 == BUG_OFF ? 1 : 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_RESETCONTENT, 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_ADDSTRING, 0, (LPARAM)"Auto");
+    SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_ADDSTRING, 0, (LPARAM)"Off");
+    SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_ADDSTRING, 0, (LPARAM)"On");
+    SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_SETCURSEL,
+                      cfg.sshbug_rsapad2 == BUG_ON ? 2 :
+                      cfg.sshbug_rsapad2 == BUG_OFF ? 1 : 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_RESETCONTENT, 0, 0);
+    SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_ADDSTRING, 0, (LPARAM)"Auto");
+    SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_ADDSTRING, 0, (LPARAM)"Off");
+    SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_ADDSTRING, 0, (LPARAM)"On");
+    SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_SETCURSEL,
+                      cfg.sshbug_dhgex2 == BUG_ON ? 2 :
+                      cfg.sshbug_dhgex2 == BUG_OFF ? 1 : 0, 0);
 }
 
 struct treeview_faff {
@@ -866,7 +1441,7 @@ static HTREEITEM treeview_insert(struct treeview_faff *faff,
 static void create_controls(HWND hwnd, int dlgtype, int panel)
 {
     if (panel == sessionpanelstart) {
-       /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
+       /* The Session panel. Accelerators used: [acgoh] nprtis elvd w */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        bartitle(&cp, "Basic options for your PuTTY session",
@@ -890,9 +1465,9 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
                          "&Telnet", IDC_PROTTELNET,
                          "Rlog&in", IDC_PROTRLOGIN,
 #ifdef FWHACK
-                         "SS&H/hack",
+                         "&SSH/hack",
 #else
-                         "SS&H",
+                         "&SSH",
 #endif
                          IDC_PROTSSH, NULL);
            }
@@ -902,7 +1477,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
            sesssaver(&cp, "Sav&ed Sessions",
                      IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
                      "&Load", IDC_SESSLOAD,
-                     "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
+                     "Sa&ve", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
            endbox(&cp);
        }
        beginbox(&cp, NULL, IDC_BOX_SESSION3);
@@ -914,7 +1489,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
     }
 
     if (panel == loggingpanelstart) {
-       /* The Logging panel. Accelerators used: [acgo] tplfwe */
+       /* The Logging panel. Accelerators used: [acgoh] tplsfwe */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        bartitle(&cp, "Options controlling session logging",
@@ -924,7 +1499,9 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
                 "Session logging:", IDC_LSTATSTATIC,
                 "Logging &turned off completely", IDC_LSTATOFF,
                 "Log &printable output only", IDC_LSTATASCII,
-                "&Log all session output", IDC_LSTATRAW, NULL);
+                "&Log all session output", IDC_LSTATRAW,
+                "Log &SSH packet data", IDC_LSTATPACKET,
+                NULL);
        editbutton(&cp, "Log &file name:",
                   IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
                   IDC_LGFBUTTON);
@@ -939,7 +1516,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
     }
 
     if (panel == terminalpanelstart) {
-       /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
+       /* The Terminal panel. Accelerators used: [acgoh] wdren lts p */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        bartitle(&cp, "Options controlling the terminal emulation",
@@ -947,7 +1524,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
        beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
        checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
        checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
-       checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
+       checkbox(&cp, "Implicit C&R in every LF", IDC_LFHASCR);
        checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
        checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
        multiedit(&cp,
@@ -956,17 +1533,45 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
        endbox(&cp);
 
        beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
-       radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
+       radioline(&cp, "&Local echo:", IDC_ECHOSTATIC, 3,
                  "Auto", IDC_ECHOBACKEND,
                  "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
        radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
                  "Auto", IDC_EDITBACKEND,
                  "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
        endbox(&cp);
+
+       beginbox(&cp, "Remote-controlled printing", IDC_BOX_TERMINAL3);
+       combobox(&cp, "&Printer to send ANSI printer output to:",
+                IDC_PRINTERSTATIC, IDC_PRINTER);
+       endbox(&cp);
+    }
+
+    if (panel == featurespanelstart) {
+       /* The Features panel. Accelerators used: [acgoh] ukswtbrx */
+       struct ctlpos cp;
+       ctlposinit(&cp, hwnd, 80, 3, 13);
+       bartitle(&cp, "Enabling and disabling advanced terminal features ",
+                IDC_TITLE_FEATURES);
+       beginbox(&cp, NULL, IDC_BOX_FEATURES1);
+       checkbox(&cp, "Disable application c&ursor keys mode", IDC_NOAPPLICC);
+       checkbox(&cp, "Disable application &keypad mode", IDC_NOAPPLICK);
+       checkbox(&cp, "Disable &xterm-style mouse reporting", IDC_NOMOUSEREP);
+       checkbox(&cp, "Disable remote-controlled terminal re&sizing",
+                IDC_NORESIZE);
+       checkbox(&cp, "Disable s&witching to alternate terminal screen",
+                IDC_NOALTSCREEN);
+       checkbox(&cp, "Disable remote-controlled window &title changing",
+                IDC_NOWINTITLE);
+       checkbox(&cp, "Disable destructive &backspace on server sending ^?",
+                IDC_NODBACKSPACE);
+       checkbox(&cp, "Disable remote-controlled cha&racter set configuration",
+                IDC_NOCHARSET);
+       endbox(&cp);
     }
 
     if (panel == bellpanelstart) {
-       /* The Bell panel. Accelerators used: [acgo] bdsm wit */
+       /* The Bell panel. Accelerators used: [acgoh] bdsm wit */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        bartitle(&cp, "Options controlling the terminal bell",
@@ -1003,18 +1608,16 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
     }
 
     if (panel == keyboardpanelstart) {
-       /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
+       /* The Keyboard panel. Accelerators used: [acgoh] bef rntd */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
-       /*
-          bartitle(&cp, "Options controlling the effects of keys",
-          IDC_TITLE_KEYBOARD);
-        */
+       bartitle(&cp, "Options controlling the effects of keys",
+                IDC_TITLE_KEYBOARD);
        beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
        radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
                  "Control-H", IDC_DEL008,
                  "Control-? (127)", IDC_DEL127, NULL);
-       radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
+       radioline(&cp, "The Home and &End keys", IDC_HOMESTATIC, 2,
                  "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
        radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
                  "ESC[n~", IDC_FUNCTILDE,
@@ -1024,15 +1627,9 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
                  "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
        endbox(&cp);
        beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
-       checkbox(&cp,
-                "Application c&ursor keys totally disabled",
-                IDC_NOAPPLICC);
        radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
                  "Normal", IDC_CURNORMAL,
                  "Application", IDC_CURAPPLIC, NULL);
-       checkbox(&cp,
-                "Application ke&ypad keys totally disabled",
-                IDC_NOAPPLICK);
        radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
                  3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
                  "NetHack", IDC_KPNH, NULL);
@@ -1046,7 +1643,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
     }
 
     if (panel == windowpanelstart) {
-       /* The Window panel. Accelerators used: [acgo] rmznb sdikp w4ylt f */
+       /* The Window panel. Accelerators used: [acgoh] rmz sdikp */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        bartitle(&cp, "Options controlling PuTTY's window",
@@ -1055,10 +1652,11 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
        multiedit(&cp,
                  "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
                  "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
-       radioline(&cp, "Action when the window is resized:", IDC_RESIZESTATIC,
-                 3, "Resi&ze terminal", IDC_RESIZETERM,
-                 "Change fo&nt", IDC_RESIZEFONT,
-                 "For&bid resizing", IDC_RESIZENONE, NULL);
+       radiobig(&cp, "When window is resi&zed:", IDC_RESIZESTATIC,
+                "Change the number of rows and columns", IDC_RESIZETERM,
+                "Change the size of the font", IDC_RESIZEFONT,
+                "Change font size only when maximised", IDC_RESIZEEITHER,
+                "Forbid resizing completely", IDC_RESIZENONE, NULL);
        endbox(&cp);
        beginbox(&cp, "Control the scrollback in the window",
                 IDC_BOX_WINDOW2);
@@ -1070,22 +1668,14 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
        checkbox(&cp, "Reset scrollback on dis&play activity",
                 IDC_SCROLLDISP);
        endbox(&cp);
-       beginbox(&cp, NULL, IDC_BOX_WINDOW3);
-       checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
-       checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
-       checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
-       checkbox(&cp, "System menu appears on A&LT alone", IDC_ALTONLY);
-       checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
-       checkbox(&cp, "&Full screen on Alt-Enter", IDC_FULLSCREENONALTENTER);
-       endbox(&cp);
     }
 
     if (panel == appearancepanelstart) {
-       /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
+       /* The Appearance panel. Accelerators used: [acgoh] luvb n ti p s */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
-       /* bartitle(&cp, "Options controlling PuTTY's appearance",
-                IDC_TITLE_APPEARANCE); */
+       bartitle(&cp, "Configure the appearance of PuTTY's window",
+                IDC_TITLE_APPEARANCE);
        beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
        radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
                  "B&lock", IDC_CURBLOCK,
@@ -1095,7 +1685,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
        endbox(&cp);
        beginbox(&cp, "Set the font used in the terminal window",
                 IDC_BOX_APPEARANCE2);
-       staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
+       staticbtn(&cp, "", IDC_FONTSTATIC, "Cha&nge...", IDC_CHOOSEFONT);
        endbox(&cp);
        beginbox(&cp, "Adjust the use of the window title",
                 IDC_BOX_APPEARANCE3);
@@ -1116,8 +1706,24 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
        endbox(&cp);
     }
 
+    if (panel == behaviourpanelstart) {
+       /* The Behaviour panel. Accelerators used: [acgoh] w4yltf */
+       struct ctlpos cp;
+       ctlposinit(&cp, hwnd, 80, 3, 13);
+       bartitle(&cp, "Configure the behaviour of PuTTY's window",
+                IDC_TITLE_WINDOW);
+       beginbox(&cp, NULL, IDC_BOX_BEHAVIOUR1);
+       checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
+       checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
+       checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
+       checkbox(&cp, "System menu appears on A&LT alone", IDC_ALTONLY);
+       checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
+       checkbox(&cp, "&Full screen on Alt-Enter", IDC_FULLSCREENONALTENTER);
+       endbox(&cp);
+    }
+
     if (panel == translationpanelstart) {
-       /* The Translation panel. Accelerators used: [acgo] rxbepus */
+       /* The Translation panel. Accelerators used: [acgoh] rxbepus */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        bartitle(&cp, "Options controlling character set translation",
@@ -1145,7 +1751,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
     }
 
     if (panel == selectionpanelstart) {
-       /* The Selection panel. Accelerators used: [acgo] d wxp hst nr */
+       /* The Selection panel. Accelerators used: [acgoh] df wxp est nr */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        bartitle(&cp, "Options controlling copy and paste",
@@ -1155,6 +1761,9 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
        checkbox(&cp,
                 "&Don't translate line drawing chars into +, - and |",
                 IDC_RAWCNP);
+       checkbox(&cp,
+                "Paste to clipboard in RT&F as well as plain text",
+                IDC_RTFPASTE);
        endbox(&cp);
        beginbox(&cp, "Control which mouse button does which thing",
                 IDC_BOX_SELECTION2);
@@ -1173,14 +1782,14 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
        endbox(&cp);
        beginbox(&cp, "Control the select-one-word-at-a-time mode",
                 IDC_BOX_SELECTION3);
-       charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
+       charclass(&cp, "Charact&er classes:", IDC_CCSTATIC, IDC_CCLIST,
                  "&Set", IDC_CCSET, IDC_CCEDIT,
                  "&to class", IDC_CCSTATIC2);
        endbox(&cp);
     }
 
     if (panel == colourspanelstart) {
-       /* The Colours panel. Accelerators used: [acgo] blum */
+       /* The Colours panel. Accelerators used: [acgoh] blum */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        bartitle(&cp, "Options controlling use of colours",
@@ -1203,7 +1812,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
     }
 
     if (panel == connectionpanelstart) {
-       /* The Connection panel. Accelerators used: [acgo] tuk */
+       /* The Connection panel. Accelerators used: [acgoh] tukn */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        bartitle(&cp, "Options controlling the connection",
@@ -1220,6 +1829,8 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
            beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
            checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
                     IDC_TELNETKEY);
+           checkbox(&cp, "Return key sends telnet New Line instead of ^M",
+                    IDC_TELNETRET);
            endbox(&cp);
        }
        beginbox(&cp, "Sending of null packets to keep session active",
@@ -1227,10 +1838,52 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
        staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
                   IDC_PINGSTATIC, IDC_PINGEDIT, 20);
        endbox(&cp);
+       if (dlgtype == 0) {
+           beginbox(&cp, "Low-level TCP connection options",
+                    IDC_BOX_CONNECTION3);
+           checkbox(&cp, "Disable &Nagle's algorithm (TCP_NODELAY option)",
+                    IDC_NODELAY);
+           endbox(&cp);
+       }
+    }
+
+    if (panel == proxypanelstart) {
+       /* The Proxy panel. Accelerators used: [acgoh] ntslypeuwmv */
+       struct ctlpos cp;
+       ctlposinit(&cp, hwnd, 80, 3, 13);
+       if (dlgtype == 0) {
+           bartitle(&cp, "Options controlling proxy usage",
+                    IDC_TITLE_PROXY);
+           beginbox(&cp, "Proxy basics", IDC_BOX_PROXY1);
+           radioline(&cp, "Proxy type:", IDC_PROXYTYPESTATIC, 4,
+                     "&None", IDC_PROXYTYPENONE,
+                     "H&TTP", IDC_PROXYTYPEHTTP,
+                     "&SOCKS", IDC_PROXYTYPESOCKS,
+                     "Te&lnet", IDC_PROXYTYPETELNET, NULL);
+           multiedit(&cp,
+                     "Prox&y Host", IDC_PROXYHOSTSTATIC, IDC_PROXYHOSTEDIT, 80,
+                     "&Port", IDC_PROXYPORTSTATIC, IDC_PROXYPORTEDIT, 20, NULL);
+           multiedit(&cp,
+                     "&Exclude Hosts/IPs", IDC_PROXYEXCLUDESTATIC,
+                     IDC_PROXYEXCLUDEEDIT, 100, NULL);
+           staticedit(&cp, "&Username", IDC_PROXYUSERSTATIC,
+                      IDC_PROXYUSEREDIT, 60);
+           staticpassedit(&cp, "Pass&word", IDC_PROXYPASSSTATIC,
+                          IDC_PROXYPASSEDIT, 60);
+           endbox(&cp);
+           beginbox(&cp, "Misc. proxy settings", IDC_BOX_PROXY2);
+           multiedit(&cp,
+                     "Telnet co&mmand", IDC_PROXYTELNETCMDSTATIC,
+                     IDC_PROXYTELNETCMDEDIT, 100, NULL);
+           radioline(&cp, "SOCKS &Version", IDC_PROXYSOCKSVERSTATIC,
+                     2, "Version 5", IDC_PROXYSOCKSVER5, "Version 4",
+                     IDC_PROXYSOCKSVER4, NULL);
+           endbox(&cp);
+       }
     }
 
     if (panel == telnetpanelstart) {
-       /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
+       /* The Telnet panel. Accelerators used: [acgoh] svldr bftk */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        if (dlgtype == 0) {
@@ -1253,12 +1906,14 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
                      IDC_TACTIVE, NULL);
            checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
                     IDC_TELNETKEY);
+           checkbox(&cp, "Return key sends telnet New Line instead of ^M",
+                    IDC_TELNETRET);
            endbox(&cp);
        }
     }
 
     if (panel == rloginpanelstart) {
-       /* The Rlogin panel. Accelerators used: [acgo] sl */
+       /* The Rlogin panel. Accelerators used: [acgoh] sl */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        if (dlgtype == 0) {
@@ -1274,7 +1929,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
     }
 
     if (panel == sshpanelstart) {
-       /* The SSH panel. Accelerators used: [acgo] r pe12i s */
+       /* The SSH panel. Accelerators used: [acgoh] r pe12ni sd */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        if (dlgtype == 0) {
@@ -1289,21 +1944,23 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
            checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
            checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
            radioline(&cp, "Preferred SSH protocol version:",
-                     IDC_SSHPROTSTATIC, 2,
-                     "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
-           checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
-                    IDC_BUGGYMAC);
+                     IDC_SSHPROTSTATIC, 4,
+                     "1 on&ly", IDC_SSHPROT1ONLY,
+                     "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2,
+                     "2 o&nly", IDC_SSHPROT2ONLY, NULL);
            endbox(&cp);
            beginbox(&cp, "Encryption options", IDC_BOX_SSH3);
            prefslist(&cipherlist, &cp, "Encryption cipher &selection policy:",
                      IDC_CIPHERSTATIC2, IDC_CIPHERLIST, IDC_CIPHERUP,
                      IDC_CIPHERDN);
+           checkbox(&cp, "Enable non-standard use of single-&DES in SSH 2",
+                    IDC_SSH2DES);
            endbox(&cp);
        }
     }
 
     if (panel == sshauthpanelstart) {
-       /* The SSH authentication panel. Accelerators used: [acgo] m fkw */
+       /* The SSH authentication panel. Accelerators used: [acgoh] m fkiuw */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        if (dlgtype == 0) {
@@ -1311,12 +1968,16 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
                     IDC_TITLE_SSHAUTH);
            beginbox(&cp, "Authentication methods",
                     IDC_BOX_SSHAUTH1);
-           checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
+           checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication (SSH1)",
                     IDC_AUTHTIS);
+           checkbox(&cp, "Attempt \"keyboard-&interactive\" authentication"
+                    " (SSH2)", IDC_AUTHKI);
            endbox(&cp);
            beginbox(&cp, "Authentication parameters",
                     IDC_BOX_SSHAUTH2);
            checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
+           checkbox(&cp, "Allow attempted changes of &username in SSH2",
+                    IDC_CHANGEUSER);
            editbutton(&cp, "Private &key file for authentication:",
                       IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
                       IDC_PKBUTTON);
@@ -1324,8 +1985,35 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
        }
     }
 
+    if (panel == sshbugspanelstart) {
+       /* The SSH bugs panel. Accelerators used: [acgoh] isrmep */
+       struct ctlpos cp;
+       ctlposinit(&cp, hwnd, 80, 3, 13);
+       if (dlgtype == 0) {
+           bartitle(&cp, "Workarounds for SSH server bugs",
+                    IDC_TITLE_SSHBUGS);
+           beginbox(&cp, "Detection of known bugs in SSH servers",
+                    IDC_BOX_SSHBUGS1);
+           staticddl(&cp, "Chokes on SSH1 &ignore messages",
+                     IDC_BUGS_IGNORE1, IDC_BUGD_IGNORE1, 20);
+           staticddl(&cp, "Refuses all SSH1 pa&ssword camouflage",
+                     IDC_BUGS_PLAINPW1, IDC_BUGD_PLAINPW1, 20);
+           staticddl(&cp, "Chokes on SSH1 &RSA authentication",
+                     IDC_BUGS_RSA1, IDC_BUGD_RSA1, 20);
+           staticddl(&cp, "Miscomputes SSH2 H&MAC keys",
+                     IDC_BUGS_HMAC2, IDC_BUGD_HMAC2, 20);
+           staticddl(&cp, "Miscomputes SSH2 &encryption keys",
+                     IDC_BUGS_DERIVEKEY2, IDC_BUGD_DERIVEKEY2, 20);
+           staticddl(&cp, "Requires &padding on SSH2 RSA signatures",
+                     IDC_BUGS_RSAPAD2, IDC_BUGD_RSAPAD2, 20);
+           staticddl(&cp, "Chokes on &Diffie-Hellman group exchange",
+                     IDC_BUGS_DHGEX2, IDC_BUGD_DHGEX2, 20);
+           endbox(&cp);
+       }
+    }
+
     if (panel == tunnelspanelstart) {
-       /* The Tunnels panel. Accelerators used: [acgo] deilmrstx */
+       /* The Tunnels panel. Accelerators used: [acgoh] deilmrstxp */
        struct ctlpos cp;
        ctlposinit(&cp, hwnd, 80, 3, 13);
        if (dlgtype == 0) {
@@ -1337,7 +2025,10 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
                      IDC_X11_DISPLAY, 50, NULL);
            endbox(&cp);
            beginbox(&cp, "Port forwarding", IDC_BOX_TUNNELS2);
-           checkbox(&cp, "Local ports accept connections from o&ther hosts", IDC_LPORT_ALL);
+           checkbox(&cp, "Local ports accept connections from o&ther hosts",
+                    IDC_LPORT_ALL);
+           checkbox(&cp, "Remote &ports do the same (SSH v2 only)",
+                    IDC_RPORT_ALL);
            staticbtn(&cp, "Forwarded ports:", IDC_PFWDSTATIC,
                      "&Remove", IDC_PFWDREMOVE);
            fwdsetter(&cp, IDC_PFWDLIST,
@@ -1346,7 +2037,8 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
                      "Dest&ination", IDC_DPORTSTATIC, IDC_DPORTEDIT,
                      "A&dd", IDC_PFWDADD);
            bareradioline(&cp, 2,
-                         "&Local", IDC_PFWDLOCAL, "Re&mote", IDC_PFWDREMOTE, NULL);
+                         "&Local", IDC_PFWDLOCAL,
+                         "Re&mote", IDC_PFWDREMOTE, NULL);
            endbox(&cp);
 
        }
@@ -1403,6 +2095,15 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
       case WM_INITDIALOG:
        readytogo = 0;
        SetWindowLong(hwnd, GWL_USERDATA, 0);
+        if (help_path)
+            SetWindowLong(hwnd, GWL_EXSTYLE,
+                          GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
+        else {
+            HWND item = GetDlgItem(hwnd, IDC_HELPBTN);
+            if (item)
+                DestroyWindow(item);
+        }
+        requested_help = FALSE;
        SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
                    (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
        /*
@@ -1469,13 +2170,16 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
        treeview_insert(&tvfaff, 0, "Terminal");
        treeview_insert(&tvfaff, 1, "Keyboard");
        treeview_insert(&tvfaff, 1, "Bell");
+       treeview_insert(&tvfaff, 1, "Features");
        treeview_insert(&tvfaff, 0, "Window");
        treeview_insert(&tvfaff, 1, "Appearance");
+       treeview_insert(&tvfaff, 1, "Behaviour");
        treeview_insert(&tvfaff, 1, "Translation");
        treeview_insert(&tvfaff, 1, "Selection");
        treeview_insert(&tvfaff, 1, "Colours");
        treeview_insert(&tvfaff, 0, "Connection");
        if (dlgtype == 0) {
+           treeview_insert(&tvfaff, 1, "Proxy");
            treeview_insert(&tvfaff, 1, "Telnet");
            treeview_insert(&tvfaff, 1, "Rlogin");
            if (backends[3].backend != NULL) {
@@ -1484,6 +2188,7 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                /* XXX make it closed by default? */
                treeview_insert(&tvfaff, 2, "Auth");
                treeview_insert(&tvfaff, 2, "Tunnels");
+               treeview_insert(&tvfaff, 2, "Bugs");
            }
        }
 
@@ -1547,14 +2252,20 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                create_controls(hwnd, dlgtype, terminalpanelstart);
            if (!strcmp(buffer, "Bell"))
                create_controls(hwnd, dlgtype, bellpanelstart);
+           if (!strcmp(buffer, "Features"))
+               create_controls(hwnd, dlgtype, featurespanelstart);
            if (!strcmp(buffer, "Window"))
                create_controls(hwnd, dlgtype, windowpanelstart);
            if (!strcmp(buffer, "Appearance"))
                create_controls(hwnd, dlgtype, appearancepanelstart);
+           if (!strcmp(buffer, "Behaviour"))
+               create_controls(hwnd, dlgtype, behaviourpanelstart);
            if (!strcmp(buffer, "Tunnels"))
                create_controls(hwnd, dlgtype, tunnelspanelstart);
            if (!strcmp(buffer, "Connection"))
                create_controls(hwnd, dlgtype, connectionpanelstart);
+           if (!strcmp(buffer, "Proxy"))
+               create_controls(hwnd, dlgtype, proxypanelstart);
            if (!strcmp(buffer, "Telnet"))
                create_controls(hwnd, dlgtype, telnetpanelstart);
            if (!strcmp(buffer, "Rlogin"))
@@ -1563,6 +2274,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                create_controls(hwnd, dlgtype, sshpanelstart);
            if (!strcmp(buffer, "Auth"))
                create_controls(hwnd, dlgtype, sshauthpanelstart);
+           if (!strcmp(buffer, "Bugs"))
+               create_controls(hwnd, dlgtype, sshbugspanelstart);
            if (!strcmp(buffer, "Selection"))
                create_controls(hwnd, dlgtype, selectionpanelstart);
            if (!strcmp(buffer, "Colours"))
@@ -1596,12 +2309,31 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                    }
                }
                /* If at this point we have a valid session, go! */
-               if (*cfg.host)
+               if (*cfg.host) {
+                    if (requested_help) {
+                        WinHelp(hwnd, help_path, HELP_QUIT, 0);
+                        requested_help = FALSE;
+                    }
                    EndDialog(hwnd, 1);
-               else
+                } else
                    MessageBeep(0);
                return 0;
+             case IDC_HELPBTN:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED) {
+                    if (help_path) {
+                        WinHelp(hwnd, help_path,
+                                help_has_contents ? HELP_FINDER : HELP_CONTENTS,
+                                0);
+                        requested_help = TRUE;
+                    }
+                }
+                break;
              case IDCANCEL:
+                if (requested_help) {
+                    WinHelp(hwnd, help_path, HELP_QUIT, 0);
+                    requested_help = FALSE;
+                }
                EndDialog(hwnd, 0);
                return 0;
              case IDC_PROTTELNET:
@@ -1616,10 +2348,22 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                    cfg.protocol =
                        i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
                        PROT_RAW;
-                   if ((cfg.protocol == PROT_SSH && cfg.port != 22)
-                       || (cfg.protocol == PROT_TELNET && cfg.port != 23)
-                       || (cfg.protocol == PROT_RLOGIN
-                           && cfg.port != 513)) {
+                   /*
+                    * When switching using the arrow keys, we
+                    * appear to get two of these messages, both
+                    * mentioning the target button in
+                    * LOWORD(wParam), but one of them called while
+                    * the previous button is still checked. This
+                    * causes an unnecessary reset of the port
+                    * number field, which we fix by ensuring here
+                    * that the button selected is indeed the one
+                    * checked.
+                    */
+                   if (IsDlgButtonChecked(hwnd, LOWORD(wParam)) &&
+                       ((cfg.protocol == PROT_SSH && cfg.port != 22)
+                        || (cfg.protocol == PROT_TELNET && cfg.port != 23)
+                        || (cfg.protocol == PROT_RLOGIN
+                            && cfg.port != 513))) {
                        cfg.port = i ? 22 : j ? 23 : 513;
                        SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
                    }
@@ -1751,6 +2495,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                    MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
                                    &cfg.ping_interval);
                break;
+             case IDC_NODELAY:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                       cfg.tcp_nodelay =
+                       IsDlgButtonChecked(hwnd, IDC_NODELAY);
+               break;
              case IDC_DEL008:
              case IDC_DEL127:
                if (HIWORD(wParam) == BN_CLICKED ||
@@ -1829,6 +2579,42 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                        cfg.no_applic_k =
                        IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
                break;
+             case IDC_NOMOUSEREP:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                       cfg.no_mouse_rep =
+                       IsDlgButtonChecked(hwnd, IDC_NOMOUSEREP);
+               break;
+             case IDC_NORESIZE:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                       cfg.no_remote_resize =
+                       IsDlgButtonChecked(hwnd, IDC_NORESIZE);
+               break;
+             case IDC_NOALTSCREEN:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                       cfg.no_alt_screen =
+                       IsDlgButtonChecked(hwnd, IDC_NOALTSCREEN);
+               break;
+             case IDC_NOWINTITLE:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                       cfg.no_remote_wintitle =
+                       IsDlgButtonChecked(hwnd, IDC_NOWINTITLE);
+               break;
+             case IDC_NODBACKSPACE:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                       cfg.no_dbackspace =
+                       IsDlgButtonChecked(hwnd, IDC_NODBACKSPACE);
+               break;
+             case IDC_NOCHARSET:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                       cfg.no_remote_charset =
+                       IsDlgButtonChecked(hwnd, IDC_NOCHARSET);
+               break;
              case IDC_ALTF4:
                if (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DOUBLECLICKED)
@@ -1919,6 +2705,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                        cfg.telnet_keyboard =
                        IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
                break;
+             case IDC_TELNETRET:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                       cfg.telnet_newline =
+                       IsDlgButtonChecked(hwnd, IDC_TELNETRET);
+               break;
              case IDC_WRAPMODE:
                if (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DOUBLECLICKED)
@@ -2135,6 +2927,7 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
              case IDC_RESIZETERM:
              case IDC_RESIZEFONT:
              case IDC_RESIZENONE:
+             case IDC_RESIZEEITHER:
                if (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DOUBLECLICKED) {
                    cfg.resize_action =
@@ -2142,6 +2935,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                                           IDC_RESIZETERM) ? RESIZE_TERM :
                        IsDlgButtonChecked(hwnd,
                                           IDC_RESIZEFONT) ? RESIZE_FONT :
+                       IsDlgButtonChecked(hwnd,
+                                          IDC_RESIZEEITHER) ? RESIZE_EITHER :
                        RESIZE_DISABLED;
                }
                break;
@@ -2174,6 +2969,73 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                    GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
                                   sizeof(cfg.termtype) - 1);
                break;
+
+               /* proxy config */
+             case IDC_PROXYHOSTEDIT:
+               if (HIWORD(wParam) == EN_CHANGE)
+                   GetDlgItemText(hwnd, IDC_PROXYHOSTEDIT, cfg.proxy_host, 
+                                  sizeof(cfg.proxy_host) - 1);
+               break;
+             case IDC_PROXYPORTEDIT:
+               if (HIWORD(wParam) == EN_CHANGE) {
+                   GetDlgItemText(hwnd, IDC_PROXYPORTEDIT, portname, 31);
+                   if (isdigit(portname[0]))
+                       MyGetDlgItemInt(hwnd, IDC_PROXYPORTEDIT, &cfg.proxy_port);
+                   else {
+                       service = getservbyname(portname, NULL);
+                       if (service)
+                           cfg.proxy_port = ntohs(service->s_port);
+                       else
+                           cfg.proxy_port = 0;
+                   }
+               }
+               break;
+             case IDC_PROXYEXCLUDEEDIT:
+               if (HIWORD(wParam) == EN_CHANGE)
+                   GetDlgItemText(hwnd, IDC_PROXYEXCLUDEEDIT,
+                                  cfg.proxy_exclude_list,
+                                  sizeof(cfg.proxy_exclude_list) - 1);
+               break;
+             case IDC_PROXYUSEREDIT:
+               if (HIWORD(wParam) == EN_CHANGE)
+                   GetDlgItemText(hwnd, IDC_PROXYUSEREDIT,
+                                  cfg.proxy_username, 
+                                  sizeof(cfg.proxy_username) - 1);
+               break;
+             case IDC_PROXYPASSEDIT:
+               if (HIWORD(wParam) == EN_CHANGE)
+                   GetDlgItemText(hwnd, IDC_PROXYPASSEDIT,
+                                  cfg.proxy_password, 
+                                  sizeof(cfg.proxy_password) - 1);
+               break;
+             case IDC_PROXYTELNETCMDEDIT:
+               if (HIWORD(wParam) == EN_CHANGE)
+                   GetDlgItemText(hwnd, IDC_PROXYTELNETCMDEDIT,
+                                  cfg.proxy_telnet_command,
+                                  sizeof(cfg.proxy_telnet_command) - 1);
+               break;
+             case IDC_PROXYSOCKSVER5:
+             case IDC_PROXYSOCKSVER4:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED) {
+                   cfg.proxy_socks_version =
+                       IsDlgButtonChecked(hwnd, IDC_PROXYSOCKSVER4) ? 4 : 5;
+               }
+               break;
+             case IDC_PROXYTYPENONE:
+             case IDC_PROXYTYPEHTTP:
+             case IDC_PROXYTYPESOCKS:
+             case IDC_PROXYTYPETELNET:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED) {
+                   cfg.proxy_type =
+                       IsDlgButtonChecked(hwnd, IDC_PROXYTYPEHTTP) ? PROXY_HTTP :
+                       IsDlgButtonChecked(hwnd, IDC_PROXYTYPESOCKS) ? PROXY_SOCKS :
+                       IsDlgButtonChecked(hwnd, IDC_PROXYTYPETELNET) ? PROXY_TELNET :
+                       PROXY_NONE;
+               }
+               break;
+
              case IDC_LGFEDIT:
                if (HIWORD(wParam) == EN_CHANGE)
                    GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
@@ -2205,14 +3067,17 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
              case IDC_LSTATOFF:
              case IDC_LSTATASCII:
              case IDC_LSTATRAW:
+             case IDC_LSTATPACKET:
                if (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DOUBLECLICKED) {
                    if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
-                       cfg.logtype = 0;
+                       cfg.logtype = LGTYP_NONE;
                    if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
-                       cfg.logtype = 1;
+                       cfg.logtype = LGTYP_ASCII;
                    if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
-                       cfg.logtype = 2;
+                       cfg.logtype = LGTYP_DEBUG;
+                   if (IsDlgButtonChecked(hwnd, IDC_LSTATPACKET))
+                       cfg.logtype = LGTYP_PACKETS;
                }
                break;
              case IDC_LSTATXASK:
@@ -2341,11 +3206,11 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                        cfg.compression =
                        IsDlgButtonChecked(hwnd, IDC_COMPRESS);
                break;
-             case IDC_BUGGYMAC:
+             case IDC_SSH2DES:
                if (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.buggymac =
-                       IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
+                       cfg.ssh2_des_cbc =
+                       IsDlgButtonChecked(hwnd, IDC_SSH2DES);
                break;
              case IDC_AGENTFWD:
                if (HIWORD(wParam) == BN_CLICKED ||
@@ -2353,6 +3218,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                        cfg.agentfwd =
                        IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
                break;
+             case IDC_CHANGEUSER:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                       cfg.change_username =
+                       IsDlgButtonChecked(hwnd, IDC_CHANGEUSER);
+               break;
              case IDC_CIPHERLIST:
              case IDC_CIPHERUP:
              case IDC_CIPHERDN:
@@ -2360,14 +3231,20 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                                 cfg.ssh_cipherlist, CIPHER_MAX,
                                 0, hwnd, wParam, lParam);
                break;
+             case IDC_SSHPROT1ONLY:
              case IDC_SSHPROT1:
              case IDC_SSHPROT2:
+             case IDC_SSHPROT2ONLY:
                if (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DOUBLECLICKED) {
+                   if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1ONLY))
+                       cfg.sshprot = 0;
                    if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
                        cfg.sshprot = 1;
                    else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
                        cfg.sshprot = 2;
+                   else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2ONLY))
+                       cfg.sshprot = 3;
                }
                break;
              case IDC_AUTHTIS:
@@ -2376,6 +3253,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                        cfg.try_tis_auth =
                        IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
                break;
+             case IDC_AUTHKI:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                       cfg.try_ki_auth =
+                       IsDlgButtonChecked(hwnd, IDC_AUTHKI);
+               break;
              case IDC_PKEDIT:
                if (HIWORD(wParam) == EN_CHANGE)
                    GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
@@ -2394,7 +3277,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                of.lStructSize = sizeof(of);
 #endif
                of.hwndOwner = hwnd;
-               of.lpstrFilter = "All Files\0*\0\0\0";
+               of.lpstrFilter = "PuTTY Private Key Files\0*.PPK\0"
+                   "AllFiles\0*\0\0\0";
                of.lpstrCustomFilter = NULL;
                of.nFilterIndex = 1;
                of.lpstrFile = filename;
@@ -2412,6 +3296,9 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
              case IDC_RAWCNP:
                cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
                break;
+             case IDC_RTFPASTE:
+               cfg.rtf_paste = IsDlgButtonChecked(hwnd, IDC_RTFPASTE);
+               break;
              case IDC_MBWINDOWS:
              case IDC_MBXTERM:
                cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
@@ -2549,6 +3436,19 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                    SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
                }
                break;
+             case IDC_PRINTER:
+               if (HIWORD(wParam) == CBN_SELCHANGE) {
+                   int index = SendDlgItemMessage(hwnd, IDC_PRINTER,
+                                                  CB_GETCURSEL, 0, 0);
+                   SendDlgItemMessage(hwnd, IDC_PRINTER, CB_GETLBTEXT,
+                                      index, (LPARAM)cfg.printer);
+               } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
+                   GetDlgItemText(hwnd, IDC_PRINTER, cfg.printer,
+                                  sizeof(cfg.printer) - 1);
+               }
+               if (!strcmp(cfg.printer, PRINTER_DISABLED_STRING))
+                   *cfg.printer = '\0';
+               break;
              case IDC_CAPSLOCKCYR:
                if (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DOUBLECLICKED) {
@@ -2574,14 +3474,20 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
              case IDC_X11_FORWARD:
                if (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.x11_forward =
-                       IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
+                   cfg.x11_forward =
+                   IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
                break;
              case IDC_LPORT_ALL:
                if (HIWORD(wParam) == BN_CLICKED ||
                    HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.lport_acceptall =
-                       IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
+                   cfg.lport_acceptall =
+                   IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
+               break;
+             case IDC_RPORT_ALL:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                   cfg.rport_acceptall =
+                   IsDlgButtonChecked(hwnd, IDC_RPORT_ALL);
                break;
              case IDC_X11_DISPLAY:
                if (HIWORD(wParam) == EN_CHANGE)
@@ -2672,9 +3578,81 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                  disaster2:;
                }
                break;
+             case IDC_BUGD_IGNORE1:
+               if (HIWORD(wParam) == CBN_SELCHANGE) {
+                   int index = SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1,
+                                                  CB_GETCURSEL, 0, 0);
+                   cfg.sshbug_ignore1 = (index == 0 ? BUG_AUTO :
+                                         index == 1 ? BUG_OFF : BUG_ON);
+               }
+               break;
+             case IDC_BUGD_PLAINPW1:
+               if (HIWORD(wParam) == CBN_SELCHANGE) {
+                   int index = SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1,
+                                                  CB_GETCURSEL, 0, 0);
+                   cfg.sshbug_plainpw1 = (index == 0 ? BUG_AUTO :
+                                          index == 1 ? BUG_OFF : BUG_ON);
+               }
+               break;
+             case IDC_BUGD_RSA1:
+               if (HIWORD(wParam) == CBN_SELCHANGE) {
+                   int index = SendDlgItemMessage(hwnd, IDC_BUGD_RSA1,
+                                                  CB_GETCURSEL, 0, 0);
+                   cfg.sshbug_rsa1 = (index == 0 ? BUG_AUTO :
+                                      index == 1 ? BUG_OFF : BUG_ON);
+               }
+               break;
+             case IDC_BUGD_HMAC2:
+               if (HIWORD(wParam) == CBN_SELCHANGE) {
+                   int index = SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2,
+                                                  CB_GETCURSEL, 0, 0);
+                   cfg.sshbug_hmac2 = (index == 0 ? BUG_AUTO :
+                                       index == 1 ? BUG_OFF : BUG_ON);
+               }
+               break;
+             case IDC_BUGD_DERIVEKEY2:
+               if (HIWORD(wParam) == CBN_SELCHANGE) {
+                   int index = SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2,
+                                                  CB_GETCURSEL, 0, 0);
+                   cfg.sshbug_derivekey2 = (index == 0 ? BUG_AUTO :
+                                            index == 1 ? BUG_OFF : BUG_ON);
+               }
+               break;
+             case IDC_BUGD_RSAPAD2:
+               if (HIWORD(wParam) == CBN_SELCHANGE) {
+                   int index = SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2,
+                                                  CB_GETCURSEL, 0, 0);
+                   cfg.sshbug_rsapad2 = (index == 0 ? BUG_AUTO :
+                                         index == 1 ? BUG_OFF : BUG_ON);
+               }
+               break;
+             case IDC_BUGD_DHGEX2:
+               if (HIWORD(wParam) == CBN_SELCHANGE) {
+                   int index = SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2,
+                                                  CB_GETCURSEL, 0, 0);
+                   cfg.sshbug_dhgex2 = (index == 0 ? BUG_AUTO :
+                                        index == 1 ? BUG_OFF : BUG_ON);
+               }
+               break;
            }
        return 0;
+      case WM_HELP:
+        if (help_path) {
+            int id = ((LPHELPINFO)lParam)->iCtrlId;
+            char *cmd = help_context_cmd(id);
+            if (cmd) {
+                WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
+                requested_help = TRUE;
+            } else {
+                MessageBeep(0);
+            }
+        }
+        break;
       case WM_CLOSE:
+        if (requested_help) {
+            WinHelp(hwnd, help_path, HELP_QUIT, 0);
+            requested_help = FALSE;
+        }
        EndDialog(hwnd, 0);
        return 0;
 
@@ -2771,11 +3749,13 @@ int do_reconfig(HWND hwnd)
     return ret;
 }
 
-void logevent(char *string)
+void logevent(void *frontend, char *string)
 {
     char timebuf[40];
     time_t t;
 
+    log_eventlog(logctx, string);
+
     if (nevents >= negsize) {
        negsize += 64;
        events = srealloc(events, negsize * sizeof(*events));
@@ -2813,7 +3793,7 @@ void showabout(HWND hwnd)
     DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
 }
 
-void verify_ssh_host_key(char *host, int port, char *keytype,
+void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
                         char *keystr, char *fingerprint)
 {
     int ret;
@@ -2870,7 +3850,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
        if (mbret == IDYES)
            store_host_key(host, port, keytype, keystr);
        if (mbret == IDCANCEL)
-           exit(0);
+           cleanup_exit(0);
     }
     if (ret == 1) {                   /* key was absent */
        int mbret;
@@ -2880,7 +3860,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
        if (mbret == IDYES)
            store_host_key(host, port, keytype, keystr);
        if (mbret == IDCANCEL)
-           exit(0);
+           cleanup_exit(0);
     }
 }
 
@@ -2889,7 +3869,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
  * below the configured 'warn' threshold).
  * cs: 0 = both ways, 1 = client->server, 2 = server->client
  */
-void askcipher(char *ciphername, int cs)
+void askcipher(void *frontend, char *ciphername, int cs)
 {
     static const char mbtitle[] = "PuTTY Security Alert";
     static const char msg[] =
@@ -2911,14 +3891,14 @@ void askcipher(char *ciphername, int cs)
     if (mbret == IDYES)
        return;
     else
-       exit(0);
+       cleanup_exit(0);
 }
 
 /*
  * Ask whether to wipe a session log file before writing to it.
  * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
  */
-int askappend(char *filename)
+int askappend(void *frontend, char *filename)
 {
     static const char mbtitle[] = "PuTTY Log to File";
     static const char msgtemplate[] =
@@ -2944,3 +3924,30 @@ int askappend(char *filename)
     else
        return 0;
 }
+
+/*
+ * Warn about the obsolescent key file format.
+ * 
+ * Uniquely among these functions, this one does _not_ expect a
+ * frontend handle. This means that if PuTTY is ported to a
+ * platform which requires frontend handles, this function will be
+ * an anomaly. Fortunately, the problem it addresses will not have
+ * been present on that platform, so it can plausibly be
+ * implemented as an empty function.
+ */
+void old_keyfile_warning(void)
+{
+    static const char mbtitle[] = "PuTTY Key File Warning";
+    static const char message[] =
+       "You are loading an SSH 2 private key which has an\n"
+       "old version of the file format. This means your key\n"
+       "file is not fully tamperproof. Future versions of\n"
+       "PuTTY may stop supporting this private key format,\n"
+       "so we recommend you convert your key to the new\n"
+       "format.\n"
+       "\n"
+       "You can perform this conversion by loading the key\n"
+       "into PuTTYgen and then saving it again.";
+
+    MessageBox(NULL, message, mbtitle, MB_OK);
+}