Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendevicelist.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Sound System "MME Buddy" Library 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: lib/drivers/sound/mmebuddy/devicelist.c 00005 * 00006 * PURPOSE: Manages lists of sound devices. 00007 * 00008 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org) 00009 */ 00010 00011 #include "precomp.h" 00012 00013 ULONG SoundDeviceCounts[SOUND_DEVICE_TYPES]; 00014 PSOUND_DEVICE SoundDeviceListHeads[SOUND_DEVICE_TYPES]; 00015 PSOUND_DEVICE SoundDeviceListTails[SOUND_DEVICE_TYPES]; 00016 00017 /* 00018 Handles the allocation and initialisation of a SOUND_DEVICE structure. 00019 */ 00020 MMRESULT 00021 AllocateSoundDevice( 00022 IN MMDEVICE_TYPE DeviceType, 00023 OUT PSOUND_DEVICE* SoundDevice) 00024 { 00025 PSOUND_DEVICE NewDevice; 00026 00027 SND_ASSERT( IsValidSoundDeviceType(DeviceType) ); 00028 SND_ASSERT( SoundDevice ); 00029 00030 SND_TRACE(L"Allocating a SOUND_DEVICE structure\n"); 00031 00032 NewDevice = AllocateStruct(SOUND_DEVICE); 00033 00034 if ( ! NewDevice ) 00035 return MMSYSERR_NOMEM; 00036 00037 NewDevice->Type = DeviceType; 00038 00039 /* Return the new structure to the caller and report success */ 00040 *SoundDevice = NewDevice; 00041 00042 return MMSYSERR_NOERROR; 00043 } 00044 00045 /* 00046 Handles the cleanup and freeing of a SOUND_DEVICE structure. 00047 */ 00048 VOID 00049 FreeSoundDevice( 00050 IN PSOUND_DEVICE SoundDevice) 00051 { 00052 SND_ASSERT( SoundDevice ); 00053 00054 SND_TRACE(L"Freeing a SOUND_DEVICE structure"); 00055 00056 /* For safety the whole struct gets zeroed */ 00057 ZeroMemory(SoundDevice, sizeof(SOUND_DEVICE)); 00058 FreeMemory(SoundDevice); 00059 } 00060 00061 /* 00062 Returns the number of devices of the specified type which have been added 00063 to the device lists. If an invalid device type is specified, the function 00064 returns zero. 00065 */ 00066 ULONG 00067 GetSoundDeviceCount( 00068 IN MMDEVICE_TYPE DeviceType) 00069 { 00070 ULONG Index = SOUND_DEVICE_TYPE_TO_INDEX(DeviceType); 00071 00072 if ( ! IsValidSoundDeviceType(DeviceType) ) 00073 { 00074 return 0; 00075 } 00076 00077 SND_TRACE(L"Returning a count of %d devices\n", SoundDeviceCounts[Index]); 00078 return SoundDeviceCounts[Index]; 00079 } 00080 00081 /* 00082 Determines if a sound device structure pointer is valid, firstly by 00083 ensuring that it is not NULL, and then by checking that the device itself 00084 exists in one of the device lists. 00085 */ 00086 BOOLEAN 00087 IsValidSoundDevice( 00088 IN PSOUND_DEVICE SoundDevice) 00089 { 00090 UCHAR TypeIndex; 00091 PSOUND_DEVICE CurrentDevice; 00092 00093 if ( ! SoundDevice ) 00094 return FALSE; 00095 00096 /* Go through all the device lists */ 00097 for ( TypeIndex = 0; TypeIndex < SOUND_DEVICE_TYPES; ++ TypeIndex ) 00098 { 00099 CurrentDevice = SoundDeviceListHeads[TypeIndex]; 00100 00101 while ( CurrentDevice ) 00102 { 00103 if ( CurrentDevice == SoundDevice ) 00104 { 00105 /* Found the device */ 00106 return TRUE; 00107 } 00108 00109 CurrentDevice = CurrentDevice->Next; 00110 } 00111 } 00112 00113 /* If we get here, nothing was found */ 00114 return FALSE; 00115 } 00116 00117 /* 00118 Informs the MME-Buddy library that it should take ownership of a device. 00119 The DevicePath is typically used for storing a device path (for subsequent 00120 opening using CreateFile) but it can be a wide-string representing any 00121 information that makes sense to your MME driver implementation. 00122 00123 MME components which operate solely in user-mode (for example, MIDI 00124 loopback devices) won't need to communicate with a kernel-mode device, 00125 so in these situations DevicePath is likely to be NULL. 00126 00127 Upon successful addition to the sound device list, the pointer to the new 00128 device's SOUND_DEVICE structure is returned via SoundDevice. 00129 */ 00130 MMRESULT 00131 ListSoundDevice( 00132 IN MMDEVICE_TYPE DeviceType, 00133 IN PVOID Identifier OPTIONAL, 00134 OUT PSOUND_DEVICE* SoundDevice OPTIONAL) 00135 { 00136 MMRESULT Result; 00137 PSOUND_DEVICE NewDevice; 00138 UCHAR TypeIndex = SOUND_DEVICE_TYPE_TO_INDEX(DeviceType); 00139 00140 VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceType(DeviceType) ); 00141 00142 Result = AllocateSoundDevice(DeviceType, &NewDevice); 00143 00144 if ( ! MMSUCCESS(Result) ) 00145 { 00146 SND_ERR(L"Failed to allocate SOUND_DEVICE structure\n"); 00147 return Result; 00148 } 00149 00150 if ( ! SoundDeviceListHeads[TypeIndex] ) 00151 { 00152 SND_TRACE(L"Putting first entry into device list %d\n", DeviceType); 00153 SoundDeviceListHeads[TypeIndex] = NewDevice; 00154 SoundDeviceListTails[TypeIndex] = NewDevice; 00155 } 00156 else 00157 { 00158 SND_TRACE(L"Putting another entry into device list %d\n", DeviceType); 00159 SoundDeviceListTails[TypeIndex]->Next = NewDevice; 00160 SoundDeviceListTails[TypeIndex] = NewDevice; 00161 } 00162 00163 /* Add to the count */ 00164 ++ SoundDeviceCounts[TypeIndex]; 00165 00166 /* Set up the default function table */ 00167 SetSoundDeviceFunctionTable(NewDevice, NULL); 00168 00169 /* Set up other members of the structure */ 00170 NewDevice->Identifier = Identifier; 00171 NewDevice->HeadInstance = NULL; 00172 NewDevice->TailInstance = NULL; 00173 00174 /* Fill in the caller's PSOUND_DEVICE */ 00175 if ( SoundDevice ) 00176 { 00177 *SoundDevice = NewDevice; 00178 } 00179 00180 return MMSYSERR_NOERROR; 00181 } 00182 00183 /* 00184 Removes a sound device from the list, and frees the memory associated 00185 with its description. 00186 */ 00187 MMRESULT 00188 UnlistSoundDevice( 00189 IN MMDEVICE_TYPE DeviceType, 00190 IN PSOUND_DEVICE SoundDevice) 00191 { 00192 PSOUND_DEVICE CurrentDevice, PreviousDevice; 00193 00194 UCHAR TypeIndex = SOUND_DEVICE_TYPE_TO_INDEX(DeviceType); 00195 00196 VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceType(DeviceType) ); 00197 VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) ); 00198 00199 PreviousDevice = NULL; 00200 CurrentDevice = SoundDeviceListHeads[TypeIndex]; 00201 00202 while ( CurrentDevice ) 00203 { 00204 if ( CurrentDevice == SoundDevice ) 00205 { 00206 if ( ! PreviousDevice ) 00207 { 00208 /* This is the head node */ 00209 SND_TRACE(L"Removing head node from device list %d\n", DeviceType); 00210 SoundDeviceListHeads[TypeIndex] = 00211 SoundDeviceListHeads[TypeIndex]->Next; 00212 } 00213 else 00214 { 00215 SND_TRACE(L"Removing node from device list %d\n", DeviceType); 00216 /* There are nodes before this one - cut our device out */ 00217 PreviousDevice->Next = CurrentDevice->Next; 00218 } 00219 00220 if ( ! CurrentDevice->Next ) 00221 { 00222 /* This is the tail node */ 00223 SND_TRACE(L"Removing tail node from device list %d\n", DeviceType); 00224 SoundDeviceListTails[TypeIndex] = PreviousDevice; 00225 } 00226 } 00227 00228 PreviousDevice = CurrentDevice; 00229 CurrentDevice = CurrentDevice->Next; 00230 } 00231 00232 /* Subtract from the count */ 00233 -- SoundDeviceCounts[TypeIndex]; 00234 00235 /* Finally, free up the deleted entry */ 00236 FreeSoundDevice(SoundDevice); 00237 00238 return MMSYSERR_NOERROR; 00239 } 00240 00241 /* 00242 Removes all devices from one of the device lists. 00243 */ 00244 MMRESULT 00245 UnlistSoundDevices( 00246 IN MMDEVICE_TYPE DeviceType) 00247 { 00248 UCHAR TypeIndex; 00249 VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceType(DeviceType) ); 00250 00251 SND_TRACE(L"Unlisting all sound devices of type %d\n", DeviceType); 00252 00253 TypeIndex = SOUND_DEVICE_TYPE_TO_INDEX(DeviceType); 00254 00255 /* Munch away at the head of the list until it's drained */ 00256 while ( SoundDeviceCounts[TypeIndex] > 0 ) 00257 { 00258 MMRESULT Result; 00259 Result = UnlistSoundDevice(DeviceType, SoundDeviceListHeads[TypeIndex]); 00260 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00261 } 00262 00263 return MMSYSERR_NOERROR; 00264 } 00265 00266 /* 00267 Removes all devices from all lists. 00268 */ 00269 VOID 00270 UnlistAllSoundDevices() 00271 { 00272 MMDEVICE_TYPE Type; 00273 00274 SND_TRACE(L"Unlisting all sound devices\n"); 00275 00276 for ( Type = MIN_SOUND_DEVICE_TYPE; Type <= MAX_SOUND_DEVICE_TYPE; ++ Type ) 00277 { 00278 MMRESULT Result; 00279 Result = UnlistSoundDevices(Type); 00280 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00281 } 00282 } 00283 00284 /* 00285 Provides the caller with a pointer to its desired sound device, based on 00286 the device type and index. 00287 */ 00288 MMRESULT 00289 GetSoundDevice( 00290 IN MMDEVICE_TYPE DeviceType, 00291 IN DWORD DeviceIndex, 00292 OUT PSOUND_DEVICE* SoundDevice) 00293 { 00294 UCHAR TypeIndex = SOUND_DEVICE_TYPE_TO_INDEX(DeviceType); 00295 DWORD CurrentIndex = 0; 00296 PSOUND_DEVICE CurrentDevice; 00297 00298 VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceType(DeviceType) ); 00299 00300 if ( DeviceIndex >= SoundDeviceCounts[TypeIndex] ) 00301 { 00302 SND_ERR(L"Invalid device ID %d for type %d\n", DeviceIndex, DeviceType); 00303 return MMSYSERR_BADDEVICEID; 00304 } 00305 00306 CurrentDevice = SoundDeviceListHeads[TypeIndex]; 00307 00308 /* Following the earlier checks, the index should be valid here. */ 00309 for ( CurrentIndex = 0; CurrentIndex != DeviceIndex; ++ CurrentIndex ) 00310 { 00311 SND_ASSERT( CurrentDevice ); 00312 CurrentDevice = CurrentDevice->Next; 00313 } 00314 00315 SND_TRACE(L"Returning sound device %x\n", CurrentDevice); 00316 00317 *SoundDevice = CurrentDevice; 00318 00319 return MMSYSERR_NOERROR; 00320 } 00321 00322 /* 00323 Provides the caller with the device path of the specified sound device. 00324 This will normally be the path to a device provided by a kernel-mode 00325 driver. 00326 */ 00327 MMRESULT 00328 GetSoundDeviceIdentifier( 00329 IN PSOUND_DEVICE SoundDevice, 00330 OUT PVOID* Identifier) 00331 { 00332 VALIDATE_MMSYS_PARAMETER( SoundDevice ); 00333 VALIDATE_MMSYS_PARAMETER( Identifier ); 00334 00335 /* The caller should not modify this! */ 00336 *Identifier = SoundDevice->Identifier; 00337 00338 return MMSYSERR_NOERROR; 00339 } 00340 00341 /* 00342 Provides the caller with the device type of the specified sound device. 00343 This will be, for example, WAVE_OUT_DEVICE_TYPE, WAVE_IN_DEVICE_TYPE ... 00344 */ 00345 MMRESULT 00346 GetSoundDeviceType( 00347 IN PSOUND_DEVICE SoundDevice, 00348 OUT PMMDEVICE_TYPE DeviceType) 00349 { 00350 VALIDATE_MMSYS_PARAMETER( SoundDevice ); 00351 VALIDATE_MMSYS_PARAMETER( DeviceType ); 00352 00353 *DeviceType = SoundDevice->Type; 00354 00355 return MMSYSERR_NOERROR; 00356 } Generated on Sun May 27 2012 04:21:43 for ReactOS by
1.7.6.1
|