Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenplaysound.c
Go to the documentation of this file.
00001 /* -*- tab-width: 8; c-basic-offset: 4 -*- */ 00002 00003 /* 00004 * MMSYSTEM functions 00005 * 00006 * Copyright 1993 Martin Ayotte 00007 * 1998-2002 Eric Pouech 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * This library is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00022 */ 00023 00024 #include <stdarg.h> 00025 #include <string.h> 00026 00027 #include "windef.h" 00028 #include "winbase.h" 00029 #include "mmsystem.h" 00030 #include "wingdi.h" 00031 #include "winuser.h" 00032 #include "winreg.h" 00033 #include "winemm.h" 00034 #include "winternl.h" 00035 00036 #include "wine/debug.h" 00037 00038 WINE_DEFAULT_DEBUG_CHANNEL(winmm); 00039 00040 typedef struct tagWINE_PLAYSOUND 00041 { 00042 unsigned bLoop : 1, 00043 bAlloc : 1; 00044 LPCWSTR pszSound; 00045 HMODULE hMod; 00046 DWORD fdwSound; 00047 HANDLE hThread; 00048 HWAVEOUT hWave; 00049 struct tagWINE_PLAYSOUND* lpNext; 00050 } WINE_PLAYSOUND; 00051 00052 static WINE_PLAYSOUND *PlaySoundList; 00053 00054 static HMMIO get_mmioFromFile(LPCWSTR lpszName) 00055 { 00056 HMMIO ret; 00057 WCHAR buf[256]; 00058 LPWSTR dummy; 00059 00060 ret = mmioOpenW((LPWSTR)lpszName, NULL, 00061 MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE); 00062 if (ret != 0) return ret; 00063 if (SearchPathW(NULL, lpszName, NULL, sizeof(buf)/sizeof(buf[0]), buf, &dummy)) 00064 { 00065 return mmioOpenW(buf, NULL, 00066 MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE); 00067 } 00068 return 0; 00069 } 00070 00071 static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName) 00072 { 00073 WCHAR str[128]; 00074 LPWSTR ptr; 00075 HMMIO hmmio; 00076 HKEY hRegSnd, hRegApp, hScheme, hSnd; 00077 DWORD err, type, count; 00078 00079 static const WCHAR wszSounds[] = {'S','o','u','n','d','s',0}; 00080 static const WCHAR wszDefault[] = {'D','e','f','a','u','l','t',0}; 00081 static const WCHAR wszKey[] = {'A','p','p','E','v','e','n','t','s','\\', 00082 'S','c','h','e','m','e','s','\\', 00083 'A','p','p','s',0}; 00084 static const WCHAR wszDotDefault[] = {'.','D','e','f','a','u','l','t',0}; 00085 static const WCHAR wszDotCurrent[] = {'.','C','u','r','r','e','n','t',0}; 00086 static const WCHAR wszNull[] = {0}; 00087 00088 TRACE("searching in SystemSound list for %s\n", debugstr_w(lpszName)); 00089 GetProfileStringW(wszSounds, lpszName, wszNull, str, sizeof(str)/sizeof(str[0])); 00090 if (lstrlenW(str) == 0) 00091 { 00092 if (uFlags & SND_NODEFAULT) goto next; 00093 GetProfileStringW(wszSounds, wszDefault, wszNull, str, sizeof(str)/sizeof(str[0])); 00094 if (lstrlenW(str) == 0) goto next; 00095 } 00096 for (ptr = str; *ptr && *ptr != ','; ptr++); 00097 if (*ptr) *ptr = 0; 00098 hmmio = mmioOpenW(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE); 00099 if (hmmio != 0) return hmmio; 00100 next: 00101 /* we look up the registry under 00102 * HKCU\AppEvents\Schemes\Apps\.Default 00103 * HKCU\AppEvents\Schemes\Apps<AppName> 00104 */ 00105 if (RegOpenKeyW(HKEY_CURRENT_USER, wszKey, &hRegSnd) != 0) goto none; 00106 if (uFlags & SND_APPLICATION) 00107 { 00108 DWORD len; 00109 00110 err = 1; /* error */ 00111 len = GetModuleFileNameW(0, str, sizeof(str)/sizeof(str[0])); 00112 if (len > 0 && len < sizeof(str)/sizeof(str[0])) 00113 { 00114 for (ptr = str + lstrlenW(str) - 1; ptr >= str; ptr--) 00115 { 00116 if (*ptr == '.') *ptr = 0; 00117 if (*ptr == '\\') 00118 { 00119 err = RegOpenKeyW(hRegSnd, ptr+1, &hRegApp); 00120 break; 00121 } 00122 } 00123 } 00124 } 00125 else 00126 { 00127 err = RegOpenKeyW(hRegSnd, wszDotDefault, &hRegApp); 00128 } 00129 RegCloseKey(hRegSnd); 00130 if (err != 0) goto none; 00131 err = RegOpenKeyW(hRegApp, lpszName, &hScheme); 00132 RegCloseKey(hRegApp); 00133 if (err != 0) goto none; 00134 /* what's the difference between .Current and .Default ? */ 00135 err = RegOpenKeyW(hScheme, wszDotDefault, &hSnd); 00136 if (err != 0) 00137 { 00138 err = RegOpenKeyW(hScheme, wszDotCurrent, &hSnd); 00139 RegCloseKey(hScheme); 00140 if (err != 0) 00141 goto none; 00142 } 00143 count = sizeof(str)/sizeof(str[0]); 00144 err = RegQueryValueExW(hSnd, NULL, 0, &type, (LPBYTE)str, &count); 00145 RegCloseKey(hSnd); 00146 if (err != 0 || !*str) goto none; 00147 hmmio = mmioOpenW(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE); 00148 if (hmmio) return hmmio; 00149 none: 00150 WARN("can't find SystemSound=%s !\n", debugstr_w(lpszName)); 00151 return 0; 00152 } 00153 00154 struct playsound_data 00155 { 00156 HANDLE hEvent; 00157 LONG dwEventCount; 00158 }; 00159 00160 static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg, 00161 DWORD_PTR dwInstance, 00162 DWORD_PTR dwParam1, DWORD_PTR dwParam2) 00163 { 00164 struct playsound_data* s = (struct playsound_data*)dwInstance; 00165 00166 switch (uMsg) { 00167 case WOM_OPEN: 00168 case WOM_CLOSE: 00169 break; 00170 case WOM_DONE: 00171 InterlockedIncrement(&s->dwEventCount); 00172 TRACE("Returning waveHdr=%lx\n", dwParam1); 00173 SetEvent(s->hEvent); 00174 break; 00175 default: 00176 ERR("Unknown uMsg=%d\n", uMsg); 00177 } 00178 } 00179 00180 static void PlaySound_WaitDone(struct playsound_data* s) 00181 { 00182 for (;;) { 00183 ResetEvent(s->hEvent); 00184 if (InterlockedDecrement(&s->dwEventCount) >= 0) break; 00185 InterlockedIncrement(&s->dwEventCount); 00186 00187 WaitForSingleObject(s->hEvent, INFINITE); 00188 } 00189 } 00190 00191 static BOOL PlaySound_IsString(DWORD fdwSound, const void* psz) 00192 { 00193 /* SND_RESOURCE is 0x40004 while 00194 * SND_MEMORY is 0x00004 00195 */ 00196 switch (fdwSound & (SND_RESOURCE|SND_ALIAS_ID|SND_FILENAME)) 00197 { 00198 case SND_RESOURCE: return HIWORD(psz) != 0; /* by name or by ID ? */ 00199 case SND_ALIAS_ID: 00200 case SND_MEMORY: return FALSE; 00201 case SND_ALIAS: 00202 case SND_FILENAME: 00203 case 0: return TRUE; 00204 default: FIXME("WTF\n"); return FALSE; 00205 } 00206 } 00207 00208 static void PlaySound_Free(WINE_PLAYSOUND* wps) 00209 { 00210 WINE_PLAYSOUND** p; 00211 00212 EnterCriticalSection(&WINMM_cs); 00213 for (p = &PlaySoundList; *p && *p != wps; p = &((*p)->lpNext)); 00214 if (*p) *p = (*p)->lpNext; 00215 if (PlaySoundList == NULL) SetEvent(psLastEvent); 00216 LeaveCriticalSection(&WINMM_cs); 00217 if (wps->bAlloc) HeapFree(GetProcessHeap(), 0, (void*)wps->pszSound); 00218 if (wps->hThread) CloseHandle(wps->hThread); 00219 HeapFree(GetProcessHeap(), 0, wps); 00220 } 00221 00222 static WINE_PLAYSOUND* PlaySound_Alloc(const void* pszSound, HMODULE hmod, 00223 DWORD fdwSound, BOOL bUnicode) 00224 { 00225 WINE_PLAYSOUND* wps; 00226 00227 wps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wps)); 00228 if (!wps) return NULL; 00229 00230 wps->hMod = hmod; 00231 wps->fdwSound = fdwSound; 00232 if (PlaySound_IsString(fdwSound, pszSound)) 00233 { 00234 if (bUnicode) 00235 { 00236 if (fdwSound & SND_ASYNC) 00237 { 00238 LPWSTR sound = HeapAlloc(GetProcessHeap(), 0, 00239 (lstrlenW(pszSound)+1) * sizeof(WCHAR)); 00240 if (!sound) goto oom_error; 00241 wps->pszSound = lstrcpyW(sound, pszSound); 00242 wps->bAlloc = TRUE; 00243 } 00244 else 00245 wps->pszSound = pszSound; 00246 } 00247 else 00248 { 00249 UNICODE_STRING usBuffer; 00250 RtlCreateUnicodeStringFromAsciiz(&usBuffer, pszSound); 00251 wps->pszSound = usBuffer.Buffer; 00252 if (!wps->pszSound) goto oom_error; 00253 wps->bAlloc = TRUE; 00254 } 00255 } 00256 else 00257 wps->pszSound = pszSound; 00258 00259 return wps; 00260 oom_error: 00261 PlaySound_Free(wps); 00262 return NULL; 00263 } 00264 00265 static DWORD WINAPI proc_PlaySound(LPVOID arg) 00266 { 00267 WINE_PLAYSOUND* wps = arg; 00268 BOOL bRet = FALSE; 00269 HMMIO hmmio = 0; 00270 MMCKINFO ckMainRIFF; 00271 MMCKINFO mmckInfo; 00272 LPWAVEFORMATEX lpWaveFormat = NULL; 00273 LPWAVEHDR waveHdr = NULL; 00274 INT count, bufsize, left, index; 00275 struct playsound_data s; 00276 void* data; 00277 00278 s.hEvent = 0; 00279 00280 TRACE("SoundName=%s !\n", debugstr_w(wps->pszSound)); 00281 00282 /* if resource, grab it */ 00283 if ((wps->fdwSound & SND_RESOURCE) == SND_RESOURCE) { 00284 static const WCHAR wszWave[] = {'W','A','V','E',0}; 00285 HRSRC hRes; 00286 HGLOBAL hGlob; 00287 00288 if ((hRes = FindResourceW(wps->hMod, wps->pszSound, wszWave)) == 0 || 00289 (hGlob = LoadResource(wps->hMod, hRes)) == 0) 00290 goto errCleanUp; 00291 if ((data = LockResource(hGlob)) == NULL) { 00292 FreeResource(hGlob); 00293 goto errCleanUp; 00294 } 00295 FreeResource(hGlob); 00296 } else 00297 data = (void*)wps->pszSound; 00298 00299 /* construct an MMIO stream (either in memory, or from a file */ 00300 if (wps->fdwSound & SND_MEMORY) 00301 { /* NOTE: SND_RESOURCE has the SND_MEMORY bit set */ 00302 MMIOINFO mminfo; 00303 00304 memset(&mminfo, 0, sizeof(mminfo)); 00305 mminfo.fccIOProc = FOURCC_MEM; 00306 mminfo.pchBuffer = data; 00307 mminfo.cchBuffer = -1; /* FIXME: when a resource, could grab real size */ 00308 TRACE("Memory sound %p\n", data); 00309 hmmio = mmioOpenW(NULL, &mminfo, MMIO_READ); 00310 } 00311 else if (wps->fdwSound & SND_ALIAS) 00312 { 00313 if ((wps->fdwSound & SND_ALIAS_ID) == SND_ALIAS_ID) 00314 { 00315 static const WCHAR wszSystemAsterisk[] = {'S','y','s','t','e','m','A','s','t','e','r','i','s','k',0}; 00316 static const WCHAR wszSystemDefault[] = {'S','y','s','t','e','m','D','e','f','a','u','l','t',0}; 00317 static const WCHAR wszSystemExclamation[] = {'S','y','s','t','e','m','E','x','c','l','a','m','a','t','i','o','n',0}; 00318 static const WCHAR wszSystemExit[] = {'S','y','s','t','e','m','E','x','i','t',0}; 00319 static const WCHAR wszSystemHand[] = {'S','y','s','t','e','m','H','a','n','d',0}; 00320 static const WCHAR wszSystemQuestion[] = {'S','y','s','t','e','m','Q','u','e','s','t','i','o','n',0}; 00321 static const WCHAR wszSystemStart[] = {'S','y','s','t','e','m','S','t','a','r','t',0}; 00322 static const WCHAR wszSystemWelcome[] = {'S','y','s','t','e','m','W','e','l','c','o','m','e',0}; 00323 00324 wps->fdwSound &= ~(SND_ALIAS_ID ^ SND_ALIAS); 00325 if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMASTERISK) 00326 wps->pszSound = wszSystemAsterisk; 00327 else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMDEFAULT) 00328 wps->pszSound = wszSystemDefault; 00329 else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMEXCLAMATION) 00330 wps->pszSound = wszSystemExclamation; 00331 else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMEXIT) 00332 wps->pszSound = wszSystemExit; 00333 else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMHAND) 00334 wps->pszSound = wszSystemHand; 00335 else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMQUESTION) 00336 wps->pszSound = wszSystemQuestion; 00337 else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMSTART) 00338 wps->pszSound = wszSystemStart; 00339 else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMWELCOME) 00340 wps->pszSound = wszSystemWelcome; 00341 else goto errCleanUp; 00342 } 00343 hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound); 00344 } 00345 else if (wps->fdwSound & SND_FILENAME) 00346 { 00347 hmmio = get_mmioFromFile(wps->pszSound); 00348 } 00349 else 00350 { 00351 if ((hmmio = get_mmioFromProfile(wps->fdwSound | SND_NODEFAULT, wps->pszSound)) == 0) 00352 { 00353 if ((hmmio = get_mmioFromFile(wps->pszSound)) == 0) 00354 { 00355 hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound); 00356 } 00357 } 00358 } 00359 if (hmmio == 0) goto errCleanUp; 00360 00361 if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0)) 00362 goto errCleanUp; 00363 00364 TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08X\n", 00365 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize); 00366 00367 if ((ckMainRIFF.ckid != FOURCC_RIFF) || 00368 (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) 00369 goto errCleanUp; 00370 00371 mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' '); 00372 if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK)) 00373 goto errCleanUp; 00374 00375 TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n", 00376 (LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize); 00377 00378 lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize); 00379 if (mmioRead(hmmio, (HPSTR)lpWaveFormat, mmckInfo.cksize) < sizeof(PCMWAVEFORMAT)) 00380 goto errCleanUp; 00381 00382 TRACE("wFormatTag=%04X !\n", lpWaveFormat->wFormatTag); 00383 TRACE("nChannels=%d\n", lpWaveFormat->nChannels); 00384 TRACE("nSamplesPerSec=%d\n", lpWaveFormat->nSamplesPerSec); 00385 TRACE("nAvgBytesPerSec=%d\n", lpWaveFormat->nAvgBytesPerSec); 00386 TRACE("nBlockAlign=%d\n", lpWaveFormat->nBlockAlign); 00387 TRACE("wBitsPerSample=%u !\n", lpWaveFormat->wBitsPerSample); 00388 00389 /* move to end of 'fmt ' chunk */ 00390 mmioAscend(hmmio, &mmckInfo, 0); 00391 00392 mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a'); 00393 if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK)) 00394 goto errCleanUp; 00395 00396 TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n", 00397 (LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize); 00398 00399 s.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); 00400 00401 if (waveOutOpen(&wps->hWave, WAVE_MAPPER, lpWaveFormat, (DWORD_PTR)PlaySound_Callback, 00402 (DWORD_PTR)&s, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) 00403 goto errCleanUp; 00404 00405 /* make it so that 3 buffers per second are needed */ 00406 bufsize = (((lpWaveFormat->nAvgBytesPerSec / 3) - 1) / lpWaveFormat->nBlockAlign + 1) * 00407 lpWaveFormat->nBlockAlign; 00408 waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize); 00409 waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR); 00410 waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize; 00411 waveHdr[0].dwUser = waveHdr[1].dwUser = 0L; 00412 waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L; 00413 waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L; 00414 waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize; 00415 if (waveOutPrepareHeader(wps->hWave, &waveHdr[0], sizeof(WAVEHDR)) || 00416 waveOutPrepareHeader(wps->hWave, &waveHdr[1], sizeof(WAVEHDR))) { 00417 goto errCleanUp; 00418 } 00419 00420 s.dwEventCount = 1L; /* for first buffer */ 00421 index = 0; 00422 00423 do { 00424 left = mmckInfo.cksize; 00425 00426 mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET); 00427 while (left) 00428 { 00429 if (WaitForSingleObject(psStopEvent, 0) == WAIT_OBJECT_0) 00430 { 00431 wps->bLoop = FALSE; 00432 break; 00433 } 00434 count = mmioRead(hmmio, waveHdr[index].lpData, min(bufsize, left)); 00435 if (count < 1) break; 00436 left -= count; 00437 waveHdr[index].dwBufferLength = count; 00438 waveHdr[index].dwFlags &= ~WHDR_DONE; 00439 if (waveOutWrite(wps->hWave, &waveHdr[index], sizeof(WAVEHDR)) == MMSYSERR_NOERROR) { 00440 index ^= 1; 00441 PlaySound_WaitDone(&s); 00442 } 00443 else FIXME("Couldn't play header\n"); 00444 } 00445 bRet = TRUE; 00446 } while (wps->bLoop); 00447 00448 PlaySound_WaitDone(&s); /* for last buffer */ 00449 waveOutReset(wps->hWave); 00450 00451 waveOutUnprepareHeader(wps->hWave, &waveHdr[0], sizeof(WAVEHDR)); 00452 waveOutUnprepareHeader(wps->hWave, &waveHdr[1], sizeof(WAVEHDR)); 00453 00454 errCleanUp: 00455 TRACE("Done playing=%s => %s!\n", debugstr_w(wps->pszSound), bRet ? "ok" : "ko"); 00456 CloseHandle(s.hEvent); 00457 HeapFree(GetProcessHeap(), 0, waveHdr); 00458 HeapFree(GetProcessHeap(), 0, lpWaveFormat); 00459 if (wps->hWave) while (waveOutClose(wps->hWave) == WAVERR_STILLPLAYING) Sleep(100); 00460 if (hmmio) mmioClose(hmmio, 0); 00461 00462 PlaySound_Free(wps); 00463 00464 return bRet; 00465 } 00466 00467 static BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode) 00468 { 00469 WINE_PLAYSOUND* wps = NULL; 00470 00471 TRACE("pszSound='%p' hmod=%p fdwSound=%08X\n", 00472 pszSound, hmod, fdwSound); 00473 00474 /* FIXME? I see no difference between SND_NOWAIT and SND_NOSTOP ! 00475 * there could be one if several sounds can be played at once... 00476 */ 00477 if ((fdwSound & (SND_NOWAIT | SND_NOSTOP)) && PlaySoundList != NULL) 00478 return FALSE; 00479 00480 /* alloc internal structure, if we need to play something */ 00481 if (pszSound && !(fdwSound & SND_PURGE)) 00482 { 00483 if (!(wps = PlaySound_Alloc(pszSound, hmod, fdwSound, bUnicode))) 00484 return FALSE; 00485 } 00486 00487 EnterCriticalSection(&WINMM_cs); 00488 /* since several threads can enter PlaySound in parallel, we're not 00489 * sure, at this point, that another thread didn't start a new playsound 00490 */ 00491 while (PlaySoundList != NULL) 00492 { 00493 ResetEvent(psLastEvent); 00494 /* FIXME: doc says we have to stop all instances of pszSound if it's non 00495 * NULL... as of today, we stop all playing instances */ 00496 SetEvent(psStopEvent); 00497 00498 waveOutReset(PlaySoundList->hWave); 00499 LeaveCriticalSection(&WINMM_cs); 00500 WaitForSingleObject(psLastEvent, INFINITE); 00501 EnterCriticalSection(&WINMM_cs); 00502 00503 ResetEvent(psStopEvent); 00504 } 00505 00506 if (wps) wps->lpNext = PlaySoundList; 00507 PlaySoundList = wps; 00508 LeaveCriticalSection(&WINMM_cs); 00509 00510 if (!pszSound || (fdwSound & SND_PURGE)) return TRUE; 00511 00512 if (fdwSound & SND_ASYNC) 00513 { 00514 DWORD id; 00515 HANDLE handle; 00516 wps->bLoop = (fdwSound & SND_LOOP) ? TRUE : FALSE; 00517 if ((handle = CreateThread(NULL, 0, proc_PlaySound, wps, 0, &id)) != 0) { 00518 wps->hThread = handle; 00519 SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL); 00520 return TRUE; 00521 } 00522 } 00523 else return proc_PlaySound(wps); 00524 00525 /* error cases */ 00526 PlaySound_Free(wps); 00527 return FALSE; 00528 } 00529 00530 /************************************************************************** 00531 * PlaySoundA [WINMM.@] 00532 */ 00533 BOOL WINAPI PlaySoundA(LPCSTR pszSoundA, HMODULE hmod, DWORD fdwSound) 00534 { 00535 return MULTIMEDIA_PlaySound(pszSoundA, hmod, fdwSound, FALSE); 00536 } 00537 00538 /************************************************************************** 00539 * PlaySoundW [WINMM.@] 00540 */ 00541 BOOL WINAPI PlaySoundW(LPCWSTR pszSoundW, HMODULE hmod, DWORD fdwSound) 00542 { 00543 return MULTIMEDIA_PlaySound(pszSoundW, hmod, fdwSound, TRUE); 00544 } 00545 00546 /************************************************************************** 00547 * sndPlaySoundA [WINMM.@] 00548 */ 00549 BOOL WINAPI sndPlaySoundA(LPCSTR pszSoundA, UINT uFlags) 00550 { 00551 uFlags &= SND_ASYNC|SND_LOOP|SND_MEMORY|SND_NODEFAULT|SND_NOSTOP|SND_SYNC; 00552 return MULTIMEDIA_PlaySound(pszSoundA, 0, uFlags, FALSE); 00553 } 00554 00555 /************************************************************************** 00556 * sndPlaySoundW [WINMM.@] 00557 */ 00558 BOOL WINAPI sndPlaySoundW(LPCWSTR pszSound, UINT uFlags) 00559 { 00560 uFlags &= SND_ASYNC|SND_LOOP|SND_MEMORY|SND_NODEFAULT|SND_NOSTOP|SND_SYNC; 00561 return MULTIMEDIA_PlaySound(pszSound, 0, uFlags, TRUE); 00562 } 00563 00564 /************************************************************************** 00565 * mmsystemGetVersion [WINMM.@] 00566 */ 00567 UINT WINAPI mmsystemGetVersion(void) 00568 { 00569 TRACE("3.10 (Win95?)\n"); 00570 return 0x030a; 00571 } Generated on Sun May 27 2012 04:26:58 for ReactOS by
1.7.6.1
|