ReactOS  0.4.14-dev-376-gaedba84
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 */
48 VOID
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 */
66 ULONG
69 {
71 
73  {
74  return 0;
75  }
76 
77  SND_TRACE(L"Returning a count of %d devices\n", SoundDeviceCounts[Index]);
78  return 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 */
86 BOOLEAN
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 */
130 MMRESULT
133  IN PVOID Identifier OPTIONAL,
134  OUT PSOUND_DEVICE* SoundDevice OPTIONAL)
135 {
137  PSOUND_DEVICE NewDevice;
139 
141 
142  Result = AllocateSoundDevice(DeviceType, &NewDevice);
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 */
167  SetSoundDeviceFunctionTable(NewDevice, NULL);
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 */
187 MMRESULT
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 */
244 MMRESULT
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 */
269 VOID
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 */
288 MMRESULT
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);
303  return MMSYSERR_BADDEVICEID;
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 */
327 MMRESULT
329  IN PSOUND_DEVICE SoundDevice,
330  OUT PVOID* Identifier)
331 {
332  VALIDATE_MMSYS_PARAMETER( SoundDevice );
333  VALIDATE_MMSYS_PARAMETER( Identifier );
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 */
345 MMRESULT
347  IN PSOUND_DEVICE SoundDevice,
349 {
350  VALIDATE_MMSYS_PARAMETER( SoundDevice );
352 
353  *DeviceType = SoundDevice->Type;
354 
355  return MMSYSERR_NOERROR;
356 }
#define IN
Definition: typedefs.h:38
static VOID FreeMemory(PCREATE_DATA Data)
Definition: create.c:134
MMRESULT GetSoundDevice(IN MMDEVICE_TYPE DeviceType, IN DWORD DeviceIndex, OUT PSOUND_DEVICE *SoundDevice)
Definition: devicelist.c:289
#define TRUE
Definition: types.h:120
MMRESULT GetSoundDeviceIdentifier(IN PSOUND_DEVICE SoundDevice, OUT PVOID *Identifier)
Definition: devicelist.c:328
struct _SOUND_DEVICE_INSTANCE * TailInstance
Definition: mmebuddy.h:260
Type
Definition: Type.h:6
MMRESULT SetSoundDeviceFunctionTable(IN PSOUND_DEVICE SoundDevice, IN PMMFUNCTION_TABLE FunctionTable)
Definition: functiontable.c:21
UCHAR * PMMDEVICE_TYPE
Definition: mmebuddy.h:88
#define MMSUCCESS(result)
Definition: mmebuddy.h:80
DeviceType
Definition: mmdrv.h:41
MMRESULT UnlistSoundDevice(IN MMDEVICE_TYPE DeviceType, IN PSOUND_DEVICE SoundDevice)
Definition: devicelist.c:188
PSOUND_DEVICE SoundDeviceListHeads[SOUND_DEVICE_TYPES]
Definition: devicelist.c:14
#define ZeroMemory
Definition: winbase.h:1642
UINT MMRESULT
Definition: mmsystem.h:962
PVOID Identifier
Definition: mmebuddy.h:262
#define VALIDATE_MMSYS_PARAMETER(parameter_condition)
Definition: mmebuddy.h:71
VOID FreeSoundDevice(IN PSOUND_DEVICE SoundDevice)
Definition: devicelist.c:49
UCHAR MMDEVICE_TYPE
Definition: mmebuddy.h:88
MMRESULT ListSoundDevice(IN MMDEVICE_TYPE DeviceType, IN PVOID Identifier OPTIONAL, OUT PSOUND_DEVICE *SoundDevice OPTIONAL)
Definition: devicelist.c:131
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
#define IsValidSoundDeviceType
Definition: mmebuddy.h:69
MMRESULT GetSoundDeviceType(IN PSOUND_DEVICE SoundDevice, OUT PMMDEVICE_TYPE DeviceType)
Definition: devicelist.c:346
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define SND_ASSERT(condition)
_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:426
struct _SOUND_DEVICE_INSTANCE * HeadInstance
Definition: mmebuddy.h:259
MMDEVICE_TYPE Type
Definition: mmebuddy.h:261
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define AllocateStruct(thing)
Definition: mmebuddy.h:27
#define SND_ERR(...)
BOOLEAN IsValidSoundDevice(IN PSOUND_DEVICE SoundDevice)
Definition: devicelist.c:87
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned char UCHAR
Definition: xmlstorage.h:181
struct _SOUND_DEVICE * Next
Definition: mmebuddy.h:258
static const WCHAR L[]
Definition: oid.c:1250
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
ULONG GetSoundDeviceCount(IN MMDEVICE_TYPE DeviceType)
Definition: devicelist.c:67
PSOUND_DEVICE SoundDeviceListTails[SOUND_DEVICE_TYPES]
Definition: devicelist.c:15
ULONG SoundDeviceCounts[SOUND_DEVICE_TYPES]
Definition: devicelist.c:13
VOID UnlistAllSoundDevices()
Definition: devicelist.c:270
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
MMRESULT UnlistSoundDevices(IN MMDEVICE_TYPE DeviceType)
Definition: devicelist.c:245
#define SOUND_DEVICE_TYPE_TO_INDEX(x)
Definition: mmebuddy.h:58
MMRESULT AllocateSoundDevice(IN MMDEVICE_TYPE DeviceType, OUT PSOUND_DEVICE *SoundDevice)
Definition: devicelist.c:21
#define SND_TRACE(...)
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68