From: Zhiyi Zhang zzhang@codeweavers.com
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/rpcrt4/tests/server.c | 106 ++++++++++++++++++++++++++++++++--- dlls/rpcrt4/tests/server.idl | 2 + 2 files changed, 101 insertions(+), 7 deletions(-)
diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index 253fd817a48..7fdb076bc73 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -40,10 +40,11 @@
#define INT_CODE 4198
-static const char *progname; +static const char *progname, *client_test_name; static BOOL old_windows_version;
static HANDLE stop_event, stop_wait_event; +static PROCESS_INFORMATION client_info;
static void (WINAPI *pNDRSContextMarshall2)(RPC_BINDING_HANDLE, NDR_SCONTEXT, void*, NDR_RUNDOWN, void*, ULONG); static NDR_SCONTEXT (WINAPI *pNDRSContextUnmarshall2)(RPC_BINDING_HANDLE, void*, ULONG, void*, ULONG); @@ -147,6 +148,7 @@ static int (__cdecl *sum_array_ptr)(int (*a)[2]); static ctx_handle_t (__cdecl *get_handle)(void); static void (__cdecl *get_handle_by_ptr)(ctx_handle_t *r); static void (__cdecl *test_handle)(ctx_handle_t ctx_handle); +static void (__cdecl *test_I_RpcBindingInqLocalClientPID)(unsigned int protseq, RPC_BINDING_HANDLE binding);
#define SERVER_FUNCTIONS \ X(int_return) \ @@ -240,7 +242,8 @@ static void (__cdecl *test_handle)(ctx_handle_t ctx_handle); X(sum_array_ptr) \ X(get_handle) \ X(get_handle_by_ptr) \ - X(test_handle) + X(test_handle) \ + X(test_I_RpcBindingInqLocalClientPID)
/* type check statements generated in header file */ fnprintf *p_printf = printf; @@ -1122,6 +1125,88 @@ void __cdecl s_test_handle(ctx_handle_t ctx_handle) ok(ctx_handle == (ctx_handle_t)0xdeadbeef, "Unexpected ctx_handle %p\n", ctx_handle); }
+struct test_thread_params +{ + unsigned int protseq; + RPC_BINDING_HANDLE binding; +}; + +static DWORD CALLBACK test_I_RpcBindingInqLocalClientPID_thread_func(void *args) +{ + struct test_thread_params *params = (struct test_thread_params *)args; + RPC_STATUS status; + ULONG pid; + + winetest_push_context("%s", client_test_name); + + status = I_RpcBindingInqLocalClientPID(NULL, &pid); + todo_wine + ok(status == RPC_S_NO_CALL_ACTIVE, "Got unexpected %ld.\n", status); + + /* Other protocol sequences throw exceptions */ + if (params->protseq == RPC_PROTSEQ_LRPC) + { + status = I_RpcBindingInqLocalClientPID(params->binding, &pid); + todo_wine + ok(status == RPC_S_OK, "Got unexpected %ld.\n", status); + todo_wine + ok(pid == client_info.dwProcessId, "Got unexpected pid.\n"); + } + + winetest_pop_context(); + return 0; +} + +void __cdecl s_test_I_RpcBindingInqLocalClientPID(unsigned int protseq, RPC_BINDING_HANDLE binding) +{ + struct test_thread_params params; + RPC_STATUS status; + HANDLE thread; + ULONG pid; + + winetest_push_context("%s", client_test_name); + + /* Crash on Windows */ + if (0) + { + status = I_RpcBindingInqLocalClientPID(NULL, NULL); + ok(status == RPC_S_INVALID_ARG, "Got unexpected %ld.\n", status); + + status = I_RpcBindingInqLocalClientPID(binding, NULL); + ok(status == RPC_S_INVALID_ARG, "Got unexpected %ld.\n", status); + } + + status = I_RpcBindingInqLocalClientPID(NULL, &pid); + if (protseq == RPC_PROTSEQ_LRPC) + { + todo_wine + ok(status == RPC_S_OK, "Got unexpected %ld.\n", status); + todo_wine + ok(pid == client_info.dwProcessId, "Got unexpected pid.\n"); + } + else + { + ok(status == RPC_S_INVALID_BINDING, "Got unexpected %ld.\n", status); + } + + if (protseq == RPC_PROTSEQ_LRPC) /* Other protocol sequences throw exceptions */ + { + status = I_RpcBindingInqLocalClientPID(binding, &pid); + todo_wine + ok(status == RPC_S_OK, "Got unexpected %ld.\n", status); + todo_wine + ok(pid == client_info.dwProcessId, "Got unexpected pid.\n"); + } + + params.protseq = protseq; + params.binding = binding; + thread = CreateThread(NULL, 0, test_I_RpcBindingInqLocalClientPID_thread_func, ¶ms, 0, NULL); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); + + winetest_pop_context(); +} + void __RPC_USER ctx_handle_t_rundown(ctx_handle_t ctx_handle) { ok(ctx_handle == (ctx_handle_t)0xdeadbeef, "Unexpected ctx_handle %p\n", ctx_handle); @@ -1137,17 +1222,17 @@ static void run_client(const char *test) { char cmdline[MAX_PATH]; - PROCESS_INFORMATION info; STARTUPINFOA startup;
memset(&startup, 0, sizeof startup); startup.cb = sizeof startup;
+ client_test_name = test; make_cmdline(cmdline, test); - ok(CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - wait_child_process( info.hProcess ); - ok(CloseHandle(info.hProcess), "CloseHandle\n"); - ok(CloseHandle(info.hThread), "CloseHandle\n"); + ok(CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &client_info), "CreateProcess\n"); + wait_child_process(client_info.hProcess); + ok(CloseHandle(client_info.hProcess), "CloseHandle\n"); + ok(CloseHandle(client_info.hThread), "CloseHandle\n"); }
static void @@ -1964,6 +2049,7 @@ client(const char *test)
run_tests(); authinfo_test(RPC_PROTSEQ_TCP, 0); + test_I_RpcBindingInqLocalClientPID(RPC_PROTSEQ_TCP, IMixedServer_IfHandle); test_is_server_listening2(IMixedServer_IfHandle, RPC_S_OK, RPC_S_ACCESS_DENIED);
ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n"); @@ -1976,6 +2062,7 @@ client(const char *test)
set_auth_info(IMixedServer_IfHandle); authinfo_test(RPC_PROTSEQ_TCP, 1); + test_I_RpcBindingInqLocalClientPID(RPC_PROTSEQ_TCP, IMixedServer_IfHandle); test_is_server_listening(IMixedServer_IfHandle, RPC_S_ACCESS_DENIED);
ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n"); @@ -1988,6 +2075,7 @@ client(const char *test)
run_tests(); /* can cause RPC_X_BAD_STUB_DATA exception */ authinfo_test(RPC_PROTSEQ_LRPC, 0); + test_I_RpcBindingInqLocalClientPID(RPC_PROTSEQ_LRPC, IMixedServer_IfHandle); test_is_server_listening(IMixedServer_IfHandle, RPC_S_OK);
ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n"); @@ -2000,6 +2088,7 @@ client(const char *test)
run_tests(); authinfo_test(RPC_PROTSEQ_LRPC, 0); + test_I_RpcBindingInqLocalClientPID(RPC_PROTSEQ_LRPC, IMixedServer_IfHandle); todo_wine test_is_server_listening(IMixedServer_IfHandle, RPC_S_NOT_LISTENING);
@@ -2016,6 +2105,7 @@ client(const char *test)
set_auth_info(IMixedServer_IfHandle); authinfo_test(RPC_PROTSEQ_LRPC, 1); + test_I_RpcBindingInqLocalClientPID(RPC_PROTSEQ_LRPC, IMixedServer_IfHandle); test_is_server_listening(IMixedServer_IfHandle, RPC_S_OK);
ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n"); @@ -2029,6 +2119,7 @@ client(const char *test) test_is_server_listening(IMixedServer_IfHandle, RPC_S_OK); run_tests(); authinfo_test(RPC_PROTSEQ_NMP, 0); + test_I_RpcBindingInqLocalClientPID(RPC_PROTSEQ_NMP, IMixedServer_IfHandle); test_is_server_listening(IMixedServer_IfHandle, RPC_S_OK); stop(); test_is_server_listening(IMixedServer_IfHandle, RPC_S_NOT_LISTENING); @@ -2046,6 +2137,7 @@ client(const char *test) test_is_server_listening(IInterpServer_IfHandle, RPC_S_OK); run_tests(); authinfo_test(RPC_PROTSEQ_NMP, 0); + test_I_RpcBindingInqLocalClientPID(RPC_PROTSEQ_NMP, IInterpServer_IfHandle); test_is_server_listening(IInterpServer_IfHandle, RPC_S_OK);
ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n"); diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl index 4d945dcca3e..8de5dce5d4e 100644 --- a/dlls/rpcrt4/tests/server.idl +++ b/dlls/rpcrt4/tests/server.idl @@ -485,4 +485,6 @@ cpp_quote("#endif") ctx_handle_t get_handle(); void get_handle_by_ptr([out] ctx_handle_t *r); void test_handle(ctx_handle_t ctx_handle); + + void test_I_RpcBindingInqLocalClientPID([in] unsigned int protseq, [in] handle_t binding); }
From: Zhiyi Zhang zzhang@codeweavers.com
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/rpcrt4/rpc_binding.c | 16 ++++++++++++++-- dlls/rpcrt4/rpc_binding.h | 2 ++ dlls/rpcrt4/rpc_transport.c | 11 +++++++++++ dlls/rpcrt4/tests/server.c | 7 ------- 4 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/dlls/rpcrt4/rpc_binding.c b/dlls/rpcrt4/rpc_binding.c index ba7ef418419..8c2d34f8a21 100644 --- a/dlls/rpcrt4/rpc_binding.c +++ b/dlls/rpcrt4/rpc_binding.c @@ -1981,6 +1981,18 @@ RPC_STATUS WINAPI RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle, ULONG Op
RPC_STATUS WINAPI I_RpcBindingInqLocalClientPID(RPC_BINDING_HANDLE ClientBinding, ULONG *ClientPID) { - FIXME("%p %p: stub\n", ClientBinding, ClientPID); - return RPC_S_INVALID_BINDING; + RpcConnection *connection = NULL; + RpcBinding *binding; + + TRACE("%p %p\n", ClientBinding, ClientPID); + + binding = ClientBinding ? ClientBinding : RPCRT4_GetThreadCurrentCallHandle(); + if (!binding) + return RPC_S_NO_CALL_ACTIVE; + + connection = binding->FromConn; + if (!connection->ops->inquire_client_pid) + return RPC_S_INVALID_BINDING; + + return connection->ops->inquire_client_pid(connection, ClientPID); } diff --git a/dlls/rpcrt4/rpc_binding.h b/dlls/rpcrt4/rpc_binding.h index 8faacbd66e2..33ac0a627b5 100644 --- a/dlls/rpcrt4/rpc_binding.h +++ b/dlls/rpcrt4/rpc_binding.h @@ -118,6 +118,7 @@ struct connection_ops { RPC_STATUS (*impersonate_client)(RpcConnection *conn); RPC_STATUS (*revert_to_self)(RpcConnection *conn); RPC_STATUS (*inquire_auth_client)(RpcConnection *, RPC_AUTHZ_HANDLE *, RPC_WSTR *, ULONG *, ULONG *, ULONG *, ULONG); + RPC_STATUS (*inquire_client_pid)(RpcConnection *conn, ULONG *pid); };
/* don't know what MS's structure looks like */ @@ -264,6 +265,7 @@ RPC_STATUS RpcTransport_ParseTopOfTower(const unsigned char *tower_data, size_t void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection) DECLSPEC_HIDDEN; void RPCRT4_SetThreadCurrentCallHandle(RpcBinding *Binding) DECLSPEC_HIDDEN; RpcBinding *RPCRT4_GetThreadCurrentCallHandle(void) DECLSPEC_HIDDEN; +RpcConnection *RPCRT4_GetThreadCurrentConnection(void) DECLSPEC_HIDDEN; void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext) DECLSPEC_HIDDEN; void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext) DECLSPEC_HIDDEN; NDR_SCONTEXT RPCRT4_PopThreadContextHandle(void) DECLSPEC_HIDDEN; diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c index 82798a5a80d..8c615b71dd9 100644 --- a/dlls/rpcrt4/rpc_transport.c +++ b/dlls/rpcrt4/rpc_transport.c @@ -893,6 +893,13 @@ static RPC_STATUS rpcrt4_ncalrpc_inquire_auth_client( return RPC_S_OK; }
+static RPC_STATUS rpcrt4_ncalrpc_inquire_client_pid(RpcConnection *conn, ULONG *pid) +{ + RpcConnection_np *connection = (RpcConnection_np *)conn; + + return GetNamedPipeClientProcessId(connection->pipe, pid) ? RPC_S_OK : RPC_S_INVALID_BINDING; +} + /**** ncacn_ip_tcp support ****/
static size_t rpcrt4_ip_tcp_get_top_of_tower(unsigned char *tower_data, @@ -3134,6 +3141,7 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_np_impersonate_client, rpcrt4_conn_np_revert_to_self, RPCRT4_default_inquire_auth_client, + NULL }, { "ncalrpc", { EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_PIPE }, @@ -3156,6 +3164,7 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_np_impersonate_client, rpcrt4_conn_np_revert_to_self, rpcrt4_ncalrpc_inquire_auth_client, + rpcrt4_ncalrpc_inquire_client_pid }, { "ncacn_ip_tcp", { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_TCP }, @@ -3178,6 +3187,7 @@ static const struct connection_ops conn_protseq_list[] = { RPCRT4_default_impersonate_client, RPCRT4_default_revert_to_self, RPCRT4_default_inquire_auth_client, + NULL }, { "ncacn_http", { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_HTTP }, @@ -3200,6 +3210,7 @@ static const struct connection_ops conn_protseq_list[] = { RPCRT4_default_impersonate_client, RPCRT4_default_revert_to_self, RPCRT4_default_inquire_auth_client, + NULL }, };
diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index 7fdb076bc73..5fe803e5a1d 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -1140,16 +1140,13 @@ static DWORD CALLBACK test_I_RpcBindingInqLocalClientPID_thread_func(void *args) winetest_push_context("%s", client_test_name);
status = I_RpcBindingInqLocalClientPID(NULL, &pid); - todo_wine ok(status == RPC_S_NO_CALL_ACTIVE, "Got unexpected %ld.\n", status);
/* Other protocol sequences throw exceptions */ if (params->protseq == RPC_PROTSEQ_LRPC) { status = I_RpcBindingInqLocalClientPID(params->binding, &pid); - todo_wine ok(status == RPC_S_OK, "Got unexpected %ld.\n", status); - todo_wine ok(pid == client_info.dwProcessId, "Got unexpected pid.\n"); }
@@ -1179,9 +1176,7 @@ void __cdecl s_test_I_RpcBindingInqLocalClientPID(unsigned int protseq, RPC_BIND status = I_RpcBindingInqLocalClientPID(NULL, &pid); if (protseq == RPC_PROTSEQ_LRPC) { - todo_wine ok(status == RPC_S_OK, "Got unexpected %ld.\n", status); - todo_wine ok(pid == client_info.dwProcessId, "Got unexpected pid.\n"); } else @@ -1192,9 +1187,7 @@ void __cdecl s_test_I_RpcBindingInqLocalClientPID(unsigned int protseq, RPC_BIND if (protseq == RPC_PROTSEQ_LRPC) /* Other protocol sequences throw exceptions */ { status = I_RpcBindingInqLocalClientPID(binding, &pid); - todo_wine ok(status == RPC_S_OK, "Got unexpected %ld.\n", status); - todo_wine ok(pid == client_info.dwProcessId, "Got unexpected pid.\n"); }
Huw Davies (@huw) commented about dlls/rpcrt4/rpc_binding.h:
void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection) DECLSPEC_HIDDEN; void RPCRT4_SetThreadCurrentCallHandle(RpcBinding *Binding) DECLSPEC_HIDDEN; RpcBinding *RPCRT4_GetThreadCurrentCallHandle(void) DECLSPEC_HIDDEN; +RpcConnection *RPCRT4_GetThreadCurrentConnection(void) DECLSPEC_HIDDEN;
This doesn't seem to exist.