ReactOS 0.4.16-dev-889-g9563c07
playsound.c File Reference
#include "winemm.h"
#include <winternl.h>
#include <userenv.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 DWORD PlaySound_ExpandEnvironmentStrings (LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize)
 
static HMMIO get_mmioFromFile (LPCWSTR lpszName)
 
static HMMIO get_mmioFromProfile (UINT uFlags, LPCWSTR lpszName)
 
static HMMIO PlaySound_GetMMIO (LPCWSTR pszSound, HMODULE hMod, DWORD fdwSound)
 
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_AllocAndGetMMIO (const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
 
static BOOL proc_PlaySound (WINE_PLAYSOUND *wps)
 
static DWORD WINAPI PlaySoundAsyncThreadProc (LPVOID lpParameter)
 
static BOOL proc_PlaySoundAsync (WINE_PLAYSOUND *wps)
 
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_PLAYSOUNDPlaySoundCurrent
 
static BOOL bPlaySoundStop
 

Typedef Documentation

◆ WINE_PLAYSOUND

Function Documentation

◆ get_mmioFromFile()

static HMMIO get_mmioFromFile ( LPCWSTR  lpszName)
static

Definition at line 98 of file playsound.c.

99{
100 HMMIO ret;
101 WCHAR buf[256];
103
104 ret = mmioOpenW((LPWSTR)lpszName, NULL,
106 if (ret != 0) return ret;
107 if (SearchPathW(NULL, lpszName, L".wav", ARRAY_SIZE(buf), buf, &dummy))
108 {
109 return mmioOpenW(buf, NULL,
111 }
112 return 0;
113}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define NULL
Definition: types.h:112
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:1298
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:670
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
#define MMIO_DENYWRITE
Definition: mmsystem.h:540
#define MMIO_READ
Definition: mmsystem.h:535
#define L(x)
Definition: ntvdm.h:50
int ret
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by PlaySound_GetMMIO().

◆ get_mmioFromProfile()

static HMMIO get_mmioFromProfile ( UINT  uFlags,
LPCWSTR  lpszName 
)
static

Definition at line 115 of file playsound.c.

116{
117 WCHAR str[128];
118 LPWSTR ptr, pszSnd;
119 HMMIO hmmio;
120 HKEY hUserKey, hRegSnd, hRegApp, hScheme, hSnd;
122 BOOL bIsDefault;
123
124 TRACE("searching in SystemSound list for %s\n", debugstr_w(lpszName));
125
126 bIsDefault = (_wcsicmp(lpszName, L"SystemDefault") == 0);
127
128 GetProfileStringW(L"Sounds",
129 bIsDefault ? L"Default" : lpszName,
130 L"",
131 str,
132 ARRAY_SIZE(str));
133 if (!*str)
134 goto Next;
135
136 for (ptr = str; *ptr && *ptr != L','; ptr++);
137
138 if (*ptr)
139 *ptr = UNICODE_NULL;
140
142 if (hmmio)
143 return hmmio;
144
145Next:
146 /* we look up the registry under
147 * HKCU\AppEvents\Schemes\Apps\.Default
148 * HKCU\AppEvents\Schemes\Apps<AppName>
149 */
150 err = RegOpenCurrentUser(KEY_READ, &hUserKey);
151 if (err == ERROR_SUCCESS)
152 {
153 err = RegOpenKeyW(hUserKey, L"AppEvents\\Schemes\\Apps", &hRegSnd);
154 RegCloseKey(hUserKey);
155 }
156
157 if (err != ERROR_SUCCESS)
158 goto None;
159
161 {
162 DWORD len;
163
164 err = ERROR_FILE_NOT_FOUND; /* error */
166 if (len > 0 && len < ARRAY_SIZE(str))
167 {
168 for (ptr = str + lstrlenW(str) - 1; ptr >= str; ptr--)
169 {
170 if (*ptr == L'.')
171 *ptr = UNICODE_NULL;
172
173 if (*ptr == L'\\')
174 {
175 err = RegOpenKeyW(hRegSnd, ptr + 1, &hRegApp);
176 break;
177 }
178 }
179 }
180 }
181 else
182 {
183 err = RegOpenKeyW(hRegSnd, L".Default", &hRegApp);
184 }
185
186 RegCloseKey(hRegSnd);
187
188 if (err != ERROR_SUCCESS)
189 goto None;
190
191 err = RegOpenKeyW(hRegApp,
192 bIsDefault ? L".Default" : lpszName,
193 &hScheme);
194
195 RegCloseKey(hRegApp);
196
197 if (err != ERROR_SUCCESS)
198 goto None;
199
200 err = RegOpenKeyW(hScheme, L".Current", &hSnd);
201
202 RegCloseKey(hScheme);
203
204 if (err != ERROR_SUCCESS)
205 goto None;
206
207 count = sizeof(str);
208 err = RegQueryValueExW(hSnd, NULL, 0, &type, (LPBYTE)str, &count);
209
210 RegCloseKey(hSnd);
211
212 if (err != ERROR_SUCCESS || !*str)
213 goto None;
214
215 if (type == REG_EXPAND_SZ)
216 {
218 if (count == 0)
219 goto None;
220
221 pszSnd = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR));
222 if (!pszSnd)
223 goto None;
224
226 {
227 HeapFree(GetProcessHeap(), 0, pszSnd);
228 goto None;
229 }
230 }
231 else if (type == REG_SZ)
232 {
233 /* The type is REG_SZ, no need to expand */
234 pszSnd = str;
235 }
236 else
237 {
238 /* Invalid type */
239 goto None;
240 }
241
243
244 if (type == REG_EXPAND_SZ)
245 HeapFree(GetProcessHeap(), 0, pszSnd);
246
247 if (hmmio)
248 return hmmio;
249
250None:
251 WARN("can't find SystemSound=%s !\n", debugstr_w(lpszName));
252 return NULL;
253}
@ None
Definition: install.h:14
#define WARN(fmt,...)
Definition: precomp.h:61
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
LONG WINAPI RegOpenCurrentUser(IN REGSAM samDesired, OUT PHKEY phkResult)
Definition: reg.c:3209
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
UINT uFlags
Definition: api.c:59
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
INT WINAPI GetProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR def_val, LPWSTR buffer, UINT len)
Definition: profile.c:1267
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLenum GLsizei len
Definition: glext.h:6722
#define debugstr_w
Definition: kernel32.h:32
#define REG_SZ
Definition: layer.c:22
#define SND_APPLICATION
Definition: mmsystem.h:165
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
#define KEY_READ
Definition: nt_native.h:1023
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define UNICODE_NULL
static DWORD PlaySound_ExpandEnvironmentStrings(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize)
Definition: playsound.c:44
#define err(...)
const WCHAR * str
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
STDMETHOD() Next(THIS_ ULONG celt, IAssociationElement *pElement, ULONG *pceltFetched) PURE
#define TRACE(s)
Definition: solgame.cpp:4
unsigned char * LPBYTE
Definition: typedefs.h:53

