diff --git a/dlls/wshom.ocx/Makefile.in b/dlls/wshom.ocx/Makefile.in index 879cc700c50..385fe734a4a 100644 --- a/dlls/wshom.ocx/Makefile.in +++ b/dlls/wshom.ocx/Makefile.in @@ -1,4 +1,5 @@ MODULE = wshom.ocx +IMPORTS = uuid oleaut32 C_SRCS = \ shell.c \ diff --git a/dlls/wshom.ocx/shell.c b/dlls/wshom.ocx/shell.c index 9392ff53924..68f14b8b2af 100644 --- a/dlls/wshom.ocx/shell.c +++ b/dlls/wshom.ocx/shell.c @@ -23,6 +23,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(wshom); +static IWshShell3 WshShell3; + static HRESULT WINAPI WshShell3_QueryInterface(IWshShell3 *iface, REFIID riid, void **ppv) { if(IsEqualGUID(riid, &IID_IUnknown)) { @@ -66,23 +68,46 @@ static HRESULT WINAPI WshShell3_GetTypeInfoCount(IWshShell3 *iface, UINT *pctinf static HRESULT WINAPI WshShell3_GetTypeInfo(IWshShell3 *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { - FIXME("(%u %u %p)\n", iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + TRACE("(%u %u %p)\n", iTInfo, lcid, ppTInfo); + return get_typeinfo(IWshShell3_tid, ppTInfo); } static HRESULT WINAPI WshShell3_GetIDsOfNames(IWshShell3 *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { - FIXME("(%s %p %u %u %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); - return E_NOTIMPL; + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%s %p %u %u %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + + hr = get_typeinfo(IWshShell3_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; } static HRESULT WINAPI WshShell3_Invoke(IWshShell3 *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { - FIXME("(%d %s %d %d %p %p %p %p)\n", dispIdMember, debugstr_guid(riid), + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%d %s %d %d %p %p %p %p)\n", dispIdMember, debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + + hr = get_typeinfo(IWshShell3_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &WshShell3, dispIdMember, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; } static HRESULT WINAPI WshShell3_get_SpecialFolders(IWshShell3 *iface, IWshCollection **out_Folders) diff --git a/dlls/wshom.ocx/tests/wshom.c b/dlls/wshom.ocx/tests/wshom.c index f9768b9d27e..36081aa135a 100644 --- a/dlls/wshom.ocx/tests/wshom.c +++ b/dlls/wshom.ocx/tests/wshom.c @@ -31,6 +31,7 @@ DEFINE_GUID(IID_IWshShell3, 0x41904400, 0xbe18, 0x11d3, 0xa2,0x8b, 0x00,0x10,0x4 static void test_wshshell(void) { + IDispatchEx *dispex; IDispatch *disp; IUnknown *shell; HRESULT hres; @@ -43,9 +44,12 @@ static void test_wshshell(void) } hres = IDispatch_QueryInterface(disp, &IID_IWshShell3, (void**)&shell); - IDispatch_Release(disp); ok(hres == S_OK, "Could not get IWshShell3 iface: %08x\n", hres); + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + ok(hres == E_NOINTERFACE, "got %08x\n", hres); + + IDispatch_Release(disp); IUnknown_Release(shell); } diff --git a/dlls/wshom.ocx/wshom_main.c b/dlls/wshom.ocx/wshom_main.c index b05eb86c9e7..c750592bc7f 100644 --- a/dlls/wshom.ocx/wshom_main.c +++ b/dlls/wshom.ocx/wshom_main.c @@ -16,8 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "initguid.h" #include "wshom_private.h" + +#include "initguid.h" #include "wshom.h" #include "rpcproxy.h" @@ -27,6 +28,70 @@ WINE_DEFAULT_DEBUG_CHANNEL(wshom); static HINSTANCE wshom_instance; +static ITypeLib *typelib; +static ITypeInfo *typeinfos[LAST_tid]; + +static REFIID tid_ids[] = { + &IID_NULL, + &IID_IWshShell3 +}; + +static HRESULT load_typelib(void) +{ + HRESULT hres; + ITypeLib *tl; + + hres = LoadRegTypeLib(&LIBID_IWshRuntimeLibrary, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl); + if(FAILED(hres)) { + ERR("LoadRegTypeLib failed: %08x\n", hres); + return hres; + } + + if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL)) + ITypeLib_Release(tl); + return hres; +} + +HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) +{ + HRESULT hres; + + if (!typelib) + hres = load_typelib(); + if (!typelib) + return hres; + + if(!typeinfos[tid]) { + ITypeInfo *ti; + + hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti); + if(FAILED(hres)) { + ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres); + return hres; + } + + if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL)) + ITypeInfo_Release(ti); + } + + *typeinfo = typeinfos[tid]; + return S_OK; +} + +void release_typelib(void) +{ + unsigned i; + + if(!typelib) + return; + + for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) + if(typeinfos[i]) + ITypeInfo_Release(typeinfos[i]); + + ITypeLib_Release(typelib); +} + static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) { *ppv = NULL; @@ -91,6 +156,9 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) wshom_instance = hInstDLL; DisableThreadLibraryCalls(wshom_instance); break; + case DLL_PROCESS_DETACH: + release_typelib(); + break; } return TRUE; diff --git a/dlls/wshom.ocx/wshom_private.h b/dlls/wshom.ocx/wshom_private.h index 50b84b3a31e..42be64194e6 100644 --- a/dlls/wshom.ocx/wshom_private.h +++ b/dlls/wshom.ocx/wshom_private.h @@ -24,4 +24,13 @@ #include "winbase.h" #include "ole2.h" +/* typelibs */ +typedef enum tid_t { + NULL_tid, + IWshShell3_tid, + LAST_tid +} tid_t; + +HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo); + HRESULT WINAPI WshShellFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;