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
) {
220 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
223 RegCloseKey(subkey1
);
230 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
231 gppi (sesskey
, "PortNumber", 23, &cfg
.port
);
232 gpps (sesskey
, "Protocol", "telnet", prot
, 10);
233 if (!strcmp(prot
, "ssh"))
234 cfg
.protocol
= PROT_SSH
;
236 cfg
.protocol
= PROT_TELNET
;
241 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
242 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
243 sizeof(cfg
.termtype
));
244 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
245 sizeof(cfg
.termspeed
));
247 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
248 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
252 while (*p
&& *p
!= ',') {
265 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
266 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
267 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
268 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
269 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
270 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.linux_funkeys
);
271 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
272 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
273 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
274 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
275 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
276 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
277 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
278 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
279 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
280 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
281 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
282 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
283 gppi (sesskey
, "FontVTMode", VT_POORMAN
, &cfg
.vtmode
);
284 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
285 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
286 for (i
=0; i
<22; i
++) {
287 static char *defaults
[] = {
288 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
289 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
290 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
291 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
292 "85,255,255", "187,187,187", "255,255,255"
294 char buf
[20], buf2
[30];
295 sprintf(buf
, "Colour%d", i
);
296 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
297 sscanf(buf2
, "%d,%d,%d", &cfg
.colours
[i
][0],
298 &cfg
.colours
[i
][1], &cfg
.colours
[i
][2]);
300 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
301 for (i
=0; i
<256; i
+=32) {
302 static char *defaults
[] = {
303 "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",
304 "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",
305 "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",
306 "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",
307 "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",
308 "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",
309 "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",
310 "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"
312 char buf
[20], buf2
[256], *p
;
314 sprintf(buf
, "Wordness%d", i
);
315 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
317 for (j
=i
; j
<i
+32; j
++) {
319 while (*p
&& *p
!= ',') p
++;
320 if (*p
== ',') *p
++ = '\0';
321 cfg
.wordness
[j
] = atoi(q
);
324 RegCloseKey(sesskey
);
327 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
330 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
335 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
336 WPARAM wParam
, LPARAM lParam
) {
341 for (i
=0; i
<nnegots
; i
++)
342 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
343 0, (LPARAM
)negots
[i
]);
345 /* case WM_CTLCOLORDLG: */
346 /* return (int) GetStockObject (LTGRAY_BRUSH); */
348 switch (LOWORD(wParam
)) {
351 DestroyWindow (hwnd
);
357 DestroyWindow (hwnd
);
363 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
364 WPARAM wParam
, LPARAM lParam
) {
369 switch (LOWORD(wParam
)) {
372 DestroyWindow (hwnd
);
378 DestroyWindow (hwnd
);
384 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
385 WPARAM wParam
, LPARAM lParam
) {
388 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
390 /* case WM_CTLCOLORDLG: */
391 /* return (int) GetStockObject (LTGRAY_BRUSH); */
392 /* case WM_CTLCOLORSTATIC: */
393 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
394 /* return (int) GetStockObject (LTGRAY_BRUSH); */
396 switch (LOWORD(wParam
)) {
399 DestroyWindow (hwnd
);
402 EnableWindow(hwnd
, 0);
403 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
405 EnableWindow(hwnd
, 1);
411 DestroyWindow (hwnd
);
417 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
418 WPARAM wParam
, LPARAM lParam
) {
421 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
423 /* case WM_CTLCOLORDLG: */
424 /* return (int) GetStockObject (LTGRAY_BRUSH); */
425 /* case WM_CTLCOLORSTATIC: */
426 /* case WM_CTLCOLORBTN: */
427 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
428 /* return (int) GetStockObject (LTGRAY_BRUSH); */
430 DestroyWindow (hwnd
);
436 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
437 WPARAM wParam
, LPARAM lParam
) {
442 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
443 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
444 for (i
= 0; i
< nsessions
; i
++)
445 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
446 0, (LPARAM
) (sessions
[i
]));
447 CheckRadioButton (hwnd
, IDC0_PROTTELNET
, IDC0_PROTSSH
,
448 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
: IDC0_PROTTELNET
);
449 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
453 * Button release should trigger WM_OK if there was a
454 * previous double click on the session list.
458 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
461 switch (LOWORD(wParam
)) {
462 case IDC0_PROTTELNET
:
464 if (HIWORD(wParam
) == BN_CLICKED
||
465 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
466 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
467 cfg
.protocol
= i ? PROT_SSH
: PROT_TELNET
;
468 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
469 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
470 cfg
.port
= i ?
22 : 23;
471 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
476 if (HIWORD(wParam
) == EN_CHANGE
)
477 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
481 if (HIWORD(wParam
) == EN_CHANGE
)
482 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
485 if (HIWORD(wParam
) == BN_CLICKED
||
486 HIWORD(wParam
) == BN_DOUBLECLICKED
)
487 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
490 if (HIWORD(wParam
) == EN_CHANGE
)
491 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
495 if (HIWORD(wParam
) == BN_CLICKED
||
496 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
501 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
503 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
509 strcpy (str
, sessions
[n
]);
511 save_settings (str
, !!strcmp(str
, "Default Settings"));
512 get_sesslist (FALSE
);
514 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
516 for (i
= 0; i
< nsessions
; i
++)
517 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
518 0, (LPARAM
) (sessions
[i
]));
519 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
525 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
526 HIWORD(wParam
) != BN_CLICKED
&&
527 HIWORD(wParam
) != BN_DOUBLECLICKED
)
529 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
530 HIWORD(wParam
) != LBN_DBLCLK
)
533 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
539 load_settings (sessions
[n
],
540 !!strcmp(sessions
[n
], "Default Settings"));
541 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
542 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
543 CheckRadioButton (hwnd
, IDC0_PROTTELNET
, IDC0_PROTSSH
,
544 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
546 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
547 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
550 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
552 * A double-click on a saved session should
553 * actually start the session, not just load it.
554 * Unless it's Default Settings or some other
555 * host-less set of saved settings.
564 if (HIWORD(wParam
) == BN_CLICKED
||
565 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
566 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
568 if (n
== LB_ERR
|| n
== 0) {
572 del_session(sessions
[n
]);
573 get_sesslist (FALSE
);
575 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
577 for (i
= 0; i
< nsessions
; i
++)
578 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
579 0, (LPARAM
) (sessions
[i
]));
580 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
585 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
588 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
589 WPARAM wParam
, LPARAM lParam
) {
592 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
593 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
594 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
595 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
596 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCLINUX
,
597 cfg
.linux_funkeys ? IDC1_FUNCLINUX
: IDC1_FUNCTILDE
);
598 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
599 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
600 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPAPPLIC
,
601 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
604 if (HIWORD(wParam
) == BN_CLICKED
||
605 HIWORD(wParam
) == BN_DOUBLECLICKED
)
606 switch (LOWORD(wParam
)) {
609 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
613 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
617 cfg
.linux_funkeys
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
621 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
625 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
629 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
632 static void fmtfont (char *buf
) {
633 sprintf (buf
, "Font: %s, ", cfg
.font
);
635 strcat(buf
, "bold, ");
636 if (cfg
.fontheight
== 0)
637 strcat (buf
, "default height");
639 sprintf (buf
+strlen(buf
), "%d-%s",
640 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
641 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
644 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
645 WPARAM wParam
, LPARAM lParam
) {
648 char fontstatic
[256];
652 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
653 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
654 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
655 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
656 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
657 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
658 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
659 fmtfont (fontstatic
);
660 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
661 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
662 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
663 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
664 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
668 switch (LOWORD(wParam
)) {
670 if (HIWORD(wParam
) == BN_CLICKED
||
671 HIWORD(wParam
) == BN_DOUBLECLICKED
)
672 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
675 if (HIWORD(wParam
) == BN_CLICKED
||
676 HIWORD(wParam
) == BN_DOUBLECLICKED
)
677 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
680 if (HIWORD(wParam
) == BN_CLICKED
||
681 HIWORD(wParam
) == BN_DOUBLECLICKED
)
682 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
685 if (HIWORD(wParam
) == BN_CLICKED
||
686 HIWORD(wParam
) == BN_DOUBLECLICKED
)
687 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
690 if (HIWORD(wParam
) == EN_CHANGE
)
691 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
694 if (HIWORD(wParam
) == EN_CHANGE
)
695 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
698 if (HIWORD(wParam
) == EN_CHANGE
)
699 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
701 case IDC2_CHOOSEFONT
:
702 lf
.lfHeight
= cfg
.fontheight
;
703 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
704 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
705 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
706 lf
.lfCharSet
= ANSI_CHARSET
;
707 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
708 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
709 lf
.lfQuality
= DEFAULT_QUALITY
;
710 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
711 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
712 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
714 cf
.lStructSize
= sizeof(cf
);
717 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
718 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
720 if (ChooseFont (&cf
)) {
721 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
722 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
723 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
724 cfg
.fontheight
= lf
.lfHeight
;
725 fmtfont (fontstatic
);
726 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
729 case IDC2_VTXWINDOWS
:
734 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
735 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
736 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
742 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
745 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
746 WPARAM wParam
, LPARAM lParam
) {
751 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
752 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
753 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
755 char *p
= cfg
.environmt
;
757 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
762 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
763 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
766 switch (LOWORD(wParam
)) {
768 if (HIWORD(wParam
) == EN_CHANGE
)
769 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
770 sizeof(cfg
.termtype
)-1);
773 if (HIWORD(wParam
) == EN_CHANGE
)
774 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
775 sizeof(cfg
.termspeed
)-1);
778 if (HIWORD(wParam
) == EN_CHANGE
)
779 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
780 sizeof(cfg
.username
)-1);
784 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
787 if (HIWORD(wParam
) == BN_CLICKED
||
788 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
789 char str
[sizeof(cfg
.environmt
)];
791 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
796 p
= str
+ strlen(str
);
798 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
808 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
810 p
[strlen(str
)+1] = '\0';
811 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
813 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
814 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
816 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
817 MB_OK
| MB_ICONERROR
);
822 if (HIWORD(wParam
) != BN_CLICKED
&&
823 HIWORD(wParam
) != BN_DOUBLECLICKED
)
825 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
831 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
858 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
861 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
862 WPARAM wParam
, LPARAM lParam
) {
865 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
866 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
867 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
870 switch (LOWORD(wParam
)) {
872 if (HIWORD(wParam
) == EN_CHANGE
)
873 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
874 sizeof(cfg
.termtype
)-1);
877 if (HIWORD(wParam
) == EN_CHANGE
)
878 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
879 sizeof(cfg
.username
)-1);
882 if (HIWORD(wParam
) == BN_CLICKED
||
883 HIWORD(wParam
) == BN_DOUBLECLICKED
)
884 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
889 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
892 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
893 WPARAM wParam
, LPARAM lParam
) {
898 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
899 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
901 static int tabs
[4] = {25, 61, 96, 128};
902 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
905 for (i
=0; i
<256; i
++) {
907 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
908 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
910 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
915 switch (LOWORD(wParam
)) {
918 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
924 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
929 for (i
=0; i
<256; i
++)
930 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
934 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
935 LB_DELETESTRING
, i
, 0);
936 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
937 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
939 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
949 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
952 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
953 WPARAM wParam
, LPARAM lParam
) {
954 static const char *const colours
[] = {
955 "Default Foreground", "Default Bold Foreground",
956 "Default Background", "Default Bold Background",
957 "Cursor Text", "Cursor Colour",
958 "ANSI Black", "ANSI Black Bold",
959 "ANSI Red", "ANSI Red Bold",
960 "ANSI Green", "ANSI Green Bold",
961 "ANSI Yellow", "ANSI Yellow Bold",
962 "ANSI Blue", "ANSI Blue Bold",
963 "ANSI Magenta", "ANSI Magenta Bold",
964 "ANSI Cyan", "ANSI Cyan Bold",
965 "ANSI White", "ANSI White Bold"
967 static const int permanent
[] = {
968 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
969 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
970 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
974 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
975 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
979 if (cfg
.bold_colour
|| permanent
[i
])
980 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
981 (LPARAM
) colours
[i
]);
983 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
984 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
985 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
986 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
989 switch (LOWORD(wParam
)) {
990 case IDC5_BOLDCOLOUR
:
991 if (HIWORD(wParam
) == BN_CLICKED
||
992 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
994 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
995 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
996 if (cfg
.bold_colour
&& n
!=22) {
999 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1001 (LPARAM
) colours
[i
]);
1002 } else if (!cfg
.bold_colour
&& n
!=12) {
1005 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1006 LB_DELETESTRING
, i
, 0);
1011 if (HIWORD(wParam
) == BN_CLICKED
||
1012 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1013 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1016 if (HIWORD(wParam
) == LBN_DBLCLK
||
1017 HIWORD(wParam
) == LBN_SELCHANGE
) {
1018 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1020 if (!cfg
.bold_colour
)
1021 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1022 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1023 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1024 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1028 if (HIWORD(wParam
) == BN_CLICKED
||
1029 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1030 static CHOOSECOLOR cc
;
1031 static DWORD custom
[16] = {0}; /* zero initialisers */
1032 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1034 if (!cfg
.bold_colour
)
1035 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1036 cc
.lStructSize
= sizeof(cc
);
1037 cc
.hwndOwner
= hwnd
;
1038 cc
.hInstance
= hinst
;
1039 cc
.lpCustColors
= custom
;
1040 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1042 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1043 if (ChooseColor(&cc
)) {
1045 (unsigned char) (cc
.rgbResult
& 0xFF);
1047 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1049 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1050 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1052 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1054 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1062 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1065 static DLGPROC panelproc
[NPANELS
] = {
1066 ConnectionProc
, KeyboardProc
, TerminalProc
,
1067 TelnetProc
, SshProc
, SelectionProc
, ColourProc
1069 static char *panelids
[NPANELS
] = {
1070 MAKEINTRESOURCE(IDD_PANEL0
),
1071 MAKEINTRESOURCE(IDD_PANEL1
),
1072 MAKEINTRESOURCE(IDD_PANEL2
),
1073 MAKEINTRESOURCE(IDD_PANEL3
),
1074 MAKEINTRESOURCE(IDD_PANEL35
),
1075 MAKEINTRESOURCE(IDD_PANEL4
),
1076 MAKEINTRESOURCE(IDD_PANEL5
)
1078 static char *names
[NPANELS
] = {
1079 "Connection", "Keyboard", "Terminal", "Telnet", "SSH", "Selection", "Colours"
1082 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6 };
1083 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6 };
1085 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1086 WPARAM wParam
, LPARAM lParam
,
1087 int npanels
, int *panelnums
, HWND
*page
) {
1092 { /* centre the window */
1095 hw
= GetDesktopWindow();
1096 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1097 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1098 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1099 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1102 { /* initialise the tab control */
1106 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1107 for (i
=0; i
<npanels
; i
++) {
1108 tab
.mask
= TCIF_TEXT
;
1109 tab
.pszText
= names
[panelnums
[i
]];
1110 TabCtrl_InsertItem (hw
, i
, &tab
);
1112 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1113 hwnd, panelproc[panelnums[0]]);*/
1114 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1115 hwnd
, panelproc
[panelnums
[0]]);
1116 SetWindowLong (*page
, GWL_EXSTYLE
,
1117 GetWindowLong (*page
, GWL_EXSTYLE
) |
1118 WS_EX_CONTROLPARENT
);
1123 if (LOWORD(wParam
) == IDC_TAB
&&
1124 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1125 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1127 DestroyWindow (*page
);
1128 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1129 hwnd, panelproc[panelnums[i]]);*/
1130 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1131 hwnd
, panelproc
[panelnums
[i
]]);
1132 SetWindowLong (*page
, GWL_EXSTYLE
,
1133 GetWindowLong (*page
, GWL_EXSTYLE
) |
1134 WS_EX_CONTROLPARENT
);
1135 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1139 /* case WM_CTLCOLORDLG: */
1140 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1142 switch (LOWORD(wParam
)) {
1145 EndDialog (hwnd
, 1);
1150 EndDialog (hwnd
, 0);
1155 EndDialog (hwnd
, 0);
1161 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1162 WPARAM wParam
, LPARAM lParam
) {
1167 static HWND page
= NULL
;
1169 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1172 * If the Connection panel is active and the Session List
1173 * box is selected, we treat a press of Open to have an
1174 * implicit press of Load preceding it.
1176 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1177 i
= TabCtrl_GetCurSel(hw
);
1178 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1179 page
&& implicit_load_ok
) {
1180 SendMessage (page
, WM_COMMAND
,
1181 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1185 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1186 EnableWindow(hwnd
, 0);
1187 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1188 GetParent(hwnd
), AboutProc
);
1189 EnableWindow(hwnd
, 1);
1191 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1192 MAIN_NPANELS
, mainp
, &page
);
1195 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1196 WPARAM wParam
, LPARAM lParam
) {
1198 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1199 RECONF_NPANELS
, reconfp
, &page
);
1202 static void get_sesslist(int allocate
) {
1203 static char *buffer
;
1204 int buflen
, bufsize
, i
, ret
;
1205 char otherbuf
[2048];
1210 if (RegCreateKey(HKEY_CURRENT_USER
,
1211 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1214 buflen
= bufsize
= 0;
1218 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1219 if (ret
== ERROR_SUCCESS
) {
1220 bufsize
= buflen
+ 2048;
1221 buffer
= srealloc(buffer
, bufsize
);
1222 unmungestr(otherbuf
, buffer
+buflen
);
1223 buflen
+= strlen(buffer
+buflen
)+1;
1225 } while (ret
== ERROR_SUCCESS
);
1226 buffer
= srealloc(buffer
, buflen
+1);
1227 buffer
[buflen
] = '\0';
1230 nsessions
= 1; /* "Default Settings" counts as one */
1232 if (strcmp(p
, "Default Settings"))
1238 sessions
= smalloc(nsessions
* sizeof(char *));
1239 sessions
[0] = "Default Settings";
1243 if (strcmp(p
, "Default Settings"))
1254 int do_config (void) {
1258 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1259 get_sesslist(FALSE
);
1264 int do_reconfig (HWND hwnd
) {
1268 backup_cfg
= cfg
; /* structure copy */
1269 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1271 cfg
= backup_cfg
; /* structure copy */
1275 void do_defaults (char *session
) {
1277 load_settings (session
, TRUE
);
1279 load_settings ("Default Settings", FALSE
);
1282 void lognegot (char *string
) {
1283 if (nnegots
>= negsize
) {
1285 negots
= srealloc (negots
, negsize
* sizeof(*negots
));
1287 negots
[nnegots
] = smalloc(1+strlen(string
));
1288 strcpy (negots
[nnegots
], string
);
1291 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1295 void shownegot (HWND hwnd
) {
1297 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1299 ShowWindow (logbox
, SW_SHOWNORMAL
);
1303 void showabout (HWND hwnd
) {
1305 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1307 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1311 void verify_ssh_host_key(char *host
, struct RSAKey
*key
) {
1312 char *keystr
, *otherstr
, *mungedhost
;
1317 * Format the key into a string.
1319 len
= rsastr_len(key
);
1320 keystr
= malloc(len
);
1322 fatalbox("Out of memory");
1323 rsastr_fmt(keystr
, key
);
1326 * Now read a saved key in from the registry and see what it
1329 otherstr
= malloc(len
);
1330 mungedhost
= malloc(3*strlen(host
)+1);
1331 if (!otherstr
|| !mungedhost
)
1332 fatalbox("Out of memory");
1334 mungestr(host
, mungedhost
);
1336 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1337 &rkey
) != ERROR_SUCCESS
) {
1338 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1339 "in the registry. There is thus no way to tell\n"
1340 "if the remote host is what you think it is.\n"
1341 "Connect anyway?", "PuTTY Problem",
1342 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1345 DWORD readlen
= len
;
1349 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1350 &type
, otherstr
, &readlen
);
1352 if (ret
== ERROR_MORE_DATA
||
1353 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1354 strcmp(otherstr
, keystr
))) {
1355 if (MessageBox(NULL
,
1356 "This host's host key is different from the\n"
1357 "one cached in the registry! Someone may be\n"
1358 "impersonating this host for malicious reasons;\n"
1359 "alternatively, the host key may have changed\n"
1360 "due to sloppy system administration.\n"
1361 "Replace key in registry and connect?",
1362 "PuTTY: Security Warning",
1363 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1365 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1367 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1368 if (MessageBox(NULL
,
1369 "This host's host key is not cached in the\n"
1370 "registry. Do you want to add it to the cache\n"
1371 "and carry on connecting?",
1373 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1375 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,