Commit 836b7df6 authored by Rolf Kalbermatter's avatar Rolf Kalbermatter Committed by Alexandre Julliard

Implement DLL registering and unregistering functions, class factory

and server locking based on how it is done with DirectX samples.
parent ce8c9426
......@@ -3,8 +3,12 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = qcap.dll
IMPORTS = ole32 oleaut32 user32 advapi32 kernel32
EXTRALIBS = -lstrmiids -luuid $(LIBUNICODE)
C_SRCS = qcap_main.c
C_SRCS = \
dllsetup.c \
qcap_main.c
RC_SRCS = version.rc
......
/*
* DirectX DLL registration and unregistration
*
* Copyright (C) 2005 Rolf Kalbermatter
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <stdarg.h>
#include <assert.h>
#define COBJMACROS
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winreg.h"
#include "objbase.h"
#include "uuids.h"
#include "dllsetup.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(qcap);
/*
* defines and constants
*/
#define MAX_KEY_LEN 260
static WCHAR const clsid_keyname[6] =
{'C','L','S','I','D',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 tmodel_keyname[15] =
{'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0};
static WCHAR const tmodel_both[] =
{'B','o','t','h',0};
/*
* Delete a key and all its subkeys
*/
HRESULT DeleteEntireSubKey(HKEY hkey, LPWSTR strSubKey)
{
WCHAR buffer[MAX_KEY_LEN];
DWORD dw = MAX_KEY_LEN;
FILETIME ft;
HKEY hk;
LONG ret = RegOpenKeyExW(hkey, strSubKey, 0, MAXIMUM_ALLOWED, &hk);
if (ERROR_SUCCESS == ret)
{
/* Keep on enumerating the first key and deleting that */
for( ; ; )
{
dw = MAX_KEY_LEN;
ret = RegEnumKeyExW(hk, 0, buffer, &dw, NULL, NULL, NULL, &ft);
if (ERROR_SUCCESS == ret)
DeleteEntireSubKey(hk, buffer);
else
break;
}
RegCloseKey(hk);
RegDeleteKeyW(hkey, strSubKey);
}
return NOERROR;
}
/*
* SetupRegisterClass()
*/
static HRESULT SetupRegisterClass(HKEY clsid, LPCWSTR szCLSID,
LPCWSTR szDescription,
LPCWSTR szFileName,
LPCWSTR szServerType,
LPCWSTR szThreadingModel)
{
HKEY hkey, hsubkey;
LONG ret = RegCreateKeyW(clsid, szCLSID, &hkey);
if (ERROR_SUCCESS != ret)
return HRESULT_FROM_WIN32(ret);
/* set description string */
ret = RegSetValueW(hkey, NULL, REG_SZ, szDescription,
sizeof(WCHAR) * (lstrlenW(szDescription) + 1));
if (ERROR_SUCCESS != ret)
goto err_out;
/* create CLSID\\{"CLSID"}\\"ServerType" key, using key to CLSID\\{"CLSID"}
passed back by last call to RegCreateKeyW(). */
ret = RegCreateKeyW(hkey, szServerType, &hsubkey);
if (ERROR_SUCCESS != ret)
goto err_out;
/* set server path */
ret = RegSetValueW(hsubkey, NULL, REG_SZ, szFileName,
sizeof(WCHAR) * (lstrlenW(szFileName) + 1));
if (ERROR_SUCCESS != ret)
goto err_out;
/* set threading model */
ret = RegSetValueExW(hsubkey, tmodel_keyname, 0L, REG_SZ,
(const BYTE*)szThreadingModel,
sizeof(WCHAR) * (lstrlenW(szThreadingModel) + 1));
err_out:
if (hsubkey)
RegCloseKey(hsubkey);
RegCloseKey(hkey);
return HRESULT_FROM_WIN32(ret);
}
/*
* SetupRegisterFilter through IFilterMapper2
*/
static HRESULT SetupRegisterFilter2(const AMOVIESETUP_FILTER * const pSetup,
IFilterMapper2 * pIFM2, BOOL bRegister)
{
HRESULT hr;
if (NULL == pSetup)
return S_FALSE;
/* unregister filter */
hr = IFilterMapper2_UnregisterFilter(pIFM2, 0, 0, pSetup->clsID);
if (bRegister)
{
REGFILTER2 rf2;
rf2.dwVersion = 1;
rf2.dwMerit = pSetup->dwMerit;
rf2.u.s.cPins = pSetup->nPins;
rf2.u.s.rgPins = pSetup->lpPin;
/* register filter */
hr = IFilterMapper2_RegisterFilter(pIFM2, pSetup->clsID,
pSetup->strName, 0, 0, NULL, &rf2);
}
else
{
/* filter not found is ignored here,
but there is no #define for 0x80070002 */
if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
hr = NOERROR;
}
return hr;
}
/*
* SetupRegisterFilter through IFilterMapper
*/
static HRESULT SetupRegisterFilter(const AMOVIESETUP_FILTER * const pSetup,
IFilterMapper * pIFM, BOOL bRegister)
{
HRESULT hr;
if (NULL == pSetup)
return S_FALSE;
/* unregister filter */
hr = IFilterMapper_UnregisterFilter(pIFM, *pSetup->clsID);
if (bRegister)
{
/* register filter */
hr = IFilterMapper_RegisterFilter(pIFM, *pSetup->clsID,
pSetup->strName, pSetup->dwMerit);
if (SUCCEEDED(hr))
{
const AMOVIESETUP_PIN *lpPin = pSetup->lpPin;
const AMOVIESETUP_MEDIATYPE *lpType;
UINT i, j;
for (i = 0; i < pSetup->nPins; i++, lpPin++)
{
hr = IFilterMapper_RegisterPin(pIFM, *(pSetup->clsID),
lpPin->strName,
lpPin->bRendered,
lpPin->bOutput,
lpPin->bZero,
lpPin->bMany,
*(lpPin->clsConnectsToFilter),
lpPin->strConnectsToPin);
if (SUCCEEDED(hr))
{
lpType = lpPin->lpMediaType;
/* and each pin's media types */
for (j = 0; j < lpPin->nMediaTypes; j++, lpType++)
{
hr = IFilterMapper_RegisterPinType(pIFM, *(pSetup->clsID),
lpPin->strName,
*(lpType->clsMajorType),
*(lpType->clsMinorType));
if (FAILED(hr)) break;
}
if (FAILED(hr)) break;
}
if (FAILED(hr)) break;
}
}
}
else
{
/* filter not registered is ignored here, there is no definition for 0x80070002 */
if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
hr = NOERROR;
}
return hr;
}
/*
* RegisterAllClasses()
*/
static HRESULT SetupRegisterAllClasses(const CFactoryTemplate * pList, int num,
LPCWSTR szFileName, BOOL bRegister)
{
HRESULT hr = NOERROR;
HKEY hkey;
OLECHAR szCLSID[CHARS_IN_GUID];
LONG i, ret = RegCreateKeyW(HKEY_CLASSES_ROOT, clsid_keyname, &hkey);
if (ERROR_SUCCESS != ret)
return HRESULT_FROM_WIN32(ret);
for (i = 0; i < num; i++, pList++)
{
/* (un)register CLSID and InprocServer32 */
hr = StringFromGUID2(pList->m_ClsID, szCLSID, CHARS_IN_GUID);
if (SUCCEEDED(hr))
{
if (bRegister )
hr = SetupRegisterClass(hkey, szCLSID,
pList->m_Name, szFileName,
ips32_keyname, tmodel_both);
else
hr = DeleteEntireSubKey(hkey, szCLSID);
}
}
RegCloseKey(hkey);
return hr;
}
/****************************************************************************
* SetupRegisterServers
*
* This function is table driven using the static members of the
* CFactoryTemplate class defined in the Dll.
*
* It registers the Dll as the InprocServer32 for all the classes in
* CFactoryTemplate
*
****************************************************************************/
HRESULT SetupRegisterServers(const CFactoryTemplate * pList, int num,
HINSTANCE hinst, BOOL bRegister)
{
HRESULT hr = NOERROR;
WCHAR szFileName[MAX_PATH];
IFilterMapper2 *pIFM2 = NULL;
IFilterMapper *pIFM = NULL;
/* Win95 wouldn't support the Unicode version of this API!! */
if (!GetModuleFileNameW(hinst, szFileName, MAX_PATH))
return HRESULT_FROM_WIN32(GetLastError());
/* first register all server classes, just to make sure */
if (bRegister)
hr = SetupRegisterAllClasses(pList, num, szFileName, TRUE );
/* next, register/unregister all filters */
if (SUCCEEDED(hr))
{
hr = CoInitialize((LPVOID)NULL);
TRACE("Getting IFilterMapper2\r\n");
hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
&IID_IFilterMapper2, (void **)&pIFM2);
if (FAILED(hr))
{
TRACE("- trying IFilterMapper instead\r\n");
hr = CoCreateInstance(&CLSID_FilterMapper, NULL, CLSCTX_INPROC_SERVER,
&IID_IFilterMapper, (void **)&pIFM);
}
if (SUCCEEDED(hr))
{
int i;
/* scan through array of CFactoryTemplates registering all filters */
for (i = 0; i < num; i++, pList++)
{
if (NULL != pList->m_pAMovieSetup_Filter)
{
if (pIFM2)
hr = SetupRegisterFilter2(pList->m_pAMovieSetup_Filter,
pIFM2, bRegister);
else
hr = SetupRegisterFilter(pList->m_pAMovieSetup_Filter,
pIFM, bRegister);
}
/* check final error for this pass and break loop if we failed */
if (FAILED(hr))
break;
}
/* release interface */
if (pIFM2)
IFilterMapper2_Release(pIFM2);
else
IFilterMapper_Release(pIFM);
}
/* and clear up */
CoFreeUnusedLibraries();
CoUninitialize();
}
/* if unregistering, unregister all OLE servers */
if (SUCCEEDED(hr) && !bRegister)
hr = SetupRegisterAllClasses(pList, num, szFileName, FALSE);
return hr;
}
/****************************************************************************
* SetupInitializeServers
*
* This function is table driven using the static members of the
* CFactoryTemplate class defined in the Dll.
*
* It calls the intialize function for any class in CFactoryTemplate with
* one defined.
*
****************************************************************************/
void SetupInitializeServers(const CFactoryTemplate * pList, int num,
BOOL bLoading)
{
int i;
for (i = 0; i < num; i++, pList++)
{
pList->m_lpfnInit(bLoading, pList->m_ClsID);
}
}
/*
* DirectX DLL registration and unregistration
*
* Copyright (C) 2005 Rolf Kalbermatter
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _QCAP_DLLSETUP_H_DEFINED
#define _QCAP_DLLSETUP_H_DEFINED
#define COBJMACROS
#include "strmif.h"
/* Filter Setup data structures not defined in axextend.idl
They are not part of the standard SDK headers but come from the combase.h header
file in the DirectX Samples/Multimedia/BaseClasses */
typedef REGPINTYPES AMOVIESETUP_MEDIATYPE,
* PAMOVIESETUP_MEDIATYPE,
* LPAMOVIESETUP_MEDIATYPE;
typedef REGFILTERPINS AMOVIESETUP_PIN,
* PAMOVIESETUP_PIN,
* LPAMOVIESETUP_PIN;
typedef struct _AMOVIESETUP_FILTER
{
const CLSID *clsID;
const WCHAR *strName;
DWORD dwMerit;
UINT nPins;
const AMOVIESETUP_PIN *lpPin;
} AMOVIESETUP_FILTER, * PAMOVIESETUP_FILTER, * LPAMOVIESETUP_FILTER;
/* This needs to go into Combase.h */
typedef IUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr);
typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid);
typedef struct tagCFactoryTemplate {
const WCHAR *m_Name;
const CLSID *m_ClsID;
LPFNNewCOMObject m_lpfnNew;
LPFNInitRoutine m_lpfnInit;
const AMOVIESETUP_FILTER *m_pAMovieSetup_Filter;
} CFactoryTemplate;
/****************************************************************************
* SetupRegisterServers
*
* This function is table driven using the static members of the
* CFactoryTemplate class defined in the Dll.
*
* It registers the Dll as the InprocServer32 for all the classes in
* CFactoryTemplate
*
****************************************************************************/
extern HRESULT SetupRegisterServers(const CFactoryTemplate * pList, int num,
HINSTANCE hinst, BOOL bRegister);
/****************************************************************************
* SetupInitializeServers
*
* This function is table driven using the static members of the
* CFactoryTemplate class defined in the Dll.
*
* It calls the intialize function for any class in CFactoryTemplate with
* one defined.
*
****************************************************************************/
extern void SetupInitializeServers(const CFactoryTemplate * pList, int num,
BOOL bLoading);
#endif /* _QCAP_DLLSETUP_H_DEFINED */
@ stub DllCanUnloadNow
@ stdcall -private DllCanUnloadNow() QCAP_DllCanUnloadNow
@ stdcall -private DllGetClassObject(ptr ptr ptr) QCAP_DllGetClassObject
@ stdcall -private DllRegisterServer() QCAP_DllRegisterServer
@ stub DllUnregisterServer
@ stdcall -private DllUnregisterServer() QCAP_DllUnregisterServer
/*
* Qcap implementation
* Qcap implementation, dllentry points
*
* Copyright (C) 2003 Dominik Strasser
* Copyright (C) 2005 Rolf Kalbermatter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -17,27 +18,339 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/debug.h"
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#define COBJMACROS
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "objbase.h"
#include "uuids.h"
#include "strmif.h"
#include "dllsetup.h"
#include "qcap_main.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(qcap);
static DWORD objects_ref = 0;
static DWORD server_locks = 0;
static HINSTANCE ghInst = NULL;
static const WCHAR wAudioCaptFilter[] =
{'A','u','d','i','o',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',0};
static const WCHAR wAVICompressor[] =
{'A','V','I',' ','C','o','m','p','r','e','s','s','o','r',0};
static const WCHAR wVFWCaptFilter[] =
{'V','F','W',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',0};
static const WCHAR wVFWCaptFilterProp[] =
{'V','F','W',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',' ',
'P','r','o','p','e','r','t','y',' ','P','a','g','e',0};
static const WCHAR wAVIMux[] =
{'A','V','I',' ','m','u','x',0};
static const WCHAR wAVIMuxPropPage[] =
{'A','V','I',' ','m','u','x',' ','P','r','o','p','e','r','t','y',' ','P','a','g','e',0};
static const WCHAR wAVIMuxPropPage1[] =
{'A','V','I',' ','m','u','x',' ','P','r','o','p','e','r','t','y',' ','P','a','g','e','1',0};
static const WCHAR wFileWriter[] =
{'F','i','l','e',' ','W','r','i','t','e','r',0};
static const WCHAR wCaptGraphBuilder[] =
{'C','a','p','t','u','r','e',' ','G','r','a','p','h',' ','B','u','i','l','d','e','r',0};
static const WCHAR wCaptGraphBuilder2[] =
{'C','a','p','t','u','r','e',' ','G','r','a','p','h',' ','B','u','i','l','d','e','r','2',0};
static const WCHAR wInfPinTeeFilter[] =
{'I','n','f','i','n','i','t','e',' ','P','i','n',' ','T','e','e',' ','F','i',
'l','t','e','r',0};
static const WCHAR wSmartTeeFilter[] =
{'S','m','a','r','t',' ','T','e','e',' ','F','i','l','t','e','r',0};
static const WCHAR wAudioInMixerProp[] =
{'A','u','d','i','o','I','n','p','u','t','M','i','x','e','r',' ','P','r','o',
'p','e','r','t','y',' ','P','a','g','e',0};
static CFactoryTemplate const g_cTemplates[] = {
/*
{
wAudioCaptureFilter,
&CLSID_AudioCaptureFilter,
QCAP_createAudioCaptureFilter,
NULL
},{
wAVICompressor,
&CLSID_AVICompressor,
QCAP_createAVICompressor,
NULL
},{
wVFWCaptFilter,
&CLSID_VFWCaptureFilter,
QCAP_createVFWCaptureFilter,
NULL
},{
wVFWCaptFilterProp,
&CLSID_VFWCaptureFilterPropertyPage,
QCAP_createVFWCaptureFilterPropertyPage,
NULL
},{
wAVIMux,
&CLSID_AVImux,
QCAP_createAVImux,
NULL
},{
wAVIMuxPropPage,
&CLSID_AVImuxPropertyPage,
QCAP_createAVImuxPropertyPage,
NULL
},{
wAVIMuxPropPage1,
&CLSID_AVImuxPropertyPage1,
QCAP_createAVImuxPropertyPage1,
NULL
},{
wFileWriter,
&CLSID_FileWriter,
QCAP_createFileWriter,
NULL
},{
wCaptGraphBuilder,
&CLSID_CaptureGraphBuilder,
QCAP_createCaptureGraphBuilder2,
NULL
},{
wCaptGraphBuilder2,
&CLSID_CaptureGraphBuilder2,
QCAP_createCaptureGraphBuilder2,
NULL
},{
wInfPinTeeFilter,
&CLSID_InfinitePinTeeFilter,
QCAP_createInfinitePinTeeFilter,
NULL
},{
wSmartTeeFilter,
&CLSID_SmartTeeFilter,
QCAP_createSmartTeeFilter,
NULL
},{
wAudioInMixerProp,
&CLSID_AudioInputMixerPropertyPage,
QCAP_createAudioInputMixerPropertyPage,
NULL
}*/
};
static int g_numTemplates = sizeof(g_cTemplates) / sizeof(g_cTemplates[0]);
/***********************************************************************
* DllRegisterServer (QCAP.@)
* Dll EntryPoint (QCAP.@)
*/
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hInstDLL);
ghInst = hInstDLL;
SetupInitializeServers(g_cTemplates, g_numTemplates, TRUE);
break;
case DLL_PROCESS_DETACH:
SetupInitializeServers(g_cTemplates, g_numTemplates, FALSE);
break;
}
return TRUE;
}
/***********************************************************************
* DllRegisterServer (QCAP.@)
*/
HRESULT WINAPI QCAP_DllRegisterServer()
{
FIXME("(): stub\n");
return 0;
TRACE("()\n");
return SetupRegisterServers(g_cTemplates, g_numTemplates, ghInst, TRUE);
}
/***********************************************************************
* DllUnregisterServer (QCAP.@)
*/
HRESULT WINAPI QCAP_DllUnregisterServer(void)
{
TRACE("\n");
return SetupRegisterServers(g_cTemplates, g_numTemplates, ghInst, FALSE);
}
/***********************************************************************
* DllGetClassObject (QCAP.@)
* DllCanUnloadNow (QCAP.@)
*/
HRESULT WINAPI QCAP_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
HRESULT WINAPI QCAP_DllCanUnloadNow(void)
{
TRACE("\n");
if (objects_ref == 0 || server_locks == 0)
return S_OK;
return S_FALSE;
}
/******************************************************************************
* DLL ClassFactory
*/
typedef struct {
IClassFactory ITF_IClassFactory;
DWORD ref;
LPFNNewCOMObject pfnCreateInstance;
} IClassFactoryImpl;
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;
}
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)
HeapFree(GetProcessHeap(), 0, This);
return ref;
}
static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
REFIID riid, LPVOID *ppobj)
{
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
HRESULT hres = ERROR_SUCCESS;
LPUNKNOWN punk;
TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj);
if (!ppobj)
return E_POINTER;
/* Enforce the normal OLE rules regarding interfaces and delegation */
if (pOuter && !IsEqualGUID(riid, &IID_IUnknown))
return E_NOINTERFACE;
*ppobj = NULL;
punk = This->pfnCreateInstance(pOuter, &hres);
if (!punk)
{
/* No object created, update error if it isn't done already and return */
if (!FAILED(hres))
hres = E_OUTOFMEMORY;
return hres;
}
if (SUCCEEDED(hres))
{
hres = IUnknown_QueryInterface(punk, riid, ppobj);
}
/* Releasing the object. If everything was successful, QueryInterface
should have incremented the refcount once more, otherwise this will
purge the object. */
IUnknown_Release(punk);
return hres;
}
static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
{
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
TRACE("(%p)->(%d)\n",This, dolock);
if (dolock)
InterlockedIncrement(&server_locks);
else
InterlockedDecrement(&server_locks);
return S_OK;
}
static IClassFactoryVtbl DSCF_Vtbl =
{
DSCF_QueryInterface,
DSCF_AddRef,
DSCF_Release,
DSCF_CreateInstance,
DSCF_LockServer
};
/***********************************************************************
* DllGetClassObject (QCAP.@)
*/
HRESULT WINAPI QCAP_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
const CFactoryTemplate *pList = g_cTemplates;
IClassFactoryImpl *factory;
int i;
TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
if (!ppv)
return E_POINTER;
*ppv = NULL;
if (!IsEqualGUID(&IID_IClassFactory, riid) &&
!IsEqualGUID(&IID_IUnknown, riid))
return E_NOINTERFACE;
for (i = 0; i < g_numTemplates; i++, pList++)
{
if (IsEqualGUID(pList->m_ClsID, rclsid))
break;
}
if (i == g_numTemplates)
{
FIXME("%s: no class found.\n", debugstr_guid(rclsid));
return CLASS_E_CLASSNOTAVAILABLE;
}
factory = HeapAlloc(GetProcessHeap(), 0, sizeof(IClassFactoryImpl));
if (!factory)
return E_OUTOFMEMORY;
factory->ITF_IClassFactory.lpVtbl = &DSCF_Vtbl;
factory->ref = 1;
factory->pfnCreateInstance = pList->m_lpfnNew;
*ppv = &(factory->ITF_IClassFactory);
return S_OK;
}
DWORD ObjectRefCount(BOOL increment)
{
FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
return CLASS_E_CLASSNOTAVAILABLE;
if (increment)
return InterlockedIncrement(&objects_ref);
return InterlockedDecrement(&objects_ref);
}
/*
* Qcap main header file
*
* Copyright (C) 2005 Rolf Kalbermatter
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _QCAP_MAIN_H_DEFINED
#define _QCAP_MAIN_H_DEFINED
extern DWORD ObjectRefCount(BOOL increment);
extern IUnknown * WINAPI QCAP_createAudioCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr);
extern IUnknown * WINAPI QCAP_createAVICompressor(IUnknown *pUnkOuter, HRESULT *phr);
extern IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr);
extern IUnknown * WINAPI QCAP_createVFWCaptureFilterPropertyPage(IUnknown *pUnkOuter, HRESULT *phr);
extern IUnknown * WINAPI QCAP_createAVImux(IUnknown *pUnkOuter, HRESULT *phr);
extern IUnknown * WINAPI QCAP_createAVImuxPropertyPage(IUnknown *pUnkOuter, HRESULT *phr);
extern IUnknown * WINAPI QCAP_createAVImuxPropertyPage1(IUnknown *pUnkOuter, HRESULT *phr);
extern IUnknown * WINAPI QCAP_createFileWriter(IUnknown *pUnkOuter, HRESULT *phr);
extern IUnknown * WINAPI QCAP_createCaptureGraphBuilder2(IUnknown *pUnkOuter, HRESULT *phr);
extern IUnknown * WINAPI QCAP_createInfinitePinTeeFilter(IUnknown *pUnkOuter, HRESULT *phr);
extern IUnknown * WINAPI QCAP_createSmartTeeFilter(IUnknown *pUnkOuter, HRESULT *phr);
extern IUnknown * WINAPI QCAP_createAudioInputMixerPropertyPage(IUnknown *pUnkOuter, HRESULT *phr);
#endif /* _QCAP_MAIN_H_DEFINED */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment