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 WARN("(%p)->(%s %p) interface not supported\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 struct object_member
*member
;
1077 TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This
, id
, lcid
, flags
, pdp
, res
, pei
, caller
);
1079 if (id
< 1 || id
> This
->member_cnt
)
1081 WARN("Unknown id %xu\n", id
);
1082 return DISP_E_MEMBERNOTFOUND
;
1084 member
= &This
->members
[id
- 1];
1086 switch (member
->type
)
1089 if ((flags
& ~DISPATCH_PROPERTYGET
) != DISPATCH_METHOD
)
1091 FIXME("unsupported method flags %x\n", flags
);
1092 return DISP_E_MEMBERNOTFOUND
;
1094 return IDispatchEx_InvokeEx(member
->u
.method
.host
->script_dispatch
, member
->u
.method
.id
, lcid
,
1095 DISPATCH_METHOD
, pdp
, res
, pei
, caller
);
1096 case MEMBER_PROPERTY
:
1097 if (flags
& DISPATCH_PROPERTYGET
)
1099 if (!member
->u
.property
.get
.host
)
1101 FIXME("No %s getter\n", debugstr_w(member
->name
));
1102 return DISP_E_MEMBERNOTFOUND
;
1104 return IDispatchEx_InvokeEx(member
->u
.property
.get
.host
->script_dispatch
, member
->u
.property
.get
.id
, lcid
,
1105 DISPATCH_METHOD
, pdp
, res
, pei
, caller
);
1107 if (flags
& DISPATCH_PROPERTYPUT
)
1111 if (!member
->u
.property
.put
.host
)
1113 FIXME("No %s setter\n", debugstr_w(member
->name
));
1114 return DISP_E_MEMBERNOTFOUND
;
1116 if (pdp
->cNamedArgs
!= 1 || pdp
->rgdispidNamedArgs
[0] != DISPID_PROPERTYPUT
)
1118 FIXME("no propput argument\n");
1123 return IDispatchEx_InvokeEx(member
->u
.property
.put
.host
->script_dispatch
, member
->u
.property
.put
.id
, lcid
,
1124 DISPATCH_METHOD
, &dp
, res
, pei
, caller
);
1127 FIXME("unsupported flags %x\n", flags
);
1130 return DISP_E_MEMBERNOTFOUND
;
1133 static HRESULT WINAPI
scriptlet_DeleteMemberByName(IDispatchEx
*iface
, BSTR bstrName
, DWORD grfdex
)
1135 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1136 FIXME("(%p)->(%s %x)\n", This
, debugstr_w(bstrName
), grfdex
);
1140 static HRESULT WINAPI
scriptlet_DeleteMemberByDispID(IDispatchEx
*iface
, DISPID id
)
1142 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1143 FIXME("(%p)->(%x)\n", This
, id
);
1147 static HRESULT WINAPI
scriptlet_GetMemberProperties(IDispatchEx
*iface
, DISPID id
, DWORD grfdexFetch
, DWORD
*pgrfdex
)
1149 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1150 FIXME("(%p)->(%x %x %p)\n", This
, id
, grfdexFetch
, pgrfdex
);
1154 static HRESULT WINAPI
scriptlet_GetMemberName(IDispatchEx
*iface
, DISPID id
, BSTR
*pbstrName
)
1156 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1157 FIXME("(%p)->(%x %p)\n", This
, id
, pbstrName
);
1161 static HRESULT WINAPI
scriptlet_GetNextDispID(IDispatchEx
*iface
, DWORD grfdex
, DISPID id
, DISPID
*pid
)
1163 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1164 FIXME("(%p)->(%x %x %p)\n", This
, grfdex
, id
, pid
);
1168 static HRESULT WINAPI
scriptlet_GetNameSpaceParent(IDispatchEx
*iface
, IUnknown
**ppunk
)
1170 struct scriptlet_instance
*This
= impl_from_IDispatchEx(iface
);
1171 FIXME("(%p)->(%p)\n", This
, ppunk
);
1175 static IDispatchExVtbl DispatchExVtbl
= {
1176 scriptlet_QueryInterface
,
1179 scriptlet_GetTypeInfoCount
,
1180 scriptlet_GetTypeInfo
,
1181 scriptlet_GetIDsOfNames
,
1183 scriptlet_GetDispID
,
1185 scriptlet_DeleteMemberByName
,
1186 scriptlet_DeleteMemberByDispID
,
1187 scriptlet_GetMemberProperties
,
1188 scriptlet_GetMemberName
,
1189 scriptlet_GetNextDispID
,
1190 scriptlet_GetNameSpaceParent
1193 static HRESULT
create_scriptlet_instance(struct scriptlet_factory
*factory
, IDispatchEx
**disp
)
1195 struct script_host
*factory_host
, *host
;
1196 struct scriptlet_instance
*obj
;
1197 IDispatch
*script_dispatch
;
1200 if (!(obj
= heap_alloc_zero(sizeof(*obj
)))) return E_OUTOFMEMORY
;
1202 obj
->IDispatchEx_iface
.lpVtbl
= &DispatchExVtbl
;
1204 list_init(&obj
->hosts
);
1206 if (!(obj
->global
= heap_alloc(sizeof(*obj
->global
))))
1208 IDispatchEx_Release(&obj
->IDispatchEx_iface
);
1209 return E_OUTOFMEMORY
;
1211 obj
->global
->IDispatchEx_iface
.lpVtbl
= &global_vtbl
;
1212 obj
->global
->ref
= 1;
1214 LIST_FOR_EACH_ENTRY(factory_host
, &factory
->hosts
, struct script_host
, entry
)
1216 hres
= create_script_host(factory_host
->language
, factory_host
->active_script
, &obj
->hosts
, &host
);
1217 if (FAILED(hres
)) break;
1220 hres
= IActiveScript_AddNamedItem(host
->active_script
, L
"scriptlet",
1221 SCRIPTITEM_ISVISIBLE
| SCRIPTITEM_GLOBALMEMBERS
);
1222 if (FAILED(hres
)) break;
1224 hres
= IActiveScript_AddNamedItem(host
->active_script
, L
"globals", SCRIPTITEM_ISVISIBLE
);
1225 if (FAILED(hres
)) break;
1227 hres
= IActiveScript_GetScriptDispatch(host
->active_script
, NULL
, &script_dispatch
);
1228 if (FAILED(hres
)) return hres
;
1230 hres
= IDispatch_QueryInterface(script_dispatch
, &IID_IDispatchEx
, (void**)&host
->script_dispatch
);
1231 IDispatch_Release(script_dispatch
);
1234 FIXME("IDispatchEx not supported by script engine\n");
1239 if (SUCCEEDED(hres
)) hres
= parse_scripts(factory
, &obj
->hosts
, TRUE
);
1240 if (SUCCEEDED(hres
)) hres
= lookup_object_properties(obj
, factory
);
1243 IDispatchEx_Release(&obj
->IDispatchEx_iface
);
1247 *disp
= &obj
->IDispatchEx_iface
;
1251 static const char *debugstr_xml_name(struct scriptlet_factory
*factory
)
1256 hres
= IXmlReader_GetLocalName(factory
->xml_reader
, &str
, &len
);
1257 if (FAILED(hres
)) return "#err";
1258 return debugstr_wn(str
, len
);
1261 static HRESULT
next_xml_node(struct scriptlet_factory
*factory
, XmlNodeType
*node_type
)
1266 hres
= IXmlReader_Read(factory
->xml_reader
, node_type
);
1267 if (FAILED(hres
)) break;
1268 if (*node_type
== XmlNodeType_Whitespace
) continue;
1269 if (*node_type
== XmlNodeType_ProcessingInstruction
)
1271 FIXME("Ignoring processing instruction\n");
1279 static BOOL
is_xml_name(struct scriptlet_factory
*factory
, const WCHAR
*name
)
1284 hres
= IXmlReader_GetQualifiedName(factory
->xml_reader
, &qname
, &len
);
1285 return hres
== S_OK
&& len
== wcslen(name
) && !memcmp(qname
, name
, len
* sizeof(WCHAR
));
1288 static HRESULT
expect_end_element(struct scriptlet_factory
*factory
)
1290 XmlNodeType node_type
;
1292 hres
= next_xml_node(factory
, &node_type
);
1293 if (hres
!= S_OK
|| node_type
!= XmlNodeType_EndElement
)
1295 FIXME("Unexpected node %u %s\n", node_type
, debugstr_xml_name(factory
));
1301 static HRESULT
expect_no_attributes(struct scriptlet_factory
*factory
)
1305 hres
= IXmlReader_GetAttributeCount(factory
->xml_reader
, &count
);
1306 if (FAILED(hres
)) return hres
;
1307 if (!count
) return S_OK
;
1308 FIXME("Unexpected attributes\n");
1312 static BOOL
is_case_xml_name(struct scriptlet_factory
*factory
, const WCHAR
*name
)
1317 hres
= IXmlReader_GetQualifiedName(factory
->xml_reader
, &qname
, &len
);
1318 return hres
== S_OK
&& len
== wcslen(name
) && !memicmp(qname
, name
, len
* sizeof(WCHAR
));
1321 static HRESULT
read_xml_value(struct scriptlet_factory
*factory
, WCHAR
**ret
)
1326 hres
= IXmlReader_GetValue(factory
->xml_reader
, &str
, &len
);
1327 if (FAILED(hres
)) return hres
;
1328 if (!(*ret
= heap_alloc((len
+ 1) * sizeof(WCHAR
)))) return E_OUTOFMEMORY
;
1329 memcpy(*ret
, str
, len
* sizeof(WCHAR
));
1334 static HRESULT
parse_scriptlet_registration(struct scriptlet_factory
*factory
)
1340 if (factory
->have_registration
)
1342 FIXME("duplicated registration element\n");
1345 factory
->have_registration
= TRUE
;
1349 hres
= IXmlReader_MoveToNextAttribute(factory
->xml_reader
);
1350 if (hres
!= S_OK
) break;
1352 if (is_xml_name(factory
, L
"description"))
1354 if (factory
->description
)
1356 FIXME("Duplicated description\n");
1359 hres
= read_xml_value(factory
, &factory
->description
);
1360 if (FAILED(hres
)) return hres
;
1362 else if (is_case_xml_name(factory
, L
"progid"))
1364 if (factory
->progid
)
1366 FIXME("Duplicated progid\n");
1369 hres
= read_xml_value(factory
, &factory
->progid
);
1370 if (FAILED(hres
)) return hres
;
1372 else if (is_xml_name(factory
, L
"version"))
1374 if (factory
->version
)
1376 FIXME("Duplicated version\n");
1379 hres
= read_xml_value(factory
, &factory
->version
);
1380 if (FAILED(hres
)) return hres
;
1382 else if (is_xml_name(factory
, L
"classid"))
1384 if (factory
->classid_str
)
1386 FIXME("Duplicated classid attribute\n");
1389 hres
= read_xml_value(factory
, &factory
->classid_str
);
1390 if (FAILED(hres
)) return hres
;
1391 hres
= IIDFromString(factory
->classid_str
, &factory
->classid
);
1394 FIXME("Invalid classid %s\n", debugstr_w(factory
->classid_str
));
1401 FIXME("Unexpected attribute\n");
1406 if (!factory
->progid
&& !factory
->classid_str
)
1408 FIXME("Incomplet registration element\n");
1412 if (factory
->progid
)
1414 size_t progid_len
= wcslen(factory
->progid
);
1415 size_t version_len
= wcslen(factory
->version
);
1417 if (!(factory
->versioned_progid
= heap_alloc((progid_len
+ version_len
+ 2) * sizeof(WCHAR
))))
1418 return E_OUTOFMEMORY
;
1420 memcpy(factory
->versioned_progid
, factory
->progid
, (progid_len
+ 1) * sizeof(WCHAR
));
1423 factory
->versioned_progid
[progid_len
++] = '.';
1424 wcscpy(factory
->versioned_progid
+ progid_len
, factory
->version
);
1426 else factory
->versioned_progid
[progid_len
] = 0;
1429 return expect_end_element(factory
);
1432 static HRESULT
parse_scriptlet_public(struct scriptlet_factory
*factory
)
1434 struct scriptlet_member
*member
, *member_iter
;
1435 enum member_type member_type
;
1436 XmlNodeType node_type
;
1442 if (factory
->have_public
)
1444 FIXME("duplicated public element\n");
1447 factory
->have_public
= TRUE
;
1451 hres
= next_xml_node(factory
, &node_type
);
1452 if (FAILED(hres
)) return hres
;
1453 if (node_type
== XmlNodeType_EndElement
) break;
1454 if (node_type
!= XmlNodeType_Element
)
1456 FIXME("Unexpected node type %u\n", node_type
);
1460 if (is_xml_name(factory
, L
"method"))
1461 member_type
= MEMBER_METHOD
;
1462 else if (is_xml_name(factory
, L
"property"))
1463 member_type
= MEMBER_PROPERTY
;
1466 FIXME("Unexpected element %s\n", debugstr_xml_name(factory
));
1470 empty
= IXmlReader_IsEmptyElement(factory
->xml_reader
);
1472 hres
= IXmlReader_MoveToAttributeByName(factory
->xml_reader
, L
"name", NULL
);
1475 FIXME("Missing method name\n");
1479 if (!(member
= heap_alloc(sizeof(*member
)))) return E_OUTOFMEMORY
;
1480 member
->type
= member_type
;
1482 hres
= read_xml_value(factory
, &member
->name
);
1489 LIST_FOR_EACH_ENTRY(member_iter
, &factory
->members
, struct scriptlet_member
, entry
)
1491 if (!wcsicmp(member_iter
->name
, member
->name
))
1493 FIXME("Duplicated member %s\n", debugstr_w(member
->name
));
1498 list_add_tail(&factory
->members
, &member
->entry
);
1500 switch (member_type
)
1503 list_init(&member
->u
.parameters
);
1508 struct method_parameter
*parameter
;
1510 hres
= next_xml_node(factory
, &node_type
);
1511 if (FAILED(hres
)) return hres
;
1512 if (node_type
== XmlNodeType_EndElement
) break;
1513 if (node_type
!= XmlNodeType_Element
)
1515 FIXME("Unexpected node type %u\n", node_type
);
1518 if (!is_case_xml_name(factory
, L
"parameter"))
1520 FIXME("Unexpected method element\n");
1524 empty
= IXmlReader_IsEmptyElement(factory
->xml_reader
);
1526 hres
= IXmlReader_MoveToAttributeByName(factory
->xml_reader
, L
"name", NULL
);
1529 FIXME("Missing parameter name\n");
1533 if (!(parameter
= heap_alloc_zero(sizeof(*parameter
)))) return E_OUTOFMEMORY
;
1534 list_add_tail(&member
->u
.parameters
, ¶meter
->entry
);
1536 hres
= read_xml_value(factory
, ¶meter
->name
);
1537 if (FAILED(hres
)) return hres
;
1538 if (!empty
&& FAILED(hres
= expect_end_element(factory
))) return hres
;
1542 case MEMBER_PROPERTY
:
1543 member
->u
.flags
= 0;
1548 hres
= next_xml_node(factory
, &node_type
);
1549 if (FAILED(hres
)) return hres
;
1550 if (node_type
== XmlNodeType_EndElement
) break;
1551 if (node_type
!= XmlNodeType_Element
)
1553 FIXME("Unexpected node type %u\n", node_type
);
1556 if (is_case_xml_name(factory
, L
"get"))
1558 if (member
->u
.flags
& PROP_GETTER
)
1560 FIXME("Duplicated getter\n");
1563 member
->u
.flags
|= PROP_GETTER
;
1565 else if (is_case_xml_name(factory
, L
"put"))
1567 if (member
->u
.flags
& PROP_SETTER
)
1569 FIXME("Duplicated setter\n");
1572 member
->u
.flags
|= PROP_SETTER
;
1576 FIXME("Unexpected property element %s\n", debugstr_xml_name(factory
));
1580 empty
= IXmlReader_IsEmptyElement(factory
->xml_reader
);
1581 if (!empty
&& FAILED(hres
= expect_end_element(factory
))) return hres
;
1583 if (!member
->u
.flags
)
1585 FIXME("No getter or setter\n");
1590 if (FAILED(hres
)) return hres
;
1596 static HRESULT
parse_scriptlet_script(struct scriptlet_factory
*factory
, struct scriptlet_script
*script
)
1598 XmlNodeType node_type
;
1599 size_t buf_size
, size
;
1608 hres
= IXmlReader_MoveToNextAttribute(factory
->xml_reader
);
1609 if (hres
!= S_OK
) break;
1611 if (is_xml_name(factory
, L
"language"))
1613 if (script
->language
)
1615 FIXME("Duplicated language\n");
1618 hres
= read_xml_value(factory
, &script
->language
);
1619 if (FAILED(hres
)) return hres
;
1623 FIXME("Unexpected attribute\n");
1628 if (!script
->language
)
1630 FIXME("Language not specified\n");
1634 if (FAILED(hres
= next_xml_node(factory
, &node_type
))) return hres
;
1636 if (node_type
!= XmlNodeType_Text
&& node_type
!= XmlNodeType_CDATA
)
1638 FIXME("Unexpected node type %u\n", node_type
);
1642 if (!(script
->body
= heap_alloc((buf_size
= 1024) * sizeof(WCHAR
)))) return E_OUTOFMEMORY
;
1648 hres
= IXmlReader_ReadValueChunk(factory
->xml_reader
, script
->body
+ size
, buf_size
- size
- 1, &read
);
1649 if (FAILED(hres
)) return hres
;
1651 if (hres
== S_FALSE
) break;
1652 if (size
+ 1 == buf_size
)
1654 if (!(new_body
= heap_realloc(script
->body
, (buf_size
*= 2) * sizeof(WCHAR
)))) return E_OUTOFMEMORY
;
1655 script
->body
= new_body
;
1658 script
->body
[size
++] = 0;
1659 if (size
!= buf_size
) script
->body
= heap_realloc(script
->body
, size
* sizeof(WCHAR
));
1661 TRACE("body %s\n", debugstr_w(script
->body
));
1662 return expect_end_element(factory
);
1665 static HRESULT
parse_scriptlet_file(struct scriptlet_factory
*factory
, const WCHAR
*url
)
1667 XmlNodeType node_type
;
1672 hres
= CreateURLMoniker(NULL
, url
, &factory
->moniker
);
1675 WARN("CreateURLMoniker failed: %08x\n", hres
);
1679 hres
= CreateBindCtx(0, &bind_ctx
);
1683 hres
= IMoniker_BindToStorage(factory
->moniker
, bind_ctx
, NULL
, &IID_IStream
, (void**)&stream
);
1684 IBindCtx_Release(bind_ctx
);
1688 hres
= CreateXmlReader(&IID_IXmlReader
, (void**)&factory
->xml_reader
, NULL
);
1690 hres
= IXmlReader_SetInput(factory
->xml_reader
, (IUnknown
*)stream
);
1691 IStream_Release(stream
);
1695 hres
= next_xml_node(factory
, &node_type
);
1696 if (hres
== S_OK
&& node_type
== XmlNodeType_XmlDeclaration
)
1697 hres
= next_xml_node(factory
, &node_type
);
1701 if (node_type
!= XmlNodeType_Element
|| !is_xml_name(factory
, L
"component"))
1703 FIXME("Unexpected %s element\n", debugstr_xml_name(factory
));
1707 hres
= expect_no_attributes(factory
);
1708 if (FAILED(hres
)) return hres
;
1712 hres
= next_xml_node(factory
, &node_type
);
1713 if (FAILED(hres
)) return hres
;
1714 if (node_type
== XmlNodeType_EndElement
) break;
1715 if (node_type
!= XmlNodeType_Element
)
1717 FIXME("Unexpected node type %u\n", node_type
);
1721 if (is_xml_name(factory
, L
"registration"))
1722 hres
= parse_scriptlet_registration(factory
);
1723 else if (is_xml_name(factory
, L
"public"))
1724 hres
= parse_scriptlet_public(factory
);
1725 else if (is_xml_name(factory
, L
"script"))
1727 struct scriptlet_script
*script
;
1728 if (!(script
= heap_alloc_zero(sizeof(*script
)))) return E_OUTOFMEMORY
;
1729 list_add_tail(&factory
->scripts
, &script
->entry
);
1730 hres
= parse_scriptlet_script(factory
, script
);
1731 if (FAILED(hres
)) return hres
;
1735 FIXME("Unexpected element %s\n", debugstr_xml_name(factory
));
1738 if (FAILED(hres
)) return hres
;
1741 hres
= next_xml_node(factory
, &node_type
);
1742 if (hres
!= S_FALSE
)
1744 FIXME("Unexpected node type %u\n", node_type
);
1750 static inline struct scriptlet_factory
*impl_from_IClassFactory(IClassFactory
*iface
)
1752 return CONTAINING_RECORD(iface
, struct scriptlet_factory
, IClassFactory_iface
);
1755 static HRESULT WINAPI
scriptlet_factory_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
1757 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1759 if (IsEqualGUID(&IID_IUnknown
, riid
))
1761 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
1762 *ppv
= &This
->IClassFactory_iface
;
1764 else if (IsEqualGUID(&IID_IClassFactory
, riid
))
1766 TRACE("(%p)->(IID_IClassFactory %p)\n", iface
, ppv
);
1767 *ppv
= &This
->IClassFactory_iface
;
1771 WARN("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
1773 return E_NOINTERFACE
;
1776 IUnknown_AddRef((IUnknown
*)*ppv
);
1780 static ULONG WINAPI
scriptlet_factory_AddRef(IClassFactory
*iface
)
1782 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1783 ULONG ref
= InterlockedIncrement(&This
->ref
);
1785 TRACE("(%p) ref=%d\n", This
, ref
);
1790 static ULONG WINAPI
scriptlet_factory_Release(IClassFactory
*iface
)
1792 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1793 ULONG ref
= InterlockedDecrement(&This
->ref
);
1795 TRACE("(%p) ref=%d\n", This
, ref
);
1799 if (This
->moniker
) IMoniker_Release(This
->moniker
);
1800 if (This
->xml_reader
) IXmlReader_Release(This
->xml_reader
);
1801 detach_script_hosts(&This
->hosts
);
1802 while (!list_empty(&This
->members
))
1804 struct scriptlet_member
*member
= LIST_ENTRY(list_head(&This
->members
), struct scriptlet_member
, entry
);
1805 list_remove(&member
->entry
);
1806 heap_free(member
->name
);
1807 if (member
->type
== MEMBER_METHOD
)
1809 while (!list_empty(&member
->u
.parameters
))
1811 struct method_parameter
*parameter
= LIST_ENTRY(list_head(&member
->u
.parameters
), struct method_parameter
, entry
);
1812 list_remove(¶meter
->entry
);
1813 heap_free(parameter
->name
);
1814 heap_free(parameter
);
1819 while (!list_empty(&This
->scripts
))
1821 struct scriptlet_script
*script
= LIST_ENTRY(list_head(&This
->scripts
), struct scriptlet_script
, entry
);
1822 list_remove(&script
->entry
);
1823 heap_free(script
->language
);
1824 heap_free(script
->body
);
1827 heap_free(This
->classid_str
);
1828 heap_free(This
->description
);
1829 heap_free(This
->versioned_progid
);
1830 heap_free(This
->progid
);
1831 heap_free(This
->version
);
1837 static HRESULT WINAPI
scriptlet_factory_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID riid
, void **ppv
)
1839 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1843 TRACE("(%p)->(%p %s %p)\n", This
, outer
, debugstr_guid(riid
), ppv
);
1845 if (outer
) FIXME("outer not supported\n");
1847 if (list_empty(&This
->hosts
))
1849 hres
= create_scriptlet_hosts(This
, &This
->hosts
);
1850 if (FAILED(hres
)) return hres
;
1852 hres
= parse_scripts(This
, &This
->hosts
, FALSE
);
1855 detach_script_hosts(&This
->hosts
);
1860 hres
= create_scriptlet_instance(This
, &disp
);
1861 if (FAILED(hres
)) return hres
;
1863 hres
= IDispatchEx_QueryInterface(disp
, riid
, ppv
);
1864 IDispatchEx_Release(disp
);
1868 static HRESULT WINAPI
scriptlet_factory_LockServer(IClassFactory
*iface
, BOOL fLock
)
1870 struct scriptlet_factory
*This
= impl_from_IClassFactory(iface
);
1871 TRACE("(%p)->(%x)\n", This
, fLock
);
1875 static const struct IClassFactoryVtbl scriptlet_factory_vtbl
=
1877 scriptlet_factory_QueryInterface
,
1878 scriptlet_factory_AddRef
,
1879 scriptlet_factory_Release
,
1880 scriptlet_factory_CreateInstance
,
1881 scriptlet_factory_LockServer
1884 static HRESULT
create_scriptlet_factory(const WCHAR
*url
, struct scriptlet_factory
**ret
)
1886 struct scriptlet_factory
*factory
;
1889 TRACE("%s\n", debugstr_w(url
));
1891 if (!(factory
= heap_alloc_zero(sizeof(*factory
))))
1893 IClassFactory_Release(&factory
->IClassFactory_iface
);
1894 return E_OUTOFMEMORY
;
1897 factory
->IClassFactory_iface
.lpVtbl
= &scriptlet_factory_vtbl
;
1899 list_init(&factory
->hosts
);
1900 list_init(&factory
->members
);
1901 list_init(&factory
->scripts
);
1903 hres
= parse_scriptlet_file(factory
, url
);
1906 IClassFactory_Release(&factory
->IClassFactory_iface
);
1914 static HRESULT
register_scriptlet(struct scriptlet_factory
*factory
)
1916 HKEY key
, clsid_key
, obj_key
;
1920 if (factory
->classid_str
)
1924 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, L
"CLSID", &clsid_key
);
1925 if (status
) return E_ACCESSDENIED
;
1927 status
= RegCreateKeyW(clsid_key
, factory
->classid_str
, &obj_key
);
1928 RegCloseKey(clsid_key
);
1929 if (status
) return E_ACCESSDENIED
;
1931 hres
= IMoniker_GetDisplayName(factory
->moniker
, NULL
, NULL
, &url
);
1934 RegCloseKey(obj_key
);
1937 status
= RegCreateKeyW(obj_key
, L
"ScriptletURL", &key
);
1940 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)url
,
1941 (wcslen(url
) + 1) * sizeof(WCHAR
));
1946 if (factory
->description
)
1947 status
= RegSetValueExW(obj_key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->description
,
1948 (wcslen(factory
->description
) + 1) * sizeof(WCHAR
));
1952 status
= RegCreateKeyW(obj_key
, L
"InprocServer32", &key
);
1955 WCHAR str
[MAX_PATH
];
1956 GetModuleFileNameW(scrobj_instance
, str
, MAX_PATH
);
1957 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)str
, (wcslen(str
) + 1) * sizeof(WCHAR
));
1962 if (!status
&& factory
->versioned_progid
)
1964 status
= RegCreateKeyW(obj_key
, L
"ProgID", &key
);
1967 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->versioned_progid
,
1968 (wcslen(factory
->versioned_progid
) + 1) * sizeof(WCHAR
));
1973 if (!status
&& factory
->progid
)
1975 status
= RegCreateKeyW(obj_key
, L
"VersionIndependentProgID", &key
);
1978 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->progid
,
1979 (wcslen(factory
->progid
) + 1) * sizeof(WCHAR
));
1984 RegCloseKey(obj_key
);
1985 if (status
) return E_ACCESSDENIED
;
1988 if (factory
->progid
)
1990 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, factory
->progid
, &key
);
1991 if (status
) return E_ACCESSDENIED
;
1993 if (factory
->description
)
1994 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->description
,
1995 (wcslen(factory
->description
) + 1) * sizeof(WCHAR
));
1997 if (!status
&& factory
->classid_str
)
1999 status
= RegCreateKeyW(key
, L
"CLSID", &clsid_key
);
2002 status
= RegSetValueExW(clsid_key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->classid_str
,
2003 (wcslen(factory
->classid_str
) + 1) * sizeof(WCHAR
));
2004 RegCloseKey(clsid_key
);
2009 if (status
) return E_ACCESSDENIED
;
2012 if (factory
->versioned_progid
)
2014 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, factory
->versioned_progid
, &key
);
2015 if (status
) return E_ACCESSDENIED
;
2017 if (factory
->description
)
2018 status
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->description
,
2019 (wcslen(factory
->description
) + 1) * sizeof(WCHAR
));
2021 if (!status
&& factory
->classid_str
)
2023 status
= RegCreateKeyW(key
, L
"CLSID", &clsid_key
);
2026 status
= RegSetValueExW(clsid_key
, NULL
, 0, REG_SZ
, (BYTE
*)factory
->classid_str
,
2027 (wcslen(factory
->classid_str
) + 1) * sizeof(WCHAR
));
2028 RegCloseKey(clsid_key
);
2033 if (status
) return E_ACCESSDENIED
;
2039 static HRESULT
unregister_scriptlet(struct scriptlet_factory
*factory
)
2043 if (factory
->classid_str
)
2046 status
= RegCreateKeyW(HKEY_CLASSES_ROOT
, L
"CLSID", &clsid_key
);
2049 RegDeleteTreeW(clsid_key
, factory
->classid_str
);
2050 RegCloseKey(clsid_key
);
2054 if (factory
->progid
) RegDeleteTreeW(HKEY_CLASSES_ROOT
, factory
->progid
);
2055 if (factory
->versioned_progid
) RegDeleteTreeW(HKEY_CLASSES_ROOT
, factory
->versioned_progid
);
2059 struct scriptlet_typelib
2061 IGenScriptletTLib IGenScriptletTLib_iface
;
2067 static inline struct scriptlet_typelib
*impl_from_IGenScriptletTLib(IGenScriptletTLib
*iface
)
2069 return CONTAINING_RECORD(iface
, struct scriptlet_typelib
, IGenScriptletTLib_iface
);
2072 static HRESULT WINAPI
scriptlet_typelib_QueryInterface(IGenScriptletTLib
*iface
, REFIID riid
, void **obj
)
2074 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2076 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), obj
);
2078 if (IsEqualIID(riid
, &IID_IGenScriptletTLib
) ||
2079 IsEqualIID(riid
, &IID_IDispatch
) ||
2080 IsEqualIID(riid
, &IID_IUnknown
))
2083 IGenScriptletTLib_AddRef(iface
);
2088 return E_NOINTERFACE
;
2091 static ULONG WINAPI
scriptlet_typelib_AddRef(IGenScriptletTLib
*iface
)
2093 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2094 ULONG ref
= InterlockedIncrement(&This
->ref
);
2095 TRACE("(%p)->(%u)\n", This
, ref
);
2099 static ULONG WINAPI
scriptlet_typelib_Release(IGenScriptletTLib
*iface
)
2101 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2102 LONG ref
= InterlockedDecrement(&This
->ref
);
2104 TRACE("(%p)->(%u)\n", This
, ref
);
2108 SysFreeString(This
->guid
);
2109 HeapFree(GetProcessHeap(), 0, This
);
2115 static HRESULT WINAPI
scriptlet_typelib_GetTypeInfoCount(IGenScriptletTLib
*iface
, UINT
*count
)
2117 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2119 TRACE("(%p, %p)\n", This
, count
);
2125 static HRESULT WINAPI
scriptlet_typelib_GetTypeInfo(IGenScriptletTLib
*iface
, UINT index
, LCID lcid
,
2128 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2130 TRACE("(%p, %u, %x, %p)\n", This
, index
, lcid
, tinfo
);
2132 return get_typeinfo(IGenScriptletTLib_tid
, tinfo
);
2135 static HRESULT WINAPI
scriptlet_typelib_GetIDsOfNames(IGenScriptletTLib
*iface
, REFIID riid
, LPOLESTR
*names
,
2136 UINT cNames
, LCID lcid
, DISPID
*dispid
)
2138 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2139 ITypeInfo
*typeinfo
;
2142 TRACE("(%p, %s, %p, %u, %x, %p)\n", This
, debugstr_guid(riid
), names
, cNames
, lcid
, dispid
);
2144 hr
= get_typeinfo(IGenScriptletTLib_tid
, &typeinfo
);
2147 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, cNames
, dispid
);
2148 ITypeInfo_Release(typeinfo
);
2154 static HRESULT WINAPI
scriptlet_typelib_Invoke(IGenScriptletTLib
*iface
, DISPID dispid
, REFIID riid
,
2155 LCID lcid
, WORD flags
, DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*ei
, UINT
*argerr
)
2157 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2158 ITypeInfo
*typeinfo
;
2161 TRACE("(%p, %d, %s, %x, %x, %p, %p, %p, %p)\n", This
, dispid
, debugstr_guid(riid
), lcid
, flags
,
2162 params
, result
, ei
, argerr
);
2164 hr
= get_typeinfo(IGenScriptletTLib_tid
, &typeinfo
);
2167 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IGenScriptletTLib_iface
, dispid
, flags
,
2168 params
, result
, ei
, argerr
);
2169 ITypeInfo_Release(typeinfo
);
2175 static HRESULT WINAPI
scriptlet_typelib_AddURL(IGenScriptletTLib
*iface
, BSTR url
)
2177 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2179 FIXME("(%p, %s): stub\n", This
, debugstr_w(url
));
2184 static HRESULT WINAPI
scriptlet_typelib_put_Path(IGenScriptletTLib
*iface
, BSTR path
)
2186 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2188 FIXME("(%p, %s): stub\n", This
, debugstr_w(path
));
2193 static HRESULT WINAPI
scriptlet_typelib_get_Path(IGenScriptletTLib
*iface
, BSTR
*path
)
2195 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2197 FIXME("(%p, %p): stub\n", This
, path
);
2202 static HRESULT WINAPI
scriptlet_typelib_put_Doc(IGenScriptletTLib
*iface
, BSTR doc
)
2204 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2206 FIXME("(%p, %s): stub\n", This
, debugstr_w(doc
));
2211 static HRESULT WINAPI
scriptlet_typelib_get_Doc(IGenScriptletTLib
*iface
, BSTR
*doc
)
2213 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2215 FIXME("(%p, %p): stub\n", This
, doc
);
2220 static HRESULT WINAPI
scriptlet_typelib_put_Name(IGenScriptletTLib
*iface
, BSTR name
)
2222 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2224 FIXME("(%p, %s): stub\n", This
, debugstr_w(name
));
2229 static HRESULT WINAPI
scriptlet_typelib_get_Name(IGenScriptletTLib
*iface
, BSTR
*name
)
2231 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2233 FIXME("(%p, %p): stub\n", This
, name
);
2238 static HRESULT WINAPI
scriptlet_typelib_put_MajorVersion(IGenScriptletTLib
*iface
, WORD version
)
2240 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2242 FIXME("(%p, %x): stub\n", This
, version
);
2247 static HRESULT WINAPI
scriptlet_typelib_get_MajorVersion(IGenScriptletTLib
*iface
, WORD
*version
)
2249 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2251 FIXME("(%p, %p): stub\n", This
, version
);
2256 static HRESULT WINAPI
scriptlet_typelib_put_MinorVersion(IGenScriptletTLib
*iface
, WORD version
)
2258 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2260 FIXME("(%p, %x): stub\n", This
, version
);
2265 static HRESULT WINAPI
scriptlet_typelib_get_MinorVersion(IGenScriptletTLib
*iface
, WORD
*version
)
2267 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2269 FIXME("(%p, %p): stub\n", This
, version
);
2274 static HRESULT WINAPI
scriptlet_typelib_Write(IGenScriptletTLib
*iface
)
2276 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2278 FIXME("(%p): stub\n", This
);
2283 static HRESULT WINAPI
scriptlet_typelib_Reset(IGenScriptletTLib
*iface
)
2285 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2287 FIXME("(%p): stub\n", This
);
2292 static HRESULT WINAPI
scriptlet_typelib_put_GUID(IGenScriptletTLib
*iface
, BSTR guid
)
2294 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2296 FIXME("(%p, %s): stub\n", This
, debugstr_w(guid
));
2301 static HRESULT WINAPI
scriptlet_typelib_get_GUID(IGenScriptletTLib
*iface
, BSTR
*ret
)
2303 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
2305 TRACE("(%p, %p)\n", This
, ret
);
2315 hr
= CoCreateGuid(&guid
);
2319 hr
= StringFromGUID2(&guid
, guidW
, ARRAY_SIZE(guidW
));
2323 if (!(This
->guid
= SysAllocString(guidW
)))
2324 return E_OUTOFMEMORY
;
2327 *ret
= SysAllocString(This
->guid
);
2328 return *ret
? S_OK
: E_OUTOFMEMORY
;
2331 static const IGenScriptletTLibVtbl scriptlet_typelib_vtbl
=
2333 scriptlet_typelib_QueryInterface
,
2334 scriptlet_typelib_AddRef
,
2335 scriptlet_typelib_Release
,
2336 scriptlet_typelib_GetTypeInfoCount
,
2337 scriptlet_typelib_GetTypeInfo
,
2338 scriptlet_typelib_GetIDsOfNames
,
2339 scriptlet_typelib_Invoke
,
2340 scriptlet_typelib_AddURL
,
2341 scriptlet_typelib_put_Path
,
2342 scriptlet_typelib_get_Path
,
2343 scriptlet_typelib_put_Doc
,
2344 scriptlet_typelib_get_Doc
,
2345 scriptlet_typelib_put_Name
,
2346 scriptlet_typelib_get_Name
,
2347 scriptlet_typelib_put_MajorVersion
,
2348 scriptlet_typelib_get_MajorVersion
,
2349 scriptlet_typelib_put_MinorVersion
,
2350 scriptlet_typelib_get_MinorVersion
,
2351 scriptlet_typelib_Write
,
2352 scriptlet_typelib_Reset
,
2353 scriptlet_typelib_put_GUID
,
2354 scriptlet_typelib_get_GUID
2357 BOOL WINAPI
DllMain(HINSTANCE hinst
, DWORD reason
, void *reserved
)
2359 TRACE("%p, %u, %p\n", hinst
, reason
, reserved
);
2363 case DLL_PROCESS_ATTACH
:
2364 DisableThreadLibraryCalls(hinst
);
2365 scrobj_instance
= hinst
;
2367 case DLL_PROCESS_DETACH
:
2368 if (reserved
) break;
2375 /***********************************************************************
2376 * DllInstall (scrobj.@)
2378 HRESULT WINAPI
DllInstall(BOOL install
, const WCHAR
*arg
)
2380 struct scriptlet_factory
*factory
;
2385 hres
= DllRegisterServer();
2386 if (!arg
|| FAILED(hres
)) return hres
;
2389 return DllUnregisterServer();
2391 hres
= create_scriptlet_factory(arg
, &factory
);
2392 if (SUCCEEDED(hres
))
2394 if (factory
->have_registration
)
2396 /* validate scripts */
2397 hres
= create_scriptlet_hosts(factory
, &factory
->hosts
);
2398 if (SUCCEEDED(hres
)) hres
= parse_scripts(factory
, &factory
->hosts
, FALSE
);
2402 FIXME("No registration info\n");
2405 if (SUCCEEDED(hres
))
2408 hres
= register_scriptlet(factory
);
2410 hres
= unregister_scriptlet(factory
);
2412 IClassFactory_Release(&factory
->IClassFactory_iface
);
2418 static HRESULT WINAPI
scriptlet_typelib_CreateInstance(IClassFactory
*factory
, IUnknown
*outer
, REFIID riid
, void **obj
)
2420 struct scriptlet_typelib
*This
;
2423 TRACE("(%p, %p, %s, %p)\n", factory
, outer
, debugstr_guid(riid
), obj
);
2427 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
2429 return E_OUTOFMEMORY
;
2431 This
->IGenScriptletTLib_iface
.lpVtbl
= &scriptlet_typelib_vtbl
;
2435 hr
= IGenScriptletTLib_QueryInterface(&This
->IGenScriptletTLib_iface
, riid
, obj
);
2436 IGenScriptletTLib_Release(&This
->IGenScriptletTLib_iface
);
2440 static HRESULT WINAPI
scrruncf_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
2444 if (IsEqualGUID(&IID_IUnknown
, riid
))
2446 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
2449 else if (IsEqualGUID(&IID_IClassFactory
, riid
))
2451 TRACE("(%p)->(IID_IClassFactory %p)\n", iface
, ppv
);
2457 IUnknown_AddRef((IUnknown
*)*ppv
);
2461 WARN("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
2462 return E_NOINTERFACE
;
2465 static ULONG WINAPI
scrruncf_AddRef(IClassFactory
*iface
)
2467 TRACE("(%p)\n", iface
);
2471 static ULONG WINAPI
scrruncf_Release(IClassFactory
*iface
)
2473 TRACE("(%p)\n", iface
);
2477 static HRESULT WINAPI
scrruncf_LockServer(IClassFactory
*iface
, BOOL fLock
)
2479 TRACE("(%p)->(%x)\n", iface
, fLock
);
2483 static const struct IClassFactoryVtbl scriptlet_typelib_factory_vtbl
=
2485 scrruncf_QueryInterface
,
2488 scriptlet_typelib_CreateInstance
,
2492 static IClassFactory scriptlet_typelib_factory
= { &scriptlet_typelib_factory_vtbl
};
2494 /***********************************************************************
2495 * DllGetClassObject (scrobj.@)
2497 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **ppv
)
2499 WCHAR key_name
[128], *p
;
2503 if (IsEqualGUID(&CLSID_TypeLib
, rclsid
))
2505 TRACE("(Scriptlet.TypeLib %s %p)\n", debugstr_guid(riid
), ppv
);
2506 return IClassFactory_QueryInterface(&scriptlet_typelib_factory
, riid
, ppv
);
2509 wcscpy(key_name
, L
"CLSID\\");
2510 p
= key_name
+ wcslen(key_name
);
2511 p
+= StringFromGUID2(rclsid
, p
, ARRAY_SIZE(key_name
) - (p
- key_name
)) - 1;
2512 wcscpy(p
, L
"\\ScriptletURL");
2513 status
= RegQueryValueW(HKEY_CLASSES_ROOT
, key_name
, NULL
, &size
);
2516 struct scriptlet_factory
*factory
;
2520 if (!(url
= heap_alloc(size
* sizeof(WCHAR
)))) return E_OUTOFMEMORY
;
2521 status
= RegQueryValueW(HKEY_CLASSES_ROOT
, key_name
, url
, &size
);
2523 hres
= create_scriptlet_factory(url
, &factory
);
2525 if (FAILED(hres
)) return hres
;
2527 hres
= IClassFactory_QueryInterface(&factory
->IClassFactory_iface
, riid
, ppv
);
2528 IClassFactory_Release(&factory
->IClassFactory_iface
);
2532 FIXME("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
2533 return CLASS_E_CLASSNOTAVAILABLE
;