Re: SetShellWindow()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> > +/* globally stored shell window handles */
> > +
> > +static HWND hwndShellWindow = 0;
> > +static HWND hwndShellListView = 0;
> > +
> > +/* id of the process, which currently owns the shell window */
> > +static DWORD pidShellWindow = 0;
>
> You must not store handles or pids in the server, you should store
> pointers to the server objects, and properly handle the case where the
> corresponding window or process gets destroyed.

OK, I moved the server implementation to window.c and replaced the handles and 
IDs by object pointers.

If you want, you can remove those two calls to grab_object() and 
release_object() from the patch. They are not really necessary, since the 
process pointer is allways automatically reset to 0 the time its windows are 
destroyed. And the windows are always destroyed before a process is killed. 
But maybe you want to play safe, and leave the calls in.


Changelog:
* Implement SetShellWindow(), SetShellWindowEx() and GetShellWindow()


-- 
Martin Fuchs
martin-fuchs@gmx.net
Index: dlls/user/focus.c
===================================================================
RCS file: /home/wine/wine/dlls/user/focus.c,v
retrieving revision 1.4
diff -u -r1.4 focus.c
--- dlls/user/focus.c	22 Nov 2002 21:22:16 -0000	1.4
+++ dlls/user/focus.c	27 Aug 2003 12:08:44 -0000
@@ -81,6 +81,12 @@
         return TRUE;
     }
 
+	if (hwnd == GetShellWindow())
+	{
+		TRACE("set_active_window(%p): ignored for desktop window\n", hwnd);
+		return TRUE;
+	}
+
     /* call CBT hook chain */
     cbt.fMouse     = mouse;
     cbt.hWndActive = previous;
@@ -341,3 +347,57 @@
     SERVER_END_REQ;
     return ret;
 }
+
+
+/***********************************************************************
+*      SetShellWindowEx (USER32.@)
+* hwndShell =    Progman[Program Manager]
+*                |-> SHELLDLL_DefView
+* hwndListView = |   |-> SysListView32
+*                |   |   |-> tooltips_class32
+*                |   |
+*                |   |-> SysHeader32
+*                |
+*                |-> ProxyTarget
+*/
+BOOL WINAPI SetShellWindowEx(HWND hwndShell, HWND hwndListView)
+{
+	BOOL ret;
+
+    SERVER_START_REQ(set_shell_windows)
+    {
+        req->shell_window = hwndShell;
+        req->shell_listview = hwndListView;
+
+        ret = !wine_server_call_err(req);
+    }
+    SERVER_END_REQ;
+
+	return ret;
+}
+
+/*******************************************************************
+*      SetShellWindow (USER32.@)
+*/
+BOOL WINAPI SetShellWindow(HWND hwndShell)
+{  
+	return SetShellWindowEx(hwndShell, hwndShell);
+}
+
+/*******************************************************************
+*      GetShellWindow (USER32.@)
+*/
+HWND WINAPI GetShellWindow()
+{
+	HWND hwndShell = 0;
+
+    SERVER_START_REQ(get_shell_windows)
+    {
+        if (!wine_server_call_err(req))
+			hwndShell = reply->shell_window;
+    }
+    SERVER_END_REQ;
+
+	return hwndShell;
+}
+
Index: include/wine/server_protocol.h
===================================================================
RCS file: /home/wine/wine/include/wine/server_protocol.h,v
retrieving revision 1.80
diff -u -r1.80 server_protocol.h
--- include/wine/server_protocol.h	19 Aug 2003 03:08:18 -0000	1.80
+++ include/wine/server_protocol.h	27 Aug 2003 12:08:47 -0000
@@ -3111,6 +3111,32 @@
 #define OPEN_TOKEN_AS_SELF  2
 
 
+
+struct set_shell_windows_request
+{
+    struct request_header __header;
+    user_handle_t	shell_window;
+    user_handle_t	shell_listview;
+};
+struct set_shell_windows_reply
+{
+    struct reply_header __header;
+};
+
+
+struct get_shell_windows_request
+{
+    struct request_header __header;
+};
+struct get_shell_windows_reply
+{
+    struct reply_header __header;
+    user_handle_t	shell_window;
+	user_handle_t	shell_listview;
+};
+
+
+
 enum request
 {
     REQ_new_process,
@@ -3291,6 +3317,8 @@
     REQ_get_next_hook,
     REQ_set_clipboard_info,
     REQ_open_token,
+    REQ_set_shell_windows,
+    REQ_get_shell_windows,
     REQ_NB_REQUESTS
 };
 
@@ -3476,6 +3504,8 @@
     struct get_next_hook_request get_next_hook_request;
     struct set_clipboard_info_request set_clipboard_info_request;
     struct open_token_request open_token_request;
