13 #define MAIN_NPANELS 7
14 #define RECONF_NPANELS 4
16 static const char *const puttystr
= PUTTY_REG_POS
"\\Sessions";
18 static void get_sesslist(int allocate
);
20 static char **negots
= NULL
;
21 static int nnegots
= 0, negsize
= 0;
22 static HWND logbox
= NULL
, abtbox
= NULL
;
24 static char hex
[16] = "0123456789ABCDEF";
26 static void mungestr(char *in
, char *out
) {
30 if (*in
== ' ' || *in
== '\\' || *in
== '*' || *in
== '?' ||
31 *in
== '%' || *in
< ' ' || *in
> '~' || (*in
== '.' && !candot
)) {
33 *out
++ = hex
[((unsigned char)*in
) >> 4];
34 *out
++ = hex
[((unsigned char)*in
) & 15];
44 static void unmungestr(char *in
, char *out
) {
48 if (*in
== '%' && in
[1] && in
[2]) {
51 i
= in
[1] - '0'; i
-= (i
> 9 ?
7 : 0);
52 j
= in
[2] - '0'; j
-= (j
> 9 ?
7 : 0);
63 static void wpps(HKEY key
, LPCTSTR name
, LPCTSTR value
) {
64 RegSetValueEx(key
, name
, 0, REG_SZ
, value
, 1+strlen(value
));
67 static void wppi(HKEY key
, LPCTSTR name
, int value
) {
68 RegSetValueEx(key
, name
, 0, REG_DWORD
,
69 (CONST BYTE
*)&value
, sizeof(value
));
72 static void gpps(HKEY key
, LPCTSTR name
, LPCTSTR def
,
73 LPTSTR val
, int len
) {
78 RegQueryValueEx(key
, name
, 0, &type
, val
, &size
) != ERROR_SUCCESS
||
80 strncpy(val
, def
, len
);
85 static void gppi(HKEY key
, LPCTSTR name
, int def
, int *i
) {
86 DWORD type
, val
, size
;
90 RegQueryValueEx(key
, name
, 0, &type
,
91 (BYTE
*)&val
, &size
) != ERROR_SUCCESS
||
92 size
!= sizeof(val
) || type
!= REG_DWORD
)
98 static HINSTANCE hinst
;
100 static char **sessions
;
101 static int nsessions
;
103 static int readytogo
;
105 static void save_settings (char *section
, int do_host
) {
107 HKEY subkey1
, sesskey
;
110 p
= malloc(3*strlen(section
)+1);
111 mungestr(section
, p
);
113 if (RegCreateKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
)!=ERROR_SUCCESS
||
114 RegCreateKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
119 RegCloseKey(subkey1
);
121 wppi (sesskey
, "Present", 1);
123 wpps (sesskey
, "HostName", cfg
.host
);
124 wppi (sesskey
, "PortNumber", cfg
.port
);
125 wpps (sesskey
, "Protocol",
126 cfg
.protocol
== PROT_SSH ?
"ssh" : "telnet");
128 wppi (sesskey
, "CloseOnExit", !!cfg
.close_on_exit
);
129 wpps (sesskey
, "TerminalType", cfg
.termtype
);
130 wpps (sesskey
, "TerminalSpeed", cfg
.termspeed
);
132 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
138 if (c
== '=' || c
== ',' || c
== '\\')
148 wpps (sesskey
, "Environment", buf
);
150 wpps (sesskey
, "UserName", cfg
.username
);
151 wppi (sesskey
, "NoPTY", cfg
.nopty
);
152 wppi (sesskey
, "RFCEnviron", cfg
.rfc_environ
);
153 wppi (sesskey
, "BackspaceIsDelete", cfg
.bksp_is_delete
);
154 wppi (sesskey
, "RXVTHomeEnd", cfg
.rxvt_homeend
);
155 wppi (sesskey
, "LinuxFunctionKeys", cfg
.linux_funkeys
);
156 wppi (sesskey
, "ApplicationCursorKeys", cfg
.app_cursor
);
157 wppi (sesskey
, "ApplicationKeypad", cfg
.app_keypad
);
158 wppi (sesskey
, "ScrollbackLines", cfg
.savelines
);
159 wppi (sesskey
, "DECOriginMode", cfg
.dec_om
);
160 wppi (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
161 wppi (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
162 wppi (sesskey
, "WinNameAlways", cfg
.win_name_always
);
163 wppi (sesskey
, "TermWidth", cfg
.width
);
164 wppi (sesskey
, "TermHeight", cfg
.height
);
165 wpps (sesskey
, "Font", cfg
.font
);
166 wppi (sesskey
, "FontIsBold", cfg
.fontisbold
);
167 wppi (sesskey
, "FontHeight", cfg
.fontheight
);
168 wppi (sesskey
, "FontVTMode", cfg
.vtmode
);
169 wppi (sesskey
, "TryPalette", cfg
.try_palette
);
170 wppi (sesskey
, "BoldAsColour", cfg
.bold_colour
);
171 for (i
=0; i
<22; i
++) {
172 char buf
[20], buf2
[30];
173 sprintf(buf
, "Colour%d", i
);
174 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
175 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
176 wpps (sesskey
, buf
, buf2
);
178 wppi (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
179 for (i
=0; i
<256; i
+=32) {
180 char buf
[20], buf2
[256];
182 sprintf(buf
, "Wordness%d", i
);
184 for (j
=i
; j
<i
+32; j
++) {
185 sprintf(buf2
+strlen(buf2
), "%s%d",
186 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
188 wpps (sesskey
, buf
, buf2
);
191 RegCloseKey(sesskey
);
194 static void del_session (char *section
) {
198 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
201 p
= malloc(3*strlen(section
)+1);
202 mungestr(section
, p
);
203 RegDeleteKey(subkey1
, p
);
206 RegCloseKey(subkey1
);
209 static void load_settings (char *section
, int do_host
) {
211 HKEY subkey1
, sesskey
;
214 p
= malloc(3*strlen(section
)+1);
215 mungestr(section
, p
);
217 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
||
218 RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
223 RegCloseKey(subkey1
);
227 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
228 gppi (sesskey
, "PortNumber", 23, &cfg
.port
);
229 gpps (sesskey
, "Protocol", "telnet", prot
, 10);
230 if (!strcmp(prot
, "ssh"))
231 cfg
.protocol
= PROT_SSH
;
233 cfg
.protocol
= PROT_TELNET
;
238 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
239 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
240 sizeof(cfg
.termtype
));
241 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
242 sizeof(cfg
.termspeed
));
244 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
245 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
249 while (*p
&& *p
!= ',') {
262 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
263 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
264 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
265 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
266 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
267 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.linux_funkeys
);
268 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
269 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
270 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
271 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
272 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
273 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
274 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
275 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
276 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
277 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
278 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
279 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
280 gppi (sesskey
, "FontVTMode", VT_POORMAN
, &cfg
.vtmode
);
281 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
282 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
283 for (i
=0; i
<22; i
++) {
284 static char *defaults
[] = {
285 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
286 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
287 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
288 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
289 "85,255,255", "187,187,187", "255,255,255"
291 char buf
[20], buf2
[30];
292 sprintf(buf
, "Colour%d", i
);
293 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
294 sscanf(buf2
, "%d,%d,%d", &cfg
.colours
[i
][0],
295 &cfg
.colours
[i
][1], &cfg
.colours
[i
][2]);
297 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
298 for (i
=0; i
<256; i
+=32) {
299 static char *defaults
[] = {
300 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
301 "0,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1",
302 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2",
303 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1",
304 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
305 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
306 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2",
307 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2"
309 char buf
[20], buf2
[256], *p
;
311 sprintf(buf
, "Wordness%d", i
);
312 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
314 for (j
=i
; j
<i
+32; j
++) {
316 while (*p
&& *p
!= ',') p
++;
317 if (*p
== ',') *p
++ = '\0';
318 cfg
.wordness
[j
] = atoi(q
);
321 RegCloseKey(sesskey
);
324 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
327 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
332 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
333 WPARAM wParam
, LPARAM lParam
) {
338 for (i
=0; i
<nnegots
; i
++)
339 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
340 0, (LPARAM
)negots
[i
]);
342 /* case WM_CTLCOLORDLG: */
343 /* return (int) GetStockObject (LTGRAY_BRUSH); */
345 switch (LOWORD(wParam
)) {
348 DestroyWindow (hwnd
);
354 DestroyWindow (hwnd
);
360 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
361 WPARAM wParam
, LPARAM lParam
) {
364 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
366 /* case WM_CTLCOLORDLG: */
367 /* return (int) GetStockObject (LTGRAY_BRUSH); */
368 /* case WM_CTLCOLORSTATIC: */
369 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
370 /* return (int) GetStockObject (LTGRAY_BRUSH); */
372 switch (LOWORD(wParam
)) {
375 DestroyWindow (hwnd
);
378 EnableWindow(hwnd
, 0);
379 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
381 EnableWindow(hwnd
, 1);
387 DestroyWindow (hwnd
);
393 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
394 WPARAM wParam
, LPARAM lParam
) {
397 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
399 /* case WM_CTLCOLORDLG: */
400 /* return (int) GetStockObject (LTGRAY_BRUSH); */
401 /* case WM_CTLCOLORSTATIC: */
402 /* case WM_CTLCOLORBTN: */
403 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
404 /* return (int) GetStockObject (LTGRAY_BRUSH); */
406 DestroyWindow (hwnd
);
412 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
413 WPARAM wParam
, LPARAM lParam
) {
418 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
419 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
420 for (i
= 0; i
< nsessions
; i
++)
421 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
422 0, (LPARAM
) (sessions
[i
]));
423 CheckRadioButton (hwnd
, IDC0_PROTTELNET
, IDC0_PROTSSH
,
424 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
: IDC0_PROTTELNET
);
425 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
429 * Button release should trigger WM_OK if there was a
430 * previous double click on the session list.
434 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
437 switch (LOWORD(wParam
)) {
438 case IDC0_PROTTELNET
:
440 if (HIWORD(wParam
) == BN_CLICKED
||
441 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
442 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
443 cfg
.protocol
= i ? PROT_SSH
: PROT_TELNET
;
444 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
445 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
446 cfg
.port
= i ?
22 : 23;
447 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
452 if (HIWORD(wParam
) == EN_CHANGE
)
453 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
457 if (HIWORD(wParam
) == EN_CHANGE
)
458 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
461 if (HIWORD(wParam
) == BN_CLICKED
||
462 HIWORD(wParam
) == BN_DOUBLECLICKED
)
463 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
466 if (HIWORD(wParam
) == EN_CHANGE
)
467 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
471 if (HIWORD(wParam
) == BN_CLICKED
||
472 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
477 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
479 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
485 strcpy (str
, sessions
[n
]);
487 save_settings (str
, !!strcmp(str
, "Default Settings"));
488 get_sesslist (FALSE
);
490 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
492 for (i
= 0; i
< nsessions
; i
++)
493 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
494 0, (LPARAM
) (sessions
[i
]));
495 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
501 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
502 HIWORD(wParam
) != BN_CLICKED
&&
503 HIWORD(wParam
) != BN_DOUBLECLICKED
)
505 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
506 HIWORD(wParam
) != LBN_DBLCLK
)
509 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
515 load_settings (sessions
[n
],
516 !!strcmp(sessions
[n
], "Default Settings"));
517 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
518 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
519 CheckRadioButton (hwnd
, IDC0_PROTTELNET
, IDC0_PROTSSH
,
520 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
522 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
523 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
526 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
528 * A double-click on a saved session should
529 * actually start the session, not just load it.
530 * Unless it's Default Settings or some other
531 * host-less set of saved settings.
540 if (HIWORD(wParam
) == BN_CLICKED
||
541 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
542 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
544 if (n
== LB_ERR
|| n
== 0) {
548 del_session(sessions
[n
]);
549 get_sesslist (FALSE
);
551 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
553 for (i
= 0; i
< nsessions
; i
++)
554 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
555 0, (LPARAM
) (sessions
[i
]));
556 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
561 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
564 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
565 WPARAM wParam
, LPARAM lParam
) {
568 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
569 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
570 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
571 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
572 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCLINUX
,
573 cfg
.linux_funkeys ? IDC1_FUNCLINUX
: IDC1_FUNCTILDE
);
574 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
575 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
576 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPAPPLIC
,
577 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
580 if (HIWORD(wParam
) == BN_CLICKED
||
581 HIWORD(wParam
) == BN_DOUBLECLICKED
)
582 switch (LOWORD(wParam
)) {
585 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
589 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
593 cfg
.linux_funkeys
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
597 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
601 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
605 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
608 static void fmtfont (char *buf
) {
609 sprintf (buf
, "Font: %s, ", cfg
.font
);
611 strcat(buf
, "bold, ");
612 if (cfg
.fontheight
== 0)
613 strcat (buf
, "default height");
615 sprintf (buf
+strlen(buf
), "%d-%s",
616 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
617 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
620 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
621 WPARAM wParam
, LPARAM lParam
) {
624 char fontstatic
[256];
628 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
629 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
630 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
631 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
632 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
633 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
634 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
635 fmtfont (fontstatic
);
636 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
637 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
638 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
639 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
640 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
644 switch (LOWORD(wParam
)) {
646 if (HIWORD(wParam
) == BN_CLICKED
||
647 HIWORD(wParam
) == BN_DOUBLECLICKED
)
648 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
651 if (HIWORD(wParam
) == BN_CLICKED
||
652 HIWORD(wParam
) == BN_DOUBLECLICKED
)
653 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
656 if (HIWORD(wParam
) == BN_CLICKED
||
657 HIWORD(wParam
) == BN_DOUBLECLICKED
)
658 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
661 if (HIWORD(wParam
) == BN_CLICKED
||
662 HIWORD(wParam
) == BN_DOUBLECLICKED
)
663 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
666 if (HIWORD(wParam
) == EN_CHANGE
)
667 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
670 if (HIWORD(wParam
) == EN_CHANGE
)
671 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
674 if (HIWORD(wParam
) == EN_CHANGE
)
675 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
677 case IDC2_CHOOSEFONT
:
678 lf
.lfHeight
= cfg
.fontheight
;
679 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
680 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
681 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
682 lf
.lfCharSet
= ANSI_CHARSET
;
683 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
684 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
685 lf
.lfQuality
= DEFAULT_QUALITY
;
686 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
687 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
688 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
690 cf
.lStructSize
= sizeof(cf
);
693 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
694 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
696 if (ChooseFont (&cf
)) {
697 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
698 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
699 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
700 cfg
.fontheight
= lf
.lfHeight
;
701 fmtfont (fontstatic
);
702 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
705 case IDC2_VTXWINDOWS
:
710 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
711 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
712 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
718 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
721 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
722 WPARAM wParam
, LPARAM lParam
) {
727 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
728 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
729 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
731 char *p
= cfg
.environmt
;
733 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
738 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
739 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
742 switch (LOWORD(wParam
)) {
744 if (HIWORD(wParam
) == EN_CHANGE
)
745 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
746 sizeof(cfg
.termtype
)-1);
749 if (HIWORD(wParam
) == EN_CHANGE
)
750 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
751 sizeof(cfg
.termspeed
)-1);
754 if (HIWORD(wParam
) == EN_CHANGE
)
755 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
756 sizeof(cfg
.username
)-1);
760 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
763 if (HIWORD(wParam
) == BN_CLICKED
||
764 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
765 char str
[sizeof(cfg
.environmt
)];
767 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
772 p
= str
+ strlen(str
);
774 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
784 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
786 p
[strlen(str
)+1] = '\0';
787 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
789 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
790 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
792 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
793 MB_OK
| MB_ICONERROR
);
798 if (HIWORD(wParam
) != BN_CLICKED
&&
799 HIWORD(wParam
) != BN_DOUBLECLICKED
)
801 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
807 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
834 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
837 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
838 WPARAM wParam
, LPARAM lParam
) {
841 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
842 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
843 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
846 switch (LOWORD(wParam
)) {
848 if (HIWORD(wParam
) == EN_CHANGE
)
849 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
850 sizeof(cfg
.termtype
)-1);
853 if (HIWORD(wParam
) == EN_CHANGE
)
854 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
855 sizeof(cfg
.username
)-1);
858 if (HIWORD(wParam
) == BN_CLICKED
||
859 HIWORD(wParam
) == BN_DOUBLECLICKED
)
860 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
865 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
868 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
869 WPARAM wParam
, LPARAM lParam
) {
874 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
875 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
877 static int tabs
[4] = {25, 61, 96, 128};
878 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
881 for (i
=0; i
<256; i
++) {
883 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
884 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
886 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
891 switch (LOWORD(wParam
)) {
894 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
900 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
905 for (i
=0; i
<256; i
++)
906 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
910 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
911 LB_DELETESTRING
, i
, 0);
912 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
913 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
915 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
925 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
928 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
929 WPARAM wParam
, LPARAM lParam
) {
930 static const char *const colours
[] = {
931 "Default Foreground", "Default Bold Foreground",
932 "Default Background", "Default Bold Background",
933 "Cursor Text", "Cursor Colour",
934 "ANSI Black", "ANSI Black Bold",
935 "ANSI Red", "ANSI Red Bold",
936 "ANSI Green", "ANSI Green Bold",
937 "ANSI Yellow", "ANSI Yellow Bold",
938 "ANSI Blue", "ANSI Blue Bold",
939 "ANSI Magenta", "ANSI Magenta Bold",
940 "ANSI Cyan", "ANSI Cyan Bold",
941 "ANSI White", "ANSI White Bold"
943 static const int permanent
[] = {
944 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
945 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
946 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
950 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
951 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
955 if (cfg
.bold_colour
|| permanent
[i
])
956 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
957 (LPARAM
) colours
[i
]);
959 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
960 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
961 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
962 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
965 switch (LOWORD(wParam
)) {
966 case IDC5_BOLDCOLOUR
:
967 if (HIWORD(wParam
) == BN_CLICKED
||
968 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
970 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
971 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
972 if (cfg
.bold_colour
&& n
!=22) {
975 SendDlgItemMessage (hwnd
, IDC5_LIST
,
977 (LPARAM
) colours
[i
]);
978 } else if (!cfg
.bold_colour
&& n
!=12) {
981 SendDlgItemMessage (hwnd
, IDC5_LIST
,
982 LB_DELETESTRING
, i
, 0);
987 if (HIWORD(wParam
) == BN_CLICKED
||
988 HIWORD(wParam
) == BN_DOUBLECLICKED
)
989 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
992 if (HIWORD(wParam
) == LBN_DBLCLK
||
993 HIWORD(wParam
) == LBN_SELCHANGE
) {
994 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
996 if (!cfg
.bold_colour
)
997 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
998 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
999 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1000 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1004 if (HIWORD(wParam
) == BN_CLICKED
||
1005 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1006 static CHOOSECOLOR cc
;
1007 static DWORD custom
[16] = {0}; /* zero initialisers */
1008 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1010 if (!cfg
.bold_colour
)
1011 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1012 cc
.lStructSize
= sizeof(cc
);
1013 cc
.hwndOwner
= hwnd
;
1014 cc
.hInstance
= hinst
;
1015 cc
.lpCustColors
= custom
;
1016 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1018 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1019 if (ChooseColor(&cc
)) {
1021 (unsigned char) (cc
.rgbResult
& 0xFF);
1023 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1025 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1026 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1028 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1030 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1038 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1041 static DLGPROC panelproc
[NPANELS
] = {
1042 ConnectionProc
, KeyboardProc
, TerminalProc
,
1043 TelnetProc
, SshProc
, SelectionProc
, ColourProc
1045 static char *panelids
[NPANELS
] = {
1046 MAKEINTRESOURCE(IDD_PANEL0
),
1047 MAKEINTRESOURCE(IDD_PANEL1
),
1048 MAKEINTRESOURCE(IDD_PANEL2
),
1049 MAKEINTRESOURCE(IDD_PANEL3
),
1050 MAKEINTRESOURCE(IDD_PANEL35
),
1051 MAKEINTRESOURCE(IDD_PANEL4
),
1052 MAKEINTRESOURCE(IDD_PANEL5
)
1054 static char *names
[NPANELS
] = {
1055 "Connection", "Keyboard", "Terminal", "Telnet", "SSH", "Selection", "Colours"
1058 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6 };
1059 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6 };
1061 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1062 WPARAM wParam
, LPARAM lParam
,
1063 int npanels
, int *panelnums
, HWND
*page
) {
1068 { /* centre the window */
1071 hw
= GetDesktopWindow();
1072 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1073 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1074 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1075 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1078 { /* initialise the tab control */
1082 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1083 for (i
=0; i
<npanels
; i
++) {
1084 tab
.mask
= TCIF_TEXT
;
1085 tab
.pszText
= names
[panelnums
[i
]];
1086 TabCtrl_InsertItem (hw
, i
, &tab
);
1088 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1089 hwnd, panelproc[panelnums[0]]);*/
1090 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1091 hwnd
, panelproc
[panelnums
[0]]);
1092 SetWindowLong (*page
, GWL_EXSTYLE
,
1093 GetWindowLong (*page
, GWL_EXSTYLE
) |
1094 WS_EX_CONTROLPARENT
);
1099 if (LOWORD(wParam
) == IDC_TAB
&&
1100 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1101 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1103 DestroyWindow (*page
);
1104 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1105 hwnd, panelproc[panelnums[i]]);*/
1106 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1107 hwnd
, panelproc
[panelnums
[i
]]);
1108 SetWindowLong (*page
, GWL_EXSTYLE
,
1109 GetWindowLong (*page
, GWL_EXSTYLE
) |
1110 WS_EX_CONTROLPARENT
);
1111 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1115 /* case WM_CTLCOLORDLG: */
1116 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1118 switch (LOWORD(wParam
)) {
1121 EndDialog (hwnd
, 1);
1126 EndDialog (hwnd
, 0);
1131 EndDialog (hwnd
, 0);
1137 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1138 WPARAM wParam
, LPARAM lParam
) {
1143 static HWND page
= NULL
;
1145 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1148 * If the Connection panel is active and the Session List
1149 * box is selected, we treat a press of Open to have an
1150 * implicit press of Load preceding it.
1152 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1153 i
= TabCtrl_GetCurSel(hw
);
1154 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1155 page
&& implicit_load_ok
) {
1156 SendMessage (page
, WM_COMMAND
,
1157 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1161 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1162 EnableWindow(hwnd
, 0);
1163 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1164 GetParent(hwnd
), AboutProc
);
1165 EnableWindow(hwnd
, 1);
1167 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1168 MAIN_NPANELS
, mainp
, &page
);
1171 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1172 WPARAM wParam
, LPARAM lParam
) {
1174 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1175 RECONF_NPANELS
, reconfp
, &page
);
1178 static void get_sesslist(int allocate
) {
1179 static char *buffer
;
1180 int buflen
, bufsize
, i
, ret
;
1181 char otherbuf
[2048];
1186 if (RegCreateKey(HKEY_CURRENT_USER
,
1187 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1190 buflen
= bufsize
= 0;
1194 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1195 if (ret
== ERROR_SUCCESS
) {
1196 bufsize
= buflen
+ 2048;
1197 buffer
= srealloc(buffer
, bufsize
);
1198 unmungestr(otherbuf
, buffer
+buflen
);
1199 buflen
+= strlen(buffer
+buflen
)+1;
1201 } while (ret
== ERROR_SUCCESS
);
1202 buffer
= srealloc(buffer
, buflen
+1);
1203 buffer
[buflen
] = '\0';
1206 nsessions
= 1; /* "Default Settings" counts as one */
1208 if (strcmp(p
, "Default Settings"))
1214 sessions
= smalloc(nsessions
* sizeof(char *));
1215 sessions
[0] = "Default Settings";
1219 if (strcmp(p
, "Default Settings"))
1230 int do_config (void) {
1234 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1235 get_sesslist(FALSE
);
1240 int do_reconfig (HWND hwnd
) {
1244 backup_cfg
= cfg
; /* structure copy */
1245 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1247 cfg
= backup_cfg
; /* structure copy */
1251 void do_defaults (char *session
) {
1253 load_settings (session
, TRUE
);
1255 load_settings ("Default Settings", FALSE
);
1258 void lognegot (char *string
) {
1259 if (nnegots
>= negsize
) {
1261 negots
= srealloc (negots
, negsize
* sizeof(*negots
));
1263 negots
[nnegots
] = smalloc(1+strlen(string
));
1264 strcpy (negots
[nnegots
], string
);
1267 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1271 void shownegot (HWND hwnd
) {
1273 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1275 ShowWindow (logbox
, SW_SHOWNORMAL
);
1279 void showabout (HWND hwnd
) {
1281 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1283 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1287 void verify_ssh_host_key(char *host
, struct RSAKey
*key
) {
1288 char *keystr
, *otherstr
, *mungedhost
;
1293 * Format the key into a string.
1295 len
= rsastr_len(key
);
1296 keystr
= malloc(len
);
1298 fatalbox("Out of memory");
1299 rsastr_fmt(keystr
, key
);
1302 * Now read a saved key in from the registry and see what it
1305 otherstr
= malloc(len
);
1306 mungedhost
= malloc(3*strlen(host
)+1);
1307 if (!otherstr
|| !mungedhost
)
1308 fatalbox("Out of memory");
1310 mungestr(host
, mungedhost
);
1312 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1313 &rkey
) != ERROR_SUCCESS
) {
1314 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1315 "in the registry. There is thus no way to tell\n"
1316 "if the remote host is what you think it is.\n"
1317 "Connect anyway?", "PuTTY Problem",
1318 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1321 DWORD readlen
= len
;
1325 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1326 &type
, otherstr
, &readlen
);
1328 if (ret
== ERROR_MORE_DATA
||
1329 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1330 strcmp(otherstr
, keystr
))) {
1331 if (MessageBox(NULL
,
1332 "This host's host key is different from the\n"
1333 "one cached in the registry! Someone may be\n"
1334 "impersonating this host for malicious reasons;\n"
1335 "alternatively, the host key may have changed\n"
1336 "due to sloppy system administration.\n"
1337 "Replace key in registry and connect?",
1338 "PuTTY: Security Warning",
1339 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1341 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1343 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1344 if (MessageBox(NULL
,
1345 "This host's host key is not cached in the\n"
1346 "registry. Do you want to add it to the cache\n"
1347 "and carry on connecting?",
1349 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1351 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,