ReactOS  0.4.15-dev-1384-g878186b
playsound.c File Reference
#include "winemm.h"
#include <winternl.h>
Include dependency graph for playsound.c:

Go to the source code of this file.

Classes

struct  tagWINE_PLAYSOUND
 
struct  playsound_data
 

Typedefs

typedef struct tagWINE_PLAYSOUND WINE_PLAYSOUND
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (winmm)
 
static HMMIO get_mmioFromFile (LPCWSTR lpszName)
 
static HMMIO get_mmioFromProfile (UINT uFlags, LPCWSTR lpszName)
 
static void CALLBACK PlaySound_Callback (HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 
static void PlaySound_WaitDone (struct playsound_data *s)
 
static BOOL PlaySound_IsString (DWORD fdwSound, const void *psz)
 
static void PlaySound_Free (WINE_PLAYSOUND *wps)
 
static WINE_PLAYSOUNDPlaySound_Alloc (const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
 
static DWORD WINAPI proc_PlaySound (LPVOID arg)
 
static BOOL MULTIMEDIA_PlaySound (const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
 
BOOL WINAPI PlaySoundA (LPCSTR pszSoundA, HMODULE hmod, DWORD fdwSound)
 
BOOL WINAPI PlaySoundW (LPCWSTR pszSoundW, HMODULE hmod, DWORD fdwSound)
 
BOOL WINAPI sndPlaySoundA (LPCSTR pszSoundA, UINT uFlags)
 
BOOL WINAPI sndPlaySoundW (LPCWSTR pszSound, UINT uFlags)
 
UINT WINAPI mmsystemGetVersion (void)
 

Variables

static WINE_PLAYSOUNDPlaySoundList
 

Typedef Documentation

◆ WINE_PLAYSOUND

Function Documentation

◆ get_mmioFromFile()

static HMMIO get_mmioFromFile ( LPCWSTR  lpszName)
static

Definition at line 44 of file playsound.c.

45 {
46  HMMIO ret;
47  WCHAR buf[256];
48  LPWSTR dummy;
49 
50  ret = mmioOpenW((LPWSTR)lpszName, NULL,
52  if (ret != 0) return ret;
53  if (SearchPathW(NULL, lpszName, NULL, sizeof(buf)/sizeof(buf[0]), buf, &dummy))
54  {
55  return mmioOpenW(buf, NULL,
57  }
58  return 0;
59 }
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:669
#define MMIO_DENYWRITE
Definition: mmsystem.h:540
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define MMIO_READ
Definition: mmsystem.h:535
__wchar_t WCHAR
Definition: xmlstorage.h:180
int ret
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1297
unsigned char dummy
Definition: maze.c:118
#define NULL
Definition: types.h:112
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by proc_PlaySound().

◆ get_mmioFromProfile()

static HMMIO get_mmioFromProfile ( UINT  uFlags,
LPCWSTR  lpszName 
)
static

Definition at line 61 of file playsound.c.

62 {
63  WCHAR str[128];
64  LPWSTR ptr;
65  HMMIO hmmio;
66  HKEY hRegSnd, hRegApp, hScheme, hSnd;
67  DWORD err, type, count;
68 
69  static const WCHAR wszSounds[] = {'S','o','u','n','d','s',0};
70  static const WCHAR wszDefault[] = {'D','e','f','a','u','l','t',0};
71  static const WCHAR wszKey[] = {'A','p','p','E','v','e','n','t','s','\\',
72  'S','c','h','e','m','e','s','\\',
73  'A','p','p','s',0};
74  static const WCHAR wszDotDefault[] = {'.','D','e','f','a','u','l','t',0};
75  static const WCHAR wszDotCurrent[] = {'.','C','u','r','r','e','n','t',0};
76  static const WCHAR wszNull[] = {0};
77 
78  TRACE("searching in SystemSound list for %s\n", debugstr_w(lpszName));
79  GetProfileStringW(wszSounds, lpszName, wszNull, str, sizeof(str)/sizeof(str[0]));
80  if (lstrlenW(str) == 0)
81  {
82  if (uFlags & SND_NODEFAULT) goto next;
83  GetProfileStringW(wszSounds, wszDefault, wszNull, str, sizeof(str)/sizeof(str[0]));
84  if (lstrlenW(str) == 0) goto next;
85  }
86  for (ptr = str; *ptr && *ptr != ','; ptr++);
87  if (*ptr) *ptr = 0;
89  if (hmmio != 0) return hmmio;
90  next:
91  /* we look up the registry under
92  * HKCU\AppEvents\Schemes\Apps\.Default
93  * HKCU\AppEvents\Schemes\Apps<AppName>
94  */
95  if (RegOpenKeyW(HKEY_CURRENT_USER, wszKey, &hRegSnd) != 0) goto none;
96  if (uFlags & SND_APPLICATION)
97  {
98  DWORD len;
99 
100  err = 1; /* error */
101  len = GetModuleFileNameW(0, str, sizeof(str)/sizeof(str[0]));
102  if (len > 0 && len < sizeof(str)/sizeof(str[0]))
103  {
104  for (ptr = str + lstrlenW(str) - 1; ptr >= str; ptr--)
105  {
106  if (*ptr == '.') *ptr = 0;
107  if (*ptr == '\\')
108  {
109  err = RegOpenKeyW(hRegSnd, ptr+1, &hRegApp);
110  break;
111  }
112  }
113  }
114  }
115  else
116  {
117  err = RegOpenKeyW(hRegSnd, wszDotDefault, &hRegApp);
118  }
119  RegCloseKey(hRegSnd);
120  if (err != 0) goto none;
121  err = RegOpenKeyW(hRegApp, lpszName, &hScheme);
122  RegCloseKey(hRegApp);
123  if (err != 0) goto none;
124  /* what's the difference between .Current and .Default ? */
125  err = RegOpenKeyW(hScheme, wszDotDefault, &hSnd);
126  if (err != 0)
127  {
128  err = RegOpenKeyW(hScheme, wszDotCurrent, &hSnd);
129  RegCloseKey(hScheme);
130  if (err != 0)
131  goto none;
132  }
133  count = sizeof(str);
134  err = RegQueryValueExW(hSnd, NULL, 0, &type, (LPBYTE)str, &count);
135  RegCloseKey(hSnd);
136  if (err != 0 || !*str) goto none;
138  if (hmmio) return hmmio;
139  none:
140  WARN("can't find SystemSound=%s !\n", debugstr_w(lpszName));
141  return 0;
142 }
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
#define SND_NODEFAULT
Definition: mmsystem.h:155
#define HKEY_CURRENT_USER
Definition: winreg.h:11
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define WARN(fmt,...)
Definition: debug.h:112
static const WCHAR wszNull[]
Definition: mci.c:53
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:669
#define MMIO_DENYWRITE
Definition: mmsystem.h:540
UINT uFlags
Definition: api.c:59
#define SND_APPLICATION
Definition: mmsystem.h:165
#define lstrlenW
Definition: compat.h:609
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3296
#define debugstr_w
Definition: kernel32.h:32
static PVOID ptr
Definition: dispmode.c:27
const WCHAR * str
#define MMIO_READ
Definition: mmsystem.h:535
#define TRACE(s)
Definition: solgame.cpp:4
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
INT WINAPI GetProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR def_val, LPWSTR buffer, UINT len)
Definition: profile.c:1267
GLenum GLsizei len
Definition: glext.h:6722
#define err(...)
static unsigned __int64 next
Definition: rand_nt.c:6
#define NULL
Definition: types.h:112
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by proc_PlaySound().

◆ mmsystemGetVersion()

UINT WINAPI mmsystemGetVersion ( void  )

Definition at line 557 of file playsound.c.

558 {
559  TRACE("3.10 (Win95?)\n");
560  return 0x030a;
561 }
#define TRACE(s)
Definition: solgame.cpp:4

◆ MULTIMEDIA_PlaySound()

static BOOL MULTIMEDIA_PlaySound ( const void pszSound,
HMODULE  hmod,
DWORD  fdwSound,
BOOL  bUnicode 
)
static

Definition at line 457 of file playsound.c.

458 {
459  WINE_PLAYSOUND* wps = NULL;
460 
461  TRACE("pszSound='%p' hmod=%p fdwSound=%08X\n",
462  pszSound, hmod, fdwSound);
463 
464  /* FIXME? I see no difference between SND_NOWAIT and SND_NOSTOP !
465  * there could be one if several sounds can be played at once...
466  */
467  if ((fdwSound & (SND_NOWAIT | SND_NOSTOP)) && PlaySoundList != NULL)
468  return FALSE;
469 
470  /* alloc internal structure, if we need to play something */
471  if (pszSound && !(fdwSound & SND_PURGE))
472  {
473  if (!(wps = PlaySound_Alloc(pszSound, hmod, fdwSound, bUnicode)))
474  return FALSE;
475  }
476 
478  /* since several threads can enter PlaySound in parallel, we're not
479  * sure, at this point, that another thread didn't start a new playsound
480  */
481  while (PlaySoundList != NULL)
482  {
484  /* FIXME: doc says we have to stop all instances of pszSound if it's non
485  * NULL... as of today, we stop all playing instances */
487 
492 
494  }
495 
496  if (wps) wps->lpNext = PlaySoundList;
497  PlaySoundList = wps;
499 
500  if (!pszSound || (fdwSound & SND_PURGE)) return TRUE;
501 
502  if (fdwSound & SND_ASYNC)
503  {
504  DWORD id;
505  HANDLE handle;
506  wps->bLoop = (fdwSound & SND_LOOP) ? TRUE : FALSE;
507  if ((handle = CreateThread(NULL, 0, proc_PlaySound, wps, 0, &id)) != 0) {
508  wps->hThread = handle;
510  return TRUE;
511  }
512  }
513  else return proc_PlaySound(wps);
514 
515  /* error cases */
516  PlaySound_Free(wps);
517  return FALSE;
518 }
#define TRUE
Definition: types.h:120
HWAVEOUT hWave
Definition: playsound.c:38
HANDLE psStopEvent
Definition: winmm.c:52
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static void PlaySound_Free(WINE_PLAYSOUND *wps)
Definition: playsound.c:198
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define FALSE
Definition: types.h:117
#define SND_NOSTOP
Definition: mmsystem.h:158
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
HANDLE psLastEvent
Definition: winmm.c:51
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:699
#define SND_PURGE
Definition: mmsystem.h:164
#define TRACE(s)
Definition: solgame.cpp:4
CRITICAL_SECTION WINMM_cs
Definition: winmm.c:54
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SND_ASYNC
Definition: mmsystem.h:154
static WINE_PLAYSOUND * PlaySound_Alloc(const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
Definition: playsound.c:212
#define SND_LOOP
Definition: mmsystem.h:157
#define SND_NOWAIT
Definition: mmsystem.h:159
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:278
static DWORD WINAPI proc_PlaySound(LPVOID arg)
Definition: playsound.c:255
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141
#define NULL
Definition: types.h:112
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
GLenum GLuint id
Definition: glext.h:5579
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define INFINITE
Definition: serial.h:102
unsigned bLoop
Definition: playsound.c:32
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2388
static WINE_PLAYSOUND * PlaySoundList
Definition: playsound.c:42
struct tagWINE_PLAYSOUND * lpNext
Definition: playsound.c:39

Referenced by PlaySoundA(), PlaySoundW(), sndPlaySoundA(), and sndPlaySoundW().

◆ PlaySound_Alloc()

static WINE_PLAYSOUND* PlaySound_Alloc ( const void pszSound,
HMODULE  hmod,
DWORD  fdwSound,
BOOL  bUnicode 
)
static

Definition at line 212 of file playsound.c.

214 {
215  WINE_PLAYSOUND* wps;
216 
217  wps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wps));
218  if (!wps) return NULL;
219 
220  wps->hMod = hmod;
221  wps->fdwSound = fdwSound;
222  if (PlaySound_IsString(fdwSound, pszSound))
223  {
224  if (bUnicode)
225  {
226  if (fdwSound & SND_ASYNC)
227  {
228  LPWSTR sound = HeapAlloc(GetProcessHeap(), 0,
229  (lstrlenW(pszSound)+1) * sizeof(WCHAR));
230  if (!sound) goto oom_error;
231  wps->pszSound = lstrcpyW(sound, pszSound);
232  wps->bAlloc = TRUE;
233  }
234  else
235  wps->pszSound = pszSound;
236  }
237  else
238  {
239  UNICODE_STRING usBuffer;
240  RtlCreateUnicodeStringFromAsciiz(&usBuffer, pszSound);
241  wps->pszSound = usBuffer.Buffer;
242  if (!wps->pszSound) goto oom_error;
243  wps->bAlloc = TRUE;
244  }
245  }
246  else
247  wps->pszSound = pszSound;
248 
249  return wps;
250  oom_error:
251  PlaySound_Free(wps);
252  return NULL;
253 }
LPCWSTR pszSound
Definition: playsound.c:34
#define TRUE
Definition: types.h:120
#define lstrlenW
Definition: compat.h:609
static void PlaySound_Free(WINE_PLAYSOUND *wps)
Definition: playsound.c:198
unsigned bAlloc
Definition: playsound.c:32
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SND_ASYNC
Definition: mmsystem.h:154
static BOOL PlaySound_IsString(DWORD fdwSound, const void *psz)
Definition: playsound.c:181
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141
#define lstrcpyW
Definition: compat.h:608
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by MULTIMEDIA_PlaySound().

◆ PlaySound_Callback()

static void CALLBACK PlaySound_Callback ( HWAVEOUT  hwo,
UINT  uMsg,
DWORD_PTR  dwInstance,
DWORD_PTR  dwParam1,
DWORD_PTR  dwParam2 
)
static

Definition at line 150 of file playsound.c.

153 {
154  struct playsound_data* s = (struct playsound_data*)dwInstance;
155 
156  switch (uMsg) {
157  case WOM_OPEN:
158  case WOM_CLOSE:
159  break;
160  case WOM_DONE:
161  InterlockedIncrement(&s->dwEventCount);
162  TRACE("Returning waveHdr=%lx\n", dwParam1);
163  SetEvent(s->hEvent);
164  break;
165  default:
166  ERR("Unknown uMsg=%d\n", uMsg);
167  }
168 }
#define WOM_DONE
Definition: mmsystem.h:183
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
#define WOM_OPEN
Definition: mmsystem.h:181
#define WOM_CLOSE
Definition: mmsystem.h:182
#define TRACE(s)
Definition: solgame.cpp:4
GLdouble s
Definition: gl.h:2039
#define ERR(fmt,...)
Definition: debug.h:110
#define InterlockedIncrement
Definition: armddk.h:53

Referenced by proc_PlaySound().

◆ PlaySound_Free()

static void PlaySound_Free ( WINE_PLAYSOUND wps)
static

Definition at line 198 of file playsound.c.

199 {
200  WINE_PLAYSOUND** p;
201 
203  for (p = &PlaySoundList; *p && *p != wps; p = &((*p)->lpNext));
204  if (*p) *p = (*p)->lpNext;
207  if (wps->bAlloc) HeapFree(GetProcessHeap(), 0, (void*)wps->pszSound);
208  if (wps->hThread) CloseHandle(wps->hThread);
209  HeapFree(GetProcessHeap(), 0, wps);
210 }
#define CloseHandle
Definition: compat.h:598
LPCWSTR pszSound
Definition: playsound.c:34
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
unsigned bAlloc
Definition: playsound.c:32
HANDLE psLastEvent
Definition: winmm.c:51
#define GetProcessHeap()
Definition: compat.h:595
CRITICAL_SECTION WINMM_cs
Definition: winmm.c:54
#define NULL
Definition: types.h:112
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
GLfloat GLfloat p
Definition: glext.h:8902
#define HeapFree(x, y, z)
Definition: compat.h:594
static WINE_PLAYSOUND * PlaySoundList
Definition: playsound.c:42

Referenced by MULTIMEDIA_PlaySound(), PlaySound_Alloc(), and proc_PlaySound().

◆ PlaySound_IsString()

static BOOL PlaySound_IsString ( DWORD  fdwSound,
const void psz 
)
static

Definition at line 181 of file playsound.c.

182 {
183  /* SND_RESOURCE is 0x40004 while
184  * SND_MEMORY is 0x00004
185  */
186  switch (fdwSound & (SND_RESOURCE|SND_ALIAS_ID|SND_FILENAME))
187  {
188  case SND_RESOURCE: return HIWORD(psz) != 0; /* by name or by ID ? */
189  case SND_ALIAS_ID:
190  case SND_MEMORY: return FALSE;
191  case SND_ALIAS:
192  case SND_FILENAME:
193  case 0: return TRUE;
194  default: FIXME("WTF\n"); return FALSE;
195  }
196 }
#define SND_ALIAS_ID
Definition: mmsystem.h:161
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define FIXME(fmt,...)
Definition: debug.h:111
#define SND_ALIAS
Definition: mmsystem.h:160
#define SND_MEMORY
Definition: mmsystem.h:156
#define SND_RESOURCE
Definition: mmsystem.h:163
#define SND_FILENAME
Definition: mmsystem.h:162
#define HIWORD(l)
Definition: typedefs.h:247

Referenced by PlaySound_Alloc().

◆ PlaySound_WaitDone()

static void PlaySound_WaitDone ( struct playsound_data s)
static

Definition at line 170 of file playsound.c.

171 {
172  for (;;) {
173  ResetEvent(s->hEvent);
174  if (InterlockedDecrement(&s->dwEventCount) >= 0) break;
175  InterlockedIncrement(&s->dwEventCount);
176 
177  WaitForSingleObject(s->hEvent, INFINITE);
178  }
179 }
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define InterlockedDecrement
Definition: armddk.h:52
GLdouble s
Definition: gl.h:2039
#define InterlockedIncrement
Definition: armddk.h:53
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
#define INFINITE
Definition: serial.h:102

Referenced by proc_PlaySound().

◆ PlaySoundA()

BOOL WINAPI PlaySoundA ( LPCSTR  pszSoundA,
HMODULE  hmod,
DWORD  fdwSound 
)

Definition at line 523 of file playsound.c.

524 {
525  return MULTIMEDIA_PlaySound(pszSoundA, hmod, fdwSound, FALSE);
526 }
#define FALSE
Definition: types.h:117
static BOOL MULTIMEDIA_PlaySound(const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
Definition: playsound.c:457
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141

Referenced by test_PlaySound().

◆ PlaySoundW()

BOOL WINAPI PlaySoundW ( LPCWSTR  pszSoundW,
HMODULE  hmod,
DWORD  fdwSound 
)

Definition at line 531 of file playsound.c.

532 {
533  return MULTIMEDIA_PlaySound(pszSoundW, hmod, fdwSound, TRUE);
534 }
#define TRUE
Definition: types.h:120
static BOOL MULTIMEDIA_PlaySound(const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
Definition: playsound.c:457
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141

Referenced by OSK_DlgCommand(), CUserNotification::PlaySound(), PlaySoundWrapW(), and SHEmptyRecycleBinW().

◆ proc_PlaySound()

static DWORD WINAPI proc_PlaySound ( LPVOID  arg)
static

Definition at line 255 of file playsound.c.

256 {
257  WINE_PLAYSOUND* wps = arg;
258  BOOL bRet = FALSE;
259  HMMIO hmmio = 0;
260  MMCKINFO ckMainRIFF;
261  MMCKINFO mmckInfo;
262  LPWAVEFORMATEX lpWaveFormat = NULL;
263  LPWAVEHDR waveHdr = NULL;
265  struct playsound_data s;
266  void* data;
267 
268  s.hEvent = 0;
269 
270  TRACE("SoundName=%s !\n", debugstr_w(wps->pszSound));
271 
272  /* if resource, grab it */
273  if ((wps->fdwSound & SND_RESOURCE) == SND_RESOURCE) {
274  static const WCHAR wszWave[] = {'W','A','V','E',0};
275  HRSRC hRes;
276  HGLOBAL hGlob;
277 
278  if ((hRes = FindResourceW(wps->hMod, wps->pszSound, wszWave)) == 0 ||
279  (hGlob = LoadResource(wps->hMod, hRes)) == 0)
280  goto errCleanUp;
281  if ((data = LockResource(hGlob)) == NULL) {
282  FreeResource(hGlob);
283  goto errCleanUp;
284  }
285  FreeResource(hGlob);
286  } else
287  data = (void*)wps->pszSound;
288 
289  /* construct an MMIO stream (either in memory, or from a file */
290  if (wps->fdwSound & SND_MEMORY)
291  { /* NOTE: SND_RESOURCE has the SND_MEMORY bit set */
292  MMIOINFO mminfo;
293 
294  memset(&mminfo, 0, sizeof(mminfo));
295  mminfo.fccIOProc = FOURCC_MEM;
296  mminfo.pchBuffer = data;
297  mminfo.cchBuffer = -1; /* FIXME: when a resource, could grab real size */
298  TRACE("Memory sound %p\n", data);
299  hmmio = mmioOpenW(NULL, &mminfo, MMIO_READ);
300  }
301  else if (wps->fdwSound & SND_ALIAS)
302  {
303  if ((wps->fdwSound & SND_ALIAS_ID) == SND_ALIAS_ID)
304  {
305  static const WCHAR wszSystemAsterisk[] = {'S','y','s','t','e','m','A','s','t','e','r','i','s','k',0};
306  static const WCHAR wszSystemDefault[] = {'S','y','s','t','e','m','D','e','f','a','u','l','t',0};
307  static const WCHAR wszSystemExclamation[] = {'S','y','s','t','e','m','E','x','c','l','a','m','a','t','i','o','n',0};
308  static const WCHAR wszSystemExit[] = {'S','y','s','t','e','m','E','x','i','t',0};
309  static const WCHAR wszSystemHand[] = {'S','y','s','t','e','m','H','a','n','d',0};
310  static const WCHAR wszSystemQuestion[] = {'S','y','s','t','e','m','Q','u','e','s','t','i','o','n',0};
311  static const WCHAR wszSystemStart[] = {'S','y','s','t','e','m','S','t','a','r','t',0};
312  static const WCHAR wszSystemWelcome[] = {'S','y','s','t','e','m','W','e','l','c','o','m','e',0};
313 
314  wps->fdwSound &= ~(SND_ALIAS_ID ^ SND_ALIAS);
316  wps->pszSound = wszSystemAsterisk;
318  wps->pszSound = wszSystemDefault;
320  wps->pszSound = wszSystemExclamation;
321  else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMEXIT)
322  wps->pszSound = wszSystemExit;
323  else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMHAND)
324  wps->pszSound = wszSystemHand;
326  wps->pszSound = wszSystemQuestion;
327  else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMSTART)
328  wps->pszSound = wszSystemStart;
330  wps->pszSound = wszSystemWelcome;
331  else goto errCleanUp;
332  }
333  hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
334  }
335  else if (wps->fdwSound & SND_FILENAME)
336  {
337  hmmio = get_mmioFromFile(wps->pszSound);
338  }
339  else
340  {
341  if ((hmmio = get_mmioFromProfile(wps->fdwSound | SND_NODEFAULT, wps->pszSound)) == 0)
342  {
343  if ((hmmio = get_mmioFromFile(wps->pszSound)) == 0)
344  {
345  hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
346  }
347  }
348  }
349  if (hmmio == 0) goto errCleanUp;
350 
351  if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0))
352  goto errCleanUp;
353 
354  TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08X\n",
355  (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
356 
357  if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
358  (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E')))
359  goto errCleanUp;
360 
361  mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
362  if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
363  goto errCleanUp;
364 
365  TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
366  (LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);
367 
368  lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
369  if (mmioRead(hmmio, (HPSTR)lpWaveFormat, mmckInfo.cksize) < sizeof(PCMWAVEFORMAT))
370  goto errCleanUp;
371 
372  TRACE("wFormatTag=%04X !\n", lpWaveFormat->wFormatTag);
373  TRACE("nChannels=%d\n", lpWaveFormat->nChannels);
374  TRACE("nSamplesPerSec=%d\n", lpWaveFormat->nSamplesPerSec);
375  TRACE("nAvgBytesPerSec=%d\n", lpWaveFormat->nAvgBytesPerSec);
376  TRACE("nBlockAlign=%d\n", lpWaveFormat->nBlockAlign);
377  TRACE("wBitsPerSample=%u !\n", lpWaveFormat->wBitsPerSample);
378 
379  /* move to end of 'fmt ' chunk */
380  mmioAscend(hmmio, &mmckInfo, 0);
381 
382  mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
383  if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
384  goto errCleanUp;
385 
386  TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
387  (LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);
388 
389  s.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
390 
391  if (waveOutOpen(&wps->hWave, WAVE_MAPPER, lpWaveFormat, (DWORD_PTR)PlaySound_Callback,
393  goto errCleanUp;
394 
395  /* make it so that 3 buffers per second are needed */
396  bufsize = (((lpWaveFormat->nAvgBytesPerSec / 3) - 1) / lpWaveFormat->nBlockAlign + 1) *
397  lpWaveFormat->nBlockAlign;
398  waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize);
399  waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
400  waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
401  waveHdr[0].dwUser = waveHdr[1].dwUser = 0L;
402  waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
403  waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
404  waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
405  if (waveOutPrepareHeader(wps->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
406  waveOutPrepareHeader(wps->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
407  goto errCleanUp;
408  }
409 
410  s.dwEventCount = 1L; /* for first buffer */
411  index = 0;
412 
413  do {
414  left = mmckInfo.cksize;
415 
416  mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET);
417  while (left)
418  {
420  {
421  wps->bLoop = FALSE;
422  break;
423  }
424  count = mmioRead(hmmio, waveHdr[index].lpData, min(bufsize, left));
425  if (count < 1) break;
426  left -= count;
427  waveHdr[index].dwBufferLength = count;
428  waveHdr[index].dwFlags &= ~WHDR_DONE;
429  if (waveOutWrite(wps->hWave, &waveHdr[index], sizeof(WAVEHDR)) == MMSYSERR_NOERROR) {
430  index ^= 1;
432  }
433  else FIXME("Couldn't play header\n");
434  }
435  bRet = TRUE;
436  } while (wps->bLoop);
437 
438  PlaySound_WaitDone(&s); /* for last buffer */
439  waveOutReset(wps->hWave);
440 
441  waveOutUnprepareHeader(wps->hWave, &waveHdr[0], sizeof(WAVEHDR));
442  waveOutUnprepareHeader(wps->hWave, &waveHdr[1], sizeof(WAVEHDR));
443 
444 errCleanUp:
445  TRACE("Done playing=%s => %s!\n", debugstr_w(wps->pszSound), bRet ? "ok" : "ko");
446  CloseHandle(s.hEvent);
447  HeapFree(GetProcessHeap(), 0, waveHdr);
448  HeapFree(GetProcessHeap(), 0, lpWaveFormat);
449  if (wps->hWave) while (waveOutClose(wps->hWave) == WAVERR_STILLPLAYING) Sleep(100);
450  if (hmmio) mmioClose(hmmio, 0);
451 
452  PlaySound_Free(wps);
453 
454  return bRet;
455 }
static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: playsound.c:150
#define SND_ALIAS_ID
Definition: mmsystem.h:161
#define CloseHandle
Definition: compat.h:598
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
static HMMIO get_mmioFromFile(LPCWSTR lpszName)
Definition: playsound.c:44
FOURCC fccIOProc
Definition: mmsystem.h:1487
LPCWSTR pszSound
Definition: playsound.c:34
LONG cchBuffer
Definition: mmsystem.h:1491
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define TRUE
Definition: types.h:120
HWAVEOUT hWave
Definition: playsound.c:38
#define SND_NODEFAULT
Definition: mmsystem.h:155
GLuint GLuint GLsizei count
Definition: gl.h:1545
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1204
DWORD dwDataOffset
Definition: mmsystem.h:1510
HANDLE psStopEvent
Definition: winmm.c:52
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:701
void * arg
Definition: msvc.h:10
#define SND_ALIAS_SYSTEMASTERISK
Definition: mmsystem.h:168
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:669
LPSTR lpData
Definition: mmsystem.h:1014
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
char * LPSTR
Definition: xmlstorage.h:182
int32_t INT
Definition: typedefs.h:58
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:835
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2280
static void PlaySound_Free(WINE_PLAYSOUND *wps)
Definition: playsound.c:198
DWORD dwLoops
Definition: mmsystem.h:1019
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define WAVERR_STILLPLAYING
Definition: mmsystem.h:177
VOID CALLBACK_FUNCTION(__in PVOID CallbackContext, __in_opt PVOID Argument1, __in_opt PVOID Argument2)
Definition: mxgeneralum.h:58
DWORD dwFlags
Definition: mmsystem.h:1018
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:111
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
#define SND_ALIAS
Definition: mmsystem.h:160
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
GLuint index
Definition: glext.h:6031
FOURCC fccType
Definition: mmsystem.h:1509
#define SND_ALIAS_SYSTEMDEFAULT
Definition: mmsystem.h:175
#define MMIO_READ
Definition: mmsystem.h:535
#define SEEK_SET
Definition: jmemansi.c:26
struct wavehdr_tag WAVEHDR
#define SND_MEMORY
Definition: mmsystem.h:156
#define TRACE(s)
Definition: solgame.cpp:4
#define SND_ALIAS_SYSTEMHAND
Definition: mmsystem.h:170
#define WAIT_OBJECT_0
Definition: winbase.h:387
HPSTR pchBuffer
Definition: mmsystem.h:1492
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define WAVE_MAPPER
Definition: mmsystem.h:187
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
GLint left
Definition: glext.h:7726
#define SND_ALIAS_SYSTEMEXIT
Definition: mmsystem.h:171
DWORD cksize
Definition: mmsystem.h:1508
static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)
Definition: playsound.c:61
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define SND_ALIAS_SYSTEMWELCOME
Definition: mmsystem.h:173
#define SND_RESOURCE
Definition: mmsystem.h:163
#define SND_ALIAS_SYSTEMQUESTION
Definition: mmsystem.h:169
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2344
static void PlaySound_WaitDone(struct playsound_data *s)
Definition: playsound.c:170
#define SND_ALIAS_SYSTEMSTART
Definition: mmsystem.h:172
char * HPSTR
Definition: mmsystem.h:1477
#define index(s, c)
Definition: various.h:29
static const WCHAR L[]
Definition: oid.c:1250
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
DWORD dwBufferLength
Definition: mmsystem.h:1015
GLdouble s
Definition: gl.h:2039
uint32_t DWORD_PTR
Definition: typedefs.h:65
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2310
#define SND_FILENAME
Definition: mmsystem.h:162
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2249
FOURCC ckid
Definition: mmsystem.h:1507
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
Definition: mmio.c:1106
#define min(a, b)
Definition: monoChain.cc:55
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2260
#define NULL
Definition: types.h:112
#define FOURCC_MEM
Definition: mmsystem.h:567
DWORD_PTR dwUser
Definition: mmsystem.h:1017
#define WHDR_DONE
Definition: mmsystem.h:193
unsigned bLoop
Definition: playsound.c:32
#define memset(x, y, z)
Definition: compat.h:39
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2388
#define HeapFree(x, y, z)
Definition: compat.h:594
#define SND_ALIAS_SYSTEMEXCLAMATION
Definition: mmsystem.h:174
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:732

Referenced by MULTIMEDIA_PlaySound().

◆ sndPlaySoundA()

BOOL WINAPI sndPlaySoundA ( LPCSTR  pszSoundA,
UINT  uFlags 
)

Definition at line 539 of file playsound.c.

540 {
542  return MULTIMEDIA_PlaySound(pszSoundA, 0, uFlags, FALSE);
543 }
#define SND_SYNC
Definition: mmsystem.h:153
#define SND_ALIAS_ID
Definition: mmsystem.h:161
#define SND_NODEFAULT
Definition: mmsystem.h:155
UINT uFlags
Definition: api.c:59
#define FALSE
Definition: types.h:117
#define SND_NOSTOP
Definition: mmsystem.h:158
static BOOL MULTIMEDIA_PlaySound(const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
Definition: playsound.c:457
#define SND_MEMORY
Definition: mmsystem.h:156
#define SND_ASYNC
Definition: mmsystem.h:154
#define SND_LOOP
Definition: mmsystem.h:157
#define SND_FILENAME
Definition: mmsystem.h:162

Referenced by test_sndPlaySound().

◆ sndPlaySoundW()

BOOL WINAPI sndPlaySoundW ( LPCWSTR  pszSound,
UINT  uFlags 
)

Definition at line 548 of file playsound.c.

549 {
551  return MULTIMEDIA_PlaySound(pszSound, 0, uFlags, TRUE);
552 }
#define SND_SYNC
Definition: mmsystem.h:153
#define SND_ALIAS_ID
Definition: mmsystem.h:161
#define TRUE
Definition: types.h:120
#define SND_NODEFAULT
Definition: mmsystem.h:155
UINT uFlags
Definition: api.c:59
#define SND_NOSTOP
Definition: mmsystem.h:158
static BOOL MULTIMEDIA_PlaySound(const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
Definition: playsound.c:457
#define SND_MEMORY
Definition: mmsystem.h:156
#define SND_ASYNC
Definition: mmsystem.h:154
#define SND_LOOP
Definition: mmsystem.h:157
#define SND_FILENAME
Definition: mmsystem.h:162

Referenced by MCI_Sound(), and test_sndPlaySound().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( winmm  )

Variable Documentation

◆ PlaySoundList

WINE_PLAYSOUND* PlaySoundList
static

Definition at line 42 of file playsound.c.

Referenced by MULTIMEDIA_PlaySound(), and PlaySound_Free().