+    struct set_shell_windows_request set_shell_windows_request;
+    struct get_shell_windows_request get_shell_windows_request;
 };
 union generic_reply
 {
@@ -3659,8 +3689,10 @@
     struct get_next_hook_reply get_next_hook_reply;
     struct set_clipboard_info_reply set_clipboard_info_reply;
     struct open_token_reply open_token_reply;
+    struct set_shell_windows_reply set_shell_windows_reply;
+    struct get_shell_windows_reply get_shell_windows_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 120
+#define SERVER_PROTOCOL_VERSION 121
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
Index: server/protocol.def
===================================================================
RCS file: /home/wine/wine/server/protocol.def,v
retrieving revision 1.80
diff -u -r1.80 protocol.def
--- server/protocol.def	19 Aug 2003 03:08:17 -0000	1.80
+++ server/protocol.def	27 Aug 2003 12:08:53 -0000
@@ -2178,3 +2178,18 @@
 @END
 #define OPEN_TOKEN_THREAD   1
 #define OPEN_TOKEN_AS_SELF  2
+
+
+/* Set the shell windows */
+@REQ(set_shell_windows)
+    user_handle_t	shell_window;	/* handle to the new shell window */
+    user_handle_t	shell_listview;	/* handle to the new shell listview window */
+@END
+
+/* Get the shell windows */
+@REQ(get_shell_windows)
+@REPLY
+    user_handle_t	shell_window;	/* handle to the shell window */
+	user_handle_t	shell_listview;	/* handle to the shell listview window */
+@END
+
Index: server/request.h
===================================================================
RCS file: /home/wine/wine/server/request.h,v
retrieving revision 1.88
diff -u -r1.88 request.h
--- server/request.h	19 Aug 2003 03:08:17 -0000	1.88
+++ server/request.h	27 Aug 2003 12:08:53 -0000
@@ -281,6 +281,8 @@
 DECL_HANDLER(get_next_hook);
 DECL_HANDLER(set_clipboard_info);
 DECL_HANDLER(open_token);
+DECL_HANDLER(set_shell_windows);
+DECL_HANDLER(get_shell_windows);
 
 #ifdef WANT_REQUEST_HANDLERS
 
@@ -465,6 +467,8 @@
     (req_handler)req_get_next_hook,
     (req_handler)req_set_clipboard_info,
     (req_handler)req_open_token,
+    (req_handler)req_set_shell_windows,
+    (req_handler)req_get_shell_windows,
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
Index: server/trace.c
===================================================================
RCS file: /home/wine/wine/server/trace.c,v
retrieving revision 1.177
diff -u -r1.177 trace.c
--- server/trace.c	19 Aug 2003 03:08:17 -0000	1.177
+++ server/trace.c	27 Aug 2003 12:08:55 -0000
@@ -2502,6 +2502,22 @@
     fprintf( stderr, " token=%p", req->token );
 }
 
+static void dump_set_shell_windows_request( const struct set_shell_windows_request *req )
+{
+    fprintf( stderr, " shell_window=%p,", req->shell_window );
+    fprintf( stderr, " shell_listview=%p", req->shell_listview );
+}
+
+static void dump_get_shell_windows_request( const struct get_shell_windows_request *req )
+{
+}
+
+static void dump_get_shell_windows_reply( const struct get_shell_windows_reply *req )
+{
+    fprintf( stderr, " shell_window=%p,", req->shell_window );
+    fprintf( stderr, " shell_listview=%p", req->shell_listview );
+}
+
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_new_process_request,
     (dump_func)dump_get_new_process_info_request,
@@ -2681,6 +2697,8 @@
     (dump_func)dump_get_next_hook_request,
     (dump_func)dump_set_clipboard_info_request,
     (dump_func)dump_open_token_request,
+    (dump_func)dump_set_shell_windows_request,
+    (dump_func)dump_get_shell_windows_request,
 };
 
 static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -2862,6 +2880,8 @@
     (dump_func)dump_get_next_hook_reply,
     (dump_func)dump_set_clipboard_info_reply,
     (dump_func)dump_open_token_reply,
+    (dump_func)0,
+    (dump_func)dump_get_shell_windows_reply,
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -3043,6 +3063,8 @@
     "get_next_hook",
     "set_clipboard_info",
     "open_token",
+    "set_shell_windows",
+    "get_shell_windows",
 };
 
 /* ### make_requests end ### */
