2 * Copyright 2017 Nikolay Sivov
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(scrobj
);
35 static HINSTANCE scrobj_instance
;
40 IGenScriptletTLib_tid
,
44 static ITypeLib
*typelib
;
45 static ITypeInfo
*typeinfos
[LAST_tid
];
47 static REFIID tid_ids
[] = {
49 &IID_IGenScriptletTLib
,
52 static HRESULT
load_typelib(void)
60 hres
= LoadRegTypeLib(&LIBID_Scriptlet
, 1, 0, LOCALE_SYSTEM_DEFAULT
, &tl
);
63 ERR("LoadRegTypeLib failed: %08x\n", hres
);
67 if (InterlockedCompareExchangePointer((void **)&typelib
, tl
, NULL
))
72 static HRESULT
get_typeinfo(tid_t tid
, ITypeInfo
**typeinfo
)
76 if (FAILED(hres
= load_typelib()))
83 hres
= ITypeLib_GetTypeInfoOfGuid(typelib
, tid_ids
[tid
], &ti
);
85 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids
[tid
]), hres
);
89 if (InterlockedCompareExchangePointer((void **)(typeinfos
+tid
), ti
, NULL
))
90 ITypeInfo_Release(ti
);
93 *typeinfo
= typeinfos
[tid
];
94 ITypeInfo_AddRef(typeinfos
[tid
]);
98 static void release_typelib(void)
105 for (i
= 0; i
< sizeof(typeinfos
)/sizeof(*typeinfos
); i
++)
107 ITypeInfo_Release(typeinfos
[i
]);
109 ITypeLib_Release(typelib
);
112 struct scriptlet_typelib
114 IGenScriptletTLib IGenScriptletTLib_iface
;
120 static inline struct scriptlet_typelib
*impl_from_IGenScriptletTLib(IGenScriptletTLib
*iface
)
122 return CONTAINING_RECORD(iface
, struct scriptlet_typelib
, IGenScriptletTLib_iface
);
125 static HRESULT WINAPI
scriptlet_typelib_QueryInterface(IGenScriptletTLib
*iface
, REFIID riid
, void **obj
)
127 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
129 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), obj
);
131 if (IsEqualIID(riid
, &IID_IGenScriptletTLib
) ||
132 IsEqualIID(riid
, &IID_IDispatch
) ||
133 IsEqualIID(riid
, &IID_IUnknown
))
136 IGenScriptletTLib_AddRef(iface
);
141 return E_NOINTERFACE
;
144 static ULONG WINAPI
scriptlet_typelib_AddRef(IGenScriptletTLib
*iface
)
146 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
147 ULONG ref
= InterlockedIncrement(&This
->ref
);
148 TRACE("(%p)->(%u)\n", This
, ref
);
152 static ULONG WINAPI
scriptlet_typelib_Release(IGenScriptletTLib
*iface
)
154 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
155 LONG ref
= InterlockedDecrement(&This
->ref
);
157 TRACE("(%p)->(%u)\n", This
, ref
);
161 SysFreeString(This
->guid
);
162 HeapFree(GetProcessHeap(), 0, This
);
168 static HRESULT WINAPI
scriptlet_typelib_GetTypeInfoCount(IGenScriptletTLib
*iface
, UINT
*count
)
170 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
172 TRACE("(%p, %p)\n", This
, count
);
178 static HRESULT WINAPI
scriptlet_typelib_GetTypeInfo(IGenScriptletTLib
*iface
, UINT index
, LCID lcid
,
181 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
183 TRACE("(%p, %u, %x, %p)\n", This
, index
, lcid
, tinfo
);
185 return get_typeinfo(IGenScriptletTLib_tid
, tinfo
);
188 static HRESULT WINAPI
scriptlet_typelib_GetIDsOfNames(IGenScriptletTLib
*iface
, REFIID riid
, LPOLESTR
*names
,
189 UINT cNames
, LCID lcid
, DISPID
*dispid
)
191 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
195 TRACE("(%p, %s, %p, %u, %x, %p)\n", This
, debugstr_guid(riid
), names
, cNames
, lcid
, dispid
);
197 hr
= get_typeinfo(IGenScriptletTLib_tid
, &typeinfo
);
200 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, cNames
, dispid
);
201 ITypeInfo_Release(typeinfo
);
207 static HRESULT WINAPI
scriptlet_typelib_Invoke(IGenScriptletTLib
*iface
, DISPID dispid
, REFIID riid
,
208 LCID lcid
, WORD flags
, DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*ei
, UINT
*argerr
)
210 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
214 TRACE("(%p, %d, %s, %x, %x, %p, %p, %p, %p)\n", This
, dispid
, debugstr_guid(riid
), lcid
, flags
,
215 params
, result
, ei
, argerr
);
217 hr
= get_typeinfo(IGenScriptletTLib_tid
, &typeinfo
);
220 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IGenScriptletTLib_iface
, dispid
, flags
,
221 params
, result
, ei
, argerr
);
222 ITypeInfo_Release(typeinfo
);
228 static HRESULT WINAPI
scriptlet_typelib_AddURL(IGenScriptletTLib
*iface
, BSTR url
)
230 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
232 FIXME("(%p, %s): stub\n", This
, debugstr_w(url
));
237 static HRESULT WINAPI
scriptlet_typelib_put_Path(IGenScriptletTLib
*iface
, BSTR path
)
239 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
241 FIXME("(%p, %s): stub\n", This
, debugstr_w(path
));
246 static HRESULT WINAPI
scriptlet_typelib_get_Path(IGenScriptletTLib
*iface
, BSTR
*path
)
248 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
250 FIXME("(%p, %p): stub\n", This
, path
);
255 static HRESULT WINAPI
scriptlet_typelib_put_Doc(IGenScriptletTLib
*iface
, BSTR doc
)
257 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
259 FIXME("(%p, %s): stub\n", This
, debugstr_w(doc
));
264 static HRESULT WINAPI
scriptlet_typelib_get_Doc(IGenScriptletTLib
*iface
, BSTR
*doc
)
266 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
268 FIXME("(%p, %p): stub\n", This
, doc
);
273 static HRESULT WINAPI
scriptlet_typelib_put_Name(IGenScriptletTLib
*iface
, BSTR name
)
275 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
277 FIXME("(%p, %s): stub\n", This
, debugstr_w(name
));
282 static HRESULT WINAPI
scriptlet_typelib_get_Name(IGenScriptletTLib
*iface
, BSTR
*name
)
284 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
286 FIXME("(%p, %p): stub\n", This
, name
);
291 static HRESULT WINAPI
scriptlet_typelib_put_MajorVersion(IGenScriptletTLib
*iface
, WORD version
)
293 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
295 FIXME("(%p, %x): stub\n", This
, version
);
300 static HRESULT WINAPI
scriptlet_typelib_get_MajorVersion(IGenScriptletTLib
*iface
, WORD
*version
)
302 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
304 FIXME("(%p, %p): stub\n", This
, version
);
309 static HRESULT WINAPI
scriptlet_typelib_put_MinorVersion(IGenScriptletTLib
*iface
, WORD version
)
311 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
313 FIXME("(%p, %x): stub\n", This
, version
);
318 static HRESULT WINAPI
scriptlet_typelib_get_MinorVersion(IGenScriptletTLib
*iface
, WORD
*version
)
320 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
322 FIXME("(%p, %p): stub\n", This
, version
);
327 static HRESULT WINAPI
scriptlet_typelib_Write(IGenScriptletTLib
*iface
)
329 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
331 FIXME("(%p): stub\n", This
);
336 static HRESULT WINAPI
scriptlet_typelib_Reset(IGenScriptletTLib
*iface
)
338 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
340 FIXME("(%p): stub\n", This
);
345 static HRESULT WINAPI
scriptlet_typelib_put_GUID(IGenScriptletTLib
*iface
, BSTR guid
)
347 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
349 FIXME("(%p, %s): stub\n", This
, debugstr_w(guid
));
354 static HRESULT WINAPI
scriptlet_typelib_get_GUID(IGenScriptletTLib
*iface
, BSTR
*ret
)
356 struct scriptlet_typelib
*This
= impl_from_IGenScriptletTLib(iface
);
358 TRACE("(%p, %p)\n", This
, ret
);
368 hr
= CoCreateGuid(&guid
);
372 hr
= StringFromGUID2(&guid
, guidW
, sizeof(guidW
)/sizeof(guidW
[0]));
376 if (!(This
->guid
= SysAllocString(guidW
)))
377 return E_OUTOFMEMORY
;
380 *ret
= SysAllocString(This
->guid
);
381 return *ret
? S_OK
: E_OUTOFMEMORY
;
384 static const IGenScriptletTLibVtbl scriptlet_typelib_vtbl
=
386 scriptlet_typelib_QueryInterface
,
387 scriptlet_typelib_AddRef
,
388 scriptlet_typelib_Release
,
389 scriptlet_typelib_GetTypeInfoCount
,
390 scriptlet_typelib_GetTypeInfo
,
391 scriptlet_typelib_GetIDsOfNames
,
392 scriptlet_typelib_Invoke
,
393 scriptlet_typelib_AddURL
,
394 scriptlet_typelib_put_Path
,
395 scriptlet_typelib_get_Path
,
396 scriptlet_typelib_put_Doc
,
397 scriptlet_typelib_get_Doc
,
398 scriptlet_typelib_put_Name
,
399 scriptlet_typelib_get_Name
,
400 scriptlet_typelib_put_MajorVersion
,
401 scriptlet_typelib_get_MajorVersion
,
402 scriptlet_typelib_put_MinorVersion
,
403 scriptlet_typelib_get_MinorVersion
,
404 scriptlet_typelib_Write
,
405 scriptlet_typelib_Reset
,
406 scriptlet_typelib_put_GUID
,
407 scriptlet_typelib_get_GUID
410 BOOL WINAPI
DllMain(HINSTANCE hinst
, DWORD reason
, void *reserved
)
412 TRACE("%p, %u, %p\n", hinst
, reason
, reserved
);
416 case DLL_WINE_PREATTACH
:
417 return FALSE
; /* prefer native version */
418 case DLL_PROCESS_ATTACH
:
419 DisableThreadLibraryCalls(hinst
);
420 scrobj_instance
= hinst
;
422 case DLL_PROCESS_DETACH
:
430 /***********************************************************************
431 * DllRegisterServer (scrobj.@)
433 HRESULT WINAPI
DllRegisterServer(void)
436 return __wine_register_resources(scrobj_instance
);
439 /***********************************************************************
440 * DllUnregisterServer (scrobj.@)
442 HRESULT WINAPI
DllUnregisterServer(void)
445 return __wine_unregister_resources(scrobj_instance
);
448 static HRESULT WINAPI
scriptlet_typelib_CreateInstance(IClassFactory
*factory
, IUnknown
*outer
, REFIID riid
, void **obj
)
450 struct scriptlet_typelib
*This
;
453 TRACE("(%p, %p, %s, %p)\n", factory
, outer
, debugstr_guid(riid
), obj
);
457 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
459 return E_OUTOFMEMORY
;
461 This
->IGenScriptletTLib_iface
.lpVtbl
= &scriptlet_typelib_vtbl
;
465 hr
= IGenScriptletTLib_QueryInterface(&This
->IGenScriptletTLib_iface
, riid
, obj
);
466 IGenScriptletTLib_Release(&This
->IGenScriptletTLib_iface
);
470 static HRESULT WINAPI
scrruncf_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
474 if (IsEqualGUID(&IID_IUnknown
, riid
))
476 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
479 else if (IsEqualGUID(&IID_IClassFactory
, riid
))
481 TRACE("(%p)->(IID_IClassFactory %p)\n", iface
, ppv
);
487 IUnknown_AddRef((IUnknown
*)*ppv
);
491 WARN("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
492 return E_NOINTERFACE
;
495 static ULONG WINAPI
scrruncf_AddRef(IClassFactory
*iface
)
497 TRACE("(%p)\n", iface
);
501 static ULONG WINAPI
scrruncf_Release(IClassFactory
*iface
)
503 TRACE("(%p)\n", iface
);
507 static HRESULT WINAPI
scrruncf_LockServer(IClassFactory
*iface
, BOOL fLock
)
509 TRACE("(%p)->(%x)\n", iface
, fLock
);
513 static const struct IClassFactoryVtbl scriptlet_typelib_factory_vtbl
=
515 scrruncf_QueryInterface
,
518 scriptlet_typelib_CreateInstance
,
522 static IClassFactory scriptlet_typelib_factory
= { &scriptlet_typelib_factory_vtbl
};
524 /***********************************************************************
525 * DllGetClassObject (scrobj.@)
527 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **ppv
)
529 if (IsEqualGUID(&CLSID_TypeLib
, rclsid
))
531 TRACE("(Scriptlet.TypeLib %s %p)\n", debugstr_guid(riid
), ppv
);
532 return IClassFactory_QueryInterface(&scriptlet_typelib_factory
, riid
, ppv
);
535 FIXME("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
536 return CLASS_E_CLASSNOTAVAILABLE
;
539 /***********************************************************************
540 * DllCanUnloadNow (scrobj.@)
542 HRESULT WINAPI
DllCanUnloadNow(void)