* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "precomp.h"
+#include "config.h"
+#include "wine/port.h"
-#include <winsvc.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winsvc.h"
+#include "objbase.h"
+#include "ole2.h"
+#include "rpc.h"
+#include "winerror.h"
+#include "winreg.h"
+#include "servprov.h"
+#include "wine/unicode.h"
+
+#include "compobj_private.h"
+
+#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
OXID oxid; /* apartment in which the channel is valid */
DWORD server_pid; /* id of server process */
HANDLE event; /* cached event handle */
+ IID iid; /* IID of the proxy this belongs to */
} ClientRpcChannelBuffer;
struct dispatch_params
cif->Length = sizeof(RPC_CLIENT_INTERFACE);
/* RPC interface ID = COM interface ID */
- cif->InterfaceId.SyntaxGUID = *riid;
+ cif->InterfaceId.SyntaxGUID = This->iid;
/* COM objects always have a version of 0.0 */
cif->InterfaceId.SyntaxVersion.MajorVersion = 0;
cif->InterfaceId.SyntaxVersion.MinorVersion = 0;
message_state->channel_hook_info.cbSize = sizeof(message_state->channel_hook_info);
message_state->channel_hook_info.uCausality = COM_CurrentCausalityId();
message_state->channel_hook_info.dwServerPid = This->server_pid;
- message_state->channel_hook_info.iMethod = msg->ProcNum;
+ message_state->channel_hook_info.iMethod = msg->ProcNum & ~RPC_FLAGS_VALID_BIT;
message_state->channel_hook_info.pObject = NULL; /* only present on server-side */
message_state->target_hwnd = NULL;
message_state->target_tid = 0;
}
RpcBindingInqObject(message_state->binding_handle, &ipid);
- hr = ipid_get_dispatch_params(&ipid, &apt, &message_state->params.stub,
+ hr = ipid_get_dispatch_params(&ipid, &apt, NULL, &message_state->params.stub,
&message_state->params.chan,
&message_state->params.iid,
&message_state->params.iface);
ORPC_EXTENT_ARRAY orpc_ext_array;
WIRE_ORPC_EXTENT *first_wire_orpc_extent = NULL;
HRESULT hrFault = S_OK;
+ APARTMENT *apt = apartment_get_current_or_mta();
TRACE("(%p) iMethod=%d\n", olemsg, olemsg->iMethod);
- hr = ClientRpcChannelBuffer_IsCorrectApartment(This, COM_CurrentApt());
+ hr = ClientRpcChannelBuffer_IsCorrectApartment(This, apt);
if (hr != S_OK)
{
ERR("called from wrong apartment, should have been 0x%s\n",
wine_dbgstr_longlong(This->oxid));
+ if (apt) apartment_release(apt);
return RPC_E_WRONG_THREAD;
}
/* This situation should be impossible in multi-threaded apartments,
* Note: doing a COM call during the processing of a sent message is
* only disallowed if a client call is already being waited for
* completion */
- if (!COM_CurrentApt()->multi_threaded &&
+ if (!apt->multi_threaded &&
COM_CurrentInfo()->pending_call_count_client &&
InSendMessage())
{
ERR("can't make an outgoing COM call in response to a sent message\n");
+ apartment_release(apt);
return RPC_E_CANTCALLOUT_ININPUTSYNCCALL;
}
TRACE("-- 0x%08x\n", hr);
+ apartment_release(apt);
return hr;
}
/* returns a channel buffer for proxies */
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
- const OXID_INFO *oxid_info,
+ const OXID_INFO *oxid_info, const IID *iid,
DWORD dest_context, void *dest_context_data,
- IRpcChannelBuffer **chan)
+ IRpcChannelBuffer **chan, APARTMENT *apt)
{
ClientRpcChannelBuffer *This;
WCHAR endpoint[200];
This->super.dest_context = dest_context;
This->super.dest_context_data = dest_context_data;
This->bind = bind;
- apartment_getoxid(COM_CurrentApt(), &This->oxid);
+ apartment_getoxid(apt, &This->oxid);
This->server_pid = oxid_info->dwPid;
This->event = NULL;
+ This->iid = *iid;
*chan = &This->super.IRpcChannelBuffer_iface;
static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)
{
struct dispatch_params *params;
+ struct stub_manager *stub_manager;
APARTMENT *apt;
IPID ipid;
HRESULT hr;
return;
}
- hr = ipid_get_dispatch_params(&ipid, &apt, ¶ms->stub, ¶ms->chan,
+ hr = ipid_get_dispatch_params(&ipid, &apt, &stub_manager, ¶ms->stub, ¶ms->chan,
¶ms->iid, ¶ms->iface);
if (hr != S_OK)
{
else
{
BOOL joined = FALSE;
- if (!COM_CurrentInfo()->apt)
+ struct oletls *info = COM_CurrentInfo();
+
+ if (!info->apt)
{
- apartment_joinmta();
+ enter_apartment(info, COINIT_MULTITHREADED);
joined = TRUE;
}
RPC_ExecuteCall(params);
if (joined)
{
- apartment_release(COM_CurrentInfo()->apt);
- COM_CurrentInfo()->apt = NULL;
+ leave_apartment(info);
}
}
IRpcStubBuffer_Release(params->stub);
HeapFree(GetProcessHeap(), 0, params);
+ stub_manager_int_release(stub_manager);
apartment_release(apt);
/* if IRpcStubBuffer_Invoke fails, we should raise an exception to tell
}
/* stub unregistration */
-void RPC_UnregisterInterface(REFIID riid)
+void RPC_UnregisterInterface(REFIID riid, BOOL wait)
{
struct registered_if *rif;
EnterCriticalSection(&csRegIf);
{
if (!--rif->refs)
{
- RpcServerUnregisterIf((RPC_IF_HANDLE)&rif->If, NULL, TRUE);
+ RpcServerUnregisterIf((RPC_IF_HANDLE)&rif->If, NULL, wait);
list_remove(&rif->entry);
HeapFree(GetProcessHeap(), 0, rif);
}
/* FIXME: move remote unknown exporting into this function */
}
- start_apartment_remote_unknown();
+ start_apartment_remote_unknown(apt);
}
static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };
HKEY key;
HRESULT hres;
- WCHAR command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)];
+ WCHAR command[MAX_PATH+ARRAY_SIZE(embedding)];
DWORD size = (MAX_PATH+1) * sizeof(WCHAR);
STARTUPINFOW sinfo;
PROCESS_INFORMATION pinfo;
{
static const WCHAR wszPipeRef[] = {'\\','\\','.','\\','p','i','p','e','\\',0};
strcpyW(pipefn, wszPipeRef);
- StringFromGUID2(rclsid, pipefn + sizeof(wszPipeRef)/sizeof(wszPipeRef[0]) - 1, CHARS_IN_GUID);
+ StringFromGUID2(rclsid, pipefn + ARRAY_SIZE(wszPipeRef) - 1, CHARS_IN_GUID);
}
/* FIXME: should call to rpcss instead */
bufferlen = 0;
if (!ReadFile(hPipe,marshalbuffer,sizeof(marshalbuffer),&bufferlen,NULL)) {
FIXME("Failed to read marshal id from classfactory of %s.\n",debugstr_guid(rclsid));
+ CloseHandle(hPipe);
Sleep(1000);
continue;
}