push dc472f8b5d4912d0c9cefe8cf7a47359e2a1e450
[wine/hacks.git] / dlls / msctf / categorymgr.c
blob648352af85a7d694f6cea59c1ea8220cbf69cdc0
1 /*
2 * ITfCategoryMgr implementation
4 * Copyright 2009 Aric Stewart, CodeWeavers
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.
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.
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
21 #include "config.h"
23 #include <stdarg.h>
25 #define COBJMACROS
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"
36 #include "wine/unicode.h"
38 #include "msctf.h"
39 #include "msctf_internal.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
43 typedef struct tagCategoryMgr {
44 const ITfCategoryMgrVtbl *CategoryMgrVtbl;
45 LONG refCount;
46 } CategoryMgr;
48 static void CategoryMgr_Destructor(CategoryMgr *This)
50 TRACE("destroying %p\n", This);
51 HeapFree(GetProcessHeap(),0,This);
54 static HRESULT WINAPI CategoryMgr_QueryInterface(ITfCategoryMgr *iface, REFIID iid, LPVOID *ppvOut)
56 CategoryMgr *This = (CategoryMgr *)iface;
57 *ppvOut = NULL;
59 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCategoryMgr))
61 *ppvOut = This;
64 if (*ppvOut)
66 IUnknown_AddRef(iface);
67 return S_OK;
70 WARN("unsupported interface: %s\n", debugstr_guid(iid));
71 return E_NOINTERFACE;
74 static ULONG WINAPI CategoryMgr_AddRef(ITfCategoryMgr *iface)
76 CategoryMgr *This = (CategoryMgr *)iface;
77 return InterlockedIncrement(&This->refCount);
80 static ULONG WINAPI CategoryMgr_Release(ITfCategoryMgr *iface)
82 CategoryMgr *This = (CategoryMgr *)iface;
83 ULONG ret;
85 ret = InterlockedDecrement(&This->refCount);
86 if (ret == 0)
87 CategoryMgr_Destructor(This);
88 return ret;
91 /*****************************************************
92 * ITfCategoryMgr functions
93 *****************************************************/
95 static HRESULT WINAPI CategoryMgr_RegisterCategory ( ITfCategoryMgr *iface,
96 REFCLSID rclsid, REFGUID rcatid, REFGUID rguid)
98 WCHAR fullkey[110];
99 WCHAR buf[39];
100 WCHAR buf2[39];
101 ULONG res;
102 HKEY tipkey,catkey,itmkey;
103 CategoryMgr *This = (CategoryMgr*)iface;
105 static const WCHAR ctg[] = {'C','a','t','e','g','o','r','y',0};
106 static const WCHAR itm[] = {'I','t','e','m',0};
107 static const WCHAR fmt[] = {'%','s','\\','%','s',0};
108 static const WCHAR fmt2[] = {'%','s','\\','%','s','\\','%','s','\\','%','s',0};
110 TRACE("(%p) %s %s %s\n",This,debugstr_guid(rclsid), debugstr_guid(rcatid), debugstr_guid(rguid));
112 StringFromGUID2(rclsid, buf, 39);
113 sprintfW(fullkey,fmt,szwSystemTIPKey,buf);
115 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ | KEY_WRITE,
116 &tipkey ) != ERROR_SUCCESS)
117 return E_FAIL;
119 StringFromGUID2(rcatid, buf, 39);
120 StringFromGUID2(rguid, buf2, 39);
121 sprintfW(fullkey,fmt2,ctg,ctg,buf,buf2);
123 res = RegCreateKeyExW(tipkey, fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
124 NULL, &catkey, NULL);
125 RegCloseKey(catkey);
127 if (!res)
129 sprintfW(fullkey,fmt2,ctg,itm,buf2,buf);
130 res = RegCreateKeyExW(tipkey, fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
131 NULL, &itmkey, NULL);
133 RegCloseKey(itmkey);
136 RegCloseKey(tipkey);
138 if (!res)
139 return S_OK;
140 else
141 return E_FAIL;
144 static HRESULT WINAPI CategoryMgr_UnregisterCategory ( ITfCategoryMgr *iface,
145 REFCLSID rclsid, REFGUID rcatid, REFGUID rguid)
147 CategoryMgr *This = (CategoryMgr*)iface;
148 FIXME("STUB:(%p)\n",This);
149 return E_NOTIMPL;
152 static HRESULT WINAPI CategoryMgr_EnumCategoriesInItem ( ITfCategoryMgr *iface,
153 REFGUID rguid, IEnumGUID **ppEnum)
155 CategoryMgr *This = (CategoryMgr*)iface;
156 FIXME("STUB:(%p)\n",This);
157 return E_NOTIMPL;
160 static HRESULT WINAPI CategoryMgr_EnumItemsInCategory ( ITfCategoryMgr *iface,
161 REFGUID rcatid, IEnumGUID **ppEnum)
163 CategoryMgr *This = (CategoryMgr*)iface;
164 FIXME("STUB:(%p)\n",This);
165 return E_NOTIMPL;
168 static HRESULT WINAPI CategoryMgr_FindClosestCategory ( ITfCategoryMgr *iface,
169 REFGUID rguid, GUID *pcatid, const GUID **ppcatidList, ULONG ulCount)
171 static const WCHAR fmt[] = { '%','s','\\','%','s','\\','C','a','t','e','g','o','r','y','\\','I','t','e','m','\\','%','s',0};
173 WCHAR fullkey[110];
174 WCHAR buf[39];
175 HKEY key;
176 HRESULT hr = S_FALSE;
177 INT index = 0;
178 CategoryMgr *This = (CategoryMgr*)iface;
180 TRACE("(%p)\n",This);
182 if (!pcatid || (ulCount && ppcatidList == NULL))
183 return E_INVALIDARG;
185 StringFromGUID2(rguid, buf, 39);
186 sprintfW(fullkey,fmt,szwSystemTIPKey,buf,buf);
187 *pcatid = GUID_NULL;
189 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ, &key ) !=
190 ERROR_SUCCESS)
191 return S_FALSE;
193 while (1)
195 HRESULT hr2;
196 ULONG res;
197 GUID guid;
198 WCHAR catid[39];
199 DWORD cName;
201 cName = 39;
202 res = RegEnumKeyExW(key, index, catid, &cName, NULL, NULL, NULL, NULL);
203 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
204 index ++;
206 hr2 = CLSIDFromString(catid, &guid);
207 if (FAILED(hr2)) continue;
209 if (ulCount)
211 int j;
212 BOOL found = FALSE;
213 for (j = 0; j < ulCount; j++)
214 if (IsEqualGUID(&guid, ppcatidList[j]))
216 found = TRUE;
217 *pcatid = guid;
218 hr = S_OK;
219 break;
221 if (found) break;
223 else
225 *pcatid = guid;
226 hr = S_OK;
227 break;
231 return hr;
234 static HRESULT WINAPI CategoryMgr_RegisterGUIDDescription (
235 ITfCategoryMgr *iface, REFCLSID rclsid, REFGUID rguid,
236 const WCHAR *pchDesc, ULONG cch)
238 CategoryMgr *This = (CategoryMgr*)iface;
239 FIXME("STUB:(%p)\n",This);
240 return E_NOTIMPL;
243 static HRESULT WINAPI CategoryMgr_UnregisterGUIDDescription (
244 ITfCategoryMgr *iface, REFCLSID rclsid, REFGUID rguid)
246 CategoryMgr *This = (CategoryMgr*)iface;
247 FIXME("STUB:(%p)\n",This);
248 return E_NOTIMPL;
251 static HRESULT WINAPI CategoryMgr_GetGUIDDescription ( ITfCategoryMgr *iface,
252 REFGUID rguid, BSTR *pbstrDesc)
254 CategoryMgr *This = (CategoryMgr*)iface;
255 FIXME("STUB:(%p)\n",This);
256 return E_NOTIMPL;
259 static HRESULT WINAPI CategoryMgr_RegisterGUIDDWORD ( ITfCategoryMgr *iface,
260 REFCLSID rclsid, REFGUID rguid, DWORD dw)
262 CategoryMgr *This = (CategoryMgr*)iface;
263 FIXME("STUB:(%p)\n",This);
264 return E_NOTIMPL;
267 static HRESULT WINAPI CategoryMgr_UnregisterGUIDDWORD ( ITfCategoryMgr *iface,
268 REFCLSID rclsid, REFGUID rguid)
270 CategoryMgr *This = (CategoryMgr*)iface;
271 FIXME("STUB:(%p)\n",This);
272 return E_NOTIMPL;
275 static HRESULT WINAPI CategoryMgr_GetGUIDDWORD ( ITfCategoryMgr *iface,
276 REFGUID rguid, DWORD *pdw)
278 CategoryMgr *This = (CategoryMgr*)iface;
279 FIXME("STUB:(%p)\n",This);
280 return E_NOTIMPL;
283 static HRESULT WINAPI CategoryMgr_RegisterGUID ( ITfCategoryMgr *iface,
284 REFGUID rguid, TfGuidAtom *pguidatom
287 CategoryMgr *This = (CategoryMgr*)iface;
288 FIXME("STUB:(%p)\n",This);
289 return E_NOTIMPL;
292 static HRESULT WINAPI CategoryMgr_GetGUID ( ITfCategoryMgr *iface,
293 TfGuidAtom guidatom, GUID *pguid)
295 CategoryMgr *This = (CategoryMgr*)iface;
296 FIXME("STUB:(%p)\n",This);
297 return E_NOTIMPL;
300 static HRESULT WINAPI CategoryMgr_IsEqualTfGuidAtom ( ITfCategoryMgr *iface,
301 TfGuidAtom guidatom, REFGUID rguid, BOOL *pfEqual)
303 CategoryMgr *This = (CategoryMgr*)iface;
304 FIXME("STUB:(%p)\n",This);
305 return E_NOTIMPL;
309 static const ITfCategoryMgrVtbl CategoryMgr_CategoryMgrVtbl =
311 CategoryMgr_QueryInterface,
312 CategoryMgr_AddRef,
313 CategoryMgr_Release,
315 CategoryMgr_RegisterCategory,
316 CategoryMgr_UnregisterCategory,
317 CategoryMgr_EnumCategoriesInItem,
318 CategoryMgr_EnumItemsInCategory,
319 CategoryMgr_FindClosestCategory,
320 CategoryMgr_RegisterGUIDDescription,
321 CategoryMgr_UnregisterGUIDDescription,
322 CategoryMgr_GetGUIDDescription,
323 CategoryMgr_RegisterGUIDDWORD,
324 CategoryMgr_UnregisterGUIDDWORD,
325 CategoryMgr_GetGUIDDWORD,
326 CategoryMgr_RegisterGUID,
327 CategoryMgr_GetGUID,
328 CategoryMgr_IsEqualTfGuidAtom
331 HRESULT CategoryMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
333 CategoryMgr *This;
334 if (pUnkOuter)
335 return CLASS_E_NOAGGREGATION;
337 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CategoryMgr));
338 if (This == NULL)
339 return E_OUTOFMEMORY;
341 This->CategoryMgrVtbl= &CategoryMgr_CategoryMgrVtbl;
342 This->refCount = 1;
344 TRACE("returning %p\n", This);
345 *ppOut = (IUnknown *)This;
346 return S_OK;