From 9f3467c174f386eba9118c80403502aab1feb0fc Mon Sep 17 00:00:00 2001 From: Dmitry Chapyshev Date: Tue, 24 Mar 2009 11:17:08 +0000 Subject: [PATCH] - Replace stub qedit on qedit from Wine svn path=/trunk/; revision=40206 --- reactos/dll/directx/qedit/main.c | 184 ++++++ reactos/dll/directx/qedit/mediadet.c | 610 ++++++++++++++++++ reactos/dll/directx/qedit/qedit.rbuild | 20 +- reactos/dll/directx/qedit/qedit.rc | 9 - .../qedit/{qedit.c => qedit_private.h} | 50 +- reactos/dll/directx/qedit/regsvr.c | 324 ++++++++++ 6 files changed, 1151 insertions(+), 46 deletions(-) create mode 100644 reactos/dll/directx/qedit/main.c create mode 100644 reactos/dll/directx/qedit/mediadet.c delete mode 100644 reactos/dll/directx/qedit/qedit.rc rename reactos/dll/directx/qedit/{qedit.c => qedit_private.h} (54%) create mode 100644 reactos/dll/directx/qedit/regsvr.c diff --git a/reactos/dll/directx/qedit/main.c b/reactos/dll/directx/qedit/main.c new file mode 100644 index 00000000000..df00137647b --- /dev/null +++ b/reactos/dll/directx/qedit/main.c @@ -0,0 +1,184 @@ +/* DirectShow Editing Services (qedit.dll) + * + * Copyright 2008 Google (Lei Zhang) + * + * 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 + */ + +#include "qedit_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(qedit); + +BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) +{ + switch(fdwReason) { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hInstDLL); + break; + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + +/****************************************************************************** + * DirectShow ClassFactory + */ +typedef struct { + IClassFactory ITF_IClassFactory; + + LONG ref; + HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); +} IClassFactoryImpl; + +struct object_creation_info +{ + const CLSID *clsid; + HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); +}; + +static const struct object_creation_info object_creation[] = +{ + { &CLSID_MediaDet, MediaDet_create }, +}; + +static HRESULT WINAPI +DSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IClassFactory)) + { + IClassFactory_AddRef(iface); + *ppobj = This; + return S_OK; + } + + *ppobj = NULL; + WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); + return E_NOINTERFACE; +} + +static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + ULONG ref = InterlockedDecrement(&This->ref); + + if (ref == 0) + CoTaskMemFree(This); + + return ref; +} + +static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + HRESULT hres; + LPUNKNOWN punk; + + TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); + + *ppobj = NULL; + hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk); + if (SUCCEEDED(hres)) { + hres = IUnknown_QueryInterface(punk, riid, ppobj); + IUnknown_Release(punk); + } + return hres; +} + +static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + FIXME("(%p)->(%d),stub!\n",This,dolock); + return S_OK; +} + +static const IClassFactoryVtbl DSCF_Vtbl = +{ + DSCF_QueryInterface, + DSCF_AddRef, + DSCF_Release, + DSCF_CreateInstance, + DSCF_LockServer +}; + + +/*********************************************************************** + * DllCanUnloadNow (QEDIT.@) + */ +HRESULT WINAPI DllCanUnloadNow(void) +{ + return S_OK; +} + +/******************************************************************************* + * DllGetClassObject [QEDIT.@] + * Retrieves class object from a DLL object + * + * PARAMS + * rclsid [I] CLSID for the class object + * riid [I] Reference to identifier of interface for class object + * ppv [O] Address of variable to receive interface pointer for riid + * + * RETURNS + * Success: S_OK + * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG, + * E_UNEXPECTED, E_NOINTERFACE + */ + +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +{ + unsigned int i; + IClassFactoryImpl *factory; + + TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); + + if ( !IsEqualGUID( &IID_IClassFactory, riid ) + && ! IsEqualGUID( &IID_IUnknown, riid) ) + return E_NOINTERFACE; + + for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) + { + if (IsEqualGUID(object_creation[i].clsid, rclsid)) + break; + } + + if (i == sizeof(object_creation)/sizeof(object_creation[0])) + { + FIXME("%s: no class found.\n", debugstr_guid(rclsid)); + return CLASS_E_CLASSNOTAVAILABLE; + } + + factory = CoTaskMemAlloc(sizeof(*factory)); + if (factory == NULL) return E_OUTOFMEMORY; + + factory->ITF_IClassFactory.lpVtbl = &DSCF_Vtbl; + factory->ref = 1; + + factory->pfnCreateInstance = object_creation[i].pfnCreateInstance; + + *ppv = &(factory->ITF_IClassFactory); + return S_OK; +} diff --git a/reactos/dll/directx/qedit/mediadet.c b/reactos/dll/directx/qedit/mediadet.c new file mode 100644 index 00000000000..2cf37f96a88 --- /dev/null +++ b/reactos/dll/directx/qedit/mediadet.c @@ -0,0 +1,610 @@ +/* DirectShow Media Detector object (QEDIT.DLL) + * + * Copyright 2008 Google (Lei Zhang, Dan Hipschman) + * + * 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 + */ + +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "ole2.h" + +#include "qedit_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(qedit); + +typedef struct MediaDetImpl { + const IMediaDetVtbl *MediaDet_Vtbl; + LONG refCount; + IGraphBuilder *graph; + IBaseFilter *source; + IBaseFilter *splitter; + long num_streams; + long cur_stream; + IPin *cur_pin; +} MediaDetImpl; + +static void MD_cleanup(MediaDetImpl *This) +{ + if (This->cur_pin) IPin_Release(This->cur_pin); + This->cur_pin = NULL; + if (This->source) IBaseFilter_Release(This->source); + This->source = NULL; + if (This->splitter) IBaseFilter_Release(This->splitter); + This->splitter = NULL; + if (This->graph) IGraphBuilder_Release(This->graph); + This->graph = NULL; + This->num_streams = -1; + This->cur_stream = 0; +} + +static ULONG WINAPI MediaDet_AddRef(IMediaDet* iface) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->refCount); + TRACE("(%p)->() AddRef from %d\n", This, refCount - 1); + return refCount; +} + +static ULONG WINAPI MediaDet_Release(IMediaDet* iface) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + ULONG refCount = InterlockedDecrement(&This->refCount); + TRACE("(%p)->() Release from %d\n", This, refCount + 1); + + if (refCount == 0) + { + MD_cleanup(This); + CoTaskMemFree(This); + return 0; + } + + return refCount; +} + +static HRESULT WINAPI MediaDet_QueryInterface(IMediaDet* iface, REFIID riid, + void **ppvObject) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IMediaDet)) { + MediaDet_AddRef(iface); + *ppvObject = This; + return S_OK; + } + *ppvObject = NULL; + WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppvObject); + return E_NOINTERFACE; +} + +static HRESULT WINAPI MediaDet_get_Filter(IMediaDet* iface, IUnknown **pVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + FIXME("(%p)->(%p): not implemented!\n", This, pVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI MediaDet_put_Filter(IMediaDet* iface, IUnknown *newVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + FIXME("(%p)->(%p): not implemented!\n", This, newVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI MediaDet_get_OutputStreams(IMediaDet* iface, long *pVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + IEnumPins *pins; + IPin *pin; + HRESULT hr; + + TRACE("(%p)\n", This); + + if (!This->splitter) + return E_INVALIDARG; + + if (This->num_streams != -1) + { + *pVal = This->num_streams; + return S_OK; + } + + *pVal = 0; + + hr = IBaseFilter_EnumPins(This->splitter, &pins); + if (FAILED(hr)) + return hr; + + while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) + { + PIN_DIRECTION dir; + hr = IPin_QueryDirection(pin, &dir); + IPin_Release(pin); + if (FAILED(hr)) + { + IEnumPins_Release(pins); + return hr; + } + + if (dir == PINDIR_OUTPUT) + ++*pVal; + } + IEnumPins_Release(pins); + + This->num_streams = *pVal; + return S_OK; +} + +static HRESULT WINAPI MediaDet_get_CurrentStream(IMediaDet* iface, long *pVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + TRACE("(%p)\n", This); + + if (!pVal) + return E_POINTER; + + *pVal = This->cur_stream; + return S_OK; +} + +static HRESULT SetCurPin(MediaDetImpl *This, long strm) +{ + IEnumPins *pins; + IPin *pin; + HRESULT hr; + + assert(This->splitter); + assert(0 <= strm && strm < This->num_streams); + + if (This->cur_pin) + { + IPin_Release(This->cur_pin); + This->cur_pin = NULL; + } + + hr = IBaseFilter_EnumPins(This->splitter, &pins); + if (FAILED(hr)) + return hr; + + while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK && !This->cur_pin) + { + PIN_DIRECTION dir; + hr = IPin_QueryDirection(pin, &dir); + if (FAILED(hr)) + { + IPin_Release(pin); + IEnumPins_Release(pins); + return hr; + } + + if (dir == PINDIR_OUTPUT && strm-- == 0) + This->cur_pin = pin; + else + IPin_Release(pin); + } + IEnumPins_Release(pins); + + assert(This->cur_pin); + return S_OK; +} + +static HRESULT WINAPI MediaDet_put_CurrentStream(IMediaDet* iface, long newVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + HRESULT hr; + + TRACE("(%p)->(%ld)\n", This, newVal); + + if (This->num_streams == -1) + { + long n; + hr = MediaDet_get_OutputStreams(iface, &n); + if (FAILED(hr)) + return hr; + } + + if (newVal < 0 || This->num_streams <= newVal) + return E_INVALIDARG; + + hr = SetCurPin(This, newVal); + if (FAILED(hr)) + return hr; + + This->cur_stream = newVal; + return S_OK; +} + +static HRESULT WINAPI MediaDet_get_StreamType(IMediaDet* iface, GUID *pVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + FIXME("(%p)->(%p): not implemented!\n", This, debugstr_guid(pVal)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MediaDet_get_StreamTypeB(IMediaDet* iface, BSTR *pVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + FIXME("(%p)->(%p): not implemented!\n", This, pVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI MediaDet_get_StreamLength(IMediaDet* iface, double *pVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + FIXME("(%p): stub!\n", This); + return VFW_E_INVALIDMEDIATYPE; +} + +static HRESULT WINAPI MediaDet_get_Filename(IMediaDet* iface, BSTR *pVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + IFileSourceFilter *file; + LPOLESTR name; + HRESULT hr; + + TRACE("(%p)\n", This); + + if (!pVal) + return E_POINTER; + + *pVal = NULL; + /* MSDN says it should return E_FAIL if no file is open, but tests + show otherwise. */ + if (!This->source) + return S_OK; + + hr = IBaseFilter_QueryInterface(This->source, &IID_IFileSourceFilter, + (void **) &file); + if (FAILED(hr)) + return hr; + + hr = IFileSourceFilter_GetCurFile(file, &name, NULL); + IFileSourceFilter_Release(file); + if (FAILED(hr)) + return hr; + + *pVal = SysAllocString(name); + CoTaskMemFree(name); + if (!*pVal) + return E_OUTOFMEMORY; + + return S_OK; +} + +/* From quartz, 2008/04/07 */ +static HRESULT GetFilterInfo(IMoniker *pMoniker, GUID *pclsid, VARIANT *pvar) +{ + static const WCHAR wszClsidName[] = {'C','L','S','I','D',0}; + static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; + IPropertyBag *pPropBagCat = NULL; + HRESULT hr; + + VariantInit(pvar); + V_VT(pvar) = VT_BSTR; + + hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, + (LPVOID *) &pPropBagCat); + + if (SUCCEEDED(hr)) + hr = IPropertyBag_Read(pPropBagCat, wszClsidName, pvar, NULL); + + if (SUCCEEDED(hr)) + hr = CLSIDFromString(V_UNION(pvar, bstrVal), pclsid); + + if (SUCCEEDED(hr)) + hr = IPropertyBag_Read(pPropBagCat, wszFriendlyName, pvar, NULL); + + if (SUCCEEDED(hr)) + TRACE("Moniker = %s - %s\n", debugstr_guid(pclsid), + debugstr_w(V_UNION(pvar, bstrVal))); + + if (pPropBagCat) + IPropertyBag_Release(pPropBagCat); + + return hr; +} + +static HRESULT GetSplitter(MediaDetImpl *This) +{ + IFileSourceFilter *file; + LPOLESTR name; + AM_MEDIA_TYPE mt; + GUID type[2]; + IFilterMapper2 *map; + IEnumMoniker *filters; + IMoniker *mon; + VARIANT var; + GUID clsid; + IBaseFilter *splitter; + IEnumPins *pins; + IPin *source_pin, *splitter_pin; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterMapper2, (void **) &map); + if (FAILED(hr)) + return hr; + + hr = IBaseFilter_QueryInterface(This->source, &IID_IFileSourceFilter, + (void **) &file); + if (FAILED(hr)) + { + IFilterMapper2_Release(map); + return hr; + } + + hr = IFileSourceFilter_GetCurFile(file, &name, &mt); + IFileSourceFilter_Release(file); + CoTaskMemFree(name); + if (FAILED(hr)) + { + IFilterMapper2_Release(map); + return hr; + } + type[0] = mt.majortype; + type[1] = mt.subtype; + CoTaskMemFree(mt.pbFormat); + + hr = IFilterMapper2_EnumMatchingFilters(map, &filters, 0, TRUE, + MERIT_UNLIKELY, FALSE, 1, type, + NULL, NULL, FALSE, TRUE, + 0, NULL, NULL, NULL); + IFilterMapper2_Release(map); + if (FAILED(hr)) + return hr; + + hr = IEnumMoniker_Next(filters, 1, &mon, NULL); + IEnumMoniker_Release(filters); + if (hr != S_OK) /* No matches, what do we do? */ + return E_NOINTERFACE; + + hr = GetFilterInfo(mon, &clsid, &var); + IMoniker_Release(mon); + if (FAILED(hr)) + return hr; + + hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **) &splitter); + if (FAILED(hr)) + return hr; + + hr = IGraphBuilder_AddFilter(This->graph, splitter, + V_UNION(&var, bstrVal)); + if (FAILED(hr)) + { + IBaseFilter_Release(splitter); + return hr; + } + This->splitter = splitter; + + hr = IBaseFilter_EnumPins(This->source, &pins); + if (FAILED(hr)) + return hr; + IEnumPins_Next(pins, 1, &source_pin, NULL); + IEnumPins_Release(pins); + + hr = IBaseFilter_EnumPins(splitter, &pins); + if (FAILED(hr)) + { + IPin_Release(source_pin); + return hr; + } + IEnumPins_Next(pins, 1, &splitter_pin, NULL); + IEnumPins_Release(pins); + + hr = IPin_Connect(source_pin, splitter_pin, NULL); + IPin_Release(source_pin); + IPin_Release(splitter_pin); + if (FAILED(hr)) + return hr; + + return S_OK; +} + +static HRESULT WINAPI MediaDet_put_Filename(IMediaDet* iface, BSTR newVal) +{ + static const WCHAR reader[] = {'R','e','a','d','e','r',0}; + MediaDetImpl *This = (MediaDetImpl *)iface; + IGraphBuilder *gb; + IBaseFilter *bf; + HRESULT hr; + + TRACE("(%p)->(%s)\n", This, debugstr_w(newVal)); + + if (This->graph) + { + WARN("MSDN says not to call this method twice\n"); + MD_cleanup(This); + } + + hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, + &IID_IGraphBuilder, (void **) &gb); + if (FAILED(hr)) + return hr; + + hr = IGraphBuilder_AddSourceFilter(gb, newVal, reader, &bf); + if (FAILED(hr)) + { + IGraphBuilder_Release(gb); + return hr; + } + + This->graph = gb; + This->source = bf; + hr = GetSplitter(This); + if (FAILED(hr)) + return hr; + + return MediaDet_put_CurrentStream(iface, 0); +} + +static HRESULT WINAPI MediaDet_GetBitmapBits(IMediaDet* iface, + double StreamTime, + long *pBufferSize, char *pBuffer, + long Width, long Height) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + FIXME("(%p)->(%f %p %p %ld %ld): not implemented!\n", This, StreamTime, pBufferSize, pBuffer, + Width, Height); + return E_NOTIMPL; +} + +static HRESULT WINAPI MediaDet_WriteBitmapBits(IMediaDet* iface, + double StreamTime, long Width, + long Height, BSTR Filename) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + FIXME("(%p)->(%f %ld %ld %p): not implemented!\n", This, StreamTime, Width, Height, Filename); + return E_NOTIMPL; +} + +static HRESULT WINAPI MediaDet_get_StreamMediaType(IMediaDet* iface, + AM_MEDIA_TYPE *pVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + IEnumMediaTypes *types; + AM_MEDIA_TYPE *pmt; + HRESULT hr; + + TRACE("(%p)\n", This); + + if (!pVal) + return E_POINTER; + + if (!This->cur_pin) + return E_INVALIDARG; + + hr = IPin_EnumMediaTypes(This->cur_pin, &types); + if (SUCCEEDED(hr)) + { + hr = (IEnumMediaTypes_Next(types, 1, &pmt, NULL) == S_OK + ? S_OK + : E_NOINTERFACE); + IEnumMediaTypes_Release(types); + } + + if (SUCCEEDED(hr)) + { + *pVal = *pmt; + CoTaskMemFree(pmt); + } + + return hr; +} + +static HRESULT WINAPI MediaDet_GetSampleGrabber(IMediaDet* iface, + ISampleGrabber **ppVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + FIXME("(%p)->(%p): not implemented!\n", This, ppVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI MediaDet_get_FrameRate(IMediaDet* iface, double *pVal) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + AM_MEDIA_TYPE mt; + VIDEOINFOHEADER *vh; + HRESULT hr; + + TRACE("(%p)\n", This); + + if (!pVal) + return E_POINTER; + + hr = MediaDet_get_StreamMediaType(iface, &mt); + if (FAILED(hr)) + return hr; + + if (!IsEqualGUID(&mt.majortype, &MEDIATYPE_Video)) + { + CoTaskMemFree(mt.pbFormat); + return VFW_E_INVALIDMEDIATYPE; + } + + vh = (VIDEOINFOHEADER *) mt.pbFormat; + *pVal = 1.0e7 / (double) vh->AvgTimePerFrame; + + CoTaskMemFree(mt.pbFormat); + return S_OK; +} + +static HRESULT WINAPI MediaDet_EnterBitmapGrabMode(IMediaDet* iface, + double SeekTime) +{ + MediaDetImpl *This = (MediaDetImpl *)iface; + FIXME("(%p)->(%f): not implemented!\n", This, SeekTime); + return E_NOTIMPL; +} + +static const IMediaDetVtbl IMediaDet_VTable = +{ + MediaDet_QueryInterface, + MediaDet_AddRef, + MediaDet_Release, + MediaDet_get_Filter, + MediaDet_put_Filter, + MediaDet_get_OutputStreams, + MediaDet_get_CurrentStream, + MediaDet_put_CurrentStream, + MediaDet_get_StreamType, + MediaDet_get_StreamTypeB, + MediaDet_get_StreamLength, + MediaDet_get_Filename, + MediaDet_put_Filename, + MediaDet_GetBitmapBits, + MediaDet_WriteBitmapBits, + MediaDet_get_StreamMediaType, + MediaDet_GetSampleGrabber, + MediaDet_get_FrameRate, + MediaDet_EnterBitmapGrabMode, +}; + +HRESULT MediaDet_create(IUnknown * pUnkOuter, LPVOID * ppv) { + MediaDetImpl* obj = NULL; + + TRACE("(%p,%p)\n", ppv, pUnkOuter); + + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + obj = CoTaskMemAlloc(sizeof(MediaDetImpl)); + if (NULL == obj) { + *ppv = NULL; + return E_OUTOFMEMORY; + } + ZeroMemory(obj, sizeof(MediaDetImpl)); + + obj->refCount = 1; + obj->MediaDet_Vtbl = &IMediaDet_VTable; + obj->graph = NULL; + obj->source = NULL; + obj->splitter = NULL; + obj->cur_pin = NULL; + obj->num_streams = -1; + obj->cur_stream = 0; + *ppv = obj; + + return S_OK; +} diff --git a/reactos/dll/directx/qedit/qedit.rbuild b/reactos/dll/directx/qedit/qedit.rbuild index 222417aec07..4d08625d79f 100644 --- a/reactos/dll/directx/qedit/qedit.rbuild +++ b/reactos/dll/directx/qedit/qedit.rbuild @@ -1,13 +1,19 @@ - - - - + + . + include/reactos/wine + 0x600 + + main.c + mediadet.c + regsvr.c + wine + strmiids + uuid + oleaut32 + ole32 advapi32 kernel32 ntdll - qedit.c - qedit.rc - diff --git a/reactos/dll/directx/qedit/qedit.rc b/reactos/dll/directx/qedit/qedit.rc deleted file mode 100644 index 13f08869f03..00000000000 --- a/reactos/dll/directx/qedit/qedit.rc +++ /dev/null @@ -1,9 +0,0 @@ - -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS DirectShow Editing\0" -#define REACTOS_STR_INTERNAL_NAME "qedit\0" -#define REACTOS_STR_ORIGINAL_FILENAME "qedit.dll\0" - -#include - -#include diff --git a/reactos/dll/directx/qedit/qedit.c b/reactos/dll/directx/qedit/qedit_private.h similarity index 54% rename from reactos/dll/directx/qedit/qedit.c rename to reactos/dll/directx/qedit/qedit_private.h index 9d0a057b9b4..87bcab012fe 100644 --- a/reactos/dll/directx/qedit/qedit.c +++ b/reactos/dll/directx/qedit/qedit_private.h @@ -1,7 +1,9 @@ -/* - * QEDIT.DLL - ReactOS DirectShow Editing +/* DirectShow Editing Services (qedit.dll) * - * Copyright 2008 Dmitry Chapyshev + * Copyright 2008 Google (Lei Zhang) + * + * This file contains the (internal) driver registration functions, + * driver enumeration APIs and DirectDraw creation functions. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,34 +20,22 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include -#include -#include -#include +#ifndef __QEDIT_PRIVATE_INCLUDED__ +#define __QEDIT_PRIVATE_INCLUDED__ -HRESULT WINAPI -DllCanUnloadNow(void) -{ - return S_OK; -} +#include -HRESULT WINAPI -DllGetClassObject( - REFCLSID rclsid, - REFIID riid, - LPVOID *ppv) -{ - return S_OK; -} +#define COBJMACROS -HRESULT WINAPI -DllRegisterServer(void) -{ - return S_OK; -} +#include "windef.h" +#include "winbase.h" +#include "wtypes.h" +#include "wingdi.h" +#include "winuser.h" +#include "dshow.h" +#define __WINE_DDRAW_H /* ROS HACK */ +#include "qedit.h" -HRESULT WINAPI -DllUnregisterServer(void) -{ - return S_OK; -} +HRESULT MediaDet_create(IUnknown *pUnkOuter, LPVOID *ppObj); + +#endif /* __QEDIT_PRIVATE_INCLUDED__ */ diff --git a/reactos/dll/directx/qedit/regsvr.c b/reactos/dll/directx/qedit/regsvr.c new file mode 100644 index 00000000000..9ff18528523 --- /dev/null +++ b/reactos/dll/directx/qedit/regsvr.c @@ -0,0 +1,324 @@ +/* + * self-registerable dll functions for qedit.dll + * + * Copyright (C) 2008 Google (Lei Zhang) + * + * 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 + */ + +#include "qedit_private.h" +#include "winreg.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(qedit); + +struct regsvr_coclass +{ + CLSID const *clsid; /* NULL for end of list */ + LPCSTR name; /* can be NULL to omit */ + LPCSTR ips; /* can be NULL to omit */ + LPCSTR ips32; /* can be NULL to omit */ + LPCSTR ips32_tmodel; /* can be NULL to omit */ + LPCSTR progid; /* can be NULL to omit */ + LPCSTR viprogid; /* can be NULL to omit */ + LPCSTR progid_extra; /* can be NULL to omit */ +}; + +static HRESULT register_coclasses(struct regsvr_coclass const *list); +static HRESULT unregister_coclasses(struct regsvr_coclass const *list); + +/*********************************************************************** + * static string constants + */ +static WCHAR const clsid_keyname[6] = { + 'C', 'L', 'S', 'I', 'D', 0 }; +static WCHAR const curver_keyname[7] = { + 'C', 'u', 'r', 'V', 'e', 'r', 0 }; +static WCHAR const ips_keyname[13] = { + 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', 0 }; +static WCHAR const ips32_keyname[15] = { + 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', '3', '2', 0 }; +static WCHAR const progid_keyname[7] = { + 'P', 'r', 'o', 'g', 'I', 'D', 0 }; +static WCHAR const viprogid_keyname[25] = { + 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p', + 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D', + 0 }; +static char const tmodel_valuename[] = "ThreadingModel"; + +/*********************************************************************** + * static helper functions + */ +static LONG register_key_defvalueW(HKEY base, WCHAR const *name, + WCHAR const *value); +static LONG register_key_defvalueA(HKEY base, WCHAR const *name, + char const *value); +static LONG register_progid(WCHAR const *clsid, + char const *progid, char const *curver_progid, + char const *name, char const *extra); + + + +/*********************************************************************** + * register_coclasses + */ +static HRESULT register_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + HKEY clsid_key; + + StringFromGUID2(list->clsid, buf, 39); + res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + if (list->name) { + res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ, + (CONST BYTE*)(list->name), + strlen(list->name) + 1); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->ips) { + res = register_key_defvalueA(clsid_key, ips_keyname, list->ips); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->ips32) { + HKEY ips32_key; + + res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, + &ips32_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ, + (CONST BYTE*)list->ips32, + lstrlenA(list->ips32) + 1); + if (res == ERROR_SUCCESS && list->ips32_tmodel) + res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ, + (CONST BYTE*)list->ips32_tmodel, + strlen(list->ips32_tmodel) + 1); + RegCloseKey(ips32_key); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->progid) { + res = register_key_defvalueA(clsid_key, progid_keyname, + list->progid); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = register_progid(buf, list->progid, NULL, + list->name, list->progid_extra); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->viprogid) { + res = register_key_defvalueA(clsid_key, viprogid_keyname, + list->viprogid); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = register_progid(buf, list->viprogid, list->progid, + list->name, list->progid_extra); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + +error_close_clsid_key: + RegCloseKey(clsid_key); + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * unregister_coclasses + */ +static HRESULT unregister_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, + KEY_READ | KEY_WRITE, &coclass_key); + if (res == ERROR_FILE_NOT_FOUND) return S_OK; + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + + StringFromGUID2(list->clsid, buf, 39); + res = RegDeleteTreeW(coclass_key, buf); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + if (list->progid) { + res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + + if (list->viprogid) { + res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * regsvr_key_defvalueW + */ +static LONG register_key_defvalueW( + HKEY base, + WCHAR const *name, + WCHAR const *value) +{ + LONG res; + HKEY key; + + res = RegCreateKeyExW(base, name, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) return res; + res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value, + (lstrlenW(value) + 1) * sizeof(WCHAR)); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * regsvr_key_defvalueA + */ +static LONG register_key_defvalueA( + HKEY base, + WCHAR const *name, + char const *value) +{ + LONG res; + HKEY key; + + res = RegCreateKeyExW(base, name, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) return res; + res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value, + lstrlenA(value) + 1); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * regsvr_progid + */ +static LONG register_progid( + WCHAR const *clsid, + char const *progid, + char const *curver_progid, + char const *name, + char const *extra) +{ + LONG res; + HKEY progid_key; + + res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0, + NULL, 0, KEY_READ | KEY_WRITE, NULL, + &progid_key, NULL); + if (res != ERROR_SUCCESS) return res; + + if (name) { + res = RegSetValueExA(progid_key, NULL, 0, REG_SZ, + (CONST BYTE*)name, strlen(name) + 1); + if (res != ERROR_SUCCESS) goto error_close_progid_key; + } + + if (clsid) { + res = register_key_defvalueW(progid_key, clsid_keyname, clsid); + if (res != ERROR_SUCCESS) goto error_close_progid_key; + } + + if (curver_progid) { + res = register_key_defvalueA(progid_key, curver_keyname, + curver_progid); + if (res != ERROR_SUCCESS) goto error_close_progid_key; + } + + if (extra) { + HKEY extra_key; + + res = RegCreateKeyExA(progid_key, extra, 0, + NULL, 0, KEY_READ | KEY_WRITE, NULL, + &extra_key, NULL); + if (res == ERROR_SUCCESS) + RegCloseKey(extra_key); + } + +error_close_progid_key: + RegCloseKey(progid_key); + return res; +} + +/*********************************************************************** + * coclass list + */ +static struct regsvr_coclass const coclass_list[] = { + { &CLSID_MediaDet, + "MediaDet", + NULL, + "qedit.dll", + "Both" + }, + { NULL } /* list terminator */ +}; + +/*********************************************************************** + * DllRegisterServer (QEDIT.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + HRESULT hr; + + TRACE("\n"); + + hr = register_coclasses(coclass_list); + return hr; +} + +/*********************************************************************** + * DllUnregisterServer (QEDIT.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + HRESULT hr; + + TRACE("\n"); + + hr = unregister_coclasses(coclass_list); + return S_OK; +}