ReactOS 0.4.16-dev-1610-g4f61d2e
categorymgr.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: ITfCategoryMgr 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
17 : public ITfCategoryMgr
18{
19public:
21 virtual ~CCategoryMgr();
22
23 // ** IUnknown methods **
24 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override;
27
28 // ** ITfCategoryMgr methods **
30 _In_ REFCLSID rclsid,
31 _In_ REFGUID rcatid,
32 _In_ REFGUID rguid) override;
34 _In_ REFCLSID rclsid,
35 _In_ REFGUID rcatid,
36 _In_ REFGUID rguid) override;
38 _In_ REFGUID rguid,
39 _Out_ IEnumGUID **ppEnum) override;
41 _In_ REFGUID rcatid,
42 _Out_ IEnumGUID **ppEnum) override;
44 _In_ REFGUID rguid,
45 _Out_ GUID *pcatid,
46 _In_ const GUID **ppcatidList,
47 _In_ ULONG ulCount) override;
49 _In_ REFCLSID rclsid,
50 _In_ REFGUID rguid,
51 _In_ const WCHAR *pchDesc,
52 _In_ ULONG cch) override;
54 _In_ REFCLSID rclsid,
55 _In_ REFGUID rguid) override;
57 _In_ REFGUID rguid,
58 _Out_ BSTR *pbstrDesc) override;
60 _In_ REFCLSID rclsid,
61 _In_ REFGUID rguid,
62 _In_ DWORD dw) override;
64 _In_ REFCLSID rclsid,
65 _In_ REFGUID rguid) override;
67 _In_ REFGUID rguid,
68 _Out_ DWORD *pdw) override;
70 _In_ REFGUID rguid,
71 _Out_ TfGuidAtom *pguidatom) override;
73 _In_ TfGuidAtom guidatom,
74 _Out_ GUID *pguid) override;
76 _In_ TfGuidAtom guidatom,
77 _In_ REFGUID rguid,
78 _Out_ BOOL *pfEqual) override;
79
80protected:
82};
83
85
87 : m_cRefs(1)
88{
89}
90
92{
93 TRACE("destroying %p\n", this);
94}
95
97{
98 if (!ppvObj)
99 return E_INVALIDARG;
100
101 *ppvObj = NULL;
102
103 if (riid == IID_IUnknown || riid == IID_ITfCategoryMgr)
104 *ppvObj = this;
105
106 if (*ppvObj)
107 {
108 AddRef();
109 return S_OK;
110 }
111
112 WARN("unsupported interface: %s\n", debugstr_guid(&riid));
113 return E_NOINTERFACE;
114}
115
117{
118 return ::InterlockedIncrement(&m_cRefs);
119}
120
122{
124 if (!ret)
125 delete this;
126 return ret;
127}
128
130 _In_ REFCLSID rclsid,
131 _In_ REFGUID rcatid,
132 _In_ REFGUID rguid)
133{
134 WCHAR szFullKey[110], szClsid[39], szCatid[39], szGuid[39];
135 HKEY hTipKey = NULL, hCatKey = NULL, hItemKey = NULL;
137 HRESULT hr = E_FAIL;
138
139 TRACE("%p -> (%s, %s, %s)\n", this, debugstr_guid(&rclsid), debugstr_guid(&rcatid),
140 debugstr_guid(&rguid));
141
142 StringFromGUID2(rclsid, szClsid, _countof(szClsid));
143 StringFromGUID2(rcatid, szCatid, _countof(szCatid));
145
146 StringCchPrintfW(szFullKey, _countof(szFullKey), L"%s\\%s", szwSystemTIPKey, szClsid);
147 error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ | KEY_WRITE, &hTipKey);
148 if (error != ERROR_SUCCESS)
149 return E_FAIL;
150
151 StringCchPrintfW(szFullKey, _countof(szFullKey), L"Category\\Category\\%s\\%s", szCatid, szGuid);
152 error = RegCreateKeyExW(hTipKey, szFullKey, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL,
153 &hCatKey, NULL);
154 if (error == ERROR_SUCCESS)
155 {
156 RegCloseKey(hCatKey);
157
158 StringCchPrintfW(szFullKey, _countof(szFullKey), L"Category\\Item\\%s\\%s", szGuid, szCatid);
159 error = RegCreateKeyExW(hTipKey, szFullKey, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL,
160 &hItemKey, NULL);
161 if (error == ERROR_SUCCESS)
162 {
163 RegCloseKey(hItemKey);
164 hr = S_OK;
165 }
166 }
167
168 RegCloseKey(hTipKey);
169 return hr;
170}
171
173 _In_ REFCLSID rclsid,
174 _In_ REFGUID rcatid,
175 _In_ REFGUID rguid)
176{
177 WCHAR szFullKey[110], szClsid[39], szCatid[39], szGuid[39];
178 HKEY hTipKey = NULL;
180
181 TRACE("%p -> (%s %s %s)\n", this, debugstr_guid(&rclsid), debugstr_guid(&rcatid),
182 debugstr_guid(&rguid));
183
184 StringFromGUID2(rclsid, szClsid, _countof(szClsid));
185 StringFromGUID2(rcatid, szCatid, _countof(szCatid));
187
188 StringCchPrintfW(szFullKey, _countof(szFullKey), L"%s\\%s", szwSystemTIPKey, szClsid);
189 error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ | KEY_WRITE, &hTipKey);
190 if (error != ERROR_SUCCESS)
191 return E_FAIL;
192
193 StringCchPrintfW(szFullKey, _countof(szFullKey), L"Category\\Category\\%s\\%s", szCatid, szGuid);
194 RegDeleteTreeW(hTipKey, szFullKey);
195
196 StringCchPrintfW(szFullKey, _countof(szFullKey), L"Category\\Item\\%s\\%s", szGuid, szCatid);
197 RegDeleteTreeW(hTipKey, szFullKey);
198
199 RegCloseKey(hTipKey);
200 return S_OK;
201}
202
204 _In_ REFGUID rguid,
205 _Out_ IEnumGUID **ppEnum)
206{
207 FIXME("STUB:(%p)\n", this);
208 return E_NOTIMPL;
209}
210
212 _In_ REFGUID rcatid,
213 _Out_ IEnumGUID **ppEnum)
214{
215 FIXME("STUB:(%p)\n", this);
216 return E_NOTIMPL;
217}
218
220 _In_ REFGUID rguid,
221 _Out_ GUID *pcatid,
222 _In_ const GUID **ppcatidList,
223 _In_ ULONG ulCount)
224{
225 WCHAR szFullKey[120], szGuid[39];
226 HKEY hKey = NULL;
228 DWORD dwIndex = 0;
230
231 TRACE("(%p)\n", this);
232
233 if (!pcatid || (ulCount && !ppcatidList))
234 return E_INVALIDARG;
235
237 StringCchPrintfW(szFullKey, _countof(szFullKey), L"%s\\%s\\Category\\Item\\%s", szwSystemTIPKey, szGuid, szGuid);
238 *pcatid = GUID_NULL;
239
241 if (error != ERROR_SUCCESS)
242 return S_FALSE;
243
244 // Enumerate subkeys to find the closest category
245 while (TRUE)
246 {
247 WCHAR szCatidName[39];
248 DWORD cchCatidName = _countof(szCatidName);
249 GUID currentCatid;
250
251 error = RegEnumKeyExW(hKey, dwIndex, szCatidName, &cchCatidName, NULL, NULL, NULL, NULL);
253 break;
254
255 dwIndex++;
256
257 HRESULT hr2 = CLSIDFromString(szCatidName, &currentCatid);
258 if (FAILED(hr2))
259 continue; // Skip invalid GUID strings
260
261 if (ulCount <= 0)
262 {
263 *pcatid = currentCatid;
264 hr = S_OK; // Found a category
265 break;
266 }
267
268 // If a list of categories is provided, check if the current one is in the list
269 BOOL bFound = FALSE;
270 for (ULONG j = 0; j < ulCount; j++)
271 {
272 if (currentCatid == *ppcatidList[j])
273 {
274 bFound = TRUE;
275 *pcatid = currentCatid;
276 hr = S_OK; // Found a matching category
277 break;
278 }
279 }
280 if (bFound)
281 break; // Found and matched, so stop searching
282 }
283
285 return hr;
286}
287
289 _In_ REFCLSID rclsid,
290 _In_ REFGUID rguid,
291 _In_ const WCHAR *pchDesc,
292 _In_ ULONG cch)
293{
294 FIXME("STUB:(%p)\n", this);
295 return E_NOTIMPL;
296}
297
299 _In_ REFCLSID rclsid,
300 _In_ REFGUID rguid)
301{
302 FIXME("STUB:(%p)\n", this);
303 return E_NOTIMPL;
304}
305
307 _In_ REFGUID rguid,
308 _Out_ BSTR *pbstrDesc)
309{
310 FIXME("STUB:(%p)\n", this);
311 return E_NOTIMPL;
312}
313
315 _In_ REFCLSID rclsid,
316 _In_ REFGUID rguid,
317 _In_ DWORD dw)
318{
319 FIXME("STUB:(%p)\n", this);
320 return E_NOTIMPL;
321}
322
324 _In_ REFCLSID rclsid,
325 _In_ REFGUID rguid)
326{
327 FIXME("STUB:(%p)\n", this);
328 return E_NOTIMPL;
329}
330
332 _In_ REFGUID rguid,
333 _Out_ DWORD *pdw)
334{
335 FIXME("STUB:(%p)\n", this);
336 return E_NOTIMPL;
337}
338
340 _In_ REFGUID rguid,
341 _Out_ TfGuidAtom *pguidatom)
342{
343 TRACE("%p -> (%s, %p)\n", this, debugstr_guid(&rguid), pguidatom);
344
345 if (!pguidatom)
346 return E_INVALIDARG;
347
348 DWORD dwCookieId = 0, dwEnumIndex = 0;
349 do
350 {
351 dwCookieId = enumerate_Cookie(COOKIE_MAGIC_GUIDATOM, &dwEnumIndex);
352 if (dwCookieId && rguid == *(const GUID *)get_Cookie_data(dwCookieId))
353 {
354 *pguidatom = dwCookieId;
355 return S_OK;
356 }
357 } while (dwCookieId != 0);
358
359 GUID *pNewGuid = (GUID *)cicMemAlloc(sizeof(GUID));
360 if (!pNewGuid)
361 return E_OUTOFMEMORY;
362
363 *pNewGuid = rguid;
364
365 dwCookieId = generate_Cookie(COOKIE_MAGIC_GUIDATOM, pNewGuid);
366 if (dwCookieId == 0)
367 {
368 cicMemFree(pNewGuid);
369 return E_FAIL;
370 }
371
372 *pguidatom = dwCookieId;
373 return S_OK;
374}
375
377 _In_ TfGuidAtom guidatom,
378 _Out_ GUID *pguid)
379{
380 TRACE("%p -> (%d, %p)\n", this, guidatom, pguid);
381
382 if (!pguid)
383 return E_INVALIDARG;
384
385 *pguid = GUID_NULL;
386
388 *pguid = *(const GUID *)get_Cookie_data(guidatom);
389
390 return S_OK;
391}
392
394 _In_ TfGuidAtom guidatom,
395 _In_ REFGUID rguid,
396 _Out_ BOOL *pfEqual)
397{
398 TRACE("%p -> (%d %s %p)\n", this, guidatom, debugstr_guid(&rguid), pfEqual);
399
400 if (!pfEqual)
401 return E_INVALIDARG;
402
403 *pfEqual = FALSE;
405 {
406 if (rguid == *(const GUID *)get_Cookie_data(guidatom))
407 *pfEqual = TRUE;
408 }
409
410 return S_OK;
411}
412
414
417{
418 if (pUnkOuter)
420
422 if (!This)
423 return E_OUTOFMEMORY;
424
425 *ppOut = static_cast<ITfCategoryMgr *>(This);
426 TRACE("returning %p\n", *ppOut);
427 return S_OK;
428}
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define szwSystemTIPKey
Definition: precomp.h:105
#define COOKIE_MAGIC_GUIDATOM
Definition: precomp.h:35
#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
#define RegCloseKey(hKey)
Definition: registry.h:49
EXTERN_C HRESULT CategoryMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
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
STDMETHODIMP_(ULONG) Release() override
virtual ~CCategoryMgr()
Definition: categorymgr.cpp:91
STDMETHODIMP UnregisterGUIDDescription(_In_ REFCLSID rclsid, _In_ REFGUID rguid) override
STDMETHODIMP GetGUID(_In_ TfGuidAtom guidatom, _Out_ GUID *pguid) override
STDMETHODIMP EnumItemsInCategory(_In_ REFGUID rcatid, _Out_ IEnumGUID **ppEnum) override
STDMETHODIMP_(ULONG) AddRef() override
STDMETHODIMP GetGUIDDWORD(_In_ REFGUID rguid, _Out_ DWORD *pdw) override
STDMETHODIMP RegisterGUID(_In_ REFGUID rguid, _Out_ TfGuidAtom *pguidatom) override
STDMETHODIMP EnumCategoriesInItem(_In_ REFGUID rguid, _Out_ IEnumGUID **ppEnum) override
STDMETHODIMP RegisterGUIDDescription(_In_ REFCLSID rclsid, _In_ REFGUID rguid, _In_ const WCHAR *pchDesc, _In_ ULONG cch) override
STDMETHODIMP UnregisterGUIDDWORD(_In_ REFCLSID rclsid, _In_ REFGUID rguid) override
STDMETHODIMP IsEqualTfGuidAtom(_In_ TfGuidAtom guidatom, _In_ REFGUID rguid, _Out_ BOOL *pfEqual) override
STDMETHODIMP UnregisterCategory(_In_ REFCLSID rclsid, _In_ REFGUID rcatid, _In_ REFGUID rguid) override
STDMETHODIMP RegisterGUIDDWORD(_In_ REFCLSID rclsid, _In_ REFGUID rguid, _In_ DWORD dw) override
STDMETHODIMP FindClosestCategory(_In_ REFGUID rguid, _Out_ GUID *pcatid, _In_ const GUID **ppcatidList, _In_ ULONG ulCount) override
STDMETHODIMP RegisterCategory(_In_ REFCLSID rclsid, _In_ REFGUID rcatid, _In_ REFGUID rguid) override
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj) override
Definition: categorymgr.cpp:96
STDMETHODIMP GetGUIDDescription(_In_ REFGUID rguid, _Out_ BSTR *pbstrDesc) override
LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2504
OLECHAR * BSTR
Definition: compat.h:2293
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
ULONG AddRef()
ULONG Release()
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define GUID_NULL
Definition: ks.h:106
#define error(str)
Definition: mkdosfs.c:1605
static const WCHAR szGuid[]
Definition: rtlstr.c:1892
EXTERN_C DWORD get_Cookie_magic(DWORD id)
Definition: msctf.cpp:203
EXTERN_C LPVOID get_Cookie_data(DWORD id)
Definition: msctf.cpp:217
EXTERN_C DWORD enumerate_Cookie(DWORD magic, DWORD *index)
Definition: msctf.cpp:246
EXTERN_C DWORD generate_Cookie(DWORD magic, LPVOID data)
Definition: msctf.cpp:157
DWORD TfGuidAtom
Definition: msctf.idl:88
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define KEY_READ
Definition: nt_native.h:1023
#define KEY_WRITE
Definition: nt_native.h:1031
long LONG
Definition: pedump.c:60
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
HRESULT hr
Definition: shlfolder.c:183
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
Definition: scsiwmi.h:51
uint32_t ULONG
Definition: typedefs.h:59
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:3771
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
__wchar_t WCHAR
Definition: xmlstorage.h:180