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