13 #define MAIN_NPANELS 8
14 #define RECONF_NPANELS 5
16 static const char *const puttystr
= PUTTY_REG_POS
"\\Sessions";
18 static char **events
= NULL
;
19 static int nevents
= 0, negsize
= 0;
21 static HWND logbox
= NULL
, abtbox
= NULL
;
23 static char hex
[16] = "0123456789ABCDEF";
25 static void mungestr(char *in
, char *out
) {
29 if (*in
== ' ' || *in
== '\\' || *in
== '*' || *in
== '?' ||
30 *in
== '%' || *in
< ' ' || *in
> '~' || (*in
== '.' && !candot
)) {
32 *out
++ = hex
[((unsigned char)*in
) >> 4];
33 *out
++ = hex
[((unsigned char)*in
) & 15];
43 static void unmungestr(char *in
, char *out
) {
45 if (*in
== '%' && in
[1] && in
[2]) {
48 i
= in
[1] - '0'; i
-= (i
> 9 ?
7 : 0);
49 j
= in
[2] - '0'; j
-= (j
> 9 ?
7 : 0);
60 static void wpps(HKEY key
, LPCTSTR name
, LPCTSTR value
) {
61 RegSetValueEx(key
, name
, 0, REG_SZ
, value
, 1+strlen(value
));
64 static void wppi(HKEY key
, LPCTSTR name
, int value
) {
65 RegSetValueEx(key
, name
, 0, REG_DWORD
,
66 (CONST BYTE
*)&value
, sizeof(value
));
69 static void gpps(HKEY key
, LPCTSTR name
, LPCTSTR def
,
70 LPTSTR val
, int len
) {
75 RegQueryValueEx(key
, name
, 0, &type
, val
, &size
) != ERROR_SUCCESS
||
77 strncpy(val
, def
, len
);
82 static void gppi(HKEY key
, LPCTSTR name
, int def
, int *i
) {
83 DWORD type
, val
, size
;
87 RegQueryValueEx(key
, name
, 0, &type
,
88 (BYTE
*)&val
, &size
) != ERROR_SUCCESS
||
89 size
!= sizeof(val
) || type
!= REG_DWORD
)
95 static HINSTANCE hinst
;
99 static void save_settings (char *section
, int do_host
) {
101 HKEY subkey1
, sesskey
;
104 p
= malloc(3*strlen(section
)+1);
105 mungestr(section
, p
);
107 if (RegCreateKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
)!=ERROR_SUCCESS
||
108 RegCreateKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
113 RegCloseKey(subkey1
);
115 wppi (sesskey
, "Present", 1);
117 wpps (sesskey
, "HostName", cfg
.host
);
118 wppi (sesskey
, "PortNumber", cfg
.port
);
119 wpps (sesskey
, "Protocol",
120 cfg
.protocol
== PROT_SSH ?
"ssh" :
121 cfg
.protocol
== PROT_TELNET ?
"telnet" : "raw" );
123 wppi (sesskey
, "CloseOnExit", !!cfg
.close_on_exit
);
124 wppi (sesskey
, "WarnOnClose", !!cfg
.warn_on_close
);
125 wpps (sesskey
, "TerminalType", cfg
.termtype
);
126 wpps (sesskey
, "TerminalSpeed", cfg
.termspeed
);
128 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
134 if (c
== '=' || c
== ',' || c
== '\\')
144 wpps (sesskey
, "Environment", buf
);
146 wpps (sesskey
, "UserName", cfg
.username
);
147 wppi (sesskey
, "NoPTY", cfg
.nopty
);
148 wpps (sesskey
, "Cipher", cfg
.cipher
== CIPHER_BLOWFISH ?
"blowfish" :
149 cfg
.cipher
== CIPHER_DES ?
"des" : "3des");
150 wppi (sesskey
, "AuthTIS", cfg
.try_tis_auth
);
151 wppi (sesskey
, "RFCEnviron", cfg
.rfc_environ
);
152 wppi (sesskey
, "BackspaceIsDelete", cfg
.bksp_is_delete
);
153 wppi (sesskey
, "RXVTHomeEnd", cfg
.rxvt_homeend
);
154 wppi (sesskey
, "LinuxFunctionKeys", cfg
.linux_funkeys
);
155 wppi (sesskey
, "ApplicationCursorKeys", cfg
.app_cursor
);
156 wppi (sesskey
, "ApplicationKeypad", cfg
.app_keypad
);
157 wppi (sesskey
, "NetHackKeypad", cfg
.nethack_keypad
);
158 wppi (sesskey
, "AltF4", cfg
.alt_f4
);
159 wppi (sesskey
, "AltSpace", cfg
.alt_space
);
160 wppi (sesskey
, "LdiscTerm", cfg
.ldisc_term
);
161 wppi (sesskey
, "ScrollbackLines", cfg
.savelines
);
162 wppi (sesskey
, "DECOriginMode", cfg
.dec_om
);
163 wppi (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
164 wppi (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
165 wppi (sesskey
, "WinNameAlways", cfg
.win_name_always
);
166 wppi (sesskey
, "TermWidth", cfg
.width
);
167 wppi (sesskey
, "TermHeight", cfg
.height
);
168 wpps (sesskey
, "Font", cfg
.font
);
169 wppi (sesskey
, "FontIsBold", cfg
.fontisbold
);
170 wppi (sesskey
, "FontCharSet", cfg
.fontcharset
);
171 wppi (sesskey
, "FontHeight", cfg
.fontheight
);
172 wppi (sesskey
, "FontVTMode", cfg
.vtmode
);
173 wppi (sesskey
, "TryPalette", cfg
.try_palette
);
174 wppi (sesskey
, "BoldAsColour", cfg
.bold_colour
);
175 for (i
=0; i
<22; i
++) {
176 char buf
[20], buf2
[30];
177 sprintf(buf
, "Colour%d", i
);
178 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
179 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
180 wpps (sesskey
, buf
, buf2
);
182 wppi (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
183 for (i
=0; i
<256; i
+=32) {
184 char buf
[20], buf2
[256];
186 sprintf(buf
, "Wordness%d", i
);
188 for (j
=i
; j
<i
+32; j
++) {
189 sprintf(buf2
+strlen(buf2
), "%s%d",
190 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
192 wpps (sesskey
, buf
, buf2
);
194 wppi (sesskey
, "KoiWinXlat", cfg
.xlat_enablekoiwin
);
195 wppi (sesskey
, "88592Xlat", cfg
.xlat_88592w1250
);
196 wppi (sesskey
, "CapsLockCyr", cfg
.xlat_capslockcyr
);
198 RegCloseKey(sesskey
);
201 static void del_session (char *section
) {
205 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
208 p
= malloc(3*strlen(section
)+1);
209 mungestr(section
, p
);
210 RegDeleteKey(subkey1
, p
);
213 RegCloseKey(subkey1
);
216 static void load_settings (char *section
, int do_host
) {
218 HKEY subkey1
, sesskey
;
222 p
= malloc(3*strlen(section
)+1);
223 mungestr(section
, p
);
225 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
) {
228 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
231 RegCloseKey(subkey1
);
236 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
237 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
238 gpps (sesskey
, "Protocol", "default", prot
, 10);
239 if (!strcmp(prot
, "ssh"))
240 cfg
.protocol
= PROT_SSH
;
241 else if (!strcmp(prot
, "telnet"))
242 cfg
.protocol
= PROT_TELNET
;
243 else if (!strcmp(prot
, "raw"))
244 cfg
.protocol
= PROT_RAW
;
246 cfg
.protocol
= default_protocol
;
248 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
249 gppi (sesskey
, "WarnOnClose", 1, &cfg
.warn_on_close
);
250 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
251 sizeof(cfg
.termtype
));
252 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
253 sizeof(cfg
.termspeed
));
255 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
256 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
260 while (*p
&& *p
!= ',') {
273 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
274 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
277 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
278 if (!strcmp(cipher
, "blowfish"))
279 cfg
.cipher
= CIPHER_BLOWFISH
;
280 else if (!strcmp(cipher
, "des"))
281 cfg
.cipher
= CIPHER_DES
;
283 cfg
.cipher
= CIPHER_3DES
;
285 gppi (sesskey
, "AuthTIS", 0, &cfg
.try_tis_auth
);
286 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
287 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
288 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
289 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.linux_funkeys
);
290 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
291 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
292 gppi (sesskey
, "NetHackKeypad", 0, &cfg
.nethack_keypad
);
293 gppi (sesskey
, "AltF4", 1, &cfg
.alt_f4
);
294 gppi (sesskey
, "AltSpace", 0, &cfg
.alt_space
);
295 gppi (sesskey
, "LdiscTerm", 0, &cfg
.ldisc_term
);
296 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
297 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
298 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
299 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
300 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
301 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
302 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
303 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
304 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
305 gppi (sesskey
, "FontCharSet", ANSI_CHARSET
, &cfg
.fontcharset
);
306 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
307 gppi (sesskey
, "FontVTMode", VT_POORMAN
, &cfg
.vtmode
);
308 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
309 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
310 for (i
=0; i
<22; i
++) {
311 static char *defaults
[] = {
312 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
313 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
314 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
315 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
316 "85,255,255", "187,187,187", "255,255,255"
318 char buf
[20], buf2
[30];
319 sprintf(buf
, "Colour%d", i
);
320 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
321 sscanf(buf2
, "%d,%d,%d", &cfg
.colours
[i
][0],
322 &cfg
.colours
[i
][1], &cfg
.colours
[i
][2]);
324 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
325 for (i
=0; i
<256; i
+=32) {
326 static char *defaults
[] = {
327 "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",
328 "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",
329 "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",
330 "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",
331 "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",
332 "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",
333 "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",
334 "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"
336 char buf
[20], buf2
[256], *p
;
338 sprintf(buf
, "Wordness%d", i
);
339 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
341 for (j
=i
; j
<i
+32; j
++) {
343 while (*p
&& *p
!= ',') p
++;
344 if (*p
== ',') *p
++ = '\0';
345 cfg
.wordness
[j
] = atoi(q
);
348 gppi (sesskey
, "KoiWinXlat", 0, &cfg
.xlat_enablekoiwin
);
349 gppi (sesskey
, "88592Xlat", 0, &cfg
.xlat_88592w1250
);
350 gppi (sesskey
, "CapsLockCyr", 0, &cfg
.xlat_capslockcyr
);
352 RegCloseKey(sesskey
);
355 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
358 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
363 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
364 WPARAM wParam
, LPARAM lParam
) {
369 for (i
=0; i
<nevents
; i
++)
370 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
371 0, (LPARAM
)events
[i
]);
373 /* case WM_CTLCOLORDLG: */
374 /* return (int) GetStockObject (LTGRAY_BRUSH); */
376 switch (LOWORD(wParam
)) {
379 DestroyWindow (hwnd
);
385 DestroyWindow (hwnd
);
391 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
392 WPARAM wParam
, LPARAM lParam
) {
397 switch (LOWORD(wParam
)) {
400 DestroyWindow (hwnd
);
406 DestroyWindow (hwnd
);
412 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
413 WPARAM wParam
, LPARAM lParam
) {
416 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
418 /* case WM_CTLCOLORDLG: */
419 /* return (int) GetStockObject (LTGRAY_BRUSH); */
420 /* case WM_CTLCOLORSTATIC: */
421 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
422 /* return (int) GetStockObject (LTGRAY_BRUSH); */
424 switch (LOWORD(wParam
)) {
427 DestroyWindow (hwnd
);
430 EnableWindow(hwnd
, 0);
431 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
433 EnableWindow(hwnd
, 1);
439 DestroyWindow (hwnd
);
445 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
446 WPARAM wParam
, LPARAM lParam
) {
449 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
451 /* case WM_CTLCOLORDLG: */
452 /* return (int) GetStockObject (LTGRAY_BRUSH); */
453 /* case WM_CTLCOLORSTATIC: */
454 /* case WM_CTLCOLORBTN: */
455 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
456 /* return (int) GetStockObject (LTGRAY_BRUSH); */
458 DestroyWindow (hwnd
);
464 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
465 WPARAM wParam
, LPARAM lParam
) {
470 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
471 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
472 for (i
= 0; i
< nsessions
; i
++)
473 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
474 0, (LPARAM
) (sessions
[i
]));
475 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
476 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
477 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
478 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
479 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
483 * Button release should trigger WM_OK if there was a
484 * previous double click on the session list.
488 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
491 switch (LOWORD(wParam
)) {
492 case IDC0_PROTTELNET
:
495 if (HIWORD(wParam
) == BN_CLICKED
||
496 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
497 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
498 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
499 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
500 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
501 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
502 cfg
.port
= i ?
22 : 23;
503 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
508 if (HIWORD(wParam
) == EN_CHANGE
)
509 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
513 if (HIWORD(wParam
) == EN_CHANGE
)
514 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
517 if (HIWORD(wParam
) == BN_CLICKED
||
518 HIWORD(wParam
) == BN_DOUBLECLICKED
)
519 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
522 if (HIWORD(wParam
) == BN_CLICKED
||
523 HIWORD(wParam
) == BN_DOUBLECLICKED
)
524 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
527 if (HIWORD(wParam
) == EN_CHANGE
)
528 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
532 if (HIWORD(wParam
) == BN_CLICKED
||
533 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
538 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
540 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
546 strcpy (str
, sessions
[n
]);
548 save_settings (str
, !!strcmp(str
, "Default Settings"));
549 get_sesslist (FALSE
);
551 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
553 for (i
= 0; i
< nsessions
; i
++)
554 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
555 0, (LPARAM
) (sessions
[i
]));
556 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
562 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
563 HIWORD(wParam
) != BN_CLICKED
&&
564 HIWORD(wParam
) != BN_DOUBLECLICKED
)
566 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
567 HIWORD(wParam
) != LBN_DBLCLK
)
570 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
576 load_settings (sessions
[n
],
577 !!strcmp(sessions
[n
], "Default Settings"));
578 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
579 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
580 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
581 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
582 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
583 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
584 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
585 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
588 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
590 * A double-click on a saved session should
591 * actually start the session, not just load it.
592 * Unless it's Default Settings or some other
593 * host-less set of saved settings.
602 if (HIWORD(wParam
) == BN_CLICKED
||
603 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
604 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
606 if (n
== LB_ERR
|| n
== 0) {
610 del_session(sessions
[n
]);
611 get_sesslist (FALSE
);
613 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
615 for (i
= 0; i
< nsessions
; i
++)
616 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
617 0, (LPARAM
) (sessions
[i
]));
618 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
623 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
626 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
627 WPARAM wParam
, LPARAM lParam
) {
630 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
631 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
632 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
633 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
634 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCLINUX
,
635 cfg
.linux_funkeys ? IDC1_FUNCLINUX
: IDC1_FUNCTILDE
);
636 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
637 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
638 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
639 cfg
.nethack_keypad ? IDC1_KPNH
:
640 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
641 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
642 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
643 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
646 if (HIWORD(wParam
) == BN_CLICKED
||
647 HIWORD(wParam
) == BN_DOUBLECLICKED
)
648 switch (LOWORD(wParam
)) {
651 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
655 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
659 cfg
.linux_funkeys
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
663 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
664 cfg
.nethack_keypad
= FALSE
;
667 cfg
.app_keypad
= FALSE
;
668 cfg
.nethack_keypad
= TRUE
;
672 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
675 if (HIWORD(wParam
) == BN_CLICKED
||
676 HIWORD(wParam
) == BN_DOUBLECLICKED
)
677 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
680 if (HIWORD(wParam
) == BN_CLICKED
||
681 HIWORD(wParam
) == BN_DOUBLECLICKED
)
682 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
685 if (HIWORD(wParam
) == BN_CLICKED
||
686 HIWORD(wParam
) == BN_DOUBLECLICKED
)
687 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
691 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
694 static void fmtfont (char *buf
) {
695 sprintf (buf
, "Font: %s, ", cfg
.font
);
697 strcat(buf
, "bold, ");
698 if (cfg
.fontheight
== 0)
699 strcat (buf
, "default height");
701 sprintf (buf
+strlen(buf
), "%d-%s",
702 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
703 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
706 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
707 WPARAM wParam
, LPARAM lParam
) {
710 char fontstatic
[256];
714 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
715 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
716 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
717 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
718 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
719 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
720 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
721 fmtfont (fontstatic
);
722 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
723 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
724 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
725 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
726 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
730 switch (LOWORD(wParam
)) {
732 if (HIWORD(wParam
) == BN_CLICKED
||
733 HIWORD(wParam
) == BN_DOUBLECLICKED
)
734 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
737 if (HIWORD(wParam
) == BN_CLICKED
||
738 HIWORD(wParam
) == BN_DOUBLECLICKED
)
739 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
742 if (HIWORD(wParam
) == BN_CLICKED
||
743 HIWORD(wParam
) == BN_DOUBLECLICKED
)
744 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
747 if (HIWORD(wParam
) == BN_CLICKED
||
748 HIWORD(wParam
) == BN_DOUBLECLICKED
)
749 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
752 if (HIWORD(wParam
) == EN_CHANGE
)
753 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
756 if (HIWORD(wParam
) == EN_CHANGE
)
757 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
760 if (HIWORD(wParam
) == EN_CHANGE
)
761 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
763 case IDC2_CHOOSEFONT
:
764 lf
.lfHeight
= cfg
.fontheight
;
765 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
766 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
767 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
768 lf
.lfCharSet
= cfg
.fontcharset
;
769 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
770 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
771 lf
.lfQuality
= DEFAULT_QUALITY
;
772 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
773 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
774 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
776 cf
.lStructSize
= sizeof(cf
);
779 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
780 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
782 if (ChooseFont (&cf
)) {
783 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
784 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
785 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
786 cfg
.fontcharset
= lf
.lfCharSet
;
787 cfg
.fontheight
= lf
.lfHeight
;
788 fmtfont (fontstatic
);
789 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
792 case IDC2_VTXWINDOWS
:
797 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
798 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
799 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
805 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
808 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
809 WPARAM wParam
, LPARAM lParam
) {
814 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
815 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
816 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
818 char *p
= cfg
.environmt
;
820 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
825 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
826 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
829 switch (LOWORD(wParam
)) {
831 if (HIWORD(wParam
) == EN_CHANGE
)
832 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
833 sizeof(cfg
.termtype
)-1);
836 if (HIWORD(wParam
) == EN_CHANGE
)
837 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
838 sizeof(cfg
.termspeed
)-1);
841 if (HIWORD(wParam
) == EN_CHANGE
)
842 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
843 sizeof(cfg
.username
)-1);
847 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
850 if (HIWORD(wParam
) == BN_CLICKED
||
851 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
852 char str
[sizeof(cfg
.environmt
)];
854 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
859 p
= str
+ strlen(str
);
861 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
871 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
873 p
[strlen(str
)+1] = '\0';
874 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
876 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
877 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
879 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
880 MB_OK
| MB_ICONERROR
);
885 if (HIWORD(wParam
) != BN_CLICKED
&&
886 HIWORD(wParam
) != BN_DOUBLECLICKED
)
888 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
894 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
921 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
924 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
925 WPARAM wParam
, LPARAM lParam
) {
928 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
929 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
930 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
931 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
932 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
933 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
936 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
939 switch (LOWORD(wParam
)) {
941 if (HIWORD(wParam
) == EN_CHANGE
)
942 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
943 sizeof(cfg
.termtype
)-1);
946 if (HIWORD(wParam
) == EN_CHANGE
)
947 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
948 sizeof(cfg
.username
)-1);
951 if (HIWORD(wParam
) == BN_CLICKED
||
952 HIWORD(wParam
) == BN_DOUBLECLICKED
)
953 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
955 case IDC3_CIPHER3DES
:
956 case IDC3_CIPHERBLOWF
:
958 if (HIWORD(wParam
) == BN_CLICKED
||
959 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
960 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
961 cfg
.cipher
= CIPHER_3DES
;
962 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
963 cfg
.cipher
= CIPHER_BLOWFISH
;
964 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
965 cfg
.cipher
= CIPHER_DES
;
969 if (HIWORD(wParam
) == BN_CLICKED
||
970 HIWORD(wParam
) == BN_DOUBLECLICKED
)
971 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
976 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
979 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
980 WPARAM wParam
, LPARAM lParam
) {
985 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
986 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
988 static int tabs
[4] = {25, 61, 96, 128};
989 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
992 for (i
=0; i
<256; i
++) {
994 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
995 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
997 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
1002 switch (LOWORD(wParam
)) {
1003 case IDC4_MBWINDOWS
:
1005 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1011 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1016 for (i
=0; i
<256; i
++)
1017 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1020 cfg
.wordness
[i
] = n
;
1021 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1022 LB_DELETESTRING
, i
, 0);
1023 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1024 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1026 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1036 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1039 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1040 WPARAM wParam
, LPARAM lParam
) {
1041 static const char *const colours
[] = {
1042 "Default Foreground", "Default Bold Foreground",
1043 "Default Background", "Default Bold Background",
1044 "Cursor Text", "Cursor Colour",
1045 "ANSI Black", "ANSI Black Bold",
1046 "ANSI Red", "ANSI Red Bold",
1047 "ANSI Green", "ANSI Green Bold",
1048 "ANSI Yellow", "ANSI Yellow Bold",
1049 "ANSI Blue", "ANSI Blue Bold",
1050 "ANSI Magenta", "ANSI Magenta Bold",
1051 "ANSI Cyan", "ANSI Cyan Bold",
1052 "ANSI White", "ANSI White Bold"
1054 static const int permanent
[] = {
1055 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1056 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1057 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1061 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1062 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1065 for (i
=0; i
<22; i
++)
1066 if (cfg
.bold_colour
|| permanent
[i
])
1067 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1068 (LPARAM
) colours
[i
]);
1070 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1071 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1072 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1073 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1076 switch (LOWORD(wParam
)) {
1077 case IDC5_BOLDCOLOUR
:
1078 if (HIWORD(wParam
) == BN_CLICKED
||
1079 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1081 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1082 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1083 if (cfg
.bold_colour
&& n
!=22) {
1084 for (i
=0; i
<22; i
++)
1086 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1088 (LPARAM
) colours
[i
]);
1089 } else if (!cfg
.bold_colour
&& n
!=12) {
1092 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1093 LB_DELETESTRING
, i
, 0);
1098 if (HIWORD(wParam
) == BN_CLICKED
||
1099 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1100 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1103 if (HIWORD(wParam
) == LBN_DBLCLK
||
1104 HIWORD(wParam
) == LBN_SELCHANGE
) {
1105 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1107 if (!cfg
.bold_colour
)
1108 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1109 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1110 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1111 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1115 if (HIWORD(wParam
) == BN_CLICKED
||
1116 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1117 static CHOOSECOLOR cc
;
1118 static DWORD custom
[16] = {0}; /* zero initialisers */
1119 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1121 if (!cfg
.bold_colour
)
1122 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1123 cc
.lStructSize
= sizeof(cc
);
1124 cc
.hwndOwner
= hwnd
;
1125 cc
.hInstance
= hinst
;
1126 cc
.lpCustColors
= custom
;
1127 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1129 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1130 if (ChooseColor(&cc
)) {
1132 (unsigned char) (cc
.rgbResult
& 0xFF);
1134 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1136 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1137 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1139 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1141 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1149 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1152 static int CALLBACK
LanguageProc (HWND hwnd
, UINT msg
,
1153 WPARAM wParam
, LPARAM lParam
) {
1156 CheckRadioButton (hwnd
, IDC6_NOXLAT
, IDC6_88592WIN1250
,
1157 cfg
.xlat_88592w1250 ? IDC6_88592WIN1250
:
1158 cfg
.xlat_enablekoiwin ? IDC6_KOI8WIN1251
:
1160 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1162 switch (LOWORD(wParam
)) {
1164 case IDC6_KOI8WIN1251
:
1165 case IDC6_88592WIN1250
:
1166 cfg
.xlat_enablekoiwin
=
1167 IsDlgButtonChecked (hwnd
, IDC6_KOI8WIN1251
);
1168 cfg
.xlat_88592w1250
=
1169 IsDlgButtonChecked (hwnd
, IDC6_88592WIN1250
);
1171 case IDC6_CAPSLOCKCYR
:
1172 if (HIWORD(wParam
) == BN_CLICKED
||
1173 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1174 cfg
.xlat_capslockcyr
=
1175 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1180 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1183 static DLGPROC panelproc
[NPANELS
] = {
1184 ConnectionProc
, KeyboardProc
, TerminalProc
,
1185 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, LanguageProc
1187 static char *panelids
[NPANELS
] = {
1188 MAKEINTRESOURCE(IDD_PANEL0
),
1189 MAKEINTRESOURCE(IDD_PANEL1
),
1190 MAKEINTRESOURCE(IDD_PANEL2
),
1191 MAKEINTRESOURCE(IDD_PANEL3
),
1192 MAKEINTRESOURCE(IDD_PANEL35
),
1193 MAKEINTRESOURCE(IDD_PANEL4
),
1194 MAKEINTRESOURCE(IDD_PANEL5
),
1195 MAKEINTRESOURCE(IDD_PANEL6
)
1198 static char *names
[NPANELS
] = {
1199 "Connection", "Keyboard", "Terminal", "Telnet",
1200 "SSH", "Selection", "Colours", "Language"
1203 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1204 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1206 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1207 WPARAM wParam
, LPARAM lParam
,
1208 int npanels
, int *panelnums
, HWND
*page
) {
1213 { /* centre the window */
1216 hw
= GetDesktopWindow();
1217 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1218 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1219 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1220 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1223 { /* initialise the tab control */
1227 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1228 for (i
=0; i
<npanels
; i
++) {
1229 tab
.mask
= TCIF_TEXT
;
1230 tab
.pszText
= names
[panelnums
[i
]];
1231 TabCtrl_InsertItem (hw
, i
, &tab
);
1233 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1234 hwnd, panelproc[panelnums[0]]);*/
1235 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1236 hwnd
, panelproc
[panelnums
[0]]);
1237 SetWindowLong (*page
, GWL_EXSTYLE
,
1238 GetWindowLong (*page
, GWL_EXSTYLE
) |
1239 WS_EX_CONTROLPARENT
);
1244 if (LOWORD(wParam
) == IDC_TAB
&&
1245 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1246 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1248 DestroyWindow (*page
);
1249 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1250 hwnd, panelproc[panelnums[i]]);*/
1251 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1252 hwnd
, panelproc
[panelnums
[i
]]);
1253 SetWindowLong (*page
, GWL_EXSTYLE
,
1254 GetWindowLong (*page
, GWL_EXSTYLE
) |
1255 WS_EX_CONTROLPARENT
);
1256 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1260 /* case WM_CTLCOLORDLG: */
1261 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1263 switch (LOWORD(wParam
)) {
1266 EndDialog (hwnd
, 1);
1271 EndDialog (hwnd
, 0);
1276 EndDialog (hwnd
, 0);
1282 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1283 WPARAM wParam
, LPARAM lParam
) {
1288 static HWND page
= NULL
;
1290 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1293 * If the Connection panel is active and the Session List
1294 * box is selected, we treat a press of Open to have an
1295 * implicit press of Load preceding it.
1297 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1298 i
= TabCtrl_GetCurSel(hw
);
1299 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1300 page
&& implicit_load_ok
) {
1301 SendMessage (page
, WM_COMMAND
,
1302 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1306 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1307 EnableWindow(hwnd
, 0);
1308 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1309 GetParent(hwnd
), AboutProc
);
1310 EnableWindow(hwnd
, 1);
1312 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1313 MAIN_NPANELS
, mainp
, &page
);
1316 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1317 WPARAM wParam
, LPARAM lParam
) {
1319 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1320 RECONF_NPANELS
, reconfp
, &page
);
1323 void get_sesslist(int allocate
) {
1324 static char *buffer
;
1325 int buflen
, bufsize
, i
, ret
;
1326 char otherbuf
[2048];
1331 if (RegCreateKey(HKEY_CURRENT_USER
,
1332 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1335 buflen
= bufsize
= 0;
1339 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1340 if (ret
== ERROR_SUCCESS
) {
1341 bufsize
= buflen
+ 2048;
1342 buffer
= srealloc(buffer
, bufsize
);
1343 unmungestr(otherbuf
, buffer
+buflen
);
1344 buflen
+= strlen(buffer
+buflen
)+1;
1346 } while (ret
== ERROR_SUCCESS
);
1347 buffer
= srealloc(buffer
, buflen
+1);
1348 buffer
[buflen
] = '\0';
1351 nsessions
= 1; /* "Default Settings" counts as one */
1353 if (strcmp(p
, "Default Settings"))
1359 sessions
= smalloc(nsessions
* sizeof(char *));
1360 sessions
[0] = "Default Settings";
1364 if (strcmp(p
, "Default Settings"))
1375 int do_config (void) {
1379 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1380 get_sesslist(FALSE
);
1385 int do_reconfig (HWND hwnd
) {
1389 backup_cfg
= cfg
; /* structure copy */
1390 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1392 cfg
= backup_cfg
; /* structure copy */
1396 void do_defaults (char *session
) {
1398 load_settings (session
, TRUE
);
1400 load_settings ("Default Settings", FALSE
);
1403 void logevent (char *string
) {
1404 if (nevents
>= negsize
) {
1406 events
= srealloc (events
, negsize
* sizeof(*events
));
1408 events
[nevents
] = smalloc(1+strlen(string
));
1409 strcpy (events
[nevents
], string
);
1412 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1416 void showeventlog (HWND hwnd
) {
1418 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1420 ShowWindow (logbox
, SW_SHOWNORMAL
);
1424 void showabout (HWND hwnd
) {
1426 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1428 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1432 void verify_ssh_host_key(char *host
, struct RSAKey
*key
) {
1433 char *keystr
, *otherstr
, *mungedhost
;
1438 * Format the key into a string.
1440 len
= rsastr_len(key
);
1441 keystr
= malloc(len
);
1443 fatalbox("Out of memory");
1444 rsastr_fmt(keystr
, key
);
1447 * Now read a saved key in from the registry and see what it
1450 otherstr
= malloc(len
);
1451 mungedhost
= malloc(3*strlen(host
)+1);
1452 if (!otherstr
|| !mungedhost
)
1453 fatalbox("Out of memory");
1455 mungestr(host
, mungedhost
);
1457 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1458 &rkey
) != ERROR_SUCCESS
) {
1459 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1460 "in the registry. There is thus no way to tell\n"
1461 "if the remote host is what you think it is.\n"
1462 "Connect anyway?", "PuTTY Problem",
1463 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1466 DWORD readlen
= len
;
1470 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1471 &type
, otherstr
, &readlen
);
1473 if (ret
== ERROR_MORE_DATA
||
1474 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1475 strcmp(otherstr
, keystr
))) {
1476 if (MessageBox(NULL
,
1477 "This host's host key is different from the\n"
1478 "one cached in the registry! Someone may be\n"
1479 "impersonating this host for malicious reasons;\n"
1480 "alternatively, the host key may have changed\n"
1481 "due to sloppy system administration.\n"
1482 "Replace key in registry and connect?",
1483 "PuTTY: Security Warning",
1484 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1486 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1488 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1489 if (MessageBox(NULL
,
1490 "This host's host key is not cached in the\n"
1491 "registry. Do you want to add it to the cache\n"
1492 "and carry on connecting?",
1494 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1496 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,