- Start rewrite of DirectSound
[reactos.git] / reactos / 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 (janderwald@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 WideCharToMultiByte(CP_ACP, 0, ProductName, -1, DriverNameA, sizeof(DriverNameA) / sizeof(char), NULL, NULL);
95
96 return lpDSEnumCallbackA(DeviceGuid, (LPSTR)Buffer, DriverNameA, lpContext);
97 }
98 }
99
100
101 HRESULT
102 DSoundEnumerate(
103 LPDSENUMCALLBACKA lpDSEnumCallbackA,
104 LPDSENUMCALLBACKW lpDSEnumCallbackW,
105 LPVOID lpContext,
106 BOOL bPlayback)
107 {
108 ULONG ResourceId;
109 BOOL bResult;
110 LPFILTERINFO CurInfo;
111 WAVEOUTCAPSW WaveOutCaps;
112 WAVEINCAPSW WaveInCaps;
113
114 if (!RootInfo)
115 {
116 EnumAudioDeviceInterfaces(&RootInfo);
117 }
118
119 if (lpDSEnumCallbackA == NULL && lpDSEnumCallbackW == NULL)
120 {
121 DPRINT("No callback\n");
122 return DSERR_INVALIDPARAM;
123 }
124
125 if (bPlayback)
126 {
127 /* use resource id of playback string */
128 ResourceId = IDS_PRIMARY_PLAYBACK_DEVICE;
129 }
130 else
131 {
132 /* use resource id of playback string */
133 ResourceId = IDS_PRIMARY_RECORD_DEVICE;
134 }
135
136 if (RootInfo)
137 {
138 /* perform first callback */
139 bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, NULL, ResourceId, NULL, L"", lpContext);
140 if (!bResult)
141 {
142 /* callback asked as to stop */
143 return DS_OK;
144 }
145
146 /* now iterate through all devices */
147 CurInfo = RootInfo;
148
149 do
150 {
151 if (bPlayback && !IsEqualGUID(&CurInfo->DeviceGuid[1], &GUID_NULL))
152 {
153 RtlZeroMemory(&WaveOutCaps, sizeof(WAVEOUTCAPSW));
154
155 /* sanity check */
156 ASSERT(CurInfo->MappedId[1] != ULONG_MAX);
157
158 /* get wave out caps */
159 waveOutGetDevCapsW((UINT_PTR)CurInfo->MappedId[1], &WaveOutCaps, sizeof(WAVEOUTCAPSW));
160 WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
161
162 bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, &CurInfo->DeviceGuid[1], 0, WaveOutCaps.szPname, L"" /* FIXME */, lpContext);
163 if (!bResult)
164 {
165 /* callback asked as to stop */
166 return DS_OK;
167 }
168 }
169 else if (!bPlayback && !IsEqualGUID(&CurInfo->DeviceGuid[0], &GUID_NULL))
170 {
171 RtlZeroMemory(&WaveInCaps, sizeof(WAVEINCAPSW));
172
173 /* sanity check */
174 ASSERT(CurInfo->MappedId[1] != ULONG_MAX);
175
176 /* get wave in caps */
177 waveInGetDevCapsW((UINT_PTR)CurInfo->MappedId[0], &WaveInCaps, sizeof(WAVEINCAPSW));
178 WaveInCaps.szPname[MAXPNAMELEN-1] = L'\0';
179
180 bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, &CurInfo->DeviceGuid[0], 0, WaveInCaps.szPname, L"" /* FIXME */, lpContext);
181 if (!bResult)
182 {
183 /* callback asked as to stop */
184 return DS_OK;
185 }
186 }
187
188 /* move to next entry */
189 CurInfo = CurInfo->lpNext;
190 }while(CurInfo);
191 }
192 return DS_OK;
193 }
194
195 HRESULT
196 WINAPI
197 DirectSoundEnumerateA(
198 LPDSENUMCALLBACKA lpDSEnumCallback,
199 LPVOID lpContext)
200 {
201 return DSoundEnumerate(lpDSEnumCallback, NULL, lpContext, TRUE);
202 }
203
204 HRESULT
205 WINAPI
206 DirectSoundEnumerateW(
207 LPDSENUMCALLBACKW lpDSEnumCallback,
208 LPVOID lpContext )
209 {
210 return DSoundEnumerate(NULL, lpDSEnumCallback, lpContext, TRUE);
211 }
212
213 HRESULT
214 WINAPI
215 DirectSoundCaptureEnumerateA(
216 LPDSENUMCALLBACKA lpDSEnumCallback,
217 LPVOID lpContext)
218 {
219 return DSoundEnumerate(lpDSEnumCallback, NULL, lpContext, FALSE);
220 }
221
222 HRESULT
223 WINAPI
224 DirectSoundCaptureEnumerateW(
225 LPDSENUMCALLBACKW lpDSEnumCallback,
226 LPVOID lpContext)
227 {
228 return DSoundEnumerate(NULL, lpDSEnumCallback, lpContext, FALSE);
229 }