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
)
101 char dataspace
[2048];
104 static HINSTANCE hinst
;
106 static char **sessions
;
107 static int nsessions
;
109 static void save_settings (char *section
, int do_host
) {
111 HKEY subkey1
, sesskey
;
114 p
= malloc(3*strlen(section
)+1);
115 mungestr(section
, p
);
117 if (RegCreateKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
)!=ERROR_SUCCESS
||
118 RegCreateKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
124 RegCloseKey(subkey1
);
126 wppi (sesskey
, "Present", 1);
128 wpps (sesskey
, "HostName", cfg
.host
);
129 wppi (sesskey
, "PortNumber", cfg
.port
);
130 wpps (sesskey
, "Protocol",
131 cfg
.protocol
== PROT_SSH ?
"ssh" : "telnet");
133 wppi (sesskey
, "CloseOnExit", !!cfg
.close_on_exit
);
134 wpps (sesskey
, "TerminalType", cfg
.termtype
);
135 wpps (sesskey
, "TerminalSpeed", cfg
.termspeed
);
137 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
143 if (c
== '=' || c
== ',' || c
== '\\')
153 wpps (sesskey
, "Environment", buf
);
155 wpps (sesskey
, "UserName", cfg
.username
);
156 wppi (sesskey
, "NoPTY", cfg
.nopty
);
157 wppi (sesskey
, "RFCEnviron", cfg
.rfc_environ
);
158 wppi (sesskey
, "BackspaceIsDelete", cfg
.bksp_is_delete
);
159 wppi (sesskey
, "RXVTHomeEnd", cfg
.rxvt_homeend
);
160 wppi (sesskey
, "LinuxFunctionKeys", cfg
.linux_funkeys
);
161 wppi (sesskey
, "ApplicationCursorKeys", cfg
.app_cursor
);
162 wppi (sesskey
, "ApplicationKeypad", cfg
.app_keypad
);
163 wppi (sesskey
, "ScrollbackLines", cfg
.savelines
);
164 wppi (sesskey
, "DECOriginMode", cfg
.dec_om
);
165 wppi (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
166 wppi (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
167 wppi (sesskey
, "WinNameAlways", cfg
.win_name_always
);
168 wppi (sesskey
, "TermWidth", cfg
.width
);
169 wppi (sesskey
, "TermHeight", cfg
.height
);
170 wpps (sesskey
, "Font", cfg
.font
);
171 wppi (sesskey
, "FontIsBold", cfg
.fontisbold
);
172 wppi (sesskey
, "FontHeight", cfg
.fontheight
);
173 wppi (sesskey
, "FontVTMode", cfg
.vtmode
);
174 wppi (sesskey
, "TryPalette", cfg
.try_palette
);
175 wppi (sesskey
, "BoldAsColour", cfg
.bold_colour
);
176 for (i
=0; i
<22; i
++) {
177 char buf
[20], buf2
[30];
178 sprintf(buf
, "Colour%d", i
);
179 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
180 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
181 wpps (sesskey
, buf
, buf2
);
183 wppi (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
184 for (i
=0; i
<256; i
+=32) {
185 char buf
[20], buf2
[256];
187 sprintf(buf
, "Wordness%d", i
);
189 for (j
=i
; j
<i
+32; j
++) {
190 sprintf(buf2
+strlen(buf2
), "%s%d",
191 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
193 wpps (sesskey
, buf
, buf2
);
196 RegCloseKey(sesskey
);
199 static void del_session (char *section
) {
203 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
206 p
= malloc(3*strlen(section
)+1);
207 mungestr(section
, p
);
208 RegDeleteKey(subkey1
, p
);
211 RegCloseKey(subkey1
);
214 static void load_settings (char *section
, int do_host
) {
216 HKEY subkey1
, sesskey
;
219 p
= malloc(3*strlen(section
)+1);
220 mungestr(section
, p
);
222 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
||
223 RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
229 RegCloseKey(subkey1
);
233 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
234 gppi (sesskey
, "PortNumber", 23, &cfg
.port
);
235 gpps (sesskey
, "Protocol", "telnet", prot
, 10);
236 if (!strcmp(prot
, "ssh"))
237 cfg
.protocol
= PROT_SSH
;
239 cfg
.protocol
= PROT_TELNET
;
244 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
245 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
246 sizeof(cfg
.termtype
));
247 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
248 sizeof(cfg
.termspeed
));
250 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
251 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
255 while (*p
&& *p
!= ',') {
268 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
269 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
270 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
271 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
272 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
273 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.linux_funkeys
);
274 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
275 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
276 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
277 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
278 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
279 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
280 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
281 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
282 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
283 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
284 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
285 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
286 gppi (sesskey
, "FontVTMode", VT_POORMAN
, &cfg
.vtmode
);
287 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
288 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
289 for (i
=0; i
<22; i
++) {
290 static char *defaults
[] = {
291 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
292 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
293 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
294 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
295 "85,255,255", "187,187,187", "255,255,255"
297 char buf
[20], buf2
[30];
298 sprintf(buf
, "Colour%d", i
);
299 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
300 sscanf(buf2
, "%d,%d,%d", &cfg
.colours
[i
][0],
301 &cfg
.colours
[i
][1], &cfg
.colours
[i
][2]);
303 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
304 for (i
=0; i
<256; i
+=32) {
305 static char *defaults
[] = {
306 "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",
307 "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",
308 "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",
309 "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",
310 "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",
311 "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",
312 "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",
313 "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"
315 char buf
[20], buf2
[256], *p
;
317 sprintf(buf
, "Wordness%d", i
);
318 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
320 for (j
=i
; j
<i
+32; j
++) {
322 while (*p
&& *p
!= ',') p
++;
323 if (*p
== ',') *p
++ = '\0';
324 cfg
.wordness
[j
] = atoi(q
);
327 RegCloseKey(sesskey
);
330 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
333 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
338 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
339 WPARAM wParam
, LPARAM lParam
) {
344 for (i
=0; i
<nnegots
; i
++)
345 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
346 0, (LPARAM
)negots
[i
]);
348 /* case WM_CTLCOLORDLG: */
349 /* return (int) GetStockObject (LTGRAY_BRUSH); */
351 switch (LOWORD(wParam
)) {
354 DestroyWindow (hwnd
);
360 DestroyWindow (hwnd
);
366 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
367 WPARAM wParam
, LPARAM lParam
) {
371 /* case WM_CTLCOLORDLG: */
372 /* return (int) GetStockObject (LTGRAY_BRUSH); */
373 /* case WM_CTLCOLORSTATIC: */
374 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
375 /* return (int) GetStockObject (LTGRAY_BRUSH); */
377 switch (LOWORD(wParam
)) {
380 DestroyWindow (hwnd
);
383 EnableWindow(hwnd
, 0);
384 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
386 EnableWindow(hwnd
, 1);
392 DestroyWindow (hwnd
);
398 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
399 WPARAM wParam
, LPARAM lParam
) {
402 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
404 /* case WM_CTLCOLORDLG: */
405 /* return (int) GetStockObject (LTGRAY_BRUSH); */
406 /* case WM_CTLCOLORSTATIC: */
407 /* case WM_CTLCOLORBTN: */
408 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
409 /* return (int) GetStockObject (LTGRAY_BRUSH); */
411 DestroyWindow (hwnd
);
417 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
418 WPARAM wParam
, LPARAM lParam
) {
423 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
424 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
425 for (i
= 0; i
< nsessions
; i
++)
426 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
427 0, (LPARAM
) (sessions
[i
]));
428 CheckRadioButton (hwnd
, IDC0_PROTTELNET
, IDC0_PROTSSH
,
429 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
: IDC0_PROTTELNET
);
430 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
433 switch (LOWORD(wParam
)) {
434 case IDC0_PROTTELNET
:
436 if (HIWORD(wParam
) == BN_CLICKED
||
437 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
438 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
439 cfg
.protocol
= i ? PROT_SSH
: PROT_TELNET
;
440 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
441 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
442 cfg
.port
= i ?
22 : 23;
443 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
448 if (HIWORD(wParam
) == EN_CHANGE
)
449 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
453 if (HIWORD(wParam
) == EN_CHANGE
)
454 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
457 if (HIWORD(wParam
) == BN_CLICKED
||
458 HIWORD(wParam
) == BN_DOUBLECLICKED
)
459 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
462 if (HIWORD(wParam
) == EN_CHANGE
)
463 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
467 if (HIWORD(wParam
) == BN_CLICKED
||
468 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
473 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
475 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
481 strcpy (str
, sessions
[n
]);
483 save_settings (str
, !!strcmp(str
, "Default Settings"));
484 get_sesslist (FALSE
);
486 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
488 for (i
= 0; i
< nsessions
; i
++)
489 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
490 0, (LPARAM
) (sessions
[i
]));
491 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
497 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
498 HIWORD(wParam
) != BN_CLICKED
&&
499 HIWORD(wParam
) != BN_DOUBLECLICKED
)
501 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
502 HIWORD(wParam
) != LBN_DBLCLK
)
505 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
511 load_settings (sessions
[n
],
512 !!strcmp(sessions
[n
], "Default Settings"));
513 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
514 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
515 CheckRadioButton (hwnd
, IDC0_PROTTELNET
, IDC0_PROTSSH
,
516 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
518 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
519 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
522 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
524 * A double-click on a saved session should
525 * actually start the session, not just load it.
526 * Unless it's Default Settings or some other
527 * host-less set of saved settings.
530 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
534 if (HIWORD(wParam
) == BN_CLICKED
||
535 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
536 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
538 if (n
== LB_ERR
|| n
== 0) {
542 del_session(sessions
[n
]);
543 get_sesslist (FALSE
);
545 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
547 for (i
= 0; i
< nsessions
; i
++)
548 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
549 0, (LPARAM
) (sessions
[i
]));
550 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
555 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
558 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
559 WPARAM wParam
, LPARAM lParam
) {
562 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
563 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
564 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
565 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
566 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCLINUX
,
567 cfg
.linux_funkeys ? IDC1_FUNCLINUX
: IDC1_FUNCTILDE
);
568 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
569 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
570 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPAPPLIC
,
571 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
574 if (HIWORD(wParam
) == BN_CLICKED
||
575 HIWORD(wParam
) == BN_DOUBLECLICKED
)
576 switch (LOWORD(wParam
)) {
579 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
583 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
587 cfg
.linux_funkeys
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
591 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
595 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
599 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
602 static void fmtfont (char *buf
) {
603 sprintf (buf
, "Font: %s, ", cfg
.font
);
605 strcat(buf
, "bold, ");
606 if (cfg
.fontheight
== 0)
607 strcat (buf
, "default height");
609 sprintf (buf
+strlen(buf
), "%d-%s",
610 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
611 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
614 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
615 WPARAM wParam
, LPARAM lParam
) {
618 char fontstatic
[256];
622 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
623 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
624 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
625 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
626 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
627 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
628 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
629 fmtfont (fontstatic
);
630 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
631 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
632 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
633 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
634 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
638 switch (LOWORD(wParam
)) {
640 if (HIWORD(wParam
) == BN_CLICKED
||
641 HIWORD(wParam
) == BN_DOUBLECLICKED
)
642 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
645 if (HIWORD(wParam
) == BN_CLICKED
||
646 HIWORD(wParam
) == BN_DOUBLECLICKED
)
647 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
650 if (HIWORD(wParam
) == BN_CLICKED
||
651 HIWORD(wParam
) == BN_DOUBLECLICKED
)
652 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
655 if (HIWORD(wParam
) == BN_CLICKED
||
656 HIWORD(wParam
) == BN_DOUBLECLICKED
)
657 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
660 if (HIWORD(wParam
) == EN_CHANGE
)
661 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
664 if (HIWORD(wParam
) == EN_CHANGE
)
665 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
668 if (HIWORD(wParam
) == EN_CHANGE
)
669 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
671 case IDC2_CHOOSEFONT
:
672 lf
.lfHeight
= cfg
.fontheight
;
673 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
674 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
675 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
676 lf
.lfCharSet
= ANSI_CHARSET
;
677 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
678 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
679 lf
.lfQuality
= DEFAULT_QUALITY
;
680 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
681 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
682 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
684 cf
.lStructSize
= sizeof(cf
);
687 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
688 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
690 if (ChooseFont (&cf
)) {
691 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
692 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
693 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
694 cfg
.fontheight
= lf
.lfHeight
;
695 fmtfont (fontstatic
);
696 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
699 case IDC2_VTXWINDOWS
:
704 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
705 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
706 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
712 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
715 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
716 WPARAM wParam
, LPARAM lParam
) {
721 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
722 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
723 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
725 char *p
= cfg
.environmt
;
727 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
732 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
733 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
736 switch (LOWORD(wParam
)) {
738 if (HIWORD(wParam
) == EN_CHANGE
)
739 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
740 sizeof(cfg
.termtype
)-1);
743 if (HIWORD(wParam
) == EN_CHANGE
)
744 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
745 sizeof(cfg
.termspeed
)-1);
748 if (HIWORD(wParam
) == EN_CHANGE
)
749 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
750 sizeof(cfg
.username
)-1);
754 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
757 if (HIWORD(wParam
) == BN_CLICKED
||
758 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
759 char str
[sizeof(cfg
.environmt
)];
761 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
766 p
= str
+ strlen(str
);
768 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
778 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
780 p
[strlen(str
)+1] = '\0';
781 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
783 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
784 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
786 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
787 MB_OK
| MB_ICONERROR
);
792 if (HIWORD(wParam
) != BN_CLICKED
&&
793 HIWORD(wParam
) != BN_DOUBLECLICKED
)
795 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
801 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
828 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
831 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
832 WPARAM wParam
, LPARAM lParam
) {
835 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
836 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
837 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
840 switch (LOWORD(wParam
)) {
842 if (HIWORD(wParam
) == EN_CHANGE
)
843 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
844 sizeof(cfg
.termtype
)-1);
847 if (HIWORD(wParam
) == EN_CHANGE
)
848 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
849 sizeof(cfg
.username
)-1);
852 if (HIWORD(wParam
) == BN_CLICKED
||
853 HIWORD(wParam
) == BN_DOUBLECLICKED
)
854 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
859 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
862 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
863 WPARAM wParam
, LPARAM lParam
) {
868 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
869 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
871 static int tabs
[4] = {25, 61, 96, 128};
872 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
875 for (i
=0; i
<256; i
++) {
877 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
878 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
880 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
885 switch (LOWORD(wParam
)) {
888 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
894 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
899 for (i
=0; i
<256; i
++)
900 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
904 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
905 LB_DELETESTRING
, i
, 0);
906 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
907 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
909 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
919 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
922 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
923 WPARAM wParam
, LPARAM lParam
) {
924 static const char *const colours
[] = {
925 "Default Foreground", "Default Bold Foreground",
926 "Default Background", "Default Bold Background",
927 "Cursor Text", "Cursor Colour",
928 "ANSI Black", "ANSI Black Bold",
929 "ANSI Red", "ANSI Red Bold",
930 "ANSI Green", "ANSI Green Bold",
931 "ANSI Yellow", "ANSI Yellow Bold",
932 "ANSI Blue", "ANSI Blue Bold",
933 "ANSI Magenta", "ANSI Magenta Bold",
934 "ANSI Cyan", "ANSI Cyan Bold",
935 "ANSI White", "ANSI White Bold"
937 static const int permanent
[] = {
938 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
939 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
940 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
944 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
945 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
949 if (cfg
.bold_colour
|| permanent
[i
])
950 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
951 (LPARAM
) colours
[i
]);
953 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
954 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
955 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
956 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
959 switch (LOWORD(wParam
)) {
960 case IDC5_BOLDCOLOUR
:
961 if (HIWORD(wParam
) == BN_CLICKED
||
962 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
964 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
965 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
966 if (cfg
.bold_colour
&& n
!=22) {
969 SendDlgItemMessage (hwnd
, IDC5_LIST
,
971 (LPARAM
) colours
[i
]);
972 } else if (!cfg
.bold_colour
&& n
!=12) {
975 SendDlgItemMessage (hwnd
, IDC5_LIST
,
976 LB_DELETESTRING
, i
, 0);
981 if (HIWORD(wParam
) == BN_CLICKED
||
982 HIWORD(wParam
) == BN_DOUBLECLICKED
)
983 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
986 if (HIWORD(wParam
) == LBN_DBLCLK
||
987 HIWORD(wParam
) == LBN_SELCHANGE
) {
988 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
990 if (!cfg
.bold_colour
)
991 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
992 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
993 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
994 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
998 if (HIWORD(wParam
) == BN_CLICKED
||
999 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1000 static CHOOSECOLOR cc
;
1001 static DWORD custom
[16] = {0}; /* zero initialisers */
1002 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1004 if (!cfg
.bold_colour
)
1005 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1006 cc
.lStructSize
= sizeof(cc
);
1007 cc
.hwndOwner
= hwnd
;
1008 cc
.hInstance
= hinst
;
1009 cc
.lpCustColors
= custom
;
1010 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1012 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1013 if (ChooseColor(&cc
)) {
1015 (unsigned char) (cc
.rgbResult
& 0xFF);
1017 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1019 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1020 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1022 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1024 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1032 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1035 static DTemplate negot
, main
, reconf
, panels
[NPANELS
];
1036 static DLGPROC panelproc
[NPANELS
] = {
1037 ConnectionProc
, KeyboardProc
, TerminalProc
,
1038 TelnetProc
, SshProc
, SelectionProc
, ColourProc
1040 static char *panelids
[NPANELS
] = {
1041 MAKEINTRESOURCE(IDD_PANEL0
),
1042 MAKEINTRESOURCE(IDD_PANEL1
),
1043 MAKEINTRESOURCE(IDD_PANEL2
),
1044 MAKEINTRESOURCE(IDD_PANEL3
),
1045 MAKEINTRESOURCE(IDD_PANEL35
),
1046 MAKEINTRESOURCE(IDD_PANEL4
),
1047 MAKEINTRESOURCE(IDD_PANEL5
)
1049 static char *names
[NPANELS
] = {
1050 "Connection", "Keyboard", "Terminal", "Telnet", "SSH", "Selection", "Colours"
1053 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6 };
1054 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6 };
1056 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1057 WPARAM wParam
, LPARAM lParam
,
1058 int npanels
, int *panelnums
, HWND
*page
) {
1063 { /* centre the window */
1066 hw
= GetDesktopWindow();
1067 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1068 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1069 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1070 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1073 { /* initialise the tab control */
1077 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1078 for (i
=0; i
<npanels
; i
++) {
1079 tab
.mask
= TCIF_TEXT
;
1080 tab
.pszText
= names
[panelnums
[i
]];
1081 TabCtrl_InsertItem (hw
, i
, &tab
);
1083 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1084 hwnd, panelproc[panelnums[0]]);*/
1085 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1086 hwnd
, panelproc
[panelnums
[0]]);
1087 SetWindowLong (*page
, GWL_EXSTYLE
,
1088 GetWindowLong (*page
, GWL_EXSTYLE
) |
1089 WS_EX_CONTROLPARENT
);
1094 if (LOWORD(wParam
) == IDC_TAB
&&
1095 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1096 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1098 DestroyWindow (*page
);
1099 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1100 hwnd, panelproc[panelnums[i]]);*/
1101 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1102 hwnd
, panelproc
[panelnums
[i
]]);
1103 SetWindowLong (*page
, GWL_EXSTYLE
,
1104 GetWindowLong (*page
, GWL_EXSTYLE
) |
1105 WS_EX_CONTROLPARENT
);
1106 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1110 /* case WM_CTLCOLORDLG: */
1111 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1113 switch (LOWORD(wParam
)) {
1116 EndDialog (hwnd
, 1);
1121 EndDialog (hwnd
, 0);
1126 EndDialog (hwnd
, 0);
1132 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1133 WPARAM wParam
, LPARAM lParam
) {
1138 static HWND page
= NULL
;
1140 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1143 * If the Connection panel is active and the Session List
1144 * box is selected, we treat a press of Open to have an
1145 * implicit press of Load preceding it.
1147 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1148 i
= TabCtrl_GetCurSel(hw
);
1149 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1150 page
&& implicit_load_ok
) {
1151 SendMessage (page
, WM_COMMAND
,
1152 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1156 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1157 EnableWindow(hwnd
, 0);
1158 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1159 GetParent(hwnd
), AboutProc
);
1160 EnableWindow(hwnd
, 1);
1162 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1163 MAIN_NPANELS
, mainp
, &page
);
1166 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1167 WPARAM wParam
, LPARAM lParam
) {
1169 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1170 RECONF_NPANELS
, reconfp
, &page
);
1173 static void get_sesslist(int allocate
) {
1174 static char *buffer
;
1175 int buflen
, bufsize
, i
, ret
;
1176 char otherbuf
[2048];
1181 if (RegCreateKey(HKEY_CURRENT_USER
,
1182 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1185 buflen
= bufsize
= 0;
1189 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1190 if (ret
== ERROR_SUCCESS
) {
1191 bufsize
= buflen
+ 2048;
1192 buffer
= srealloc(buffer
, bufsize
);
1193 unmungestr(otherbuf
, buffer
+buflen
);
1194 buflen
+= strlen(buffer
+buflen
)+1;
1196 } while (ret
== ERROR_SUCCESS
);
1197 buffer
= srealloc(buffer
, buflen
+1);
1198 buffer
[buflen
] = '\0';
1201 nsessions
= 1; /* "Default Settings" counts as one */
1203 if (strcmp(p
, "Default Settings"))
1209 sessions
= smalloc(nsessions
* sizeof(char *));
1210 sessions
[0] = "Default Settings";
1214 if (strcmp(p
, "Default Settings"))
1225 int do_config (void) {
1229 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1230 get_sesslist(FALSE
);
1235 int do_reconfig (HWND hwnd
) {
1239 backup_cfg
= cfg
; /* structure copy */
1240 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1242 cfg
= backup_cfg
; /* structure copy */
1246 void do_defaults (char *session
) {
1248 load_settings (session
, TRUE
);
1250 load_settings ("Default Settings", FALSE
);
1253 void lognegot (char *string
) {
1254 if (nnegots
>= negsize
) {
1256 negots
= srealloc (negots
, negsize
* sizeof(*negots
));
1258 negots
[nnegots
] = smalloc(1+strlen(string
));
1259 strcpy (negots
[nnegots
], string
);
1262 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1266 void shownegot (HWND hwnd
) {
1268 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1270 ShowWindow (logbox
, SW_SHOWNORMAL
);
1274 void showabout (HWND hwnd
) {
1276 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1278 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1282 void verify_ssh_host_key(char *host
, struct RSAKey
*key
) {
1283 char *keystr
, *otherstr
, *mungedhost
;
1288 * Format the key into a string.
1290 len
= rsastr_len(key
);
1291 keystr
= malloc(len
);
1293 fatalbox("Out of memory");
1294 rsastr_fmt(keystr
, key
);
1297 * Now read a saved key in from the registry and see what it
1300 otherstr
= malloc(len
);
1301 mungedhost
= malloc(3*strlen(host
)+1);
1302 if (!otherstr
|| !mungedhost
)
1303 fatalbox("Out of memory");
1305 mungestr(host
, mungedhost
);
1307 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1308 &rkey
) != ERROR_SUCCESS
) {
1309 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1310 "in the registry. There is thus no way to tell\n"
1311 "if the remote host is what you think it is.\n"
1312 "Connect anyway?", "PuTTY Problem",
1313 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1316 DWORD readlen
= len
;
1320 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1321 &type
, otherstr
, &readlen
);
1323 if (ret
== ERROR_MORE_DATA
||
1324 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1325 strcmp(otherstr
, keystr
))) {
1326 if (MessageBox(NULL
,
1327 "This host's host key is different from the\n"
1328 "one cached in the registry! Someone may be\n"
1329 "impersonating this host for malicious reasons;\n"
1330 "alternatively, the host key may have changed\n"
1331 "due to sloppy system administration.\n"
1332 "Replace key in registry and connect?",
1333 "PuTTY: Security Warning",
1334 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1336 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1338 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1339 if (MessageBox(NULL
,
1340 "This host's host key is not cached in the\n"
1341 "registry. Do you want to add it to the cache\n"
1342 "and carry on connecting?",
1344 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1346 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,