Added support for inter-process GetWindowWord.
Do better range checking on the window extra bytes.

diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 575c2a7..40ce933 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -2605,6 +2605,7 @@
     void*          instance;
     void*          user_data;
     int            extra_offset;
+    size_t         extra_size;
     unsigned int   extra_value;
 };
 struct set_window_info_reply
@@ -2622,8 +2623,7 @@
 #define SET_WIN_ID        0x04
 #define SET_WIN_INSTANCE  0x08
 #define SET_WIN_USERDATA  0x10
-#define SET_WIN_EXTRAWORD 0x20
-#define SET_WIN_EXTRALONG 0x40
+#define SET_WIN_EXTRA     0x20
 
 
 
@@ -3673,6 +3673,6 @@
     struct set_global_windows_reply set_global_windows_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 127
+#define SERVER_PROTOCOL_VERSION 128
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index 69004f7..c9d4df9 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1834,6 +1834,7 @@
     void*          instance;      /* creator instance */
     void*          user_data;     /* user-specific data */
     int            extra_offset;  /* offset to set in extra bytes */
+    size_t         extra_size;    /* size to set in extra bytes */
     unsigned int   extra_value;   /* value to set in extra bytes */
 @REPLY
     unsigned int   old_style;     /* old window style */
@@ -1848,8 +1849,7 @@
 #define SET_WIN_ID        0x04
 #define SET_WIN_INSTANCE  0x08
 #define SET_WIN_USERDATA  0x10
-#define SET_WIN_EXTRAWORD 0x20
-#define SET_WIN_EXTRALONG 0x40
+#define SET_WIN_EXTRA     0x20
 
 
 /* Get a list of the window parents, up to the root of the tree */
diff --git a/server/trace.c b/server/trace.c
index a73d34c..9cd0650 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2157,6 +2157,7 @@
     fprintf( stderr, " instance=%p,", req->instance );
     fprintf( stderr, " user_data=%p,", req->user_data );
     fprintf( stderr, " extra_offset=%d,", req->extra_offset );
+    fprintf( stderr, " extra_size=%d,", req->extra_size );
     fprintf( stderr, " extra_value=%08x", req->extra_value );
 }
 
diff --git a/server/window.c b/server/window.c
index ff16793..6373068 100644
--- a/server/window.c
+++ b/server/window.c
@@ -586,20 +586,20 @@
         set_error( STATUS_ACCESS_DENIED );
         return;
     }
-    if (req->extra_offset < -1 || req->extra_offset >= win->nb_extra_bytes)
+    if (req->extra_size > sizeof(req->extra_value) ||
+        req->extra_offset < -1 ||
+        req->extra_offset > win->nb_extra_bytes - (int)req->extra_size)
     {
-        set_error( STATUS_INVALID_PARAMETER );
+        set_win32_error( ERROR_INVALID_INDEX );
         return;
     }
     if (req->extra_offset != -1)
     {
-        memcpy( &reply->old_extra_value, win->extra_bytes + req->extra_offset,
-                min( sizeof(reply->old_extra_value),
-                     (size_t)(win->nb_extra_bytes - req->extra_offset) ));
+        memcpy( &reply->old_extra_value, win->extra_bytes + req->extra_offset, req->extra_size );
     }
-    else if (req->flags & (SET_WIN_EXTRAWORD|SET_WIN_EXTRALONG))
+    else if (req->flags & SET_WIN_EXTRA)
     {
-        set_error( STATUS_INVALID_PARAMETER );
+        set_win32_error( ERROR_INVALID_INDEX );
         return;
     }
     reply->old_style     = win->style;
@@ -612,12 +612,8 @@
     if (req->flags & SET_WIN_ID) win->id = req->id;
     if (req->flags & SET_WIN_INSTANCE) win->instance = req->instance;
     if (req->flags & SET_WIN_USERDATA) win->user_data = req->user_data;
