ReactOS 0.4.15-dev-7998-gdb93cb1
comcat.c
Go to the documentation of this file.
1/*
2 * Comcat implementation
3 *
4 * Copyright (C) 2002 John K. Hohm
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 <string.h>
22#include <stdarg.h>
23
24#define COBJMACROS
25
26#include "windef.h"
27#include "winbase.h"
28#include "winuser.h"
29#include "winreg.h"
30#include "winerror.h"
31
32#include "ole2.h"
33#include "comcat.h"
34#include "compobj_private.h"
35
36#include "wine/debug.h"
37
39
40static const ICatRegisterVtbl COMCAT_ICatRegister_Vtbl;
41static const ICatInformationVtbl COMCAT_ICatInformation_Vtbl;
42
43typedef struct
44{
48
49/* static ComCatMgr instance */
51{
54};
55
57{
58 ULONG size; /* total length, including structure itself */
61};
62
66
67/**********************************************************************
68 * File-scope string constants
69 */
70static const WCHAR comcat_keyname[] = {
71 'C','o','m','p','o','n','e','n','t',' ','C','a','t','e','g','o','r','i','e','s',0 };
72static const WCHAR impl_keyname[] = {
73 'I','m','p','l','e','m','e','n','t','e','d',' ','C','a','t','e','g','o','r','i','e','s',0 };
74static const WCHAR req_keyname[] = {
75 'R','e','q','u','i','r','e','d',' ','C','a','t','e','g','o','r','i','e','s',0 };
76static const WCHAR clsid_keyname[] = { 'C','L','S','I','D',0 };
77
78
79/**********************************************************************
80 * COMCAT_RegisterClassCategories
81 */
83 REFCLSID rclsid,
85 ULONG cCategories,
86 const CATID *rgcatid)
87{
88 WCHAR keyname[CHARS_IN_GUID];
90 HKEY clsid_key, class_key, type_key;
91
92 if (cCategories && rgcatid == NULL) return E_POINTER;
93
94 /* Format the class key name. */
95 res = StringFromGUID2(rclsid, keyname, CHARS_IN_GUID);
96 if (FAILED(res)) return res;
97
98 /* Create (or open) the CLSID key. */
100 if (res != ERROR_SUCCESS) return E_FAIL;
101
102 /* Create (or open) the class key. */
103 res = create_classes_key(clsid_key, keyname, KEY_READ|KEY_WRITE, &class_key);
104 if (res == ERROR_SUCCESS) {
105 /* Create (or open) the category type key. */
106 res = create_classes_key(class_key, type, KEY_READ|KEY_WRITE, &type_key);
107 if (res == ERROR_SUCCESS) {
108 for (; cCategories; --cCategories, ++rgcatid) {
109 HKEY key;
110
111 /* Format the category key name. */
112 res = StringFromGUID2(rgcatid, keyname, CHARS_IN_GUID);
113 if (FAILED(res)) continue;
114
115 /* Do the register. */
116 res = create_classes_key(type_key, keyname, KEY_READ|KEY_WRITE, &key);
118 }
119 res = S_OK;
120 } else res = E_FAIL;
121 RegCloseKey(class_key);
122 } else res = E_FAIL;
123 RegCloseKey(clsid_key);
124
125 return res;
126}
127
128/**********************************************************************
129 * COMCAT_UnRegisterClassCategories
130 */
132 REFCLSID rclsid,
134 ULONG cCategories,
135 const CATID *rgcatid)
136{
137 WCHAR keyname[68] = { 'C', 'L', 'S', 'I', 'D', '\\' };
138 HRESULT res;
139 HKEY type_key;
140
141 if (cCategories && rgcatid == NULL) return E_POINTER;
142
143 /* Format the class category type key name. */
144 res = StringFromGUID2(rclsid, keyname + 6, CHARS_IN_GUID);
145 if (FAILED(res)) return res;
146 keyname[44] = '\\';
147 lstrcpyW(keyname + 45, type);
148
149 /* Open the class category type key. */
151 if (res != ERROR_SUCCESS) return E_FAIL;
152
153 for (; cCategories; --cCategories, ++rgcatid) {
154 /* Format the category key name. */
155 res = StringFromGUID2(rgcatid, keyname, CHARS_IN_GUID);
156 if (FAILED(res)) continue;
157
158 /* Do the unregister. */
159 RegDeleteKeyW(type_key, keyname);
160 }
161 RegCloseKey(type_key);
162
163 return S_OK;
164}
165
166/**********************************************************************
167 * COMCAT_GetCategoryDesc
168 */
170 ULONG buf_wchars)
171{
172 static const WCHAR fmt[] = { '%', 'l', 'X', 0 };
173 WCHAR valname[5];
174 HRESULT res;
175 DWORD type, size = (buf_wchars - 1) * sizeof(WCHAR);
176
177 if (pszDesc == NULL) return E_INVALIDARG;
178
179 /* FIXME: lcid comparisons are more complex than this! */
180 wsprintfW(valname, fmt, lcid);
181 res = RegQueryValueExW(key, valname, 0, &type, (LPBYTE)pszDesc, &size);
182 if (res != ERROR_SUCCESS || type != REG_SZ) {
183 FIXME("Simplified lcid comparison\n");
184 return CAT_E_NODESCRIPTION;
185 }
186 pszDesc[size / sizeof(WCHAR)] = 0;
187
188 return S_OK;
189}
190
191/**********************************************************************
192 * COMCAT_PrepareClassCategories
193 */
195 ULONG impl_count, const CATID *impl_catids, ULONG req_count, const CATID *req_catids)
196{
198 WCHAR *strings;
199 ULONG size;
200
201 size = sizeof(struct class_categories) + ((impl_count + req_count)*CHARS_IN_GUID + 2)*sizeof(WCHAR);
203 if (categories == NULL) return categories;
204
205 categories->size = size;
206 categories->impl_offset = sizeof(struct class_categories);
207 categories->req_offset = categories->impl_offset + (impl_count*CHARS_IN_GUID + 1)*sizeof(WCHAR);
208
209 strings = (WCHAR *)(categories + 1);
210 while (impl_count--) {
211 StringFromGUID2(impl_catids++, strings, CHARS_IN_GUID);
213 }
214 *strings++ = 0;
215
216 while (req_count--) {
217 StringFromGUID2(req_catids++, strings, CHARS_IN_GUID);
219 }
220 *strings++ = 0;
221
222 return categories;
223}
224
225/**********************************************************************
226 * COMCAT_IsClassOfCategories
227 */
229 HKEY key,
230 struct class_categories const* categories)
231{
232 const WCHAR *impl_strings, *req_strings;
233 HKEY subkey;
234 HRESULT res;
235 DWORD index;
237
238 impl_strings = (WCHAR*)((BYTE*)categories + categories->impl_offset);
239 req_strings = (WCHAR*)((BYTE*)categories + categories->req_offset);
240
241 /* Check that every given category is implemented by class. */
242 if (*impl_strings) {
244 if (res != ERROR_SUCCESS) return S_FALSE;
245 for (string = impl_strings; *string; string += CHARS_IN_GUID) {
246 HKEY catkey;
247 res = open_classes_key(subkey, string, READ_CONTROL, &catkey);
248 if (res != ERROR_SUCCESS) {
249 RegCloseKey(subkey);
250 return S_FALSE;
251 }
252 RegCloseKey(catkey);
253 }
254 RegCloseKey(subkey);
255 }
256
257 /* Check that all categories required by class are given. */
259 if (res == ERROR_SUCCESS) {
260 for (index = 0; ; ++index) {
261 WCHAR keyname[CHARS_IN_GUID];
263
264 res = RegEnumKeyExW(subkey, index, keyname, &size,
265 NULL, NULL, NULL, NULL);
266 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
267 if (size != CHARS_IN_GUID-1) continue; /* bogus catid in registry */
268 for (string = req_strings; *string; string += CHARS_IN_GUID)
269 if (!wcsicmp(string, keyname)) break;
270 if (!*string) {
271 RegCloseKey(subkey);
272 return S_FALSE;
273 }
274 }
275 RegCloseKey(subkey);
276 }
277
278 return S_OK;
279}
280
281/**********************************************************************
282 * COMCAT_ICatRegister_QueryInterface
283 */
285 LPCATREGISTER iface,
286 REFIID riid,
287 LPVOID *ppvObj)
288{
289 TRACE("%s\n",debugstr_guid(riid));
290
291 if (ppvObj == NULL) return E_POINTER;
292
293 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ICatRegister)) {
294 *ppvObj = iface;
295 ICatRegister_AddRef(iface);
296 return S_OK;
297 }
298
299 if (IsEqualGUID(riid, &IID_ICatInformation)) {
301 ICatRegister_AddRef(iface);
302 return S_OK;
303 }
304
305 return E_NOINTERFACE;
306}
307
308/**********************************************************************
309 * COMCAT_ICatRegister_AddRef
310 */
311static ULONG WINAPI COMCAT_ICatRegister_AddRef(LPCATREGISTER iface)
312{
313 return 2; /* non-heap based object */
314}
315
316/**********************************************************************
317 * COMCAT_ICatRegister_Release
318 */
319static ULONG WINAPI COMCAT_ICatRegister_Release(LPCATREGISTER iface)
320{
321 return 1; /* non-heap based object */
322}
323
324/**********************************************************************
325 * COMCAT_ICatRegister_RegisterCategories
326 */
328 LPCATREGISTER iface,
329 ULONG cCategories,
330 CATEGORYINFO *rgci)
331{
332 HKEY comcat_key;
333 HRESULT res;
334
335 TRACE("\n");
336
337 if (cCategories && rgci == NULL)
338 return E_POINTER;
339
340 /* Create (or open) the component categories key. */
342 if (res != ERROR_SUCCESS) return E_FAIL;
343
344 for (; cCategories; --cCategories, ++rgci) {
345 static const WCHAR fmt[] = { '%', 'l', 'X', 0 };
346 WCHAR keyname[CHARS_IN_GUID];
347 WCHAR valname[9];
348 HKEY cat_key;
349
350 /* Create (or open) the key for this category. */
351 if (!StringFromGUID2(&rgci->catid, keyname, CHARS_IN_GUID)) continue;
352 res = create_classes_key(comcat_key, keyname, KEY_READ|KEY_WRITE, &cat_key);
353 if (res != ERROR_SUCCESS) continue;
354
355 /* Set the value for this locale's description. */
356 wsprintfW(valname, fmt, rgci->lcid);
357 RegSetValueExW(cat_key, valname, 0, REG_SZ, (const BYTE*)rgci->szDescription,
358 (lstrlenW(rgci->szDescription) + 1) * sizeof(WCHAR));
359
360 RegCloseKey(cat_key);
361 }
362
363 RegCloseKey(comcat_key);
364 return S_OK;
365}
366
367/**********************************************************************
368 * COMCAT_ICatRegister_UnRegisterCategories
369 */
371 LPCATREGISTER iface,
372 ULONG cCategories,
373 CATID *rgcatid)
374{
375 HKEY comcat_key;
376 HRESULT res;
377
378 TRACE("\n");
379
380 if (cCategories && rgcatid == NULL)
381 return E_POINTER;
382
383 /* Open the component categories key. */
385 if (res != ERROR_SUCCESS) return E_FAIL;
386
387 for (; cCategories; --cCategories, ++rgcatid) {
388 WCHAR keyname[CHARS_IN_GUID];
389
390 /* Delete the key for this category. */
391 if (!StringFromGUID2(rgcatid, keyname, CHARS_IN_GUID)) continue;
392 RegDeleteKeyW(comcat_key, keyname);
393 }
394
395 RegCloseKey(comcat_key);
396 return S_OK;
397}
398
399/**********************************************************************
400 * COMCAT_ICatRegister_RegisterClassImplCategories
401 */
403 LPCATREGISTER iface,
404 REFCLSID rclsid,
405 ULONG cCategories,
406 CATID *rgcatid)
407{
408 TRACE("\n");
409
411 rclsid, impl_keyname, cCategories, rgcatid);
412}
413
414/**********************************************************************
415 * COMCAT_ICatRegister_UnRegisterClassImplCategories
416 */
418 LPCATREGISTER iface,
419 REFCLSID rclsid,
420 ULONG cCategories,
421 CATID *rgcatid)
422{
423 TRACE("\n");
424
426 rclsid, impl_keyname, cCategories, rgcatid);
427}
428
429/**********************************************************************
430 * COMCAT_ICatRegister_RegisterClassReqCategories
431 */
433 LPCATREGISTER iface,
434 REFCLSID rclsid,
435 ULONG cCategories,
436 CATID *rgcatid)
437{
438 TRACE("\n");
439
441 rclsid, req_keyname, cCategories, rgcatid);
442}
443
444/**********************************************************************
445 * COMCAT_ICatRegister_UnRegisterClassReqCategories
446 */
448 LPCATREGISTER iface,
449 REFCLSID rclsid,
450 ULONG cCategories,
451 CATID *rgcatid)
452{
453 TRACE("\n");
454
456 rclsid, req_keyname, cCategories, rgcatid);
457}
458
459/**********************************************************************
460 * COMCAT_ICatInformation_QueryInterface
461 */
463 LPCATINFORMATION iface,
464 REFIID riid,
465 LPVOID *ppvObj)
466{
467 return ICatRegister_QueryInterface(&COMCAT_ComCatMgr.ICatRegister_iface, riid, ppvObj);
468}
469
470/**********************************************************************
471 * COMCAT_ICatInformation_AddRef
472 */
473static ULONG WINAPI COMCAT_ICatInformation_AddRef(LPCATINFORMATION iface)
474{
475 return ICatRegister_AddRef(&COMCAT_ComCatMgr.ICatRegister_iface);
476}
477
478/**********************************************************************
479 * COMCAT_ICatInformation_Release
480 */
481static ULONG WINAPI COMCAT_ICatInformation_Release(LPCATINFORMATION iface)
482{
483 return ICatRegister_Release(&COMCAT_ComCatMgr.ICatRegister_iface);
484}
485
486/**********************************************************************
487 * COMCAT_ICatInformation_EnumCategories
488 */
490 LPCATINFORMATION iface,
491 LCID lcid,
492 IEnumCATEGORYINFO **ppenumCatInfo)
493{
494 TRACE("\n");
495
496 if (ppenumCatInfo == NULL) return E_POINTER;
497
498 return EnumCATEGORYINFO_Construct(lcid, ppenumCatInfo);
499}
500
501/**********************************************************************
502 * COMCAT_ICatInformation_GetCategoryDesc
503 */
505 LPCATINFORMATION iface,
506 REFCATID rcatid,
507 LCID lcid,
508 PWCHAR *ppszDesc)
509{
510 WCHAR keyname[60] = { 'C', 'o', 'm', 'p', 'o', 'n', 'e', 'n',
511 't', ' ', 'C', 'a', 't', 'e', 'g', 'o',
512 'r', 'i', 'e', 's', '\\', 0 };
513 HKEY key;
514 HRESULT res;
515
516 TRACE("CATID: %s LCID: %x\n",debugstr_guid(rcatid), lcid);
517
518 if (rcatid == NULL || ppszDesc == NULL) return E_INVALIDARG;
519
520 /* Open the key for this category. */
521 if (!StringFromGUID2(rcatid, keyname + 21, CHARS_IN_GUID)) return E_FAIL;
523 if (res != ERROR_SUCCESS) return CAT_E_CATIDNOEXIST;
524
525 /* Allocate a sensible amount of memory for the description. */
526 *ppszDesc = CoTaskMemAlloc(128 * sizeof(WCHAR));
527 if (*ppszDesc == NULL) {
529 return E_OUTOFMEMORY;
530 }
531
532 /* Get the description, and make sure it's null terminated. */
533 res = COMCAT_GetCategoryDesc(key, lcid, *ppszDesc, 128);
535 if (FAILED(res)) {
536 CoTaskMemFree(*ppszDesc);
537 return res;
538 }
539
540 return S_OK;
541}
542
543/**********************************************************************
544 * COMCAT_ICatInformation_EnumClassesOfCategories
545 */
547 LPCATINFORMATION iface,
548 ULONG cImplemented,
549 CATID *rgcatidImpl,
550 ULONG cRequired,
551 CATID *rgcatidReq,
552 LPENUMCLSID *ppenumCLSID)
553{
555 HRESULT hr;
556
557 TRACE("\n");
558
559 if (cImplemented == (ULONG)-1)
560 cImplemented = 0;
561 if (cRequired == (ULONG)-1)
562 cRequired = 0;
563
564 if (ppenumCLSID == NULL ||
565 (cImplemented && rgcatidImpl == NULL) ||
566 (cRequired && rgcatidReq == NULL)) return E_POINTER;
567
568 categories = COMCAT_PrepareClassCategories(cImplemented, rgcatidImpl,
569 cRequired, rgcatidReq);
570 if (categories == NULL) return E_OUTOFMEMORY;
571
572 hr = CLSIDEnumGUID_Construct(categories, ppenumCLSID);
573 if (FAILED(hr))
574 {
576 return hr;
577 }
578
579 return hr;
580}
581
582/**********************************************************************
583 * COMCAT_ICatInformation_IsClassOfCategories
584 */
586 LPCATINFORMATION iface,
587 REFCLSID rclsid,
588 ULONG cImplemented,
589 CATID *rgcatidImpl,
590 ULONG cRequired,
591 CATID *rgcatidReq)
592{
593 WCHAR keyname[45] = { 'C', 'L', 'S', 'I', 'D', '\\', 0 };
594 HRESULT res;
596 HKEY key;
597
598 if (TRACE_ON(ole)) {
599 ULONG count;
600 TRACE("CLSID: %s Implemented %u\n",debugstr_guid(rclsid),cImplemented);
601 for (count = 0; count < cImplemented; ++count)
602 TRACE(" %s\n",debugstr_guid(&rgcatidImpl[count]));
603 TRACE("Required %u\n",cRequired);
604 for (count = 0; count < cRequired; ++count)
605 TRACE(" %s\n",debugstr_guid(&rgcatidReq[count]));
606 }
607
608 if ((cImplemented && rgcatidImpl == NULL) ||
609 (cRequired && rgcatidReq == NULL)) return E_POINTER;
610
611 res = StringFromGUID2(rclsid, keyname + 6, CHARS_IN_GUID);
612 if (FAILED(res)) return res;
613
614 categories = COMCAT_PrepareClassCategories(cImplemented, rgcatidImpl,
615 cRequired, rgcatidReq);
616 if (categories == NULL) return E_OUTOFMEMORY;
617
619 if (res == ERROR_SUCCESS) {
622 } else res = S_FALSE;
623
625
626 return res;
627}
628
629/**********************************************************************
630 * COMCAT_ICatInformation_EnumImplCategoriesOfClass
631 */
633 LPCATINFORMATION iface,
634 REFCLSID rclsid,
635 LPENUMCATID *ppenumCATID)
636{
637 static const WCHAR postfix[] = { '\\', 'I', 'm', 'p', 'l', 'e', 'm', 'e',
638 'n', 't', 'e', 'd', ' ', 'C', 'a', 't',
639 'e', 'g', 'o', 'r', 'i', 'e', 's', 0 };
640
641 TRACE("%s\n",debugstr_guid(rclsid));
642
643 if (rclsid == NULL || ppenumCATID == NULL)
644 return E_POINTER;
645
646 return CATIDEnumGUID_Construct(rclsid, postfix, ppenumCATID);
647}
648
649/**********************************************************************
650 * COMCAT_ICatInformation_EnumReqCategoriesOfClass
651 */
653 LPCATINFORMATION iface,
654 REFCLSID rclsid,
655 LPENUMCATID *ppenumCATID)
656{
657 static const WCHAR postfix[] = { '\\', 'R', 'e', 'q', 'u', 'i', 'r', 'e',
658 'd', ' ', 'C', 'a', 't', 'e', 'g', 'o',
659 'r', 'i', 'e', 's', 0 };
660
661 TRACE("%s\n",debugstr_guid(rclsid));
662
663 if (rclsid == NULL || ppenumCATID == NULL)
664 return E_POINTER;
665
666 return CATIDEnumGUID_Construct(rclsid, postfix, ppenumCATID);
667}
668
669/**********************************************************************
670 * COMCAT_ICatRegister_Vtbl
671 */
672static const ICatRegisterVtbl COMCAT_ICatRegister_Vtbl =
673{
683};
684
685
686/**********************************************************************
687 * COMCAT_ICatInformation_Vtbl
688 */
689static const ICatInformationVtbl COMCAT_ICatInformation_Vtbl =
690{
700};
701
703{
704 HRESULT res;
705 TRACE("%s\n",debugstr_guid(riid));
706
707 if (ppvObj == NULL) return E_POINTER;
708
709 /* Don't support aggregation (Windows doesn't) */
710 if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION;
711
712 res = ICatRegister_QueryInterface(&COMCAT_ComCatMgr.ICatRegister_iface, riid, ppvObj);
713 if (SUCCEEDED(res)) {
714 return res;
715 }
716
718}
719
720/**********************************************************************
721 * IEnumCATEGORYINFO implementation
722 *
723 * This implementation is not thread-safe. The manager itself is, but
724 * I can't imagine a valid use of an enumerator in several threads.
725 */
726typedef struct
727{
734
736{
737 return CONTAINING_RECORD(iface, IEnumCATEGORYINFOImpl, IEnumCATEGORYINFO_iface);
738}
739
741{
743
744 TRACE("\n");
745
746 return InterlockedIncrement(&This->ref);
747}
748
750 IEnumCATEGORYINFO *iface,
751 REFIID riid,
752 LPVOID *ppvObj)
753{
754 TRACE("%s\n",debugstr_guid(riid));
755
756 if (ppvObj == NULL) return E_POINTER;
757
759 IsEqualGUID(riid, &IID_IEnumCATEGORYINFO))
760 {
761 *ppvObj = iface;
763 return S_OK;
764 }
765
766 return E_NOINTERFACE;
767}
768
770{
772 ULONG ref;
773
774 TRACE("\n");
775
777 if (ref == 0) {
778 if (This->key) RegCloseKey(This->key);
780 return 0;
781 }
782 return ref;
783}
784
786 IEnumCATEGORYINFO *iface,
787 ULONG celt,
788 CATEGORYINFO *rgelt,
789 ULONG *pceltFetched)
790{
792 ULONG fetched = 0;
793
794 TRACE("\n");
795
796 if (rgelt == NULL) return E_POINTER;
797
798 if (This->key) while (fetched < celt) {
799 LSTATUS res;
800 HRESULT hr;
802 DWORD cName = CHARS_IN_GUID;
803 HKEY subkey;
804
805 res = RegEnumKeyExW(This->key, This->next_index, catid, &cName,
806 NULL, NULL, NULL, NULL);
807 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
808 ++(This->next_index);
809
810 hr = CLSIDFromString(catid, &rgelt->catid);
811 if (FAILED(hr)) continue;
812
813 res = open_classes_key(This->key, catid, KEY_READ, &subkey);
814 if (res != ERROR_SUCCESS) continue;
815
816 hr = COMCAT_GetCategoryDesc(subkey, This->lcid,
817 rgelt->szDescription, 128);
818 RegCloseKey(subkey);
819 if (FAILED(hr)) continue;
820
821 rgelt->lcid = This->lcid;
822 ++fetched;
823 ++rgelt;
824 }
825
826 if (pceltFetched) *pceltFetched = fetched;
827 return fetched == celt ? S_OK : S_FALSE;
828}
829
831 IEnumCATEGORYINFO *iface,
832 ULONG celt)
833{
835
836 TRACE("\n");
837
838 This->next_index += celt;
839 /* This should return S_FALSE when there aren't celt elems to skip. */
840 return S_OK;
841}
842
844{
846
847 TRACE("\n");
848
849 This->next_index = 0;
850 return S_OK;
851}
852
854 IEnumCATEGORYINFO *iface,
855 IEnumCATEGORYINFO **ppenum)
856{
858 static const WCHAR keyname[] = { 'C', 'o', 'm', 'p', 'o', 'n', 'e', 'n',
859 't', ' ', 'C', 'a', 't', 'e', 'g', 'o',
860 'r', 'i', 'e', 's', 0 };
861 IEnumCATEGORYINFOImpl *new_this;
862
863 TRACE("\n");
864
865 if (ppenum == NULL) return E_POINTER;
866
868 if (new_this == NULL) return E_OUTOFMEMORY;
869
870 new_this->IEnumCATEGORYINFO_iface = This->IEnumCATEGORYINFO_iface;
871 new_this->ref = 1;
872 new_this->lcid = This->lcid;
873 /* FIXME: could we more efficiently use DuplicateHandle? */
874 open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &new_this->key);
875 new_this->next_index = This->next_index;
876
877 *ppenum = &new_this->IEnumCATEGORYINFO_iface;
878 return S_OK;
879}
880
881static const IEnumCATEGORYINFOVtbl COMCAT_IEnumCATEGORYINFO_Vtbl =
882{
890};
891
893{
894 static const WCHAR keyname[] = {'C','o','m','p','o','n','e','n','t',' ','C','a','t','e','g','o','r','i','e','s',0};
896
897 *ret = NULL;
898
900 if (!This) return E_OUTOFMEMORY;
901
902 This->IEnumCATEGORYINFO_iface.lpVtbl = &COMCAT_IEnumCATEGORYINFO_Vtbl;
903 This->ref = 1;
904 This->lcid = lcid;
906
907 *ret = &This->IEnumCATEGORYINFO_iface;
908 return S_OK;
909}
910
911/**********************************************************************
912 * ClassesOfCategories IEnumCLSID (IEnumGUID) implementation
913 *
914 * This implementation is not thread-safe. The manager itself is, but
915 * I can't imagine a valid use of an enumerator in several threads.
916 */
917typedef struct
918{
925
927{
928 return CONTAINING_RECORD(iface, CLSID_IEnumGUIDImpl, IEnumGUID_iface);
929}
930
932 IEnumGUID *iface,
933 REFIID riid,
934 LPVOID *ppvObj)
935{
936 TRACE("%s\n",debugstr_guid(riid));
937
938 if (ppvObj == NULL) return E_POINTER;
939
941 IsEqualGUID(riid, &IID_IEnumGUID))
942 {
943 *ppvObj = iface;
944 IEnumGUID_AddRef(iface);
945 return S_OK;
946 }
947
948 return E_NOINTERFACE;
949}
950
952{
954 TRACE("\n");
955
956 return InterlockedIncrement(&This->ref);
957}
958
960{
962 ULONG ref;
963
964 TRACE("\n");
965
967 if (ref == 0) {
968 if (This->key) RegCloseKey(This->key);
969 HeapFree(GetProcessHeap(), 0, This->categories);
971 return 0;
972 }
973 return ref;
974}
975
977 IEnumGUID *iface,
978 ULONG celt,
979 GUID *rgelt,
980 ULONG *pceltFetched)
981{
983 ULONG fetched = 0;
984
985 TRACE("\n");
986
987 if (rgelt == NULL) return E_POINTER;
988
989 if (This->key) while (fetched < celt) {
990 LSTATUS res;
991 HRESULT hr;
993 DWORD cName = CHARS_IN_GUID;
994 HKEY subkey;
995
996 res = RegEnumKeyExW(This->key, This->next_index, clsid, &cName,
997 NULL, NULL, NULL, NULL);
998 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
999 ++(This->next_index);
1000
1001 hr = CLSIDFromString(clsid, rgelt);
1002 if (FAILED(hr)) continue;
1003
1004 res = open_classes_key(This->key, clsid, KEY_READ, &subkey);
1005 if (res != ERROR_SUCCESS) continue;
1006
1007 hr = COMCAT_IsClassOfCategories(subkey, This->categories);
1008 RegCloseKey(subkey);
1009 if (hr != S_OK) continue;
1010
1011 ++fetched;
1012 ++rgelt;
1013 }
1014
1015 if (pceltFetched) *pceltFetched = fetched;
1016 return fetched == celt ? S_OK : S_FALSE;
1017}
1018
1020 IEnumGUID *iface,
1021 ULONG celt)
1022{
1024
1025 TRACE("\n");
1026
1027 This->next_index += celt;
1028 FIXME("Never returns S_FALSE\n");
1029 return S_OK;
1030}
1031
1033{
1035
1036 TRACE("\n");
1037
1038 This->next_index = 0;
1039 return S_OK;
1040}
1041
1043 IEnumGUID *iface,
1044 IEnumGUID **ppenum)
1045{
1046 static const WCHAR keynameW[] = {'C','L','S','I','D',0};
1048 CLSID_IEnumGUIDImpl *cloned;
1049
1050 TRACE("(%p)->(%p)\n", This, ppenum);
1051
1052 if (ppenum == NULL) return E_POINTER;
1053
1054 *ppenum = NULL;
1055
1056 cloned = HeapAlloc(GetProcessHeap(), 0, sizeof(CLSID_IEnumGUIDImpl));
1057 if (cloned == NULL) return E_OUTOFMEMORY;
1058
1059 cloned->IEnumGUID_iface.lpVtbl = This->IEnumGUID_iface.lpVtbl;
1060 cloned->ref = 1;
1061
1062 cloned->categories = HeapAlloc(GetProcessHeap(), 0, This->categories->size);
1063 if (cloned->categories == NULL) {
1064 HeapFree(GetProcessHeap(), 0, cloned);
1065 return E_OUTOFMEMORY;
1066 }
1067 memcpy(cloned->categories, This->categories, This->categories->size);
1068
1069 cloned->key = NULL;
1070 open_classes_key(HKEY_CLASSES_ROOT, keynameW, KEY_READ, &cloned->key);
1071 cloned->next_index = This->next_index;
1072
1073 *ppenum = &cloned->IEnumGUID_iface;
1074 return S_OK;
1075}
1076
1077static const IEnumGUIDVtbl CLSIDEnumGUIDVtbl =
1078{
1086};
1087
1089{
1090 static const WCHAR keyname[] = {'C','L','S','I','D',0};
1092
1093 *ret = NULL;
1094
1096 if (!This) return E_OUTOFMEMORY;
1097
1098 This->IEnumGUID_iface.lpVtbl = &CLSIDEnumGUIDVtbl;
1099 This->ref = 1;
1100 This->categories = categories;
1102
1103 *ret = &This->IEnumGUID_iface;
1104
1105 return S_OK;
1106}
1107
1108/**********************************************************************
1109 * CategoriesOfClass IEnumCATID (IEnumGUID) implementation
1110 *
1111 * This implementation is not thread-safe. The manager itself is, but
1112 * I can't imagine a valid use of an enumerator in several threads.
1113 */
1114typedef struct
1115{
1118 WCHAR keyname[68];
1122
1124{
1125 return CONTAINING_RECORD(iface, CATID_IEnumGUIDImpl, IEnumGUID_iface);
1126}
1127
1129 IEnumGUID *iface,
1130 REFIID riid,
1131 LPVOID *ppvObj)
1132{
1133 TRACE("%s\n",debugstr_guid(riid));
1134
1135 if (ppvObj == NULL) return E_POINTER;
1136
1137 if (IsEqualGUID(riid, &IID_IUnknown) ||
1138 IsEqualGUID(riid, &IID_IEnumGUID))
1139 {
1140 *ppvObj = iface;
1141 IEnumGUID_AddRef(iface);
1142 return S_OK;
1143 }
1144
1145 return E_NOINTERFACE;
1146}
1147
1149{
1151 TRACE("\n");
1152
1153 return InterlockedIncrement(&This->ref);
1154}
1155
1157{
1159 ULONG ref;
1160
1161 TRACE("\n");
1162
1163 ref = InterlockedDecrement(&This->ref);
1164 if (ref == 0) {
1165 if (This->key) RegCloseKey(This->key);
1167 return 0;
1168 }
1169 return ref;
1170}
1171
1173 IEnumGUID *iface,
1174 ULONG celt,
1175 GUID *rgelt,
1176 ULONG *pceltFetched)
1177{
1179 ULONG fetched = 0;
1180
1181 TRACE("\n");
1182
1183 if (rgelt == NULL) return E_POINTER;
1184
1185 if (This->key) while (fetched < celt) {
1186 LSTATUS res;
1187 HRESULT hr;
1189 DWORD cName = CHARS_IN_GUID;
1190
1191 res = RegEnumKeyExW(This->key, This->next_index, catid, &cName,
1192 NULL, NULL, NULL, NULL);
1193 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
1194 ++(This->next_index);
1195
1196 hr = CLSIDFromString(catid, rgelt);
1197 if (FAILED(hr)) continue;
1198
1199 ++fetched;
1200 ++rgelt;
1201 }
1202
1203 if (pceltFetched) *pceltFetched = fetched;
1204 return fetched == celt ? S_OK : S_FALSE;
1205}
1206
1208 IEnumGUID *iface,
1209 ULONG celt)
1210{
1212
1213 TRACE("\n");
1214
1215 This->next_index += celt;
1216 FIXME("Never returns S_FALSE\n");
1217 return S_OK;
1218}
1219
1221{
1223
1224 TRACE("\n");
1225
1226 This->next_index = 0;
1227 return S_OK;
1228}
1229
1231 IEnumGUID *iface,
1232 IEnumGUID **ppenum)
1233{
1235 CATID_IEnumGUIDImpl *new_this;
1236
1237 TRACE("\n");
1238
1239 if (ppenum == NULL) return E_POINTER;
1240
1242 if (new_this == NULL) return E_OUTOFMEMORY;
1243
1244 new_this->IEnumGUID_iface.lpVtbl = This->IEnumGUID_iface.lpVtbl;
1245 new_this->ref = 1;
1246 lstrcpyW(new_this->keyname, This->keyname);
1247 /* FIXME: could we more efficiently use DuplicateHandle? */
1248 open_classes_key(HKEY_CLASSES_ROOT, new_this->keyname, KEY_READ, &new_this->key);
1249 new_this->next_index = This->next_index;
1250
1251 *ppenum = &new_this->IEnumGUID_iface;
1252 return S_OK;
1253}
1254
1255static const IEnumGUIDVtbl CATIDEnumGUIDVtbl =
1256{
1264};
1265
1267{
1268 static const WCHAR prefixW[] = {'C','L','S','I','D','\\',0};
1269 WCHAR keyname[100], clsidW[CHARS_IN_GUID];
1271
1272 *ret = NULL;
1273
1275 if (!This) return E_OUTOFMEMORY;
1276
1278
1279 This->IEnumGUID_iface.lpVtbl = &CATIDEnumGUIDVtbl;
1280 This->ref = 1;
1281 lstrcpyW(keyname, prefixW);
1282 lstrcatW(keyname, clsidW);
1283 lstrcatW(keyname, postfix);
1284
1286
1287 *ret = &This->IEnumGUID_iface;
1288 return S_OK;
1289}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define RegCloseKey(hKey)
Definition: registry.h:49
#define IEnumCLSID
Definition: comcat.idl:40
#define IEnumCATID
Definition: comcat.idl:36
#define CHARS_IN_GUID
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
static const WCHAR clsidW[]
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
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
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define TRACE_ON(x)
Definition: compat.h:75
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define wcsicmp
Definition: compat.h:15
#define lstrlenW
Definition: compat.h:750
static HRESULT CATIDEnumGUID_Construct(REFCLSID rclsid, LPCWSTR impl_req, IEnumCATID **ret)
static HRESULT WINAPI COMCAT_IEnumCATEGORYINFO_QueryInterface(IEnumCATEGORYINFO *iface, REFIID riid, LPVOID *ppvObj)
Definition: comcat.c:749
static HRESULT WINAPI COMCAT_IEnumCATEGORYINFO_Clone(IEnumCATEGORYINFO *iface, IEnumCATEGORYINFO **ppenum)
Definition: comcat.c:853
static ULONG WINAPI COMCAT_IEnumCATEGORYINFO_AddRef(IEnumCATEGORYINFO *iface)
Definition: comcat.c:740
static HRESULT WINAPI CATIDEnumGUID_Skip(IEnumGUID *iface, ULONG celt)
Definition: comcat.c:1207
static ULONG WINAPI CLSIDEnumGUID_AddRef(IEnumGUID *iface)
Definition: comcat.c:951
static HRESULT WINAPI COMCAT_ICatInformation_QueryInterface(LPCATINFORMATION iface, REFIID riid, LPVOID *ppvObj)
Definition: comcat.c:462
static ULONG WINAPI CATIDEnumGUID_Release(IEnumGUID *iface)
Definition: comcat.c:1156
static HRESULT WINAPI CLSIDEnumGUID_QueryInterface(IEnumGUID *iface, REFIID riid, LPVOID *ppvObj)
Definition: comcat.c:931
static ULONG WINAPI CATIDEnumGUID_AddRef(IEnumGUID *iface)
Definition: comcat.c:1148
static const WCHAR impl_keyname[]
Definition: comcat.c:72
static HRESULT WINAPI CATIDEnumGUID_Clone(IEnumGUID *iface, IEnumGUID **ppenum)
Definition: comcat.c:1230
HRESULT WINAPI ComCat_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
Definition: comcat.c:702
static ULONG WINAPI COMCAT_ICatRegister_AddRef(LPCATREGISTER iface)
Definition: comcat.c:311
static const ICatRegisterVtbl COMCAT_ICatRegister_Vtbl
Definition: comcat.c:40
static HRESULT WINAPI COMCAT_ICatRegister_UnRegisterClassImplCategories(LPCATREGISTER iface, REFCLSID rclsid, ULONG cCategories, CATID *rgcatid)
Definition: comcat.c:417
static const IEnumCATEGORYINFOVtbl COMCAT_IEnumCATEGORYINFO_Vtbl
Definition: comcat.c:881
static HRESULT CLSIDEnumGUID_Construct(struct class_categories *class_categories, IEnumCLSID **ret)
Definition: comcat.c:1088
static HRESULT WINAPI COMCAT_IEnumCATEGORYINFO_Skip(IEnumCATEGORYINFO *iface, ULONG celt)
Definition: comcat.c:830
static HRESULT WINAPI CLSIDEnumGUID_Skip(IEnumGUID *iface, ULONG celt)
Definition: comcat.c:1019
static IEnumCATEGORYINFOImpl * impl_from_IEnumCATEGORYINFO(IEnumCATEGORYINFO *iface)
Definition: comcat.c:735
static ULONG WINAPI COMCAT_IEnumCATEGORYINFO_Release(IEnumCATEGORYINFO *iface)
Definition: comcat.c:769
static ComCatMgrImpl COMCAT_ComCatMgr
Definition: comcat.c:50
static HRESULT WINAPI COMCAT_ICatInformation_EnumCategories(LPCATINFORMATION iface, LCID lcid, IEnumCATEGORYINFO **ppenumCatInfo)
Definition: comcat.c:489
static HRESULT WINAPI COMCAT_ICatRegister_RegisterCategories(LPCATREGISTER iface, ULONG cCategories, CATEGORYINFO *rgci)
Definition: comcat.c:327
static CLSID_IEnumGUIDImpl * impl_from_IEnumCLSID(IEnumGUID *iface)
Definition: comcat.c:926
static HRESULT COMCAT_UnRegisterClassCategories(REFCLSID rclsid, LPCWSTR type, ULONG cCategories, const CATID *rgcatid)
Definition: comcat.c:131
static ULONG WINAPI CLSIDEnumGUID_Release(IEnumGUID *iface)
Definition: comcat.c:959
static const WCHAR req_keyname[]
Definition: comcat.c:74
static HRESULT WINAPI COMCAT_ICatInformation_GetCategoryDesc(LPCATINFORMATION iface, REFCATID rcatid, LCID lcid, PWCHAR *ppszDesc)
Definition: comcat.c:504
static CATID_IEnumGUIDImpl * impl_from_IEnumCATID(IEnumGUID *iface)
Definition: comcat.c:1123
static HRESULT COMCAT_RegisterClassCategories(REFCLSID rclsid, LPCWSTR type, ULONG cCategories, const CATID *rgcatid)
Definition: comcat.c:82
static HRESULT WINAPI COMCAT_ICatInformation_EnumClassesOfCategories(LPCATINFORMATION iface, ULONG cImplemented, CATID *rgcatidImpl, ULONG cRequired, CATID *rgcatidReq, LPENUMCLSID *ppenumCLSID)
Definition: comcat.c:546
static HRESULT WINAPI COMCAT_ICatRegister_RegisterClassImplCategories(LPCATREGISTER iface, REFCLSID rclsid, ULONG cCategories, CATID *rgcatid)
Definition: comcat.c:402
static ULONG WINAPI COMCAT_ICatInformation_AddRef(LPCATINFORMATION iface)
Definition: comcat.c:473
static HRESULT WINAPI CATIDEnumGUID_Next(IEnumGUID *iface, ULONG celt, GUID *rgelt, ULONG *pceltFetched)
Definition: comcat.c:1172
static HRESULT WINAPI COMCAT_ICatRegister_UnRegisterClassReqCategories(LPCATREGISTER iface, REFCLSID rclsid, ULONG cCategories, CATID *rgcatid)
Definition: comcat.c:447
static HRESULT WINAPI COMCAT_ICatRegister_UnRegisterCategories(LPCATREGISTER iface, ULONG cCategories, CATID *rgcatid)
Definition: comcat.c:370
static HRESULT WINAPI COMCAT_ICatInformation_IsClassOfCategories(LPCATINFORMATION iface, REFCLSID rclsid, ULONG cImplemented, CATID *rgcatidImpl, ULONG cRequired, CATID *rgcatidReq)
Definition: comcat.c:585
static const ICatInformationVtbl COMCAT_ICatInformation_Vtbl
Definition: comcat.c:41
static HRESULT COMCAT_GetCategoryDesc(HKEY key, LCID lcid, PWCHAR pszDesc, ULONG buf_wchars)
Definition: comcat.c:169
static const WCHAR comcat_keyname[]
Definition: comcat.c:70
static const WCHAR clsid_keyname[]
Definition: comcat.c:76
static HRESULT WINAPI CATIDEnumGUID_Reset(IEnumGUID *iface)
Definition: comcat.c:1220
static HRESULT EnumCATEGORYINFO_Construct(LCID lcid, IEnumCATEGORYINFO **ret)
Definition: comcat.c:892
static HRESULT WINAPI CLSIDEnumGUID_Next(IEnumGUID *iface, ULONG celt, GUID *rgelt, ULONG *pceltFetched)
Definition: comcat.c:976
static HRESULT COMCAT_IsClassOfCategories(HKEY key, struct class_categories const *categories)
Definition: comcat.c:228
static HRESULT WINAPI COMCAT_ICatInformation_EnumImplCategoriesOfClass(LPCATINFORMATION iface, REFCLSID rclsid, LPENUMCATID *ppenumCATID)
Definition: comcat.c:632
static HRESULT WINAPI COMCAT_ICatInformation_EnumReqCategoriesOfClass(LPCATINFORMATION iface, REFCLSID rclsid, LPENUMCATID *ppenumCATID)
Definition: comcat.c:652
static HRESULT WINAPI CLSIDEnumGUID_Reset(IEnumGUID *iface)
Definition: comcat.c:1032
static HRESULT WINAPI CLSIDEnumGUID_Clone(IEnumGUID *iface, IEnumGUID **ppenum)
Definition: comcat.c:1042
static HRESULT WINAPI COMCAT_IEnumCATEGORYINFO_Next(IEnumCATEGORYINFO *iface, ULONG celt, CATEGORYINFO *rgelt, ULONG *pceltFetched)
Definition: comcat.c:785
static HRESULT WINAPI CATIDEnumGUID_QueryInterface(IEnumGUID *iface, REFIID riid, LPVOID *ppvObj)
Definition: comcat.c:1128
static HRESULT WINAPI COMCAT_IEnumCATEGORYINFO_Reset(IEnumCATEGORYINFO *iface)
Definition: comcat.c:843
static const IEnumGUIDVtbl CATIDEnumGUIDVtbl
Definition: comcat.c:1255
static struct class_categories * COMCAT_PrepareClassCategories(ULONG impl_count, const CATID *impl_catids, ULONG req_count, const CATID *req_catids)
Definition: comcat.c:194
static HRESULT WINAPI COMCAT_ICatRegister_RegisterClassReqCategories(LPCATREGISTER iface, REFCLSID rclsid, ULONG cCategories, CATID *rgcatid)
Definition: comcat.c:432
static ULONG WINAPI COMCAT_ICatInformation_Release(LPCATINFORMATION iface)
Definition: comcat.c:481
static ULONG WINAPI COMCAT_ICatRegister_Release(LPCATREGISTER iface)
Definition: comcat.c:319
static const IEnumGUIDVtbl CLSIDEnumGUIDVtbl
Definition: comcat.c:1077
static HRESULT WINAPI COMCAT_ICatRegister_QueryInterface(LPCATREGISTER iface, REFIID riid, LPVOID *ppvObj)
Definition: comcat.c:284
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
LSTATUS create_classes_key(HKEY hkey, const WCHAR *name, REGSAM access, HKEY *retkey)
Definition: compobj.c:402
LSTATUS open_classes_key(HKEY hkey, const WCHAR *name, REGSAM access, HKEY *retkey)
Definition: compobj.c:420
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLsizei GLenum * categories
Definition: glext.h:11561
GLuint res
Definition: glext.h:9613
GLsizei const GLchar *const * strings
Definition: glext.h:7622
GLuint index
Definition: glext.h:6031
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define REG_SZ
Definition: layer.c:22
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
char string[160]
Definition: util.h:11
REFCLSID clsid
Definition: msctf.c:82
GUID catid
Definition: msctf.idl:647
#define KEY_READ
Definition: nt_native.h:1023
#define KEY_WRITE
Definition: nt_native.h:1031
#define READ_CONTROL
Definition: nt_native.h:58
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
DWORD LCID
Definition: nls.h:13
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
IEnumGUID IEnumGUID_iface
Definition: comcat.c:1116
WCHAR keyname[68]
Definition: comcat.c:1118
IEnumGUID IEnumGUID_iface
Definition: comcat.c:919
struct class_categories * categories
Definition: comcat.c:921
ICatRegister ICatRegister_iface
Definition: comcat.c:45
ICatInformation ICatInformation_iface
Definition: comcat.c:46
IEnumCATEGORYINFO IEnumCATEGORYINFO_iface
Definition: comcat.c:728
Definition: scsiwmi.h:51
ULONG size
Definition: comcat.c:58
ULONG impl_offset
Definition: comcat.c:59
ULONG req_offset
Definition: comcat.c:60
Definition: dsound.c:943
Definition: copy.c:22
Definition: send.c:48
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
int ret
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
#define CAT_E_NODESCRIPTION
Definition: winerror.h:2702
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define E_POINTER
Definition: winerror.h:2365
#define CAT_E_CATIDNOEXIST
Definition: winerror.h:2701
#define CLASS_E_CLASSNOTAVAILABLE
Definition: winerror.h:2663
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193