[WINHTTP] Sync with Wine Staging 3.9. CORE-14656
[reactos.git] / dll / directx / dsound_new / enum.c
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 }