- Implement ProtocolResetComplete
[reactos.git] / dll / win32 / ole32 / defaulthandler.c
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 /****************************************************************************
68 * DefaultHandler
69 *
70 */
71 struct DefaultHandler
72 {
73 const IOleObjectVtbl* lpVtbl;
74 const IUnknownVtbl* lpvtblIUnknown;
75 const IDataObjectVtbl* lpvtblIDataObject;
76 const IRunnableObjectVtbl* lpvtblIRunnableObject;
77 const IAdviseSinkVtbl *lpvtblIAdviseSink;
78 const IPersistStorageVtbl *lpvtblIPersistStorage;
79
80 /* Reference count of this object */
81 LONG ref;
82
83 /* IUnknown implementation of the outer object. */
84 IUnknown* outerUnknown;
85
86 /* Class Id that this handler object represents. */
87 CLSID clsid;
88
89 /* IUnknown implementation of the datacache. */
90 IUnknown* dataCache;
91 /* IPersistStorage implementation of the datacache. */
92 IPersistStorage* dataCache_PersistStg;
93
94 /* Client site for the embedded object. */
95 IOleClientSite* clientSite;
96
97 /*
98 * The IOleAdviseHolder maintains the connections
99 * on behalf of the default handler.
100 */
101 IOleAdviseHolder* oleAdviseHolder;
102
103 /*
104 * The IDataAdviseHolder maintains the data
105 * connections on behalf of the default handler.
106 */
107 IDataAdviseHolder* dataAdviseHolder;
108
109 /* Name of the container and object contained */
110 LPWSTR containerApp;
111 LPWSTR containerObj;
112
113 /* IOleObject delegate */
114 IOleObject *pOleDelegate;
115 /* IPersistStorage delegate */
116 IPersistStorage *pPSDelegate;
117 /* IDataObject delegate */
118 IDataObject *pDataDelegate;
119
120 /* connection cookie for the advise on the delegate OLE object */
121 DWORD dwAdvConn;
122 };
123
124 typedef struct DefaultHandler DefaultHandler;
125
126 /*
127 * Here, I define utility functions to help with the casting of the
128 * "This" parameter.
129 * There is a version to accommodate all of the VTables implemented
130 * by this object.
131 */
132 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
133 {
134 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpVtbl));
135 }
136
137 static inline DefaultHandler *impl_from_NDIUnknown( IUnknown *iface )
138 {
139 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIUnknown));
140 }
141
142 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
143 {
144 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIDataObject));
145 }
146
147 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
148 {
149 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIRunnableObject));
150 }
151
152 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
153 {
154 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIAdviseSink));
155 }
156
157 static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
158 {
159 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIPersistStorage));
160 }
161
162 static void DefaultHandler_Destroy(DefaultHandler* This);
163
164 static inline BOOL object_is_running(DefaultHandler *This)
165 {
166 return IRunnableObject_IsRunning((IRunnableObject*)&This->lpvtblIRunnableObject);
167 }
168
169 /*********************************************************
170 * Method implementation for the non delegating IUnknown
171 * part of the DefaultHandler class.
172 */
173
174 /************************************************************************
175 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
176 *
177 * See Windows documentation for more details on IUnknown methods.
178 *
179 * This version of QueryInterface will not delegate its implementation
180 * to the outer unknown.
181 */
182 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
183 IUnknown* iface,
184 REFIID riid,
185 void** ppvObject)
186 {
187 DefaultHandler *This = impl_from_NDIUnknown(iface);
188
189 /* Perform a sanity check on the parameters. */
190 if (!ppvObject)
191 return E_INVALIDARG;
192
193 *ppvObject = NULL;
194
195 if (IsEqualIID(&IID_IUnknown, riid))
196 *ppvObject = iface;
197 else if (IsEqualIID(&IID_IOleObject, riid))
198 *ppvObject = (IOleObject*)&This->lpVtbl;
199 else if (IsEqualIID(&IID_IDataObject, riid))
200 *ppvObject = (IDataObject*)&This->lpvtblIDataObject;
201 else if (IsEqualIID(&IID_IRunnableObject, riid))
202 *ppvObject = (IRunnableObject*)&This->lpvtblIRunnableObject;
203 else if (IsEqualIID(&IID_IPersist, riid) ||
204 IsEqualIID(&IID_IPersistStorage, riid))
205 *ppvObject = &This->lpvtblIPersistStorage;
206 else if (IsEqualIID(&IID_IViewObject, riid) ||
207 IsEqualIID(&IID_IViewObject2, riid) ||
208 IsEqualIID(&IID_IOleCache, riid) ||
209 IsEqualIID(&IID_IOleCache2, riid))
210 {
211 HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
212 if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
213 return hr;
214 }
215
216 /* Check that we obtained an interface. */
217 if (*ppvObject == NULL)
218 {
219 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
220 return E_NOINTERFACE;
221 }
222
223 /*
224 * Query Interface always increases the reference count by one when it is
225 * successful.
226 */
227 IUnknown_AddRef((IUnknown*)*ppvObject);
228
229 return S_OK;
230 }
231
232 /************************************************************************
233 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
234 *
235 * See Windows documentation for more details on IUnknown methods.
236 *
237 * This version of QueryInterface will not delegate its implementation
238 * to the outer unknown.
239 */
240 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
241 IUnknown* iface)
242 {
243 DefaultHandler *This = impl_from_NDIUnknown(iface);
244 return InterlockedIncrement(&This->ref);
245 }
246
247 /************************************************************************
248 * DefaultHandler_NDIUnknown_Release (IUnknown)
249 *
250 * See Windows documentation for more details on IUnknown methods.
251 *
252 * This version of QueryInterface will not delegate its implementation
253 * to the outer unknown.
254 */
255 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
256 IUnknown* iface)
257 {
258 DefaultHandler *This = impl_from_NDIUnknown(iface);
259 ULONG ref;
260
261 /* Decrease the reference count on this object. */
262 ref = InterlockedDecrement(&This->ref);
263
264 if (!ref) DefaultHandler_Destroy(This);
265
266 return ref;
267 }
268
269 /*********************************************************
270 * Methods implementation for the IOleObject part of
271 * the DefaultHandler class.
272 */
273
274 /************************************************************************
275 * DefaultHandler_QueryInterface (IUnknown)
276 *
277 * See Windows documentation for more details on IUnknown methods.
278 */
279 static HRESULT WINAPI DefaultHandler_QueryInterface(
280 IOleObject* iface,
281 REFIID riid,
282 void** ppvObject)
283 {
284 DefaultHandler *This = impl_from_IOleObject(iface);
285
286 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
287 }
288
289 /************************************************************************
290 * DefaultHandler_AddRef (IUnknown)
291 *
292 * See Windows documentation for more details on IUnknown methods.
293 */
294 static ULONG WINAPI DefaultHandler_AddRef(
295 IOleObject* iface)
296 {
297 DefaultHandler *This = impl_from_IOleObject(iface);
298
299 return IUnknown_AddRef(This->outerUnknown);
300 }
301
302 /************************************************************************
303 * DefaultHandler_Release (IUnknown)
304 *
305 * See Windows documentation for more details on IUnknown methods.
306 */
307 static ULONG WINAPI DefaultHandler_Release(
308 IOleObject* iface)
309 {
310 DefaultHandler *This = impl_from_IOleObject(iface);
311
312 return IUnknown_Release(This->outerUnknown);
313 }
314
315 /************************************************************************
316 * DefaultHandler_SetClientSite (IOleObject)
317 *
318 * The default handler's implementation of this method only keeps the
319 * client site pointer for future reference.
320 *
321 * See Windows documentation for more details on IOleObject methods.
322 */
323 static HRESULT WINAPI DefaultHandler_SetClientSite(
324 IOleObject* iface,
325 IOleClientSite* pClientSite)
326 {
327 DefaultHandler *This = impl_from_IOleObject(iface);
328 HRESULT hr = S_OK;
329
330 TRACE("(%p, %p)\n", iface, pClientSite);
331
332 if (object_is_running(This))
333 hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
334
335 /*
336 * Make sure we release the previous client site if there
337 * was one.
338 */
339 if (This->clientSite)
340 IOleClientSite_Release(This->clientSite);
341
342 This->clientSite = pClientSite;
343
344 if (This->clientSite)
345 IOleClientSite_AddRef(This->clientSite);
346
347 return S_OK;
348 }
349
350 /************************************************************************
351 * DefaultHandler_GetClientSite (IOleObject)
352 *
353 * The default handler's implementation of this method returns the
354 * last pointer set in IOleObject_SetClientSite.
355 *
356 * See Windows documentation for more details on IOleObject methods.
357 */
358 static HRESULT WINAPI DefaultHandler_GetClientSite(
359 IOleObject* iface,
360 IOleClientSite** ppClientSite)
361 {
362 DefaultHandler *This = impl_from_IOleObject(iface);
363
364 /* Sanity check. */
365 if (!ppClientSite)
366 return E_POINTER;
367
368 *ppClientSite = This->clientSite;
369
370 if (This->clientSite)
371 IOleClientSite_AddRef(This->clientSite);
372
373 return S_OK;
374 }
375
376 /************************************************************************
377 * DefaultHandler_SetHostNames (IOleObject)
378 *
379 * The default handler's implementation of this method just stores
380 * the strings and returns S_OK.
381 *
382 * See Windows documentation for more details on IOleObject methods.
383 */
384 static HRESULT WINAPI DefaultHandler_SetHostNames(
385 IOleObject* iface,
386 LPCOLESTR szContainerApp,
387 LPCOLESTR szContainerObj)
388 {
389 DefaultHandler *This = impl_from_IOleObject(iface);
390
391 TRACE("(%p, %s, %s)\n",
392 iface,
393 debugstr_w(szContainerApp),
394 debugstr_w(szContainerObj));
395
396 if (object_is_running(This))
397 IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
398
399 /* Be sure to cleanup before re-assigning the strings. */
400 HeapFree( GetProcessHeap(), 0, This->containerApp );
401 This->containerApp = NULL;
402 HeapFree( GetProcessHeap(), 0, This->containerObj );
403 This->containerObj = NULL;
404
405 /* Copy the string supplied. */
406 if (szContainerApp)
407 {
408 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
409 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
410 strcpyW( This->containerApp, szContainerApp );
411 }
412
413 if (szContainerObj)
414 {
415 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
416 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
417 strcpyW( This->containerObj, szContainerObj );
418 }
419 return S_OK;
420 }
421
422 /* undos the work done by DefaultHandler_Run */
423 static void WINAPI DefaultHandler_Stop(DefaultHandler *This)
424 {
425 if (!object_is_running(This))
426 return;
427
428 IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
429
430 /* FIXME: call IOleCache_OnStop */
431
432 if (This->dataAdviseHolder)
433 DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
434 if (This->pDataDelegate)
435 {
436 IDataObject_Release(This->pDataDelegate);
437 This->pDataDelegate = NULL;
438 }
439 if (This->pPSDelegate)
440 {
441 IPersistStorage_Release(This->pPSDelegate);
442 This->pPSDelegate = NULL;
443 }
444 IOleObject_Release(This->pOleDelegate);
445 This->pOleDelegate = NULL;
446 }
447
448 /************************************************************************
449 * DefaultHandler_Close (IOleObject)
450 *
451 * The default handler's implementation of this method is meaningless
452 * without a running server so it does nothing.
453 *
454 * See Windows documentation for more details on IOleObject methods.
455 */
456 static HRESULT WINAPI DefaultHandler_Close(
457 IOleObject* iface,
458 DWORD dwSaveOption)
459 {
460 DefaultHandler *This = impl_from_IOleObject(iface);
461 HRESULT hr;
462
463 TRACE("(%d)\n", dwSaveOption);
464
465 if (!object_is_running(This))
466 return S_OK;
467
468 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
469
470 DefaultHandler_Stop(This);
471
472 return hr;
473 }
474
475 /************************************************************************
476 * DefaultHandler_SetMoniker (IOleObject)
477 *
478 * The default handler's implementation of this method does nothing.
479 *
480 * See Windows documentation for more details on IOleObject methods.
481 */
482 static HRESULT WINAPI DefaultHandler_SetMoniker(
483 IOleObject* iface,
484 DWORD dwWhichMoniker,
485 IMoniker* pmk)
486 {
487 DefaultHandler *This = impl_from_IOleObject(iface);
488
489 TRACE("(%p, %d, %p)\n",
490 iface,
491 dwWhichMoniker,
492 pmk);
493
494 if (object_is_running(This))
495 return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
496
497 return S_OK;
498 }
499
500 /************************************************************************
501 * DefaultHandler_GetMoniker (IOleObject)
502 *
503 * Delegate this request to the client site if we have one.
504 *
505 * See Windows documentation for more details on IOleObject methods.
506 */
507 static HRESULT WINAPI DefaultHandler_GetMoniker(
508 IOleObject* iface,
509 DWORD dwAssign,
510 DWORD dwWhichMoniker,
511 IMoniker** ppmk)
512 {
513 DefaultHandler *This = impl_from_IOleObject(iface);
514
515 TRACE("(%p, %d, %d, %p)\n",
516 iface, dwAssign, dwWhichMoniker, ppmk);
517
518 if (object_is_running(This))
519 return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
520 ppmk);
521
522 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
523 if (This->clientSite)
524 {
525 return IOleClientSite_GetMoniker(This->clientSite,
526 dwAssign,
527 dwWhichMoniker,
528 ppmk);
529
530 }
531
532 return E_FAIL;
533 }
534
535 /************************************************************************
536 * DefaultHandler_InitFromData (IOleObject)
537 *
538 * This method is meaningless if the server is not running
539 *
540 * See Windows documentation for more details on IOleObject methods.
541 */
542 static HRESULT WINAPI DefaultHandler_InitFromData(
543 IOleObject* iface,
544 IDataObject* pDataObject,
545 BOOL fCreation,
546 DWORD dwReserved)
547 {
548 DefaultHandler *This = impl_from_IOleObject(iface);
549
550 TRACE("(%p, %p, %d, %d)\n",
551 iface, pDataObject, fCreation, dwReserved);
552
553 if (object_is_running(This))
554 return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
555 dwReserved);
556 return OLE_E_NOTRUNNING;
557 }
558
559 /************************************************************************
560 * DefaultHandler_GetClipboardData (IOleObject)
561 *
562 * This method is meaningless if the server is not running
563 *
564 * See Windows documentation for more details on IOleObject methods.
565 */
566 static HRESULT WINAPI DefaultHandler_GetClipboardData(
567 IOleObject* iface,
568 DWORD dwReserved,
569 IDataObject** ppDataObject)
570 {
571 DefaultHandler *This = impl_from_IOleObject(iface);
572
573 TRACE("(%p, %d, %p)\n",
574 iface, dwReserved, ppDataObject);
575
576 if (object_is_running(This))
577 return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
578 ppDataObject);
579
580 return OLE_E_NOTRUNNING;
581 }
582
583 static HRESULT WINAPI DefaultHandler_DoVerb(
584 IOleObject* iface,
585 LONG iVerb,
586 struct tagMSG* lpmsg,
587 IOleClientSite* pActiveSite,
588 LONG lindex,
589 HWND hwndParent,
590 LPCRECT lprcPosRect)
591 {
592 DefaultHandler *This = impl_from_IOleObject(iface);
593 IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
594 HRESULT hr;
595
596 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
597
598 hr = IRunnableObject_Run(pRunnableObj, NULL);
599 if (FAILED(hr)) return hr;
600
601 return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
602 lindex, hwndParent, lprcPosRect);
603 }
604
605 /************************************************************************
606 * DefaultHandler_EnumVerbs (IOleObject)
607 *
608 * The default handler implementation of this method simply delegates
609 * to OleRegEnumVerbs
610 *
611 * See Windows documentation for more details on IOleObject methods.
612 */
613 static HRESULT WINAPI DefaultHandler_EnumVerbs(
614 IOleObject* iface,
615 IEnumOLEVERB** ppEnumOleVerb)
616 {
617 DefaultHandler *This = impl_from_IOleObject(iface);
618 HRESULT hr = OLE_S_USEREG;
619
620 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
621
622 if (object_is_running(This))
623 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
624
625 if (hr == OLE_S_USEREG)
626 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
627 else
628 return hr;
629 }
630
631 static HRESULT WINAPI DefaultHandler_Update(
632 IOleObject* iface)
633 {
634 FIXME(": Stub\n");
635 return E_NOTIMPL;
636 }
637
638 /************************************************************************
639 * DefaultHandler_IsUpToDate (IOleObject)
640 *
641 * This method is meaningless if the server is not running
642 *
643 * See Windows documentation for more details on IOleObject methods.
644 */
645 static HRESULT WINAPI DefaultHandler_IsUpToDate(
646 IOleObject* iface)
647 {
648 TRACE("(%p)\n", iface);
649
650 return OLE_E_NOTRUNNING;
651 }
652
653 /************************************************************************
654 * DefaultHandler_GetUserClassID (IOleObject)
655 *
656 * TODO: Map to a new class ID if emulation is active.
657 *
658 * See Windows documentation for more details on IOleObject methods.
659 */
660 static HRESULT WINAPI DefaultHandler_GetUserClassID(
661 IOleObject* iface,
662 CLSID* pClsid)
663 {
664 DefaultHandler *This = impl_from_IOleObject(iface);
665
666 TRACE("(%p, %p)\n", iface, pClsid);
667
668 if (object_is_running(This))
669 return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
670
671 /* Sanity check. */
672 if (!pClsid)
673 return E_POINTER;
674
675 *pClsid = This->clsid;
676
677 return S_OK;
678 }
679
680 /************************************************************************
681 * DefaultHandler_GetUserType (IOleObject)
682 *
683 * The default handler implementation of this method simply delegates
684 * to OleRegGetUserType
685 *
686 * See Windows documentation for more details on IOleObject methods.
687 */
688 static HRESULT WINAPI DefaultHandler_GetUserType(
689 IOleObject* iface,
690 DWORD dwFormOfType,
691 LPOLESTR* pszUserType)
692 {
693 DefaultHandler *This = impl_from_IOleObject(iface);
694
695 TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
696
697 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
698 }
699
700 /************************************************************************
701 * DefaultHandler_SetExtent (IOleObject)
702 *
703 * This method is meaningless if the server is not running
704 *
705 * See Windows documentation for more details on IOleObject methods.
706 */
707 static HRESULT WINAPI DefaultHandler_SetExtent(
708 IOleObject* iface,
709 DWORD dwDrawAspect,
710 SIZEL* psizel)
711 {
712 DefaultHandler *This = impl_from_IOleObject(iface);
713
714 TRACE("(%p, %x, (%d x %d))\n", iface,
715 dwDrawAspect, psizel->cx, psizel->cy);
716
717 if (object_is_running(This))
718 IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
719
720 return OLE_E_NOTRUNNING;
721 }
722
723 /************************************************************************
724 * DefaultHandler_GetExtent (IOleObject)
725 *
726 * The default handler's implementation of this method returns uses
727 * the cache to locate the aspect and extract the extent from it.
728 *
729 * See Windows documentation for more details on IOleObject methods.
730 */
731 static HRESULT WINAPI DefaultHandler_GetExtent(
732 IOleObject* iface,
733 DWORD dwDrawAspect,
734 SIZEL* psizel)
735 {
736 DVTARGETDEVICE* targetDevice;
737 IViewObject2* cacheView = NULL;
738 HRESULT hres;
739
740 DefaultHandler *This = impl_from_IOleObject(iface);
741
742 TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
743
744 if (object_is_running(This))
745 return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
746
747 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
748 if (FAILED(hres))
749 return E_UNEXPECTED;
750
751 /*
752 * Prepare the call to the cache's GetExtent method.
753 *
754 * Here we would build a valid DVTARGETDEVICE structure
755 * but, since we are calling into the data cache, we
756 * know its implementation and we'll skip this
757 * extra work until later.
758 */
759 targetDevice = NULL;
760
761 hres = IViewObject2_GetExtent(cacheView,
762 dwDrawAspect,
763 -1,
764 targetDevice,
765 psizel);
766
767 /*
768 * Cleanup
769 */
770 IViewObject2_Release(cacheView);
771
772 return hres;
773 }
774
775 /************************************************************************
776 * DefaultHandler_Advise (IOleObject)
777 *
778 * The default handler's implementation of this method simply
779 * delegates to the OleAdviseHolder.
780 *
781 * See Windows documentation for more details on IOleObject methods.
782 */
783 static HRESULT WINAPI DefaultHandler_Advise(
784 IOleObject* iface,
785 IAdviseSink* pAdvSink,
786 DWORD* pdwConnection)
787 {
788 HRESULT hres = S_OK;
789 DefaultHandler *This = impl_from_IOleObject(iface);
790
791 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
792
793 /* Make sure we have an advise holder before we start. */
794 if (!This->oleAdviseHolder)
795 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
796
797 if (SUCCEEDED(hres))
798 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
799 pAdvSink,
800 pdwConnection);
801
802 return hres;
803 }
804
805 /************************************************************************
806 * DefaultHandler_Unadvise (IOleObject)
807 *
808 * The default handler's implementation of this method simply
809 * delegates to the OleAdviseHolder.
810 *
811 * See Windows documentation for more details on IOleObject methods.
812 */
813 static HRESULT WINAPI DefaultHandler_Unadvise(
814 IOleObject* iface,
815 DWORD dwConnection)
816 {
817 DefaultHandler *This = impl_from_IOleObject(iface);
818
819 TRACE("(%p, %d)\n", iface, dwConnection);
820
821 /*
822 * If we don't have an advise holder yet, it means we don't have
823 * a connection.
824 */
825 if (!This->oleAdviseHolder)
826 return OLE_E_NOCONNECTION;
827
828 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
829 dwConnection);
830 }
831
832 /************************************************************************
833 * DefaultHandler_EnumAdvise (IOleObject)
834 *
835 * The default handler's implementation of this method simply
836 * delegates to the OleAdviseHolder.
837 *
838 * See Windows documentation for more details on IOleObject methods.
839 */
840 static HRESULT WINAPI DefaultHandler_EnumAdvise(
841 IOleObject* iface,
842 IEnumSTATDATA** ppenumAdvise)
843 {
844 DefaultHandler *This = impl_from_IOleObject(iface);
845
846 TRACE("(%p, %p)\n", iface, ppenumAdvise);
847
848 /* Sanity check */
849 if (!ppenumAdvise)
850 return E_POINTER;
851
852 *ppenumAdvise = NULL;
853
854 if (!This->oleAdviseHolder)
855 return S_OK;
856
857 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
858 }
859
860 /************************************************************************
861 * DefaultHandler_GetMiscStatus (IOleObject)
862 *
863 * The default handler's implementation of this method simply delegates
864 * to OleRegGetMiscStatus.
865 *
866 * See Windows documentation for more details on IOleObject methods.
867 */
868 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
869 IOleObject* iface,
870 DWORD dwAspect,
871 DWORD* pdwStatus)
872 {
873 HRESULT hres;
874 DefaultHandler *This = impl_from_IOleObject(iface);
875
876 TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
877
878 if (object_is_running(This))
879 return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
880
881 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
882
883 if (FAILED(hres))
884 *pdwStatus = 0;
885
886 return S_OK;
887 }
888
889 /************************************************************************
890 * DefaultHandler_SetColorScheme (IOleObject)
891 *
892 * This method is meaningless if the server is not running
893 *
894 * See Windows documentation for more details on IOleObject methods.
895 */
896 static HRESULT WINAPI DefaultHandler_SetColorScheme(
897 IOleObject* iface,
898 struct tagLOGPALETTE* pLogpal)
899 {
900 DefaultHandler *This = impl_from_IOleObject(iface);
901
902 TRACE("(%p, %p))\n", iface, pLogpal);
903
904 if (object_is_running(This))
905 return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
906
907 return OLE_E_NOTRUNNING;
908 }
909
910 /*********************************************************
911 * Methods implementation for the IDataObject part of
912 * the DefaultHandler class.
913 */
914
915 /************************************************************************
916 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
917 *
918 * See Windows documentation for more details on IUnknown methods.
919 */
920 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
921 IDataObject* iface,
922 REFIID riid,
923 void** ppvObject)
924 {
925 DefaultHandler *This = impl_from_IDataObject(iface);
926
927 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
928 }
929
930 /************************************************************************
931 * DefaultHandler_IDataObject_AddRef (IUnknown)
932 *
933 * See Windows documentation for more details on IUnknown methods.
934 */
935 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
936 IDataObject* iface)
937 {
938 DefaultHandler *This = impl_from_IDataObject(iface);
939
940 return IUnknown_AddRef(This->outerUnknown);
941 }
942
943 /************************************************************************
944 * DefaultHandler_IDataObject_Release (IUnknown)
945 *
946 * See Windows documentation for more details on IUnknown methods.
947 */
948 static ULONG WINAPI DefaultHandler_IDataObject_Release(
949 IDataObject* iface)
950 {
951 DefaultHandler *This = impl_from_IDataObject(iface);
952
953 return IUnknown_Release(This->outerUnknown);
954 }
955
956 /************************************************************************
957 * DefaultHandler_GetData
958 *
959 * Get Data from a source dataobject using format pformatetcIn->cfFormat
960 * See Windows documentation for more details on GetData.
961 * Default handler's implementation of this method delegates to the cache.
962 */
963 static HRESULT WINAPI DefaultHandler_GetData(
964 IDataObject* iface,
965 LPFORMATETC pformatetcIn,
966 STGMEDIUM* pmedium)
967 {
968 IDataObject* cacheDataObject = NULL;
969 HRESULT hres;
970
971 DefaultHandler *This = impl_from_IDataObject(iface);
972
973 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
974
975 hres = IUnknown_QueryInterface(This->dataCache,
976 &IID_IDataObject,
977 (void**)&cacheDataObject);
978
979 if (FAILED(hres))
980 return E_UNEXPECTED;
981
982 hres = IDataObject_GetData(cacheDataObject,
983 pformatetcIn,
984 pmedium);
985
986 IDataObject_Release(cacheDataObject);
987
988 if (FAILED(hres) && This->pDataDelegate)
989 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
990
991 return hres;
992 }
993
994 static HRESULT WINAPI DefaultHandler_GetDataHere(
995 IDataObject* iface,
996 LPFORMATETC pformatetc,
997 STGMEDIUM* pmedium)
998 {
999 FIXME(": Stub\n");
1000 return E_NOTIMPL;
1001 }
1002
1003 /************************************************************************
1004 * DefaultHandler_QueryGetData (IDataObject)
1005 *
1006 * The default handler's implementation of this method delegates to
1007 * the cache.
1008 *
1009 * See Windows documentation for more details on IDataObject methods.
1010 */
1011 static HRESULT WINAPI DefaultHandler_QueryGetData(
1012 IDataObject* iface,
1013 LPFORMATETC pformatetc)
1014 {
1015 IDataObject* cacheDataObject = NULL;
1016 HRESULT hres;
1017
1018 DefaultHandler *This = impl_from_IDataObject(iface);
1019
1020 TRACE("(%p, %p)\n", iface, pformatetc);
1021
1022 hres = IUnknown_QueryInterface(This->dataCache,
1023 &IID_IDataObject,
1024 (void**)&cacheDataObject);
1025
1026 if (FAILED(hres))
1027 return E_UNEXPECTED;
1028
1029 hres = IDataObject_QueryGetData(cacheDataObject,
1030 pformatetc);
1031
1032 IDataObject_Release(cacheDataObject);
1033
1034 if (FAILED(hres) && This->pDataDelegate)
1035 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1036
1037 return hres;
1038 }
1039
1040 /************************************************************************
1041 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1042 *
1043 * This method is meaningless if the server is not running
1044 *
1045 * See Windows documentation for more details on IDataObject methods.
1046 */
1047 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1048 IDataObject* iface,
1049 LPFORMATETC pformatetcIn,
1050 LPFORMATETC pformatetcOut)
1051 {
1052 DefaultHandler *This = impl_from_IDataObject(iface);
1053
1054 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1055
1056 if (!This->pDataDelegate)
1057 return OLE_E_NOTRUNNING;
1058
1059 return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1060 }
1061
1062 /************************************************************************
1063 * DefaultHandler_SetData (IDataObject)
1064 *
1065 * The default handler's implementation of this method delegates to
1066 * the cache.
1067 *
1068 * See Windows documentation for more details on IDataObject methods.
1069 */
1070 static HRESULT WINAPI DefaultHandler_SetData(
1071 IDataObject* iface,
1072 LPFORMATETC pformatetc,
1073 STGMEDIUM* pmedium,
1074 BOOL fRelease)
1075 {
1076 DefaultHandler *This = impl_from_IDataObject(iface);
1077 IDataObject* cacheDataObject = NULL;
1078 HRESULT hres;
1079
1080 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1081
1082 hres = IUnknown_QueryInterface(This->dataCache,
1083 &IID_IDataObject,
1084 (void**)&cacheDataObject);
1085
1086 if (FAILED(hres))
1087 return E_UNEXPECTED;
1088
1089 hres = IDataObject_SetData(cacheDataObject,
1090 pformatetc,
1091 pmedium,
1092 fRelease);
1093
1094 IDataObject_Release(cacheDataObject);
1095
1096 return hres;
1097 }
1098
1099 /************************************************************************
1100 * DefaultHandler_EnumFormatEtc (IDataObject)
1101 *
1102 * The default handler's implementation of This method simply delegates
1103 * to OleRegEnumFormatEtc.
1104 *
1105 * See Windows documentation for more details on IDataObject methods.
1106 */
1107 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1108 IDataObject* iface,
1109 DWORD dwDirection,
1110 IEnumFORMATETC** ppenumFormatEtc)
1111 {
1112 HRESULT hres;
1113 DefaultHandler *This = impl_from_IDataObject(iface);
1114
1115 TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1116
1117 hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1118
1119 return hres;
1120 }
1121
1122 /************************************************************************
1123 * DefaultHandler_DAdvise (IDataObject)
1124 *
1125 * The default handler's implementation of this method simply
1126 * delegates to the DataAdviseHolder.
1127 *
1128 * See Windows documentation for more details on IDataObject methods.
1129 */
1130 static HRESULT WINAPI DefaultHandler_DAdvise(
1131 IDataObject* iface,
1132 FORMATETC* pformatetc,
1133 DWORD advf,
1134 IAdviseSink* pAdvSink,
1135 DWORD* pdwConnection)
1136 {
1137 HRESULT hres = S_OK;
1138 DefaultHandler *This = impl_from_IDataObject(iface);
1139
1140 TRACE("(%p, %p, %d, %p, %p)\n",
1141 iface, pformatetc, advf, pAdvSink, pdwConnection);
1142
1143 /* Make sure we have a data advise holder before we start. */
1144 if (!This->dataAdviseHolder)
1145 {
1146 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1147 if (SUCCEEDED(hres) && This->pDataDelegate)
1148 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1149 }
1150
1151 if (SUCCEEDED(hres))
1152 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1153 iface,
1154 pformatetc,
1155 advf,
1156 pAdvSink,
1157 pdwConnection);
1158
1159 return hres;
1160 }
1161
1162 /************************************************************************
1163 * DefaultHandler_DUnadvise (IDataObject)
1164 *
1165 * The default handler's implementation of this method simply
1166 * delegates to the DataAdviseHolder.
1167 *
1168 * See Windows documentation for more details on IDataObject methods.
1169 */
1170 static HRESULT WINAPI DefaultHandler_DUnadvise(
1171 IDataObject* iface,
1172 DWORD dwConnection)
1173 {
1174 DefaultHandler *This = impl_from_IDataObject(iface);
1175
1176 TRACE("(%p, %d)\n", iface, dwConnection);
1177
1178 /*
1179 * If we don't have a data advise holder yet, it means that
1180 * we don't have any connections..
1181 */
1182 if (!This->dataAdviseHolder)
1183 return OLE_E_NOCONNECTION;
1184
1185 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1186 dwConnection);
1187 }
1188
1189 /************************************************************************
1190 * DefaultHandler_EnumDAdvise (IDataObject)
1191 *
1192 * The default handler's implementation of this method simply
1193 * delegates to the DataAdviseHolder.
1194 *
1195 * See Windows documentation for more details on IDataObject methods.
1196 */
1197 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1198 IDataObject* iface,
1199 IEnumSTATDATA** ppenumAdvise)
1200 {
1201 DefaultHandler *This = impl_from_IDataObject(iface);
1202
1203 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1204
1205 /* Sanity check */
1206 if (!ppenumAdvise)
1207 return E_POINTER;
1208
1209 *ppenumAdvise = NULL;
1210
1211 /* If we have a data advise holder object, delegate. */
1212 if (This->dataAdviseHolder)
1213 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1214 ppenumAdvise);
1215
1216 return S_OK;
1217 }
1218
1219 /*********************************************************
1220 * Methods implementation for the IRunnableObject part
1221 * of the DefaultHandler class.
1222 */
1223
1224 /************************************************************************
1225 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1226 *
1227 * See Windows documentation for more details on IUnknown methods.
1228 */
1229 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1230 IRunnableObject* iface,
1231 REFIID riid,
1232 void** ppvObject)
1233 {
1234 DefaultHandler *This = impl_from_IRunnableObject(iface);
1235
1236 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1237 }
1238
1239 /************************************************************************
1240 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1241 *
1242 * See Windows documentation for more details on IUnknown methods.
1243 */
1244 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1245 IRunnableObject* iface)
1246 {
1247 DefaultHandler *This = impl_from_IRunnableObject(iface);
1248
1249 return IUnknown_AddRef(This->outerUnknown);
1250 }
1251
1252 /************************************************************************
1253 * DefaultHandler_IRunnableObject_Release (IUnknown)
1254 *
1255 * See Windows documentation for more details on IUnknown methods.
1256 */
1257 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1258 IRunnableObject* iface)
1259 {
1260 DefaultHandler *This = impl_from_IRunnableObject(iface);
1261
1262 return IUnknown_Release(This->outerUnknown);
1263 }
1264
1265 /************************************************************************
1266 * DefaultHandler_GetRunningClass (IRunnableObject)
1267 *
1268 * See Windows documentation for more details on IRunnableObject methods.
1269 */
1270 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1271 IRunnableObject* iface,
1272 LPCLSID lpClsid)
1273 {
1274 FIXME("()\n");
1275 return S_OK;
1276 }
1277
1278 static HRESULT WINAPI DefaultHandler_Run(
1279 IRunnableObject* iface,
1280 IBindCtx* pbc)
1281 {
1282 DefaultHandler *This = impl_from_IRunnableObject(iface);
1283 HRESULT hr;
1284
1285 FIXME("(%p): semi-stub\n", pbc);
1286
1287 /* already running? if so nothing to do */
1288 if (object_is_running(This))
1289 return S_OK;
1290
1291 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1292 &IID_IOleObject, (void **)&This->pOleDelegate);
1293 if (FAILED(hr))
1294 return hr;
1295
1296 hr = IOleObject_Advise(This->pOleDelegate,
1297 (IAdviseSink *)&This->lpvtblIAdviseSink,
1298 &This->dwAdvConn);
1299
1300 if (SUCCEEDED(hr) && This->clientSite)
1301 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1302
1303 if (SUCCEEDED(hr))
1304 {
1305 IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1306 (void **)&This->pPSDelegate);
1307 if (This->pPSDelegate)
1308 hr = IPersistStorage_InitNew(This->pPSDelegate, NULL);
1309 }
1310
1311 if (SUCCEEDED(hr) && This->containerApp)
1312 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1313 This->containerObj);
1314
1315 /* FIXME: do more stuff here:
1316 * - IOleObject_GetMiscStatus
1317 * - IOleObject_GetMoniker
1318 * - IOleCache_OnRun
1319 */
1320
1321 if (SUCCEEDED(hr))
1322 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1323 (void **)&This->pDataDelegate);
1324
1325 if (SUCCEEDED(hr) && This->dataAdviseHolder)
1326 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1327
1328 if (FAILED(hr))
1329 DefaultHandler_Stop(This);
1330
1331 return hr;
1332 }
1333
1334 /************************************************************************
1335 * DefaultHandler_IsRunning (IRunnableObject)
1336 *
1337 * See Windows documentation for more details on IRunnableObject methods.
1338 */
1339 static BOOL WINAPI DefaultHandler_IsRunning(
1340 IRunnableObject* iface)
1341 {
1342 DefaultHandler *This = impl_from_IRunnableObject(iface);
1343
1344 TRACE("()\n");
1345
1346 if (This->pOleDelegate)
1347 return TRUE;
1348 else
1349 return FALSE;
1350 }
1351
1352 /************************************************************************
1353 * DefaultHandler_LockRunning (IRunnableObject)
1354 *
1355 * See Windows documentation for more details on IRunnableObject methods.
1356 */
1357 static HRESULT WINAPI DefaultHandler_LockRunning(
1358 IRunnableObject* iface,
1359 BOOL fLock,
1360 BOOL fLastUnlockCloses)
1361 {
1362 FIXME("()\n");
1363 return S_OK;
1364 }
1365
1366 /************************************************************************
1367 * DefaultHandler_SetContainedObject (IRunnableObject)
1368 *
1369 * See Windows documentation for more details on IRunnableObject methods.
1370 */
1371 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1372 IRunnableObject* iface,
1373 BOOL fContained)
1374 {
1375 FIXME("()\n");
1376 return S_OK;
1377 }
1378
1379 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1380 IAdviseSink *iface,
1381 REFIID riid,
1382 void **ppvObject)
1383 {
1384 if (IsEqualIID(riid, &IID_IUnknown) ||
1385 IsEqualIID(riid, &IID_IAdviseSink))
1386 {
1387 *ppvObject = iface;
1388 IAdviseSink_AddRef(iface);
1389 return S_OK;
1390 }
1391
1392 return E_NOINTERFACE;
1393 }
1394
1395 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1396 IAdviseSink *iface)
1397 {
1398 DefaultHandler *This = impl_from_IAdviseSink(iface);
1399
1400 return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
1401 }
1402
1403 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1404 IAdviseSink *iface)
1405 {
1406 DefaultHandler *This = impl_from_IAdviseSink(iface);
1407
1408 return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
1409 }
1410
1411 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1412 IAdviseSink *iface,
1413 FORMATETC *pFormatetc,
1414 STGMEDIUM *pStgmed)
1415 {
1416 FIXME(": stub\n");
1417 }
1418
1419 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1420 IAdviseSink *iface,
1421 DWORD dwAspect,
1422 LONG lindex)
1423 {
1424 FIXME(": stub\n");
1425 }
1426
1427 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1428 IAdviseSink *iface,
1429 IMoniker *pmk)
1430 {
1431 DefaultHandler *This = impl_from_IAdviseSink(iface);
1432
1433 TRACE("(%p)\n", pmk);
1434
1435 if (This->oleAdviseHolder)
1436 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1437 }
1438
1439 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1440 IAdviseSink *iface)
1441 {
1442 DefaultHandler *This = impl_from_IAdviseSink(iface);
1443
1444 TRACE("()\n");
1445
1446 if (This->oleAdviseHolder)
1447 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1448 }
1449
1450 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1451 IAdviseSink *iface)
1452 {
1453 DefaultHandler *This = impl_from_IAdviseSink(iface);
1454
1455 TRACE("()\n");
1456
1457 if (This->oleAdviseHolder)
1458 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1459
1460 DefaultHandler_Stop(This);
1461 }
1462
1463
1464 /************************************************************************
1465 * DefaultHandler_IPersistStorage_QueryInterface
1466 *
1467 */
1468 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface(
1469 IPersistStorage* iface,
1470 REFIID riid,
1471 void** ppvObject)
1472 {
1473 DefaultHandler *This = impl_from_IPersistStorage(iface);
1474
1475 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1476 }
1477
1478 /************************************************************************
1479 * DefaultHandler_IPersistStorage_AddRef
1480 *
1481 */
1482 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef(
1483 IPersistStorage* iface)
1484 {
1485 DefaultHandler *This = impl_from_IPersistStorage(iface);
1486
1487 return IUnknown_AddRef(This->outerUnknown);
1488 }
1489
1490 /************************************************************************
1491 * DefaultHandler_IPersistStorage_Release
1492 *
1493 */
1494 static ULONG WINAPI DefaultHandler_IPersistStorage_Release(
1495 IPersistStorage* iface)
1496 {
1497 DefaultHandler *This = impl_from_IPersistStorage(iface);
1498
1499 return IUnknown_Release(This->outerUnknown);
1500 }
1501
1502 /************************************************************************
1503 * DefaultHandler_IPersistStorage_GetClassID
1504 *
1505 */
1506 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
1507 IPersistStorage* iface,
1508 CLSID* clsid)
1509 {
1510 DefaultHandler *This = impl_from_IPersistStorage(iface);
1511
1512 return IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
1513 }
1514
1515 /************************************************************************
1516 * DefaultHandler_IPersistStorage_IsDirty
1517 *
1518 */
1519 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
1520 IPersistStorage* iface)
1521 {
1522 DefaultHandler *This = impl_from_IPersistStorage(iface);
1523
1524 return IPersistStorage_IsDirty(This->dataCache_PersistStg);
1525 }
1526
1527 /************************************************************************
1528 * DefaultHandler_IPersistStorage_InitNew
1529 *
1530 */
1531 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
1532 IPersistStorage* iface,
1533 IStorage* pStg)
1534 {
1535 DefaultHandler *This = impl_from_IPersistStorage(iface);
1536
1537 return IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
1538 }
1539
1540
1541 /************************************************************************
1542 * DefaultHandler_IPersistStorage_Load
1543 *
1544 */
1545 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
1546 IPersistStorage* iface,
1547 IStorage* pStg)
1548 {
1549 DefaultHandler *This = impl_from_IPersistStorage(iface);
1550
1551 return IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1552 }
1553
1554
1555 /************************************************************************
1556 * DefaultHandler_IPersistStorage_Save
1557 *
1558 */
1559 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
1560 IPersistStorage* iface,
1561 IStorage* pStgSave,
1562 BOOL fSaveAsLoad)
1563 {
1564 DefaultHandler *This = impl_from_IPersistStorage(iface);
1565
1566 return IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSaveAsLoad);
1567 }
1568
1569
1570 /************************************************************************
1571 * DefaultHandler_IPersistStorage_SaveCompleted
1572 *
1573 */
1574 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
1575 IPersistStorage* iface,
1576 IStorage* pStgNew)
1577 {
1578 DefaultHandler *This = impl_from_IPersistStorage(iface);
1579
1580 return IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
1581 }
1582
1583
1584 /************************************************************************
1585 * DefaultHandler_IPersistStorage_HandsOffStorage
1586 *
1587 */
1588 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
1589 IPersistStorage* iface)
1590 {
1591 DefaultHandler *This = impl_from_IPersistStorage(iface);
1592
1593 return IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
1594 }
1595
1596
1597 /*
1598 * Virtual function tables for the DefaultHandler class.
1599 */
1600 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1601 {
1602 DefaultHandler_QueryInterface,
1603 DefaultHandler_AddRef,
1604 DefaultHandler_Release,
1605 DefaultHandler_SetClientSite,
1606 DefaultHandler_GetClientSite,
1607 DefaultHandler_SetHostNames,
1608 DefaultHandler_Close,
1609 DefaultHandler_SetMoniker,
1610 DefaultHandler_GetMoniker,
1611 DefaultHandler_InitFromData,
1612 DefaultHandler_GetClipboardData,
1613 DefaultHandler_DoVerb,
1614 DefaultHandler_EnumVerbs,
1615 DefaultHandler_Update,
1616 DefaultHandler_IsUpToDate,
1617 DefaultHandler_GetUserClassID,
1618 DefaultHandler_GetUserType,
1619 DefaultHandler_SetExtent,
1620 DefaultHandler_GetExtent,
1621 DefaultHandler_Advise,
1622 DefaultHandler_Unadvise,
1623 DefaultHandler_EnumAdvise,
1624 DefaultHandler_GetMiscStatus,
1625 DefaultHandler_SetColorScheme
1626 };
1627
1628 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1629 {
1630 DefaultHandler_NDIUnknown_QueryInterface,
1631 DefaultHandler_NDIUnknown_AddRef,
1632 DefaultHandler_NDIUnknown_Release,
1633 };
1634
1635 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1636 {
1637 DefaultHandler_IDataObject_QueryInterface,
1638 DefaultHandler_IDataObject_AddRef,
1639 DefaultHandler_IDataObject_Release,
1640 DefaultHandler_GetData,
1641 DefaultHandler_GetDataHere,
1642 DefaultHandler_QueryGetData,
1643 DefaultHandler_GetCanonicalFormatEtc,
1644 DefaultHandler_SetData,
1645 DefaultHandler_EnumFormatEtc,
1646 DefaultHandler_DAdvise,
1647 DefaultHandler_DUnadvise,
1648 DefaultHandler_EnumDAdvise
1649 };
1650
1651 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1652 {
1653 DefaultHandler_IRunnableObject_QueryInterface,
1654 DefaultHandler_IRunnableObject_AddRef,
1655 DefaultHandler_IRunnableObject_Release,
1656 DefaultHandler_GetRunningClass,
1657 DefaultHandler_Run,
1658 DefaultHandler_IsRunning,
1659 DefaultHandler_LockRunning,
1660 DefaultHandler_SetContainedObject
1661 };
1662
1663 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1664 {
1665 DefaultHandler_IAdviseSink_QueryInterface,
1666 DefaultHandler_IAdviseSink_AddRef,
1667 DefaultHandler_IAdviseSink_Release,
1668 DefaultHandler_IAdviseSink_OnDataChange,
1669 DefaultHandler_IAdviseSink_OnViewChange,
1670 DefaultHandler_IAdviseSink_OnRename,
1671 DefaultHandler_IAdviseSink_OnSave,
1672 DefaultHandler_IAdviseSink_OnClose
1673 };
1674
1675 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
1676 {
1677 DefaultHandler_IPersistStorage_QueryInterface,
1678 DefaultHandler_IPersistStorage_AddRef,
1679 DefaultHandler_IPersistStorage_Release,
1680 DefaultHandler_IPersistStorage_GetClassID,
1681 DefaultHandler_IPersistStorage_IsDirty,
1682 DefaultHandler_IPersistStorage_InitNew,
1683 DefaultHandler_IPersistStorage_Load,
1684 DefaultHandler_IPersistStorage_Save,
1685 DefaultHandler_IPersistStorage_SaveCompleted,
1686 DefaultHandler_IPersistStorage_HandsOffStorage
1687 };
1688
1689 /*********************************************************
1690 * Methods implementation for the DefaultHandler class.
1691 */
1692 static DefaultHandler* DefaultHandler_Construct(
1693 REFCLSID clsid,
1694 LPUNKNOWN pUnkOuter)
1695 {
1696 DefaultHandler* This = NULL;
1697 HRESULT hr;
1698
1699 /*
1700 * Allocate space for the object.
1701 */
1702 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1703
1704 if (!This)
1705 return This;
1706
1707 This->lpVtbl = &DefaultHandler_IOleObject_VTable;
1708 This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
1709 This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
1710 This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1711 This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
1712 This->lpvtblIPersistStorage = &DefaultHandler_IPersistStorage_VTable;
1713
1714 /*
1715 * Start with one reference count. The caller of this function
1716 * must release the interface pointer when it is done.
1717 */
1718 This->ref = 1;
1719
1720 /*
1721 * Initialize the outer unknown
1722 * We don't keep a reference on the outer unknown since, the way
1723 * aggregation works, our lifetime is at least as large as its
1724 * lifetime.
1725 */
1726 if (!pUnkOuter)
1727 pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1728
1729 This->outerUnknown = pUnkOuter;
1730
1731 /*
1732 * Create a datacache object.
1733 * We aggregate with the datacache. Make sure we pass our outer
1734 * unknown as the datacache's outer unknown.
1735 */
1736 hr = CreateDataCache(This->outerUnknown,
1737 clsid,
1738 &IID_IUnknown,
1739 (void**)&This->dataCache);
1740 if(SUCCEEDED(hr))
1741 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
1742 if(FAILED(hr))
1743 ERR("Unexpected error creating data cache\n");
1744 /*
1745 * Initialize the other data members of the class.
1746 */
1747 This->clsid = *clsid;
1748 This->clientSite = NULL;
1749 This->oleAdviseHolder = NULL;
1750 This->dataAdviseHolder = NULL;
1751 This->containerApp = NULL;
1752 This->containerObj = NULL;
1753 This->pOleDelegate = NULL;
1754 This->pPSDelegate = NULL;
1755 This->pDataDelegate = NULL;
1756
1757 This->dwAdvConn = 0;
1758
1759 return This;
1760 }
1761
1762 static void DefaultHandler_Destroy(
1763 DefaultHandler* This)
1764 {
1765 /* release delegates */
1766 DefaultHandler_Stop(This);
1767
1768 /* Free the strings idenfitying the object */
1769 HeapFree( GetProcessHeap(), 0, This->containerApp );
1770 This->containerApp = NULL;
1771 HeapFree( GetProcessHeap(), 0, This->containerObj );
1772 This->containerObj = NULL;
1773
1774 /* Release our reference to the data cache. */
1775 if (This->dataCache)
1776 {
1777 IPersistStorage_Release(This->dataCache_PersistStg);
1778 IUnknown_Release(This->dataCache);
1779 This->dataCache_PersistStg = NULL;
1780 This->dataCache = NULL;
1781 }
1782
1783 /* Same thing for the client site. */
1784 if (This->clientSite)
1785 {
1786 IOleClientSite_Release(This->clientSite);
1787 This->clientSite = NULL;
1788 }
1789
1790 /* And the advise holder. */
1791 if (This->oleAdviseHolder)
1792 {
1793 IOleAdviseHolder_Release(This->oleAdviseHolder);
1794 This->oleAdviseHolder = NULL;
1795 }
1796
1797 /* And the data advise holder. */
1798 if (This->dataAdviseHolder)
1799 {
1800 IDataAdviseHolder_Release(This->dataAdviseHolder);
1801 This->dataAdviseHolder = NULL;
1802 }
1803
1804 /* Free the actual default handler structure. */
1805 HeapFree(GetProcessHeap(), 0, This);
1806 }
1807
1808 /******************************************************************************
1809 * OleCreateDefaultHandler [OLE32.@]
1810 */
1811 HRESULT WINAPI OleCreateDefaultHandler(
1812 REFCLSID clsid,
1813 LPUNKNOWN pUnkOuter,
1814 REFIID riid,
1815 LPVOID* ppvObj)
1816 {
1817 DefaultHandler* newHandler = NULL;
1818 HRESULT hr = S_OK;
1819
1820 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
1821
1822 /*
1823 * Sanity check
1824 */
1825 if (!ppvObj)
1826 return E_POINTER;
1827
1828 *ppvObj = NULL;
1829
1830 /*
1831 * If This handler is constructed for aggregation, make sure
1832 * the caller is requesting the IUnknown interface.
1833 * This is necessary because it's the only time the non-delegating
1834 * IUnknown pointer can be returned to the outside.
1835 */
1836 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
1837 return CLASS_E_NOAGGREGATION;
1838
1839 /*
1840 * Try to construct a new instance of the class.
1841 */
1842 newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
1843
1844 if (!newHandler)
1845 return E_OUTOFMEMORY;
1846
1847 /*
1848 * Make sure it supports the interface required by the caller.
1849 */
1850 hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
1851
1852 /*
1853 * Release the reference obtained in the constructor. If
1854 * the QueryInterface was unsuccessful, it will free the class.
1855 */
1856 IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
1857
1858 return hr;
1859 }