Rob Shearman : ole32: Shortcut the RPC runtime for allocation of the message when processing the COM call by just sending a message to a window in the process .
Alexandre Julliard
julliard at winehq.org
Mon Jan 7 16:24:59 CST 2008
Module: wine
Branch: master
Commit: b6553e7e297fc234aaaa632ff84ab4936c544292
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b6553e7e297fc234aaaa632ff84ab4936c544292
Author: Rob Shearman <rob at codeweavers.com>
Date: Mon Jan 7 17:14:54 2008 +0000
ole32: Shortcut the RPC runtime for allocation of the message when processing the COM call by just sending a message to a window in the process.
---
dlls/ole32/rpc.c | 50 +++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c
index 2ee8a9c..ad6a39f 100644
--- a/dlls/ole32/rpc.c
+++ b/dlls/ole32/rpc.c
@@ -118,6 +118,7 @@ struct dispatch_params
IID iid; /* ID of interface being called */
IUnknown *iface; /* interface being called */
HANDLE handle; /* handle that will become signaled when call finishes */
+ BOOL bypass_rpcrt; /* bypass RPC runtime? */
RPC_STATUS status; /* status (out) */
HRESULT hr; /* hresult (out) */
};
@@ -127,6 +128,7 @@ struct message_state
RPC_BINDING_HANDLE binding_handle;
ULONG prefix_data_len;
SChannelHookCallInfo channel_hook_info;
+ BOOL bypass_rpcrt;
/* client only */
HWND target_hwnd;
@@ -513,7 +515,16 @@ static HRESULT WINAPI ServerRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
msg->BufferLength += FIELD_OFFSET(WIRE_ORPC_EXTENT, data[0]);
}
- status = I_RpcGetBuffer(msg);
+ if (message_state->bypass_rpcrt)
+ {
+ msg->Buffer = HeapAlloc(GetProcessHeap(), 0, msg->BufferLength);
+ if (msg->Buffer)
+ status = RPC_S_OK;
+ else
+ status = ERROR_OUTOFMEMORY;
+ }
+ else
+ status = I_RpcGetBuffer(msg);
orpcthat = (ORPCTHAT *)msg->Buffer;
msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(ORPCTHAT, extensions);
@@ -663,6 +674,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
}
else
{
+ message_state->params.bypass_rpcrt = TRUE;
message_state->target_hwnd = apartment_getwindow(apt);
message_state->target_tid = apt->tid;
/* we assume later on that this being non-NULL is the indicator that
@@ -676,7 +688,17 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
/* Note: message_state->params.msg is initialised in
* ClientRpcChannelBuffer_SendReceive */
- status = I_RpcGetBuffer(msg);
+ /* shortcut the RPC runtime */
+ if (message_state->target_hwnd)
+ {
+ msg->Buffer = HeapAlloc(GetProcessHeap(), 0, msg->BufferLength);
+ if (msg->Buffer)
+ status = RPC_S_OK;
+ else
+ status = ERROR_OUTOFMEMORY;
+ }
+ else
+ status = I_RpcGetBuffer(msg);
msg->Handle = message_state;
@@ -817,7 +839,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER ifac
* from DllMain */
message_state->params.msg = olemsg;
- if (message_state->target_hwnd)
+ if (message_state->params.bypass_rpcrt)
{
TRACE("Calling apartment thread 0x%08x...\n", message_state->target_tid);
@@ -939,7 +961,13 @@ static HRESULT WINAPI ServerRpcChannelBuffer_FreeBuffer(LPRPCCHANNELBUFFER iface
msg->BufferLength += message_state->prefix_data_len;
message_state->prefix_data_len = 0;
- status = I_RpcFreeBuffer(msg);
+ if (message_state->bypass_rpcrt)
+ {
+ HeapFree(GetProcessHeap(), 0, msg->Buffer);
+ status = RPC_S_OK;
+ }
+ else
+ status = I_RpcFreeBuffer(msg);
msg->Handle = message_state;
@@ -962,7 +990,13 @@ static HRESULT WINAPI ClientRpcChannelBuffer_FreeBuffer(LPRPCCHANNELBUFFER iface
msg->Buffer = (char *)msg->Buffer - message_state->prefix_data_len;
msg->BufferLength += message_state->prefix_data_len;
- status = I_RpcFreeBuffer(msg);
+ if (message_state->params.bypass_rpcrt)
+ {
+ HeapFree(GetProcessHeap(), 0, msg->Buffer);
+ status = RPC_S_OK;
+ }
+ else
+ status = I_RpcFreeBuffer(msg);
HeapFree(GetProcessHeap(), 0, msg->RpcInterfaceInformation);
msg->RpcInterfaceInformation = NULL;
@@ -1286,6 +1320,7 @@ void RPC_ExecuteCall(struct dispatch_params *params)
message_state->prefix_data_len = (char *)msg->Buffer - original_buffer;
message_state->binding_handle = msg->Handle;
+ message_state->bypass_rpcrt = params->bypass_rpcrt;
message_state->channel_hook_info.iid = params->iid;
message_state->channel_hook_info.cbSize = sizeof(message_state->channel_hook_info);
@@ -1357,6 +1392,10 @@ void RPC_ExecuteCall(struct dispatch_params *params)
COM_CurrentInfo()->pending_call_count_server--;
COM_CurrentInfo()->causality_id = old_causality_id;
+ /* the invoke allocated a new buffer, so free the old one */
+ if (message_state->bypass_rpcrt && original_buffer != msg->Buffer)
+ HeapFree(GetProcessHeap(), 0, original_buffer);
+
exit_reset_state:
message_state = (struct message_state *)msg->Handle;
msg->Handle = message_state->binding_handle;
@@ -1400,6 +1439,7 @@ static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)
params->status = RPC_S_OK;
params->hr = S_OK;
params->handle = NULL;
+ params->bypass_rpcrt = FALSE;
/* Note: this is the important difference between STAs and MTAs - we
* always execute RPCs to STAs in the thread that originally created the
More information about the wine-cvs
mailing list