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