Configuration option for agent forwarding
[u/mdw/putty] / windlg.c
CommitLineData
374330e2 1#include <windows.h>
2#include <commctrl.h>
3#include <commdlg.h>
4#include <winsock.h>
5#include <stdio.h>
6#include <stdlib.h>
7
374330e2 8#include "ssh.h"
bea1ef5f 9#include "putty.h"
374330e2 10#include "win_res.h"
11
14963b8f 12#define NPANELS 8
13#define MAIN_NPANELS 8
14#define RECONF_NPANELS 5
374330e2 15
16static const char *const puttystr = PUTTY_REG_POS "\\Sessions";
17
c5e9c988 18static char **events = NULL;
19static int nevents = 0, negsize = 0;
20
374330e2 21static HWND logbox = NULL, abtbox = NULL;
22
23static char hex[16] = "0123456789ABCDEF";
24
25static void mungestr(char *in, char *out) {
26 int candot = 0;
27
28 while (*in) {
29 if (*in == ' ' || *in == '\\' || *in == '*' || *in == '?' ||
30 *in == '%' || *in < ' ' || *in > '~' || (*in == '.' && !candot)) {
31 *out++ = '%';
32 *out++ = hex[((unsigned char)*in) >> 4];
33 *out++ = hex[((unsigned char)*in) & 15];
34 } else
35 *out++ = *in;
36 in++;
37 candot = 1;
38 }
39 *out = '\0';
40 return;
41}
42
43static void unmungestr(char *in, char *out) {
374330e2 44 while (*in) {
45 if (*in == '%' && in[1] && in[2]) {
46 int i, j;
47
48 i = in[1] - '0'; i -= (i > 9 ? 7 : 0);
49 j = in[2] - '0'; j -= (j > 9 ? 7 : 0);
50
51 *out++ = (i<<4) + j;
52 in += 3;
53 } else
54 *out++ = *in++;
55 }
56 *out = '\0';
57 return;
58}
59
60static void wpps(HKEY key, LPCTSTR name, LPCTSTR value) {
61 RegSetValueEx(key, name, 0, REG_SZ, value, 1+strlen(value));
62}
63
64static void wppi(HKEY key, LPCTSTR name, int value) {
65 RegSetValueEx(key, name, 0, REG_DWORD,
66 (CONST BYTE *)&value, sizeof(value));
67}
68
69static void gpps(HKEY key, LPCTSTR name, LPCTSTR def,
70 LPTSTR val, int len) {
71 DWORD type, size;
72 size = len;
73
74 if (key == NULL ||
75 RegQueryValueEx(key, name, 0, &type, val, &size) != ERROR_SUCCESS ||
76 type != REG_SZ) {
77 strncpy(val, def, len);
78 val[len-1] = '\0';
79 }
80}
81
82static void gppi(HKEY key, LPCTSTR name, int def, int *i) {
83 DWORD type, val, size;
84 size = sizeof(val);
85
86 if (key == NULL ||
87 RegQueryValueEx(key, name, 0, &type,
88 (BYTE *)&val, &size) != ERROR_SUCCESS ||
89 size != sizeof(val) || type != REG_DWORD)
90 *i = def;
91 else
92 *i = val;
93}
94
374330e2 95static HINSTANCE hinst;
96
1cd246bb 97static int readytogo;
98
374330e2 99static void save_settings (char *section, int do_host) {
100 int i;
101 HKEY subkey1, sesskey;
102 char *p;
103
104 p = malloc(3*strlen(section)+1);
105 mungestr(section, p);
106
107 if (RegCreateKey(HKEY_CURRENT_USER, puttystr, &subkey1)!=ERROR_SUCCESS ||
108 RegCreateKey(subkey1, p, &sesskey) != ERROR_SUCCESS) {
374330e2 109 sesskey = NULL;
110 }
111
112 free(p);
113 RegCloseKey(subkey1);
114
115 wppi (sesskey, "Present", 1);
116 if (do_host) {
117 wpps (sesskey, "HostName", cfg.host);
118 wppi (sesskey, "PortNumber", cfg.port);
89ee5268 119 p = "raw";
a721b9eb 120 for (i = 0; backends[i].name != NULL; i++)
89ee5268 121 if (backends[i].protocol == cfg.protocol) {
122 p = backends[i].name;
123 break;
124 }
125 wpps (sesskey, "Protocol", p);
374330e2 126 }
127 wppi (sesskey, "CloseOnExit", !!cfg.close_on_exit);
9ef49106 128 wppi (sesskey, "WarnOnClose", !!cfg.warn_on_close);
374330e2 129 wpps (sesskey, "TerminalType", cfg.termtype);
130 wpps (sesskey, "TerminalSpeed", cfg.termspeed);
131 {
37508af4 132 char buf[2*sizeof(cfg.environmt)], *p, *q;
374330e2 133 p = buf;
37508af4 134 q = cfg.environmt;
374330e2 135 while (*q) {
136 while (*q) {
137 int c = *q++;
138 if (c == '=' || c == ',' || c == '\\')
139 *p++ = '\\';
140 if (c == '\t')
141 c = '=';
142 *p++ = c;
143 }
144 *p++ = ',';
145 q++;
146 }
147 *p = '\0';
148 wpps (sesskey, "Environment", buf);
149 }
150 wpps (sesskey, "UserName", cfg.username);
fef97f43 151 wppi (sesskey, "NoPTY", cfg.nopty);
979310f1 152 wppi (sesskey, "AgentFwd", cfg.agentfwd);
6abbf9e3 153 wpps (sesskey, "RemoteCmd", cfg.remote_cmd);
bea1ef5f 154 wpps (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
9697bfd2 155 cfg.cipher == CIPHER_DES ? "des" : "3des");
ccbfb941 156 wppi (sesskey, "AuthTIS", cfg.try_tis_auth);
adf799dd 157 wppi (sesskey, "SshProt", cfg.sshprot);
7cca0d81 158 wpps (sesskey, "PublicKeyFile", cfg.keyfile);
374330e2 159 wppi (sesskey, "RFCEnviron", cfg.rfc_environ);
160 wppi (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
161 wppi (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
c9def1b8 162 wppi (sesskey, "LinuxFunctionKeys", cfg.funky_type);
374330e2 163 wppi (sesskey, "ApplicationCursorKeys", cfg.app_cursor);
164 wppi (sesskey, "ApplicationKeypad", cfg.app_keypad);
c5e9c988 165 wppi (sesskey, "NetHackKeypad", cfg.nethack_keypad);
166 wppi (sesskey, "AltF4", cfg.alt_f4);
167 wppi (sesskey, "AltSpace", cfg.alt_space);
5bc238bb 168 wppi (sesskey, "LdiscTerm", cfg.ldisc_term);
217dceef 169 wppi (sesskey, "BlinkCur", cfg.blink_cur);
2a25a1b4 170 wppi (sesskey, "Beep", cfg.beep);
374330e2 171 wppi (sesskey, "ScrollbackLines", cfg.savelines);
172 wppi (sesskey, "DECOriginMode", cfg.dec_om);
173 wppi (sesskey, "AutoWrapMode", cfg.wrap_mode);
fef97f43 174 wppi (sesskey, "LFImpliesCR", cfg.lfhascr);
374330e2 175 wppi (sesskey, "WinNameAlways", cfg.win_name_always);
176 wppi (sesskey, "TermWidth", cfg.width);
177 wppi (sesskey, "TermHeight", cfg.height);
178 wpps (sesskey, "Font", cfg.font);
179 wppi (sesskey, "FontIsBold", cfg.fontisbold);
14963b8f 180 wppi (sesskey, "FontCharSet", cfg.fontcharset);
374330e2 181 wppi (sesskey, "FontHeight", cfg.fontheight);
182 wppi (sesskey, "FontVTMode", cfg.vtmode);
183 wppi (sesskey, "TryPalette", cfg.try_palette);
184 wppi (sesskey, "BoldAsColour", cfg.bold_colour);
185 for (i=0; i<22; i++) {
186 char buf[20], buf2[30];
187 sprintf(buf, "Colour%d", i);
188 sprintf(buf2, "%d,%d,%d", cfg.colours[i][0],
189 cfg.colours[i][1], cfg.colours[i][2]);
190 wpps (sesskey, buf, buf2);
191 }
192 wppi (sesskey, "MouseIsXterm", cfg.mouse_is_xterm);
193 for (i=0; i<256; i+=32) {
194 char buf[20], buf2[256];
195 int j;
196 sprintf(buf, "Wordness%d", i);
197 *buf2 = '\0';
198 for (j=i; j<i+32; j++) {
199 sprintf(buf2+strlen(buf2), "%s%d",
200 (*buf2 ? "," : ""), cfg.wordness[j]);
201 }
202 wpps (sesskey, buf, buf2);
203 }
14963b8f 204 wppi (sesskey, "KoiWinXlat", cfg.xlat_enablekoiwin);
d3d16feb 205 wppi (sesskey, "88592Xlat", cfg.xlat_88592w1250);
14963b8f 206 wppi (sesskey, "CapsLockCyr", cfg.xlat_capslockcyr);
c9def1b8 207 wppi (sesskey, "ScrollBar", cfg.scrollbar);
208 wppi (sesskey, "ScrollOnKey", cfg.scroll_on_key);
209 wppi (sesskey, "LockSize", cfg.locksize);
210 wppi (sesskey, "BCE", cfg.bce);
211 wppi (sesskey, "BlinkText", cfg.blinktext);
374330e2 212
213 RegCloseKey(sesskey);
214}
215
216static void del_session (char *section) {
217 HKEY subkey1;
218 char *p;
219
220 if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS)
221 return;
222
223 p = malloc(3*strlen(section)+1);
224 mungestr(section, p);
225 RegDeleteKey(subkey1, p);
226 free(p);
227
228 RegCloseKey(subkey1);
229}
230
231static void load_settings (char *section, int do_host) {
232 int i;
233 HKEY subkey1, sesskey;
234 char *p;
e277c42d 235 char prot[10];
374330e2 236
237 p = malloc(3*strlen(section)+1);
238 mungestr(section, p);
9816085c 239
240 if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS) {
374330e2 241 sesskey = NULL;
9816085c 242 } else {
243 if (RegOpenKey(subkey1, p, &sesskey) != ERROR_SUCCESS) {
244 sesskey = NULL;
245 }
246 RegCloseKey(subkey1);
374330e2 247 }
248
249 free(p);
374330e2 250
e277c42d 251 gpps (sesskey, "HostName", "", cfg.host, sizeof(cfg.host));
252 gppi (sesskey, "PortNumber", default_port, &cfg.port);
89ee5268 253
e277c42d 254 gpps (sesskey, "Protocol", "default", prot, 10);
89ee5268 255 cfg.protocol = default_protocol;
a721b9eb 256 for (i = 0; backends[i].name != NULL; i++)
89ee5268 257 if (!strcmp(prot, backends[i].name)) {
258 cfg.protocol = backends[i].protocol;
259 break;
260 }
e277c42d 261
374330e2 262 gppi (sesskey, "CloseOnExit", 1, &cfg.close_on_exit);
9ef49106 263 gppi (sesskey, "WarnOnClose", 1, &cfg.warn_on_close);
374330e2 264 gpps (sesskey, "TerminalType", "xterm", cfg.termtype,
265 sizeof(cfg.termtype));
266 gpps (sesskey, "TerminalSpeed", "38400,38400", cfg.termspeed,
267 sizeof(cfg.termspeed));
268 {
37508af4 269 char buf[2*sizeof(cfg.environmt)], *p, *q;
374330e2 270 gpps (sesskey, "Environment", "", buf, sizeof(buf));
271 p = buf;
29b611b7 272 q = cfg.environmt;
374330e2 273 while (*p) {
274 while (*p && *p != ',') {
275 int c = *p++;
276 if (c == '=')
277 c = '\t';
278 if (c == '\\')
279 c = *p++;
29b611b7 280 *q++ = c;
374330e2 281 }
282 if (*p == ',') p++;
283 *q++ = '\0';
284 }
285 *q = '\0';
286 }
287 gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username));
fef97f43 288 gppi (sesskey, "NoPTY", 0, &cfg.nopty);
979310f1 289 gppi (sesskey, "AgentFwd", 0, &cfg.agentfwd);
6abbf9e3 290 gpps (sesskey, "RemoteCmd", "", cfg.remote_cmd, sizeof(cfg.remote_cmd));
bea1ef5f 291 {
292 char cipher[10];
293 gpps (sesskey, "Cipher", "3des", cipher, 10);
294 if (!strcmp(cipher, "blowfish"))
295 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 296 else if (!strcmp(cipher, "des"))
297 cfg.cipher = CIPHER_DES;
bea1ef5f 298 else
299 cfg.cipher = CIPHER_3DES;
300 }
adf799dd 301 gppi (sesskey, "SshProt", 1, &cfg.sshprot);
ccbfb941 302 gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
7cca0d81 303 gpps (sesskey, "PublicKeyFile", "", cfg.keyfile, sizeof(cfg.keyfile));
374330e2 304 gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
305 gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
306 gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
c9def1b8 307 gppi (sesskey, "LinuxFunctionKeys", 0, &cfg.funky_type);
374330e2 308 gppi (sesskey, "ApplicationCursorKeys", 0, &cfg.app_cursor);
309 gppi (sesskey, "ApplicationKeypad", 0, &cfg.app_keypad);
c5e9c988 310 gppi (sesskey, "NetHackKeypad", 0, &cfg.nethack_keypad);
311 gppi (sesskey, "AltF4", 1, &cfg.alt_f4);
312 gppi (sesskey, "AltSpace", 0, &cfg.alt_space);
5bc238bb 313 gppi (sesskey, "LdiscTerm", 0, &cfg.ldisc_term);
217dceef 314 gppi (sesskey, "BlinkCur", 0, &cfg.blink_cur);
2a25a1b4 315 gppi (sesskey, "Beep", 1, &cfg.beep);
374330e2 316 gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines);
317 gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om);
318 gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode);
fef97f43 319 gppi (sesskey, "LFImpliesCR", 0, &cfg.lfhascr);
374330e2 320 gppi (sesskey, "WinNameAlways", 0, &cfg.win_name_always);
321 gppi (sesskey, "TermWidth", 80, &cfg.width);
322 gppi (sesskey, "TermHeight", 24, &cfg.height);
323 gpps (sesskey, "Font", "Courier", cfg.font, sizeof(cfg.font));
324 gppi (sesskey, "FontIsBold", 0, &cfg.fontisbold);
14963b8f 325 gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg.fontcharset);
374330e2 326 gppi (sesskey, "FontHeight", 10, &cfg.fontheight);
2a7bfc6e 327 gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg.vtmode);
374330e2 328 gppi (sesskey, "TryPalette", 0, &cfg.try_palette);
329 gppi (sesskey, "BoldAsColour", 1, &cfg.bold_colour);
330 for (i=0; i<22; i++) {
331 static char *defaults[] = {
332 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
333 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
334 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
335 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
336 "85,255,255", "187,187,187", "255,255,255"
337 };
338 char buf[20], buf2[30];
1d470ad2 339 int c0, c1, c2;
374330e2 340 sprintf(buf, "Colour%d", i);
341 gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2));
1d470ad2 342 if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
343 cfg.colours[i][0] = c0;
344 cfg.colours[i][1] = c1;
345 cfg.colours[i][2] = c2;
346 }
374330e2 347 }
348 gppi (sesskey, "MouseIsXterm", 0, &cfg.mouse_is_xterm);
349 for (i=0; i<256; i+=32) {
350 static char *defaults[] = {
351 "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",
352 "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",
353 "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",
354 "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",
355 "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",
356 "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",
357 "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",
358 "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"
359 };
360 char buf[20], buf2[256], *p;
361 int j;
362 sprintf(buf, "Wordness%d", i);
363 gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2));
364 p = buf2;
365 for (j=i; j<i+32; j++) {
366 char *q = p;
367 while (*p && *p != ',') p++;
368 if (*p == ',') *p++ = '\0';
369 cfg.wordness[j] = atoi(q);
370 }
371 }
14963b8f 372 gppi (sesskey, "KoiWinXlat", 0, &cfg.xlat_enablekoiwin);
d3d16feb 373 gppi (sesskey, "88592Xlat", 0, &cfg.xlat_88592w1250);
14963b8f 374 gppi (sesskey, "CapsLockCyr", 0, &cfg.xlat_capslockcyr);
c9def1b8 375 gppi (sesskey, "ScrollBar", 1, &cfg.scrollbar);
376 gppi (sesskey, "ScrollOnKey", 0, &cfg.scroll_on_key);
377 gppi (sesskey, "LockSize", 0, &cfg.locksize);
378 gppi (sesskey, "BCE", 0, &cfg.bce);
379 gppi (sesskey, "BlinkText", 0, &cfg.blinktext);
14963b8f 380
374330e2 381 RegCloseKey(sesskey);
382}
383
c9def1b8 384static void force_normal(HWND hwnd)
385{
386static int recurse = 0;
387
388 WINDOWPLACEMENT wp;
389
390 if(recurse) return;
391 recurse = 1;
392
393 wp.length = sizeof(wp);
394 if (GetWindowPlacement(hwnd, &wp))
395 {
396 wp.showCmd = SW_SHOWNORMAL;
397 SetWindowPlacement(hwnd, &wp);
398 }
399 recurse = 0;
400}
401
374330e2 402static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
403 BOOL ok;
404 int n;
405 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
406 if (ok)
407 *result = n;
408}
409
410static int CALLBACK LogProc (HWND hwnd, UINT msg,
411 WPARAM wParam, LPARAM lParam) {
412 int i;
413
414 switch (msg) {
415 case WM_INITDIALOG:
c5e9c988 416 for (i=0; i<nevents; i++)
374330e2 417 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
c5e9c988 418 0, (LPARAM)events[i]);
374330e2 419 return 1;
420/* case WM_CTLCOLORDLG: */
421/* return (int) GetStockObject (LTGRAY_BRUSH); */
422 case WM_COMMAND:
423 switch (LOWORD(wParam)) {
424 case IDOK:
425 logbox = NULL;
426 DestroyWindow (hwnd);
427 return 0;
428 }
429 return 0;
430 case WM_CLOSE:
431 logbox = NULL;
432 DestroyWindow (hwnd);
433 return 0;
434 }
435 return 0;
436}
437
d57835ab 438static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
439 WPARAM wParam, LPARAM lParam) {
440 switch (msg) {
441 case WM_INITDIALOG:
442 return 1;
443 case WM_COMMAND:
444 switch (LOWORD(wParam)) {
445 case IDOK:
446 abtbox = NULL;
447 DestroyWindow (hwnd);
448 return 0;
449 }
450 return 0;
451 case WM_CLOSE:
452 abtbox = NULL;
453 DestroyWindow (hwnd);
454 return 0;
455 }
456 return 0;
457}
458
374330e2 459static int CALLBACK AboutProc (HWND hwnd, UINT msg,
460 WPARAM wParam, LPARAM lParam) {
461 switch (msg) {
462 case WM_INITDIALOG:
067a15ea 463 SetDlgItemText (hwnd, IDA_VERSION, ver);
374330e2 464 return 1;
465/* case WM_CTLCOLORDLG: */
466/* return (int) GetStockObject (LTGRAY_BRUSH); */
467/* case WM_CTLCOLORSTATIC: */
468/* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
469/* return (int) GetStockObject (LTGRAY_BRUSH); */
470 case WM_COMMAND:
471 switch (LOWORD(wParam)) {
472 case IDOK:
473 abtbox = NULL;
474 DestroyWindow (hwnd);
475 return 0;
476 case IDA_LICENCE:
477 EnableWindow(hwnd, 0);
478 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
d57835ab 479 NULL, LicenceProc);
374330e2 480 EnableWindow(hwnd, 1);
481 return 0;
482 }
483 return 0;
484 case WM_CLOSE:
485 abtbox = NULL;
486 DestroyWindow (hwnd);
487 return 0;
488 }
489 return 0;
490}
491
492static int GeneralPanelProc (HWND hwnd, UINT msg,
493 WPARAM wParam, LPARAM lParam) {
494 switch (msg) {
495 case WM_INITDIALOG:
496 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
497 return 1;
498/* case WM_CTLCOLORDLG: */
499/* return (int) GetStockObject (LTGRAY_BRUSH); */
500/* case WM_CTLCOLORSTATIC: */
501/* case WM_CTLCOLORBTN: */
502/* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
503/* return (int) GetStockObject (LTGRAY_BRUSH); */
504 case WM_CLOSE:
505 DestroyWindow (hwnd);
506 return 1;
507 }
508 return 0;
509}
510
511static int CALLBACK ConnectionProc (HWND hwnd, UINT msg,
512 WPARAM wParam, LPARAM lParam) {
513 int i;
514
515 switch (msg) {
516 case WM_INITDIALOG:
517 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
518 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
519 for (i = 0; i < nsessions; i++)
520 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
521 0, (LPARAM) (sessions[i]));
5e1a8e27 522 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
523 cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
524 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW );
374330e2 525 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 526 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 527 break;
1cd246bb 528 case WM_LBUTTONUP:
529 /*
530 * Button release should trigger WM_OK if there was a
531 * previous double click on the session list.
532 */
533 ReleaseCapture();
534 if (readytogo)
535 SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0);
536 break;
374330e2 537 case WM_COMMAND:
538 switch (LOWORD(wParam)) {
539 case IDC0_PROTTELNET:
540 case IDC0_PROTSSH:
5e1a8e27 541 case IDC0_PROTRAW:
374330e2 542 if (HIWORD(wParam) == BN_CLICKED ||
543 HIWORD(wParam) == BN_DOUBLECLICKED) {
544 int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH);
5e1a8e27 545 int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET);
546 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
374330e2 547 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
548 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
549 cfg.port = i ? 22 : 23;
550 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
551 }
552 }
553 break;
554 case IDC0_HOST:
555 if (HIWORD(wParam) == EN_CHANGE)
556 GetDlgItemText (hwnd, IDC0_HOST, cfg.host,
557 sizeof(cfg.host)-1);
558 break;
559 case IDC0_PORT:
560 if (HIWORD(wParam) == EN_CHANGE)
561 MyGetDlgItemInt (hwnd, IDC0_PORT, &cfg.port);
562 break;
563 case IDC0_CLOSEEXIT:
564 if (HIWORD(wParam) == BN_CLICKED ||
565 HIWORD(wParam) == BN_DOUBLECLICKED)
566 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC0_CLOSEEXIT);
567 break;
9ef49106 568 case IDC0_CLOSEWARN:
569 if (HIWORD(wParam) == BN_CLICKED ||
570 HIWORD(wParam) == BN_DOUBLECLICKED)
571 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC0_CLOSEWARN);
572 break;
374330e2 573 case IDC0_SESSEDIT:
574 if (HIWORD(wParam) == EN_CHANGE)
575 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
576 (WPARAM) -1, 0);
577 break;
578 case IDC0_SESSSAVE:
579 if (HIWORD(wParam) == BN_CLICKED ||
580 HIWORD(wParam) == BN_DOUBLECLICKED) {
581 /*
582 * Save a session
583 */
584 char str[2048];
585 GetDlgItemText (hwnd, IDC0_SESSEDIT, str, sizeof(str)-1);
586 if (!*str) {
587 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
588 LB_GETCURSEL, 0, 0);
589 if (n == LB_ERR) {
590 MessageBeep(0);
591 break;
592 }
593 strcpy (str, sessions[n]);
594 }
595 save_settings (str, !!strcmp(str, "Default Settings"));
596 get_sesslist (FALSE);
597 get_sesslist (TRUE);
598 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
599 0, 0);
600 for (i = 0; i < nsessions; i++)
601 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
602 0, (LPARAM) (sessions[i]));
603 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
604 (WPARAM) -1, 0);
605 }
606 break;
607 case IDC0_SESSLIST:
608 case IDC0_SESSLOAD:
609 if (LOWORD(wParam) == IDC0_SESSLOAD &&
610 HIWORD(wParam) != BN_CLICKED &&
611 HIWORD(wParam) != BN_DOUBLECLICKED)
612 break;
613 if (LOWORD(wParam) == IDC0_SESSLIST &&
614 HIWORD(wParam) != LBN_DBLCLK)
615 break;
616 {
617 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
618 LB_GETCURSEL, 0, 0);
619 if (n == LB_ERR) {
620 MessageBeep(0);
621 break;
622 }
623 load_settings (sessions[n],
624 !!strcmp(sessions[n], "Default Settings"));
625 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
626 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
5e1a8e27 627 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
374330e2 628 (cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
5e1a8e27 629 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW));
374330e2 630 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 631 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 632 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
633 (WPARAM) -1, 0);
634 }
635 if (LOWORD(wParam) == IDC0_SESSLIST) {
636 /*
637 * A double-click on a saved session should
638 * actually start the session, not just load it.
639 * Unless it's Default Settings or some other
640 * host-less set of saved settings.
641 */
1cd246bb 642 if (*cfg.host) {
643 readytogo = TRUE;
644 SetCapture(hwnd);
645 }
374330e2 646 }
647 break;
648 case IDC0_SESSDEL:
649 if (HIWORD(wParam) == BN_CLICKED ||
650 HIWORD(wParam) == BN_DOUBLECLICKED) {
651 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
652 LB_GETCURSEL, 0, 0);
653 if (n == LB_ERR || n == 0) {
654 MessageBeep(0);
655 break;
656 }
657 del_session(sessions[n]);
658 get_sesslist (FALSE);
659 get_sesslist (TRUE);
660 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
661 0, 0);
662 for (i = 0; i < nsessions; i++)
663 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
664 0, (LPARAM) (sessions[i]));
665 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
666 (WPARAM) -1, 0);
667 }
668 }
669 }
670 return GeneralPanelProc (hwnd, msg, wParam, lParam);
671}
672
673static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
674 WPARAM wParam, LPARAM lParam) {
675 switch (msg) {
676 case WM_INITDIALOG:
677 CheckRadioButton (hwnd, IDC1_DEL008, IDC1_DEL127,
678 cfg.bksp_is_delete ? IDC1_DEL127 : IDC1_DEL008);
679 CheckRadioButton (hwnd, IDC1_HOMETILDE, IDC1_HOMERXVT,
680 cfg.rxvt_homeend ? IDC1_HOMERXVT : IDC1_HOMETILDE);
c9def1b8 681 CheckRadioButton (hwnd, IDC1_FUNCTILDE, IDC1_FUNCXTERM,
682 cfg.funky_type ?
683 (cfg.funky_type==2 ? IDC1_FUNCXTERM
684 : IDC1_FUNCLINUX )
685 : IDC1_FUNCTILDE);
374330e2 686 CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
687 cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
c5e9c988 688 CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
689 cfg.nethack_keypad ? IDC1_KPNH :
374330e2 690 cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
c5e9c988 691 CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
692 CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
5bc238bb 693 CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
c9def1b8 694 CheckDlgButton (hwnd, IDC1_SCROLLKEY, cfg.scroll_on_key);
374330e2 695 break;
696 case WM_COMMAND:
697 if (HIWORD(wParam) == BN_CLICKED ||
698 HIWORD(wParam) == BN_DOUBLECLICKED)
699 switch (LOWORD(wParam)) {
700 case IDC1_DEL008:
701 case IDC1_DEL127:
702 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC1_DEL127);
703 break;
704 case IDC1_HOMETILDE:
705 case IDC1_HOMERXVT:
706 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC1_HOMERXVT);
707 break;
c9def1b8 708 case IDC1_FUNCXTERM:
709 cfg.funky_type = 2;
710 break;
374330e2 711 case IDC1_FUNCTILDE:
712 case IDC1_FUNCLINUX:
c9def1b8 713 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC1_FUNCLINUX);
374330e2 714 break;
715 case IDC1_KPNORMAL:
716 case IDC1_KPAPPLIC:
717 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
c5e9c988 718 cfg.nethack_keypad = FALSE;
719 break;
720 case IDC1_KPNH:
721 cfg.app_keypad = FALSE;
722 cfg.nethack_keypad = TRUE;
374330e2 723 break;
724 case IDC1_CURNORMAL:
725 case IDC1_CURAPPLIC:
726 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
727 break;
c5e9c988 728 case IDC1_ALTF4:
729 if (HIWORD(wParam) == BN_CLICKED ||
730 HIWORD(wParam) == BN_DOUBLECLICKED)
731 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
732 break;
733 case IDC1_ALTSPACE:
734 if (HIWORD(wParam) == BN_CLICKED ||
735 HIWORD(wParam) == BN_DOUBLECLICKED)
736 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
737 break;
5bc238bb 738 case IDC1_LDISCTERM:
739 if (HIWORD(wParam) == BN_CLICKED ||
740 HIWORD(wParam) == BN_DOUBLECLICKED)
741 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
742 break;
c9def1b8 743 case IDC1_SCROLLKEY:
217dceef 744 if (HIWORD(wParam) == BN_CLICKED ||
745 HIWORD(wParam) == BN_DOUBLECLICKED)
c9def1b8 746 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC1_SCROLLKEY);
217dceef 747 break;
374330e2 748 }
749 }
750 return GeneralPanelProc (hwnd, msg, wParam, lParam);
751}
752
753static void fmtfont (char *buf) {
754 sprintf (buf, "Font: %s, ", cfg.font);
755 if (cfg.fontisbold)
756 strcat(buf, "bold, ");
757 if (cfg.fontheight == 0)
758 strcat (buf, "default height");
759 else
760 sprintf (buf+strlen(buf), "%d-%s",
761 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
762 (cfg.fontheight < 0 ? "pixel" : "point"));
763}
764
765static int CALLBACK TerminalProc (HWND hwnd, UINT msg,
766 WPARAM wParam, LPARAM lParam) {
767 CHOOSEFONT cf;
768 LOGFONT lf;
769 char fontstatic[256];
770
771 switch (msg) {
772 case WM_INITDIALOG:
773 CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode);
774 CheckDlgButton (hwnd, IDC2_WINNAME, cfg.win_name_always);
775 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
fef97f43 776 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
374330e2 777 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
778 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
779 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
780 fmtfont (fontstatic);
781 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
c9def1b8 782 CheckDlgButton (hwnd, IDC1_BLINKCUR, cfg.blink_cur);
783 CheckDlgButton (hwnd, IDC1_BEEP, cfg.beep);
784 CheckDlgButton (hwnd, IDC2_SCROLLBAR, cfg.scrollbar);
785 CheckDlgButton (hwnd, IDC2_LOCKSIZE, cfg.locksize);
786 CheckDlgButton (hwnd, IDC2_BCE, cfg.bce);
787 CheckDlgButton (hwnd, IDC2_BLINKTEXT, cfg.blinktext);
374330e2 788 break;
789 case WM_COMMAND:
790 switch (LOWORD(wParam)) {
791 case IDC2_WRAPMODE:
792 if (HIWORD(wParam) == BN_CLICKED ||
793 HIWORD(wParam) == BN_DOUBLECLICKED)
794 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
795 break;
796 case IDC2_WINNAME:
797 if (HIWORD(wParam) == BN_CLICKED ||
798 HIWORD(wParam) == BN_DOUBLECLICKED)
799 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC2_WINNAME);
800 break;
801 case IDC2_DECOM:
802 if (HIWORD(wParam) == BN_CLICKED ||
803 HIWORD(wParam) == BN_DOUBLECLICKED)
804 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
805 break;
fef97f43 806 case IDC2_LFHASCR:
807 if (HIWORD(wParam) == BN_CLICKED ||
808 HIWORD(wParam) == BN_DOUBLECLICKED)
809 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
810 break;
374330e2 811 case IDC2_ROWSEDIT:
812 if (HIWORD(wParam) == EN_CHANGE)
813 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
814 break;
815 case IDC2_COLSEDIT:
816 if (HIWORD(wParam) == EN_CHANGE)
817 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
818 break;
819 case IDC2_SAVEEDIT:
820 if (HIWORD(wParam) == EN_CHANGE)
821 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
822 break;
823 case IDC2_CHOOSEFONT:
824 lf.lfHeight = cfg.fontheight;
825 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
826 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
827 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
14963b8f 828 lf.lfCharSet = cfg.fontcharset;
374330e2 829 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
830 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
831 lf.lfQuality = DEFAULT_QUALITY;
832 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
833 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
834 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
835
836 cf.lStructSize = sizeof(cf);
837 cf.hwndOwner = hwnd;
838 cf.lpLogFont = &lf;
839 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
840 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
841
842 if (ChooseFont (&cf)) {
843 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
844 cfg.font[sizeof(cfg.font)-1] = '\0';
845 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
14963b8f 846 cfg.fontcharset = lf.lfCharSet;
374330e2 847 cfg.fontheight = lf.lfHeight;
848 fmtfont (fontstatic);
849 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
850 }
851 break;
c9def1b8 852 case IDC1_BLINKCUR:
853 if (HIWORD(wParam) == BN_CLICKED ||
854 HIWORD(wParam) == BN_DOUBLECLICKED)
855 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC1_BLINKCUR);
856 break;
857 case IDC1_BEEP:
858 if (HIWORD(wParam) == BN_CLICKED ||
859 HIWORD(wParam) == BN_DOUBLECLICKED)
860 cfg.beep = IsDlgButtonChecked (hwnd, IDC1_BEEP);
861 break;
862 case IDC2_SCROLLBAR:
863 if (HIWORD(wParam) == BN_CLICKED ||
864 HIWORD(wParam) == BN_DOUBLECLICKED)
865 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC2_SCROLLBAR);
866 break;
867 case IDC2_LOCKSIZE:
868 if (HIWORD(wParam) == BN_CLICKED ||
869 HIWORD(wParam) == BN_DOUBLECLICKED)
870 cfg.locksize = IsDlgButtonChecked (hwnd, IDC2_LOCKSIZE);
871 break;
872 case IDC2_BLINKTEXT:
873 if (HIWORD(wParam) == BN_CLICKED ||
874 HIWORD(wParam) == BN_DOUBLECLICKED)
875 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC2_BLINKTEXT);
876 break;
877 case IDC2_BCE:
878 if (HIWORD(wParam) == BN_CLICKED ||
879 HIWORD(wParam) == BN_DOUBLECLICKED)
880 cfg.bce = IsDlgButtonChecked (hwnd, IDC2_BCE);
881 break;
374330e2 882 }
883 break;
884 }
885 return GeneralPanelProc (hwnd, msg, wParam, lParam);
886}
887
888static int CALLBACK TelnetProc (HWND hwnd, UINT msg,
889 WPARAM wParam, LPARAM lParam) {
890 int i;
891
892 switch (msg) {
893 case WM_INITDIALOG:
894 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
895 SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed);
896 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
897 {
37508af4 898 char *p = cfg.environmt;
374330e2 899 while (*p) {
900 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0,
901 (LPARAM) p);
902 p += strlen(p)+1;
903 }
904 }
905 CheckRadioButton (hwnd, IDC3_EMBSD, IDC3_EMRFC,
906 cfg.rfc_environ ? IDC3_EMRFC : IDC3_EMBSD);
907 break;
908 case WM_COMMAND:
909 switch (LOWORD(wParam)) {
910 case IDC3_TTEDIT:
911 if (HIWORD(wParam) == EN_CHANGE)
912 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
913 sizeof(cfg.termtype)-1);
914 break;
915 case IDC3_TSEDIT:
916 if (HIWORD(wParam) == EN_CHANGE)
917 GetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed,
918 sizeof(cfg.termspeed)-1);
919 break;
920 case IDC3_LOGEDIT:
921 if (HIWORD(wParam) == EN_CHANGE)
922 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
923 sizeof(cfg.username)-1);
924 break;
925 case IDC3_EMBSD:
926 case IDC3_EMRFC:
927 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC3_EMRFC);
928 break;
929 case IDC3_ENVADD:
930 if (HIWORD(wParam) == BN_CLICKED ||
931 HIWORD(wParam) == BN_DOUBLECLICKED) {
37508af4 932 char str[sizeof(cfg.environmt)];
374330e2 933 char *p;
934 GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1);
935 if (!*str) {
936 MessageBeep(0);
937 break;
938 }
939 p = str + strlen(str);
940 *p++ = '\t';
941 GetDlgItemText (hwnd, IDC3_VALEDIT, p, sizeof(str)-1-(p-str));
942 if (!*p) {
943 MessageBeep(0);
944 break;
945 }
37508af4 946 p = cfg.environmt;
374330e2 947 while (*p) {
948 while (*p) p++;
949 p++;
950 }
37508af4 951 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
374330e2 952 strcpy (p, str);
953 p[strlen(str)+1] = '\0';
954 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING,
955 0, (LPARAM)str);
956 SetDlgItemText (hwnd, IDC3_VAREDIT, "");
957 SetDlgItemText (hwnd, IDC3_VALEDIT, "");
958 } else {
959 MessageBox(hwnd, "Environment too big", "PuTTY Error",
960 MB_OK | MB_ICONERROR);
961 }
962 }
963 break;
964 case IDC3_ENVREMOVE:
965 if (HIWORD(wParam) != BN_CLICKED &&
966 HIWORD(wParam) != BN_DOUBLECLICKED)
967 break;
968 i = SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_GETCURSEL, 0, 0);
969 if (i == LB_ERR)
970 MessageBeep (0);
971 else {
972 char *p, *q;
973
974 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING,
975 i, 0);
37508af4 976 p = cfg.environmt;
374330e2 977 while (i > 0) {
978 if (!*p)
979 goto disaster;
980 while (*p) p++;
981 p++;
982 i--;
983 }
984 q = p;
985 if (!*p)
986 goto disaster;
987 while (*p) p++;
988 p++;
989 while (*p) {
990 while (*p)
991 *q++ = *p++;
992 *q++ = *p++;
993 }
994 *q = '\0';
995 disaster:;
996 }
997 break;
998 }
999 break;
1000 }
1001 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1002}
1003
1004static int CALLBACK SshProc (HWND hwnd, UINT msg,
1005 WPARAM wParam, LPARAM lParam) {
7cca0d81 1006 OPENFILENAME of;
1007 char filename[sizeof(cfg.keyfile)];
1008
374330e2 1009 switch (msg) {
1010 case WM_INITDIALOG:
1011 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
1012 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
fef97f43 1013 CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty);
979310f1 1014 CheckDlgButton (hwnd, IDC3_AGENTFWD, cfg.agentfwd);
9697bfd2 1015 CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES,
bea1ef5f 1016 cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF :
9697bfd2 1017 cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES :
bea1ef5f 1018 IDC3_CIPHER3DES);
adf799dd 1019 CheckRadioButton (hwnd, IDC3_SSHPROT1, IDC3_SSHPROT2,
1020 cfg.sshprot == 1 ? IDC3_SSHPROT1 : IDC3_SSHPROT2);
ccbfb941 1021 CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
7cca0d81 1022 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
374330e2 1023 break;
1024 case WM_COMMAND:
1025 switch (LOWORD(wParam)) {
1026 case IDC3_TTEDIT:
1027 if (HIWORD(wParam) == EN_CHANGE)
1028 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
1029 sizeof(cfg.termtype)-1);
1030 break;
1031 case IDC3_LOGEDIT:
1032 if (HIWORD(wParam) == EN_CHANGE)
1033 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
1034 sizeof(cfg.username)-1);
1035 break;
fef97f43 1036 case IDC3_NOPTY:
1037 if (HIWORD(wParam) == BN_CLICKED ||
1038 HIWORD(wParam) == BN_DOUBLECLICKED)
1039 cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY);
1040 break;
979310f1 1041 case IDC3_AGENTFWD:
1042 if (HIWORD(wParam) == BN_CLICKED ||
1043 HIWORD(wParam) == BN_DOUBLECLICKED)
1044 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC3_AGENTFWD);
1045 break;
bea1ef5f 1046 case IDC3_CIPHER3DES:
1047 case IDC3_CIPHERBLOWF:
9697bfd2 1048 case IDC3_CIPHERDES:
bea1ef5f 1049 if (HIWORD(wParam) == BN_CLICKED ||
1050 HIWORD(wParam) == BN_DOUBLECLICKED) {
1051 if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES))
1052 cfg.cipher = CIPHER_3DES;
1053 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF))
1054 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 1055 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES))
1056 cfg.cipher = CIPHER_DES;
bea1ef5f 1057 }
1058 break;
adf799dd 1059 case IDC3_SSHPROT1:
1060 case IDC3_SSHPROT2:
1061 if (HIWORD(wParam) == BN_CLICKED ||
1062 HIWORD(wParam) == BN_DOUBLECLICKED) {
1063 if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT1))
1064 cfg.sshprot = 1;
1065 else if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT2))
1066 cfg.sshprot = 2;
1067 }
1068 break;
ccbfb941 1069 case IDC3_AUTHTIS:
1070 if (HIWORD(wParam) == BN_CLICKED ||
1071 HIWORD(wParam) == BN_DOUBLECLICKED)
1072 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
1073 break;
7cca0d81 1074 case IDC3_PKEDIT:
1075 if (HIWORD(wParam) == EN_CHANGE)
1076 GetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile,
1077 sizeof(cfg.keyfile)-1);
1078 break;
1079 case IDC3_PKBUTTON:
1080 /*
1081 * FIXME: this crashes. Find out why.
1082 */
1083 memset(&of, 0, sizeof(of));
1084#ifdef OPENFILENAME_SIZE_VERSION_400
1085 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1086#else
1087 of.lStructSize = sizeof(of);
1088#endif
1089 of.hwndOwner = hwnd;
1090 of.lpstrFilter = "All Files\0*\0\0\0";
1091 of.lpstrCustomFilter = NULL;
1092 of.nFilterIndex = 1;
1093 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1094 of.nMaxFile = sizeof(filename);
1095 of.lpstrFileTitle = NULL;
1096 of.lpstrInitialDir = NULL;
1097 of.lpstrTitle = "Select Public Key File";
1098 of.Flags = 0;
1099 if (GetOpenFileName(&of)) {
1100 strcpy(cfg.keyfile, filename);
1101 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
1102 }
1103 break;
374330e2 1104 }
1105 break;
1106 }
1107 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1108}
1109
1110static int CALLBACK SelectionProc (HWND hwnd, UINT msg,
1111 WPARAM wParam, LPARAM lParam) {
1112 int i;
1113
1114 switch (msg) {
1115 case WM_INITDIALOG:
1116 CheckRadioButton (hwnd, IDC4_MBWINDOWS, IDC4_MBXTERM,
1117 cfg.mouse_is_xterm ? IDC4_MBXTERM : IDC4_MBWINDOWS);
1118 {
1119 static int tabs[4] = {25, 61, 96, 128};
1120 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_SETTABSTOPS, 4,
1121 (LPARAM) tabs);
1122 }
1123 for (i=0; i<256; i++) {
1124 char str[100];
1125 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1126 (i>=0x21 && i != 0x7F) ? i : ' ',
1127 cfg.wordness[i]);
1128 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_ADDSTRING, 0,
1129 (LPARAM) str);
1130 }
1131 break;
1132 case WM_COMMAND:
1133 switch (LOWORD(wParam)) {
1134 case IDC4_MBWINDOWS:
1135 case IDC4_MBXTERM:
1136 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC4_MBXTERM);
1137 break;
1138 case IDC4_CCSET:
1139 {
1140 BOOL ok;
1141 int i;
1142 int n = GetDlgItemInt (hwnd, IDC4_CCEDIT, &ok, FALSE);
1143
1144 if (!ok)
1145 MessageBeep (0);
1146 else {
1147 for (i=0; i<256; i++)
1148 if (SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_GETSEL,
1149 i, 0)) {
1150 char str[100];
1151 cfg.wordness[i] = n;
1152 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1153 LB_DELETESTRING, i, 0);
1154 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1155 (i>=0x21 && i != 0x7F) ? i : ' ',
1156 cfg.wordness[i]);
1157 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1158 LB_INSERTSTRING, i,
1159 (LPARAM)str);
1160 }
1161 }
1162 }
1163 break;
1164 }
1165 break;
1166 }
1167 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1168}
1169
1170static int CALLBACK ColourProc (HWND hwnd, UINT msg,
1171 WPARAM wParam, LPARAM lParam) {
1172 static const char *const colours[] = {
1173 "Default Foreground", "Default Bold Foreground",
1174 "Default Background", "Default Bold Background",
1175 "Cursor Text", "Cursor Colour",
1176 "ANSI Black", "ANSI Black Bold",
1177 "ANSI Red", "ANSI Red Bold",
1178 "ANSI Green", "ANSI Green Bold",
1179 "ANSI Yellow", "ANSI Yellow Bold",
1180 "ANSI Blue", "ANSI Blue Bold",
1181 "ANSI Magenta", "ANSI Magenta Bold",
1182 "ANSI Cyan", "ANSI Cyan Bold",
1183 "ANSI White", "ANSI White Bold"
1184 };
1185 static const int permanent[] = {
1186 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
1187 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
1188 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
1189 };
1190 switch (msg) {
1191 case WM_INITDIALOG:
1192 CheckDlgButton (hwnd, IDC5_BOLDCOLOUR, cfg.bold_colour);
1193 CheckDlgButton (hwnd, IDC5_PALETTE, cfg.try_palette);
1194 {
1195 int i;
1196 for (i=0; i<22; i++)
1197 if (cfg.bold_colour || permanent[i])
1198 SendDlgItemMessage (hwnd, IDC5_LIST, LB_ADDSTRING, 0,
1199 (LPARAM) colours[i]);
1200 }
1201 SendDlgItemMessage (hwnd, IDC5_LIST, LB_SETCURSEL, 0, 0);
1202 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[0][0], FALSE);
1203 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[0][1], FALSE);
1204 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[0][2], FALSE);
1205 break;
1206 case WM_COMMAND:
1207 switch (LOWORD(wParam)) {
1208 case IDC5_BOLDCOLOUR:
1209 if (HIWORD(wParam) == BN_CLICKED ||
1210 HIWORD(wParam) == BN_DOUBLECLICKED) {
1211 int n, i;
1212 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC5_BOLDCOLOUR);
1213 n = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCOUNT, 0, 0);
1214 if (cfg.bold_colour && n!=22) {
1215 for (i=0; i<22; i++)
1216 if (!permanent[i])
1217 SendDlgItemMessage (hwnd, IDC5_LIST,
1218 LB_INSERTSTRING, i,
1219 (LPARAM) colours[i]);
1220 } else if (!cfg.bold_colour && n!=12) {
1221 for (i=22; i-- ;)
1222 if (!permanent[i])
1223 SendDlgItemMessage (hwnd, IDC5_LIST,
1224 LB_DELETESTRING, i, 0);
1225 }
1226 }
1227 break;
1228 case IDC5_PALETTE:
1229 if (HIWORD(wParam) == BN_CLICKED ||
1230 HIWORD(wParam) == BN_DOUBLECLICKED)
1231 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC5_PALETTE);
1232 break;
1233 case IDC5_LIST:
1234 if (HIWORD(wParam) == LBN_DBLCLK ||
1235 HIWORD(wParam) == LBN_SELCHANGE) {
1236 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1237 0, 0);
1238 if (!cfg.bold_colour)
1239 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1240 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0], FALSE);
1241 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1], FALSE);
1242 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2], FALSE);
1243 }
1244 break;
1245 case IDC5_CHANGE:
1246 if (HIWORD(wParam) == BN_CLICKED ||
1247 HIWORD(wParam) == BN_DOUBLECLICKED) {
1248 static CHOOSECOLOR cc;
1249 static DWORD custom[16] = {0}; /* zero initialisers */
1250 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1251 0, 0);
1252 if (!cfg.bold_colour)
1253 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1254 cc.lStructSize = sizeof(cc);
1255 cc.hwndOwner = hwnd;
1d470ad2 1256 cc.hInstance = (HWND)hinst;
374330e2 1257 cc.lpCustColors = custom;
1258 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1259 cfg.colours[i][2]);
1260 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1261 if (ChooseColor(&cc)) {
1262 cfg.colours[i][0] =
1263 (unsigned char) (cc.rgbResult & 0xFF);
1264 cfg.colours[i][1] =
1265 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1266 cfg.colours[i][2] =
1267 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1268 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0],
1269 FALSE);
1270 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1],
1271 FALSE);
1272 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2],
1273 FALSE);
1274 }
1275 }
1276 break;
1277 }
1278 break;
1279 }
1280 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1281}
1282
c9def1b8 1283static int CALLBACK TranslationProc (HWND hwnd, UINT msg,
14963b8f 1284 WPARAM wParam, LPARAM lParam) {
1285 switch (msg) {
1286 case WM_INITDIALOG:
d3d16feb 1287 CheckRadioButton (hwnd, IDC6_NOXLAT, IDC6_88592WIN1250,
1288 cfg.xlat_88592w1250 ? IDC6_88592WIN1250 :
1289 cfg.xlat_enablekoiwin ? IDC6_KOI8WIN1251 :
1290 IDC6_NOXLAT);
14963b8f 1291 CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr);
c9def1b8 1292 CheckRadioButton (hwnd, IDC2_VTXWINDOWS, IDC2_VTPOORMAN,
1293 cfg.vtmode == VT_XWINDOWS ? IDC2_VTXWINDOWS :
1294 cfg.vtmode == VT_OEMANSI ? IDC2_VTOEMANSI :
1295 cfg.vtmode == VT_OEMONLY ? IDC2_VTOEMONLY :
1296 IDC2_VTPOORMAN);
14963b8f 1297 case WM_COMMAND:
1298 switch (LOWORD(wParam)) {
d3d16feb 1299 case IDC6_NOXLAT:
1300 case IDC6_KOI8WIN1251:
1301 case IDC6_88592WIN1250:
1302 cfg.xlat_enablekoiwin =
1303 IsDlgButtonChecked (hwnd, IDC6_KOI8WIN1251);
1304 cfg.xlat_88592w1250 =
1305 IsDlgButtonChecked (hwnd, IDC6_88592WIN1250);
14963b8f 1306 break;
1307 case IDC6_CAPSLOCKCYR:
1308 if (HIWORD(wParam) == BN_CLICKED ||
1309 HIWORD(wParam) == BN_DOUBLECLICKED) {
1310 cfg.xlat_capslockcyr =
1311 IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR);
1312 }
1313 break;
c9def1b8 1314 case IDC2_VTXWINDOWS:
1315 case IDC2_VTOEMANSI:
1316 case IDC2_VTOEMONLY:
1317 case IDC2_VTPOORMAN:
1318 cfg.vtmode =
1319 (IsDlgButtonChecked (hwnd, IDC2_VTXWINDOWS) ? VT_XWINDOWS :
1320 IsDlgButtonChecked (hwnd, IDC2_VTOEMANSI) ? VT_OEMANSI :
1321 IsDlgButtonChecked (hwnd, IDC2_VTOEMONLY) ? VT_OEMONLY :
1322 VT_POORMAN);
1323 break;
14963b8f 1324 }
1325 }
1326 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1327}
1328
374330e2 1329static DLGPROC panelproc[NPANELS] = {
1330 ConnectionProc, KeyboardProc, TerminalProc,
c9def1b8 1331 TelnetProc, SshProc, SelectionProc, ColourProc, TranslationProc
374330e2 1332};
1333static char *panelids[NPANELS] = {
1334 MAKEINTRESOURCE(IDD_PANEL0),
1335 MAKEINTRESOURCE(IDD_PANEL1),
1336 MAKEINTRESOURCE(IDD_PANEL2),
1337 MAKEINTRESOURCE(IDD_PANEL3),
1338 MAKEINTRESOURCE(IDD_PANEL35),
1339 MAKEINTRESOURCE(IDD_PANEL4),
14963b8f 1340 MAKEINTRESOURCE(IDD_PANEL5),
1341 MAKEINTRESOURCE(IDD_PANEL6)
374330e2 1342};
14963b8f 1343
374330e2 1344static char *names[NPANELS] = {
14963b8f 1345 "Connection", "Keyboard", "Terminal", "Telnet",
c9def1b8 1346 "SSH", "Selection", "Colours", "Translation"
374330e2 1347};
1348
14963b8f 1349static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7};
1350static int reconfp[RECONF_NPANELS] = { 1, 2, 5, 6, 7};
374330e2 1351
1352static int GenericMainDlgProc (HWND hwnd, UINT msg,
1353 WPARAM wParam, LPARAM lParam,
1354 int npanels, int *panelnums, HWND *page) {
1355 HWND hw;
1356
1357 switch (msg) {
1358 case WM_INITDIALOG:
1359 { /* centre the window */
1360 RECT rs, rd;
1361
1362 hw = GetDesktopWindow();
1363 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1364 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1365 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1366 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1367 }
1368 *page = NULL;
1369 { /* initialise the tab control */
1370 TC_ITEMHEADER tab;
1371 int i;
1372
1373 hw = GetDlgItem (hwnd, IDC_TAB);
1374 for (i=0; i<npanels; i++) {
1375 tab.mask = TCIF_TEXT;
1376 tab.pszText = names[panelnums[i]];
1377 TabCtrl_InsertItem (hw, i, &tab);
1378 }
1379/* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1380 hwnd, panelproc[panelnums[0]]);*/
1381 *page = CreateDialog (hinst, panelids[panelnums[0]],
1382 hwnd, panelproc[panelnums[0]]);
1383 SetWindowLong (*page, GWL_EXSTYLE,
1384 GetWindowLong (*page, GWL_EXSTYLE) |
1385 WS_EX_CONTROLPARENT);
1386 }
1387 SetFocus (*page);
1388 return 0;
1389 case WM_NOTIFY:
1390 if (LOWORD(wParam) == IDC_TAB &&
1391 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1392 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1393 if (*page)
1394 DestroyWindow (*page);
1395/* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1396 hwnd, panelproc[panelnums[i]]);*/
1397 *page = CreateDialog (hinst, panelids[panelnums[i]],
1398 hwnd, panelproc[panelnums[i]]);
1399 SetWindowLong (*page, GWL_EXSTYLE,
1400 GetWindowLong (*page, GWL_EXSTYLE) |
1401 WS_EX_CONTROLPARENT);
1402 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1403 return 0;
1404 }
1405 break;
1406/* case WM_CTLCOLORDLG: */
1407/* return (int) GetStockObject (LTGRAY_BRUSH); */
1408 case WM_COMMAND:
1409 switch (LOWORD(wParam)) {
1410 case IDOK:
1411 if (*cfg.host)
1412 EndDialog (hwnd, 1);
1413 else
1414 MessageBeep (0);
1415 return 0;
1416 case IDCANCEL:
1417 EndDialog (hwnd, 0);
1418 return 0;
1419 }
1420 return 0;
1421 case WM_CLOSE:
1422 EndDialog (hwnd, 0);
1423 return 0;
c9def1b8 1424
1425 /* Grrr Explorer will maximize Dialogs! */
1426 case WM_SIZE:
1427 if (wParam == SIZE_MAXIMIZED)
1428 force_normal(hwnd);
1429 return 0;
374330e2 1430 }
1431 return 0;
1432}
1433
1434static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1435 WPARAM wParam, LPARAM lParam) {
1436#if 0
1437 HWND hw;
1438 int i;
1439#endif
1440 static HWND page = NULL;
1441
1442 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1443#if 0
1444 /*
1445 * If the Connection panel is active and the Session List
1446 * box is selected, we treat a press of Open to have an
1447 * implicit press of Load preceding it.
1448 */
1449 hw = GetDlgItem (hwnd, IDC_TAB);
1450 i = TabCtrl_GetCurSel(hw);
1451 if (panelproc[mainp[i]] == ConnectionProc &&
1452 page && implicit_load_ok) {
1453 SendMessage (page, WM_COMMAND,
1454 MAKELONG(IDC0_SESSLOAD, BN_CLICKED), 0);
1455 }
1456#endif
1457 }
1458 if (msg == WM_COMMAND && LOWORD(wParam) == IDC_ABOUT) {
1459 EnableWindow(hwnd, 0);
1460 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1461 GetParent(hwnd), AboutProc);
1462 EnableWindow(hwnd, 1);
1463 }
1464 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1465 MAIN_NPANELS, mainp, &page);
1466}
1467
1468static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1469 WPARAM wParam, LPARAM lParam) {
1470 static HWND page;
1471 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1472 RECONF_NPANELS, reconfp, &page);
1473}
1474
0a4aa984 1475void get_sesslist(int allocate) {
374330e2 1476 static char *buffer;
1477 int buflen, bufsize, i, ret;
1478 char otherbuf[2048];
1479 char *p;
1480 HKEY subkey1;
1481
1482 if (allocate) {
1483 if (RegCreateKey(HKEY_CURRENT_USER,
1484 puttystr, &subkey1) != ERROR_SUCCESS)
1485 return;
1486
1487 buflen = bufsize = 0;
1488 buffer = NULL;
1489 i = 0;
1490 do {
1491 ret = RegEnumKey(subkey1, i++, otherbuf, sizeof(otherbuf));
1492 if (ret == ERROR_SUCCESS) {
1493 bufsize = buflen + 2048;
1494 buffer = srealloc(buffer, bufsize);
1495 unmungestr(otherbuf, buffer+buflen);
1496 buflen += strlen(buffer+buflen)+1;
1497 }
1498 } while (ret == ERROR_SUCCESS);
1499 buffer = srealloc(buffer, buflen+1);
1500 buffer[buflen] = '\0';
1501
1502 p = buffer;
1503 nsessions = 1; /* "Default Settings" counts as one */
1504 while (*p) {
1505 if (strcmp(p, "Default Settings"))
1506 nsessions++;
1507 while (*p) p++;
1508 p++;
1509 }
1510
1511 sessions = smalloc(nsessions * sizeof(char *));
1512 sessions[0] = "Default Settings";
1513 p = buffer;
1514 i = 1;
1515 while (*p) {
1516 if (strcmp(p, "Default Settings"))
1517 sessions[i++] = p;
1518 while (*p) p++;
1519 p++;
1520 }
1521 } else {
1522 sfree (buffer);
1523 sfree (sessions);
1524 }
1525}
1526
1527int do_config (void) {
1528 int ret;
1529
1530 get_sesslist(TRUE);
1531 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1532 get_sesslist(FALSE);
1533
1534 return ret;
1535}
1536
1537int do_reconfig (HWND hwnd) {
1538 Config backup_cfg;
1539 int ret;
1540
1541 backup_cfg = cfg; /* structure copy */
1542 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1543 if (!ret)
1544 cfg = backup_cfg; /* structure copy */
c9def1b8 1545 else
1546 force_normal(hwnd);
1547
374330e2 1548 return ret;
1549}
1550
1551void do_defaults (char *session) {
1552 if (session)
1553 load_settings (session, TRUE);
1554 else
1555 load_settings ("Default Settings", FALSE);
1556}
1557
c5e9c988 1558void logevent (char *string) {
1559 if (nevents >= negsize) {
374330e2 1560 negsize += 64;
c5e9c988 1561 events = srealloc (events, negsize * sizeof(*events));
374330e2 1562 }
c5e9c988 1563 events[nevents] = smalloc(1+strlen(string));
1564 strcpy (events[nevents], string);
1565 nevents++;
374330e2 1566 if (logbox)
1567 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1568 0, (LPARAM)string);
1569}
1570
c5e9c988 1571void showeventlog (HWND hwnd) {
374330e2 1572 if (!logbox) {
1573 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1574 hwnd, LogProc);
1575 ShowWindow (logbox, SW_SHOWNORMAL);
1576 }
1577}
1578
1579void showabout (HWND hwnd) {
1580 if (!abtbox) {
1581 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1582 hwnd, AboutProc);
1583 ShowWindow (abtbox, SW_SHOWNORMAL);
1584 }
1585}
1586
89ee5268 1587void verify_ssh_host_key(char *host, char *keystr) {
1588 char *otherstr, *mungedhost;
374330e2 1589 int len;
1590 HKEY rkey;
1591
89ee5268 1592 len = 1 + strlen(keystr);
374330e2 1593
1594 /*
1595 * Now read a saved key in from the registry and see what it
1596 * says.
1597 */
c9def1b8 1598 otherstr = smalloc(len);
1599 mungedhost = smalloc(3*strlen(host)+1);
374330e2 1600 if (!otherstr || !mungedhost)
1601 fatalbox("Out of memory");
1602
1603 mungestr(host, mungedhost);
1604
1605 if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",
1606 &rkey) != ERROR_SUCCESS) {
1607 if (MessageBox(NULL, "PuTTY was unable to open the host key cache\n"
1608 "in the registry. There is thus no way to tell\n"
1609 "if the remote host is what you think it is.\n"
1610 "Connect anyway?", "PuTTY Problem",
1611 MB_ICONWARNING | MB_YESNO) == IDNO)
1612 exit(0);
1613 } else {
1614 DWORD readlen = len;
1615 DWORD type;
1616 int ret;
1617
1618 ret = RegQueryValueEx(rkey, mungedhost, NULL,
1619 &type, otherstr, &readlen);
1620
1621 if (ret == ERROR_MORE_DATA ||
1622 (ret == ERROR_SUCCESS && type == REG_SZ &&
1623 strcmp(otherstr, keystr))) {
1624 if (MessageBox(NULL,
1625 "This host's host key is different from the\n"
1626 "one cached in the registry! Someone may be\n"
1627 "impersonating this host for malicious reasons;\n"
1628 "alternatively, the host key may have changed\n"
1629 "due to sloppy system administration.\n"
1630 "Replace key in registry and connect?",
1631 "PuTTY: Security Warning",
1632 MB_ICONWARNING | MB_YESNO) == IDNO)
1633 exit(0);
1634 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,
1635 strlen(keystr)+1);
1636 } else if (ret != ERROR_SUCCESS || type != REG_SZ) {
1637 if (MessageBox(NULL,
1638 "This host's host key is not cached in the\n"
1639 "registry. Do you want to add it to the cache\n"
1640 "and carry on connecting?",
1641 "PuTTY: New Host",
1642 MB_ICONWARNING | MB_YESNO) == IDNO)
1643 exit(0);
1644 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,
1645 strlen(keystr)+1);
1646 }
1647
1648 RegCloseKey(rkey);
1649 }
1650}