13 #define MAIN_NPANELS 8
14 #define RECONF_NPANELS 5
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 wppi (sesskey
, "WarnOnClose", !!cfg
.warn_on_close
);
124 wpps (sesskey
, "TerminalType", cfg
.termtype
);
125 wpps (sesskey
, "TerminalSpeed", cfg
.termspeed
);
127 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
133 if (c
== '=' || c
== ',' || c
== '\\')
143 wpps (sesskey
, "Environment", buf
);
145 wpps (sesskey
, "UserName", cfg
.username
);
146 wppi (sesskey
, "NoPTY", cfg
.nopty
);
147 wpps (sesskey
, "Cipher", cfg
.cipher
== CIPHER_BLOWFISH ?
"blowfish" :
148 cfg
.cipher
== CIPHER_DES ?
"des" : "3des");
149 wppi (sesskey
, "AuthTIS", cfg
.try_tis_auth
);
150 wppi (sesskey
, "RFCEnviron", cfg
.rfc_environ
);
151 wppi (sesskey
, "BackspaceIsDelete", cfg
.bksp_is_delete
);
152 wppi (sesskey
, "RXVTHomeEnd", cfg
.rxvt_homeend
);
153 wppi (sesskey
, "LinuxFunctionKeys", cfg
.linux_funkeys
);
154 wppi (sesskey
, "ApplicationCursorKeys", cfg
.app_cursor
);
155 wppi (sesskey
, "ApplicationKeypad", cfg
.app_keypad
);
156 wppi (sesskey
, "ScrollbackLines", cfg
.savelines
);
157 wppi (sesskey
, "DECOriginMode", cfg
.dec_om
);
158 wppi (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
159 wppi (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
160 wppi (sesskey
, "WinNameAlways", cfg
.win_name_always
);
161 wppi (sesskey
, "TermWidth", cfg
.width
);
162 wppi (sesskey
, "TermHeight", cfg
.height
);
163 wpps (sesskey
, "Font", cfg
.font
);
164 wppi (sesskey
, "FontIsBold", cfg
.fontisbold
);
165 wppi (sesskey
, "FontCharSet", cfg
.fontcharset
);
166 wppi (sesskey
, "FontHeight", cfg
.fontheight
);
167 wppi (sesskey
, "FontVTMode", cfg
.vtmode
);
168 wppi (sesskey
, "TryPalette", cfg
.try_palette
);
169 wppi (sesskey
, "BoldAsColour", cfg
.bold_colour
);
170 for (i
=0; i
<22; i
++) {
171 char buf
[20], buf2
[30];
172 sprintf(buf
, "Colour%d", i
);
173 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
174 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
175 wpps (sesskey
, buf
, buf2
);
177 wppi (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
178 for (i
=0; i
<256; i
+=32) {
179 char buf
[20], buf2
[256];
181 sprintf(buf
, "Wordness%d", i
);
183 for (j
=i
; j
<i
+32; j
++) {
184 sprintf(buf2
+strlen(buf2
), "%s%d",
185 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
187 wpps (sesskey
, buf
, buf2
);
189 wppi (sesskey
, "KoiWinXlat", cfg
.xlat_enablekoiwin
);
190 wppi (sesskey
, "CapsLockCyr", cfg
.xlat_capslockcyr
);
192 RegCloseKey(sesskey
);
195 static void del_session (char *section
) {
199 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
202 p
= malloc(3*strlen(section
)+1);
203 mungestr(section
, p
);
204 RegDeleteKey(subkey1
, p
);
207 RegCloseKey(subkey1
);
210 static void load_settings (char *section
, int do_host
) {
212 HKEY subkey1
, sesskey
;
216 p
= malloc(3*strlen(section
)+1);
217 mungestr(section
, p
);
219 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
) {
222 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
225 RegCloseKey(subkey1
);
230 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
231 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
232 gpps (sesskey
, "Protocol", "default", prot
, 10);
233 if (!strcmp(prot
, "ssh"))
234 cfg
.protocol
= PROT_SSH
;
235 else if (!strcmp(prot
, "telnet"))
236 cfg
.protocol
= PROT_TELNET
;
237 else if (!strcmp(prot
, "raw"))
238 cfg
.protocol
= PROT_RAW
;
240 cfg
.protocol
= default_protocol
;
242 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
243 gppi (sesskey
, "WarnOnClose", 1, &cfg
.warn_on_close
);
244 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
245 sizeof(cfg
.termtype
));
246 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
247 sizeof(cfg
.termspeed
));
249 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
250 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
254 while (*p
&& *p
!= ',') {
267 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
268 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
271 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
272 if (!strcmp(cipher
, "blowfish"))
273 cfg
.cipher
= CIPHER_BLOWFISH
;
274 else if (!strcmp(cipher
, "des"))
275 cfg
.cipher
= CIPHER_DES
;
277 cfg
.cipher
= CIPHER_3DES
;
279 gppi (sesskey
, "AuthTIS", 0, &cfg
.try_tis_auth
);
280 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
281 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
282 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
283 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.linux_funkeys
);
284 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
285 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
286 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
287 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
288 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
289 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
290 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
291 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
292 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
293 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
294 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
295 gppi (sesskey
, "FontCharSet", ANSI_CHARSET
, &cfg
.fontcharset
);
296 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
297 gppi (sesskey
, "FontVTMode", VT_POORMAN
, &cfg
.vtmode
);
298 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
299 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
300 for (i
=0; i
<22; i
++) {
301 static char *defaults
[] = {
302 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
303 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
304 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
305 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
306 "85,255,255", "187,187,187", "255,255,255"
308 char buf
[20], buf2
[30];
309 sprintf(buf
, "Colour%d", i
);
310 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
311 sscanf(buf2
, "%d,%d,%d", &cfg
.colours
[i
][0],
312 &cfg
.colours
[i
][1], &cfg
.colours
[i
][2]);
314 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
315 for (i
=0; i
<256; i
+=32) {
316 static char *defaults
[] = {
317 "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",
318 "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",
319 "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",
320 "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",
321 "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",
322 "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",
323 "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",
324 "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"
326 char buf
[20], buf2
[256], *p
;
328 sprintf(buf
, "Wordness%d", i
);
329 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
331 for (j
=i
; j
<i
+32; j
++) {
333 while (*p
&& *p
!= ',') p
++;
334 if (*p
== ',') *p
++ = '\0';
335 cfg
.wordness
[j
] = atoi(q
);
338 gppi (sesskey
, "KoiWinXlat", 0, &cfg
.xlat_enablekoiwin
);
339 gppi (sesskey
, "CapsLockCyr", 0, &cfg
.xlat_capslockcyr
);
341 RegCloseKey(sesskey
);
344 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
347 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
352 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
353 WPARAM wParam
, LPARAM lParam
) {
358 for (i
=0; i
<nnegots
; i
++)
359 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
360 0, (LPARAM
)negots
[i
]);
362 /* case WM_CTLCOLORDLG: */
363 /* return (int) GetStockObject (LTGRAY_BRUSH); */
365 switch (LOWORD(wParam
)) {
368 DestroyWindow (hwnd
);
374 DestroyWindow (hwnd
);
380 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
381 WPARAM wParam
, LPARAM lParam
) {
386 switch (LOWORD(wParam
)) {
389 DestroyWindow (hwnd
);
395 DestroyWindow (hwnd
);
401 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
402 WPARAM wParam
, LPARAM lParam
) {
405 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
407 /* case WM_CTLCOLORDLG: */
408 /* return (int) GetStockObject (LTGRAY_BRUSH); */
409 /* case WM_CTLCOLORSTATIC: */
410 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
411 /* return (int) GetStockObject (LTGRAY_BRUSH); */
413 switch (LOWORD(wParam
)) {
416 DestroyWindow (hwnd
);
419 EnableWindow(hwnd
, 0);
420 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
422 EnableWindow(hwnd
, 1);
428 DestroyWindow (hwnd
);
434 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
435 WPARAM wParam
, LPARAM lParam
) {
438 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
440 /* case WM_CTLCOLORDLG: */
441 /* return (int) GetStockObject (LTGRAY_BRUSH); */
442 /* case WM_CTLCOLORSTATIC: */
443 /* case WM_CTLCOLORBTN: */
444 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
445 /* return (int) GetStockObject (LTGRAY_BRUSH); */
447 DestroyWindow (hwnd
);
453 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
454 WPARAM wParam
, LPARAM lParam
) {
459 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
460 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
461 for (i
= 0; i
< nsessions
; i
++)
462 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
463 0, (LPARAM
) (sessions
[i
]));
464 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
465 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
466 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
467 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
468 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
472 * Button release should trigger WM_OK if there was a
473 * previous double click on the session list.
477 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
480 switch (LOWORD(wParam
)) {
481 case IDC0_PROTTELNET
:
484 if (HIWORD(wParam
) == BN_CLICKED
||
485 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
486 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
487 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
488 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
489 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
490 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
491 cfg
.port
= i ?
22 : 23;
492 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
497 if (HIWORD(wParam
) == EN_CHANGE
)
498 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
502 if (HIWORD(wParam
) == EN_CHANGE
)
503 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
506 if (HIWORD(wParam
) == BN_CLICKED
||
507 HIWORD(wParam
) == BN_DOUBLECLICKED
)
508 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
511 if (HIWORD(wParam
) == BN_CLICKED
||
512 HIWORD(wParam
) == BN_DOUBLECLICKED
)
513 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
516 if (HIWORD(wParam
) == EN_CHANGE
)
517 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
521 if (HIWORD(wParam
) == BN_CLICKED
||
522 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
527 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
529 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
535 strcpy (str
, sessions
[n
]);
537 save_settings (str
, !!strcmp(str
, "Default Settings"));
538 get_sesslist (FALSE
);
540 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
542 for (i
= 0; i
< nsessions
; i
++)
543 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
544 0, (LPARAM
) (sessions
[i
]));
545 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
551 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
552 HIWORD(wParam
) != BN_CLICKED
&&
553 HIWORD(wParam
) != BN_DOUBLECLICKED
)
555 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
556 HIWORD(wParam
) != LBN_DBLCLK
)
559 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
565 load_settings (sessions
[n
],
566 !!strcmp(sessions
[n
], "Default Settings"));
567 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
568 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
569 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
570 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
571 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
572 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
573 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
574 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
577 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
579 * A double-click on a saved session should
580 * actually start the session, not just load it.
581 * Unless it's Default Settings or some other
582 * host-less set of saved settings.
591 if (HIWORD(wParam
) == BN_CLICKED
||
592 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
593 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
595 if (n
== LB_ERR
|| n
== 0) {
599 del_session(sessions
[n
]);
600 get_sesslist (FALSE
);
602 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
604 for (i
= 0; i
< nsessions
; i
++)
605 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
606 0, (LPARAM
) (sessions
[i
]));
607 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
612 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
615 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
616 WPARAM wParam
, LPARAM lParam
) {
619 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
620 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
621 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
622 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
623 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCLINUX
,
624 cfg
.linux_funkeys ? IDC1_FUNCLINUX
: IDC1_FUNCTILDE
);
625 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
626 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
627 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPAPPLIC
,
628 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
631 if (HIWORD(wParam
) == BN_CLICKED
||
632 HIWORD(wParam
) == BN_DOUBLECLICKED
)
633 switch (LOWORD(wParam
)) {
636 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
640 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
644 cfg
.linux_funkeys
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
648 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
652 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
656 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
659 static void fmtfont (char *buf
) {
660 sprintf (buf
, "Font: %s, ", cfg
.font
);
662 strcat(buf
, "bold, ");
663 if (cfg
.fontheight
== 0)
664 strcat (buf
, "default height");
666 sprintf (buf
+strlen(buf
), "%d-%s",
667 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
668 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
671 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
672 WPARAM wParam
, LPARAM lParam
) {
675 char fontstatic
[256];
679 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
680 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
681 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
682 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
683 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
684 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
685 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
686 fmtfont (fontstatic
);
687 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
688 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
689 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
690 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
691 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
695 switch (LOWORD(wParam
)) {
697 if (HIWORD(wParam
) == BN_CLICKED
||
698 HIWORD(wParam
) == BN_DOUBLECLICKED
)
699 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
702 if (HIWORD(wParam
) == BN_CLICKED
||
703 HIWORD(wParam
) == BN_DOUBLECLICKED
)
704 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
707 if (HIWORD(wParam
) == BN_CLICKED
||
708 HIWORD(wParam
) == BN_DOUBLECLICKED
)
709 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
712 if (HIWORD(wParam
) == BN_CLICKED
||
713 HIWORD(wParam
) == BN_DOUBLECLICKED
)
714 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
717 if (HIWORD(wParam
) == EN_CHANGE
)
718 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
721 if (HIWORD(wParam
) == EN_CHANGE
)
722 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
725 if (HIWORD(wParam
) == EN_CHANGE
)
726 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
728 case IDC2_CHOOSEFONT
:
729 lf
.lfHeight
= cfg
.fontheight
;
730 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
731 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
732 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
733 lf
.lfCharSet
= cfg
.fontcharset
;
734 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
735 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
736 lf
.lfQuality
= DEFAULT_QUALITY
;
737 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
738 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
739 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
741 cf
.lStructSize
= sizeof(cf
);
744 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
745 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
747 if (ChooseFont (&cf
)) {
748 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
749 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
750 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
751 cfg
.fontcharset
= lf
.lfCharSet
;
752 cfg
.fontheight
= lf
.lfHeight
;
753 fmtfont (fontstatic
);
754 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
757 case IDC2_VTXWINDOWS
:
762 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
763 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
764 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
770 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
773 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
774 WPARAM wParam
, LPARAM lParam
) {
779 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
780 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
781 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
783 char *p
= cfg
.environmt
;
785 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
790 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
791 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
794 switch (LOWORD(wParam
)) {
796 if (HIWORD(wParam
) == EN_CHANGE
)
797 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
798 sizeof(cfg
.termtype
)-1);
801 if (HIWORD(wParam
) == EN_CHANGE
)
802 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
803 sizeof(cfg
.termspeed
)-1);
806 if (HIWORD(wParam
) == EN_CHANGE
)
807 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
808 sizeof(cfg
.username
)-1);
812 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
815 if (HIWORD(wParam
) == BN_CLICKED
||
816 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
817 char str
[sizeof(cfg
.environmt
)];
819 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
824 p
= str
+ strlen(str
);
826 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
836 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
838 p
[strlen(str
)+1] = '\0';
839 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
841 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
842 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
844 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
845 MB_OK
| MB_ICONERROR
);
850 if (HIWORD(wParam
) != BN_CLICKED
&&
851 HIWORD(wParam
) != BN_DOUBLECLICKED
)
853 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
859 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
886 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
889 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
890 WPARAM wParam
, LPARAM lParam
) {
893 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
894 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
895 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
896 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
897 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
898 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
901 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
904 switch (LOWORD(wParam
)) {
906 if (HIWORD(wParam
) == EN_CHANGE
)
907 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
908 sizeof(cfg
.termtype
)-1);
911 if (HIWORD(wParam
) == EN_CHANGE
)
912 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
913 sizeof(cfg
.username
)-1);
916 if (HIWORD(wParam
) == BN_CLICKED
||
917 HIWORD(wParam
) == BN_DOUBLECLICKED
)
918 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
920 case IDC3_CIPHER3DES
:
921 case IDC3_CIPHERBLOWF
:
923 if (HIWORD(wParam
) == BN_CLICKED
||
924 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
925 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
926 cfg
.cipher
= CIPHER_3DES
;
927 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
928 cfg
.cipher
= CIPHER_BLOWFISH
;
929 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
930 cfg
.cipher
= CIPHER_DES
;
934 if (HIWORD(wParam
) == BN_CLICKED
||
935 HIWORD(wParam
) == BN_DOUBLECLICKED
)
936 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
941 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
944 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
945 WPARAM wParam
, LPARAM lParam
) {
950 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
951 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
953 static int tabs
[4] = {25, 61, 96, 128};
954 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
957 for (i
=0; i
<256; i
++) {
959 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
960 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
962 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
967 switch (LOWORD(wParam
)) {
970 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
976 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
981 for (i
=0; i
<256; i
++)
982 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
986 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
987 LB_DELETESTRING
, i
, 0);
988 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
989 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
991 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1001 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1004 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1005 WPARAM wParam
, LPARAM lParam
) {
1006 static const char *const colours
[] = {
1007 "Default Foreground", "Default Bold Foreground",
1008 "Default Background", "Default Bold Background",
1009 "Cursor Text", "Cursor Colour",
1010 "ANSI Black", "ANSI Black Bold",
1011 "ANSI Red", "ANSI Red Bold",
1012 "ANSI Green", "ANSI Green Bold",
1013 "ANSI Yellow", "ANSI Yellow Bold",
1014 "ANSI Blue", "ANSI Blue Bold",
1015 "ANSI Magenta", "ANSI Magenta Bold",
1016 "ANSI Cyan", "ANSI Cyan Bold",
1017 "ANSI White", "ANSI White Bold"
1019 static const int permanent
[] = {
1020 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1021 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1022 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1026 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1027 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1030 for (i
=0; i
<22; i
++)
1031 if (cfg
.bold_colour
|| permanent
[i
])
1032 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1033 (LPARAM
) colours
[i
]);
1035 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1036 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1037 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1038 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1041 switch (LOWORD(wParam
)) {
1042 case IDC5_BOLDCOLOUR
:
1043 if (HIWORD(wParam
) == BN_CLICKED
||
1044 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1046 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1047 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1048 if (cfg
.bold_colour
&& n
!=22) {
1049 for (i
=0; i
<22; i
++)
1051 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1053 (LPARAM
) colours
[i
]);
1054 } else if (!cfg
.bold_colour
&& n
!=12) {
1057 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1058 LB_DELETESTRING
, i
, 0);
1063 if (HIWORD(wParam
) == BN_CLICKED
||
1064 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1065 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1068 if (HIWORD(wParam
) == LBN_DBLCLK
||
1069 HIWORD(wParam
) == LBN_SELCHANGE
) {
1070 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1072 if (!cfg
.bold_colour
)
1073 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1074 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1075 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1076 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1080 if (HIWORD(wParam
) == BN_CLICKED
||
1081 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1082 static CHOOSECOLOR cc
;
1083 static DWORD custom
[16] = {0}; /* zero initialisers */
1084 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1086 if (!cfg
.bold_colour
)
1087 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1088 cc
.lStructSize
= sizeof(cc
);
1089 cc
.hwndOwner
= hwnd
;
1090 cc
.hInstance
= hinst
;
1091 cc
.lpCustColors
= custom
;
1092 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1094 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1095 if (ChooseColor(&cc
)) {
1097 (unsigned char) (cc
.rgbResult
& 0xFF);
1099 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1101 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1102 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1104 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1106 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1114 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1117 static int CALLBACK
LanguageProc (HWND hwnd
, UINT msg
,
1118 WPARAM wParam
, LPARAM lParam
) {
1121 CheckDlgButton (hwnd
, IDC6_ENABLEKOIWINXLAT
, cfg
.xlat_enablekoiwin
);
1122 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1124 switch (LOWORD(wParam
)) {
1125 case IDC6_ENABLEKOIWINXLAT
:
1126 if (HIWORD(wParam
) == BN_CLICKED
||
1127 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1128 cfg
.xlat_enablekoiwin
=
1129 IsDlgButtonChecked (hwnd
, IDC6_ENABLEKOIWINXLAT
);
1132 case IDC6_CAPSLOCKCYR
:
1133 if (HIWORD(wParam
) == BN_CLICKED
||
1134 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1135 cfg
.xlat_capslockcyr
=
1136 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1141 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1144 static DLGPROC panelproc
[NPANELS
] = {
1145 ConnectionProc
, KeyboardProc
, TerminalProc
,
1146 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, LanguageProc
1148 static char *panelids
[NPANELS
] = {
1149 MAKEINTRESOURCE(IDD_PANEL0
),
1150 MAKEINTRESOURCE(IDD_PANEL1
),
1151 MAKEINTRESOURCE(IDD_PANEL2
),
1152 MAKEINTRESOURCE(IDD_PANEL3
),
1153 MAKEINTRESOURCE(IDD_PANEL35
),
1154 MAKEINTRESOURCE(IDD_PANEL4
),
1155 MAKEINTRESOURCE(IDD_PANEL5
),
1156 MAKEINTRESOURCE(IDD_PANEL6
)
1159 static char *names
[NPANELS
] = {
1160 "Connection", "Keyboard", "Terminal", "Telnet",
1161 "SSH", "Selection", "Colours", "Language"
1164 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1165 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1167 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1168 WPARAM wParam
, LPARAM lParam
,
1169 int npanels
, int *panelnums
, HWND
*page
) {
1174 { /* centre the window */
1177 hw
= GetDesktopWindow();
1178 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1179 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1180 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1181 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1184 { /* initialise the tab control */
1188 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1189 for (i
=0; i
<npanels
; i
++) {
1190 tab
.mask
= TCIF_TEXT
;
1191 tab
.pszText
= names
[panelnums
[i
]];
1192 TabCtrl_InsertItem (hw
, i
, &tab
);
1194 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1195 hwnd, panelproc[panelnums[0]]);*/
1196 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1197 hwnd
, panelproc
[panelnums
[0]]);
1198 SetWindowLong (*page
, GWL_EXSTYLE
,
1199 GetWindowLong (*page
, GWL_EXSTYLE
) |
1200 WS_EX_CONTROLPARENT
);
1205 if (LOWORD(wParam
) == IDC_TAB
&&
1206 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1207 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1209 DestroyWindow (*page
);
1210 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1211 hwnd, panelproc[panelnums[i]]);*/
1212 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1213 hwnd
, panelproc
[panelnums
[i
]]);
1214 SetWindowLong (*page
, GWL_EXSTYLE
,
1215 GetWindowLong (*page
, GWL_EXSTYLE
) |
1216 WS_EX_CONTROLPARENT
);
1217 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1221 /* case WM_CTLCOLORDLG: */
1222 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1224 switch (LOWORD(wParam
)) {
1227 EndDialog (hwnd
, 1);
1232 EndDialog (hwnd
, 0);
1237 EndDialog (hwnd
, 0);
1243 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1244 WPARAM wParam
, LPARAM lParam
) {
1249 static HWND page
= NULL
;
1251 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1254 * If the Connection panel is active and the Session List
1255 * box is selected, we treat a press of Open to have an
1256 * implicit press of Load preceding it.
1258 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1259 i
= TabCtrl_GetCurSel(hw
);
1260 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1261 page
&& implicit_load_ok
) {
1262 SendMessage (page
, WM_COMMAND
,
1263 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1267 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1268 EnableWindow(hwnd
, 0);
1269 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1270 GetParent(hwnd
), AboutProc
);
1271 EnableWindow(hwnd
, 1);
1273 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1274 MAIN_NPANELS
, mainp
, &page
);
1277 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1278 WPARAM wParam
, LPARAM lParam
) {
1280 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1281 RECONF_NPANELS
, reconfp
, &page
);
1284 void get_sesslist(int allocate
) {
1285 static char *buffer
;
1286 int buflen
, bufsize
, i
, ret
;
1287 char otherbuf
[2048];
1292 if (RegCreateKey(HKEY_CURRENT_USER
,
1293 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1296 buflen
= bufsize
= 0;
1300 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1301 if (ret
== ERROR_SUCCESS
) {
1302 bufsize
= buflen
+ 2048;
1303 buffer
= srealloc(buffer
, bufsize
);
1304 unmungestr(otherbuf
, buffer
+buflen
);
1305 buflen
+= strlen(buffer
+buflen
)+1;
1307 } while (ret
== ERROR_SUCCESS
);
1308 buffer
= srealloc(buffer
, buflen
+1);
1309 buffer
[buflen
] = '\0';
1312 nsessions
= 1; /* "Default Settings" counts as one */
1314 if (strcmp(p
, "Default Settings"))
1320 sessions
= smalloc(nsessions
* sizeof(char *));
1321 sessions
[0] = "Default Settings";
1325 if (strcmp(p
, "Default Settings"))
1336 int do_config (void) {
1340 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1341 get_sesslist(FALSE
);
1346 int do_reconfig (HWND hwnd
) {
1350 backup_cfg
= cfg
; /* structure copy */
1351 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1353 cfg
= backup_cfg
; /* structure copy */
1357 void do_defaults (char *session
) {
1359 load_settings (session
, TRUE
);
1361 load_settings ("Default Settings", FALSE
);
1364 void lognegot (char *string
) {
1365 if (nnegots
>= negsize
) {
1367 negots
= srealloc (negots
, negsize
* sizeof(*negots
));
1369 negots
[nnegots
] = smalloc(1+strlen(string
));
1370 strcpy (negots
[nnegots
], string
);
1373 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1377 void shownegot (HWND hwnd
) {
1379 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1381 ShowWindow (logbox
, SW_SHOWNORMAL
);
1385 void showabout (HWND hwnd
) {
1387 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1389 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1393 void verify_ssh_host_key(char *host
, struct RSAKey
*key
) {
1394 char *keystr
, *otherstr
, *mungedhost
;
1399 * Format the key into a string.
1401 len
= rsastr_len(key
);
1402 keystr
= malloc(len
);
1404 fatalbox("Out of memory");
1405 rsastr_fmt(keystr
, key
);
1408 * Now read a saved key in from the registry and see what it
1411 otherstr
= malloc(len
);
1412 mungedhost
= malloc(3*strlen(host
)+1);
1413 if (!otherstr
|| !mungedhost
)
1414 fatalbox("Out of memory");
1416 mungestr(host
, mungedhost
);
1418 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1419 &rkey
) != ERROR_SUCCESS
) {
1420 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1421 "in the registry. There is thus no way to tell\n"
1422 "if the remote host is what you think it is.\n"
1423 "Connect anyway?", "PuTTY Problem",
1424 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1427 DWORD readlen
= len
;
1431 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1432 &type
, otherstr
, &readlen
);
1434 if (ret
== ERROR_MORE_DATA
||
1435 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1436 strcmp(otherstr
, keystr
))) {
1437 if (MessageBox(NULL
,
1438 "This host's host key is different from the\n"
1439 "one cached in the registry! Someone may be\n"
1440 "impersonating this host for malicious reasons;\n"
1441 "alternatively, the host key may have changed\n"
1442 "due to sloppy system administration.\n"
1443 "Replace key in registry and connect?",
1444 "PuTTY: Security Warning",
1445 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1447 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1449 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1450 if (MessageBox(NULL
,
1451 "This host's host key is not cached in the\n"
1452 "registry. Do you want to add it to the cache\n"
1453 "and carry on connecting?",
1455 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1457 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,