wine/dlls/combase/roapi.c
Rémi Bernon ea0fa9f1dc combase: Lookup activatable class library in the activation context.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
2022-05-20 12:24:38 +02:00

348 lines
10 KiB
C

/*
* Copyright 2014 Martin Storsjo
* Copyright 2016 Michael Müller
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include "objbase.h"
#include "initguid.h"
#include "roapi.h"
#include "roparameterizediid.h"
#include "roerrorapi.h"
#include "winstring.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(combase);
static const char *debugstr_hstring(HSTRING hstr)
{
const WCHAR *str;
UINT32 len;
if (hstr && !((ULONG_PTR)hstr >> 16)) return "(invalid)";
str = WindowsGetStringRawBuffer(hstr, &len);
return wine_dbgstr_wn(str, len);
}
struct activatable_class_data
{
ULONG size;
DWORD unk;
DWORD module_len;
DWORD module_offset;
DWORD threading_model;
};
static HRESULT get_library_for_classid(const WCHAR *classid, WCHAR **out)
{
ACTCTX_SECTION_KEYED_DATA data;
HKEY hkey_root, hkey_class;
DWORD type, size;
HRESULT hr;
WCHAR *buf = NULL;
*out = NULL;
/* search activation context first */
data.cbSize = sizeof(data);
if (FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
ACTIVATION_CONTEXT_SECTION_WINRT_ACTIVATABLE_CLASSES, classid, &data))
{
struct activatable_class_data *activatable_class = (struct activatable_class_data *)data.lpData;
void *ptr = (BYTE *)data.lpSectionBase + activatable_class->module_offset;
*out = wcsdup(ptr);
return S_OK;
}
/* load class registry key */
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\WindowsRuntime\\ActivatableClassId",
0, KEY_READ, &hkey_root))
return REGDB_E_READREGDB;
if (RegOpenKeyExW(hkey_root, classid, 0, KEY_READ, &hkey_class))
{
WARN("Class %s not found in registry\n", debugstr_w(classid));
RegCloseKey(hkey_root);
return REGDB_E_CLASSNOTREG;
}
RegCloseKey(hkey_root);
/* load (and expand) DllPath registry value */
if (RegQueryValueExW(hkey_class, L"DllPath", NULL, &type, NULL, &size))
{
hr = REGDB_E_READREGDB;
goto done;
}
if (type != REG_SZ && type != REG_EXPAND_SZ)
{
hr = REGDB_E_READREGDB;
goto done;
}
if (!(buf = malloc(size)))
{
hr = E_OUTOFMEMORY;
goto done;
}
if (RegQueryValueExW(hkey_class, L"DllPath", NULL, NULL, (BYTE *)buf, &size))
{
hr = REGDB_E_READREGDB;
goto done;
}
if (type == REG_EXPAND_SZ)
{
WCHAR *expanded;
DWORD len = ExpandEnvironmentStringsW(buf, NULL, 0);
if (!(expanded = malloc(len * sizeof(WCHAR))))
{
hr = E_OUTOFMEMORY;
goto done;
}
ExpandEnvironmentStringsW(buf, expanded, len);
free(buf);
buf = expanded;
}
*out = buf;
return S_OK;
done:
free(buf);
RegCloseKey(hkey_class);
return hr;
}
/***********************************************************************
* RoInitialize (combase.@)
*/
HRESULT WINAPI RoInitialize(RO_INIT_TYPE type)
{
switch (type) {
case RO_INIT_SINGLETHREADED:
return CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
default:
FIXME("type %d\n", type);
case RO_INIT_MULTITHREADED:
return CoInitializeEx(NULL, COINIT_MULTITHREADED);
}
}
/***********************************************************************
* RoUninitialize (combase.@)
*/
void WINAPI RoUninitialize(void)
{
CoUninitialize();
}
/***********************************************************************
* RoGetActivationFactory (combase.@)
*/
HRESULT WINAPI RoGetActivationFactory(HSTRING classid, REFIID iid, void **class_factory)
{
PFNGETACTIVATIONFACTORY pDllGetActivationFactory;
IActivationFactory *factory;
WCHAR *library;
HMODULE module;
HRESULT hr;
FIXME("(%s, %s, %p): semi-stub\n", debugstr_hstring(classid), debugstr_guid(iid), class_factory);
if (!iid || !class_factory)
return E_INVALIDARG;
hr = get_library_for_classid(WindowsGetStringRawBuffer(classid, NULL), &library);
if (FAILED(hr))
{
ERR("Failed to find library for %s\n", debugstr_hstring(classid));
return hr;
}
if (!(module = LoadLibraryW(library)))
{
ERR("Failed to load module %s\n", debugstr_w(library));
hr = HRESULT_FROM_WIN32(GetLastError());
goto done;
}
if (!(pDllGetActivationFactory = (void *)GetProcAddress(module, "DllGetActivationFactory")))
{
ERR("Module %s does not implement DllGetActivationFactory\n", debugstr_w(library));
hr = E_FAIL;
goto done;
}
TRACE("Found library %s for class %s\n", debugstr_w(library), debugstr_hstring(classid));
hr = pDllGetActivationFactory(classid, &factory);
if (SUCCEEDED(hr))
{
hr = IActivationFactory_QueryInterface(factory, iid, class_factory);
if (SUCCEEDED(hr))
{
TRACE("Created interface %p\n", *class_factory);
module = NULL;
}
IActivationFactory_Release(factory);
}
done:
free(library);
if (module) FreeLibrary(module);
return hr;
}
/***********************************************************************
* RoGetParameterizedTypeInstanceIID (combase.@)
*/
HRESULT WINAPI RoGetParameterizedTypeInstanceIID(UINT32 name_element_count, const WCHAR **name_elements,
const IRoMetaDataLocator *meta_data_locator, GUID *iid,
ROPARAMIIDHANDLE *hiid)
{
FIXME("stub: %d %p %p %p %p\n", name_element_count, name_elements, meta_data_locator, iid, hiid);
if (iid) *iid = GUID_NULL;
if (hiid) *hiid = INVALID_HANDLE_VALUE;
return E_NOTIMPL;
}
/***********************************************************************
* RoActivateInstance (combase.@)
*/
HRESULT WINAPI RoActivateInstance(HSTRING classid, IInspectable **instance)
{
IActivationFactory *factory;
HRESULT hr;
FIXME("(%p, %p): semi-stub\n", classid, instance);
hr = RoGetActivationFactory(classid, &IID_IActivationFactory, (void **)&factory);
if (SUCCEEDED(hr))
{
hr = IActivationFactory_ActivateInstance(factory, instance);
IActivationFactory_Release(factory);
}
return hr;
}
/***********************************************************************
* RoGetApartmentIdentifier (combase.@)
*/
HRESULT WINAPI RoGetApartmentIdentifier(UINT64 *identifier)
{
FIXME("(%p): stub\n", identifier);
if (!identifier)
return E_INVALIDARG;
*identifier = 0xdeadbeef;
return S_OK;
}
/***********************************************************************
* RoRegisterForApartmentShutdown (combase.@)
*/
HRESULT WINAPI RoRegisterForApartmentShutdown(IApartmentShutdown *callback,
UINT64 *identifier, APARTMENT_SHUTDOWN_REGISTRATION_COOKIE *cookie)
{
HRESULT hr;
FIXME("(%p, %p, %p): stub\n", callback, identifier, cookie);
hr = RoGetApartmentIdentifier(identifier);
if (FAILED(hr))
return hr;
if (cookie)
*cookie = (void *)0xcafecafe;
return S_OK;
}
/***********************************************************************
* RoGetServerActivatableClasses (combase.@)
*/
HRESULT WINAPI RoGetServerActivatableClasses(HSTRING name, HSTRING **classes, DWORD *count)
{
FIXME("(%p, %p, %p): stub\n", name, classes, count);
if (count)
*count = 0;
return S_OK;
}
/***********************************************************************
* RoRegisterActivationFactories (combase.@)
*/
HRESULT WINAPI RoRegisterActivationFactories(HSTRING *classes, PFNGETACTIVATIONFACTORY *callbacks,
UINT32 count, RO_REGISTRATION_COOKIE *cookie)
{
FIXME("(%p, %p, %d, %p): stub\n", classes, callbacks, count, cookie);
return S_OK;
}
/***********************************************************************
* GetRestrictedErrorInfo (combase.@)
*/
HRESULT WINAPI GetRestrictedErrorInfo(IRestrictedErrorInfo **info)
{
FIXME( "(%p)\n", info );
return E_NOTIMPL;
}
/***********************************************************************
* RoOriginateLanguageException (combase.@)
*/
BOOL WINAPI RoOriginateLanguageException(HRESULT error, HSTRING message, IUnknown *language_exception)
{
FIXME("%#lx, %s, %p: stub\n", error, debugstr_hstring(message), language_exception);
return FALSE;
}
/***********************************************************************
* RoOriginateError (combase.@)
*/
BOOL WINAPI RoOriginateError(HRESULT error, HSTRING message)
{
FIXME("%#lx, %s: stub\n", error, debugstr_hstring(message));
return FALSE;
}
/***********************************************************************
* RoSetErrorReportingFlags (combase.@)
*/
HRESULT WINAPI RoSetErrorReportingFlags(UINT32 flags)
{
FIXME("(%08x): stub\n", flags);
return S_OK;
}
/***********************************************************************
* CleanupTlsOleState (combase.@)
*/
void WINAPI CleanupTlsOleState(void *unknown)
{
FIXME("(%p): stub\n", unknown);
}
/***********************************************************************
* DllGetActivationFactory (combase.@)
*/
HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **factory)
{
FIXME("(%s, %p): stub\n", debugstr_hstring(classid), factory);
return REGDB_E_CLASSNOTREG;
}