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].backend != 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, "RFCEnviron", cfg.rfc_environ);
156 wppi (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
157 wppi (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
158 wppi (sesskey, "LinuxFunctionKeys", cfg.linux_funkeys);
159 wppi (sesskey, "ApplicationCursorKeys", cfg.app_cursor);
160 wppi (sesskey, "ApplicationKeypad", cfg.app_keypad);
161 wppi (sesskey, "NetHackKeypad", cfg.nethack_keypad);
162 wppi (sesskey, "AltF4", cfg.alt_f4);
163 wppi (sesskey, "AltSpace", cfg.alt_space);
164 wppi (sesskey, "LdiscTerm", cfg.ldisc_term);
165 wppi (sesskey, "BlinkCur", cfg.blink_cur);
166 wppi (sesskey, "ScrollbackLines", cfg.savelines);
167 wppi (sesskey, "DECOriginMode", cfg.dec_om);
168 wppi (sesskey, "AutoWrapMode", cfg.wrap_mode);
169 wppi (sesskey, "LFImpliesCR", cfg.lfhascr);
170 wppi (sesskey, "WinNameAlways", cfg.win_name_always);
171 wppi (sesskey, "TermWidth", cfg.width);
172 wppi (sesskey, "TermHeight", cfg.height);
173 wpps (sesskey, "Font", cfg.font);
174 wppi (sesskey, "FontIsBold", cfg.fontisbold);
175 wppi (sesskey, "FontCharSet", cfg.fontcharset);
176 wppi (sesskey, "FontHeight", cfg.fontheight);
177 wppi (sesskey, "FontVTMode", cfg.vtmode);
178 wppi (sesskey, "TryPalette", cfg.try_palette);
179 wppi (sesskey, "BoldAsColour", cfg.bold_colour);
180 for (i=0; i<22; i++) {
181 char buf[20], buf2[30];
182 sprintf(buf, "Colour%d", i);
183 sprintf(buf2, "%d,%d,%d", cfg.colours[i][0],
184 cfg.colours[i][1], cfg.colours[i][2]);
185 wpps (sesskey, buf, buf2);
187 wppi (sesskey, "MouseIsXterm", cfg.mouse_is_xterm);
188 for (i=0; i<256; i+=32) {
189 char buf[20], buf2[256];
191 sprintf(buf, "Wordness%d", i);
193 for (j=i; j<i+32; j++) {
194 sprintf(buf2+strlen(buf2), "%s%d",
195 (*buf2 ? "," : ""), cfg.wordness[j]);
197 wpps (sesskey, buf, buf2);
199 wppi (sesskey, "KoiWinXlat", cfg.xlat_enablekoiwin);
200 wppi (sesskey, "88592Xlat", cfg.xlat_88592w1250);
201 wppi (sesskey, "CapsLockCyr", cfg.xlat_capslockcyr);
203 RegCloseKey(sesskey);
206 static void del_session (char *section) {
210 if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS)
213 p = malloc(3*strlen(section)+1);
214 mungestr(section, p);
215 RegDeleteKey(subkey1, p);
218 RegCloseKey(subkey1);
221 static void load_settings (char *section, int do_host) {
223 HKEY subkey1, sesskey;
227 p = malloc(3*strlen(section)+1);
228 mungestr(section, p);
230 if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS) {
233 if (RegOpenKey(subkey1, p, &sesskey) != ERROR_SUCCESS) {
236 RegCloseKey(subkey1);
241 gpps (sesskey, "HostName", "", cfg.host, sizeof(cfg.host));
242 gppi (sesskey, "PortNumber", default_port, &cfg.port);
244 gpps (sesskey, "Protocol", "default", prot, 10);
245 cfg.protocol = default_protocol;
246 for (i = 0; backends[i].backend != NULL; i++)
247 if (!strcmp(prot, backends[i].name)) {
248 cfg.protocol = backends[i].protocol;
252 gppi (sesskey, "CloseOnExit", 1, &cfg.close_on_exit);
253 gppi (sesskey, "WarnOnClose", 1, &cfg.warn_on_close);
254 gpps (sesskey, "TerminalType", "xterm", cfg.termtype,
255 sizeof(cfg.termtype));
256 gpps (sesskey, "TerminalSpeed", "38400,38400", cfg.termspeed,
257 sizeof(cfg.termspeed));
259 char buf[2*sizeof(cfg.environmt)], *p, *q;
260 gpps (sesskey, "Environment", "", buf, sizeof(buf));
264 while (*p && *p != ',') {
277 gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username));
278 gppi (sesskey, "NoPTY", 0, &cfg.nopty);
281 gpps (sesskey, "Cipher", "3des", cipher, 10);
282 if (!strcmp(cipher, "blowfish"))
283 cfg.cipher = CIPHER_BLOWFISH;
284 else if (!strcmp(cipher, "des"))
285 cfg.cipher = CIPHER_DES;
287 cfg.cipher = CIPHER_3DES;
289 gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
290 gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
291 gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
292 gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
293 gppi (sesskey, "LinuxFunctionKeys", 0, &cfg.linux_funkeys);
294 gppi (sesskey, "ApplicationCursorKeys", 0, &cfg.app_cursor);
295 gppi (sesskey, "ApplicationKeypad", 0, &cfg.app_keypad);
296 gppi (sesskey, "NetHackKeypad", 0, &cfg.nethack_keypad);
297 gppi (sesskey, "AltF4", 1, &cfg.alt_f4);
298 gppi (sesskey, "AltSpace", 0, &cfg.alt_space);
299 gppi (sesskey, "LdiscTerm", 0, &cfg.ldisc_term);
300 gppi (sesskey, "BlinkCur", 0, &cfg.blink_cur);
301 gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines);
302 gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om);
303 gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode);
304 gppi (sesskey, "LFImpliesCR", 0, &cfg.lfhascr);
305 gppi (sesskey, "WinNameAlways", 0, &cfg.win_name_always);
306 gppi (sesskey, "TermWidth", 80, &cfg.width);
307 gppi (sesskey, "TermHeight", 24, &cfg.height);
308 gpps (sesskey, "Font", "Courier", cfg.font, sizeof(cfg.font));
309 gppi (sesskey, "FontIsBold", 0, &cfg.fontisbold);
310 gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg.fontcharset);
311 gppi (sesskey, "FontHeight", 10, &cfg.fontheight);
312 gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg.vtmode);
313 gppi (sesskey, "TryPalette", 0, &cfg.try_palette);
314 gppi (sesskey, "BoldAsColour", 1, &cfg.bold_colour);
315 for (i=0; i<22; i++) {
316 static char *defaults[] = {
317 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
318 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
319 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
320 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
321 "85,255,255", "187,187,187", "255,255,255"
323 char buf[20], buf2[30];
325 sprintf(buf, "Colour%d", i);
326 gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2));
327 if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
328 cfg.colours[i][0] = c0;
329 cfg.colours[i][1] = c1;
330 cfg.colours[i][2] = c2;
333 gppi (sesskey, "MouseIsXterm", 0, &cfg.mouse_is_xterm);
334 for (i=0; i<256; i+=32) {
335 static char *defaults[] = {
336 "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",
337 "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",
338 "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",
339 "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",
340 "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",
341 "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",
342 "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",
343 "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"
345 char buf[20], buf2[256], *p;
347 sprintf(buf, "Wordness%d", i);
348 gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2));
350 for (j=i; j<i+32; j++) {
352 while (*p && *p != ',') p++;
353 if (*p == ',') *p++ = '\0';
354 cfg.wordness[j] = atoi(q);
357 gppi (sesskey, "KoiWinXlat", 0, &cfg.xlat_enablekoiwin);
358 gppi (sesskey, "88592Xlat", 0, &cfg.xlat_88592w1250);
359 gppi (sesskey, "CapsLockCyr", 0, &cfg.xlat_capslockcyr);
361 RegCloseKey(sesskey);
364 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
367 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
372 static int CALLBACK LogProc (HWND hwnd, UINT msg,
373 WPARAM wParam, LPARAM lParam) {
378 for (i=0; i<nevents; i++)
379 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
380 0, (LPARAM)events[i]);
382 /* case WM_CTLCOLORDLG: */
383 /* return (int) GetStockObject (LTGRAY_BRUSH); */
385 switch (LOWORD(wParam)) {
388 DestroyWindow (hwnd);
394 DestroyWindow (hwnd);
400 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
401 WPARAM wParam, LPARAM lParam) {
406 switch (LOWORD(wParam)) {
409 DestroyWindow (hwnd);
415 DestroyWindow (hwnd);
421 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
422 WPARAM wParam, LPARAM lParam) {
425 SetDlgItemText (hwnd, IDA_VERSION, ver);
427 /* case WM_CTLCOLORDLG: */
428 /* return (int) GetStockObject (LTGRAY_BRUSH); */
429 /* case WM_CTLCOLORSTATIC: */
430 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
431 /* return (int) GetStockObject (LTGRAY_BRUSH); */
433 switch (LOWORD(wParam)) {
436 DestroyWindow (hwnd);
439 EnableWindow(hwnd, 0);
440 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
442 EnableWindow(hwnd, 1);
448 DestroyWindow (hwnd);
454 static int GeneralPanelProc (HWND hwnd, UINT msg,
455 WPARAM wParam, LPARAM lParam) {
458 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
460 /* case WM_CTLCOLORDLG: */
461 /* return (int) GetStockObject (LTGRAY_BRUSH); */
462 /* case WM_CTLCOLORSTATIC: */
463 /* case WM_CTLCOLORBTN: */
464 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
465 /* return (int) GetStockObject (LTGRAY_BRUSH); */
467 DestroyWindow (hwnd);
473 static int CALLBACK ConnectionProc (HWND hwnd, UINT msg,
474 WPARAM wParam, LPARAM lParam) {
479 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
480 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
481 for (i = 0; i < nsessions; i++)
482 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
483 0, (LPARAM) (sessions[i]));
484 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
485 cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
486 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW );
487 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
488 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
492 * Button release should trigger WM_OK if there was a
493 * previous double click on the session list.
497 SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0);
500 switch (LOWORD(wParam)) {
501 case IDC0_PROTTELNET:
504 if (HIWORD(wParam) == BN_CLICKED ||
505 HIWORD(wParam) == BN_DOUBLECLICKED) {
506 int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH);
507 int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET);
508 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
509 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
510 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
511 cfg.port = i ? 22 : 23;
512 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
517 if (HIWORD(wParam) == EN_CHANGE)
518 GetDlgItemText (hwnd, IDC0_HOST, cfg.host,
522 if (HIWORD(wParam) == EN_CHANGE)
523 MyGetDlgItemInt (hwnd, IDC0_PORT, &cfg.port);
526 if (HIWORD(wParam) == BN_CLICKED ||
527 HIWORD(wParam) == BN_DOUBLECLICKED)
528 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC0_CLOSEEXIT);
531 if (HIWORD(wParam) == BN_CLICKED ||
532 HIWORD(wParam) == BN_DOUBLECLICKED)
533 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC0_CLOSEWARN);
536 if (HIWORD(wParam) == EN_CHANGE)
537 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
541 if (HIWORD(wParam) == BN_CLICKED ||
542 HIWORD(wParam) == BN_DOUBLECLICKED) {
547 GetDlgItemText (hwnd, IDC0_SESSEDIT, str, sizeof(str)-1);
549 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
555 strcpy (str, sessions[n]);
557 save_settings (str, !!strcmp(str, "Default Settings"));
558 get_sesslist (FALSE);
560 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
562 for (i = 0; i < nsessions; i++)
563 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
564 0, (LPARAM) (sessions[i]));
565 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
571 if (LOWORD(wParam) == IDC0_SESSLOAD &&
572 HIWORD(wParam) != BN_CLICKED &&
573 HIWORD(wParam) != BN_DOUBLECLICKED)
575 if (LOWORD(wParam) == IDC0_SESSLIST &&
576 HIWORD(wParam) != LBN_DBLCLK)
579 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
585 load_settings (sessions[n],
586 !!strcmp(sessions[n], "Default Settings"));
587 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
588 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
589 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
590 (cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
591 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW));
592 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
593 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
594 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
597 if (LOWORD(wParam) == IDC0_SESSLIST) {
599 * A double-click on a saved session should
600 * actually start the session, not just load it.
601 * Unless it's Default Settings or some other
602 * host-less set of saved settings.
611 if (HIWORD(wParam) == BN_CLICKED ||
612 HIWORD(wParam) == BN_DOUBLECLICKED) {
613 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
615 if (n == LB_ERR || n == 0) {
619 del_session(sessions[n]);
620 get_sesslist (FALSE);
622 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
624 for (i = 0; i < nsessions; i++)
625 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
626 0, (LPARAM) (sessions[i]));
627 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
632 return GeneralPanelProc (hwnd, msg, wParam, lParam);
635 static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
636 WPARAM wParam, LPARAM lParam) {
639 CheckRadioButton (hwnd, IDC1_DEL008, IDC1_DEL127,
640 cfg.bksp_is_delete ? IDC1_DEL127 : IDC1_DEL008);
641 CheckRadioButton (hwnd, IDC1_HOMETILDE, IDC1_HOMERXVT,
642 cfg.rxvt_homeend ? IDC1_HOMERXVT : IDC1_HOMETILDE);
643 CheckRadioButton (hwnd, IDC1_FUNCTILDE, IDC1_FUNCLINUX,
644 cfg.linux_funkeys ? IDC1_FUNCLINUX : IDC1_FUNCTILDE);
645 CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
646 cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
647 CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
648 cfg.nethack_keypad ? IDC1_KPNH :
649 cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
650 CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
651 CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
652 CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
653 CheckDlgButton (hwnd, IDC1_BLINKCUR, cfg.blink_cur);
656 if (HIWORD(wParam) == BN_CLICKED ||
657 HIWORD(wParam) == BN_DOUBLECLICKED)
658 switch (LOWORD(wParam)) {
661 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC1_DEL127);
665 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC1_HOMERXVT);
669 cfg.linux_funkeys = IsDlgButtonChecked (hwnd, IDC1_FUNCLINUX);
673 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
674 cfg.nethack_keypad = FALSE;
677 cfg.app_keypad = FALSE;
678 cfg.nethack_keypad = TRUE;
682 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
685 if (HIWORD(wParam) == BN_CLICKED ||
686 HIWORD(wParam) == BN_DOUBLECLICKED)
687 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
690 if (HIWORD(wParam) == BN_CLICKED ||
691 HIWORD(wParam) == BN_DOUBLECLICKED)
692 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
695 if (HIWORD(wParam) == BN_CLICKED ||
696 HIWORD(wParam) == BN_DOUBLECLICKED)
697 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
700 if (HIWORD(wParam) == BN_CLICKED ||
701 HIWORD(wParam) == BN_DOUBLECLICKED)
702 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC1_BLINKCUR);
706 return GeneralPanelProc (hwnd, msg, wParam, lParam);
709 static void fmtfont (char *buf) {
710 sprintf (buf, "Font: %s, ", cfg.font);
712 strcat(buf, "bold, ");
713 if (cfg.fontheight == 0)
714 strcat (buf, "default height");
716 sprintf (buf+strlen(buf), "%d-%s",
717 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
718 (cfg.fontheight < 0 ? "pixel" : "point"));
721 static int CALLBACK TerminalProc (HWND hwnd, UINT msg,
722 WPARAM wParam, LPARAM lParam) {
725 char fontstatic[256];
729 CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode);
730 CheckDlgButton (hwnd, IDC2_WINNAME, cfg.win_name_always);
731 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
732 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
733 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
734 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
735 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
736 fmtfont (fontstatic);
737 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
738 CheckRadioButton (hwnd, IDC2_VTXWINDOWS, IDC2_VTPOORMAN,
739 cfg.vtmode == VT_XWINDOWS ? IDC2_VTXWINDOWS :
740 cfg.vtmode == VT_OEMANSI ? IDC2_VTOEMANSI :
741 cfg.vtmode == VT_OEMONLY ? IDC2_VTOEMONLY :
745 switch (LOWORD(wParam)) {
747 if (HIWORD(wParam) == BN_CLICKED ||
748 HIWORD(wParam) == BN_DOUBLECLICKED)
749 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
752 if (HIWORD(wParam) == BN_CLICKED ||
753 HIWORD(wParam) == BN_DOUBLECLICKED)
754 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC2_WINNAME);
757 if (HIWORD(wParam) == BN_CLICKED ||
758 HIWORD(wParam) == BN_DOUBLECLICKED)
759 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
762 if (HIWORD(wParam) == BN_CLICKED ||
763 HIWORD(wParam) == BN_DOUBLECLICKED)
764 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
767 if (HIWORD(wParam) == EN_CHANGE)
768 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
771 if (HIWORD(wParam) == EN_CHANGE)
772 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
775 if (HIWORD(wParam) == EN_CHANGE)
776 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
778 case IDC2_CHOOSEFONT:
779 lf.lfHeight = cfg.fontheight;
780 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
781 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
782 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
783 lf.lfCharSet = cfg.fontcharset;
784 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
785 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
786 lf.lfQuality = DEFAULT_QUALITY;
787 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
788 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
789 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
791 cf.lStructSize = sizeof(cf);
794 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
795 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
797 if (ChooseFont (&cf)) {
798 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
799 cfg.font[sizeof(cfg.font)-1] = '\0';
800 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
801 cfg.fontcharset = lf.lfCharSet;
802 cfg.fontheight = lf.lfHeight;
803 fmtfont (fontstatic);
804 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
807 case IDC2_VTXWINDOWS:
812 (IsDlgButtonChecked (hwnd, IDC2_VTXWINDOWS) ? VT_XWINDOWS :
813 IsDlgButtonChecked (hwnd, IDC2_VTOEMANSI) ? VT_OEMANSI :
814 IsDlgButtonChecked (hwnd, IDC2_VTOEMONLY) ? VT_OEMONLY :
820 return GeneralPanelProc (hwnd, msg, wParam, lParam);
823 static int CALLBACK TelnetProc (HWND hwnd, UINT msg,
824 WPARAM wParam, LPARAM lParam) {
829 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
830 SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed);
831 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
833 char *p = cfg.environmt;
835 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0,
840 CheckRadioButton (hwnd, IDC3_EMBSD, IDC3_EMRFC,
841 cfg.rfc_environ ? IDC3_EMRFC : IDC3_EMBSD);
844 switch (LOWORD(wParam)) {
846 if (HIWORD(wParam) == EN_CHANGE)
847 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
848 sizeof(cfg.termtype)-1);
851 if (HIWORD(wParam) == EN_CHANGE)
852 GetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed,
853 sizeof(cfg.termspeed)-1);
856 if (HIWORD(wParam) == EN_CHANGE)
857 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
858 sizeof(cfg.username)-1);
862 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC3_EMRFC);
865 if (HIWORD(wParam) == BN_CLICKED ||
866 HIWORD(wParam) == BN_DOUBLECLICKED) {
867 char str[sizeof(cfg.environmt)];
869 GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1);
874 p = str + strlen(str);
876 GetDlgItemText (hwnd, IDC3_VALEDIT, p, sizeof(str)-1-(p-str));
886 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
888 p[strlen(str)+1] = '\0';
889 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING,
891 SetDlgItemText (hwnd, IDC3_VAREDIT, "");
892 SetDlgItemText (hwnd, IDC3_VALEDIT, "");
894 MessageBox(hwnd, "Environment too big", "PuTTY Error",
895 MB_OK | MB_ICONERROR);
900 if (HIWORD(wParam) != BN_CLICKED &&
901 HIWORD(wParam) != BN_DOUBLECLICKED)
903 i = SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_GETCURSEL, 0, 0);
909 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING,
936 return GeneralPanelProc (hwnd, msg, wParam, lParam);
939 static int CALLBACK SshProc (HWND hwnd, UINT msg,
940 WPARAM wParam, LPARAM lParam) {
943 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
944 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
945 CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty);
946 CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES,
947 cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF :
948 cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES :
951 CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
954 switch (LOWORD(wParam)) {
956 if (HIWORD(wParam) == EN_CHANGE)
957 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
958 sizeof(cfg.termtype)-1);
961 if (HIWORD(wParam) == EN_CHANGE)
962 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
963 sizeof(cfg.username)-1);
966 if (HIWORD(wParam) == BN_CLICKED ||
967 HIWORD(wParam) == BN_DOUBLECLICKED)
968 cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY);
970 case IDC3_CIPHER3DES:
971 case IDC3_CIPHERBLOWF:
973 if (HIWORD(wParam) == BN_CLICKED ||
974 HIWORD(wParam) == BN_DOUBLECLICKED) {
975 if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES))
976 cfg.cipher = CIPHER_3DES;
977 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF))
978 cfg.cipher = CIPHER_BLOWFISH;
979 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES))
980 cfg.cipher = CIPHER_DES;
984 if (HIWORD(wParam) == BN_CLICKED ||
985 HIWORD(wParam) == BN_DOUBLECLICKED)
986 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
991 return GeneralPanelProc (hwnd, msg, wParam, lParam);
994 static int CALLBACK SelectionProc (HWND hwnd, UINT msg,
995 WPARAM wParam, LPARAM lParam) {
1000 CheckRadioButton (hwnd, IDC4_MBWINDOWS, IDC4_MBXTERM,
1001 cfg.mouse_is_xterm ? IDC4_MBXTERM : IDC4_MBWINDOWS);
1003 static int tabs[4] = {25, 61, 96, 128};
1004 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_SETTABSTOPS, 4,
1007 for (i=0; i<256; i++) {
1009 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1010 (i>=0x21 && i != 0x7F) ? i : ' ',
1012 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_ADDSTRING, 0,
1017 switch (LOWORD(wParam)) {
1018 case IDC4_MBWINDOWS:
1020 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC4_MBXTERM);
1026 int n = GetDlgItemInt (hwnd, IDC4_CCEDIT, &ok, FALSE);
1031 for (i=0; i<256; i++)
1032 if (SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_GETSEL,
1035 cfg.wordness[i] = n;
1036 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1037 LB_DELETESTRING, i, 0);
1038 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1039 (i>=0x21 && i != 0x7F) ? i : ' ',
1041 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1051 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1054 static int CALLBACK ColourProc (HWND hwnd, UINT msg,
1055 WPARAM wParam, LPARAM lParam) {
1056 static const char *const colours[] = {
1057 "Default Foreground", "Default Bold Foreground",
1058 "Default Background", "Default Bold Background",
1059 "Cursor Text", "Cursor Colour",
1060 "ANSI Black", "ANSI Black Bold",
1061 "ANSI Red", "ANSI Red Bold",
1062 "ANSI Green", "ANSI Green Bold",
1063 "ANSI Yellow", "ANSI Yellow Bold",
1064 "ANSI Blue", "ANSI Blue Bold",
1065 "ANSI Magenta", "ANSI Magenta Bold",
1066 "ANSI Cyan", "ANSI Cyan Bold",
1067 "ANSI White", "ANSI White Bold"
1069 static const int permanent[] = {
1070 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
1071 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
1072 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
1076 CheckDlgButton (hwnd, IDC5_BOLDCOLOUR, cfg.bold_colour);
1077 CheckDlgButton (hwnd, IDC5_PALETTE, cfg.try_palette);
1080 for (i=0; i<22; i++)
1081 if (cfg.bold_colour || permanent[i])
1082 SendDlgItemMessage (hwnd, IDC5_LIST, LB_ADDSTRING, 0,
1083 (LPARAM) colours[i]);
1085 SendDlgItemMessage (hwnd, IDC5_LIST, LB_SETCURSEL, 0, 0);
1086 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[0][0], FALSE);
1087 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[0][1], FALSE);
1088 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[0][2], FALSE);
1091 switch (LOWORD(wParam)) {
1092 case IDC5_BOLDCOLOUR:
1093 if (HIWORD(wParam) == BN_CLICKED ||
1094 HIWORD(wParam) == BN_DOUBLECLICKED) {
1096 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC5_BOLDCOLOUR);
1097 n = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCOUNT, 0, 0);
1098 if (cfg.bold_colour && n!=22) {
1099 for (i=0; i<22; i++)
1101 SendDlgItemMessage (hwnd, IDC5_LIST,
1103 (LPARAM) colours[i]);
1104 } else if (!cfg.bold_colour && n!=12) {
1107 SendDlgItemMessage (hwnd, IDC5_LIST,
1108 LB_DELETESTRING, i, 0);
1113 if (HIWORD(wParam) == BN_CLICKED ||
1114 HIWORD(wParam) == BN_DOUBLECLICKED)
1115 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC5_PALETTE);
1118 if (HIWORD(wParam) == LBN_DBLCLK ||
1119 HIWORD(wParam) == LBN_SELCHANGE) {
1120 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1122 if (!cfg.bold_colour)
1123 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1124 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0], FALSE);
1125 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1], FALSE);
1126 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2], FALSE);
1130 if (HIWORD(wParam) == BN_CLICKED ||
1131 HIWORD(wParam) == BN_DOUBLECLICKED) {
1132 static CHOOSECOLOR cc;
1133 static DWORD custom[16] = {0}; /* zero initialisers */
1134 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1136 if (!cfg.bold_colour)
1137 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1138 cc.lStructSize = sizeof(cc);
1139 cc.hwndOwner = hwnd;
1140 cc.hInstance = (HWND)hinst;
1141 cc.lpCustColors = custom;
1142 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1144 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1145 if (ChooseColor(&cc)) {
1147 (unsigned char) (cc.rgbResult & 0xFF);
1149 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1151 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1152 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0],
1154 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1],
1156 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2],
1164 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1167 static int CALLBACK LanguageProc (HWND hwnd, UINT msg,
1168 WPARAM wParam, LPARAM lParam) {
1171 CheckRadioButton (hwnd, IDC6_NOXLAT, IDC6_88592WIN1250,
1172 cfg.xlat_88592w1250 ? IDC6_88592WIN1250 :
1173 cfg.xlat_enablekoiwin ? IDC6_KOI8WIN1251 :
1175 CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr);
1177 switch (LOWORD(wParam)) {
1179 case IDC6_KOI8WIN1251:
1180 case IDC6_88592WIN1250:
1181 cfg.xlat_enablekoiwin =
1182 IsDlgButtonChecked (hwnd, IDC6_KOI8WIN1251);
1183 cfg.xlat_88592w1250 =
1184 IsDlgButtonChecked (hwnd, IDC6_88592WIN1250);
1186 case IDC6_CAPSLOCKCYR:
1187 if (HIWORD(wParam) == BN_CLICKED ||
1188 HIWORD(wParam) == BN_DOUBLECLICKED) {
1189 cfg.xlat_capslockcyr =
1190 IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR);
1195 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1198 static DLGPROC panelproc[NPANELS] = {
1199 ConnectionProc, KeyboardProc, TerminalProc,
1200 TelnetProc, SshProc, SelectionProc, ColourProc, LanguageProc
1202 static char *panelids[NPANELS] = {
1203 MAKEINTRESOURCE(IDD_PANEL0),
1204 MAKEINTRESOURCE(IDD_PANEL1),
1205 MAKEINTRESOURCE(IDD_PANEL2),
1206 MAKEINTRESOURCE(IDD_PANEL3),
1207 MAKEINTRESOURCE(IDD_PANEL35),
1208 MAKEINTRESOURCE(IDD_PANEL4),
1209 MAKEINTRESOURCE(IDD_PANEL5),
1210 MAKEINTRESOURCE(IDD_PANEL6)
1213 static char *names[NPANELS] = {
1214 "Connection", "Keyboard", "Terminal", "Telnet",
1215 "SSH", "Selection", "Colours", "Language"
1218 static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7};
1219 static int reconfp[RECONF_NPANELS] = { 1, 2, 5, 6, 7};
1221 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1222 WPARAM wParam, LPARAM lParam,
1223 int npanels, int *panelnums, HWND *page) {
1228 { /* centre the window */
1231 hw = GetDesktopWindow();
1232 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1233 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1234 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1235 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1238 { /* initialise the tab control */
1242 hw = GetDlgItem (hwnd, IDC_TAB);
1243 for (i=0; i<npanels; i++) {
1244 tab.mask = TCIF_TEXT;
1245 tab.pszText = names[panelnums[i]];
1246 TabCtrl_InsertItem (hw, i, &tab);
1248 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1249 hwnd, panelproc[panelnums[0]]);*/
1250 *page = CreateDialog (hinst, panelids[panelnums[0]],
1251 hwnd, panelproc[panelnums[0]]);
1252 SetWindowLong (*page, GWL_EXSTYLE,
1253 GetWindowLong (*page, GWL_EXSTYLE) |
1254 WS_EX_CONTROLPARENT);
1259 if (LOWORD(wParam) == IDC_TAB &&
1260 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1261 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1263 DestroyWindow (*page);
1264 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1265 hwnd, panelproc[panelnums[i]]);*/
1266 *page = CreateDialog (hinst, panelids[panelnums[i]],
1267 hwnd, panelproc[panelnums[i]]);
1268 SetWindowLong (*page, GWL_EXSTYLE,
1269 GetWindowLong (*page, GWL_EXSTYLE) |
1270 WS_EX_CONTROLPARENT);
1271 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1275 /* case WM_CTLCOLORDLG: */
1276 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1278 switch (LOWORD(wParam)) {
1281 EndDialog (hwnd, 1);
1286 EndDialog (hwnd, 0);
1291 EndDialog (hwnd, 0);
1297 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1298 WPARAM wParam, LPARAM lParam) {
1303 static HWND page = NULL;
1305 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1308 * If the Connection panel is active and the Session List
1309 * box is selected, we treat a press of Open to have an
1310 * implicit press of Load preceding it.
1312 hw = GetDlgItem (hwnd, IDC_TAB);
1313 i = TabCtrl_GetCurSel(hw);
1314 if (panelproc[mainp[i]] == ConnectionProc &&
1315 page && implicit_load_ok) {
1316 SendMessage (page, WM_COMMAND,
1317 MAKELONG(IDC0_SESSLOAD, BN_CLICKED), 0);
1321 if (msg == WM_COMMAND && LOWORD(wParam) == IDC_ABOUT) {
1322 EnableWindow(hwnd, 0);
1323 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1324 GetParent(hwnd), AboutProc);
1325 EnableWindow(hwnd, 1);
1327 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1328 MAIN_NPANELS, mainp, &page);
1331 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1332 WPARAM wParam, LPARAM lParam) {
1334 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1335 RECONF_NPANELS, reconfp, &page);
1338 void get_sesslist(int allocate) {
1339 static char *buffer;
1340 int buflen, bufsize, i, ret;
1341 char otherbuf[2048];
1346 if (RegCreateKey(HKEY_CURRENT_USER,
1347 puttystr, &subkey1) != ERROR_SUCCESS)
1350 buflen = bufsize = 0;
1354 ret = RegEnumKey(subkey1, i++, otherbuf, sizeof(otherbuf));
1355 if (ret == ERROR_SUCCESS) {
1356 bufsize = buflen + 2048;
1357 buffer = srealloc(buffer, bufsize);
1358 unmungestr(otherbuf, buffer+buflen);
1359 buflen += strlen(buffer+buflen)+1;
1361 } while (ret == ERROR_SUCCESS);
1362 buffer = srealloc(buffer, buflen+1);
1363 buffer[buflen] = '\0';
1366 nsessions = 1; /* "Default Settings" counts as one */
1368 if (strcmp(p, "Default Settings"))
1374 sessions = smalloc(nsessions * sizeof(char *));
1375 sessions[0] = "Default Settings";
1379 if (strcmp(p, "Default Settings"))
1390 int do_config (void) {
1394 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1395 get_sesslist(FALSE);
1400 int do_reconfig (HWND hwnd) {
1404 backup_cfg = cfg; /* structure copy */
1405 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1407 cfg = backup_cfg; /* structure copy */
1411 void do_defaults (char *session) {
1413 load_settings (session, TRUE);
1415 load_settings ("Default Settings", FALSE);
1418 void logevent (char *string) {
1419 if (nevents >= negsize) {
1421 events = srealloc (events, negsize * sizeof(*events));
1423 events[nevents] = smalloc(1+strlen(string));
1424 strcpy (events[nevents], string);
1427 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1431 void showeventlog (HWND hwnd) {
1433 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1435 ShowWindow (logbox, SW_SHOWNORMAL);
1439 void showabout (HWND hwnd) {
1441 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1443 ShowWindow (abtbox, SW_SHOWNORMAL);
1447 void verify_ssh_host_key(char *host, char *keystr) {
1448 char *otherstr, *mungedhost;
1452 len = 1 + strlen(keystr);
1455 * Now read a saved key in from the registry and see what it
1458 otherstr = malloc(len);
1459 mungedhost = malloc(3*strlen(host)+1);
1460 if (!otherstr || !mungedhost)
1461 fatalbox("Out of memory");
1463 mungestr(host, mungedhost);
1465 if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",
1466 &rkey) != ERROR_SUCCESS) {
1467 if (MessageBox(NULL, "PuTTY was unable to open the host key cache\n"
1468 "in the registry. There is thus no way to tell\n"
1469 "if the remote host is what you think it is.\n"
1470 "Connect anyway?", "PuTTY Problem",
1471 MB_ICONWARNING | MB_YESNO) == IDNO)
1474 DWORD readlen = len;
1478 ret = RegQueryValueEx(rkey, mungedhost, NULL,
1479 &type, otherstr, &readlen);
1481 if (ret == ERROR_MORE_DATA ||
1482 (ret == ERROR_SUCCESS && type == REG_SZ &&
1483 strcmp(otherstr, keystr))) {
1484 if (MessageBox(NULL,
1485 "This host's host key is different from the\n"
1486 "one cached in the registry! Someone may be\n"
1487 "impersonating this host for malicious reasons;\n"
1488 "alternatively, the host key may have changed\n"
1489 "due to sloppy system administration.\n"
1490 "Replace key in registry and connect?",
1491 "PuTTY: Security Warning",
1492 MB_ICONWARNING | MB_YESNO) == IDNO)
1494 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,
1496 } else if (ret != ERROR_SUCCESS || type != REG_SZ) {
1497 if (MessageBox(NULL,
1498 "This host's host key is not cached in the\n"
1499 "registry. Do you want to add it to the cache\n"
1500 "and carry on connecting?",
1502 MB_ICONWARNING | MB_YESNO) == IDNO)
1504 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,