Added support for inter-process GetWindowLong on the window extra
bytes.

diff --git a/server/protocol.def b/server/protocol.def
index 384eb24..69004f7 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1780,6 +1780,7 @@
     user_handle_t  parent;      /* parent window */
     user_handle_t  owner;       /* owner window */
     atom_t         atom;        /* class atom */
+    int            extra;       /* number of extra bytes */
 @REPLY
     user_handle_t  handle;      /* created window */
 @END
@@ -1832,18 +1833,23 @@
     unsigned int   id;            /* window id */
     void*          instance;      /* creator instance */
     void*          user_data;     /* user-specific data */
+    int            extra_offset;  /* offset to set in extra bytes */
+    unsigned int   extra_value;   /* value to set in extra bytes */
 @REPLY
     unsigned int   old_style;     /* old window style */
     unsigned int   old_ex_style;  /* old window extended style */
     unsigned int   old_id;        /* old window id */
     void*          old_instance;  /* old creator instance */
     void*          old_user_data; /* old user-specific data */
+    unsigned int   old_extra_value; /* old value in extra bytes */
 @END
 #define SET_WIN_STYLE     0x01
 #define SET_WIN_EXSTYLE   0x02
 #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
 
 
 /* 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 fb93e53..a73d34c 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2095,7 +2095,8 @@
 {
     fprintf( stderr, " parent=%p,", req->parent );
     fprintf( stderr, " owner=%p,", req->owner );
-    fprintf( stderr, " atom=%04x", req->atom );
+    fprintf( stderr, " atom=%04x,", req->atom );
+    fprintf( stderr, " extra=%d", req->extra );
 }
 
 static void dump_create_window_reply( const struct create_window_reply *req )
@@ -2154,7 +2155,9 @@
     fprintf( stderr, " ex_style=%08x,", req->ex_style );
     fprintf( stderr, " id=%08x,", req->id );
     fprintf( stderr, " instance=%p,", req->instance );
-    fprintf( stderr, " user_data=%p", req->user_data );
+    fprintf( stderr, " user_data=%p,", req->user_data );
+    fprintf( stderr, " extra_offset=%d,", req->extra_offset );
+    fprintf( stderr, " extra_value=%08x", req->extra_value );
 }
 
 static void dump_set_window_info_reply( const struct set_window_info_reply *req )
@@ -2163,7 +2166,8 @@
     fprintf( stderr, " old_ex_style=%08x,", req->old_ex_style );
     fprintf( stderr, " old_id=%08x,", req->old_id );
     fprintf( stderr, " old_instance=%p,", req->old_instance );
-    fprintf( stderr, " old_user_data=%p", req->old_user_data );
+    fprintf( stderr, " old_user_data=%p,", req->old_user_data );
+    fprintf( stderr, " old_extra_value=%08x", req->old_extra_value );
 }
 
 static void dump_get_window_parents_request( const struct get_window_parents_request *req )
diff --git a/server/window.c b/server/window.c
index a13c734..ff16793 100644
--- a/server/window.c
+++ b/server/window.c
@@ -77,6 +77,8 @@
     int              prop_inuse;      /* number of in-use window properties */
     int              prop_alloc;      /* number of allocated window properties */
     struct property *properties;      /* window properties array */
+    int              nb_extra_bytes;  /* number of extra bytes */
+    char             extra_bytes[1];  /* extra bytes storage */
 };
 
 static struct window *top_window;  /* top-level (desktop) window */
@@ -264,9 +266,10 @@
 }
 
 /* create a new window structure (note: the window is not linked in the window tree) */
-static struct window *create_window( struct window *parent, struct window *owner, atom_t atom )
+static struct window *create_window( struct window *parent, struct window *owner, atom_t atom,
+                                     int extra_bytes )
 {
-    struct window *win = mem_alloc( sizeof(*win) );
+    struct window *win = mem_alloc( sizeof(*win) + extra_bytes - 1 );
     if (!win) return NULL;
 
     if (!(win->handle = alloc_user_handle( win, USER_WINDOW )))
@@ -292,6 +295,8 @@
     win->prop_inuse     = 0;
     win->prop_alloc     = 0;
     win->properties     = NULL;
+    win->nb_extra_bytes = extra_bytes;
+    memset( win->extra_bytes, 0, extra_bytes );
 
     if (parent)  /* put it on parent unlinked list */
     {
@@ -448,11 +453,16 @@
 DECL_HANDLER(create_window)
 {
     reply->handle = 0;
+    if (req->extra < 0 || req->extra > 4096)  /* don't allow stupid values here */
+    {
+        set_error( STATUS_INVALID_PARAMETER );
+        return;
+    }
     if (!req->parent)  /* return desktop window */
     {
         if (!top_window)
         {
-            if (!(top_window = create_window( NULL, NULL, req->atom ))) return;
+            if (!(top_window = create_window( NULL, NULL, req->atom, req->extra ))) return;
             top_window->thread = NULL;  /* no thread owns the desktop */
             top_window->style  = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
         }
@@ -471,7 +481,7 @@
             set_error( STATUS_ACCESS_DENIED );
             return;
         }
-        if (!(win = create_window( parent, owner, req->atom ))) return;
+        if (!(win = create_window( parent, owner, req->atom, req->extra ))) return;
         reply->handle = win->handle;
     }
 }
@@ -576,6 +586,22 @@
         set_error( STATUS_ACCESS_DENIED );
         return;
     }
+    if (req->extra_offset < -1 || req->extra_offset >= win->nb_extra_bytes)
+    {
+        set_error( STATUS_INVALID_PARAMETER );
+        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) ));
+    }
+    else if (req->flags & (SET_WIN_EXTRAWORD|SET_WIN_EXTRALONG))
+    {
+        set_error( STATUS_INVALID_PARAMETER );
+        return;
+    }
     reply->old_style     = win->style;
     reply->old_ex_style  = win->ex_style;
     reply->old_id        = win->id;
@@ -586,6 +612,12 @@
     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 ));
+    }
 }