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/heap.h"
38 #include "wine/list.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(scrobj
);
44 #define IActiveScriptParse_Release IActiveScriptParse64_Release
45 #define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
46 #define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
50 #define IActiveScriptParse_Release IActiveScriptParse32_Release
51 #define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
52 #define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
56 static HINSTANCE scrobj_instance
;
64 #define PROP_GETTER 0x01
65 #define PROP_SETTER 0x02
67 struct scriptlet_member
70 enum member_type type
;
74 struct list parameters
;
79 struct method_parameter
85 struct scriptlet_script
92 struct scriptlet_global
94 IDispatchEx IDispatchEx_iface
;
98 struct scriptlet_factory
100 IClassFactory IClassFactory_iface
;
104 IXmlReader
*xml_reader
;
107 BOOL have_registration
;
111 WCHAR
*versioned_progid
;
121 struct script_reference
123 struct script_host
*host
;
129 enum member_type type
;
133 struct script_reference method
;
136 struct script_reference get
;
137 struct script_reference put
;
142 struct scriptlet_instance
144 IDispatchEx IDispatchEx_iface
;
147 struct scriptlet_global
*global
;
149 struct object_member
*members
;
154 IActiveScriptSite IActiveScriptSite_iface
;
155 IActiveScriptSiteWindow IActiveScriptSiteWindow_iface
;
156 IServiceProvider IServiceProvider_iface
;
163 IActiveScript
*active_script
;
164 IActiveScriptParse
*parser
;
165 IDispatchEx
*script_dispatch
;
166 struct scriptlet_instance
*object
;
174 IGenScriptletTLib_tid
,
178 static ITypeLib
*typelib
;
179 static ITypeInfo
*typeinfos
[LAST_tid
];
181 static REFIID tid_ids
[] = {
183 &IID_IGenScriptletTLib
,
186 static HRESULT
load_typelib(void)
194 hres
= LoadRegTypeLib(&LIBID_Scriptlet
, 1, 0, LOCALE_SYSTEM_DEFAULT
, &tl
);
197 ERR("LoadRegTypeLib failed: %08x\n", hres
);
201 if (InterlockedCompareExchangePointer((void **)&typelib
, tl
, NULL
))
202 ITypeLib_Release(tl
);
206 static HRESULT
get_typeinfo(tid_t tid
, ITypeInfo
**typeinfo
)
210 if (FAILED(hres
= load_typelib()))
217 hres
= ITypeLib_GetTypeInfoOfGuid(typelib
, tid_ids
[tid
], &ti
);
219 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids
[tid
]), hres
);
223 if (InterlockedCompareExchangePointer((void **)(typeinfos
+tid
), ti
, NULL
))
224 ITypeInfo_Release(ti
);
227 *typeinfo
= typeinfos
[tid
];
228 ITypeInfo_AddRef(typeinfos
[tid
]);
232 static void release_typelib(void)
239 for (i
= 0; i
< ARRAY_SIZE(typeinfos
); i
++)
241 ITypeInfo_Release(typeinfos
[i
]);
243 ITypeLib_Release(typelib
);
246 static WCHAR
*heap_strdupW(const WCHAR
*str
)
249 size_t size
= (wcslen(str
) + 1) * sizeof(WCHAR
);
250 if (!(ret
= heap_alloc(size
))) return NULL
;
251 memcpy(ret
, str
, size
);
255 static inline struct scriptlet_global
*global_from_IDispatchEx(IDispatchEx
*iface
)
257 return CONTAINING_RECORD(iface
, struct scriptlet_global
, IDispatchEx_iface
);
260 static HRESULT WINAPI
global_QueryInterface(IDispatchEx
*iface
, REFIID riid
, void **ppv
)
262 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
264 if (IsEqualGUID(&IID_IUnknown
, riid
))
266 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
267 *ppv
= &This
->IDispatchEx_iface
;
269 else if (IsEqualGUID(&IID_IDispatch
, riid
))
271 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
272 *ppv
= &This
->IDispatchEx_iface
;
274 else if (IsEqualGUID(&IID_IDispatchEx
, riid
))
276 TRACE("(%p)->(IID_IDispatchEx %p)\n", This
, ppv
);
277 *ppv
= &This
->IDispatchEx_iface
;
281 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
283 return E_NOINTERFACE
;
286 IUnknown_AddRef((IUnknown
*)*ppv
);
290 static ULONG WINAPI
global_AddRef(IDispatchEx
*iface
)
292 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
293 ULONG ref
= InterlockedIncrement(&This
->ref
);
295 TRACE("(%p) ref=%d\n", This
, ref
);
300 static ULONG WINAPI
global_Release(IDispatchEx
*iface
)
302 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
303 ULONG ref
= InterlockedDecrement(&This
->ref
);
305 TRACE("(%p) ref=%d\n", This
, ref
);
307 if (!ref
) heap_free(This
);
311 static HRESULT WINAPI
global_GetTypeInfoCount(IDispatchEx
*iface
, UINT
*pctinfo
)
313 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
314 FIXME("(%p)->(%p)\n", This
, pctinfo
);
318 static HRESULT WINAPI
global_GetTypeInfo(IDispatchEx
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
320 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
321 FIXME("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
325 static HRESULT WINAPI
global_GetIDsOfNames(IDispatchEx
*iface
, REFIID riid
,
326 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
328 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
332 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
334 for(i
=0; i
< cNames
; i
++)
336 hres
= IDispatchEx_GetDispID(&This
->IDispatchEx_iface
, rgszNames
[i
], 0, rgDispId
+ i
);
344 static HRESULT WINAPI
global_Invoke(IDispatchEx
*iface
, DISPID dispIdMember
,
345 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
346 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
348 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
349 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
350 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
351 return IDispatchEx_InvokeEx(&This
->IDispatchEx_iface
, dispIdMember
, lcid
, wFlags
,
352 pDispParams
, pVarResult
, pExcepInfo
, NULL
);
355 static HRESULT WINAPI
global_GetDispID(IDispatchEx
*iface
, BSTR bstrName
, DWORD grfdex
, DISPID
*pid
)
357 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
358 FIXME("(%p)->(%s %x %p)\n", This
, debugstr_w(bstrName
), grfdex
, pid
);
362 static HRESULT WINAPI
global_InvokeEx(IDispatchEx
*iface
, DISPID id
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pdp
,
363 VARIANT
*pvarRes
, EXCEPINFO
*pei
, IServiceProvider
*pspCaller
)
365 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
366 FIXME("(%p)->(%x %x %x %p %p %p %p)\n", This
, id
, lcid
, wFlags
, pdp
, pvarRes
, pei
, pspCaller
);
370 static HRESULT WINAPI
global_DeleteMemberByName(IDispatchEx
*iface
, BSTR bstrName
, DWORD grfdex
)
372 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
373 FIXME("(%p)->(%s %x)\n", This
, debugstr_w(bstrName
), grfdex
);
377 static HRESULT WINAPI
global_DeleteMemberByDispID(IDispatchEx
*iface
, DISPID id
)
379 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
380 FIXME("(%p)->(%x)\n", This
, id
);
384 static HRESULT WINAPI
global_GetMemberProperties(IDispatchEx
*iface
, DISPID id
, DWORD grfdexFetch
, DWORD
*pgrfdex
)
386 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
387 FIXME("(%p)->(%x %x %p)\n", This
, id
, grfdexFetch
, pgrfdex
);
391 static HRESULT WINAPI
global_GetMemberName(IDispatchEx
*iface
, DISPID id
, BSTR
*pbstrName
)
393 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
394 FIXME("(%p)->(%x %p)\n", This
, id
, pbstrName
);
398 static HRESULT WINAPI
global_GetNextDispID(IDispatchEx
*iface
, DWORD grfdex
, DISPID id
, DISPID
*pid
)
400 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
401 FIXME("(%p)->(%x %x %p)\n", This
, grfdex
, id
, pid
);
405 static HRESULT WINAPI
global_GetNameSpaceParent(IDispatchEx
*iface
, IUnknown
**ppunk
)
407 struct scriptlet_global
*This
= global_from_IDispatchEx(iface
);
408 FIXME("(%p)->(%p)\n", This
, ppunk
);
412 static IDispatchExVtbl global_vtbl
= {
413 global_QueryInterface
,
416 global_GetTypeInfoCount
,
418 global_GetIDsOfNames
,
422 global_DeleteMemberByName
,
423 global_DeleteMemberByDispID
,
424 global_GetMemberProperties
,
425 global_GetMemberName
,
426 global_GetNextDispID
,
427 global_GetNameSpaceParent
430 static HRESULT
set_script_state(struct script_host
*host
, SCRIPTSTATE state
)
433 if (state
== host
->state
) return S_OK
;
434 hres
= IActiveScript_SetScriptState(host
->active_script
, state
);
435 if (FAILED(hres
)) return hres
;
440 static inline struct script_host
*impl_from_IActiveScriptSite(IActiveScriptSite
*iface
)
442 return CONTAINING_RECORD(iface
, struct script_host
, IActiveScriptSite_iface
);
445 static HRESULT WINAPI
ActiveScriptSite_QueryInterface(IActiveScriptSite
*iface
, REFIID riid
, void **ppv
)
447 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
449 if (IsEqualGUID(&IID_IUnknown
, riid
))
451 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
452 *ppv
= &This
->IActiveScriptSite_iface
;
454 else if (IsEqualGUID(&IID_IActiveScriptSite
, riid
))
456 TRACE("(%p)->(IID_IActiveScriptSite %p)\n", This
, ppv
);
457 *ppv
= &This
->IActiveScriptSite_iface
;
459 else if (IsEqualGUID(&IID_IActiveScriptSiteWindow
, riid
))
461 TRACE("(%p)->(IID_IActiveScriptSiteWindow %p)\n", This
, ppv
);
462 *ppv
= &This
->IActiveScriptSiteWindow_iface
;
464 else if(IsEqualGUID(&IID_IServiceProvider
, riid
))
466 TRACE("(%p)->(IID_IServiceProvider %p)\n", This
, ppv
);
467 *ppv
= &This
->IServiceProvider_iface
;
471 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
473 return E_NOINTERFACE
;
476 IUnknown_AddRef((IUnknown
*)*ppv
);
480 static ULONG WINAPI
ActiveScriptSite_AddRef(IActiveScriptSite
*iface
)
482 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
483 LONG ref
= InterlockedIncrement(&This
->ref
);
485 TRACE("(%p) ref=%d\n", This
, ref
);
490 static ULONG WINAPI
ActiveScriptSite_Release(IActiveScriptSite
*iface
)
492 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
493 LONG ref
= InterlockedDecrement(&This
->ref
);
495 TRACE("(%p) ref=%d\n", This
, ref
);
498 heap_free(This
->language
);
505 static HRESULT WINAPI
ActiveScriptSite_GetLCID(IActiveScriptSite
*iface
, LCID
*lcid
)
507 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
509 TRACE("(%p, %p)\n", This
, lcid
);
511 *lcid
= GetUserDefaultLCID();
515 static HRESULT WINAPI
ActiveScriptSite_GetItemInfo(IActiveScriptSite
*iface
, LPCOLESTR name
, DWORD mask
,
516 IUnknown
**unk
, ITypeInfo
**ti
)
518 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
520 TRACE("(%p, %s, %#x, %p, %p)\n", This
, debugstr_w(name
), mask
, unk
, ti
);
522 if (mask
!= SCRIPTINFO_IUNKNOWN
)
524 FIXME("mask %x not supported\n", mask
);
528 if (wcscmp(name
, L
"scriptlet") && wcscmp(name
, L
"globals"))
530 FIXME("%s not supported\n", debugstr_w(name
));
534 if (!This
->object
) return E_UNEXPECTED
;
536 *unk
= (IUnknown
*)&This
->object
->global
->IDispatchEx_iface
;
537 IUnknown_AddRef(*unk
);
541 static HRESULT WINAPI
ActiveScriptSite_GetDocVersionString(IActiveScriptSite
*iface
, BSTR
*version
)
543 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
544 FIXME("(%p, %p)\n", This
, version
);
548 static HRESULT WINAPI
ActiveScriptSite_OnScriptTerminate(IActiveScriptSite
*iface
, const VARIANT
*result
,
551 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
552 FIXME("(%p, %s, %p)\n", This
, debugstr_variant(result
), ei
);
556 static HRESULT WINAPI
ActiveScriptSite_OnStateChange(IActiveScriptSite
*iface
, SCRIPTSTATE state
)
558 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
559 TRACE("(%p, %d)\n", This
, state
);
563 static HRESULT WINAPI
ActiveScriptSite_OnScriptError(IActiveScriptSite
*iface
, IActiveScriptError
*script_error
)
565 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
566 FIXME("(%p, %p)\n", This
, script_error
);
570 static HRESULT WINAPI
ActiveScriptSite_OnEnterScript(IActiveScriptSite
*iface
)
572 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
573 TRACE("(%p)\n", This
);
577 static HRESULT WINAPI
ActiveScriptSite_OnLeaveScript(IActiveScriptSite
*iface
)
579 struct script_host
*This
= impl_from_IActiveScriptSite(iface
);
580 TRACE("(%p)\n", This
);
584 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl
= {
585 ActiveScriptSite_QueryInterface
,
586 ActiveScriptSite_AddRef
,
587 ActiveScriptSite_Release
,
588 ActiveScriptSite_GetLCID
,
589 ActiveScriptSite_GetItemInfo
,
590 ActiveScriptSite_GetDocVersionString
,
591 ActiveScriptSite_OnScriptTerminate
,
592 ActiveScriptSite_OnStateChange
,
593 ActiveScriptSite_OnScriptError
,
594 ActiveScriptSite_OnEnterScript
,
595 ActiveScriptSite_OnLeaveScript
598 static inline struct script_host
*impl_from_IActiveScriptSiteWindow(IActiveScriptSiteWindow
*iface
)
600 return CONTAINING_RECORD(iface
, struct script_host
, IActiveScriptSiteWindow_iface
);
603 static HRESULT WINAPI
ActiveScriptSiteWindow_QueryInterface(IActiveScriptSiteWindow
*iface
, REFIID riid
, void **obj
)
605 struct script_host
*This
= impl_from_IActiveScriptSiteWindow(iface
);
606 return IActiveScriptSite_QueryInterface(&This
->IActiveScriptSite_iface
, riid
, obj
);
609 static ULONG WINAPI
ActiveScriptSiteWindow_AddRef(IActiveScriptSiteWindow
*iface
)
611 struct script_host
*This
= impl_from_IActiveScriptSiteWindow(iface
);
612 return IActiveScriptSite_AddRef(&This
->IActiveScriptSite_iface
);
615 static ULONG WINAPI
ActiveScriptSiteWindow_Release(IActiveScriptSiteWindow
*iface
)
617 struct script_host
*This
= impl_from_IActiveScriptSiteWindow(iface
);
618 return IActiveScriptSite_Release(&This
->IActiveScriptSite_iface
);
621 static HRESULT WINAPI
ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow
*iface
, HWND
*hwnd
)
623 struct script_host
*This
= impl_from_IActiveScriptSiteWindow(iface
);
624 FIXME("(%p, %p)\n", This
, hwnd
);
628 static HRESULT WINAPI
ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWindow
*iface
, BOOL enable
)
630 struct script_host
*This
= impl_from_IActiveScriptSiteWindow(iface
);
631 FIXME("(%p, %d)\n", This
, enable
);
635 static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl
= {
636 ActiveScriptSiteWindow_QueryInterface
,
637 ActiveScriptSiteWindow_AddRef
,
638 ActiveScriptSiteWindow_Release
,
639 ActiveScriptSiteWindow_GetWindow
,
640 ActiveScriptSiteWindow_EnableModeless
643 static inline struct script_host
*impl_from_IServiceProvider(IServiceProvider
*iface
)
645 return CONTAINING_RECORD(iface
, struct script_host
, IServiceProvider_iface
);
648 static HRESULT WINAPI
ServiceProvider_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **obj
)
650 struct script_host
*This
= impl_from_IServiceProvider(iface
);
651 return IActiveScriptSite_QueryInterface(&This
->IActiveScriptSite_iface
, riid
, obj
);
654 static ULONG WINAPI
ServiceProvider_AddRef(IServiceProvider
*iface
)
656 struct script_host
*This
= impl_from_IServiceProvider(iface
);
657 return IActiveScriptSite_AddRef(&This
->IActiveScriptSite_iface
);
660 static ULONG WINAPI
ServiceProvider_Release(IServiceProvider
*iface
)
662 struct script_host
*This
= impl_from_IServiceProvider(iface
);
663 return IActiveScriptSite_Release(&This
->IActiveScriptSite_iface
);
666 static HRESULT WINAPI
ServiceProvider_QueryService(IServiceProvider
*iface
, REFGUID service
,
667 REFIID riid
, void **obj
)
669 struct script_host
*This
= impl_from_IServiceProvider(iface
);
670 FIXME("(%p)->(%s %s %p)\n", This
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
674 static const IServiceProviderVtbl ServiceProviderVtbl
= {
675 ServiceProvider_QueryInterface
,
676 ServiceProvider_AddRef
,
677 ServiceProvider_Release
,
678 ServiceProvider_QueryService
681 static struct script_host
*find_script_host(struct list
*hosts
, const WCHAR
*language
)
683 struct script_host
*host
;
684 LIST_FOR_EACH_ENTRY(host
, hosts
, struct script_host
, entry
)
686 if (!wcscmp(host
->language
, language
)) return host
;
691 static HRESULT
parse_scripts(struct scriptlet_factory
*factory
, struct list
*hosts
, BOOL start
)
693 DWORD parse_flags
= SCRIPTTEXT_ISVISIBLE
;
694 struct scriptlet_script
*script
;
695 struct script_host
*host
;
698 if (!start
) parse_flags
|= SCRIPTITEM_ISPERSISTENT
;
700 LIST_FOR_EACH_ENTRY(script
, &factory
->scripts
, struct scriptlet_script
, entry
)
702 host
= find_script_host(hosts
, script
->language
);
704 if (start
&& host
->state
!= SCRIPTSTATE_STARTED
)
706 hres
= set_script_state(host
, SCRIPTSTATE_STARTED
);
707 if (FAILED(hres
)) return hres
;
710 if (host
->cloned
) continue;
712 hres
= IActiveScriptParse_ParseScriptText(host
->parser
, script
->body
, NULL
, NULL
, NULL
, 0, 0 /* FIXME */,
713 parse_flags
, NULL
, NULL
);
716 WARN("ParseScriptText failed: %08x\n", hres
);
722 LIST_FOR_EACH_ENTRY(host
, hosts
, struct script_host
, entry
)
724 if (host
->state
!= SCRIPTSTATE_UNINITIALIZED
)
725 set_script_state(host
, SCRIPTSTATE_UNINITIALIZED
);
731 static HRESULT
lookup_script_properties(struct scriptlet_instance
*object
, BSTR name
, struct script_reference
*ret
)
733 struct script_host
*host
;
736 LIST_FOR_EACH_ENTRY(host
, &object
->hosts
, struct script_host
, entry
)
738 hres
= IDispatchEx_GetDispID(host
->script_dispatch
, name
, 0, &ret
->id
);
739 if (FAILED(hres
)) continue;
744 FIXME("Could not find %s in scripts\n", debugstr_w(name
));
748 static HRESULT
lookup_object_properties(struct scriptlet_instance
*object
, struct scriptlet_factory
*factory
)
750 struct scriptlet_member
*member
;
751 unsigned i
= 0, member_cnt
= 0;
756 LIST_FOR_EACH_ENTRY(member
, &factory
->members
, struct scriptlet_member
, entry
)
759 if (!member_cnt
) return S_OK
;
761 if (!(object
->members
= heap_alloc_zero(member_cnt
* sizeof(*object
->members
)))) return E_OUTOFMEMORY
;
762 object
->member_cnt
= member_cnt
;
764 LIST_FOR_EACH_ENTRY(member
, &factory
->members
, struct scriptlet_member
, entry
)
766 object
->members
[i
].type
= member
->type
;
767 if (!(object
->members
[i
].name
= SysAllocString(member
->name
))) return E_OUTOFMEMORY
;
768 switch (member
->type
)
771 hres
= lookup_script_properties(object
, object
->members
[i
].name
, &object
->members
[i
].u
.method
);
772 if (FAILED(hres
)) return hres
;
774 case MEMBER_PROPERTY
:
775 len
= wcslen(member
->name
);
776 if (!(name
= SysAllocStringLen(NULL
, len
+ 4))) return E_OUTOFMEMORY
;
777 wcscpy(name
, L
"get_");
778 wcscat(name
, member
->name
);
779 hres
= lookup_script_properties(object
, name
, &object
->members
[i
].u
.property
.get
);
782 memcpy(name
, L
"put", 3 * sizeof(WCHAR
));
783 hres
= lookup_script_properties(object
, name
, &object
->members
[i
].u
.property
.put
);
786 if (FAILED(hres
)) return hres
;
795 static HRESULT
init_script_host(struct script_host
*host
, IActiveScript
*clone
)
801 IClassFactoryEx
*factory_ex
;
802 IClassFactory
*factory
;
806 if (FAILED(hres
= CLSIDFromProgID(host
->language
, &clsid
)))
808 WARN("Could not find script engine for %s\n", debugstr_w(host
->language
));
812 hres
= CoGetClassObject(&clsid
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
, NULL
,
813 &IID_IClassFactory
, (void**)&factory
);
814 if (FAILED(hres
)) return hres
;
816 hres
= IClassFactory_QueryInterface(factory
, &IID_IClassFactoryEx
, (void**)&factory_ex
);
819 FIXME("Use IClassFactoryEx\n");
820 IClassFactoryEx_Release(factory_ex
);
823 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IUnknown
, (void**)&unk
);
824 IClassFactory_Release(factory
);
825 if (FAILED(hres
)) return hres
;
827 hres
= IUnknown_QueryInterface(unk
, &IID_IActiveScript
, (void**)&host
->active_script
);
828 IUnknown_Release(unk
);
829 if (FAILED(hres
)) return hres
;
833 IActiveScript_AddRef(clone
);
834 host
->active_script
= clone
;
838 hres
= IActiveScript_QueryInterface(host
->active_script
, &IID_IActiveScriptParse
, (void**)&host
->parser
);
839 if (FAILED(hres
)) return hres
;
843 hres
= IActiveScriptParse_InitNew(host
->parser
);
846 IActiveScriptParse_Release(host
->parser
);
852 return IActiveScript_SetScriptSite(host
->active_script
, &host
->IActiveScriptSite_iface
);
855 static HRESULT
create_script_host(const WCHAR
*language
, IActiveScript
*origin_script
, struct list
*hosts
, struct script_host
**ret
)
857 IActiveScript
*clone
= NULL
;
858 struct script_host
*host
;
861 if (!(host
= heap_alloc_zero(sizeof(*host
)))) return E_OUTOFMEMORY
;
863 host
->IActiveScriptSite_iface
.lpVtbl
= &ActiveScriptSiteVtbl
;
864 host
->IActiveScriptSiteWindow_iface
.lpVtbl
= &ActiveScriptSiteWindowVtbl
;
865 host
->IServiceProvider_iface
.lpVtbl
= &ServiceProviderVtbl
;
867 host
->state
= SCRIPTSTATE_CLOSED
;
869 if (!(host
->language
= heap_strdupW(language
)))
871 IActiveScriptSite_Release(&host
->IActiveScriptSite_iface
);
872 return E_OUTOFMEMORY
;
877 hres
= IActiveScript_Clone(origin_script
, &clone
);
878 if (FAILED(hres
)) clone
= NULL
;
881 list_add_tail(hosts
, &host
->entry
);
882 hres
= init_script_host(host
, clone
);
883 if (clone
) IActiveScript_Release(clone
);
884 if (FAILED(hres
)) return hres
;
885 if (ret
) *ret
= host
;
889 static void detach_script_hosts(struct list
*hosts
)
891 while (!list_empty(hosts
))
893 struct script_host
*host
= LIST_ENTRY(list_head(hosts
), struct script_host
, entry
);
894 if (host
->state
!= SCRIPTSTATE_UNINITIALIZED
) set_script_state(host
, SCRIPTSTATE_UNINITIALIZED
);
895 list_remove(&host
->entry
);
897 if (host
->script_dispatch
)
899 IDispatchEx_Release(host
->script_dispatch
);
900 host
->script_dispatch
= NULL
;
904 IActiveScript_Close(host
->active_script
);
905 IActiveScriptParse_Release(host
->parser
);
908 if (host
->active_script
)
910 IActiveScript_Release(host
->active_script
);
911 host
->active_script
= NULL
;
913 IActiveScriptSite_Release(&host
->IActiveScriptSite_iface
);
917 static HRESULT
create_scriptlet_hosts(struct scriptlet_factory
*factory
, struct list
*hosts
)
919 struct scriptlet_script
*script
;
922 LIST_FOR_EACH_ENTRY(script
, &factory
->scripts
, struct scriptlet_script
, entry
)
924 if (find_script_host(hosts
, script
->language
)) continue;
925 hres
= create_script_host(script
->language
, NULL
, hosts
, NULL
);
928 detach_script_hosts(hosts
);
936 static inline struct scriptlet_instance
*impl_from_IDispatchEx(IDispatchEx
*iface
)
938 return CONTAINING_RECORD(iface
, struct scriptlet_instance
, IDispatchEx_iface
);
941 static HRESULT WINAPI
scriptlet_QueryInterface(IDispatchEx
*iface
, REFIID riid
, void **ppv
)
943 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
945 if (IsEqualGUID(&IID_IUnknown
, riid
))
947 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
948 *ppv
= &This
->IDispatchEx_iface
;
950 else if (IsEqualGUID(&IID_IDispatch
, riid
))
952 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
953 *ppv
= &This
->IDispatchEx_iface
;
955 else if (IsEqualGUID(&IID_IDispatchEx
, riid
))
957 TRACE("(%p)->(IID_IDispatchEx %p)\n", This
, ppv
);
958 *ppv
= &This
->IDispatchEx_iface
;
962 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
964 return E_NOINTERFACE
;
967 IUnknown_AddRef((IUnknown
*)*ppv
);
971 static ULONG WINAPI
scriptlet_AddRef(IDispatchEx
*iface
)
973 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
974 ULONG ref
= InterlockedIncrement(&This
->ref
);
976 TRACE("(%p) ref=%d\n", This
, ref
);
981 static ULONG WINAPI
scriptlet_Release(IDispatchEx
*iface
)
983 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
984 ULONG ref
= InterlockedDecrement(&This
->ref
);
986 TRACE("(%p) ref=%d\n", This
, ref
);
991 for (i
= 0; i
< This
->member_cnt
; i
++)
992 SysFreeString(This
->members
[i
].name
);
993 heap_free(This
->members
);
994 detach_script_hosts(&This
->hosts
);
995 if (This
->global
) IDispatchEx_Release(&This
->global
->IDispatchEx_iface
);
1001 static HRESULT WINAPI
scriptlet_GetTypeInfoCount(IDispatchEx
*iface
, UINT
*pctinfo
)
1003 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1004 FIXME("(%p)->(%p)\n", This
, pctinfo
);
1008 static HRESULT WINAPI
scriptlet_GetTypeInfo(IDispatchEx
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1010 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1011 FIXME("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1015 static HRESULT WINAPI
scriptlet_GetIDsOfNames(IDispatchEx
*iface
, REFIID riid
,
1016 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1018 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1022 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
1025 for(i
=0; i
< cNames
; i
++)
1027 hres
= IDispatchEx_GetDispID(&This
->IDispatchEx_iface
, rgszNames
[i
], 0, rgDispId
+ i
);
1035 static HRESULT WINAPI
scriptlet_Invoke(IDispatchEx
*iface
, DISPID dispIdMember
,
1036 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
1037 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1039 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1040 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1041 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1042 return IDispatchEx_InvokeEx(&This
->IDispatchEx_iface
, dispIdMember
, lcid
, wFlags
,
1043 pDispParams
, pVarResult
, pExcepInfo
, NULL
);
1046 static HRESULT WINAPI
scriptlet_GetDispID(IDispatchEx
*iface
, BSTR bstrName
, DWORD grfdex
, DISPID
*pid
)
1048 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1051 TRACE("(%p)->(%s %x %p)\n", This
, debugstr_w(bstrName
), grfdex
, pid
);
1053 if (grfdex
& ~(fdexNameCaseInsensitive
|fdexNameCaseSensitive
))
1054 FIXME("Unsupported grfdex %x\n", grfdex
);
1056 for (i
= 0; i
< This
->member_cnt
; i
++)
1058 if (grfdex
& fdexNameCaseInsensitive
)
1060 if (wcsicmp(This
->members
[i
].name
, bstrName
)) continue;
1062 else if (wcscmp(This
->members
[i
].name
, bstrName
)) continue;
1067 WARN("Unknown property %s\n", debugstr_w(bstrName
));
1068 return DISP_E_UNKNOWNNAME
;
1071 static HRESULT WINAPI
scriptlet_InvokeEx(IDispatchEx
*iface
, DISPID id
, LCID lcid
, WORD flags
, DISPPARAMS
*pdp
,
1072 VARIANT
*res
, EXCEPINFO
*pei
, IServiceProvider
*caller
)
1074 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1075 FIXME("(%p)->(%x %x %x %p %p %p %p)\n", This
, id
, lcid
, flags
, pdp
, res
, pei
, caller
);
1076 return DISP_E_MEMBERNOTFOUND
;
1079 static HRESULT WINAPI
scriptlet_DeleteMemberByName(IDispatchEx
*iface
, BSTR bstrName
, DWORD grfdex
)
1081 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1082 FIXME("(%p)->(%s %x)\n", This
, debugstr_w(bstrName
), grfdex
);
1086 static HRESULT WINAPI
scriptlet_DeleteMemberByDispID(IDispatchEx
*iface
, DISPID id
)
1088 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1089 FIXME("(%p)->(%x)\n", This
, id
);
1093 static HRESULT WINAPI
scriptlet_GetMemberProperties(IDispatchEx
*iface
, DISPID id
, DWORD grfdexFetch
, DWORD
*pgrfdex
)
1095 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1096 FIXME("(%p)->(%x %x %p)\n", This
, id
, grfdexFetch
, pgrfdex
);
1100 static HRESULT WINAPI
scriptlet_GetMemberName(IDispatchEx
*iface
, DISPID id
, BSTR
*pbstrName
)
1102 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1103 FIXME("(%p)->(%x %p)\n", This
, id
, pbstrName
);
1107 static HRESULT WINAPI
scriptlet_GetNextDispID(IDispatchEx
*iface
, DWORD grfdex
, DISPID id
, DISPID
*pid
)
1109 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1110 FIXME("(%p)->(%x %x %p)\n", This
, grfdex
, id
, pid
);
1114 static HRESULT WINAPI
scriptlet_GetNameSpaceParent(IDispatchEx
*iface
, IUnknown
**ppunk
)
1116 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1117 FIXME("(%p)->(%p)\n", This
, ppunk
);
1121 static IDispatchExVtbl DispatchExVtbl
= {
1122 scriptlet_QueryInterface
,
1125 scriptlet_GetTypeInfoCount
,
1126 scriptlet_GetTypeInfo
,
1127 scriptlet_GetIDsOfNames
,
1129 scriptlet_GetDispID
,
1131 scriptlet_DeleteMemberByName
,
1132 scriptlet_DeleteMemberByDispID
,
1133 scriptlet_GetMemberProperties
,
1134 scriptlet_GetMemberName
,
1135 scriptlet_GetNextDispID
,
1136 scriptlet_GetNameSpaceParent
1139 static HRESULT
create_scriptlet_instance(struct scriptlet_factory
*factory
, IDispatchEx
**disp
)
1141 struct script_host
*factory_host
, *host
;
1142 struct scriptlet_instance
*obj
;
1143 IDispatch
*script_dispatch
;
1146 if (!(obj
= heap_alloc_zero(sizeof(*obj
)))) return E_OUTOFMEMORY
;
1148 obj
->IDispatchEx_iface
.lpVtbl
= &DispatchExVtbl
;
1150 list_init(&obj
->hosts
);
1152 if (!(obj
->global
= heap_alloc(sizeof(*obj
->global
))))
1154 IDispatchEx_Release(&obj
->IDispatchEx_iface
);
1155 return E_OUTOFMEMORY
;
1157 obj
->global
->IDispatchEx_iface
.lpVtbl
= &global_vtbl
;
1158 obj
->global
->ref
= 1;
1160 LIST_FOR_EACH_ENTRY(factory_host
, &factory
->hosts
, struct script_host
, entry
)
1162 hres
= create_script_host(factory_host
->language
, factory_host
->active_script
, &obj
->hosts
, &host
);
1163 if (FAILED(hres
)) break;
1166 hres
= IActiveScript_AddNamedItem(host
->active_script
, L
"scriptlet",
1167 SCRIPTITEM_ISVISIBLE
| SCRIPTITEM_GLOBALMEMBERS
);
1168 if (FAILED(hres
)) break;
1170 hres
= IActiveScript_AddNamedItem(host
->active_script
, L
"globals", SCRIPTITEM_ISVISIBLE
);
1171 if (FAILED(hres
)) break;
1173 hres
= IActiveScript_GetScriptDispatch(host
->active_script
, NULL
, &script_dispatch
);
1174 if (FAILED(hres
)) return hres
;
1176 hres
= IDispatch_QueryInterface(script_dispatch
, &IID_IDispatchEx
, (void**)&host
->script_dispatch
);
1177 IDispatch_Release(script_dispatch
);
1180 FIXME("IDispatchEx not supported by script engine\n");
1185 if (SUCCEEDED(hres
)) hres
= parse_scripts(factory
, &obj
->hosts
, TRUE
);
1186 if (SUCCEEDED(hres
)) hres
= lookup_object_properties(obj
, factory
);
1189 IDispatchEx_Release(&obj
->IDispatchEx_iface
);
1193 *disp
= &obj
->IDispatchEx_iface
;
1197 static const char *debugstr_xml_name(struct scriptlet_factory
*factory
)
1202 hres
= IXmlReader_GetLocalName(factory
->xml_reader
, &str
, &len
);
1203 if (FAILED(hres
)) return "#err";
1204 return debugstr_wn(str
, len
);
1207 static HRESULT
next_xml_node(struct scriptlet_factory
*factory
, XmlNodeType
*node_type
)
1210 do hres
= IXmlReader_Read(factory
->xml_reader
, node_type
);
1211 while (hres
== S_OK
&& *node_type
== XmlNodeType_Whitespace
);
1215 static BOOL
is_xml_name(struct scriptlet_factory
*factory
, const WCHAR
*name
)
1220 hres
= IXmlReader_GetQualifiedName(factory
->xml_reader
, &qname
, &len
);
1221 return hres
== S_OK
&& len
== wcslen(name
) && !memcmp(qname
, name
, len
* sizeof(WCHAR
));
1224 static HRESULT
expect_end_element(struct scriptlet_factory
*factory
)
1226 XmlNodeType node_type
;
1228 hres
= next_xml_node(factory
, &node_type
);
1229 if (hres
!= S_OK
|| node_type
!= XmlNodeType_EndElement
)
1231 FIXME("Unexpected node %u %s\n", node_type
, debugstr_xml_name(factory
));
1237 static HRESULT
expect_no_attributes(struct scriptlet_factory
*factory
)
1241 hres
= IXmlReader_GetAttributeCount(factory
->xml_reader
, &count
);
1242 if (FAILED(hres
)) return hres
;
1243 if (!count
) return S_OK
;
1244 FIXME("Unexpected attributes\n");
1248 static BOOL
is_case_xml_name(struct scriptlet_factory
*factory
, const WCHAR
*name
)
1253 hres
= IXmlReader_GetQualifiedName(factory
->xml_reader
, &qname
, &len
);
1254 return hres
== S_OK
&& len
== wcslen(name
) && !memicmp(qname
, name
, len
* sizeof(WCHAR
));
1257 static HRESULT
read_xml_value(struct scriptlet_factory
*factory
, WCHAR
**ret
)
1262 hres
= IXmlReader_GetValue(factory
->xml_reader
, &str
, &len
);
1263 if (FAILED(hres
)) return hres
;
1264 if (!(*ret
= heap_alloc((len
+ 1) * sizeof(WCHAR
)))) return E_OUTOFMEMORY
;
1265 memcpy(*ret
, str
, len
* sizeof(WCHAR
));
1270 static HRESULT
parse_scriptlet_registration(struct scriptlet_factory
*factory
)
1274 if (factory
->have_registration
)
1276 FIXME("duplicated registration element\n");
1279 factory
->have_registration
= TRUE
;
1283 hres
= IXmlReader_MoveToNextAttribute(factory
->xml_reader
);
1284 if (hres
!= S_OK
) break;
1286 if (is_xml_name(factory
, L
"description"))
1288 if (factory
->description
)
1290 FIXME("Duplicated description\n");
1293 hres
= read_xml_value(factory
, &factory
->description
);
1294 if (FAILED(hres
)) return hres
;
1296 else if (is_case_xml_name(factory
, L
"progid"))
1298 if (factory
->progid
)
1300 FIXME("Duplicated progid\n");
1303 hres
= read_xml_value(factory
, &factory
->progid
);
1304 if (FAILED(hres
)) return hres
;
1306 else if (is_xml_name(factory
, L
"version"))
1308 if (factory
->version
)
1310 FIXME("Duplicated version\n");
1313 hres
= read_xml_value(factory
, &factory
->version
);
1314 if (FAILED(hres
)) return hres
;
1316 else if (is_xml_name(factory
, L
"classid"))
1318 if (factory
->classid_str
)
1320 FIXME("Duplicated classid attribute\n");
1323 hres
= read_xml_value(factory
, &factory
->classid_str
);
1324 if (FAILED(hres
)) return hres
;
1325 hres
= IIDFromString(factory
->classid_str
, &factory
->classid
);
1328 FIXME("Invalid classid %s\n", debugstr_w(factory
->classid_str
));
1335 FIXME("Unexpected attribute\n");
1340 if (!factory
->progid
&& !factory
->classid_str
)
1342 FIXME("Incomplet registration element\n");
1346 if (factory
->progid
)
1348 size_t progid_len
= wcslen(factory
->progid
);
1349 size_t version_len
= wcslen(factory
->version
);
1351 if (!(factory
->versioned_progid
= heap_alloc((progid_len
+ version_len
+ 2) * sizeof(WCHAR
))))
1352 return E_OUTOFMEMORY
;
1354 memcpy(factory
->versioned_progid
, factory
->progid
, (progid_len
+ 1) * sizeof(WCHAR
));
1357 factory
->versioned_progid
[progid_len
++] = '.';
1358 wcscpy(factory
->versioned_progid
+ progid_len
, factory
->version
);
1360 else factory
->versioned_progid
[progid_len
] = 0;
1363 return expect_end_element(factory
);
1366 static HRESULT
parse_scriptlet_public(struct scriptlet_factory
*factory
)
1368 struct scriptlet_member
*member
, *member_iter
;
1369 enum member_type member_type
;
1370 XmlNodeType node_type
;
1376 if (factory
->have_public
)
1378 FIXME("duplicated public element\n");
1381 factory
->have_public
= TRUE
;
1385 hres
= next_xml_node(factory
, &node_type
);
1386 if (FAILED(hres
)) return hres
;
1387 if (node_type
== XmlNodeType_EndElement
) break;
1388 if (node_type
!= XmlNodeType_Element
)
1390 FIXME("Unexpected node type %u\n", node_type
);
1394 if (is_xml_name(factory
, L
"method"))
1395 member_type
= MEMBER_METHOD
;
1396 else if (is_xml_name(factory
, L
"property"))
1397 member_type
= MEMBER_PROPERTY
;
1400 FIXME("Unexpected element %s\n", debugstr_xml_name(factory
));
1404 empty
= IXmlReader_IsEmptyElement(factory
->xml_reader
);
1406 hres
= IXmlReader_MoveToAttributeByName(factory
->xml_reader
, L
"name", NULL
);
1409 FIXME("Missing method name\n");
1413 if (!(member
= heap_alloc(sizeof(*member
)))) return E_OUTOFMEMORY
;
1414 member
->type
= member_type
;
1416 hres
= read_xml_value(factory
, &member
->name
);
1423 LIST_FOR_EACH_ENTRY(member_iter
, &factory
->members
, struct scriptlet_member
, entry
)
1425 if (!wcsicmp(member_iter
->name
, member
->name
))
1427 FIXME("Duplicated member %s\n", debugstr_w(member
->name
));
1431 list_add_tail(&factory
->members
, &member
->entry
);
1433 switch (member_type
)
1436 list_init(&member
->u
.parameters
);
1441 struct method_parameter
*parameter
;
1443 hres
= next_xml_node(factory
, &node_type
);
1444 if (FAILED(hres
)) return hres
;
1445 if (node_type
== XmlNodeType_EndElement
) break;
1446 if (node_type
!= XmlNodeType_Element
)
1448 FIXME("Unexpected node type %u\n", node_type
);
1451 if (!is_case_xml_name(factory
, L
"parameter"))
1453 FIXME("Unexpected method element\n");
1457 empty
= IXmlReader_IsEmptyElement(factory
->xml_reader
);
1459 hres
= IXmlReader_MoveToAttributeByName(factory
->xml_reader
, L
"name", NULL
);
1462 FIXME("Missing parameter name\n");
1466 if (!(parameter
= heap_alloc(sizeof(*parameter
)))) return E_OUTOFMEMORY
;
1468 hres
= read_xml_value(factory
, ¶meter
->name
);
1469 if (FAILED(hres
)) return hres
;
1470 list_add_tail(&member
->u
.parameters
, ¶meter
->entry
);
1471 if (!empty
&& FAILED(hres
= expect_end_element(factory
))) return hres
;
1475 case MEMBER_PROPERTY
:
1476 member
->u
.flags
= 0;
1481 hres
= next_xml_node(factory
, &node_type
);
1482 if (FAILED(hres
)) return hres
;
1483 if (node_type
== XmlNodeType_EndElement
) break;
1484 if (node_type
!= XmlNodeType_Element
)
1486 FIXME("Unexpected node type %u\n", node_type
);
1489 if (is_case_xml_name(factory
, L
"get"))
1491 if (member
->u
.flags
& PROP_GETTER
)
1493 FIXME("Duplicated getter\n");
1496 member
->u
.flags
|= PROP_GETTER
;
1498 else if (is_case_xml_name(factory
, L
"put"))
1500 if (member
->u
.flags
& PROP_SETTER
)
1502 FIXME("Duplicated setter\n");
1505 member
->u
.flags
|= PROP_SETTER
;
1509 FIXME("Unexpected property element %s\n", debugstr_xml_name(factory
));
1513 empty
= IXmlReader_IsEmptyElement(factory
->xml_reader
);
1514 if (!empty
&& FAILED(hres
= expect_end_element(factory
))) return hres
;
1516 if (!member
->u
.flags
)
1518 FIXME("No getter or setter\n");
1523 if (FAILED(hres
)) return hres
;
1529 static HRESULT
parse_scriptlet_script(struct scriptlet_factory
*factory
, struct scriptlet_script
*script
)
1531 XmlNodeType node_type
;
1536 hres
= IXmlReader_MoveToNextAttribute(factory
->xml_reader
);
1537 if (hres
!= S_OK
) break;
1539 if (is_xml_name(factory
, L
"language"))
1541 if (script
->language
)
1543 FIXME("Duplicated language\n");
1546 hres
= read_xml_value(factory
, &script
->language
);
1547 if (FAILED(hres
)) return hres
;
1551 FIXME("Unexpected attribute\n");
1556 if (!script
->language
)
1558 FIXME("Language not specified\n");
1562 if (FAILED(hres
= next_xml_node(factory
, &node_type
))) return hres
;
1564 if (node_type
!= XmlNodeType_Text
&& node_type
!= XmlNodeType_CDATA
)
1566 FIXME("Unexpected node type %u\n", node_type
);
1570 hres
= read_xml_value(factory
, &script
->body
);
1571 if (FAILED(hres
)) return hres
;
1573 return expect_end_element(factory
);
1576 static HRESULT
parse_scriptlet_file(struct scriptlet_factory
*factory
, const WCHAR
*url
)
1578 XmlNodeType node_type
;
1583 hres
= CreateURLMoniker(NULL
, url
, &factory
->moniker
);
1586 WARN("CreateURLMoniker failed: %08x\n", hres
);
1590 hres
= CreateBindCtx(0, &bind_ctx
);
1594 hres
= IMoniker_BindToStorage(factory
->moniker
, bind_ctx
, NULL
, &IID_IStream
, (void**)&stream
);
1595 IBindCtx_Release(bind_ctx
);
1599 hres
= CreateXmlReader(&IID_IXmlReader
, (void**)&factory
->xml_reader
, NULL
);
1601 hres
= IXmlReader_SetInput(factory
->xml_reader
, (IUnknown
*)stream
);
1602 IStream_Release(stream
);
1606 hres
= next_xml_node(factory
, &node_type
);
1607 if (hres
== S_OK
&& node_type
== XmlNodeType_XmlDeclaration
)
1608 hres
= next_xml_node(factory
, &node_type
);
1610 if (node_type
!= XmlNodeType_Element
|| !is_xml_name(factory
, L
"component"))
1612 FIXME("Unexpected %s element\n", debugstr_xml_name(factory
));
1616 hres
= expect_no_attributes(factory
);
1617 if (FAILED(hres
)) return hres
;
1621 hres
= next_xml_node(factory
, &node_type
);
1622 if (FAILED(hres
)) return hres
;
1623 if (node_type
== XmlNodeType_EndElement
) break;
1624 if (node_type
!= XmlNodeType_Element
)
1626 FIXME("Unexpected node type %u\n", node_type
);
1630 if (is_xml_name(factory
, L
"registration"))
1631 hres
= parse_scriptlet_registration(factory
);
1632 else if (is_xml_name(factory
, L
"public"))
1633 hres
= parse_scriptlet_public(factory
);
1634 else if (is_xml_name(factory
, L
"script"))
1636 struct scriptlet_script
*script
;
1637 if (!(script
= heap_alloc_zero(sizeof(*script
)))) return E_OUTOFMEMORY
;
1638 list_add_tail(&factory
->scripts
, &script
->entry
);
1639 hres
= parse_scriptlet_script(factory
, script
);
1640 if (FAILED(hres
)) return hres
;
1644 FIXME("Unexpected element %s\n", debugstr_xml_name(factory
));
1647 if (FAILED(hres
)) return hres
;
1650 hres
= next_xml_node(factory
, &node_type
);
1651 if (hres
!= S_FALSE
)
1653 FIXME("Unexpected node type %u\n", node_type
);
1659 static inline struct scriptlet_factory
*impl_from_IClassFactory(IClassFactory
*iface
)
1661 return CONTAINING_RECORD(iface
, struct scriptlet_factory
, IClassFactory_iface
);
1664 static HRESULT WINAPI
scriptlet_factory_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
1666 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1668 if (IsEqualGUID(&IID_IUnknown
, riid
))
1670 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
1671 *ppv
= &This
->IClassFactory_iface
;
1673 else if (IsEqualGUID(&IID_IClassFactory
, riid
))
1675 TRACE("(%p)->(IID_IClassFactory %p)\n", iface
, ppv
);
1676 *ppv
= &This
->IClassFactory_iface
;
1680 WARN("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
1682 return E_NOINTERFACE
;
1685 IUnknown_AddRef((IUnknown
*)*ppv
);
1689 static ULONG WINAPI
scriptlet_factory_AddRef(IClassFactory
*iface
)
1691 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1692 ULONG ref
= InterlockedIncrement(&This
->ref
);
1694 TRACE("(%p) ref=%d\n", This
, ref
);
1699 static ULONG WINAPI
scriptlet_factory_Release(IClassFactory
*iface
)
1701 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1702 ULONG ref
= InterlockedDecrement(&This
->ref
);
1704 TRACE("(%p) ref=%d\n", This
, ref
);
1708 if (This
->moniker
) IMoniker_Release(This
->moniker
);
1709 if (This
->xml_reader
) IXmlReader_Release(This
->xml_reader
);
1710 detach_script_hosts(&This
->hosts
);
1711 while (!list_empty(&This
->members
))
1713 struct scriptlet_member
*member
= LIST_ENTRY(list_head(&This
->members
), struct scriptlet_member
, entry
);
1714 list_remove(&member
->entry
);
1715 heap_free(member
->name
);
1716 if (member
->type
== MEMBER_METHOD
)
1718 while (!list_empty(&member
->u
.parameters
))
1720 struct method_parameter
*parameter
= LIST_ENTRY(list_head(&member
->u
.parameters
), struct method_parameter
, entry
);
1721 list_remove(¶meter
->entry
);
1722 heap_free(parameter
->name
);
1723 heap_free(parameter
);
1728 while (!list_empty(&This
->scripts
))
1730 struct scriptlet_script
*script
= LIST_ENTRY(list_head(&This
->scripts
), struct scriptlet_script
, entry
);
1731 list_remove(&script
->entry
);
1732 heap_free(script
->language
);
1733 heap_free(script
->body
);
1736 heap_free(This
->classid_str
);
1737 heap_free(This
->description
);
1738 heap_free(This
->versioned_progid
);
1739 heap_free(This
->progid
);
1740 heap_free(This
->version
);
1746 static HRESULT WINAPI
scriptlet_factory_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID riid
, void **ppv
)
1748 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1752 TRACE("(%p)->(%p %s %p)\n", This
, outer
, debugstr_guid(riid
), ppv
);
1754 if (outer
) FIXME("outer not supported\n");
1756 if (list_empty(&This
->hosts
))
1758 hres
= create_scriptlet_hosts(This
, &This
->hosts
);
1759 if (FAILED(hres
)) return hres
;
1761 hres
= parse_scripts(This
, &This
->hosts
, FALSE
);
1764 detach_script_hosts(&This
->hosts
);
1769 hres
= create_scriptlet_instance(This
, &disp
);
1770 if (FAILED(hres
)) return hres
;
1772 hres
= IDispatchEx_QueryInterface(disp
, riid
, ppv
);
1773 IDispatchEx_Release(disp
);
1777 static HRESULT WINAPI
scriptlet_factory_LockServer(IClassFactory
*iface
, BOOL fLock
)
1779 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1780 TRACE("(%p)->(%x)\n", This
, fLock
);
1784 static const struct IClassFactoryVtbl scriptlet_factory_vtbl
=
1786 scriptlet_factory_QueryInterface
,
1787 scriptlet_factory_AddRef
,
1788 scriptlet_factory_Release
,
1789 scriptlet_factory_CreateInstance
,
1790 scriptlet_factory_LockServer
1793 static HRESULT
create_scriptlet_factory(const WCHAR
*url
, struct scriptlet_factory
**ret
)
1795 struct scriptlet_factory
*factory
;
1798 TRACE("%s\n", debugstr_w(url
));
1800 if (!(factory
= heap_alloc_zero(sizeof(*factory
))))
1802 IClassFactory_Release(&factory
->IClassFactory_iface
);
1803 return E_OUTOFMEMORY
;
1806 factory
->IClassFactory_iface
.lpVtbl
= &scriptlet_factory_vtbl
;
1808 list_init(&factory
->hosts
);
1809 list_init(&factory
->members
);
1810 list_init(&factory
->scripts
);
1812 hres
= parse_scriptlet_file(factory
, url
);
1815 IClassFactory_Release(&factory
->IClassFactory_iface
);
1823 static HRESULT
register_scriptlet(struct scriptlet_factory
*factory
)
1825 HKEY key
, clsid_key
, obj_key
;
1829 if (factory
->classid_str
)
1833 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, L
"CLSID", &clsid_key
);
1834 if (status
) return E_ACCESSDENIED
;
1836 status
= RegCreateKeyW(clsid_key
, factory
->classid_str
, &obj_key
);
1837 RegCloseKey(clsid_key
);
1838 if (status
) return E_ACCESSDENIED
;
1840 hres
= IMoniker_GetDisplayName(factory
->moniker
, NULL
, NULL
, &url
);
1843 RegCloseKey(obj_key
);
1846 status
= RegCreateKeyW(obj_key
, L
"ScriptletURL", &key
);
1849 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)url
,
1850 (wcslen(url
) + 1) * sizeof(WCHAR
));
1855 if (factory
->description
)
1856 status
= RegSetValueExW(obj_key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->description
,
1857 (wcslen(factory
->description
) + 1) * sizeof(WCHAR
));
1861 status
= RegCreateKeyW(obj_key
, L
"InprocServer32", &key
);
1864 WCHAR str
[MAX_PATH
];
1865 GetModuleFileNameW(scrobj_instance
, str
, MAX_PATH
);
1866 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)str
, (wcslen(str
) + 1) * sizeof(WCHAR
));
1871 if (!status
&& factory
->versioned_progid
)
1873 status
= RegCreateKeyW(obj_key
, L
"ProgID", &key
);
1876 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->versioned_progid
,
1877 (wcslen(factory
->versioned_progid
) + 1) * sizeof(WCHAR
));
1882 if (!status
&& factory
->progid
)
1884 status
= RegCreateKeyW(obj_key
, L
"VersionIndependentProgID", &key
);
1887 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->progid
,
1888 (wcslen(factory
->progid
) + 1) * sizeof(WCHAR
));
1893 RegCloseKey(obj_key
);
1894 if (status
) return E_ACCESSDENIED
;
1897 if (factory
->progid
)
1899 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, factory
->progid
, &key
);
1900 if (status
) return E_ACCESSDENIED
;
1902 if (factory
->description
)
1903 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->description
,
1904 (wcslen(factory
->description
) + 1) * sizeof(WCHAR
));
1906 if (!status
&& factory
->classid_str
)
1908 status
= RegCreateKeyW(key
, L
"CLSID", &clsid_key
);
1911 status
= RegSetValueExW(clsid_key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->classid_str
,
1912 (wcslen(factory
->classid_str
) + 1) * sizeof(WCHAR
));
1913 RegCloseKey(clsid_key
);
1918 if (status
) return E_ACCESSDENIED
;
1921 if (factory
->versioned_progid
)
1923 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, factory
->versioned_progid
, &key
);
1924 if (status
) return E_ACCESSDENIED
;
1926 if (factory
->description
)
1927 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->description
,
1928 (wcslen(factory
->description
) + 1) * sizeof(WCHAR
));
1930 if (!status
&& factory
->classid_str
)
1932 status
= RegCreateKeyW(key
, L
"CLSID", &clsid_key
);
1935 status
= RegSetValueExW(clsid_key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->classid_str
,
1936 (wcslen(factory
->classid_str
) + 1) * sizeof(WCHAR
));
1937 RegCloseKey(clsid_key
);
1942 if (status
) return E_ACCESSDENIED
;
1948 static HRESULT
unregister_scriptlet(struct scriptlet_factory
*factory
)
1952 if (factory
->classid_str
)
1955 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, L
"CLSID", &clsid_key
);
1958 RegDeleteTreeW(clsid_key
, factory
->classid_str
);
1959 RegCloseKey(clsid_key
);
1963 if (factory
->progid
) RegDeleteTreeW(HKEY_CLASSES_ROOT
, factory
->progid
);
1964 if (factory
->versioned_progid
) RegDeleteTreeW(HKEY_CLASSES_ROOT
, factory
->versioned_progid
);
1968 struct scriptlet_typelib
1970 IGenScriptletTLib IGenScriptletTLib_iface
;
1976 static inline struct scriptlet_typelib
*impl_from_IGenScriptletTLib(IGenScriptletTLib
*iface
)
1978 return CONTAINING_RECORD(iface
, struct scriptlet_typelib
, IGenScriptletTLib_iface
);
1981 static HRESULT WINAPI
scriptlet_typelib_QueryInterface(IGenScriptletTLib
*iface
, REFIID riid
, void **obj
)
1983 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
1985 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), obj
);
1987 if (IsEqualIID(riid
, &IID_IGenScriptletTLib
) ||
1988 IsEqualIID(riid
, &IID_IDispatch
) ||
1989 IsEqualIID(riid
, &IID_IUnknown
))
1992 IGenScriptletTLib_AddRef(iface
);
1997 return E_NOINTERFACE
;
2000 static ULONG WINAPI
scriptlet_typelib_AddRef(IGenScriptletTLib
*iface
)
2002 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2003 ULONG ref
= InterlockedIncrement(&This
->ref
);
2004 TRACE("(%p)->(%u)\n", This
, ref
);
2008 static ULONG WINAPI
scriptlet_typelib_Release(IGenScriptletTLib
*iface
)
2010 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2011 LONG ref
= InterlockedDecrement(&This
->ref
);
2013 TRACE("(%p)->(%u)\n", This
, ref
);
2017 SysFreeString(This
->guid
);
2018 HeapFree(GetProcessHeap(), 0, This
);
2024 static HRESULT WINAPI
scriptlet_typelib_GetTypeInfoCount(IGenScriptletTLib
*iface
, UINT
*count
)
2026 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2028 TRACE("(%p, %p)\n", This
, count
);
2034 static HRESULT WINAPI
scriptlet_typelib_GetTypeInfo(IGenScriptletTLib
*iface
, UINT index
, LCID lcid
,
2037 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2039 TRACE("(%p, %u, %x, %p)\n", This
, index
, lcid
, tinfo
);
2041 return get_typeinfo(IGenScriptletTLib_tid
, tinfo
);
2044 static HRESULT WINAPI
scriptlet_typelib_GetIDsOfNames(IGenScriptletTLib
*iface
, REFIID riid
, LPOLESTR
*names
,
2045 UINT cNames
, LCID lcid
, DISPID
*dispid
)
2047 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2048 ITypeInfo
*typeinfo
;
2051 TRACE("(%p, %s, %p, %u, %x, %p)\n", This
, debugstr_guid(riid
), names
, cNames
, lcid
, dispid
);
2053 hr
= get_typeinfo(IGenScriptletTLib_tid
, &typeinfo
);
2056 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, cNames
, dispid
);
2057 ITypeInfo_Release(typeinfo
);
2063 static HRESULT WINAPI
scriptlet_typelib_Invoke(IGenScriptletTLib
*iface
, DISPID dispid
, REFIID riid
,
2064 LCID lcid
, WORD flags
, DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*ei
, UINT
*argerr
)
2066 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2067 ITypeInfo
*typeinfo
;
2070 TRACE("(%p, %d, %s, %x, %x, %p, %p, %p, %p)\n", This
, dispid
, debugstr_guid(riid
), lcid
, flags
,
2071 params
, result
, ei
, argerr
);
2073 hr
= get_typeinfo(IGenScriptletTLib_tid
, &typeinfo
);
2076 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IGenScriptletTLib_iface
, dispid
, flags
,
2077 params
, result
, ei
, argerr
);
2078 ITypeInfo_Release(typeinfo
);
2084 static HRESULT WINAPI
scriptlet_typelib_AddURL(IGenScriptletTLib
*iface
, BSTR url
)
2086 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2088 FIXME("(%p, %s): stub\n", This
, debugstr_w(url
));
2093 static HRESULT WINAPI
scriptlet_typelib_put_Path(IGenScriptletTLib
*iface
, BSTR path
)
2095 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2097 FIXME("(%p, %s): stub\n", This
, debugstr_w(path
));
2102 static HRESULT WINAPI
scriptlet_typelib_get_Path(IGenScriptletTLib
*iface
, BSTR
*path
)
2104 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2106 FIXME("(%p, %p): stub\n", This
, path
);
2111 static HRESULT WINAPI
scriptlet_typelib_put_Doc(IGenScriptletTLib
*iface
, BSTR doc
)
2113 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2115 FIXME("(%p, %s): stub\n", This
, debugstr_w(doc
));
2120 static HRESULT WINAPI
scriptlet_typelib_get_Doc(IGenScriptletTLib
*iface
, BSTR
*doc
)
2122 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2124 FIXME("(%p, %p): stub\n", This
, doc
);
2129 static HRESULT WINAPI
scriptlet_typelib_put_Name(IGenScriptletTLib
*iface
, BSTR name
)
2131 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2133 FIXME("(%p, %s): stub\n", This
, debugstr_w(name
));
2138 static HRESULT WINAPI
scriptlet_typelib_get_Name(IGenScriptletTLib
*iface
, BSTR
*name
)
2140 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2142 FIXME("(%p, %p): stub\n", This
, name
);
2147 static HRESULT WINAPI
scriptlet_typelib_put_MajorVersion(IGenScriptletTLib
*iface
, WORD version
)
2149 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2151 FIXME("(%p, %x): stub\n", This
, version
);
2156 static HRESULT WINAPI
scriptlet_typelib_get_MajorVersion(IGenScriptletTLib
*iface
, WORD
*version
)
2158 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2160 FIXME("(%p, %p): stub\n", This
, version
);
2165 static HRESULT WINAPI
scriptlet_typelib_put_MinorVersion(IGenScriptletTLib
*iface
, WORD version
)
2167 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2169 FIXME("(%p, %x): stub\n", This
, version
);
2174 static HRESULT WINAPI
scriptlet_typelib_get_MinorVersion(IGenScriptletTLib
*iface
, WORD
*version
)
2176 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2178 FIXME("(%p, %p): stub\n", This
, version
);
2183 static HRESULT WINAPI
scriptlet_typelib_Write(IGenScriptletTLib
*iface
)
2185 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2187 FIXME("(%p): stub\n", This
);
2192 static HRESULT WINAPI
scriptlet_typelib_Reset(IGenScriptletTLib
*iface
)
2194 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2196 FIXME("(%p): stub\n", This
);
2201 static HRESULT WINAPI
scriptlet_typelib_put_GUID(IGenScriptletTLib
*iface
, BSTR guid
)
2203 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2205 FIXME("(%p, %s): stub\n", This
, debugstr_w(guid
));
2210 static HRESULT WINAPI
scriptlet_typelib_get_GUID(IGenScriptletTLib
*iface
, BSTR
*ret
)
2212 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2214 TRACE("(%p, %p)\n", This
, ret
);
2224 hr
= CoCreateGuid(&guid
);
2228 hr
= StringFromGUID2(&guid
, guidW
, ARRAY_SIZE(guidW
));
2232 if (!(This
->guid
= SysAllocString(guidW
)))
2233 return E_OUTOFMEMORY
;
2236 *ret
= SysAllocString(This
->guid
);
2237 return *ret
? S_OK
: E_OUTOFMEMORY
;
2240 static const IGenScriptletTLibVtbl scriptlet_typelib_vtbl
=
2242 scriptlet_typelib_QueryInterface
,
2243 scriptlet_typelib_AddRef
,
2244 scriptlet_typelib_Release
,
2245 scriptlet_typelib_GetTypeInfoCount
,
2246 scriptlet_typelib_GetTypeInfo
,
2247 scriptlet_typelib_GetIDsOfNames
,
2248 scriptlet_typelib_Invoke
,
2249 scriptlet_typelib_AddURL
,
2250 scriptlet_typelib_put_Path
,
2251 scriptlet_typelib_get_Path
,
2252 scriptlet_typelib_put_Doc
,
2253 scriptlet_typelib_get_Doc
,
2254 scriptlet_typelib_put_Name
,
2255 scriptlet_typelib_get_Name
,
2256 scriptlet_typelib_put_MajorVersion
,
2257 scriptlet_typelib_get_MajorVersion
,
2258 scriptlet_typelib_put_MinorVersion
,
2259 scriptlet_typelib_get_MinorVersion
,
2260 scriptlet_typelib_Write
,
2261 scriptlet_typelib_Reset
,
2262 scriptlet_typelib_put_GUID
,
2263 scriptlet_typelib_get_GUID
2266 BOOL WINAPI
DllMain(HINSTANCE hinst
, DWORD reason
, void *reserved
)
2268 TRACE("%p, %u, %p\n", hinst
, reason
, reserved
);
2272 case DLL_WINE_PREATTACH
:
2273 return FALSE
; /* prefer native version */
2274 case DLL_PROCESS_ATTACH
:
2275 DisableThreadLibraryCalls(hinst
);
2276 scrobj_instance
= hinst
;
2278 case DLL_PROCESS_DETACH
:
2279 if (reserved
) break;
2286 /***********************************************************************
2287 * DllRegisterServer (scrobj.@)
2289 HRESULT WINAPI
DllRegisterServer(void)
2292 return __wine_register_resources(scrobj_instance
);
2295 /***********************************************************************
2296 * DllUnregisterServer (scrobj.@)
2298 HRESULT WINAPI
DllUnregisterServer(void)
2301 return __wine_unregister_resources(scrobj_instance
);
2304 /***********************************************************************
2305 * DllInstall (scrobj.@)
2307 HRESULT WINAPI
DllInstall(BOOL install
, const WCHAR
*arg
)
2309 struct scriptlet_factory
*factory
;
2314 hres
= DllRegisterServer();
2315 if (!arg
|| FAILED(hres
)) return hres
;
2318 return DllUnregisterServer();
2320 hres
= create_scriptlet_factory(arg
, &factory
);
2321 if (SUCCEEDED(hres
))
2323 if (factory
->have_registration
)
2325 /* validate scripts */
2326 hres
= create_scriptlet_hosts(factory
, &factory
->hosts
);
2327 if (SUCCEEDED(hres
)) hres
= parse_scripts(factory
, &factory
->hosts
, FALSE
);
2331 FIXME("No registration info\n");
2334 if (SUCCEEDED(hres
))
2337 hres
= register_scriptlet(factory
);
2339 hres
= unregister_scriptlet(factory
);
2341 IClassFactory_Release(&factory
->IClassFactory_iface
);
2347 static HRESULT WINAPI
scriptlet_typelib_CreateInstance(IClassFactory
*factory
, IUnknown
*outer
, REFIID riid
, void **obj
)
2349 struct scriptlet_typelib
*This
;
2352 TRACE("(%p, %p, %s, %p)\n", factory
, outer
, debugstr_guid(riid
), obj
);
2356 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
2358 return E_OUTOFMEMORY
;
2360 This
->IGenScriptletTLib_iface
.lpVtbl
= &scriptlet_typelib_vtbl
;
2364 hr
= IGenScriptletTLib_QueryInterface(&This
->IGenScriptletTLib_iface
, riid
, obj
);
2365 IGenScriptletTLib_Release(&This
->IGenScriptletTLib_iface
);
2369 static HRESULT WINAPI
scrruncf_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
2373 if (IsEqualGUID(&IID_IUnknown
, riid
))
2375 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
2378 else if (IsEqualGUID(&IID_IClassFactory
, riid
))
2380 TRACE("(%p)->(IID_IClassFactory %p)\n", iface
, ppv
);
2386 IUnknown_AddRef((IUnknown
*)*ppv
);
2390 WARN("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
2391 return E_NOINTERFACE
;
2394 static ULONG WINAPI
scrruncf_AddRef(IClassFactory
*iface
)
2396 TRACE("(%p)\n", iface
);
2400 static ULONG WINAPI
scrruncf_Release(IClassFactory
*iface
)
2402 TRACE("(%p)\n", iface
);
2406 static HRESULT WINAPI
scrruncf_LockServer(IClassFactory
*iface
, BOOL fLock
)
2408 TRACE("(%p)->(%x)\n", iface
, fLock
);
2412 static const struct IClassFactoryVtbl scriptlet_typelib_factory_vtbl
=
2414 scrruncf_QueryInterface
,
2417 scriptlet_typelib_CreateInstance
,
2421 static IClassFactory scriptlet_typelib_factory
= { &scriptlet_typelib_factory_vtbl
};
2423 /***********************************************************************
2424 * DllGetClassObject (scrobj.@)
2426 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **ppv
)
2428 WCHAR key_name
[128], *p
;
2432 if (IsEqualGUID(&CLSID_TypeLib
, rclsid
))
2434 TRACE("(Scriptlet.TypeLib %s %p)\n", debugstr_guid(riid
), ppv
);
2435 return IClassFactory_QueryInterface(&scriptlet_typelib_factory
, riid
, ppv
);
2438 wcscpy(key_name
, L
"CLSID\\");
2439 p
= key_name
+ wcslen(key_name
);
2440 p
+= StringFromGUID2(rclsid
, p
, ARRAY_SIZE(key_name
) - (p
- key_name
)) - 1;
2441 wcscpy(p
, L
"\\ScriptletURL");
2442 status
= RegQueryValueW(HKEY_CLASSES_ROOT
, key_name
, NULL
, &size
);
2445 struct scriptlet_factory
*factory
;
2449 if (!(url
= heap_alloc(size
* sizeof(WCHAR
)))) return E_OUTOFMEMORY
;
2450 status
= RegQueryValueW(HKEY_CLASSES_ROOT
, key_name
, url
, &size
);
2452 hres
= create_scriptlet_factory(url
, &factory
);
2454 if (FAILED(hres
)) return hres
;
2456 hres
= IClassFactory_QueryInterface(&factory
->IClassFactory_iface
, riid
, ppv
);
2457 IClassFactory_Release(&factory
->IClassFactory_iface
);
2461 FIXME("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
2462 return CLASS_E_CLASSNOTAVAILABLE
;
2465 /***********************************************************************
2466 * DllCanUnloadNow (scrobj.@)
2468 HRESULT WINAPI
DllCanUnloadNow(void)