ReactOS  0.4.14-dev-608-gd495a4f
rpc.c
Go to the documentation of this file.
1 /*
2  * RPC Manager
3  *
4  * Copyright 2001 Ove K√•ven, TransGaming Technologies
5  * Copyright 2002 Marcus Meissner
6  * Copyright 2005 Mike Hearn, Rob Shearman for CodeWeavers
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include <stdarg.h>
24 #include <string.h>
25 
26 #define COBJMACROS
27 #define NONAMELESSUNION
28 
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "winsvc.h"
33 #include "objbase.h"
34 #include "ole2.h"
35 #include "rpc.h"
36 #include "winerror.h"
37 #include "winreg.h"
38 #include "servprov.h"
39 
40 #include "compobj_private.h"
41 
42 #include "wine/debug.h"
43 
45 
47 
48 /* we only use one function to dispatch calls for all methods - we use the
49  * RPC_IF_OLE flag to tell the RPC runtime that this is the case */
52 
53 static struct list registered_interfaces = LIST_INIT(registered_interfaces); /* (CS csRegIf) */
56 {
57  0, 0, &csRegIf,
59  0, 0, { (DWORD_PTR)(__FILE__ ": dcom registered server interfaces") }
60 };
61 static CRITICAL_SECTION csRegIf = { &csRegIf_debug, -1, 0, 0, 0, 0 };
62 
63 static struct list channel_hooks = LIST_INIT(channel_hooks); /* (CS csChannelHook) */
66 {
67  0, 0, &csChannelHook,
69  0, 0, { (DWORD_PTR)(__FILE__ ": channel hooks") }
70 };
71 static CRITICAL_SECTION csChannelHook = { &csChannelHook_debug, -1, 0, 0, 0, 0 };
72 
73 static WCHAR wszRpcTransport[] = {'n','c','a','l','r','p','c',0};
74 
75 
77 {
78  struct list entry;
79  DWORD refs; /* ref count */
80  RPC_SERVER_INTERFACE If; /* interface registered with the RPC runtime */
81 };
82 
83 /* get the pipe endpoint specified of the specified apartment */
84 static inline void get_rpc_endpoint(LPWSTR endpoint, const OXID *oxid)
85 {
86  /* FIXME: should get endpoint from rpcss */
87  static const WCHAR wszEndpointFormat[] = {'\\','p','i','p','e','\\','O','L','E','_','%','0','8','l','x','%','0','8','l','x',0};
88  wsprintfW(endpoint, wszEndpointFormat, (DWORD)(*oxid >> 32),(DWORD)*oxid);
89 }
90 
91 typedef struct
92 {
95 
96  DWORD dest_context; /* returned from GetDestCtx */
97  void *dest_context_data; /* returned from GetDestCtx */
99 
100 typedef struct
101 {
102  RpcChannelBuffer super; /* superclass */
103 
104  RPC_BINDING_HANDLE bind; /* handle to the remote server */
105  OXID oxid; /* apartment in which the channel is valid */
106  DWORD server_pid; /* id of server process */
107  HANDLE event; /* cached event handle */
108  IID iid; /* IID of the proxy this belongs to */
110 
112 {
113  RPCOLEMESSAGE *msg; /* message */
114  IRpcStubBuffer *stub; /* stub buffer, if applicable */
115  IRpcChannelBuffer *chan; /* server channel buffer, if applicable */
116  IID iid; /* ID of interface being called */
117  IUnknown *iface; /* interface being called */
118  HANDLE handle; /* handle that will become signaled when call finishes */
119  BOOL bypass_rpcrt; /* bypass RPC runtime? */
120  RPC_STATUS status; /* status (out) */
121  HRESULT hr; /* hresult (out) */
122 };
123 
125 {
128  SChannelHookCallInfo channel_hook_info;
130 
131  /* client only */
135 };
136 
137 typedef struct
138 {
139  ULONG conformance; /* NDR */
142  /* [size_is((size+7)&~7)] */ unsigned char data[1];
144 
145 typedef struct
146 {
149  unsigned char extent[1];
151 
152 typedef struct
153 {
158  unsigned char extensions[1];
159 } WIRE_ORPCTHIS;
160 
161 typedef struct
162 {
164  unsigned char extensions[1];
165 } WIRE_ORPCTHAT;
166 
168 {
169  struct list entry;
172 };
173 
175 {
178 };
179 
180 
181 static HRESULT unmarshal_ORPCTHAT(RPC_MESSAGE *msg, ORPCTHAT *orpcthat,
182  ORPC_EXTENT_ARRAY *orpc_ext_array, WIRE_ORPC_EXTENT **first_wire_orpc_extent);
183 
184 /* Channel Hook Functions */
185 
186 static ULONG ChannelHooks_ClientGetSize(SChannelHookCallInfo *info,
187  struct channel_hook_buffer_data **data, unsigned int *hook_count,
188  ULONG *extension_count)
189 {
190  struct channel_hook_entry *entry;
191  ULONG total_size = 0;
192  unsigned int hook_index = 0;
193 
194  *hook_count = 0;
195  *extension_count = 0;
196 
198 
200  (*hook_count)++;
201 
202  if (*hook_count)
203  *data = HeapAlloc(GetProcessHeap(), 0, *hook_count * sizeof(struct channel_hook_buffer_data));
204  else
205  *data = NULL;
206 
208  {
209  ULONG extension_size = 0;
210 
211  IChannelHook_ClientGetSize(entry->hook, &entry->id, &info->iid, &extension_size);
212 
213  TRACE("%s: extension_size = %u\n", debugstr_guid(&entry->id), extension_size);
214 
215  extension_size = (extension_size+7)&~7;
216  (*data)[hook_index].id = entry->id;
217  (*data)[hook_index].extension_size = extension_size;
218 
219  /* an extension is only put onto the wire if it has data to write */
220  if (extension_size)
221  {
222  total_size += FIELD_OFFSET(WIRE_ORPC_EXTENT, data[extension_size]);
223  (*extension_count)++;
224  }
225 
226  hook_index++;
227  }
228 
230 
231  return total_size;
232 }
233 
234 static unsigned char * ChannelHooks_ClientFillBuffer(SChannelHookCallInfo *info,
235  unsigned char *buffer, struct channel_hook_buffer_data *data,
236  unsigned int hook_count)
237 {
238  struct channel_hook_entry *entry;
239 
241 
243  {
244  unsigned int i;
245  ULONG extension_size = 0;
246  WIRE_ORPC_EXTENT *wire_orpc_extent = (WIRE_ORPC_EXTENT *)buffer;
247 
248  for (i = 0; i < hook_count; i++)
249  if (IsEqualGUID(&entry->id, &data[i].id))
250  extension_size = data[i].extension_size;
251 
252  /* an extension is only put onto the wire if it has data to write */
253  if (!extension_size)
254  continue;
255 
256  IChannelHook_ClientFillBuffer(entry->hook, &entry->id, &info->iid,
257  &extension_size, buffer + FIELD_OFFSET(WIRE_ORPC_EXTENT, data[0]));
258 
259  TRACE("%s: extension_size = %u\n", debugstr_guid(&entry->id), extension_size);
260 
261  /* FIXME: set unused portion of wire_orpc_extent->data to 0? */
262 
263  wire_orpc_extent->conformance = (extension_size+7)&~7;
264  wire_orpc_extent->size = extension_size;
265  wire_orpc_extent->id = entry->id;
266  buffer += FIELD_OFFSET(WIRE_ORPC_EXTENT, data[wire_orpc_extent->conformance]);
267  }
268 
270 
271  return buffer;
272 }
273 
274 static void ChannelHooks_ServerNotify(SChannelHookCallInfo *info,
275  DWORD lDataRep, WIRE_ORPC_EXTENT *first_wire_orpc_extent,
276  ULONG extension_count)
277 {
278  struct channel_hook_entry *entry;
279  ULONG i;
280 
282 
284  {
285  WIRE_ORPC_EXTENT *wire_orpc_extent;
286  for (i = 0, wire_orpc_extent = first_wire_orpc_extent;
287  i < extension_count;
288  i++, wire_orpc_extent = (WIRE_ORPC_EXTENT *)&wire_orpc_extent->data[wire_orpc_extent->conformance])
289  {
290  if (IsEqualGUID(&entry->id, &wire_orpc_extent->id))
291  break;
292  }
293  if (i == extension_count) wire_orpc_extent = NULL;
294 
295  IChannelHook_ServerNotify(entry->hook, &entry->id, &info->iid,
296  wire_orpc_extent ? wire_orpc_extent->size : 0,
297  wire_orpc_extent ? wire_orpc_extent->data : NULL,
298  lDataRep);
299  }
300 
302 }
303 
304 static ULONG ChannelHooks_ServerGetSize(SChannelHookCallInfo *info,
305  struct channel_hook_buffer_data **data, unsigned int *hook_count,
306  ULONG *extension_count)
307 {
308  struct channel_hook_entry *entry;
309  ULONG total_size = 0;
310  unsigned int hook_index = 0;
311 
312  *hook_count = 0;
313  *extension_count = 0;
314 
316 
318  (*hook_count)++;
319 
320  if (*hook_count)
321  *data = HeapAlloc(GetProcessHeap(), 0, *hook_count * sizeof(struct channel_hook_buffer_data));
322  else
323  *data = NULL;
324 
326  {
327  ULONG extension_size = 0;
328 
329  IChannelHook_ServerGetSize(entry->hook, &entry->id, &info->iid, S_OK,
330  &extension_size);
331 
332  TRACE("%s: extension_size = %u\n", debugstr_guid(&entry->id), extension_size);
333 
334  extension_size = (extension_size+7)&~7;
335  (*data)[hook_index].id = entry->id;
336  (*data)[hook_index].extension_size = extension_size;
337 
338  /* an extension is only put onto the wire if it has data to write */
339  if (extension_size)
340  {
341  total_size += FIELD_OFFSET(WIRE_ORPC_EXTENT, data[extension_size]);
342  (*extension_count)++;
343  }
344 
345  hook_index++;
346  }
347 
349 
350  return total_size;
351 }
352 
353 static unsigned char * ChannelHooks_ServerFillBuffer(SChannelHookCallInfo *info,
354  unsigned char *buffer, struct channel_hook_buffer_data *data,
355  unsigned int hook_count)
356 {
357  struct channel_hook_entry *entry;
358 
360 
362  {
363  unsigned int i;
364  ULONG extension_size = 0;
365  WIRE_ORPC_EXTENT *wire_orpc_extent = (WIRE_ORPC_EXTENT *)buffer;
366 
367  for (i = 0; i < hook_count; i++)
368  if (IsEqualGUID(&entry->id, &data[i].id))
369  extension_size = data[i].extension_size;
370 
371  /* an extension is only put onto the wire if it has data to write */
372  if (!extension_size)
373  continue;
374 
375  IChannelHook_ServerFillBuffer(entry->hook, &entry->id, &info->iid,
376  &extension_size, buffer + FIELD_OFFSET(WIRE_ORPC_EXTENT, data[0]),
377  S_OK);
378 
379  TRACE("%s: extension_size = %u\n", debugstr_guid(&entry->id), extension_size);
380 
381  /* FIXME: set unused portion of wire_orpc_extent->data to 0? */
382 
383  wire_orpc_extent->conformance = (extension_size+7)&~7;
384  wire_orpc_extent->size = extension_size;
385  wire_orpc_extent->id = entry->id;
386  buffer += FIELD_OFFSET(WIRE_ORPC_EXTENT, data[wire_orpc_extent->conformance]);
387  }
388 
390 
391  return buffer;
392 }
393 
394 static void ChannelHooks_ClientNotify(SChannelHookCallInfo *info,
395  DWORD lDataRep, WIRE_ORPC_EXTENT *first_wire_orpc_extent,
396  ULONG extension_count, HRESULT hrFault)
397 {
398  struct channel_hook_entry *entry;
399  ULONG i;
400 
402 
404  {
405  WIRE_ORPC_EXTENT *wire_orpc_extent;
406  for (i = 0, wire_orpc_extent = first_wire_orpc_extent;
407  i < extension_count;
408  i++, wire_orpc_extent = (WIRE_ORPC_EXTENT *)&wire_orpc_extent->data[wire_orpc_extent->conformance])
409  {
410  if (IsEqualGUID(&entry->id, &wire_orpc_extent->id))
411  break;
412  }
413  if (i == extension_count) wire_orpc_extent = NULL;
414 
415  IChannelHook_ClientNotify(entry->hook, &entry->id, &info->iid,
416  wire_orpc_extent ? wire_orpc_extent->size : 0,
417  wire_orpc_extent ? wire_orpc_extent->data : NULL,
418  lDataRep, hrFault);
419  }
420 
422 }
423 
425 {
426  struct channel_hook_entry *entry;
427 
428  TRACE("(%s, %p)\n", debugstr_guid(rguid), hook);
429 
430  entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
431  if (!entry)
432  return E_OUTOFMEMORY;
433 
434  entry->id = *rguid;
435  entry->hook = hook;
436  IChannelHook_AddRef(hook);
437 
439  list_add_tail(&channel_hooks, &entry->entry);
441 
442  return S_OK;
443 }
444 
446 {
447  struct channel_hook_entry *cursor;
448  struct channel_hook_entry *cursor2;
449 
456 }
457 
458 /* RPC Channel Buffer Functions */
459 
461 {
462  *ppv = NULL;
463  if (IsEqualIID(riid,&IID_IRpcChannelBuffer) || IsEqualIID(riid,&IID_IUnknown))
464  {
465  *ppv = iface;
466  IRpcChannelBuffer_AddRef(iface);
467  return S_OK;
468  }
469  return E_NOINTERFACE;
470 }
471 
473 {
475  return InterlockedIncrement(&This->refs);
476 }
477 
479 {
481  ULONG ref;
482 
483  ref = InterlockedDecrement(&This->refs);
484  if (ref)
485  return ref;
486 
488  return 0;
489 }
490 
492 {
494  ULONG ref;
495 
496  ref = InterlockedDecrement(&This->super.refs);
497  if (ref)
498  return ref;
499 
500  if (This->event) CloseHandle(This->event);
501  RpcBindingFree(&This->bind);
503  return 0;
504 }
505 
507 {
509  RPC_MESSAGE *msg = (RPC_MESSAGE *)olemsg;
511  ORPCTHAT *orpcthat;
513  ULONG extensions_size;
514  struct channel_hook_buffer_data *channel_hook_data;
515  unsigned int channel_hook_count;
516  ULONG extension_count;
517 
518  TRACE("(%p)->(%p,%s)\n", This, olemsg, debugstr_guid(riid));
519 
520  message_state = msg->Handle;
521  /* restore the binding handle and the real start of data */
522  msg->Handle = message_state->binding_handle;
523  msg->Buffer = (char *)msg->Buffer - message_state->prefix_data_len;
524 
526  &channel_hook_data, &channel_hook_count, &extension_count);
527 
528  msg->BufferLength += FIELD_OFFSET(WIRE_ORPCTHAT, extensions) + sizeof(DWORD);
529  if (extensions_size)
530  {
531  msg->BufferLength += FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent[2*sizeof(DWORD) + extensions_size]);
532  if (extension_count & 1)
533  msg->BufferLength += FIELD_OFFSET(WIRE_ORPC_EXTENT, data[0]);
534  }
535 
537  {
538  msg->Buffer = HeapAlloc(GetProcessHeap(), 0, msg->BufferLength);
539  if (msg->Buffer)
540  status = RPC_S_OK;
541  else
542  {
543  HeapFree(GetProcessHeap(), 0, channel_hook_data);
544  return E_OUTOFMEMORY;
545  }
546  }
547  else
549 
550  orpcthat = msg->Buffer;
551  msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPCTHAT, extensions);
552 
553  orpcthat->flags = ORPCF_NULL /* FIXME? */;
554 
555  /* NDR representation of orpcthat->extensions */
556  *(DWORD *)msg->Buffer = extensions_size ? 1 : 0;
557  msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
558 
559  if (extensions_size)
560  {
561  WIRE_ORPC_EXTENT_ARRAY *orpc_extent_array = msg->Buffer;
562  orpc_extent_array->size = extension_count;
563  orpc_extent_array->reserved = 0;
564  msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent);
565  /* NDR representation of orpc_extent_array->extent */
566  *(DWORD *)msg->Buffer = 1;
567  msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
568  /* NDR representation of [size_is] attribute of orpc_extent_array->extent */
569  *(DWORD *)msg->Buffer = (extension_count + 1) & ~1;
570  msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
571 
573  msg->Buffer, channel_hook_data, channel_hook_count);
574 
575  /* we must add a dummy extension if there is an odd extension
576  * count to meet the contract specified by the size_is attribute */
577  if (extension_count & 1)
578  {
579  WIRE_ORPC_EXTENT *wire_orpc_extent = msg->Buffer;
580  wire_orpc_extent->conformance = 0;
581  wire_orpc_extent->id = GUID_NULL;
582  wire_orpc_extent->size = 0;
583  msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPC_EXTENT, data[0]);
584  }
585  }
586 
587  HeapFree(GetProcessHeap(), 0, channel_hook_data);
588 
589  /* store the prefixed data length so that we can restore the real buffer
590  * later */
591  message_state->prefix_data_len = (char *)msg->Buffer - (char *)orpcthat;
592  msg->BufferLength -= message_state->prefix_data_len;
593  /* save away the message state again */
594  msg->Handle = message_state;
595 
596  TRACE("-- %d\n", status);
597 
598  return HRESULT_FROM_WIN32(status);
599 }
600 
602 {
603  HANDLE event = InterlockedExchangePointer(&This->event, NULL);
604 
605  /* Note: must be auto-reset event so we can reuse it without a call
606  * to ResetEvent */
607  if (!event) event = CreateEventW(NULL, FALSE, FALSE, NULL);
608 
609  return event;
610 }
611 
613 {
615  /* already a handle cached in This */
617 }
618 
620 {
622  RPC_MESSAGE *msg = (RPC_MESSAGE *)olemsg;
625  ORPCTHIS *orpcthis;
627  ULONG extensions_size;
628  struct channel_hook_buffer_data *channel_hook_data;
629  unsigned int channel_hook_count;
630  ULONG extension_count;
631  IPID ipid;
632  HRESULT hr;
633  APARTMENT *apt = NULL;
634 
635  TRACE("(%p)->(%p,%s)\n", This, olemsg, debugstr_guid(riid));
636 
638  if (!cif)
639  return E_OUTOFMEMORY;
640 
642  if (!message_state)
643  {
644  HeapFree(GetProcessHeap(), 0, cif);
645  return E_OUTOFMEMORY;
646  }
647 
648  cif->Length = sizeof(RPC_CLIENT_INTERFACE);
649  /* RPC interface ID = COM interface ID */
650  cif->InterfaceId.SyntaxGUID = This->iid;
651  /* COM objects always have a version of 0.0 */
654  msg->Handle = This->bind;
655  msg->RpcInterfaceInformation = cif;
656 
659 
663  message_state->channel_hook_info.dwServerPid = This->server_pid;
665  message_state->channel_hook_info.pObject = NULL; /* only present on server-side */
669 
671  &channel_hook_data, &channel_hook_count, &extension_count);
672 
673  msg->BufferLength += FIELD_OFFSET(WIRE_ORPCTHIS, extensions) + sizeof(DWORD);
674  if (extensions_size)
675  {
676  msg->BufferLength += FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent[2*sizeof(DWORD) + extensions_size]);
677  if (extension_count & 1)
678  msg->BufferLength += FIELD_OFFSET(WIRE_ORPC_EXTENT, data[0]);
679  }
680 
682  hr = ipid_get_dispatch_params(&ipid, &apt, NULL, &message_state->params.stub,
683  &message_state->params.chan,
684  &message_state->params.iid,
685  &message_state->params.iface);
686  if (hr == S_OK)
687  {
688  /* stub, chan, iface and iid are unneeded in multi-threaded case as we go
689  * via the RPC runtime */
690  if (apt->multi_threaded)
691  {
692  IRpcStubBuffer_Release(message_state->params.stub);
693  message_state->params.stub = NULL;
694  IRpcChannelBuffer_Release(message_state->params.chan);
695  message_state->params.chan = NULL;
696  message_state->params.iface = NULL;
697  }
698  else
699  {
700  message_state->params.bypass_rpcrt = TRUE;
702  message_state->target_tid = apt->tid;
703  /* we assume later on that this being non-NULL is the indicator that
704  * means call directly instead of going through RPC runtime */
706  ERR("window for apartment %s is NULL\n", wine_dbgstr_longlong(apt->oxid));
707  }
708  }
709  if (apt) apartment_release(apt);
711  /* Note: message_state->params.msg is initialised in
712  * ClientRpcChannelBuffer_SendReceive */
713 
714  /* shortcut the RPC runtime */
716  {
717  msg->Buffer = HeapAlloc(GetProcessHeap(), 0, msg->BufferLength);
718  if (msg->Buffer)
719  status = RPC_S_OK;
720  else
722  }
723  else
725 
726  msg->Handle = message_state;
727 
728  if (status == RPC_S_OK)
729  {
730  orpcthis = msg->Buffer;
731  msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPCTHIS, extensions);
732 
733  orpcthis->version.MajorVersion = COM_MAJOR_VERSION;
734  orpcthis->version.MinorVersion = COM_MINOR_VERSION;
735  orpcthis->flags = message_state->channel_hook_info.dwServerPid ? ORPCF_LOCAL : ORPCF_NULL;
736  orpcthis->reserved1 = 0;
737  orpcthis->cid = message_state->channel_hook_info.uCausality;
738 
739  /* NDR representation of orpcthis->extensions */
740  *(DWORD *)msg->Buffer = extensions_size ? 1 : 0;
741  msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
742 
743  if (extensions_size)
744  {
745  ORPC_EXTENT_ARRAY *orpc_extent_array = msg->Buffer;
746  orpc_extent_array->size = extension_count;
747  orpc_extent_array->reserved = 0;
748  msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent);
749  /* NDR representation of orpc_extent_array->extent */
750  *(DWORD *)msg->Buffer = 1;
751  msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
752  /* NDR representation of [size_is] attribute of orpc_extent_array->extent */
753  *(DWORD *)msg->Buffer = (extension_count + 1) & ~1;
754  msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
755 
757  msg->Buffer, channel_hook_data, channel_hook_count);
758 
759  /* we must add a dummy extension if there is an odd extension
760  * count to meet the contract specified by the size_is attribute */
761  if (extension_count & 1)
762  {
763  WIRE_ORPC_EXTENT *wire_orpc_extent = msg->Buffer;
764  wire_orpc_extent->conformance = 0;
765  wire_orpc_extent->id = GUID_NULL;
766  wire_orpc_extent->size = 0;
767  msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPC_EXTENT, data[0]);
768  }
769  }
770 
771  /* store the prefixed data length so that we can restore the real buffer
772  * pointer in ClientRpcChannelBuffer_SendReceive. */
773  message_state->prefix_data_len = (char *)msg->Buffer - (char *)orpcthis;
774  msg->BufferLength -= message_state->prefix_data_len;
775  }
776 
777  HeapFree(GetProcessHeap(), 0, channel_hook_data);
778 
779  TRACE("-- %d\n", status);
780 
781  return HRESULT_FROM_WIN32(status);
782 }
783 
784 static HRESULT WINAPI ServerRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus)
785 {
786  FIXME("stub\n");
787  return E_NOTIMPL;
788 }
789 
790 /* this thread runs an outgoing RPC */
792 {
793  struct dispatch_params *data = param;
794 
795  /* Note: I_RpcSendReceive doesn't raise exceptions like the higher-level
796  * RPC functions do */
797  data->status = I_RpcSendReceive((RPC_MESSAGE *)data->msg);
798 
799  TRACE("completed with status 0x%x\n", data->status);
800 
801  SetEvent(data->handle);
802 
803  return 0;
804 }
805 
807 {
808  OXID oxid;
809  if (!apt)
810  return S_FALSE;
811  if (apartment_getoxid(apt, &oxid) != S_OK)
812  return S_FALSE;
813  if (This->oxid != oxid)
814  return S_FALSE;
815  return S_OK;
816 }
817 
819 {
821  HRESULT hr;
822  RPC_MESSAGE *msg = (RPC_MESSAGE *)olemsg;
824  DWORD index;
826  ORPCTHAT orpcthat;
827  ORPC_EXTENT_ARRAY orpc_ext_array;
828  WIRE_ORPC_EXTENT *first_wire_orpc_extent = NULL;
829  HRESULT hrFault = S_OK;
831 
832  TRACE("(%p) iMethod=%d\n", olemsg, olemsg->iMethod);
833 
835  if (hr != S_OK)
836  {
837  ERR("called from wrong apartment, should have been 0x%s\n",
838  wine_dbgstr_longlong(This->oxid));
839  if (apt) apartment_release(apt);
840  return RPC_E_WRONG_THREAD;
841  }
842  /* This situation should be impossible in multi-threaded apartments,
843  * because the calling thread isn't re-enterable.
844  * Note: doing a COM call during the processing of a sent message is
845  * only disallowed if a client call is already being waited for
846  * completion */
847  if (!apt->multi_threaded &&
848  COM_CurrentInfo()->pending_call_count_client &&
849  InSendMessage())
850  {
851  ERR("can't make an outgoing COM call in response to a sent message\n");
852  apartment_release(apt);
854  }
855 
856  message_state = msg->Handle;
857  /* restore the binding handle and the real start of data */
858  msg->Handle = message_state->binding_handle;
859  msg->Buffer = (char *)msg->Buffer - message_state->prefix_data_len;
860  msg->BufferLength += message_state->prefix_data_len;
861 
862  /* Note: this is an optimization in the Microsoft OLE runtime that we need
863  * to copy, as shown by the test_no_couninitialize_client test. without
864  * short-circuiting the RPC runtime in the case below, the test will
865  * deadlock on the loader lock due to the RPC runtime needing to create
866  * a thread to process the RPC when this function is called indirectly
867  * from DllMain */
868 
869  message_state->params.msg = olemsg;
870  if (message_state->params.bypass_rpcrt)
871  {
872  TRACE("Calling apartment thread 0x%08x...\n", message_state->target_tid);
873 
874  msg->ProcNum &= ~RPC_FLAGS_VALID_BIT;
875 
878  {
879  ERR("PostMessage failed with error %u\n", GetLastError());
880 
881  /* Note: message_state->params.iface doesn't have a reference and
882  * so doesn't need to be released */
883 
885  }
886  }
887  else
888  {
889  /* we use a separate thread here because we need to be able to
890  * pump the message loop in the application thread: if we do not,
891  * any windows created by this thread will hang and RPCs that try
892  * and re-enter this STA from an incoming server thread will
893  * deadlock. InstallShield is an example of that.
894  */
896  {
897  ERR("QueueUserWorkItem failed with error %u\n", GetLastError());
898  hr = E_UNEXPECTED;
899  }
900  else
901  hr = S_OK;
902  }
903 
904  if (hr == S_OK)
905  {
906  if (WaitForSingleObject(message_state->params.handle, 0))
907  {
908  COM_CurrentInfo()->pending_call_count_client++;
910  COM_CurrentInfo()->pending_call_count_client--;
911  }
912  }
914 
915  /* for WM shortcut, faults are returned in params->hr */
916  if (hr == S_OK)
917  hrFault = message_state->params.hr;
918 
919  status = message_state->params.status;
920 
921  orpcthat.flags = ORPCF_NULL;
922  orpcthat.extensions = NULL;
923 
924  TRACE("RPC call status: 0x%x\n", status);
925  if (status != RPC_S_OK)
927 
928  TRACE("hrFault = 0x%08x\n", hrFault);
929 
930  /* FIXME: this condition should be
931  * "hr == S_OK && (!hrFault || msg->BufferLength > FIELD_OFFSET(ORPCTHAT, extensions) + 4)"
932  * but we don't currently reset the message length for PostMessage
933  * dispatched calls */
934  if (hr == S_OK && hrFault == S_OK)
935  {
936  HRESULT hr2;
937  char *original_buffer = msg->Buffer;
938 
939  /* handle ORPCTHAT and client extensions */
940 
941  hr2 = unmarshal_ORPCTHAT(msg, &orpcthat, &orpc_ext_array, &first_wire_orpc_extent);
942  if (FAILED(hr2))
943  hr = hr2;
944 
945  message_state->prefix_data_len = (char *)msg->Buffer - original_buffer;
946  msg->BufferLength -= message_state->prefix_data_len;
947  }
948  else
950 
951  if (hr == S_OK)
952  {
954  msg->DataRepresentation,
955  first_wire_orpc_extent,
956  orpcthat.extensions && first_wire_orpc_extent ? orpcthat.extensions->size : 0,
957  hrFault);
958  }
959 
960  /* save away the message state again */
961  msg->Handle = message_state;
962 
963  if (pstatus) *pstatus = status;
964 
965  if (hr == S_OK)
966  hr = hrFault;
967 
968  TRACE("-- 0x%08x\n", hr);
969 
970  apartment_release(apt);
971  return hr;
972 }
973 
975 {
976  RPC_MESSAGE *msg = (RPC_MESSAGE *)olemsg;
979 
980  TRACE("(%p)\n", msg);
981 
982  message_state = msg->Handle;
983  /* restore the binding handle and the real start of data */
984  msg->Handle = message_state->binding_handle;
985  msg->Buffer = (char *)msg->Buffer - message_state->prefix_data_len;
986  msg->BufferLength += message_state->prefix_data_len;
988 
990  {
991  HeapFree(GetProcessHeap(), 0, msg->Buffer);
992  status = RPC_S_OK;
993  }
994  else
996 
997  msg->Handle = message_state;
998 
999  TRACE("-- %d\n", status);
1000 
1001  return HRESULT_FROM_WIN32(status);
1002 }
1003 
1005 {
1006  RPC_MESSAGE *msg = (RPC_MESSAGE *)olemsg;
1008  struct message_state *message_state;
1009 
1010  TRACE("(%p)\n", msg);
1011 
1012  message_state = msg->Handle;
1013  /* restore the binding handle and the real start of data */
1014  msg->Handle = message_state->binding_handle;
1015  msg->Buffer = (char *)msg->Buffer - message_state->prefix_data_len;
1016  msg->BufferLength += message_state->prefix_data_len;
1017 
1018  if (message_state->params.bypass_rpcrt)
1019  {
1020  HeapFree(GetProcessHeap(), 0, msg->Buffer);
1021  status = RPC_S_OK;
1022  }
1023  else
1025 
1026  HeapFree(GetProcessHeap(), 0, msg->RpcInterfaceInformation);
1027  msg->RpcInterfaceInformation = NULL;
1028 
1029  if (message_state->params.stub)
1030  IRpcStubBuffer_Release(message_state->params.stub);
1031  if (message_state->params.chan)
1032  IRpcChannelBuffer_Release(message_state->params.chan);
1034 
1035  TRACE("-- %d\n", status);
1036 
1037  return HRESULT_FROM_WIN32(status);
1038 }
1039 
1040 static HRESULT WINAPI ClientRpcChannelBuffer_GetDestCtx(LPRPCCHANNELBUFFER iface, DWORD* pdwDestContext, void** ppvDestContext)
1041 {
1043 
1044  TRACE("(%p,%p)\n", pdwDestContext, ppvDestContext);
1045 
1046  *pdwDestContext = This->super.dest_context;
1047  *ppvDestContext = This->super.dest_context_data;
1048 
1049  return S_OK;
1050 }
1051 
1052 static HRESULT WINAPI ServerRpcChannelBuffer_GetDestCtx(LPRPCCHANNELBUFFER iface, DWORD* dest_context, void** dest_context_data)
1053 {
1055 
1056  TRACE("(%p,%p)\n", dest_context, dest_context_data);
1057 
1058  *dest_context = This->dest_context;
1059  *dest_context_data = This->dest_context_data;
1060  return S_OK;
1061 }
1062 
1064 {
1065  TRACE("()\n");
1066  /* native does nothing too */
1067  return S_OK;
1068 }
1069 
1070 static const IRpcChannelBufferVtbl ClientRpcChannelBufferVtbl =
1071 {
1080 };
1081 
1082 static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl =
1083 {
1092 };
1093 
1094 /* returns a channel buffer for proxies */
1095 HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
1096  const OXID_INFO *oxid_info, const IID *iid,
1097  DWORD dest_context, void *dest_context_data,
1098  IRpcChannelBuffer **chan, APARTMENT *apt)
1099 {
1101  WCHAR endpoint[200];
1104  LPWSTR string_binding;
1105 
1106  /* FIXME: get the endpoint from oxid_info->psa instead */
1107  get_rpc_endpoint(endpoint, oxid);
1108 
1109  TRACE("proxy pipe: connecting to endpoint: %s\n", debugstr_w(endpoint));
1110 
1112  NULL,
1114  NULL,
1115  endpoint,
1116  NULL,
1117  &string_binding);
1118 
1119  if (status == RPC_S_OK)
1120  {
1121  status = RpcBindingFromStringBindingW(string_binding, &bind);
1122 
1123  if (status == RPC_S_OK)
1124  {
1125  IPID ipid2 = *ipid; /* why can't RpcBindingSetObject take a const? */
1126  status = RpcBindingSetObject(bind, &ipid2);
1127  if (status != RPC_S_OK)
1128  RpcBindingFree(&bind);
1129  }
1130 
1131  RpcStringFreeW(&string_binding);
1132  }
1133 
1134  if (status != RPC_S_OK)
1135  {
1136  ERR("Couldn't get binding for endpoint %s, status = %d\n", debugstr_w(endpoint), status);
1137  return HRESULT_FROM_WIN32(status);
1138  }
1139 
1140  This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1141  if (!This)
1142  {
1143  RpcBindingFree(&bind);
1144  return E_OUTOFMEMORY;
1145  }
1146 
1147  This->super.IRpcChannelBuffer_iface.lpVtbl = &ClientRpcChannelBufferVtbl;
1148  This->super.refs = 1;
1149  This->super.dest_context = dest_context;
1150  This->super.dest_context_data = dest_context_data;
1151  This->bind = bind;
1152  apartment_getoxid(apt, &This->oxid);
1153  This->server_pid = oxid_info->dwPid;
1154  This->event = NULL;
1155  This->iid = *iid;
1156 
1157  *chan = &This->super.IRpcChannelBuffer_iface;
1158 
1159  return S_OK;
1160 }
1161 
1162 HRESULT RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan)
1163 {
1164  RpcChannelBuffer *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1165  if (!This)
1166  return E_OUTOFMEMORY;
1167 
1168  This->IRpcChannelBuffer_iface.lpVtbl = &ServerRpcChannelBufferVtbl;
1169  This->refs = 1;
1170  This->dest_context = dest_context;
1171  This->dest_context_data = dest_context_data;
1172 
1173  *chan = &This->IRpcChannelBuffer_iface;
1174 
1175  return S_OK;
1176 }
1177 
1178 /* unmarshals ORPC_EXTENT_ARRAY according to NDR rules, but doesn't allocate
1179  * any memory */
1181  ORPC_EXTENT_ARRAY *extensions,
1182  WIRE_ORPC_EXTENT **first_wire_orpc_extent)
1183 {
1184  DWORD pointer_id;
1185  DWORD i;
1186 
1187  memcpy(extensions, msg->Buffer, FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent));
1188  msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent);
1189 
1190  if ((const char *)msg->Buffer + 2 * sizeof(DWORD) > end)
1191  return RPC_E_INVALID_HEADER;
1192 
1193  pointer_id = *(DWORD *)msg->Buffer;
1194  msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
1195  extensions->extent = NULL;
1196 
1197  if (pointer_id)
1198  {
1199  WIRE_ORPC_EXTENT *wire_orpc_extent;
1200 
1201  /* conformance */
1202  if (*(DWORD *)msg->Buffer != ((extensions->size+1)&~1))
1203  return RPC_S_INVALID_BOUND;
1204 
1205  msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
1206 
1207  /* arbitrary limit for security (don't know what native does) */
1208  if (extensions->size > 256)
1209  {
1210  ERR("too many extensions: %d\n", extensions->size);
1211  return RPC_S_INVALID_BOUND;
1212  }
1213 
1214  *first_wire_orpc_extent = wire_orpc_extent = msg->Buffer;
1215  for (i = 0; i < ((extensions->size+1)&~1); i++)
1216  {
1217  if ((const char *)&wire_orpc_extent->data[0] > end)
1218  return RPC_S_INVALID_BOUND;
1219  if (wire_orpc_extent->conformance != ((wire_orpc_extent->size+7)&~7))
1220  return RPC_S_INVALID_BOUND;
1221  if ((const char *)&wire_orpc_extent->data[wire_orpc_extent->conformance] > end)
1222  return RPC_S_INVALID_BOUND;
1223  TRACE("size %u, guid %s\n", wire_orpc_extent->size, debugstr_guid(&wire_orpc_extent->id));
1224  wire_orpc_extent = (WIRE_ORPC_EXTENT *)&wire_orpc_extent->data[wire_orpc_extent->conformance];
1225  }
1226  msg->Buffer = wire_orpc_extent;
1227  }
1228 
1229  return S_OK;
1230 }
1231 
1232 /* unmarshals ORPCTHIS according to NDR rules, but doesn't allocate any memory */
1233 static HRESULT unmarshal_ORPCTHIS(RPC_MESSAGE *msg, ORPCTHIS *orpcthis,
1234  ORPC_EXTENT_ARRAY *orpc_ext_array, WIRE_ORPC_EXTENT **first_wire_orpc_extent)
1235 {
1236  const char *end = (char *)msg->Buffer + msg->BufferLength;
1237 
1238  *first_wire_orpc_extent = NULL;
1239 
1240  if (msg->BufferLength < FIELD_OFFSET(WIRE_ORPCTHIS, extensions) + sizeof(DWORD))
1241  {
1242  ERR("invalid buffer length\n");
1243  return RPC_E_INVALID_HEADER;
1244  }
1245 
1246  memcpy(orpcthis, msg->Buffer, FIELD_OFFSET(WIRE_ORPCTHIS, extensions));
1247  msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPCTHIS, extensions);
1248 
1249  if ((const char *)msg->Buffer + sizeof(DWORD) > end)
1250  return RPC_E_INVALID_HEADER;
1251 
1252  if (*(DWORD *)msg->Buffer)
1253  orpcthis->extensions = orpc_ext_array;
1254  else
1255  orpcthis->extensions = NULL;
1256 
1257  msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
1258 
1259  if (orpcthis->extensions)
1260  {
1261  HRESULT hr = unmarshal_ORPC_EXTENT_ARRAY(msg, end, orpc_ext_array,
1262  first_wire_orpc_extent);
1263  if (FAILED(hr))
1264  return hr;
1265  }
1266 
1267  if ((orpcthis->version.MajorVersion != COM_MAJOR_VERSION) ||
1268  (orpcthis->version.MinorVersion > COM_MINOR_VERSION))
1269  {
1270  ERR("COM version {%d, %d} not supported\n",
1271  orpcthis->version.MajorVersion, orpcthis->version.MinorVersion);
1272  return RPC_E_VERSION_MISMATCH;
1273  }
1274 
1275  if (orpcthis->flags & ~(ORPCF_LOCAL|ORPCF_RESERVED1|ORPCF_RESERVED2|ORPCF_RESERVED3|ORPCF_RESERVED4))
1276  {
1277  ERR("invalid flags 0x%x\n", orpcthis->flags & ~(ORPCF_LOCAL|ORPCF_RESERVED1|ORPCF_RESERVED2|ORPCF_RESERVED3|ORPCF_RESERVED4));
1278  return RPC_E_INVALID_HEADER;
1279  }
1280 
1281  return S_OK;
1282 }
1283 
1284 static HRESULT unmarshal_ORPCTHAT(RPC_MESSAGE *msg, ORPCTHAT *orpcthat,
1285  ORPC_EXTENT_ARRAY *orpc_ext_array, WIRE_ORPC_EXTENT **first_wire_orpc_extent)
1286 {
1287  const char *end = (char *)msg->Buffer + msg->BufferLength;
1288 
1289  *first_wire_orpc_extent = NULL;
1290 
1291  if (msg->BufferLength < FIELD_OFFSET(WIRE_ORPCTHAT, extensions) + sizeof(DWORD))
1292  {
1293  ERR("invalid buffer length\n");
1294  return RPC_E_INVALID_HEADER;
1295  }
1296 
1297  memcpy(orpcthat, msg->Buffer, FIELD_OFFSET(WIRE_ORPCTHAT, extensions));
1298  msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPCTHAT, extensions);
1299 
1300  if ((const char *)msg->Buffer + sizeof(DWORD) > end)
1301  return RPC_E_INVALID_HEADER;
1302 
1303  if (*(DWORD *)msg->Buffer)
1304  orpcthat->extensions = orpc_ext_array;
1305  else
1306  orpcthat->extensions = NULL;
1307 
1308  msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
1309 
1310  if (orpcthat->extensions)
1311  {
1312  HRESULT hr = unmarshal_ORPC_EXTENT_ARRAY(msg, end, orpc_ext_array,
1313  first_wire_orpc_extent);
1314  if (FAILED(hr))
1315  return hr;
1316  }
1317 
1318  if (orpcthat->flags & ~(ORPCF_LOCAL|ORPCF_RESERVED1|ORPCF_RESERVED2|ORPCF_RESERVED3|ORPCF_RESERVED4))
1319  {
1320  ERR("invalid flags 0x%x\n", orpcthat->flags & ~(ORPCF_LOCAL|ORPCF_RESERVED1|ORPCF_RESERVED2|ORPCF_RESERVED3|ORPCF_RESERVED4));
1321  return RPC_E_INVALID_HEADER;
1322  }
1323 
1324  return S_OK;
1325 }
1326 
1328 {
1329  struct message_state *message_state = NULL;
1330  RPC_MESSAGE *msg = (RPC_MESSAGE *)params->msg;
1331  char *original_buffer = msg->Buffer;
1332  ORPCTHIS orpcthis;
1333  ORPC_EXTENT_ARRAY orpc_ext_array;
1334  WIRE_ORPC_EXTENT *first_wire_orpc_extent;
1335  GUID old_causality_id;
1336 
1337  /* handle ORPCTHIS and server extensions */
1338 
1339  params->hr = unmarshal_ORPCTHIS(msg, &orpcthis, &orpc_ext_array, &first_wire_orpc_extent);
1340  if (params->hr != S_OK)
1341  {
1342  msg->Buffer = original_buffer;
1343  goto exit;
1344  }
1345 
1347  if (!message_state)
1348  {
1349  params->hr = E_OUTOFMEMORY;
1350  msg->Buffer = original_buffer;
1351  goto exit;
1352  }
1353 
1354  message_state->prefix_data_len = (char *)msg->Buffer - original_buffer;
1355  message_state->binding_handle = msg->Handle;
1356  message_state->bypass_rpcrt = params->bypass_rpcrt;
1357 
1360  message_state->channel_hook_info.uCausality = orpcthis.cid;
1362  message_state->channel_hook_info.iMethod = msg->ProcNum;
1363  message_state->channel_hook_info.pObject = params->iface;
1364 
1365  if (orpcthis.extensions && first_wire_orpc_extent &&
1366  orpcthis.extensions->size)
1367  ChannelHooks_ServerNotify(&message_state->channel_hook_info, msg->DataRepresentation, first_wire_orpc_extent, orpcthis.extensions->size);
1368 
1369  msg->Handle = message_state;
1370  msg->BufferLength -= message_state->prefix_data_len;
1371 
1372  /* call message filter */
1373 
1374  if (COM_CurrentApt()->filter)
1375  {
1376  DWORD handlecall;
1377  INTERFACEINFO interface_info;
1378  CALLTYPE calltype;
1379 
1380  interface_info.pUnk = params->iface;
1381  interface_info.iid = params->iid;
1382  interface_info.wMethod = msg->ProcNum;
1383 
1384  if (IsEqualGUID(&orpcthis.cid, &COM_CurrentInfo()->causality_id))
1385  calltype = CALLTYPE_NESTED;
1386  else if (COM_CurrentInfo()->pending_call_count_server == 0)
1387  calltype = CALLTYPE_TOPLEVEL;
1388  else
1389  calltype = CALLTYPE_TOPLEVEL_CALLPENDING;
1390 
1391  handlecall = IMessageFilter_HandleInComingCall(COM_CurrentApt()->filter,
1392  calltype,
1394  0 /* FIXME */,
1395  &interface_info);
1396  TRACE("IMessageFilter_HandleInComingCall returned %d\n", handlecall);
1397  switch (handlecall)
1398  {
1399  case SERVERCALL_REJECTED:
1401  goto exit_reset_state;
1402  case SERVERCALL_RETRYLATER:
1403 #if 0 /* FIXME: handle retries on the client side before enabling this code */
1404  params->hr = RPC_E_RETRY;
1405  goto exit_reset_state;
1406 #else
1407  FIXME("retry call later not implemented\n");
1408  break;
1409 #endif
1410  case SERVERCALL_ISHANDLED:
1411  default:
1412  break;
1413  }
1414  }
1415 
1416  /* invoke the method */
1417 
1418  /* save the old causality ID - note: any calls executed while processing
1419  * messages received during the SendReceive will appear to originate from
1420  * this call - this should be checked with what Windows does */
1421  old_causality_id = COM_CurrentInfo()->causality_id;
1422  COM_CurrentInfo()->causality_id = orpcthis.cid;
1423  COM_CurrentInfo()->pending_call_count_server++;
1424  params->hr = IRpcStubBuffer_Invoke(params->stub, params->msg, params->chan);
1425  COM_CurrentInfo()->pending_call_count_server--;
1426  COM_CurrentInfo()->causality_id = old_causality_id;
1427 
1428  /* the invoke allocated a new buffer, so free the old one */
1429  if (message_state->bypass_rpcrt && original_buffer != msg->Buffer)
1430  HeapFree(GetProcessHeap(), 0, original_buffer);
1431 
1432 exit_reset_state:
1433  message_state = msg->Handle;
1434  msg->Handle = message_state->binding_handle;
1435  msg->Buffer = (char *)msg->Buffer - message_state->prefix_data_len;
1436  msg->BufferLength += message_state->prefix_data_len;
1437 
1438 exit:
1440  if (params->handle) SetEvent(params->handle);
1441 }
1442 
1444 {
1445  struct dispatch_params *params;
1446  struct stub_manager *stub_manager;
1447  APARTMENT *apt;
1448  IPID ipid;
1449  HRESULT hr;
1450 
1451  RpcBindingInqObject(msg->Handle, &ipid);
1452 
1453  TRACE("ipid = %s, iMethod = %d\n", debugstr_guid(&ipid), msg->ProcNum);
1454 
1455  params = HeapAlloc(GetProcessHeap(), 0, sizeof(*params));
1456  if (!params)
1457  {
1459  return;
1460  }
1461 
1462  hr = ipid_get_dispatch_params(&ipid, &apt, &stub_manager, &params->stub, &params->chan,
1463  &params->iid, &params->iface);
1464  if (hr != S_OK)
1465  {
1466  ERR("no apartment found for ipid %s\n", debugstr_guid(&ipid));
1469  return;
1470  }
1471 
1472  params->msg = (RPCOLEMESSAGE *)msg;
1473  params->status = RPC_S_OK;
1474  params->hr = S_OK;
1475  params->handle = NULL;
1476  params->bypass_rpcrt = FALSE;
1477 
1478  /* Note: this is the important difference between STAs and MTAs - we
1479  * always execute RPCs to STAs in the thread that originally created the
1480  * apartment (i.e. the one that pumps messages to the window) */
1481  if (!apt->multi_threaded)
1482  {
1483  params->handle = CreateEventW(NULL, FALSE, FALSE, NULL);
1484 
1485  TRACE("Calling apartment thread 0x%08x...\n", apt->tid);
1486 
1489  else
1490  {
1491  ERR("PostMessage failed with error %u\n", GetLastError());
1492  IRpcChannelBuffer_Release(params->chan);
1493  IRpcStubBuffer_Release(params->stub);
1494  }
1495  CloseHandle(params->handle);
1496  }
1497  else
1498  {
1499  BOOL joined = FALSE;
1500  struct oletls *info = COM_CurrentInfo();
1501 
1502  if (!info->apt)
1503  {
1505  joined = TRUE;
1506  }
1508  if (joined)
1509  {
1511  }
1512  }
1513 
1514  hr = params->hr;
1515  if (params->chan)
1516  IRpcChannelBuffer_Release(params->chan);
1517  if (params->stub)
1518  IRpcStubBuffer_Release(params->stub);
1520 
1523 
1524  /* if IRpcStubBuffer_Invoke fails, we should raise an exception to tell
1525  * the RPC runtime that the call failed */
1526  if (hr != S_OK) RpcRaiseException(hr);
1527 }
1528 
1529 /* stub registration */
1531 {
1532  struct registered_if *rif;
1533  BOOL found = FALSE;
1534  HRESULT hr = S_OK;
1535 
1536  TRACE("(%s)\n", debugstr_guid(riid));
1537 
1540  {
1542  {
1543  rif->refs++;
1544  found = TRUE;
1545  break;
1546  }
1547  }
1548  if (!found)
1549  {
1550  TRACE("Creating new interface\n");
1551 
1552  rif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rif));
1553  if (rif)
1554  {
1556 
1557  rif->refs = 1;
1558  rif->If.Length = sizeof(RPC_SERVER_INTERFACE);
1559  /* RPC interface ID = COM interface ID */
1560  rif->If.InterfaceId.SyntaxGUID = *riid;
1561  rif->If.DispatchTable = &rpc_dispatch;
1562  /* all other fields are 0, including the version asCOM objects
1563  * always have a version of 0.0 */
1565  (RPC_IF_HANDLE)&rif->If,
1566  NULL, NULL,
1569  NULL);
1570  if (status == RPC_S_OK)
1572  else
1573  {
1574  ERR("RpcServerRegisterIfEx failed with error %d\n", status);
1575  HeapFree(GetProcessHeap(), 0, rif);
1577  }
1578  }
1579  else
1580  hr = E_OUTOFMEMORY;
1581  }
1583  return hr;
1584 }
1585 
1586 /* stub unregistration */
1588 {
1589  struct registered_if *rif;
1592  {
1594  {
1595  if (!--rif->refs)
1596  {
1597  RpcServerUnregisterIf((RPC_IF_HANDLE)&rif->If, NULL, wait);
1598  list_remove(&rif->entry);
1599  HeapFree(GetProcessHeap(), 0, rif);
1600  }
1601  break;
1602  }
1603  }
1605 }
1606 
1607 /* get the info for an OXID, including the IPID for the rem unknown interface
1608  * and the string binding */
1609 HRESULT RPC_ResolveOxid(OXID oxid, OXID_INFO *oxid_info)
1610 {
1611  TRACE("%s\n", wine_dbgstr_longlong(oxid));
1612 
1613  oxid_info->dwTid = 0;
1614  oxid_info->dwPid = 0;
1615  oxid_info->dwAuthnHint = RPC_C_AUTHN_LEVEL_NONE;
1616  /* FIXME: this is a hack around not having an OXID resolver yet -
1617  * this function should contact the machine's OXID resolver and then it
1618  * should give us the IPID of the IRemUnknown interface */
1619  oxid_info->ipidRemUnknown.Data1 = 0xffffffff;
1620  oxid_info->ipidRemUnknown.Data2 = 0xffff;
1621  oxid_info->ipidRemUnknown.Data3 = 0xffff;
1622  memcpy(oxid_info->ipidRemUnknown.Data4, &oxid, sizeof(OXID));
1623  oxid_info->psa = NULL /* FIXME */;
1624 
1625  return S_OK;
1626 }
1627 
1628 /* make the apartment reachable by other threads and processes and create the
1629  * IRemUnknown object */
1630 void RPC_StartRemoting(struct apartment *apt)
1631 {
1633  {
1634  WCHAR endpoint[200];
1636 
1637  get_rpc_endpoint(endpoint, &apt->oxid);
1638 
1642  endpoint,
1643  NULL);
1644  if (status != RPC_S_OK)
1645  ERR("Couldn't register endpoint %s\n", debugstr_w(endpoint));
1646 
1647  /* FIXME: move remote unknown exporting into this function */
1648  }
1650 }
1651 
1652 
1654 {
1655  static const WCHAR wszLocalServer32[] = { 'L','o','c','a','l','S','e','r','v','e','r','3','2',0 };
1656  static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };
1657  HKEY key;
1658  HRESULT hres;
1659  WCHAR command[MAX_PATH+ARRAY_SIZE(embedding)];
1660  DWORD size = (MAX_PATH+1) * sizeof(WCHAR);
1662  PROCESS_INFORMATION pinfo;
1663  LONG ret;
1664 
1665  hres = COM_OpenKeyForCLSID(rclsid, wszLocalServer32, KEY_READ, &key);
1666  if (FAILED(hres)) {
1667  ERR("class %s not registered\n", debugstr_guid(rclsid));
1668  return hres;
1669  }
1670 
1672  RegCloseKey(key);
1673  if (ret) {
1674  WARN("No default value for LocalServer32 key\n");
1675  return REGDB_E_CLASSNOTREG; /* FIXME: check retval */
1676  }
1677 
1678  memset(&sinfo,0,sizeof(sinfo));
1679  sinfo.cb = sizeof(sinfo);
1680 
1681  /* EXE servers are started with the -Embedding switch. */
1682 
1683  lstrcatW(command, embedding);
1684 
1685  TRACE("activating local server %s for %s\n", debugstr_w(command), debugstr_guid(rclsid));
1686 
1687  /* FIXME: Win2003 supports a ServerExecutable value that is passed into
1688  * CreateProcess */
1690  WARN("failed to run local server %s\n", debugstr_w(command));
1691  return HRESULT_FROM_WIN32(GetLastError());
1692  }
1693  *process = pinfo.hProcess;
1694  CloseHandle(pinfo.hThread);
1695 
1696  return S_OK;
1697 }
1698 
1699 /*
1700  * start_local_service() - start a service given its name and parameters
1701  */
1703 {
1704  SC_HANDLE handle, hsvc;
1706 
1707  TRACE("Starting service %s %d params\n", debugstr_w(name), num);
1708 
1710  if (!handle)
1711  return r;
1713  if (hsvc)
1714  {
1715  if(StartServiceW(hsvc, num, params))
1716  r = ERROR_SUCCESS;
1717  else
1718  r = GetLastError();
1720  r = ERROR_SUCCESS;
1721  CloseServiceHandle(hsvc);
1722  }
1723  else
1724  r = GetLastError();
1726 
1727  TRACE("StartService returned error %u (%s)\n", r, (r == ERROR_SUCCESS) ? "ok":"failed");
1728 
1729  return r;
1730 }
1731 
1732 /*
1733  * create_local_service() - start a COM server in a service
1734  *
1735  * To start a Local Service, we read the AppID value under
1736  * the class's CLSID key, then open the HKCR\\AppId key specified
1737  * there and check for a LocalService value.
1738  *
1739  * Note: Local Services are not supported under Windows 9x
1740  */
1742 {
1743  HRESULT hres;
1745  static const WCHAR szLocalService[] = { 'L','o','c','a','l','S','e','r','v','i','c','e',0 };
1746  static const WCHAR szServiceParams[] = {'S','e','r','v','i','c','e','P','a','r','a','m','s',0};
1747  HKEY hkey;
1748  LONG r;
1749  DWORD type, sz;
1750 
1751  TRACE("Attempting to start Local service for %s\n", debugstr_guid(rclsid));
1752 
1753  hres = COM_OpenKeyForAppIdFromCLSID(rclsid, KEY_READ, &hkey);
1754  if (FAILED(hres))
1755  return hres;
1756 
1757  /* read the LocalService and ServiceParameters values from the AppID key */
1758  sz = sizeof buf;
1759  r = RegQueryValueExW(hkey, szLocalService, NULL, &type, (LPBYTE)buf, &sz);
1760  if (r==ERROR_SUCCESS && type==REG_SZ)
1761  {
1762  DWORD num_args = 0;
1763  LPWSTR args[1] = { NULL };
1764 
1765  /*
1766  * FIXME: I'm not really sure how to deal with the service parameters.
1767  * I suspect that the string returned from RegQueryValueExW
1768  * should be split into a number of arguments by spaces.
1769  * It would make more sense if ServiceParams contained a
1770  * REG_MULTI_SZ here, but it's a REG_SZ for the services
1771  * that I'm interested in for the moment.
1772  */
1773  r = RegQueryValueExW(hkey, szServiceParams, NULL, &type, NULL, &sz);
1774  if (r == ERROR_SUCCESS && type == REG_SZ && sz)
1775  {
1777  num_args++;
1778  RegQueryValueExW(hkey, szServiceParams, NULL, &type, (LPBYTE)args[0], &sz);
1779  }
1780  r = start_local_service(buf, num_args, (LPCWSTR *)args);
1781  if (r != ERROR_SUCCESS)
1782  hres = REGDB_E_CLASSNOTREG; /* FIXME: check retval */
1783  HeapFree(GetProcessHeap(),0,args[0]);
1784  }
1785  else
1786  {
1787  WARN("No LocalService value\n");
1788  hres = REGDB_E_CLASSNOTREG; /* FIXME: check retval */
1789  }
1790  RegCloseKey(hkey);
1791 
1792  return hres;
1793 }
1794 
1795 
1796 static void get_localserver_pipe_name(WCHAR *pipefn, REFCLSID rclsid)
1797 {
1798  static const WCHAR wszPipeRef[] = {'\\','\\','.','\\','p','i','p','e','\\',0};
1799  lstrcpyW(pipefn, wszPipeRef);
1800  StringFromGUID2(rclsid, pipefn + ARRAY_SIZE(wszPipeRef) - 1, CHARS_IN_GUID);
1801 }
1802 
1803 /* FIXME: should call to rpcss instead */
1805 {
1806  HRESULT hres;
1807  HANDLE hPipe;
1808  WCHAR pipefn[100];
1809  DWORD res, bufferlen;
1810  char marshalbuffer[200];
1811  IStream *pStm;
1813  ULARGE_INTEGER newpos;
1814  int tries = 0;
1816 
1817  static const int MAXTRIES = 30; /* 30 seconds */
1818 
1819  TRACE("rclsid=%s, iid=%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
1820 
1821  get_localserver_pipe_name(pipefn, rclsid);
1822 
1823  while (tries++ < MAXTRIES) {
1824  TRACE("waiting for %s\n", debugstr_w(pipefn));
1825 
1827  hPipe = CreateFileW(pipefn, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1828  if (hPipe == INVALID_HANDLE_VALUE) {
1829  DWORD index;
1830  DWORD start_ticks;
1831  HANDLE process = 0;
1832  if (tries == 1) {
1833  if ( (hres = create_local_service(rclsid)) &&
1834  (hres = create_server(rclsid, &process)) )
1835  return hres;
1836  } else {
1837  WARN("Connecting to %s, no response yet, retrying: le is %u\n", debugstr_w(pipefn), GetLastError());
1838  }
1839  /* wait for one second, even if messages arrive */
1840  start_ticks = GetTickCount();
1841  do {
1842  if (SUCCEEDED(CoWaitForMultipleHandles(0, 1000, (process != 0),
1843  &process, &index)) && process && !index)
1844  {
1845  WARN( "server for %s failed to start\n", debugstr_guid(rclsid) );
1846  CloseHandle( hPipe );
1847  CloseHandle( process );
1848  return E_NOINTERFACE;
1849  }
1850  } while (GetTickCount() - start_ticks < 1000);
1851  if (process) CloseHandle( process );
1852  continue;
1853  }
1854  bufferlen = 0;
1855  if (!ReadFile(hPipe,marshalbuffer,sizeof(marshalbuffer),&bufferlen,NULL)) {
1856  FIXME("Failed to read marshal id from classfactory of %s.\n",debugstr_guid(rclsid));
1857  CloseHandle(hPipe);
1858  Sleep(1000);
1859  continue;
1860  }
1861  TRACE("read marshal id from pipe\n");
1862  CloseHandle(hPipe);
1863  break;
1864  }
1865 
1866  if (tries >= MAXTRIES)
1867  return E_NOINTERFACE;
1868 
1869  hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
1870  if (hres != S_OK) return hres;
1871  hres = IStream_Write(pStm,marshalbuffer,bufferlen,&res);
1872  if (hres != S_OK) goto out;
1873  seekto.u.LowPart = 0;seekto.u.HighPart = 0;
1874  hres = IStream_Seek(pStm,seekto,STREAM_SEEK_SET,&newpos);
1875 
1876  TRACE("unmarshalling local server\n");
1877  hres = CoUnmarshalInterface(pStm, &IID_IServiceProvider, (void**)&local_server);
1878  if(SUCCEEDED(hres))
1879  hres = IServiceProvider_QueryService(local_server, rclsid, iid, ppv);
1880  IServiceProvider_Release(local_server);
1881 out:
1882  IStream_Release(pStm);
1883  return hres;
1884 }
1885 
1886 
1888 {
1895 };
1896 
1897 /* FIXME: should call to rpcss instead */
1899 {
1900  struct local_server_params * lsp = param;
1901  WCHAR pipefn[100];
1902  HRESULT hres;
1903  IStream *pStm = lsp->stream;
1904  STATSTG ststg;
1905  unsigned char *buffer;
1906  int buflen;
1908  ULARGE_INTEGER newpos;
1909  ULONG res;
1910  BOOL multi_use = lsp->multi_use;
1911  OVERLAPPED ovl;
1912  HANDLE pipe_event, hPipe = lsp->pipe, new_pipe;
1913  DWORD bytes;
1914 
1915  TRACE("Starting threader for %s.\n",debugstr_guid(&lsp->clsid));
1916 
1917  memset(&ovl, 0, sizeof(ovl));
1918  get_localserver_pipe_name(pipefn, &lsp->clsid);
1919  ovl.hEvent = pipe_event = CreateEventW(NULL, FALSE, FALSE, NULL);
1920 
1921  while (1) {
1922  if (!ConnectNamedPipe(hPipe, &ovl))
1923  {
1924  DWORD error = GetLastError();
1925  if (error == ERROR_IO_PENDING)
1926  {
1927  HANDLE handles[2] = { pipe_event, lsp->stop_event };
1928  DWORD ret;
1930  if (ret != WAIT_OBJECT_0)
1931  break;
1932  }
1933  /* client already connected isn't an error */
1934  else if (error != ERROR_PIPE_CONNECTED)
1935  {
1936  ERR("ConnectNamedPipe failed with error %d\n", GetLastError());
1937  break;
1938  }
1939  }
1940 
1941  TRACE("marshalling LocalServer to client\n");
1942 
1943  hres = IStream_Stat(pStm,&ststg,STATFLAG_NONAME);
1944  if (hres != S_OK)
1945  break;
1946 
1947  seekto.u.LowPart = 0;
1948  seekto.u.HighPart = 0;
1949  hres = IStream_Seek(pStm,seekto,STREAM_SEEK_SET,&newpos);
1950  if (hres != S_OK) {
1951  FIXME("IStream_Seek failed, %x\n",hres);
1952  break;
1953  }
1954 
1955  buflen = ststg.cbSize.u.LowPart;
1956  buffer = HeapAlloc(GetProcessHeap(),0,buflen);
1957 
1958  hres = IStream_Read(pStm,buffer,buflen,&res);
1959  if (hres != S_OK) {
1960  FIXME("Stream Read failed, %x\n",hres);
1962  break;
1963  }
1964 
1965  WriteFile(hPipe,buffer,buflen,&res,&ovl);
1966  GetOverlappedResult(hPipe, &ovl, &bytes, TRUE);
1968 
1969  FlushFileBuffers(hPipe);
1970  DisconnectNamedPipe(hPipe);
1971  TRACE("done marshalling LocalServer\n");
1972 
1973  if (!multi_use)
1974  {
1975  TRACE("single use object, shutting down pipe %s\n", debugstr_w(pipefn));
1976  break;
1977  }
1980  4096, 4096, 500 /* 0.5 second timeout */, NULL );
1981  if (new_pipe == INVALID_HANDLE_VALUE)
1982  {
1983  FIXME("pipe creation failed for %s, le is %u\n", debugstr_w(pipefn), GetLastError());
1984  break;
1985  }
1986  CloseHandle(hPipe);
1987  hPipe = new_pipe;
1988  }
1989 
1990  CloseHandle(pipe_event);
1991  CloseHandle(hPipe);
1992  return 0;
1993 }
1994 
1995 /* starts listening for a local server */
1997 {
1998  DWORD tid, err;
1999  struct local_server_params *lsp;
2000  WCHAR pipefn[100];
2001 
2002  lsp = HeapAlloc(GetProcessHeap(), 0, sizeof(*lsp));
2003  if (!lsp)
2004  return E_OUTOFMEMORY;
2005 
2006  lsp->clsid = *clsid;
2007  lsp->stream = stream;
2008  IStream_AddRef(stream);
2010  if (!lsp->stop_event)
2011  {
2012  HeapFree(GetProcessHeap(), 0, lsp);
2013  return HRESULT_FROM_WIN32(GetLastError());
2014  }
2015  lsp->multi_use = multi_use;
2016 
2017  get_localserver_pipe_name(pipefn, &lsp->clsid);
2020  4096, 4096, 500 /* 0.5 second timeout */, NULL);
2021  if (lsp->pipe == INVALID_HANDLE_VALUE)
2022  {
2023  err = GetLastError();
2024  FIXME("pipe creation failed for %s, le is %u\n", debugstr_w(pipefn), GetLastError());
2025  CloseHandle(lsp->stop_event);
2026  HeapFree(GetProcessHeap(), 0, lsp);
2027  return HRESULT_FROM_WIN32(err);
2028  }
2029 
2030  lsp->thread = CreateThread(NULL, 0, local_server_thread, lsp, 0, &tid);
2031  if (!lsp->thread)
2032  {
2033  CloseHandle(lsp->pipe);
2034  CloseHandle(lsp->stop_event);
2035  HeapFree(GetProcessHeap(), 0, lsp);
2036  return HRESULT_FROM_WIN32(GetLastError());
2037  }
2038 
2039  *registration = lsp;
2040  return S_OK;
2041 }
2042 
2043 /* stops listening for a local server */
2044 void RPC_StopLocalServer(void *registration)
2045 {
2046  struct local_server_params *lsp = registration;
2047 
2048  /* signal local_server_thread to stop */
2049  SetEvent(lsp->stop_event);
2050  /* wait for it to exit */
2052 
2053  IStream_Release(lsp->stream);
2054  CloseHandle(lsp->stop_event);
2055  CloseHandle(lsp->thread);
2056  HeapFree(GetProcessHeap(), 0, lsp);
2057 }
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
ULONG flags
Definition: rpc.c:155
RPC_STATUS WINAPI RpcBindingFromStringBindingW(RPC_WSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:876
static HANDLE ClientRpcChannelBuffer_GetEventHandle(ClientRpcChannelBuffer *This)
Definition: rpc.c:601
void RPC_StopLocalServer(void *registration)
Definition: rpc.c:2044
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
Definition: marshal.c:1981
#define PIPE_UNLIMITED_INSTANCES
Definition: winbase.h:175
void RPC_UnregisterAllChannelHooks(void)
Definition: rpc.c:445
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:783
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:406
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define E_NOINTERFACE
Definition: winerror.h:2364
ULONG conformance
Definition: rpc.c:139
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
PRPC_DISPATCH_TABLE DispatchTable
Definition: rpcdcep.h:106
static void ChannelHooks_ClientNotify(SChannelHookCallInfo *info, DWORD lDataRep, WIRE_ORPC_EXTENT *first_wire_orpc_extent, ULONG extension_count, HRESULT hrFault)
Definition: rpc.c:394
IUnknown * iface
Definition: rpc.c:117
#define RPC_S_INVALID_BOUND
Definition: winerror.h:1043
static struct object_header ** handles
Definition: handle.c:45
static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, REFIID riid)
Definition: rpc.c:619
#define ERROR_SUCCESS
Definition: deptool.c:10
#define DWORD_PTR
Definition: treelist.c:76
HRESULT hr
Definition: shlfolder.c:183
#define error(str)
Definition: mkdosfs.c:1605
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
static HRESULT apartment_getoxid(const struct apartment *apt, OXID *oxid)
Definition: scsiwmi.h:51
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned short MajorVersion
Definition: rpcdcep.h:27
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
Definition: rpcrt4_main.c:174
static HRESULT WINAPI ClientRpcChannelBuffer_FreeBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg)
Definition: rpc.c:1004
static ULONG ChannelHooks_ClientGetSize(SChannelHookCallInfo *info, struct channel_hook_buffer_data **data, unsigned int *hook_count, ULONG *extension_count)
Definition: rpc.c:186
struct dispatch_params params
Definition: rpc.c:134
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define KEY_READ
Definition: nt_native.h:1023
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
REFIID riid
Definition: precomp.h:44
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static void ChannelHooks_ServerNotify(SChannelHookCallInfo *info, DWORD lDataRep, WIRE_ORPC_EXTENT *first_wire_orpc_extent, ULONG extension_count)
Definition: rpc.c:274
#define REFCLSID
Definition: guiddef.h:117
DWORD apartment_release(struct apartment *apt)
Definition: compobj.c:1172
static unsigned char * ChannelHooks_ServerFillBuffer(SChannelHookCallInfo *info, unsigned char *buffer, struct channel_hook_buffer_data *data, unsigned int hook_count)
Definition: rpc.c:353
static HRESULT WINAPI ServerRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus)
Definition: rpc.c:784
void(__RPC_STUB * RPC_DISPATCH_FUNCTION)(PRPC_MESSAGE Message)
Definition: rpcdcep.h:82
RPC_BINDING_HANDLE binding_handle
Definition: rpc.c:126
void DECLSPEC_NORETURN WINAPI RpcRaiseException(RPC_STATUS exception)
Definition: rpcrt4_main.c:186
ULONG stub_manager_int_release(struct stub_manager *This) DECLSPEC_HIDDEN
Definition: stubmanager.c:311
#define WARN(fmt,...)
Definition: debug.h:111
BOOL WINAPI WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
Definition: npipe.c:458
APARTMENT * apt
static void ClientRpcChannelBuffer_ReleaseEventHandle(ClientRpcChannelBuffer *This, HANDLE event)
Definition: rpc.c:612
BOOL multi_threaded
#define CHARS_IN_GUID
static HRESULT WINAPI ClientRpcChannelBuffer_GetDestCtx(LPRPCCHANNELBUFFER iface, DWORD *pdwDestContext, void **ppvDestContext)
Definition: rpc.c:1040
#define RPC_E_WRONG_THREAD
Definition: winerror.h:2490
SChannelHookCallInfo channel_hook_info
Definition: rpc.c:128
REFIID LPVOID * ppv
Definition: atlbase.h:39
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
static CRITICAL_SECTION csChannelHook
Definition: rpc.c:64
#define PIPE_WAIT
Definition: winbase.h:171
void RPC_UnregisterInterface(REFIID riid, BOOL wait)
Definition: rpc.c:1587
BOOL WINAPI InSendMessage(void)
Definition: message.c:1371
IRpcChannelBuffer * chan
Definition: rpc.c:115
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
static HRESULT WINAPI ServerRpcChannelBuffer_GetDestCtx(LPRPCCHANNELBUFFER iface, DWORD *dest_context, void **dest_context_data)
Definition: rpc.c:1052
#define RPC_E_CANTCALLOUT_ININPUTSYNCCALL
Definition: winerror.h:2489
#define RPC_IF_OLE
Definition: rpcdce.h:314
GLuint buffer
Definition: glext.h:5915
LONG refs
Definition: rpc.c:94
struct list entry
Definition: rpc.c:78
static CRITICAL_SECTION_DEBUG csRegIf_debug
Definition: rpc.c:55
RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
Definition: rpc_message.c:1638
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
static LONG bufferlen
Definition: sync.c:1601
GLuint GLuint end
Definition: gl.h:1545
DWORD refs
Definition: rpc.c:79
#define RPC_E_INVALID_HEADER
Definition: winerror.h:2493
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static struct list channel_hooks
Definition: rpc.c:63
RPC_STATUS status
Definition: rpc.c:120
IChannelHook * hook
Definition: rpc.c:171
#define ERROR_IO_PENDING
Definition: dderror.h:15
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
RPCOLEMESSAGE * msg
Definition: rpc.c:113
Definition: match.c:390
#define RPC_IF_AUTOLISTEN
Definition: rpcdce.h:313
#define DWORD
Definition: nt_native.h:44
Definition: send.c:47
static struct oletls * COM_CurrentInfo(void)
RPC_STATUS WINAPI RpcServerUnregisterIf(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, UINT WaitForCallsToComplete)
Definition: rpc_server.c:1202
static DWORD WINAPI rpc_sendreceive_thread(LPVOID param)
Definition: rpc.c:791
static ULONG WINAPI ClientRpcChannelBuffer_Release(LPRPCCHANNELBUFFER iface)
Definition: rpc.c:491
RPC_STATUS WINAPI RpcStringBindingComposeW(RPC_WSTR ObjUuid, RPC_WSTR Protseq, RPC_WSTR NetworkAddr, RPC_WSTR Endpoint, RPC_WSTR Options, RPC_WSTR *StringBinding)
Definition: rpc_binding.c:510
static HRESULT create_server(REFCLSID rclsid, HANDLE *process)
Definition: rpc.c:1653
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
static CRITICAL_SECTION csRegIf
Definition: rpc.c:54
static APARTMENT * COM_CurrentApt(void)
static HRESULT ClientRpcChannelBuffer_IsCorrectApartment(ClientRpcChannelBuffer *This, APARTMENT *apt)
Definition: rpc.c:806
static DWORD start_local_service(LPCWSTR name, DWORD num, LPCWSTR *params)
Definition: rpc.c:1702
IRpcChannelBuffer IRpcChannelBuffer_iface
Definition: rpc.c:93
struct apartment * apt
static ULONG WINAPI RpcChannelBuffer_AddRef(LPRPCCHANNELBUFFER iface)
Definition: rpc.c:472
RPC_STATUS WINAPI RpcServerRegisterIfEx(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, RPC_MGR_EPV *MgrEpv, UINT Flags, UINT MaxCalls, RPC_IF_CALLBACK_FN *IfCallbackFn)
Definition: rpc_server.c:1125
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, BOOL multi_use, void **registration)
Definition: rpc.c:1996
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
RPC_SYNTAX_IDENTIFIER InterfaceId
Definition: rpcdcep.h:104
long RPC_STATUS
Definition: rpc.h:52
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg)
Definition: rpc_message.c:1918
HANDLE stop_event
Definition: rpc.c:1892
static unsigned char * ChannelHooks_ClientFillBuffer(SChannelHookCallInfo *info, unsigned char *buffer, struct channel_hook_buffer_data *data, unsigned int hook_count)
Definition: rpc.c:234
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
static void get_rpc_endpoint(LPWSTR endpoint, const OXID *oxid)
Definition: rpc.c:84
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
GLenum const GLfloat * params
Definition: glext.h:5645
unsigned int BOOL
Definition: ntddk_ex.h:94
static LPSTR local_server
Definition: info.c:87
long LONG
Definition: pedump.c:60
#define GENERIC_WRITE
Definition: nt_native.h:90
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
#define NMPWAIT_WAIT_FOREVER
Definition: winbase.h:133
#define FIXME(fmt,...)
Definition: debug.h:110
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
static RPC_DISPATCH_FUNCTION rpc_dispatch_table[1]
Definition: rpc.c:50
unsigned int Length
Definition: rpcdcep.h:116
static GUID COM_CurrentCausalityId(void)
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2103
#define PIPE_TYPE_BYTE
Definition: winbase.h:167
#define RPC_C_LISTEN_MAX_CALLS_DEFAULT
Definition: rpcdce.h:122
GUID cid
Definition: rpc.c:157
#define S_FALSE
Definition: winerror.h:2357
RPC_BINDING_HANDLE bind
Definition: rpc.c:104
HANDLE hEvent
Definition: winbase.h:792
struct list entry
Definition: rpc.c:169
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:577
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
RPC_VERSION SyntaxVersion
Definition: rpcdcep.h:33
smooth NULL
Definition: ftsmooth.c:416
LONG remoting_started
RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
Definition: rpc_message.c:1696
LONG_PTR LPARAM
Definition: windef.h:208
HANDLE handle
Definition: rpc.c:118
struct _RPC_CLIENT_INTERFACE RPC_CLIENT_INTERFACE
BOOL bypass_rpcrt
Definition: rpc.c:129
Definition: general.c:220
GLuint index
Definition: glext.h:6031
unsigned int Length
Definition: rpcdcep.h:103
#define __RPC_STUB
Definition: rpc.h:66
HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *subkey)
Definition: compobj.c:2448
void * dest_context_data
Definition: rpc.c:97
#define debugstr_guid
Definition: kernel32.h:35
#define OPEN_EXISTING
Definition: compat.h:434
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4593
void leave_apartment(struct oletls *info)
Definition: compobj.c:1937
static HRESULT WINAPI RpcChannelBuffer_IsConnected(LPRPCCHANNELBUFFER iface)
Definition: rpc.c:1063
static RPC_DISPATCH_TABLE rpc_dispatch
Definition: rpc.c:51
HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout, ULONG cHandles, LPHANDLE pHandles, LPDWORD lpdwindex)
Definition: compobj.c:4578
HRESULT RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan)
Definition: rpc.c:1162
static ULONG ChannelHooks_ServerGetSize(SChannelHookCallInfo *info, struct channel_hook_buffer_data **data, unsigned int *hook_count, ULONG *extension_count)
Definition: rpc.c:304
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
Definition: msg.h:42
BOOL WINAPI StartServiceW(SC_HANDLE hService, DWORD dwNumServiceArgs, LPCWSTR *lpServiceArgVectors)
Definition: scm.c:2923
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define WAIT_OBJECT_0
Definition: winbase.h:387
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
#define GetProcessHeap()
Definition: compat.h:403
BOOL WINAPI FlushFileBuffers(IN HANDLE hFile)
Definition: fileinfo.c:175
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
ULONG prefix_data_len
Definition: rpc.c:127
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define LIST_INIT(head)
Definition: queue.h:197
__wchar_t WCHAR
Definition: xmlstorage.h:180
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
LONG HRESULT
Definition: typedefs.h:77
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define PIPE_ACCESS_DUPLEX
Definition: winbase.h:164
const GUID IID_IUnknown
RPC_SERVER_INTERFACE If
Definition: rpc.c:80
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
HRESULT RPC_RegisterChannelHook(REFGUID rguid, IChannelHook *hook)
Definition: rpc.c:424
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
ULONG size
Definition: rpc.c:141
static FILE * out
Definition: regtests2xml.c:44
HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
Definition: rpc.c:1804
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
static HRESULT unmarshal_ORPC_EXTENT_ARRAY(RPC_MESSAGE *msg, const char *end, ORPC_EXTENT_ARRAY *extensions, WIRE_ORPC_EXTENT **first_wire_orpc_extent)
Definition: rpc.c:1180
Definition: rpc.c:167
struct _RPC_SERVER_INTERFACE RPC_SERVER_INTERFACE
HWND apartment_getwindow(const struct apartment *apt)
Definition: compobj.c:1733
HRESULT start_apartment_remote_unknown(APARTMENT *apt) DECLSPEC_HIDDEN
Definition: stubmanager.c:818
HRESULT COM_OpenKeyForAppIdFromCLSID(REFCLSID clsid, REGSAM access, HKEY *subkey)
Definition: compobj.c:2480
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
IStream * stream
Definition: rpc.c:1890
void RPC_ExecuteCall(struct dispatch_params *params)
Definition: rpc.c:1327
BOOL WINAPI QueueUserWorkItem(IN LPTHREAD_START_ROUTINE Function, IN PVOID Context, IN ULONG Flags)
Definition: thread.c:1064
RpcChannelBuffer super
Definition: rpc.c:102
int ret
REFCLSID clsid
Definition: msctf.c:82
#define index(s, c)
Definition: various.h:29
#define seekto(pos, errstr)
Definition: mkdosfs.c:1613
#define InterlockedDecrement
Definition: armddk.h:52
Definition: parse.h:22
#define ERROR_PIPE_CONNECTED
Definition: winerror.h:352
GLuint GLuint stream
Definition: glext.h:7522
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2011
HRESULT enter_apartment(struct oletls *info, DWORD model)
Definition: compobj.c:1913
unsigned short MinorVersion
Definition: rpcdcep.h:28
HKEY key
Definition: reg.c:42
BOOL WINAPI DisconnectNamedPipe(HANDLE hNamedPipe)
Definition: npipe.c:961
APARTMENT * apartment_get_current_or_mta(void)
Definition: compobj.c:742
uint32_t entry
Definition: isohybrid.c:63
static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)
Definition: rpc.c:1443
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static struct list registered_interfaces
Definition: rpc.c:53
#define GUID_NULL
Definition: ks.h:106
Definition: _list.h:228
static DWORD WINAPI local_server_thread(LPVOID param)
Definition: rpc.c:1898
#define GENERIC_READ
Definition: compat.h:124
#define err(...)
RPC_STATUS WINAPI RpcBindingInqObject(RPC_BINDING_HANDLE Binding, UUID *ObjectUuid)
Definition: rpc_binding.c:812
struct _cl_event * event
Definition: glext.h:7739
LIST_ENTRY ProcessLocksList
Definition: winbase.h:855
#define RPC_E_CALL_REJECTED
Definition: winerror.h:2458
RPC_STATUS WINAPI RpcBindingSetObject(RPC_BINDING_HANDLE Binding, UUID *ObjectUuid)
Definition: rpc_binding.c:824
#define InterlockedExchange
Definition: armddk.h:54
#define SERVICE_START
Definition: winsvc.h:57
static HRESULT WINAPI ServerRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, REFIID riid)
Definition: rpc.c:506
static HRESULT unmarshal_ORPCTHAT(RPC_MESSAGE *msg, ORPCTHAT *orpcthat, ORPC_EXTENT_ARRAY *orpc_ext_array, WIRE_ORPC_EXTENT **first_wire_orpc_extent)
Definition: rpc.c:1284
RPC_STATUS WINAPI RpcServerUseProtseqEpW(RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor)
Definition: rpc_server.c:927
#define ERR(fmt,...)
Definition: debug.h:109
HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **manager, IRpcStubBuffer **stub, IRpcChannelBuffer **chan, IID *iid, IUnknown **iface) DECLSPEC_HIDDEN
Definition: stubmanager.c:533
#define S_OK
Definition: intsafe.h:59
Definition: nis.h:10
static HRESULT create_local_service(REFCLSID rclsid)
Definition: rpc.c:1741
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:2696
WINE_DEFAULT_DEBUG_CHANNEL(ole)
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
#define InterlockedIncrement
Definition: armddk.h:53
static HRESULT unmarshal_ORPCTHIS(RPC_MESSAGE *msg, ORPCTHIS *orpcthis, ORPC_EXTENT_ARRAY *orpc_ext_array, WIRE_ORPC_EXTENT **first_wire_orpc_extent)
Definition: rpc.c:1233
const char cursor[]
Definition: icontest.c:13
#define lstrcpyW
Definition: compat.h:414
UINT64 OXID
Definition: marshal.c:87
static const IRpcChannelBufferVtbl ClientRpcChannelBufferVtbl
Definition: rpc.c:1070
#define ARRAY_SIZE(a)
Definition: main.h:24
#define E_NOTIMPL
Definition: ddrawi.h:99
#define DETACHED_PROCESS
Definition: winbase.h:179
HRESULT RPC_RegisterInterface(REFIID riid)
Definition: rpc.c:1530
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define RPC_FLAGS_VALID_BIT
Definition: rpcdcep.h:52
#define RPC_C_PROTSEQ_MAX_REQS_DEFAULT
Definition: rpcdce.h:123
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
HANDLE thread
Definition: rpc.c:1893
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
DWORD target_tid
Definition: rpc.c:133
static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl
Definition: rpc.c:1082
BOOL bypass_rpcrt
Definition: rpc.c:119
#define E_UNEXPECTED
Definition: winerror.h:2456
#define CreateFileW
Definition: compat.h:408
#define RPC_E_VERSION_MISMATCH
Definition: winerror.h:2492
ULONG flags
Definition: rpc.c:163
#define RPC_E_RETRY
Definition: winerror.h:2485
#define msg(x)
Definition: auth_time.c:54
Definition: name.c:38
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus)
Definition: rpc.c:818
HRESULT RPC_ResolveOxid(OXID oxid, OXID_INFO *oxid_info)
Definition: rpc.c:1609
GLuint res
Definition: glext.h:9613
HWND target_hwnd
Definition: rpc.c:132
static HRESULT WINAPI ServerRpcChannelBuffer_FreeBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg)
Definition: rpc.c:974
unsigned int ULONG
Definition: retypes.h:1
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:41
HRESULT hr
Definition: rpc.c:121
static CRITICAL_SECTION_DEBUG csChannelHook_debug
Definition: rpc.c:65
ULONG reserved1
Definition: rpc.c:156
interface IRpcChannelBuffer * LPRPCCHANNELBUFFER
Definition: objfwd.h:39
static HRESULT WINAPI RpcChannelBuffer_QueryInterface(IRpcChannelBuffer *iface, REFIID riid, LPVOID *ppv)
Definition: rpc.c:460
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, const OXID_INFO *oxid_info, const IID *iid, DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan, APARTMENT *apt)
Definition: rpc.c:1095
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
static ULONG WINAPI ServerRpcChannelBuffer_Release(LPRPCCHANNELBUFFER iface)
Definition: rpc.c:478
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void exit(int exitcode)
Definition: _exit.c:33
void RPC_StartRemoting(struct apartment *apt)
Definition: rpc.c:1630
DWORD dest_context
Definition: rpc.c:96
WCHAR * LPWSTR
Definition: xmlstorage.h:184
HANDLE WINAPI CreateNamedPipeW(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: npipe.c:246
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
#define DM_EXECUTERPC
IRpcStubBuffer * stub
Definition: rpc.c:114
#define INFINITE
Definition: serial.h:102
#define ERROR_SERVICE_ALREADY_RUNNING
Definition: winerror.h:607
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
ULONG version
Definition: rpc.c:154
#define memset(x, y, z)
Definition: compat.h:39
RPC_SYNTAX_IDENTIFIER InterfaceId
Definition: rpcdcep.h:117
static SERVICE_STATUS status
Definition: service.c:31
BOOL WINAPI ConnectNamedPipe(IN HANDLE hNamedPipe, IN LPOVERLAPPED lpOverlapped)
Definition: npipe.c:701
static TfClientId tid
#define RPC_C_AUTHN_LEVEL_NONE
Definition: rpcdce.h:146
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
unsigned char data[1]
Definition: rpc.c:142
#define HeapFree(x, y, z)
Definition: compat.h:402
GUID id
Definition: rpc.c:170
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define WT_EXECUTEDEFAULT
Definition: winnt_old.h:1071
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1158
#define RPC_S_OK
Definition: rpcnterr.h:22
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static WCHAR wszRpcTransport[]
Definition: rpc.c:73
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
Definition: path.c:41
static void get_localserver_pipe_name(WCHAR *pipefn, REFCLSID rclsid)
Definition: rpc.c:1796
#define REG_SZ
Definition: layer.c:22
Definition: ps.c:97