diff --git a/dlls/rpcrt4/rpcrt4.spec b/dlls/rpcrt4/rpcrt4.spec index 135beab0ff2..5a294df65ad 100644 --- a/dlls/rpcrt4/rpcrt4.spec +++ b/dlls/rpcrt4/rpcrt4.spec @@ -389,7 +389,7 @@ @ stub RpcFreeAuthorizationContext # wxp @ stdcall RpcGetAsyncCallStatus(ptr) RpcAsyncGetCallStatus @ stub RpcIfIdVectorFree -@ stub RpcIfInqId +@ stdcall RpcIfInqId(ptr ptr) @ stdcall RpcImpersonateClient(ptr) @ stdcall RpcInitializeAsyncHandle(ptr long) RpcAsyncInitializeHandle @ stdcall RpcMgmtEnableIdleCleanup() diff --git a/dlls/rpcrt4/rpcrt4_main.c b/dlls/rpcrt4/rpcrt4_main.c index e716f7cfff2..57e33673c7a 100644 --- a/dlls/rpcrt4/rpcrt4_main.c +++ b/dlls/rpcrt4/rpcrt4_main.c @@ -95,6 +95,12 @@ struct threaddata struct context_handle_list *context_handle_list; }; +struct interface_header +{ + unsigned int length; + RPC_SYNTAX_IDENTIFIER id; +}; + /*********************************************************************** * DllMain * @@ -178,6 +184,25 @@ RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR* String) return RPC_S_OK; } +/************************************************************************* + * RpcIfInqId [RPCRT4.@] + * + * Get interface UUID and version. + */ +RPC_STATUS WINAPI RpcIfInqId(RPC_IF_HANDLE if_handle, RPC_IF_ID *if_id) +{ + struct interface_header *header = (struct interface_header *)if_handle; + + TRACE("(%p,%p)\n", if_handle, if_id); + + if_id->Uuid = header->id.SyntaxGUID; + if_id->VersMajor = header->id.SyntaxVersion.MajorVersion; + if_id->VersMinor = header->id.SyntaxVersion.MinorVersion; + TRACE("UUID:%s VersMajor:%hu VersMinor:%hu.\n", debugstr_guid(&if_id->Uuid), if_id->VersMajor, + if_id->VersMinor); + return RPC_S_OK; +} + /************************************************************************* * RpcRaiseException [RPCRT4.@] * diff --git a/dlls/rpcrt4/tests/rpc.c b/dlls/rpcrt4/tests/rpc.c index d3a3aee6c8c..ce16145119b 100644 --- a/dlls/rpcrt4/tests/rpc.c +++ b/dlls/rpcrt4/tests/rpc.c @@ -854,6 +854,55 @@ static void test_RpcBindingFree(void) status); } +static void test_RpcIfInqId(void) +{ + static const GUID guid = {0x12345678, 0xdead, 0xbeef, {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}}; + static RPC_STATUS (WINAPI *pRpcIfInqId)(RPC_IF_HANDLE, RPC_IF_ID *); + RPC_SERVER_INTERFACE server_interface; + RPC_CLIENT_INTERFACE client_interface; + RPC_IF_HANDLE test_handles[2]; + RPC_STATUS status; + RPC_IF_ID if_id; + UINT test_idx; + + pRpcIfInqId = (void *)GetProcAddress(GetModuleHandleA("rpcrt4.dll"), "RpcIfInqId"); + + memset(&server_interface, 0, sizeof(server_interface)); + memset(&client_interface, 0, sizeof(client_interface)); + server_interface.InterfaceId.SyntaxGUID = guid; + server_interface.InterfaceId.SyntaxVersion.MajorVersion = 1; + server_interface.InterfaceId.SyntaxVersion.MinorVersion = 2; + client_interface.InterfaceId.SyntaxGUID = guid; + client_interface.InterfaceId.SyntaxVersion.MajorVersion = 1; + client_interface.InterfaceId.SyntaxVersion.MinorVersion = 2; + + /* Crash on Windows */ + if (0) + { + status = pRpcIfInqId(NULL, &if_id); + ok(status == RPC_S_INVALID_ARG, "Expected %#x, got %#x.\n", RPC_S_INVALID_ARG, status); + + status = pRpcIfInqId((RPC_IF_HANDLE)&server_interface, NULL); + ok(status == RPC_S_INVALID_ARG, "Expected %#x, got %#x.\n", RPC_S_INVALID_ARG, status); + } + + test_handles[0] = (RPC_IF_HANDLE)&server_interface; + test_handles[1] = (RPC_IF_HANDLE)&client_interface; + + for (test_idx = 0; test_idx < ARRAY_SIZE(test_handles); ++test_idx) + { + memset(&if_id, 0, sizeof(if_id)); + status = pRpcIfInqId(test_handles[test_idx], &if_id); + ok(status == RPC_S_OK, "Test %u: Expected %#x, got %#x.\n", test_idx, RPC_S_OK, status); + ok(!memcmp(&if_id.Uuid, &guid, sizeof(guid)), "Test %u: Expected UUID %s, got %s.\n", test_idx, + wine_dbgstr_guid(&guid), wine_dbgstr_guid(&if_id.Uuid)); + ok(if_id.VersMajor == 1, "Test %u: Expected major version %hu, got %hu.\n", test_idx, 1, + if_id.VersMajor); + ok(if_id.VersMinor == 2, "Test %u: Expected minor version %hu, got %hu.\n", test_idx, 2, + if_id.VersMinor); + } +} + static void test_RpcServerInqDefaultPrincName(void) { RPC_STATUS ret; @@ -1204,6 +1253,7 @@ START_TEST( rpc ) test_UuidCreate(); test_UuidCreateSequential(); test_RpcBindingFree(); + test_RpcIfInqId(); test_RpcServerInqDefaultPrincName(); test_RpcServerRegisterAuthInfo(); diff --git a/include/rpcdce.h b/include/rpcdce.h index fc1fcea77b9..2b289b26550 100644 --- a/include/rpcdce.h +++ b/include/rpcdce.h @@ -593,6 +593,9 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RpcStringFreeW(RPC_WSTR* String); #define RpcStringFree WINELIB_NAME_AW(RpcStringFree) +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcIfInqId( RPC_IF_HANDLE RpcIfHandle, RPC_IF_ID *RpcIfId ); + RPCRTAPI RPC_STATUS RPC_ENTRY UuidToStringA( UUID* Uuid, RPC_CSTR* StringUuid ); RPCRTAPI RPC_STATUS RPC_ENTRY