Jacek Caban : scrobj: Suport scriptlet registration.
Alexandre Julliard
julliard at winehq.org
Fri Sep 20 15:54:43 CDT 2019
Module: wine
Branch: master
Commit: 2974c8e574929ccc371d75a1cb58bbe021a653b2
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2974c8e574929ccc371d75a1cb58bbe021a653b2
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Sep 20 16:23:15 2019 +0200
scrobj: Suport scriptlet registration.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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);
More information about the wine-cvs
mailing list