Declaration, implemention and test for BuildTrusteeWithSid.
[wine] / dlls / dsound / tests / dsound8.c
1 /*
2  * Tests basic sound playback in DirectSound.
3  * In particular we test each standard Windows sound format to make sure
4  * we handle the sound card/driver quirks correctly.
5  *
6  * Part of this test involves playing test tones. But this only makes
7  * sense if someone is going to carefully listen to it, and would only
8  * bother everyone else.
9  * So this is only done if the test is being run in interactive mode.
10  *
11  * Copyright (c) 2002-2004 Francois Gouget
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2.1 of the License, or (at your option) any later version.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  * Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with this library; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27
28 #define NONAMELESSSTRUCT
29 #define NONAMELESSUNION
30 #include <windows.h>
31
32 #include <math.h>
33 #include <stdlib.h>
34
35 #include "wine/test.h"
36 #include "windef.h"
37 #include "wingdi.h"
38 #include "dsound.h"
39 #include "dxerr8.h"
40 #include "dsconf.h"
41
42 #include "dsound_test.h"
43
44 static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized,
45                                LPCGUID lpGuid)
46 {
47     HRESULT rc;
48     DSCAPS dscaps;
49     int ref;
50     IUnknown * unknown;
51     IDirectSound * ds;
52     IDirectSound8 * ds8;
53     DWORD speaker_config, new_speaker_config;
54     DWORD certified;
55
56     /* Try to Query for objects */
57     rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
58     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",
59        DXGetErrorString8(rc));
60     if (rc==DS_OK)
61         IDirectSound8_Release(unknown);
62
63     rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
64     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",
65        DXGetErrorString8(rc));
66     if (rc==DS_OK)
67         IDirectSound_Release(ds);
68
69     rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
70     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
71        "should have returned DSERR_INVALIDPARAM, returned: %s\n",
72        DXGetErrorString8(rc));
73     if (rc==DS_OK)
74         IDirectSound8_Release(ds8);
75
76     if (initialized == FALSE) {
77         /* try unitialized object */
78         rc=IDirectSound8_GetCaps(dso,0);
79         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps(NULL) "
80            "should have returned DSERR_UNINITIALIZED, returned: %s\n",
81            DXGetErrorString8(rc));
82
83         rc=IDirectSound8_GetCaps(dso,&dscaps);
84         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps() "
85            "should have returned DSERR_UNINITIALIZED, returned: %s\n",
86            DXGetErrorString8(rc));
87
88         rc=IDirectSound8_Compact(dso);
89         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_Compact() "
90            "should have returned DSERR_UNINITIALIZED, returned: %s\n",
91            DXGetErrorString8(rc));
92
93         rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
94         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetSpeakerConfig() "
95            "should have returned DSERR_UNINITIALIZED, returned: %s\n",
96            DXGetErrorString8(rc));
97
98         rc=IDirectSound8_VerifyCertification(dso, &certified);
99         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_VerifyCertification() "
100            "should have returned DSERR_UNINITIALIZED, returned: %s\n",
101            DXGetErrorString8(rc));
102
103         rc=IDirectSound8_Initialize(dso,lpGuid);
104         ok(rc==DS_OK,"IDirectSound8_Initialize() failed: %s\n",
105            DXGetErrorString8(rc));
106     }
107
108     /* DSOUND: Error: Invalid caps buffer */
109     rc=IDirectSound8_GetCaps(dso,0);
110     ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
111        "should have returned DSERR_INVALIDPARAM, returned: %s\n",
112        DXGetErrorString8(rc));
113
114     ZeroMemory(&dscaps, sizeof(dscaps));
115
116     /* DSOUND: Error: Invalid caps buffer */
117     rc=IDirectSound8_GetCaps(dso,&dscaps);
118     ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
119        "should have returned DSERR_INVALIDPARAM, returned: %s\n",
120        DXGetErrorString8(rc));
121
122     dscaps.dwSize=sizeof(dscaps);
123
124     /* DSOUND: Running on a certified driver */
125     rc=IDirectSound8_GetCaps(dso,&dscaps);
126     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
127
128     rc=IDirectSound8_Compact(dso);
129     ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
130        DXGetErrorString8(rc));
131
132     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
133     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
134        DXGetErrorString8(rc));
135
136     rc=IDirectSound8_Compact(dso);
137     ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));
138
139     rc=IDirectSound8_GetSpeakerConfig(dso,0);
140     ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
141        "should have returned DSERR_INVALIDPARAM, returned: %s\n",
142        DXGetErrorString8(rc));
143
144     rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
145     ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
146        DXGetErrorString8(rc));
147
148     speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
149                                         DSSPEAKER_GEOMETRY_WIDE);
150     rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
151     ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
152        DXGetErrorString8(rc));
153     if (rc==DS_OK) {
154         rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
155         ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
156            DXGetErrorString8(rc));
157         if (rc==DS_OK)
158             ok(speaker_config==new_speaker_config,
159                "IDirectSound8_GetSpeakerConfig() failed to set speaker config: "
160                "expected 0x%08lx, got 0x%08lx\n",
161                speaker_config,new_speaker_config);
162     }
163
164     rc=IDirectSound8_VerifyCertification(dso, &certified);
165     ok(rc==DS_OK,"IDirectSound8_VerifyCertification() failed: %s\n",
166        DXGetErrorString8(rc));
167
168     ref=IDirectSound8_Release(dso);
169     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
170 }
171
172 static void IDirectSound8_tests()
173 {
174     HRESULT rc;
175     LPDIRECTSOUND8 dso=NULL;
176
177     trace("Testing IDirectSound8\n");
178
179     /* try the COM class factory method of creation with no device specified */
180     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
181                         &IID_IDirectSound8, (void**)&dso);
182     ok(rc==S_OK,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc));
183     if (dso)
184         IDirectSound8_test(dso, FALSE, NULL);
185
186     /* try the COM class factory method of creation with default playback
187      *  device specified */
188     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
189                         &IID_IDirectSound8, (void**)&dso);
190     ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
191        DXGetErrorString8(rc));
192     if (dso)
193         IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
194
195     /* try the COM class factory method of creation with default voice
196      * playback device specified */
197     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
198                         &IID_IDirectSound8, (void**)&dso);
199     ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
200        DXGetErrorString8(rc));
201     if (dso)
202         IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
203
204     /* try the COM class factory method of creation with a bad
205      * IID specified */
206     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
207                         &CLSID_DirectSoundPrivate, (void**)&dso);
208     ok(rc==E_NOINTERFACE,
209        "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
210        "should have failed: %s\n",DXGetErrorString8(rc));
211
212     /* try the COM class factory method of creation with a bad
213      * GUID and IID specified */
214     rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
215                         &IID_IDirectSound8, (void**)&dso);
216     ok(rc==REGDB_E_CLASSNOTREG,
217        "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
218        "should have failed: %s\n",DXGetErrorString8(rc));
219
220     /* try with no device specified */
221     rc=DirectSoundCreate8(NULL,&dso,NULL);
222     ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
223     if (dso)
224         IDirectSound8_test(dso, TRUE, NULL);
225
226     /* try with default playback device specified */
227     rc=DirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
228     ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
229     if (dso)
230         IDirectSound8_test(dso, TRUE, NULL);
231
232     /* try with default voice playback device specified */
233     rc=DirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
234     ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
235     if (dso)
236         IDirectSound8_test(dso, TRUE, NULL);
237
238     /* try with a bad device specified */
239     rc=DirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
240     ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
241        "should have failed: %s\n",DXGetErrorString8(rc));
242 }
243
244 static HRESULT test_dsound8(LPGUID lpGuid)
245 {
246     HRESULT rc;
247     LPDIRECTSOUND8 dso=NULL;
248     int ref;
249
250     /* DSOUND: Error: Invalid interface buffer */
251     rc=DirectSoundCreate8(lpGuid,0,NULL);
252     ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
253        "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
254
255     /* Create the DirectSound8 object */
256     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
257     ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
258     if (rc!=DS_OK)
259         return rc;
260
261     /* Try the enumerated device */
262     IDirectSound8_test(dso, TRUE, lpGuid);
263
264     /* Try the COM class factory method of creation with enumerated device */
265     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
266                         &IID_IDirectSound8, (void**)&dso);
267     ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
268        DXGetErrorString8(rc));
269     if (dso)
270         IDirectSound8_test(dso, FALSE, lpGuid);
271
272     /* Create a DirectSound8 object */
273     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
274     ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
275     if (rc==DS_OK) {
276         LPDIRECTSOUND8 dso1=NULL;
277
278         /* Create a second DirectSound8 object */
279         rc=DirectSoundCreate8(lpGuid,&dso1,NULL);
280         ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
281         if (rc==DS_OK) {
282             /* Release the second DirectSound8 object */
283             ref=IDirectSound8_Release(dso1);
284             ok(ref==0,"IDirectSound8_Release() has %d references, "
285                "should have 0\n",ref);
286             ok(dso!=dso1,"DirectSound8 objects should be unique: "
287                "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
288         }
289
290         /* Release the first DirectSound8 object */
291         ref=IDirectSound8_Release(dso);
292         ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
293            ref);
294         if (ref!=0)
295             return DSERR_GENERIC;
296     } else
297         return rc;
298
299     /* Create a DirectSound8 object */
300     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
301     ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
302     if (rc==DS_OK) {
303         LPDIRECTSOUNDBUFFER secondary;
304         DSBUFFERDESC bufdesc;
305         WAVEFORMATEX wfx;
306
307         init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
308         ZeroMemory(&bufdesc, sizeof(bufdesc));
309         bufdesc.dwSize=sizeof(bufdesc);
310         bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
311         bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
312         bufdesc.lpwfxFormat=&wfx;
313         rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
314         ok(rc==DS_OK && secondary!=NULL,
315            "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
316            "buffer: %s\n",DXGetErrorString8(rc));
317         if (rc==DS_OK && secondary!=NULL) {
318             LPDIRECTSOUND3DBUFFER buffer3d;
319             LPDIRECTSOUNDBUFFER8 buffer8;
320             rc=IDirectSound8_QueryInterface(secondary,
321                                             &IID_IDirectSound3DBuffer,
322                                             (void **)&buffer3d);
323             ok(rc==DS_OK && buffer3d!=NULL,
324                "IDirectSound8_QueryInterface() failed: %s\n",
325                DXGetErrorString8(rc));
326             if (rc==DS_OK && buffer3d!=NULL) {
327                 ref=IDirectSound3DBuffer_AddRef(buffer3d);
328                 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
329                    "should have 2\n",ref);
330             }
331             rc=IDirectSound8_QueryInterface(secondary,
332                                             &IID_IDirectSoundBuffer8,
333                                             (void **)&buffer8);
334             if (rc==DS_OK && buffer8!=NULL) {
335                 ref=IDirectSoundBuffer8_AddRef(buffer8);
336                 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
337                    "should have 3\n",ref);
338             }
339             ref=IDirectSoundBuffer_AddRef(secondary);
340             ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
341                "should have 4\n",ref);
342         }
343         /* release with buffer */
344         ref=IDirectSound8_Release(dso);
345         ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
346            ref);
347         if (ref!=0)
348             return DSERR_GENERIC;
349     } else
350         return rc;
351
352     return DS_OK;
353 }
354
355 static HRESULT test_primary8(LPGUID lpGuid)
356 {
357     HRESULT rc;
358     LPDIRECTSOUND8 dso=NULL;
359     LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
360     DSBUFFERDESC bufdesc;
361     DSCAPS dscaps;
362     int ref;
363
364     /* Create the DirectSound object */
365     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
366     ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
367     if (rc!=DS_OK)
368         return rc;
369
370     /* Get the device capabilities */
371     ZeroMemory(&dscaps, sizeof(dscaps));
372     dscaps.dwSize=sizeof(dscaps);
373     rc=IDirectSound8_GetCaps(dso,&dscaps);
374     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
375     if (rc!=DS_OK)
376         goto EXIT;
377
378     /* DSOUND: Error: Invalid buffer description pointer */
379     rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
380     ok(rc==DSERR_INVALIDPARAM,
381        "IDirectSound8_CreateSoundBuffer should have returned "
382        "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
383
384     /* DSOUND: Error: Invalid buffer description pointer */
385     rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
386     ok(rc==DSERR_INVALIDPARAM && primary==0,
387        "IDirectSound8_CreateSoundBuffer() should have returned "
388        "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=0x%lx\n",
389        DXGetErrorString8(rc),(DWORD)primary);
390
391     /* DSOUND: Error: Invalid buffer description pointer */
392     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
393     ok(rc==DSERR_INVALIDPARAM && primary==0,
394        "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
395        "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
396
397     ZeroMemory(&bufdesc, sizeof(bufdesc));
398
399     /* DSOUND: Error: Invalid size */
400     /* DSOUND: Error: Invalid buffer description */
401     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
402     ok(rc==DSERR_INVALIDPARAM && primary==0,
403        "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
404        "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
405
406     /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
407     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
408     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
409     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
410        DXGetErrorString8(rc));
411     if (rc!=DS_OK)
412         goto EXIT;
413
414     /* Testing the primary buffer */
415     primary=NULL;
416     ZeroMemory(&bufdesc, sizeof(bufdesc));
417     bufdesc.dwSize=sizeof(bufdesc);
418     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
419     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
420     ok(rc==DS_OK && primary!=NULL,
421        "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
422        "%s\n",DXGetErrorString8(rc));
423     if (rc==DS_OK && primary!=NULL) {
424         LONG vol;
425
426         /* Try to create a second primary buffer */
427         /* DSOUND: Error: The primary buffer already exists.
428          * Any changes made to the buffer description will be ignored. */
429         rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
430         ok(rc==DS_OK && second==primary,
431            "IDirectSound8_CreateSoundBuffer() should have returned original "
432            "primary buffer: %s\n",DXGetErrorString8(rc));
433         ref=IDirectSoundBuffer_Release(second);
434         ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
435            "should have 1\n",ref);
436
437         /* Try to duplicate a primary buffer */
438         /* DSOUND: Error: Can't duplicate primary buffers */
439         rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
440         /* rc=0x88780032 */
441         ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
442            "should have failed %s\n",DXGetErrorString8(rc));
443
444         rc=IDirectSoundBuffer_GetVolume(primary,&vol);
445         ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
446            DXGetErrorString8(rc));
447
448         if (winetest_interactive) {
449             trace("Playing a 5 seconds reference tone at the current volume.\n");
450             if (rc==DS_OK)
451                 trace("(the current volume is %ld according to DirectSound)\n",
452                       vol);
453             trace("All subsequent tones should be identical to this one.\n");
454             trace("Listen for stutter, changes in pitch, volume, etc.\n");
455         }
456         test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
457                      !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
458
459         ref=IDirectSoundBuffer_Release(primary);
460         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
461            "should have 0\n",ref);
462     }
463
464     /* Set the CooperativeLevel back to normal */
465     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
466     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
467     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
468        DXGetErrorString8(rc));
469
470 EXIT:
471     ref=IDirectSound8_Release(dso);
472     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
473     if (ref!=0)
474         return DSERR_GENERIC;
475
476     return rc;
477 }
478
479 /*
480  * Test the primary buffer at different formats while keeping the
481  * secondary buffer at a constant format.
482  */
483 static HRESULT test_primary_secondary8(LPGUID lpGuid)
484 {
485     HRESULT rc;
486     LPDIRECTSOUND8 dso=NULL;
487     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
488     DSBUFFERDESC bufdesc;
489     DSCAPS dscaps;
490     WAVEFORMATEX wfx, wfx2;
491     int f,ref;
492
493     /* Create the DirectSound object */
494     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
495     ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
496     if (rc!=DS_OK)
497         return rc;
498
499     /* Get the device capabilities */
500     ZeroMemory(&dscaps, sizeof(dscaps));
501     dscaps.dwSize=sizeof(dscaps);
502     rc=IDirectSound8_GetCaps(dso,&dscaps);
503     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
504     if (rc!=DS_OK)
505         goto EXIT;
506
507     /* We must call SetCooperativeLevel before creating primary buffer */
508     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
509     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
510     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
511        DXGetErrorString8(rc));
512     if (rc!=DS_OK)
513         goto EXIT;
514
515     ZeroMemory(&bufdesc, sizeof(bufdesc));
516     bufdesc.dwSize=sizeof(bufdesc);
517     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
518     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
519     ok(rc==DS_OK && primary!=NULL,
520        "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
521        "%s\n",DXGetErrorString8(rc));
522
523     if (rc==DS_OK && primary!=NULL) {
524         for (f=0;f<NB_FORMATS;f++) {
525             /* We must call SetCooperativeLevel to be allowed to call SetFormat */
526             /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
527             rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
528             ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
529                DXGetErrorString8(rc));
530             if (rc!=DS_OK)
531                 goto EXIT;
532
533             init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
534                         formats[f][2]);
535             wfx2=wfx;
536             rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
537             ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
538                DXGetErrorString8(rc));
539
540             /* There is no garantee that SetFormat will actually change the
541              * format to what we asked for. It depends on what the soundcard
542              * supports. So we must re-query the format.
543              */
544             rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
545             ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
546                DXGetErrorString8(rc));
547             if (rc==DS_OK &&
548                 (wfx.wFormatTag!=wfx2.wFormatTag ||
549                  wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
550                  wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
551                  wfx.nChannels!=wfx2.nChannels)) {
552                 trace("Requested primary format tag=0x%04x %ldx%dx%d "
553                       "avg.B/s=%ld align=%d\n",
554                       wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
555                       wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
556                 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
557                       wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
558                       wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
559             }
560
561             /* Set the CooperativeLevel back to normal */
562             /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
563             rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
564             ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
565                DXGetErrorString8(rc));
566
567             init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
568
569             secondary=NULL;
570             ZeroMemory(&bufdesc, sizeof(bufdesc));
571             bufdesc.dwSize=sizeof(bufdesc);
572             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
573             bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
574             bufdesc.lpwfxFormat=&wfx2;
575             if (winetest_interactive) {
576                 trace("  Testing a primary buffer at %ldx%dx%d with a "
577                       "secondary buffer at %ldx%dx%d\n",
578                       wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
579                       wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
580             }
581             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
582             ok(rc==DS_OK && secondary!=NULL,
583                "IDirectSound_CreateSoundBuffer() failed to create a secondary "
584                "buffer %s\n",DXGetErrorString8(rc));
585
586             if (rc==DS_OK && secondary!=NULL) {
587                 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
588                              winetest_interactive,1.0,0,NULL,0,0);
589
590                 ref=IDirectSoundBuffer_Release(secondary);
591                 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
592                    "should have 0\n",ref);
593             }
594         }
595
596         ref=IDirectSoundBuffer_Release(primary);
597         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
598            "should have 0\n",ref);
599     }
600
601     /* Set the CooperativeLevel back to normal */
602     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
603     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
604     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
605        DXGetErrorString8(rc));
606
607 EXIT:
608     ref=IDirectSound8_Release(dso);
609     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
610     if (ref!=0)
611         return DSERR_GENERIC;
612
613     return rc;
614 }
615
616 static HRESULT test_secondary8(LPGUID lpGuid)
617 {
618     HRESULT rc;
619     LPDIRECTSOUND8 dso=NULL;
620     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
621     DSBUFFERDESC bufdesc;
622     DSCAPS dscaps;
623     WAVEFORMATEX wfx;
624     DWORD f;
625     int ref;
626
627     /* Create the DirectSound object */
628     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
629     ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
630     if (rc!=DS_OK)
631         return rc;
632
633     /* Get the device capabilities */
634     ZeroMemory(&dscaps, sizeof(dscaps));
635     dscaps.dwSize=sizeof(dscaps);
636     rc=IDirectSound8_GetCaps(dso,&dscaps);
637     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
638     if (rc!=DS_OK)
639         goto EXIT;
640
641     /* We must call SetCooperativeLevel before creating primary buffer */
642     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
643     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
644     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
645        DXGetErrorString8(rc));
646     if (rc!=DS_OK)
647         goto EXIT;
648
649     ZeroMemory(&bufdesc, sizeof(bufdesc));
650     bufdesc.dwSize=sizeof(bufdesc);
651     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
652     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
653     ok(rc==DS_OK && primary!=NULL,
654        "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
655        "%s\n",DXGetErrorString8(rc));
656
657     if (rc==DS_OK && primary!=NULL) {
658         for (f=0;f<NB_FORMATS;f++) {
659             init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
660                         formats[f][2]);
661             secondary=NULL;
662             ZeroMemory(&bufdesc, sizeof(bufdesc));
663             bufdesc.dwSize=sizeof(bufdesc);
664             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
665             bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
666             bufdesc.lpwfxFormat=&wfx;
667             if (winetest_interactive) {
668                 trace("  Testing a secondary buffer at %ldx%dx%d\n",
669                       wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
670             }
671             rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
672             ok(rc==DS_OK && secondary!=NULL,
673                "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
674                "buffer: %s\n",DXGetErrorString8(rc));
675
676             if (rc==DS_OK && secondary!=NULL) {
677                 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
678                              winetest_interactive,1.0,0,NULL,0,0);
679
680                 ref=IDirectSoundBuffer_Release(secondary);
681                 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
682                    "should have 0\n",ref);
683             }
684         }
685
686         ref=IDirectSoundBuffer_Release(primary);
687         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
688            "should have 0\n",ref);
689     }
690
691     /* Set the CooperativeLevel back to normal */
692     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
693     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
694     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
695        DXGetErrorString8(rc));
696
697 EXIT:
698     ref=IDirectSound8_Release(dso);
699     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
700     if (ref!=0)
701         return DSERR_GENERIC;
702
703     return rc;
704 }
705
706 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
707                                    LPCSTR lpcstrModule, LPVOID lpContext)
708 {
709     trace("*** Testing %s - %s\n",lpcstrDescription,lpcstrModule);
710     test_dsound8(lpGuid);
711     test_primary8(lpGuid);
712     test_primary_secondary8(lpGuid);
713     test_secondary8(lpGuid);
714
715     return 1;
716 }
717
718 static void dsound8_tests()
719 {
720     HRESULT rc;
721     rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
722     ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
723 }
724
725 START_TEST(dsound8)
726 {
727     HMODULE hDsound;
728     FARPROC pFunc;
729
730     CoInitialize(NULL);
731
732     hDsound = LoadLibraryA("dsound.dll");
733     if (!hDsound) {
734         trace("dsound.dll not found\n");
735         return;
736     }
737
738     pFunc = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
739     if (!pFunc) {
740         trace("dsound8 test skipped\n");
741         return;
742     }
743
744     IDirectSound8_tests();
745     dsound8_tests();
746 }