Fix a potential vulnerability in incoming `pscp -r'. The server
[u/mdw/putty] / window.c
index bb43636..7db845e 100644 (file)
--- a/window.c
+++ b/window.c
@@ -14,6 +14,7 @@
 
 #define PUTTY_DO_GLOBALS                      /* actually _define_ globals */
 #include "putty.h"
+#include "winstuff.h"
 #include "storage.h"
 #include "win_res.h"
 
 #define WM_IGNORE_SIZE (WM_XUSER + 1)
 #define WM_IGNORE_CLIP (WM_XUSER + 2)
 
+/* Needed for Chinese support and apparently not always defined. */
+#ifndef VK_PROCESSKEY
+#define VK_PROCESSKEY 0xE5
+#endif
+
 static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
 static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned char *output);
 static void cfgtopalette(void);
@@ -107,7 +113,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
     MSG msg;
     int guess_width, guess_height;
 
-    putty_inst = inst;
+    hinst = inst;
     flags = FLAG_VERBOSE | FLAG_INTERACTIVE;
 
     winsock_ver = MAKEWORD(1, 1);
@@ -197,6 +203,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
         * An initial @ means to activate a saved session.
         */
        if (*p == '@') {
+           int i = strlen(p);
+           while (i > 1 && isspace(p[i-1]))
+               i--;
+           p[i] = '\0';
            do_defaults (p+1, &cfg);
            if (!*cfg.host && !do_config()) {
                WSACleanup();
@@ -352,14 +362,14 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
     }
 
     {
-       int winmode = WS_OVERLAPPEDWINDOW|WS_VSCROLL;
-       if (!cfg.scrollbar) winmode &= ~(WS_VSCROLL);
-       if (cfg.locksize)   winmode &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX);
-       hwnd = CreateWindow (appname, appname,
-                           winmode,
-                           CW_USEDEFAULT, CW_USEDEFAULT,
-                           guess_width, guess_height,
-                           NULL, NULL, inst, NULL);
+       int winmode = WS_OVERLAPPEDWINDOW|WS_VSCROLL;
+       if (!cfg.scrollbar) winmode &= ~(WS_VSCROLL);
+       if (cfg.locksize)   winmode &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX);
+       hwnd = CreateWindow (appname, appname,
+                            winmode,
+                            CW_USEDEFAULT, CW_USEDEFAULT,
+                            guess_width, guess_height,
+                            NULL, NULL, inst, NULL);
     }
 
     /*
@@ -1483,12 +1493,29 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
            unsigned char buf[20];
            int len;
 
-           len = TranslateKey (message, wParam, lParam, buf);
-           if (len == -1)
-               return DefWindowProc (hwnd, message, wParam, lParam);
-           ldisc->send (buf, len);
+            if (wParam==VK_PROCESSKEY) {
+               MSG m;
+                m.hwnd = hwnd;
+                m.message = WM_KEYDOWN;
+                m.wParam = wParam;
+                m.lParam = lParam & 0xdfff;
+                TranslateMessage(&m);
+            } else {
+               len = TranslateKey (message, wParam, lParam, buf);
+               if (len == -1)
+                   return DefWindowProc (hwnd, message, wParam, lParam);
+               ldisc->send (buf, len);
+           }
        }
        return 0;
+      case WM_IME_CHAR:
+       {
+           unsigned char buf[2];
+
+           buf[1] = wParam;
+           buf[0] = wParam >> 8;
+           ldisc->send (buf, 2);
+       }
       case WM_CHAR:
       case WM_SYSCHAR:
        /*
@@ -1743,15 +1770,6 @@ static int check_compose(int first, int second) {
     static int recurse = 0;
     int nc = -1;
 
-    if(0)
-    {
-       char buf[256];
-       char * p;
-       sprintf(buf, "cc(%d,%d)", first, second);
-       for(p=buf; *p; p++)
-           c_write1(*p);
-    }
-
     for(c=composetbl; *c; c++) {
        if( (*c)[0] == first && (*c)[1] == second)
        {
@@ -1778,7 +1796,8 @@ static int check_compose(int first, int second) {
  * codes. Returns number of bytes used or zero to drop the message
  * or -1 to forward the message to windows.
  */
-static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned char *output) {
+static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
+                       unsigned char *output) {
     BYTE keystate[256];
     int  scan, left_alt = 0, key_down, shift_state;
     int  r, i, code;
@@ -1851,25 +1870,28 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned cha
 #endif
 
        /* Note if AltGr was pressed and if it was used as a compose key */
-       if (wParam == VK_MENU && (HIWORD(lParam)&KF_EXTENDED))
-       {
-           keystate[VK_RMENU] = keystate[VK_MENU];
-           if (!compose_state) compose_key = wParam;
-       }
-       if (wParam == VK_APPS && !compose_state)
-           compose_key = wParam;
+       if (cfg.compose_key) {
+           if (wParam == VK_MENU && (HIWORD(lParam)&KF_EXTENDED))
+           {
+               keystate[VK_RMENU] = keystate[VK_MENU];
+               if (!compose_state) compose_key = wParam;
+           }
+           if (wParam == VK_APPS && !compose_state)
+               compose_key = wParam;
 
-       if (wParam == compose_key)
-       {
-            if (compose_state == 0 && (HIWORD(lParam)&(KF_UP|KF_REPEAT))==0)
-              compose_state = 1;
-           else if (compose_state == 1 && (HIWORD(lParam)&KF_UP))
-              compose_state = 2;
-           else
-              compose_state = 0;
-       }
-       else if (compose_state==1 && wParam != VK_CONTROL)
-          compose_state = 0;
+           if (wParam == compose_key)
+           {
+               if (compose_state == 0 && (HIWORD(lParam)&(KF_UP|KF_REPEAT))==0)
+                   compose_state = 1;
+               else if (compose_state == 1 && (HIWORD(lParam)&KF_UP))
+                   compose_state = 2;
+               else
+                   compose_state = 0;
+           }
+           else if (compose_state==1 && wParam != VK_CONTROL)
+               compose_state = 0;
+       } else
+           compose_state = 0;
 
        /* Nastyness with NUMLock - Shift-NUMLock is left alone though */
        if ( (cfg.funky_type == 3 || (cfg.funky_type <= 1 && app_keypad_keys))
@@ -2214,7 +2236,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned cha
 
                    if ((nc=check_compose(compose_char,ch)) == -1)
                    {
-                       c_write1('\007');
+                       MessageBeep(MB_ICONHAND);
                        return 0;
                    }
                    *p++ = xlat_kbd2tty((unsigned char)nc);
@@ -2242,8 +2264,10 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned cha
     }
 
     /* This stops ALT press-release doing a 'COMMAND MENU' function */
-    if (message == WM_SYSKEYUP && wParam == VK_MENU) 
-       return 0;
+    if (!cfg.alt_only) {
+       if (message == WM_SYSKEYUP && wParam == VK_MENU) 
+           return 0;
+    }
 
     return -1;
 }