Referenced by PlaySound_GetMMIO().

◆ mmsystemGetVersion()

UINT WINAPI mmsystemGetVersion ( void  )

Definition at line 735 of file playsound.c.

736{
737 TRACE("3.10 (Win95?)\n");
738 return 0x030a;
739}

◆ MULTIMEDIA_PlaySound()

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

Definition at line 645 of file playsound.c.

646{
647 WINE_PLAYSOUND* wps = NULL;
648
649 TRACE("pszSound='%p' hmod=%p fdwSound=%08X\n",
650 pszSound, hmod, fdwSound);
651
652 /* SND_NOWAIT is ignored in w95/2k/xp. */
653 if ((fdwSound & SND_NOSTOP) && PlaySoundCurrent != NULL)
654 return FALSE;
655
656 /* alloc internal structure, if we need to play something */
657 if (pszSound && !(fdwSound & SND_PURGE))
658 {
659 if (!(wps = PlaySound_AllocAndGetMMIO(pszSound, hmod, fdwSound, bUnicode)))
660 return FALSE;
661 }
662
664 /* since several threads can enter PlaySound in parallel, we're not
665 * sure, at this point, that another thread didn't start a new playsound
666 */
667 while (PlaySoundCurrent != NULL)
668 {
670 /* FIXME: doc says we have to stop all instances of pszSound if it's non
671 * NULL... as of today, we stop all playing instances */
675
679
681 }
682
683 PlaySoundCurrent = wps;
685
686 if (!wps) return TRUE;
687
688 if (fdwSound & SND_ASYNC)
689 {
690 wps->bLoop = (fdwSound & SND_LOOP) ? TRUE : FALSE;
691
692 return proc_PlaySoundAsync(wps);
693 }
694
695 return proc_PlaySound(wps);
696}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define INFINITE
Definition: serial.h:102
#define SND_PURGE
Definition: mmsystem.h:164
#define SND_LOOP
Definition: mmsystem.h:157
#define SND_ASYNC
Definition: mmsystem.h:154
#define SND_NOSTOP
Definition: mmsystem.h:158
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
static WINE_PLAYSOUND * PlaySoundCurrent
Definition: playsound.c:40
static BOOL proc_PlaySound(WINE_PLAYSOUND *wps)
Definition: playsound.c:479
static WINE_PLAYSOUND * PlaySound_AllocAndGetMMIO(const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
Definition: playsound.c:438
static BOOL bPlaySoundStop
Definition: playsound.c:41
static BOOL proc_PlaySoundAsync(WINE_PLAYSOUND *wps)
Definition: playsound.c:627
unsigned bLoop
Definition: playsound.c:35
HWAVEOUT hWave
Definition: playsound.c:37
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
HANDLE psLastEvent
Definition: winmm.c:51
CRITICAL_SECTION WINMM_cs
Definition: winmm.c:53
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2385

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

◆ PlaySound_AllocAndGetMMIO()

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

Definition at line 438 of file playsound.c.

440{
441 BOOL bIsString;
442 LPCWSTR pszSoundW;
443 UNICODE_STRING usBuffer;
444 WINE_PLAYSOUND* wps;
445
446 bIsString = PlaySound_IsString(fdwSound, pszSound);
447
448 if (bIsString && !bUnicode)
449 {
450 RtlCreateUnicodeStringFromAsciiz(&usBuffer, pszSound);
451 if (!usBuffer.Buffer)
452 return NULL;
453
454 pszSoundW = usBuffer.Buffer;
455 }
456 else
457 {
458 pszSoundW = pszSound;
459 }
460
461 wps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wps));
462 if (wps)
463 {
464 /* construct an MMIO stream (either in memory, or from a file) */
465 wps->hmmio = PlaySound_GetMMIO(pszSoundW, hmod, fdwSound);
466 if (!wps->hmmio)
467 {
468 PlaySound_Free(wps);
469 wps = NULL;
470 }
471 }
472
473 if (bIsString && !bUnicode)
474 RtlFreeUnicodeString(&usBuffer);
475
476 return wps;
477}
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
static void PlaySound_Free(WINE_PLAYSOUND *wps)
Definition: playsound.c:428
static HMMIO PlaySound_GetMMIO(LPCWSTR pszSound, HMODULE hMod, DWORD fdwSound)
Definition: playsound.c:255
static BOOL PlaySound_IsString(DWORD fdwSound, const void *psz)
Definition: playsound.c:403
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

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 373 of file playsound.c.

