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