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