ReactOS 0.4.15-dev-7961-gdcf9eb0
devicelist.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Sound System "MME Buddy" Library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: lib/drivers/sound/mmebuddy/devicelist.c
5 *
6 * PURPOSE: Manages lists of sound devices.
7 *
8 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
9*/
10
11#include "precomp.h"
12
16
17/*
18 Handles the allocation and initialisation of a SOUND_DEVICE structure.
19*/
23 OUT PSOUND_DEVICE* SoundDevice)
24{
25 PSOUND_DEVICE NewDevice;
26
28 SND_ASSERT( SoundDevice );
29
30 SND_TRACE(L"Allocating a SOUND_DEVICE structure\n");
31
32 NewDevice = AllocateStruct(SOUND_DEVICE);
33
34 if ( ! NewDevice )
35 return MMSYSERR_NOMEM;
36
37 NewDevice->Type = DeviceType;
38
39 /* Return the new structure to the caller and report success */
40 *SoundDevice = NewDevice;
41
42 return MMSYSERR_NOERROR;
43}
44
45/*
46 Handles the cleanup and freeing of a SOUND_DEVICE structure.
47*/
48VOID
50 IN PSOUND_DEVICE SoundDevice)
51{
52 SND_ASSERT( SoundDevice );
53
54 SND_TRACE(L"Freeing a SOUND_DEVICE structure");
55
56 /* For safety the whole struct gets zeroed */
57 ZeroMemory(SoundDevice, sizeof(SOUND_DEVICE));
58 FreeMemory(SoundDevice);
59}
60
61/*
62 Returns the number of devices of the specified type which have been added
63 to the device lists. If an invalid device type is specified, the function
64 returns zero.
65*/
69{
71
73 {
74 return 0;
75 }
76
77 SND_TRACE(L"Returning a count of %d devices\n", SoundDeviceCounts[Index]);
79}
80
81/*
82 Determines if a sound device structure pointer is valid, firstly by
83 ensuring that it is not NULL, and then by checking that the device itself
84 exists in one of the device lists.
85*/
88 IN PSOUND_DEVICE SoundDevice)
89{
90 UCHAR TypeIndex;
91 PSOUND_DEVICE CurrentDevice;
92
93 if ( ! SoundDevice )
94 return FALSE;
95
96 /* Go through all the device lists */
97 for ( TypeIndex = 0; TypeIndex < SOUND_DEVICE_TYPES; ++ TypeIndex )
98 {
99 CurrentDevice = SoundDeviceListHeads[TypeIndex];
100
101 while ( CurrentDevice )
102 {
103 if ( CurrentDevice == SoundDevice )
104 {
105 /* Found the device */
106 return TRUE;
107 }
108
109 CurrentDevice = CurrentDevice->Next;
110 }
111 }
112
113 /* If we get here, nothing was found */
114 return FALSE;
115}
116
117/*
118 Informs the MME-Buddy library that it should take ownership of a device.
119 The DevicePath is typically used for storing a device path (for subsequent
120 opening using CreateFile) but it can be a wide-string representing any
121 information that makes sense to your MME driver implementation.
122
123 MME components which operate solely in user-mode (for example, MIDI
124 loopback devices) won't need to communicate with a kernel-mode device,
125 so in these situations DevicePath is likely to be NULL.
126
127 Upon successful addition to the sound device list, the pointer to the new
128 device's SOUND_DEVICE structure is returned via SoundDevice.
129*/
134 OUT PSOUND_DEVICE* SoundDevice OPTIONAL)
135{
137 PSOUND_DEVICE NewDevice;
139
141
143
144 if ( ! MMSUCCESS(Result) )
145 {
146 SND_ERR(L"Failed to allocate SOUND_DEVICE structure\n");
147 return Result;
148 }
149
150 if ( ! SoundDeviceListHeads[TypeIndex] )
151 {
152 SND_TRACE(L"Putting first entry into device list %d\n", DeviceType);
153 SoundDeviceListHeads[TypeIndex] = NewDevice;
154 SoundDeviceListTails[TypeIndex] = NewDevice;
155 }
156 else
157 {
158 SND_TRACE(L"Putting another entry into device list %d\n", DeviceType);
159 SoundDeviceListTails[TypeIndex]->Next = NewDevice;
160 SoundDeviceListTails[TypeIndex] = NewDevice;
161 }
162
163 /* Add to the count */
164 ++ SoundDeviceCounts[TypeIndex];
165
166 /* Set up the default function table */
168
169 /* Set up other members of the structure */
170 NewDevice->Identifier = Identifier;
171 NewDevice->HeadInstance = NULL;
172 NewDevice->TailInstance = NULL;
173
174 /* Fill in the caller's PSOUND_DEVICE */
175 if ( SoundDevice )
176 {
177 *SoundDevice = NewDevice;
178 }
179
180 return MMSYSERR_NOERROR;
181}
182
183/*
184 Removes a sound device from the list, and frees the memory associated
185 with its description.
186*/
190 IN PSOUND_DEVICE SoundDevice)
191{
192 PSOUND_DEVICE CurrentDevice, PreviousDevice;
193
195
198
199 PreviousDevice = NULL;
200 CurrentDevice = SoundDeviceListHeads[TypeIndex];
201
202 while ( CurrentDevice )
203 {
204 if ( CurrentDevice == SoundDevice )
205 {
206 if ( ! PreviousDevice )
207 {
208 /* This is the head node */
209 SND_TRACE(L"Removing head node from device list %d\n", DeviceType);
210 SoundDeviceListHeads[TypeIndex] =
211 SoundDeviceListHeads[TypeIndex]->Next;
212 }
213 else
214 {
215 SND_TRACE(L"Removing node from device list %d\n", DeviceType);
216 /* There are nodes before this one - cut our device out */
217 PreviousDevice->Next = CurrentDevice->Next;
218 }
219
220 if ( ! CurrentDevice->Next )
221 {
222 /* This is the tail node */
223 SND_TRACE(L"Removing tail node from device list %d\n", DeviceType);
224 SoundDeviceListTails[TypeIndex] = PreviousDevice;
225 }
226 }
227
228 PreviousDevice = CurrentDevice;
229 CurrentDevice = CurrentDevice->Next;
230 }
231
232 /* Subtract from the count */
233 -- SoundDeviceCounts[TypeIndex];
234
235 /* Finally, free up the deleted entry */
236 FreeSoundDevice(SoundDevice);
237
238 return MMSYSERR_NOERROR;
239}
240
241/*
242 Removes all devices from one of the device lists.
243*/
247{
248 UCHAR TypeIndex;
250
251 SND_TRACE(L"Unlisting all sound devices of type %d\n", DeviceType);
252
254
255 /* Munch away at the head of the list until it's drained */
256 while ( SoundDeviceCounts[TypeIndex] > 0 )
257 {
261 }
262
263 return MMSYSERR_NOERROR;
264}
265
266/*
267 Removes all devices from all lists.
268*/
269VOID
271{
273
274 SND_TRACE(L"Unlisting all sound devices\n");
275
277 {
281 }
282}
283
284/*
285 Provides the caller with a pointer to its desired sound device, based on
286 the device type and index.
287*/
291 IN DWORD DeviceIndex,
292 OUT PSOUND_DEVICE* SoundDevice)
293{
295 DWORD CurrentIndex = 0;
296 PSOUND_DEVICE CurrentDevice;
297
299
300 if ( DeviceIndex >= SoundDeviceCounts[TypeIndex] )
301 {
302 SND_ERR(L"Invalid device ID %d for type %d\n", DeviceIndex, DeviceType);
304 }
305
306 CurrentDevice = SoundDeviceListHeads[TypeIndex];
307
308 /* Following the earlier checks, the index should be valid here. */
309 for ( CurrentIndex = 0; CurrentIndex != DeviceIndex; ++ CurrentIndex )
310 {
311 SND_ASSERT( CurrentDevice );
312 CurrentDevice = CurrentDevice->Next;
313 }
314
315 SND_TRACE(L"Returning sound device %x\n", CurrentDevice);
316
317 *SoundDevice = CurrentDevice;
318
319 return MMSYSERR_NOERROR;
320}
321
322/*
323 Provides the caller with the device path of the specified sound device.
324 This will normally be the path to a device provided by a kernel-mode
325 driver.
326*/
329 IN PSOUND_DEVICE SoundDevice,
331{
332 VALIDATE_MMSYS_PARAMETER( SoundDevice );
334
335 /* The caller should not modify this! */
336 *Identifier = SoundDevice->Identifier;
337
338 return MMSYSERR_NOERROR;
339}
340
341/*
342 Provides the caller with the device type of the specified sound device.
343 This will be, for example, WAVE_OUT_DEVICE_TYPE, WAVE_IN_DEVICE_TYPE ...
344*/
347 IN PSOUND_DEVICE SoundDevice,
349{
350 VALIDATE_MMSYS_PARAMETER( SoundDevice );
352
353 *DeviceType = SoundDevice->Type;
354
355 return MMSYSERR_NOERROR;
356}
unsigned char BOOLEAN
Type
Definition: Type.h:7
@ Identifier
Definition: asmpp.cpp:95
static VOID FreeMemory(PCREATE_DATA Data)
Definition: create.c:134
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned long DWORD
Definition: ntddk_ex.h:95
DeviceType
Definition: mmdrv.h:42
#define SOUND_DEVICE_TYPE_TO_INDEX(x)
Definition: mmebuddy.h:58
#define VALIDATE_MMSYS_PARAMETER(parameter_condition)
Definition: mmebuddy.h:71
#define AllocateStruct(thing)
Definition: mmebuddy.h:27
MMRESULT SetSoundDeviceFunctionTable(IN PSOUND_DEVICE SoundDevice, IN PMMFUNCTION_TABLE FunctionTable)
Definition: functiontable.c:21
UCHAR MMDEVICE_TYPE
Definition: mmebuddy.h:88
UCHAR * PMMDEVICE_TYPE
Definition: mmebuddy.h:88
#define IsValidSoundDeviceType
Definition: mmebuddy.h:69
#define MMSUCCESS(result)
Definition: mmebuddy.h:80
#define SND_TRACE(...)
#define SND_ERR(...)
#define SND_ASSERT(condition)
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
UINT MMRESULT
Definition: mmsystem.h:962
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
#define L(x)
Definition: ntvdm.h:50
MMRESULT UnlistSoundDevice(IN MMDEVICE_TYPE DeviceType, IN PSOUND_DEVICE SoundDevice)
Definition: devicelist.c:188
BOOLEAN IsValidSoundDevice(IN PSOUND_DEVICE SoundDevice)
Definition: devicelist.c:87
VOID UnlistAllSoundDevices()
Definition: devicelist.c:270
MMRESULT ListSoundDevice(IN MMDEVICE_TYPE DeviceType, IN PVOID Identifier OPTIONAL, OUT PSOUND_DEVICE *SoundDevice OPTIONAL)
Definition: devicelist.c:131
VOID FreeSoundDevice(IN PSOUND_DEVICE SoundDevice)
Definition: devicelist.c:49
ULONG GetSoundDeviceCount(IN MMDEVICE_TYPE DeviceType)
Definition: devicelist.c:67
ULONG SoundDeviceCounts[SOUND_DEVICE_TYPES]
Definition: devicelist.c:13
MMRESULT GetSoundDevice(IN MMDEVICE_TYPE DeviceType, IN DWORD DeviceIndex, OUT PSOUND_DEVICE *SoundDevice)
Definition: devicelist.c:289
PSOUND_DEVICE SoundDeviceListTails[SOUND_DEVICE_TYPES]
Definition: devicelist.c:15
MMRESULT UnlistSoundDevices(IN MMDEVICE_TYPE DeviceType)
Definition: devicelist.c:245
MMRESULT GetSoundDeviceIdentifier(IN PSOUND_DEVICE SoundDevice, OUT PVOID *Identifier)
Definition: devicelist.c:328
MMRESULT AllocateSoundDevice(IN MMDEVICE_TYPE DeviceType, OUT PSOUND_DEVICE *SoundDevice)
Definition: devicelist.c:21
MMRESULT GetSoundDeviceType(IN PSOUND_DEVICE SoundDevice, OUT PMMDEVICE_TYPE DeviceType)
Definition: devicelist.c:346
PSOUND_DEVICE SoundDeviceListHeads[SOUND_DEVICE_TYPES]
Definition: devicelist.c:14
@ MIN_SOUND_DEVICE_TYPE
Definition: sndtypes.h:36
@ SOUND_DEVICE_TYPES
Definition: sndtypes.h:40
@ MAX_SOUND_DEVICE_TYPE
Definition: sndtypes.h:37
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PVOID Identifier
Definition: mmebuddy.h:261
struct _SOUND_DEVICE_INSTANCE * HeadInstance
Definition: mmebuddy.h:258
MMDEVICE_TYPE Type
Definition: mmebuddy.h:260
struct _SOUND_DEVICE * Next
Definition: mmebuddy.h:257
struct _SOUND_DEVICE_INSTANCE * TailInstance
Definition: mmebuddy.h:259
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_In_ WDFCOLLECTION _In_ ULONG Index
#define ZeroMemory
Definition: winbase.h:1712
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
unsigned char UCHAR
Definition: xmlstorage.h:181