13 #define MAIN_NPANELS 8
14 #define RECONF_NPANELS 5
16 static const char *const puttystr = PUTTY_REG_POS "\\Sessions";
18 static char **events = NULL;
19 static int nevents = 0, negsize = 0;
21 static HWND logbox = NULL, abtbox = NULL;
23 static char hex[16] = "0123456789ABCDEF";
25 static void mungestr(char *in, char *out) {
29 if (*in == ' ' || *in == '\\' || *in == '*' || *in == '?' ||
30 *in == '%' || *in < ' ' || *in > '~' || (*in == '.' && !candot)) {
32 *out++ = hex[((unsigned char)*in) >> 4];
33 *out++ = hex[((unsigned char)*in) & 15];
43 static void unmungestr(char *in, char *out) {
45 if (*in == '%' && in[1] && in[2]) {
48 i = in[1] - '0'; i -= (i > 9 ? 7 : 0);
49 j = in[2] - '0'; j -= (j > 9 ? 7 : 0);
60 static void wpps(HKEY key, LPCTSTR name, LPCTSTR value) {
61 RegSetValueEx(key, name, 0, REG_SZ, value, 1+strlen(value));
64 static void wppi(HKEY key, LPCTSTR name, int value) {
65 RegSetValueEx(key, name, 0, REG_DWORD,
66 (CONST BYTE *)&value, sizeof(value));
69 static void gpps(HKEY key, LPCTSTR name, LPCTSTR def,
70 LPTSTR val, int len) {
75 RegQueryValueEx(key, name, 0, &type, val, &size) != ERROR_SUCCESS ||
77 strncpy(val, def, len);
82 static void gppi(HKEY key, LPCTSTR name, int def, int *i) {
83 DWORD type, val, size;
87 RegQueryValueEx(key, name, 0, &type,
88 (BYTE *)&val, &size) != ERROR_SUCCESS ||
89 size != sizeof(val) || type != REG_DWORD)
95 static HINSTANCE hinst;
99 static void save_settings (char *section, int do_host) {
101 HKEY subkey1, sesskey;
104 p = malloc(3*strlen(section)+1);
105 mungestr(section, p);
107 if (RegCreateKey(HKEY_CURRENT_USER, puttystr, &subkey1)!=ERROR_SUCCESS ||
108 RegCreateKey(subkey1, p, &sesskey) != ERROR_SUCCESS) {
113 RegCloseKey(subkey1);
115 wppi (sesskey, "Present", 1);
117 wpps (sesskey, "HostName", cfg.host);
118 wppi (sesskey, "PortNumber", cfg.port);
120 for (i = 0; backends[i].name != NULL; i++)
121 if (backends[i].protocol == cfg.protocol) {
122 p = backends[i].name;
125 wpps (sesskey, "Protocol", p);
127 wppi (sesskey, "CloseOnExit", !!cfg.close_on_exit);
128 wppi (sesskey, "WarnOnClose", !!cfg.warn_on_close);
129 wpps (sesskey, "TerminalType", cfg.termtype);
130 wpps (sesskey, "TerminalSpeed", cfg.termspeed);
132 char buf[2*sizeof(cfg.environmt)], *p, *q;
138 if (c == '=' || c == ',' || c == '\\')
148 wpps (sesskey, "Environment", buf);
150 wpps (sesskey, "UserName", cfg.username);
151 wppi (sesskey, "NoPTY", cfg.nopty);
152 wpps (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
153 cfg.cipher == CIPHER_DES ? "des" : "3des");
154 wppi (sesskey, "AuthTIS", cfg.try_tis_auth);
155 wppi (sesskey, "SSHCompression", cfg.ssh_compression);
156 wppi (sesskey, "RFCEnviron", cfg.rfc_environ);
157 wppi (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
158 wppi (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
159 wppi (sesskey, "LinuxFunctionKeys", cfg.linux_funkeys);
160 wppi (sesskey, "ApplicationCursorKeys", cfg.app_cursor);
161 wppi (sesskey, "ApplicationKeypad", cfg.app_keypad);
162 wppi (sesskey, "NetHackKeypad", cfg.nethack_keypad);
163 wppi (sesskey, "AltF4", cfg.alt_f4);
164 wppi (sesskey, "AltSpace", cfg.alt_space);
165 wppi (sesskey, "LdiscTerm", cfg.ldisc_term);
166 wppi (sesskey, "BlinkCur", cfg.blink_cur);
167 wppi (sesskey, "Beep", cfg.beep);
168 wppi (sesskey, "ScrollbackLines", cfg.savelines);
169 wppi (sesskey, "DECOriginMode", cfg.dec_om);
170 wppi (sesskey, "AutoWrapMode", cfg.wrap_mode);
171 wppi (sesskey, "LFImpliesCR", cfg.lfhascr);
172 wppi (sesskey, "WinNameAlways", cfg.win_name_always);
173 wppi (sesskey, "TermWidth", cfg.width);
174 wppi (sesskey, "TermHeight", cfg.height);
175 wpps (sesskey, "Font", cfg.font);
176 wppi (sesskey, "FontIsBold", cfg.fontisbold);
177 wppi (sesskey, "FontCharSet", cfg.fontcharset);
178 wppi (sesskey, "FontHeight", cfg.fontheight);
179 wppi (sesskey, "FontVTMode", cfg.vtmode);
180 wppi (sesskey, "TryPalette", cfg.try_palette);
181 wppi (sesskey, "BoldAsColour", cfg.bold_colour);
182 for (i=0; i<22; i++) {
183 char buf[20], buf2[30];
184 sprintf(buf, "Colour%d", i);
185 sprintf(buf2, "%d,%d,%d", cfg.colours[i][0],
186 cfg.colours[i][1], cfg.colours[i][2]);
187 wpps (sesskey, buf, buf2);
189 wppi (sesskey, "MouseIsXterm", cfg.mouse_is_xterm);
190 for (i=0; i<256; i+=32) {
191 char buf[20], buf2[256];
193 sprintf(buf, "Wordness%d", i);
195 for (j=i; j<i+32; j++) {
196 sprintf(buf2+strlen(buf2), "%s%d",
197 (*buf2 ? "," : ""), cfg.wordness[j]);
199 wpps (sesskey, buf, buf2);
201 wppi (sesskey, "KoiWinXlat", cfg.xlat_enablekoiwin);
202 wppi (sesskey, "88592Xlat", cfg.xlat_88592w1250);
203 wppi (sesskey, "CapsLockCyr", cfg.xlat_capslockcyr);
205 RegCloseKey(sesskey);
208 static void del_session (char *section) {
212 if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS)
215 p = malloc(3*strlen(section)+1);
216 mungestr(section, p);
217 RegDeleteKey(subkey1, p);
220 RegCloseKey(subkey1);
223 static void load_settings (char *section, int do_host) {
225 HKEY subkey1, sesskey;
229 p = malloc(3*strlen(section)+1);
230 mungestr(section, p);
232 if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS) {
235 if (RegOpenKey(subkey1, p, &sesskey) != ERROR_SUCCESS) {
238 RegCloseKey(subkey1);
243 gpps (sesskey, "HostName", "", cfg.host, sizeof(cfg.host));
244 gppi (sesskey, "PortNumber", default_port, &cfg.port);
246 gpps (sesskey, "Protocol", "default", prot, 10);
247 cfg.protocol = default_protocol;
248 for (i = 0; backends[i].name != NULL; i++)
249 if (!strcmp(prot, backends[i].name)) {
250 cfg.protocol = backends[i].protocol;
254 gppi (sesskey, "CloseOnExit", 1, &cfg.close_on_exit);
255 gppi (sesskey, "WarnOnClose", 1, &cfg.warn_on_close);
256 gpps (sesskey, "TerminalType", "xterm", cfg.termtype,
257 sizeof(cfg.termtype));
258 gpps (sesskey, "TerminalSpeed", "38400,38400", cfg.termspeed,
259 sizeof(cfg.termspeed));
261 char buf[2*sizeof(cfg.environmt)], *p, *q;
262 gpps (sesskey, "Environment", "", buf, sizeof(buf));
266 while (*p && *p != ',') {
279 gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username));
280 gppi (sesskey, "NoPTY", 0, &cfg.nopty);
283 gpps (sesskey, "Cipher", "3des", cipher, 10);
284 if (!strcmp(cipher, "blowfish"))
285 cfg.cipher = CIPHER_BLOWFISH;
286 else if (!strcmp(cipher, "des"))
287 cfg.cipher = CIPHER_DES;
289 cfg.cipher = CIPHER_3DES;
291 gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
292 gppi (sesskey, "SSHCompression", 0, &cfg.ssh_compression);
293 gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
294 gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
295 gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
296 gppi (sesskey, "LinuxFunctionKeys", 0, &cfg.linux_funkeys);
297 gppi (sesskey, "ApplicationCursorKeys", 0, &cfg.app_cursor);
298 gppi (sesskey, "ApplicationKeypad", 0, &cfg.app_keypad);
299 gppi (sesskey, "NetHackKeypad", 0, &cfg.nethack_keypad);
300 gppi (sesskey, "AltF4", 1, &cfg.alt_f4);
301 gppi (sesskey, "AltSpace", 0, &cfg.alt_space);
302 gppi (sesskey, "LdiscTerm", 0, &cfg.ldisc_term);
303 gppi (sesskey, "BlinkCur", 0, &cfg.blink_cur);
304 gppi (sesskey, "Beep", 1, &cfg.beep);
305 gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines);
306 gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om);
307 gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode);
308 gppi (sesskey, "LFImpliesCR", 0, &cfg.lfhascr);
309 gppi (sesskey, "WinNameAlways", 0, &cfg.win_name_always);
310 gppi (sesskey, "TermWidth", 80, &cfg.width);
311 gppi (sesskey, "TermHeight", 24, &cfg.height);
312 gpps (sesskey, "Font", "Courier", cfg.font, sizeof(cfg.font));
313 gppi (sesskey, "FontIsBold", 0, &cfg.fontisbold);
314 gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg.fontcharset);
315 gppi (sesskey, "FontHeight", 10, &cfg.fontheight);
316 gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg.vtmode);
317 gppi (sesskey, "TryPalette", 0, &cfg.try_palette);
318 gppi (sesskey, "BoldAsColour", 1, &cfg.bold_colour);
319 for (i=0; i<22; i++) {
320 static char *defaults[] = {
321 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
322 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
323 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
324 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
325 "85,255,255", "187,187,187", "255,255,255"
327 char buf[20], buf2[30];
329 sprintf(buf, "Colour%d", i);
330 gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2));
331 if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
332 cfg.colours[i][0] = c0;
333 cfg.colours[i][1] = c1;
334 cfg.colours[i][2] = c2;
337 gppi (sesskey, "MouseIsXterm", 0, &cfg.mouse_is_xterm);
338 for (i=0; i<256; i+=32) {
339 static char *defaults[] = {
340 "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",
341 "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",
342 "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",
343 "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",
344 "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",
345 "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",
346 "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",
347 "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"
349 char buf[20], buf2[256], *p;
351 sprintf(buf, "Wordness%d", i);
352 gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2));
354 for (j=i; j<i+32; j++) {
356 while (*p && *p != ',') p++;
357 if (*p == ',') *p++ = '\0';
358 cfg.wordness[j] = atoi(q);
361 gppi (sesskey, "KoiWinXlat", 0, &cfg.xlat_enablekoiwin);
362 gppi (sesskey, "88592Xlat", 0, &cfg.xlat_88592w1250);
363 gppi (sesskey, "CapsLockCyr", 0, &cfg.xlat_capslockcyr);
365 RegCloseKey(sesskey);
368 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
371 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
376 static int CALLBACK LogProc (HWND hwnd, UINT msg,
377 WPARAM wParam, LPARAM lParam) {
382 for (i=0; i<nevents; i++)
383 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
384 0, (LPARAM)events[i]);
386 /* case WM_CTLCOLORDLG: */
387 /* return (int) GetStockObject (LTGRAY_BRUSH); */
389 switch (LOWORD(wParam)) {
392 DestroyWindow (hwnd);
398 DestroyWindow (hwnd);
404 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
405 WPARAM wParam, LPARAM lParam) {
410 switch (LOWORD(wParam)) {
413 DestroyWindow (hwnd);
419 DestroyWindow (hwnd);
425 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
426 WPARAM wParam, LPARAM lParam) {
429 SetDlgItemText (hwnd, IDA_VERSION, ver);
431 /* case WM_CTLCOLORDLG: */
432 /* return (int) GetStockObject (LTGRAY_BRUSH); */
433 /* case WM_CTLCOLORSTATIC: */
434 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
435 /* return (int) GetStockObject (LTGRAY_BRUSH); */
437 switch (LOWORD(wParam)) {
440 DestroyWindow (hwnd);
443 EnableWindow(hwnd, 0);
444 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
446 EnableWindow(hwnd, 1);
452 DestroyWindow (hwnd);
458 static int GeneralPanelProc (HWND hwnd, UINT msg,
459 WPARAM wParam, LPARAM lParam) {
462 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
464 /* case WM_CTLCOLORDLG: */
465 /* return (int) GetStockObject (LTGRAY_BRUSH); */
466 /* case WM_CTLCOLORSTATIC: */
467 /* case WM_CTLCOLORBTN: */
468 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
469 /* return (int) GetStockObject (LTGRAY_BRUSH); */
471 DestroyWindow (hwnd);
477 static int CALLBACK ConnectionProc (HWND hwnd, UINT msg,
478 WPARAM wParam, LPARAM lParam) {
483 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
484 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
485 for (i = 0; i < nsessions; i++)
486 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
487 0, (LPARAM) (sessions[i]));
488 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
489 cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
490 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW );
491 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
492 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
496 * Button release should trigger WM_OK if there was a
497 * previous double click on the session list.
501 SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0);
504 switch (LOWORD(wParam)) {
505 case IDC0_PROTTELNET:
508 if (HIWORD(wParam) == BN_CLICKED ||
509 HIWORD(wParam) == BN_DOUBLECLICKED) {
510 int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH);
511 int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET);
512 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
513 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
514 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
515 cfg.port = i ? 22 : 23;
516 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
521 if (HIWORD(wParam) == EN_CHANGE)
522 GetDlgItemText (hwnd, IDC0_HOST, cfg.host,
526 if (HIWORD(wParam) == EN_CHANGE)
527 MyGetDlgItemInt (hwnd, IDC0_PORT, &cfg.port);
530 if (HIWORD(wParam) == BN_CLICKED ||
531 HIWORD(wParam) == BN_DOUBLECLICKED)
532 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC0_CLOSEEXIT);
535 if (HIWORD(wParam) == BN_CLICKED ||
536 HIWORD(wParam) == BN_DOUBLECLICKED)
537 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC0_CLOSEWARN);
540 if (HIWORD(wParam) == EN_CHANGE)
541 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
545 if (HIWORD(wParam) == BN_CLICKED ||
546 HIWORD(wParam) == BN_DOUBLECLICKED) {
551 GetDlgItemText (hwnd, IDC0_SESSEDIT, str, sizeof(str)-1);
553 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
559 strcpy (str, sessions[n]);
561 save_settings (str, !!strcmp(str, "Default Settings"));
562 get_sesslist (FALSE);
564 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
566 for (i = 0; i < nsessions; i++)
567 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
568 0, (LPARAM) (sessions[i]));
569 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
575 if (LOWORD(wParam) == IDC0_SESSLOAD &&
576 HIWORD(wParam) != BN_CLICKED &&
577 HIWORD(wParam) != BN_DOUBLECLICKED)
579 if (LOWORD(wParam) == IDC0_SESSLIST &&
580 HIWORD(wParam) != LBN_DBLCLK)
583 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
589 load_settings (sessions[n],
590 !!strcmp(sessions[n], "Default Settings"));
591 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
592 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
593 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
594 (cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
595 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW));
596 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
597 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
598 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
601 if (LOWORD(wParam) == IDC0_SESSLIST) {
603 * A double-click on a saved session should
604 * actually start the session, not just load it.
605 * Unless it's Default Settings or some other
606 * host-less set of saved settings.
615 if (HIWORD(wParam) == BN_CLICKED ||
616 HIWORD(wParam) == BN_DOUBLECLICKED) {
617 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
619 if (n == LB_ERR || n == 0) {
623 del_session(sessions[n]);
624 get_sesslist (FALSE);
626 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
628 for (i = 0; i < nsessions; i++)
629 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
630 0, (LPARAM) (sessions[i]));
631 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
636 return GeneralPanelProc (hwnd, msg, wParam, lParam);
639 static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
640 WPARAM wParam, LPARAM lParam) {
643 CheckRadioButton (hwnd, IDC1_DEL008, IDC1_DEL127,
644 cfg.bksp_is_delete ? IDC1_DEL127 : IDC1_DEL008);
645 CheckRadioButton (hwnd, IDC1_HOMETILDE, IDC1_HOMERXVT,
646 cfg.rxvt_homeend ? IDC1_HOMERXVT : IDC1_HOMETILDE);
647 CheckRadioButton (hwnd, IDC1_FUNCTILDE, IDC1_FUNCLINUX,
648 cfg.linux_funkeys ? IDC1_FUNCLINUX : IDC1_FUNCTILDE);
649 CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
650 cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
651 CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
652 cfg.nethack_keypad ? IDC1_KPNH :
653 cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
654 CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
655 CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
656 CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
657 CheckDlgButton (hwnd, IDC1_BLINKCUR, cfg.blink_cur);
658 CheckDlgButton (hwnd, IDC1_BEEP, cfg.beep);
661 if (HIWORD(wParam) == BN_CLICKED ||
662 HIWORD(wParam) == BN_DOUBLECLICKED)
663 switch (LOWORD(wParam)) {
666 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC1_DEL127);
670 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC1_HOMERXVT);
674 cfg.linux_funkeys = IsDlgButtonChecked (hwnd, IDC1_FUNCLINUX);
678 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
679 cfg.nethack_keypad = FALSE;
682 cfg.app_keypad = FALSE;
683 cfg.nethack_keypad = TRUE;
687 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
690 if (HIWORD(wParam) == BN_CLICKED ||
691 HIWORD(wParam) == BN_DOUBLECLICKED)
692 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
695 if (HIWORD(wParam) == BN_CLICKED ||
696 HIWORD(wParam) == BN_DOUBLECLICKED)
697 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
700 if (HIWORD(wParam) == BN_CLICKED ||
701 HIWORD(wParam) == BN_DOUBLECLICKED)
702 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
705 if (HIWORD(wParam) == BN_CLICKED ||
706 HIWORD(wParam) == BN_DOUBLECLICKED)
707 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC1_BLINKCUR);
709 if (HIWORD(wParam) == BN_CLICKED ||
710 HIWORD(wParam) == BN_DOUBLECLICKED)
711 cfg.beep = IsDlgButtonChecked (hwnd, IDC1_BEEP);
715 return GeneralPanelProc (hwnd, msg, wParam, lParam);
718 static void fmtfont (char *buf) {
719 sprintf (buf, "Font: %s, ", cfg.font);
721 strcat(buf, "bold, ");
722 if (cfg.fontheight == 0)
723 strcat (buf, "default height");
725 sprintf (buf+strlen(buf), "%d-%s",
726 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
727 (cfg.fontheight < 0 ? "pixel" : "point"));
730 static int CALLBACK TerminalProc (HWND hwnd, UINT msg,
731 WPARAM wParam, LPARAM lParam) {
734 char fontstatic[256];
738 CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode);
739 CheckDlgButton (hwnd, IDC2_WINNAME, cfg.win_name_always);
740 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
741 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
742 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
743 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
744 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
745 fmtfont (fontstatic);
746 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
747 CheckRadioButton (hwnd, IDC2_VTXWINDOWS, IDC2_VTPOORMAN,
748 cfg.vtmode == VT_XWINDOWS ? IDC2_VTXWINDOWS :
749 cfg.vtmode == VT_OEMANSI ? IDC2_VTOEMANSI :
750 cfg.vtmode == VT_OEMONLY ? IDC2_VTOEMONLY :
754 switch (LOWORD(wParam)) {
756 if (HIWORD(wParam) == BN_CLICKED ||
757 HIWORD(wParam) == BN_DOUBLECLICKED)
758 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
761 if (HIWORD(wParam) == BN_CLICKED ||
762 HIWORD(wParam) == BN_DOUBLECLICKED)
763 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC2_WINNAME);
766 if (HIWORD(wParam) == BN_CLICKED ||
767 HIWORD(wParam) == BN_DOUBLECLICKED)
768 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
771 if (HIWORD(wParam) == BN_CLICKED ||
772 HIWORD(wParam) == BN_DOUBLECLICKED)
773 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
776 if (HIWORD(wParam) == EN_CHANGE)
777 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
780 if (HIWORD(wParam) == EN_CHANGE)
781 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
784 if (HIWORD(wParam) == EN_CHANGE)
785 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
787 case IDC2_CHOOSEFONT:
788 lf.lfHeight = cfg.fontheight;
789 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
790 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
791 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
792 lf.lfCharSet = cfg.fontcharset;
793 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
794 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
795 lf.lfQuality = DEFAULT_QUALITY;
796 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
797 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
798 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
800 cf.lStructSize = sizeof(cf);
803 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
804 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
806 if (ChooseFont (&cf)) {
807 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
808 cfg.font[sizeof(cfg.font)-1] = '\0';
809 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
810 cfg.fontcharset = lf.lfCharSet;
811 cfg.fontheight = lf.lfHeight;
812 fmtfont (fontstatic);
813 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
816 case IDC2_VTXWINDOWS:
821 (IsDlgButtonChecked (hwnd, IDC2_VTXWINDOWS) ? VT_XWINDOWS :
822 IsDlgButtonChecked (hwnd, IDC2_VTOEMANSI) ? VT_OEMANSI :
823 IsDlgButtonChecked (hwnd, IDC2_VTOEMONLY) ? VT_OEMONLY :
829 return GeneralPanelProc (hwnd, msg, wParam, lParam);
832 static int CALLBACK TelnetProc (HWND hwnd, UINT msg,
833 WPARAM wParam, LPARAM lParam) {
838 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
839 SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed);
840 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
842 char *p = cfg.environmt;
844 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0,
849 CheckRadioButton (hwnd, IDC3_EMBSD, IDC3_EMRFC,
850 cfg.rfc_environ ? IDC3_EMRFC : IDC3_EMBSD);
853 switch (LOWORD(wParam)) {
855 if (HIWORD(wParam) == EN_CHANGE)
856 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
857 sizeof(cfg.termtype)-1);
860 if (HIWORD(wParam) == EN_CHANGE)
861 GetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed,
862 sizeof(cfg.termspeed)-1);
865 if (HIWORD(wParam) == EN_CHANGE)
866 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
867 sizeof(cfg.username)-1);
871 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC3_EMRFC);
874 if (HIWORD(wParam) == BN_CLICKED ||
875 HIWORD(wParam) == BN_DOUBLECLICKED) {
876 char str[sizeof(cfg.environmt)];
878 GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1);
883 p = str + strlen(str);
885 GetDlgItemText (hwnd, IDC3_VALEDIT, p, sizeof(str)-1-(p-str));
895 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
897 p[strlen(str)+1] = '\0';
898 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING,
900 SetDlgItemText (hwnd, IDC3_VAREDIT, "");
901 SetDlgItemText (hwnd, IDC3_VALEDIT, "");
903 MessageBox(hwnd, "Environment too big", "PuTTY Error",
904 MB_OK | MB_ICONERROR);
909 if (HIWORD(wParam) != BN_CLICKED &&
910 HIWORD(wParam) != BN_DOUBLECLICKED)
912 i = SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_GETCURSEL, 0, 0);
918 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING,
945 return GeneralPanelProc (hwnd, msg, wParam, lParam);
948 static int CALLBACK SshProc (HWND hwnd, UINT msg,
949 WPARAM wParam, LPARAM lParam) {
952 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
953 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
954 CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty);
955 CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES,
956 cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF :
957 cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES :
960 CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
961 CheckDlgButton (hwnd, IDC3_COMPRESS, cfg.ssh_compression);
964 switch (LOWORD(wParam)) {
966 if (HIWORD(wParam) == EN_CHANGE)
967 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
968 sizeof(cfg.termtype)-1);
971 if (HIWORD(wParam) == EN_CHANGE)
972 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
973 sizeof(cfg.username)-1);
976 if (HIWORD(wParam) == BN_CLICKED ||
977 HIWORD(wParam) == BN_DOUBLECLICKED)
978 cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY);
980 case IDC3_CIPHER3DES:
981 case IDC3_CIPHERBLOWF:
983 if (HIWORD(wParam) == BN_CLICKED ||
984 HIWORD(wParam) == BN_DOUBLECLICKED) {
985 if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES))
986 cfg.cipher = CIPHER_3DES;
987 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF))
988 cfg.cipher = CIPHER_BLOWFISH;
989 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES))
990 cfg.cipher = CIPHER_DES;
994 if (HIWORD(wParam) == BN_CLICKED ||
995 HIWORD(wParam) == BN_DOUBLECLICKED)
996 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
999 if (HIWORD(wParam) == BN_CLICKED ||
1000 HIWORD(wParam) == BN_DOUBLECLICKED)
1001 cfg.ssh_compression = IsDlgButtonChecked (hwnd, IDC3_COMPRESS);
1006 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1009 static int CALLBACK SelectionProc (HWND hwnd, UINT msg,
1010 WPARAM wParam, LPARAM lParam) {
1015 CheckRadioButton (hwnd, IDC4_MBWINDOWS, IDC4_MBXTERM,
1016 cfg.mouse_is_xterm ? IDC4_MBXTERM : IDC4_MBWINDOWS);
1018 static int tabs[4] = {25, 61, 96, 128};
1019 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_SETTABSTOPS, 4,
1022 for (i=0; i<256; i++) {
1024 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1025 (i>=0x21 && i != 0x7F) ? i : ' ',
1027 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_ADDSTRING, 0,
1032 switch (LOWORD(wParam)) {
1033 case IDC4_MBWINDOWS:
1035 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC4_MBXTERM);
1041 int n = GetDlgItemInt (hwnd, IDC4_CCEDIT, &ok, FALSE);
1046 for (i=0; i<256; i++)
1047 if (SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_GETSEL,
1050 cfg.wordness[i] = n;
1051 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1052 LB_DELETESTRING, i, 0);
1053 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1054 (i>=0x21 && i != 0x7F) ? i : ' ',
1056 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1066 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1069 static int CALLBACK ColourProc (HWND hwnd, UINT msg,
1070 WPARAM wParam, LPARAM lParam) {
1071 static const char *const colours[] = {
1072 "Default Foreground", "Default Bold Foreground",
1073 "Default Background", "Default Bold Background",
1074 "Cursor Text", "Cursor Colour",
1075 "ANSI Black", "ANSI Black Bold",
1076 "ANSI Red", "ANSI Red Bold",
1077 "ANSI Green", "ANSI Green Bold",
1078 "ANSI Yellow", "ANSI Yellow Bold",
1079 "ANSI Blue", "ANSI Blue Bold",
1080 "ANSI Magenta", "ANSI Magenta Bold",
1081 "ANSI Cyan", "ANSI Cyan Bold",
1082 "ANSI White", "ANSI White Bold"
1084 static const int permanent[] = {
1085 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
1086 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
1087 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
1091 CheckDlgButton (hwnd, IDC5_BOLDCOLOUR, cfg.bold_colour);
1092 CheckDlgButton (hwnd, IDC5_PALETTE, cfg.try_palette);
1095 for (i=0; i<22; i++)
1096 if (cfg.bold_colour || permanent[i])
1097 SendDlgItemMessage (hwnd, IDC5_LIST, LB_ADDSTRING, 0,
1098 (LPARAM) colours[i]);
1100 SendDlgItemMessage (hwnd, IDC5_LIST, LB_SETCURSEL, 0, 0);
1101 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[0][0], FALSE);
1102 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[0][1], FALSE);
1103 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[0][2], FALSE);
1106 switch (LOWORD(wParam)) {
1107 case IDC5_BOLDCOLOUR:
1108 if (HIWORD(wParam) == BN_CLICKED ||
1109 HIWORD(wParam) == BN_DOUBLECLICKED) {
1111 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC5_BOLDCOLOUR);
1112 n = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCOUNT, 0, 0);
1113 if (cfg.bold_colour && n!=22) {
1114 for (i=0; i<22; i++)
1116 SendDlgItemMessage (hwnd, IDC5_LIST,
1118 (LPARAM) colours[i]);
1119 } else if (!cfg.bold_colour && n!=12) {
1122 SendDlgItemMessage (hwnd, IDC5_LIST,
1123 LB_DELETESTRING, i, 0);
1128 if (HIWORD(wParam) == BN_CLICKED ||
1129 HIWORD(wParam) == BN_DOUBLECLICKED)
1130 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC5_PALETTE);
1133 if (HIWORD(wParam) == LBN_DBLCLK ||
1134 HIWORD(wParam) == LBN_SELCHANGE) {
1135 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1137 if (!cfg.bold_colour)
1138 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1139 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0], FALSE);
1140 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1], FALSE);
1141 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2], FALSE);
1145 if (HIWORD(wParam) == BN_CLICKED ||
1146 HIWORD(wParam) == BN_DOUBLECLICKED) {
1147 static CHOOSECOLOR cc;
1148 static DWORD custom[16] = {0}; /* zero initialisers */
1149 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1151 if (!cfg.bold_colour)
1152 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1153 cc.lStructSize = sizeof(cc);
1154 cc.hwndOwner = hwnd;
1155 cc.hInstance = (HWND)hinst;
1156 cc.lpCustColors = custom;
1157 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1159 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1160 if (ChooseColor(&cc)) {
1162 (unsigned char) (cc.rgbResult & 0xFF);
1164 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1166 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1167 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0],
1169 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1],
1171 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2],
1179 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1182 static int CALLBACK LanguageProc (HWND hwnd, UINT msg,
1183 WPARAM wParam, LPARAM lParam) {
1186 CheckRadioButton (hwnd, IDC6_NOXLAT, IDC6_88592WIN1250,
1187 cfg.xlat_88592w1250 ? IDC6_88592WIN1250 :
1188 cfg.xlat_enablekoiwin ? IDC6_KOI8WIN1251 :
1190 CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr);
1192 switch (LOWORD(wParam)) {
1194 case IDC6_KOI8WIN1251:
1195 case IDC6_88592WIN1250:
1196 cfg.xlat_enablekoiwin =
1197 IsDlgButtonChecked (hwnd, IDC6_KOI8WIN1251);
1198 cfg.xlat_88592w1250 =
1199 IsDlgButtonChecked (hwnd, IDC6_88592WIN1250);
1201 case IDC6_CAPSLOCKCYR:
1202 if (HIWORD(wParam) == BN_CLICKED ||
1203 HIWORD(wParam) == BN_DOUBLECLICKED) {
1204 cfg.xlat_capslockcyr =
1205 IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR);
1210 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1213 static DLGPROC panelproc[NPANELS] = {
1214 ConnectionProc, KeyboardProc, TerminalProc,
1215 TelnetProc, SshProc, SelectionProc, ColourProc, LanguageProc
1217 static char *panelids[NPANELS] = {
1218 MAKEINTRESOURCE(IDD_PANEL0),
1219 MAKEINTRESOURCE(IDD_PANEL1),
1220 MAKEINTRESOURCE(IDD_PANEL2),
1221 MAKEINTRESOURCE(IDD_PANEL3),
1222 MAKEINTRESOURCE(IDD_PANEL35),
1223 MAKEINTRESOURCE(IDD_PANEL4),
1224 MAKEINTRESOURCE(IDD_PANEL5),
1225 MAKEINTRESOURCE(IDD_PANEL6)
1228 static char *names[NPANELS] = {
1229 "Connection", "Keyboard", "Terminal", "Telnet",
1230 "SSH", "Selection", "Colours", "Language"
1233 static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7};
1234 static int reconfp[RECONF_NPANELS] = { 1, 2, 5, 6, 7};
1236 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1237 WPARAM wParam, LPARAM lParam,
1238 int npanels, int *panelnums, HWND *page) {
1243 { /* centre the window */
1246 hw = GetDesktopWindow();
1247 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1248 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1249 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1250 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1253 { /* initialise the tab control */
1257 hw = GetDlgItem (hwnd, IDC_TAB);
1258 for (i=0; i<npanels; i++) {
1259 tab.mask = TCIF_TEXT;
1260 tab.pszText = names[panelnums[i]];
1261 TabCtrl_InsertItem (hw, i, &tab);
1263 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1264 hwnd, panelproc[panelnums[0]]);*/
1265 *page = CreateDialog (hinst, panelids[panelnums[0]],
1266 hwnd, panelproc[panelnums[0]]);
1267 SetWindowLong (*page, GWL_EXSTYLE,
1268 GetWindowLong (*page, GWL_EXSTYLE) |
1269 WS_EX_CONTROLPARENT);
1274 if (LOWORD(wParam) == IDC_TAB &&
1275 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1276 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1278 DestroyWindow (*page);
1279 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1280 hwnd, panelproc[panelnums[i]]);*/
1281 *page = CreateDialog (hinst, panelids[panelnums[i]],
1282 hwnd, panelproc[panelnums[i]]);
1283 SetWindowLong (*page, GWL_EXSTYLE,
1284 GetWindowLong (*page, GWL_EXSTYLE) |
1285 WS_EX_CONTROLPARENT);
1286 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1290 /* case WM_CTLCOLORDLG: */
1291 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1293 switch (LOWORD(wParam)) {
1296 EndDialog (hwnd, 1);
1301 EndDialog (hwnd, 0);
1306 EndDialog (hwnd, 0);
1312 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1313 WPARAM wParam, LPARAM lParam) {
1318 static HWND page = NULL;
1320 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1323 * If the Connection panel is active and the Session List
1324 * box is selected, we treat a press of Open to have an
1325 * implicit press of Load preceding it.
1327 hw = GetDlgItem (hwnd, IDC_TAB);
1328 i = TabCtrl_GetCurSel(hw);
1329 if (panelproc[mainp[i]] == ConnectionProc &&
1330 page && implicit_load_ok) {
1331 SendMessage (page, WM_COMMAND,
1332 MAKELONG(IDC0_SESSLOAD, BN_CLICKED), 0);
1336 if (msg == WM_COMMAND && LOWORD(wParam) == IDC_ABOUT) {
1337 EnableWindow(hwnd, 0);
1338 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1339 GetParent(hwnd), AboutProc);
1340 EnableWindow(hwnd, 1);
1342 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1343 MAIN_NPANELS, mainp, &page);
1346 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1347 WPARAM wParam, LPARAM lParam) {
1349 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1350 RECONF_NPANELS, reconfp, &page);
1353 void get_sesslist(int allocate) {
1354 static char *buffer;
1355 int buflen, bufsize, i, ret;
1356 char otherbuf[2048];
1361 if (RegCreateKey(HKEY_CURRENT_USER,
1362 puttystr, &subkey1) != ERROR_SUCCESS)
1365 buflen = bufsize = 0;
1369 ret = RegEnumKey(subkey1, i++, otherbuf, sizeof(otherbuf));
1370 if (ret == ERROR_SUCCESS) {
1371 bufsize = buflen + 2048;
1372 buffer = srealloc(buffer, bufsize);
1373 unmungestr(otherbuf, buffer+buflen);
1374 buflen += strlen(buffer+buflen)+1;
1376 } while (ret == ERROR_SUCCESS);
1377 buffer = srealloc(buffer, buflen+1);
1378 buffer[buflen] = '\0';
1381 nsessions = 1; /* "Default Settings" counts as one */
1383 if (strcmp(p, "Default Settings"))
1389 sessions = smalloc(nsessions * sizeof(char *));
1390 sessions[0] = "Default Settings";
1394 if (strcmp(p, "Default Settings"))
1405 int do_config (void) {
1409 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1410 get_sesslist(FALSE);
1415 int do_reconfig (HWND hwnd) {
1419 backup_cfg = cfg; /* structure copy */
1420 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1422 cfg = backup_cfg; /* structure copy */
1426 void do_defaults (char *session) {
1428 load_settings (session, TRUE);
1430 load_settings ("Default Settings", FALSE);
1433 void logevent (char *string) {
1434 if (IS_SCP && (scp_flags & SCP_VERBOSE) != 0)
1435 fprintf(stderr, "%s\n", string);
1436 if (nevents >= negsize) {
1438 events = srealloc (events, negsize * sizeof(*events));
1440 events[nevents] = smalloc(1+strlen(string));
1441 strcpy (events[nevents], string);
1444 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1448 void showeventlog (HWND hwnd) {
1450 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1452 ShowWindow (logbox, SW_SHOWNORMAL);
1456 void showabout (HWND hwnd) {
1458 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1460 ShowWindow (abtbox, SW_SHOWNORMAL);
1464 void verify_ssh_host_key(char *host, char *keystr) {
1465 char *otherstr, *mungedhost;
1469 len = 1 + strlen(keystr);
1472 * Now read a saved key in from the registry and see what it
1475 otherstr = malloc(len);
1476 mungedhost = malloc(3*strlen(host)+1);
1477 if (!otherstr || !mungedhost)
1478 fatalbox("Out of memory");
1480 mungestr(host, mungedhost);
1482 if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",
1483 &rkey) != ERROR_SUCCESS) {
1484 if (MessageBox(NULL, "PuTTY was unable to open the host key cache\n"
1485 "in the registry. There is thus no way to tell\n"
1486 "if the remote host is what you think it is.\n"
1487 "Connect anyway?", "PuTTY Problem",
1488 MB_ICONWARNING | MB_YESNO) == IDNO)
1491 DWORD readlen = len;
1495 ret = RegQueryValueEx(rkey, mungedhost, NULL,
1496 &type, otherstr, &readlen);
1498 if (ret == ERROR_MORE_DATA ||
1499 (ret == ERROR_SUCCESS && type == REG_SZ &&
1500 strcmp(otherstr, keystr))) {
1501 if (MessageBox(NULL,
1502 "This host's host key is different from the\n"
1503 "one cached in the registry! Someone may be\n"
1504 "impersonating this host for malicious reasons;\n"
1505 "alternatively, the host key may have changed\n"
1506 "due to sloppy system administration.\n"
1507 "Replace key in registry and connect?",
1508 "PuTTY: Security Warning",
1509 MB_ICONWARNING | MB_YESNO) == IDNO)
1511 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,
1513 } else if (ret != ERROR_SUCCESS || type != REG_SZ) {
1514 if (MessageBox(NULL,
1515 "This host's host key is not cached in the\n"
1516 "registry. Do you want to add it to the cache\n"
1517 "and carry on connecting?",
1519 MB_ICONWARNING | MB_YESNO) == IDNO)
1521 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,