ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

devicelist.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.