376{
377 struct playsound_data* s = (struct playsound_data*)dwInstance;
378
379 switch (uMsg) {
380 case WOM_OPEN:
381 case WOM_CLOSE:
382 break;
383 case WOM_DONE:
384 InterlockedIncrement(&s->dwEventCount);
385 TRACE("Returning waveHdr=%lx\n", dwParam1);
386 SetEvent(s->hEvent);
387 break;
388 default:
389 ERR("Unknown uMsg=%d\n", uMsg);
390 }
391}
#define InterlockedIncrement
Definition: armddk.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
GLdouble s
Definition: gl.h:2039
#define WOM_DONE
Definition: mmsystem.h:183
#define WOM_OPEN
Definition: mmsystem.h:181
#define WOM_CLOSE
Definition: mmsystem.h:182
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733

Referenced by proc_PlaySound().

◆ PlaySound_ExpandEnvironmentStrings()

static DWORD PlaySound_ExpandEnvironmentStrings ( LPCWSTR  lpSrc,
LPWSTR  lpDst,
DWORD  nSize 
)
static

Definition at line 44 of file playsound.c.

45{
46 HANDLE hToken;
47 DWORD dwError;
48 DWORD dwLength = 0;
49
52 TRUE,
53 &hToken))
54 {
55 dwError = GetLastError();
56
57 if (dwError == ERROR_NO_TOKEN)
58 {
59 /* We are not impersonating, forward this to ExpandEnvironmentStrings */
60 return ExpandEnvironmentStringsW(lpSrc, lpDst, nSize);
61 }
62
63 ERR("OpenThreadToken failed (0x%x)\n", dwError);
64 return 0;
65 }
66
67 if (!ExpandEnvironmentStringsForUserW(hToken, lpSrc, lpDst, nSize))
68 {
69 dwError = GetLastError();
70
71 if (dwError == ERROR_INSUFFICIENT_BUFFER || nSize == 0)
72 {
73 /* The buffer is too small, find the required buffer size.
74 * NOTE: ExpandEnvironmentStringsForUser doesn't support retrieving buffer size. */
75 WCHAR szExpanded[1024];
76
77 if (ExpandEnvironmentStringsForUserW(hToken, lpSrc, szExpanded, ARRAY_SIZE(szExpanded)))
78 {
79 /* We success, return the required buffer size */
80 dwLength = lstrlenW(szExpanded) + 1;
81 goto Cleanup;
82 }
83 }
84
85 ERR("ExpandEnvironmentStringsForUser failed (0x%x)\n", dwError);
86 }
87 else
88 {
89 /* We success, return the size of the string */
90 dwLength = lstrlenW(lpDst) + 1;
91 }
92
94 CloseHandle(hToken);
95 return dwLength;
96}
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
BOOL WINAPI OpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, HANDLE *TokenHandle)
Definition: security.c:336
#define CloseHandle
Definition: compat.h:739
static DWORD DWORD * dwLength
Definition: fusion.c:86
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
BOOL WINAPI ExpandEnvironmentStringsForUserW(IN HANDLE hToken, IN LPCWSTR lpSrc, OUT LPWSTR lpDest, IN DWORD dwSize)
Definition: environment.c:743
static const WCHAR Cleanup[]
Definition: register.c:80
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2109
#define ERROR_NO_TOKEN
Definition: winerror.h:587
#define TOKEN_DUPLICATE
Definition: setypes.h:926
#define TOKEN_QUERY
Definition: setypes.h:928
#define TOKEN_IMPERSONATE
Definition: setypes.h:927

