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
30 #include "wine/heap.h"
31 #include "wine/debug.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
;
43 CO_MTA_USAGE_COOKIE mta_cookie
;
48 IHolder IHolder_iface
;
51 IDispenserDriver
*driver
;
56 IMoniker IMoniker_iface
;
57 IROTData IROTData_iface
;
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
);
93 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
94 IsEqualGUID(riid
, &IID_IHolder
))
96 *object
= &This
->IHolder_iface
;
97 IUnknown_AddRef( (IUnknown
*)*object
);
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
);
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
);
128 static HRESULT WINAPI
holder_AllocResource(IHolder
*iface
, const RESTYPID
typeid, RESID
*resid
)
130 holder
*This
= impl_from_IHolder(iface
);
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
);
142 static HRESULT WINAPI
holder_FreeResource(IHolder
*iface
, const RESID resid
)
144 holder
*This
= impl_from_IHolder(iface
);
147 TRACE("(%p)->(%08lx) stub\n", This
, resid
);
149 hr
= IDispenserDriver_DestroyResource(This
->driver
, resid
);
151 TRACE("<- 0x%08x\n", 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
);
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
));
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
);
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
);
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
);
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
);
212 struct IHolderVtbl holder_vtbl
=
214 holder_QueryInterface
,
217 holder_AllocResource
,
219 holder_TrackResource
,
220 holder_TrackResourceS
,
221 holder_UntrackResource
,
222 holder_UntrackResourceS
,
224 holder_RequestDestroyResource
227 static HRESULT
create_holder(IDispenserDriver
*driver
, IHolder
**object
)
232 TRACE("(%p)\n", object
);
234 hold
= heap_alloc(sizeof(*hold
));
238 return E_OUTOFMEMORY
;
241 hold
->IHolder_iface
.lpVtbl
= &holder_vtbl
;
243 hold
->driver
= driver
;
245 ret
= holder_QueryInterface(&hold
->IHolder_iface
, &IID_IHolder
, (void**)object
);
246 holder_Release(&hold
->IHolder_iface
);
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
);
259 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
260 IsEqualGUID(riid
, &IID_IDispenserManager
))
262 *object
= &This
->IDispenserManager_iface
;
263 IUnknown_AddRef( (IUnknown
*)*object
);
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
);
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
);
288 if (This
->mta_cookie
)
289 CoDecrementMTAUsage(This
->mta_cookie
);
296 static HRESULT WINAPI
dismanager_RegisterDispenser(IDispenserManager
*iface
, IDispenserDriver
*driver
,
297 LPCOLESTR name
, IHolder
**dispenser
)
299 dispensermanager
*This
= impl_from_IDispenserManager(iface
);
302 TRACE("(%p)->(%p, %s, %p)\n", This
, driver
, debugstr_w(name
), dispenser
);
307 hr
= create_holder(driver
, dispenser
);
309 if (!This
->mta_cookie
)
310 CoIncrementMTAUsage(&This
->mta_cookie
);
312 TRACE("<-- 0x%08x, %p\n", hr
, *dispenser
);
317 static HRESULT WINAPI
dismanager_GetContext(IDispenserManager
*iface
, INSTID
*id
, TRANSID
*transid
)
319 dispensermanager
*This
= impl_from_IDispenserManager(iface
);
321 FIXME("(%p)->(%p, %p) stub\n", This
, id
, transid
);
326 struct IDispenserManagerVtbl dismanager_vtbl
=
328 dismanager_QueryInterface
,
331 dismanager_RegisterDispenser
,
332 dismanager_GetContext
335 static HRESULT WINAPI
dispenser_manager_cf_CreateInstance(IClassFactory
*iface
, IUnknown
* outer
, REFIID riid
,
338 dispensermanager
*dismanager
;
341 TRACE("(%p %s %p)\n", outer
, debugstr_guid(riid
), object
);
343 dismanager
= heap_alloc_zero(sizeof(*dismanager
));
347 return E_OUTOFMEMORY
;
350 dismanager
->IDispenserManager_iface
.lpVtbl
= &dismanager_vtbl
;
353 ret
= dismanager_QueryInterface(&dismanager
->IDispenserManager_iface
, riid
, object
);
354 dismanager_Release(&dismanager
->IDispenserManager_iface
);
359 BOOL WINAPI
DllMain(HINSTANCE hinst
, DWORD reason
, LPVOID lpv
)
363 case DLL_PROCESS_ATTACH
:
364 COMSVCS_hInstance
= hinst
;
365 DisableThreadLibraryCalls(hinst
);
371 static HRESULT WINAPI
comsvcscf_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
375 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
376 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
378 }else if(IsEqualGUID(&IID_IClassFactory
, riid
)) {
379 TRACE("(%p)->(IID_IClassFactory %p)\n", iface
, ppv
);
384 IUnknown_AddRef((IUnknown
*)*ppv
);
388 WARN("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
389 return E_NOINTERFACE
;
392 static ULONG WINAPI
comsvcscf_AddRef(IClassFactory
*iface
)
394 TRACE("(%p)\n", iface
);
398 static ULONG WINAPI
comsvcscf_Release(IClassFactory
*iface
)
400 TRACE("(%p)\n", iface
);
404 static HRESULT WINAPI
comsvcscf_LockServer(IClassFactory
*iface
, BOOL fLock
)
406 TRACE("(%p)->(%x)\n", iface
, fLock
);
410 static const IClassFactoryVtbl comsvcscf_vtbl
=
412 comsvcscf_QueryInterface
,
415 dispenser_manager_cf_CreateInstance
,
419 static HRESULT WINAPI
new_moniker_QueryInterface(IMoniker
* iface
, REFIID riid
, void **obj
)
421 struct new_moniker
*moniker
= impl_from_IMoniker(iface
);
423 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
427 if (IsEqualIID(&IID_IUnknown
, riid
) ||
428 IsEqualIID(&IID_IPersist
, riid
) ||
429 IsEqualIID(&IID_IPersistStream
, riid
) ||
430 IsEqualIID(&IID_IMoniker
, riid
))
434 else if (IsEqualIID(&IID_IROTData
, riid
))
436 *obj
= &moniker
->IROTData_iface
;
441 IUnknown_AddRef((IUnknown
*)*obj
);
445 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
446 return E_NOINTERFACE
;
449 static ULONG WINAPI
new_moniker_AddRef(IMoniker
* iface
)
451 struct new_moniker
*moniker
= impl_from_IMoniker(iface
);
452 ULONG refcount
= InterlockedIncrement(&moniker
->refcount
);
454 TRACE("%p, refcount %u.\n", iface
, refcount
);
459 static ULONG WINAPI
new_moniker_Release(IMoniker
* iface
)
461 struct new_moniker
*moniker
= impl_from_IMoniker(iface
);
462 ULONG refcount
= InterlockedDecrement(&moniker
->refcount
);
464 TRACE("%p, refcount %u.\n", iface
, refcount
);
468 heap_free(moniker
->progid
);
475 static HRESULT WINAPI
new_moniker_GetClassID(IMoniker
*iface
, CLSID
*clsid
)
477 TRACE("%p, %p.\n", iface
, clsid
);
482 *clsid
= CLSID_NewMoniker
;
487 static HRESULT WINAPI
new_moniker_IsDirty(IMoniker
* iface
)
489 TRACE("%p.\n", iface
);
494 static HRESULT WINAPI
new_moniker_Load(IMoniker
*iface
, IStream
*stream
)
496 struct new_moniker
*moniker
= impl_from_IMoniker(iface
);
497 DWORD progid_len
= 0, len
, pad
= ~0u;
498 WCHAR
*progid
= NULL
;
502 TRACE("%p, %p.\n", iface
, stream
);
504 hr
= IStream_Read(stream
, &clsid
, sizeof(clsid
), &len
);
509 hr
= IStream_Read(stream
, &progid_len
, sizeof(progid_len
), &len
);
511 if (SUCCEEDED(hr
) && progid_len
)
513 if (!(progid
= heap_alloc(progid_len
)))
514 return E_OUTOFMEMORY
;
515 hr
= IStream_Read(stream
, progid
, progid_len
, &len
);
518 /* Skip terminator. */
520 hr
= IStream_Read(stream
, &pad
, sizeof(pad
), &len
);
522 if (SUCCEEDED(hr
) && pad
== 0)
524 moniker
->clsid
= clsid
;
525 heap_free(moniker
->progid
);
526 moniker
->progid
= progid
;
535 static HRESULT WINAPI
new_moniker_Save(IMoniker
*iface
, IStream
*stream
, BOOL clear_dirty
)
537 struct new_moniker
*moniker
= impl_from_IMoniker(iface
);
538 ULONG written
, pad
= 0, progid_len
= 0;
541 TRACE("%p, %p, %d.\n", iface
, stream
, clear_dirty
);
544 progid_len
= lstrlenW(moniker
->progid
) * sizeof(WCHAR
);
546 hr
= IStream_Write(stream
, &moniker
->clsid
, sizeof(moniker
->clsid
), &written
);
548 hr
= IStream_Write(stream
, &progid_len
, sizeof(progid_len
), &written
);
549 if (SUCCEEDED(hr
) && progid_len
)
550 hr
= IStream_Write(stream
, moniker
->progid
, progid_len
, &written
);
552 hr
= IStream_Write(stream
, &pad
, sizeof(pad
), &written
);
557 static HRESULT WINAPI
new_moniker_GetSizeMax(IMoniker
*iface
, ULARGE_INTEGER
*size
)
559 struct new_moniker
*moniker
= impl_from_IMoniker(iface
);
561 TRACE("%p, %p.\n", iface
, size
);
566 size
->QuadPart
= sizeof(CLSID
) + 2 * sizeof(DWORD
);
568 size
->QuadPart
+= lstrlenW(moniker
->progid
) * sizeof(WCHAR
);
573 static HRESULT WINAPI
new_moniker_BindToObject(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
,
574 REFIID riid
, void **ret
)
576 struct new_moniker
*moniker
= impl_from_IMoniker(iface
);
577 IClassActivator
*activator
;
578 IClassFactory
*factory
;
583 TRACE("%p, %p, %p, %s, %p.\n", iface
, pbc
, pmkToLeft
, debugstr_guid(riid
), ret
);
585 bindopts
.cbStruct
= sizeof(bindopts
);
586 if (FAILED(hr
= IBindCtx_GetBindOptions(pbc
, (BIND_OPTS
*)&bindopts
)))
594 hr
= CoCreateInstanceEx(&moniker
->clsid
, NULL
, bindopts
.dwClassContext
, bindopts
.pServerInfo
, 1, &qi
);
599 if (SUCCEEDED(hr
= IMoniker_BindToObject(pmkToLeft
, pbc
, NULL
, &IID_IClassActivator
, (void **)&activator
)))
601 hr
= IClassActivator_GetClassObject(activator
, &moniker
->clsid
, bindopts
.dwClassContext
, bindopts
.locale
, riid
, ret
);
602 IClassActivator_Release(activator
);
604 else if (SUCCEEDED(hr
= IMoniker_BindToObject(pmkToLeft
, pbc
, NULL
, &IID_IClassFactory
, (void **)&factory
)))
606 hr
= IClassFactory_CreateInstance(factory
, NULL
, riid
, ret
);
607 IClassFactory_Release(factory
);
614 static HRESULT WINAPI
new_moniker_BindToStorage(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, REFIID riid
,
617 FIXME("%p, %p, %p, %s, %p.\n", iface
, pbc
, pmkToLeft
, debugstr_guid(riid
), ret
);
622 static HRESULT WINAPI
new_moniker_Reduce(IMoniker
*iface
, IBindCtx
*pbc
, DWORD flags
, IMoniker
**ppmkToLeft
,
625 TRACE("%p, %p, %d, %p, %p.\n", iface
, pbc
, flags
, ppmkToLeft
, ret
);
631 IMoniker_AddRef(iface
);
633 return MK_S_REDUCED_TO_SELF
;
636 static HRESULT WINAPI
new_moniker_ComposeWith(IMoniker
*iface
, IMoniker
*mkRight
, BOOL fOnlyIfNotGeneric
,
639 FIXME("%p, %p, %d, %p.\n", iface
, mkRight
, fOnlyIfNotGeneric
, ret
);
644 static HRESULT WINAPI
new_moniker_Enum(IMoniker
*iface
, BOOL forward
, IEnumMoniker
**enum_moniker
)
646 TRACE("%p, %d, %p.\n", iface
, forward
, enum_moniker
);
651 *enum_moniker
= NULL
;
656 static HRESULT WINAPI
new_moniker_IsEqual(IMoniker
*iface
, IMoniker
*other_moniker
)
658 FIXME("%p, %p.\n", iface
, other_moniker
);
663 static HRESULT WINAPI
new_moniker_Hash(IMoniker
*iface
, DWORD
*hash
)
665 struct new_moniker
*moniker
= impl_from_IMoniker(iface
);
667 TRACE("%p, %p.\n", iface
, hash
);
669 *hash
= moniker
->clsid
.Data1
;
674 static HRESULT WINAPI
new_moniker_IsRunning(IMoniker
* iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
,
675 IMoniker
*pmkNewlyRunning
)
677 FIXME("%p, %p, %p, %p.\n", iface
, pbc
, pmkToLeft
, pmkNewlyRunning
);
682 static HRESULT WINAPI
new_moniker_GetTimeOfLastChange(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
,
685 TRACE("%p, %p, %p, %p.\n", iface
, pbc
, pmkToLeft
, itemtime
);
687 return MK_E_UNAVAILABLE
;
690 static HRESULT WINAPI
new_moniker_Inverse(IMoniker
*iface
, IMoniker
**inverse
)
692 TRACE("%p, %p.\n", iface
, inverse
);
694 return CreateAntiMoniker(inverse
);
697 static HRESULT WINAPI
new_moniker_CommonPrefixWith(IMoniker
*iface
, IMoniker
*other
, IMoniker
**ret
)
699 FIXME("%p, %p, %p.\n", iface
, other
, ret
);
704 static HRESULT WINAPI
new_moniker_RelativePathTo(IMoniker
*iface
, IMoniker
*other
, IMoniker
**ret
)
706 FIXME("%p, %p, %p.\n", iface
, other
, ret
);
711 static HRESULT WINAPI
new_moniker_GetDisplayName(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
,
714 FIXME("%p, %p, %p, %p.\n", iface
, pbc
, pmkToLeft
, name
);
719 static HRESULT WINAPI
new_moniker_ParseDisplayName(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
,
720 LPOLESTR name
, ULONG
*eaten
, IMoniker
**ret
)
722 TRACE("%p, %p, %p, %s, %p, %p.\n", iface
, pbc
, pmkToLeft
, debugstr_w(name
), eaten
, ret
);
724 return new_moniker_parse_displayname(pbc
, name
, eaten
, ret
);
727 static HRESULT WINAPI
new_moniker_IsSystemMoniker(IMoniker
*iface
, DWORD
*moniker_type
)
729 TRACE("%p, %p.\n", iface
, moniker_type
);
731 *moniker_type
= MKSYS_NONE
;
736 static const IMonikerVtbl new_moniker_vtbl
=
738 new_moniker_QueryInterface
,
741 new_moniker_GetClassID
,
745 new_moniker_GetSizeMax
,
746 new_moniker_BindToObject
,
747 new_moniker_BindToStorage
,
749 new_moniker_ComposeWith
,
753 new_moniker_IsRunning
,
754 new_moniker_GetTimeOfLastChange
,
756 new_moniker_CommonPrefixWith
,
757 new_moniker_RelativePathTo
,
758 new_moniker_GetDisplayName
,
759 new_moniker_ParseDisplayName
,
760 new_moniker_IsSystemMoniker
763 static HRESULT WINAPI
new_moniker_rotdata_QueryInterface(IROTData
*iface
, REFIID riid
, void **obj
)
765 struct new_moniker
*moniker
= impl_from_IROTData(iface
);
766 return IMoniker_QueryInterface(&moniker
->IMoniker_iface
, riid
, obj
);
769 static ULONG WINAPI
new_moniker_rotdata_AddRef(IROTData
*iface
)
771 struct new_moniker
*moniker
= impl_from_IROTData(iface
);
772 return IMoniker_AddRef(&moniker
->IMoniker_iface
);
775 static ULONG WINAPI
new_moniker_rotdata_Release(IROTData
*iface
)
777 struct new_moniker
*moniker
= impl_from_IROTData(iface
);
778 return IMoniker_Release(&moniker
->IMoniker_iface
);
781 static HRESULT WINAPI
new_moniker_rotdata_GetComparisonData(IROTData
*iface
, byte
*data
, ULONG data_len
, ULONG
*length
)
783 FIXME("%p, %p, %u, %p.\n", iface
, data
, data_len
, length
);
788 static const IROTDataVtbl new_moniker_rotdata_vtbl
=
790 new_moniker_rotdata_QueryInterface
,
791 new_moniker_rotdata_AddRef
,
792 new_moniker_rotdata_Release
,
793 new_moniker_rotdata_GetComparisonData
,
796 static const BYTE guid_conv_table
[256] =
798 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
799 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
800 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
801 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
802 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
803 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
804 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */
807 static BOOL
is_valid_hex(WCHAR c
)
809 return (c
>= '0' && c
<= '9') || (c
>= 'a' && c
<= 'f') ||
810 (c
>= 'A' && c
<= 'F');
813 static HRESULT
guid_from_string(const WCHAR
*s
, GUID
*ret
)
819 memset(ret
, 0, sizeof(*ret
));
821 /* Curly brackets are optional. */
822 has_brackets
= s
[0] == '{';
827 for (i
= 0; i
< 8; i
++)
829 if (!is_valid_hex(s
[i
])) return FALSE
;
830 guid
.Data1
= (guid
.Data1
<< 4) | guid_conv_table
[s
[i
]];
834 if (s
[0] != '-') return FALSE
;
837 for (i
= 0; i
< 4; i
++)
839 if (!is_valid_hex(s
[0])) return FALSE
;
840 guid
.Data2
= (guid
.Data2
<< 4) | guid_conv_table
[s
[i
]];
844 if (s
[0] != '-') return FALSE
;
847 for (i
= 0; i
< 4; i
++)
849 if (!is_valid_hex(s
[i
])) return FALSE
;
850 guid
.Data3
= (guid
.Data3
<< 4) | guid_conv_table
[s
[i
]];
854 if (s
[0] != '-') return FALSE
;
857 for (i
= 0; i
< 17; i
+= 2)
861 if (s
[i
] != '-') return FALSE
;
864 if (!is_valid_hex(s
[i
]) || !is_valid_hex(s
[i
+1])) return FALSE
;
865 guid
.Data4
[i
/ 2] = guid_conv_table
[s
[i
]] << 4 | guid_conv_table
[s
[i
+1]];
869 if (has_brackets
&& s
[0] != '}')
877 static HRESULT
new_moniker_parse_displayname(IBindCtx
*pbc
, LPOLESTR name
, ULONG
*eaten
, IMoniker
**ret
)
879 struct new_moniker
*moniker
;
880 WCHAR
*progid
= NULL
, *str
;
885 if (wcsnicmp(name
, L
"new:", 4))
889 if (!guid_from_string(str
, &guid
))
891 if (FAILED(CLSIDFromProgID(str
, &guid
)))
896 moniker
= heap_alloc_zero(sizeof(*moniker
));
898 return E_OUTOFMEMORY
;
900 moniker
->IMoniker_iface
.lpVtbl
= &new_moniker_vtbl
;
901 moniker
->IROTData_iface
.lpVtbl
= &new_moniker_rotdata_vtbl
;
902 moniker
->refcount
= 1;
903 moniker
->clsid
= guid
;
906 if (!(moniker
->progid
= heap_alloc((lstrlenW(progid
) + 1) * sizeof(WCHAR
))))
908 IMoniker_Release(&moniker
->IMoniker_iface
);
909 return E_OUTOFMEMORY
;
911 lstrcpyW(moniker
->progid
, progid
);
914 *ret
= &moniker
->IMoniker_iface
;
917 *eaten
= lstrlenW(name
);
922 static HRESULT WINAPI
new_moniker_parse_QueryInterface(IParseDisplayName
*iface
, REFIID riid
, void **obj
)
924 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
926 if (IsEqualIID(riid
, &IID_IParseDisplayName
) ||
927 IsEqualIID(riid
, &IID_IUnknown
))
930 IParseDisplayName_AddRef(iface
);
935 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
936 return E_NOINTERFACE
;
939 static ULONG WINAPI
new_moniker_parse_AddRef(IParseDisplayName
*iface
)
944 static ULONG WINAPI
new_moniker_parse_Release(IParseDisplayName
*iface
)
949 static HRESULT WINAPI
new_moniker_parse_ParseDisplayName(IParseDisplayName
*iface
, IBindCtx
*pbc
, LPOLESTR name
,
950 ULONG
*eaten
, IMoniker
**ret
)
952 TRACE("%p, %p, %s, %p, %p.\n", iface
, pbc
, debugstr_w(name
), eaten
, ret
);
954 return new_moniker_parse_displayname(pbc
, name
, eaten
, ret
);
957 static const IParseDisplayNameVtbl new_moniker_parse_vtbl
=
959 new_moniker_parse_QueryInterface
,
960 new_moniker_parse_AddRef
,
961 new_moniker_parse_Release
,
962 new_moniker_parse_ParseDisplayName
,
965 static IParseDisplayName new_moniker_parse
= { &new_moniker_parse_vtbl
};
967 static HRESULT WINAPI
new_moniker_cf_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **obj
)
969 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
973 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
974 IsEqualGUID(&IID_IClassFactory
, riid
))
978 else if (IsEqualIID(&IID_IParseDisplayName
, riid
))
980 *obj
= &new_moniker_parse
;
985 IUnknown_AddRef((IUnknown
*)*obj
);
989 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
990 return E_NOINTERFACE
;
993 static HRESULT WINAPI
new_moniker_cf_CreateInstance(IClassFactory
*iface
, IUnknown
* outer
, REFIID riid
, void **object
)
995 TRACE("%p, %p, %s, %p.\n", iface
, outer
, debugstr_guid(riid
), object
);
998 FIXME("Aggregation is not supported.\n");
1000 return IParseDisplayName_QueryInterface(&new_moniker_parse
, riid
, object
);
1003 static const IClassFactoryVtbl newmoniker_cf_vtbl
=
1005 new_moniker_cf_QueryInterface
,
1008 new_moniker_cf_CreateInstance
,
1009 comsvcscf_LockServer
1012 static IClassFactory DispenserManageFactory
= { &comsvcscf_vtbl
};
1013 static IClassFactory NewMonikerFactory
= { &newmoniker_cf_vtbl
};
1015 /******************************************************************
1018 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **ppv
)
1020 if(IsEqualGUID(&CLSID_DispenserManager
, rclsid
))
1022 TRACE("(CLSID_DispenserManager %s %p)\n", debugstr_guid(riid
), ppv
);
1023 return IClassFactory_QueryInterface(&DispenserManageFactory
, riid
, ppv
);
1025 else if (IsEqualGUID(&CLSID_NewMoniker
, rclsid
))
1027 TRACE("(CLSID_NewMoniker %s %p)\n", debugstr_guid(riid
), ppv
);
1028 return IClassFactory_QueryInterface(&NewMonikerFactory
, riid
, ppv
);
1031 FIXME("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1032 return CLASS_E_CLASSNOTAVAILABLE
;
1035 /******************************************************************
1038 HRESULT WINAPI
DllCanUnloadNow(void)
1043 /***********************************************************************
1044 * DllRegisterServer (comsvcs.@)
1046 HRESULT WINAPI
DllRegisterServer(void)
1048 return __wine_register_resources( COMSVCS_hInstance
);
1051 /***********************************************************************
1052 * DllUnregisterServer (comsvcs.@)
1054 HRESULT WINAPI
DllUnregisterServer(void)
1056 return __wine_unregister_resources( COMSVCS_hInstance
);