X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=windows%2Fwindow.c;h=baed768f10a4c4ae5d181bdf4bd1535ea97c4521;hb=0f5299e5a86e87068277b19c008ff5eb0f78d022;hp=04059f064a4cbd721ef57a104af5e94a77d3bac5;hpb=c269dd0135a927d4d22a334cfefb09361f311fcd;p=PuTTY.git diff --git a/windows/window.c b/windows/window.c index 04059f06..baed768f 100644 --- a/windows/window.c +++ b/windows/window.c @@ -19,6 +19,7 @@ #include "terminal.h" #include "storage.h" #include "win_res.h" +#include "winsecur.h" #ifndef NO_MULTIMON #include @@ -76,6 +77,11 @@ #define WHEEL_DELTA 120 #endif +/* VK_PACKET, used to send Unicode characters in WM_KEYDOWNs */ +#ifndef VK_PACKET +#define VK_PACKET 0xE7 +#endif + static Mouse_Button translate_button(Mouse_Button button); static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, @@ -332,7 +338,6 @@ static void close_session(void *ignored_context) int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { - WNDCLASS wndclass; MSG msg; HRESULT hr; int guess_width, guess_height; @@ -386,6 +391,19 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) return 1; } + /* + * Protect our process + */ + { +#ifndef UNPROTECT + char *error = NULL; + if (! setprocessacl(error)) { + logevent(NULL, "Could not restrict process ACL: %s", + error); + sfree(error); + } +#endif + } /* * Process the command line. */ @@ -645,6 +663,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) } if (!prev) { + WNDCLASSW wndclass; + wndclass.style = 0; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; @@ -654,9 +674,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM); wndclass.hbrBackground = NULL; wndclass.lpszMenuName = NULL; - wndclass.lpszClassName = appname; + wndclass.lpszClassName = dup_mb_to_wc(DEFAULT_CODEPAGE, 0, appname); - RegisterClass(&wndclass); + RegisterClassW(&wndclass); } memset(&ucsdata, 0, sizeof(ucsdata)); @@ -690,6 +710,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { int winmode = WS_OVERLAPPEDWINDOW | WS_VSCROLL; int exwinmode = 0; + wchar_t *uappname = dup_mb_to_wc(DEFAULT_CODEPAGE, 0, appname); if (!conf_get_int(conf, CONF_scrollbar)) winmode &= ~(WS_VSCROLL); if (conf_get_int(conf, CONF_resize_action) == RESIZE_DISABLED) @@ -698,10 +719,11 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) exwinmode |= WS_EX_TOPMOST; if (conf_get_int(conf, CONF_sunken_edge)) exwinmode |= WS_EX_CLIENTEDGE; - hwnd = CreateWindowEx(exwinmode, appname, appname, - winmode, CW_USEDEFAULT, CW_USEDEFAULT, - guess_width, guess_height, - NULL, NULL, inst, NULL); + hwnd = CreateWindowExW(exwinmode, uappname, uappname, + winmode, CW_USEDEFAULT, CW_USEDEFAULT, + guess_width, guess_height, + NULL, NULL, inst, NULL); + sfree(uappname); } /* @@ -888,12 +910,34 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) } else sfree(handles); - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) goto finished; /* two-level break */ if (!(IsWindow(logbox) && IsDialogMessage(logbox, &msg))) - DispatchMessage(&msg); + DispatchMessageW(&msg); + + /* + * WM_NETEVENT messages seem to jump ahead of others in + * the message queue. I'm not sure why; the docs for + * PeekMessage mention that messages are prioritised in + * some way, but I'm unclear on which priorities go where. + * + * Anyway, in practice I observe that WM_NETEVENT seems to + * jump to the head of the queue, which means that if we + * were to only process one message every time round this + * loop, we'd get nothing but NETEVENTs if the server + * flooded us with data, and stop responding to any other + * kind of window message. So instead, we keep on round + * this loop until we've consumed at least one message + * that _isn't_ a NETEVENT, or run out of messages + * completely (whichever comes first). And we don't go to + * run_toplevel_callbacks (which is where the netevents + * are actually processed, causing fresh NETEVENT messages + * to appear) until we've done this. + */ + if (msg.message != WM_NETEVENT) + break; } run_toplevel_callbacks(); @@ -1104,7 +1148,7 @@ void set_raw_mouse_mode(void *frontend, int activate) /* * Print a message box and close the connection. */ -void connection_fatal(void *frontend, char *fmt, ...) +void connection_fatal(void *frontend, const char *fmt, ...) { va_list ap; char *stuff, morestuff[100]; @@ -1126,7 +1170,7 @@ void connection_fatal(void *frontend, char *fmt, ...) /* * Report an error at the command-line parsing stage. */ -void cmdline_error(char *fmt, ...) +void cmdline_error(const char *fmt, ...) { va_list ap; char *stuff, morestuff[100]; @@ -2143,7 +2187,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, unsigned int sessno = ((lParam - IDM_SAVED_MIN) / MENU_SAVED_STEP) + 1; if (sessno < (unsigned)sesslist.nsessions) { - char *session = sesslist.sessions[sessno]; + const char *session = sesslist.sessions[sessno]; cl = dupprintf("putty @%s", session); inherit_handles = FALSE; freecl = TRUE; @@ -3061,7 +3105,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, unsigned char buf[20]; int len; - if (wParam == VK_PROCESSKEY) { /* IME PROCESS key */ + if (wParam == VK_PROCESSKEY || /* IME PROCESS key */ + wParam == VK_PACKET) { /* 'this key is a Unicode char' */ if (message == WM_KEYDOWN) { MSG m; m.hwnd = hwnd; @@ -3073,7 +3118,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, } else { len = TranslateKey(message, wParam, lParam, buf); if (len == -1) - return DefWindowProc(hwnd, message, wParam, lParam); + return DefWindowProcW(hwnd, message, wParam, lParam); if (len != 0) { /* @@ -3177,10 +3222,21 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, * we're ready to cope. */ { - char c = (unsigned char)wParam; - term_seen_key_event(term); - if (ldisc) - lpage_send(ldisc, CP_ACP, &c, 1, 1); + static wchar_t pending_surrogate = 0; + wchar_t c = wParam; + + if (IS_HIGH_SURROGATE(c)) { + pending_surrogate = c; + } else if (IS_SURROGATE_PAIR(pending_surrogate, c)) { + wchar_t pair[2]; + pair[0] = pending_surrogate; + pair[1] = c; + term_seen_key_event(term); + luni_send(ldisc, pair, 2, 1); + } else if (!IS_SURROGATE(c)) { + term_seen_key_event(term); + luni_send(ldisc, &c, 1, 1); + } } return 0; case WM_SYSCOLORCHANGE: @@ -3265,7 +3321,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, * Any messages we don't process completely above are passed through to * DefWindowProc() for default processing. */ - return DefWindowProc(hwnd, message, wParam, lParam); + return DefWindowProcW(hwnd, message, wParam, lParam); } /* @@ -5323,7 +5379,7 @@ void optimised_move(void *frontend, int to, int from, int lines) /* * Print a message box and perform a fatal exit. */ -void fatalbox(char *fmt, ...) +void fatalbox(const char *fmt, ...) { va_list ap; char *stuff, morestuff[100]; @@ -5340,7 +5396,7 @@ void fatalbox(char *fmt, ...) /* * Print a modal (Really Bad) message box and perform a fatal exit. */ -void modalfatalbox(char *fmt, ...) +void modalfatalbox(const char *fmt, ...) { va_list ap; char *stuff, morestuff[100]; @@ -5358,7 +5414,7 @@ void modalfatalbox(char *fmt, ...) /* * Print a message box and don't close the connection. */ -void nonfatal(char *fmt, ...) +void nonfatal(const char *fmt, ...) { va_list ap; char *stuff, morestuff[100]; @@ -5765,7 +5821,7 @@ int from_backend_eof(void *frontend) return TRUE; /* do respond to incoming EOF with outgoing */ } -int get_userpass_input(prompts_t *p, unsigned char *in, int inlen) +int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen) { int ret; ret = cmdline_get_passwd_input(p, in, inlen);