source: trunk/src/ole32/marshal.c@ 7954

Last change on this file since 7954 was 7954, checked in by phaller, 24 years ago

Moved CoGetPSClsid call to where it belongs

File size: 17.2 KB
Line 
1/*
2 * Marshaling library
3 *
4 * Copyright 2002 Marcus Meissner
5 */
6
7#include "config.h"
8
9#include <stdlib.h>
10#include <stdio.h>
11#include <string.h>
12#include <assert.h>
13
14#include "windef.h"
15#include "objbase.h"
16#include "ole2.h"
17#include "ole2ver.h"
18#include "rpc.h"
19#include "winerror.h"
20#include "winreg.h"
21#include "wownt32.h"
22#include "wtypes.h"
23#include "wine/unicode.h"
24#include "wine/obj_base.h"
25#include "wine/obj_clientserver.h"
26#include "wine/obj_misc.h"
27#include "wine/obj_marshal.h"
28#include "wine/obj_storage.h"
29#include "wine/obj_channel.h"
30#include "wine/winbase16.h"
31#include "compobj_private.h"
32#include "ifs.h"
33
34#include "debugtools.h"
35
36DEFAULT_DEBUG_CHANNEL(ole);
37
38/* Marshaling just passes a unique identifier to the remote client,
39 * that makes it possible to find the passed interface again.
40 *
41 * So basically we need a set of values that make it unique.
42 *
43 * Process Identifier, Object IUnknown ptr, IID
44 *
45 * Note that the IUnknown_QI(ob,xiid,&ppv) always returns the SAME ppv value!
46 */
47
48typedef struct _mid2unknown {
49 wine_marshal_id mid;
50 LPUNKNOWN pUnk;
51} mid2unknown;
52
53typedef struct _mid2stub {
54 wine_marshal_id mid;
55 IRpcStubBuffer *stub;
56 LPUNKNOWN pUnkServer;
57} mid2stub;
58
59static mid2stub *stubs = NULL;
60static int nrofstubs = 0;
61
62static mid2unknown *proxies = NULL;
63static int nrofproxies = 0;
64
65#ifdef __WIN32OS2__
66inline static HRESULT
67get_facbuf_for_iid(REFIID riid,IPSFactoryBuffer **facbuf) {
68 HRESULT hres;
69 CLSID pxclsid;
70
71 if ((hres = CoGetPSClsid(riid,&pxclsid)))
72 return hres;
73 return CoGetClassObject(&pxclsid,CLSCTX_INPROC_SERVER,NULL,&IID_IPSFactoryBuffer,(LPVOID*)facbuf);
74}
75#endif
76
77
78HRESULT
79MARSHAL_Find_Stub_Server(wine_marshal_id *mid,LPUNKNOWN *punk) {
80 int i;
81
82 for (i=0;i<nrofstubs;i++) {
83 if (MARSHAL_Compare_Mids_NoInterface(mid,&(stubs[i].mid))) {
84 *punk = stubs[i].pUnkServer;
85 IUnknown_AddRef((*punk));
86 return S_OK;
87 }
88 }
89 return E_FAIL;
90}
91
92HRESULT
93MARSHAL_Find_Stub_Buffer(wine_marshal_id *mid,IRpcStubBuffer **stub) {
94 int i;
95
96 for (i=0;i<nrofstubs;i++) {
97 if (MARSHAL_Compare_Mids(mid,&(stubs[i].mid))) {
98 *stub = stubs[i].stub;
99 IUnknown_AddRef((*stub));
100 return S_OK;
101 }
102 }
103 return E_FAIL;
104}
105
106HRESULT
107MARSHAL_Find_Stub(wine_marshal_id *mid,LPUNKNOWN *pUnk) {
108 int i;
109
110 for (i=0;i<nrofstubs;i++) {
111 if (MARSHAL_Compare_Mids(mid,&(stubs[i].mid))) {
112 *pUnk = stubs[i].pUnkServer;
113 IUnknown_AddRef((*pUnk));
114 return S_OK;
115 }
116 }
117 return E_FAIL;
118}
119
120HRESULT
121MARSHAL_Register_Stub(wine_marshal_id *mid,LPUNKNOWN pUnk,IRpcStubBuffer *stub) {
122 LPUNKNOWN xPunk;
123 if (!MARSHAL_Find_Stub(mid,&xPunk)) {
124 FIXME("Already have entry for (%lx/%s)!\n",mid->objectid,debugstr_guid(&(mid->iid)));
125 return S_OK;
126 }
127 if (nrofstubs)
128 stubs=HeapReAlloc(GetProcessHeap(),0,stubs,sizeof(stubs[0])*(nrofstubs+1));
129 else
130 stubs=HeapAlloc(GetProcessHeap(),0,sizeof(stubs[0]));
131 if (!stubs) return E_OUTOFMEMORY;
132 stubs[nrofstubs].stub = stub;
133 stubs[nrofstubs].pUnkServer = pUnk;
134 memcpy(&(stubs[nrofstubs].mid),mid,sizeof(*mid));
135 nrofstubs++;
136 return S_OK;
137}
138
139HRESULT
140MARSHAL_Find_Proxy(wine_marshal_id *mid,LPUNKNOWN *punk) {
141 int i;
142
143 for (i=0;i<nrofproxies;i++)
144 if (MARSHAL_Compare_Mids(mid,&(proxies[i].mid))) {
145 *punk = proxies[i].pUnk;
146 IUnknown_AddRef((*punk));
147 return S_OK;
148 }
149 return E_FAIL;
150}
151
152HRESULT
153MARSHAL_Find_Proxy_Object(wine_marshal_id *mid,LPUNKNOWN *punk) {
154 int i;
155
156 for (i=0;i<nrofproxies;i++)
157 if (MARSHAL_Compare_Mids_NoInterface(mid,&(proxies[i].mid))) {
158 *punk = proxies[i].pUnk;
159 IUnknown_AddRef((*punk));
160 return S_OK;
161 }
162 return E_FAIL;
163}
164
165HRESULT
166MARSHAL_Register_Proxy(wine_marshal_id *mid,LPUNKNOWN punk) {
167 int i;
168
169 for (i=0;i<nrofproxies;i++) {
170 if (MARSHAL_Compare_Mids(mid,&(proxies[i].mid))) {
171 ERR("Already have mid?\n");
172 return E_FAIL;
173 }
174 }
175 if (nrofproxies)
176 proxies = HeapReAlloc(GetProcessHeap(),0,proxies,sizeof(proxies[0])*(nrofproxies+1));
177 else
178 proxies = HeapAlloc(GetProcessHeap(),0,sizeof(proxies[0]));
179 memcpy(&(proxies[nrofproxies].mid),mid,sizeof(*mid));
180 proxies[nrofproxies].pUnk = punk;
181 nrofproxies++;
182 IUnknown_AddRef(punk);
183 return S_OK;
184}
185
186/********************** StdMarshal implementation ****************************/
187typedef struct _StdMarshalImpl {
188 ICOM_VTABLE(IMarshal) *lpvtbl;
189 DWORD ref;
190
191 IID iid;
192 DWORD dwDestContext;
193 LPVOID pvDestContext;
194 DWORD mshlflags;
195} StdMarshalImpl;
196
197HRESULT WINAPI
198StdMarshalImpl_QueryInterface(LPMARSHAL iface,REFIID riid,LPVOID *ppv) {
199 *ppv = NULL;
200 if (IsEqualIID(&IID_IUnknown,riid) || IsEqualIID(&IID_IMarshal,riid)) {
201 *ppv = iface;
202 IUnknown_AddRef(iface);
203 return S_OK;
204 }
205 FIXME("No interface for %s.\n",debugstr_guid(riid));
206 return E_NOINTERFACE;
207}
208
209ULONG WINAPI
210StdMarshalImpl_AddRef(LPMARSHAL iface) {
211 ICOM_THIS(StdMarshalImpl,iface);
212 This->ref++;
213 return This->ref;
214}
215
216ULONG WINAPI
217StdMarshalImpl_Release(LPMARSHAL iface) {
218 ICOM_THIS(StdMarshalImpl,iface);
219 This->ref--;
220
221 if (This->ref)
222 return This->ref;
223 HeapFree(GetProcessHeap(),0,This);
224 return 0;
225}
226
227HRESULT WINAPI
228StdMarshalImpl_GetUnmarshalClass(
229 LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
230 void* pvDestContext, DWORD mshlflags, CLSID* pCid
231) {
232 memcpy(pCid,&CLSID_DfMarshal,sizeof(CLSID_DfMarshal));
233 return S_OK;
234}
235
236HRESULT WINAPI
237StdMarshalImpl_GetMarshalSizeMax(
238 LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
239 void* pvDestContext, DWORD mshlflags, DWORD* pSize
240) {
241 *pSize = sizeof(wine_marshal_id)+sizeof(wine_marshal_data);
242 return S_OK;
243}
244
245HRESULT WINAPI
246StdMarshalImpl_MarshalInterface(
247 LPMARSHAL iface, IStream *pStm,REFIID riid, void* pv, DWORD dwDestContext,
248 void* pvDestContext, DWORD mshlflags
249) {
250 wine_marshal_id mid;
251 wine_marshal_data md;
252 IUnknown *pUnk;
253 ULONG res;
254 HRESULT hres;
255 IRpcStubBuffer *stub;
256 IPSFactoryBuffer *psfacbuf;
257
258 TRACE("(...,%s,...)\n",debugstr_guid(riid));
259 IUnknown_QueryInterface((LPUNKNOWN)pv,&IID_IUnknown,(LPVOID*)&pUnk);
260 mid.processid = GetCurrentProcessId();
261 mid.objectid = (DWORD)pUnk; /* FIXME */
262 IUnknown_Release(pUnk);
263 memcpy(&mid.iid,riid,sizeof(mid.iid));
264 md.dwDestContext = dwDestContext;
265 md.mshlflags = mshlflags;
266 hres = IStream_Write(pStm,&mid,sizeof(mid),&res);
267 if (hres) return hres;
268 hres = IStream_Write(pStm,&md,sizeof(md),&res);
269 if (hres) return hres;
270
271 if (SUCCEEDED(MARSHAL_Find_Stub(&mid,&pUnk))) {
272 IUnknown_Release(pUnk);
273 return S_OK;
274 }
275 hres = get_facbuf_for_iid(riid,&psfacbuf);
276 if (hres) return hres;
277 hres = IPSFactoryBuffer_CreateStub(psfacbuf,riid,pv,&stub);
278 IPSFactoryBuffer_Release(psfacbuf);
279 if (hres) {
280 FIXME("Failed to create a stub for %s\n",debugstr_guid(riid));
281 return hres;
282 }
283 IUnknown_QueryInterface((LPUNKNOWN)pv,riid,(LPVOID*)&pUnk);
284 MARSHAL_Register_Stub(&mid,pUnk,stub);
285 IUnknown_Release(pUnk);
286 return S_OK;
287}
288
289HRESULT WINAPI
290StdMarshalImpl_UnmarshalInterface(
291 LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv
292) {
293 wine_marshal_id mid;
294 wine_marshal_data md;
295 ULONG res;
296 HRESULT hres;
297 IPSFactoryBuffer *psfacbuf;
298 IRpcProxyBuffer *rpcproxy;
299 IRpcChannelBuffer *chanbuf;
300
301 TRACE("(...,%s,....)\n",debugstr_guid(riid));
302 hres = IStream_Read(pStm,&mid,sizeof(mid),&res);
303 if (hres) return hres;
304 hres = IStream_Read(pStm,&md,sizeof(md),&res);
305 if (hres) return hres;
306 if (SUCCEEDED(MARSHAL_Find_Stub(&mid,(LPUNKNOWN*)ppv))) {
307 FIXME("Calling back to ourselves for %s!\n",debugstr_guid(riid));
308 return S_OK;
309 }
310 hres = get_facbuf_for_iid(riid,&psfacbuf);
311 if (hres) return hres;
312 hres = IPSFactoryBuffer_CreateProxy(psfacbuf,NULL,riid,&rpcproxy,ppv);
313 if (hres) {
314 FIXME("Failed to create a proxy for %s\n",debugstr_guid(riid));
315 return hres;
316 }
317 hres = PIPE_GetNewPipeBuf(&mid,&chanbuf);
318 if (hres)
319 FIXME("Failed to get an rpc channel buffer for %s\n",debugstr_guid(riid));
320 IRpcProxyBuffer_Connect(rpcproxy,chanbuf);
321 IRpcProxyBuffer_Release(rpcproxy); /* no need */
322 IPSFactoryBuffer_Release(psfacbuf);
323 return S_OK;
324}
325
326HRESULT WINAPI
327StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
328 FIXME("(), stub!\n");
329 return S_OK;
330}
331
332HRESULT WINAPI
333StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved) {
334 FIXME("(), stub!\n");
335 return S_OK;
336}
337
338ICOM_VTABLE(IMarshal) stdmvtbl = {
339 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
340 StdMarshalImpl_QueryInterface,
341 StdMarshalImpl_AddRef,
342 StdMarshalImpl_Release,
343 StdMarshalImpl_GetUnmarshalClass,
344 StdMarshalImpl_GetMarshalSizeMax,
345 StdMarshalImpl_MarshalInterface,
346 StdMarshalImpl_UnmarshalInterface,
347 StdMarshalImpl_ReleaseMarshalData,
348 StdMarshalImpl_DisconnectObject
349};
350
351/***********************************************************************
352 * CoGetStandardMarshal [OLE32.23]
353 *
354 * When the COM library in the client process receives a marshaled
355 * interface pointer, it looks for a CLSID to be used in creating a proxy
356 * for the purposes of unmarshaling the packet. If the packet does not
357 * contain a CLSID for the proxy, COM calls CoGetStandardMarshal, passing a
358 * NULL pUnk value.
359 * This function creates a standard proxy in the client process and returns
360 * a pointer to that proxy's implementation of IMarshal.
361 * COM uses this pointer to call CoUnmarshalInterface to retrieve the pointer
362 * to the requested interface.
363 */
364HRESULT WINAPI
365CoGetStandardMarshal(
366 REFIID riid,IUnknown *pUnk,DWORD dwDestContext,LPVOID pvDestContext,
367 DWORD mshlflags, LPMARSHAL *pMarshal
368) {
369 StdMarshalImpl *dm;
370
371 if (pUnk == NULL) {
372 FIXME("(%s,NULL,%lx,%p,%lx,%p), unimplemented yet.\n",
373 debugstr_guid(riid),dwDestContext,pvDestContext,mshlflags,pMarshal
374 );
375 return E_FAIL;
376 }
377 TRACE("(%s,%p,%lx,%p,%lx,%p)\n",
378 debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,pMarshal
379 );
380#ifdef __WIN32OS2__
381 *pMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
382 dm = (StdMarshalImpl*) *pMarshal;
383#else
384 dm = (StdMarshalImpl*) *pMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
385#endif
386 if (!dm) return E_FAIL;
387 dm->lpvtbl = &stdmvtbl;
388 dm->ref = 1;
389
390 memcpy(&dm->iid,riid,sizeof(dm->iid));
391 dm->dwDestContext = dwDestContext;
392 dm->pvDestContext = pvDestContext;
393 dm->mshlflags = mshlflags;
394 return S_OK;
395}
396
397/* Helper function for getting Marshaler */
398static HRESULT WINAPI
399_GetMarshaller(REFIID riid, IUnknown *pUnk,DWORD dwDestContext,
400 void *pvDestContext, DWORD mshlFlags, LPMARSHAL *pMarshal
401) {
402 HRESULT hres;
403
404 if (!pUnk)
405 return E_POINTER;
406 hres = IUnknown_QueryInterface(pUnk,&IID_IMarshal,(LPVOID*)pMarshal);
407 if (hres)
408 hres = CoGetStandardMarshal(riid,pUnk,dwDestContext,pvDestContext,mshlFlags,pMarshal);
409 return hres;
410}
411
412/***********************************************************************
413 * CoGetMarshalSizeMax [OLE32.21]
414 */
415HRESULT WINAPI
416CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk,
417 DWORD dwDestContext, void *pvDestContext, DWORD mshlFlags
418) {
419 HRESULT hres;
420 LPMARSHAL pMarshal;
421
422 hres = _GetMarshaller(riid,pUnk,dwDestContext,pvDestContext,mshlFlags,&pMarshal);
423 if (hres)
424 return hres;
425 hres = IMarshal_GetMarshalSizeMax(pMarshal,riid,pUnk,dwDestContext,pvDestContext,mshlFlags,pulSize);
426 *pulSize += sizeof(wine_marshal_id)+sizeof(wine_marshal_data)+sizeof(CLSID);
427 IMarshal_Release(pMarshal);
428 return hres;
429}
430
431
432/***********************************************************************
433 * CoMarshalInterface [OLE32.34]
434 */
435HRESULT WINAPI
436CoMarshalInterface( IStream *pStm, REFIID riid, IUnknown *pUnk,
437 DWORD dwDestContext, void *pvDestContext, DWORD mshlflags
438) {
439 HRESULT hres;
440 LPMARSHAL pMarshal;
441 CLSID xclsid;
442 ULONG writeres;
443 wine_marshal_id mid;
444 wine_marshal_data md;
445 ULONG res;
446 IUnknown *pUnknown;
447
448 TRACE("(%p, %s, %p, %lx, %p, %lx)\n",
449 pStm,debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags
450 );
451 STUBMGR_Start(); /* Just to be sure we have one running. */
452 mid.processid = GetCurrentProcessId();
453 IUnknown_QueryInterface(pUnk,&IID_IUnknown,(LPVOID*)&pUnknown);
454 mid.objectid = (DWORD)pUnknown;
455 IUnknown_Release(pUnknown);
456 memcpy(&mid.iid,riid,sizeof(mid.iid));
457 md.dwDestContext = dwDestContext;
458 md.mshlflags = mshlflags;
459 hres = IStream_Write(pStm,&mid,sizeof(mid),&res);
460 if (hres) return hres;
461 hres = IStream_Write(pStm,&md,sizeof(md),&res);
462 if (hres) return hres;
463 hres = _GetMarshaller(riid,pUnk,dwDestContext,pvDestContext,mshlflags,&pMarshal);
464 if (hres) {
465 FIXME("Failed to get marshaller, %lx?\n",hres);
466 return hres;
467 }
468 hres = IMarshal_GetUnmarshalClass(pMarshal,riid,pUnk,dwDestContext,pvDestContext,mshlflags,&xclsid);
469 if (hres) {
470 FIXME("IMarshal:GetUnmarshalClass failed, %lx\n",hres);
471 goto release_marshal;
472 }
473 hres = IStream_Write(pStm,&xclsid,sizeof(xclsid),&writeres);
474 if (hres) {
475 FIXME("Stream write failed, %lx\n",hres);
476 goto release_marshal;
477 }
478 hres = IMarshal_MarshalInterface(pMarshal,pStm,riid,pUnk,dwDestContext,pvDestContext,mshlflags);
479 if (hres) {
480 FIXME("Failed to Marshal the interface, %lx?\n",hres);
481 goto release_marshal;
482 }
483release_marshal:
484 IMarshal_Release(pMarshal);
485 return hres;
486}
487
488
489/***********************************************************************
490 * CoUnmarshalInterface [OLE32.50]
491 */
492HRESULT WINAPI
493CoUnmarshalInterface(IStream *pStm, REFIID riid, LPVOID *ppv) {
494 HRESULT hres;
495 wine_marshal_id mid;
496 wine_marshal_data md;
497 ULONG res;
498 LPMARSHAL pMarshal;
499 LPUNKNOWN pUnk;
500 CLSID xclsid;
501
502 TRACE("(%p,%s,%p)\n",pStm,debugstr_guid(riid),ppv);
503
504 hres = IStream_Read(pStm,&mid,sizeof(mid),&res);
505 if (hres) {
506 FIXME("Stream read 1 failed, %lx, (%ld of %d)\n",hres,res,sizeof(mid));
507 return hres;
508 }
509 hres = IStream_Read(pStm,&md,sizeof(md),&res);
510 if (hres) {
511 FIXME("Stream read 2 failed, %lx, (%ld of %d)\n",hres,res,sizeof(md));
512 return hres;
513 }
514 hres = IStream_Read(pStm,&xclsid,sizeof(xclsid),&res);
515 if (hres) {
516 FIXME("Stream read 3 failed, %lx, (%ld of %d)\n",hres,res,sizeof(xclsid));
517 return hres;
518 }
519 hres=CoCreateInstance(&xclsid,NULL,CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER,&IID_IMarshal,(void**)&pUnk);
520 if (hres) {
521 FIXME("Failed to create instance of unmarshaller %s.\n",debugstr_guid(&xclsid));
522 return hres;
523 }
524 hres = _GetMarshaller(riid,pUnk,md.dwDestContext,NULL,md.mshlflags,&pMarshal);
525 if (hres) {
526 FIXME("Failed to get unmarshaller, %lx?\n",hres);
527 return hres;
528 }
529 hres = IMarshal_UnmarshalInterface(pMarshal,pStm,riid,ppv);
530 if (hres) {
531 FIXME("Failed to Unmarshal the interface, %lx?\n",hres);
532 goto release_marshal;
533 }
534release_marshal:
535 IMarshal_Release(pMarshal);
536 return hres;
537}
538
539/***********************************************************************
540 * CoMarshalInterThreadInterfaceInStream [OLE32.33]
541 *
542 * Marshal interfaces across threads. We don't have a thread distinction,
543 * meaning most interfaces just work across different threads, the RPC
544 * handles it.
545 */
546HRESULT WINAPI
547CoMarshalInterThreadInterfaceInStream(
548 REFIID riid, LPUNKNOWN pUnk, LPSTREAM * ppStm
549) {
550 ULONG res;
551 ULARGE_INTEGER xpos;
552 LARGE_INTEGER seekto;
553 HRESULT hres;
554
555 TRACE("(,%s,)\n",debugstr_guid(riid));
556 hres = CreateStreamOnHGlobal(0, TRUE, ppStm);
557 if (hres) return hres;
558 /* CoMarshalInterface(...); */
559 hres = IStream_Write(*ppStm,&pUnk,sizeof(LPUNKNOWN),&res);
560 if (hres) return hres;
561 memset(&seekto,0,sizeof(seekto));
562 IStream_Seek(*ppStm,seekto,SEEK_SET,&xpos);
563 return S_OK;
564}
565
566/***********************************************************************
567 * CoGetInterfaceAndReleaseStream [OLE32.19]
568 */
569HRESULT WINAPI
570CoGetInterfaceAndReleaseStream(LPSTREAM pStm,REFIID riid, LPVOID *ppv) {
571 ULONG res;
572 HRESULT hres;
573 LPUNKNOWN pUnk;
574
575 TRACE("(,%s,)\n",debugstr_guid(riid));
576 /* CoUnmarshalInterface(...); */
577 hres = IStream_Read(pStm,&pUnk,sizeof(LPUNKNOWN),&res);
578 if (hres) return hres;
579 IStream_Release(pStm);
580 return IUnknown_QueryInterface(pUnk,riid,ppv);
581}
582
583static HRESULT WINAPI
584SMCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv) {
585 *ppv = NULL;
586 if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IClassFactory)) {
587 *ppv = (LPVOID)iface;
588 return S_OK;
589 }
590 return E_NOINTERFACE;
591}
592static ULONG WINAPI SMCF_AddRef(LPCLASSFACTORY iface) { return 2; }
593static ULONG WINAPI SMCF_Release(LPCLASSFACTORY iface) { return 1; }
594
595static HRESULT WINAPI
596SMCF_CreateInstance(
597 LPCLASSFACTORY iface, LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv
598) {
599 if (IsEqualIID(riid,&IID_IMarshal)) {
600 StdMarshalImpl *dm;
601 dm=(StdMarshalImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
602 if (!dm)
603 return E_FAIL;
604 dm->lpvtbl = &stdmvtbl;
605 dm->ref = 1;
606 *ppv = (LPVOID)dm;
607 return S_OK;
608 }
609 FIXME("(%s), not supported.\n",debugstr_guid(riid));
610 return E_NOINTERFACE;
611}
612
613static HRESULT WINAPI
614SMCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) {
615 FIXME("(%d), stub!\n",fLock);
616 return S_OK;
617}
618
619static ICOM_VTABLE(IClassFactory) dfmarshalcfvtbl = {
620 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
621 SMCF_QueryInterface,
622 SMCF_AddRef,
623 SMCF_Release,
624 SMCF_CreateInstance,
625 SMCF_LockServer
626};
627static ICOM_VTABLE(IClassFactory) *pdfmarshalcfvtbl = &dfmarshalcfvtbl;
628
629HRESULT
630MARSHAL_GetStandardMarshalCF(LPVOID *ppv) {
631 *ppv = &pdfmarshalcfvtbl;
632 return S_OK;
633}
Note: See TracBrowser for help on using the repository browser.