Commit 2974c8e5 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

scrobj: Suport scriptlet registration.

parent 2f965ed6
/*
* 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)
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment