1 /*
2  * PROJECT:     ReactOS API Tests
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Test for SHEnumClassesOfCategories
5  * COPYRIGHT:   Copyright 2019 Serge Gautherie <reactos-git_serge_171003@gautherie.fr>
6  */
7 
8 /*
9 TODO, if they make sense:
10 * Test more than 1 Implemented/Required.
11   And maybe not "matching" ones.
12 * Check pEnumGUID after S_OK cases.
13 */
14 
15 #include <apitest.h>
16 
17 #include <shlobj.h>
18 #include <atlbase.h>
19 
20 typedef HRESULT (WINAPI *SHENUMCLASSESOFCATEGORIES)(ULONG cImplemented, CATID *pImplemented, ULONG cRequired, CATID *pRequired, IEnumGUID **out);
21 
22 static SHENUMCLASSESOFCATEGORIES pSHEnumClassesOfCategories;
23 
24 START_TEST(SHEnumClassesOfCategories)
25 {
26     HRESULT hr;
27     HMODULE hbrowseui;
28     CATID CategoryImplemented, CategoryRequired;
29     CComPtr<IEnumGUID> pEnumGUID;
30 
31     // Set up.
32 
33     hbrowseui = LoadLibraryA("browseui.dll");
34     ok(hbrowseui != NULL, "LoadLibraryA() failed\n");
35     if (!hbrowseui)
36     {
37         skip("No dll\n");
38         return;
39     }
40 
41     pSHEnumClassesOfCategories = (SHENUMCLASSESOFCATEGORIES)GetProcAddress(hbrowseui, MAKEINTRESOURCEA(136));
42     ok(pSHEnumClassesOfCategories != NULL, "GetProcAddress() failed\n");
43     if (!pSHEnumClassesOfCategories)
44     {
45         skip("No function, as on NT 6.1+\n");
46         return;
47     }
48 
49     // Test (mostly) invalid arguments.
50 
51     // Implemented, '(ULONG)-1, NULL'.
52     // Keep this odd case, as ReactOS used to "implement" it.
53 
54     // hr = pSHEnumClassesOfCategories((ULONG)-1, NULL, 0, NULL, NULL);
55     // ok_long(hr, E_INVALIDARG);
56     hr = pSHEnumClassesOfCategories((ULONG)-1, NULL, 0, NULL, &pEnumGUID);
57     ok_long(hr, E_INVALIDARG);
58 
59     CategoryRequired = CATID_DeskBand;
60     // hr = pSHEnumClassesOfCategories((ULONG)-1, NULL, 1, &CategoryRequired, NULL);
61     // ok_long(hr, E_INVALIDARG);
62     hr = pSHEnumClassesOfCategories((ULONG)-1, NULL, 1, &CategoryRequired, &pEnumGUID);
63     ok_long(hr, E_INVALIDARG);
64 
65     // Implemented, '0, NULL'.
66 
67     // hr = pSHEnumClassesOfCategories(0, NULL, 0, NULL, NULL);
68     // ok_long(hr, E_INVALIDARG);
69     hr = pSHEnumClassesOfCategories(0, NULL, 0, NULL, &pEnumGUID);
70     ok_long(hr, E_INVALIDARG);
71 
72     // CategoryRequired = CATID_DeskBand;
73     // hr = pSHEnumClassesOfCategories(0, NULL, 1, &CategoryRequired, NULL);
74     // ok_long(hr, E_INVALIDARG);
75     // The following case duplicates a later one.
76     // hr = pSHEnumClassesOfCategories(0, NULL, 1, &CategoryRequired, &pEnumGUID);
77     // ok_long(hr, S_OK);
78     // ok(CategoryRequired == CATID_DeskBand, "CategoryRequired was modified\n");
79     // pEnumGUID = NULL;
80 
81     // Implemented, '0, &CategoryImplemented'.
82 
83     CategoryImplemented = CATID_DeskBand;
84     // hr = pSHEnumClassesOfCategories(0, &CategoryImplemented, 0, NULL, NULL);
85     // ok_long(hr, E_INVALIDARG);
86     hr = pSHEnumClassesOfCategories(0, &CategoryImplemented, 0, NULL, &pEnumGUID);
87     ok_long(hr, E_INVALIDARG);
88 
89     CategoryRequired = CATID_DeskBand;
90     // hr = pSHEnumClassesOfCategories(0, &CategoryImplemented, 1, &CategoryRequired, NULL);
91     // ok_long(hr, E_INVALIDARG);
92     hr = pSHEnumClassesOfCategories(0, &CategoryImplemented, 1, &CategoryRequired, &pEnumGUID);
93     ok_long(hr, S_OK);
94     ok(CategoryImplemented == CATID_DeskBand, "CategoryImplemented was modified\n");
95     ok(CategoryRequired == CATID_DeskBand, "CategoryRequired was modified\n");
96     pEnumGUID = NULL;
97 
98     CategoryRequired = CATID_InfoBand;
99     // hr = pSHEnumClassesOfCategories(0, &CategoryImplemented, 1, &CategoryRequired, NULL);
100     // ok_long(hr, E_INVALIDARG);
101     hr = pSHEnumClassesOfCategories(0, &CategoryImplemented, 1, &CategoryRequired, &pEnumGUID);
102     ok_long(hr, S_OK);
103     ok(CategoryImplemented == CATID_DeskBand, "CategoryImplemented was modified\n");
104     ok(CategoryRequired == CATID_InfoBand, "CategoryRequired was modified\n");
105     pEnumGUID = NULL;
106 
107     // Implemented, '1, NULL'.
108 
109     // hr = pSHEnumClassesOfCategories(1, NULL, 0, NULL, NULL);
110     // ok_long(hr, E_INVALIDARG);
111     hr = pSHEnumClassesOfCategories(1, NULL, 0, NULL, &pEnumGUID);
112     ok_long(hr, E_INVALIDARG);
113 
114     CategoryRequired = CATID_DeskBand;
115     // hr = pSHEnumClassesOfCategories(1, NULL, 1, &CategoryRequired, NULL);
116     // ok_long(hr, E_INVALIDARG);
117     hr = pSHEnumClassesOfCategories(1, NULL, 1, &CategoryRequired, &pEnumGUID);
118     ok_long(hr, E_INVALIDARG);
119 
120     // Required, '0, &CategoryRequired'.
121 
122     CategoryRequired = CATID_DeskBand;
123 
124     CategoryImplemented = CATID_DeskBand;
125     // hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 0, &CategoryRequired, NULL);
126     // ok_long(hr, E_INVALIDARG);
127     hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 0, &CategoryRequired, &pEnumGUID);
128     ok_long(hr, S_OK);
129     ok(CategoryImplemented == CATID_DeskBand, "CategoryImplemented was modified\n");
130     ok(CategoryRequired == CATID_DeskBand, "CategoryRequired was modified\n");
131     pEnumGUID = NULL;
132 
133     CategoryImplemented = CATID_InfoBand;
134     // hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 0, &CategoryRequired, NULL);
135     // ok_long(hr, E_INVALIDARG);
136     hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 0, &CategoryRequired, &pEnumGUID);
137     ok_long(hr, S_OK);
138     ok(CategoryImplemented == CATID_InfoBand, "CategoryImplemented was modified\n");
139     ok(CategoryRequired == CATID_DeskBand, "CategoryRequired was modified\n");
140     pEnumGUID = NULL;
141 
142     // Required, '1, NULL'.
143 
144     // hr = pSHEnumClassesOfCategories(0, NULL, 1, NULL, NULL);
145     // ok_long(hr, E_INVALIDARG);
146     hr = pSHEnumClassesOfCategories(0, NULL, 1, NULL, &pEnumGUID);
147     ok_long(hr, E_INVALIDARG);
148 
149     CategoryImplemented = CATID_DeskBand;
150     // hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 1, NULL, NULL);
151     // ok_long(hr, E_INVALIDARG);
152     hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 1, NULL, &pEnumGUID);
153     ok_long(hr, E_INVALIDARG);
154 
155     // Out, 'NULL'.
156     // Previous similar checks are commented out, for usual use.
157 
158     CategoryImplemented = CATID_DeskBand;
159     hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 0, NULL, NULL);
160     ok_long(hr, E_INVALIDARG);
161 
162     CategoryRequired = CATID_DeskBand;
163     hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 1, &CategoryRequired, NULL);
164     ok_long(hr, E_INVALIDARG);
165 
166     // Test success.
167     // CATID_* from sdk/include/psdk/shlguid.h.
168     // See also modules/rostests/winetests/shlwapi/clsid.c.
169 
170     // Each CATID, as Implemented.
171 
172     CategoryImplemented = CATID_BrowsableShellExt;
173     hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 0, NULL, &pEnumGUID);
174     ok_long(hr, S_OK);
175     ok(CategoryImplemented == CATID_BrowsableShellExt, "CategoryImplemented was modified\n");
176     pEnumGUID = NULL;
177 
178     CategoryImplemented = CATID_BrowseInPlace;
179     hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 0, NULL, &pEnumGUID);
180     ok_long(hr, S_OK);
181     ok(CategoryImplemented == CATID_BrowseInPlace, "CategoryImplemented was modified\n");
182     pEnumGUID = NULL;
183 
184     CategoryImplemented = CATID_DeskBand;
185     hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 0, NULL, &pEnumGUID);
186     ok_long(hr, S_OK);
187     ok(CategoryImplemented == CATID_DeskBand, "CategoryImplemented was modified\n");
188     pEnumGUID = NULL;
189 
190     CategoryImplemented = CATID_InfoBand;
191     hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 0, NULL, &pEnumGUID);
192     ok_long(hr, S_OK);
193     ok(CategoryImplemented == CATID_InfoBand, "CategoryImplemented was modified\n");
194     pEnumGUID = NULL;
195 
196     CategoryImplemented = CATID_CommBand;
197     hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 0, NULL, &pEnumGUID);
198     ok_long(hr, S_OK);
199     ok(CategoryImplemented == CATID_CommBand, "CategoryImplemented was modified\n");
200     pEnumGUID = NULL;
201 
202     // Each CATID, as Required.
203 
204     CategoryRequired = CATID_BrowsableShellExt;
205     hr = pSHEnumClassesOfCategories(0, NULL, 1, &CategoryRequired, &pEnumGUID);
206     ok_long(hr, S_OK);
207     ok(CategoryRequired == CATID_BrowsableShellExt, "CategoryRequired was modified\n");
208     pEnumGUID = NULL;
209 
210     CategoryRequired = CATID_BrowseInPlace;
211     hr = pSHEnumClassesOfCategories(0, NULL, 1, &CategoryRequired, &pEnumGUID);
212     ok_long(hr, S_OK);
213     ok(CategoryRequired == CATID_BrowseInPlace, "CategoryRequired was modified\n");
214     pEnumGUID = NULL;
215 
216     CategoryRequired = CATID_DeskBand;
217     hr = pSHEnumClassesOfCategories(0, NULL, 1, &CategoryRequired, &pEnumGUID);
218     ok_long(hr, S_OK);
219     ok(CategoryRequired == CATID_DeskBand, "CategoryRequired was modified\n");
220     pEnumGUID = NULL;
221 
222     CategoryRequired = CATID_InfoBand;
223     hr = pSHEnumClassesOfCategories(0, NULL, 1, &CategoryRequired, &pEnumGUID);
224     ok_long(hr, S_OK);
225     ok(CategoryRequired == CATID_InfoBand, "CategoryRequired was modified\n");
226     pEnumGUID = NULL;
227 
228     CategoryRequired = CATID_CommBand;
229     hr = pSHEnumClassesOfCategories(0, NULL, 1, &CategoryRequired, &pEnumGUID);
230     ok_long(hr, S_OK);
231     ok(CategoryRequired == CATID_CommBand, "CategoryRequired was modified\n");
232     pEnumGUID = NULL;
233 
234     // Same CATID, as Implemented and Required.
235 
236     CategoryImplemented = CATID_DeskBand;
237     CategoryRequired = CATID_DeskBand;
238     hr = pSHEnumClassesOfCategories(1, &CategoryImplemented, 1, &CategoryRequired, &pEnumGUID);
239     ok_long(hr, S_OK);
240     ok(CategoryImplemented == CATID_DeskBand, "CategoryImplemented was modified\n");
241     ok(CategoryRequired == CATID_DeskBand, "CategoryRequired was modified\n");
242     pEnumGUID = NULL;
243 
244     // Clean up.
245 
246     ok(FreeLibrary(hbrowseui) != 0, "FreeLibrary() failed\n");
247 }
248