Referenced by get_mmioFromProfile().

◆ PlaySound_Free()

static void PlaySound_Free ( WINE_PLAYSOUND wps)
static

Definition at line 428 of file playsound.c.

429{
434 if (wps->hmmio) mmioClose(wps->hmmio, 0);
435 HeapFree(GetProcessHeap(), 0, wps);
436}
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:702

Referenced by PlaySound_AllocAndGetMMIO(), proc_PlaySound(), and proc_PlaySoundAsync().

◆ PlaySound_GetMMIO()

static HMMIO PlaySound_GetMMIO ( LPCWSTR  pszSound,
HMODULE  hMod,
DWORD  fdwSound 
)
static

Definition at line 255 of file playsound.c.

256{
257 BOOL bIsDefault = FALSE;
258 HMMIO hmmio = NULL;
259
260 TRACE("SoundName=%s !\n", debugstr_w(pszSound));
261
262 if (fdwSound & SND_MEMORY)
263 {
264 PVOID data;
265 MMIOINFO mminfo;
266
267 /* NOTE: SND_RESOURCE has the SND_MEMORY bit set */
268 if ((fdwSound & SND_RESOURCE) == SND_RESOURCE)
269 {
270 HRSRC hRes;
271 HGLOBAL hGlob;
272
273 hRes = FindResourceW(hMod, pszSound, L"WAVE");
274 hGlob = LoadResource(hMod, hRes);
275 if (!hRes || !hGlob)
276 goto Quit;
277
278 data = LockResource(hGlob);
279 FreeResource(hGlob);
280 if (!data)
281 goto Quit;
282 }
283 else
284 {
285 data = (PVOID)pszSound;
286 }
287
288 ZeroMemory(&mminfo, sizeof(mminfo));
289 mminfo.fccIOProc = FOURCC_MEM;
290 mminfo.pchBuffer = data;
291 mminfo.cchBuffer = -1; /* FIXME: when a resource, could grab real size */
292
293 TRACE("Memory sound %p\n", data);
294
295 hmmio = mmioOpenW(NULL, &mminfo, MMIO_READ);
296 }
297 else if (fdwSound & SND_ALIAS)
298 {
299 LPCWSTR pszName;
300
301 /* NOTE: SND_ALIAS_ID has the SND_ALIAS bit set */
302 if ((fdwSound & SND_ALIAS_ID) == SND_ALIAS_ID)
303 {
304 if (pszSound == (LPCWSTR)SND_ALIAS_SYSTEMASTERISK)
305 pszName = L"SystemAsterisk";
306 else if (pszSound == (LPCWSTR)SND_ALIAS_SYSTEMDEFAULT)
307 pszName = L"SystemDefault";
308 else if (pszSound == (LPCWSTR)SND_ALIAS_SYSTEMEXCLAMATION)
309 pszName = L"SystemExclamation";
310 else if (pszSound == (LPCWSTR)SND_ALIAS_SYSTEMEXIT)
311 pszName = L"SystemExit";
312 else if (pszSound == (LPCWSTR)SND_ALIAS_SYSTEMHAND)
313 pszName = L"SystemHand";
314 else if (pszSound == (LPCWSTR)SND_ALIAS_SYSTEMQUESTION)
315 pszName = L"SystemQuestion";
316 else if (pszSound == (LPCWSTR)SND_ALIAS_SYSTEMSTART)
317 pszName = L"SystemStart";
318 else if (pszSound == (LPCWSTR)SND_ALIAS_SYSTEMWELCOME)
319 pszName = L"SystemWelcome";
320 else
321 goto Quit;
322 }
323 else
324 {
325 pszName = pszSound;
326 }
327
328 bIsDefault = (_wcsicmp(pszName, L"SystemDefault") == 0);
329 hmmio = get_mmioFromProfile(fdwSound, pszName);
330 }
331 else if (fdwSound & SND_FILENAME)
332 {
333 hmmio = get_mmioFromFile(pszSound);
334 }
335 else
336 {
337 hmmio = get_mmioFromProfile(fdwSound, pszSound);
338 if (!hmmio)
339 hmmio = get_mmioFromFile(pszSound);
340 }
341
342Quit:
343 if (!hmmio && !(fdwSound & SND_NODEFAULT))
344 {
345 if (fdwSound & SND_APPLICATION)
346 {
347 if (!bIsDefault)
348 {
349 /* Find application-defined default sound */
350 hmmio = get_mmioFromProfile(fdwSound, L"SystemDefault");
351 if (hmmio)
352 return hmmio;
353 }
354
355 /* Find system default sound */
356 hmmio = get_mmioFromProfile(fdwSound & ~SND_APPLICATION, L"SystemDefault");
357 }
358 else if (!bIsDefault)
359 {
360 hmmio = get_mmioFromProfile(fdwSound, L"SystemDefault");
361 }
362 }
363
364 return hmmio;
365}
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define SND_ALIAS_SYSTEMEXCLAMATION
Definition: mmsystem.h:174
#define SND_ALIAS_SYSTEMSTART
Definition: mmsystem.h:172
#define SND_ALIAS_SYSTEMDEFAULT
Definition: mmsystem.h:175
#define SND_ALIAS_SYSTEMHAND
Definition: mmsystem.h:170
#define SND_ALIAS_SYSTEMEXIT
Definition: mmsystem.h:171
#define SND_RESOURCE
Definition: mmsystem.h:163
#define SND_ALIAS_SYSTEMWELCOME
Definition: mmsystem.h:173
#define SND_FILENAME
Definition: mmsystem.h:162
#define FOURCC_MEM
Definition: mmsystem.h:567
#define SND_ALIAS_ID
Definition: mmsystem.h:161
#define SND_MEMORY
Definition: mmsystem.h:156
#define SND_ALIAS
Definition: mmsystem.h:160
#define SND_ALIAS_SYSTEMQUESTION
Definition: mmsystem.h:169
#define SND_NODEFAULT
Definition: mmsystem.h:155
#define SND_ALIAS_SYSTEMASTERISK
Definition: mmsystem.h:168
static HMMIO get_mmioFromFile(LPCWSTR lpszName)
Definition: playsound.c:98
static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)
Definition: playsound.c:115
LONG cchBuffer
Definition: mmsystem.h:1491
HPSTR pchBuffer
Definition: mmsystem.h:1492
FOURCC fccIOProc
Definition: mmsystem.h:1487
void * PVOID
Definition: typedefs.h:50
#define ZeroMemory
Definition: winbase.h:1737

