rpcrt4: Implement RpcServerUnregisterIf.
This commit is contained in:
parent
0b1cc1061b
commit
29a9abff8a
|
@ -133,7 +133,10 @@ static RpcServerInterface* RPCRT4_find_interface(UUID* object,
|
||||||
LIST_FOR_EACH_ENTRY(cif, &server_interfaces, RpcServerInterface, entry) {
|
LIST_FOR_EACH_ENTRY(cif, &server_interfaces, RpcServerInterface, entry) {
|
||||||
if (!memcmp(if_id, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER)) &&
|
if (!memcmp(if_id, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER)) &&
|
||||||
(check_object == FALSE || UuidEqual(MgrType, &cif->MgrTypeUuid, &status)) &&
|
(check_object == FALSE || UuidEqual(MgrType, &cif->MgrTypeUuid, &status)) &&
|
||||||
std_listen) break;
|
std_listen) {
|
||||||
|
InterlockedIncrement(&cif->CurrentCalls);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&server_cs);
|
LeaveCriticalSection(&server_cs);
|
||||||
if (&cif->entry == &server_interfaces) cif = NULL;
|
if (&cif->entry == &server_interfaces) cif = NULL;
|
||||||
|
@ -141,6 +144,17 @@ static RpcServerInterface* RPCRT4_find_interface(UUID* object,
|
||||||
return cif;
|
return cif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void RPCRT4_release_server_interface(RpcServerInterface *sif)
|
||||||
|
{
|
||||||
|
if (!InterlockedDecrement(&sif->CurrentCalls) &&
|
||||||
|
sif->CallsCompletedEvent) {
|
||||||
|
/* sif must have been removed from server_interfaces before
|
||||||
|
* CallsCompletedEvent is set */
|
||||||
|
SetEvent(sif->CallsCompletedEvent);
|
||||||
|
HeapFree(GetProcessHeap(), 0, sif);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static WINE_EXCEPTION_FILTER(rpc_filter)
|
static WINE_EXCEPTION_FILTER(rpc_filter)
|
||||||
{
|
{
|
||||||
WARN("exception caught with code 0x%08x = %d\n", GetExceptionCode(), GetExceptionCode());
|
WARN("exception caught with code 0x%08x = %d\n", GetExceptionCode(), GetExceptionCode());
|
||||||
|
@ -190,6 +204,8 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
||||||
/* save the interface for later use */
|
/* save the interface for later use */
|
||||||
conn->ActiveInterface = hdr->bind.abstract;
|
conn->ActiveInterface = hdr->bind.abstract;
|
||||||
conn->MaxTransmissionSize = hdr->bind.max_tsize;
|
conn->MaxTransmissionSize = hdr->bind.max_tsize;
|
||||||
|
|
||||||
|
RPCRT4_release_server_interface(sif);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = RPCRT4_Send(conn, response, NULL, 0);
|
status = RPCRT4_Send(conn, response, NULL, 0);
|
||||||
|
@ -219,6 +235,10 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
||||||
}
|
}
|
||||||
|
|
||||||
sif = RPCRT4_find_interface(object_uuid, &conn->ActiveInterface, TRUE);
|
sif = RPCRT4_find_interface(object_uuid, &conn->ActiveInterface, TRUE);
|
||||||
|
if (!sif) {
|
||||||
|
/* FIXME: send fault packet? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
msg->RpcInterfaceInformation = sif->If;
|
msg->RpcInterfaceInformation = sif->If;
|
||||||
/* copy the endpoint vector from sif to msg so that midl-generated code will use it */
|
/* copy the endpoint vector from sif to msg so that midl-generated code will use it */
|
||||||
msg->ManagerEpv = sif->MgrEpv;
|
msg->ManagerEpv = sif->MgrEpv;
|
||||||
|
@ -262,6 +282,7 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
||||||
I_RpcSend(msg);
|
I_RpcSend(msg);
|
||||||
|
|
||||||
msg->RpcInterfaceInformation = NULL;
|
msg->RpcInterfaceInformation = NULL;
|
||||||
|
RPCRT4_release_server_interface(sif);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -798,8 +819,45 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid,
|
||||||
*/
|
*/
|
||||||
RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete )
|
RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete )
|
||||||
{
|
{
|
||||||
FIXME("(IfSpec == (RPC_IF_HANDLE)^%p, MgrTypeUuid == %s, WaitForCallsToComplete == %u): stub\n",
|
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||||
IfSpec, debugstr_guid(MgrTypeUuid), WaitForCallsToComplete);
|
HANDLE event = NULL;
|
||||||
|
BOOL found = FALSE;
|
||||||
|
BOOL completed = TRUE;
|
||||||
|
RpcServerInterface *cif;
|
||||||
|
RPC_STATUS status;
|
||||||
|
|
||||||
|
TRACE("(IfSpec == (RPC_IF_HANDLE)^%p (%s), MgrTypeUuid == %s, WaitForCallsToComplete == %u)\n",
|
||||||
|
IfSpec, debugstr_guid(&If->InterfaceId.SyntaxGUID), debugstr_guid(MgrTypeUuid), WaitForCallsToComplete);
|
||||||
|
|
||||||
|
EnterCriticalSection(&server_cs);
|
||||||
|
LIST_FOR_EACH_ENTRY(cif, &server_interfaces, RpcServerInterface, entry) {
|
||||||
|
if (!memcmp(&If->InterfaceId, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER)) &&
|
||||||
|
UuidEqual(MgrTypeUuid, &cif->MgrTypeUuid, &status)) {
|
||||||
|
list_remove(&cif->entry);
|
||||||
|
if (cif->CurrentCalls) {
|
||||||
|
completed = FALSE;
|
||||||
|
if (WaitForCallsToComplete)
|
||||||
|
cif->CallsCompletedEvent = event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
|
}
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(&server_cs);
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
ERR("not found for object %s\n", debugstr_guid(MgrTypeUuid));
|
||||||
|
return RPC_S_UNKNOWN_IF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (completed)
|
||||||
|
HeapFree(GetProcessHeap(), 0, cif);
|
||||||
|
else if (event) {
|
||||||
|
/* sif will be freed when the last call is completed, so be careful not to
|
||||||
|
* touch that memory here as that could happen before we get here */
|
||||||
|
WaitForSingleObject(event, INFINITE);
|
||||||
|
CloseHandle(event);
|
||||||
|
}
|
||||||
|
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,10 @@ typedef struct _RpcServerInterface
|
||||||
UINT MaxCalls;
|
UINT MaxCalls;
|
||||||
UINT MaxRpcSize;
|
UINT MaxRpcSize;
|
||||||
RPC_IF_CALLBACK_FN* IfCallbackFn;
|
RPC_IF_CALLBACK_FN* IfCallbackFn;
|
||||||
|
LONG CurrentCalls; /* number of calls currently executing */
|
||||||
|
/* set when unregistering interface to let the caller of
|
||||||
|
* RpcServerUnregisterIf* know that all calls have finished */
|
||||||
|
HANDLE CallsCompletedEvent;
|
||||||
} RpcServerInterface;
|
} RpcServerInterface;
|
||||||
|
|
||||||
void RPCRT4_new_client(RpcConnection* conn);
|
void RPCRT4_new_client(RpcConnection* conn);
|
||||||
|
|
Loading…
Reference in New Issue