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