comsvcs: Implement Hash() for "new" moniker.
[wine.git] / dlls / comsvcs / main.c
blob7addd1ee80aab4d1a748628b72ecb794bd99e6e6
1 /*
2 * COM+ Services
4 * Copyright 2013 Alistair Leslie-Hughes
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "ole2.h"
28 #include "rpcproxy.h"
29 #include "comsvcs.h"
30 #include "wine/heap.h"
31 #include "wine/debug.h"
32 #include "initguid.h"
33 #include "comsvcs_classes.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(comsvcs);
37 static HINSTANCE COMSVCS_hInstance;
39 typedef struct dispensermanager
41 IDispenserManager IDispenserManager_iface;
42 LONG ref;
43 HANDLE mta_thread, mta_stop_event;
44 } dispensermanager;
46 typedef struct holder
48 IHolder IHolder_iface;
49 LONG ref;
51 IDispenserDriver *driver;
52 } holder;
54 struct new_moniker
56 IMoniker IMoniker_iface;
57 LONG refcount;
58 CLSID clsid;
61 static HRESULT new_moniker_parse_displayname(IBindCtx *pbc, LPOLESTR name, ULONG *eaten, IMoniker **ret);
63 static inline dispensermanager *impl_from_IDispenserManager(IDispenserManager *iface)
65 return CONTAINING_RECORD(iface, dispensermanager, IDispenserManager_iface);
68 static inline holder *impl_from_IHolder(IHolder *iface)
70 return CONTAINING_RECORD(iface, holder, IHolder_iface);
73 static struct new_moniker *impl_from_IMoniker(IMoniker *iface)
75 return CONTAINING_RECORD(iface, struct new_moniker, IMoniker_iface);
78 static HRESULT WINAPI holder_QueryInterface(IHolder *iface, REFIID riid, void **object)
80 holder *This = impl_from_IHolder(iface);
82 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), object);
84 *object = NULL;
86 if (IsEqualGUID(riid, &IID_IUnknown) ||
87 IsEqualGUID(riid, &IID_IHolder))
89 *object = &This->IHolder_iface;
90 IUnknown_AddRef( (IUnknown*)*object);
92 return S_OK;
95 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),object);
96 return E_NOINTERFACE;
99 static ULONG WINAPI holder_AddRef(IHolder *iface)
101 holder *This = impl_from_IHolder(iface);
102 ULONG ref = InterlockedIncrement(&This->ref);
103 TRACE("(%p)->(%d)\n", This, ref);
104 return ref;
107 static ULONG WINAPI holder_Release(IHolder *iface)
109 holder *This = impl_from_IHolder(iface);
110 ULONG ref = InterlockedDecrement(&This->ref);
111 TRACE("(%p)->(%d)\n", This, ref);
113 if (!ref)
115 heap_free(This);
118 return ref;
121 static HRESULT WINAPI holder_AllocResource(IHolder *iface, const RESTYPID typeid, RESID *resid)
123 holder *This = impl_from_IHolder(iface);
124 HRESULT hr;
125 TIMEINSECS secs;
127 TRACE("(%p)->(%08lx, %p) stub\n", This, typeid, resid);
129 hr = IDispenserDriver_CreateResource(This->driver, typeid, resid, &secs);
131 TRACE("<- 0x%08x\n", hr);
132 return hr;
135 static HRESULT WINAPI holder_FreeResource(IHolder *iface, const RESID resid)
137 holder *This = impl_from_IHolder(iface);
138 HRESULT hr;
140 TRACE("(%p)->(%08lx) stub\n", This, resid);
142 hr = IDispenserDriver_DestroyResource(This->driver, resid);
144 TRACE("<- 0x%08x\n", hr);
146 return hr;
149 static HRESULT WINAPI holder_TrackResource(IHolder *iface, const RESID resid)
151 holder *This = impl_from_IHolder(iface);
153 FIXME("(%p)->(%08lx) stub\n", This, resid);
155 return E_NOTIMPL;
158 static HRESULT WINAPI holder_TrackResourceS(IHolder *iface, const SRESID resid)
160 holder *This = impl_from_IHolder(iface);
162 FIXME("(%p)->(%s) stub\n", This, debugstr_w(resid));
164 return E_NOTIMPL;
167 static HRESULT WINAPI holder_UntrackResource(IHolder *iface, const RESID resid, const BOOL value)
169 holder *This = impl_from_IHolder(iface);
171 FIXME("(%p)->(%08lx, %d) stub\n", This, resid, value);
173 return E_NOTIMPL;
176 static HRESULT WINAPI holder_UntrackResourceS(IHolder *iface, const SRESID resid, const BOOL value)
178 holder *This = impl_from_IHolder(iface);
180 FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(resid), value);
182 return E_NOTIMPL;
185 static HRESULT WINAPI holder_Close(IHolder *iface)
187 holder *This = impl_from_IHolder(iface);
189 FIXME("(%p) stub\n", This);
191 IDispenserDriver_Release(This->driver);
193 return S_OK;
196 static HRESULT WINAPI holder_RequestDestroyResource(IHolder *iface, const RESID resid)
198 holder *This = impl_from_IHolder(iface);
200 FIXME("(%p)->(%08lx) stub\n", This, resid);
202 return E_NOTIMPL;
205 struct IHolderVtbl holder_vtbl =
207 holder_QueryInterface,
208 holder_AddRef,
209 holder_Release,
210 holder_AllocResource,
211 holder_FreeResource,
212 holder_TrackResource,
213 holder_TrackResourceS,
214 holder_UntrackResource,
215 holder_UntrackResourceS,
216 holder_Close,
217 holder_RequestDestroyResource
220 static HRESULT create_holder(IDispenserDriver *driver, IHolder **object)
222 holder *hold;
223 HRESULT ret;
225 TRACE("(%p)\n", object);
227 hold = heap_alloc(sizeof(*hold));
228 if (!hold)
230 *object = NULL;
231 return E_OUTOFMEMORY;
234 hold->IHolder_iface.lpVtbl = &holder_vtbl;
235 hold->ref = 1;
236 hold->driver = driver;
238 ret = holder_QueryInterface(&hold->IHolder_iface, &IID_IHolder, (void**)object);
239 holder_Release(&hold->IHolder_iface);
241 return ret;
244 static HRESULT WINAPI dismanager_QueryInterface(IDispenserManager *iface, REFIID riid, void **object)
246 dispensermanager *This = impl_from_IDispenserManager(iface);
248 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), object);
250 *object = NULL;
252 if (IsEqualGUID(riid, &IID_IUnknown) ||
253 IsEqualGUID(riid, &IID_IDispenserManager))
255 *object = &This->IDispenserManager_iface;
256 IUnknown_AddRef( (IUnknown*)*object);
258 return S_OK;
261 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),object);
262 return E_NOINTERFACE;
265 static ULONG WINAPI dismanager_AddRef(IDispenserManager *iface)
267 dispensermanager *This = impl_from_IDispenserManager(iface);
268 ULONG ref = InterlockedIncrement(&This->ref);
269 TRACE("(%p)->(%d)\n", This, ref);
270 return ref;
273 static ULONG WINAPI dismanager_Release(IDispenserManager *iface)
275 dispensermanager *This = impl_from_IDispenserManager(iface);
276 ULONG ref = InterlockedDecrement(&This->ref);
277 TRACE("(%p)->(%d)\n", This, ref);
279 if (!ref)
281 if (This->mta_thread)
283 SetEvent(This->mta_stop_event);
284 WaitForSingleObject(This->mta_thread, INFINITE);
285 CloseHandle(This->mta_stop_event);
286 CloseHandle(This->mta_thread);
288 heap_free(This);
291 return ref;
294 static DWORD WINAPI mta_thread_proc(void *arg)
296 CoInitializeEx(NULL, COINIT_MULTITHREADED);
297 WaitForSingleObject(arg, INFINITE);
298 CoUninitialize();
299 return 0;
302 static HRESULT WINAPI dismanager_RegisterDispenser(IDispenserManager *iface, IDispenserDriver *driver,
303 LPCOLESTR name, IHolder **dispenser)
305 dispensermanager *This = impl_from_IDispenserManager(iface);
306 HRESULT hr;
308 TRACE("(%p)->(%p, %s, %p)\n", This, driver, debugstr_w(name), dispenser);
310 if(!dispenser)
311 return E_INVALIDARG;
313 hr = create_holder(driver, dispenser);
315 if (!This->mta_thread)
317 This->mta_stop_event = CreateEventA(NULL, TRUE, FALSE, NULL);
318 This->mta_thread = CreateThread(NULL, 0, mta_thread_proc, This->mta_stop_event, 0, NULL);
321 TRACE("<-- 0x%08x, %p\n", hr, *dispenser);
323 return hr;
326 static HRESULT WINAPI dismanager_GetContext(IDispenserManager *iface, INSTID *id, TRANSID *transid)
328 dispensermanager *This = impl_from_IDispenserManager(iface);
330 FIXME("(%p)->(%p, %p) stub\n", This, id, transid);
332 return E_NOTIMPL;
335 struct IDispenserManagerVtbl dismanager_vtbl =
337 dismanager_QueryInterface,
338 dismanager_AddRef,
339 dismanager_Release,
340 dismanager_RegisterDispenser,
341 dismanager_GetContext
344 static HRESULT WINAPI dispenser_manager_cf_CreateInstance(IClassFactory *iface, IUnknown* outer, REFIID riid,
345 void **object)
347 dispensermanager *dismanager;
348 HRESULT ret;
350 TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), object);
352 dismanager = heap_alloc_zero(sizeof(*dismanager));
353 if (!dismanager)
355 *object = NULL;
356 return E_OUTOFMEMORY;
359 dismanager->IDispenserManager_iface.lpVtbl = &dismanager_vtbl;
360 dismanager->ref = 1;
362 ret = dismanager_QueryInterface(&dismanager->IDispenserManager_iface, riid, object);
363 dismanager_Release(&dismanager->IDispenserManager_iface);
365 return ret;
368 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID lpv)
370 switch(reason)
372 case DLL_WINE_PREATTACH:
373 return FALSE; /* prefer native version */
374 case DLL_PROCESS_ATTACH:
375 COMSVCS_hInstance = hinst;
376 DisableThreadLibraryCalls(hinst);
377 break;
379 return TRUE;
382 static HRESULT WINAPI comsvcscf_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv )
384 *ppv = NULL;
386 if(IsEqualGUID(&IID_IUnknown, riid)) {
387 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
388 *ppv = iface;
389 }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
390 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
391 *ppv = iface;
394 if(*ppv) {
395 IUnknown_AddRef((IUnknown*)*ppv);
396 return S_OK;
399 WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
400 return E_NOINTERFACE;
403 static ULONG WINAPI comsvcscf_AddRef(IClassFactory *iface )
405 TRACE("(%p)\n", iface);
406 return 2;
409 static ULONG WINAPI comsvcscf_Release(IClassFactory *iface )
411 TRACE("(%p)\n", iface);
412 return 1;
415 static HRESULT WINAPI comsvcscf_LockServer(IClassFactory *iface, BOOL fLock)
417 TRACE("(%p)->(%x)\n", iface, fLock);
418 return S_OK;
421 static const IClassFactoryVtbl comsvcscf_vtbl =
423 comsvcscf_QueryInterface,
424 comsvcscf_AddRef,
425 comsvcscf_Release,
426 dispenser_manager_cf_CreateInstance,
427 comsvcscf_LockServer
430 static HRESULT WINAPI new_moniker_QueryInterface(IMoniker* iface, REFIID riid, void **obj)
432 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
434 *obj = NULL;
436 if (IsEqualIID(&IID_IUnknown, riid) ||
437 IsEqualIID(&IID_IPersist, riid) ||
438 IsEqualIID(&IID_IPersistStream, riid) ||
439 IsEqualIID(&IID_IMoniker, riid))
441 *obj = iface;
444 if (*obj)
446 IUnknown_AddRef((IUnknown *)*obj);
447 return S_OK;
450 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
451 return E_NOINTERFACE;
454 static ULONG WINAPI new_moniker_AddRef(IMoniker* iface)
456 struct new_moniker *moniker = impl_from_IMoniker(iface);
457 ULONG refcount = InterlockedIncrement(&moniker->refcount);
459 TRACE("%p, refcount %u.\n", iface, refcount);
461 return refcount;
464 static ULONG WINAPI new_moniker_Release(IMoniker* iface)
466 struct new_moniker *moniker = impl_from_IMoniker(iface);
467 ULONG refcount = InterlockedDecrement(&moniker->refcount);
469 TRACE("%p, refcount %u.\n", iface, refcount);
471 if (!refcount)
472 heap_free(moniker);
474 return refcount;
477 static HRESULT WINAPI new_moniker_GetClassID(IMoniker *iface, CLSID *clsid)
479 FIXME("%p, %p.\n", iface, clsid);
481 return E_NOTIMPL;
484 static HRESULT WINAPI new_moniker_IsDirty(IMoniker* iface)
486 FIXME("%p.\n", iface);
488 return E_NOTIMPL;
491 static HRESULT WINAPI new_moniker_Load(IMoniker *iface, IStream *stream)
493 FIXME("%p, %p.\n", iface, stream);
495 return E_NOTIMPL;
498 static HRESULT WINAPI new_moniker_Save(IMoniker *iface, IStream *stream, BOOL clear_dirty)
500 FIXME("%p, %p, %d.\n", iface, stream, clear_dirty);
502 return E_NOTIMPL;
505 static HRESULT WINAPI new_moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *size)
507 FIXME("%p, %p.\n", iface, size);
509 return E_NOTIMPL;
512 static HRESULT WINAPI new_moniker_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
513 REFIID riid, void **ret)
515 FIXME("%p, %p, %p, %s, %p.\n", iface, pbc, pmkToLeft, debugstr_guid(riid), ret);
517 return E_NOTIMPL;
520 static HRESULT WINAPI new_moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid,
521 void **ret)
523 FIXME("%p, %p, %p, %s, %p.\n", iface, pbc, pmkToLeft, debugstr_guid(riid), ret);
525 return E_NOTIMPL;
528 static HRESULT WINAPI new_moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD flags, IMoniker **ppmkToLeft,
529 IMoniker **ret)
531 FIXME("%p, %p, %d, %p, %p.\n", iface, pbc, flags, ppmkToLeft, ret);
533 return E_NOTIMPL;
536 static HRESULT WINAPI new_moniker_ComposeWith(IMoniker *iface, IMoniker *mkRight, BOOL fOnlyIfNotGeneric,
537 IMoniker **ret)
539 FIXME("%p, %p, %d, %p.\n", iface, mkRight, fOnlyIfNotGeneric, ret);
541 return E_NOTIMPL;
544 static HRESULT WINAPI new_moniker_Enum(IMoniker *iface, BOOL forward, IEnumMoniker **enum_moniker)
546 FIXME("%p, %d, %p.\n", iface, forward, enum_moniker);
548 return E_NOTIMPL;
551 static HRESULT WINAPI new_moniker_IsEqual(IMoniker *iface, IMoniker *other_moniker)
553 FIXME("%p, %p.\n", iface, other_moniker);
555 return E_NOTIMPL;
558 static HRESULT WINAPI new_moniker_Hash(IMoniker *iface, DWORD *hash)
560 struct new_moniker *moniker = impl_from_IMoniker(iface);
562 TRACE("%p, %p.\n", iface, hash);
564 *hash = moniker->clsid.Data1;
566 return S_OK;
569 static HRESULT WINAPI new_moniker_IsRunning(IMoniker* iface, IBindCtx *pbc, IMoniker *pmkToLeft,
570 IMoniker *pmkNewlyRunning)
572 FIXME("%p, %p, %p, %p.\n", iface, pbc, pmkToLeft, pmkNewlyRunning);
574 return E_NOTIMPL;
577 static HRESULT WINAPI new_moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
578 FILETIME *itemtime)
580 FIXME("%p, %p, %p, %p.\n", iface, pbc, pmkToLeft, itemtime);
582 return E_NOTIMPL;
585 static HRESULT WINAPI new_moniker_Inverse(IMoniker *iface, IMoniker **inverse)
587 FIXME("%p, %p.\n", iface, inverse);
589 return E_NOTIMPL;
592 static HRESULT WINAPI new_moniker_CommonPrefixWith(IMoniker *iface, IMoniker *other, IMoniker **ret)
594 FIXME("%p, %p, %p.\n", iface, other, ret);
596 return E_NOTIMPL;
599 static HRESULT WINAPI new_moniker_RelativePathTo(IMoniker *iface, IMoniker *other, IMoniker **ret)
601 FIXME("%p, %p, %p.\n", iface, other, ret);
603 return E_NOTIMPL;
606 static HRESULT WINAPI new_moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
607 LPOLESTR *name)
609 FIXME("%p, %p, %p, %p.\n", iface, pbc, pmkToLeft, name);
611 return E_NOTIMPL;
614 static HRESULT WINAPI new_moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
615 LPOLESTR name, ULONG *eaten, IMoniker **ret)
617 TRACE("%p, %p, %p, %s, %p, %p.\n", iface, pbc, pmkToLeft, debugstr_w(name), eaten, ret);
619 return new_moniker_parse_displayname(pbc, name, eaten, ret);
622 static HRESULT WINAPI new_moniker_IsSystemMoniker(IMoniker *iface, DWORD *moniker_type)
624 FIXME("%p, %p.\n", iface, moniker_type);
626 return E_NOTIMPL;
629 static const IMonikerVtbl new_moniker_vtbl =
631 new_moniker_QueryInterface,
632 new_moniker_AddRef,
633 new_moniker_Release,
634 new_moniker_GetClassID,
635 new_moniker_IsDirty,
636 new_moniker_Load,
637 new_moniker_Save,
638 new_moniker_GetSizeMax,
639 new_moniker_BindToObject,
640 new_moniker_BindToStorage,
641 new_moniker_Reduce,
642 new_moniker_ComposeWith,
643 new_moniker_Enum,
644 new_moniker_IsEqual,
645 new_moniker_Hash,
646 new_moniker_IsRunning,
647 new_moniker_GetTimeOfLastChange,
648 new_moniker_Inverse,
649 new_moniker_CommonPrefixWith,
650 new_moniker_RelativePathTo,
651 new_moniker_GetDisplayName,
652 new_moniker_ParseDisplayName,
653 new_moniker_IsSystemMoniker
656 static const BYTE guid_conv_table[256] =
658 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
659 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
660 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
661 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
662 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
663 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
664 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */
667 static BOOL is_valid_hex(WCHAR c)
669 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
670 (c >= 'A' && c <= 'F');
673 static HRESULT guid_from_string(const WCHAR *s, GUID *ret)
675 BOOL has_brackets;
676 GUID guid = { 0 };
677 int i;
679 memset(ret, 0, sizeof(*ret));
681 /* Curly brackets are optional. */
682 has_brackets = s[0] == '{';
684 if (has_brackets)
685 s++;
687 for (i = 0; i < 8; i++)
689 if (!is_valid_hex(s[i])) return FALSE;
690 guid.Data1 = (guid.Data1 << 4) | guid_conv_table[s[i]];
692 s += 8;
694 if (s[0] != '-') return FALSE;
695 s++;
697 for (i = 0; i < 4; i++)
699 if (!is_valid_hex(s[0])) return FALSE;
700 guid.Data2 = (guid.Data2 << 4) | guid_conv_table[s[i]];
702 s += 4;
704 if (s[0] != '-') return FALSE;
705 s++;
707 for (i = 0; i < 4; i++)
709 if (!is_valid_hex(s[i])) return FALSE;
710 guid.Data3 = (guid.Data3 << 4) | guid_conv_table[s[i]];
712 s += 4;
714 if (s[0] != '-') return FALSE;
715 s++;
717 for (i = 0; i < 17; i += 2)
719 if (i == 4)
721 if (s[i] != '-') return FALSE;
722 i++;
724 if (!is_valid_hex(s[i]) || !is_valid_hex(s[i+1])) return FALSE;
725 guid.Data4[i / 2] = guid_conv_table[s[i]] << 4 | guid_conv_table[s[i+1]];
727 s += 17;
729 if (has_brackets && s[0] != '}')
730 return FALSE;
732 *ret = guid;
734 return TRUE;
737 static HRESULT new_moniker_parse_displayname(IBindCtx *pbc, LPOLESTR name, ULONG *eaten, IMoniker **ret)
739 struct new_moniker *moniker;
740 GUID guid;
742 *ret = NULL;
744 if (wcsnicmp(name, L"new:", 4))
745 return MK_E_SYNTAX;
747 if (!guid_from_string(name + 4, &guid))
748 return MK_E_SYNTAX;
750 moniker = heap_alloc_zero(sizeof(*moniker));
751 if (!moniker)
752 return E_OUTOFMEMORY;
754 moniker->IMoniker_iface.lpVtbl = &new_moniker_vtbl;
755 moniker->refcount = 1;
756 moniker->clsid = guid;
758 *ret = &moniker->IMoniker_iface;
760 if (eaten)
761 *eaten = lstrlenW(name);
763 return S_OK;
766 static HRESULT WINAPI new_moniker_parse_QueryInterface(IParseDisplayName *iface, REFIID riid, void **obj)
768 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
770 if (IsEqualIID(riid, &IID_IParseDisplayName) ||
771 IsEqualIID(riid, &IID_IUnknown))
773 *obj = iface;
774 IParseDisplayName_AddRef(iface);
775 return S_OK;
778 *obj = NULL;
779 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
780 return E_NOINTERFACE;
783 static ULONG WINAPI new_moniker_parse_AddRef(IParseDisplayName *iface)
785 return 2;
788 static ULONG WINAPI new_moniker_parse_Release(IParseDisplayName *iface)
790 return 1;
793 static HRESULT WINAPI new_moniker_parse_ParseDisplayName(IParseDisplayName *iface, IBindCtx *pbc, LPOLESTR name,
794 ULONG *eaten, IMoniker **ret)
796 TRACE("%p, %p, %s, %p, %p.\n", iface, pbc, debugstr_w(name), eaten, ret);
798 return new_moniker_parse_displayname(pbc, name, eaten, ret);
801 static const IParseDisplayNameVtbl new_moniker_parse_vtbl =
803 new_moniker_parse_QueryInterface,
804 new_moniker_parse_AddRef,
805 new_moniker_parse_Release,
806 new_moniker_parse_ParseDisplayName,
809 static IParseDisplayName new_moniker_parse = { &new_moniker_parse_vtbl };
811 static HRESULT WINAPI new_moniker_cf_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
813 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
815 *obj = NULL;
817 if (IsEqualGUID(&IID_IUnknown, riid) ||
818 IsEqualGUID(&IID_IClassFactory, riid))
820 *obj = iface;
822 else if (IsEqualIID(&IID_IParseDisplayName, riid))
824 *obj = &new_moniker_parse;
827 if (*obj)
829 IUnknown_AddRef((IUnknown *)*obj);
830 return S_OK;
833 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
834 return E_NOINTERFACE;
837 static HRESULT WINAPI new_moniker_cf_CreateInstance(IClassFactory *iface, IUnknown* outer, REFIID riid, void **object)
839 TRACE("%p, %p, %s, %p.\n", iface, outer, debugstr_guid(riid), object);
841 if (outer)
842 FIXME("Aggregation is not supported.\n");
844 return IParseDisplayName_QueryInterface(&new_moniker_parse, riid, object);
847 static const IClassFactoryVtbl newmoniker_cf_vtbl =
849 new_moniker_cf_QueryInterface,
850 comsvcscf_AddRef,
851 comsvcscf_Release,
852 new_moniker_cf_CreateInstance,
853 comsvcscf_LockServer
856 static IClassFactory DispenserManageFactory = { &comsvcscf_vtbl };
857 static IClassFactory NewMonikerFactory = { &newmoniker_cf_vtbl };
859 /******************************************************************
860 * DllGetClassObject
862 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
864 if(IsEqualGUID(&CLSID_DispenserManager, rclsid))
866 TRACE("(CLSID_DispenserManager %s %p)\n", debugstr_guid(riid), ppv);
867 return IClassFactory_QueryInterface(&DispenserManageFactory, riid, ppv);
869 else if (IsEqualGUID(&CLSID_NewMoniker, rclsid))
871 TRACE("(CLSID_NewMoniker %s %p)\n", debugstr_guid(riid), ppv);
872 return IClassFactory_QueryInterface(&NewMonikerFactory, riid, ppv);
875 FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
876 return CLASS_E_CLASSNOTAVAILABLE;
879 /******************************************************************
880 * DllCanUnloadNow
882 HRESULT WINAPI DllCanUnloadNow(void)
884 return S_FALSE;
887 /***********************************************************************
888 * DllRegisterServer (comsvcs.@)
890 HRESULT WINAPI DllRegisterServer(void)
892 return __wine_register_resources( COMSVCS_hInstance );
895 /***********************************************************************
896 * DllUnregisterServer (comsvcs.@)
898 HRESULT WINAPI DllUnregisterServer(void)
900 return __wine_unregister_resources( COMSVCS_hInstance );