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 "msctf_internal.h"
23 typedef struct tagCategoryMgr
{
24 ITfCategoryMgr ITfCategoryMgr_iface
;
28 static inline CategoryMgr
*impl_from_ITfCategoryMgr(ITfCategoryMgr
*iface
)
30 return CONTAINING_RECORD(iface
, CategoryMgr
, ITfCategoryMgr_iface
);
33 static void CategoryMgr_Destructor(CategoryMgr
*This
)
35 TRACE("destroying %p\n", This
);
36 HeapFree(GetProcessHeap(),0,This
);
39 static HRESULT WINAPI
CategoryMgr_QueryInterface(ITfCategoryMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
41 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
44 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfCategoryMgr
))
46 *ppvOut
= &This
->ITfCategoryMgr_iface
;
51 ITfCategoryMgr_AddRef(iface
);
55 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
59 static ULONG WINAPI
CategoryMgr_AddRef(ITfCategoryMgr
*iface
)
61 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
62 return InterlockedIncrement(&This
->refCount
);
65 static ULONG WINAPI
CategoryMgr_Release(ITfCategoryMgr
*iface
)
67 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
70 ret
= InterlockedDecrement(&This
->refCount
);
72 CategoryMgr_Destructor(This
);
76 /*****************************************************
77 * ITfCategoryMgr functions
78 *****************************************************/
80 static HRESULT WINAPI
CategoryMgr_RegisterCategory ( ITfCategoryMgr
*iface
,
81 REFCLSID rclsid
, REFGUID rcatid
, REFGUID rguid
)
87 HKEY tipkey
,catkey
,itmkey
;
88 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
90 static const WCHAR ctg
[] = {'C','a','t','e','g','o','r','y',0};
91 static const WCHAR itm
[] = {'I','t','e','m',0};
92 static const WCHAR fmt
[] = {'%','s','\\','%','s',0};
93 static const WCHAR fmt2
[] = {'%','s','\\','%','s','\\','%','s','\\','%','s',0};
95 TRACE("(%p) %s %s %s\n",This
,debugstr_guid(rclsid
), debugstr_guid(rcatid
), debugstr_guid(rguid
));
97 StringFromGUID2(rclsid
, buf
, 39);
98 sprintfW(fullkey
,fmt
,szwSystemTIPKey
,buf
);
100 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, KEY_READ
| KEY_WRITE
,
101 &tipkey
) != ERROR_SUCCESS
)
104 StringFromGUID2(rcatid
, buf
, 39);
105 StringFromGUID2(rguid
, buf2
, 39);
106 sprintfW(fullkey
,fmt2
,ctg
,ctg
,buf
,buf2
);
108 res
= RegCreateKeyExW(tipkey
, fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
109 NULL
, &catkey
, NULL
);
114 sprintfW(fullkey
,fmt2
,ctg
,itm
,buf2
,buf
);
115 res
= RegCreateKeyExW(tipkey
, fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
116 NULL
, &itmkey
, NULL
);
129 static HRESULT WINAPI
CategoryMgr_UnregisterCategory ( ITfCategoryMgr
*iface
,
130 REFCLSID rclsid
, REFGUID rcatid
, REFGUID rguid
)
136 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
138 static const WCHAR ctg
[] = {'C','a','t','e','g','o','r','y',0};
139 static const WCHAR itm
[] = {'I','t','e','m',0};
140 static const WCHAR fmt
[] = {'%','s','\\','%','s',0};
141 static const WCHAR fmt2
[] = {'%','s','\\','%','s','\\','%','s','\\','%','s',0};
143 TRACE("(%p) %s %s %s\n",This
,debugstr_guid(rclsid
), debugstr_guid(rcatid
), debugstr_guid(rguid
));
145 StringFromGUID2(rclsid
, buf
, 39);
146 sprintfW(fullkey
,fmt
,szwSystemTIPKey
,buf
);
148 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, KEY_READ
| KEY_WRITE
,
149 &tipkey
) != ERROR_SUCCESS
)
152 StringFromGUID2(rcatid
, buf
, 39);
153 StringFromGUID2(rguid
, buf2
, 39);
154 sprintfW(fullkey
,fmt2
,ctg
,ctg
,buf
,buf2
);
156 sprintfW(fullkey
,fmt2
,ctg
,itm
,buf2
,buf
);
157 RegDeleteTreeW(tipkey
, fullkey
);
158 sprintfW(fullkey
,fmt2
,ctg
,itm
,buf2
,buf
);
159 RegDeleteTreeW(tipkey
, fullkey
);
165 static HRESULT WINAPI
CategoryMgr_EnumCategoriesInItem ( ITfCategoryMgr
*iface
,
166 REFGUID rguid
, IEnumGUID
**ppEnum
)
168 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
169 FIXME("STUB:(%p)\n",This
);
173 static HRESULT WINAPI
CategoryMgr_EnumItemsInCategory ( ITfCategoryMgr
*iface
,
174 REFGUID rcatid
, IEnumGUID
**ppEnum
)
176 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
177 FIXME("STUB:(%p)\n",This
);
181 static HRESULT WINAPI
CategoryMgr_FindClosestCategory ( ITfCategoryMgr
*iface
,
182 REFGUID rguid
, GUID
*pcatid
, const GUID
**ppcatidList
, ULONG ulCount
)
184 static const WCHAR fmt
[] = { '%','s','\\','%','s','\\','C','a','t','e','g','o','r','y','\\','I','t','e','m','\\','%','s',0};
189 HRESULT hr
= S_FALSE
;
191 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
193 TRACE("(%p)\n",This
);
195 if (!pcatid
|| (ulCount
&& ppcatidList
== NULL
))
198 StringFromGUID2(rguid
, buf
, 39);
199 sprintfW(fullkey
,fmt
,szwSystemTIPKey
,buf
,buf
);
202 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, KEY_READ
, &key
) !=
215 res
= RegEnumKeyExW(key
, index
, catid
, &cName
, NULL
, NULL
, NULL
, NULL
);
216 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
219 hr2
= CLSIDFromString(catid
, &guid
);
220 if (FAILED(hr2
)) continue;
226 for (j
= 0; j
< ulCount
; j
++)
227 if (IsEqualGUID(&guid
, ppcatidList
[j
]))
247 static HRESULT WINAPI
CategoryMgr_RegisterGUIDDescription (
248 ITfCategoryMgr
*iface
, REFCLSID rclsid
, REFGUID rguid
,
249 const WCHAR
*pchDesc
, ULONG cch
)
251 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
252 FIXME("STUB:(%p)\n",This
);
256 static HRESULT WINAPI
CategoryMgr_UnregisterGUIDDescription (
257 ITfCategoryMgr
*iface
, REFCLSID rclsid
, REFGUID rguid
)
259 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
260 FIXME("STUB:(%p)\n",This
);
264 static HRESULT WINAPI
CategoryMgr_GetGUIDDescription ( ITfCategoryMgr
*iface
,
265 REFGUID rguid
, BSTR
*pbstrDesc
)
267 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
268 FIXME("STUB:(%p)\n",This
);
272 static HRESULT WINAPI
CategoryMgr_RegisterGUIDDWORD ( ITfCategoryMgr
*iface
,
273 REFCLSID rclsid
, REFGUID rguid
, DWORD dw
)
275 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
276 FIXME("STUB:(%p)\n",This
);
280 static HRESULT WINAPI
CategoryMgr_UnregisterGUIDDWORD ( ITfCategoryMgr
*iface
,
281 REFCLSID rclsid
, REFGUID rguid
)
283 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
284 FIXME("STUB:(%p)\n",This
);
288 static HRESULT WINAPI
CategoryMgr_GetGUIDDWORD ( ITfCategoryMgr
*iface
,
289 REFGUID rguid
, DWORD
*pdw
)
291 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
292 FIXME("STUB:(%p)\n",This
);
296 static HRESULT WINAPI
CategoryMgr_RegisterGUID ( ITfCategoryMgr
*iface
,
297 REFGUID rguid
, TfGuidAtom
*pguidatom
303 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
305 TRACE("(%p) %s %p\n",This
,debugstr_guid(rguid
),pguidatom
);
312 id
= enumerate_Cookie(COOKIE_MAGIC_GUIDATOM
,&index
);
313 if (id
&& IsEqualGUID(rguid
,get_Cookie_data(id
)))
320 checkguid
= HeapAlloc(GetProcessHeap(),0,sizeof(GUID
));
322 id
= generate_Cookie(COOKIE_MAGIC_GUIDATOM
,checkguid
);
326 HeapFree(GetProcessHeap(),0,checkguid
);
335 static HRESULT WINAPI
CategoryMgr_GetGUID ( ITfCategoryMgr
*iface
,
336 TfGuidAtom guidatom
, GUID
*pguid
)
338 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
340 TRACE("(%p) %i\n",This
,guidatom
);
347 if (get_Cookie_magic(guidatom
) == COOKIE_MAGIC_GUIDATOM
)
348 *pguid
= *((REFGUID
)get_Cookie_data(guidatom
));
353 static HRESULT WINAPI
CategoryMgr_IsEqualTfGuidAtom ( ITfCategoryMgr
*iface
,
354 TfGuidAtom guidatom
, REFGUID rguid
, BOOL
*pfEqual
)
356 CategoryMgr
*This
= impl_from_ITfCategoryMgr(iface
);
358 TRACE("(%p) %i %s %p\n",This
,guidatom
,debugstr_guid(rguid
),pfEqual
);
364 if (get_Cookie_magic(guidatom
) == COOKIE_MAGIC_GUIDATOM
)
366 if (IsEqualGUID(rguid
,get_Cookie_data(guidatom
)))
374 static const ITfCategoryMgrVtbl CategoryMgrVtbl
=
376 CategoryMgr_QueryInterface
,
379 CategoryMgr_RegisterCategory
,
380 CategoryMgr_UnregisterCategory
,
381 CategoryMgr_EnumCategoriesInItem
,
382 CategoryMgr_EnumItemsInCategory
,
383 CategoryMgr_FindClosestCategory
,
384 CategoryMgr_RegisterGUIDDescription
,
385 CategoryMgr_UnregisterGUIDDescription
,
386 CategoryMgr_GetGUIDDescription
,
387 CategoryMgr_RegisterGUIDDWORD
,
388 CategoryMgr_UnregisterGUIDDWORD
,
389 CategoryMgr_GetGUIDDWORD
,
390 CategoryMgr_RegisterGUID
,
392 CategoryMgr_IsEqualTfGuidAtom
395 HRESULT
CategoryMgr_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
399 return CLASS_E_NOAGGREGATION
;
401 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(CategoryMgr
));
403 return E_OUTOFMEMORY
;
405 This
->ITfCategoryMgr_iface
.lpVtbl
= &CategoryMgrVtbl
;
408 *ppOut
= (IUnknown
*)&This
->ITfCategoryMgr_iface
;
409 TRACE("returning %p\n", *ppOut
);