Referenced by PlaySound_AllocAndGetMMIO().

◆ PlaySound_IsString()

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

Definition at line 403 of file playsound.c.

404{
405 /* SND_RESOURCE is 0x40004 while
406 * SND_MEMORY is 0x00004
407 */
408 switch (fdwSound & (SND_RESOURCE | SND_ALIAS_ID | SND_FILENAME))
409 {
410 case SND_RESOURCE:
411 return HIWORD(psz) != 0; /* by name or by ID ? */
412
413 case SND_ALIAS_ID:
414 case SND_MEMORY:
415 return FALSE;
416
417 case SND_ALIAS:
418 case SND_FILENAME:
419 case 0:
420 return TRUE;
421
422 default:
423 FIXME("WTF\n");
424 return FALSE;
425 }
426}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define HIWORD(l)
Definition: typedefs.h:247

Referenced by PlaySound_AllocAndGetMMIO().

◆ PlaySound_WaitDone()

static void PlaySound_WaitDone ( struct playsound_data s)
static

Definition at line 393 of file playsound.c.

394{
395 for (;;) {
396 if (InterlockedDecrement(&s->dwEventCount) >= 0) break;
397 InterlockedIncrement(&s->dwEventCount);
398
400 }
401}
#define InterlockedDecrement
Definition: armddk.h:52