Index: server/window.c
===================================================================
RCS file: /home/wine/wine/server/window.c,v
retrieving revision 1.22
diff -u -r1.22 window.c
--- server/window.c	8 Jan 2003 19:55:08 -0000	1.22
+++ server/window.c	27 Aug 2003 12:08:56 -0000
@@ -80,6 +80,15 @@
 static struct window *top_window;  /* top-level (desktop) window */
 
 
+/* globally stored shell window pointers */
+
+static struct window* shell_window = 0;
+static struct window* shell_listview = 0;
+
+/* process, which currently owns the shell window */
+static struct process* shell_window_owner = 0;
+
+
 /* retrieve a pointer to a window from its handle */
 inline static struct window *get_window( user_handle_t handle )
 {
@@ -243,6 +252,23 @@
         if (win->paint_count) inc_queue_paint_count( win->thread, -win->paint_count );
         queue_cleanup_window( win->thread, win->handle );
     }
+
+	/* reset shell window pointers, if the corresponding window is destroyed */
+	if (win == shell_window)
+	{
+		shell_window = 0;
+
+		/* release the shell window owner pointer */
+		if (shell_window_owner)
+		{
+			release_object(shell_window_owner);
+			shell_window_owner = 0;
+		}
+	}
+
+	if (win == shell_listview)
+		shell_listview = 0;
+
     free_user_handle( win->handle );
     destroy_properties( win );
     unlink_window( win );
@@ -817,4 +843,37 @@
         data++;
         count--;
     }
+}
+
+
+/* set the shell windows */
+DECL_HANDLER(set_shell_windows)
+{
+	/* test if we are permitted to change the shell window */
+	if (shell_window_owner && current->process!=shell_window_owner)
+	{
+		set_error(STATUS_ACCESS_DENIED);
+	}
+	else
+	{
+		shell_window = req->shell_window? get_window(req->shell_window): 0;
+		shell_listview = req->shell_listview? get_window(req->shell_listview): 0;
+
+		/* We only have to set shell_window_owner if there was none previously.
+		   It can't be the case, that we have to owerwrite the owner with
+		   another process, since we already checked for this case above. */
+		if (shell_window && !shell_window_owner)
+		{
+			/* request shell window for the calling process */
+			shell_window_owner = (struct process*)grab_object(current->process);
+		}
+	}
+}
+
+
+/* get the shell windows */
+DECL_HANDLER(get_shell_windows)
+{
+	reply->shell_window = shell_window? shell_window->handle: 0;
+	reply->shell_listview = shell_listview? shell_listview->handle: 0;
 }
Index: windows/winpos.c
===================================================================
RCS file: /home/wine/wine/windows/winpos.c,v
retrieving revision 1.145
diff -u -r1.145 winpos.c
--- windows/winpos.c	19 May 2003 19:00:02 -0000	1.145
+++ windows/winpos.c	27 Aug 2003 12:08:58 -0000
@@ -65,7 +65,6 @@
 
 /* ----- internal variables ----- */
 
-static HWND hGlobalShellWindow=0; /*the shell*/
 static HWND hGlobalTaskmanWindow=0;
 static HWND hGlobalProgmanWindow=0;
 
@@ -630,27 +629,6 @@
 }
 
 
-/*******************************************************************
- *		SetShellWindow (USER32.@)
- */
-HWND WINAPI SetShellWindow(HWND hwndshell)
-{   WARN("(hWnd=%p) semi stub\n",hwndshell );
-
-    hGlobalShellWindow = WIN_GetFullHandle( hwndshell );
-    return hGlobalShellWindow;
-}
-
-
-/*******************************************************************
- *		GetShellWindow (USER32.@)
- */
-HWND WINAPI GetShellWindow(void)
-{   WARN("(hWnd=%p) semi stub\n",hGlobalShellWindow );
-
-    return hGlobalShellWindow;
-}
-
-
 /***********************************************************************
  *		BringWindowToTop (USER32.@)
  */
@@ -1360,25 +1338,6 @@
 HWND WINAPI GetProgmanWindow(void)
 {
 	return hGlobalProgmanWindow;
-}
-
-/***********************************************************************
- *		SetShellWindowEx (USER32.@)
- * hwndProgman =  Progman[Program Manager]
- *                |-> SHELLDLL_DefView
- * hwndListView = |   |-> SysListView32
- *                |   |   |-> tooltips_class32
- *                |   |
- *                |   |-> SysHeader32
- *                |
- *                |-> ProxyTarget
- */
-HWND WINAPI SetShellWindowEx ( HWND hwndProgman, HWND hwndListView )
-{
-	FIXME("%p %p stub\n",hwndProgman ,hwndListView );
-	hGlobalShellWindow = hwndProgman;
-	return hGlobalShellWindow;
-
 }
 
 /***********************************************************************

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux