secur32: Update ntlm_auth version detection to detect new samba4 version numbers.
[wine] / dlls / dsound / tests / capture.c
1 /*
2  * Unit tests for capture functions
3  *
4  * Copyright (c) 2002 Francois Gouget
5  * Copyright (c) 2003 Robert Reif
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #define NONAMELESSSTRUCT
23 #define NONAMELESSUNION
24 #include <windows.h>
25
26 #include <stdio.h>
27
28 #include "wine/test.h"
29 #include "dsound.h"
30 #include "mmreg.h"
31 #include "dxerr8.h"
32 #include "dsconf.h"
33
34 #include "dsound_test.h"
35
36 #define NOTIFICATIONS    5
37
38 static HRESULT (WINAPI *pDirectSoundCaptureCreate)(LPCGUID,LPDIRECTSOUNDCAPTURE*,LPUNKNOWN)=NULL;
39 static HRESULT (WINAPI *pDirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL;
40
41 const char * get_format_str(WORD format)
42 {
43     static char msg[32];
44 #define WAVE_FORMAT(f) case f: return #f
45     switch (format) {
46     WAVE_FORMAT(WAVE_FORMAT_PCM);
47     WAVE_FORMAT(WAVE_FORMAT_ADPCM);
48     WAVE_FORMAT(WAVE_FORMAT_IBM_CVSD);
49     WAVE_FORMAT(WAVE_FORMAT_ALAW);
50     WAVE_FORMAT(WAVE_FORMAT_MULAW);
51     WAVE_FORMAT(WAVE_FORMAT_OKI_ADPCM);
52     WAVE_FORMAT(WAVE_FORMAT_IMA_ADPCM);
53     WAVE_FORMAT(WAVE_FORMAT_MEDIASPACE_ADPCM);
54     WAVE_FORMAT(WAVE_FORMAT_SIERRA_ADPCM);
55     WAVE_FORMAT(WAVE_FORMAT_G723_ADPCM);
56     WAVE_FORMAT(WAVE_FORMAT_DIGISTD);
57     WAVE_FORMAT(WAVE_FORMAT_DIGIFIX);
58     WAVE_FORMAT(WAVE_FORMAT_DIALOGIC_OKI_ADPCM);
59     WAVE_FORMAT(WAVE_FORMAT_YAMAHA_ADPCM);
60     WAVE_FORMAT(WAVE_FORMAT_SONARC);
61     WAVE_FORMAT(WAVE_FORMAT_DSPGROUP_TRUESPEECH);
62     WAVE_FORMAT(WAVE_FORMAT_ECHOSC1);
63     WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF36);
64     WAVE_FORMAT(WAVE_FORMAT_APTX);
65     WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF10);
66     WAVE_FORMAT(WAVE_FORMAT_DOLBY_AC2);
67     WAVE_FORMAT(WAVE_FORMAT_GSM610);
68     WAVE_FORMAT(WAVE_FORMAT_ANTEX_ADPCME);
69     WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_VQLPC);
70     WAVE_FORMAT(WAVE_FORMAT_DIGIREAL);
71     WAVE_FORMAT(WAVE_FORMAT_DIGIADPCM);
72     WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_CR10);
73     WAVE_FORMAT(WAVE_FORMAT_NMS_VBXADPCM);
74     WAVE_FORMAT(WAVE_FORMAT_G721_ADPCM);
75     WAVE_FORMAT(WAVE_FORMAT_MPEG);
76     WAVE_FORMAT(WAVE_FORMAT_MPEGLAYER3);
77     WAVE_FORMAT(WAVE_FORMAT_CREATIVE_ADPCM);
78     WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH8);
79     WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH10);
80     WAVE_FORMAT(WAVE_FORMAT_FM_TOWNS_SND);
81     WAVE_FORMAT(WAVE_FORMAT_OLIGSM);
82     WAVE_FORMAT(WAVE_FORMAT_OLIADPCM);
83     WAVE_FORMAT(WAVE_FORMAT_OLICELP);
84     WAVE_FORMAT(WAVE_FORMAT_OLISBC);
85     WAVE_FORMAT(WAVE_FORMAT_OLIOPR);
86     WAVE_FORMAT(WAVE_FORMAT_DEVELOPMENT);
87     WAVE_FORMAT(WAVE_FORMAT_EXTENSIBLE);
88     }
89 #undef WAVE_FORMAT
90     sprintf(msg, "Unknown(0x%04x)", format);
91     return msg;
92 }
93
94 const char * format_string(const WAVEFORMATEX* wfx)
95 {
96     static char str[64];
97
98     sprintf(str, "%5ldx%2dx%d %s",
99         wfx->nSamplesPerSec, wfx->wBitsPerSample, wfx->nChannels,
100         get_format_str(wfx->wFormatTag));
101
102     return str;
103 }
104
105 static void IDirectSoundCapture_test(LPDIRECTSOUNDCAPTURE dsco,
106                                      BOOL initialized, LPCGUID lpGuid)
107 {
108     HRESULT rc;
109     DSCCAPS dsccaps;
110     int ref;
111     IUnknown * unknown;
112     IDirectSoundCapture * dsc;
113
114     /* Try to Query for objects */
115     rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IUnknown,
116                                           (LPVOID*)&unknown);
117     ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IUnknown) "
118        "failed: %s\n", DXGetErrorString8(rc));
119     if (rc==DS_OK)
120         IDirectSoundCapture_Release(unknown);
121
122     rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IDirectSoundCapture,
123                                           (LPVOID*)&dsc);
124     ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IDirectSoundCapture) "
125        "failed: %s\n", DXGetErrorString8(rc));
126     if (rc==DS_OK)
127         IDirectSoundCapture_Release(dsc);
128
129     if (initialized == FALSE) {
130         /* try unitialized object */
131         rc=IDirectSoundCapture_GetCaps(dsco,0);
132         ok(rc==DSERR_UNINITIALIZED||rc==E_INVALIDARG,
133            "IDirectSoundCapture_GetCaps(NULL) should have returned "
134            "DSERR_UNINITIALIZED or E_INVALIDARG, returned: %s\n",
135            DXGetErrorString8(rc));
136
137         rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
138         ok(rc==DSERR_UNINITIALIZED,"IDirectSoundCapture_GetCaps() "
139            "should have returned DSERR_UNINITIALIZED, returned: %s\n",
140            DXGetErrorString8(rc));
141
142         rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
143         ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||
144            rc==E_FAIL||rc==E_INVALIDARG,
145            "IDirectSoundCapture_Initialize() failed: %s\n",
146            DXGetErrorString8(rc));
147         if (rc==DSERR_NODRIVER||rc==E_INVALIDARG) {
148             trace("  No Driver\n");
149             goto EXIT;
150         } else if (rc==E_FAIL) {
151             trace("  No Device\n");
152             goto EXIT;
153         } else if (rc==DSERR_ALLOCATED) {
154             trace("  Already In Use\n");
155             goto EXIT;
156         }
157     }
158
159     rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
160     ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSoundCapture_Initialize() "
161        "should have returned DSERR_ALREADYINITIALIZED: %s\n",
162        DXGetErrorString8(rc));
163
164     /* DSOUND: Error: Invalid caps buffer */
165     rc=IDirectSoundCapture_GetCaps(dsco, 0);
166     ok(rc==DSERR_INVALIDPARAM, "IDirectSoundCapture_GetCaps(NULL) "
167        "should have returned DSERR_INVALIDPARAM, returned: %s\n",
168        DXGetErrorString8(rc));
169
170     ZeroMemory(&dsccaps, sizeof(dsccaps));
171
172     /* DSOUND: Error: Invalid caps buffer */
173     rc=IDirectSound_GetCaps(dsco, &dsccaps);
174     ok(rc==DSERR_INVALIDPARAM, "IDirectSound_GetCaps() "
175        "should have returned DSERR_INVALIDPARAM, returned: %s\n",
176        DXGetErrorString8(rc));
177
178     dsccaps.dwSize=sizeof(dsccaps);
179
180     /* DSOUND: Running on a certified driver */
181     rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
182     ok(rc==DS_OK, "IDirectSoundCapture_GetCaps() failed: %s\n",
183        DXGetErrorString8(rc));
184
185 EXIT:
186     ref=IDirectSoundCapture_Release(dsco);
187     ok(ref==0, "IDirectSoundCapture_Release() has %d references, "
188        "should have 0\n", ref);
189 }
190
191 static void IDirectSoundCapture_tests(void)
192 {
193     HRESULT rc;
194     LPDIRECTSOUNDCAPTURE dsco=NULL;
195
196     trace("Testing IDirectSoundCapture\n");
197
198     /* try the COM class factory method of creation with no device specified */
199     rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
200                         &IID_IDirectSoundCapture, (void**)&dsco);
201     ok(rc==S_OK||rc==REGDB_E_CLASSNOTREG,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
202        DXGetErrorString8(rc));
203     if (rc==REGDB_E_CLASSNOTREG) {
204         trace("  Class Not Registered\n");
205         return;
206     }
207     if (dsco)
208         IDirectSoundCapture_test(dsco, FALSE, NULL);
209
210     /* try the COM class factory method of creation with default capture
211      * device specified */
212     rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
213                         &IID_IDirectSoundCapture, (void**)&dsco);
214     ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
215        DXGetErrorString8(rc));
216     if (dsco)
217         IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultCapture);
218
219     /* try the COM class factory method of creation with default voice
220      * capture device specified */
221     rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
222                         &IID_IDirectSoundCapture, (void**)&dsco);
223     ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
224        DXGetErrorString8(rc));
225     if (dsco)
226         IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultVoiceCapture);
227
228     /* try the COM class factory method of creation with a bad
229      * IID specified */
230     rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
231                         &CLSID_DirectSoundPrivate, (void**)&dsco);
232     ok(rc==E_NOINTERFACE,
233        "CoCreateInstance(CLSID_DirectSoundCapture,CLSID_DirectSoundPrivate) "
234        "should have failed: %s\n",DXGetErrorString8(rc));
235
236     /* try with no device specified */
237     rc=pDirectSoundCaptureCreate(NULL,&dsco,NULL);
238     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
239        "DirectSoundCaptureCreate(NULL) failed: %s\n",DXGetErrorString8(rc));
240     if (rc==S_OK && dsco)
241         IDirectSoundCapture_test(dsco, TRUE, NULL);
242
243     /* try with default capture device specified */
244     rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultCapture,&dsco,NULL);
245     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
246        "DirectSoundCaptureCreate(DSDEVID_DefaultCapture) failed: %s\n",
247        DXGetErrorString8(rc));
248     if (rc==DS_OK && dsco)
249         IDirectSoundCapture_test(dsco, TRUE, NULL);
250
251     /* try with default voice capture device specified */
252     rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoiceCapture,&dsco,NULL);
253     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
254        "DirectSoundCaptureCreate(DSDEVID_DefaultVoiceCapture) failed: %s\n",
255        DXGetErrorString8(rc));
256     if (rc==DS_OK && dsco)
257         IDirectSoundCapture_test(dsco, TRUE, NULL);
258
259     /* try with a bad device specified */
260     rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoicePlayback,&dsco,NULL);
261     ok(rc==DSERR_NODRIVER,
262        "DirectSoundCaptureCreate(DSDEVID_DefaultVoicePlatback) "
263        "should have failed: %s\n",DXGetErrorString8(rc));
264     if (rc==DS_OK && dsco)
265         IDirectSoundCapture_Release(dsco);
266 }
267
268 typedef struct {
269     char* wave;
270     DWORD wave_len;
271
272     LPDIRECTSOUNDCAPTUREBUFFER dscbo;
273     LPWAVEFORMATEX wfx;
274     DSBPOSITIONNOTIFY posnotify[NOTIFICATIONS];
275     HANDLE event[NOTIFICATIONS];
276     LPDIRECTSOUNDNOTIFY notify;
277
278     DWORD buffer_size;
279     DWORD read;
280     DWORD offset;
281     DWORD size;
282
283     DWORD last_pos;
284 } capture_state_t;
285
286 static int capture_buffer_service(capture_state_t* state)
287 {
288     HRESULT rc;
289     LPVOID ptr1,ptr2;
290     DWORD len1,len2;
291     DWORD capture_pos,read_pos;
292
293     rc=IDirectSoundCaptureBuffer_GetCurrentPosition(state->dscbo,&capture_pos,
294                                                     &read_pos);
295     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCurrentPosition() failed: %s\n",
296        DXGetErrorString8(rc));
297     if (rc!=DS_OK)
298         return 0;
299
300     rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,state->size,
301                                       &ptr1,&len1,&ptr2,&len2,0);
302     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Lock() failed: %s\n",
303        DXGetErrorString8(rc));
304     if (rc!=DS_OK)
305         return 0;
306
307     rc=IDirectSoundCaptureBuffer_Unlock(state->dscbo,ptr1,len1,ptr2,len2);
308     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Unlock() failed: %s\n",
309        DXGetErrorString8(rc));
310     if (rc!=DS_OK)
311         return 0;
312
313     state->offset = (state->offset + state->size) % state->buffer_size;
314
315     return 1;
316 }
317
318 static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco,
319                                 LPDIRECTSOUNDCAPTUREBUFFER dscbo, int record)
320 {
321     HRESULT rc;
322     DSCBCAPS dscbcaps;
323     WAVEFORMATEX wfx;
324     DWORD size,status;
325     capture_state_t state;
326     int i, ref;
327
328     /* Private dsound.dll: Error: Invalid caps pointer */
329     rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,0);
330     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
331        "have returned DSERR_INVALIDPARAM, returned: %s\n",
332        DXGetErrorString8(rc));
333
334     /* Private dsound.dll: Error: Invalid caps pointer */
335     dscbcaps.dwSize=0;
336     rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
337     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
338        "have returned DSERR_INVALIDPARAM, returned: %s\n",
339        DXGetErrorString8(rc));
340
341     dscbcaps.dwSize=sizeof(dscbcaps);
342     rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
343     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCaps() failed: %s\n",
344        DXGetErrorString8(rc));
345     if (rc==DS_OK && winetest_debug > 1) {
346         trace("    Caps: size = %ld flags=0x%08lx buffer size=%ld\n",
347             dscbcaps.dwSize,dscbcaps.dwFlags,dscbcaps.dwBufferBytes);
348     }
349
350     /* Query the format size. Note that it may not match sizeof(wfx) */
351     /* Private dsound.dll: Error: Either pwfxFormat or pdwSizeWritten must
352      * be non-NULL */
353     rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,NULL);
354     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetFormat() should "
355        "have returned DSERR_INVALIDPARAM, returned: %s\n",
356        DXGetErrorString8(rc));
357
358     size=0;
359     rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,&size);
360     ok(rc==DS_OK && size!=0,"IDirectSoundCaptureBuffer_GetFormat() should "
361        "have returned the needed size: rc=%s, size=%ld\n",
362        DXGetErrorString8(rc),size);
363
364     rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,&wfx,sizeof(wfx),NULL);
365     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetFormat() failed: %s\n",
366        DXGetErrorString8(rc));
367     if (rc==DS_OK && winetest_debug > 1) {
368         trace("    Format: tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
369               wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
370               wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
371     }
372
373     /* Private dsound.dll: Error: Invalid status pointer */
374     rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,0);
375     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetStatus() should "
376        "have returned DSERR_INVALIDPARAM, returned: %s\n",
377        DXGetErrorString8(rc));
378
379     rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
380     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %s\n",
381        DXGetErrorString8(rc));
382     if (rc==DS_OK && winetest_debug > 1) {
383         trace("    Status=0x%04lx\n",status);
384     }
385
386     ZeroMemory(&state, sizeof(state));
387     state.dscbo=dscbo;
388     state.wfx=&wfx;
389     state.buffer_size = dscbcaps.dwBufferBytes;
390     for (i = 0; i < NOTIFICATIONS; i++)
391         state.event[i] = CreateEvent( NULL, FALSE, FALSE, NULL );
392     state.size = dscbcaps.dwBufferBytes / NOTIFICATIONS;
393
394     rc=IDirectSoundCaptureBuffer_QueryInterface(dscbo,&IID_IDirectSoundNotify,
395                                                 (void **)&(state.notify));
396     ok((rc==DS_OK)&&(state.notify!=NULL),
397        "IDirectSoundCaptureBuffer_QueryInterface() failed: %s\n",
398        DXGetErrorString8(rc));
399     if (rc!=DS_OK)
400         return;
401
402     for (i = 0; i < NOTIFICATIONS; i++) {
403         state.posnotify[i].dwOffset = (i * state.size) + state.size - 1;
404         state.posnotify[i].hEventNotify = state.event[i];
405     }
406
407     rc=IDirectSoundNotify_SetNotificationPositions(state.notify,NOTIFICATIONS,
408                                                    state.posnotify);
409     ok(rc==DS_OK,"IDirectSoundNotify_SetNotificationPositions() failed: %s\n",
410        DXGetErrorString8(rc));
411     if (rc!=DS_OK)
412         return;
413
414     ref=IDirectSoundNotify_Release(state.notify);
415     ok(ref==0,"IDirectSoundNotify_Release(): has %d references, should have "
416        "0\n",ref);
417     if (ref!=0)
418         return;
419
420     if (record) {
421         rc=IDirectSoundCaptureBuffer_Start(dscbo,DSCBSTART_LOOPING);
422         ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Start() failed: %s\n",
423            DXGetErrorString8(rc));
424         if (rc!=DS_OK)
425             return;
426
427         rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
428         ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %s\n",
429            DXGetErrorString8(rc));
430         ok(status==(DSCBSTATUS_CAPTURING|DSCBSTATUS_LOOPING),
431            "GetStatus: bad status: %lx\n",status);
432         if (rc!=DS_OK)
433             return;
434
435         /* wait for the notifications */
436         for (i = 0; i < (NOTIFICATIONS * 2); i++) {
437             rc=WaitForMultipleObjects(NOTIFICATIONS,state.event,FALSE,3000);
438             ok(rc==(WAIT_OBJECT_0+(i%NOTIFICATIONS)),
439                "WaitForMultipleObjects failed: 0x%lx\n",rc);
440             if (rc!=(WAIT_OBJECT_0+(i%NOTIFICATIONS))) {
441                 ok((rc==WAIT_TIMEOUT)||(rc==WAIT_FAILED),
442                    "Wrong notification: should be %d, got %ld\n",
443                     i%NOTIFICATIONS,rc-WAIT_OBJECT_0);
444             }
445             if (!capture_buffer_service(&state))
446                 break;
447         }
448
449         rc=IDirectSoundCaptureBuffer_Stop(dscbo);
450         ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Stop() failed: %s\n",
451            DXGetErrorString8(rc));
452         if (rc!=DS_OK)
453             return;
454     }
455 }
456
457 static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
458                                     LPCSTR lpcstrModule, LPVOID lpContext)
459 {
460     HRESULT rc;
461     LPDIRECTSOUNDCAPTURE dsco=NULL;
462     LPDIRECTSOUNDCAPTUREBUFFER dscbo=NULL;
463     DSCBUFFERDESC bufdesc;
464     WAVEFORMATEX wfx;
465     DSCCAPS dsccaps;
466     DWORD f;
467     int ref;
468
469     /* Private dsound.dll: Error: Invalid interface buffer */
470     trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
471     rc=pDirectSoundCaptureCreate(lpGuid,NULL,NULL);
472     ok(rc==DSERR_INVALIDPARAM,"DirectSoundCaptureCreate() should have "
473        "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
474     if (rc==DS_OK) {
475         ref=IDirectSoundCapture_Release(dsco);
476         ok(ref==0,"IDirectSoundCapture_Release() has %d references, should "
477            "have 0\n",ref);
478     }
479
480     rc=pDirectSoundCaptureCreate(lpGuid,&dsco,NULL);
481     ok((rc==DS_OK)||(rc==DSERR_NODRIVER)||(rc==E_FAIL)||(rc==DSERR_ALLOCATED),
482        "DirectSoundCaptureCreate() failed: %s\n",DXGetErrorString8(rc));
483     if (rc!=DS_OK) {
484         if (rc==DSERR_NODRIVER)
485             trace("  No Driver\n");
486         else if (rc==E_FAIL)
487             trace("  No Device\n");
488         else if (rc==DSERR_ALLOCATED)
489             trace("  Already In Use\n");
490         goto EXIT;
491     }
492
493     /* Private dsound.dll: Error: Invalid caps buffer */
494     rc=IDirectSoundCapture_GetCaps(dsco,NULL);
495     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
496        "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
497
498     /* Private dsound.dll: Error: Invalid caps buffer */
499     dsccaps.dwSize=0;
500     rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
501     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
502        "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
503
504     dsccaps.dwSize=sizeof(dsccaps);
505     rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
506     ok(rc==DS_OK,"IDirectSoundCapture_GetCaps() failed: %s\n",
507        DXGetErrorString8(rc));
508     if (rc==DS_OK && winetest_debug > 1) {
509         trace("  Caps: size=%ld flags=0x%08lx formats=%05lx channels=%ld\n",
510               dsccaps.dwSize,dsccaps.dwFlags,dsccaps.dwFormats,
511               dsccaps.dwChannels);
512     }
513
514     /* Private dsound.dll: Error: Invalid size */
515     /* Private dsound.dll: Error: Invalid capture buffer description */
516     ZeroMemory(&bufdesc, sizeof(bufdesc));
517     bufdesc.dwSize=0;
518     bufdesc.dwFlags=0;
519     bufdesc.dwBufferBytes=0;
520     bufdesc.dwReserved=0;
521     bufdesc.lpwfxFormat=NULL;
522     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
523     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
524        "should have returned DSERR_INVALIDPARAM, returned: %s\n",
525        DXGetErrorString8(rc));
526     if (rc==DS_OK) {
527         ref=IDirectSoundCaptureBuffer_Release(dscbo);
528         ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
529            "should have 0\n",ref);
530     }
531
532     /* Private dsound.dll: Error: Invalid buffer size */
533     /* Private dsound.dll: Error: Invalid capture buffer description */
534     ZeroMemory(&bufdesc, sizeof(bufdesc));
535     bufdesc.dwSize=sizeof(bufdesc);
536     bufdesc.dwFlags=0;
537     bufdesc.dwBufferBytes=0;
538     bufdesc.dwReserved=0;
539     bufdesc.lpwfxFormat=NULL;
540     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
541     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
542        "should have returned DSERR_INVALIDPARAM, returned %s\n",
543        DXGetErrorString8(rc));
544     if (rc==DS_OK) {
545         ref=IDirectSoundCaptureBuffer_Release(dscbo);
546         ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
547            "should have 0\n",ref);
548     }
549
550     /* Private dsound.dll: Error: Invalid buffer size */
551     /* Private dsound.dll: Error: Invalid capture buffer description */
552     ZeroMemory(&bufdesc, sizeof(bufdesc));
553     ZeroMemory(&wfx, sizeof(wfx));
554     bufdesc.dwSize=sizeof(bufdesc);
555     bufdesc.dwFlags=0;
556     bufdesc.dwBufferBytes=0;
557     bufdesc.dwReserved=0;
558     bufdesc.lpwfxFormat=&wfx;
559     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
560     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
561        "should have returned DSERR_INVALIDPARAM, returned :%s\n",
562        DXGetErrorString8(rc));
563     if (rc==DS_OK) {
564         ref=IDirectSoundCaptureBuffer_Release(dscbo);
565         ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
566            "should have 0\n",ref);
567     }
568
569     /* Private dsound.dll: Error: Invalid buffer size */
570     /* Private dsound.dll: Error: Invalid capture buffer description */
571     init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
572     ZeroMemory(&bufdesc, sizeof(bufdesc));
573     bufdesc.dwSize=sizeof(bufdesc);
574     bufdesc.dwFlags=0;
575     bufdesc.dwBufferBytes=0;
576     bufdesc.dwReserved=0;
577     bufdesc.lpwfxFormat=&wfx;
578     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
579     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
580        "should have returned DSERR_INVALIDPARAM, returned: %s\n",
581        DXGetErrorString8(rc));
582     if (rc==DS_OK) {
583         ref=IDirectSoundCaptureBuffer_Release(dscbo);
584         ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
585            "should have 0\n",ref);
586     }
587
588     for (f=0;f<NB_FORMATS;f++) {
589         dscbo=NULL;
590         init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
591                     formats[f][2]);
592         ZeroMemory(&bufdesc, sizeof(bufdesc));
593         bufdesc.dwSize=sizeof(bufdesc);
594         bufdesc.dwFlags=0;
595         bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
596         bufdesc.dwReserved=0;
597         bufdesc.lpwfxFormat=&wfx;
598         if (winetest_interactive)
599             trace("  Testing the capture buffer at %s\n", format_string(&wfx));
600         rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
601         ok(((rc==DS_OK)&&(dscbo!=NULL))||(rc==DSERR_BADFORMAT)||
602            ((rc==DSERR_NODRIVER))||(rc==DSERR_ALLOCATED)||(rc==E_INVALIDARG),
603            "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
604            "%s capture buffer: %s\n",format_string(&wfx),DXGetErrorString8(rc));
605         if (rc==DS_OK) {
606             test_capture_buffer(dsco, dscbo, winetest_interactive);
607             ref=IDirectSoundCaptureBuffer_Release(dscbo);
608             ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
609                "should have 0\n",ref);
610         } else if (rc==DSERR_BADFORMAT) {
611             ok(!(dsccaps.dwFormats & formats[f][3]),
612                "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
613                "capture buffer: format listed as supported but using it failed\n");
614             if (!(dsccaps.dwFormats & formats[f][3]))
615                 trace("  Format not supported: %s\n", format_string(&wfx));
616         } else if (rc==DSERR_NODRIVER) {
617             trace("  No Driver\n");
618         } else if (rc==DSERR_ALLOCATED) {
619             trace("  Already In Use\n");
620         } else if (rc==E_INVALIDARG) { /* try the old version struct */
621             DSCBUFFERDESC1 bufdesc1;
622             ZeroMemory(&bufdesc1, sizeof(bufdesc1));
623             bufdesc1.dwSize=sizeof(bufdesc1);
624             bufdesc1.dwFlags=0;
625             bufdesc1.dwBufferBytes=wfx.nAvgBytesPerSec;
626             bufdesc1.dwReserved=0;
627             bufdesc1.lpwfxFormat=&wfx;
628             rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,
629                 (DSCBUFFERDESC*)&bufdesc1,&dscbo,NULL);
630             ok(rc==DS_OK,
631                "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
632                "%s capture buffer: %s\n",format_string(&wfx),
633                DXGetErrorString8(rc));
634             if (rc==DS_OK) {
635                 test_capture_buffer(dsco, dscbo, winetest_interactive);
636                 ref=IDirectSoundCaptureBuffer_Release(dscbo);
637                 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d "
638                    "references, should have 0\n",ref);
639             }
640         }
641     }
642
643     /* try a non PCM format */
644 #if 0
645     init_format(&wfx,WAVE_FORMAT_MULAW,8000,8,1);
646     ZeroMemory(&bufdesc, sizeof(bufdesc));
647     bufdesc.dwSize=sizeof(bufdesc);
648     bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
649     bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
650     bufdesc.dwReserved=0;
651     bufdesc.lpwfxFormat=&wfx;
652     if (winetest_interactive)
653         trace("  Testing the capture buffer at %s\n", format_string(&wfx));
654     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
655     ok((rc==DS_OK)&&(dscbo!=NULL),"IDirectSoundCapture_CreateCaptureBuffer() "
656        "failed to create a capture buffer: %s\n",DXGetErrorString8(rc));
657     if ((rc==DS_OK)&&(dscbo!=NULL)) {
658         test_capture_buffer(dsco, dscbo, winetest_interactive);
659         ref=IDirectSoundCaptureBuffer_Release(dscbo);
660         ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
661            "should have 0\n",ref);
662     }
663 #endif
664
665     /* Try an invalid format to test error handling */
666 #if 0
667     init_format(&wfx,WAVE_FORMAT_PCM,2000000,16,2);
668     ZeroMemory(&bufdesc, sizeof(bufdesc));
669     bufdesc.dwSize=sizeof(bufdesc);
670     bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
671     bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
672     bufdesc.dwReserved=0;
673     bufdesc.lpwfxFormat=&wfx;
674     if (winetest_interactive)
675         trace("  Testing the capture buffer at %s\n", format_string(&wfx));
676     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
677     ok(rc!=DS_OK,"IDirectSoundCapture_CreateCaptureBuffer() should have failed "
678        "at 2 MHz %s\n",DXGetErrorString8(rc));
679 #endif
680
681 EXIT:
682     if (dsco!=NULL) {
683         ref=IDirectSoundCapture_Release(dsco);
684         ok(ref==0,"IDirectSoundCapture_Release() has %d references, should "
685            "have 0\n",ref);
686     }
687
688     return TRUE;
689 }
690
691 static void capture_tests(void)
692 {
693     HRESULT rc;
694     rc=pDirectSoundCaptureEnumerateA(&dscenum_callback,NULL);
695     ok(rc==DS_OK,"DirectSoundCaptureEnumerateA() failed: %s\n",
696        DXGetErrorString8(rc));
697 }
698
699 START_TEST(capture)
700 {
701     HMODULE hDsound;
702
703     CoInitialize(NULL);
704
705     hDsound = LoadLibraryA("dsound.dll");
706     if (!hDsound) {
707         trace("dsound.dll not found\n");
708         return;
709     }
710
711     trace("DLL Version: %s\n", get_file_version("dsound.dll"));
712
713     pDirectSoundCaptureCreate=(void*)GetProcAddress(hDsound,"DirectSoundCaptureCreate");
714     pDirectSoundCaptureEnumerateA=(void*)GetProcAddress(hDsound,"DirectSoundCaptureEnumerateA");
715     if (!pDirectSoundCaptureCreate || !pDirectSoundCaptureEnumerateA)
716     {
717         trace("capture test skipped\n");
718         return;
719     }
720
721     IDirectSoundCapture_tests();
722     capture_tests();
723
724     CoUninitialize();
725 }