Referenced by proc_PlaySound().

◆ PlaySoundA()

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

Definition at line 701 of file playsound.c.

702{
703 return MULTIMEDIA_PlaySound(pszSoundA, hmod, fdwSound, FALSE);
704}
static BOOL MULTIMEDIA_PlaySound(const void *pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
Definition: playsound.c:645

Referenced by test_PlaySound().

◆ PlaySoundAsyncThreadProc()

static DWORD WINAPI PlaySoundAsyncThreadProc ( LPVOID  lpParameter)
static

Definition at line 617 of file playsound.c.

618{
619 WINE_PLAYSOUND *wps = (WINE_PLAYSOUND*)lpParameter;
620
621 /* Play the sound */
622 proc_PlaySound(wps);
623
624 return 0;
625}

Referenced by proc_PlaySoundAsync().

◆ PlaySoundW()

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

◆ proc_PlaySound()

static BOOL proc_PlaySound ( WINE_PLAYSOUND wps)
static

Definition at line 479 of file playsound.c.

480{
481 BOOL bRet = FALSE;
482 MMCKINFO ckMainRIFF;
483 MMCKINFO mmckInfo;
484 LPWAVEFORMATEX lpWaveFormat = NULL;
485 HWAVEOUT hWave = 0;
486 LPWAVEHDR waveHdr = NULL;
488 struct playsound_data s;
489 LONG r;
490
491 s.hEvent = 0;
492
493 if (mmioDescend(wps->hmmio, &ckMainRIFF, NULL, 0))
494 goto errCleanUp;
495
496 TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08X\n",
497 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
498
499 if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
500 (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E')))
501 goto errCleanUp;
502
503 mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
504 if (mmioDescend(wps->hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
505 goto errCleanUp;
506
507 TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
508 (LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);
509
510 lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
511 if (!lpWaveFormat)
512 goto errCleanUp;
513 r = mmioRead(wps->hmmio, (HPSTR)lpWaveFormat, mmckInfo.cksize);
514 if (r < 0 || r < sizeof(PCMWAVEFORMAT))
515 goto errCleanUp;
516
517 TRACE("wFormatTag=%04X !\n", lpWaveFormat->wFormatTag);
518 TRACE("nChannels=%d\n", lpWaveFormat->nChannels);
519 TRACE("nSamplesPerSec=%d\n", lpWaveFormat->nSamplesPerSec);
520 TRACE("nAvgBytesPerSec=%d\n", lpWaveFormat->nAvgBytesPerSec);
521 TRACE("nBlockAlign=%d\n", lpWaveFormat->nBlockAlign);
522 TRACE("wBitsPerSample=%u !\n", lpWaveFormat->wBitsPerSample);
523
524 /* move to end of 'fmt ' chunk */
525 mmioAscend(wps->hmmio, &mmckInfo, 0);
526
527 mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
528 if (mmioDescend(wps->hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
529 goto errCleanUp;
530
531 TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
532 (LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);
533
534 s.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
535 if (!s.hEvent || bPlaySoundStop)
536 goto errCleanUp;
537
540 goto errCleanUp;
541
542 /* make it so that 3 buffers per second are needed */
543 bufsize = (((lpWaveFormat->nAvgBytesPerSec / 3) - 1) / lpWaveFormat->nBlockAlign + 1) *
544 lpWaveFormat->nBlockAlign;
545 waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize);
546 if (!waveHdr)
547 goto errCleanUp;
548 waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
549 waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
550 waveHdr[0].dwUser = waveHdr[1].dwUser = 0L;
551 waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
552 waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
553 waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
554 if (waveOutPrepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
555 waveOutPrepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR))) {
556 goto errCleanUp;
557 }
558
559 wps->hWave = hWave;
560 s.dwEventCount = 1L; /* for first buffer */
561 index = 0;
562
563 do {
564 left = mmckInfo.cksize;
565
566 mmioSeek(wps->hmmio, mmckInfo.dwDataOffset, SEEK_SET);
567 while (left)
568 {
569 if (bPlaySoundStop)
570 {
571 wps->bLoop = FALSE;
572 break;
573 }
574 count = mmioRead(wps->hmmio, waveHdr[index].lpData, min(bufsize, left));
575 if (count < 1) break;
576 left -= count;
577 waveHdr[index].dwBufferLength = count;
578 if (waveOutWrite(hWave, &waveHdr[index], sizeof(WAVEHDR)) == MMSYSERR_NOERROR) {
579 index ^= 1;
581 }
582 else {
583 ERR("Aborting play loop, waveOutWrite error\n");
584 wps->bLoop = FALSE;
585 break;
586 }
587 }
588 bRet = TRUE;
589 } while (wps->bLoop);
590
591 PlaySound_WaitDone(&s); /* to balance first buffer */
593
594 waveOutUnprepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR));
595 waveOutUnprepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR));
596
597errCleanUp:
598 TRACE("Done playing sound => %s!\n", bRet ? "ok" : "ko");
599 HeapFree(GetProcessHeap(), 0, lpWaveFormat);
600 if (hWave)
601 {
603 /* the CS prevents a concurrent waveOutReset */
604 wps->hWave = 0;
607 Sleep(100);
608 }
609 CloseHandle(s.hEvent);
610 HeapFree(GetProcessHeap(), 0, waveHdr);
611
612 PlaySound_Free(wps);
613
614 return bRet;
615}
#define index(s, c)
Definition: various.h:29
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1205
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:836
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
Definition: mmio.c:1107
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:733
HWAVEOUT hWave
Definition: main.h:78
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint index
Definition: glext.h:6031
GLint left
Definition: glext.h:7726
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
#define SEEK_SET
Definition: jmemansi.c:26
#define WAVERR_STILLPLAYING
Definition: mmsystem.h:177
struct wavehdr_tag WAVEHDR
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
#define WAVE_MAPPER
Definition: mmsystem.h:187
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
char * HPSTR
Definition: mmsystem.h:1477
#define min(a, b)
Definition: monoChain.cc:55
long LONG
Definition: pedump.c:60
static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: playsound.c:373
static void PlaySound_WaitDone(struct playsound_data *s)
Definition: playsound.c:393
FOURCC ckid
Definition: mmsystem.h:1507
DWORD cksize
Definition: mmsystem.h:1508
DWORD dwDataOffset
Definition: mmsystem.h:1510
FOURCC fccType
Definition: mmsystem.h:1509
WORD nBlockAlign
Definition: mmreg.h:82
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nChannels
Definition: mmreg.h:79
WORD wFormatTag
Definition: mmreg.h:78
WORD wBitsPerSample
Definition: mmreg.h:83
DWORD dwBufferLength
Definition: mmsystem.h:1015
DWORD dwLoops
Definition: mmsystem.h:1019
DWORD dwFlags
Definition: mmsystem.h:1018
DWORD_PTR dwUser
Definition: mmsystem.h:1017
LPSTR lpData
Definition: mmsystem.h:1014
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
uint32_t DWORD_PTR
Definition: typedefs.h:65
int32_t INT
Definition: typedefs.h:58
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2341
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2307
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2246
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2277
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2257
char * LPSTR
Definition: xmlstorage.h:182

