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