xref: /reactos/dll/directx/dsound_new/enum.c (revision 845faec4)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Configuration of network devices
4  * FILE:            dll/directx/dsound_new/enum.c
5  * PURPOSE:         Handles DSound device enumeration
6  *
7  * PROGRAMMERS:     Johannes Anderwald (johannes.anderwald@reactos.org)
8  */
9 
10 #include "precomp.h"
11 
12 VOID
13 LoadResourceString(
14     UINT ResourceId,
15     LPVOID Buffer,
16     UINT ccount,
17     LPVOID DefaultString,
18     BOOL bUnicode)
19 {
20     if (bUnicode)
21     {
22         /* load localized string */
23         if (!LoadStringW(dsound_hInstance, ResourceId, (LPWSTR)Buffer, ccount))
24         {
25             /* default device name */
26             wcscpy((LPWSTR)Buffer, (LPWSTR)DefaultString);
27         }
28     }
29     else
30     {
31         /* load localized string */
32         if (!LoadStringA(dsound_hInstance, ResourceId, (LPSTR)Buffer, ccount))
33         {
34             /* default device name */
35             strcpy((LPSTR)Buffer, (LPSTR)DefaultString);
36         }
37     }
38 }
39 
40 
41 BOOL
42 DoDSoundCallback(
43     LPDSENUMCALLBACKA lpDSEnumCallbackA,
44     LPDSENUMCALLBACKW lpDSEnumCallbackW,
45     LPGUID DeviceGuid,
46     UINT ResourceId,
47     LPWSTR ProductName,
48     LPWSTR DriverName,
49     LPVOID lpContext)
50 {
51     WCHAR Buffer[200] = {0};
52     char DriverNameA[200];
53 
54     static LPWSTR SoundDriverW = L"Primary Sound Driver";
55     static LPWSTR SoundDriverA = L"Primary Sound Driver";
56 
57     if (lpDSEnumCallbackW)
58     {
59         if (ResourceId)
60         {
61             /* load resource string */
62             Buffer[0] = 0;
63             LoadResourceString(ResourceId, (LPVOID)Buffer, sizeof(Buffer)/sizeof(WCHAR), (LPVOID)SoundDriverW, TRUE);
64             Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = '\0';
65         }
66         else
67         {
68             /* use passed string */
69             ASSERT(ProductName);
70             wcscpy(Buffer, ProductName);
71         }
72 
73         /* perform callback */
74         return lpDSEnumCallbackW(DeviceGuid, Buffer, DriverName, lpContext);
75     }
76     else
77     {
78         if (ResourceId)
79         {
80             /* load resource string */
81             Buffer[0] = 0;
82             LoadResourceString(ResourceId, (LPVOID)Buffer, sizeof(Buffer)/sizeof(char), (LPVOID)SoundDriverA, FALSE);
83             Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = 0;
84         }
85         else
86         {
87             /* use passed string */
88             Buffer[0] = 0;
89             WideCharToMultiByte(CP_ACP, 0, ProductName, -1, (LPSTR)Buffer, sizeof(Buffer) / sizeof(char), NULL, NULL);
90             Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = 0;
91         }
92 
93         DriverNameA[0] = 0;
94         if (ProductName)
95         {
96             WideCharToMultiByte(CP_ACP, 0, ProductName, -1, DriverNameA, sizeof(DriverNameA) / sizeof(char), NULL, NULL);
97             DriverNameA[(sizeof(DriverNameA) / sizeof(char))-1] = 0;
98         }
99 
100         return lpDSEnumCallbackA(DeviceGuid, (LPSTR)Buffer, DriverNameA, lpContext);
101     }
102 }
103 
104 
105 HRESULT
106 DSoundEnumerate(
107     LPDSENUMCALLBACKA lpDSEnumCallbackA,
108     LPDSENUMCALLBACKW lpDSEnumCallbackW,
109     LPVOID lpContext,
110     BOOL bPlayback)
111 {
112     ULONG ResourceId;
113     BOOL bResult;
114     LPFILTERINFO CurInfo;
115     WAVEOUTCAPSW WaveOutCaps;
116     WAVEINCAPSW  WaveInCaps;
117 
118     if (!RootInfo)
119     {
120         EnumAudioDeviceInterfaces(&RootInfo);
121     }
122 
123     if (lpDSEnumCallbackA == NULL && lpDSEnumCallbackW == NULL)
124     {
125         DPRINT("No callback\n");
126         return DSERR_INVALIDPARAM;
127     }
128 
129     if (bPlayback)
130     {
131         /* use resource id of playback string */
132         ResourceId = IDS_PRIMARY_PLAYBACK_DEVICE;
133     }
134     else
135     {
136         /* use resource id of playback string */
137         ResourceId = IDS_PRIMARY_RECORD_DEVICE;
138     }
139 
140     if (RootInfo)
141     {
142         /* perform first callback */
143         bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, NULL, ResourceId, NULL, L"", lpContext);
144         if (!bResult)
145         {
146             /* callback asked as to stop */
147             return DS_OK;
148         }
149 
150         /* now iterate through all devices */
151         CurInfo = RootInfo;
152 
153         do
154         {
155             if (bPlayback && !IsEqualGUID(&CurInfo->DeviceGuid[1], &GUID_NULL))
156             {
157                 RtlZeroMemory(&WaveOutCaps, sizeof(WAVEOUTCAPSW));
158 
159                 /* sanity check */
160                 ASSERT(CurInfo->MappedId[1] != ULONG_MAX);
161 
162                 /* get wave out caps */
163                 waveOutGetDevCapsW((UINT_PTR)CurInfo->MappedId[1], &WaveOutCaps, sizeof(WAVEOUTCAPSW));
164                 WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
165 
166                 bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, &CurInfo->DeviceGuid[1], 0, WaveOutCaps.szPname, L"" /* FIXME */, lpContext);
167                 if (!bResult)
168                 {
169                     /* callback asked as to stop */
170                     return DS_OK;
171                 }
172             }
173             else if (!bPlayback && !IsEqualGUID(&CurInfo->DeviceGuid[0], &GUID_NULL))
174             {
175                 RtlZeroMemory(&WaveInCaps, sizeof(WAVEINCAPSW));
176 
177                 /* sanity check */
178                 ASSERT(CurInfo->MappedId[1] != ULONG_MAX);
179 
180                 /* get wave in caps */
181                 waveInGetDevCapsW((UINT_PTR)CurInfo->MappedId[0], &WaveInCaps, sizeof(WAVEINCAPSW));
182                 WaveInCaps.szPname[MAXPNAMELEN-1] = L'\0';
183 
184                 bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, &CurInfo->DeviceGuid[0], 0, WaveInCaps.szPname, L"" /* FIXME */, lpContext);
185                 if (!bResult)
186                 {
187                     /* callback asked as to stop */
188                     return DS_OK;
189                 }
190             }
191 
192             /* move to next entry */
193             CurInfo = CurInfo->lpNext;
194         }while(CurInfo);
195     }
196     return DS_OK;
197 }
198 
199 HRESULT
200 WINAPI
201 DirectSoundEnumerateA(
202     LPDSENUMCALLBACKA lpDSEnumCallback,
203     LPVOID lpContext)
204 {
205     return DSoundEnumerate(lpDSEnumCallback, NULL, lpContext, TRUE);
206 }
207 
208 HRESULT
209 WINAPI
210 DirectSoundEnumerateW(
211     LPDSENUMCALLBACKW lpDSEnumCallback,
212     LPVOID lpContext )
213 {
214     return DSoundEnumerate(NULL, lpDSEnumCallback, lpContext, TRUE);
215 }
216 
217 HRESULT
218 WINAPI
219 DirectSoundCaptureEnumerateA(
220     LPDSENUMCALLBACKA lpDSEnumCallback,
221     LPVOID lpContext)
222 {
223     return DSoundEnumerate(lpDSEnumCallback, NULL, lpContext, FALSE);
224 }
225 
226 HRESULT
227 WINAPI
228 DirectSoundCaptureEnumerateW(
229     LPDSENUMCALLBACKW lpDSEnumCallback,
230     LPVOID lpContext)
231 {
232     return DSoundEnumerate(NULL, lpDSEnumCallback, lpContext, FALSE);
233 }
234