X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/9a30e26b7801d63e4ccfe8d36169299c09b89dff..7bd029472d96162f71f61df67baedc00fc0bb1a8:/window.c diff --git a/window.c b/window.c index effa2deb..3c3cdb68 100644 --- a/window.c +++ b/window.c @@ -37,19 +37,6 @@ #define IDM_RECONF 0x0040 #define IDM_CLRSB 0x0050 #define IDM_RESET 0x0060 -#define IDM_TEL_AYT 0x0070 -#define IDM_TEL_BRK 0x0080 -#define IDM_TEL_SYNCH 0x0090 -#define IDM_TEL_EC 0x00a0 -#define IDM_TEL_EL 0x00b0 -#define IDM_TEL_GA 0x00c0 -#define IDM_TEL_NOP 0x00d0 -#define IDM_TEL_ABORT 0x00e0 -#define IDM_TEL_AO 0x00f0 -#define IDM_TEL_IP 0x0100 -#define IDM_TEL_SUSP 0x0110 -#define IDM_TEL_EOR 0x0120 -#define IDM_TEL_EOF 0x0130 #define IDM_HELP 0x0140 #define IDM_ABOUT 0x0150 #define IDM_SAVEDSESS 0x0160 @@ -59,6 +46,10 @@ #define IDM_SESSLGP 0x0250 /* log type printable */ #define IDM_SESSLGA 0x0260 /* log type all chars */ #define IDM_SESSLGE 0x0270 /* log end */ + +#define IDM_SPECIAL_MIN 0x0400 +#define IDM_SPECIAL_MAX 0x0800 + #define IDM_SAVED_MIN 0x1000 #define IDM_SAVED_MAX 0x2000 @@ -124,6 +115,9 @@ static void *backhandle; static struct unicode_data ucsdata; static int session_closed; +static const struct telnet_special *specials; +static int specials_menu_position; + Config cfg; /* exported to windlg.c */ extern struct sesslist sesslist; /* imported from windlg.c */ @@ -188,7 +182,6 @@ void ldisc_update(void *frontend, int echo, int edit) int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { - static char appname[] = "PuTTY"; WORD winsock_ver; WSADATA wsadata; WNDCLASS wndclass; @@ -224,8 +217,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) ZeroMemory(&osVersion, sizeof(osVersion)); osVersion.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (!GetVersionEx ( (OSVERSIONINFO *) &osVersion)) { + char *str = dupprintf("%s Fatal Error", appname); MessageBox(NULL, "Windows refuses to report a version", - "PuTTY Fatal Error", MB_OK | MB_ICONEXCLAMATION); + str, MB_OK | MB_ICONEXCLAMATION); + sfree(str); return 1; } } @@ -356,18 +351,21 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) * entries associated with PuTTY, and also find * and delete the random seed file. */ - if (MessageBox(NULL, - "This procedure will remove ALL Registry\n" - "entries associated with PuTTY, and will\n" - "also remove the PuTTY random seed file.\n" + char *s1, *s2; + s1 = dupprintf("This procedure will remove ALL Registry\n" + "entries associated with %s, and will\n" + "also remove the random seed file.\n" "\n" "THIS PROCESS WILL DESTROY YOUR SAVED\n" "SESSIONS. Are you really sure you want\n" - "to continue?", - "PuTTY Warning", + "to continue?", appname); + s2 = dupprintf("%s Warning", appname); + if (MessageBox(NULL, s1, s2, MB_YESNO | MB_ICONWARNING) == IDYES) { cleanup_all(); } + sfree(s1); + sfree(s2); exit(0); } else if (*p != '-') { char *q = p; @@ -487,8 +485,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) break; } if (back == NULL) { + char *str = dupprintf("%s Internal Error", appname); MessageBox(NULL, "Unsupported protocol number found", - "PuTTY Internal Error", MB_OK | MB_ICONEXCLAMATION); + str, MB_OK | MB_ICONEXCLAMATION); + sfree(str); WSACleanup(); return 1; } @@ -496,8 +496,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) /* Check for invalid Port number (i.e. zero) */ if (cfg.port == 0) { + char *str = dupprintf("%s Internal Error", appname); MessageBox(NULL, "Invalid Port Number", - "PuTTY Internal Error", MB_OK | MB_ICONEXCLAMATION); + str, MB_OK | MB_ICONEXCLAMATION); + sfree(str); WSACleanup(); return 1; } @@ -600,7 +602,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { char *bits; int size = (font_width + 15) / 16 * 2 * font_height; - bits = smalloc(size); + bits = snewn(size, char); memset(bits, 0, size); caretbm = CreateBitmap(font_width, font_height, 1, 1, bits); sfree(bits); @@ -630,20 +632,22 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) char msg[1024], *title; char *realhost; - error = back->init((void *)term, &backhandle, &cfg, + error = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost, cfg.tcp_nodelay); back->provide_logctx(backhandle, logctx); if (error) { + char *str = dupprintf("%s Error", appname); sprintf(msg, "Unable to open connection to\n" "%.800s\n" "%s", cfg.host, error); - MessageBox(NULL, msg, "PuTTY Error", MB_ICONERROR | MB_OK); + MessageBox(NULL, msg, str, MB_ICONERROR | MB_OK); + sfree(str); return 0; } window_name = icon_name = NULL; if (*cfg.wintitle) { title = cfg.wintitle; } else { - sprintf(msg, "%s - PuTTY", realhost); + sprintf(msg, "%s - %s", realhost, appname); title = msg; } sfree(realhost); @@ -675,32 +679,12 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) */ { HMENU m = GetSystemMenu(hwnd, FALSE); - HMENU p, s; + HMENU s; int i; + char *str; AppendMenu(m, MF_SEPARATOR, 0, 0); - if (cfg.protocol == PROT_TELNET) { - p = CreateMenu(); - AppendMenu(p, MF_ENABLED, IDM_TEL_AYT, "Are You There"); - AppendMenu(p, MF_ENABLED, IDM_TEL_BRK, "Break"); - AppendMenu(p, MF_ENABLED, IDM_TEL_SYNCH, "Synch"); - AppendMenu(p, MF_SEPARATOR, 0, 0); - AppendMenu(p, MF_ENABLED, IDM_TEL_EC, "Erase Character"); - AppendMenu(p, MF_ENABLED, IDM_TEL_EL, "Erase Line"); - AppendMenu(p, MF_ENABLED, IDM_TEL_GA, "Go Ahead"); - AppendMenu(p, MF_ENABLED, IDM_TEL_NOP, "No Operation"); - AppendMenu(p, MF_SEPARATOR, 0, 0); - AppendMenu(p, MF_ENABLED, IDM_TEL_ABORT, "Abort Process"); - AppendMenu(p, MF_ENABLED, IDM_TEL_AO, "Abort Output"); - AppendMenu(p, MF_ENABLED, IDM_TEL_IP, "Interrupt Process"); - AppendMenu(p, MF_ENABLED, IDM_TEL_SUSP, "Suspend Process"); - AppendMenu(p, MF_SEPARATOR, 0, 0); - AppendMenu(p, MF_ENABLED, IDM_TEL_EOR, "End Of Record"); - AppendMenu(p, MF_ENABLED, IDM_TEL_EOF, "End Of File"); - AppendMenu(m, MF_POPUP | MF_ENABLED, (UINT) p, - "Telnet Command"); - AppendMenu(m, MF_SEPARATOR, 0, 0); - } + specials_menu_position = GetMenuItemCount(m); AppendMenu(m, MF_ENABLED, IDM_SHOWLOG, "&Event Log"); AppendMenu(m, MF_SEPARATOR, 0, 0); AppendMenu(m, MF_ENABLED, IDM_NEWSESS, "Ne&w Session..."); @@ -724,9 +708,13 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) AppendMenu(m, MF_SEPARATOR, 0, 0); if (help_path) AppendMenu(m, MF_ENABLED, IDM_HELP, "&Help"); - AppendMenu(m, MF_ENABLED, IDM_ABOUT, "&About PuTTY"); + str = dupprintf("&About %s", appname); + AppendMenu(m, MF_ENABLED, IDM_ABOUT, str); + sfree(str); } + update_specials_menu(NULL); + /* * Set up the initial input locale. */ @@ -788,9 +776,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) if (pending_netevent) { enact_pending_netevent(); - /* Force the cursor blink on */ - term_blink(term, 1); - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) continue; } @@ -891,6 +876,37 @@ char *do_select(SOCKET skt, int startup) } /* + * Update the Special Commands submenu. + */ +void update_specials_menu(void *frontend) +{ + HMENU m = GetSystemMenu(hwnd, FALSE); + int menu_already_exists = (specials != NULL); + int i; + + specials = back->get_specials(backhandle); + if (specials) { + HMENU p = CreateMenu(); + for (i = 0; specials[i].name; i++) { + assert(IDM_SPECIAL_MIN + 0x10 * i < IDM_SPECIAL_MAX); + if (*specials[i].name) + AppendMenu(p, MF_ENABLED, IDM_SPECIAL_MIN + 0x10 * i, + specials[i].name); + else + AppendMenu(p, MF_SEPARATOR, 0, 0); + } + if (menu_already_exists) + DeleteMenu(m, specials_menu_position, MF_BYPOSITION); + else + InsertMenu(m, specials_menu_position, + MF_BYPOSITION | MF_SEPARATOR, 0, 0); + InsertMenu(m, specials_menu_position, + MF_BYPOSITION | MF_POPUP | MF_ENABLED, + (UINT) p, "Special Command"); + } +} + +/* * set or clear the "raw mouse message" mode */ void set_raw_mouse_mode(void *frontend, int activate) @@ -906,18 +922,20 @@ void set_raw_mouse_mode(void *frontend, int activate) void connection_fatal(void *frontend, char *fmt, ...) { va_list ap; - char stuff[200]; + char stuff[200], morestuff[100]; va_start(ap, fmt); vsprintf(stuff, fmt, ap); va_end(ap); - MessageBox(hwnd, stuff, "PuTTY Fatal Error", MB_ICONERROR | MB_OK); + sprintf(morestuff, "%.70s Fatal Error", appname); + MessageBox(hwnd, stuff, morestuff, MB_ICONERROR | MB_OK); if (cfg.close_on_exit == FORCE_ON) PostQuitMessage(1); else { session_closed = TRUE; - set_icon(NULL, "PuTTY (inactive)"); - set_title(NULL, "PuTTY (inactive)"); + sprintf(morestuff, "%.70s (inactive)", appname); + set_icon(NULL, morestuff); + set_title(NULL, morestuff); } } @@ -927,12 +945,13 @@ void connection_fatal(void *frontend, char *fmt, ...) void cmdline_error(char *fmt, ...) { va_list ap; - char stuff[200]; + char stuff[200], morestuff[100]; va_start(ap, fmt); vsprintf(stuff, fmt, ap); va_end(ap); - MessageBox(hwnd, stuff, "PuTTY Command Line Error", MB_ICONERROR | MB_OK); + sprintf(morestuff, "%.70s Command Line Error", appname); + MessageBox(hwnd, stuff, morestuff, MB_ICONERROR | MB_OK); exit(1); } @@ -960,11 +979,13 @@ static void enact_pending_netevent(void) if (cfg.close_on_exit == FORCE_ON || cfg.close_on_exit == AUTO) PostQuitMessage(0); else { + char morestuff[100]; session_closed = TRUE; - set_icon(NULL, "PuTTY (inactive)"); - set_title(NULL, "PuTTY (inactive)"); + sprintf(morestuff, "%.70s (inactive)", appname); + set_icon(NULL, morestuff); + set_title(NULL, morestuff); MessageBox(hwnd, "Connection closed by remote host", - "PuTTY", MB_OK | MB_ICONINFORMATION); + appname, MB_OK | MB_ICONINFORMATION); } } } @@ -999,6 +1020,10 @@ static void init_palette(void) HDC hdc = GetDC(hwnd); if (hdc) { if (cfg.try_palette && GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) { + /* + * This is a genuine case where we must use smalloc + * because the snew macros can't cope. + */ logpal = smalloc(sizeof(*logpal) - sizeof(logpal->palPalEntry) + NCOLOURS * sizeof(PALETTEENTRY)); @@ -1665,13 +1690,17 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, case WM_CREATE: break; case WM_CLOSE: - show_mouseptr(1); - if (!cfg.warn_on_close || session_closed || - MessageBox(hwnd, - "Are you sure you want to close this session?", - "PuTTY Exit Confirmation", - MB_ICONWARNING | MB_OKCANCEL) == IDOK) - DestroyWindow(hwnd); + { + char *str; + show_mouseptr(1); + str = dupprintf("%s Exit Confirmation", appname); + if (!cfg.warn_on_close || session_closed || + MessageBox(hwnd, + "Are you sure you want to close this session?", + str, MB_ICONWARNING | MB_OKCANCEL) == IDOK) + DestroyWindow(hwnd); + sfree(str); + } return 0; case WM_DESTROY: show_mouseptr(1); @@ -1723,7 +1752,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, if ((lParam - IDM_SAVED_MIN) / 16 < sesslist.nsessions) { char *session = sesslist.sessions[(lParam - IDM_SAVED_MIN) / 16]; - cl = smalloc(16 + strlen(session)); + cl = snewn(16 + strlen(session), char); /* 8, but play safe */ if (!cl) cl = NULL; @@ -1905,58 +1934,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, term_pwron(term); ldisc_send(ldisc, NULL, 0, 0); break; - case IDM_TEL_AYT: - back->special(backhandle, TS_AYT); - net_pending_errors(); - break; - case IDM_TEL_BRK: - back->special(backhandle, TS_BRK); - net_pending_errors(); - break; - case IDM_TEL_SYNCH: - back->special(backhandle, TS_SYNCH); - net_pending_errors(); - break; - case IDM_TEL_EC: - back->special(backhandle, TS_EC); - net_pending_errors(); - break; - case IDM_TEL_EL: - back->special(backhandle, TS_EL); - net_pending_errors(); - break; - case IDM_TEL_GA: - back->special(backhandle, TS_GA); - net_pending_errors(); - break; - case IDM_TEL_NOP: - back->special(backhandle, TS_NOP); - net_pending_errors(); - break; - case IDM_TEL_ABORT: - back->special(backhandle, TS_ABORT); - net_pending_errors(); - break; - case IDM_TEL_AO: - back->special(backhandle, TS_AO); - net_pending_errors(); - break; - case IDM_TEL_IP: - back->special(backhandle, TS_IP); - net_pending_errors(); - break; - case IDM_TEL_SUSP: - back->special(backhandle, TS_SUSP); - net_pending_errors(); - break; - case IDM_TEL_EOR: - back->special(backhandle, TS_EOR); - net_pending_errors(); - break; - case IDM_TEL_EOF: - back->special(backhandle, TS_EOF); - net_pending_errors(); - break; case IDM_ABOUT: showabout(hwnd); break; @@ -1991,6 +1968,22 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, if (wParam >= IDM_SAVED_MIN && wParam <= IDM_SAVED_MAX) { SendMessage(hwnd, WM_SYSCOMMAND, IDM_SAVEDSESS, wParam); } + if (wParam >= IDM_SPECIAL_MIN && wParam <= IDM_SPECIAL_MAX) { + int i = (wParam - IDM_SPECIAL_MIN) / 0x10; + int j; + /* + * Ensure we haven't been sent a bogus SYSCOMMAND + * which would cause us to reference invalid memory + * and crash. Perhaps I'm just too paranoid here. + */ + for (j = 0; j < i; j++) + if (!specials || !specials[j].name) + break; + if (j == i) { + back->special(backhandle, specials[i].code); + net_pending_errors(); + } + } } break; @@ -2531,7 +2524,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, if (n > 0) { int i; - buff = (char*) smalloc(n); + buff = snewn(n, char); ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buff, n); /* * Jaeyoun Chung reports that Korean character @@ -2719,7 +2712,7 @@ void do_text(Context ctx, int x, int y, char *text, int len, int i; if (len > IpDxLEN) { sfree(IpDx); - IpDx = smalloc((len + 16) * sizeof(int)); + IpDx = snewn(len + 16, int); IpDxLEN = (len + 16); } for (i = 0; i < IpDxLEN; i++) @@ -2850,7 +2843,8 @@ void do_text(Context ctx, int x, int y, char *text, int len, int nlen, mptr; if (len > uni_len) { sfree(uni_buf); - uni_buf = smalloc((uni_len = len) * sizeof(wchar_t)); + uni_len = len; + uni_buf = snewn(uni_len, wchar_t); } for(nlen = mptr = 0; mptr