1 /*
2 * OLE 2 default object handler
3 *
4 * Copyright 1999 Francis Beaudet
5 * Copyright 2000 Abey George
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 *
21 * NOTES:
22 * The OLE2 default object handler supports a whole whack of
23 * interfaces including:
24 * IOleObject, IDataObject, IPersistStorage, IViewObject2,
25 * IRunnableObject, IOleCache2, IOleCacheControl and much more.
26 *
27 * All the implementation details are taken from: Inside OLE
28 * second edition by Kraig Brockschmidt,
29 *
30 * TODO
31 * - This implementation of the default handler does not launch the
32 * server in the DoVerb, Update, GetData, GetDataHere and Run
33 * methods. When it is fixed to do so, all the methods will have
34 * to be revisited to allow delegating to the running object
35 *
36 * - All methods in the class that use the class ID should be
37 * aware that it is possible for a class to be treated as
38 * another one and go into emulation mode. Nothing has been
39 * done in this area.
40 *
41 * - Some functions still return E_NOTIMPL they have to be
42 * implemented. Most of those are related to the running of the
43 * actual server.
44 *
45 * - All the methods related to notification and advise sinks are
46 * in place but no notifications are sent to the sinks yet.
47 */
48 #include <assert.h>
49 #include <stdarg.h>
50 #include <string.h>
51
52 #define COBJMACROS
53
54 #include "windef.h"
55 #include "winbase.h"
56 #include "winuser.h"
57 #include "winerror.h"
58 #include "ole2.h"
59
60 #include "compobj_private.h"
61
62 #include "wine/unicode.h"
63 #include "wine/debug.h"
64
65 WINE_DEFAULT_DEBUG_CHANNEL(ole);
66
67 enum storage_state
68 {
69 storage_state_uninitialised,
70 storage_state_initialised,
71 storage_state_loaded
72 };
73
74 enum object_state
75 {
76 object_state_not_running,
77 object_state_running
78 };
79
80 /****************************************************************************
81 * DefaultHandler
82 *
83 */
84 struct DefaultHandler
85 {
86 IOleObject IOleObject_iface;
87 IUnknown IUnknown_iface;
88 IDataObject IDataObject_iface;
89 IRunnableObject IRunnableObject_iface;
90 IAdviseSink IAdviseSink_iface;
91 IPersistStorage IPersistStorage_iface;
92
93 /* Reference count of this object */
94 LONG ref;
95
96 /* IUnknown implementation of the outer object. */
97 IUnknown* outerUnknown;
98
99 /* Class Id that this handler object represents. */
100 CLSID clsid;
101
102 /* IUnknown implementation of the datacache. */
103 IUnknown* dataCache;
104 /* IPersistStorage implementation of the datacache. */
105 IPersistStorage* dataCache_PersistStg;
106
107 /* Client site for the embedded object. */
108 IOleClientSite* clientSite;
109
110 /*
111 * The IOleAdviseHolder maintains the connections
112 * on behalf of the default handler.
113 */
114 IOleAdviseHolder* oleAdviseHolder;
115
116 /*
117 * The IDataAdviseHolder maintains the data
118 * connections on behalf of the default handler.
119 */
120 IDataAdviseHolder* dataAdviseHolder;
121
122 /* Name of the container and object contained */
123 LPWSTR containerApp;
124 LPWSTR containerObj;
125
126 /* IOleObject delegate */
127 IOleObject *pOleDelegate;
128 /* IPersistStorage delegate */
129 IPersistStorage *pPSDelegate;
130 /* IDataObject delegate */
131 IDataObject *pDataDelegate;
132 enum object_state object_state;
133
134 /* connection cookie for the advise on the delegate OLE object */
135 DWORD dwAdvConn;
136
137 /* storage passed to Load or InitNew */
138 IStorage *storage;
139 enum storage_state storage_state;
140
141 /* optional class factory for object */
142 IClassFactory *pCFObject;
143 /* TRUE if acting as an inproc server instead of an inproc handler */
144 BOOL inproc_server;
145 };
146
147 typedef struct DefaultHandler DefaultHandler;
148
149 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
150 {
151 return CONTAINING_RECORD(iface, DefaultHandler, IOleObject_iface);
152 }
153
154 static inline DefaultHandler *impl_from_IUnknown( IUnknown *iface )
155 {
156 return CONTAINING_RECORD(iface, DefaultHandler, IUnknown_iface);
157 }
158
159 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
160 {
161 return CONTAINING_RECORD(iface, DefaultHandler, IDataObject_iface);
162 }
163
164 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
165 {
166 return CONTAINING_RECORD(iface, DefaultHandler, IRunnableObject_iface);
167 }
168
169 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
170 {
171 return CONTAINING_RECORD(iface, DefaultHandler, IAdviseSink_iface);
172 }
173
174 static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
175 {
176 return CONTAINING_RECORD(iface, DefaultHandler, IPersistStorage_iface);
177 }
178
179 static void DefaultHandler_Destroy(DefaultHandler* This);
180
181 static inline BOOL object_is_running(DefaultHandler *This)
182 {
183 return IRunnableObject_IsRunning(&This->IRunnableObject_iface);
184 }
185
186 /*********************************************************
187 * Method implementation for the non delegating IUnknown
188 * part of the DefaultHandler class.
189 */
190
191 /************************************************************************
192 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
193 *
194 * See Windows documentation for more details on IUnknown methods.
195 *
196 * This version of QueryInterface will not delegate its implementation
197 * to the outer unknown.
198 */
199 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
200 IUnknown* iface,
201 REFIID riid,
202 void** ppvObject)
203 {
204 DefaultHandler *This = impl_from_IUnknown(iface);
205
206 if (!ppvObject)
207 return E_INVALIDARG;
208
209 *ppvObject = NULL;
210
211 if (IsEqualIID(&IID_IUnknown, riid))
212 *ppvObject = iface;
213 else if (IsEqualIID(&IID_IOleObject, riid))
214 *ppvObject = &This->IOleObject_iface;
215 else if (IsEqualIID(&IID_IDataObject, riid))
216 *ppvObject = &This->IDataObject_iface;
217 else if (IsEqualIID(&IID_IRunnableObject, riid))
218 *ppvObject = &This->IRunnableObject_iface;
219 else if (IsEqualIID(&IID_IPersist, riid) ||
220 IsEqualIID(&IID_IPersistStorage, riid))
221 *ppvObject = &This->IPersistStorage_iface;
222 else if (IsEqualIID(&IID_IViewObject, riid) ||
223 IsEqualIID(&IID_IViewObject2, riid) ||
224 IsEqualIID(&IID_IOleCache, riid) ||
225 IsEqualIID(&IID_IOleCache2, riid))
226 {
227 HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
228 if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
229 return hr;
230 }
231 else if (This->inproc_server && This->pOleDelegate)
232 {
233 return IUnknown_QueryInterface(This->pOleDelegate, riid, ppvObject);
234 }
235
236 /* Check that we obtained an interface. */
237 if (*ppvObject == NULL)
238 {
239 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
240 return E_NOINTERFACE;
241 }
242
243 /*
244 * Query Interface always increases the reference count by one when it is
245 * successful.
246 */
247 IUnknown_AddRef((IUnknown*)*ppvObject);
248
249 return S_OK;
250 }
251
252 /************************************************************************
253 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
254 *
255 * See Windows documentation for more details on IUnknown methods.
256 *
257 * This version of QueryInterface will not delegate its implementation
258 * to the outer unknown.
259 */
260 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
261 IUnknown* iface)
262 {
263 DefaultHandler *This = impl_from_IUnknown(iface);
264 return InterlockedIncrement(&This->ref);
265 }
266
267 /************************************************************************
268 * DefaultHandler_NDIUnknown_Release (IUnknown)
269 *
270 * See Windows documentation for more details on IUnknown methods.
271 *
272 * This version of QueryInterface will not delegate its implementation
273 * to the outer unknown.
274 */
275 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
276 IUnknown* iface)
277 {
278 DefaultHandler *This = impl_from_IUnknown(iface);
279 ULONG ref;
280
281 ref = InterlockedDecrement(&This->ref);
282
283 if (!ref) DefaultHandler_Destroy(This);
284
285 return ref;
286 }
287
288 /*********************************************************
289 * Methods implementation for the IOleObject part of
290 * the DefaultHandler class.
291 */
292
293 /************************************************************************
294 * DefaultHandler_QueryInterface (IUnknown)
295 *
296 * See Windows documentation for more details on IUnknown methods.
297 */
298 static HRESULT WINAPI DefaultHandler_QueryInterface(
299 IOleObject* iface,
300 REFIID riid,
301 void** ppvObject)
302 {
303 DefaultHandler *This = impl_from_IOleObject(iface);
304
305 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
306 }
307
308 /************************************************************************
309 * DefaultHandler_AddRef (IUnknown)
310 *
311 * See Windows documentation for more details on IUnknown methods.
312 */
313 static ULONG WINAPI DefaultHandler_AddRef(
314 IOleObject* iface)
315 {
316 DefaultHandler *This = impl_from_IOleObject(iface);
317
318 return IUnknown_AddRef(This->outerUnknown);
319 }
320
321 /************************************************************************
322 * DefaultHandler_Release (IUnknown)
323 *
324 * See Windows documentation for more details on IUnknown methods.
325 */
326 static ULONG WINAPI DefaultHandler_Release(
327 IOleObject* iface)
328 {
329 DefaultHandler *This = impl_from_IOleObject(iface);
330
331 return IUnknown_Release(This->outerUnknown);
332 }
333
334 /************************************************************************
335 * DefaultHandler_SetClientSite (IOleObject)
336 *
337 * The default handler's implementation of this method only keeps the
338 * client site pointer for future reference.
339 *
340 * See Windows documentation for more details on IOleObject methods.
341 */
342 static HRESULT WINAPI DefaultHandler_SetClientSite(
343 IOleObject* iface,
344 IOleClientSite* pClientSite)
345 {
346 DefaultHandler *This = impl_from_IOleObject(iface);
347 HRESULT hr = S_OK;
348
349 TRACE("(%p, %p)\n", iface, pClientSite);
350
351 if (object_is_running(This))
352 hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
353
354 /*
355 * Make sure we release the previous client site if there
356 * was one.
357 */
358 if (This->clientSite)
359 IOleClientSite_Release(This->clientSite);
360
361 This->clientSite = pClientSite;
362
363 if (This->clientSite)
364 IOleClientSite_AddRef(This->clientSite);
365
366 return hr;
367 }
368
369 /************************************************************************
370 * DefaultHandler_GetClientSite (IOleObject)
371 *
372 * The default handler's implementation of this method returns the
373 * last pointer set in IOleObject_SetClientSite.
374 *
375 * See Windows documentation for more details on IOleObject methods.
376 */
377 static HRESULT WINAPI DefaultHandler_GetClientSite(
378 IOleObject* iface,
379 IOleClientSite** ppClientSite)
380 {
381 DefaultHandler *This = impl_from_IOleObject(iface);
382
383 if (!ppClientSite)
384 return E_POINTER;
385
386 *ppClientSite = This->clientSite;
387
388 if (This->clientSite)
389 IOleClientSite_AddRef(This->clientSite);
390
391 return S_OK;
392 }
393
394 /************************************************************************
395 * DefaultHandler_SetHostNames (IOleObject)
396 *
397 * The default handler's implementation of this method just stores
398 * the strings and returns S_OK.
399 *
400 * See Windows documentation for more details on IOleObject methods.
401 */
402 static HRESULT WINAPI DefaultHandler_SetHostNames(
403 IOleObject* iface,
404 LPCOLESTR szContainerApp,
405 LPCOLESTR szContainerObj)
406 {
407 DefaultHandler *This = impl_from_IOleObject(iface);
408
409 TRACE("(%p, %s, %s)\n",
410 iface,
411 debugstr_w(szContainerApp),
412 debugstr_w(szContainerObj));
413
414 if (object_is_running(This))
415 IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
416
417 /* Be sure to cleanup before re-assigning the strings. */
418 HeapFree( GetProcessHeap(), 0, This->containerApp );
419 This->containerApp = NULL;
420 HeapFree( GetProcessHeap(), 0, This->containerObj );
421 This->containerObj = NULL;
422
423 if (szContainerApp)
424 {
425 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
426 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
427 strcpyW( This->containerApp, szContainerApp );
428 }
429
430 if (szContainerObj)
431 {
432 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
433 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
434 strcpyW( This->containerObj, szContainerObj );
435 }
436 return S_OK;
437 }
438
439 static void release_delegates(DefaultHandler *This)
440 {
441 if (This->pDataDelegate)
442 {
443 IDataObject_Release(This->pDataDelegate);
444 This->pDataDelegate = NULL;
445 }
446 if (This->pPSDelegate)
447 {
448 IPersistStorage_Release(This->pPSDelegate);
449 This->pPSDelegate = NULL;
450 }
451 if (This->pOleDelegate)
452 {
453 IOleObject_Release(This->pOleDelegate);
454 This->pOleDelegate = NULL;
455 }
456 }
457
458 /* undoes the work done by DefaultHandler_Run */
459 static void DefaultHandler_Stop(DefaultHandler *This)
460 {
461 if (!object_is_running(This))
462 return;
463
464 IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
465
466 /* FIXME: call IOleCache_OnStop */
467
468 if (This->dataAdviseHolder)
469 DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
470
471 This->object_state = object_state_not_running;
472 }
473
474 /************************************************************************
475 * DefaultHandler_Close (IOleObject)
476 *
477 * The default handler's implementation of this method is meaningless
478 * without a running server so it does nothing.
479 *
480 * See Windows documentation for more details on IOleObject methods.
481 */
482 static HRESULT WINAPI DefaultHandler_Close(
483 IOleObject* iface,
484 DWORD dwSaveOption)
485 {
486 DefaultHandler *This = impl_from_IOleObject(iface);
487 HRESULT hr;
488
489 TRACE("(%d)\n", dwSaveOption);
490
491 if (!object_is_running(This))
492 return S_OK;
493
494 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
495
496 DefaultHandler_Stop(This);
497 release_delegates(This);
498
499 return hr;
500 }
501
502 /************************************************************************
503 * DefaultHandler_SetMoniker (IOleObject)
504 *
505 * The default handler's implementation of this method does nothing.
506 *
507 * See Windows documentation for more details on IOleObject methods.
508 */
509 static HRESULT WINAPI DefaultHandler_SetMoniker(
510 IOleObject* iface,
511 DWORD dwWhichMoniker,
512 IMoniker* pmk)
513 {
514 DefaultHandler *This = impl_from_IOleObject(iface);
515
516 TRACE("(%p, %d, %p)\n",
517 iface,
518 dwWhichMoniker,
519 pmk);
520
521 if (object_is_running(This))
522 return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
523
524 return S_OK;
525 }
526
527 /************************************************************************
528 * DefaultHandler_GetMoniker (IOleObject)
529 *
530 * Delegate this request to the client site if we have one.
531 *
532 * See Windows documentation for more details on IOleObject methods.
533 */
534 static HRESULT WINAPI DefaultHandler_GetMoniker(
535 IOleObject* iface,
536 DWORD dwAssign,
537 DWORD dwWhichMoniker,
538 IMoniker** ppmk)
539 {
540 DefaultHandler *This = impl_from_IOleObject(iface);
541
542 TRACE("(%p, %d, %d, %p)\n",
543 iface, dwAssign, dwWhichMoniker, ppmk);
544
545 if (object_is_running(This))
546 return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
547 ppmk);
548
549 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
550 if (This->clientSite)
551 {
552 return IOleClientSite_GetMoniker(This->clientSite,
553 dwAssign,
554 dwWhichMoniker,
555 ppmk);
556
557 }
558
559 return E_FAIL;
560 }
561
562 /************************************************************************
563 * DefaultHandler_InitFromData (IOleObject)
564 *
565 * This method is meaningless if the server is not running
566 *
567 * See Windows documentation for more details on IOleObject methods.
568 */
569 static HRESULT WINAPI DefaultHandler_InitFromData(
570 IOleObject* iface,
571 IDataObject* pDataObject,
572 BOOL fCreation,
573 DWORD dwReserved)
574 {
575 DefaultHandler *This = impl_from_IOleObject(iface);
576
577 TRACE("(%p, %p, %d, %d)\n",
578 iface, pDataObject, fCreation, dwReserved);
579
580 if (object_is_running(This))
581 return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
582 dwReserved);
583 return OLE_E_NOTRUNNING;
584 }
585
586 /************************************************************************
587 * DefaultHandler_GetClipboardData (IOleObject)
588 *
589 * This method is meaningless if the server is not running
590 *
591 * See Windows documentation for more details on IOleObject methods.
592 */
593 static HRESULT WINAPI DefaultHandler_GetClipboardData(
594 IOleObject* iface,
595 DWORD dwReserved,
596 IDataObject** ppDataObject)
597 {
598 DefaultHandler *This = impl_from_IOleObject(iface);
599
600 TRACE("(%p, %d, %p)\n",
601 iface, dwReserved, ppDataObject);
602
603 if (object_is_running(This))
604 return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
605 ppDataObject);
606
607 return OLE_E_NOTRUNNING;
608 }
609
610 static HRESULT WINAPI DefaultHandler_DoVerb(
611 IOleObject* iface,
612 LONG iVerb,
613 struct tagMSG* lpmsg,
614 IOleClientSite* pActiveSite,
615 LONG lindex,
616 HWND hwndParent,
617 LPCRECT lprcPosRect)
618 {
619 DefaultHandler *This = impl_from_IOleObject(iface);
620 IRunnableObject *pRunnableObj = &This->IRunnableObject_iface;
621 HRESULT hr;
622
623 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
624
625 hr = IRunnableObject_Run(pRunnableObj, NULL);
626 if (FAILED(hr)) return hr;
627
628 return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
629 lindex, hwndParent, lprcPosRect);
630 }
631
632 /************************************************************************
633 * DefaultHandler_EnumVerbs (IOleObject)
634 *
635 * The default handler implementation of this method simply delegates
636 * to OleRegEnumVerbs
637 *
638 * See Windows documentation for more details on IOleObject methods.
639 */
640 static HRESULT WINAPI DefaultHandler_EnumVerbs(
641 IOleObject* iface,
642 IEnumOLEVERB** ppEnumOleVerb)
643 {
644 DefaultHandler *This = impl_from_IOleObject(iface);
645 HRESULT hr = OLE_S_USEREG;
646
647 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
648
649 if (object_is_running(This))
650 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
651
652 if (hr == OLE_S_USEREG)
653 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
654 else
655 return hr;
656 }
657
658 static HRESULT WINAPI DefaultHandler_Update(
659 IOleObject* iface)
660 {
661 DefaultHandler *This = impl_from_IOleObject(iface);
662 TRACE("(%p)\n", iface);
663
664 if (!object_is_running(This))
665 {
666 FIXME("Should run object\n");
667 return E_NOTIMPL;
668 }
669 return IOleObject_Update(This->pOleDelegate);
670 }
671
672 /************************************************************************
673 * DefaultHandler_IsUpToDate (IOleObject)
674 *
675 * This method is meaningless if the server is not running
676 *
677 * See Windows documentation for more details on IOleObject methods.
678 */
679 static HRESULT WINAPI DefaultHandler_IsUpToDate(
680 IOleObject* iface)
681 {
682 DefaultHandler *This = impl_from_IOleObject(iface);
683 TRACE("(%p)\n", iface);
684
685 if (object_is_running(This))
686 return IOleObject_IsUpToDate(This->pOleDelegate);
687
688 return OLE_E_NOTRUNNING;
689 }
690
691 /************************************************************************
692 * DefaultHandler_GetUserClassID (IOleObject)
693 *
694 * TODO: Map to a new class ID if emulation is active.
695 *
696 * See Windows documentation for more details on IOleObject methods.
697 */
698 static HRESULT WINAPI DefaultHandler_GetUserClassID(
699 IOleObject* iface,
700 CLSID* pClsid)
701 {
702 DefaultHandler *This = impl_from_IOleObject(iface);
703
704 TRACE("(%p, %p)\n", iface, pClsid);
705
706 if (object_is_running(This))
707 return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
708
709 if (!pClsid)
710 return E_POINTER;
711
712 *pClsid = This->clsid;
713
714 return S_OK;
715 }
716
717 /************************************************************************
718 * DefaultHandler_GetUserType (IOleObject)
719 *
720 * The default handler implementation of this method simply delegates
721 * to OleRegGetUserType
722 *
723 * See Windows documentation for more details on IOleObject methods.
724 */
725 static HRESULT WINAPI DefaultHandler_GetUserType(
726 IOleObject* iface,
727 DWORD dwFormOfType,
728 LPOLESTR* pszUserType)
729 {
730 DefaultHandler *This = impl_from_IOleObject(iface);
731
732 TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
733 if (object_is_running(This))
734 return IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
735
736 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
737 }
738
739 /************************************************************************
740 * DefaultHandler_SetExtent (IOleObject)
741 *
742 * This method is meaningless if the server is not running
743 *
744 * See Windows documentation for more details on IOleObject methods.
745 */
746 static HRESULT WINAPI DefaultHandler_SetExtent(
747 IOleObject* iface,
748 DWORD dwDrawAspect,
749 SIZEL* psizel)
750 {
751 DefaultHandler *This = impl_from_IOleObject(iface);
752
753 TRACE("(%p, %x, (%d x %d))\n", iface,
754 dwDrawAspect, psizel->cx, psizel->cy);
755
756 if (object_is_running(This))
757 return IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
758
759 return OLE_E_NOTRUNNING;
760 }
761
762 /************************************************************************
763 * DefaultHandler_GetExtent (IOleObject)
764 *
765 * The default handler's implementation of this method returns uses
766 * the cache to locate the aspect and extract the extent from it.
767 *
768 * See Windows documentation for more details on IOleObject methods.
769 */
770 static HRESULT WINAPI DefaultHandler_GetExtent(
771 IOleObject* iface,
772 DWORD dwDrawAspect,
773 SIZEL* psizel)
774 {
775 DVTARGETDEVICE* targetDevice;
776 IViewObject2* cacheView = NULL;
777 HRESULT hres;
778
779 DefaultHandler *This = impl_from_IOleObject(iface);
780
781 TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
782
783 if (object_is_running(This))
784 return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
785
786 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
787 if (FAILED(hres))
788 return E_UNEXPECTED;
789
790 /*
791 * Prepare the call to the cache's GetExtent method.
792 *
793 * Here we would build a valid DVTARGETDEVICE structure
794 * but, since we are calling into the data cache, we
795 * know its implementation and we'll skip this
796 * extra work until later.
797 */
798 targetDevice = NULL;
799
800 hres = IViewObject2_GetExtent(cacheView,
801 dwDrawAspect,
802 -1,
803 targetDevice,
804 psizel);
805
806 IViewObject2_Release(cacheView);
807
808 return hres;
809 }
810
811 /************************************************************************
812 * DefaultHandler_Advise (IOleObject)
813 *
814 * The default handler's implementation of this method simply
815 * delegates to the OleAdviseHolder.
816 *
817 * See Windows documentation for more details on IOleObject methods.
818 */
819 static HRESULT WINAPI DefaultHandler_Advise(
820 IOleObject* iface,
821 IAdviseSink* pAdvSink,
822 DWORD* pdwConnection)
823 {
824 HRESULT hres = S_OK;
825 DefaultHandler *This = impl_from_IOleObject(iface);
826
827 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
828
829 /* Make sure we have an advise holder before we start. */
830 if (!This->oleAdviseHolder)
831 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
832
833 if (SUCCEEDED(hres))
834 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
835 pAdvSink,
836 pdwConnection);
837
838 return hres;
839 }
840
841 /************************************************************************
842 * DefaultHandler_Unadvise (IOleObject)
843 *
844 * The default handler's implementation of this method simply
845 * delegates to the OleAdviseHolder.
846 *
847 * See Windows documentation for more details on IOleObject methods.
848 */
849 static HRESULT WINAPI DefaultHandler_Unadvise(
850 IOleObject* iface,
851 DWORD dwConnection)
852 {
853 DefaultHandler *This = impl_from_IOleObject(iface);
854
855 TRACE("(%p, %d)\n", iface, dwConnection);
856
857 /*
858 * If we don't have an advise holder yet, it means we don't have
859 * a connection.
860 */
861 if (!This->oleAdviseHolder)
862 return OLE_E_NOCONNECTION;
863
864 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
865 dwConnection);
866 }
867
868 /************************************************************************
869 * DefaultHandler_EnumAdvise (IOleObject)
870 *
871 * The default handler's implementation of this method simply
872 * delegates to the OleAdviseHolder.
873 *
874 * See Windows documentation for more details on IOleObject methods.
875 */
876 static HRESULT WINAPI DefaultHandler_EnumAdvise(
877 IOleObject* iface,
878 IEnumSTATDATA** ppenumAdvise)
879 {
880 DefaultHandler *This = impl_from_IOleObject(iface);
881
882 TRACE("(%p, %p)\n", iface, ppenumAdvise);
883
884 if (!ppenumAdvise)
885 return E_POINTER;
886
887 *ppenumAdvise = NULL;
888
889 if (!This->oleAdviseHolder)
890 return S_OK;
891
892 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
893 }
894
895 /************************************************************************
896 * DefaultHandler_GetMiscStatus (IOleObject)
897 *
898 * The default handler's implementation of this method simply delegates
899 * to OleRegGetMiscStatus.
900 *
901 * See Windows documentation for more details on IOleObject methods.
902 */
903 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
904 IOleObject* iface,
905 DWORD dwAspect,
906 DWORD* pdwStatus)
907 {
908 HRESULT hres;
909 DefaultHandler *This = impl_from_IOleObject(iface);
910
911 TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
912
913 if (object_is_running(This))
914 return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
915
916 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
917
918 if (FAILED(hres))
919 *pdwStatus = 0;
920
921 return hres;
922 }
923
924 /************************************************************************
925 * DefaultHandler_SetColorScheme (IOleObject)
926 *
927 * This method is meaningless if the server is not running
928 *
929 * See Windows documentation for more details on IOleObject methods.
930 */
931 static HRESULT WINAPI DefaultHandler_SetColorScheme(
932 IOleObject* iface,
933 struct tagLOGPALETTE* pLogpal)
934 {
935 DefaultHandler *This = impl_from_IOleObject(iface);
936
937 TRACE("(%p, %p))\n", iface, pLogpal);
938
939 if (object_is_running(This))
940 return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
941
942 return OLE_E_NOTRUNNING;
943 }
944
945 /*********************************************************
946 * Methods implementation for the IDataObject part of
947 * the DefaultHandler class.
948 */
949
950 /************************************************************************
951 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
952 *
953 * See Windows documentation for more details on IUnknown methods.
954 */
955 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
956 IDataObject* iface,
957 REFIID riid,
958 void** ppvObject)
959 {
960 DefaultHandler *This = impl_from_IDataObject(iface);
961
962 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
963 }
964
965 /************************************************************************
966 * DefaultHandler_IDataObject_AddRef (IUnknown)
967 *
968 * See Windows documentation for more details on IUnknown methods.
969 */
970 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
971 IDataObject* iface)
972 {
973 DefaultHandler *This = impl_from_IDataObject(iface);
974
975 return IUnknown_AddRef(This->outerUnknown);
976 }
977
978 /************************************************************************
979 * DefaultHandler_IDataObject_Release (IUnknown)
980 *
981 * See Windows documentation for more details on IUnknown methods.
982 */
983 static ULONG WINAPI DefaultHandler_IDataObject_Release(
984 IDataObject* iface)
985 {
986 DefaultHandler *This = impl_from_IDataObject(iface);
987
988 return IUnknown_Release(This->outerUnknown);
989 }
990
991 /************************************************************************
992 * DefaultHandler_GetData
993 *
994 * Get Data from a source dataobject using format pformatetcIn->cfFormat
995 * See Windows documentation for more details on GetData.
996 * Default handler's implementation of this method delegates to the cache.
997 */
998 static HRESULT WINAPI DefaultHandler_GetData(
999 IDataObject* iface,
1000 LPFORMATETC pformatetcIn,
1001 STGMEDIUM* pmedium)
1002 {
1003 IDataObject* cacheDataObject = NULL;
1004 HRESULT hres;
1005
1006 DefaultHandler *This = impl_from_IDataObject(iface);
1007
1008 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
1009
1010 hres = IUnknown_QueryInterface(This->dataCache,
1011 &IID_IDataObject,
1012 (void**)&cacheDataObject);
1013
1014 if (FAILED(hres))
1015 return E_UNEXPECTED;
1016
1017 hres = IDataObject_GetData(cacheDataObject,
1018 pformatetcIn,
1019 pmedium);
1020
1021 IDataObject_Release(cacheDataObject);
1022
1023 if (FAILED(hres) && This->pDataDelegate)
1024 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
1025
1026 return hres;
1027 }
1028
1029 static HRESULT WINAPI DefaultHandler_GetDataHere(
1030 IDataObject* iface,
1031 LPFORMATETC pformatetc,
1032 STGMEDIUM* pmedium)
1033 {
1034 FIXME(": Stub\n");
1035 return E_NOTIMPL;
1036 }
1037
1038 /************************************************************************
1039 * DefaultHandler_QueryGetData (IDataObject)
1040 *
1041 * The default handler's implementation of this method delegates to
1042 * the cache.
1043 *
1044 * See Windows documentation for more details on IDataObject methods.
1045 */
1046 static HRESULT WINAPI DefaultHandler_QueryGetData(
1047 IDataObject* iface,
1048 LPFORMATETC pformatetc)
1049 {
1050 IDataObject* cacheDataObject = NULL;
1051 HRESULT hres;
1052
1053 DefaultHandler *This = impl_from_IDataObject(iface);
1054
1055 TRACE("(%p, %p)\n", iface, pformatetc);
1056
1057 hres = IUnknown_QueryInterface(This->dataCache,
1058 &IID_IDataObject,
1059 (void**)&cacheDataObject);
1060
1061 if (FAILED(hres))
1062 return E_UNEXPECTED;
1063
1064 hres = IDataObject_QueryGetData(cacheDataObject,
1065 pformatetc);
1066
1067 IDataObject_Release(cacheDataObject);
1068
1069 if (FAILED(hres) && This->pDataDelegate)
1070 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1071
1072 return hres;
1073 }
1074
1075 /************************************************************************
1076 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1077 *
1078 * This method is meaningless if the server is not running
1079 *
1080 * See Windows documentation for more details on IDataObject methods.
1081 */
1082 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1083 IDataObject* iface,
1084 LPFORMATETC pformatetcIn,
1085 LPFORMATETC pformatetcOut)
1086 {
1087 DefaultHandler *This = impl_from_IDataObject(iface);
1088
1089 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1090
1091 if (!This->pDataDelegate)
1092 return OLE_E_NOTRUNNING;
1093
1094 return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1095 }
1096
1097 /************************************************************************
1098 * DefaultHandler_SetData (IDataObject)
1099 *
1100 * The default handler's implementation of this method delegates to
1101 * the cache.
1102 *
1103 * See Windows documentation for more details on IDataObject methods.
1104 */
1105 static HRESULT WINAPI DefaultHandler_SetData(
1106 IDataObject* iface,
1107 LPFORMATETC pformatetc,
1108 STGMEDIUM* pmedium,
1109 BOOL fRelease)
1110 {
1111 DefaultHandler *This = impl_from_IDataObject(iface);
1112 IDataObject* cacheDataObject = NULL;
1113 HRESULT hres;
1114
1115 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1116
1117 hres = IUnknown_QueryInterface(This->dataCache,
1118 &IID_IDataObject,
1119 (void**)&cacheDataObject);
1120
1121 if (FAILED(hres))
1122 return E_UNEXPECTED;
1123
1124 hres = IDataObject_SetData(cacheDataObject,
1125 pformatetc,
1126 pmedium,
1127 fRelease);
1128
1129 IDataObject_Release(cacheDataObject);
1130
1131 return hres;
1132 }
1133
1134 /************************************************************************
1135 * DefaultHandler_EnumFormatEtc (IDataObject)
1136 *
1137 * The default handler's implementation of This method simply delegates
1138 * to OleRegEnumFormatEtc.
1139 *
1140 * See Windows documentation for more details on IDataObject methods.
1141 */
1142 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1143 IDataObject* iface,
1144 DWORD dwDirection,
1145 IEnumFORMATETC** ppenumFormatEtc)
1146 {
1147 DefaultHandler *This = impl_from_IDataObject(iface);
1148
1149 TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1150
1151 return OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1152 }
1153
1154 /************************************************************************
1155 * DefaultHandler_DAdvise (IDataObject)
1156 *
1157 * The default handler's implementation of this method simply
1158 * delegates to the DataAdviseHolder.
1159 *
1160 * See Windows documentation for more details on IDataObject methods.
1161 */
1162 static HRESULT WINAPI DefaultHandler_DAdvise(
1163 IDataObject* iface,
1164 FORMATETC* pformatetc,
1165 DWORD advf,
1166 IAdviseSink* pAdvSink,
1167 DWORD* pdwConnection)
1168 {
1169 HRESULT hres = S_OK;
1170 DefaultHandler *This = impl_from_IDataObject(iface);
1171
1172 TRACE("(%p, %p, %d, %p, %p)\n",
1173 iface, pformatetc, advf, pAdvSink, pdwConnection);
1174
1175 /* Make sure we have a data advise holder before we start. */
1176 if (!This->dataAdviseHolder)
1177 {
1178 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1179 if (SUCCEEDED(hres) && This->pDataDelegate)
1180 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1181 }
1182
1183 if (SUCCEEDED(hres))
1184 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1185 iface,
1186 pformatetc,
1187 advf,
1188 pAdvSink,
1189 pdwConnection);
1190
1191 return hres;
1192 }
1193
1194 /************************************************************************
1195 * DefaultHandler_DUnadvise (IDataObject)
1196 *
1197 * The default handler's implementation of this method simply
1198 * delegates to the DataAdviseHolder.
1199 *
1200 * See Windows documentation for more details on IDataObject methods.
1201 */
1202 static HRESULT WINAPI DefaultHandler_DUnadvise(
1203 IDataObject* iface,
1204 DWORD dwConnection)
1205 {
1206 DefaultHandler *This = impl_from_IDataObject(iface);
1207
1208 TRACE("(%p, %d)\n", iface, dwConnection);
1209
1210 /*
1211 * If we don't have a data advise holder yet, it means that
1212 * we don't have any connections..
1213 */
1214 if (!This->dataAdviseHolder)
1215 return OLE_E_NOCONNECTION;
1216
1217 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1218 dwConnection);
1219 }
1220
1221 /************************************************************************
1222 * DefaultHandler_EnumDAdvise (IDataObject)
1223 *
1224 * The default handler's implementation of this method simply
1225 * delegates to the DataAdviseHolder.
1226 *
1227 * See Windows documentation for more details on IDataObject methods.
1228 */
1229 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1230 IDataObject* iface,
1231 IEnumSTATDATA** ppenumAdvise)
1232 {
1233 DefaultHandler *This = impl_from_IDataObject(iface);
1234
1235 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1236
1237 if (!ppenumAdvise)
1238 return E_POINTER;
1239
1240 *ppenumAdvise = NULL;
1241
1242 /* If we have a data advise holder object, delegate. */
1243 if (This->dataAdviseHolder)
1244 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1245 ppenumAdvise);
1246
1247 return S_OK;
1248 }
1249
1250 /*********************************************************
1251 * Methods implementation for the IRunnableObject part
1252 * of the DefaultHandler class.
1253 */
1254
1255 /************************************************************************
1256 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1257 *
1258 * See Windows documentation for more details on IUnknown methods.
1259 */
1260 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1261 IRunnableObject* iface,
1262 REFIID riid,
1263 void** ppvObject)
1264 {
1265 DefaultHandler *This = impl_from_IRunnableObject(iface);
1266
1267 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1268 }
1269
1270 /************************************************************************
1271 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1272 *
1273 * See Windows documentation for more details on IUnknown methods.
1274 */
1275 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1276 IRunnableObject* iface)
1277 {
1278 DefaultHandler *This = impl_from_IRunnableObject(iface);
1279
1280 return IUnknown_AddRef(This->outerUnknown);
1281 }
1282
1283 /************************************************************************
1284 * DefaultHandler_IRunnableObject_Release (IUnknown)
1285 *
1286 * See Windows documentation for more details on IUnknown methods.
1287 */
1288 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1289 IRunnableObject* iface)
1290 {
1291 DefaultHandler *This = impl_from_IRunnableObject(iface);
1292
1293 return IUnknown_Release(This->outerUnknown);
1294 }
1295
1296 /************************************************************************
1297 * DefaultHandler_GetRunningClass (IRunnableObject)
1298 *
1299 * See Windows documentation for more details on IRunnableObject methods.
1300 */
1301 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1302 IRunnableObject* iface,
1303 LPCLSID lpClsid)
1304 {
1305 FIXME("()\n");
1306 return S_OK;
1307 }
1308
1309 static HRESULT WINAPI DefaultHandler_Run(
1310 IRunnableObject* iface,
1311 IBindCtx* pbc)
1312 {
1313 DefaultHandler *This = impl_from_IRunnableObject(iface);
1314 HRESULT hr;
1315
1316 FIXME("(%p): semi-stub\n", pbc);
1317
1318 /* already running? if so nothing to do */
1319 if (object_is_running(This))
1320 return S_OK;
1321
1322 release_delegates(This);
1323
1324 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1325 &IID_IOleObject, (void **)&This->pOleDelegate);
1326 if (FAILED(hr))
1327 return hr;
1328
1329 This->object_state = object_state_running;
1330
1331 hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn);
1332
1333 if (SUCCEEDED(hr) && This->clientSite)
1334 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1335
1336 if (SUCCEEDED(hr))
1337 {
1338 IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1339 (void **)&This->pPSDelegate);
1340 if (This->pPSDelegate)
1341 {
1342 if(This->storage_state == storage_state_initialised)
1343 hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
1344 else if(This->storage_state == storage_state_loaded)
1345 hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
1346 }
1347 }
1348
1349 if (SUCCEEDED(hr) && This->containerApp)
1350 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1351 This->containerObj);
1352
1353 /* FIXME: do more stuff here:
1354 * - IOleObject_GetMiscStatus
1355 * - IOleObject_GetMoniker
1356 * - IOleCache_OnRun
1357 */
1358
1359 if (SUCCEEDED(hr))
1360 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1361 (void **)&This->pDataDelegate);
1362
1363 if (SUCCEEDED(hr) && This->dataAdviseHolder)
1364 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1365
1366 if (FAILED(hr))
1367 {
1368 DefaultHandler_Stop(This);
1369 release_delegates(This);
1370 }
1371
1372 return hr;
1373 }
1374
1375 /************************************************************************
1376 * DefaultHandler_IsRunning (IRunnableObject)
1377 *
1378 * See Windows documentation for more details on IRunnableObject methods.
1379 */
1380 static BOOL WINAPI DefaultHandler_IsRunning(
1381 IRunnableObject* iface)
1382 {
1383 DefaultHandler *This = impl_from_IRunnableObject(iface);
1384
1385 TRACE("()\n");
1386
1387 if (This->object_state == object_state_running)
1388 return TRUE;
1389 else
1390 return FALSE;
1391 }
1392
1393 /************************************************************************
1394 * DefaultHandler_LockRunning (IRunnableObject)
1395 *
1396 * See Windows documentation for more details on IRunnableObject methods.
1397 */
1398 static HRESULT WINAPI DefaultHandler_LockRunning(
1399 IRunnableObject* iface,
1400 BOOL fLock,
1401 BOOL fLastUnlockCloses)
1402 {
1403 FIXME("()\n");
1404 return S_OK;
1405 }
1406
1407 /************************************************************************
1408 * DefaultHandler_SetContainedObject (IRunnableObject)
1409 *
1410 * See Windows documentation for more details on IRunnableObject methods.
1411 */
1412 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1413 IRunnableObject* iface,
1414 BOOL fContained)
1415 {
1416 FIXME("()\n");
1417 return S_OK;
1418 }
1419
1420 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1421 IAdviseSink *iface,
1422 REFIID riid,
1423 void **ppvObject)
1424 {
1425 if (IsEqualIID(riid, &IID_IUnknown) ||
1426 IsEqualIID(riid, &IID_IAdviseSink))
1427 {
1428 *ppvObject = iface;
1429 IAdviseSink_AddRef(iface);
1430 return S_OK;
1431 }
1432
1433 return E_NOINTERFACE;
1434 }
1435
1436 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1437 IAdviseSink *iface)
1438 {
1439 DefaultHandler *This = impl_from_IAdviseSink(iface);
1440
1441 return IUnknown_AddRef(&This->IUnknown_iface);
1442 }
1443
1444 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1445 IAdviseSink *iface)
1446 {
1447 DefaultHandler *This = impl_from_IAdviseSink(iface);
1448
1449 return IUnknown_Release(&This->IUnknown_iface);
1450 }
1451
1452 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1453 IAdviseSink *iface,
1454 FORMATETC *pFormatetc,
1455 STGMEDIUM *pStgmed)
1456 {
1457 FIXME(": stub\n");
1458 }
1459
1460 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1461 IAdviseSink *iface,
1462 DWORD dwAspect,
1463 LONG lindex)
1464 {
1465 FIXME(": stub\n");
1466 }
1467
1468 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1469 IAdviseSink *iface,
1470 IMoniker *pmk)
1471 {
1472 DefaultHandler *This = impl_from_IAdviseSink(iface);
1473
1474 TRACE("(%p)\n", pmk);
1475
1476 if (This->oleAdviseHolder)
1477 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1478 }
1479
1480 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1481 IAdviseSink *iface)
1482 {
1483 DefaultHandler *This = impl_from_IAdviseSink(iface);
1484
1485 TRACE("()\n");
1486
1487 if (This->oleAdviseHolder)
1488 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1489 }
1490
1491 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1492 IAdviseSink *iface)
1493 {
1494 DefaultHandler *This = impl_from_IAdviseSink(iface);
1495
1496 TRACE("()\n");
1497
1498 if (This->oleAdviseHolder)
1499 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1500
1501 DefaultHandler_Stop(This);
1502 }
1503
1504
1505 /************************************************************************
1506 * DefaultHandler_IPersistStorage_QueryInterface
1507 *
1508 */
1509 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface(
1510 IPersistStorage* iface,
1511 REFIID riid,
1512 void** ppvObject)
1513 {
1514 DefaultHandler *This = impl_from_IPersistStorage(iface);
1515
1516 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1517 }
1518
1519 /************************************************************************
1520 * DefaultHandler_IPersistStorage_AddRef
1521 *
1522 */
1523 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef(
1524 IPersistStorage* iface)
1525 {
1526 DefaultHandler *This = impl_from_IPersistStorage(iface);
1527
1528 return IUnknown_AddRef(This->outerUnknown);
1529 }
1530
1531 /************************************************************************
1532 * DefaultHandler_IPersistStorage_Release
1533 *
1534 */
1535 static ULONG WINAPI DefaultHandler_IPersistStorage_Release(
1536 IPersistStorage* iface)
1537 {
1538 DefaultHandler *This = impl_from_IPersistStorage(iface);
1539
1540 return IUnknown_Release(This->outerUnknown);
1541 }
1542
1543 /************************************************************************
1544 * DefaultHandler_IPersistStorage_GetClassID
1545 *
1546 */
1547 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
1548 IPersistStorage* iface,
1549 CLSID* clsid)
1550 {
1551 DefaultHandler *This = impl_from_IPersistStorage(iface);
1552 HRESULT hr;
1553
1554 TRACE("(%p)->(%p)\n", iface, clsid);
1555
1556 if(object_is_running(This))
1557 hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
1558 else
1559 hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
1560
1561 return hr;
1562 }
1563
1564 /************************************************************************
1565 * DefaultHandler_IPersistStorage_IsDirty
1566 *
1567 */
1568 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
1569 IPersistStorage* iface)
1570 {
1571 DefaultHandler *This = impl_from_IPersistStorage(iface);
1572 HRESULT hr;
1573
1574 TRACE("(%p)\n", iface);
1575
1576 hr = IPersistStorage_IsDirty(This->dataCache_PersistStg);
1577 if(hr != S_FALSE) return hr;
1578
1579 if(object_is_running(This))
1580 hr = IPersistStorage_IsDirty(This->pPSDelegate);
1581
1582 return hr;
1583 }
1584
1585 /***********************************************************************
1586 * init_ole_stream
1587 *
1588 * Creates the '\1Ole' stream.
1589 * The format of this stream is as follows:
1590 *
1591 * DWORD Version == 0x02000001
1592 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1593 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1594 * supplied by the app that creates the data structure. May be
1595 * ignored on processing].
1596 *
1597 * DWORD Reserved == 0
1598 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1599 * CLSID clsid - class id of object capable of processing the moniker
1600 * BYTE data[] - moniker data for a link
1601 */
1602
1603 static const WCHAR OleStream[] = {1,'O','l','e',0};
1604 typedef struct
1605 {
1606 DWORD version;
1607 DWORD flags;
1608 DWORD link_update_opt;
1609 DWORD res;
1610 DWORD moniker_size;
1611 } ole_stream_header_t;
1612 static const DWORD ole_stream_version = 0x02000001;
1613
1614 static void init_ole_stream(IStorage *storage)
1615 {
1616 HRESULT hr;
1617 IStream *stream;
1618
1619 hr = IStorage_CreateStream(storage, OleStream, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stream);
1620 if(SUCCEEDED(hr))
1621 {
1622 DWORD written;
1623 ole_stream_header_t header;
1624
1625 header.version = ole_stream_version;
1626 header.flags = 0;
1627 header.link_update_opt = 0;
1628 header.res = 0;
1629 header.moniker_size = 0;
1630
1631 IStream_Write(stream, &header, sizeof(header), &written);
1632 IStream_Release(stream);
1633 }
1634 return;
1635 }
1636
1637 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage)
1638 {
1639 IStream *stream;
1640 HRESULT hr;
1641
1642 hr = IStorage_OpenStream(storage, OleStream, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);
1643
1644 if(SUCCEEDED(hr))
1645 {
1646 DWORD read;
1647 ole_stream_header_t header;
1648
1649 hr = IStream_Read(stream, &header, sizeof(header), &read);
1650 if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version)
1651 {
1652 if(header.flags & 1)
1653 {
1654 /* FIXME: Read the moniker and deal with the link */
1655 FIXME("Linked objects are not supported yet\n");
1656 }
1657 }
1658 else
1659 {
1660 WARN("Incorrect OleStream header\n");
1661 hr = DV_E_CLIPFORMAT;
1662 }
1663 IStream_Release(stream);
1664 }
1665 else
1666 {
1667 init_ole_stream(storage);
1668 hr = S_OK;
1669 }
1670 return hr;
1671 }
1672
1673 /************************************************************************
1674 * DefaultHandler_IPersistStorage_InitNew
1675 *
1676 */
1677 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
1678 IPersistStorage* iface,
1679 IStorage* pStg)
1680 {
1681 DefaultHandler *This = impl_from_IPersistStorage(iface);
1682 HRESULT hr;
1683
1684 TRACE("(%p)->(%p)\n", iface, pStg);
1685 init_ole_stream(pStg);
1686
1687 hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
1688
1689 if(SUCCEEDED(hr) && object_is_running(This))
1690 hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
1691
1692 if(SUCCEEDED(hr))
1693 {
1694 IStorage_AddRef(pStg);
1695 This->storage = pStg;
1696 This->storage_state = storage_state_initialised;
1697 }
1698
1699 return hr;
1700 }
1701
1702
1703 /************************************************************************
1704 * DefaultHandler_IPersistStorage_Load
1705 *
1706 */
1707 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
1708 IPersistStorage* iface,
1709 IStorage* pStg)
1710 {
1711 DefaultHandler *This = impl_from_IPersistStorage(iface);
1712 HRESULT hr;
1713
1714 TRACE("(%p)->(%p)\n", iface, pStg);
1715
1716 hr = load_ole_stream(This, pStg);
1717
1718 if(SUCCEEDED(hr))
1719 hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1720
1721 if(SUCCEEDED(hr) && object_is_running(This))
1722 hr = IPersistStorage_Load(This->pPSDelegate, pStg);
1723
1724 if(SUCCEEDED(hr))
1725 {
1726 IStorage_AddRef(pStg);
1727 This->storage = pStg;
1728 This->storage_state = storage_state_loaded;
1729 }
1730 return hr;
1731 }
1732
1733
1734 /************************************************************************
1735 * DefaultHandler_IPersistStorage_Save
1736 *
1737 */
1738 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
1739 IPersistStorage* iface,
1740 IStorage* pStgSave,
1741 BOOL fSameAsLoad)
1742 {
1743 DefaultHandler *This = impl_from_IPersistStorage(iface);
1744 HRESULT hr;
1745
1746 TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad);
1747
1748 hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
1749 if(SUCCEEDED(hr) && object_is_running(This))
1750 hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
1751
1752 return hr;
1753 }
1754
1755
1756 /************************************************************************
1757 * DefaultHandler_IPersistStorage_SaveCompleted
1758 *
1759 */
1760 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
1761 IPersistStorage* iface,
1762 IStorage* pStgNew)
1763 {
1764 DefaultHandler *This = impl_from_IPersistStorage(iface);
1765 HRESULT hr;
1766
1767 TRACE("(%p)->(%p)\n", iface, pStgNew);
1768
1769 hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
1770
1771 if(SUCCEEDED(hr) && object_is_running(This))
1772 hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
1773
1774 if(pStgNew)
1775 {
1776 IStorage_AddRef(pStgNew);
1777 if(This->storage) IStorage_Release(This->storage);
1778 This->storage = pStgNew;
1779 This->storage_state = storage_state_loaded;
1780 }
1781
1782 return hr;
1783 }
1784
1785
1786 /************************************************************************
1787 * DefaultHandler_IPersistStorage_HandsOffStorage
1788 *
1789 */
1790 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
1791 IPersistStorage* iface)
1792 {
1793 DefaultHandler *This = impl_from_IPersistStorage(iface);
1794 HRESULT hr;
1795
1796 TRACE("(%p)\n", iface);
1797
1798 hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
1799
1800 if(SUCCEEDED(hr) && object_is_running(This))
1801 hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
1802
1803 if(This->storage) IStorage_Release(This->storage);
1804 This->storage = NULL;
1805 This->storage_state = storage_state_uninitialised;
1806
1807 return hr;
1808 }
1809
1810
1811 /*
1812 * Virtual function tables for the DefaultHandler class.
1813 */
1814 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1815 {
1816 DefaultHandler_QueryInterface,
1817 DefaultHandler_AddRef,
1818 DefaultHandler_Release,
1819 DefaultHandler_SetClientSite,
1820 DefaultHandler_GetClientSite,
1821 DefaultHandler_SetHostNames,
1822 DefaultHandler_Close,
1823 DefaultHandler_SetMoniker,
1824 DefaultHandler_GetMoniker,
1825 DefaultHandler_InitFromData,
1826 DefaultHandler_GetClipboardData,
1827 DefaultHandler_DoVerb,
1828 DefaultHandler_EnumVerbs,
1829 DefaultHandler_Update,
1830 DefaultHandler_IsUpToDate,
1831 DefaultHandler_GetUserClassID,
1832 DefaultHandler_GetUserType,
1833 DefaultHandler_SetExtent,
1834 DefaultHandler_GetExtent,
1835 DefaultHandler_Advise,
1836 DefaultHandler_Unadvise,
1837 DefaultHandler_EnumAdvise,
1838 DefaultHandler_GetMiscStatus,
1839 DefaultHandler_SetColorScheme
1840 };
1841
1842 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1843 {
1844 DefaultHandler_NDIUnknown_QueryInterface,
1845 DefaultHandler_NDIUnknown_AddRef,
1846 DefaultHandler_NDIUnknown_Release,
1847 };
1848
1849 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1850 {
1851 DefaultHandler_IDataObject_QueryInterface,
1852 DefaultHandler_IDataObject_AddRef,
1853 DefaultHandler_IDataObject_Release,
1854 DefaultHandler_GetData,
1855 DefaultHandler_GetDataHere,
1856 DefaultHandler_QueryGetData,
1857 DefaultHandler_GetCanonicalFormatEtc,
1858 DefaultHandler_SetData,
1859 DefaultHandler_EnumFormatEtc,
1860 DefaultHandler_DAdvise,
1861 DefaultHandler_DUnadvise,
1862 DefaultHandler_EnumDAdvise
1863 };
1864
1865 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1866 {
1867 DefaultHandler_IRunnableObject_QueryInterface,
1868 DefaultHandler_IRunnableObject_AddRef,
1869 DefaultHandler_IRunnableObject_Release,
1870 DefaultHandler_GetRunningClass,
1871 DefaultHandler_Run,
1872 DefaultHandler_IsRunning,
1873 DefaultHandler_LockRunning,
1874 DefaultHandler_SetContainedObject
1875 };
1876
1877 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1878 {
1879 DefaultHandler_IAdviseSink_QueryInterface,
1880 DefaultHandler_IAdviseSink_AddRef,
1881 DefaultHandler_IAdviseSink_Release,
1882 DefaultHandler_IAdviseSink_OnDataChange,
1883 DefaultHandler_IAdviseSink_OnViewChange,
1884 DefaultHandler_IAdviseSink_OnRename,
1885 DefaultHandler_IAdviseSink_OnSave,
1886 DefaultHandler_IAdviseSink_OnClose
1887 };
1888
1889 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
1890 {
1891 DefaultHandler_IPersistStorage_QueryInterface,
1892 DefaultHandler_IPersistStorage_AddRef,
1893 DefaultHandler_IPersistStorage_Release,
1894 DefaultHandler_IPersistStorage_GetClassID,
1895 DefaultHandler_IPersistStorage_IsDirty,
1896 DefaultHandler_IPersistStorage_InitNew,
1897 DefaultHandler_IPersistStorage_Load,
1898 DefaultHandler_IPersistStorage_Save,
1899 DefaultHandler_IPersistStorage_SaveCompleted,
1900 DefaultHandler_IPersistStorage_HandsOffStorage
1901 };
1902
1903 /*********************************************************
1904 * Methods implementation for the DefaultHandler class.
1905 */
1906 static DefaultHandler* DefaultHandler_Construct(
1907 REFCLSID clsid,
1908 LPUNKNOWN pUnkOuter,
1909 DWORD flags,
1910 IClassFactory *pCF)
1911 {
1912 DefaultHandler* This = NULL;
1913 HRESULT hr;
1914
1915 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1916
1917 if (!This)
1918 return This;
1919
1920 This->IOleObject_iface.lpVtbl = &DefaultHandler_IOleObject_VTable;
1921 This->IUnknown_iface.lpVtbl = &DefaultHandler_NDIUnknown_VTable;
1922 This->IDataObject_iface.lpVtbl = &DefaultHandler_IDataObject_VTable;
1923 This->IRunnableObject_iface.lpVtbl = &DefaultHandler_IRunnableObject_VTable;
1924 This->IAdviseSink_iface.lpVtbl = &DefaultHandler_IAdviseSink_VTable;
1925 This->IPersistStorage_iface.lpVtbl = &DefaultHandler_IPersistStorage_VTable;
1926
1927 This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) ? TRUE : FALSE;
1928
1929 /*
1930 * Start with one reference count. The caller of this function
1931 * must release the interface pointer when it is done.
1932 */
1933 This->ref = 1;
1934
1935 /*
1936 * Initialize the outer unknown
1937 * We don't keep a reference on the outer unknown since, the way
1938 * aggregation works, our lifetime is at least as large as its
1939 * lifetime.
1940 */
1941 if (!pUnkOuter)
1942 pUnkOuter = &This->IUnknown_iface;
1943
1944 This->outerUnknown = pUnkOuter;
1945
1946 /*
1947 * Create a datacache object.
1948 * We aggregate with the datacache. Make sure we pass our outer
1949 * unknown as the datacache's outer unknown.
1950 */
1951 hr = CreateDataCache(This->outerUnknown,
1952 clsid,
1953 &IID_IUnknown,
1954 (void**)&This->dataCache);
1955 if(SUCCEEDED(hr))
1956 {
1957 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
1958 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
1959 * reference on the outer object */
1960 if (SUCCEEDED(hr))
1961 IUnknown_Release(This->outerUnknown);
1962 else
1963 IUnknown_Release(This->dataCache);
1964 }
1965 if(FAILED(hr))
1966 {
1967 ERR("Unexpected error creating data cache\n");
1968 HeapFree(GetProcessHeap(), 0, This);
1969 return NULL;
1970 }
1971
1972 This->clsid = *clsid;
1973 This->clientSite = NULL;
1974 This->oleAdviseHolder = NULL;
1975 This->dataAdviseHolder = NULL;
1976 This->containerApp = NULL;
1977 This->containerObj = NULL;
1978 This->pOleDelegate = NULL;
1979 This->pPSDelegate = NULL;
1980 This->pDataDelegate = NULL;
1981 This->object_state = object_state_not_running;
1982
1983 This->dwAdvConn = 0;
1984 This->storage = NULL;
1985 This->storage_state = storage_state_uninitialised;
1986
1987 if (This->inproc_server && !(flags & EMBDHLP_DELAYCREATE))
1988 {
1989 HRESULT hr;
1990 This->pCFObject = NULL;
1991 if (pCF)
1992 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IOleObject, (void **)&This->pOleDelegate);
1993 else
1994 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1995 &IID_IOleObject, (void **)&This->pOleDelegate);
1996 if (SUCCEEDED(hr))
1997 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
1998 if (SUCCEEDED(hr))
1999 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&This->pDataDelegate);
2000 if (SUCCEEDED(hr))
2001 This->object_state = object_state_running;
2002 if (FAILED(hr))
2003 WARN("object creation failed with error %08x\n", hr);
2004 }
2005 else
2006 {
2007 This->pCFObject = pCF;
2008 if (pCF) IClassFactory_AddRef(pCF);
2009 }
2010
2011 return This;
2012 }
2013
2014 static void DefaultHandler_Destroy(
2015 DefaultHandler* This)
2016 {
2017 TRACE("(%p)\n", This);
2018
2019 /* AddRef/Release may be called on this object during destruction.
2020 * Prevent the object being destroyed recursively by artificially raising
2021 * the reference count. */
2022 This->ref = 10000;
2023
2024 /* release delegates */
2025 DefaultHandler_Stop(This);
2026 release_delegates(This);
2027
2028 HeapFree( GetProcessHeap(), 0, This->containerApp );
2029 This->containerApp = NULL;
2030 HeapFree( GetProcessHeap(), 0, This->containerObj );
2031 This->containerObj = NULL;
2032
2033 if (This->dataCache)
2034 {
2035 /* to balance out the release of dataCache_PersistStg which will result
2036 * in a reference being released from the outer unknown */
2037 IUnknown_AddRef(This->outerUnknown);
2038 IPersistStorage_Release(This->dataCache_PersistStg);
2039 IUnknown_Release(This->dataCache);
2040 This->dataCache_PersistStg = NULL;
2041 This->dataCache = NULL;
2042 }
2043
2044 if (This->clientSite)
2045 {
2046 IOleClientSite_Release(This->clientSite);
2047 This->clientSite = NULL;
2048 }
2049
2050 if (This->oleAdviseHolder)
2051 {
2052 IOleAdviseHolder_Release(This->oleAdviseHolder);
2053 This->oleAdviseHolder = NULL;
2054 }
2055
2056 if (This->dataAdviseHolder)
2057 {
2058 IDataAdviseHolder_Release(This->dataAdviseHolder);
2059 This->dataAdviseHolder = NULL;
2060 }
2061
2062 if (This->storage)
2063 {
2064 IStorage_Release(This->storage);
2065 This->storage = NULL;
2066 }
2067
2068 if (This->pCFObject)
2069 {
2070 IClassFactory_Release(This->pCFObject);
2071 This->pCFObject = NULL;
2072 }
2073
2074 HeapFree(GetProcessHeap(), 0, This);
2075 }
2076
2077 /******************************************************************************
2078 * OleCreateEmbeddingHelper [OLE32.@]
2079 */
2080 HRESULT WINAPI OleCreateEmbeddingHelper(
2081 REFCLSID clsid,
2082 LPUNKNOWN pUnkOuter,
2083 DWORD flags,
2084 IClassFactory *pCF,
2085 REFIID riid,
2086 LPVOID* ppvObj)
2087 {
2088 DefaultHandler* newHandler = NULL;
2089 HRESULT hr = S_OK;
2090
2091 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj);
2092
2093 if (!ppvObj)
2094 return E_POINTER;
2095
2096 *ppvObj = NULL;
2097
2098 /*
2099 * If This handler is constructed for aggregation, make sure
2100 * the caller is requesting the IUnknown interface.
2101 * This is necessary because it's the only time the non-delegating
2102 * IUnknown pointer can be returned to the outside.
2103 */
2104 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
2105 return CLASS_E_NOAGGREGATION;
2106
2107 /*
2108 * Try to construct a new instance of the class.
2109 */
2110 newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF);
2111
2112 if (!newHandler)
2113 return E_OUTOFMEMORY;
2114
2115 /*
2116 * Make sure it supports the interface required by the caller.
2117 */
2118 hr = IUnknown_QueryInterface(&newHandler->IUnknown_iface, riid, ppvObj);
2119
2120 /*
2121 * Release the reference obtained in the constructor. If
2122 * the QueryInterface was unsuccessful, it will free the class.
2123 */
2124 IUnknown_Release(&newHandler->IUnknown_iface);
2125
2126 return hr;
2127 }
2128
2129
2130 /******************************************************************************
2131 * OleCreateDefaultHandler [OLE32.@]
2132 */
2133 HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
2134 REFIID riid, LPVOID* ppvObj)
2135 {
2136 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter,debugstr_guid(riid), ppvObj);
2137 return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
2138 NULL, riid, ppvObj);
2139 }
2140
2141 typedef struct HandlerCF
2142 {
2143 IClassFactory IClassFactory_iface;
2144 LONG refs;
2145 CLSID clsid;
2146 } HandlerCF;
2147
2148 static inline HandlerCF *impl_from_IClassFactory(IClassFactory *iface)
2149 {
2150 return CONTAINING_RECORD(iface, HandlerCF, IClassFactory_iface);
2151 }
2152
2153 static HRESULT WINAPI
2154 HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
2155 {
2156 *ppv = NULL;
2157 if (IsEqualIID(riid,&IID_IUnknown) ||
2158 IsEqualIID(riid,&IID_IClassFactory))
2159 {
2160 *ppv = iface;
2161 IClassFactory_AddRef(iface);
2162 return S_OK;
2163 }
2164 return E_NOINTERFACE;
2165 }
2166
2167 static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface)
2168 {
2169 HandlerCF *This = impl_from_IClassFactory(iface);
2170 return InterlockedIncrement(&This->refs);
2171 }
2172
2173 static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
2174 {
2175 HandlerCF *This = impl_from_IClassFactory(iface);
2176 ULONG refs = InterlockedDecrement(&This->refs);
2177 if (!refs)
2178 HeapFree(GetProcessHeap(), 0, This);
2179 return refs;
2180 }
2181
2182 static HRESULT WINAPI
2183 HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
2184 REFIID riid, LPVOID *ppv)
2185 {
2186 HandlerCF *This = impl_from_IClassFactory(iface);
2187 return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv);
2188 }
2189
2190 static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
2191 {
2192 FIXME("(%d), stub!\n",fLock);
2193 return S_OK;
2194 }
2195
2196 static const IClassFactoryVtbl HandlerClassFactoryVtbl = {
2197 HandlerCF_QueryInterface,
2198 HandlerCF_AddRef,
2199 HandlerCF_Release,
2200 HandlerCF_CreateInstance,
2201 HandlerCF_LockServer
2202 };
2203
2204 HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
2205 {
2206 HRESULT hr;
2207 HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
2208 if (!This) return E_OUTOFMEMORY;
2209 This->IClassFactory_iface.lpVtbl = &HandlerClassFactoryVtbl;
2210 This->refs = 0;
2211 This->clsid = *rclsid;
2212
2213 hr = IUnknown_QueryInterface((IUnknown *)&This->IClassFactory_iface, riid, ppv);
2214 if (FAILED(hr))
2215 HeapFree(GetProcessHeap(), 0, This);
2216
2217 return hr;
2218 }
2219
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.