-    if (req->flags & (SET_WIN_EXTRAWORD|SET_WIN_EXTRALONG))
-    {
-        const int len = (req->flags & SET_WIN_EXTRALONG) ? sizeof(int) : sizeof(short);
-        memcpy( win->extra_bytes + req->extra_offset, &req->extra_value,
-                min( len, win->nb_extra_bytes - req->extra_offset ));
-    }
+    if (req->flags & SET_WIN_EXTRA) memcpy( win->extra_bytes + req->extra_offset,
+                                            &req->extra_value, req->extra_size );
 }
 
 
diff --git a/windows/win.c b/windows/win.c
index 0e9ce70..0c41bda 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -1752,17 +1752,24 @@
         }
         if (wndPtr == WND_OTHER_PROCESS)
         {
-            if (IsWindow( hwnd ))
-                FIXME( "(%d) not supported yet on other process window %p\n", offset, hwnd );
-            SetLastError( ERROR_INVALID_WINDOW_HANDLE );
-            return 0;
+            SERVER_START_REQ( set_window_info )
+            {
+                req->handle = hwnd;
+                req->flags  = 0;  /* don't set anything, just retrieve */
+                req->extra_offset = offset;
+                req->extra_size = sizeof(retvalue);
+                if (!wine_server_call_err( req ))
+                    memcpy( &retvalue, &reply->old_extra_value, sizeof(retvalue) );
+            }
+            SERVER_END_REQ;
+            return retvalue;
         }
         if (offset > (int)(wndPtr->cbWndExtra - sizeof(WORD)))
         {
             WARN("Invalid offset %d\n", offset );
             SetLastError( ERROR_INVALID_INDEX );
         }
-        else retvalue = *(WORD *)(((char *)wndPtr->wExtra) + offset);
+        else memcpy( &retvalue,  (char *)wndPtr->wExtra + offset, sizeof(retvalue) );
         WIN_ReleasePtr( wndPtr );
         return retvalue;
     }
@@ -1834,14 +1841,15 @@
     SERVER_START_REQ( set_window_info )
     {
         req->handle = hwnd;
-        req->flags = SET_WIN_EXTRAWORD;
+        req->flags = SET_WIN_EXTRA;
         req->extra_offset = offset;
-        req->extra_value = newval;
+        req->extra_size = sizeof(newval);
+        memcpy( &req->extra_value, &newval, sizeof(newval) );
         if (!wine_server_call_err( req ))
         {
-            WORD *ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
-            retval = *ptr;
-            *ptr = newval;
+            void *ptr = (char *)wndPtr->wExtra + offset;
+            memcpy( &retval, ptr, sizeof(retval) );
+            memcpy( ptr, &newval, sizeof(newval) );
         }
     }
     SERVER_END_REQ;
@@ -1885,6 +1893,7 @@
             req->handle = hwnd;
             req->flags  = 0;  /* don't set anything, just retrieve */
             req->extra_offset = (offset >= 0) ? offset : -1;
+            req->extra_size = (offset >= 0) ? sizeof(retvalue) : 0;
             if (!wine_server_call_err( req ))
             {
                 switch(offset)
@@ -1900,8 +1909,6 @@
                     break;
                 }
             }
-            else if (offset >= 0 && GetLastError() == ERROR_INVALID_PARAMETER)
-                SetLastError( ERROR_INVALID_INDEX );
         }
         SERVER_END_REQ;
         return retvalue;
@@ -2094,9 +2101,10 @@
             req->user_data = (void *)newval;
             break;
         default:
-            req->flags = SET_WIN_EXTRALONG;
+            req->flags = SET_WIN_EXTRA;
             req->extra_offset = offset;
-            req->extra_value = newval;
+            req->extra_size = sizeof(newval);
+            memcpy( &req->extra_value, &newval, sizeof(newval) );
         }
         if ((ok = !wine_server_call_err( req )))
         {
@@ -2124,9 +2132,9 @@
                 break;
             default:
                 {
-                    LONG *ptr = (LONG *)((char *)wndPtr->wExtra + offset);
-                    retval = *ptr;
-                    *ptr = newval;
+                    void *ptr = (char *)wndPtr->wExtra + offset;
+                    memcpy( &retval, ptr, sizeof(retval) );
+                    memcpy( ptr, &newval, sizeof(newval) );
                 }
                 break;
             }