36#include "wine/unicode.h"
127 DWORD size1, size2, playpos, writepos, old_writepos, old_playpos, adv;
131 old_writepos =
This->writepos;
132 old_playpos =
This->last_playpos;
133 if (old_writepos <= old_playpos)
134 old_writepos +=
This->buf_size;
137 if (old_playpos > playpos) {
138 adv =
This->buf_size + playpos - old_playpos;
141 adv = playpos - old_playpos;
142 This->last_playpos = playpos;
144 TRACE(
"Moving from %u to %u: clearing %u bytes\n", old_playpos, playpos, adv);
150 *minwritepos = writepos;
151 if (!writepos_set || old_writepos < writepos) {
154 FIXME(
"Underrun of data occurred!\n");
156 *seqwritepos = writepos;
158 *seqwritepos =
This->writepos;
164 DWORD writepos, min_writepos, playpos;
170 playpos =
This->last_playpos;
171 if (
This->renderer.filter.pClock == &
This->IReferenceClock_iface) {
174 cur -=
This->renderer.filter.rtStreamStart;
175 }
else if (
This->renderer.filter.pClock) {
177 cur -=
This->renderer.filter.rtStreamStart;
181 if (writepos == min_writepos)
186 *ret_writepos = writepos;
190 if (writepos >= playpos)
198 delta_t = write_at - writepos_t;
199 if (delta_t >= -max_lag && delta_t <= max_lag) {
200 TRACE(
"Continuing from old position\n");
201 *ret_writepos = writepos;
202 }
else if (delta_t < 0) {
204 WARN(
"Delta too big %i/%i, overwriting old data or even skipping\n", (
int)delta_t / 10000, (
int)max_lag / 10000);
205 if (min_writepos >= playpos)
209 past = min_writepos_t - write_at;
212 WARN(
"Skipping %u bytes\n", skipbytes);
214 *ret_writepos = min_writepos;
217 WARN(
"Advancing %u bytes\n", aheadbytes);
218 *ret_writepos = (min_writepos + aheadbytes) %
This->buf_size;
222 WARN(
"Delta too big %i/%i, too far ahead\n", (
int)delta_t / 10000, (
int)max_lag / 10000);
224 WARN(
"Advancing %u bytes\n", aheadbytes);
227 *ret_writepos = (min_writepos + aheadbytes) %
This->buf_size;
230 if (playpos > *ret_writepos)
231 *pfree = playpos - *ret_writepos;
232 else if (playpos == *ret_writepos)
235 *pfree =
This->buf_size + playpos - *ret_writepos;
245 while (
This->renderer.filter.state == State_Running)
268 while (
size &&
This->renderer.filter.state != State_Stopped) {
272 if (
This->renderer.filter.state == State_Running)
283 if (
This->renderer.pInputPin->flushing ||
284 This->renderer.filter.state == State_Stopped) {
302 ERR(
"Unable to lock sound buffer! (%x)\n",
hr);
309 This->writepos = (writepos + size1 + size2) %
This->buf_size;
310 TRACE(
"Wrote %u bytes at %u, next at %u - (%u/%u)\n", size1+size2, writepos,
This->writepos,
free,
size);
311 data += size1 + size2;
312 size -= size1 + size2;
330 if (IMediaSample_GetMediaType(pSample, &amt) ==
S_OK)
336 if (origfmt->
wFormatTag == newfmt->wFormatTag &&
337 origfmt->
nChannels == newfmt->nChannels &&
340 origfmt->
cbSize == newfmt->cbSize)
345 newfmt->nSamplesPerSec);
350 IMediaSample_SetMediaType(pSample,
NULL);
363 LONG cbSrcStream = 0;
367 TRACE(
"%p %p\n", iface, pSample);
373 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
376 ERR(
"Cannot get pointer to sample data (%x)\n",
hr);
380 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
382 ERR(
"Cannot get sample time (%x)\n",
hr);
386 IMediaSample_IsDiscontinuity(pSample);
388 if (IMediaSample_IsPreroll(pSample) ==
S_OK)
394 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
395 TRACE(
"Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream);
398 if (
This->renderer.filter.state == State_Running &&
This->renderer.filter.pClock && tStart >= 0) {
402 jitter =
now -
This->renderer.filter.rtStreamStart - tStart;
407 q.Type = (jitter > 0 ? Famine : Flood);
410 q.TimeStamp = tStart;
420 if (!
IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio))
427 TRACE(
"nSamplesPerSec = %d\n",
format->nSamplesPerSec);
428 TRACE(
"nAvgBytesPerSec = %d\n",
format->nAvgBytesPerSec);
430 TRACE(
"wBitsPerSample = %d\n",
format->wBitsPerSample);
432 if (!
IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_PCM))
455 if (
This->renderer.pInputPin->pin.pConnectedTo)
457 if (
This->renderer.filter.state == State_Paused)
475 TRACE(
"(%p)->(%p)\n",
This, pReceivePin);
481 TRACE(
"Size %d\n", pmt->cbFormat);
497 ERR(
"Can't create sound buffer (%x)\n",
hr);
503 ERR(
"Can't set volume to %d (%x)\n",
This->volume,
hr);
507 ERR(
"Can't set pan to %d (%x)\n",
This->pan,
hr);
525 TRACE(
"(%p)->()\n", iface);
527 if (
This->threadid) {
546 TRACE(
"(%p)->()\n",iface);
578 if (
This->renderer.filter.state != State_Stopped)
623 TRACE(
"(%p, %p)\n", pUnkOuter,
ppv);
646 ERR(
"Cannot create Direct Sound object (%x)\n",
hr);
650 IDirectSoundBuffer *
buf;
674 *
ppv = pDSoundRender;
693 *
ppv = &
This->basicAudio.IBasicAudio_iface;
695 *
ppv = &
This->IReferenceClock_iface;
697 *
ppv = &
This->IAMDirectSound_iface;
699 *
ppv = &
This->IAMFilterMiscFlags_iface;
725 TRACE(
"(%p)->() Release from %d\n",
This, refCount + 1);
729 if (
This->threadid) {
745 TRACE(
"Destroying Audio Renderer\n");
762 if (
This->renderer.filter.state != State_Paused)
764 if (
This->renderer.filter.state == State_Stopped)
766 if (
This->renderer.pInputPin->pin.pConnectedTo)
768 This->renderer.pInputPin->end_of_stream = 0;
773 This->renderer.filter.state = State_Paused;
835 TRACE(
"(%p/%p)->(%d)\n",
This, iface, lVolume);
840 if (
This->dsbuffer) {
845 This->volume = lVolume;
853 TRACE(
"(%p/%p)->(%p)\n",
This, iface, plVolume);
858 *plVolume =
This->volume;
866 TRACE(
"(%p/%p)->(%d)\n",
This, iface, lBalance);
871 if (
This->dsbuffer) {
876 This->pan = lBalance;
884 TRACE(
"(%p/%p)->(%p)\n",
This, iface, plBalance);
889 *plBalance =
This->pan;
939 if (
cur->start > curtime) {
942 }
else if (
cur->periodicity) {
943 while (
cur->start <= curtime) {
944 cur->start +=
cur->periodicity;
963 case 0:
TRACE(
"Exiting\n");
return 0;
968 TRACE(
"Adding one-shot timer %p\n",
t);
970 TRACE(
"Adding periodic timer %p\n",
t);
979 if (
cur->cookie ==
msg.wParam) {
1037 if (
This->dsbuffer) {
1038 DWORD writepos1, writepos2;
1041 if (
This->renderer.pInputPin &&
This->renderer.pInputPin->pin.mtCurrent.pbFormat)
1048 ERR(
"pInputPin Disconnected\n");
1054 WARN(
"Could not get reference time (%x)!\n",
hr);
1073 if (!pdwAdviseCookie)
1077 future = when -
This->play_time;
1078 if (!
This->threadid &&
This->dsbuffer) {
1086 if (future <= 10000) {
1088 *pdwAdviseCookie = 0;
1097 *pdwAdviseCookie =
t->cookie;
1114 if (rtStartTime <= 0 || rtPeriodTime <= 0)
1117 if (!pdwAdviseCookie)
1121 if (!
This->threadid &&
This->dsbuffer) {
1131 t->start = rtStartTime;
1132 t->periodicity = rtPeriodTime;
1133 t->handle = (
HANDLE)hSemaphore;
1136 *pdwAdviseCookie =
t->cookie;
1146 TRACE(
"(%p/%p)->(%p)\n",
This, iface, (
void*)dwAdviseCookie);
1147 if (!
This->advisethread || !dwAdviseCookie)
1253 FIXME(
"(%p/%p)->(%p,%d): stub\n",
This, iface,
hwnd, bgaudible);
1262 FIXME(
"(%p/%p)->(%p,%p): stub\n",
This, iface,
hwnd, bgaudible);
1284 return IBaseFilter_QueryInterface(&
This->renderer.filter.IBaseFilter_iface,
riid,
ppv);
1289 return IBaseFilter_AddRef(&
This->renderer.filter.IBaseFilter_iface);
1294 return IBaseFilter_Release(&
This->renderer.filter.IBaseFilter_iface);
struct outqueuenode * head
#define InterlockedIncrement
@ AM_FILTER_MISC_FLAGS_IS_RENDERER
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID, LPDIRECTSOUND8 *ppDS, IUnknown *pUnkOuter)
static HRESULT WINAPI DSoundRender_QueryInterface(IBaseFilter *iface, REFIID riid, LPVOID *ppv)
static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl
static const IAMDirectSoundVtbl IAMDirectSound_Vtbl
static const IBaseFilterVtbl DSoundRender_Vtbl
static ULONG WINAPI ReferenceClock_AddRef(IReferenceClock *iface)
static ULONG WINAPI AMDirectSound_AddRef(IAMDirectSound *iface)
static void DSoundRender_UpdatePositions(DSoundRenderImpl *This, DWORD *seqwritepos, DWORD *minwritepos)
static HRESULT WINAPI DSoundRender_PrepareReceive(BaseRenderer *iface, IMediaSample *pSample)
static HRESULT WINAPI AMDirectSound_GetPrimaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer **buf)
static HRESULT WINAPI DSoundRender_BeginFlush(BaseRenderer *iface)
static HRESULT WINAPI Basicaudio_get_Balance(IBasicAudio *iface, LONG *plBalance)
static const REFERENCE_TIME DSoundRenderer_Max_Fill
static HRESULT WINAPI DSoundRender_EndOfStream(BaseRenderer *iface)
static HRESULT WINAPI Basicaudio_QueryInterface(IBasicAudio *iface, REFIID riid, LPVOID *ppvObj)
static HRESULT WINAPI AMDirectSound_GetFocusWindow(IAMDirectSound *iface, HWND *hwnd, BOOL *bgaudible)
HRESULT DSoundRender_create(IUnknown *pUnkOuter, LPVOID *ppv)
static ULONG WINAPI AMDirectSound_Release(IAMDirectSound *iface)
static DSoundRenderImpl * impl_from_BaseRenderer(BaseRenderer *iface)
static HRESULT DSoundRender_HandleEndOfStream(DSoundRenderImpl *This)
static DWORD WINAPI DSoundAdviseThread(LPVOID lpParam)
static HRESULT WINAPI ReferenceClock_AdviseTime(IReferenceClock *iface, REFERENCE_TIME rtBaseTime, REFERENCE_TIME rtStreamTime, HEVENT hEvent, DWORD_PTR *pdwAdviseCookie)
static LONG cookie_counter
static HRESULT WINAPI Basicaudio_put_Volume(IBasicAudio *iface, LONG lVolume)
static DSoundRenderImpl * impl_from_IReferenceClock(IReferenceClock *iface)
static REFERENCE_TIME time_from_pos(DSoundRenderImpl *This, DWORD pos)
static const BaseRendererFuncTable BaseFuncTable
static DSoundRenderImpl * impl_from_IAMDirectSound(IAMDirectSound *iface)
static HRESULT WINAPI ReferenceClock_QueryInterface(IReferenceClock *iface, REFIID riid, LPVOID *ppvObj)
static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl *This, REFERENCE_TIME tStart, REFERENCE_TIME tStop, const BYTE *data, DWORD size)
static const IReferenceClockVtbl IReferenceClock_Vtbl
static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface)
static HRESULT WINAPI DSoundRender_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pMediaSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime)
static HRESULT WINAPI DSoundRender_CompleteConnect(BaseRenderer *iface, IPin *pReceivePin)
static HRESULT DSoundRender_GetWritePos(DSoundRenderImpl *This, DWORD *ret_writepos, REFERENCE_TIME write_at, DWORD *pfree, DWORD *skip)
static ULONG WINAPI Basicaudio_Release(IBasicAudio *iface)
static HRESULT WINAPI ReferenceClock_GetTime(IReferenceClock *iface, REFERENCE_TIME *pTime)
static HRESULT WINAPI AMDirectSound_ReleasePrimaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer *buf)
static DSoundRenderImpl * impl_from_IBasicAudio(IBasicAudio *iface)
static VOID WINAPI DSoundRender_OnStopStreaming(BaseRenderer *iface)
static HRESULT WINAPI AMDirectSound_ReleaseSecondaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer *buf)
static HRESULT WINAPI AMDirectSound_ReleaseDirectSoundInterface(IAMDirectSound *iface, IDirectSound *ds)
static HRESULT WINAPI DSoundRender_DoRenderSample(BaseRenderer *iface, IMediaSample *pSample)
static HRESULT WINAPI Basicaudio_put_Balance(IBasicAudio *iface, LONG lBalance)
static ULONG WINAPI DSoundRender_Release(IBaseFilter *iface)
static DSoundRenderImpl * impl_from_IBaseFilter(IBaseFilter *iface)
static ULONG WINAPI Basicaudio_AddRef(IBasicAudio *iface)
static HRESULT WINAPI AMDirectSound_GetDirectSoundInterface(IAMDirectSound *iface, IDirectSound **ds)
static HRESULT WINAPI DSoundRender_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE *pmt)
static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv)
static HRESULT WINAPI AMDirectSound_GetSecondaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer **buf)
static HRESULT WINAPI ReferenceClock_Unadvise(IReferenceClock *iface, DWORD_PTR dwAdviseCookie)
static HRESULT WINAPI DSoundRender_Pause(IBaseFilter *iface)
static HRESULT WINAPI ReferenceClock_AdvisePeriodic(IReferenceClock *iface, REFERENCE_TIME rtStartTime, REFERENCE_TIME rtPeriodTime, HSEMAPHORE hSemaphore, DWORD_PTR *pdwAdviseCookie)
static HRESULT WINAPI DSoundRender_EndFlush(BaseRenderer *iface)
static ULONG WINAPI ReferenceClock_Release(IReferenceClock *iface)
static HRESULT WINAPI Basicaudio_get_Volume(IBasicAudio *iface, LONG *plVolume)
static HRESULT WINAPI AMDirectSound_SetFocusWindow(IAMDirectSound *iface, HWND hwnd, BOOL bgaudible)
static DSoundRenderImpl * impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
static VOID WINAPI DSoundRender_OnStartStreaming(BaseRenderer *iface)
static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface)
static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface)
static const IBasicAudioVtbl IBasicAudio_Vtbl
static HRESULT WINAPI DSoundRender_BreakConnect(BaseRenderer *iface)
static HRESULT WINAPI AMDirectSound_QueryInterface(IAMDirectSound *iface, REFIID riid, LPVOID *ppvObj)
static DWORD pos_from_time(DSoundRenderImpl *This, REFERENCE_TIME time)
const char * qzdebugstr_guid(const GUID *id)
#define INVALID_HANDLE_VALUE
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
#define HeapFree(x, y, z)
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)
#define IReferenceClock_GetTime(p, a)
#define IDirectSound8_CreateSoundBuffer(p, a, b, c)
struct _DSBUFFERDESC DSBUFFERDESC
#define IDirectSoundBuffer_Unlock(p, a, b, c, d)
#define DSBCAPS_GLOBALFOCUS
#define DSBCAPS_CTRLVOLUME
struct IDirectSoundBuffer * LPDIRECTSOUNDBUFFER
#define IDirectSoundBuffer_GetCurrentPosition(p, a, b)
#define DSBCAPS_GETCURRENTPOSITION2
#define DSBLOCK_ENTIREBUFFER
#define IDirectSoundBuffer_Stop(p)
#define IDirectSoundBuffer_SetPan(p, a)
#define DSBCAPS_CTRLFREQUENCY
#define IDirectSound8_Release(p)
#define IDirectSoundBuffer_Play(p, a, b, c)
#define IDirectSoundBuffer_SetVolume(p, a)
#define IDirectSoundBuffer_SetFrequency(p, a)
#define IDirectSoundBuffer_Lock(p, a, b, c, d, e, f, g)
#define IDirectSoundBuffer_Release(p)
#define DSBCAPS_PRIMARYBUFFER
#define IDirectSound8_SetCooperativeLevel(p, a, b)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLdouble GLdouble GLdouble GLdouble q
GLenum GLuint GLenum GLsizei const GLchar * buf
VOID WINAPI CoTaskMemFree(LPVOID ptr)
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
#define memcpy(s1, s2, n)
static void FreeMediaType(AM_MEDIA_TYPE *pMediaType)
static HRESULT CopyMediaType(AM_MEDIA_TYPE *pDest, const AM_MEDIA_TYPE *pSrc)
#define IsEqualIID(riid1, riid2)
static unsigned __int64 next
HRESULT WINAPI BasicAudioImpl_Invoke(IBasicAudio *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr)
HRESULT WINAPI BasicAudio_Init(BasicAudio *pBasicAudio, const IBasicAudioVtbl *lpVtbl)
HRESULT WINAPI BasicAudioImpl_GetTypeInfo(IBasicAudio *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
HRESULT WINAPI BasicAudioImpl_GetIDsOfNames(IBasicAudio *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
HRESULT WINAPI BasicAudio_Destroy(BasicAudio *pBasicAudio)
HRESULT WINAPI BasicAudioImpl_GetTypeInfoCount(IBasicAudio *iface, UINT *pctinfo)
HRESULT WINAPI BaseRendererImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock)
HRESULT WINAPI BaseRendererImpl_EndFlush(BaseRenderer *iface)
HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter *iface, CLSID *pClsid)
ULONG WINAPI BaseRendererImpl_Release(IBaseFilter *iface)
HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)
HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter *iface)
HRESULT WINAPI BaseRendererImpl_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin)
HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter *iface)
HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, LPCWSTR pName)
HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter *iface, LPWSTR *pVendorInfo)
HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock)
HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer *iface)
HRESULT WINAPI BaseRendererImpl_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
HRESULT WINAPI BaseRendererImpl_QueryInterface(IBaseFilter *iface, REFIID riid, LPVOID *ppv)
HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
HRESULT WINAPI BaseRenderer_Init(BaseRenderer *This, const IBaseFilterVtbl *Vtbl, IUnknown *pUnkOuter, const CLSID *pClsid, DWORD_PTR DebugInfo, const BaseRendererFuncTable *pBaseFuncsTable)
HRESULT WINAPI BaseRendererImpl_EndOfStream(BaseRenderer *iface)
IBaseFilter IBaseFilter_iface
IAMFilterMiscFlags IAMFilterMiscFlags_iface
LPDIRECTSOUNDBUFFER dsbuffer
IReferenceClock IReferenceClock_iface
IAMDirectSound IAMDirectSound_iface
LPWAVEFORMATEX lpwfxFormat
struct dsoundrender_timer * next
REFERENCE_TIME periodicity
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseSemaphore(IN HANDLE hSemaphore, IN LONG lReleaseCount, IN LPLONG lpPreviousCount)
TW_UINT32 TW_UINT16 TW_UINT16 MSG
#define CONTAINING_RECORD(address, type, field)
#define VFW_E_ALREADY_CONNECTED
#define VFW_E_TYPE_NOT_ACCEPTED
#define VFW_E_WRONG_STATE
DWORD WINAPI GetLastError(void)
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
_In_ PCCERT_CONTEXT _In_opt_ LPFILETIME pTime
#define CLASS_E_NOAGGREGATION
#define HRESULT_FROM_WIN32(x)
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
HWND WINAPI GetDesktopWindow(void)
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
BOOL WINAPI PostThreadMessageW(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)