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