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