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"
24 #include "comsvcs_classes.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(comsvcs
);
28 typedef struct dispensermanager
30 IDispenserManager IDispenserManager_iface
;
32 CO_MTA_USAGE_COOKIE mta_cookie
;
37 IHolder IHolder_iface
;
40 IDispenserDriver
*driver
;
45 IMoniker IMoniker_iface
;
46 IROTData IROTData_iface
;
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
);
82 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
83 IsEqualGUID(riid
, &IID_IHolder
))
85 *object
= &This
->IHolder_iface
;
86 IUnknown_AddRef( (IUnknown
*)*object
);
91 WARN("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),object
);
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
);
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
);
117 static HRESULT WINAPI
holder_AllocResource(IHolder
*iface
, const RESTYPID
typeid, RESID
*resid
)
119 holder
*This
= impl_from_IHolder(iface
);
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
);
131 static HRESULT WINAPI
holder_FreeResource(IHolder
*iface
, const RESID resid
)
133 holder
*This
= impl_from_IHolder(iface
);
136 TRACE("(%p)->(%08Ix) stub\n", This
, resid
);
138 hr
= IDispenserDriver_DestroyResource(This
->driver
, resid
);
140 TRACE("<- 0x%08lx\n", 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
);
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
));
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
);
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
);
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
);
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
);
201 struct IHolderVtbl holder_vtbl
=
203 holder_QueryInterface
,
206 holder_AllocResource
,
208 holder_TrackResource
,
209 holder_TrackResourceS
,
210 holder_UntrackResource
,
211 holder_UntrackResourceS
,
213 holder_RequestDestroyResource
216 static HRESULT
create_holder(IDispenserDriver
*driver
, IHolder
**object
)
221 TRACE("(%p)\n", object
);
223 hold
= malloc(sizeof(*hold
));
227 return E_OUTOFMEMORY
;
230 hold
->IHolder_iface
.lpVtbl
= &holder_vtbl
;
232 hold
->driver
= driver
;
234 ret
= holder_QueryInterface(&hold
->IHolder_iface
, &IID_IHolder
, (void**)object
);
235 holder_Release(&hold
->IHolder_iface
);
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
);
248 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
249 IsEqualGUID(riid
, &IID_IDispenserManager
))
251 *object
= &This
->IDispenserManager_iface
;
252 IUnknown_AddRef( (IUnknown
*)*object
);
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
);
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
);
277 if (This
->mta_cookie
)
278 CoDecrementMTAUsage(This
->mta_cookie
);
285 static HRESULT WINAPI
dismanager_RegisterDispenser(IDispenserManager
*iface
, IDispenserDriver
*driver
,
286 LPCOLESTR name
, IHolder
**dispenser
)
288 dispensermanager
*This
= impl_from_IDispenserManager(iface
);
291 TRACE("(%p)->(%p, %s, %p)\n", This
, driver
, debugstr_w(name
), dispenser
);
296 hr
= create_holder(driver
, dispenser
);
298 if (!This
->mta_cookie
)
299 CoIncrementMTAUsage(&This
->mta_cookie
);
301 TRACE("<-- 0x%08lx, %p\n", hr
, *dispenser
);
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
);
315 struct IDispenserManagerVtbl dismanager_vtbl
=
317 dismanager_QueryInterface
,
320 dismanager_RegisterDispenser
,
321 dismanager_GetContext
324 static HRESULT WINAPI
dispenser_manager_cf_CreateInstance(IClassFactory
*iface
, IUnknown
* outer
, REFIID riid
,
327 dispensermanager
*dismanager
;
330 TRACE("(%p %s %p)\n", outer
, debugstr_guid(riid
), object
);
332 dismanager
= calloc(1, sizeof(*dismanager
));
336 return E_OUTOFMEMORY
;
339 dismanager
->IDispenserManager_iface
.lpVtbl
= &dismanager_vtbl
;
342 ret
= dismanager_QueryInterface(&dismanager
->IDispenserManager_iface
, riid
, object
);
343 dismanager_Release(&dismanager
->IDispenserManager_iface
);
348 static HRESULT WINAPI
comsvcscf_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
352 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
353 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
355 }else if(IsEqualGUID(&IID_IClassFactory
, riid
)) {
356 TRACE("(%p)->(IID_IClassFactory %p)\n", iface
, ppv
);
361 IUnknown_AddRef((IUnknown
*)*ppv
);
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
);
375 static ULONG WINAPI
comsvcscf_Release(IClassFactory
*iface
)
377 TRACE("(%p)\n", iface
);
381 static HRESULT WINAPI
comsvcscf_LockServer(IClassFactory
*iface
, BOOL fLock
)
383 TRACE("(%p)->(%x)\n", iface
, fLock
);
387 static const IClassFactoryVtbl comsvcscf_vtbl
=
389 comsvcscf_QueryInterface
,
392 dispenser_manager_cf_CreateInstance
,
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
);
404 if (IsEqualIID(&IID_IUnknown
, riid
) ||
405 IsEqualIID(&IID_IPersist
, riid
) ||
406 IsEqualIID(&IID_IPersistStream
, riid
) ||
407 IsEqualIID(&IID_IMoniker
, riid
))
411 else if (IsEqualIID(&IID_IROTData
, riid
))
413 *obj
= &moniker
->IROTData_iface
;
418 IUnknown_AddRef((IUnknown
*)*obj
);
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
);
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
);
445 free(moniker
->progid
);
452 static HRESULT WINAPI
new_moniker_GetClassID(IMoniker
*iface
, CLSID
*clsid
)
454 TRACE("%p, %p.\n", iface
, clsid
);
459 *clsid
= CLSID_NewMoniker
;
464 static HRESULT WINAPI
new_moniker_IsDirty(IMoniker
* iface
)
466 TRACE("%p.\n", iface
);
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
;
479 TRACE("%p, %p.\n", iface
, stream
);
481 hr
= IStream_Read(stream
, &clsid
, sizeof(clsid
), &len
);
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. */
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
;
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;
518 TRACE("%p, %p, %d.\n", iface
, stream
, clear_dirty
);
521 progid_len
= lstrlenW(moniker
->progid
) * sizeof(WCHAR
);
523 hr
= IStream_Write(stream
, &moniker
->clsid
, sizeof(moniker
->clsid
), &written
);
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
);
529 hr
= IStream_Write(stream
, &pad
, sizeof(pad
), &written
);
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
);
543 size
->QuadPart
= sizeof(CLSID
) + 2 * sizeof(DWORD
);
545 size
->QuadPart
+= lstrlenW(moniker
->progid
) * sizeof(WCHAR
);
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
;
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
)))
571 hr
= CoCreateInstanceEx(&moniker
->clsid
, NULL
, bindopts
.dwClassContext
, bindopts
.pServerInfo
, 1, &qi
);
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
);
591 static HRESULT WINAPI
new_moniker_BindToStorage(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, REFIID riid
,
594 FIXME("%p, %p, %p, %s, %p.\n", iface
, pbc
, pmkToLeft
, debugstr_guid(riid
), ret
);
599 static HRESULT WINAPI
new_moniker_Reduce(IMoniker
*iface
, IBindCtx
*pbc
, DWORD flags
, IMoniker
**ppmkToLeft
,
602 TRACE("%p, %p, %ld, %p, %p.\n", iface
, pbc
, flags
, ppmkToLeft
, ret
);
608 IMoniker_AddRef(iface
);
610 return MK_S_REDUCED_TO_SELF
;
613 static HRESULT WINAPI
new_moniker_ComposeWith(IMoniker
*iface
, IMoniker
*mkRight
, BOOL fOnlyIfNotGeneric
,
616 FIXME("%p, %p, %d, %p.\n", iface
, mkRight
, fOnlyIfNotGeneric
, ret
);
621 static HRESULT WINAPI
new_moniker_Enum(IMoniker
*iface
, BOOL forward
, IEnumMoniker
**enum_moniker
)
623 TRACE("%p, %d, %p.\n", iface
, forward
, enum_moniker
);
628 *enum_moniker
= NULL
;
633 static HRESULT WINAPI
new_moniker_IsEqual(IMoniker
*iface
, IMoniker
*other_moniker
)
635 FIXME("%p, %p.\n", iface
, other_moniker
);
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
;
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
);
659 static HRESULT WINAPI
new_moniker_GetTimeOfLastChange(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
,
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
);
681 static HRESULT WINAPI
new_moniker_RelativePathTo(IMoniker
*iface
, IMoniker
*other
, IMoniker
**ret
)
683 FIXME("%p, %p, %p.\n", iface
, other
, ret
);
688 static HRESULT WINAPI
new_moniker_GetDisplayName(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
,
691 FIXME("%p, %p, %p, %p.\n", iface
, pbc
, pmkToLeft
, name
);
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
;
713 static const IMonikerVtbl new_moniker_vtbl
=
715 new_moniker_QueryInterface
,
718 new_moniker_GetClassID
,
722 new_moniker_GetSizeMax
,
723 new_moniker_BindToObject
,
724 new_moniker_BindToStorage
,
726 new_moniker_ComposeWith
,
730 new_moniker_IsRunning
,
731 new_moniker_GetTimeOfLastChange
,
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
);
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
)
796 memset(ret
, 0, sizeof(*ret
));
798 /* Curly brackets are optional. */
799 has_brackets
= s
[0] == '{';
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
]];
811 if (s
[0] != '-') return FALSE
;
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
]];
821 if (s
[0] != '-') return FALSE
;
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
]];
831 if (s
[0] != '-') return FALSE
;
834 for (i
= 0; i
< 17; i
+= 2)
838 if (s
[i
] != '-') return FALSE
;
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]];
846 if (has_brackets
&& s
[0] != '}')
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
;
862 if (wcsnicmp(name
, L
"new:", 4))
866 if (!guid_from_string(str
, &guid
))
868 if (FAILED(CLSIDFromProgID(str
, &guid
)))
873 moniker
= calloc(1, sizeof(*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
;
883 if (!(moniker
->progid
= wcsdup(progid
)))
885 IMoniker_Release(&moniker
->IMoniker_iface
);
886 return E_OUTOFMEMORY
;
890 *ret
= &moniker
->IMoniker_iface
;
893 *eaten
= lstrlenW(name
);
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
))
906 IParseDisplayName_AddRef(iface
);
911 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
912 return E_NOINTERFACE
;
915 static ULONG WINAPI
new_moniker_parse_AddRef(IParseDisplayName
*iface
)
920 static ULONG WINAPI
new_moniker_parse_Release(IParseDisplayName
*iface
)
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
);
949 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
950 IsEqualGUID(&IID_IClassFactory
, riid
))
954 else if (IsEqualIID(&IID_IParseDisplayName
, riid
))
956 *obj
= &new_moniker_parse
;
961 IUnknown_AddRef((IUnknown
*)*obj
);
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
);
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
,
984 new_moniker_cf_CreateInstance
,
988 static const IClassFactoryVtbl group_manager_cf_vtbl
=
990 comsvcscf_QueryInterface
,
993 group_manager_create
,
997 static IClassFactory DispenserManageFactory
= { &comsvcscf_vtbl
};
998 static IClassFactory NewMonikerFactory
= { &newmoniker_cf_vtbl
};
999 static IClassFactory GroupManagerFactory
= { &group_manager_cf_vtbl
};
1001 /******************************************************************
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
;