Referenced by MULTIMEDIA_PlaySound(), and PlaySoundAsyncThreadProc().

◆ proc_PlaySoundAsync()

static BOOL proc_PlaySoundAsync ( WINE_PLAYSOUND wps)
static

Definition at line 627 of file playsound.c.

628{
630
631 /* Create a thread to play the sound asynchronously */
633 if (hThread)
634 {
637 return TRUE;
638 }
639
640 /* Error cases */
641 PlaySound_Free(wps);
642 return FALSE;
643}
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:700
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:137
HANDLE hThread
Definition: wizard.c:28
static DWORD WINAPI PlaySoundAsyncThreadProc(LPVOID lpParameter)
Definition: playsound.c:617
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:307

Referenced by MULTIMEDIA_PlaySound().

◆ sndPlaySoundA()

BOOL WINAPI sndPlaySoundA ( LPCSTR  pszSoundA,
UINT  uFlags 
)

Definition at line 717 of file playsound.c.

Referenced by test_sndPlaySound().

◆ sndPlaySoundW()

BOOL WINAPI sndPlaySoundW ( LPCWSTR  pszSound,
UINT  uFlags 
)

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( winmm  )

Variable Documentation

◆ bPlaySoundStop

BOOL bPlaySoundStop
static

Definition at line 41 of file playsound.c.

Referenced by MULTIMEDIA_PlaySound(), and proc_PlaySound().

◆ PlaySoundCurrent

WINE_PLAYSOUND* PlaySoundCurrent
static

Definition at line 40 of file playsound.c.

Referenced by MULTIMEDIA_PlaySound(), and PlaySound_Free().