13 #define MAIN_NPANELS 7
14 #define RECONF_NPANELS 4
16 static const char *const puttystr
= PUTTY_REG_POS
"\\Sessions";
18 static char **negots
= NULL
;
19 static int nnegots
= 0, negsize
= 0;
20 static HWND logbox
= NULL
, abtbox
= NULL
;
22 static char hex
[16] = "0123456789ABCDEF";
24 static void mungestr(char *in
, char *out
) {
28 if (*in
== ' ' || *in
== '\\' || *in
== '*' || *in
== '?' ||
29 *in
== '%' || *in
< ' ' || *in
> '~' || (*in
== '.' && !candot
)) {
31 *out
++ = hex
[((unsigned char)*in
) >> 4];
32 *out
++ = hex
[((unsigned char)*in
) & 15];
42 static void unmungestr(char *in
, char *out
) {
44 if (*in
== '%' && in
[1] && in
[2]) {
47 i
= in
[1] - '0'; i
-= (i
> 9 ?
7 : 0);
48 j
= in
[2] - '0'; j
-= (j
> 9 ?
7 : 0);
59 static void wpps(HKEY key
, LPCTSTR name
, LPCTSTR value
) {
60 RegSetValueEx(key
, name
, 0, REG_SZ
, value
, 1+strlen(value
));
63 static void wppi(HKEY key
, LPCTSTR name
, int value
) {
64 RegSetValueEx(key
, name
, 0, REG_DWORD
,
65 (CONST BYTE
*)&value
, sizeof(value
));
68 static void gpps(HKEY key
, LPCTSTR name
, LPCTSTR def
,
69 LPTSTR val
, int len
) {
74 RegQueryValueEx(key
, name
, 0, &type
, val
, &size
) != ERROR_SUCCESS
||
76 strncpy(val
, def
, len
);
81 static void gppi(HKEY key
, LPCTSTR name
, int def
, int *i
) {
82 DWORD type
, val
, size
;
86 RegQueryValueEx(key
, name
, 0, &type
,
87 (BYTE
*)&val
, &size
) != ERROR_SUCCESS
||
88 size
!= sizeof(val
) || type
!= REG_DWORD
)
94 static HINSTANCE hinst
;
98 static void save_settings (char *section
, int do_host
) {
100 HKEY subkey1
, sesskey
;
103 p
= malloc(3*strlen(section
)+1);
104 mungestr(section
, p
);
106 if (RegCreateKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
)!=ERROR_SUCCESS
||
107 RegCreateKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
112 RegCloseKey(subkey1
);
114 wppi (sesskey
, "Present", 1);
116 wpps (sesskey
, "HostName", cfg
.host
);
117 wppi (sesskey
, "PortNumber", cfg
.port
);
118 wpps (sesskey
, "Protocol",
119 cfg
.protocol
== PROT_SSH ?
"ssh" :
120 cfg
.protocol
== PROT_TELNET ?
"telnet" : "raw" );
122 wppi (sesskey
, "CloseOnExit", !!cfg
.close_on_exit
);
123 wpps (sesskey
, "TerminalType", cfg
.termtype
);
124 wpps (sesskey
, "TerminalSpeed", cfg
.termspeed
);
126 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
132 if (c
== '=' || c
== ',' || c
== '\\')
142 wpps (sesskey
, "Environment", buf
);
144 wpps (sesskey
, "UserName", cfg
.username
);
145 wppi (sesskey
, "NoPTY", cfg
.nopty
);
146 wpps (sesskey
, "Cipher", cfg
.cipher
== CIPHER_BLOWFISH ?
"blowfish" :
147 cfg
.cipher
== CIPHER_DES ?
"des" : "3des");
148 wppi (sesskey
, "RFCEnviron", cfg
.rfc_environ
);
149 wppi (sesskey
, "BackspaceIsDelete", cfg
.bksp_is_delete
);
150 wppi (sesskey
, "RXVTHomeEnd", cfg
.rxvt_homeend
);
151 wppi (sesskey
, "LinuxFunctionKeys", cfg
.linux_funkeys
);
152 wppi (sesskey
, "ApplicationCursorKeys", cfg
.app_cursor
);
153 wppi (sesskey
, "ApplicationKeypad", cfg
.app_keypad
);
154 wppi (sesskey
, "ScrollbackLines", cfg
.savelines
);
155 wppi (sesskey
, "DECOriginMode", cfg
.dec_om
);
156 wppi (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
157 wppi (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
158 wppi (sesskey
, "WinNameAlways", cfg
.win_name_always
);
159 wppi (sesskey
, "TermWidth", cfg
.width
);
160 wppi (sesskey
, "TermHeight", cfg
.height
);
161 wpps (sesskey
, "Font", cfg
.font
);
162 wppi (sesskey
, "FontIsBold", cfg
.fontisbold
);
163 wppi (sesskey
, "FontHeight", cfg
.fontheight
);
164 wppi (sesskey
, "FontVTMode", cfg
.vtmode
);
165 wppi (sesskey
, "TryPalette", cfg
.try_palette
);
166 wppi (sesskey
, "BoldAsColour", cfg
.bold_colour
);
167 for (i
=0; i
<22; i
++) {
168 char buf
[20], buf2
[30];
169 sprintf(buf
, "Colour%d", i
);
170 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
171 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
172 wpps (sesskey
, buf
, buf2
);
174 wppi (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
175 for (i
=0; i
<256; i
+=32) {
176 char buf
[20], buf2
[256];
178 sprintf(buf
, "Wordness%d", i
);
180 for (j
=i
; j
<i
+32; j
++) {
181 sprintf(buf2
+strlen(buf2
), "%s%d",
182 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
184 wpps (sesskey
, buf
, buf2
);
187 RegCloseKey(sesskey
);
190 static void del_session (char *section
) {
194 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
197 p
= malloc(3*strlen(section
)+1);
198 mungestr(section
, p
);
199 RegDeleteKey(subkey1
, p
);
202 RegCloseKey(subkey1
);
205 static void load_settings (char *section
, int do_host
) {
207 HKEY subkey1
, sesskey
;
211 p
= malloc(3*strlen(section
)+1);
212 mungestr(section
, p
);
214 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
) {
217 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
220 RegCloseKey(subkey1
);
225 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
226 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
227 gpps (sesskey
, "Protocol", "default", prot
, 10);
228 if (!strcmp(prot
, "ssh"))
229 cfg
.protocol
= PROT_SSH
;
230 else if (!strcmp(prot
, "telnet"))
231 cfg
.protocol
= PROT_TELNET
;
232 else if (!strcmp(prot
, "raw"))
233 cfg
.protocol
= PROT_RAW
;
235 cfg
.protocol
= default_protocol
;
237 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
238 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
239 sizeof(cfg
.termtype
));
240 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
241 sizeof(cfg
.termspeed
));
243 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
244 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
248 while (*p
&& *p
!= ',') {
261 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
262 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
265 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
266 if (!strcmp(cipher
, "blowfish"))
267 cfg
.cipher
= CIPHER_BLOWFISH
;
268 else if (!strcmp(cipher
, "des"))
269 cfg
.cipher
= CIPHER_DES
;
271 cfg
.cipher
= CIPHER_3DES
;
273 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
274 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
275 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
276 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.linux_funkeys
);
277 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
278 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
279 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
280 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
281 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
282 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
283 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
284 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
285 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
286 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
287 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
288 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
289 gppi (sesskey
, "FontVTMode", VT_POORMAN
, &cfg
.vtmode
);
290 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
291 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
292 for (i
=0; i
<22; i
++) {
293 static char *defaults
[] = {
294 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
295 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
296 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
297 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
298 "85,255,255", "187,187,187", "255,255,255"
300 char buf
[20], buf2
[30];
301 sprintf(buf
, "Colour%d", i
);
302 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
303 sscanf(buf2
, "%d,%d,%d", &cfg
.colours
[i
][0],
304 &cfg
.colours
[i
][1], &cfg
.colours
[i
][2]);
306 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
307 for (i
=0; i
<256; i
+=32) {
308 static char *defaults
[] = {
309 "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",
310 "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",
311 "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",
312 "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",
313 "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",
314 "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",
315 "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",
316 "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 char buf
[20], buf2
[256], *p
;
320 sprintf(buf
, "Wordness%d", i
);
321 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
323 for (j
=i
; j
<i
+32; j
++) {
325 while (*p
&& *p
!= ',') p
++;
326 if (*p
== ',') *p
++ = '\0';
327 cfg
.wordness
[j
] = atoi(q
);
330 RegCloseKey(sesskey
);
333 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
336 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
341 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
342 WPARAM wParam
, LPARAM lParam
) {
347 for (i
=0; i
<nnegots
; i
++)
348 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
349 0, (LPARAM
)negots
[i
]);
351 /* case WM_CTLCOLORDLG: */
352 /* return (int) GetStockObject (LTGRAY_BRUSH); */
354 switch (LOWORD(wParam
)) {
357 DestroyWindow (hwnd
);
363 DestroyWindow (hwnd
);
369 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
370 WPARAM wParam
, LPARAM lParam
) {
375 switch (LOWORD(wParam
)) {
378 DestroyWindow (hwnd
);
384 DestroyWindow (hwnd
);
390 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
391 WPARAM wParam
, LPARAM lParam
) {
394 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
396 /* case WM_CTLCOLORDLG: */
397 /* return (int) GetStockObject (LTGRAY_BRUSH); */
398 /* case WM_CTLCOLORSTATIC: */
399 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
400 /* return (int) GetStockObject (LTGRAY_BRUSH); */
402 switch (LOWORD(wParam
)) {
405 DestroyWindow (hwnd
);
408 EnableWindow(hwnd
, 0);
409 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
411 EnableWindow(hwnd
, 1);
417 DestroyWindow (hwnd
);
423 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
424 WPARAM wParam
, LPARAM lParam
) {
427 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
429 /* case WM_CTLCOLORDLG: */
430 /* return (int) GetStockObject (LTGRAY_BRUSH); */
431 /* case WM_CTLCOLORSTATIC: */
432 /* case WM_CTLCOLORBTN: */
433 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
434 /* return (int) GetStockObject (LTGRAY_BRUSH); */
436 DestroyWindow (hwnd
);
442 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
443 WPARAM wParam
, LPARAM lParam
) {
448 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
449 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
450 for (i
= 0; i
< nsessions
; i
++)
451 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
452 0, (LPARAM
) (sessions
[i
]));
453 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
454 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
455 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
456 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
460 * Button release should trigger WM_OK if there was a
461 * previous double click on the session list.
465 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
468 switch (LOWORD(wParam
)) {
469 case IDC0_PROTTELNET
:
472 if (HIWORD(wParam
) == BN_CLICKED
||
473 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
474 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
475 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
476 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
477 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
478 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
479 cfg
.port
= i ?
22 : 23;
480 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
485 if (HIWORD(wParam
) == EN_CHANGE
)
486 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
490 if (HIWORD(wParam
) == EN_CHANGE
)
491 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
494 if (HIWORD(wParam
) == BN_CLICKED
||
495 HIWORD(wParam
) == BN_DOUBLECLICKED
)
496 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
499 if (HIWORD(wParam
) == EN_CHANGE
)
500 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
504 if (HIWORD(wParam
) == BN_CLICKED
||
505 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
510 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
512 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
518 strcpy (str
, sessions
[n
]);
520 save_settings (str
, !!strcmp(str
, "Default Settings"));
521 get_sesslist (FALSE
);
523 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
525 for (i
= 0; i
< nsessions
; i
++)
526 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
527 0, (LPARAM
) (sessions
[i
]));
528 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
534 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
535 HIWORD(wParam
) != BN_CLICKED
&&
536 HIWORD(wParam
) != BN_DOUBLECLICKED
)
538 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
539 HIWORD(wParam
) != LBN_DBLCLK
)
542 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
548 load_settings (sessions
[n
],
549 !!strcmp(sessions
[n
], "Default Settings"));
550 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
551 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
552 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
553 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
554 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
555 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
556 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
559 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
561 * A double-click on a saved session should
562 * actually start the session, not just load it.
563 * Unless it's Default Settings or some other
564 * host-less set of saved settings.
573 if (HIWORD(wParam
) == BN_CLICKED
||
574 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
575 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
577 if (n
== LB_ERR
|| n
== 0) {
581 del_session(sessions
[n
]);
582 get_sesslist (FALSE
);
584 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
586 for (i
= 0; i
< nsessions
; i
++)
587 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
588 0, (LPARAM
) (sessions
[i
]));
589 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
594 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
597 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
598 WPARAM wParam
, LPARAM lParam
) {
601 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
602 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
603 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
604 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
605 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCLINUX
,
606 cfg
.linux_funkeys ? IDC1_FUNCLINUX
: IDC1_FUNCTILDE
);
607 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
608 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
609 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPAPPLIC
,
610 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
613 if (HIWORD(wParam
) == BN_CLICKED
||
614 HIWORD(wParam
) == BN_DOUBLECLICKED
)
615 switch (LOWORD(wParam
)) {
618 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
622 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
626 cfg
.linux_funkeys
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
630 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
634 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
638 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
641 static void fmtfont (char *buf
) {
642 sprintf (buf
, "Font: %s, ", cfg
.font
);
644 strcat(buf
, "bold, ");
645 if (cfg
.fontheight
== 0)
646 strcat (buf
, "default height");
648 sprintf (buf
+strlen(buf
), "%d-%s",
649 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
650 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
653 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
654 WPARAM wParam
, LPARAM lParam
) {
657 char fontstatic
[256];
661 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
662 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
663 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
664 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
665 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
666 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
667 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
668 fmtfont (fontstatic
);
669 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
670 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
671 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
672 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
673 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
677 switch (LOWORD(wParam
)) {
679 if (HIWORD(wParam
) == BN_CLICKED
||
680 HIWORD(wParam
) == BN_DOUBLECLICKED
)
681 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
684 if (HIWORD(wParam
) == BN_CLICKED
||
685 HIWORD(wParam
) == BN_DOUBLECLICKED
)
686 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
689 if (HIWORD(wParam
) == BN_CLICKED
||
690 HIWORD(wParam
) == BN_DOUBLECLICKED
)
691 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
694 if (HIWORD(wParam
) == BN_CLICKED
||
695 HIWORD(wParam
) == BN_DOUBLECLICKED
)
696 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
699 if (HIWORD(wParam
) == EN_CHANGE
)
700 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
703 if (HIWORD(wParam
) == EN_CHANGE
)
704 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
707 if (HIWORD(wParam
) == EN_CHANGE
)
708 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
710 case IDC2_CHOOSEFONT
:
711 lf
.lfHeight
= cfg
.fontheight
;
712 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
713 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
714 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
715 lf
.lfCharSet
= ANSI_CHARSET
;
716 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
717 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
718 lf
.lfQuality
= DEFAULT_QUALITY
;
719 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
720 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
721 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
723 cf
.lStructSize
= sizeof(cf
);
726 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
727 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
729 if (ChooseFont (&cf
)) {
730 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
731 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
732 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
733 cfg
.fontheight
= lf
.lfHeight
;
734 fmtfont (fontstatic
);
735 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
738 case IDC2_VTXWINDOWS
:
743 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
744 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
745 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
751 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
754 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
755 WPARAM wParam
, LPARAM lParam
) {
760 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
761 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
762 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
764 char *p
= cfg
.environmt
;
766 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
771 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
772 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
775 switch (LOWORD(wParam
)) {
777 if (HIWORD(wParam
) == EN_CHANGE
)
778 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
779 sizeof(cfg
.termtype
)-1);
782 if (HIWORD(wParam
) == EN_CHANGE
)
783 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
784 sizeof(cfg
.termspeed
)-1);
787 if (HIWORD(wParam
) == EN_CHANGE
)
788 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
789 sizeof(cfg
.username
)-1);
793 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
796 if (HIWORD(wParam
) == BN_CLICKED
||
797 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
798 char str
[sizeof(cfg
.environmt
)];
800 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
805 p
= str
+ strlen(str
);
807 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
817 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
819 p
[strlen(str
)+1] = '\0';
820 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
822 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
823 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
825 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
826 MB_OK
| MB_ICONERROR
);
831 if (HIWORD(wParam
) != BN_CLICKED
&&
832 HIWORD(wParam
) != BN_DOUBLECLICKED
)
834 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
840 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
867 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
870 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
871 WPARAM wParam
, LPARAM lParam
) {
874 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
875 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
876 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
877 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
878 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
879 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
884 switch (LOWORD(wParam
)) {
886 if (HIWORD(wParam
) == EN_CHANGE
)
887 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
888 sizeof(cfg
.termtype
)-1);
891 if (HIWORD(wParam
) == EN_CHANGE
)
892 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
893 sizeof(cfg
.username
)-1);
896 if (HIWORD(wParam
) == BN_CLICKED
||
897 HIWORD(wParam
) == BN_DOUBLECLICKED
)
898 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
900 case IDC3_CIPHER3DES
:
901 case IDC3_CIPHERBLOWF
:
903 if (HIWORD(wParam
) == BN_CLICKED
||
904 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
905 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
906 cfg
.cipher
= CIPHER_3DES
;
907 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
908 cfg
.cipher
= CIPHER_BLOWFISH
;
909 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
910 cfg
.cipher
= CIPHER_DES
;
916 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
919 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
920 WPARAM wParam
, LPARAM lParam
) {
925 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
926 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
928 static int tabs
[4] = {25, 61, 96, 128};
929 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
932 for (i
=0; i
<256; i
++) {
934 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
935 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
937 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
942 switch (LOWORD(wParam
)) {
945 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
951 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
956 for (i
=0; i
<256; i
++)
957 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
961 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
962 LB_DELETESTRING
, i
, 0);
963 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
964 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
966 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
976 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
979 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
980 WPARAM wParam
, LPARAM lParam
) {
981 static const char *const colours
[] = {
982 "Default Foreground", "Default Bold Foreground",
983 "Default Background", "Default Bold Background",
984 "Cursor Text", "Cursor Colour",
985 "ANSI Black", "ANSI Black Bold",
986 "ANSI Red", "ANSI Red Bold",
987 "ANSI Green", "ANSI Green Bold",
988 "ANSI Yellow", "ANSI Yellow Bold",
989 "ANSI Blue", "ANSI Blue Bold",
990 "ANSI Magenta", "ANSI Magenta Bold",
991 "ANSI Cyan", "ANSI Cyan Bold",
992 "ANSI White", "ANSI White Bold"
994 static const int permanent
[] = {
995 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
996 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
997 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1001 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1002 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1005 for (i
=0; i
<22; i
++)
1006 if (cfg
.bold_colour
|| permanent
[i
])
1007 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1008 (LPARAM
) colours
[i
]);
1010 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1011 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1012 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1013 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1016 switch (LOWORD(wParam
)) {
1017 case IDC5_BOLDCOLOUR
:
1018 if (HIWORD(wParam
) == BN_CLICKED
||
1019 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1021 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1022 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1023 if (cfg
.bold_colour
&& n
!=22) {
1024 for (i
=0; i
<22; i
++)
1026 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1028 (LPARAM
) colours
[i
]);
1029 } else if (!cfg
.bold_colour
&& n
!=12) {
1032 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1033 LB_DELETESTRING
, i
, 0);
1038 if (HIWORD(wParam
) == BN_CLICKED
||
1039 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1040 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1043 if (HIWORD(wParam
) == LBN_DBLCLK
||
1044 HIWORD(wParam
) == LBN_SELCHANGE
) {
1045 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1047 if (!cfg
.bold_colour
)
1048 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1049 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1050 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1051 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1055 if (HIWORD(wParam
) == BN_CLICKED
||
1056 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1057 static CHOOSECOLOR cc
;
1058 static DWORD custom
[16] = {0}; /* zero initialisers */
1059 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1061 if (!cfg
.bold_colour
)
1062 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1063 cc
.lStructSize
= sizeof(cc
);
1064 cc
.hwndOwner
= hwnd
;
1065 cc
.hInstance
= hinst
;
1066 cc
.lpCustColors
= custom
;
1067 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1069 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1070 if (ChooseColor(&cc
)) {
1072 (unsigned char) (cc
.rgbResult
& 0xFF);
1074 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1076 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1077 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1079 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1081 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1089 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1092 static DLGPROC panelproc
[NPANELS
] = {
1093 ConnectionProc
, KeyboardProc
, TerminalProc
,
1094 TelnetProc
, SshProc
, SelectionProc
, ColourProc
1096 static char *panelids
[NPANELS
] = {
1097 MAKEINTRESOURCE(IDD_PANEL0
),
1098 MAKEINTRESOURCE(IDD_PANEL1
),
1099 MAKEINTRESOURCE(IDD_PANEL2
),
1100 MAKEINTRESOURCE(IDD_PANEL3
),
1101 MAKEINTRESOURCE(IDD_PANEL35
),
1102 MAKEINTRESOURCE(IDD_PANEL4
),
1103 MAKEINTRESOURCE(IDD_PANEL5
)
1105 static char *names
[NPANELS
] = {
1106 "Connection", "Keyboard", "Terminal", "Telnet", "SSH", "Selection", "Colours"
1109 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6 };
1110 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6 };
1112 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1113 WPARAM wParam
, LPARAM lParam
,
1114 int npanels
, int *panelnums
, HWND
*page
) {
1119 { /* centre the window */
1122 hw
= GetDesktopWindow();
1123 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1124 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1125 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1126 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1129 { /* initialise the tab control */
1133 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1134 for (i
=0; i
<npanels
; i
++) {
1135 tab
.mask
= TCIF_TEXT
;
1136 tab
.pszText
= names
[panelnums
[i
]];
1137 TabCtrl_InsertItem (hw
, i
, &tab
);
1139 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1140 hwnd, panelproc[panelnums[0]]);*/
1141 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1142 hwnd
, panelproc
[panelnums
[0]]);
1143 SetWindowLong (*page
, GWL_EXSTYLE
,
1144 GetWindowLong (*page
, GWL_EXSTYLE
) |
1145 WS_EX_CONTROLPARENT
);
1150 if (LOWORD(wParam
) == IDC_TAB
&&
1151 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1152 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1154 DestroyWindow (*page
);
1155 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1156 hwnd, panelproc[panelnums[i]]);*/
1157 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1158 hwnd
, panelproc
[panelnums
[i
]]);
1159 SetWindowLong (*page
, GWL_EXSTYLE
,
1160 GetWindowLong (*page
, GWL_EXSTYLE
) |
1161 WS_EX_CONTROLPARENT
);
1162 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1166 /* case WM_CTLCOLORDLG: */
1167 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1169 switch (LOWORD(wParam
)) {
1172 EndDialog (hwnd
, 1);
1177 EndDialog (hwnd
, 0);
1182 EndDialog (hwnd
, 0);
1188 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1189 WPARAM wParam
, LPARAM lParam
) {
1194 static HWND page
= NULL
;
1196 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1199 * If the Connection panel is active and the Session List
1200 * box is selected, we treat a press of Open to have an
1201 * implicit press of Load preceding it.
1203 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1204 i
= TabCtrl_GetCurSel(hw
);
1205 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1206 page
&& implicit_load_ok
) {
1207 SendMessage (page
, WM_COMMAND
,
1208 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1212 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1213 EnableWindow(hwnd
, 0);
1214 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1215 GetParent(hwnd
), AboutProc
);
1216 EnableWindow(hwnd
, 1);
1218 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1219 MAIN_NPANELS
, mainp
, &page
);
1222 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1223 WPARAM wParam
, LPARAM lParam
) {
1225 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1226 RECONF_NPANELS
, reconfp
, &page
);
1229 void get_sesslist(int allocate
) {
1230 static char *buffer
;
1231 int buflen
, bufsize
, i
, ret
;
1232 char otherbuf
[2048];
1237 if (RegCreateKey(HKEY_CURRENT_USER
,
1238 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1241 buflen
= bufsize
= 0;
1245 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1246 if (ret
== ERROR_SUCCESS
) {
1247 bufsize
= buflen
+ 2048;
1248 buffer
= srealloc(buffer
, bufsize
);
1249 unmungestr(otherbuf
, buffer
+buflen
);
1250 buflen
+= strlen(buffer
+buflen
)+1;
1252 } while (ret
== ERROR_SUCCESS
);
1253 buffer
= srealloc(buffer
, buflen
+1);
1254 buffer
[buflen
] = '\0';
1257 nsessions
= 1; /* "Default Settings" counts as one */
1259 if (strcmp(p
, "Default Settings"))
1265 sessions
= smalloc(nsessions
* sizeof(char *));
1266 sessions
[0] = "Default Settings";
1270 if (strcmp(p
, "Default Settings"))
1281 int do_config (void) {
1285 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1286 get_sesslist(FALSE
);
1291 int do_reconfig (HWND hwnd
) {
1295 backup_cfg
= cfg
; /* structure copy */
1296 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1298 cfg
= backup_cfg
; /* structure copy */
1302 void do_defaults (char *session
) {
1304 load_settings (session
, TRUE
);
1306 load_settings ("Default Settings", FALSE
);
1309 void lognegot (char *string
) {
1310 if (nnegots
>= negsize
) {
1312 negots
= srealloc (negots
, negsize
* sizeof(*negots
));
1314 negots
[nnegots
] = smalloc(1+strlen(string
));
1315 strcpy (negots
[nnegots
], string
);
1318 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1322 void shownegot (HWND hwnd
) {
1324 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1326 ShowWindow (logbox
, SW_SHOWNORMAL
);
1330 void showabout (HWND hwnd
) {
1332 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1334 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1338 void verify_ssh_host_key(char *host
, struct RSAKey
*key
) {
1339 char *keystr
, *otherstr
, *mungedhost
;
1344 * Format the key into a string.
1346 len
= rsastr_len(key
);
1347 keystr
= malloc(len
);
1349 fatalbox("Out of memory");
1350 rsastr_fmt(keystr
, key
);
1353 * Now read a saved key in from the registry and see what it
1356 otherstr
= malloc(len
);
1357 mungedhost
= malloc(3*strlen(host
)+1);
1358 if (!otherstr
|| !mungedhost
)
1359 fatalbox("Out of memory");
1361 mungestr(host
, mungedhost
);
1363 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1364 &rkey
) != ERROR_SUCCESS
) {
1365 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1366 "in the registry. There is thus no way to tell\n"
1367 "if the remote host is what you think it is.\n"
1368 "Connect anyway?", "PuTTY Problem",
1369 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1372 DWORD readlen
= len
;
1376 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1377 &type
, otherstr
, &readlen
);
1379 if (ret
== ERROR_MORE_DATA
||
1380 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1381 strcmp(otherstr
, keystr
))) {
1382 if (MessageBox(NULL
,
1383 "This host's host key is different from the\n"
1384 "one cached in the registry! Someone may be\n"
1385 "impersonating this host for malicious reasons;\n"
1386 "alternatively, the host key may have changed\n"
1387 "due to sloppy system administration.\n"
1388 "Replace key in registry and connect?",
1389 "PuTTY: Security Warning",
1390 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1392 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1394 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1395 if (MessageBox(NULL
,
1396 "This host's host key is not cached in the\n"
1397 "registry. Do you want to add it to the cache\n"
1398 "and carry on connecting?",
1400 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1402 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,