Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/combase/roapi.c
4394 views
1
/*
2
* Copyright 2014 Martin Storsjo
3
* Copyright 2016 Michael Müller
4
*
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
9
*
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
14
*
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18
*/
19
#define COBJMACROS
20
#include "objbase.h"
21
#include "initguid.h"
22
#include "roapi.h"
23
#include "roparameterizediid.h"
24
#include "roerrorapi.h"
25
#include "winstring.h"
26
#include "errhandlingapi.h"
27
28
#include "combase_private.h"
29
30
#include "wine/debug.h"
31
32
WINE_DEFAULT_DEBUG_CHANNEL(combase);
33
34
struct activatable_class_data
35
{
36
ULONG size;
37
DWORD unk;
38
DWORD module_len;
39
DWORD module_offset;
40
DWORD threading_model;
41
};
42
43
static HRESULT get_library_for_classid(const WCHAR *classid, WCHAR **out)
44
{
45
ACTCTX_SECTION_KEYED_DATA data;
46
HKEY hkey_root, hkey_class;
47
DWORD type, size;
48
HRESULT hr;
49
WCHAR *buf = NULL;
50
51
*out = NULL;
52
53
/* search activation context first */
54
data.cbSize = sizeof(data);
55
if (FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
56
ACTIVATION_CONTEXT_SECTION_WINRT_ACTIVATABLE_CLASSES, classid, &data))
57
{
58
struct activatable_class_data *activatable_class = (struct activatable_class_data *)data.lpData;
59
void *ptr = (BYTE *)data.lpSectionBase + activatable_class->module_offset;
60
*out = wcsdup(ptr);
61
return S_OK;
62
}
63
64
/* load class registry key */
65
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\WindowsRuntime\\ActivatableClassId",
66
0, KEY_READ, &hkey_root))
67
return REGDB_E_READREGDB;
68
if (RegOpenKeyExW(hkey_root, classid, 0, KEY_READ, &hkey_class))
69
{
70
WARN("Class %s not found in registry\n", debugstr_w(classid));
71
RegCloseKey(hkey_root);
72
return REGDB_E_CLASSNOTREG;
73
}
74
RegCloseKey(hkey_root);
75
76
/* load (and expand) DllPath registry value */
77
if (RegQueryValueExW(hkey_class, L"DllPath", NULL, &type, NULL, &size))
78
{
79
hr = REGDB_E_READREGDB;
80
goto done;
81
}
82
if (type != REG_SZ && type != REG_EXPAND_SZ)
83
{
84
hr = REGDB_E_READREGDB;
85
goto done;
86
}
87
if (!(buf = malloc(size)))
88
{
89
hr = E_OUTOFMEMORY;
90
goto done;
91
}
92
if (RegQueryValueExW(hkey_class, L"DllPath", NULL, NULL, (BYTE *)buf, &size))
93
{
94
hr = REGDB_E_READREGDB;
95
goto done;
96
}
97
if (type == REG_EXPAND_SZ)
98
{
99
WCHAR *expanded;
100
DWORD len = ExpandEnvironmentStringsW(buf, NULL, 0);
101
if (!(expanded = malloc(len * sizeof(WCHAR))))
102
{
103
hr = E_OUTOFMEMORY;
104
goto done;
105
}
106
ExpandEnvironmentStringsW(buf, expanded, len);
107
free(buf);
108
buf = expanded;
109
}
110
111
*out = buf;
112
return S_OK;
113
114
done:
115
free(buf);
116
RegCloseKey(hkey_class);
117
return hr;
118
}
119
120
121
/***********************************************************************
122
* RoInitialize (combase.@)
123
*/
124
HRESULT WINAPI RoInitialize(RO_INIT_TYPE type)
125
{
126
switch (type) {
127
case RO_INIT_SINGLETHREADED:
128
return CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
129
default:
130
FIXME("type %d\n", type);
131
case RO_INIT_MULTITHREADED:
132
return CoInitializeEx(NULL, COINIT_MULTITHREADED);
133
}
134
}
135
136
/***********************************************************************
137
* RoUninitialize (combase.@)
138
*/
139
void WINAPI RoUninitialize(void)
140
{
141
CoUninitialize();
142
}
143
144
/***********************************************************************
145
* RoGetActivationFactory (combase.@)
146
*/
147
HRESULT WINAPI DECLSPEC_HOTPATCH RoGetActivationFactory(HSTRING classid, REFIID iid, void **class_factory)
148
{
149
PFNGETACTIVATIONFACTORY pDllGetActivationFactory;
150
IActivationFactory *factory;
151
WCHAR *library;
152
HMODULE module;
153
HRESULT hr;
154
155
FIXME("(%s, %s, %p): semi-stub\n", debugstr_hstring(classid), debugstr_guid(iid), class_factory);
156
157
if (!iid || !class_factory)
158
return E_INVALIDARG;
159
160
if (FAILED(hr = ensure_mta()))
161
return hr;
162
163
hr = get_library_for_classid(WindowsGetStringRawBuffer(classid, NULL), &library);
164
if (FAILED(hr))
165
{
166
ERR("Failed to find library for %s\n", debugstr_hstring(classid));
167
return hr;
168
}
169
170
if (!(module = LoadLibraryW(library)))
171
{
172
ERR("Failed to load module %s\n", debugstr_w(library));
173
hr = HRESULT_FROM_WIN32(GetLastError());
174
goto done;
175
}
176
177
if (!(pDllGetActivationFactory = (void *)GetProcAddress(module, "DllGetActivationFactory")))
178
{
179
ERR("Module %s does not implement DllGetActivationFactory\n", debugstr_w(library));
180
hr = E_FAIL;
181
goto done;
182
}
183
184
TRACE("Found library %s for class %s\n", debugstr_w(library), debugstr_hstring(classid));
185
186
hr = pDllGetActivationFactory(classid, &factory);
187
if (SUCCEEDED(hr))
188
{
189
hr = IActivationFactory_QueryInterface(factory, iid, class_factory);
190
if (SUCCEEDED(hr))
191
{
192
TRACE("Created interface %p\n", *class_factory);
193
module = NULL;
194
}
195
IActivationFactory_Release(factory);
196
}
197
else
198
{
199
ERR("Class %s not found in %s, hr %#lx.\n", wine_dbgstr_hstring(classid), debugstr_w(library), hr);
200
}
201
202
done:
203
free(library);
204
if (module) FreeLibrary(module);
205
return hr;
206
}
207
208
/***********************************************************************
209
* RoGetParameterizedTypeInstanceIID (combase.@)
210
*/
211
HRESULT WINAPI RoGetParameterizedTypeInstanceIID(UINT32 name_element_count, const WCHAR **name_elements,
212
const IRoMetaDataLocator *meta_data_locator, GUID *iid,
213
ROPARAMIIDHANDLE *hiid)
214
{
215
FIXME("stub: %d %p %p %p %p\n", name_element_count, name_elements, meta_data_locator, iid, hiid);
216
if (iid) *iid = GUID_NULL;
217
if (hiid) *hiid = INVALID_HANDLE_VALUE;
218
return E_NOTIMPL;
219
}
220
221
/***********************************************************************
222
* RoActivateInstance (combase.@)
223
*/
224
HRESULT WINAPI RoActivateInstance(HSTRING classid, IInspectable **instance)
225
{
226
IActivationFactory *factory;
227
HRESULT hr;
228
229
FIXME("(%p, %p): semi-stub\n", classid, instance);
230
231
hr = RoGetActivationFactory(classid, &IID_IActivationFactory, (void **)&factory);
232
if (SUCCEEDED(hr))
233
{
234
hr = IActivationFactory_ActivateInstance(factory, instance);
235
IActivationFactory_Release(factory);
236
}
237
238
return hr;
239
}
240
241
struct agile_reference
242
{
243
IAgileReference IAgileReference_iface;
244
enum AgileReferenceOptions option;
245
IStream *marshal_stream;
246
CRITICAL_SECTION cs;
247
IUnknown *obj;
248
BOOLEAN is_agile;
249
LONG ref;
250
};
251
252
static HRESULT marshal_object_in_agile_reference(struct agile_reference *ref, REFIID riid, IUnknown *obj)
253
{
254
HRESULT hr;
255
256
hr = CreateStreamOnHGlobal(0, TRUE, &ref->marshal_stream);
257
if (FAILED(hr))
258
return hr;
259
260
hr = CoMarshalInterface(ref->marshal_stream, riid, obj, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);
261
if (FAILED(hr))
262
{
263
IStream_Release(ref->marshal_stream);
264
ref->marshal_stream = NULL;
265
}
266
return hr;
267
}
268
269
static inline struct agile_reference *impl_from_IAgileReference(IAgileReference *iface)
270
{
271
return CONTAINING_RECORD(iface, struct agile_reference, IAgileReference_iface);
272
}
273
274
static HRESULT WINAPI agile_ref_QueryInterface(IAgileReference *iface, REFIID riid, void **obj)
275
{
276
TRACE("(%p, %s, %p)\n", iface, debugstr_guid(riid), obj);
277
278
if (!riid || !obj) return E_INVALIDARG;
279
280
if (IsEqualGUID(riid, &IID_IUnknown)
281
|| IsEqualGUID(riid, &IID_IAgileObject)
282
|| IsEqualGUID(riid, &IID_IAgileReference))
283
{
284
IUnknown_AddRef(iface);
285
*obj = iface;
286
return S_OK;
287
}
288
289
*obj = NULL;
290
FIXME("interface %s is not implemented\n", debugstr_guid(riid));
291
return E_NOINTERFACE;
292
}
293
294
static ULONG WINAPI agile_ref_AddRef(IAgileReference *iface)
295
{
296
struct agile_reference *impl = impl_from_IAgileReference(iface);
297
return InterlockedIncrement(&impl->ref);
298
}
299
300
static ULONG WINAPI agile_ref_Release(IAgileReference *iface)
301
{
302
struct agile_reference *impl = impl_from_IAgileReference(iface);
303
LONG ref = InterlockedDecrement(&impl->ref);
304
305
if (!ref)
306
{
307
TRACE("destroying %p\n", iface);
308
309
if (impl->obj)
310
IUnknown_Release(impl->obj);
311
312
if (impl->marshal_stream)
313
{
314
LARGE_INTEGER zero = {0};
315
316
IStream_Seek(impl->marshal_stream, zero, STREAM_SEEK_SET, NULL);
317
CoReleaseMarshalData(impl->marshal_stream);
318
IStream_Release(impl->marshal_stream);
319
}
320
DeleteCriticalSection(&impl->cs);
321
free(impl);
322
}
323
324
return ref;
325
}
326
327
static HRESULT WINAPI agile_ref_Resolve(IAgileReference *iface, REFIID riid, void **obj)
328
{
329
struct agile_reference *impl = impl_from_IAgileReference(iface);
330
LARGE_INTEGER zero = {0};
331
HRESULT hr;
332
333
TRACE("(%p, %s, %p)\n", iface, debugstr_guid(riid), obj);
334
335
if (impl->is_agile)
336
return IUnknown_QueryInterface(impl->obj, riid, obj);
337
338
EnterCriticalSection(&impl->cs);
339
if (impl->option == AGILEREFERENCE_DELAYEDMARSHAL && impl->marshal_stream == NULL)
340
{
341
if (FAILED(hr = marshal_object_in_agile_reference(impl, riid, impl->obj)))
342
{
343
LeaveCriticalSection(&impl->cs);
344
return hr;
345
}
346
347
IUnknown_Release(impl->obj);
348
impl->obj = NULL;
349
}
350
351
if (SUCCEEDED(hr = IStream_Seek(impl->marshal_stream, zero, STREAM_SEEK_SET, NULL)))
352
hr = CoUnmarshalInterface(impl->marshal_stream, riid, obj);
353
354
LeaveCriticalSection(&impl->cs);
355
return hr;
356
}
357
358
static const IAgileReferenceVtbl agile_ref_vtbl =
359
{
360
agile_ref_QueryInterface,
361
agile_ref_AddRef,
362
agile_ref_Release,
363
agile_ref_Resolve,
364
};
365
366
static BOOL object_has_interface(IUnknown *obj, REFIID iid)
367
{
368
IUnknown *unk;
369
HRESULT hr;
370
371
hr = IUnknown_QueryInterface(obj, iid, (void **)&unk);
372
if (SUCCEEDED(hr))
373
IUnknown_Release(unk);
374
return SUCCEEDED(hr);
375
}
376
377
/***********************************************************************
378
* RoGetAgileReference (combase.@)
379
*/
380
HRESULT WINAPI RoGetAgileReference(enum AgileReferenceOptions option, REFIID riid, IUnknown *obj,
381
IAgileReference **agile_reference)
382
{
383
struct agile_reference *impl;
384
HRESULT hr;
385
386
TRACE("(%d, %s, %p, %p).\n", option, debugstr_guid(riid), obj, agile_reference);
387
388
if (option != AGILEREFERENCE_DEFAULT && option != AGILEREFERENCE_DELAYEDMARSHAL)
389
return E_INVALIDARG;
390
391
if (!InternalIsProcessInitialized())
392
{
393
ERR("Apartment not initialized\n");
394
return CO_E_NOTINITIALIZED;
395
}
396
397
if (!object_has_interface(obj, riid))
398
return E_NOINTERFACE;
399
if (object_has_interface(obj, &IID_INoMarshal))
400
return CO_E_NOT_SUPPORTED;
401
402
impl = calloc(1, sizeof(*impl));
403
if (!impl)
404
return E_OUTOFMEMORY;
405
406
impl->IAgileReference_iface.lpVtbl = &agile_ref_vtbl;
407
impl->option = option;
408
impl->is_agile = object_has_interface(obj, &IID_IAgileObject);
409
impl->ref = 1;
410
411
if (option == AGILEREFERENCE_DELAYEDMARSHAL || impl->is_agile)
412
{
413
impl->obj = obj;
414
IUnknown_AddRef(impl->obj);
415
}
416
else if (option == AGILEREFERENCE_DEFAULT)
417
{
418
if (FAILED(hr = marshal_object_in_agile_reference(impl, riid, obj)))
419
{
420
free(impl);
421
return hr;
422
}
423
}
424
425
InitializeCriticalSection(&impl->cs);
426
427
*agile_reference = &impl->IAgileReference_iface;
428
return S_OK;
429
}
430
431
/***********************************************************************
432
* RoFailFastWithErrorContextInternal2 (combase.@)
433
*/
434
void WINAPI RoFailFastWithErrorContextInternal2(HRESULT error, ULONG exception_count, /* PSTOWED_EXCEPTION_INFORMATION_V2 */void *information)
435
{
436
FIXME("%#lx, %lu, %p stub.\n", error, exception_count, information);
437
RaiseFailFastException(NULL, NULL, 0);
438
}
439
440
/***********************************************************************
441
* RoGetApartmentIdentifier (combase.@)
442
*/
443
HRESULT WINAPI RoGetApartmentIdentifier(UINT64 *identifier)
444
{
445
FIXME("(%p): stub\n", identifier);
446
447
if (!identifier)
448
return E_INVALIDARG;
449
450
*identifier = 0xdeadbeef;
451
return S_OK;
452
}
453
454
/***********************************************************************
455
* RoRegisterForApartmentShutdown (combase.@)
456
*/
457
HRESULT WINAPI RoRegisterForApartmentShutdown(IApartmentShutdown *callback,
458
UINT64 *identifier, APARTMENT_SHUTDOWN_REGISTRATION_COOKIE *cookie)
459
{
460
HRESULT hr;
461
462
FIXME("(%p, %p, %p): stub\n", callback, identifier, cookie);
463
464
hr = RoGetApartmentIdentifier(identifier);
465
if (FAILED(hr))
466
return hr;
467
468
if (cookie)
469
*cookie = (void *)0xcafecafe;
470
return S_OK;
471
}
472
473
/***********************************************************************
474
* RoGetServerActivatableClasses (combase.@)
475
*/
476
HRESULT WINAPI RoGetServerActivatableClasses(HSTRING name, HSTRING **classes, DWORD *count)
477
{
478
FIXME("(%p, %p, %p): stub\n", name, classes, count);
479
480
if (count)
481
*count = 0;
482
return S_OK;
483
}
484
485
/***********************************************************************
486
* RoRegisterActivationFactories (combase.@)
487
*/
488
HRESULT WINAPI RoRegisterActivationFactories(HSTRING *classes, PFNGETACTIVATIONFACTORY *callbacks,
489
UINT32 count, RO_REGISTRATION_COOKIE *cookie)
490
{
491
FIXME("(%p, %p, %d, %p): stub\n", classes, callbacks, count, cookie);
492
493
return S_OK;
494
}
495
496
/***********************************************************************
497
* GetRestrictedErrorInfo (combase.@)
498
*/
499
HRESULT WINAPI GetRestrictedErrorInfo(IRestrictedErrorInfo **info)
500
{
501
FIXME( "(%p)\n", info );
502
return E_NOTIMPL;
503
}
504
505
/***********************************************************************
506
* SetRestrictedErrorInfo (combase.@)
507
*/
508
HRESULT WINAPI SetRestrictedErrorInfo(IRestrictedErrorInfo *info)
509
{
510
FIXME( "(%p)\n", info );
511
return E_NOTIMPL;
512
}
513
514
/***********************************************************************
515
* RoOriginateLanguageException (combase.@)
516
*/
517
BOOL WINAPI RoOriginateLanguageException(HRESULT error, HSTRING message, IUnknown *language_exception)
518
{
519
FIXME("%#lx, %s, %p: stub\n", error, debugstr_hstring(message), language_exception);
520
return FALSE;
521
}
522
523
/***********************************************************************
524
* RoOriginateError (combase.@)
525
*/
526
BOOL WINAPI RoOriginateError(HRESULT error, HSTRING message)
527
{
528
FIXME("%#lx, %s: stub\n", error, debugstr_hstring(message));
529
return FALSE;
530
}
531
532
/***********************************************************************
533
* RoOriginateErrorW (combase.@)
534
*/
535
BOOL WINAPI RoOriginateErrorW(HRESULT error, UINT max_len, const WCHAR *message)
536
{
537
FIXME("%#lx, %u, %p: stub\n", error, max_len, message);
538
return FALSE;
539
}
540
541
/***********************************************************************
542
* RoReportUnhandledError (combase.@)
543
*/
544
HRESULT WINAPI RoReportUnhandledError(IRestrictedErrorInfo *info)
545
{
546
FIXME("(%p): stub\n", info);
547
return S_OK;
548
}
549
550
/***********************************************************************
551
* RoSetErrorReportingFlags (combase.@)
552
*/
553
HRESULT WINAPI RoSetErrorReportingFlags(UINT32 flags)
554
{
555
FIXME("(%08x): stub\n", flags);
556
return S_OK;
557
}
558
559
/***********************************************************************
560
* RoGetErrorReportingFlags (combase.@)
561
*/
562
HRESULT WINAPI RoGetErrorReportingFlags(UINT32 *flags)
563
{
564
FIXME("(%p): stub\n", flags);
565
566
if (!flags)
567
return E_POINTER;
568
569
*flags = RO_ERROR_REPORTING_USESETERRORINFO;
570
return S_OK;
571
}
572
573
574
/***********************************************************************
575
* CleanupTlsOleState (combase.@)
576
*/
577
void WINAPI CleanupTlsOleState(void *unknown)
578
{
579
FIXME("(%p): stub\n", unknown);
580
}
581
582
/***********************************************************************
583
* DllGetActivationFactory (combase.@)
584
*/
585
HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **factory)
586
{
587
FIXME("(%s, %p): stub\n", debugstr_hstring(classid), factory);
588
589
return REGDB_E_CLASSNOTREG;
590
}
591
592