2 * Copyright 2017 Nikolay Sivov
3 * Copyright 2019 Jacek Caban for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
36 #include "wine/debug.h"
37 #include "wine/list.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(scrobj
);
43 #define IActiveScriptParse_Release IActiveScriptParse64_Release
44 #define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
45 #define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
49 #define IActiveScriptParse_Release IActiveScriptParse32_Release
50 #define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
51 #define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
55 static HINSTANCE scrobj_instance
;
63 #define PROP_GETTER 0x01
64 #define PROP_SETTER 0x02
66 struct scriptlet_member
69 enum member_type type
;
73 struct list parameters
;
78 struct method_parameter
84 struct scriptlet_script
91 struct scriptlet_global
93 IDispatchEx IDispatchEx_iface
;
97 struct scriptlet_factory
99 IClassFactory IClassFactory_iface
;
103 IXmlReader
*xml_reader
;
106 BOOL have_registration
;
110 WCHAR
*versioned_progid
;
120 struct script_reference
122 struct script_host
*host
;
128 enum member_type type
;
132 struct script_reference method
;
135 struct script_reference get
;
136 struct script_reference put
;
141 struct scriptlet_instance
143 IDispatchEx IDispatchEx_iface
;
146 struct scriptlet_global
*global
;
148 struct object_member
*members
;
153 IActiveScriptSite IActiveScriptSite_iface
;
154 IActiveScriptSiteWindow IActiveScriptSiteWindow_iface
;
155 IServiceProvider IServiceProvider_iface
;
162 IActiveScript
*active_script
;
163 IActiveScriptParse
*parser
;
164 IDispatchEx
*script_dispatch
;
165 struct scriptlet_instance
*object
;
173 IGenScriptletTLib_tid
,
177 static ITypeLib
*typelib
;
178 static ITypeInfo
*typeinfos
[LAST_tid
];
180 static REFIID tid_ids
[] = {
182 &IID_IGenScriptletTLib
,
185 static HRESULT
load_typelib(void)
193 hres
= LoadRegTypeLib(&LIBID_Scriptlet
, 1, 0, LOCALE_SYSTEM_DEFAULT
, &tl
);
196 ERR("LoadRegTypeLib failed: %08lx\n", hres
);
200 if (InterlockedCompareExchangePointer((void **)&typelib
, tl
, NULL
))
201 ITypeLib_Release(tl
);
205 static HRESULT
get_typeinfo(tid_t tid
, ITypeInfo
**typeinfo
)
209 if (FAILED(hres
= load_typelib()))
216 hres
= ITypeLib_GetTypeInfoOfGuid(typelib
, tid_ids
[tid
], &ti
);
218 ERR("GetTypeInfoOfGuid(%s) failed: %08lx\n", debugstr_guid(tid_ids
[tid
]), hres
);
222 if (InterlockedCompareExchangePointer((void **)(typeinfos
+tid
), ti
, NULL
))
223 ITypeInfo_Release(ti
);
226 *typeinfo
= typeinfos
[tid
];
227 ITypeInfo_AddRef(typeinfos
[tid
]);
231 static void release_typelib(void)
238 for (i
= 0; i
< ARRAY_SIZE(typeinfos
); i
++)
240 ITypeInfo_Release(typeinfos
[i
]);
242 ITypeLib_Release(typelib
);
245 static inline struct scriptlet_global
*global_from_IDispatchEx(IDispatchEx
*iface
)
247 return CONTAINING_RECORD(iface
, struct scriptlet_global
, IDispatchEx_iface
);
250 static HRESULT WINAPI
global_QueryInterface(IDispatchEx
*iface
, REFIID riid
, void **ppv
)
252 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
254 if (IsEqualGUID(&IID_IUnknown
, riid
))
256 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
257 *ppv
= &This
->IDispatchEx_iface
;
259 else if (IsEqualGUID(&IID_IDispatch
, riid
))
261 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
262 *ppv
= &This
->IDispatchEx_iface
;
264 else if (IsEqualGUID(&IID_IDispatchEx
, riid
))
266 TRACE("(%p)->(IID_IDispatchEx %p)\n", This
, ppv
);
267 *ppv
= &This
->IDispatchEx_iface
;
271 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
273 return E_NOINTERFACE
;
276 IUnknown_AddRef((IUnknown
*)*ppv
);
280 static ULONG WINAPI
global_AddRef(IDispatchEx
*iface
)
282 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
283 ULONG ref
= InterlockedIncrement(&This
->ref
);
285 TRACE("(%p) ref=%ld\n", This
, ref
);
290 static ULONG WINAPI
global_Release(IDispatchEx
*iface
)
292 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
293 ULONG ref
= InterlockedDecrement(&This
->ref
);
295 TRACE("(%p) ref=%ld\n", This
, ref
);
297 if (!ref
) free(This
);
302 static HRESULT WINAPI
global_GetTypeInfoCount(IDispatchEx
*iface
, UINT
*pctinfo
)
304 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
305 FIXME("(%p)->(%p)\n", This
, pctinfo
);
309 static HRESULT WINAPI
global_GetTypeInfo(IDispatchEx
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
311 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
312 FIXME("(%p)->(%u %lu %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
316 static HRESULT WINAPI
global_GetIDsOfNames(IDispatchEx
*iface
, REFIID riid
,
317 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
319 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
323 TRACE("(%p)->(%s %p %u %lu %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
325 for(i
=0; i
< cNames
; i
++)
327 hres
= IDispatchEx_GetDispID(&This
->IDispatchEx_iface
, rgszNames
[i
], 0, rgDispId
+ i
);
335 static HRESULT WINAPI
global_Invoke(IDispatchEx
*iface
, DISPID dispIdMember
,
336 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
337 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
339 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
340 TRACE("(%p)->(%ld %s %ld %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
341 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
342 return IDispatchEx_InvokeEx(&This
->IDispatchEx_iface
, dispIdMember
, lcid
, wFlags
,
343 pDispParams
, pVarResult
, pExcepInfo
, NULL
);
346 static HRESULT WINAPI
global_GetDispID(IDispatchEx
*iface
, BSTR bstrName
, DWORD grfdex
, DISPID
*pid
)
348 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
349 FIXME("(%p)->(%s %lx %p)\n", This
, debugstr_w(bstrName
), grfdex
, pid
);
353 static HRESULT WINAPI
global_InvokeEx(IDispatchEx
*iface
, DISPID id
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pdp
,
354 VARIANT
*pvarRes
, EXCEPINFO
*pei
, IServiceProvider
*pspCaller
)
356 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
357 FIXME("(%p)->(%lx %lx %x %p %p %p %p)\n", This
, id
, lcid
, wFlags
, pdp
, pvarRes
, pei
, pspCaller
);
361 static HRESULT WINAPI
global_DeleteMemberByName(IDispatchEx
*iface
, BSTR bstrName
, DWORD grfdex
)
363 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
364 FIXME("(%p)->(%s %lx)\n", This
, debugstr_w(bstrName
), grfdex
);
368 static HRESULT WINAPI
global_DeleteMemberByDispID(IDispatchEx
*iface
, DISPID id
)
370 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
371 FIXME("(%p)->(%lx)\n", This
, id
);
375 static HRESULT WINAPI
global_GetMemberProperties(IDispatchEx
*iface
, DISPID id
, DWORD grfdexFetch
, DWORD
*pgrfdex
)
377 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
378 FIXME("(%p)->(%lx %lx %p)\n", This
, id
, grfdexFetch
, pgrfdex
);
382 static HRESULT WINAPI
global_GetMemberName(IDispatchEx
*iface
, DISPID id
, BSTR
*pbstrName
)
384 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
385 FIXME("(%p)->(%lx %p)\n", This
, id
, pbstrName
);
389 static HRESULT WINAPI
global_GetNextDispID(IDispatchEx
*iface
, DWORD grfdex
, DISPID id
, DISPID
*pid
)
391 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
392 FIXME("(%p)->(%lx %lx %p)\n", This
, grfdex
, id
, pid
);
396 static HRESULT WINAPI
global_GetNameSpaceParent(IDispatchEx
*iface
, IUnknown
**ppunk
)
398 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
399 FIXME("(%p)->(%p)\n", This
, ppunk
);
403 static IDispatchExVtbl global_vtbl
= {
404 global_QueryInterface
,
407 global_GetTypeInfoCount
,
409 global_GetIDsOfNames
,
413 global_DeleteMemberByName
,
414 global_DeleteMemberByDispID
,
415 global_GetMemberProperties
,
416 global_GetMemberName
,
417 global_GetNextDispID
,
418 global_GetNameSpaceParent
421 static HRESULT
set_script_state(struct script_host
*host
, SCRIPTSTATE state
)
424 if (state
== host
->state
) return S_OK
;
425 hres
= IActiveScript_SetScriptState(host
->active_script
, state
);
426 if (FAILED(hres
)) return hres
;
431 static inline struct script_host
*impl_from_IActiveScriptSite(IActiveScriptSite
*iface
)
433 return CONTAINING_RECORD(iface
, struct script_host
, IActiveScriptSite_iface
);
436 static HRESULT WINAPI
ActiveScriptSite_QueryInterface(IActiveScriptSite
*iface
, REFIID riid
, void **ppv
)
438 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
440 if (IsEqualGUID(&IID_IUnknown
, riid
))
442 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
443 *ppv
= &This
->IActiveScriptSite_iface
;
445 else if (IsEqualGUID(&IID_IActiveScriptSite
, riid
))
447 TRACE("(%p)->(IID_IActiveScriptSite %p)\n", This
, ppv
);
448 *ppv
= &This
->IActiveScriptSite_iface
;
450 else if (IsEqualGUID(&IID_IActiveScriptSiteWindow
, riid
))
452 TRACE("(%p)->(IID_IActiveScriptSiteWindow %p)\n", This
, ppv
);
453 *ppv
= &This
->IActiveScriptSiteWindow_iface
;
455 else if(IsEqualGUID(&IID_IServiceProvider
, riid
))
457 TRACE("(%p)->(IID_IServiceProvider %p)\n", This
, ppv
);
458 *ppv
= &This
->IServiceProvider_iface
;
462 WARN("(%p)->(%s %p) interface not supported\n", This
, debugstr_guid(riid
), ppv
);
464 return E_NOINTERFACE
;
467 IUnknown_AddRef((IUnknown
*)*ppv
);
471 static ULONG WINAPI
ActiveScriptSite_AddRef(IActiveScriptSite
*iface
)
473 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
474 LONG ref
= InterlockedIncrement(&This
->ref
);
476 TRACE("(%p) ref=%ld\n", This
, ref
);
481 static ULONG WINAPI
ActiveScriptSite_Release(IActiveScriptSite
*iface
)
483 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
484 LONG ref
= InterlockedDecrement(&This
->ref
);
486 TRACE("(%p) ref=%ld\n", This
, ref
);
489 free(This
->language
);
496 static HRESULT WINAPI
ActiveScriptSite_GetLCID(IActiveScriptSite
*iface
, LCID
*lcid
)
498 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
500 TRACE("(%p, %p)\n", This
, lcid
);
502 *lcid
= GetUserDefaultLCID();
506 static HRESULT WINAPI
ActiveScriptSite_GetItemInfo(IActiveScriptSite
*iface
, LPCOLESTR name
, DWORD mask
,
507 IUnknown
**unk
, ITypeInfo
**ti
)
509 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
511 TRACE("(%p, %s, %#lx, %p, %p)\n", This
, debugstr_w(name
), mask
, unk
, ti
);
513 if (mask
!= SCRIPTINFO_IUNKNOWN
)
515 FIXME("mask %lx not supported\n", mask
);
519 if (wcscmp(name
, L
"scriptlet") && wcscmp(name
, L
"globals"))
521 FIXME("%s not supported\n", debugstr_w(name
));
525 if (!This
->object
) return E_UNEXPECTED
;
527 *unk
= (IUnknown
*)&This
->object
->global
->IDispatchEx_iface
;
528 IUnknown_AddRef(*unk
);
532 static HRESULT WINAPI
ActiveScriptSite_GetDocVersionString(IActiveScriptSite
*iface
, BSTR
*version
)
534 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
535 FIXME("(%p, %p)\n", This
, version
);
539 static HRESULT WINAPI
ActiveScriptSite_OnScriptTerminate(IActiveScriptSite
*iface
, const VARIANT
*result
,
542 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
543 FIXME("(%p, %s, %p)\n", This
, debugstr_variant(result
), ei
);
547 static HRESULT WINAPI
ActiveScriptSite_OnStateChange(IActiveScriptSite
*iface
, SCRIPTSTATE state
)
549 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
550 TRACE("(%p, %d)\n", This
, state
);
554 static HRESULT WINAPI
ActiveScriptSite_OnScriptError(IActiveScriptSite
*iface
, IActiveScriptError
*script_error
)
556 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
557 FIXME("(%p, %p)\n", This
, script_error
);
561 static HRESULT WINAPI
ActiveScriptSite_OnEnterScript(IActiveScriptSite
*iface
)
563 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
564 TRACE("(%p)\n", This
);
568 static HRESULT WINAPI
ActiveScriptSite_OnLeaveScript(IActiveScriptSite
*iface
)
570 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
571 TRACE("(%p)\n", This
);
575 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl
= {
576 ActiveScriptSite_QueryInterface
,
577 ActiveScriptSite_AddRef
,
578 ActiveScriptSite_Release
,
579 ActiveScriptSite_GetLCID
,
580 ActiveScriptSite_GetItemInfo
,
581 ActiveScriptSite_GetDocVersionString
,
582 ActiveScriptSite_OnScriptTerminate
,
583 ActiveScriptSite_OnStateChange
,
584 ActiveScriptSite_OnScriptError
,
585 ActiveScriptSite_OnEnterScript
,
586 ActiveScriptSite_OnLeaveScript
589 static inline struct script_host
*impl_from_IActiveScriptSiteWindow(IActiveScriptSiteWindow
*iface
)
591 return CONTAINING_RECORD(iface
, struct script_host
, IActiveScriptSiteWindow_iface
);
594 static HRESULT WINAPI
ActiveScriptSiteWindow_QueryInterface(IActiveScriptSiteWindow
*iface
, REFIID riid
, void **obj
)
596 struct script_host
*This
= impl_from_IActiveScriptSiteWindow(iface
);
597 return IActiveScriptSite_QueryInterface(&This
->IActiveScriptSite_iface
, riid
, obj
);
600 static ULONG WINAPI
ActiveScriptSiteWindow_AddRef(IActiveScriptSiteWindow
*iface
)
602 struct script_host
*This
= impl_from_IActiveScriptSiteWindow(iface
);
603 return IActiveScriptSite_AddRef(&This
->IActiveScriptSite_iface
);
606 static ULONG WINAPI
ActiveScriptSiteWindow_Release(IActiveScriptSiteWindow
*iface
)
608 struct script_host
*This
= impl_from_IActiveScriptSiteWindow(iface
);
609 return IActiveScriptSite_Release(&This
->IActiveScriptSite_iface
);
612 static HRESULT WINAPI
ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow
*iface
, HWND
*hwnd
)
614 struct script_host
*This
= impl_from_IActiveScriptSiteWindow(iface
);
615 FIXME("(%p, %p)\n", This
, hwnd
);
619 static HRESULT WINAPI
ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWindow
*iface
, BOOL enable
)
621 struct script_host
*This
= impl_from_IActiveScriptSiteWindow(iface
);
622 FIXME("(%p, %d)\n", This
, enable
);
626 static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl
= {
627 ActiveScriptSiteWindow_QueryInterface
,
628 ActiveScriptSiteWindow_AddRef
,
629 ActiveScriptSiteWindow_Release
,
630 ActiveScriptSiteWindow_GetWindow
,
631 ActiveScriptSiteWindow_EnableModeless
634 static inline struct script_host
*impl_from_IServiceProvider(IServiceProvider
*iface
)
636 return CONTAINING_RECORD(iface
, struct script_host
, IServiceProvider_iface
);
639 static HRESULT WINAPI
ServiceProvider_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **obj
)
641 struct script_host
*This
= impl_from_IServiceProvider(iface
);
642 return IActiveScriptSite_QueryInterface(&This
->IActiveScriptSite_iface
, riid
, obj
);
645 static ULONG WINAPI
ServiceProvider_AddRef(IServiceProvider
*iface
)
647 struct script_host
*This
= impl_from_IServiceProvider(iface
);
648 return IActiveScriptSite_AddRef(&This
->IActiveScriptSite_iface
);
651 static ULONG WINAPI
ServiceProvider_Release(IServiceProvider
*iface
)
653 struct script_host
*This
= impl_from_IServiceProvider(iface
);
654 return IActiveScriptSite_Release(&This
->IActiveScriptSite_iface
);
657 static HRESULT WINAPI
ServiceProvider_QueryService(IServiceProvider
*iface
, REFGUID service
,
658 REFIID riid
, void **obj
)
660 struct script_host
*This
= impl_from_IServiceProvider(iface
);
661 FIXME("(%p)->(%s %s %p)\n", This
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
665 static const IServiceProviderVtbl ServiceProviderVtbl
= {
666 ServiceProvider_QueryInterface
,
667 ServiceProvider_AddRef
,
668 ServiceProvider_Release
,
669 ServiceProvider_QueryService
672 static struct script_host
*find_script_host(struct list
*hosts
, const WCHAR
*language
)
674 struct script_host
*host
;
675 LIST_FOR_EACH_ENTRY(host
, hosts
, struct script_host
, entry
)
677 if (!wcscmp(host
->language
, language
)) return host
;
682 static HRESULT
parse_scripts(struct scriptlet_factory
*factory
, struct list
*hosts
, BOOL start
)
684 DWORD parse_flags
= SCRIPTTEXT_ISVISIBLE
;
685 struct scriptlet_script
*script
;
686 struct script_host
*host
;
689 if (!start
) parse_flags
|= SCRIPTITEM_ISPERSISTENT
;
691 LIST_FOR_EACH_ENTRY(script
, &factory
->scripts
, struct scriptlet_script
, entry
)
693 host
= find_script_host(hosts
, script
->language
);
695 if (start
&& host
->state
!= SCRIPTSTATE_STARTED
)
697 hres
= set_script_state(host
, SCRIPTSTATE_STARTED
);
698 if (FAILED(hres
)) return hres
;
701 if (host
->cloned
) continue;
703 hres
= IActiveScriptParse_ParseScriptText(host
->parser
, script
->body
, NULL
, NULL
, NULL
, 0, 0 /* FIXME */,
704 parse_flags
, NULL
, NULL
);
707 WARN("ParseScriptText failed: %08lx\n", hres
);
713 LIST_FOR_EACH_ENTRY(host
, hosts
, struct script_host
, entry
)
715 if (host
->state
!= SCRIPTSTATE_UNINITIALIZED
)
716 set_script_state(host
, SCRIPTSTATE_UNINITIALIZED
);
722 static HRESULT
lookup_script_properties(struct scriptlet_instance
*object
, BSTR name
, struct script_reference
*ret
)
724 struct script_host
*host
;
727 LIST_FOR_EACH_ENTRY(host
, &object
->hosts
, struct script_host
, entry
)
729 hres
= IDispatchEx_GetDispID(host
->script_dispatch
, name
, 0, &ret
->id
);
730 if (FAILED(hres
)) continue;
735 FIXME("Could not find %s in scripts\n", debugstr_w(name
));
739 static HRESULT
lookup_object_properties(struct scriptlet_instance
*object
, struct scriptlet_factory
*factory
)
741 struct scriptlet_member
*member
;
742 unsigned i
= 0, member_cnt
= 0;
747 LIST_FOR_EACH_ENTRY(member
, &factory
->members
, struct scriptlet_member
, entry
)
750 if (!member_cnt
) return S_OK
;
752 if (!(object
->members
= calloc(member_cnt
, sizeof(*object
->members
))))
753 return E_OUTOFMEMORY
;
754 object
->member_cnt
= member_cnt
;
756 LIST_FOR_EACH_ENTRY(member
, &factory
->members
, struct scriptlet_member
, entry
)
758 object
->members
[i
].type
= member
->type
;
759 if (!(object
->members
[i
].name
= SysAllocString(member
->name
))) return E_OUTOFMEMORY
;
760 switch (member
->type
)
763 hres
= lookup_script_properties(object
, object
->members
[i
].name
, &object
->members
[i
].u
.method
);
764 if (FAILED(hres
)) return hres
;
766 case MEMBER_PROPERTY
:
767 len
= wcslen(member
->name
);
768 if (!(name
= SysAllocStringLen(NULL
, len
+ 4))) return E_OUTOFMEMORY
;
769 wcscpy(name
, L
"get_");
770 wcscat(name
, member
->name
);
771 hres
= lookup_script_properties(object
, name
, &object
->members
[i
].u
.property
.get
);
774 memcpy(name
, L
"put", 3 * sizeof(WCHAR
));
775 hres
= lookup_script_properties(object
, name
, &object
->members
[i
].u
.property
.put
);
778 if (FAILED(hres
)) return hres
;
787 static HRESULT
init_script_host(struct script_host
*host
, IActiveScript
*clone
)
793 IClassFactoryEx
*factory_ex
;
794 IClassFactory
*factory
;
798 if (FAILED(hres
= CLSIDFromProgID(host
->language
, &clsid
)))
800 WARN("Could not find script engine for %s\n", debugstr_w(host
->language
));
804 hres
= CoGetClassObject(&clsid
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
, NULL
,
805 &IID_IClassFactory
, (void**)&factory
);
806 if (FAILED(hres
)) return hres
;
808 hres
= IClassFactory_QueryInterface(factory
, &IID_IClassFactoryEx
, (void**)&factory_ex
);
811 FIXME("Use IClassFactoryEx\n");
812 IClassFactoryEx_Release(factory_ex
);
815 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IUnknown
, (void**)&unk
);
816 IClassFactory_Release(factory
);
817 if (FAILED(hres
)) return hres
;
819 hres
= IUnknown_QueryInterface(unk
, &IID_IActiveScript
, (void**)&host
->active_script
);
820 IUnknown_Release(unk
);
821 if (FAILED(hres
)) return hres
;
825 IActiveScript_AddRef(clone
);
826 host
->active_script
= clone
;
830 hres
= IActiveScript_QueryInterface(host
->active_script
, &IID_IActiveScriptParse
, (void**)&host
->parser
);
831 if (FAILED(hres
)) return hres
;
835 hres
= IActiveScriptParse_InitNew(host
->parser
);
838 IActiveScriptParse_Release(host
->parser
);
844 return IActiveScript_SetScriptSite(host
->active_script
, &host
->IActiveScriptSite_iface
);
847 static HRESULT
create_script_host(const WCHAR
*language
, IActiveScript
*origin_script
, struct list
*hosts
, struct script_host
**ret
)
849 IActiveScript
*clone
= NULL
;
850 struct script_host
*host
;
853 if (!(host
= calloc(1, sizeof(*host
))))
854 return E_OUTOFMEMORY
;
856 host
->IActiveScriptSite_iface
.lpVtbl
= &ActiveScriptSiteVtbl
;
857 host
->IActiveScriptSiteWindow_iface
.lpVtbl
= &ActiveScriptSiteWindowVtbl
;
858 host
->IServiceProvider_iface
.lpVtbl
= &ServiceProviderVtbl
;
860 host
->state
= SCRIPTSTATE_CLOSED
;
862 if (!(host
->language
= wcsdup(language
)))
864 IActiveScriptSite_Release(&host
->IActiveScriptSite_iface
);
865 return E_OUTOFMEMORY
;
870 hres
= IActiveScript_Clone(origin_script
, &clone
);
871 if (FAILED(hres
)) clone
= NULL
;
874 list_add_tail(hosts
, &host
->entry
);
875 hres
= init_script_host(host
, clone
);
876 if (clone
) IActiveScript_Release(clone
);
877 if (FAILED(hres
)) return hres
;
878 if (ret
) *ret
= host
;
882 static void detach_script_hosts(struct list
*hosts
)
884 while (!list_empty(hosts
))
886 struct script_host
*host
= LIST_ENTRY(list_head(hosts
), struct script_host
, entry
);
887 if (host
->state
!= SCRIPTSTATE_UNINITIALIZED
) set_script_state(host
, SCRIPTSTATE_UNINITIALIZED
);
888 list_remove(&host
->entry
);
890 if (host
->script_dispatch
)
892 IDispatchEx_Release(host
->script_dispatch
);
893 host
->script_dispatch
= NULL
;
897 IActiveScript_Close(host
->active_script
);
898 IActiveScriptParse_Release(host
->parser
);
901 if (host
->active_script
)
903 IActiveScript_Release(host
->active_script
);
904 host
->active_script
= NULL
;
906 IActiveScriptSite_Release(&host
->IActiveScriptSite_iface
);
910 static HRESULT
create_scriptlet_hosts(struct scriptlet_factory
*factory
, struct list
*hosts
)
912 struct scriptlet_script
*script
;
915 LIST_FOR_EACH_ENTRY(script
, &factory
->scripts
, struct scriptlet_script
, entry
)
917 if (find_script_host(hosts
, script
->language
)) continue;
918 hres
= create_script_host(script
->language
, NULL
, hosts
, NULL
);
921 detach_script_hosts(hosts
);
929 static inline struct scriptlet_instance
*impl_from_IDispatchEx(IDispatchEx
*iface
)
931 return CONTAINING_RECORD(iface
, struct scriptlet_instance
, IDispatchEx_iface
);
934 static HRESULT WINAPI
scriptlet_QueryInterface(IDispatchEx
*iface
, REFIID riid
, void **ppv
)
936 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
938 if (IsEqualGUID(&IID_IUnknown
, riid
))
940 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
941 *ppv
= &This
->IDispatchEx_iface
;
943 else if (IsEqualGUID(&IID_IDispatch
, riid
))
945 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
946 *ppv
= &This
->IDispatchEx_iface
;
948 else if (IsEqualGUID(&IID_IDispatchEx
, riid
))
950 TRACE("(%p)->(IID_IDispatchEx %p)\n", This
, ppv
);
951 *ppv
= &This
->IDispatchEx_iface
;
955 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
957 return E_NOINTERFACE
;
960 IUnknown_AddRef((IUnknown
*)*ppv
);
964 static ULONG WINAPI
scriptlet_AddRef(IDispatchEx
*iface
)
966 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
967 ULONG ref
= InterlockedIncrement(&This
->ref
);
969 TRACE("(%p) ref=%ld\n", This
, ref
);
974 static ULONG WINAPI
scriptlet_Release(IDispatchEx
*iface
)
976 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
977 ULONG ref
= InterlockedDecrement(&This
->ref
);
979 TRACE("(%p) ref=%ld\n", This
, ref
);
984 for (i
= 0; i
< This
->member_cnt
; i
++)
985 SysFreeString(This
->members
[i
].name
);
987 detach_script_hosts(&This
->hosts
);
988 if (This
->global
) IDispatchEx_Release(&This
->global
->IDispatchEx_iface
);
994 static HRESULT WINAPI
scriptlet_GetTypeInfoCount(IDispatchEx
*iface
, UINT
*pctinfo
)
996 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
997 FIXME("(%p)->(%p)\n", This
, pctinfo
);
1001 static HRESULT WINAPI
scriptlet_GetTypeInfo(IDispatchEx
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1003 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1004 FIXME("(%p)->(%u %lu %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1008 static HRESULT WINAPI
scriptlet_GetIDsOfNames(IDispatchEx
*iface
, REFIID riid
,
1009 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1011 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1015 TRACE("(%p)->(%s %p %u %lu %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
1018 for(i
=0; i
< cNames
; i
++)
1020 hres
= IDispatchEx_GetDispID(&This
->IDispatchEx_iface
, rgszNames
[i
], 0, rgDispId
+ i
);
1028 static HRESULT WINAPI
scriptlet_Invoke(IDispatchEx
*iface
, DISPID dispIdMember
,
1029 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
1030 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1032 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1033 TRACE("(%p)->(%ld %s %ld %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1034 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1035 return IDispatchEx_InvokeEx(&This
->IDispatchEx_iface
, dispIdMember
, lcid
, wFlags
,
1036 pDispParams
, pVarResult
, pExcepInfo
, NULL
);
1039 static HRESULT WINAPI
scriptlet_GetDispID(IDispatchEx
*iface
, BSTR bstrName
, DWORD grfdex
, DISPID
*pid
)
1041 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1044 TRACE("(%p)->(%s %lx %p)\n", This
, debugstr_w(bstrName
), grfdex
, pid
);
1046 if (grfdex
& ~(fdexNameCaseInsensitive
|fdexNameCaseSensitive
))
1047 FIXME("Unsupported grfdex %lx\n", grfdex
);
1049 for (i
= 0; i
< This
->member_cnt
; i
++)
1051 if (grfdex
& fdexNameCaseInsensitive
)
1053 if (wcsicmp(This
->members
[i
].name
, bstrName
)) continue;
1055 else if (wcscmp(This
->members
[i
].name
, bstrName
)) continue;
1060 WARN("Unknown property %s\n", debugstr_w(bstrName
));
1061 return DISP_E_UNKNOWNNAME
;
1064 static HRESULT WINAPI
scriptlet_InvokeEx(IDispatchEx
*iface
, DISPID id
, LCID lcid
, WORD flags
, DISPPARAMS
*pdp
,
1065 VARIANT
*res
, EXCEPINFO
*pei
, IServiceProvider
*caller
)
1067 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1068 struct object_member
*member
;
1070 TRACE("(%p)->(%lx %lx %x %p %p %p %p)\n", This
, id
, lcid
, flags
, pdp
, res
, pei
, caller
);
1072 if (id
< 1 || id
> This
->member_cnt
)
1074 WARN("Unknown id %lxu\n", id
);
1075 return DISP_E_MEMBERNOTFOUND
;
1077 member
= &This
->members
[id
- 1];
1079 switch (member
->type
)
1082 if ((flags
& ~DISPATCH_PROPERTYGET
) != DISPATCH_METHOD
)
1084 FIXME("unsupported method flags %x\n", flags
);
1085 return DISP_E_MEMBERNOTFOUND
;
1087 return IDispatchEx_InvokeEx(member
->u
.method
.host
->script_dispatch
, member
->u
.method
.id
, lcid
,
1088 DISPATCH_METHOD
, pdp
, res
, pei
, caller
);
1089 case MEMBER_PROPERTY
:
1090 if (flags
& DISPATCH_PROPERTYGET
)
1092 if (!member
->u
.property
.get
.host
)
1094 FIXME("No %s getter\n", debugstr_w(member
->name
));
1095 return DISP_E_MEMBERNOTFOUND
;
1097 return IDispatchEx_InvokeEx(member
->u
.property
.get
.host
->script_dispatch
, member
->u
.property
.get
.id
, lcid
,
1098 DISPATCH_METHOD
, pdp
, res
, pei
, caller
);
1100 if (flags
& DISPATCH_PROPERTYPUT
)
1104 if (!member
->u
.property
.put
.host
)
1106 FIXME("No %s setter\n", debugstr_w(member
->name
));
1107 return DISP_E_MEMBERNOTFOUND
;
1109 if (pdp
->cNamedArgs
!= 1 || pdp
->rgdispidNamedArgs
[0] != DISPID_PROPERTYPUT
)
1111 FIXME("no propput argument\n");
1116 return IDispatchEx_InvokeEx(member
->u
.property
.put
.host
->script_dispatch
, member
->u
.property
.put
.id
, lcid
,
1117 DISPATCH_METHOD
, &dp
, res
, pei
, caller
);
1120 FIXME("unsupported flags %x\n", flags
);
1123 return DISP_E_MEMBERNOTFOUND
;
1126 static HRESULT WINAPI
scriptlet_DeleteMemberByName(IDispatchEx
*iface
, BSTR bstrName
, DWORD grfdex
)
1128 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1129 FIXME("(%p)->(%s %lx)\n", This
, debugstr_w(bstrName
), grfdex
);
1133 static HRESULT WINAPI
scriptlet_DeleteMemberByDispID(IDispatchEx
*iface
, DISPID id
)
1135 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1136 FIXME("(%p)->(%lx)\n", This
, id
);
1140 static HRESULT WINAPI
scriptlet_GetMemberProperties(IDispatchEx
*iface
, DISPID id
, DWORD grfdexFetch
, DWORD
*pgrfdex
)
1142 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1143 FIXME("(%p)->(%lx %lx %p)\n", This
, id
, grfdexFetch
, pgrfdex
);
1147 static HRESULT WINAPI
scriptlet_GetMemberName(IDispatchEx
*iface
, DISPID id
, BSTR
*pbstrName
)
1149 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1150 FIXME("(%p)->(%lx %p)\n", This
, id
, pbstrName
);
1154 static HRESULT WINAPI
scriptlet_GetNextDispID(IDispatchEx
*iface
, DWORD grfdex
, DISPID id
, DISPID
*pid
)
1156 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1157 FIXME("(%p)->(%lx %lx %p)\n", This
, grfdex
, id
, pid
);
1161 static HRESULT WINAPI
scriptlet_GetNameSpaceParent(IDispatchEx
*iface
, IUnknown
**ppunk
)
1163 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1164 FIXME("(%p)->(%p)\n", This
, ppunk
);
1168 static IDispatchExVtbl DispatchExVtbl
= {
1169 scriptlet_QueryInterface
,
1172 scriptlet_GetTypeInfoCount
,
1173 scriptlet_GetTypeInfo
,
1174 scriptlet_GetIDsOfNames
,
1176 scriptlet_GetDispID
,
1178 scriptlet_DeleteMemberByName
,
1179 scriptlet_DeleteMemberByDispID
,
1180 scriptlet_GetMemberProperties
,
1181 scriptlet_GetMemberName
,
1182 scriptlet_GetNextDispID
,
1183 scriptlet_GetNameSpaceParent
1186 static HRESULT
create_scriptlet_instance(struct scriptlet_factory
*factory
, IDispatchEx
**disp
)
1188 struct script_host
*factory_host
, *host
;
1189 struct scriptlet_instance
*obj
;
1190 IDispatch
*script_dispatch
;
1191 HRESULT hres
= S_OK
;
1193 if (!(obj
= calloc(1, sizeof(*obj
))))
1194 return E_OUTOFMEMORY
;
1196 obj
->IDispatchEx_iface
.lpVtbl
= &DispatchExVtbl
;
1198 list_init(&obj
->hosts
);
1200 if (!(obj
->global
= malloc(sizeof(*obj
->global
))))
1202 IDispatchEx_Release(&obj
->IDispatchEx_iface
);
1203 return E_OUTOFMEMORY
;
1205 obj
->global
->IDispatchEx_iface
.lpVtbl
= &global_vtbl
;
1206 obj
->global
->ref
= 1;
1208 LIST_FOR_EACH_ENTRY(factory_host
, &factory
->hosts
, struct script_host
, entry
)
1210 hres
= create_script_host(factory_host
->language
, factory_host
->active_script
, &obj
->hosts
, &host
);
1211 if (FAILED(hres
)) break;
1214 hres
= IActiveScript_AddNamedItem(host
->active_script
, L
"scriptlet",
1215 SCRIPTITEM_ISVISIBLE
| SCRIPTITEM_GLOBALMEMBERS
);
1216 if (FAILED(hres
)) break;
1218 hres
= IActiveScript_AddNamedItem(host
->active_script
, L
"globals", SCRIPTITEM_ISVISIBLE
);
1219 if (FAILED(hres
)) break;
1221 hres
= IActiveScript_GetScriptDispatch(host
->active_script
, NULL
, &script_dispatch
);
1222 if (FAILED(hres
)) return hres
;
1224 hres
= IDispatch_QueryInterface(script_dispatch
, &IID_IDispatchEx
, (void**)&host
->script_dispatch
);
1225 IDispatch_Release(script_dispatch
);
1228 FIXME("IDispatchEx not supported by script engine\n");
1233 if (SUCCEEDED(hres
)) hres
= parse_scripts(factory
, &obj
->hosts
, TRUE
);
1234 if (SUCCEEDED(hres
)) hres
= lookup_object_properties(obj
, factory
);
1237 IDispatchEx_Release(&obj
->IDispatchEx_iface
);
1241 *disp
= &obj
->IDispatchEx_iface
;
1245 static const char *debugstr_xml_name(struct scriptlet_factory
*factory
)
1250 hres
= IXmlReader_GetLocalName(factory
->xml_reader
, &str
, &len
);
1251 if (FAILED(hres
)) return "#err";
1252 return debugstr_wn(str
, len
);
1255 static HRESULT
next_xml_node(struct scriptlet_factory
*factory
, XmlNodeType
*node_type
)
1260 hres
= IXmlReader_Read(factory
->xml_reader
, node_type
);
1261 if (FAILED(hres
)) break;
1262 if (*node_type
== XmlNodeType_Whitespace
) continue;
1263 if (*node_type
== XmlNodeType_ProcessingInstruction
)
1265 FIXME("Ignoring processing instruction\n");
1273 static BOOL
is_xml_name(struct scriptlet_factory
*factory
, const WCHAR
*name
)
1278 hres
= IXmlReader_GetQualifiedName(factory
->xml_reader
, &qname
, &len
);
1279 return hres
== S_OK
&& len
== wcslen(name
) && !memcmp(qname
, name
, len
* sizeof(WCHAR
));
1282 static HRESULT
expect_end_element(struct scriptlet_factory
*factory
)
1284 XmlNodeType node_type
;
1286 hres
= next_xml_node(factory
, &node_type
);
1287 if (hres
!= S_OK
|| node_type
!= XmlNodeType_EndElement
)
1289 FIXME("Unexpected node %u %s\n", node_type
, debugstr_xml_name(factory
));
1295 static HRESULT
expect_no_attributes(struct scriptlet_factory
*factory
)
1299 hres
= IXmlReader_GetAttributeCount(factory
->xml_reader
, &count
);
1300 if (FAILED(hres
)) return hres
;
1301 if (!count
) return S_OK
;
1302 FIXME("Unexpected attributes\n");
1306 static BOOL
is_case_xml_name(struct scriptlet_factory
*factory
, const WCHAR
*name
)
1311 hres
= IXmlReader_GetQualifiedName(factory
->xml_reader
, &qname
, &len
);
1312 return hres
== S_OK
&& len
== wcslen(name
) && !memicmp(qname
, name
, len
* sizeof(WCHAR
));
1315 static HRESULT
read_xml_value(struct scriptlet_factory
*factory
, WCHAR
**ret
)
1320 hres
= IXmlReader_GetValue(factory
->xml_reader
, &str
, &len
);
1321 if (FAILED(hres
)) return hres
;
1322 if (!(*ret
= malloc((len
+ 1) * sizeof(WCHAR
)))) return E_OUTOFMEMORY
;
1323 memcpy(*ret
, str
, len
* sizeof(WCHAR
));
1328 static HRESULT
parse_scriptlet_registration(struct scriptlet_factory
*factory
)
1334 if (factory
->have_registration
)
1336 FIXME("duplicated registration element\n");
1339 factory
->have_registration
= TRUE
;
1343 hres
= IXmlReader_MoveToNextAttribute(factory
->xml_reader
);
1344 if (hres
!= S_OK
) break;
1346 if (is_xml_name(factory
, L
"description"))
1348 if (factory
->description
)
1350 FIXME("Duplicated description\n");
1353 hres
= read_xml_value(factory
, &factory
->description
);
1354 if (FAILED(hres
)) return hres
;
1356 else if (is_case_xml_name(factory
, L
"progid"))
1358 if (factory
->progid
)
1360 FIXME("Duplicated progid\n");
1363 hres
= read_xml_value(factory
, &factory
->progid
);
1364 if (FAILED(hres
)) return hres
;
1366 else if (is_xml_name(factory
, L
"version"))
1368 if (factory
->version
)
1370 FIXME("Duplicated version\n");
1373 hres
= read_xml_value(factory
, &factory
->version
);
1374 if (FAILED(hres
)) return hres
;
1376 else if (is_xml_name(factory
, L
"classid"))
1378 if (factory
->classid_str
)
1380 FIXME("Duplicated classid attribute\n");
1383 hres
= read_xml_value(factory
, &factory
->classid_str
);
1384 if (FAILED(hres
)) return hres
;
1385 hres
= IIDFromString(factory
->classid_str
, &factory
->classid
);
1388 FIXME("Invalid classid %s\n", debugstr_w(factory
->classid_str
));
1395 FIXME("Unexpected attribute\n");
1400 if (!factory
->progid
&& !factory
->classid_str
)
1402 FIXME("Incomplet registration element\n");
1406 if (factory
->progid
)
1408 size_t progid_len
= wcslen(factory
->progid
);
1409 size_t version_len
= wcslen(factory
->version
);
1411 if (!(factory
->versioned_progid
= malloc((progid_len
+ version_len
+ 2) * sizeof(WCHAR
))))
1412 return E_OUTOFMEMORY
;
1414 memcpy(factory
->versioned_progid
, factory
->progid
, (progid_len
+ 1) * sizeof(WCHAR
));
1417 factory
->versioned_progid
[progid_len
++] = '.';
1418 wcscpy(factory
->versioned_progid
+ progid_len
, factory
->version
);
1420 else factory
->versioned_progid
[progid_len
] = 0;
1423 return expect_end_element(factory
);
1426 static HRESULT
parse_scriptlet_public(struct scriptlet_factory
*factory
)
1428 struct scriptlet_member
*member
, *member_iter
;
1429 enum member_type member_type
;
1430 XmlNodeType node_type
;
1436 if (factory
->have_public
)
1438 FIXME("duplicated public element\n");
1441 factory
->have_public
= TRUE
;
1445 hres
= next_xml_node(factory
, &node_type
);
1446 if (FAILED(hres
)) return hres
;
1447 if (node_type
== XmlNodeType_EndElement
) break;
1448 if (node_type
!= XmlNodeType_Element
)
1450 FIXME("Unexpected node type %u\n", node_type
);
1454 if (is_xml_name(factory
, L
"method"))
1455 member_type
= MEMBER_METHOD
;
1456 else if (is_xml_name(factory
, L
"property"))
1457 member_type
= MEMBER_PROPERTY
;
1460 FIXME("Unexpected element %s\n", debugstr_xml_name(factory
));
1464 empty
= IXmlReader_IsEmptyElement(factory
->xml_reader
);
1466 hres
= IXmlReader_MoveToAttributeByName(factory
->xml_reader
, L
"name", NULL
);
1469 FIXME("Missing method name\n");
1473 if (!(member
= malloc(sizeof(*member
)))) return E_OUTOFMEMORY
;
1474 member
->type
= member_type
;
1476 hres
= read_xml_value(factory
, &member
->name
);
1483 LIST_FOR_EACH_ENTRY(member_iter
, &factory
->members
, struct scriptlet_member
, entry
)
1485 if (!wcsicmp(member_iter
->name
, member
->name
))
1487 FIXME("Duplicated member %s\n", debugstr_w(member
->name
));
1492 list_add_tail(&factory
->members
, &member
->entry
);
1494 switch (member_type
)
1497 list_init(&member
->u
.parameters
);
1502 struct method_parameter
*parameter
;
1504 hres
= next_xml_node(factory
, &node_type
);
1505 if (FAILED(hres
)) return hres
;
1506 if (node_type
== XmlNodeType_EndElement
) break;
1507 if (node_type
!= XmlNodeType_Element
)
1509 FIXME("Unexpected node type %u\n", node_type
);
1512 if (!is_case_xml_name(factory
, L
"parameter"))
1514 FIXME("Unexpected method element\n");
1518 empty
= IXmlReader_IsEmptyElement(factory
->xml_reader
);
1520 hres
= IXmlReader_MoveToAttributeByName(factory
->xml_reader
, L
"name", NULL
);
1523 FIXME("Missing parameter name\n");
1527 if (!(parameter
= calloc(1, sizeof(*parameter
)))) return E_OUTOFMEMORY
;
1528 list_add_tail(&member
->u
.parameters
, ¶meter
->entry
);
1530 hres
= read_xml_value(factory
, ¶meter
->name
);
1531 if (FAILED(hres
)) return hres
;
1532 if (!empty
&& FAILED(hres
= expect_end_element(factory
))) return hres
;
1536 case MEMBER_PROPERTY
:
1537 member
->u
.flags
= 0;
1542 hres
= next_xml_node(factory
, &node_type
);
1543 if (FAILED(hres
)) return hres
;
1544 if (node_type
== XmlNodeType_EndElement
) break;
1545 if (node_type
!= XmlNodeType_Element
)
1547 FIXME("Unexpected node type %u\n", node_type
);
1550 if (is_case_xml_name(factory
, L
"get"))
1552 if (member
->u
.flags
& PROP_GETTER
)
1554 FIXME("Duplicated getter\n");
1557 member
->u
.flags
|= PROP_GETTER
;
1559 else if (is_case_xml_name(factory
, L
"put"))
1561 if (member
->u
.flags
& PROP_SETTER
)
1563 FIXME("Duplicated setter\n");
1566 member
->u
.flags
|= PROP_SETTER
;
1570 FIXME("Unexpected property element %s\n", debugstr_xml_name(factory
));
1574 empty
= IXmlReader_IsEmptyElement(factory
->xml_reader
);
1575 if (!empty
&& FAILED(hres
= expect_end_element(factory
))) return hres
;
1577 if (!member
->u
.flags
)
1579 FIXME("No getter or setter\n");
1584 if (FAILED(hres
)) return hres
;
1590 static HRESULT
parse_scriptlet_script(struct scriptlet_factory
*factory
, struct scriptlet_script
*script
)
1592 XmlNodeType node_type
;
1593 size_t buf_size
, size
;
1602 hres
= IXmlReader_MoveToNextAttribute(factory
->xml_reader
);
1603 if (hres
!= S_OK
) break;
1605 if (is_xml_name(factory
, L
"language"))
1607 if (script
->language
)
1609 FIXME("Duplicated language\n");
1612 hres
= read_xml_value(factory
, &script
->language
);
1613 if (FAILED(hres
)) return hres
;
1617 FIXME("Unexpected attribute\n");
1622 if (!script
->language
)
1624 FIXME("Language not specified\n");
1628 if (FAILED(hres
= next_xml_node(factory
, &node_type
))) return hres
;
1630 if (node_type
!= XmlNodeType_Text
&& node_type
!= XmlNodeType_CDATA
)
1632 FIXME("Unexpected node type %u\n", node_type
);
1636 if (!(script
->body
= malloc((buf_size
= 1024) * sizeof(WCHAR
)))) return E_OUTOFMEMORY
;
1642 hres
= IXmlReader_ReadValueChunk(factory
->xml_reader
, script
->body
+ size
, buf_size
- size
- 1, &read
);
1643 if (FAILED(hres
)) return hres
;
1645 if (hres
== S_FALSE
) break;
1646 if (size
+ 1 == buf_size
)
1648 if (!(new_body
= realloc(script
->body
, (buf_size
*= 2) * sizeof(WCHAR
)))) return E_OUTOFMEMORY
;
1649 script
->body
= new_body
;
1652 script
->body
[size
++] = 0;
1653 if (size
!= buf_size
) script
->body
= realloc(script
->body
, size
* sizeof(WCHAR
));
1655 TRACE("body %s\n", debugstr_w(script
->body
));
1656 return expect_end_element(factory
);
1659 static HRESULT
parse_scriptlet_file(struct scriptlet_factory
*factory
, const WCHAR
*url
)
1661 XmlNodeType node_type
;
1666 hres
= CreateURLMoniker(NULL
, url
, &factory
->moniker
);
1669 WARN("CreateURLMoniker failed: %08lx\n", hres
);
1673 hres
= CreateBindCtx(0, &bind_ctx
);
1677 hres
= IMoniker_BindToStorage(factory
->moniker
, bind_ctx
, NULL
, &IID_IStream
, (void**)&stream
);
1678 IBindCtx_Release(bind_ctx
);
1682 hres
= CreateXmlReader(&IID_IXmlReader
, (void**)&factory
->xml_reader
, NULL
);
1684 hres
= IXmlReader_SetInput(factory
->xml_reader
, (IUnknown
*)stream
);
1685 IStream_Release(stream
);
1689 hres
= next_xml_node(factory
, &node_type
);
1690 if (hres
== S_OK
&& node_type
== XmlNodeType_XmlDeclaration
)
1691 hres
= next_xml_node(factory
, &node_type
);
1695 if (node_type
!= XmlNodeType_Element
|| !is_xml_name(factory
, L
"component"))
1697 FIXME("Unexpected %s element\n", debugstr_xml_name(factory
));
1701 hres
= expect_no_attributes(factory
);
1702 if (FAILED(hres
)) return hres
;
1706 hres
= next_xml_node(factory
, &node_type
);
1707 if (FAILED(hres
)) return hres
;
1708 if (node_type
== XmlNodeType_EndElement
) break;
1709 if (node_type
!= XmlNodeType_Element
)
1711 FIXME("Unexpected node type %u\n", node_type
);
1715 if (is_xml_name(factory
, L
"registration"))
1716 hres
= parse_scriptlet_registration(factory
);
1717 else if (is_xml_name(factory
, L
"public"))
1718 hres
= parse_scriptlet_public(factory
);
1719 else if (is_xml_name(factory
, L
"script"))
1721 struct scriptlet_script
*script
;
1722 if (!(script
= calloc(1, sizeof(*script
)))) return E_OUTOFMEMORY
;
1723 list_add_tail(&factory
->scripts
, &script
->entry
);
1724 hres
= parse_scriptlet_script(factory
, script
);
1725 if (FAILED(hres
)) return hres
;
1729 FIXME("Unexpected element %s\n", debugstr_xml_name(factory
));
1732 if (FAILED(hres
)) return hres
;
1735 hres
= next_xml_node(factory
, &node_type
);
1736 if (hres
!= S_FALSE
)
1738 FIXME("Unexpected node type %u\n", node_type
);
1744 static inline struct scriptlet_factory
*impl_from_IClassFactory(IClassFactory
*iface
)
1746 return CONTAINING_RECORD(iface
, struct scriptlet_factory
, IClassFactory_iface
);
1749 static HRESULT WINAPI
scriptlet_factory_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
1751 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1753 if (IsEqualGUID(&IID_IUnknown
, riid
))
1755 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
1756 *ppv
= &This
->IClassFactory_iface
;
1758 else if (IsEqualGUID(&IID_IClassFactory
, riid
))
1760 TRACE("(%p)->(IID_IClassFactory %p)\n", iface
, ppv
);
1761 *ppv
= &This
->IClassFactory_iface
;
1765 WARN("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
1767 return E_NOINTERFACE
;
1770 IUnknown_AddRef((IUnknown
*)*ppv
);
1774 static ULONG WINAPI
scriptlet_factory_AddRef(IClassFactory
*iface
)
1776 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1777 ULONG ref
= InterlockedIncrement(&This
->ref
);
1779 TRACE("(%p) ref=%ld\n", This
, ref
);
1784 static ULONG WINAPI
scriptlet_factory_Release(IClassFactory
*iface
)
1786 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1787 ULONG ref
= InterlockedDecrement(&This
->ref
);
1789 TRACE("(%p) ref=%ld\n", This
, ref
);
1793 if (This
->moniker
) IMoniker_Release(This
->moniker
);
1794 if (This
->xml_reader
) IXmlReader_Release(This
->xml_reader
);
1795 detach_script_hosts(&This
->hosts
);
1796 while (!list_empty(&This
->members
))
1798 struct scriptlet_member
*member
= LIST_ENTRY(list_head(&This
->members
), struct scriptlet_member
, entry
);
1799 list_remove(&member
->entry
);
1801 if (member
->type
== MEMBER_METHOD
)
1803 while (!list_empty(&member
->u
.parameters
))
1805 struct method_parameter
*parameter
= LIST_ENTRY(list_head(&member
->u
.parameters
), struct method_parameter
, entry
);
1806 list_remove(¶meter
->entry
);
1807 free(parameter
->name
);
1813 while (!list_empty(&This
->scripts
))
1815 struct scriptlet_script
*script
= LIST_ENTRY(list_head(&This
->scripts
), struct scriptlet_script
, entry
);
1816 list_remove(&script
->entry
);
1817 free(script
->language
);
1821 free(This
->classid_str
);
1822 free(This
->description
);
1823 free(This
->versioned_progid
);
1825 free(This
->version
);
1831 static HRESULT WINAPI
scriptlet_factory_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID riid
, void **ppv
)
1833 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1837 TRACE("(%p)->(%p %s %p)\n", This
, outer
, debugstr_guid(riid
), ppv
);
1839 if (outer
) FIXME("outer not supported\n");
1841 if (list_empty(&This
->hosts
))
1843 hres
= create_scriptlet_hosts(This
, &This
->hosts
);
1844 if (FAILED(hres
)) return hres
;
1846 hres
= parse_scripts(This
, &This
->hosts
, FALSE
);
1849 detach_script_hosts(&This
->hosts
);
1854 hres
= create_scriptlet_instance(This
, &disp
);
1855 if (FAILED(hres
)) return hres
;
1857 hres
= IDispatchEx_QueryInterface(disp
, riid
, ppv
);
1858 IDispatchEx_Release(disp
);
1862 static HRESULT WINAPI
scriptlet_factory_LockServer(IClassFactory
*iface
, BOOL fLock
)
1864 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1865 TRACE("(%p)->(%x)\n", This
, fLock
);
1869 static const struct IClassFactoryVtbl scriptlet_factory_vtbl
=
1871 scriptlet_factory_QueryInterface
,
1872 scriptlet_factory_AddRef
,
1873 scriptlet_factory_Release
,
1874 scriptlet_factory_CreateInstance
,
1875 scriptlet_factory_LockServer
1878 static HRESULT
create_scriptlet_factory(const WCHAR
*url
, struct scriptlet_factory
**ret
)
1880 struct scriptlet_factory
*factory
;
1883 TRACE("%s\n", debugstr_w(url
));
1885 if (!(factory
= calloc(1, sizeof(*factory
))))
1886 return E_OUTOFMEMORY
;
1888 factory
->IClassFactory_iface
.lpVtbl
= &scriptlet_factory_vtbl
;
1890 list_init(&factory
->hosts
);
1891 list_init(&factory
->members
);
1892 list_init(&factory
->scripts
);
1894 hres
= parse_scriptlet_file(factory
, url
);
1897 IClassFactory_Release(&factory
->IClassFactory_iface
);
1905 static HRESULT
register_scriptlet(struct scriptlet_factory
*factory
)
1907 HKEY key
, clsid_key
, obj_key
;
1911 if (factory
->classid_str
)
1915 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, L
"CLSID", &clsid_key
);
1916 if (status
) return E_ACCESSDENIED
;
1918 status
= RegCreateKeyW(clsid_key
, factory
->classid_str
, &obj_key
);
1919 RegCloseKey(clsid_key
);
1920 if (status
) return E_ACCESSDENIED
;
1922 hres
= IMoniker_GetDisplayName(factory
->moniker
, NULL
, NULL
, &url
);
1925 RegCloseKey(obj_key
);
1928 status
= RegCreateKeyW(obj_key
, L
"ScriptletURL", &key
);
1931 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)url
,
1932 (wcslen(url
) + 1) * sizeof(WCHAR
));
1937 if (factory
->description
)
1938 status
= RegSetValueExW(obj_key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->description
,
1939 (wcslen(factory
->description
) + 1) * sizeof(WCHAR
));
1943 status
= RegCreateKeyW(obj_key
, L
"InprocServer32", &key
);
1946 WCHAR str
[MAX_PATH
];
1947 GetModuleFileNameW(scrobj_instance
, str
, MAX_PATH
);
1948 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)str
, (wcslen(str
) + 1) * sizeof(WCHAR
));
1953 if (!status
&& factory
->versioned_progid
)
1955 status
= RegCreateKeyW(obj_key
, L
"ProgID", &key
);
1958 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->versioned_progid
,
1959 (wcslen(factory
->versioned_progid
) + 1) * sizeof(WCHAR
));
1964 if (!status
&& factory
->progid
)
1966 status
= RegCreateKeyW(obj_key
, L
"VersionIndependentProgID", &key
);
1969 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->progid
,
1970 (wcslen(factory
->progid
) + 1) * sizeof(WCHAR
));
1975 RegCloseKey(obj_key
);
1976 if (status
) return E_ACCESSDENIED
;
1979 if (factory
->progid
)
1981 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, factory
->progid
, &key
);
1982 if (status
) return E_ACCESSDENIED
;
1984 if (factory
->description
)
1985 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->description
,
1986 (wcslen(factory
->description
) + 1) * sizeof(WCHAR
));
1988 if (!status
&& factory
->classid_str
)
1990 status
= RegCreateKeyW(key
, L
"CLSID", &clsid_key
);
1993 status
= RegSetValueExW(clsid_key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->classid_str
,
1994 (wcslen(factory
->classid_str
) + 1) * sizeof(WCHAR
));
1995 RegCloseKey(clsid_key
);
2000 if (status
) return E_ACCESSDENIED
;
2003 if (factory
->versioned_progid
)
2005 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, factory
->versioned_progid
, &key
);
2006 if (status
) return E_ACCESSDENIED
;
2008 if (factory
->description
)
2009 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->description
,
2010 (wcslen(factory
->description
) + 1) * sizeof(WCHAR
));
2012 if (!status
&& factory
->classid_str
)
2014 status
= RegCreateKeyW(key
, L
"CLSID", &clsid_key
);
2017 status
= RegSetValueExW(clsid_key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->classid_str
,
2018 (wcslen(factory
->classid_str
) + 1) * sizeof(WCHAR
));
2019 RegCloseKey(clsid_key
);
2024 if (status
) return E_ACCESSDENIED
;
2030 static HRESULT
unregister_scriptlet(struct scriptlet_factory
*factory
)
2034 if (factory
->classid_str
)
2037 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, L
"CLSID", &clsid_key
);
2040 RegDeleteTreeW(clsid_key
, factory
->classid_str
);
2041 RegCloseKey(clsid_key
);
2045 if (factory
->progid
) RegDeleteTreeW(HKEY_CLASSES_ROOT
, factory
->progid
);
2046 if (factory
->versioned_progid
) RegDeleteTreeW(HKEY_CLASSES_ROOT
, factory
->versioned_progid
);
2050 struct scriptlet_typelib
2052 IGenScriptletTLib IGenScriptletTLib_iface
;
2058 static inline struct scriptlet_typelib
*impl_from_IGenScriptletTLib(IGenScriptletTLib
*iface
)
2060 return CONTAINING_RECORD(iface
, struct scriptlet_typelib
, IGenScriptletTLib_iface
);
2063 static HRESULT WINAPI
scriptlet_typelib_QueryInterface(IGenScriptletTLib
*iface
, REFIID riid
, void **obj
)
2065 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2067 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), obj
);
2069 if (IsEqualIID(riid
, &IID_IGenScriptletTLib
) ||
2070 IsEqualIID(riid
, &IID_IDispatch
) ||
2071 IsEqualIID(riid
, &IID_IUnknown
))
2074 IGenScriptletTLib_AddRef(iface
);
2079 return E_NOINTERFACE
;
2082 static ULONG WINAPI
scriptlet_typelib_AddRef(IGenScriptletTLib
*iface
)
2084 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2085 ULONG ref
= InterlockedIncrement(&This
->ref
);
2086 TRACE("(%p)->(%lu)\n", This
, ref
);
2090 static ULONG WINAPI
scriptlet_typelib_Release(IGenScriptletTLib
*iface
)
2092 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2093 LONG ref
= InterlockedDecrement(&This
->ref
);
2095 TRACE("(%p)->(%lu)\n", This
, ref
);
2099 SysFreeString(This
->guid
);
2106 static HRESULT WINAPI
scriptlet_typelib_GetTypeInfoCount(IGenScriptletTLib
*iface
, UINT
*count
)
2108 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2110 TRACE("(%p, %p)\n", This
, count
);
2116 static HRESULT WINAPI
scriptlet_typelib_GetTypeInfo(IGenScriptletTLib
*iface
, UINT index
, LCID lcid
,
2119 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2121 TRACE("(%p, %u, %lx, %p)\n", This
, index
, lcid
, tinfo
);
2123 return get_typeinfo(IGenScriptletTLib_tid
, tinfo
);
2126 static HRESULT WINAPI
scriptlet_typelib_GetIDsOfNames(IGenScriptletTLib
*iface
, REFIID riid
, LPOLESTR
*names
,
2127 UINT cNames
, LCID lcid
, DISPID
*dispid
)
2129 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2130 ITypeInfo
*typeinfo
;
2133 TRACE("(%p, %s, %p, %u, %lx, %p)\n", This
, debugstr_guid(riid
), names
, cNames
, lcid
, dispid
);
2135 hr
= get_typeinfo(IGenScriptletTLib_tid
, &typeinfo
);
2138 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, cNames
, dispid
);
2139 ITypeInfo_Release(typeinfo
);
2145 static HRESULT WINAPI
scriptlet_typelib_Invoke(IGenScriptletTLib
*iface
, DISPID dispid
, REFIID riid
,
2146 LCID lcid
, WORD flags
, DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*ei
, UINT
*argerr
)
2148 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2149 ITypeInfo
*typeinfo
;
2152 TRACE("(%p, %ld, %s, %lx, %x, %p, %p, %p, %p)\n", This
, dispid
, debugstr_guid(riid
), lcid
, flags
,
2153 params
, result
, ei
, argerr
);
2155 hr
= get_typeinfo(IGenScriptletTLib_tid
, &typeinfo
);
2158 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IGenScriptletTLib_iface
, dispid
, flags
,
2159 params
, result
, ei
, argerr
);
2160 ITypeInfo_Release(typeinfo
);
2166 static HRESULT WINAPI
scriptlet_typelib_AddURL(IGenScriptletTLib
*iface
, BSTR url
)
2168 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2170 FIXME("(%p, %s): stub\n", This
, debugstr_w(url
));
2175 static HRESULT WINAPI
scriptlet_typelib_put_Path(IGenScriptletTLib
*iface
, BSTR path
)
2177 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2179 FIXME("(%p, %s): stub\n", This
, debugstr_w(path
));
2184 static HRESULT WINAPI
scriptlet_typelib_get_Path(IGenScriptletTLib
*iface
, BSTR
*path
)
2186 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2188 FIXME("(%p, %p): stub\n", This
, path
);
2193 static HRESULT WINAPI
scriptlet_typelib_put_Doc(IGenScriptletTLib
*iface
, BSTR doc
)
2195 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2197 FIXME("(%p, %s): stub\n", This
, debugstr_w(doc
));
2202 static HRESULT WINAPI
scriptlet_typelib_get_Doc(IGenScriptletTLib
*iface
, BSTR
*doc
)
2204 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2206 FIXME("(%p, %p): stub\n", This
, doc
);
2211 static HRESULT WINAPI
scriptlet_typelib_put_Name(IGenScriptletTLib
*iface
, BSTR name
)
2213 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2215 FIXME("(%p, %s): stub\n", This
, debugstr_w(name
));
2220 static HRESULT WINAPI
scriptlet_typelib_get_Name(IGenScriptletTLib
*iface
, BSTR
*name
)
2222 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2224 FIXME("(%p, %p): stub\n", This
, name
);
2229 static HRESULT WINAPI
scriptlet_typelib_put_MajorVersion(IGenScriptletTLib
*iface
, WORD version
)
2231 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2233 FIXME("(%p, %x): stub\n", This
, version
);
2238 static HRESULT WINAPI
scriptlet_typelib_get_MajorVersion(IGenScriptletTLib
*iface
, WORD
*version
)
2240 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2242 FIXME("(%p, %p): stub\n", This
, version
);
2247 static HRESULT WINAPI
scriptlet_typelib_put_MinorVersion(IGenScriptletTLib
*iface
, WORD version
)
2249 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2251 FIXME("(%p, %x): stub\n", This
, version
);
2256 static HRESULT WINAPI
scriptlet_typelib_get_MinorVersion(IGenScriptletTLib
*iface
, WORD
*version
)
2258 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2260 FIXME("(%p, %p): stub\n", This
, version
);
2265 static HRESULT WINAPI
scriptlet_typelib_Write(IGenScriptletTLib
*iface
)
2267 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2269 FIXME("(%p): stub\n", This
);
2274 static HRESULT WINAPI
scriptlet_typelib_Reset(IGenScriptletTLib
*iface
)
2276 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2278 FIXME("(%p): stub\n", This
);
2283 static HRESULT WINAPI
scriptlet_typelib_put_GUID(IGenScriptletTLib
*iface
, BSTR guid
)
2285 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2287 FIXME("(%p, %s): stub\n", This
, debugstr_w(guid
));
2292 static HRESULT WINAPI
scriptlet_typelib_get_GUID(IGenScriptletTLib
*iface
, BSTR
*ret
)
2294 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2296 TRACE("(%p, %p)\n", This
, ret
);
2306 hr
= CoCreateGuid(&guid
);
2310 hr
= StringFromGUID2(&guid
, guidW
, ARRAY_SIZE(guidW
));
2314 if (!(This
->guid
= SysAllocString(guidW
)))
2315 return E_OUTOFMEMORY
;
2318 *ret
= SysAllocString(This
->guid
);
2319 return *ret
? S_OK
: E_OUTOFMEMORY
;
2322 static const IGenScriptletTLibVtbl scriptlet_typelib_vtbl
=
2324 scriptlet_typelib_QueryInterface
,
2325 scriptlet_typelib_AddRef
,
2326 scriptlet_typelib_Release
,
2327 scriptlet_typelib_GetTypeInfoCount
,
2328 scriptlet_typelib_GetTypeInfo
,
2329 scriptlet_typelib_GetIDsOfNames
,
2330 scriptlet_typelib_Invoke
,
2331 scriptlet_typelib_AddURL
,
2332 scriptlet_typelib_put_Path
,
2333 scriptlet_typelib_get_Path
,
2334 scriptlet_typelib_put_Doc
,
2335 scriptlet_typelib_get_Doc
,
2336 scriptlet_typelib_put_Name
,
2337 scriptlet_typelib_get_Name
,
2338 scriptlet_typelib_put_MajorVersion
,
2339 scriptlet_typelib_get_MajorVersion
,
2340 scriptlet_typelib_put_MinorVersion
,
2341 scriptlet_typelib_get_MinorVersion
,
2342 scriptlet_typelib_Write
,
2343 scriptlet_typelib_Reset
,
2344 scriptlet_typelib_put_GUID
,
2345 scriptlet_typelib_get_GUID
2348 BOOL WINAPI
DllMain(HINSTANCE hinst
, DWORD reason
, void *reserved
)
2350 TRACE("%p, %lu, %p\n", hinst
, reason
, reserved
);
2354 case DLL_PROCESS_ATTACH
:
2355 DisableThreadLibraryCalls(hinst
);
2356 scrobj_instance
= hinst
;
2358 case DLL_PROCESS_DETACH
:
2359 if (reserved
) break;
2366 /***********************************************************************
2367 * DllInstall (scrobj.@)
2369 HRESULT WINAPI
DllInstall(BOOL install
, const WCHAR
*arg
)
2371 struct scriptlet_factory
*factory
;
2376 hres
= DllRegisterServer();
2377 if (!arg
|| FAILED(hres
)) return hres
;
2380 return DllUnregisterServer();
2382 hres
= create_scriptlet_factory(arg
, &factory
);
2383 if (SUCCEEDED(hres
))
2385 if (factory
->have_registration
)
2387 /* validate scripts */
2388 hres
= create_scriptlet_hosts(factory
, &factory
->hosts
);
2389 if (SUCCEEDED(hres
)) hres
= parse_scripts(factory
, &factory
->hosts
, FALSE
);
2393 FIXME("No registration info\n");
2396 if (SUCCEEDED(hres
))
2399 hres
= register_scriptlet(factory
);
2401 hres
= unregister_scriptlet(factory
);
2403 IClassFactory_Release(&factory
->IClassFactory_iface
);
2409 static HRESULT WINAPI
scriptlet_typelib_CreateInstance(IClassFactory
*factory
, IUnknown
*outer
, REFIID riid
, void **obj
)
2411 struct scriptlet_typelib
*This
;
2414 TRACE("(%p, %p, %s, %p)\n", factory
, outer
, debugstr_guid(riid
), obj
);
2418 if (!(This
= calloc(1, sizeof(*This
))))
2419 return E_OUTOFMEMORY
;
2421 This
->IGenScriptletTLib_iface
.lpVtbl
= &scriptlet_typelib_vtbl
;
2424 hr
= IGenScriptletTLib_QueryInterface(&This
->IGenScriptletTLib_iface
, riid
, obj
);
2425 IGenScriptletTLib_Release(&This
->IGenScriptletTLib_iface
);
2429 static HRESULT WINAPI
scrruncf_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
2433 if (IsEqualGUID(&IID_IUnknown
, riid
))
2435 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
2438 else if (IsEqualGUID(&IID_IClassFactory
, riid
))
2440 TRACE("(%p)->(IID_IClassFactory %p)\n", iface
, ppv
);
2446 IUnknown_AddRef((IUnknown
*)*ppv
);
2450 WARN("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
2451 return E_NOINTERFACE
;
2454 static ULONG WINAPI
scrruncf_AddRef(IClassFactory
*iface
)
2456 TRACE("(%p)\n", iface
);
2460 static ULONG WINAPI
scrruncf_Release(IClassFactory
*iface
)
2462 TRACE("(%p)\n", iface
);
2466 static HRESULT WINAPI
scrruncf_LockServer(IClassFactory
*iface
, BOOL fLock
)
2468 TRACE("(%p)->(%x)\n", iface
, fLock
);
2472 static const struct IClassFactoryVtbl scriptlet_typelib_factory_vtbl
=
2474 scrruncf_QueryInterface
,
2477 scriptlet_typelib_CreateInstance
,
2481 static IClassFactory scriptlet_typelib_factory
= { &scriptlet_typelib_factory_vtbl
};
2483 /***********************************************************************
2484 * DllGetClassObject (scrobj.@)
2486 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **ppv
)
2488 WCHAR key_name
[128], *p
;
2492 if (IsEqualGUID(&CLSID_TypeLib
, rclsid
))
2494 TRACE("(Scriptlet.TypeLib %s %p)\n", debugstr_guid(riid
), ppv
);
2495 return IClassFactory_QueryInterface(&scriptlet_typelib_factory
, riid
, ppv
);
2498 wcscpy(key_name
, L
"CLSID\\");
2499 p
= key_name
+ wcslen(key_name
);
2500 p
+= StringFromGUID2(rclsid
, p
, ARRAY_SIZE(key_name
) - (p
- key_name
)) - 1;
2501 wcscpy(p
, L
"\\ScriptletURL");
2502 status
= RegQueryValueW(HKEY_CLASSES_ROOT
, key_name
, NULL
, &size
);
2505 struct scriptlet_factory
*factory
;
2509 if (!(url
= malloc(size
* sizeof(WCHAR
)))) return E_OUTOFMEMORY
;
2510 status
= RegQueryValueW(HKEY_CLASSES_ROOT
, key_name
, url
, &size
);
2512 hres
= create_scriptlet_factory(url
, &factory
);
2514 if (FAILED(hres
)) return hres
;
2516 hres
= IClassFactory_QueryInterface(&factory
->IClassFactory_iface
, riid
, ppv
);
2517 IClassFactory_Release(&factory
->IClassFactory_iface
);
2521 FIXME("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
2522 return CLASS_E_CLASSNOTAVAILABLE
;