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
) {
46 if (*in
== '%' && in
[1] && in
[2]) {
49 i
= in
[1] - '0'; i
-= (i
> 9 ?
7 : 0);
50 j
= in
[2] - '0'; j
-= (j
> 9 ?
7 : 0);
61 static void wpps(HKEY key
, LPCTSTR name
, LPCTSTR value
) {
62 RegSetValueEx(key
, name
, 0, REG_SZ
, value
, 1+strlen(value
));
65 static void wppi(HKEY key
, LPCTSTR name
, int value
) {
66 RegSetValueEx(key
, name
, 0, REG_DWORD
,
67 (CONST BYTE
*)&value
, sizeof(value
));
70 static void gpps(HKEY key
, LPCTSTR name
, LPCTSTR def
,
71 LPTSTR val
, int len
) {
76 RegQueryValueEx(key
, name
, 0, &type
, val
, &size
) != ERROR_SUCCESS
||
78 strncpy(val
, def
, len
);
83 static void gppi(HKEY key
, LPCTSTR name
, int def
, int *i
) {
84 DWORD type
, val
, size
;
88 RegQueryValueEx(key
, name
, 0, &type
,
89 (BYTE
*)&val
, &size
) != ERROR_SUCCESS
||
90 size
!= sizeof(val
) || type
!= REG_DWORD
)
96 static HINSTANCE hinst
;
98 static char **sessions
;
101 static int readytogo
;
103 static void save_settings (char *section
, int do_host
) {
105 HKEY subkey1
, sesskey
;
108 p
= malloc(3*strlen(section
)+1);
109 mungestr(section
, p
);
111 if (RegCreateKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
)!=ERROR_SUCCESS
||
112 RegCreateKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
117 RegCloseKey(subkey1
);
119 wppi (sesskey
, "Present", 1);
121 wpps (sesskey
, "HostName", cfg
.host
);
122 wppi (sesskey
, "PortNumber", cfg
.port
);
123 wpps (sesskey
, "Protocol",
124 cfg
.protocol
== PROT_SSH ?
"ssh" : "telnet");
126 wppi (sesskey
, "CloseOnExit", !!cfg
.close_on_exit
);
127 wpps (sesskey
, "TerminalType", cfg
.termtype
);
128 wpps (sesskey
, "TerminalSpeed", cfg
.termspeed
);
130 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
136 if (c
== '=' || c
== ',' || c
== '\\')
146 wpps (sesskey
, "Environment", buf
);
148 wpps (sesskey
, "UserName", cfg
.username
);
149 wppi (sesskey
, "NoPTY", cfg
.nopty
);
150 wpps (sesskey
, "Cipher", cfg
.cipher
== CIPHER_BLOWFISH ?
"blowfish" :
151 cfg
.cipher
== CIPHER_DES ?
"des" : "3des");
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
;
215 p
= malloc(3*strlen(section
)+1);
216 mungestr(section
, p
);
218 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
) {
221 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
224 RegCloseKey(subkey1
);
229 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
230 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
231 gpps (sesskey
, "Protocol", "default", prot
, 10);
232 if (!strcmp(prot
, "ssh"))
233 cfg
.protocol
= PROT_SSH
;
234 else if (!strcmp(prot
, "telnet"))
235 cfg
.protocol
= PROT_TELNET
;
237 cfg
.protocol
= default_protocol
;
239 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
240 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
241 sizeof(cfg
.termtype
));
242 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
243 sizeof(cfg
.termspeed
));
245 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
246 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
250 while (*p
&& *p
!= ',') {
263 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
264 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
267 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
268 if (!strcmp(cipher
, "blowfish"))
269 cfg
.cipher
= CIPHER_BLOWFISH
;
270 else if (!strcmp(cipher
, "des"))
271 cfg
.cipher
= CIPHER_DES
;
273 cfg
.cipher
= CIPHER_3DES
;
275 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
276 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
277 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
278 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.linux_funkeys
);
279 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
280 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
281 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
282 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
283 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
284 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
285 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
286 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
287 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
288 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
289 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
290 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
291 gppi (sesskey
, "FontVTMode", VT_POORMAN
, &cfg
.vtmode
);
292 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
293 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
294 for (i
=0; i
<22; i
++) {
295 static char *defaults
[] = {
296 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
297 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
298 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
299 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
300 "85,255,255", "187,187,187", "255,255,255"
302 char buf
[20], buf2
[30];
303 sprintf(buf
, "Colour%d", i
);
304 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
305 sscanf(buf2
, "%d,%d,%d", &cfg
.colours
[i
][0],
306 &cfg
.colours
[i
][1], &cfg
.colours
[i
][2]);
308 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
309 for (i
=0; i
<256; i
+=32) {
310 static char *defaults
[] = {
311 "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",
312 "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",
313 "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",
314 "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",
315 "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",
316 "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",
317 "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",
318 "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"
320 char buf
[20], buf2
[256], *p
;
322 sprintf(buf
, "Wordness%d", i
);
323 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
325 for (j
=i
; j
<i
+32; j
++) {
327 while (*p
&& *p
!= ',') p
++;
328 if (*p
== ',') *p
++ = '\0';
329 cfg
.wordness
[j
] = atoi(q
);
332 RegCloseKey(sesskey
);
335 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
338 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
343 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
344 WPARAM wParam
, LPARAM lParam
) {
349 for (i
=0; i
<nnegots
; i
++)
350 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
351 0, (LPARAM
)negots
[i
]);
353 /* case WM_CTLCOLORDLG: */
354 /* return (int) GetStockObject (LTGRAY_BRUSH); */
356 switch (LOWORD(wParam
)) {
359 DestroyWindow (hwnd
);
365 DestroyWindow (hwnd
);
371 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
372 WPARAM wParam
, LPARAM lParam
) {
377 switch (LOWORD(wParam
)) {
380 DestroyWindow (hwnd
);
386 DestroyWindow (hwnd
);
392 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
393 WPARAM wParam
, LPARAM lParam
) {
396 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
398 /* case WM_CTLCOLORDLG: */
399 /* return (int) GetStockObject (LTGRAY_BRUSH); */
400 /* case WM_CTLCOLORSTATIC: */
401 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
402 /* return (int) GetStockObject (LTGRAY_BRUSH); */
404 switch (LOWORD(wParam
)) {
407 DestroyWindow (hwnd
);
410 EnableWindow(hwnd
, 0);
411 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
413 EnableWindow(hwnd
, 1);
419 DestroyWindow (hwnd
);
425 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
426 WPARAM wParam
, LPARAM lParam
) {
429 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
431 /* case WM_CTLCOLORDLG: */
432 /* return (int) GetStockObject (LTGRAY_BRUSH); */
433 /* case WM_CTLCOLORSTATIC: */
434 /* case WM_CTLCOLORBTN: */
435 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
436 /* return (int) GetStockObject (LTGRAY_BRUSH); */
438 DestroyWindow (hwnd
);
444 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
445 WPARAM wParam
, LPARAM lParam
) {
450 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
451 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
452 for (i
= 0; i
< nsessions
; i
++)
453 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
454 0, (LPARAM
) (sessions
[i
]));
455 CheckRadioButton (hwnd
, IDC0_PROTTELNET
, IDC0_PROTSSH
,
456 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
: IDC0_PROTTELNET
);
457 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
461 * Button release should trigger WM_OK if there was a
462 * previous double click on the session list.
466 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
469 switch (LOWORD(wParam
)) {
470 case IDC0_PROTTELNET
:
472 if (HIWORD(wParam
) == BN_CLICKED
||
473 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
474 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
475 cfg
.protocol
= i ? PROT_SSH
: PROT_TELNET
;
476 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
477 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
478 cfg
.port
= i ?
22 : 23;
479 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
484 if (HIWORD(wParam
) == EN_CHANGE
)
485 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
489 if (HIWORD(wParam
) == EN_CHANGE
)
490 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
493 if (HIWORD(wParam
) == BN_CLICKED
||
494 HIWORD(wParam
) == BN_DOUBLECLICKED
)
495 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
498 if (HIWORD(wParam
) == EN_CHANGE
)
499 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
503 if (HIWORD(wParam
) == BN_CLICKED
||
504 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
509 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
511 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
517 strcpy (str
, sessions
[n
]);
519 save_settings (str
, !!strcmp(str
, "Default Settings"));
520 get_sesslist (FALSE
);
522 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
524 for (i
= 0; i
< nsessions
; i
++)
525 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
526 0, (LPARAM
) (sessions
[i
]));
527 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
533 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
534 HIWORD(wParam
) != BN_CLICKED
&&
535 HIWORD(wParam
) != BN_DOUBLECLICKED
)
537 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
538 HIWORD(wParam
) != LBN_DBLCLK
)
541 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
547 load_settings (sessions
[n
],
548 !!strcmp(sessions
[n
], "Default Settings"));
549 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
550 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
551 CheckRadioButton (hwnd
, IDC0_PROTTELNET
, IDC0_PROTSSH
,
552 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
554 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
555 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
558 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
560 * A double-click on a saved session should
561 * actually start the session, not just load it.
562 * Unless it's Default Settings or some other
563 * host-less set of saved settings.
572 if (HIWORD(wParam
) == BN_CLICKED
||
573 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
574 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
576 if (n
== LB_ERR
|| n
== 0) {
580 del_session(sessions
[n
]);
581 get_sesslist (FALSE
);
583 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
585 for (i
= 0; i
< nsessions
; i
++)
586 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
587 0, (LPARAM
) (sessions
[i
]));
588 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
593 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
596 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
597 WPARAM wParam
, LPARAM lParam
) {
600 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
601 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
602 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
603 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
604 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCLINUX
,
605 cfg
.linux_funkeys ? IDC1_FUNCLINUX
: IDC1_FUNCTILDE
);
606 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
607 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
608 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPAPPLIC
,
609 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
612 if (HIWORD(wParam
) == BN_CLICKED
||
613 HIWORD(wParam
) == BN_DOUBLECLICKED
)
614 switch (LOWORD(wParam
)) {
617 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
621 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
625 cfg
.linux_funkeys
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
629 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
633 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
637 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
640 static void fmtfont (char *buf
) {
641 sprintf (buf
, "Font: %s, ", cfg
.font
);
643 strcat(buf
, "bold, ");
644 if (cfg
.fontheight
== 0)
645 strcat (buf
, "default height");
647 sprintf (buf
+strlen(buf
), "%d-%s",
648 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
649 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
652 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
653 WPARAM wParam
, LPARAM lParam
) {
656 char fontstatic
[256];
660 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
661 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
662 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
663 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
664 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
665 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
666 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
667 fmtfont (fontstatic
);
668 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
669 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
670 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
671 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
672 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
676 switch (LOWORD(wParam
)) {
678 if (HIWORD(wParam
) == BN_CLICKED
||
679 HIWORD(wParam
) == BN_DOUBLECLICKED
)
680 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
683 if (HIWORD(wParam
) == BN_CLICKED
||
684 HIWORD(wParam
) == BN_DOUBLECLICKED
)
685 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
688 if (HIWORD(wParam
) == BN_CLICKED
||
689 HIWORD(wParam
) == BN_DOUBLECLICKED
)
690 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
693 if (HIWORD(wParam
) == BN_CLICKED
||
694 HIWORD(wParam
) == BN_DOUBLECLICKED
)
695 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
698 if (HIWORD(wParam
) == EN_CHANGE
)
699 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
702 if (HIWORD(wParam
) == EN_CHANGE
)
703 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
706 if (HIWORD(wParam
) == EN_CHANGE
)
707 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
709 case IDC2_CHOOSEFONT
:
710 lf
.lfHeight
= cfg
.fontheight
;
711 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
712 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
713 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
714 lf
.lfCharSet
= ANSI_CHARSET
;
715 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
716 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
717 lf
.lfQuality
= DEFAULT_QUALITY
;
718 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
719 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
720 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
722 cf
.lStructSize
= sizeof(cf
);
725 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
726 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
728 if (ChooseFont (&cf
)) {
729 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
730 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
731 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
732 cfg
.fontheight
= lf
.lfHeight
;
733 fmtfont (fontstatic
);
734 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
737 case IDC2_VTXWINDOWS
:
742 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
743 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
744 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
750 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
753 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
754 WPARAM wParam
, LPARAM lParam
) {
759 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
760 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
761 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
763 char *p
= cfg
.environmt
;
765 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
770 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
771 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
774 switch (LOWORD(wParam
)) {
776 if (HIWORD(wParam
) == EN_CHANGE
)
777 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
778 sizeof(cfg
.termtype
)-1);
781 if (HIWORD(wParam
) == EN_CHANGE
)
782 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
783 sizeof(cfg
.termspeed
)-1);
786 if (HIWORD(wParam
) == EN_CHANGE
)
787 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
788 sizeof(cfg
.username
)-1);
792 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
795 if (HIWORD(wParam
) == BN_CLICKED
||
796 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
797 char str
[sizeof(cfg
.environmt
)];
799 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
804 p
= str
+ strlen(str
);
806 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
816 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
818 p
[strlen(str
)+1] = '\0';
819 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
821 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
822 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
824 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
825 MB_OK
| MB_ICONERROR
);
830 if (HIWORD(wParam
) != BN_CLICKED
&&
831 HIWORD(wParam
) != BN_DOUBLECLICKED
)
833 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
839 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
866 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
869 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
870 WPARAM wParam
, LPARAM lParam
) {
873 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
874 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
875 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
876 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
877 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
878 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
883 switch (LOWORD(wParam
)) {
885 if (HIWORD(wParam
) == EN_CHANGE
)
886 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
887 sizeof(cfg
.termtype
)-1);
890 if (HIWORD(wParam
) == EN_CHANGE
)
891 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
892 sizeof(cfg
.username
)-1);
895 if (HIWORD(wParam
) == BN_CLICKED
||
896 HIWORD(wParam
) == BN_DOUBLECLICKED
)
897 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
899 case IDC3_CIPHER3DES
:
900 case IDC3_CIPHERBLOWF
:
902 if (HIWORD(wParam
) == BN_CLICKED
||
903 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
904 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
905 cfg
.cipher
= CIPHER_3DES
;
906 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
907 cfg
.cipher
= CIPHER_BLOWFISH
;
908 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
909 cfg
.cipher
= CIPHER_DES
;
915 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
918 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
919 WPARAM wParam
, LPARAM lParam
) {
924 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
925 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
927 static int tabs
[4] = {25, 61, 96, 128};
928 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
931 for (i
=0; i
<256; i
++) {
933 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
934 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
936 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
941 switch (LOWORD(wParam
)) {
944 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
950 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
955 for (i
=0; i
<256; i
++)
956 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
960 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
961 LB_DELETESTRING
, i
, 0);
962 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
963 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
965 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
975 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
978 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
979 WPARAM wParam
, LPARAM lParam
) {
980 static const char *const colours
[] = {
981 "Default Foreground", "Default Bold Foreground",
982 "Default Background", "Default Bold Background",
983 "Cursor Text", "Cursor Colour",
984 "ANSI Black", "ANSI Black Bold",
985 "ANSI Red", "ANSI Red Bold",
986 "ANSI Green", "ANSI Green Bold",
987 "ANSI Yellow", "ANSI Yellow Bold",
988 "ANSI Blue", "ANSI Blue Bold",
989 "ANSI Magenta", "ANSI Magenta Bold",
990 "ANSI Cyan", "ANSI Cyan Bold",
991 "ANSI White", "ANSI White Bold"
993 static const int permanent
[] = {
994 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
995 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
996 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1000 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1001 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1004 for (i
=0; i
<22; i
++)
1005 if (cfg
.bold_colour
|| permanent
[i
])
1006 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1007 (LPARAM
) colours
[i
]);
1009 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1010 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1011 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1012 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1015 switch (LOWORD(wParam
)) {
1016 case IDC5_BOLDCOLOUR
:
1017 if (HIWORD(wParam
) == BN_CLICKED
||
1018 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1020 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1021 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1022 if (cfg
.bold_colour
&& n
!=22) {
1023 for (i
=0; i
<22; i
++)
1025 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1027 (LPARAM
) colours
[i
]);
1028 } else if (!cfg
.bold_colour
&& n
!=12) {
1031 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1032 LB_DELETESTRING
, i
, 0);
1037 if (HIWORD(wParam
) == BN_CLICKED
||
1038 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1039 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1042 if (HIWORD(wParam
) == LBN_DBLCLK
||
1043 HIWORD(wParam
) == LBN_SELCHANGE
) {
1044 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1046 if (!cfg
.bold_colour
)
1047 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1048 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1049 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1050 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1054 if (HIWORD(wParam
) == BN_CLICKED
||
1055 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1056 static CHOOSECOLOR cc
;
1057 static DWORD custom
[16] = {0}; /* zero initialisers */
1058 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1060 if (!cfg
.bold_colour
)
1061 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1062 cc
.lStructSize
= sizeof(cc
);
1063 cc
.hwndOwner
= hwnd
;
1064 cc
.hInstance
= hinst
;
1065 cc
.lpCustColors
= custom
;
1066 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1068 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1069 if (ChooseColor(&cc
)) {
1071 (unsigned char) (cc
.rgbResult
& 0xFF);
1073 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1075 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1076 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1078 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1080 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1088 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1091 static DLGPROC panelproc
[NPANELS
] = {
1092 ConnectionProc
, KeyboardProc
, TerminalProc
,
1093 TelnetProc
, SshProc
, SelectionProc
, ColourProc
1095 static char *panelids
[NPANELS
] = {
1096 MAKEINTRESOURCE(IDD_PANEL0
),
1097 MAKEINTRESOURCE(IDD_PANEL1
),
1098 MAKEINTRESOURCE(IDD_PANEL2
),
1099 MAKEINTRESOURCE(IDD_PANEL3
),
1100 MAKEINTRESOURCE(IDD_PANEL35
),
1101 MAKEINTRESOURCE(IDD_PANEL4
),
1102 MAKEINTRESOURCE(IDD_PANEL5
)
1104 static char *names
[NPANELS
] = {
1105 "Connection", "Keyboard", "Terminal", "Telnet", "SSH", "Selection", "Colours"
1108 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6 };
1109 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6 };
1111 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1112 WPARAM wParam
, LPARAM lParam
,
1113 int npanels
, int *panelnums
, HWND
*page
) {
1118 { /* centre the window */
1121 hw
= GetDesktopWindow();
1122 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1123 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1124 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1125 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1128 { /* initialise the tab control */
1132 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1133 for (i
=0; i
<npanels
; i
++) {
1134 tab
.mask
= TCIF_TEXT
;
1135 tab
.pszText
= names
[panelnums
[i
]];
1136 TabCtrl_InsertItem (hw
, i
, &tab
);
1138 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1139 hwnd, panelproc[panelnums[0]]);*/
1140 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1141 hwnd
, panelproc
[panelnums
[0]]);
1142 SetWindowLong (*page
, GWL_EXSTYLE
,
1143 GetWindowLong (*page
, GWL_EXSTYLE
) |
1144 WS_EX_CONTROLPARENT
);
1149 if (LOWORD(wParam
) == IDC_TAB
&&
1150 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1151 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1153 DestroyWindow (*page
);
1154 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1155 hwnd, panelproc[panelnums[i]]);*/
1156 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1157 hwnd
, panelproc
[panelnums
[i
]]);
1158 SetWindowLong (*page
, GWL_EXSTYLE
,
1159 GetWindowLong (*page
, GWL_EXSTYLE
) |
1160 WS_EX_CONTROLPARENT
);
1161 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1165 /* case WM_CTLCOLORDLG: */
1166 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1168 switch (LOWORD(wParam
)) {
1171 EndDialog (hwnd
, 1);
1176 EndDialog (hwnd
, 0);
1181 EndDialog (hwnd
, 0);
1187 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1188 WPARAM wParam
, LPARAM lParam
) {
1193 static HWND page
= NULL
;
1195 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1198 * If the Connection panel is active and the Session List
1199 * box is selected, we treat a press of Open to have an
1200 * implicit press of Load preceding it.
1202 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1203 i
= TabCtrl_GetCurSel(hw
);
1204 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1205 page
&& implicit_load_ok
) {
1206 SendMessage (page
, WM_COMMAND
,
1207 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1211 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1212 EnableWindow(hwnd
, 0);
1213 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1214 GetParent(hwnd
), AboutProc
);
1215 EnableWindow(hwnd
, 1);
1217 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1218 MAIN_NPANELS
, mainp
, &page
);
1221 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1222 WPARAM wParam
, LPARAM lParam
) {
1224 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1225 RECONF_NPANELS
, reconfp
, &page
);
1228 static void get_sesslist(int allocate
) {
1229 static char *buffer
;
1230 int buflen
, bufsize
, i
, ret
;
1231 char otherbuf
[2048];
1236 if (RegCreateKey(HKEY_CURRENT_USER
,
1237 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1240 buflen
= bufsize
= 0;
1244 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1245 if (ret
== ERROR_SUCCESS
) {
1246 bufsize
= buflen
+ 2048;
1247 buffer
= srealloc(buffer
, bufsize
);
1248 unmungestr(otherbuf
, buffer
+buflen
);
1249 buflen
+= strlen(buffer
+buflen
)+1;
1251 } while (ret
== ERROR_SUCCESS
);
1252 buffer
= srealloc(buffer
, buflen
+1);
1253 buffer
[buflen
] = '\0';
1256 nsessions
= 1; /* "Default Settings" counts as one */
1258 if (strcmp(p
, "Default Settings"))
1264 sessions
= smalloc(nsessions
* sizeof(char *));
1265 sessions
[0] = "Default Settings";
1269 if (strcmp(p
, "Default Settings"))
1280 int do_config (void) {
1284 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1285 get_sesslist(FALSE
);
1290 int do_reconfig (HWND hwnd
) {
1294 backup_cfg
= cfg
; /* structure copy */
1295 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1297 cfg
= backup_cfg
; /* structure copy */
1301 void do_defaults (char *session
) {
1303 load_settings (session
, TRUE
);
1305 load_settings ("Default Settings", FALSE
);
1308 void lognegot (char *string
) {
1309 if (nnegots
>= negsize
) {
1311 negots
= srealloc (negots
, negsize
* sizeof(*negots
));
1313 negots
[nnegots
] = smalloc(1+strlen(string
));
1314 strcpy (negots
[nnegots
], string
);
1317 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1321 void shownegot (HWND hwnd
) {
1323 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1325 ShowWindow (logbox
, SW_SHOWNORMAL
);
1329 void showabout (HWND hwnd
) {
1331 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1333 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1337 void verify_ssh_host_key(char *host
, struct RSAKey
*key
) {
1338 char *keystr
, *otherstr
, *mungedhost
;
1343 * Format the key into a string.
1345 len
= rsastr_len(key
);
1346 keystr
= malloc(len
);
1348 fatalbox("Out of memory");
1349 rsastr_fmt(keystr
, key
);
1352 * Now read a saved key in from the registry and see what it
1355 otherstr
= malloc(len
);
1356 mungedhost
= malloc(3*strlen(host
)+1);
1357 if (!otherstr
|| !mungedhost
)
1358 fatalbox("Out of memory");
1360 mungestr(host
, mungedhost
);
1362 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1363 &rkey
) != ERROR_SUCCESS
) {
1364 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1365 "in the registry. There is thus no way to tell\n"
1366 "if the remote host is what you think it is.\n"
1367 "Connect anyway?", "PuTTY Problem",
1368 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1371 DWORD readlen
= len
;
1375 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1376 &type
, otherstr
, &readlen
);
1378 if (ret
== ERROR_MORE_DATA
||
1379 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1380 strcmp(otherstr
, keystr
))) {
1381 if (MessageBox(NULL
,
1382 "This host's host key is different from the\n"
1383 "one cached in the registry! Someone may be\n"
1384 "impersonating this host for malicious reasons;\n"
1385 "alternatively, the host key may have changed\n"
1386 "due to sloppy system administration.\n"
1387 "Replace key in registry and connect?",
1388 "PuTTY: Security Warning",
1389 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1391 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1393 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1394 if (MessageBox(NULL
,
1395 "This host's host key is not cached in the\n"
1396 "registry. Do you want to add it to the cache\n"
1397 "and carry on connecting?",
1399 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1401 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,