http.sys: Keep connection sockets open after sending a 400 response.
[wine.git] / dlls / sapi / tests / token.c
blob8befd98c2a59075b1dc95c968c5f0a2788d20de1
1 /*
2 * Speech API (SAPI) token tests.
4 * Copyright (C) 2017 Huw Davies
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 #define COBJMACROS
23 #include "initguid.h"
24 #include "sapiddk.h"
25 #include "sperror.h"
27 #include "wine/test.h"
29 static void test_data_key(void)
31 ISpRegDataKey *data_key;
32 ISpDataKey *sub;
33 HRESULT hr;
34 HKEY key;
35 LONG res;
36 WCHAR *value = NULL;
38 hr = CoCreateInstance( &CLSID_SpDataKey, NULL, CLSCTX_INPROC_SERVER,
39 &IID_ISpRegDataKey, (void **)&data_key );
40 ok( hr == S_OK, "got %08lx\n", hr );
42 res = RegCreateKeyExA( HKEY_CURRENT_USER, "Software\\Winetest\\sapi", 0, NULL, 0, KEY_ALL_ACCESS,
43 NULL, &key, NULL );
44 ok( res == ERROR_SUCCESS, "got %ld\n", res );
46 hr = ISpRegDataKey_CreateKey( data_key, L"Testing", &sub );
47 ok( hr == E_HANDLE, "got %08lx\n", hr );
49 hr = ISpRegDataKey_GetStringValue( data_key, L"Voice", &value );
50 ok( hr == E_HANDLE, "got %08lx\n", hr );
52 hr = ISpRegDataKey_SetStringValue( data_key, L"Voice", L"Test" );
53 ok( hr == E_HANDLE, "got %08lx\n", hr );
55 hr = ISpRegDataKey_SetKey( data_key, key, FALSE );
56 ok( hr == S_OK, "got %08lx\n", hr );
57 hr = ISpRegDataKey_SetKey( data_key, key, FALSE );
58 ok( hr == SPERR_ALREADY_INITIALIZED, "got %08lx\n", hr );
60 hr = ISpRegDataKey_GetStringValue( data_key, L"Voice", &value );
61 ok( hr == SPERR_NOT_FOUND, "got %08lx\n", hr );
63 hr = ISpRegDataKey_GetStringValue( data_key, L"", &value );
64 ok( hr == SPERR_NOT_FOUND, "got %08lx\n", hr );
66 hr = ISpRegDataKey_SetStringValue( data_key, L"Voice", L"Test" );
67 ok( hr == S_OK, "got %08lx\n", hr );
69 hr = ISpRegDataKey_GetStringValue( data_key, L"Voice", &value );
70 ok( hr == S_OK, "got %08lx\n", hr );
71 ok( !wcscmp( value, L"Test" ), "got %s\n", wine_dbgstr_w(value) );
72 CoTaskMemFree( value );
74 hr = ISpRegDataKey_OpenKey( data_key, L"Testing", &sub );
75 ok( hr == SPERR_NOT_FOUND, "got %08lx\n", hr );
77 hr = ISpRegDataKey_CreateKey( data_key, L"Testing", &sub );
78 ok( hr == S_OK, "got %08lx\n", hr );
79 ISpDataKey_Release(sub);
81 hr = ISpRegDataKey_OpenKey( data_key, L"Testing", &sub );
82 ok( hr == S_OK, "got %08lx\n", hr );
83 ISpDataKey_Release(sub);
85 ISpRegDataKey_Release( data_key );
87 hr = CoCreateInstance( &CLSID_SpDataKey, NULL, CLSCTX_INPROC_SERVER,
88 &IID_ISpRegDataKey, (void **)&data_key );
89 ok( hr == S_OK, "got %08lx\n", hr );
91 res = RegOpenKeyExA( HKEY_CURRENT_USER, "Software\\Winetest\\sapi", 0, KEY_ALL_ACCESS, &key );
92 ok( res == ERROR_SUCCESS, "got %ld\n", res );
94 hr = ISpRegDataKey_SetKey( data_key, key, TRUE );
95 ok( hr == S_OK, "got %08lx\n", hr );
97 hr = ISpRegDataKey_SetStringValue( data_key, L"Voice2", L"Test2" );
98 ok( hr == S_OK, "got %08lx\n", hr );
100 hr = ISpRegDataKey_GetStringValue( data_key, L"Voice2", &value );
101 ok( hr == S_OK, "got %08lx\n", hr );
102 ok( !wcscmp( value, L"Test2" ), "got %s\n", wine_dbgstr_w(value) );
103 CoTaskMemFree( value );
105 hr = ISpRegDataKey_CreateKey( data_key, L"Testing2", &sub );
106 ok( hr == S_OK, "got %08lx\n", hr );
107 ISpDataKey_Release(sub);
109 ISpRegDataKey_Release( data_key );
112 static void setup_test_voice_tokens(void)
114 HKEY key;
115 ISpRegDataKey *data_key;
116 ISpDataKey *attrs_key;
117 LSTATUS ret;
118 HRESULT hr;
120 ret = RegCreateKeyExA( HKEY_CURRENT_USER, "Software\\Winetest\\sapi\\TestVoices\\Tokens", 0, NULL, 0,
121 KEY_ALL_ACCESS, NULL, &key, NULL );
122 ok( ret == ERROR_SUCCESS, "got %ld\n", ret );
124 hr = CoCreateInstance( &CLSID_SpDataKey, NULL, CLSCTX_INPROC_SERVER,
125 &IID_ISpRegDataKey, (void **)&data_key );
126 ok( hr == S_OK, "got %08lx\n", hr );
127 hr = ISpRegDataKey_SetKey( data_key, key, FALSE );
128 ok( hr == S_OK, "got %08lx\n", hr );
130 ISpRegDataKey_CreateKey( data_key, L"Voice1\\Attributes", &attrs_key );
131 ISpDataKey_SetStringValue( attrs_key, L"Language", L"409" );
132 ISpDataKey_SetStringValue( attrs_key, L"Gender", L"Female" );
133 ISpDataKey_SetStringValue( attrs_key, L"Age", L"Child" );
134 ISpDataKey_SetStringValue( attrs_key, L"Vendor", L"Vendor2" );
135 ISpDataKey_Release( attrs_key );
137 ISpRegDataKey_CreateKey( data_key, L"Voice2\\Attributes", &attrs_key );
138 ISpDataKey_SetStringValue( attrs_key, L"Language", L"406;407;408;409;40a" );
139 ISpDataKey_SetStringValue( attrs_key, L"Gender", L"Female" );
140 ISpDataKey_SetStringValue( attrs_key, L"Age", L"Adult" );
141 ISpDataKey_SetStringValue( attrs_key, L"Vendor", L"Vendor1" );
142 ISpDataKey_Release( attrs_key );
144 ISpRegDataKey_CreateKey( data_key, L"Voice3\\Attributes", &attrs_key );
145 ISpDataKey_SetStringValue( attrs_key, L"Language", L"409;411" );
146 ISpDataKey_SetStringValue( attrs_key, L"Gender", L"Female" );
147 ISpDataKey_SetStringValue( attrs_key, L"Age", L"Child" );
148 ISpDataKey_SetStringValue( attrs_key, L"Vendor", L"Vendor1" );
149 ISpDataKey_Release( attrs_key );
151 ISpRegDataKey_CreateKey( data_key, L"Voice4\\Attributes", &attrs_key );
152 ISpDataKey_SetStringValue( attrs_key, L"Language", L"411" );
153 ISpDataKey_SetStringValue( attrs_key, L"Gender", L"Male" );
154 ISpDataKey_SetStringValue( attrs_key, L"Age", L"Adult" );
155 ISpDataKey_Release( attrs_key );
157 ISpRegDataKey_CreateKey( data_key, L"Voice5\\Attributes", &attrs_key );
158 ISpDataKey_SetStringValue( attrs_key, L"Language", L"411" );
159 ISpDataKey_SetStringValue( attrs_key, L"Gender", L"Female" );
160 ISpDataKey_SetStringValue( attrs_key, L"Age", L"Adult" );
161 ISpDataKey_SetStringValue( attrs_key, L"Vendor", L"Vendor2" );
162 ISpDataKey_Release( attrs_key );
164 ISpRegDataKey_Release( data_key );
167 static const WCHAR test_cat[] = L"HKEY_CURRENT_USER\\Software\\Winetest\\sapi\\TestVoices";
169 static void test_token_category(void)
171 ISpObjectTokenCategory *cat;
172 IEnumSpObjectTokens *enum_tokens;
173 HRESULT hr;
174 ULONG count;
175 int i;
176 ISpObjectToken *token;
177 WCHAR *token_id;
178 WCHAR tmp[MAX_PATH];
180 hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
181 &IID_ISpObjectTokenCategory, (void **)&cat );
182 ok( hr == S_OK, "got %08lx\n", hr );
184 hr = ISpObjectTokenCategory_EnumTokens( cat, NULL, NULL, &enum_tokens );
185 ok( hr == SPERR_UNINITIALIZED, "got %08lx\n", hr );
187 hr = ISpObjectTokenCategory_SetId( cat, L"bogus", FALSE );
188 ok( hr == SPERR_INVALID_REGISTRY_KEY, "got %08lx\n", hr );
190 hr = ISpObjectTokenCategory_SetId( cat, test_cat, FALSE );
191 ok( hr == S_OK, "got %08lx\n", hr );
193 hr = ISpObjectTokenCategory_SetId( cat, test_cat, FALSE );
194 ok( hr == SPERR_ALREADY_INITIALIZED, "got %08lx\n", hr );
196 hr = ISpObjectTokenCategory_EnumTokens( cat, NULL, NULL, &enum_tokens );
197 ok( hr == S_OK, "got %08lx\n", hr );
199 count = 0xdeadbeef;
200 hr = IEnumSpObjectTokens_GetCount( enum_tokens, &count );
201 ok( hr == S_OK, "got %08lx\n", hr );
202 ok( count == 5, "got %lu\n", count );
204 IEnumSpObjectTokens_Release( enum_tokens );
206 hr = ISpObjectTokenCategory_EnumTokens( cat, L"Language=409", NULL, &enum_tokens );
207 ok( hr == S_OK, "got %08lx\n", hr );
209 count = 0xdeadbeef;
210 hr = IEnumSpObjectTokens_GetCount( enum_tokens, &count );
211 ok( hr == S_OK, "got %08lx\n", hr );
212 ok( count == 3, "got %lu\n", count );
214 IEnumSpObjectTokens_Release( enum_tokens );
216 hr = ISpObjectTokenCategory_EnumTokens( cat, L"Language=409", L"Vendor=Vendor1;Age=Child;Gender=Female",
217 &enum_tokens );
218 ok( hr == S_OK, "got %08lx\n", hr );
220 count = 0xdeadbeef;
221 hr = IEnumSpObjectTokens_GetCount( enum_tokens, &count );
222 ok( hr == S_OK, "got %08lx\n", hr );
223 ok( count == 3, "got %lu\n", count );
225 for ( i = 0; i < 3; i++ ) {
226 token = NULL;
227 hr = IEnumSpObjectTokens_Item( enum_tokens, i, &token );
228 ok( hr == S_OK, "i = %d: got %08lx\n", i, hr );
230 token_id = NULL;
231 hr = ISpObjectToken_GetId( token, &token_id );
232 ok( hr == S_OK, "i = %d: got %08lx\n", i, hr );
233 swprintf( tmp, MAX_PATH, L"%ls\\Tokens\\Voice%d", test_cat, 3 - i );
234 ok( !wcscmp( token_id, tmp ), "i = %d: got %s\n", i, wine_dbgstr_w(token_id) );
236 CoTaskMemFree( token_id );
237 ISpObjectToken_Release( token );
240 IEnumSpObjectTokens_Release( enum_tokens );
242 ISpObjectTokenCategory_Release( cat );
245 static void test_token_enum(void)
247 ISpObjectTokenEnumBuilder *token_enum;
248 HRESULT hr;
249 ISpObjectToken *tokens[5];
250 ISpObjectToken *out_tokens[5];
251 WCHAR token_id[MAX_PATH];
252 ULONG count;
253 int i;
255 hr = CoCreateInstance( &CLSID_SpObjectTokenEnum, NULL, CLSCTX_INPROC_SERVER,
256 &IID_ISpObjectTokenEnumBuilder, (void **)&token_enum );
257 ok( hr == S_OK, "got %08lx\n", hr );
259 hr = ISpObjectTokenEnumBuilder_GetCount( token_enum, &count );
260 ok( hr == SPERR_UNINITIALIZED, "got %08lx\n", hr );
262 hr = ISpObjectTokenEnumBuilder_Next( token_enum, 1, tokens, &count );
263 ok( hr == SPERR_UNINITIALIZED, "got %08lx\n", hr );
265 hr = ISpObjectTokenEnumBuilder_SetAttribs( token_enum, NULL, NULL );
266 ok( hr == S_OK, "got %08lx\n", hr );
268 count = 0xdeadbeef;
269 hr = ISpObjectTokenEnumBuilder_GetCount( token_enum, &count );
270 ok( hr == S_OK, "got %08lx\n", hr );
271 ok( count == 0, "got %lu\n", count );
273 count = 0xdeadbeef;
274 hr = ISpObjectTokenEnumBuilder_Next( token_enum, 1, &out_tokens[0], &count );
275 ok( hr == S_FALSE, "got %08lx\n", hr );
276 ok( count == 0, "got %lu\n", count );
278 for ( i = 0; i < 5; i++ ) {
279 hr = CoCreateInstance( &CLSID_SpObjectToken, NULL, CLSCTX_INPROC_SERVER,
280 &IID_ISpObjectToken, (void **)&tokens[i] );
281 ok( hr == S_OK, "got %08lx\n", hr );
283 swprintf( token_id, MAX_PATH, L"%ls\\Tokens\\Voice%d", test_cat, i + 1 );
284 hr = ISpObjectToken_SetId( tokens[i], NULL, token_id, FALSE );
285 ok( hr == S_OK, "got %08lx\n", hr );
288 hr = ISpObjectTokenEnumBuilder_AddTokens( token_enum, 3, tokens );
289 ok( hr == S_OK, "got %08lx\n", hr );
291 out_tokens[0] = (ISpObjectToken *)0xdeadbeef;
292 hr = ISpObjectTokenEnumBuilder_Next( token_enum, 1, &out_tokens[0], NULL );
293 ok( hr == S_OK, "got %08lx\n", hr );
294 ok( out_tokens[0] == tokens[0], "got %p\n", out_tokens[0] );
296 out_tokens[0] = (ISpObjectToken *)0xdeadbeef;
297 hr = ISpObjectTokenEnumBuilder_Item( token_enum, 0, &out_tokens[0] );
298 ok( hr == S_OK, "got %08lx\n", hr );
299 ok( out_tokens[0] == tokens[0], "got %p\n", out_tokens[0] );
301 hr = ISpObjectTokenEnumBuilder_Item( token_enum, 3, &out_tokens[0] );
302 ok( hr == SPERR_NO_MORE_ITEMS, "got %08lx\n", hr );
304 hr = ISpObjectTokenEnumBuilder_Next( token_enum, 3, &out_tokens[1], NULL );
305 ok( hr == E_POINTER, "got %08lx\n", hr );
307 count = 0xdeadbeef;
308 out_tokens[1] = out_tokens[2] = (ISpObjectToken *)0xdeadbeef;
309 hr = ISpObjectTokenEnumBuilder_Next( token_enum, 3, &out_tokens[1], &count );
310 ok( hr == S_FALSE, "got %08lx\n", hr );
311 ok( count == 2, "got %lu\n", count );
312 ok( out_tokens[1] == tokens[1], "got %p\n", out_tokens[1] );
313 ok( out_tokens[2] == tokens[2], "got %p\n", out_tokens[2] );
315 ISpObjectTokenEnumBuilder_Release( token_enum );
317 hr = CoCreateInstance( &CLSID_SpObjectTokenEnum, NULL, CLSCTX_INPROC_SERVER,
318 &IID_ISpObjectTokenEnumBuilder, (void **)&token_enum );
319 ok( hr == S_OK, "got %08lx\n", hr );
321 /* Vendor attribute must exist */
322 hr = ISpObjectTokenEnumBuilder_SetAttribs( token_enum, L"Vendor", NULL );
323 ok( hr == S_OK, "got %08lx\n", hr );
324 hr = ISpObjectTokenEnumBuilder_AddTokens( token_enum, 5, tokens );
325 ok( hr == S_OK, "got %08lx\n", hr );
327 count = 0xdeadbeef;
328 hr = ISpObjectTokenEnumBuilder_Next( token_enum, 5, &out_tokens[0], &count );
329 ok( hr == S_FALSE, "got %08lx\n", hr );
330 ok( count == 4, "got %lu\n", count );
332 ISpObjectTokenEnumBuilder_Release( token_enum );
334 hr = CoCreateInstance( &CLSID_SpObjectTokenEnum, NULL, CLSCTX_INPROC_SERVER,
335 &IID_ISpObjectTokenEnumBuilder, (void **)&token_enum );
336 ok( hr == S_OK, "got %08lx\n", hr );
338 /* Vendor attribute must contain Vendor1 */
339 hr = ISpObjectTokenEnumBuilder_SetAttribs( token_enum, L"Vendor=Vendor1", NULL );
340 ok( hr == S_OK, "got %08lx\n", hr );
341 hr = ISpObjectTokenEnumBuilder_AddTokens( token_enum, 5, tokens );
342 ok( hr == S_OK, "got %08lx\n", hr );
344 count = 0xdeadbeef;
345 hr = ISpObjectTokenEnumBuilder_Next( token_enum, 5, &out_tokens[0], &count );
346 ok( hr == S_FALSE, "got %08lx\n", hr );
347 ok( count == 2, "got %lu\n", count );
349 ISpObjectTokenEnumBuilder_Release( token_enum );
351 hr = CoCreateInstance( &CLSID_SpObjectTokenEnum, NULL, CLSCTX_INPROC_SERVER,
352 &IID_ISpObjectTokenEnumBuilder, (void **)&token_enum );
353 ok( hr == S_OK, "got %08lx\n", hr );
355 /* Vendor attribute must not contain Vendor1 */
356 hr = ISpObjectTokenEnumBuilder_SetAttribs( token_enum, L"Vendor!=Vendor1", NULL );
357 ok( hr == S_OK, "got %08lx\n", hr );
358 hr = ISpObjectTokenEnumBuilder_AddTokens( token_enum, 5, tokens );
359 ok( hr == S_OK, "got %08lx\n", hr );
361 count = 0xdeadbeef;
362 hr = ISpObjectTokenEnumBuilder_Next( token_enum, 5, &out_tokens[0], &count );
363 ok( hr == S_FALSE, "got %08lx\n", hr );
364 ok( count == 3, "got %lu\n", count );
366 ISpObjectTokenEnumBuilder_Release( token_enum );
368 hr = CoCreateInstance( &CLSID_SpObjectTokenEnum, NULL, CLSCTX_INPROC_SERVER,
369 &IID_ISpObjectTokenEnumBuilder, (void **)&token_enum );
370 ok( hr == S_OK, "got %08lx\n", hr );
372 /* Vendor attribute must contain Vendor1 and Language attribute must contain 407 */
373 hr = ISpObjectTokenEnumBuilder_SetAttribs( token_enum, L"Vendor=Vendor1;Language=407", NULL );
374 ok( hr == S_OK, "got %08lx\n", hr );
375 hr = ISpObjectTokenEnumBuilder_AddTokens( token_enum, 5, tokens );
376 ok( hr == S_OK, "got %08lx\n", hr );
378 count = 0xdeadbeef;
379 hr = ISpObjectTokenEnumBuilder_Next( token_enum, 5, &out_tokens[0], &count );
380 ok( hr == S_FALSE, "got %08lx\n", hr );
381 ok( count == 1, "got %lu\n", count );
383 hr = CoCreateInstance( &CLSID_SpObjectTokenEnum, NULL, CLSCTX_INPROC_SERVER,
384 &IID_ISpObjectTokenEnumBuilder, (void **)&token_enum );
385 ok( hr == S_OK, "got %08lx\n", hr );
387 hr = ISpObjectTokenEnumBuilder_SetAttribs( token_enum, L"Language=409",
388 L"Vendor=Vendor1;Age=Child;Gender=Female" );
389 ok( hr == S_OK, "got %08lx\n", hr );
390 hr = ISpObjectTokenEnumBuilder_AddTokens( token_enum, 5, tokens );
391 ok( hr == S_OK, "got %08lx\n", hr );
393 hr = ISpObjectTokenEnumBuilder_Sort( token_enum, NULL );
394 ok( hr == S_OK, "got %08lx\n", hr );
396 count = 0xdeadbeef;
397 hr = ISpObjectTokenEnumBuilder_Next( token_enum, 5, &out_tokens[0], &count );
398 ok( hr == S_FALSE, "got %08lx\n", hr );
399 ok( count == 3, "got %lu\n", count );
400 ok( out_tokens[0] == tokens[2], "got %p\n", out_tokens[0] );
401 ok( out_tokens[1] == tokens[1], "got %p\n", out_tokens[1] );
402 ok( out_tokens[2] == tokens[0], "got %p\n", out_tokens[2] );
404 ISpObjectTokenEnumBuilder_Release( token_enum );
406 for ( i = 0; i < 5; i++ ) ISpObjectToken_Release( tokens[i] );
409 static void test_default_token_id(void)
411 ISpObjectTokenCategory *cat;
412 HRESULT hr;
413 LPWSTR token_id = NULL;
414 LONG res;
415 WCHAR regvalue[512];
416 DWORD regvalue_size;
418 hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
419 &IID_ISpObjectTokenCategory, (void **)&cat );
420 ok( hr == S_OK, "got %08lx\n", hr );
422 token_id = (LPWSTR)0xdeadbeef;
423 hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
424 ok( hr == SPERR_UNINITIALIZED, "got %08lx\n", hr );
425 ok( token_id == (LPWSTR)0xdeadbeef, "got %p\n", token_id );
427 hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, NULL );
428 ok( hr == SPERR_UNINITIALIZED, "got %08lx\n", hr );
430 hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
431 ok( hr == S_OK, "got %08lx\n", hr );
433 hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, NULL );
434 ok( hr == E_POINTER, "got %08lx\n", hr );
436 token_id = (LPWSTR)0xdeadbeef;
437 hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
439 /* AudioOutput under windows server returns this error */
440 if (hr == SPERR_NOT_FOUND) {
441 /* also happens if TokenEnums/Tokens is empty or doesn't exist */
442 skip( "AudioOutput category not found for GetDefaultTokenId\n" );
443 return;
446 ok( hr == S_OK, "got %08lx\n", hr );
447 ok( token_id != (LPWSTR)0xdeadbeef && token_id != NULL, "got %p\n", token_id );
449 regvalue_size = sizeof( regvalue );
450 res = RegGetValueW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput",
451 L"DefaultDefaultTokenId", RRF_RT_REG_SZ, NULL,
452 (LPVOID)&regvalue, &regvalue_size);
453 if (res == ERROR_FILE_NOT_FOUND) {
454 skip( "DefaultDefaultTokenId not found for AudioOutput category (%s)\n",
455 wine_dbgstr_w(token_id) );
456 } else {
457 ok( res == ERROR_SUCCESS, "got %08lx\n", res );
458 ok( !wcscmp(regvalue, token_id),
459 "GetDefaultTokenId (%s) should be equal to the DefaultDefaultTokenId key (%s)\n",
460 wine_dbgstr_w(token_id), wine_dbgstr_w(regvalue) );
463 CoTaskMemFree( token_id );
464 ISpObjectTokenCategory_Release( cat );
467 static void tests_token_voices(void)
469 ISpObjectTokenCategory *cat;
470 HRESULT hr;
471 IEnumSpObjectTokens *tokens;
472 ISpObjectToken *item;
473 ULONG fetched = 0;
474 ULONG count;
476 hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
477 &IID_ISpObjectTokenCategory, (void **)&cat );
478 ok( hr == S_OK, "got %08lx\n", hr );
480 hr = ISpObjectTokenCategory_SetId( cat, SPCAT_VOICES, FALSE );
481 ok( hr == S_OK, "got %08lx\n", hr );
483 hr = ISpObjectTokenCategory_EnumTokens(cat, NULL, NULL, &tokens);
484 ok( hr == S_OK, "got %08lx\n", hr );
486 hr = IEnumSpObjectTokens_GetCount( tokens, &count );
487 ok( hr == S_OK, "got %08lx\n", hr );
488 ok( count != 0, "got %lu\n", count );
489 ISpObjectTokenCategory_Release( cat );
491 hr = IEnumSpObjectTokens_Item(tokens, 0, &item);
492 ok( hr == S_OK, "got %08lx\n", hr );
493 ISpObjectToken_Release(item);
495 hr = IEnumSpObjectTokens_Next(tokens, 1, &item, &fetched);
496 ok( hr == S_OK, "got %08lx\n", hr );
497 ISpObjectToken_Release(item);
499 IEnumSpObjectTokens_Release(tokens);
503 #define TESTCLASS_CLSID L"{67DD26B6-50BA-3297-253E-619346F177F8}"
504 static const GUID CLSID_TestClass = {0x67DD26B6,0x50BA,0x3297,{0x25,0x3E,0x61,0x93,0x46,0xF1,0x77,0xF8}};
506 static ISpObjectToken *test_class_token;
508 static HRESULT WINAPI test_class_QueryInterface(ISpObjectWithToken *iface, REFIID riid, void **ppv)
510 if (IsEqualGUID( riid, &IID_IUnknown ) || IsEqualGUID( riid, &IID_ISpObjectWithToken ))
512 *ppv = iface;
513 return S_OK;
516 *ppv = NULL;
517 return E_NOINTERFACE;
520 static ULONG WINAPI test_class_AddRef(ISpObjectWithToken *iface)
522 return 2;
525 static ULONG WINAPI test_class_Release(ISpObjectWithToken *iface)
527 return 1;
530 static HRESULT WINAPI test_class_SetObjectToken(ISpObjectWithToken *iface, ISpObjectToken *token)
532 ok( token != NULL, "token == NULL\n" );
533 test_class_token = token;
534 ISpObjectToken_AddRef(test_class_token);
535 return S_OK;
538 static HRESULT WINAPI test_class_GetObjectToken(ISpObjectWithToken *iface, ISpObjectToken **token)
540 ok( 0, "unexpected call\n" );
541 return E_NOTIMPL;
544 static const ISpObjectWithTokenVtbl test_class_vtbl = {
545 test_class_QueryInterface,
546 test_class_AddRef,
547 test_class_Release,
548 test_class_SetObjectToken,
549 test_class_GetObjectToken
552 static ISpObjectWithToken test_class = { &test_class_vtbl };
554 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
556 if (IsEqualGUID( &IID_IUnknown, riid ) || IsEqualGUID( &IID_IClassFactory, riid ))
558 *ppv = iface;
559 return S_OK;
562 *ppv = NULL;
563 return E_NOINTERFACE;
566 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
568 return 2;
571 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
573 return 1;
576 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface,
577 IUnknown *pUnkOuter, REFIID riid, void **ppv)
579 ok( pUnkOuter == NULL, "pUnkOuter != NULL\n" );
580 ok( IsEqualGUID(riid, &IID_IUnknown), "riid = %s\n", wine_dbgstr_guid(riid) );
582 *ppv = &test_class;
583 return S_OK;
586 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
588 ok( 0, "unexpected call\n" );
589 return E_NOTIMPL;
592 static const IClassFactoryVtbl ClassFactoryVtbl = {
593 ClassFactory_QueryInterface,
594 ClassFactory_AddRef,
595 ClassFactory_Release,
596 ClassFactory_CreateInstance,
597 ClassFactory_LockServer
600 static IClassFactory test_class_cf = { &ClassFactoryVtbl };
602 static void test_object_token(void)
604 static const WCHAR test_token_id[] = L"HKEY_LOCAL_MACHINE\\Software\\Wine\\Winetest\\sapi\\TestToken";
606 ISpObjectToken *token;
607 ISpDataKey *sub_key;
608 HRESULT hr;
609 LPWSTR tempW, token_id;
610 ISpObjectTokenCategory *cat;
611 DWORD regid;
612 IUnknown *obj;
614 hr = CoCreateInstance( &CLSID_SpObjectToken, NULL, CLSCTX_INPROC_SERVER,
615 &IID_ISpObjectToken, (void **)&token );
616 ok( hr == S_OK, "got %08lx\n", hr );
618 hr = ISpObjectToken_GetId( token, NULL );
619 ok( hr == SPERR_UNINITIALIZED, "got %08lx\n", hr );
621 tempW = (LPWSTR)0xdeadbeef;
622 hr = ISpObjectToken_GetId( token, &tempW );
623 ok( hr == SPERR_UNINITIALIZED, "got %08lx\n", hr );
624 ok( tempW == (LPWSTR)0xdeadbeef, "got %s\n", wine_dbgstr_w(tempW) );
626 hr = ISpObjectToken_GetCategory( token, NULL );
627 todo_wine ok( hr == SPERR_UNINITIALIZED, "got %08lx\n", hr );
629 cat = (LPVOID)0xdeadbeef;
630 hr = ISpObjectToken_GetCategory( token, &cat );
631 todo_wine ok( hr == SPERR_UNINITIALIZED, "got %08lx\n", hr );
632 ok( cat == (LPVOID)0xdeadbeef, "got %p\n", cat );
634 hr = ISpObjectToken_SetId( token, NULL, NULL, FALSE );
635 ok( hr == E_POINTER, "got %08lx\n", hr );
636 hr = ISpObjectToken_SetId( token, L"bogus", NULL, FALSE );
637 ok( hr == E_POINTER, "got %08lx\n", hr );
639 hr = ISpObjectToken_SetId( token, NULL, L"bogus", FALSE );
640 ok( hr == SPERR_NOT_FOUND, "got %08lx\n", hr );
641 hr = ISpObjectToken_SetId( token, NULL, L"HKEY_LOCAL_MACHINE\\SOFTWARE\\winetest bogus", FALSE );
642 ok( hr == SPERR_NOT_FOUND, "got %08lx\n", hr );
644 /* SetId succeeds even if the key is invalid, but exists */
645 hr = ISpObjectToken_SetId( token, NULL, L"HKEY_LOCAL_MACHINE\\SOFTWARE", FALSE );
646 ok( hr == S_OK, "got %08lx\n", hr );
648 hr = ISpObjectToken_SetId( token, NULL, NULL, FALSE );
649 ok( hr == SPERR_ALREADY_INITIALIZED, "got %08lx\n", hr );
650 hr = ISpObjectToken_SetId( token, NULL, L"bogus", FALSE );
651 ok( hr == SPERR_ALREADY_INITIALIZED, "got %08lx\n", hr );
653 hr = ISpObjectToken_GetId( token, NULL );
654 ok( hr == E_POINTER, "got %08lx\n", hr );
656 hr = ISpObjectToken_GetCategory( token, NULL );
657 todo_wine ok( hr == E_POINTER, "got %08lx\n", hr );
659 tempW = NULL;
660 hr = ISpObjectToken_GetId( token, &tempW );
661 ok( hr == S_OK, "got %08lx\n", hr );
662 ok( tempW != NULL, "got %p\n", tempW );
663 if (tempW) {
664 ok( !wcscmp(tempW, L"HKEY_LOCAL_MACHINE\\SOFTWARE"), "got %s\n",
665 wine_dbgstr_w(tempW) );
666 CoTaskMemFree( tempW );
669 hr = ISpObjectToken_OpenKey(token, L"Non-exist", &sub_key);
670 ok( hr == SPERR_NOT_FOUND, "got %08lx\n", hr );
672 hr = ISpObjectToken_OpenKey(token, L"Classes", &sub_key);
673 ok( hr == S_OK, "got %08lx\n", hr );
674 ISpDataKey_Release(sub_key);
676 cat = (LPVOID)0xdeadbeef;
677 hr = ISpObjectToken_GetCategory( token, &cat );
678 todo_wine ok( hr == SPERR_INVALID_REGISTRY_KEY, "got %08lx\n", hr );
679 ok( cat == (LPVOID)0xdeadbeef, "got %p\n", cat );
681 /* get the default token id for SPCAT_AUDIOOUT */
682 hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
683 &IID_ISpObjectTokenCategory, (void **)&cat );
684 ok( hr == S_OK, "got %08lx\n", hr );
685 hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
686 ok( hr == S_OK, "got %08lx\n", hr );
687 token_id = (LPWSTR)0xdeadbeef;
688 hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
689 if (hr == SPERR_NOT_FOUND) {
690 skip( "AudioOutput category not found for GetDefaultTokenId\n" );
691 return;
693 ok( hr == S_OK, "got %08lx\n", hr );
694 ok( token_id != (LPWSTR)0xdeadbeef && token_id != NULL, "got %p\n", token_id );
695 ISpObjectTokenCategory_Release( cat );
697 /* recreate token in order to SetId again */
698 ISpObjectToken_Release( token );
699 hr = CoCreateInstance( &CLSID_SpObjectToken, NULL, CLSCTX_INPROC_SERVER,
700 &IID_ISpObjectToken, (void **)&token );
701 ok( hr == S_OK, "got %08lx\n", hr );
703 /* NULL appears to auto-detect the category */
704 hr = ISpObjectToken_SetId( token, NULL, token_id, FALSE );
705 ok( hr == S_OK, "got %08lx\n", hr );
707 tempW = NULL;
708 hr = ISpObjectToken_GetId( token, &tempW );
709 ok( hr == S_OK, "got %08lx\n", hr );
710 ok( tempW != NULL, "got %p\n", tempW );
711 if (tempW) {
712 ok( !wcsncmp(tempW, token_id, wcslen(token_id)),
713 "got %s (expected %s)\n", wine_dbgstr_w(tempW), wine_dbgstr_w(token_id) );
714 CoTaskMemFree( tempW );
717 cat = (LPVOID)0xdeadbeef;
718 hr = ISpObjectToken_GetCategory( token, &cat );
719 todo_wine ok( hr == S_OK, "got %08lx\n", hr );
720 todo_wine ok( cat != (LPVOID)0xdeadbeef, "got %p\n", cat );
721 if (cat != (LPVOID)0xdeadbeef) {
722 tempW = NULL;
723 hr = ISpObjectTokenCategory_GetId( cat, &tempW );
724 todo_wine ok( hr == S_OK, "got %08lx\n", hr );
725 todo_wine ok( tempW != NULL, "got %p\n", tempW );
726 if (tempW) {
727 ok( !wcscmp(tempW, SPCAT_AUDIOOUT), "got %s\n", wine_dbgstr_w(tempW) );
728 CoTaskMemFree( tempW );
731 /* not freed by ISpObjectToken_Release */
732 ISpObjectTokenCategory_Release( cat );
735 hr = CoRegisterClassObject( &CLSID_TestClass, (IUnknown *)&test_class_cf,
736 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid );
737 ok( hr == S_OK, "got %08lx\n", hr );
739 ISpObjectToken_Release( token );
740 hr = CoCreateInstance( &CLSID_SpObjectToken, NULL, CLSCTX_INPROC_SERVER,
741 &IID_ISpObjectToken, (void **)&token );
742 ok( hr == S_OK, "got %08lx\n", hr );
744 hr = ISpObjectToken_SetId( token, NULL, test_token_id, TRUE );
745 ok( hr == S_OK || broken(hr == E_ACCESSDENIED) /* win1064_adm */, "got %08lx\n", hr );
746 if (hr == E_ACCESSDENIED) {
747 win_skip( "token SetId access denied\n" );
748 ISpObjectToken_Release( token );
749 return;
752 hr = ISpObjectToken_CreateKey( token, L"Attributes", &sub_key );
753 ok( hr == S_OK, "got %08lx\n", hr );
754 ISpDataKey_Release( sub_key );
756 hr = ISpObjectToken_SetStringValue( token, L"CLSID", TESTCLASS_CLSID );
757 ok( hr == S_OK, "got %08lx\n", hr );
759 tempW = NULL;
760 hr = ISpObjectToken_GetStringValue( token, L"CLSID", &tempW );
762 ok( hr == S_OK, "got %08lx\n", hr );
763 if ( tempW ) {
764 ok( !wcsncmp( tempW, TESTCLASS_CLSID, wcslen(TESTCLASS_CLSID) ),
765 "got %s (expected %s)\n", wine_dbgstr_w(tempW), wine_dbgstr_w(TESTCLASS_CLSID) );
766 CoTaskMemFree( tempW );
769 test_class_token = NULL;
770 hr = ISpObjectToken_CreateInstance( token, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&obj );
771 ok( hr == S_OK, "got %08lx\n", hr );
772 ok( test_class_token != NULL, "test_class_token not set\n" );
774 tempW = NULL;
775 hr = ISpObjectToken_GetId( test_class_token, &tempW );
776 ok( tempW != NULL, "got %p\n", tempW );
777 if (tempW) {
778 ok( !wcsncmp(tempW, test_token_id, wcslen(test_token_id)),
779 "got %s (expected %s)\n", wine_dbgstr_w(tempW), wine_dbgstr_w(test_token_id) );
780 CoTaskMemFree( tempW );
783 ISpObjectToken_Release( test_class_token );
784 IUnknown_Release( obj );
785 ISpObjectToken_Release( token );
788 START_TEST(token)
790 CoInitialize( NULL );
791 RegDeleteTreeA( HKEY_CURRENT_USER, "Software\\Winetest\\sapi" );
792 test_data_key();
793 setup_test_voice_tokens();
794 test_token_category();
795 test_token_enum();
796 test_default_token_id();
797 test_object_token();
798 tests_token_voices();
799 CoUninitialize();