include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / comsvcs / main.c
blob43803f60632d3d6070825e013cc221d39b37ec2a
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 #include "comsvcs_private.h"
22 #include "wine/debug.h"
23 #include "initguid.h"
24 #include "comsvcs_classes.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(comsvcs);
28 typedef struct dispensermanager
30 IDispenserManager IDispenserManager_iface;
31 LONG ref;
32 CO_MTA_USAGE_COOKIE mta_cookie;
33 } dispensermanager;
35 typedef struct holder
37 IHolder IHolder_iface;
38 LONG ref;
40 IDispenserDriver *driver;
41 } holder;
43 struct new_moniker
45 IMoniker IMoniker_iface;
46 IROTData IROTData_iface;
47 LONG refcount;
48 CLSID clsid;
49 WCHAR *progid;
52 static HRESULT new_moniker_parse_displayname(IBindCtx *pbc, LPOLESTR name, ULONG *eaten, IMoniker **ret);
54 static inline dispensermanager *impl_from_IDispenserManager(IDispenserManager *iface)
56 return CONTAINING_RECORD(iface, dispensermanager, IDispenserManager_iface);
59 static inline holder *impl_from_IHolder(IHolder *iface)
61 return CONTAINING_RECORD(iface, holder, IHolder_iface);
64 static struct new_moniker *impl_from_IMoniker(IMoniker *iface)
66 return CONTAINING_RECORD(iface, struct new_moniker, IMoniker_iface);
69 static struct new_moniker *impl_from_IROTData(IROTData *iface)
71 return CONTAINING_RECORD(iface, struct new_moniker, IROTData_iface);
74 static HRESULT WINAPI holder_QueryInterface(IHolder *iface, REFIID riid, void **object)
76 holder *This = impl_from_IHolder(iface);
78 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), object);
80 *object = NULL;
82 if (IsEqualGUID(riid, &IID_IUnknown) ||
83 IsEqualGUID(riid, &IID_IHolder))
85 *object = &This->IHolder_iface;
86 IUnknown_AddRef( (IUnknown*)*object);
88 return S_OK;
91 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),object);
92 return E_NOINTERFACE;
95 static ULONG WINAPI holder_AddRef(IHolder *iface)
97 holder *This = impl_from_IHolder(iface);
98 ULONG ref = InterlockedIncrement(&This->ref);
99 TRACE("(%p)->(%ld)\n", This, ref);
100 return ref;
103 static ULONG WINAPI holder_Release(IHolder *iface)
105 holder *This = impl_from_IHolder(iface);
106 ULONG ref = InterlockedDecrement(&This->ref);
107 TRACE("(%p)->(%ld)\n", This, ref);
109 if (!ref)
111 free(This);
114 return ref;
117 static HRESULT WINAPI holder_AllocResource(IHolder *iface, const RESTYPID typeid, RESID *resid)
119 holder *This = impl_from_IHolder(iface);
120 HRESULT hr;
121 TIMEINSECS secs;
123 TRACE("(%p)->(%08Ix, %p) stub\n", This, typeid, resid);
125 hr = IDispenserDriver_CreateResource(This->driver, typeid, resid, &secs);
127 TRACE("<- 0x%08lx\n", hr);
128 return hr;
131 static HRESULT WINAPI holder_FreeResource(IHolder *iface, const RESID resid)
133 holder *This = impl_from_IHolder(iface);
134 HRESULT hr;
136 TRACE("(%p)->(%08Ix) stub\n", This, resid);
138 hr = IDispenserDriver_DestroyResource(This->driver, resid);
140 TRACE("<- 0x%08lx\n", hr);
142 return hr;
145 static HRESULT WINAPI holder_TrackResource(IHolder *iface, const RESID resid)
147 holder *This = impl_from_IHolder(iface);
149 FIXME("(%p)->(%08Ix) stub\n", This, resid);
151 return E_NOTIMPL;
154 static HRESULT WINAPI holder_TrackResourceS(IHolder *iface, const SRESID resid)
156 holder *This = impl_from_IHolder(iface);
158 FIXME("(%p)->(%s) stub\n", This, debugstr_w(resid));
160 return E_NOTIMPL;
163 static HRESULT WINAPI holder_UntrackResource(IHolder *iface, const RESID resid, const BOOL value)
165 holder *This = impl_from_IHolder(iface);
167 FIXME("(%p)->(%08Ix, %d) stub\n", This, resid, value);
169 return E_NOTIMPL;
172 static HRESULT WINAPI holder_UntrackResourceS(IHolder *iface, const SRESID resid, const BOOL value)
174 holder *This = impl_from_IHolder(iface);
176 FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(resid), value);
178 return E_NOTIMPL;
181 static HRESULT WINAPI holder_Close(IHolder *iface)
183 holder *This = impl_from_IHolder(iface);
185 FIXME("(%p) stub\n", This);
187 IDispenserDriver_Release(This->driver);
189 return S_OK;
192 static HRESULT WINAPI holder_RequestDestroyResource(IHolder *iface, const RESID resid)
194 holder *This = impl_from_IHolder(iface);
196 FIXME("(%p)->(%08Ix) stub\n", This, resid);
198 return E_NOTIMPL;
201 struct IHolderVtbl holder_vtbl =
203 holder_QueryInterface,
204 holder_AddRef,
205 holder_Release,
206 holder_AllocResource,
207 holder_FreeResource,
208 holder_TrackResource,
209 holder_TrackResourceS,
210 holder_UntrackResource,
211 holder_UntrackResourceS,
212 holder_Close,
213 holder_RequestDestroyResource
216 static HRESULT create_holder(IDispenserDriver *driver, IHolder **object)
218 holder *hold;
219 HRESULT ret;
221 TRACE("(%p)\n", object);
223 hold = malloc(sizeof(*hold));
224 if (!hold)
226 *object = NULL;
227 return E_OUTOFMEMORY;
230 hold->IHolder_iface.lpVtbl = &holder_vtbl;
231 hold->ref = 1;
232 hold->driver = driver;
234 ret = holder_QueryInterface(&hold->IHolder_iface, &IID_IHolder, (void**)object);
235 holder_Release(&hold->IHolder_iface);
237 return ret;
240 static HRESULT WINAPI dismanager_QueryInterface(IDispenserManager *iface, REFIID riid, void **object)
242 dispensermanager *This = impl_from_IDispenserManager(iface);
244 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), object);
246 *object = NULL;
248 if (IsEqualGUID(riid, &IID_IUnknown) ||
249 IsEqualGUID(riid, &IID_IDispenserManager))
251 *object = &This->IDispenserManager_iface;
252 IUnknown_AddRef( (IUnknown*)*object);
254 return S_OK;
257 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),object);
258 return E_NOINTERFACE;
261 static ULONG WINAPI dismanager_AddRef(IDispenserManager *iface)
263 dispensermanager *This = impl_from_IDispenserManager(iface);
264 ULONG ref = InterlockedIncrement(&This->ref);
265 TRACE("(%p)->(%ld)\n", This, ref);
266 return ref;
269 static ULONG WINAPI dismanager_Release(IDispenserManager *iface)
271 dispensermanager *This = impl_from_IDispenserManager(iface);
272 ULONG ref = InterlockedDecrement(&This->ref);
273 TRACE("(%p)->(%ld)\n", This, ref);
275 if (!ref)
277 if (This->mta_cookie)
278 CoDecrementMTAUsage(This->mta_cookie);
279 free(This);
282 return ref;
285 static HRESULT WINAPI dismanager_RegisterDispenser(IDispenserManager *iface, IDispenserDriver *driver,
286 LPCOLESTR name, IHolder **dispenser)
288 dispensermanager *This = impl_from_IDispenserManager(iface);
289 HRESULT hr;
291 TRACE("(%p)->(%p, %s, %p)\n", This, driver, debugstr_w(name), dispenser);
293 if(!dispenser)
294 return E_INVALIDARG;
296 hr = create_holder(driver, dispenser);
298 if (!This->mta_cookie)
299 CoIncrementMTAUsage(&This->mta_cookie);
301 TRACE("<-- 0x%08lx, %p\n", hr, *dispenser);
303 return hr;
306 static HRESULT WINAPI dismanager_GetContext(IDispenserManager *iface, INSTID *id, TRANSID *transid)
308 dispensermanager *This = impl_from_IDispenserManager(iface);
310 FIXME("(%p)->(%p, %p) stub\n", This, id, transid);
312 return E_NOTIMPL;
315 struct IDispenserManagerVtbl dismanager_vtbl =
317 dismanager_QueryInterface,
318 dismanager_AddRef,
319 dismanager_Release,
320 dismanager_RegisterDispenser,
321 dismanager_GetContext
324 static HRESULT WINAPI dispenser_manager_cf_CreateInstance(IClassFactory *iface, IUnknown* outer, REFIID riid,
325 void **object)
327 dispensermanager *dismanager;
328 HRESULT ret;
330 TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), object);
332 dismanager = calloc(1, sizeof(*dismanager));
333 if (!dismanager)
335 *object = NULL;
336 return E_OUTOFMEMORY;
339 dismanager->IDispenserManager_iface.lpVtbl = &dismanager_vtbl;
340 dismanager->ref = 1;
342 ret = dismanager_QueryInterface(&dismanager->IDispenserManager_iface, riid, object);
343 dismanager_Release(&dismanager->IDispenserManager_iface);
345 return ret;
348 static HRESULT WINAPI comsvcscf_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv )
350 *ppv = NULL;
352 if(IsEqualGUID(&IID_IUnknown, riid)) {
353 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
354 *ppv = iface;
355 }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
356 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
357 *ppv = iface;
360 if(*ppv) {
361 IUnknown_AddRef((IUnknown*)*ppv);
362 return S_OK;
365 WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
366 return E_NOINTERFACE;
369 static ULONG WINAPI comsvcscf_AddRef(IClassFactory *iface )
371 TRACE("(%p)\n", iface);
372 return 2;
375 static ULONG WINAPI comsvcscf_Release(IClassFactory *iface )
377 TRACE("(%p)\n", iface);
378 return 1;
381 static HRESULT WINAPI comsvcscf_LockServer(IClassFactory *iface, BOOL fLock)
383 TRACE("(%p)->(%x)\n", iface, fLock);
384 return S_OK;
387 static const IClassFactoryVtbl comsvcscf_vtbl =
389 comsvcscf_QueryInterface,
390 comsvcscf_AddRef,
391 comsvcscf_Release,
392 dispenser_manager_cf_CreateInstance,
393 comsvcscf_LockServer
396 static HRESULT WINAPI new_moniker_QueryInterface(IMoniker* iface, REFIID riid, void **obj)
398 struct new_moniker *moniker = impl_from_IMoniker(iface);
400 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
402 *obj = NULL;
404 if (IsEqualIID(&IID_IUnknown, riid) ||
405 IsEqualIID(&IID_IPersist, riid) ||
406 IsEqualIID(&IID_IPersistStream, riid) ||
407 IsEqualIID(&IID_IMoniker, riid))
409 *obj = iface;
411 else if (IsEqualIID(&IID_IROTData, riid))
413 *obj = &moniker->IROTData_iface;
416 if (*obj)
418 IUnknown_AddRef((IUnknown *)*obj);
419 return S_OK;
422 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
423 return E_NOINTERFACE;
426 static ULONG WINAPI new_moniker_AddRef(IMoniker* iface)
428 struct new_moniker *moniker = impl_from_IMoniker(iface);
429 ULONG refcount = InterlockedIncrement(&moniker->refcount);
431 TRACE("%p, refcount %lu.\n", iface, refcount);
433 return refcount;
436 static ULONG WINAPI new_moniker_Release(IMoniker* iface)
438 struct new_moniker *moniker = impl_from_IMoniker(iface);
439 ULONG refcount = InterlockedDecrement(&moniker->refcount);
441 TRACE("%p, refcount %lu.\n", iface, refcount);
443 if (!refcount)
445 free(moniker->progid);
446 free(moniker);
449 return refcount;
452 static HRESULT WINAPI new_moniker_GetClassID(IMoniker *iface, CLSID *clsid)
454 TRACE("%p, %p.\n", iface, clsid);
456 if (!clsid)
457 return E_POINTER;
459 *clsid = CLSID_NewMoniker;
461 return S_OK;
464 static HRESULT WINAPI new_moniker_IsDirty(IMoniker* iface)
466 TRACE("%p.\n", iface);
468 return S_FALSE;
471 static HRESULT WINAPI new_moniker_Load(IMoniker *iface, IStream *stream)
473 struct new_moniker *moniker = impl_from_IMoniker(iface);
474 DWORD progid_len = 0, len, pad = ~0u;
475 WCHAR *progid = NULL;
476 CLSID clsid;
477 HRESULT hr;
479 TRACE("%p, %p.\n", iface, stream);
481 hr = IStream_Read(stream, &clsid, sizeof(clsid), &len);
482 if (FAILED(hr))
483 return hr;
485 if (SUCCEEDED(hr))
486 hr = IStream_Read(stream, &progid_len, sizeof(progid_len), &len);
488 if (SUCCEEDED(hr) && progid_len)
490 if (!(progid = malloc(progid_len)))
491 return E_OUTOFMEMORY;
492 hr = IStream_Read(stream, progid, progid_len, &len);
495 /* Skip terminator. */
496 if (SUCCEEDED(hr))
497 hr = IStream_Read(stream, &pad, sizeof(pad), &len);
499 if (SUCCEEDED(hr) && pad == 0)
501 moniker->clsid = clsid;
502 free(moniker->progid);
503 moniker->progid = progid;
504 progid = NULL;
507 free(progid);
509 return hr;
512 static HRESULT WINAPI new_moniker_Save(IMoniker *iface, IStream *stream, BOOL clear_dirty)
514 struct new_moniker *moniker = impl_from_IMoniker(iface);
515 ULONG written, pad = 0, progid_len = 0;
516 HRESULT hr;
518 TRACE("%p, %p, %d.\n", iface, stream, clear_dirty);
520 if (moniker->progid)
521 progid_len = lstrlenW(moniker->progid) * sizeof(WCHAR);
523 hr = IStream_Write(stream, &moniker->clsid, sizeof(moniker->clsid), &written);
524 if (SUCCEEDED(hr))
525 hr = IStream_Write(stream, &progid_len, sizeof(progid_len), &written);
526 if (SUCCEEDED(hr) && progid_len)
527 hr = IStream_Write(stream, moniker->progid, progid_len, &written);
528 if (SUCCEEDED(hr))
529 hr = IStream_Write(stream, &pad, sizeof(pad), &written);
531 return hr;
534 static HRESULT WINAPI new_moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *size)
536 struct new_moniker *moniker = impl_from_IMoniker(iface);
538 TRACE("%p, %p.\n", iface, size);
540 if (!size)
541 return E_POINTER;
543 size->QuadPart = sizeof(CLSID) + 2 * sizeof(DWORD);
544 if (moniker->progid)
545 size->QuadPart += lstrlenW(moniker->progid) * sizeof(WCHAR);
547 return S_OK;
550 static HRESULT WINAPI new_moniker_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
551 REFIID riid, void **ret)
553 struct new_moniker *moniker = impl_from_IMoniker(iface);
554 IClassActivator *activator;
555 IClassFactory *factory;
556 BIND_OPTS2 bindopts;
557 MULTI_QI qi;
558 HRESULT hr;
560 TRACE("%p, %p, %p, %s, %p.\n", iface, pbc, pmkToLeft, debugstr_guid(riid), ret);
562 bindopts.cbStruct = sizeof(bindopts);
563 if (FAILED(hr = IBindCtx_GetBindOptions(pbc, (BIND_OPTS *)&bindopts)))
564 return hr;
566 if (!pmkToLeft)
568 qi.pIID = riid;
569 qi.pItf = NULL;
570 qi.hr = S_OK;
571 hr = CoCreateInstanceEx(&moniker->clsid, NULL, bindopts.dwClassContext, bindopts.pServerInfo, 1, &qi);
572 *ret = qi.pItf;
574 else
576 if (SUCCEEDED(hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassActivator, (void **)&activator)))
578 hr = IClassActivator_GetClassObject(activator, &moniker->clsid, bindopts.dwClassContext, bindopts.locale, riid, ret);
579 IClassActivator_Release(activator);
581 else if (SUCCEEDED(hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassFactory, (void **)&factory)))
583 hr = IClassFactory_CreateInstance(factory, NULL, riid, ret);
584 IClassFactory_Release(factory);
588 return hr;
591 static HRESULT WINAPI new_moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid,
592 void **ret)
594 FIXME("%p, %p, %p, %s, %p.\n", iface, pbc, pmkToLeft, debugstr_guid(riid), ret);
596 return E_NOTIMPL;
599 static HRESULT WINAPI new_moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD flags, IMoniker **ppmkToLeft,
600 IMoniker **ret)
602 TRACE("%p, %p, %ld, %p, %p.\n", iface, pbc, flags, ppmkToLeft, ret);
604 if (!ret)
605 return E_POINTER;
607 *ret = iface;
608 IMoniker_AddRef(iface);
610 return MK_S_REDUCED_TO_SELF;
613 static HRESULT WINAPI new_moniker_ComposeWith(IMoniker *iface, IMoniker *mkRight, BOOL fOnlyIfNotGeneric,
614 IMoniker **ret)
616 FIXME("%p, %p, %d, %p.\n", iface, mkRight, fOnlyIfNotGeneric, ret);
618 return E_NOTIMPL;
621 static HRESULT WINAPI new_moniker_Enum(IMoniker *iface, BOOL forward, IEnumMoniker **enum_moniker)
623 TRACE("%p, %d, %p.\n", iface, forward, enum_moniker);
625 if (!enum_moniker)
626 return E_POINTER;
628 *enum_moniker = NULL;
630 return S_OK;
633 static HRESULT WINAPI new_moniker_IsEqual(IMoniker *iface, IMoniker *other_moniker)
635 FIXME("%p, %p.\n", iface, other_moniker);
637 return E_NOTIMPL;
640 static HRESULT WINAPI new_moniker_Hash(IMoniker *iface, DWORD *hash)
642 struct new_moniker *moniker = impl_from_IMoniker(iface);
644 TRACE("%p, %p.\n", iface, hash);
646 *hash = moniker->clsid.Data1;
648 return S_OK;
651 static HRESULT WINAPI new_moniker_IsRunning(IMoniker* iface, IBindCtx *pbc, IMoniker *pmkToLeft,
652 IMoniker *pmkNewlyRunning)
654 FIXME("%p, %p, %p, %p.\n", iface, pbc, pmkToLeft, pmkNewlyRunning);
656 return E_NOTIMPL;
659 static HRESULT WINAPI new_moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
660 FILETIME *itemtime)
662 TRACE("%p, %p, %p, %p.\n", iface, pbc, pmkToLeft, itemtime);
664 return MK_E_UNAVAILABLE;
667 static HRESULT WINAPI new_moniker_Inverse(IMoniker *iface, IMoniker **inverse)
669 TRACE("%p, %p.\n", iface, inverse);
671 return CreateAntiMoniker(inverse);
674 static HRESULT WINAPI new_moniker_CommonPrefixWith(IMoniker *iface, IMoniker *other, IMoniker **ret)
676 FIXME("%p, %p, %p.\n", iface, other, ret);
678 return E_NOTIMPL;
681 static HRESULT WINAPI new_moniker_RelativePathTo(IMoniker *iface, IMoniker *other, IMoniker **ret)
683 FIXME("%p, %p, %p.\n", iface, other, ret);
685 return E_NOTIMPL;
688 static HRESULT WINAPI new_moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
689 LPOLESTR *name)
691 FIXME("%p, %p, %p, %p.\n", iface, pbc, pmkToLeft, name);
693 return E_NOTIMPL;
696 static HRESULT WINAPI new_moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
697 LPOLESTR name, ULONG *eaten, IMoniker **ret)
699 TRACE("%p, %p, %p, %s, %p, %p.\n", iface, pbc, pmkToLeft, debugstr_w(name), eaten, ret);
701 return new_moniker_parse_displayname(pbc, name, eaten, ret);
704 static HRESULT WINAPI new_moniker_IsSystemMoniker(IMoniker *iface, DWORD *moniker_type)
706 TRACE("%p, %p.\n", iface, moniker_type);
708 *moniker_type = MKSYS_NONE;
710 return S_FALSE;
713 static const IMonikerVtbl new_moniker_vtbl =
715 new_moniker_QueryInterface,
716 new_moniker_AddRef,
717 new_moniker_Release,
718 new_moniker_GetClassID,
719 new_moniker_IsDirty,
720 new_moniker_Load,
721 new_moniker_Save,
722 new_moniker_GetSizeMax,
723 new_moniker_BindToObject,
724 new_moniker_BindToStorage,
725 new_moniker_Reduce,
726 new_moniker_ComposeWith,
727 new_moniker_Enum,
728 new_moniker_IsEqual,
729 new_moniker_Hash,
730 new_moniker_IsRunning,
731 new_moniker_GetTimeOfLastChange,
732 new_moniker_Inverse,
733 new_moniker_CommonPrefixWith,
734 new_moniker_RelativePathTo,
735 new_moniker_GetDisplayName,
736 new_moniker_ParseDisplayName,
737 new_moniker_IsSystemMoniker
740 static HRESULT WINAPI new_moniker_rotdata_QueryInterface(IROTData *iface, REFIID riid, void **obj)
742 struct new_moniker *moniker = impl_from_IROTData(iface);
743 return IMoniker_QueryInterface(&moniker->IMoniker_iface, riid, obj);
746 static ULONG WINAPI new_moniker_rotdata_AddRef(IROTData *iface)
748 struct new_moniker *moniker = impl_from_IROTData(iface);
749 return IMoniker_AddRef(&moniker->IMoniker_iface);
752 static ULONG WINAPI new_moniker_rotdata_Release(IROTData *iface)
754 struct new_moniker *moniker = impl_from_IROTData(iface);
755 return IMoniker_Release(&moniker->IMoniker_iface);
758 static HRESULT WINAPI new_moniker_rotdata_GetComparisonData(IROTData *iface, byte *data, ULONG data_len, ULONG *length)
760 FIXME("%p, %p, %lu, %p.\n", iface, data, data_len, length);
762 return E_NOTIMPL;
765 static const IROTDataVtbl new_moniker_rotdata_vtbl =
767 new_moniker_rotdata_QueryInterface,
768 new_moniker_rotdata_AddRef,
769 new_moniker_rotdata_Release,
770 new_moniker_rotdata_GetComparisonData,
773 static const BYTE guid_conv_table[256] =
775 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
776 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
777 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
778 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
779 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
780 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
781 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */
784 static BOOL is_valid_hex(WCHAR c)
786 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
787 (c >= 'A' && c <= 'F');
790 static HRESULT guid_from_string(const WCHAR *s, GUID *ret)
792 BOOL has_brackets;
793 GUID guid = { 0 };
794 int i;
796 memset(ret, 0, sizeof(*ret));
798 /* Curly brackets are optional. */
799 has_brackets = s[0] == '{';
801 if (has_brackets)
802 s++;
804 for (i = 0; i < 8; i++)
806 if (!is_valid_hex(s[i])) return FALSE;
807 guid.Data1 = (guid.Data1 << 4) | guid_conv_table[s[i]];
809 s += 8;
811 if (s[0] != '-') return FALSE;
812 s++;
814 for (i = 0; i < 4; i++)
816 if (!is_valid_hex(s[0])) return FALSE;
817 guid.Data2 = (guid.Data2 << 4) | guid_conv_table[s[i]];
819 s += 4;
821 if (s[0] != '-') return FALSE;
822 s++;
824 for (i = 0; i < 4; i++)
826 if (!is_valid_hex(s[i])) return FALSE;
827 guid.Data3 = (guid.Data3 << 4) | guid_conv_table[s[i]];
829 s += 4;
831 if (s[0] != '-') return FALSE;
832 s++;
834 for (i = 0; i < 17; i += 2)
836 if (i == 4)
838 if (s[i] != '-') return FALSE;
839 i++;
841 if (!is_valid_hex(s[i]) || !is_valid_hex(s[i+1])) return FALSE;
842 guid.Data4[i / 2] = guid_conv_table[s[i]] << 4 | guid_conv_table[s[i+1]];
844 s += 17;
846 if (has_brackets && s[0] != '}')
847 return FALSE;
849 *ret = guid;
851 return TRUE;
854 static HRESULT new_moniker_parse_displayname(IBindCtx *pbc, LPOLESTR name, ULONG *eaten, IMoniker **ret)
856 struct new_moniker *moniker;
857 WCHAR *progid = NULL, *str;
858 GUID guid;
860 *ret = NULL;
862 if (wcsnicmp(name, L"new:", 4))
863 return MK_E_SYNTAX;
864 str = name + 4;
866 if (!guid_from_string(str, &guid))
868 if (FAILED(CLSIDFromProgID(str, &guid)))
869 return MK_E_SYNTAX;
870 progid = str;
873 moniker = calloc(1, sizeof(*moniker));
874 if (!moniker)
875 return E_OUTOFMEMORY;
877 moniker->IMoniker_iface.lpVtbl = &new_moniker_vtbl;
878 moniker->IROTData_iface.lpVtbl = &new_moniker_rotdata_vtbl;
879 moniker->refcount = 1;
880 moniker->clsid = guid;
881 if (progid)
883 if (!(moniker->progid = wcsdup(progid)))
885 IMoniker_Release(&moniker->IMoniker_iface);
886 return E_OUTOFMEMORY;
890 *ret = &moniker->IMoniker_iface;
892 if (eaten)
893 *eaten = lstrlenW(name);
895 return S_OK;
898 static HRESULT WINAPI new_moniker_parse_QueryInterface(IParseDisplayName *iface, REFIID riid, void **obj)
900 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
902 if (IsEqualIID(riid, &IID_IParseDisplayName) ||
903 IsEqualIID(riid, &IID_IUnknown))
905 *obj = iface;
906 IParseDisplayName_AddRef(iface);
907 return S_OK;
910 *obj = NULL;
911 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
912 return E_NOINTERFACE;
915 static ULONG WINAPI new_moniker_parse_AddRef(IParseDisplayName *iface)
917 return 2;
920 static ULONG WINAPI new_moniker_parse_Release(IParseDisplayName *iface)
922 return 1;
925 static HRESULT WINAPI new_moniker_parse_ParseDisplayName(IParseDisplayName *iface, IBindCtx *pbc, LPOLESTR name,
926 ULONG *eaten, IMoniker **ret)
928 TRACE("%p, %p, %s, %p, %p.\n", iface, pbc, debugstr_w(name), eaten, ret);
930 return new_moniker_parse_displayname(pbc, name, eaten, ret);
933 static const IParseDisplayNameVtbl new_moniker_parse_vtbl =
935 new_moniker_parse_QueryInterface,
936 new_moniker_parse_AddRef,
937 new_moniker_parse_Release,
938 new_moniker_parse_ParseDisplayName,
941 static IParseDisplayName new_moniker_parse = { &new_moniker_parse_vtbl };
943 static HRESULT WINAPI new_moniker_cf_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
945 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
947 *obj = NULL;
949 if (IsEqualGUID(&IID_IUnknown, riid) ||
950 IsEqualGUID(&IID_IClassFactory, riid))
952 *obj = iface;
954 else if (IsEqualIID(&IID_IParseDisplayName, riid))
956 *obj = &new_moniker_parse;
959 if (*obj)
961 IUnknown_AddRef((IUnknown *)*obj);
962 return S_OK;
965 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
966 return E_NOINTERFACE;
969 static HRESULT WINAPI new_moniker_cf_CreateInstance(IClassFactory *iface, IUnknown* outer, REFIID riid, void **object)
971 TRACE("%p, %p, %s, %p.\n", iface, outer, debugstr_guid(riid), object);
973 if (outer)
974 FIXME("Aggregation is not supported.\n");
976 return IParseDisplayName_QueryInterface(&new_moniker_parse, riid, object);
979 static const IClassFactoryVtbl newmoniker_cf_vtbl =
981 new_moniker_cf_QueryInterface,
982 comsvcscf_AddRef,
983 comsvcscf_Release,
984 new_moniker_cf_CreateInstance,
985 comsvcscf_LockServer
988 static const IClassFactoryVtbl group_manager_cf_vtbl =
990 comsvcscf_QueryInterface,
991 comsvcscf_AddRef,
992 comsvcscf_Release,
993 group_manager_create,
994 comsvcscf_LockServer
997 static IClassFactory DispenserManageFactory = { &comsvcscf_vtbl };
998 static IClassFactory NewMonikerFactory = { &newmoniker_cf_vtbl };
999 static IClassFactory GroupManagerFactory = { &group_manager_cf_vtbl };
1001 /******************************************************************
1002 * DllGetClassObject
1004 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
1006 if(IsEqualGUID(&CLSID_DispenserManager, rclsid))
1008 TRACE("(CLSID_DispenserManager %s %p)\n", debugstr_guid(riid), ppv);
1009 return IClassFactory_QueryInterface(&DispenserManageFactory, riid, ppv);
1011 else if (IsEqualGUID(&CLSID_NewMoniker, rclsid))
1013 TRACE("(CLSID_NewMoniker %s %p)\n", debugstr_guid(riid), ppv);
1014 return IClassFactory_QueryInterface(&NewMonikerFactory, riid, ppv);
1016 else if (IsEqualGUID(&CLSID_SharedPropertyGroupManager, rclsid))
1018 TRACE("(CLSID_SharedPropertyGroupManager %s %p)\n", debugstr_guid(riid), ppv);
1019 return IClassFactory_QueryInterface(&GroupManagerFactory, riid, ppv);
1022 FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1023 return CLASS_E_CLASSNOTAVAILABLE;