crypt32: Implement CryptBinaryToStringW(HEXRAW).
[wine.git] / dlls / comsvcs / main.c
blob9ab77dfceda21281ae0d90375bb4d85781aa3637
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 IROTData IROTData_iface;
58 LONG refcount;
59 CLSID clsid;
60 WCHAR *progid;
63 static HRESULT new_moniker_parse_displayname(IBindCtx *pbc, LPOLESTR name, ULONG *eaten, IMoniker **ret);
65 static inline dispensermanager *impl_from_IDispenserManager(IDispenserManager *iface)
67 return CONTAINING_RECORD(iface, dispensermanager, IDispenserManager_iface);
70 static inline holder *impl_from_IHolder(IHolder *iface)
72 return CONTAINING_RECORD(iface, holder, IHolder_iface);
75 static struct new_moniker *impl_from_IMoniker(IMoniker *iface)
77 return CONTAINING_RECORD(iface, struct new_moniker, IMoniker_iface);
80 static struct new_moniker *impl_from_IROTData(IROTData *iface)
82 return CONTAINING_RECORD(iface, struct new_moniker, IROTData_iface);
85 static HRESULT WINAPI holder_QueryInterface(IHolder *iface, REFIID riid, void **object)
87 holder *This = impl_from_IHolder(iface);
89 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), object);
91 *object = NULL;
93 if (IsEqualGUID(riid, &IID_IUnknown) ||
94 IsEqualGUID(riid, &IID_IHolder))
96 *object = &This->IHolder_iface;
97 IUnknown_AddRef( (IUnknown*)*object);
99 return S_OK;
102 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),object);
103 return E_NOINTERFACE;
106 static ULONG WINAPI holder_AddRef(IHolder *iface)
108 holder *This = impl_from_IHolder(iface);
109 ULONG ref = InterlockedIncrement(&This->ref);
110 TRACE("(%p)->(%d)\n", This, ref);
111 return ref;
114 static ULONG WINAPI holder_Release(IHolder *iface)
116 holder *This = impl_from_IHolder(iface);
117 ULONG ref = InterlockedDecrement(&This->ref);
118 TRACE("(%p)->(%d)\n", This, ref);
120 if (!ref)
122 heap_free(This);
125 return ref;
128 static HRESULT WINAPI holder_AllocResource(IHolder *iface, const RESTYPID typeid, RESID *resid)
130 holder *This = impl_from_IHolder(iface);
131 HRESULT hr;
132 TIMEINSECS secs;
134 TRACE("(%p)->(%08lx, %p) stub\n", This, typeid, resid);
136 hr = IDispenserDriver_CreateResource(This->driver, typeid, resid, &secs);
138 TRACE("<- 0x%08x\n", hr);
139 return hr;
142 static HRESULT WINAPI holder_FreeResource(IHolder *iface, const RESID resid)
144 holder *This = impl_from_IHolder(iface);
145 HRESULT hr;
147 TRACE("(%p)->(%08lx) stub\n", This, resid);
149 hr = IDispenserDriver_DestroyResource(This->driver, resid);
151 TRACE("<- 0x%08x\n", hr);
153 return hr;
156 static HRESULT WINAPI holder_TrackResource(IHolder *iface, const RESID resid)
158 holder *This = impl_from_IHolder(iface);
160 FIXME("(%p)->(%08lx) stub\n", This, resid);
162 return E_NOTIMPL;
165 static HRESULT WINAPI holder_TrackResourceS(IHolder *iface, const SRESID resid)
167 holder *This = impl_from_IHolder(iface);
169 FIXME("(%p)->(%s) stub\n", This, debugstr_w(resid));
171 return E_NOTIMPL;
174 static HRESULT WINAPI holder_UntrackResource(IHolder *iface, const RESID resid, const BOOL value)
176 holder *This = impl_from_IHolder(iface);
178 FIXME("(%p)->(%08lx, %d) stub\n", This, resid, value);
180 return E_NOTIMPL;
183 static HRESULT WINAPI holder_UntrackResourceS(IHolder *iface, const SRESID resid, const BOOL value)
185 holder *This = impl_from_IHolder(iface);
187 FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(resid), value);
189 return E_NOTIMPL;
192 static HRESULT WINAPI holder_Close(IHolder *iface)
194 holder *This = impl_from_IHolder(iface);
196 FIXME("(%p) stub\n", This);
198 IDispenserDriver_Release(This->driver);
200 return S_OK;
203 static HRESULT WINAPI holder_RequestDestroyResource(IHolder *iface, const RESID resid)
205 holder *This = impl_from_IHolder(iface);
207 FIXME("(%p)->(%08lx) stub\n", This, resid);
209 return E_NOTIMPL;
212 struct IHolderVtbl holder_vtbl =
214 holder_QueryInterface,
215 holder_AddRef,
216 holder_Release,
217 holder_AllocResource,
218 holder_FreeResource,
219 holder_TrackResource,
220 holder_TrackResourceS,
221 holder_UntrackResource,
222 holder_UntrackResourceS,
223 holder_Close,
224 holder_RequestDestroyResource
227 static HRESULT create_holder(IDispenserDriver *driver, IHolder **object)
229 holder *hold;
230 HRESULT ret;
232 TRACE("(%p)\n", object);
234 hold = heap_alloc(sizeof(*hold));
235 if (!hold)
237 *object = NULL;
238 return E_OUTOFMEMORY;
241 hold->IHolder_iface.lpVtbl = &holder_vtbl;
242 hold->ref = 1;
243 hold->driver = driver;
245 ret = holder_QueryInterface(&hold->IHolder_iface, &IID_IHolder, (void**)object);
246 holder_Release(&hold->IHolder_iface);
248 return ret;
251 static HRESULT WINAPI dismanager_QueryInterface(IDispenserManager *iface, REFIID riid, void **object)
253 dispensermanager *This = impl_from_IDispenserManager(iface);
255 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), object);
257 *object = NULL;
259 if (IsEqualGUID(riid, &IID_IUnknown) ||
260 IsEqualGUID(riid, &IID_IDispenserManager))
262 *object = &This->IDispenserManager_iface;
263 IUnknown_AddRef( (IUnknown*)*object);
265 return S_OK;
268 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),object);
269 return E_NOINTERFACE;
272 static ULONG WINAPI dismanager_AddRef(IDispenserManager *iface)
274 dispensermanager *This = impl_from_IDispenserManager(iface);
275 ULONG ref = InterlockedIncrement(&This->ref);
276 TRACE("(%p)->(%d)\n", This, ref);
277 return ref;
280 static ULONG WINAPI dismanager_Release(IDispenserManager *iface)
282 dispensermanager *This = impl_from_IDispenserManager(iface);
283 ULONG ref = InterlockedDecrement(&This->ref);
284 TRACE("(%p)->(%d)\n", This, ref);
286 if (!ref)
288 if (This->mta_thread)
290 SetEvent(This->mta_stop_event);
291 WaitForSingleObject(This->mta_thread, INFINITE);
292 CloseHandle(This->mta_stop_event);
293 CloseHandle(This->mta_thread);
295 heap_free(This);
298 return ref;
301 static DWORD WINAPI mta_thread_proc(void *arg)
303 CoInitializeEx(NULL, COINIT_MULTITHREADED);
304 WaitForSingleObject(arg, INFINITE);
305 CoUninitialize();
306 return 0;
309 static HRESULT WINAPI dismanager_RegisterDispenser(IDispenserManager *iface, IDispenserDriver *driver,
310 LPCOLESTR name, IHolder **dispenser)
312 dispensermanager *This = impl_from_IDispenserManager(iface);
313 HRESULT hr;
315 TRACE("(%p)->(%p, %s, %p)\n", This, driver, debugstr_w(name), dispenser);
317 if(!dispenser)
318 return E_INVALIDARG;
320 hr = create_holder(driver, dispenser);
322 if (!This->mta_thread)
324 This->mta_stop_event = CreateEventA(NULL, TRUE, FALSE, NULL);
325 This->mta_thread = CreateThread(NULL, 0, mta_thread_proc, This->mta_stop_event, 0, NULL);
328 TRACE("<-- 0x%08x, %p\n", hr, *dispenser);
330 return hr;
333 static HRESULT WINAPI dismanager_GetContext(IDispenserManager *iface, INSTID *id, TRANSID *transid)
335 dispensermanager *This = impl_from_IDispenserManager(iface);
337 FIXME("(%p)->(%p, %p) stub\n", This, id, transid);
339 return E_NOTIMPL;
342 struct IDispenserManagerVtbl dismanager_vtbl =
344 dismanager_QueryInterface,
345 dismanager_AddRef,
346 dismanager_Release,
347 dismanager_RegisterDispenser,
348 dismanager_GetContext
351 static HRESULT WINAPI dispenser_manager_cf_CreateInstance(IClassFactory *iface, IUnknown* outer, REFIID riid,
352 void **object)
354 dispensermanager *dismanager;
355 HRESULT ret;
357 TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), object);
359 dismanager = heap_alloc_zero(sizeof(*dismanager));
360 if (!dismanager)
362 *object = NULL;
363 return E_OUTOFMEMORY;
366 dismanager->IDispenserManager_iface.lpVtbl = &dismanager_vtbl;
367 dismanager->ref = 1;
369 ret = dismanager_QueryInterface(&dismanager->IDispenserManager_iface, riid, object);
370 dismanager_Release(&dismanager->IDispenserManager_iface);
372 return ret;
375 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID lpv)
377 switch(reason)
379 case DLL_WINE_PREATTACH:
380 return FALSE; /* prefer native version */
381 case DLL_PROCESS_ATTACH:
382 COMSVCS_hInstance = hinst;
383 DisableThreadLibraryCalls(hinst);
384 break;
386 return TRUE;
389 static HRESULT WINAPI comsvcscf_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv )
391 *ppv = NULL;
393 if(IsEqualGUID(&IID_IUnknown, riid)) {
394 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
395 *ppv = iface;
396 }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
397 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
398 *ppv = iface;
401 if(*ppv) {
402 IUnknown_AddRef((IUnknown*)*ppv);
403 return S_OK;
406 WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
407 return E_NOINTERFACE;
410 static ULONG WINAPI comsvcscf_AddRef(IClassFactory *iface )
412 TRACE("(%p)\n", iface);
413 return 2;
416 static ULONG WINAPI comsvcscf_Release(IClassFactory *iface )
418 TRACE("(%p)\n", iface);
419 return 1;
422 static HRESULT WINAPI comsvcscf_LockServer(IClassFactory *iface, BOOL fLock)
424 TRACE("(%p)->(%x)\n", iface, fLock);
425 return S_OK;
428 static const IClassFactoryVtbl comsvcscf_vtbl =
430 comsvcscf_QueryInterface,
431 comsvcscf_AddRef,
432 comsvcscf_Release,
433 dispenser_manager_cf_CreateInstance,
434 comsvcscf_LockServer
437 static HRESULT WINAPI new_moniker_QueryInterface(IMoniker* iface, REFIID riid, void **obj)
439 struct new_moniker *moniker = impl_from_IMoniker(iface);
441 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
443 *obj = NULL;
445 if (IsEqualIID(&IID_IUnknown, riid) ||
446 IsEqualIID(&IID_IPersist, riid) ||
447 IsEqualIID(&IID_IPersistStream, riid) ||
448 IsEqualIID(&IID_IMoniker, riid))
450 *obj = iface;
452 else if (IsEqualIID(&IID_IROTData, riid))
454 *obj = &moniker->IROTData_iface;
457 if (*obj)
459 IUnknown_AddRef((IUnknown *)*obj);
460 return S_OK;
463 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
464 return E_NOINTERFACE;
467 static ULONG WINAPI new_moniker_AddRef(IMoniker* iface)
469 struct new_moniker *moniker = impl_from_IMoniker(iface);
470 ULONG refcount = InterlockedIncrement(&moniker->refcount);
472 TRACE("%p, refcount %u.\n", iface, refcount);
474 return refcount;
477 static ULONG WINAPI new_moniker_Release(IMoniker* iface)
479 struct new_moniker *moniker = impl_from_IMoniker(iface);
480 ULONG refcount = InterlockedDecrement(&moniker->refcount);
482 TRACE("%p, refcount %u.\n", iface, refcount);
484 if (!refcount)
486 heap_free(moniker->progid);
487 heap_free(moniker);
490 return refcount;
493 static HRESULT WINAPI new_moniker_GetClassID(IMoniker *iface, CLSID *clsid)
495 TRACE("%p, %p.\n", iface, clsid);
497 if (!clsid)
498 return E_POINTER;
500 *clsid = CLSID_NewMoniker;
502 return S_OK;
505 static HRESULT WINAPI new_moniker_IsDirty(IMoniker* iface)
507 TRACE("%p.\n", iface);
509 return S_FALSE;
512 static HRESULT WINAPI new_moniker_Load(IMoniker *iface, IStream *stream)
514 struct new_moniker *moniker = impl_from_IMoniker(iface);
515 DWORD progid_len = 0, len, pad = ~0u;
516 WCHAR *progid = NULL;
517 CLSID clsid;
518 HRESULT hr;
520 TRACE("%p, %p.\n", iface, stream);
522 hr = IStream_Read(stream, &clsid, sizeof(clsid), &len);
523 if (FAILED(hr))
524 return hr;
526 if (SUCCEEDED(hr))
527 hr = IStream_Read(stream, &progid_len, sizeof(progid_len), &len);
529 if (SUCCEEDED(hr) && progid_len)
531 if (!(progid = heap_alloc(progid_len)))
532 return E_OUTOFMEMORY;
533 hr = IStream_Read(stream, progid, progid_len, &len);
536 /* Skip terminator. */
537 if (SUCCEEDED(hr))
538 hr = IStream_Read(stream, &pad, sizeof(pad), &len);
540 if (SUCCEEDED(hr) && pad == 0)
542 moniker->clsid = clsid;
543 heap_free(moniker->progid);
544 moniker->progid = progid;
545 progid = NULL;
548 heap_free(progid);
550 return hr;
553 static HRESULT WINAPI new_moniker_Save(IMoniker *iface, IStream *stream, BOOL clear_dirty)
555 struct new_moniker *moniker = impl_from_IMoniker(iface);
556 ULONG written, pad = 0, progid_len = 0;
557 HRESULT hr;
559 TRACE("%p, %p, %d.\n", iface, stream, clear_dirty);
561 if (moniker->progid)
562 progid_len = lstrlenW(moniker->progid) * sizeof(WCHAR);
564 hr = IStream_Write(stream, &moniker->clsid, sizeof(moniker->clsid), &written);
565 if (SUCCEEDED(hr))
566 hr = IStream_Write(stream, &progid_len, sizeof(progid_len), &written);
567 if (SUCCEEDED(hr) && progid_len)
568 hr = IStream_Write(stream, moniker->progid, progid_len, &written);
569 if (SUCCEEDED(hr))
570 hr = IStream_Write(stream, &pad, sizeof(pad), &written);
572 return hr;
575 static HRESULT WINAPI new_moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *size)
577 struct new_moniker *moniker = impl_from_IMoniker(iface);
579 TRACE("%p, %p.\n", iface, size);
581 if (!size)
582 return E_POINTER;
584 size->QuadPart = sizeof(CLSID) + 2 * sizeof(DWORD);
585 if (moniker->progid)
586 size->QuadPart += lstrlenW(moniker->progid) * sizeof(WCHAR);
588 return S_OK;
591 static HRESULT WINAPI new_moniker_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
592 REFIID riid, void **ret)
594 struct new_moniker *moniker = impl_from_IMoniker(iface);
595 IClassActivator *activator;
596 IClassFactory *factory;
597 BIND_OPTS2 bindopts;
598 MULTI_QI qi;
599 HRESULT hr;
601 TRACE("%p, %p, %p, %s, %p.\n", iface, pbc, pmkToLeft, debugstr_guid(riid), ret);
603 bindopts.cbStruct = sizeof(bindopts);
604 if (FAILED(hr = IBindCtx_GetBindOptions(pbc, (BIND_OPTS *)&bindopts)))
605 return hr;
607 if (!pmkToLeft)
609 qi.pIID = riid;
610 qi.pItf = NULL;
611 qi.hr = S_OK;
612 hr = CoCreateInstanceEx(&moniker->clsid, NULL, bindopts.dwClassContext, bindopts.pServerInfo, 1, &qi);
613 *ret = qi.pItf;
615 else
617 if (SUCCEEDED(hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassActivator, (void **)&activator)))
619 hr = IClassActivator_GetClassObject(activator, &moniker->clsid, bindopts.dwClassContext, bindopts.locale, riid, ret);
620 IClassActivator_Release(activator);
622 else if (SUCCEEDED(hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassFactory, (void **)&factory)))
624 hr = IClassFactory_CreateInstance(factory, NULL, riid, ret);
625 IClassFactory_Release(factory);
629 return hr;
632 static HRESULT WINAPI new_moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid,
633 void **ret)
635 FIXME("%p, %p, %p, %s, %p.\n", iface, pbc, pmkToLeft, debugstr_guid(riid), ret);
637 return E_NOTIMPL;
640 static HRESULT WINAPI new_moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD flags, IMoniker **ppmkToLeft,
641 IMoniker **ret)
643 TRACE("%p, %p, %d, %p, %p.\n", iface, pbc, flags, ppmkToLeft, ret);
645 if (!ret)
646 return E_POINTER;
648 *ret = iface;
649 IMoniker_AddRef(iface);
651 return MK_S_REDUCED_TO_SELF;
654 static HRESULT WINAPI new_moniker_ComposeWith(IMoniker *iface, IMoniker *mkRight, BOOL fOnlyIfNotGeneric,
655 IMoniker **ret)
657 FIXME("%p, %p, %d, %p.\n", iface, mkRight, fOnlyIfNotGeneric, ret);
659 return E_NOTIMPL;
662 static HRESULT WINAPI new_moniker_Enum(IMoniker *iface, BOOL forward, IEnumMoniker **enum_moniker)
664 TRACE("%p, %d, %p.\n", iface, forward, enum_moniker);
666 if (!enum_moniker)
667 return E_POINTER;
669 *enum_moniker = NULL;
671 return S_OK;
674 static HRESULT WINAPI new_moniker_IsEqual(IMoniker *iface, IMoniker *other_moniker)
676 FIXME("%p, %p.\n", iface, other_moniker);
678 return E_NOTIMPL;
681 static HRESULT WINAPI new_moniker_Hash(IMoniker *iface, DWORD *hash)
683 struct new_moniker *moniker = impl_from_IMoniker(iface);
685 TRACE("%p, %p.\n", iface, hash);
687 *hash = moniker->clsid.Data1;
689 return S_OK;
692 static HRESULT WINAPI new_moniker_IsRunning(IMoniker* iface, IBindCtx *pbc, IMoniker *pmkToLeft,
693 IMoniker *pmkNewlyRunning)
695 FIXME("%p, %p, %p, %p.\n", iface, pbc, pmkToLeft, pmkNewlyRunning);
697 return E_NOTIMPL;
700 static HRESULT WINAPI new_moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
701 FILETIME *itemtime)
703 TRACE("%p, %p, %p, %p.\n", iface, pbc, pmkToLeft, itemtime);
705 return MK_E_UNAVAILABLE;
708 static HRESULT WINAPI new_moniker_Inverse(IMoniker *iface, IMoniker **inverse)
710 TRACE("%p, %p.\n", iface, inverse);
712 return CreateAntiMoniker(inverse);
715 static HRESULT WINAPI new_moniker_CommonPrefixWith(IMoniker *iface, IMoniker *other, IMoniker **ret)
717 FIXME("%p, %p, %p.\n", iface, other, ret);
719 return E_NOTIMPL;
722 static HRESULT WINAPI new_moniker_RelativePathTo(IMoniker *iface, IMoniker *other, IMoniker **ret)
724 FIXME("%p, %p, %p.\n", iface, other, ret);
726 return E_NOTIMPL;
729 static HRESULT WINAPI new_moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
730 LPOLESTR *name)
732 FIXME("%p, %p, %p, %p.\n", iface, pbc, pmkToLeft, name);
734 return E_NOTIMPL;
737 static HRESULT WINAPI new_moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
738 LPOLESTR name, ULONG *eaten, IMoniker **ret)
740 TRACE("%p, %p, %p, %s, %p, %p.\n", iface, pbc, pmkToLeft, debugstr_w(name), eaten, ret);
742 return new_moniker_parse_displayname(pbc, name, eaten, ret);
745 static HRESULT WINAPI new_moniker_IsSystemMoniker(IMoniker *iface, DWORD *moniker_type)
747 TRACE("%p, %p.\n", iface, moniker_type);
749 *moniker_type = MKSYS_NONE;
751 return S_FALSE;
754 static const IMonikerVtbl new_moniker_vtbl =
756 new_moniker_QueryInterface,
757 new_moniker_AddRef,
758 new_moniker_Release,
759 new_moniker_GetClassID,
760 new_moniker_IsDirty,
761 new_moniker_Load,
762 new_moniker_Save,
763 new_moniker_GetSizeMax,
764 new_moniker_BindToObject,
765 new_moniker_BindToStorage,
766 new_moniker_Reduce,
767 new_moniker_ComposeWith,
768 new_moniker_Enum,
769 new_moniker_IsEqual,
770 new_moniker_Hash,
771 new_moniker_IsRunning,
772 new_moniker_GetTimeOfLastChange,
773 new_moniker_Inverse,
774 new_moniker_CommonPrefixWith,
775 new_moniker_RelativePathTo,
776 new_moniker_GetDisplayName,
777 new_moniker_ParseDisplayName,
778 new_moniker_IsSystemMoniker
781 static HRESULT WINAPI new_moniker_rotdata_QueryInterface(IROTData *iface, REFIID riid, void **obj)
783 struct new_moniker *moniker = impl_from_IROTData(iface);
784 return IMoniker_QueryInterface(&moniker->IMoniker_iface, riid, obj);
787 static ULONG WINAPI new_moniker_rotdata_AddRef(IROTData *iface)
789 struct new_moniker *moniker = impl_from_IROTData(iface);
790 return IMoniker_AddRef(&moniker->IMoniker_iface);
793 static ULONG WINAPI new_moniker_rotdata_Release(IROTData *iface)
795 struct new_moniker *moniker = impl_from_IROTData(iface);
796 return IMoniker_Release(&moniker->IMoniker_iface);
799 static HRESULT WINAPI new_moniker_rotdata_GetComparisonData(IROTData *iface, byte *data, ULONG data_len, ULONG *length)
801 FIXME("%p, %p, %u, %p.\n", iface, data, data_len, length);
803 return E_NOTIMPL;
806 static const IROTDataVtbl new_moniker_rotdata_vtbl =
808 new_moniker_rotdata_QueryInterface,
809 new_moniker_rotdata_AddRef,
810 new_moniker_rotdata_Release,
811 new_moniker_rotdata_GetComparisonData,
814 static const BYTE guid_conv_table[256] =
816 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
817 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
818 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
819 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
820 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
821 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
822 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */
825 static BOOL is_valid_hex(WCHAR c)
827 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
828 (c >= 'A' && c <= 'F');
831 static HRESULT guid_from_string(const WCHAR *s, GUID *ret)
833 BOOL has_brackets;
834 GUID guid = { 0 };
835 int i;
837 memset(ret, 0, sizeof(*ret));
839 /* Curly brackets are optional. */
840 has_brackets = s[0] == '{';
842 if (has_brackets)
843 s++;
845 for (i = 0; i < 8; i++)
847 if (!is_valid_hex(s[i])) return FALSE;
848 guid.Data1 = (guid.Data1 << 4) | guid_conv_table[s[i]];
850 s += 8;
852 if (s[0] != '-') return FALSE;
853 s++;
855 for (i = 0; i < 4; i++)
857 if (!is_valid_hex(s[0])) return FALSE;
858 guid.Data2 = (guid.Data2 << 4) | guid_conv_table[s[i]];
860 s += 4;
862 if (s[0] != '-') return FALSE;
863 s++;
865 for (i = 0; i < 4; i++)
867 if (!is_valid_hex(s[i])) return FALSE;
868 guid.Data3 = (guid.Data3 << 4) | guid_conv_table[s[i]];
870 s += 4;
872 if (s[0] != '-') return FALSE;
873 s++;
875 for (i = 0; i < 17; i += 2)
877 if (i == 4)
879 if (s[i] != '-') return FALSE;
880 i++;
882 if (!is_valid_hex(s[i]) || !is_valid_hex(s[i+1])) return FALSE;
883 guid.Data4[i / 2] = guid_conv_table[s[i]] << 4 | guid_conv_table[s[i+1]];
885 s += 17;
887 if (has_brackets && s[0] != '}')
888 return FALSE;
890 *ret = guid;
892 return TRUE;
895 static HRESULT new_moniker_parse_displayname(IBindCtx *pbc, LPOLESTR name, ULONG *eaten, IMoniker **ret)
897 struct new_moniker *moniker;
898 WCHAR *progid = NULL, *str;
899 GUID guid;
901 *ret = NULL;
903 if (wcsnicmp(name, L"new:", 4))
904 return MK_E_SYNTAX;
905 str = name + 4;
907 if (!guid_from_string(str, &guid))
909 if (FAILED(CLSIDFromProgID(str, &guid)))
910 return MK_E_SYNTAX;
911 progid = str;
914 moniker = heap_alloc_zero(sizeof(*moniker));
915 if (!moniker)
916 return E_OUTOFMEMORY;
918 moniker->IMoniker_iface.lpVtbl = &new_moniker_vtbl;
919 moniker->IROTData_iface.lpVtbl = &new_moniker_rotdata_vtbl;
920 moniker->refcount = 1;
921 moniker->clsid = guid;
922 if (progid)
924 if (!(moniker->progid = heap_alloc((lstrlenW(progid) + 1) * sizeof(WCHAR))))
926 IMoniker_Release(&moniker->IMoniker_iface);
927 return E_OUTOFMEMORY;
929 lstrcpyW(moniker->progid, progid);
932 *ret = &moniker->IMoniker_iface;
934 if (eaten)
935 *eaten = lstrlenW(name);
937 return S_OK;
940 static HRESULT WINAPI new_moniker_parse_QueryInterface(IParseDisplayName *iface, REFIID riid, void **obj)
942 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
944 if (IsEqualIID(riid, &IID_IParseDisplayName) ||
945 IsEqualIID(riid, &IID_IUnknown))
947 *obj = iface;
948 IParseDisplayName_AddRef(iface);
949 return S_OK;
952 *obj = NULL;
953 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
954 return E_NOINTERFACE;
957 static ULONG WINAPI new_moniker_parse_AddRef(IParseDisplayName *iface)
959 return 2;
962 static ULONG WINAPI new_moniker_parse_Release(IParseDisplayName *iface)
964 return 1;
967 static HRESULT WINAPI new_moniker_parse_ParseDisplayName(IParseDisplayName *iface, IBindCtx *pbc, LPOLESTR name,
968 ULONG *eaten, IMoniker **ret)
970 TRACE("%p, %p, %s, %p, %p.\n", iface, pbc, debugstr_w(name), eaten, ret);
972 return new_moniker_parse_displayname(pbc, name, eaten, ret);
975 static const IParseDisplayNameVtbl new_moniker_parse_vtbl =
977 new_moniker_parse_QueryInterface,
978 new_moniker_parse_AddRef,
979 new_moniker_parse_Release,
980 new_moniker_parse_ParseDisplayName,
983 static IParseDisplayName new_moniker_parse = { &new_moniker_parse_vtbl };
985 static HRESULT WINAPI new_moniker_cf_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
987 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
989 *obj = NULL;
991 if (IsEqualGUID(&IID_IUnknown, riid) ||
992 IsEqualGUID(&IID_IClassFactory, riid))
994 *obj = iface;
996 else if (IsEqualIID(&IID_IParseDisplayName, riid))
998 *obj = &new_moniker_parse;
1001 if (*obj)
1003 IUnknown_AddRef((IUnknown *)*obj);
1004 return S_OK;
1007 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
1008 return E_NOINTERFACE;
1011 static HRESULT WINAPI new_moniker_cf_CreateInstance(IClassFactory *iface, IUnknown* outer, REFIID riid, void **object)
1013 TRACE("%p, %p, %s, %p.\n", iface, outer, debugstr_guid(riid), object);
1015 if (outer)
1016 FIXME("Aggregation is not supported.\n");
1018 return IParseDisplayName_QueryInterface(&new_moniker_parse, riid, object);
1021 static const IClassFactoryVtbl newmoniker_cf_vtbl =
1023 new_moniker_cf_QueryInterface,
1024 comsvcscf_AddRef,
1025 comsvcscf_Release,
1026 new_moniker_cf_CreateInstance,
1027 comsvcscf_LockServer
1030 static IClassFactory DispenserManageFactory = { &comsvcscf_vtbl };
1031 static IClassFactory NewMonikerFactory = { &newmoniker_cf_vtbl };
1033 /******************************************************************
1034 * DllGetClassObject
1036 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
1038 if(IsEqualGUID(&CLSID_DispenserManager, rclsid))
1040 TRACE("(CLSID_DispenserManager %s %p)\n", debugstr_guid(riid), ppv);
1041 return IClassFactory_QueryInterface(&DispenserManageFactory, riid, ppv);
1043 else if (IsEqualGUID(&CLSID_NewMoniker, rclsid))
1045 TRACE("(CLSID_NewMoniker %s %p)\n", debugstr_guid(riid), ppv);
1046 return IClassFactory_QueryInterface(&NewMonikerFactory, riid, ppv);
1049 FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1050 return CLASS_E_CLASSNOTAVAILABLE;
1053 /******************************************************************
1054 * DllCanUnloadNow
1056 HRESULT WINAPI DllCanUnloadNow(void)
1058 return S_FALSE;
1061 /***********************************************************************
1062 * DllRegisterServer (comsvcs.@)
1064 HRESULT WINAPI DllRegisterServer(void)
1066 return __wine_register_resources( COMSVCS_hInstance );
1069 /***********************************************************************
1070 * DllUnregisterServer (comsvcs.@)
1072 HRESULT WINAPI DllUnregisterServer(void)
1074 return __wine_unregister_resources( COMSVCS_hInstance );