Module: wine Branch: master Commit: 2974c8e574929ccc371d75a1cb58bbe021a653b2 URL: https://source.winehq.org/git/wine.git/?a=commit;h=2974c8e574929ccc371d75a1c...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Sep 20 16:23:15 2019 +0200
scrobj: Suport scriptlet registration.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/scrobj/scrobj.c | 168 ++++++++++++++++++++++++++++++++++++++++++++- dlls/scrobj/tests/scrobj.c | 18 +++-- 2 files changed, 180 insertions(+), 6 deletions(-)
diff --git a/dlls/scrobj/scrobj.c b/dlls/scrobj/scrobj.c index 6de0e8ce01..e1dc6182f3 100644 --- a/dlls/scrobj/scrobj.c +++ b/dlls/scrobj/scrobj.c @@ -1,5 +1,6 @@ /* * Copyright 2017 Nikolay Sivov + * Copyright 2019 Jacek Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -679,6 +680,151 @@ static HRESULT create_scriptlet_factory(const WCHAR *url, struct scriptlet_facto return S_OK; }
+static HRESULT register_scriptlet(struct scriptlet_factory *factory) +{ + HKEY key, clsid_key, obj_key; + LSTATUS status; + HRESULT hres; + + if (factory->classid_str) + { + WCHAR *url; + + status = RegCreateKeyW(HKEY_CLASSES_ROOT, L"CLSID", &clsid_key); + if (status) return E_ACCESSDENIED; + + status = RegCreateKeyW(clsid_key, factory->classid_str, &obj_key); + RegCloseKey(clsid_key); + if (status) return E_ACCESSDENIED; + + hres = IMoniker_GetDisplayName(factory->moniker, NULL, NULL, &url); + if (FAILED(hres)) + { + RegCloseKey(obj_key); + return hres; + } + status = RegCreateKeyW(obj_key, L"ScriptletURL", &key); + if (!status) + { + status = RegSetValueExW(key, NULL, 0, REG_SZ, (BYTE*)url, + (wcslen(url) + 1) * sizeof(WCHAR)); + RegCloseKey(key); + } + CoTaskMemFree(url); + + if (factory->description) + status = RegSetValueExW(obj_key, NULL, 0, REG_SZ, (BYTE*)factory->description, + (wcslen(factory->description) + 1) * sizeof(WCHAR)); + + if (!status) + { + status = RegCreateKeyW(obj_key, L"InprocServer32", &key); + if (!status) + { + WCHAR str[MAX_PATH]; + GetModuleFileNameW(scrobj_instance, str, MAX_PATH); + status = RegSetValueExW(key, NULL, 0, REG_SZ, (BYTE*)str, (wcslen(str) + 1) * sizeof(WCHAR)); + RegCloseKey(key); + } + } + + if (!status && factory->versioned_progid) + { + status = RegCreateKeyW(obj_key, L"ProgID", &key); + if (!status) + { + status = RegSetValueExW(key, NULL, 0, REG_SZ, (BYTE*)factory->versioned_progid, + (wcslen(factory->versioned_progid) + 1) * sizeof(WCHAR)); + RegCloseKey(key); + } + } + + if (!status && factory->progid) + { + status = RegCreateKeyW(obj_key, L"VersionIndependentProgID", &key); + if (!status) + { + status = RegSetValueExW(key, NULL, 0, REG_SZ, (BYTE*)factory->progid, + (wcslen(factory->progid) + 1) * sizeof(WCHAR)); + RegCloseKey(key); + } + } + + RegCloseKey(obj_key); + if (status) return E_ACCESSDENIED; + } + + if (factory->progid) + { + status = RegCreateKeyW(HKEY_CLASSES_ROOT, factory->progid, &key); + if (status) return E_ACCESSDENIED; + + if (factory->description) + status = RegSetValueExW(key, NULL, 0, REG_SZ, (BYTE*)factory->description, + (wcslen(factory->description) + 1) * sizeof(WCHAR)); + + if (!status && factory->classid_str) + { + status = RegCreateKeyW(key, L"CLSID", &clsid_key); + if (!status) + { + status = RegSetValueExW(clsid_key, NULL, 0, REG_SZ, (BYTE*)factory->classid_str, + (wcslen(factory->classid_str) + 1) * sizeof(WCHAR)); + RegCloseKey(clsid_key); + } + } + + RegCloseKey(key); + if (status) return E_ACCESSDENIED; + } + + if (factory->versioned_progid) + { + status = RegCreateKeyW(HKEY_CLASSES_ROOT, factory->versioned_progid, &key); + if (status) return E_ACCESSDENIED; + + if (factory->description) + status = RegSetValueExW(key, NULL, 0, REG_SZ, (BYTE*)factory->description, + (wcslen(factory->description) + 1) * sizeof(WCHAR)); + + if (!status && factory->classid_str) + { + status = RegCreateKeyW(key, L"CLSID", &clsid_key); + if (!status) + { + status = RegSetValueExW(clsid_key, NULL, 0, REG_SZ, (BYTE*)factory->classid_str, + (wcslen(factory->classid_str) + 1) * sizeof(WCHAR)); + RegCloseKey(clsid_key); + } + } + + RegCloseKey(key); + if (status) return E_ACCESSDENIED; + } + + return S_OK; +} + +static HRESULT unregister_scriptlet(struct scriptlet_factory *factory) +{ + LSTATUS status; + + if (factory->classid_str) + { + HKEY clsid_key; + status = RegCreateKeyW(HKEY_CLASSES_ROOT, L"CLSID", &clsid_key); + if (!status) + { + RegDeleteTreeW(clsid_key, factory->classid_str); + RegCloseKey(clsid_key); + } + } + + if (factory->progid) RegDeleteTreeW(HKEY_CLASSES_ROOT, factory->progid); + if (factory->versioned_progid) RegDeleteTreeW(HKEY_CLASSES_ROOT, factory->versioned_progid); + return S_OK; +} + struct scriptlet_typelib { IGenScriptletTLib IGenScriptletTLib_iface; @@ -1020,6 +1166,7 @@ HRESULT WINAPI DllUnregisterServer(void) */ HRESULT WINAPI DllInstall(BOOL install, const WCHAR *arg) { + struct scriptlet_factory *factory; HRESULT hres;
if (install) @@ -1030,8 +1177,25 @@ HRESULT WINAPI DllInstall(BOOL install, const WCHAR *arg) else if (!arg) return DllUnregisterServer();
- FIXME("argument %s not supported\n", debugstr_w(arg)); - return E_NOTIMPL; + hres = create_scriptlet_factory(arg, &factory); + if (SUCCEEDED(hres)) + { + if (factory->have_registration) + { + if (install) + hres = register_scriptlet(factory); + else + hres = unregister_scriptlet(factory); + } + else + { + FIXME("No registration info\n"); + hres = E_FAIL; + } + IClassFactory_Release(&factory->IClassFactory_iface); + } + + return hres; }
static HRESULT WINAPI scriptlet_typelib_CreateInstance(IClassFactory *factory, IUnknown *outer, REFIID riid, void **obj) diff --git a/dlls/scrobj/tests/scrobj.c b/dlls/scrobj/tests/scrobj.c index bfd864dbee..259417e60e 100644 --- a/dlls/scrobj/tests/scrobj.c +++ b/dlls/scrobj/tests/scrobj.c @@ -730,7 +730,6 @@ static void register_script_object(BOOL do_register, const WCHAR *file_name) CHECK_CALLED(SetScriptState_UNINITIALIZED); todo_wine CHECK_CALLED(Close); - todo_wine ok(hres == S_OK, "DllInstall failed: %08x\n", hres); if (FAILED(hres)) return; @@ -769,10 +768,7 @@ static void test_create_object(void)
hres = CoGetClassObject(&CLSID_WineTest, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, NULL, &IID_IClassFactory, (void**)&cf); - todo_wine ok(hres == S_OK, "Could not get class factory: %08x\n", hres); - if (FAILED(hres)) - return;
parse_flags = SCRIPTTEXT_ISPERSISTENT | SCRIPTTEXT_ISVISIBLE;
@@ -790,20 +786,34 @@ static void test_create_object(void) SET_EXPECT(SetScriptState_UNINITIALIZED); SET_EXPECT(Clone); hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&unk); + todo_wine ok(hres == S_OK, "Could not create scriptlet instance: %08x\n", hres); + todo_wine CHECK_CALLED(Clone); + todo_wine CHECK_CALLED(CreateInstance); + todo_wine CHECK_CALLED(QI_IActiveScriptParse); + todo_wine CHECK_CALLED(InitNew); + todo_wine CHECK_CALLED(SetScriptSite); + todo_wine CHECK_CALLED(AddNamedItem_scriptlet); + todo_wine CHECK_CALLED(AddNamedItem_globals); + todo_wine CHECK_CALLED(GetScriptDispatch); todo_wine CHECK_CALLED(GetDispID_vbAddOne); + todo_wine CHECK_CALLED(GetDispID_wtTest); + todo_wine CHECK_CALLED(SetScriptState_STARTED); + todo_wine CHECK_CALLED(ParseScriptText); + if (FAILED(hres)) + return;
hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp); ok(hres == S_OK, "Could not get IDispatch iface: %08x\n", hres);