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