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