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 HANDLE mta_thread
, mta_stop_event
;
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_thread
)
290 SetEvent(This
->mta_stop_event
);
291 WaitForSingleObject(This
->mta_thread
, INFINITE
);
292 CloseHandle(This
->mta_stop_event
);
293 CloseHandle(This
->mta_thread
);
301 static DWORD WINAPI
mta_thread_proc(void *arg
)
303 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
304 WaitForSingleObject(arg
, INFINITE
);
309 static HRESULT WINAPI
dismanager_RegisterDispenser(IDispenserManager
*iface
, IDispenserDriver
*driver
,
310 LPCOLESTR name
, IHolder
**dispenser
)
312 dispensermanager
*This
= impl_from_IDispenserManager(iface
);
315 TRACE("(%p)->(%p, %s, %p)\n", This
, driver
, debugstr_w(name
), dispenser
);
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
);
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
);
342 struct IDispenserManagerVtbl dismanager_vtbl
=
344 dismanager_QueryInterface
,
347 dismanager_RegisterDispenser
,
348 dismanager_GetContext
351 static HRESULT WINAPI
dispenser_manager_cf_CreateInstance(IClassFactory
*iface
, IUnknown
* outer
, REFIID riid
,
354 dispensermanager
*dismanager
;
357 TRACE("(%p %s %p)\n", outer
, debugstr_guid(riid
), object
);
359 dismanager
= heap_alloc_zero(sizeof(*dismanager
));
363 return E_OUTOFMEMORY
;
366 dismanager
->IDispenserManager_iface
.lpVtbl
= &dismanager_vtbl
;
369 ret
= dismanager_QueryInterface(&dismanager
->IDispenserManager_iface
, riid
, object
);
370 dismanager_Release(&dismanager
->IDispenserManager_iface
);
375 BOOL WINAPI
DllMain(HINSTANCE hinst
, DWORD reason
, LPVOID lpv
)
379 case DLL_WINE_PREATTACH
:
380 return FALSE
; /* prefer native version */
381 case DLL_PROCESS_ATTACH
:
382 COMSVCS_hInstance
= hinst
;
383 DisableThreadLibraryCalls(hinst
);
389 static HRESULT WINAPI
comsvcscf_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
393 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
394 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
396 }else if(IsEqualGUID(&IID_IClassFactory
, riid
)) {
397 TRACE("(%p)->(IID_IClassFactory %p)\n", iface
, ppv
);
402 IUnknown_AddRef((IUnknown
*)*ppv
);
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
);
416 static ULONG WINAPI
comsvcscf_Release(IClassFactory
*iface
)
418 TRACE("(%p)\n", iface
);
422 static HRESULT WINAPI
comsvcscf_LockServer(IClassFactory
*iface
, BOOL fLock
)
424 TRACE("(%p)->(%x)\n", iface
, fLock
);
428 static const IClassFactoryVtbl comsvcscf_vtbl
=
430 comsvcscf_QueryInterface
,
433 dispenser_manager_cf_CreateInstance
,
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
);
445 if (IsEqualIID(&IID_IUnknown
, riid
) ||
446 IsEqualIID(&IID_IPersist
, riid
) ||
447 IsEqualIID(&IID_IPersistStream
, riid
) ||
448 IsEqualIID(&IID_IMoniker
, riid
))
452 else if (IsEqualIID(&IID_IROTData
, riid
))
454 *obj
= &moniker
->IROTData_iface
;
459 IUnknown_AddRef((IUnknown
*)*obj
);
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
);
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
);
486 heap_free(moniker
->progid
);
493 static HRESULT WINAPI
new_moniker_GetClassID(IMoniker
*iface
, CLSID
*clsid
)
495 TRACE("%p, %p.\n", iface
, clsid
);
500 *clsid
= CLSID_NewMoniker
;
505 static HRESULT WINAPI
new_moniker_IsDirty(IMoniker
* iface
)
507 TRACE("%p.\n", iface
);
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
;
520 TRACE("%p, %p.\n", iface
, stream
);
522 hr
= IStream_Read(stream
, &clsid
, sizeof(clsid
), &len
);
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. */
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
;
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;
559 TRACE("%p, %p, %d.\n", iface
, stream
, clear_dirty
);
562 progid_len
= lstrlenW(moniker
->progid
) * sizeof(WCHAR
);
564 hr
= IStream_Write(stream
, &moniker
->clsid
, sizeof(moniker
->clsid
), &written
);
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
);
570 hr
= IStream_Write(stream
, &pad
, sizeof(pad
), &written
);
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
);
584 size
->QuadPart
= sizeof(CLSID
) + 2 * sizeof(DWORD
);
586 size
->QuadPart
+= lstrlenW(moniker
->progid
) * sizeof(WCHAR
);
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
;
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
)))
612 hr
= CoCreateInstanceEx(&moniker
->clsid
, NULL
, bindopts
.dwClassContext
, bindopts
.pServerInfo
, 1, &qi
);
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
);
632 static HRESULT WINAPI
new_moniker_BindToStorage(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, REFIID riid
,
635 FIXME("%p, %p, %p, %s, %p.\n", iface
, pbc
, pmkToLeft
, debugstr_guid(riid
), ret
);
640 static HRESULT WINAPI
new_moniker_Reduce(IMoniker
*iface
, IBindCtx
*pbc
, DWORD flags
, IMoniker
**ppmkToLeft
,
643 TRACE("%p, %p, %d, %p, %p.\n", iface
, pbc
, flags
, ppmkToLeft
, ret
);
649 IMoniker_AddRef(iface
);
651 return MK_S_REDUCED_TO_SELF
;
654 static HRESULT WINAPI
new_moniker_ComposeWith(IMoniker
*iface
, IMoniker
*mkRight
, BOOL fOnlyIfNotGeneric
,
657 FIXME("%p, %p, %d, %p.\n", iface
, mkRight
, fOnlyIfNotGeneric
, ret
);
662 static HRESULT WINAPI
new_moniker_Enum(IMoniker
*iface
, BOOL forward
, IEnumMoniker
**enum_moniker
)
664 TRACE("%p, %d, %p.\n", iface
, forward
, enum_moniker
);
669 *enum_moniker
= NULL
;
674 static HRESULT WINAPI
new_moniker_IsEqual(IMoniker
*iface
, IMoniker
*other_moniker
)
676 FIXME("%p, %p.\n", iface
, other_moniker
);
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
;
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
);
700 static HRESULT WINAPI
new_moniker_GetTimeOfLastChange(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
,
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
);
722 static HRESULT WINAPI
new_moniker_RelativePathTo(IMoniker
*iface
, IMoniker
*other
, IMoniker
**ret
)
724 FIXME("%p, %p, %p.\n", iface
, other
, ret
);
729 static HRESULT WINAPI
new_moniker_GetDisplayName(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
,
732 FIXME("%p, %p, %p, %p.\n", iface
, pbc
, pmkToLeft
, name
);
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
;
754 static const IMonikerVtbl new_moniker_vtbl
=
756 new_moniker_QueryInterface
,
759 new_moniker_GetClassID
,
763 new_moniker_GetSizeMax
,
764 new_moniker_BindToObject
,
765 new_moniker_BindToStorage
,
767 new_moniker_ComposeWith
,
771 new_moniker_IsRunning
,
772 new_moniker_GetTimeOfLastChange
,
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
);
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
)
837 memset(ret
, 0, sizeof(*ret
));
839 /* Curly brackets are optional. */
840 has_brackets
= s
[0] == '{';
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
]];
852 if (s
[0] != '-') return FALSE
;
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
]];
862 if (s
[0] != '-') return FALSE
;
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
]];
872 if (s
[0] != '-') return FALSE
;
875 for (i
= 0; i
< 17; i
+= 2)
879 if (s
[i
] != '-') return FALSE
;
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]];
887 if (has_brackets
&& s
[0] != '}')
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
;
903 if (wcsnicmp(name
, L
"new:", 4))
907 if (!guid_from_string(str
, &guid
))
909 if (FAILED(CLSIDFromProgID(str
, &guid
)))
914 moniker
= heap_alloc_zero(sizeof(*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
;
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
;
935 *eaten
= lstrlenW(name
);
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
))
948 IParseDisplayName_AddRef(iface
);
953 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
954 return E_NOINTERFACE
;
957 static ULONG WINAPI
new_moniker_parse_AddRef(IParseDisplayName
*iface
)
962 static ULONG WINAPI
new_moniker_parse_Release(IParseDisplayName
*iface
)
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
);
991 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
992 IsEqualGUID(&IID_IClassFactory
, riid
))
996 else if (IsEqualIID(&IID_IParseDisplayName
, riid
))
998 *obj
= &new_moniker_parse
;
1003 IUnknown_AddRef((IUnknown
*)*obj
);
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
);
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
,
1026 new_moniker_cf_CreateInstance
,
1027 comsvcscf_LockServer
1030 static IClassFactory DispenserManageFactory
= { &comsvcscf_vtbl
};
1031 static IClassFactory NewMonikerFactory
= { &newmoniker_cf_vtbl
};
1033 /******************************************************************
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 /******************************************************************
1056 HRESULT WINAPI
DllCanUnloadNow(void)
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
);