home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
xwphescr.zip
/
XWPH0208.ZIP
/
src
/
helpers
/
syssound.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-07-05
|
28KB
|
780 lines
/*
*@@sourcefile syssound.c:
* this has code for querying and manipulating the
* system sounds, which are stored in MMPM.INI in
* the MMOS2 directory. Also, we have support for
* manipulating Warp 4 sound schemes in here too.
* This code works on Warp 3 also.
*
* Usage: All OS/2 programs.
*
* Some of this code used to be in XWorkplace's main\common.c,
* as far as the regular system sounds were concerned.
* However, all this code has been greatly reworked
* and extended with V0.9.0.
*
* <B>About system sound configuration data</B>
*
* The current system sounds are stored in ?:\MMOS2\MMPM.INI.
*
* These are the general flags in the "MMPM2_AlarmSoundsData"
* application:
*
* -- If "EnableSounds" is FALSE, all system sounds are disabled.
* This defaults to TRUE (tested).
*
* -- If "ApplyVolumeToAll" is TRUE, the same volume is used for
* all sounds. This defaults to FALSE (tested).
*
* -- If ApplyVolumeToAll is TRUE, "Volume" is used for the
* global volume. Otherwise, the individual sound volumes
* (below) will be used.
*
* "MMPM2_AlarmSounds" then has all the system sounds. The keys
* in that application are numerical indices, which are listed
* in syssound.h.
*
* Each sound data block in there consists of three elements:
*
+ soundfile#description#volume
*
* where "description" is what is listed in the "Sound" object.
* "volume" is only used when "ApplyVolumeToAll" (above) is FALSE.
*
* We have functions in this code file for decoding/setting this
* (sndParseSoundData, sndQuerySystemSound, sndWriteSoundData,
* sndSetSystemSound).
*
* By contrast (and for no real reason), Warp 4 stores the
* "sound schemes" in OS2SYS.INI. I stuck with that for compatibility,
* although this prevents several users from having different
* sound schemes. What the heck.
*
* Anyways, the "PM_SOUND_SCHEMES_LIST" application is a directory of
* schemes, which in turn point to other applications in OS2SYS.INI
* which have the actual sound scheme data. All these applications
* appear to start with "PM_SOUND_xxx" by convention.
*
* Note that as opposed to the sound data in MMPM.INI, only the
* sound file name is stored here (not the three elements as
* described above). We slightly extend that mechanism to add an
* additional volume data field after the first null byte. This
* allows the default WPSound object to still be able to read
* the sound scheme data (it apparently uses PrfQueryProfileString)
* while the XWorkplace sound object replacement (XWPSound) can
* still store volume data as well.
*
* I have created more functions in this code file to easily load and
* store sound schemes (sndDoesSchemeExist, sndCreateSoundScheme,
* sndLoadSoundScheme, sndDestroySoundScheme).
*
* Note: Version numbering in this file relates to XWorkplace version
* numbering.
*
*@@header "helpers\syssound.h"
*@@added V0.9.0 [umoeller]
*/
#define OS2EMX_PLAIN_CHAR
// this is needed for "os2emx.h"; if this is defined,
// emx will define PSZ as _signed_ char, otherwise
// as unsigned char
#define INCL_DOSERRORS
#define INCL_WINSHELLDATA
#include <os2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "setup.h" // code generation and debugging options
#include "helpers\dosh.h"
#include "helpers\prfh.h"
#include "helpers\syssound.h"
#pragma hdrstop
/*
*@@category: Helpers\Profile (INI) helpers\System sounds
* see syssound.c.
*/
/*
*@@ sndParseSoundData:
* this helper func splits the system sound data
* passed to it into three buffers.
* Each key data in there has the following format:
+ soundfile#description#volume.
*
* This is copied into the three specified buffers.
* You can set any buffer pointer to NULL if you're
* not interested in that data.
*
* Returns the number of items successfully parsed,
* which should be 3.
*
*@@added V0.9.0 [umoeller]
*@@changed V0.9.20 (2002-07-03) [umoeller]: optimized
*/
ULONG sndParseSoundData(PCSZ pszSoundData, // in: INI data from MMPM.INI
PSZ pszDescr, // out: sound description, as displayed
// in the "Sound" object (ptr may be NULL)
PSZ pszFile, // out: sound file to (ptr may be NULL)
PULONG pulVolume) // out: sound volume (0-100). Note:
// this always returns the individual sound volume,
// even if "Global volume" is set in MMPM.INI.
{
PCSZ p1 = pszSoundData, p2;
ULONG ulrc = 0;
// get sound file
if (p2 = strchr(p1, '#'))
{
ulrc++;
if (pszFile)
{
strncpy(pszFile, p1, p2 - p1);
pszFile[p2-p1] = '\0';
}
p1 = p2+1;
// get sound description
if (p2 = strchr(p1, '#'))
{
ulrc++;
if (pszDescr)
{
strncpy(pszDescr, p1, p2-p1);
pszDescr[p2-p1] = '\0';
}
p1 = p2+1;
// get volume (0-100)
if (pulVolume)
{
// individual volume settings per sound
*pulVolume = atoi(p1); // V0.9.20 (2002-07-03) [umoeller]
// sscanf(p1, "%lu", pulVolume);
ulrc++;
}
}
}
return ulrc;
}
/*
*@@ sndQueryMmpmIniPath:
* writes the full path of MMPM.INI into
* the specified buffer (e.g. C:\MMOS2\MMPM.INI).
*
*@@added V0.9.10 (2001-04-16) [umoeller]
*/
VOID sndQueryMmpmIniPath(PSZ pszMMPM) // out: fully q'fied MMPM.INI
{
PSZ pszMMPMPath;
if (pszMMPMPath = getenv("MMBASE")) // V0.9.6 (2000-10-16) [umoeller]
{
// variable set:
PSZ p;
strcpy(pszMMPM, pszMMPMPath); // V0.9.7 (2000-12-17) [umoeller]
// kill semicolon if present
if (p = strchr(pszMMPM, ';'))
*p = 0;
strcat(pszMMPM, "\\MMPM.INI");
}
else
// variable not set (shouldn't happen): try boot drive
sprintf(pszMMPM, "%c:\\MMOS2\\MMPM.INI", doshQueryBootDrive());
}
/*
*@@ sndOpenMmpmIni:
* this opens \MMOS2\MMPM.INI on the
* boot drive and returns the profile
* handle (or NULLHANDLE upon errors).
* Use PrfCloseProfile to close the
* profile again.
*
*@@added V0.9.1 (99-12-19) [umoeller]
*@@changed V0.9.6 (2000-10-16) [umoeller]: now using MMBASE environment variable
*@@changed V0.9.6 (2000-10-16) [umoeller]: added proper HAB param
*@@changed V0.9.7 (2000-12-17) [umoeller]: fixed broken MMBASE handling
*/
HINI sndOpenMmpmIni(HAB hab)
{
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
CHAR szMMPM[CCHMAXPATH];
sndQueryMmpmIniPath(szMMPM);
return PrfOpenProfile(habDesktop, szMMPM);
}
/*
*@@ sndQuerySystemSound:
* this gets a system sound from the MMPM.INI file.
* usIndex must be the sound to query. The following
* MMSOUND_* IDs are declared in syssound.h:
*
* Default system sounds (syssound.h):
* -- MMSOUND_WARNING 0
* -- MMSOUND_INFORMATION 1
* -- MMSOUND_ERROR 2
* -- MMSOUND_ANIMATEOPEN 3
* -- MMSOUND_ANIMATECLOSE 4
* -- MMSOUND_DRAG 5
* -- MMSOUND_DROP 6
* -- MMSOUND_SYSTEMSTARTUP 7
* -- MMSOUND_SHUTDOWN 8
* -- MMSOUND_SHREDDER 9
* -- MMSOUND_LOCKUP 10
* -- MMSOUND_ALARMCLOCK 11
* -- MMSOUND_PRINTERROR 12
*
* BTW, these values match those of the WinAlarm call
* (WA_* values), but only the first three are documented
* in PMREF and pmwin.h (WA_WARNING, WA_NOTE, WA_ERROR).
*
* New XWorkplace system sounds:
* -- MMSOUND_XFLD_SHUTDOWN 555
* -- MMSOUND_XFLD_RESTARTWPS 556
* -- MMSOUND_XFLD_CTXTOPEN 558
* -- MMSOUND_XFLD_CTXTSELECT 559
* -- MMSOUND_XFLD_CNRDBLCLK 560
*
* The string buffers are recommended to be at least
* CCHMAXPATH in size.
*
*@@changed V0.9.0 [umoeller]: this used to be cmnQuerySystemSound
*@@changed V0.9.0 [umoeller]: exported stuff to sndParseSoundData
*@@changed V0.9.6 (2000-10-16) [umoeller]: added proper HAB param
*/
BOOL sndQuerySystemSound(HAB hab, // in: caller's anchor block
USHORT usIndex, // in: sound index to query
PSZ pszDescr, // out: sound description, as displayed
// in the "Sound" object (ptr may be NULL)
PSZ pszFile, // out: sound file to (ptr may be NULL)
PULONG pulVolume) // out: sound volume (0-100).
// If the "Global volume" flag is
// set in MMPM.INI, this will return the global
// volume instead. Ptr may be NULL also.
{
BOOL rc = FALSE;
HINI hiniMMPM = sndOpenMmpmIni(hab);
#ifdef DEBUG_SOUNDS
_Pmpf((__FUNCTION__ ": entering, hiniMMPM is 0x%lX", hiniMMPM));
#endif
if (hiniMMPM)
{
CHAR szData[1000];
CHAR szData2[100];
CHAR szKey[10];
sprintf(szKey, "%d", usIndex);
PrfQueryProfileString(hiniMMPM,
MMINIKEY_SOUNDSETTINGS, "EnableSounds",
"TRUE", // default string
szData2, sizeof(szData2));
#ifdef DEBUG_SOUNDS
_Pmpf((" sounds enabled: %s", szData2));
#endif
if (strcmp(szData2, "TRUE") == 0)
// sounds enabled at all?
if (PrfQueryProfileString(hiniMMPM,
MMINIKEY_SYSSOUNDS, szKey,
".",
szData, sizeof(szData)-1) > 3)
{
sndParseSoundData(szData,
pszDescr,
pszFile,
pulVolume);
// if "global volume" has been enabled,
// we do not return the value specified
// here, but the global value
PrfQueryProfileString(hiniMMPM,
MMINIKEY_SOUNDSETTINGS, "ApplyVolumeToAll",
"FALSE",
szData2, sizeof(szData2));
if (strcmp(szData2, "FALSE") != 0)
{
// global volume setting for all sounds
PrfQueryProfileString(hiniMMPM,
MMINIKEY_SOUNDSETTINGS, "Volume",
"100",
szData2, sizeof(szData2));
sscanf(szData2, "%lu", pulVolume);
}
rc = TRUE;
}
PrfCloseProfile(hiniMMPM);
}
return rc;
}
/*
*@@ sndWriteSoundData:
* this sets a system sound in MMPM.INI.
* Gets called by sndSetSystemSound. As opposed
* to that function, this needs the profile handle
* of MMPM.INI.
*
* If (pszDescr == NULL), that sound entry is removed.
*
* Returns the return value of PrfWriteProfileString.
*
*@@added V0.9.0 [umoeller]
*@@changed V0.9.1 (99-12-30) [umoeller]: added delete support
*@@changed V0.9.6 (2000-10-16) [umoeller]: added MMPM/2 notify
*/
BOOL sndWriteSoundData(HINI hiniMMPM, // in: MMPM.INI handle (from sndOpenMmpmIni)
USHORT usIndex, // in: sound index
PCSZ pszDescr, // in: sound name or NULL for removal
PCSZ pszFile, // in: sound file
ULONG ulVolume) // in: sound volume
{
BOOL brc = FALSE;
CHAR szKey[10];
sprintf(szKey, "%d", usIndex);
if (pszDescr)
{
CHAR szData[1000];
// format: soundfile#description#volume
sprintf(szData, "%s#%s#%lu", pszFile, pszDescr, ulVolume);
brc = PrfWriteProfileString(hiniMMPM,
MMINIKEY_SYSSOUNDS,
szKey,
szData);
}
else
// pszDescr == NULL:
// delete entry
brc = PrfWriteProfileString(hiniMMPM,
MMINIKEY_SYSSOUNDS,
szKey,
NULL);
if (brc)
// success:
if (usIndex < 100)
// one of the default OS/2 sounds has changed:
// we then need to notify MMPM/2...
// this is done by calling WinAlarm with 1000+index!
// sick stuff..
WinAlarm(HWND_DESKTOP, usIndex+1000); // V0.9.6 (2000-10-16) [umoeller]
return brc;
}
/*
*@@ sndSetSystemSound:
* this sets a system sound in MMPM.INI by
* calling sndWriteSoundData.
* Returns FALSE if an error occured.
*
* See sndQuerySystemSound for the parameters.
*
*@@changed V0.9.0 [umoeller]: this used to be cmnSetSystemSound
*@@changed V0.9.0 [umoeller]: exported stuff to sndWriteSoundData
*@@changed V0.9.6 (2000-10-16) [umoeller]: added proper HAB param
*/
BOOL sndSetSystemSound(HAB hab,
USHORT usIndex,
PCSZ pszDescr,
PCSZ pszFile,
ULONG ulVolume)
{
BOOL brc = FALSE;
HINI hiniMMPM;
if (hiniMMPM = sndOpenMmpmIni(hab))
{
brc = sndWriteSoundData(hiniMMPM, usIndex, pszDescr, pszFile, ulVolume);
PrfCloseProfile(hiniMMPM);
}
return brc;
}
/*
*@@ sndDoesSchemeExist:
* returns TRUE if pszScheme already exists
* in OS2SYS.INI.
*
* If so, and *ppszRealScheme is != NULL, it
* is set to the key name found. Since the
* scheme names are case-insensitive, this
* check is necessary to delete the original
* scheme for overwrites. The caller is
* responsible for free()ing *ppszRealScheme
* then.
*
*@@added V0.9.0 [umoeller]
*@@changed V0.9.20 (2002-07-03) [umoeller]: check has to be case-insensitive, fixed; changed prototype
*/
BOOL sndDoesSchemeExist(PCSZ pcszScheme,
PSZ *ppszRealScheme) // out: actual key name (ptr can be NULL)
{
BOOL fExists = FALSE;
PSZ pszKeysList;
if (!prfhQueryKeysForApp(HINI_SYSTEM,
MMINIKEY_SOUNDSCHEMES, // "PM_SOUND_SCHEMES_LIST"
&pszKeysList))
{
PSZ pKey2 = pszKeysList;
while (*pKey2)
{
if (!stricmp(pKey2, pcszScheme))
{
fExists = TRUE;
if (ppszRealScheme)
*ppszRealScheme = strdup(pKey2);
break;
}
pKey2 += strlen(pKey2)+1; // next key
}
free(pszKeysList);
}
return fExists;
/* old code V0.9.20 (2002-07-03) [umoeller]
// check in OS2SYS.INI's scheme list whether that
// scheme exists already
PSZ pszExisting = prfhQueryProfileData(HINI_SYSTEM,
MMINIKEY_SOUNDSCHEMES, // "PM_SOUND_SCHEMES_LIST"
pszScheme,
NULL);
if (pszExisting)
{
free(pszExisting);
return (TRUE);
}
return (FALSE);
*/
}
/*
*@@ sndCreateSoundScheme:
* this creates a new sound scheme and copies
* the current data in MMPM.INI into it.
* No check is made for whether that sound
* scheme exists already (use sndDoesSchemeExist
* for that). Data is overwritten without further
* discussion.
*
* Returns:
* -- NO_ERROR
* -- ERROR_INVALID_HANDLE: hiniMMPM invalid
* -- ERROR_NO_DATA: scheme not found.
*
*@@added V0.9.0 [umoeller]
*/
APIRET sndCreateSoundScheme(HINI hiniMMPM, // in: MMPM.INI handle (from sndOpenMmpmIni)
PCSZ pszNewScheme) // in: name of new scheme
{
APIRET arc = NO_ERROR;
CHAR szNewAppName[200] = "PM_SOUNDS_";
// create a unique new application name for
// this scheme in OS2SYS.INI (this is how
// Warp 4 apparently does it)
strcat(szNewAppName, pszNewScheme); // PM_SOUNDS_blahblah
strupr(szNewAppName); // PM_SOUNDS_BLAHBLAH
if (hiniMMPM)
{
// get applications list for sounds list in MMPM.INI
PSZ pszKeysList = NULL;
if (!(arc = prfhQueryKeysForApp(hiniMMPM,
MMINIKEY_SYSSOUNDS, // "MMPM2_AlarmSounds"
&pszKeysList)))
{
PSZ pKey2 = pszKeysList;
CHAR szFile[CCHMAXPATH+50];
ULONG ulVolume,
ulKeyLen;
while (*pKey2 != 0)
{
// now copy this key to the new sound scheme;
// however, we can't just copy the whole key,
// but need to extract the file name and
// volume first.
// Warp 4 normally _only_ stores the file name
// in the sound schemes. Since we want the
// volume also, we add a null char after the
// file name and append the volume...
PSZ pSoundData;
if (pSoundData = prfhQueryProfileData(hiniMMPM,
MMINIKEY_SYSSOUNDS, // "MMPM2_AlarmSounds"
pKey2,
NULL))
{
sndParseSoundData(pSoundData,
NULL, // we don't need the description
szFile,
&ulVolume);
ulKeyLen = strlen(szFile)+1; // go beyond null byte
ulKeyLen += sprintf(szFile+ulKeyLen,
"%lu",
ulVolume) + 1;
// and write to OS2SYS.INI
PrfWriteProfileData(HINI_SYSTEM,
szNewAppName,
pKey2,
szFile,
ulKeyLen);
free(pSoundData);
} // end if (pSoundData)
pKey2 += strlen(pKey2)+1;
} // end while (*pKey2 != 0)
free (pszKeysList);
// finally, store new scheme in schemes list
PrfWriteProfileString(HINI_SYSTEM,
MMINIKEY_SOUNDSCHEMES, // "PM_SOUND_SCHEMES_LIST"
(PSZ)pszNewScheme, // key is scheme name
szNewAppName); // data is new OS2SYS.INI application
}
else
arc = ERROR_NO_DATA;
}
else
arc = ERROR_INVALID_HANDLE;
return arc;
}
/*
*@@ sndLoadSoundScheme:
* this loads the data in pszScheme (OS2SYS.INI)
* into MMPM.INI. Existing sound data
* in that profile will be overwritten.
*
* Note: Only those sounds in MMPM.INI will be
* overwritten for which a corresponding entry
* in the sound scheme exists. If it doesn't,
* the data in MMPM.INI for _that_ sound only
* will _not_ be changed. In other words, existing
* sound data will be merged with the scheme data.
*
* If you don't like this, delete the whole
* "MMPM2_AlarmSounds" application in MMPM.INI
* before calling this function.
*
* Returns:
* -- NO_ERROR
* -- ERROR_INVALID_HANDLE: hiniMMPM invalid
* -- ERROR_NO_DATA: scheme not found.
* -- ERROR_BAD_FORMAT: error in MMPM.INI data.
*
*@@added V0.9.0 [umoeller]
*@@changed V0.9.1 (99-12-20) [umoeller]: fixed memory leak
*@@changed V0.9.6 (2000-10-16) [umoeller]: added MMPM/2 notify
*/
APIRET sndLoadSoundScheme(HINI hiniMMPM, // in: HINI of ?:\MMOS2\MMPM.INI (PrfOpenProfile)
PCSZ pszScheme) // in: scheme name
{
APIRET arc = NO_ERROR;
#ifdef DEBUG_SOUNDS
_Pmpf(("Entering sndLoadSoundScheme"));
#endif
if (hiniMMPM)
{
// check in OS2SYS.INI's scheme list whether that
// scheme exists already
PSZ pszSchemeAppName = prfhQueryProfileData(HINI_SYSTEM,
MMINIKEY_SOUNDSCHEMES, // "PM_SOUND_SCHEMES_LIST"
pszScheme,
NULL);
#ifdef DEBUG_SOUNDS
_Pmpf((" pszSchemeAppName: %s", pszSchemeAppName));
#endif
if (pszSchemeAppName)
{
// now copy keys from OS2SYS.INI to MMPM.INI;
// since OS2SYS.INI _only_ has the file name
// (and _maybe_ the individual volume, if it
// was us who created the sound scheme --
// see sndCreateSoundScheme above), we need
// to go thru the MMPM.INI (!) sounds lists
// and merge the data in there with the
// corresponding sound data for the current
// scheme...
// get applications list for sounds list in MMPM.INI
PSZ pszMMPMKeysList = NULL;
if (!(arc = prfhQueryKeysForApp(hiniMMPM,
MMINIKEY_SYSSOUNDS,// "MMPM2_AlarmSounds"
&pszMMPMKeysList)))
{
PSZ pMMPMKey2 = pszMMPMKeysList,
pMMPMSoundData,
pSchemeSoundData;
CHAR szDescription[300]; // from MMPM.INI
CHAR szFile[CCHMAXPATH+50]; // from OS2SYS.INI
ULONG ulVolume; // from MMPM.INI _or_ OS2SYS.INI
CHAR szData[1000];
// go thru keys (numbers)
while (*pMMPMKey2 != 0)
{
ULONG cbSchemeSoundData = 0,
cbSchemeSoundFile = 0;
pMMPMSoundData = prfhQueryProfileData(hiniMMPM,
MMINIKEY_SYSSOUNDS, // "MMPM2_AlarmSounds"
pMMPMKey2,
NULL);
pSchemeSoundData = prfhQueryProfileData(HINI_SYSTEM,
pszSchemeAppName,
pMMPMKey2,
&cbSchemeSoundData);
if ((pMMPMSoundData) && (pSchemeSoundData))
{
sndParseSoundData(pMMPMSoundData,
szDescription,
NULL, // we don't need the file
&ulVolume);
// now overwrite this data with scheme data
strcpy(szFile,
pSchemeSoundData); // up to first null byte
cbSchemeSoundFile = strlen(pSchemeSoundData)+1;
if (cbSchemeSoundData > cbSchemeSoundFile)
// this means we have an additional volume string
// after the null byte (sndCreateSoundScheme);
// copy it
sscanf(pSchemeSoundData + cbSchemeSoundFile,
"%lu",
&ulVolume);
// and write data to MMPM.INI
// format: soundfile#description#volume
sprintf(szData, "%s#%s#%lu", szFile, szDescription, ulVolume);
if (PrfWriteProfileString(hiniMMPM,
MMINIKEY_SYSSOUNDS, // "MMPM2_AlarmSounds"
pMMPMKey2, // key (decimal number)
szData))
{
// success:
USHORT usIndex = atoi(pMMPMKey2);
if (usIndex < 100)
// this was one of the default OS/2 sounds:
// notify MMPM/2 of the change... see sndWriteSoundData
// V0.9.6 (2000-10-16) [umoeller]
WinAlarm(HWND_DESKTOP, usIndex+1000);
}
}
if (pMMPMSoundData)
free(pMMPMSoundData);
if (pSchemeSoundData)
free(pSchemeSoundData);
pMMPMKey2 += strlen(pMMPMKey2)+1;
} // end while (*pMMPMKey2 != 0)
free (pszMMPMKeysList);
}
else
arc = ERROR_BAD_FORMAT;
free(pszSchemeAppName);
} // end if (pszSchemeAppName)
else
arc = ERROR_NO_DATA;
}
else
arc = ERROR_INVALID_HANDLE;
#ifdef DEBUG_SOUNDS
_Pmpf(("End of sndLoadSoundScheme, arc: %d", arc));
#endif
return arc;
}
/*
*@@ sndDestroySoundScheme:
* destroys pszScheme in OS2SYS.INI;
* returns TRUE is pszScheme was found
* and deleted.
*
* See xsound.c for explanations.
*
* Returns:
* -- NO_ERROR
* -- ERROR_NO_DATA: scheme not found.
*
*@@added V0.9.0 [umoeller]
*/
APIRET sndDestroySoundScheme(PCSZ pszScheme)
{
APIRET arc = NO_ERROR;
// check in OS2SYS.INI's scheme list whether that
// scheme exists
PSZ pszExisting;
if (pszExisting = prfhQueryProfileData(HINI_SYSTEM,
MMINIKEY_SOUNDSCHEMES, // "PM_SOUND_SCHEMES_LIST"
pszScheme,
NULL))
{
// delete whole existing PM_SOUNDS_BLAHBLAH application
PrfWriteProfileString(HINI_SYSTEM,
pszExisting, // application
NULL,
NULL);
// and delete entry in sound schemes list
PrfWriteProfileString(HINI_SYSTEM,
MMINIKEY_SOUNDSCHEMES, // "PM_SOUND_SCHEMES_LIST"
(PSZ)pszScheme,
NULL);
free(pszExisting);
}
else
arc = ERROR_NO_DATA;
return arc;
}