From f7835dea2ddbd3aa8fb53fb4b83ccaf16f5efde9 Mon Sep 17 00:00:00 2001 From: Qian Hong Date: Fri, 8 Nov 2013 17:10:24 +0800 Subject: [PATCH] user32: Implement OpenInputDesktop. --- dlls/user32/tests/winstation.c | 22 ---------------------- dlls/user32/winstation.c | 20 +++++++++++++++++--- include/wine/server_protocol.h | 21 ++++++++++++++++++++- server/protocol.def | 10 ++++++++++ server/request.h | 8 ++++++++ server/trace.c | 15 +++++++++++++++ server/winstation.c | 22 ++++++++++++++++++++++ 7 files changed, 92 insertions(+), 26 deletions(-) diff --git a/dlls/user32/tests/winstation.c b/dlls/user32/tests/winstation.c index d7825a1603..4f664dd547 100644 --- a/dlls/user32/tests/winstation.c +++ b/dlls/user32/tests/winstation.c @@ -492,29 +492,21 @@ static void test_inputdesktop(void) /* OpenInputDesktop creates new handles for each calls */ old_input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); -todo_wine ok(old_input_desk != NULL, "OpenInputDesktop failed!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(old_input_desk, UOI_NAME, name, 1024, NULL); -todo_wine ok(ret, "GetUserObjectInformation failed!\n"); -todo_wine ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); -todo_wine ok(input_desk != NULL, "OpenInputDesktop failed!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(input_desk, UOI_NAME, name, 1024, NULL); -todo_wine ok(ret, "GetUserObjectInformation failed!\n"); -todo_wine ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name); -todo_wine ok(old_input_desk != input_desk, "returned the same handle!\n"); ret = CloseDesktop(input_desk); -todo_wine ok(ret, "CloseDesktop failed!\n"); /* by default, GetThreadDesktop is the input desktop, SendInput should success. */ @@ -571,10 +563,8 @@ todo_wine /* Set thread desktop to the input desktop, SendInput should success. */ ret = SetThreadDesktop(old_input_desk); -todo_wine ok(ret, "SetThreadDesktop failed!\n"); thread_desk = GetThreadDesktop(GetCurrentThreadId()); -todo_wine ok(thread_desk == old_input_desk, "thread desktop doesn't match!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(thread_desk, UOI_NAME, name, 1024, NULL); @@ -589,17 +579,14 @@ todo_wine ret = SwitchDesktop(new_desk); ok(ret, "SwitchDesktop failed!\n"); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); -todo_wine ok(input_desk != NULL, "OpenInputDesktop failed!\n"); ok(input_desk != new_desk, "returned the same handle!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(input_desk, UOI_NAME, name, 1024, NULL); -todo_wine ok(ret, "GetUserObjectInformation failed!\n"); todo_wine ok(!strcmp(name, "new_desk"), "unexpected desktop %s\n", name); ret = CloseDesktop(input_desk); -todo_wine ok(ret, "CloseDesktop failed!\n"); SetLastError(0xdeadbeef); @@ -626,15 +613,11 @@ todo_wine * thread desktop, clean side effects. SendInput should success. */ ret = SwitchDesktop(old_input_desk); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); -todo_wine ok(input_desk != NULL, "OpenInputDesktop failed!\n"); -todo_wine ok(input_desk != old_input_desk, "returned the same handle!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(input_desk, UOI_NAME, name, 1024, NULL); -todo_wine ok(ret, "GetUserObjectInformation failed!\n"); -todo_wine ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name); ret = SetThreadDesktop(old_thread_desk); @@ -652,10 +635,8 @@ todo_wine /* free resources */ ret = CloseDesktop(input_desk); -todo_wine ok(ret, "CloseDesktop failed!\n"); ret = CloseDesktop(old_input_desk); -todo_wine ok(ret, "CloseDesktop failed!\n"); ret = CloseDesktop(new_desk); ok(ret, "CloseDesktop failed!\n"); @@ -684,10 +665,8 @@ static void test_inputdesktop2(void) ret = EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA, 0); ok(!ret, "EnumDesktopsA failed!\n"); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); -todo_wine ok(input_desk != NULL, "OpenInputDesktop failed!\n"); ret = CloseDesktop(input_desk); -todo_wine ok(ret, "CloseDesktop failed!\n"); ret = SetProcessWindowStation(w2); @@ -704,7 +683,6 @@ todo_wine SetLastError(0xdeadbeef); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(input_desk == NULL, "OpenInputDesktop should fail on non default winstation!\n"); -todo_wine ok(GetLastError() == ERROR_INVALID_FUNCTION || broken(GetLastError() == 0xdeadbeef), "last error %08x\n", GetLastError()); hdesk = OpenDesktopA("desk_test", 0, TRUE, DESKTOP_ALL_ACCESS); diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c index 96b5117969..12b9edcd41 100644 --- a/dlls/user32/winstation.c +++ b/dlls/user32/winstation.c @@ -462,9 +462,23 @@ BOOL WINAPI EnumDesktopsW( HWINSTA winsta, DESKTOPENUMPROCW func, LPARAM lparam */ HDESK WINAPI OpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access ) { - FIXME( "(%x,%i,%x): stub\n", flags, inherit, access ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return 0; + HANDLE ret = 0; + + TRACE( "(%x,%i,%x)\n", flags, inherit, access ); + + if (flags) + FIXME( "partial stub flags %08x\n", flags ); + + SERVER_START_REQ( open_input_desktop ) + { + req->flags = flags; + req->access = access; + req->attributes = inherit ? OBJ_INHERIT : 0; + if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + + return ret; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 7136d9b212..604affd871 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -3804,6 +3804,22 @@ struct open_desktop_reply +struct open_input_desktop_request +{ + struct request_header __header; + unsigned int flags; + unsigned int access; + unsigned int attributes; +}; +struct open_input_desktop_reply +{ + struct reply_header __header; + obj_handle_t handle; + char __pad_12[4]; +}; + + + struct close_desktop_request { struct request_header __header; @@ -5233,6 +5249,7 @@ enum request REQ_enum_winstation, REQ_create_desktop, REQ_open_desktop, + REQ_open_input_desktop, REQ_close_desktop, REQ_get_thread_desktop, REQ_set_thread_desktop, @@ -5493,6 +5510,7 @@ union generic_request struct enum_winstation_request enum_winstation_request; struct create_desktop_request create_desktop_request; struct open_desktop_request open_desktop_request; + struct open_input_desktop_request open_input_desktop_request; struct close_desktop_request close_desktop_request; struct get_thread_desktop_request get_thread_desktop_request; struct set_thread_desktop_request set_thread_desktop_request; @@ -5751,6 +5769,7 @@ union generic_reply struct enum_winstation_reply enum_winstation_reply; struct create_desktop_reply create_desktop_reply; struct open_desktop_reply open_desktop_reply; + struct open_input_desktop_reply open_input_desktop_reply; struct close_desktop_reply close_desktop_reply; struct get_thread_desktop_reply get_thread_desktop_reply; struct set_thread_desktop_reply set_thread_desktop_reply; @@ -5826,6 +5845,6 @@ union generic_reply struct set_suspend_context_reply set_suspend_context_reply; }; -#define SERVER_PROTOCOL_VERSION 450 +#define SERVER_PROTOCOL_VERSION 451 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index 95d79948f0..31b85f8dfa 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2707,6 +2707,16 @@ enum coords_relative @END +/* Open a handle to current input desktop */ +@REQ(open_input_desktop) + unsigned int flags; /* desktop flags */ + unsigned int access; /* wanted access rights */ + unsigned int attributes; /* object attributes */ +@REPLY + obj_handle_t handle; /* handle to the desktop */ +@END + + /* Close a desktop */ @REQ(close_desktop) obj_handle_t handle; /* handle to the desktop */ diff --git a/server/request.h b/server/request.h index 41c67ee030..74f5892119 100644 --- a/server/request.h +++ b/server/request.h @@ -286,6 +286,7 @@ DECL_HANDLER(set_process_winstation); DECL_HANDLER(enum_winstation); DECL_HANDLER(create_desktop); DECL_HANDLER(open_desktop); +DECL_HANDLER(open_input_desktop); DECL_HANDLER(close_desktop); DECL_HANDLER(get_thread_desktop); DECL_HANDLER(set_thread_desktop); @@ -545,6 +546,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_enum_winstation, (req_handler)req_create_desktop, (req_handler)req_open_desktop, + (req_handler)req_open_input_desktop, (req_handler)req_close_desktop, (req_handler)req_get_thread_desktop, (req_handler)req_set_thread_desktop, @@ -1735,6 +1737,12 @@ C_ASSERT( FIELD_OFFSET(struct open_desktop_request, attributes) == 24 ); C_ASSERT( sizeof(struct open_desktop_request) == 32 ); C_ASSERT( FIELD_OFFSET(struct open_desktop_reply, handle) == 8 ); C_ASSERT( sizeof(struct open_desktop_reply) == 16 ); +C_ASSERT( FIELD_OFFSET(struct open_input_desktop_request, flags) == 12 ); +C_ASSERT( FIELD_OFFSET(struct open_input_desktop_request, access) == 16 ); +C_ASSERT( FIELD_OFFSET(struct open_input_desktop_request, attributes) == 20 ); +C_ASSERT( sizeof(struct open_input_desktop_request) == 24 ); +C_ASSERT( FIELD_OFFSET(struct open_input_desktop_reply, handle) == 8 ); +C_ASSERT( sizeof(struct open_input_desktop_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct close_desktop_request, handle) == 12 ); C_ASSERT( sizeof(struct close_desktop_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_thread_desktop_request, tid) == 12 ); diff --git a/server/trace.c b/server/trace.c index 1a9f403354..2171a2578c 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3192,6 +3192,18 @@ static void dump_open_desktop_reply( const struct open_desktop_reply *req ) fprintf( stderr, " handle=%04x", req->handle ); } +static void dump_open_input_desktop_request( const struct open_input_desktop_request *req ) +{ + fprintf( stderr, " flags=%08x", req->flags ); + fprintf( stderr, ", access=%08x", req->access ); + fprintf( stderr, ", attributes=%08x", req->attributes ); +} + +static void dump_open_input_desktop_reply( const struct open_input_desktop_reply *req ) +{ + fprintf( stderr, " handle=%04x", req->handle ); +} + static void dump_close_desktop_request( const struct close_desktop_request *req ) { fprintf( stderr, " handle=%04x", req->handle ); @@ -4252,6 +4264,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_enum_winstation_request, (dump_func)dump_create_desktop_request, (dump_func)dump_open_desktop_request, + (dump_func)dump_open_input_desktop_request, (dump_func)dump_close_desktop_request, (dump_func)dump_get_thread_desktop_request, (dump_func)dump_set_thread_desktop_request, @@ -4508,6 +4521,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_enum_winstation_reply, (dump_func)dump_create_desktop_reply, (dump_func)dump_open_desktop_reply, + (dump_func)dump_open_input_desktop_reply, NULL, (dump_func)dump_get_thread_desktop_reply, NULL, @@ -4764,6 +4778,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "enum_winstation", "create_desktop", "open_desktop", + "open_input_desktop", "close_desktop", "get_thread_desktop", "set_thread_desktop", diff --git a/server/winstation.c b/server/winstation.c index 57e6995a03..2eaffb0bbe 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -551,6 +551,28 @@ DECL_HANDLER(open_desktop) } } +/* open a handle to current input desktop */ +DECL_HANDLER(open_input_desktop) +{ + /* FIXME: check access rights */ + struct winstation *winstation = get_process_winstation( current->process, 0 ); + struct desktop *desktop; + + if (!winstation) return; + + if (!(winstation->flags & WSF_VISIBLE)) + { + set_error( STATUS_ILLEGAL_FUNCTION ); + return; + } + + if ((desktop = get_desktop_obj( current->process, current->process->desktop, 0 ))) + { + reply->handle = alloc_handle( current->process, desktop, req->access, req->attributes ); + release_object( desktop ); + } + release_object( winstation ); +} /* close a desktop */ DECL_HANDLER(close_desktop)