Saved-session name box now persists over panel switches
[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
6584031a 511static char savedsession[2048];
512
374330e2 513static int CALLBACK ConnectionProc (HWND hwnd, UINT msg,
514 WPARAM wParam, LPARAM lParam) {
515 int i;
516
517 switch (msg) {
518 case WM_INITDIALOG:
519 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
6584031a 520 SetDlgItemText (hwnd, IDC0_SESSEDIT, savedsession);
374330e2 521 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
522 for (i = 0; i < nsessions; i++)
523 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
524 0, (LPARAM) (sessions[i]));
5e1a8e27 525 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
526 cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
527 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW );
374330e2 528 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 529 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 530 break;
1cd246bb 531 case WM_LBUTTONUP:
532 /*
533 * Button release should trigger WM_OK if there was a
534 * previous double click on the session list.
535 */
536 ReleaseCapture();
537 if (readytogo)
538 SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0);
539 break;
374330e2 540 case WM_COMMAND:
541 switch (LOWORD(wParam)) {
542 case IDC0_PROTTELNET:
543 case IDC0_PROTSSH:
5e1a8e27 544 case IDC0_PROTRAW:
374330e2 545 if (HIWORD(wParam) == BN_CLICKED ||
546 HIWORD(wParam) == BN_DOUBLECLICKED) {
547 int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH);
5e1a8e27 548 int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET);
549 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
374330e2 550 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
551 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
552 cfg.port = i ? 22 : 23;
553 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
554 }
555 }
556 break;
557 case IDC0_HOST:
558 if (HIWORD(wParam) == EN_CHANGE)
559 GetDlgItemText (hwnd, IDC0_HOST, cfg.host,
560 sizeof(cfg.host)-1);
561 break;
562 case IDC0_PORT:
563 if (HIWORD(wParam) == EN_CHANGE)
564 MyGetDlgItemInt (hwnd, IDC0_PORT, &cfg.port);
565 break;
566 case IDC0_CLOSEEXIT:
567 if (HIWORD(wParam) == BN_CLICKED ||
568 HIWORD(wParam) == BN_DOUBLECLICKED)
569 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC0_CLOSEEXIT);
570 break;
9ef49106 571 case IDC0_CLOSEWARN:
572 if (HIWORD(wParam) == BN_CLICKED ||
573 HIWORD(wParam) == BN_DOUBLECLICKED)
574 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC0_CLOSEWARN);
575 break;
374330e2 576 case IDC0_SESSEDIT:
6584031a 577 if (HIWORD(wParam) == EN_CHANGE) {
374330e2 578 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
579 (WPARAM) -1, 0);
6584031a 580 GetDlgItemText (hwnd, IDC0_SESSEDIT,
581 savedsession, sizeof(savedsession)-1);
582 savedsession[sizeof(savedsession)-1] = '\0';
583 }
374330e2 584 break;
585 case IDC0_SESSSAVE:
586 if (HIWORD(wParam) == BN_CLICKED ||
587 HIWORD(wParam) == BN_DOUBLECLICKED) {
588 /*
589 * Save a session
590 */
591 char str[2048];
592 GetDlgItemText (hwnd, IDC0_SESSEDIT, str, sizeof(str)-1);
593 if (!*str) {
594 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
595 LB_GETCURSEL, 0, 0);
596 if (n == LB_ERR) {
597 MessageBeep(0);
598 break;
599 }
600 strcpy (str, sessions[n]);
601 }
602 save_settings (str, !!strcmp(str, "Default Settings"));
603 get_sesslist (FALSE);
604 get_sesslist (TRUE);
605 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
606 0, 0);
607 for (i = 0; i < nsessions; i++)
608 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
609 0, (LPARAM) (sessions[i]));
610 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
611 (WPARAM) -1, 0);
612 }
613 break;
614 case IDC0_SESSLIST:
615 case IDC0_SESSLOAD:
616 if (LOWORD(wParam) == IDC0_SESSLOAD &&
617 HIWORD(wParam) != BN_CLICKED &&
618 HIWORD(wParam) != BN_DOUBLECLICKED)
619 break;
620 if (LOWORD(wParam) == IDC0_SESSLIST &&
621 HIWORD(wParam) != LBN_DBLCLK)
622 break;
623 {
624 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
625 LB_GETCURSEL, 0, 0);
626 if (n == LB_ERR) {
627 MessageBeep(0);
628 break;
629 }
630 load_settings (sessions[n],
631 !!strcmp(sessions[n], "Default Settings"));
632 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
633 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
5e1a8e27 634 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
374330e2 635 (cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
5e1a8e27 636 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW));
374330e2 637 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 638 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 639 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
640 (WPARAM) -1, 0);
641 }
642 if (LOWORD(wParam) == IDC0_SESSLIST) {
643 /*
644 * A double-click on a saved session should
645 * actually start the session, not just load it.
646 * Unless it's Default Settings or some other
647 * host-less set of saved settings.
648 */
1cd246bb 649 if (*cfg.host) {
650 readytogo = TRUE;
651 SetCapture(hwnd);
652 }
374330e2 653 }
654 break;
655 case IDC0_SESSDEL:
656 if (HIWORD(wParam) == BN_CLICKED ||
657 HIWORD(wParam) == BN_DOUBLECLICKED) {
658 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
659 LB_GETCURSEL, 0, 0);
660 if (n == LB_ERR || n == 0) {
661 MessageBeep(0);
662 break;
663 }
664 del_session(sessions[n]);
665 get_sesslist (FALSE);
666 get_sesslist (TRUE);
667 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
668 0, 0);
669 for (i = 0; i < nsessions; i++)
670 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
671 0, (LPARAM) (sessions[i]));
672 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
673 (WPARAM) -1, 0);
674 }
675 }
676 }
677 return GeneralPanelProc (hwnd, msg, wParam, lParam);
678}
679
680static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
681 WPARAM wParam, LPARAM lParam) {
682 switch (msg) {
683 case WM_INITDIALOG:
684 CheckRadioButton (hwnd, IDC1_DEL008, IDC1_DEL127,
685 cfg.bksp_is_delete ? IDC1_DEL127 : IDC1_DEL008);
686 CheckRadioButton (hwnd, IDC1_HOMETILDE, IDC1_HOMERXVT,
687 cfg.rxvt_homeend ? IDC1_HOMERXVT : IDC1_HOMETILDE);
c9def1b8 688 CheckRadioButton (hwnd, IDC1_FUNCTILDE, IDC1_FUNCXTERM,
689 cfg.funky_type ?
690 (cfg.funky_type==2 ? IDC1_FUNCXTERM
691 : IDC1_FUNCLINUX )
692 : IDC1_FUNCTILDE);
374330e2 693 CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
694 cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
c5e9c988 695 CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
696 cfg.nethack_keypad ? IDC1_KPNH :
374330e2 697 cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
c5e9c988 698 CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
699 CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
5bc238bb 700 CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
c9def1b8 701 CheckDlgButton (hwnd, IDC1_SCROLLKEY, cfg.scroll_on_key);
374330e2 702 break;
703 case WM_COMMAND:
704 if (HIWORD(wParam) == BN_CLICKED ||
705 HIWORD(wParam) == BN_DOUBLECLICKED)
706 switch (LOWORD(wParam)) {
707 case IDC1_DEL008:
708 case IDC1_DEL127:
709 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC1_DEL127);
710 break;
711 case IDC1_HOMETILDE:
712 case IDC1_HOMERXVT:
713 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC1_HOMERXVT);
714 break;
c9def1b8 715 case IDC1_FUNCXTERM:
716 cfg.funky_type = 2;
717 break;
374330e2 718 case IDC1_FUNCTILDE:
719 case IDC1_FUNCLINUX:
c9def1b8 720 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC1_FUNCLINUX);
374330e2 721 break;
722 case IDC1_KPNORMAL:
723 case IDC1_KPAPPLIC:
724 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
c5e9c988 725 cfg.nethack_keypad = FALSE;
726 break;
727 case IDC1_KPNH:
728 cfg.app_keypad = FALSE;
729 cfg.nethack_keypad = TRUE;
374330e2 730 break;
731 case IDC1_CURNORMAL:
732 case IDC1_CURAPPLIC:
733 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
734 break;
c5e9c988 735 case IDC1_ALTF4:
736 if (HIWORD(wParam) == BN_CLICKED ||
737 HIWORD(wParam) == BN_DOUBLECLICKED)
738 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
739 break;
740 case IDC1_ALTSPACE:
741 if (HIWORD(wParam) == BN_CLICKED ||
742 HIWORD(wParam) == BN_DOUBLECLICKED)
743 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
744 break;
5bc238bb 745 case IDC1_LDISCTERM:
746 if (HIWORD(wParam) == BN_CLICKED ||
747 HIWORD(wParam) == BN_DOUBLECLICKED)
748 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
749 break;
c9def1b8 750 case IDC1_SCROLLKEY:
217dceef 751 if (HIWORD(wParam) == BN_CLICKED ||
752 HIWORD(wParam) == BN_DOUBLECLICKED)
c9def1b8 753 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC1_SCROLLKEY);
217dceef 754 break;
374330e2 755 }
756 }
757 return GeneralPanelProc (hwnd, msg, wParam, lParam);
758}
759
760static void fmtfont (char *buf) {
761 sprintf (buf, "Font: %s, ", cfg.font);
762 if (cfg.fontisbold)
763 strcat(buf, "bold, ");
764 if (cfg.fontheight == 0)
765 strcat (buf, "default height");
766 else
767 sprintf (buf+strlen(buf), "%d-%s",
768 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
769 (cfg.fontheight < 0 ? "pixel" : "point"));
770}
771
772static int CALLBACK TerminalProc (HWND hwnd, UINT msg,
773 WPARAM wParam, LPARAM lParam) {
774 CHOOSEFONT cf;
775 LOGFONT lf;
776 char fontstatic[256];
777
778 switch (msg) {
779 case WM_INITDIALOG:
780 CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode);
781 CheckDlgButton (hwnd, IDC2_WINNAME, cfg.win_name_always);
782 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
fef97f43 783 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
374330e2 784 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
785 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
786 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
787 fmtfont (fontstatic);
788 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
c9def1b8 789 CheckDlgButton (hwnd, IDC1_BLINKCUR, cfg.blink_cur);
790 CheckDlgButton (hwnd, IDC1_BEEP, cfg.beep);
791 CheckDlgButton (hwnd, IDC2_SCROLLBAR, cfg.scrollbar);
792 CheckDlgButton (hwnd, IDC2_LOCKSIZE, cfg.locksize);
793 CheckDlgButton (hwnd, IDC2_BCE, cfg.bce);
794 CheckDlgButton (hwnd, IDC2_BLINKTEXT, cfg.blinktext);
374330e2 795 break;
796 case WM_COMMAND:
797 switch (LOWORD(wParam)) {
798 case IDC2_WRAPMODE:
799 if (HIWORD(wParam) == BN_CLICKED ||
800 HIWORD(wParam) == BN_DOUBLECLICKED)
801 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
802 break;
803 case IDC2_WINNAME:
804 if (HIWORD(wParam) == BN_CLICKED ||
805 HIWORD(wParam) == BN_DOUBLECLICKED)
806 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC2_WINNAME);
807 break;
808 case IDC2_DECOM:
809 if (HIWORD(wParam) == BN_CLICKED ||
810 HIWORD(wParam) == BN_DOUBLECLICKED)
811 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
812 break;
fef97f43 813 case IDC2_LFHASCR:
814 if (HIWORD(wParam) == BN_CLICKED ||
815 HIWORD(wParam) == BN_DOUBLECLICKED)
816 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
817 break;
374330e2 818 case IDC2_ROWSEDIT:
819 if (HIWORD(wParam) == EN_CHANGE)
820 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
821 break;
822 case IDC2_COLSEDIT:
823 if (HIWORD(wParam) == EN_CHANGE)
824 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
825 break;
826 case IDC2_SAVEEDIT:
827 if (HIWORD(wParam) == EN_CHANGE)
828 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
829 break;
830 case IDC2_CHOOSEFONT:
831 lf.lfHeight = cfg.fontheight;
832 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
833 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
834 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
14963b8f 835 lf.lfCharSet = cfg.fontcharset;
374330e2 836 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
837 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
838 lf.lfQuality = DEFAULT_QUALITY;
839 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
840 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
841 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
842
843 cf.lStructSize = sizeof(cf);
844 cf.hwndOwner = hwnd;
845 cf.lpLogFont = &lf;
846 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
847 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
848
849 if (ChooseFont (&cf)) {
850 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
851 cfg.font[sizeof(cfg.font)-1] = '\0';
852 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
14963b8f 853 cfg.fontcharset = lf.lfCharSet;
374330e2 854 cfg.fontheight = lf.lfHeight;
855 fmtfont (fontstatic);
856 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
857 }
858 break;
c9def1b8 859 case IDC1_BLINKCUR:
860 if (HIWORD(wParam) == BN_CLICKED ||
861 HIWORD(wParam) == BN_DOUBLECLICKED)
862 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC1_BLINKCUR);
863 break;
864 case IDC1_BEEP:
865 if (HIWORD(wParam) == BN_CLICKED ||
866 HIWORD(wParam) == BN_DOUBLECLICKED)
867 cfg.beep = IsDlgButtonChecked (hwnd, IDC1_BEEP);
868 break;
869 case IDC2_SCROLLBAR:
870 if (HIWORD(wParam) == BN_CLICKED ||
871 HIWORD(wParam) == BN_DOUBLECLICKED)
872 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC2_SCROLLBAR);
873 break;
874 case IDC2_LOCKSIZE:
875 if (HIWORD(wParam) == BN_CLICKED ||
876 HIWORD(wParam) == BN_DOUBLECLICKED)
877 cfg.locksize = IsDlgButtonChecked (hwnd, IDC2_LOCKSIZE);
878 break;
879 case IDC2_BLINKTEXT:
880 if (HIWORD(wParam) == BN_CLICKED ||
881 HIWORD(wParam) == BN_DOUBLECLICKED)
882 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC2_BLINKTEXT);
883 break;
884 case IDC2_BCE:
885 if (HIWORD(wParam) == BN_CLICKED ||
886 HIWORD(wParam) == BN_DOUBLECLICKED)
887 cfg.bce = IsDlgButtonChecked (hwnd, IDC2_BCE);
888 break;
374330e2 889 }
890 break;
891 }
892 return GeneralPanelProc (hwnd, msg, wParam, lParam);
893}
894
895static int CALLBACK TelnetProc (HWND hwnd, UINT msg,
896 WPARAM wParam, LPARAM lParam) {
897 int i;
898
899 switch (msg) {
900 case WM_INITDIALOG:
901 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
902 SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed);
903 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
904 {
37508af4 905 char *p = cfg.environmt;
374330e2 906 while (*p) {
907 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0,
908 (LPARAM) p);
909 p += strlen(p)+1;
910 }
911 }
912 CheckRadioButton (hwnd, IDC3_EMBSD, IDC3_EMRFC,
913 cfg.rfc_environ ? IDC3_EMRFC : IDC3_EMBSD);
914 break;
915 case WM_COMMAND:
916 switch (LOWORD(wParam)) {
917 case IDC3_TTEDIT:
918 if (HIWORD(wParam) == EN_CHANGE)
919 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
920 sizeof(cfg.termtype)-1);
921 break;
922 case IDC3_TSEDIT:
923 if (HIWORD(wParam) == EN_CHANGE)
924 GetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed,
925 sizeof(cfg.termspeed)-1);
926 break;
927 case IDC3_LOGEDIT:
928 if (HIWORD(wParam) == EN_CHANGE)
929 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
930 sizeof(cfg.username)-1);
931 break;
932 case IDC3_EMBSD:
933 case IDC3_EMRFC:
934 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC3_EMRFC);
935 break;
936 case IDC3_ENVADD:
937 if (HIWORD(wParam) == BN_CLICKED ||
938 HIWORD(wParam) == BN_DOUBLECLICKED) {
37508af4 939 char str[sizeof(cfg.environmt)];
374330e2 940 char *p;
941 GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1);
942 if (!*str) {
943 MessageBeep(0);
944 break;
945 }
946 p = str + strlen(str);
947 *p++ = '\t';
948 GetDlgItemText (hwnd, IDC3_VALEDIT, p, sizeof(str)-1-(p-str));
949 if (!*p) {
950 MessageBeep(0);
951 break;
952 }
37508af4 953 p = cfg.environmt;
374330e2 954 while (*p) {
955 while (*p) p++;
956 p++;
957 }
37508af4 958 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
374330e2 959 strcpy (p, str);
960 p[strlen(str)+1] = '\0';
961 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING,
962 0, (LPARAM)str);
963 SetDlgItemText (hwnd, IDC3_VAREDIT, "");
964 SetDlgItemText (hwnd, IDC3_VALEDIT, "");
965 } else {
966 MessageBox(hwnd, "Environment too big", "PuTTY Error",
967 MB_OK | MB_ICONERROR);
968 }
969 }
970 break;
971 case IDC3_ENVREMOVE:
972 if (HIWORD(wParam) != BN_CLICKED &&
973 HIWORD(wParam) != BN_DOUBLECLICKED)
974 break;
975 i = SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_GETCURSEL, 0, 0);
976 if (i == LB_ERR)
977 MessageBeep (0);
978 else {
979 char *p, *q;
980
981 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING,
982 i, 0);
37508af4 983 p = cfg.environmt;
374330e2 984 while (i > 0) {
985 if (!*p)
986 goto disaster;
987 while (*p) p++;
988 p++;
989 i--;
990 }
991 q = p;
992 if (!*p)
993 goto disaster;
994 while (*p) p++;
995 p++;
996 while (*p) {
997 while (*p)
998 *q++ = *p++;
999 *q++ = *p++;
1000 }
1001 *q = '\0';
1002 disaster:;
1003 }
1004 break;
1005 }
1006 break;
1007 }
1008 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1009}
1010
1011static int CALLBACK SshProc (HWND hwnd, UINT msg,
1012 WPARAM wParam, LPARAM lParam) {
7cca0d81 1013 OPENFILENAME of;
1014 char filename[sizeof(cfg.keyfile)];
1015
374330e2 1016 switch (msg) {
1017 case WM_INITDIALOG:
1018 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
1019 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
fef97f43 1020 CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty);
979310f1 1021 CheckDlgButton (hwnd, IDC3_AGENTFWD, cfg.agentfwd);
9697bfd2 1022 CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES,
bea1ef5f 1023 cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF :
9697bfd2 1024 cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES :
bea1ef5f 1025 IDC3_CIPHER3DES);
adf799dd 1026 CheckRadioButton (hwnd, IDC3_SSHPROT1, IDC3_SSHPROT2,
1027 cfg.sshprot == 1 ? IDC3_SSHPROT1 : IDC3_SSHPROT2);
ccbfb941 1028 CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
7cca0d81 1029 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
374330e2 1030 break;
1031 case WM_COMMAND:
1032 switch (LOWORD(wParam)) {
1033 case IDC3_TTEDIT:
1034 if (HIWORD(wParam) == EN_CHANGE)
1035 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
1036 sizeof(cfg.termtype)-1);
1037 break;
1038 case IDC3_LOGEDIT:
1039 if (HIWORD(wParam) == EN_CHANGE)
1040 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
1041 sizeof(cfg.username)-1);
1042 break;
fef97f43 1043 case IDC3_NOPTY:
1044 if (HIWORD(wParam) == BN_CLICKED ||
1045 HIWORD(wParam) == BN_DOUBLECLICKED)
1046 cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY);
1047 break;
979310f1 1048 case IDC3_AGENTFWD:
1049 if (HIWORD(wParam) == BN_CLICKED ||
1050 HIWORD(wParam) == BN_DOUBLECLICKED)
1051 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC3_AGENTFWD);
1052 break;
bea1ef5f 1053 case IDC3_CIPHER3DES:
1054 case IDC3_CIPHERBLOWF:
9697bfd2 1055 case IDC3_CIPHERDES:
bea1ef5f 1056 if (HIWORD(wParam) == BN_CLICKED ||
1057 HIWORD(wParam) == BN_DOUBLECLICKED) {
1058 if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES))
1059 cfg.cipher = CIPHER_3DES;
1060 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF))
1061 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 1062 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES))
1063 cfg.cipher = CIPHER_DES;
bea1ef5f 1064 }
1065 break;
adf799dd 1066 case IDC3_SSHPROT1:
1067 case IDC3_SSHPROT2:
1068 if (HIWORD(wParam) == BN_CLICKED ||
1069 HIWORD(wParam) == BN_DOUBLECLICKED) {
1070 if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT1))
1071 cfg.sshprot = 1;
1072 else if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT2))
1073 cfg.sshprot = 2;
1074 }
1075 break;
ccbfb941 1076 case IDC3_AUTHTIS:
1077 if (HIWORD(wParam) == BN_CLICKED ||
1078 HIWORD(wParam) == BN_DOUBLECLICKED)
1079 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
1080 break;
7cca0d81 1081 case IDC3_PKEDIT:
1082 if (HIWORD(wParam) == EN_CHANGE)
1083 GetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile,
1084 sizeof(cfg.keyfile)-1);
1085 break;
1086 case IDC3_PKBUTTON:
1087 /*
1088 * FIXME: this crashes. Find out why.
1089 */
1090 memset(&of, 0, sizeof(of));
1091#ifdef OPENFILENAME_SIZE_VERSION_400
1092 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1093#else
1094 of.lStructSize = sizeof(of);
1095#endif
1096 of.hwndOwner = hwnd;
1097 of.lpstrFilter = "All Files\0*\0\0\0";
1098 of.lpstrCustomFilter = NULL;
1099 of.nFilterIndex = 1;
1100 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1101 of.nMaxFile = sizeof(filename);
1102 of.lpstrFileTitle = NULL;
1103 of.lpstrInitialDir = NULL;
1104 of.lpstrTitle = "Select Public Key File";
1105 of.Flags = 0;
1106 if (GetOpenFileName(&of)) {
1107 strcpy(cfg.keyfile, filename);
1108 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
1109 }
1110 break;
374330e2 1111 }
1112 break;
1113 }
1114 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1115}
1116
1117static int CALLBACK SelectionProc (HWND hwnd, UINT msg,
1118 WPARAM wParam, LPARAM lParam) {
1119 int i;
1120
1121 switch (msg) {
1122 case WM_INITDIALOG:
1123 CheckRadioButton (hwnd, IDC4_MBWINDOWS, IDC4_MBXTERM,
1124 cfg.mouse_is_xterm ? IDC4_MBXTERM : IDC4_MBWINDOWS);
1125 {
1126 static int tabs[4] = {25, 61, 96, 128};
1127 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_SETTABSTOPS, 4,
1128 (LPARAM) tabs);
1129 }
1130 for (i=0; i<256; i++) {
1131 char str[100];
1132 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1133 (i>=0x21 && i != 0x7F) ? i : ' ',
1134 cfg.wordness[i]);
1135 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_ADDSTRING, 0,
1136 (LPARAM) str);
1137 }
1138 break;
1139 case WM_COMMAND:
1140 switch (LOWORD(wParam)) {
1141 case IDC4_MBWINDOWS:
1142 case IDC4_MBXTERM:
1143 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC4_MBXTERM);
1144 break;
1145 case IDC4_CCSET:
1146 {
1147 BOOL ok;
1148 int i;
1149 int n = GetDlgItemInt (hwnd, IDC4_CCEDIT, &ok, FALSE);
1150
1151 if (!ok)
1152 MessageBeep (0);
1153 else {
1154 for (i=0; i<256; i++)
1155 if (SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_GETSEL,
1156 i, 0)) {
1157 char str[100];
1158 cfg.wordness[i] = n;
1159 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1160 LB_DELETESTRING, i, 0);
1161 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1162 (i>=0x21 && i != 0x7F) ? i : ' ',
1163 cfg.wordness[i]);
1164 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1165 LB_INSERTSTRING, i,
1166 (LPARAM)str);
1167 }
1168 }
1169 }
1170 break;
1171 }
1172 break;
1173 }
1174 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1175}
1176
1177static int CALLBACK ColourProc (HWND hwnd, UINT msg,
1178 WPARAM wParam, LPARAM lParam) {
1179 static const char *const colours[] = {
1180 "Default Foreground", "Default Bold Foreground",
1181 "Default Background", "Default Bold Background",
1182 "Cursor Text", "Cursor Colour",
1183 "ANSI Black", "ANSI Black Bold",
1184 "ANSI Red", "ANSI Red Bold",
1185 "ANSI Green", "ANSI Green Bold",
1186 "ANSI Yellow", "ANSI Yellow Bold",
1187 "ANSI Blue", "ANSI Blue Bold",
1188 "ANSI Magenta", "ANSI Magenta Bold",
1189 "ANSI Cyan", "ANSI Cyan Bold",
1190 "ANSI White", "ANSI White Bold"
1191 };
1192 static const int permanent[] = {
1193 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
1194 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
1195 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
1196 };
1197 switch (msg) {
1198 case WM_INITDIALOG:
1199 CheckDlgButton (hwnd, IDC5_BOLDCOLOUR, cfg.bold_colour);
1200 CheckDlgButton (hwnd, IDC5_PALETTE, cfg.try_palette);
1201 {
1202 int i;
1203 for (i=0; i<22; i++)
1204 if (cfg.bold_colour || permanent[i])
1205 SendDlgItemMessage (hwnd, IDC5_LIST, LB_ADDSTRING, 0,
1206 (LPARAM) colours[i]);
1207 }
1208 SendDlgItemMessage (hwnd, IDC5_LIST, LB_SETCURSEL, 0, 0);
1209 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[0][0], FALSE);
1210 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[0][1], FALSE);
1211 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[0][2], FALSE);
1212 break;
1213 case WM_COMMAND:
1214 switch (LOWORD(wParam)) {
1215 case IDC5_BOLDCOLOUR:
1216 if (HIWORD(wParam) == BN_CLICKED ||
1217 HIWORD(wParam) == BN_DOUBLECLICKED) {
1218 int n, i;
1219 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC5_BOLDCOLOUR);
1220 n = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCOUNT, 0, 0);
1221 if (cfg.bold_colour && n!=22) {
1222 for (i=0; i<22; i++)
1223 if (!permanent[i])
1224 SendDlgItemMessage (hwnd, IDC5_LIST,
1225 LB_INSERTSTRING, i,
1226 (LPARAM) colours[i]);
1227 } else if (!cfg.bold_colour && n!=12) {
1228 for (i=22; i-- ;)
1229 if (!permanent[i])
1230 SendDlgItemMessage (hwnd, IDC5_LIST,
1231 LB_DELETESTRING, i, 0);
1232 }
1233 }
1234 break;
1235 case IDC5_PALETTE:
1236 if (HIWORD(wParam) == BN_CLICKED ||
1237 HIWORD(wParam) == BN_DOUBLECLICKED)
1238 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC5_PALETTE);
1239 break;
1240 case IDC5_LIST:
1241 if (HIWORD(wParam) == LBN_DBLCLK ||
1242 HIWORD(wParam) == LBN_SELCHANGE) {
1243 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1244 0, 0);
1245 if (!cfg.bold_colour)
1246 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1247 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0], FALSE);
1248 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1], FALSE);
1249 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2], FALSE);
1250 }
1251 break;
1252 case IDC5_CHANGE:
1253 if (HIWORD(wParam) == BN_CLICKED ||
1254 HIWORD(wParam) == BN_DOUBLECLICKED) {
1255 static CHOOSECOLOR cc;
1256 static DWORD custom[16] = {0}; /* zero initialisers */
1257 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1258 0, 0);
1259 if (!cfg.bold_colour)
1260 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1261 cc.lStructSize = sizeof(cc);
1262 cc.hwndOwner = hwnd;
1d470ad2 1263 cc.hInstance = (HWND)hinst;
374330e2 1264 cc.lpCustColors = custom;
1265 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1266 cfg.colours[i][2]);
1267 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1268 if (ChooseColor(&cc)) {
1269 cfg.colours[i][0] =
1270 (unsigned char) (cc.rgbResult & 0xFF);
1271 cfg.colours[i][1] =
1272 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1273 cfg.colours[i][2] =
1274 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1275 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0],
1276 FALSE);
1277 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1],
1278 FALSE);
1279 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2],
1280 FALSE);
1281 }
1282 }
1283 break;
1284 }
1285 break;
1286 }
1287 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1288}
1289
c9def1b8 1290static int CALLBACK TranslationProc (HWND hwnd, UINT msg,
14963b8f 1291 WPARAM wParam, LPARAM lParam) {
1292 switch (msg) {
1293 case WM_INITDIALOG:
d3d16feb 1294 CheckRadioButton (hwnd, IDC6_NOXLAT, IDC6_88592WIN1250,
1295 cfg.xlat_88592w1250 ? IDC6_88592WIN1250 :
1296 cfg.xlat_enablekoiwin ? IDC6_KOI8WIN1251 :
1297 IDC6_NOXLAT);
14963b8f 1298 CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr);
c9def1b8 1299 CheckRadioButton (hwnd, IDC2_VTXWINDOWS, IDC2_VTPOORMAN,
1300 cfg.vtmode == VT_XWINDOWS ? IDC2_VTXWINDOWS :
1301 cfg.vtmode == VT_OEMANSI ? IDC2_VTOEMANSI :
1302 cfg.vtmode == VT_OEMONLY ? IDC2_VTOEMONLY :
1303 IDC2_VTPOORMAN);
14963b8f 1304 case WM_COMMAND:
1305 switch (LOWORD(wParam)) {
d3d16feb 1306 case IDC6_NOXLAT:
1307 case IDC6_KOI8WIN1251:
1308 case IDC6_88592WIN1250:
1309 cfg.xlat_enablekoiwin =
1310 IsDlgButtonChecked (hwnd, IDC6_KOI8WIN1251);
1311 cfg.xlat_88592w1250 =
1312 IsDlgButtonChecked (hwnd, IDC6_88592WIN1250);
14963b8f 1313 break;
1314 case IDC6_CAPSLOCKCYR:
1315 if (HIWORD(wParam) == BN_CLICKED ||
1316 HIWORD(wParam) == BN_DOUBLECLICKED) {
1317 cfg.xlat_capslockcyr =
1318 IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR);
1319 }
1320 break;
c9def1b8 1321 case IDC2_VTXWINDOWS:
1322 case IDC2_VTOEMANSI:
1323 case IDC2_VTOEMONLY:
1324 case IDC2_VTPOORMAN:
1325 cfg.vtmode =
1326 (IsDlgButtonChecked (hwnd, IDC2_VTXWINDOWS) ? VT_XWINDOWS :
1327 IsDlgButtonChecked (hwnd, IDC2_VTOEMANSI) ? VT_OEMANSI :
1328 IsDlgButtonChecked (hwnd, IDC2_VTOEMONLY) ? VT_OEMONLY :
1329 VT_POORMAN);
1330 break;
14963b8f 1331 }
1332 }
1333 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1334}
1335
374330e2 1336static DLGPROC panelproc[NPANELS] = {
1337 ConnectionProc, KeyboardProc, TerminalProc,
c9def1b8 1338 TelnetProc, SshProc, SelectionProc, ColourProc, TranslationProc
374330e2 1339};
1340static char *panelids[NPANELS] = {
1341 MAKEINTRESOURCE(IDD_PANEL0),
1342 MAKEINTRESOURCE(IDD_PANEL1),
1343 MAKEINTRESOURCE(IDD_PANEL2),
1344 MAKEINTRESOURCE(IDD_PANEL3),
1345 MAKEINTRESOURCE(IDD_PANEL35),
1346 MAKEINTRESOURCE(IDD_PANEL4),
14963b8f 1347 MAKEINTRESOURCE(IDD_PANEL5),
1348 MAKEINTRESOURCE(IDD_PANEL6)
374330e2 1349};
14963b8f 1350
374330e2 1351static char *names[NPANELS] = {
14963b8f 1352 "Connection", "Keyboard", "Terminal", "Telnet",
c9def1b8 1353 "SSH", "Selection", "Colours", "Translation"
374330e2 1354};
1355
14963b8f 1356static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7};
1357static int reconfp[RECONF_NPANELS] = { 1, 2, 5, 6, 7};
374330e2 1358
1359static int GenericMainDlgProc (HWND hwnd, UINT msg,
1360 WPARAM wParam, LPARAM lParam,
1361 int npanels, int *panelnums, HWND *page) {
1362 HWND hw;
1363
1364 switch (msg) {
1365 case WM_INITDIALOG:
1366 { /* centre the window */
1367 RECT rs, rd;
1368
1369 hw = GetDesktopWindow();
1370 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1371 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1372 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1373 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1374 }
1375 *page = NULL;
1376 { /* initialise the tab control */
1377 TC_ITEMHEADER tab;
1378 int i;
1379
1380 hw = GetDlgItem (hwnd, IDC_TAB);
1381 for (i=0; i<npanels; i++) {
1382 tab.mask = TCIF_TEXT;
1383 tab.pszText = names[panelnums[i]];
1384 TabCtrl_InsertItem (hw, i, &tab);
1385 }
1386/* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1387 hwnd, panelproc[panelnums[0]]);*/
1388 *page = CreateDialog (hinst, panelids[panelnums[0]],
1389 hwnd, panelproc[panelnums[0]]);
1390 SetWindowLong (*page, GWL_EXSTYLE,
1391 GetWindowLong (*page, GWL_EXSTYLE) |
1392 WS_EX_CONTROLPARENT);
1393 }
1394 SetFocus (*page);
1395 return 0;
1396 case WM_NOTIFY:
1397 if (LOWORD(wParam) == IDC_TAB &&
1398 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1399 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1400 if (*page)
1401 DestroyWindow (*page);
1402/* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1403 hwnd, panelproc[panelnums[i]]);*/
1404 *page = CreateDialog (hinst, panelids[panelnums[i]],
1405 hwnd, panelproc[panelnums[i]]);
1406 SetWindowLong (*page, GWL_EXSTYLE,
1407 GetWindowLong (*page, GWL_EXSTYLE) |
1408 WS_EX_CONTROLPARENT);
1409 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1410 return 0;
1411 }
1412 break;
1413/* case WM_CTLCOLORDLG: */
1414/* return (int) GetStockObject (LTGRAY_BRUSH); */
1415 case WM_COMMAND:
1416 switch (LOWORD(wParam)) {
1417 case IDOK:
1418 if (*cfg.host)
1419 EndDialog (hwnd, 1);
1420 else
1421 MessageBeep (0);
1422 return 0;
1423 case IDCANCEL:
1424 EndDialog (hwnd, 0);
1425 return 0;
1426 }
1427 return 0;
1428 case WM_CLOSE:
1429 EndDialog (hwnd, 0);
1430 return 0;
c9def1b8 1431
1432 /* Grrr Explorer will maximize Dialogs! */
1433 case WM_SIZE:
1434 if (wParam == SIZE_MAXIMIZED)
1435 force_normal(hwnd);
1436 return 0;
374330e2 1437 }
1438 return 0;
1439}
1440
1441static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1442 WPARAM wParam, LPARAM lParam) {
1443#if 0
1444 HWND hw;
1445 int i;
1446#endif
1447 static HWND page = NULL;
1448
1449 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1450#if 0
1451 /*
1452 * If the Connection panel is active and the Session List
1453 * box is selected, we treat a press of Open to have an
1454 * implicit press of Load preceding it.
1455 */
1456 hw = GetDlgItem (hwnd, IDC_TAB);
1457 i = TabCtrl_GetCurSel(hw);
1458 if (panelproc[mainp[i]] == ConnectionProc &&
1459 page && implicit_load_ok) {
1460 SendMessage (page, WM_COMMAND,
1461 MAKELONG(IDC0_SESSLOAD, BN_CLICKED), 0);
1462 }
1463#endif
1464 }
1465 if (msg == WM_COMMAND && LOWORD(wParam) == IDC_ABOUT) {
1466 EnableWindow(hwnd, 0);
1467 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1468 GetParent(hwnd), AboutProc);
1469 EnableWindow(hwnd, 1);
1470 }
1471 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1472 MAIN_NPANELS, mainp, &page);
1473}
1474
1475static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1476 WPARAM wParam, LPARAM lParam) {
1477 static HWND page;
1478 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1479 RECONF_NPANELS, reconfp, &page);
1480}
1481
0a4aa984 1482void get_sesslist(int allocate) {
374330e2 1483 static char *buffer;
1484 int buflen, bufsize, i, ret;
1485 char otherbuf[2048];
1486 char *p;
1487 HKEY subkey1;
1488
1489 if (allocate) {
1490 if (RegCreateKey(HKEY_CURRENT_USER,
1491 puttystr, &subkey1) != ERROR_SUCCESS)
1492 return;
1493
1494 buflen = bufsize = 0;
1495 buffer = NULL;
1496 i = 0;
1497 do {
1498 ret = RegEnumKey(subkey1, i++, otherbuf, sizeof(otherbuf));
1499 if (ret == ERROR_SUCCESS) {
1500 bufsize = buflen + 2048;
1501 buffer = srealloc(buffer, bufsize);
1502 unmungestr(otherbuf, buffer+buflen);
1503 buflen += strlen(buffer+buflen)+1;
1504 }
1505 } while (ret == ERROR_SUCCESS);
1506 buffer = srealloc(buffer, buflen+1);
1507 buffer[buflen] = '\0';
1508
1509 p = buffer;
1510 nsessions = 1; /* "Default Settings" counts as one */
1511 while (*p) {
1512 if (strcmp(p, "Default Settings"))
1513 nsessions++;
1514 while (*p) p++;
1515 p++;
1516 }
1517
1518 sessions = smalloc(nsessions * sizeof(char *));
1519 sessions[0] = "Default Settings";
1520 p = buffer;
1521 i = 1;
1522 while (*p) {
1523 if (strcmp(p, "Default Settings"))
1524 sessions[i++] = p;
1525 while (*p) p++;
1526 p++;
1527 }
1528 } else {
1529 sfree (buffer);
1530 sfree (sessions);
1531 }
1532}
1533
1534int do_config (void) {
1535 int ret;
1536
1537 get_sesslist(TRUE);
6584031a 1538 savedsession[0] = '\0';
374330e2 1539 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1540 get_sesslist(FALSE);
1541
1542 return ret;
1543}
1544
1545int do_reconfig (HWND hwnd) {
1546 Config backup_cfg;
1547 int ret;
1548
1549 backup_cfg = cfg; /* structure copy */
1550 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1551 if (!ret)
1552 cfg = backup_cfg; /* structure copy */
c9def1b8 1553 else
1554 force_normal(hwnd);
1555
374330e2 1556 return ret;
1557}
1558
1559void do_defaults (char *session) {
1560 if (session)
1561 load_settings (session, TRUE);
1562 else
1563 load_settings ("Default Settings", FALSE);
1564}
1565
c5e9c988 1566void logevent (char *string) {
1567 if (nevents >= negsize) {
374330e2 1568 negsize += 64;
c5e9c988 1569 events = srealloc (events, negsize * sizeof(*events));
374330e2 1570 }
c5e9c988 1571 events[nevents] = smalloc(1+strlen(string));
1572 strcpy (events[nevents], string);
1573 nevents++;
374330e2 1574 if (logbox)
1575 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1576 0, (LPARAM)string);
1577}
1578
c5e9c988 1579void showeventlog (HWND hwnd) {
374330e2 1580 if (!logbox) {
1581 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1582 hwnd, LogProc);
1583 ShowWindow (logbox, SW_SHOWNORMAL);
1584 }
1585}
1586
1587void showabout (HWND hwnd) {
1588 if (!abtbox) {
1589 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1590 hwnd, AboutProc);
1591 ShowWindow (abtbox, SW_SHOWNORMAL);
1592 }
1593}
1594
89ee5268 1595void verify_ssh_host_key(char *host, char *keystr) {
1596 char *otherstr, *mungedhost;
374330e2 1597 int len;
1598 HKEY rkey;
1599
89ee5268 1600 len = 1 + strlen(keystr);
374330e2 1601
1602 /*
1603 * Now read a saved key in from the registry and see what it
1604 * says.
1605 */
c9def1b8 1606 otherstr = smalloc(len);
1607 mungedhost = smalloc(3*strlen(host)+1);
374330e2 1608 if (!otherstr || !mungedhost)
1609 fatalbox("Out of memory");
1610
1611 mungestr(host, mungedhost);
1612
1613 if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",
1614 &rkey) != ERROR_SUCCESS) {
1615 if (MessageBox(NULL, "PuTTY was unable to open the host key cache\n"
1616 "in the registry. There is thus no way to tell\n"
1617 "if the remote host is what you think it is.\n"
1618 "Connect anyway?", "PuTTY Problem",
1619 MB_ICONWARNING | MB_YESNO) == IDNO)
1620 exit(0);
1621 } else {
1622 DWORD readlen = len;
1623 DWORD type;
1624 int ret;
1625
1626 ret = RegQueryValueEx(rkey, mungedhost, NULL,
1627 &type, otherstr, &readlen);
1628
1629 if (ret == ERROR_MORE_DATA ||
1630 (ret == ERROR_SUCCESS && type == REG_SZ &&
1631 strcmp(otherstr, keystr))) {
1632 if (MessageBox(NULL,
1633 "This host's host key is different from the\n"
1634 "one cached in the registry! Someone may be\n"
1635 "impersonating this host for malicious reasons;\n"
1636 "alternatively, the host key may have changed\n"
1637 "due to sloppy system administration.\n"
1638 "Replace key in registry and connect?",
1639 "PuTTY: Security Warning",
1640 MB_ICONWARNING | MB_YESNO) == IDNO)
1641 exit(0);
1642 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,
1643 strlen(keystr)+1);
1644 } else if (ret != ERROR_SUCCESS || type != REG_SZ) {
1645 if (MessageBox(NULL,
1646 "This host's host key is not cached in the\n"
1647 "registry. Do you want to add it to the cache\n"
1648 "and carry on connecting?",
1649 "PuTTY: New Host",
1650 MB_ICONWARNING | MB_YESNO) == IDNO)
1651 exit(0);
1652 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,
1653 strlen(keystr)+1);
1654 }
1655
1656 RegCloseKey(rkey);
1657 }
1658}