crypt32: Constify some variables.
[wine] / dlls / msctf / compartmentmgr.c
1 /*
2  *  ITfCompartmentMgr implementation
3  *
4  *  Copyright 2009 Aric Stewart, CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24
25 #define COBJMACROS
26
27 #include "wine/debug.h"
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winreg.h"
31 #include "winuser.h"
32 #include "shlwapi.h"
33 #include "winerror.h"
34 #include "objbase.h"
35 #include "oleauto.h"
36
37 #include "wine/unicode.h"
38 #include "wine/list.h"
39
40 #include "msctf.h"
41 #include "msctf_internal.h"
42
43 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
44
45 typedef struct tagCompartmentValue {
46     struct list entry;
47     GUID guid;
48     TfClientId owner;
49     ITfCompartment *compartment;
50 } CompartmentValue;
51
52 typedef struct tagCompartmentMgr {
53     const ITfCompartmentMgrVtbl *CompartmentMgrVtbl;
54     LONG refCount;
55
56     IUnknown *pUnkOuter;
57
58     struct list values;
59 } CompartmentMgr;
60
61
62 HRESULT CompartmentMgr_Destructor(ITfCompartmentMgr *iface)
63 {
64     CompartmentMgr *This = (CompartmentMgr *)iface;
65     struct list *cursor, *cursor2;
66
67     LIST_FOR_EACH_SAFE(cursor, cursor2, &This->values)
68     {
69         CompartmentValue* value = LIST_ENTRY(cursor,CompartmentValue,entry);
70         list_remove(cursor);
71         ITfCompartment_Release(value->compartment);
72         HeapFree(GetProcessHeap(),0,value);
73     }
74
75     HeapFree(GetProcessHeap(),0,This);
76     return S_OK;
77 }
78
79 /*****************************************************
80  * ITfCompartmentMgr functions
81  *****************************************************/
82 static HRESULT WINAPI CompartmentMgr_QueryInterface(ITfCompartmentMgr *iface, REFIID iid, LPVOID *ppvOut)
83 {
84     CompartmentMgr *This = (CompartmentMgr *)iface;
85     if (This->pUnkOuter)
86         return IUnknown_QueryInterface(This->pUnkOuter, iid, *ppvOut);
87     else
88     {
89         *ppvOut = NULL;
90
91         if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCompartmentMgr))
92         {
93             *ppvOut = This;
94         }
95
96         if (*ppvOut)
97         {
98             IUnknown_AddRef(iface);
99             return S_OK;
100         }
101
102         WARN("unsupported interface: %s\n", debugstr_guid(iid));
103         return E_NOINTERFACE;
104     }
105 }
106
107 static ULONG WINAPI CompartmentMgr_AddRef(ITfCompartmentMgr *iface)
108 {
109     CompartmentMgr *This = (CompartmentMgr *)iface;
110     if (This->pUnkOuter)
111         return IUnknown_AddRef(This->pUnkOuter);
112     else
113         return InterlockedIncrement(&This->refCount);
114 }
115
116 static ULONG WINAPI CompartmentMgr_Release(ITfCompartmentMgr *iface)
117 {
118     CompartmentMgr *This = (CompartmentMgr *)iface;
119     if (This->pUnkOuter)
120         return IUnknown_Release(This->pUnkOuter);
121     else
122     {
123         ULONG ret;
124
125         ret = InterlockedDecrement(&This->refCount);
126         if (ret == 0)
127             CompartmentMgr_Destructor(iface);
128         return ret;
129     }
130 }
131
132 static HRESULT WINAPI CompartmentMgr_GetCompartment(ITfCompartmentMgr *iface,
133         REFGUID rguid, ITfCompartment **ppcomp)
134 {
135     CompartmentMgr *This = (CompartmentMgr *)iface;
136     FIXME("STUB:(%p)\n",This);
137     return E_NOTIMPL;
138 }
139
140 static HRESULT WINAPI CompartmentMgr_ClearCompartment(ITfCompartmentMgr *iface,
141     TfClientId tid, REFGUID rguid)
142 {
143     CompartmentMgr *This = (CompartmentMgr *)iface;
144     FIXME("STUB:(%p)\n",This);
145     return E_NOTIMPL;
146 }
147
148 static HRESULT WINAPI CompartmentMgr_EnumCompartments(ITfCompartmentMgr *iface,
149  IEnumGUID **ppEnum)
150 {
151     CompartmentMgr *This = (CompartmentMgr *)iface;
152     FIXME("STUB:(%p)\n",This);
153     return E_NOTIMPL;
154 }
155
156 static const ITfCompartmentMgrVtbl CompartmentMgr_CompartmentMgrVtbl =
157 {
158     CompartmentMgr_QueryInterface,
159     CompartmentMgr_AddRef,
160     CompartmentMgr_Release,
161
162     CompartmentMgr_GetCompartment,
163     CompartmentMgr_ClearCompartment,
164     CompartmentMgr_EnumCompartments
165 };
166
167 HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut)
168 {
169     CompartmentMgr *This;
170
171     if (!ppOut)
172         return E_POINTER;
173
174     if (pUnkOuter && !IsEqualIID (riid, &IID_IUnknown))
175         return CLASS_E_NOAGGREGATION;
176
177     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CompartmentMgr));
178     if (This == NULL)
179         return E_OUTOFMEMORY;
180
181     This->CompartmentMgrVtbl = &CompartmentMgr_CompartmentMgrVtbl;
182     This->pUnkOuter = pUnkOuter;
183     list_init(&This->values);
184
185     if (pUnkOuter)
186     {
187         TRACE("returning %p\n", This);
188         *ppOut = (IUnknown*)This;
189         return S_OK;
190     }
191     else
192     {
193         HRESULT hr;
194         hr = IUnknown_QueryInterface((IUnknown*)This, riid, (LPVOID*)ppOut);
195         if (FAILED(hr))
196             HeapFree(GetProcessHeap(),0,This);
197         return hr;
198     }
199 }