ReactOS 0.4.16-dev-1612-g0f4e223
compartmentmgr.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS CTF
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: ITfCompartmentMgr implementation
5 * COPYRIGHT: Copyright 2009 Aric Stewart, CodeWeavers
6 * Copyright 2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7 */
8
9#include "precomp.h"
10
11#include <wine/debug.h>
13
15
16typedef struct tagCompartmentValue
17{
18 struct list entry;
23
25
27 : public ITfCompartmentMgr
28{
29public:
30 CCompartmentMgr(IUnknown *pUnkOuter = NULL);
31 virtual ~CCompartmentMgr();
32
33 static HRESULT CreateInstance(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut);
34
35 // ** IUnknown methods **
36 STDMETHODIMP QueryInterface(REFIID iid, LPVOID *ppvObj) override;
39
40 // ** ITfCompartmentMgr methods **
44
45protected:
48 struct list m_values;
49};
50
52
54 : public IEnumGUID
55{
56public:
58 virtual ~CCompartmentEnumGuid();
59
60 static HRESULT CreateInstance(struct list *values, IEnumGUID **ppOut);
61 static HRESULT CreateInstance(struct list *values, IEnumGUID **ppOut, struct list *cursor);
62
63 // ** IUnknown methods **
64 STDMETHODIMP QueryInterface(REFIID iid, LPVOID *ppvObj) override;
67
68 // ** IEnumGUID methods **
70 _In_ ULONG celt,
71 _Out_ GUID *rgelt,
72 _Out_ ULONG *pceltFetched) override;
73 STDMETHODIMP Skip(_In_ ULONG celt) override;
74 STDMETHODIMP Reset() override;
75 STDMETHODIMP Clone(_Out_ IEnumGUID **ppenum) override;
76
77protected:
79 struct list *m_values;
80 struct list *m_cursor;
81};
82
84
86 : public ITfCompartment
87 , public ITfSource
88{
89public:
91 virtual ~CCompartment();
92
93 static HRESULT CreateInstance(CompartmentValue *valueData, ITfCompartment **ppOut);
94
95 // ** IUnknown methods **
96 STDMETHODIMP QueryInterface(REFIID iid, LPVOID *ppvObj) override;
99
100 // ** ITfCompartment methods **
101 STDMETHODIMP SetValue(_In_ TfClientId tid, _In_ const VARIANT *pvarValue) override;
102 STDMETHODIMP GetValue(_Out_ VARIANT *pvarValue) override;
103
104 // ** ITfSource methods **
107 _In_ IUnknown *punk,
108 _Out_ DWORD *pdwCookie) override;
109 STDMETHODIMP UnadviseSink(_In_ DWORD dwCookie) override;
110
111protected:
113 VARIANT m_variant; // Only VT_I4, VT_UNKNOWN and VT_BSTR data types are allowed
116};
117
119
121 : m_cRefs(1)
122 , m_pUnkOuter(pUnkOuter)
123{
125}
126
128{
129 struct list *cursor, *cursor2;
130
132 {
135 value->compartment->Release();
137 }
138}
139
141{
142 if (!ppOut)
143 return E_POINTER;
144
145 if (pUnkOuter && riid != IID_IUnknown)
147
149 if (!This)
150 return E_OUTOFMEMORY;
151
152 if (pUnkOuter)
153 {
154 *ppOut = static_cast<ITfCompartmentMgr *>(This);
155 TRACE("returning %p\n", *ppOut);
156 return S_OK;
157 }
158 else
159 {
160 HRESULT hr;
161 hr = This->QueryInterface(riid, (void **)ppOut);
162 if (FAILED(hr))
163 delete This;
164 return hr;
165 }
166}
167
169{
170 if (m_pUnkOuter)
171 return m_pUnkOuter->QueryInterface(iid, ppvOut);
172
173 *ppvOut = NULL;
174
175 if (iid == IID_IUnknown || iid == IID_ITfCompartmentMgr)
176 *ppvOut = static_cast<ITfCompartmentMgr *>(this);
177
178 if (*ppvOut)
179 {
180 AddRef();
181 return S_OK;
182 }
183
184 WARN("unsupported interface: %s\n", debugstr_guid(&iid));
185 return E_NOINTERFACE;
186}
187
189{
190 if (m_pUnkOuter)
191 return m_pUnkOuter->AddRef();
192 return ::InterlockedIncrement(&m_cRefs);
193}
194
196{
197 if (m_pUnkOuter)
198 return m_pUnkOuter->Release();
200 if (!ret)
201 delete this;
202 return ret;
203}
204
206{
207 if (!ppcomp)
208 return E_POINTER;
210 struct list *cursor;
211 HRESULT hr;
212
213 TRACE("(%p) %s %p\n", this, debugstr_guid(&rguid), ppcomp);
214
216 {
218 if (rguid == value->guid)
219 {
220 value->compartment->AddRef();
221 *ppcomp = value->compartment;
222 return S_OK;
223 }
224 }
225
227 if (!value)
228 return E_OUTOFMEMORY;
229
230 value->guid = rguid;
231 value->owner = 0;
232 hr = CCompartment::CreateInstance(value, &value->compartment);
233 if (SUCCEEDED(hr))
234 {
235 list_add_head(&m_values, &value->entry);
236 value->compartment->AddRef();
237 *ppcomp = value->compartment;
238 }
239 else
240 {
242 *ppcomp = NULL;
243 }
244
245 return hr;
246}
247
249{
250 struct list *cursor;
251
252 TRACE("(%p) %i %s\n", this, tid, debugstr_guid(&rguid));
253
255 {
257 if (rguid == value->guid)
258 {
259 if (value->owner && tid != value->owner)
260 return E_UNEXPECTED;
262 value->compartment->Release();
264 return S_OK;
265 }
266 }
267
269}
270
272{
273 TRACE("(%p) %p\n", this, ppEnum);
274 if (!ppEnum)
275 return E_INVALIDARG;
276
278}
279
281
283 : m_cRefs(1)
284 , m_values(NULL)
285 , m_cursor(NULL)
286{
287}
288
290{
291 TRACE("destroying %p\n", this);
292}
293
296{
298 if (!This)
299 return E_OUTOFMEMORY;
300
301 This->m_values = values;
302 This->m_cursor = list_head(values);
303
304 *ppOut = static_cast<IEnumGUID *>(This);
305 TRACE("returning %p\n", *ppOut);
306 return S_OK;
307}
308
311{
313 if (!This)
314 return E_OUTOFMEMORY;
315
316 This->m_values = values;
317 This->m_cursor = cursor;
318
319 *ppOut = static_cast<IEnumGUID *>(This);
320 TRACE("returning %p\n", *ppOut);
321 return S_OK;
322}
323
325{
326 *ppvObj = NULL;
327
328 if (iid == IID_IUnknown || iid == IID_IEnumGUID)
329 *ppvObj = static_cast<IEnumGUID *>(this);
330
331 if (*ppvObj)
332 {
333 AddRef();
334 return S_OK;
335 }
336
337 WARN("unsupported interface: %s\n", debugstr_guid(&iid));
338 return E_NOINTERFACE;
339}
340
342{
343 return ::InterlockedIncrement(&m_cRefs);
344}
345
347{
349 if (!ret)
350 delete this;
351 return ret;
352}
353
355 _In_ ULONG celt,
356 _Out_ GUID *rgelt,
357 _Out_ ULONG *pceltFetched)
358{
359 ULONG fetched = 0;
360
361 TRACE("(%p)\n", this);
362
363 if (!rgelt)
364 return E_POINTER;
365
366 while (fetched < celt && m_cursor)
367 {
369 if (!value)
370 break;
371
373 *rgelt = value->guid;
374
375 ++fetched;
376 ++rgelt;
377 }
378
379 if (pceltFetched)
380 *pceltFetched = fetched;
381 return fetched == celt ? S_OK : S_FALSE;
382}
383
385{
386 TRACE("(%p)\n", this);
388 return S_OK;
389}
390
392{
393 TRACE("(%p)\n", this);
395 return S_OK;
396}
397
399{
400 TRACE("(%p)\n", this);
401
402 if (!ppenum)
403 return E_POINTER;
404
406}
407
409
411 : m_cRefs(1)
412 , m_valueData(valueData)
413{
416}
417
419{
420 TRACE("destroying %p\n", this);
423}
424
426{
427 CCompartment *This = new(cicNoThrow) CCompartment(valueData);
428 if (!This)
429 return E_OUTOFMEMORY;
430
431 *ppOut = static_cast<ITfCompartment *>(This);
432 TRACE("returning %p\n", *ppOut);
433 return S_OK;
434}
435
437{
438 *ppvObj = NULL;
439
440 if (iid == IID_IUnknown || iid == IID_ITfCompartment)
441 *ppvObj = static_cast<ITfCompartment *>(this);
442 else if (iid == IID_ITfSource)
443 *ppvObj = static_cast<ITfSource *>(this);
444
445 if (*ppvObj)
446 {
447 AddRef();
448 return S_OK;
449 }
450
451 WARN("unsupported interface: %s\n", debugstr_guid(&iid));
452 return E_NOINTERFACE;
453}
454
456{
457 return ::InterlockedIncrement(&m_cRefs);
458}
459
461{
463 if (!ret)
464 delete this;
465 return ret;
466}
467
469{
471 struct list *cursor;
472
473 TRACE("(%p) %i %p\n", this, tid, pvarValue);
474
475 if (!pvarValue)
476 return E_INVALIDARG;
477
478 if (!(V_VT(pvarValue) == VT_BSTR || V_VT(pvarValue) == VT_I4 || V_VT(pvarValue) == VT_UNKNOWN))
479 return E_INVALIDARG;
480
481 if (!m_valueData->owner)
483
485
486 /* Shallow copy of value and type */
487 m_variant = *pvarValue;
488
489 if (V_VT(pvarValue) == VT_BSTR)
490 {
491 V_BSTR(&m_variant) = ::SysAllocStringByteLen((char*)V_BSTR(pvarValue),
492 ::SysStringByteLen(V_BSTR(pvarValue)));
493 }
494 else if (V_VT(pvarValue) == VT_UNKNOWN)
495 {
496 V_UNKNOWN(&m_variant)->AddRef();
497 }
498
500 {
501 sink->OnChange(m_valueData->guid);
502 }
503
504 return S_OK;
505}
506
508{
509 TRACE("(%p) %p\n", this, pvarValue);
510
511 if (!pvarValue)
512 return E_INVALIDARG;
513
514 ::VariantInit(pvarValue);
515 if (V_VT(&m_variant) == VT_EMPTY)
516 return S_FALSE;
517 return ::VariantCopy(pvarValue, &m_variant);
518}
519
522 _In_ IUnknown *punk,
523 _Out_ DWORD *pdwCookie)
524{
525 TRACE("(%p) %s %p %p\n", this, debugstr_guid(&riid), punk, pdwCookie);
526
527 if (cicIsNullPtr(&riid) || !punk || !pdwCookie)
528 return E_INVALIDARG;
529
530 if (riid == IID_ITfCompartmentEventSink)
531 {
532 return advise_sink(&m_CompartmentEventSink, IID_ITfCompartmentEventSink,
533 COOKIE_MAGIC_COMPARTMENTSINK, punk, pdwCookie);
534 }
535
536 FIXME("(%p) Unhandled Sink: %s\n", this, debugstr_guid(&riid));
537 return E_NOTIMPL;
538}
539
541{
542 TRACE("(%p) %x\n", this, dwCookie);
543
545 return E_INVALIDARG;
546
547 return unadvise_sink(dwCookie);
548}
549
551
554{
555 return CCompartmentMgr::CreateInstance(pUnkOuter, riid, ppOut);
556}
557
560{
561 iface->Release();
562 return S_OK;
563}
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define SINK_FOR_EACH(cursor, list, type, elem)
Definition: precomp.h:96
#define COOKIE_MAGIC_COMPARTMENTSINK
Definition: precomp.h:38
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define EXTERN_C
Definition: basetyps.h:12
#define STDMETHODIMP
Definition: basetyps.h:43
#define STDMETHODIMP_(t)
Definition: basetyps.h:44
const GUID IID_IUnknown
static LPVOID cicMemAlloc(SIZE_T size)
Definition: cicbase.h:10
#define cicNoThrow
Definition: cicbase.h:46
static void cicMemFree(LPVOID ptr)
Definition: cicbase.h:20
static bool cicIsNullPtr(LPCVOID ptr)
Definition: cicbase.h:40
STDMETHODIMP_(ULONG) AddRef() override
STDMETHODIMP_(ULONG) Release() override
struct list * m_values
STDMETHODIMP Next(_In_ ULONG celt, _Out_ GUID *rgelt, _Out_ ULONG *pceltFetched) override
static HRESULT CreateInstance(struct list *values, IEnumGUID **ppOut)
STDMETHODIMP Skip(_In_ ULONG celt) override
STDMETHODIMP Reset() override
STDMETHODIMP Clone(_Out_ IEnumGUID **ppenum) override
STDMETHODIMP QueryInterface(REFIID iid, LPVOID *ppvObj) override
struct list * m_cursor
CCompartmentMgr(IUnknown *pUnkOuter=NULL)
IUnknown * m_pUnkOuter
STDMETHODIMP QueryInterface(REFIID iid, LPVOID *ppvObj) override
struct list m_values
STDMETHODIMP GetCompartment(_In_ REFGUID rguid, _Out_ ITfCompartment **ppcomp) override
STDMETHODIMP_(ULONG) AddRef() override
STDMETHODIMP ClearCompartment(_In_ TfClientId tid, _In_ REFGUID rguid) override
STDMETHODIMP EnumCompartments(_Out_ IEnumGUID **ppEnum) override
STDMETHODIMP_(ULONG) Release() override
virtual ~CCompartmentMgr()
static HRESULT CreateInstance(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut)
STDMETHODIMP_(ULONG) Release() override
CCompartment(CompartmentValue *valueData)
STDMETHODIMP QueryInterface(REFIID iid, LPVOID *ppvObj) override
STDMETHODIMP_(ULONG) AddRef() override
STDMETHODIMP SetValue(_In_ TfClientId tid, _In_ const VARIANT *pvarValue) override
struct list m_CompartmentEventSink
STDMETHODIMP AdviseSink(_In_ REFIID riid, _In_ IUnknown *punk, _Out_ DWORD *pdwCookie) override
static HRESULT CreateInstance(CompartmentValue *valueData, ITfCompartment **ppOut)
CompartmentValue * m_valueData
STDMETHODIMP UnadviseSink(_In_ DWORD dwCookie) override
virtual ~CCompartment()
STDMETHODIMP GetValue(_Out_ VARIANT *pvarValue) override
Definition: list.h:37
EXTERN_C HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut)
EXTERN_C HRESULT CompartmentMgr_Destructor(ITfCompartmentMgr *iface)
struct tagCompartmentValue CompartmentValue
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define NULL
Definition: types.h:112
@ VT_BSTR
Definition: compat.h:2303
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_I4
Definition: compat.h:2298
@ VT_EMPTY
Definition: compat.h:2295
return ret
Definition: mutex.c:146
unsigned long DWORD
Definition: ntddk_ex.h:95
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
const char cursor[]
Definition: icontest.c:13
REFIID riid
Definition: atlbase.h:39
static CInternetFolder * CreateInstance(void)
Definition: inetfolder.c:330
static TfClientId tid
ULONG AddRef()
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
ULONG Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
@ SetValue
Definition: shader.c:1968
static IAdviseSinkEx AdviseSink
Definition: htmldoc.c:5184
EXTERN_C HRESULT advise_sink(struct list *sink_list, REFIID riid, DWORD cookie_magic, IUnknown *unk, DWORD *cookie)
Definition: msctf.cpp:259
EXTERN_C DWORD get_Cookie_magic(DWORD id)
Definition: msctf.cpp:203
EXTERN_C HRESULT unadvise_sink(DWORD cookie)
Definition: msctf.cpp:286
EXTERN_C void free_sinks(struct list *sink_list)
Definition: msctf.cpp:297
DWORD TfClientId
Definition: msctf.idl:87
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
UINT WINAPI SysStringByteLen(BSTR str)
Definition: oleaut.c:215
BSTR WINAPI DECLSPEC_HOTPATCH SysAllocStringByteLen(LPCSTR str, UINT len)
Definition: oleaut.c:428
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define CONNECT_E_NOCONNECTION
Definition: olectl.h:251
long LONG
Definition: pedump.c:60
#define REFIID
Definition: guiddef.h:118
__WINE_SERVER_LIST_INLINE struct list * list_next(const struct list *list, const struct list *elem)
Definition: list.h:115
#define LIST_FOR_EACH(cursor, list)
Definition: list.h:188
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:192
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
Definition: scsiwmi.h:51
Definition: list.h:15
ITfCompartment * compartment
#define LIST_ENTRY(type)
Definition: queue.h:175
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:96
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:3771
#define E_UNEXPECTED
Definition: winerror.h:3528
#define E_POINTER
Definition: winerror.h:3480