Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/dsdmo/Makefile.in | 5 +- dlls/dsdmo/dsdmo_classes.idl | 28 +++ dlls/dsdmo/dsdmo_private.h | 32 +++ dlls/dsdmo/echo.c | 397 +++++++++++++++++++++++++++++++++++ dlls/dsdmo/main.c | 57 ++++- 5 files changed, 517 insertions(+), 2 deletions(-) create mode 100644 dlls/dsdmo/dsdmo_classes.idl create mode 100644 dlls/dsdmo/dsdmo_private.h create mode 100644 dlls/dsdmo/echo.c
diff --git a/dlls/dsdmo/Makefile.in b/dlls/dsdmo/Makefile.in index 99816ae0c0..cb4f8f8a4b 100644 --- a/dlls/dsdmo/Makefile.in +++ b/dlls/dsdmo/Makefile.in @@ -1,6 +1,9 @@ MODULE = dsdmo.dll - +IMPORTS = uuid EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ + echo.c \ main.c + +IDL_SRCS = dsdmo_classes.idl diff --git a/dlls/dsdmo/dsdmo_classes.idl b/dlls/dsdmo/dsdmo_classes.idl new file mode 100644 index 0000000000..649db8f61b --- /dev/null +++ b/dlls/dsdmo/dsdmo_classes.idl @@ -0,0 +1,28 @@ +/* + * Copyright 2019 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#pragma makedep register + +[ + uuid(ef3e932c-d40b-4f51-8ccf-3f98f1b29d5d), + threading(both), + progid("Microsoft.DirectSoundEchoDMO.1"), + vi_progid("Microsoft.DirectSoundEchoDMO") +] +coclass DirectSoundEchoDMO +{ +} diff --git a/dlls/dsdmo/dsdmo_private.h b/dlls/dsdmo/dsdmo_private.h new file mode 100644 index 0000000000..4abe5a9f60 --- /dev/null +++ b/dlls/dsdmo/dsdmo_private.h @@ -0,0 +1,32 @@ +/* + * Copyright 2019 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#ifndef WINE_DSDMO_PRIVATE +#define WINE_DSDMO_PRIVATE + +#include "windows.h" +#include "mmsystem.h" +#include "mediaobj.h" + +#include "wine/heap.h" +#include "wine/debug.h" + +#include "dsound.h" + +extern HRESULT WINAPI EchoFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv) DECLSPEC_HIDDEN; + +#endif diff --git a/dlls/dsdmo/echo.c b/dlls/dsdmo/echo.c new file mode 100644 index 0000000000..3e8b0be115 --- /dev/null +++ b/dlls/dsdmo/echo.c @@ -0,0 +1,397 @@ +/* + * Copyright 2019 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS + +#include "dsdmo_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dsdmo); + +struct dmo_echofx +{ + IDirectSoundFXEcho IDirectSoundFXEcho_iface; + IMediaObject IMediaObject_iface; + IMediaObjectInPlace IMediaObjectInPlace_iface; + LONG ref; +}; + +static inline struct dmo_echofx *impl_from_IDirectSoundFXEcho(IDirectSoundFXEcho *iface) +{ + return CONTAINING_RECORD(iface, struct dmo_echofx, IDirectSoundFXEcho_iface); +} + +static inline struct dmo_echofx *impl_from_IMediaObject(IMediaObject *iface) +{ + return CONTAINING_RECORD(iface, struct dmo_echofx, IMediaObject_iface); +} + +static inline struct dmo_echofx *impl_from_IMediaObjectInPlace(IMediaObjectInPlace *iface) +{ + return CONTAINING_RECORD(iface, struct dmo_echofx, IMediaObjectInPlace_iface); +} + +static HRESULT WINAPI echo_mediaobj_QueryInterface(IMediaObject *iface, REFIID riid, void **obj) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + return IDirectSoundFXEcho_QueryInterface(&This->IDirectSoundFXEcho_iface, riid, obj); +} + +static ULONG WINAPI echo_mediaobj_AddRef(IMediaObject *iface) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + return IDirectSoundFXEcho_AddRef(&This->IDirectSoundFXEcho_iface); +} + +static ULONG WINAPI echo_mediaobj_Release(IMediaObject *iface) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + return IDirectSoundFXEcho_Release(&This->IDirectSoundFXEcho_iface); +} + +static HRESULT WINAPI echo_mediaobj_GetStreamCount(IMediaObject *iface, DWORD *inputs, DWORD *outputs) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %p, %p\n", This, inputs, outputs); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_GetInputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %p\n", This, index, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_GetOutputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %p\n", This, index, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_GetInputType(IMediaObject *iface, DWORD index, DWORD type, DMO_MEDIA_TYPE *pmt) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %d, %p\n", This, index, type, pmt); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_GetOutputType(IMediaObject *iface, DWORD index, DWORD type, DMO_MEDIA_TYPE *pmt) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %d, %p\n", This, index, type, pmt); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_SetInputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *pmt, DWORD flags) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %p, %x\n", This, index, pmt, flags); + return S_OK; +} + +static HRESULT WINAPI echo_mediaobj_SetOutputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *pmt, DWORD flags) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %p, %x\n", This, index, pmt, flags); + return S_OK; +} + +static HRESULT WINAPI echo_mediaobj_GetInputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *pmt) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %p\n", This, index, pmt); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_GetOutputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *pmt) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %p\n", This, index, pmt); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_GetInputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *ahead, DWORD *alignment) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %p, %p, %p\n", This, index, size, ahead, alignment); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_GetOutputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *alignment) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %p, %p\n", This, index, size, alignment); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_GetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME *latency) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %p\n", This, index, latency); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_SetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME latency) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %s\n", This, index, wine_dbgstr_longlong(latency)); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_Flush(IMediaObject *iface) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_Discontinuity(IMediaObject *iface, DWORD index) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d\n", This, index); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_AllocateStreamingResources(IMediaObject *iface) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_FreeStreamingResources(IMediaObject *iface) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_GetInputStatus(IMediaObject *iface, DWORD index, DWORD *flags) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %p\n", This, index, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_ProcessInput(IMediaObject *iface, DWORD index, IMediaBuffer *buffer, + DWORD flags, REFERENCE_TIME timestamp, REFERENCE_TIME length) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d, %p, %x, %s, %s\n", This, index, buffer, flags, wine_dbgstr_longlong(timestamp), wine_dbgstr_longlong(length)); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_ProcessOutput(IMediaObject *iface, DWORD flags, DWORD count, + DMO_OUTPUT_DATA_BUFFER *buffers, DWORD *status) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %x, %d, %p, %p\n", This, flags, count, buffers, status); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediaobj_Lock(IMediaObject *iface, LONG lock) +{ + struct dmo_echofx *This = impl_from_IMediaObject(iface); + FIXME("%p, %d\n", This, lock); + return E_NOTIMPL; +} + +static const IMediaObjectVtbl echo_mediaobjectVtbl = +{ + echo_mediaobj_QueryInterface, + echo_mediaobj_AddRef, + echo_mediaobj_Release, + echo_mediaobj_GetStreamCount, + echo_mediaobj_GetInputStreamInfo, + echo_mediaobj_GetOutputStreamInfo, + echo_mediaobj_GetInputType, + echo_mediaobj_GetOutputType, + echo_mediaobj_SetInputType, + echo_mediaobj_SetOutputType, + echo_mediaobj_GetInputCurrentType, + echo_mediaobj_GetOutputCurrentType, + echo_mediaobj_GetInputSizeInfo, + echo_mediaobj_GetOutputSizeInfo, + echo_mediaobj_GetInputMaxLatency, + echo_mediaobj_SetInputMaxLatency, + echo_mediaobj_Flush, + echo_mediaobj_Discontinuity, + echo_mediaobj_AllocateStreamingResources, + echo_mediaobj_FreeStreamingResources, + echo_mediaobj_GetInputStatus, + echo_mediaobj_ProcessInput, + echo_mediaobj_ProcessOutput, + echo_mediaobj_Lock +}; + +static HRESULT WINAPI echo_mediainplace_QueryInterface(IMediaObjectInPlace *iface, REFIID riid, void **obj) +{ + struct dmo_echofx *This = impl_from_IMediaObjectInPlace(iface); + return IDirectSoundFXEcho_QueryInterface(&This->IDirectSoundFXEcho_iface, riid, obj); +} + +static ULONG WINAPI echo_mediainplace_AddRef(IMediaObjectInPlace *iface) +{ + struct dmo_echofx *This = impl_from_IMediaObjectInPlace(iface); + return IDirectSoundFXEcho_AddRef(&This->IDirectSoundFXEcho_iface); +} + +static ULONG WINAPI echo_mediainplace_Release(IMediaObjectInPlace *iface) +{ + struct dmo_echofx *This = impl_from_IMediaObjectInPlace(iface); + return IDirectSoundFXEcho_Release(&This->IDirectSoundFXEcho_iface); +} + +static HRESULT WINAPI echo_mediainplace_Process(IMediaObjectInPlace *iface, ULONG size, BYTE *data, REFERENCE_TIME start, DWORD flags) +{ + struct dmo_echofx *This = impl_from_IMediaObjectInPlace(iface); + static BOOL once = 0; + if(!once++) + FIXME("%p, %d, %p, %s, %x\n", This, size, data, wine_dbgstr_longlong(start), flags); + else + TRACE("%p, %d, %p, %s, %x\n", This, size, data, wine_dbgstr_longlong(start), flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediainplace_Clone(IMediaObjectInPlace *iface, IMediaObjectInPlace **object) +{ + struct dmo_echofx *This = impl_from_IMediaObjectInPlace(iface); + FIXME("%p, %p\n", This, object); + return E_NOTIMPL; +} + +static HRESULT WINAPI echo_mediainplace_GetLatency(IMediaObjectInPlace *iface, REFERENCE_TIME *latency) +{ + struct dmo_echofx *This = impl_from_IMediaObjectInPlace(iface); + FIXME("%p, %p\n", This, latency); + return E_NOTIMPL; +} + +static const IMediaObjectInPlaceVtbl echo_mediainplaceVtbl = +{ + echo_mediainplace_QueryInterface, + echo_mediainplace_AddRef, + echo_mediainplace_Release, + echo_mediainplace_Process, + echo_mediainplace_Clone, + echo_mediainplace_GetLatency +}; + +static HRESULT WINAPI echofx_QueryInterface(IDirectSoundFXEcho *iface, REFIID riid, void **ppv) +{ + struct dmo_echofx *This = impl_from_IDirectSoundFXEcho(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IDirectSoundFXEcho)) + { + *ppv = &This->IDirectSoundFXEcho_iface; + } + else if(IsEqualGUID(riid, &IID_IMediaObject)) + { + *ppv = &This->IMediaObject_iface; + } + else if(IsEqualGUID(riid, &IID_IMediaObjectInPlace)) + { + *ppv = &This->IMediaObjectInPlace_iface; + } + + if(!*ppv) + { + FIXME("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppv); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + + return S_OK; +} + +static ULONG WINAPI echofx_AddRef(IDirectSoundFXEcho *iface) +{ + struct dmo_echofx *This = impl_from_IDirectSoundFXEcho(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%u\n", This, ref); + + return ref; +} + +static ULONG WINAPI echofx_Release(IDirectSoundFXEcho *iface) +{ + struct dmo_echofx *This = impl_from_IDirectSoundFXEcho(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%u\n", This, ref); + + if (!ref) + { + heap_free(This); + } + return ref; +} + +static HRESULT WINAPI echofx_SetAllParameters(IDirectSoundFXEcho *iface, const DSFXEcho *echo) +{ + struct dmo_echofx *This = impl_from_IDirectSoundFXEcho(iface); + FIXME("(%p) %p\n", This, echo); + + return E_NOTIMPL; +} + +static HRESULT WINAPI echofx_GetAllParameters(IDirectSoundFXEcho *iface, DSFXEcho *echo) +{ + struct dmo_echofx *This = impl_from_IDirectSoundFXEcho(iface); + FIXME("(%p) %p\n", This, echo); + + return E_NOTIMPL; +} + +static const struct IDirectSoundFXEchoVtbl echofxVtbl = +{ + echofx_QueryInterface, + echofx_AddRef, + echofx_Release, + echofx_SetAllParameters, + echofx_GetAllParameters +}; + +HRESULT WINAPI EchoFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv) +{ + struct dmo_echofx *object; + HRESULT ret; + + TRACE("(%p, %s, %p)\n", outer, debugstr_guid(riid), ppv); + + *ppv = NULL; + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->IDirectSoundFXEcho_iface.lpVtbl = &echofxVtbl; + object->IMediaObject_iface.lpVtbl = &echo_mediaobjectVtbl; + object->IMediaObjectInPlace_iface.lpVtbl = &echo_mediainplaceVtbl; + object->ref = 1; + + ret = echofx_QueryInterface(&object->IDirectSoundFXEcho_iface, riid, ppv); + echofx_Release(&object->IDirectSoundFXEcho_iface); + + return ret; +} diff --git a/dlls/dsdmo/main.c b/dlls/dsdmo/main.c index 61a67f44d8..d751f90dc9 100644 --- a/dlls/dsdmo/main.c +++ b/dlls/dsdmo/main.c @@ -17,10 +17,12 @@ */ #define COBJMACROS
+#include "windows.h" #include "ole2.h" #include "rpcproxy.h"
-#include "wine/debug.h" +#include "initguid.h" +#include "dsdmo_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dsdmo);
@@ -49,11 +51,64 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) return TRUE; }
+static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) +{ + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) { + *ppv = iface; + } + + if(*ppv) { + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + } + + WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv); + return E_NOINTERFACE; +} + +static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface) +{ + TRACE("(%p)\n", iface); + return 2; +} + +static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) +{ + TRACE("(%p)\n", iface); + return 1; +} + +static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock) +{ + TRACE("(%p)->(%x)\n", iface, fLock); + return S_OK; +} + +static const IClassFactoryVtbl EchoFactoryVtbl = { + ClassFactory_QueryInterface, + ClassFactory_AddRef, + ClassFactory_Release, + EchoFactory_CreateInstance, + ClassFactory_LockServer +}; + +static IClassFactory echofx_factory = { &EchoFactoryVtbl }; + /*********************************************************************** * DllGetClassObject */ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { + TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); + + if(IsEqualGUID(&GUID_DSFX_STANDARD_ECHO, rclsid)) + { + TRACE("GUID_DSFX_STANDARD_ECHO\n"); + return IClassFactory_QueryInterface(&echofx_factory, riid, ppv); + } + FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); return CLASS_E_CLASSNOTAVAILABLE; }