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