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

Last change on this file since 7958 was 7958, checked in by sandervl, 24 years ago

put back old code

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