Added some stubs.

diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in
index 2f93e21..ef6264d 100644
--- a/dlls/quartz/Makefile.in
+++ b/dlls/quartz/Makefile.in
@@ -11,10 +11,16 @@
 C_SRCS = \
 	amerror.c \
 	complist.c \
+	devenum.c \
 	fgraph.c \
+	fmap.c \
+	fmap2.c \
 	ibasaud.c \
 	ibasvid.c \
+	idevenum.c \
 	ifgraph.c \
+	ifmap.c \
+	ifmap3.c \
 	imcntl.c \
 	imem.c \
 	imevent.c \
@@ -25,6 +31,7 @@
 	ividwin.c \
 	main.c \
 	memalloc.c \
+	regsvr.c \
 	sysclock.c
 
 @MAKE_DLL_RULES@
diff --git a/dlls/quartz/devenum.c b/dlls/quartz/devenum.c
new file mode 100644
index 0000000..390409b
--- /dev/null
+++ b/dlls/quartz/devenum.c
@@ -0,0 +1,63 @@
+/*
+ * Implementation of CLSID_SystemDeviceEnum.
+ *
+ * FIXME - stub.
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "wine/obj_oleaut.h"
+#include "strmif.h"
+#include "control.h"
+#include "uuids.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "devenum.h"
+
+/* can I use offsetof safely? - FIXME? */
+static QUARTZ_IFEntry IFEntries[] =
+{
+  { &IID_ICreateDevEnum, offsetof(CSysDevEnum,createdevenum)-offsetof(CSysDevEnum,unk) },
+};
+
+
+static void QUARTZ_DestroySystemDeviceEnum(IUnknown* punk)
+{
+	CSysDevEnum_THIS(punk,unk);
+
+	CSysDevEnum_UninitICreateDevEnum( This );
+}
+
+HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj)
+{
+	CSysDevEnum*	psde;
+
+	TRACE("(%p,%p)\n",punkOuter,ppobj);
+
+	psde = (CSysDevEnum*)QUARTZ_AllocObj( sizeof(CSysDevEnum) );
+	if ( psde == NULL )
+		return E_OUTOFMEMORY;
+
+	QUARTZ_IUnkInit( &psde->unk, punkOuter );
+
+	CSysDevEnum_InitICreateDevEnum( psde );
+
+	psde->unk.pEntries = IFEntries;
+	psde->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
+	psde->unk.pOnFinalRelease = QUARTZ_DestroySystemDeviceEnum;
+
+	*ppobj = (void*)(&psde->unk);
+
+	return S_OK;
+}
+
diff --git a/dlls/quartz/devenum.h b/dlls/quartz/devenum.h
new file mode 100644
index 0000000..10ce46f
--- /dev/null
+++ b/dlls/quartz/devenum.h
@@ -0,0 +1,36 @@
+#ifndef	WINE_DSHOW_DEVENUM_H
+#define	WINE_DSHOW_DEVENUM_H
+
+/*
+		implements CLSID_SystemDeviceEnum.
+
+	- At least, the following interfaces should be implemented:
+
+	IUnknown
+		+ ICreateDevEnum
+ */
+
+#include "iunk.h"
+
+typedef struct SDE_ICreateDevEnumImpl
+{
+	ICOM_VFIELD(ICreateDevEnum);
+} SDE_ICreateDevEnumImpl;
+
+typedef struct CSysDevEnum
+{
+	QUARTZ_IUnkImpl	unk;
+	SDE_ICreateDevEnumImpl	createdevenum;
+} CSysDevEnum;
+
+#define	CSysDevEnum_THIS(iface,member)		CSysDevEnum*	This = ((CSysDevEnum*)(((char*)iface)-offsetof(CSysDevEnum,member)))
+
+HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj);
+
+
+void CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde );
+void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde );
+
+
+#endif	/* WINE_DSHOW_DEVENUM_H */
+
diff --git a/dlls/quartz/fgraph.c b/dlls/quartz/fgraph.c
index e73aa4a..3889fa8 100644
--- a/dlls/quartz/fgraph.c
+++ b/dlls/quartz/fgraph.c
@@ -36,10 +36,26 @@
   { &IID_IMediaPosition, offsetof(CFilterGraph,mediaposition)-offsetof(CFilterGraph,unk) },
   { &IID_IMediaSeeking, offsetof(CFilterGraph,mediaseeking)-offsetof(CFilterGraph,unk) },
   { &IID_IBasicVideo, offsetof(CFilterGraph,basvid)-offsetof(CFilterGraph,unk) },
+  { &IID_IBasicVideo2, offsetof(CFilterGraph,basvid)-offsetof(CFilterGraph,unk) },
   { &IID_IBasicAudio, offsetof(CFilterGraph,basaud)-offsetof(CFilterGraph,unk) },
   { &IID_IVideoWindow, offsetof(CFilterGraph,vidwin)-offsetof(CFilterGraph,unk) },
 };
 
+
+static void QUARTZ_DestroyFilterGraph(IUnknown* punk)
+{
+	CFilterGraph_THIS(punk,unk);
+
+	CFilterGraph_UninitIFilterGraph2( This );
+	CFilterGraph_UninitIMediaControl( This );
+	CFilterGraph_UninitIMediaEventEx( This );
+	CFilterGraph_UninitIMediaPosition( This );
+	CFilterGraph_UninitIMediaSeeking( This );
+	CFilterGraph_UninitIBasicVideo2( This );
+	CFilterGraph_UninitIBasicAudio( This );
+	CFilterGraph_UninitIVideoWindow( This );
+}
+
 HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj)
 {
 	CFilterGraph*	pfg;
@@ -62,8 +78,11 @@
 
 	pfg->unk.pEntries = IFEntries;
 	pfg->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
+	pfg->unk.pOnFinalRelease = QUARTZ_DestroyFilterGraph;
 
 	*ppobj = (void*)(&pfg->unk);
 
 	return S_OK;
 }
+
+
diff --git a/dlls/quartz/fgraph.h b/dlls/quartz/fgraph.h
index 46f132e..d606c11 100644
--- a/dlls/quartz/fgraph.h
+++ b/dlls/quartz/fgraph.h
@@ -15,6 +15,10 @@
 		+ IDispatch - IBasicVideo (pass to a renderer)
 		+ IDispatch - IBasicAudio (pass to a renderer)
 		+ IDispatch - IVideoWindow  (pass to a renderer)
+	(following interfaces are not implemented)
+		+ IDispatch
+		+ IMediaEventSink
+		+ IGraphVerson
  */
 
 #include "iunk.h"
@@ -77,7 +81,7 @@
 	/* IMediaEvent fields. */
 	/* IMediaPosition fields. */
 	/* IMediaSeeking fields. */
-	/* IBasicVideo fields. */
+	/* IBasicVideo2 fields. */
 	/* IBasicAudio fields. */
 	/* IVideoWindow fields. */
 } CFilterGraph;
@@ -87,13 +91,21 @@
 HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj);
 
 void CFilterGraph_InitIFilterGraph2( CFilterGraph* pfg );
+void CFilterGraph_UninitIFilterGraph2( CFilterGraph* pfg );
 void CFilterGraph_InitIMediaControl( CFilterGraph* pfg );
+void CFilterGraph_UninitIMediaControl( CFilterGraph* pfg );
 void CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg );
+void CFilterGraph_UninitIMediaEventEx( CFilterGraph* pfg );
 void CFilterGraph_InitIMediaPosition( CFilterGraph* pfg );
+void CFilterGraph_UninitIMediaPosition( CFilterGraph* pfg );
 void CFilterGraph_InitIMediaSeeking( CFilterGraph* pfg );
+void CFilterGraph_UninitIMediaSeeking( CFilterGraph* pfg );
 void CFilterGraph_InitIBasicVideo2( CFilterGraph* pfg );
+void CFilterGraph_UninitIBasicVideo2( CFilterGraph* pfg );
 void CFilterGraph_InitIBasicAudio( CFilterGraph* pfg );
+void CFilterGraph_UninitIBasicAudio( CFilterGraph* pfg );
 void CFilterGraph_InitIVideoWindow( CFilterGraph* pfg );
+void CFilterGraph_UninitIVideoWindow( CFilterGraph* pfg );
 
 
 #endif	/* WINE_DSHOW_FGRAPH_H */
diff --git a/dlls/quartz/fmap.c b/dlls/quartz/fmap.c
new file mode 100644
index 0000000..e588f7c
--- /dev/null
+++ b/dlls/quartz/fmap.c
@@ -0,0 +1,61 @@
+/*
+ * Implementation of CLSID_FilterMapper.
+ *
+ * FIXME - stub.
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "wine/obj_oleaut.h"
+#include "strmif.h"
+#include "control.h"
+#include "uuids.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "fmap.h"
+
+/* can I use offsetof safely? - FIXME? */
+static QUARTZ_IFEntry IFEntries[] =
+{
+  { &IID_IFilterMapper, offsetof(CFilterMapper,fmap)-offsetof(CFilterMapper,unk) },
+};
+
+
+static void QUARTZ_DestroyFilterMapper(IUnknown* punk)
+{
+	CFilterMapper_THIS(punk,unk);
+
+	CFilterMapper_UninitIFilterMapper( This );
+}
+
+HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj)
+{
+	CFilterMapper*	pfm;
+
+	TRACE("(%p,%p)\n",punkOuter,ppobj);
+
+	pfm = (CFilterMapper*)QUARTZ_AllocObj( sizeof(CFilterMapper) );
+	if ( pfm == NULL )
+		return E_OUTOFMEMORY;
+
+	QUARTZ_IUnkInit( &pfm->unk, punkOuter );
+	CFilterMapper_InitIFilterMapper( pfm );
+
+	pfm->unk.pEntries = IFEntries;
+	pfm->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
+	pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper;
+
+	*ppobj = (void*)(&pfm->unk);
+
+	return S_OK;
+}
diff --git a/dlls/quartz/fmap.h b/dlls/quartz/fmap.h
new file mode 100644
index 0000000..3538981
--- /dev/null
+++ b/dlls/quartz/fmap.h
@@ -0,0 +1,37 @@
+#ifndef	WINE_DSHOW_FMAP_H
+#define	WINE_DSHOW_FMAP_H
+
+/*
+		implements CLSID_FilterMapper.
+
+	- At least, the following interfaces should be implemented:
+
+	IUnknown
+		+ IFilterMapper
+ */
+
+#include "iunk.h"
+
+
+typedef struct FM_IFilterMapperImpl
+{
+	ICOM_VFIELD(IFilterMapper);
+} FM_IFilterMapperImpl;
+
+typedef struct CFilterMapper
+{
+	QUARTZ_IUnkImpl	unk;
+	FM_IFilterMapperImpl	fmap;
+} CFilterMapper;
+
+#define	CFilterMapper_THIS(iface,member)		CFilterMapper*	This = ((CFilterMapper*)(((char*)iface)-offsetof(CFilterMapper,member)))
+
+HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj);
+
+
+void CFilterMapper_InitIFilterMapper( CFilterMapper* pfm );
+void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm );
+
+
+#endif	/* WINE_DSHOW_FMAP_H */
+
diff --git a/dlls/quartz/fmap2.c b/dlls/quartz/fmap2.c
new file mode 100644
index 0000000..ff32717
--- /dev/null
+++ b/dlls/quartz/fmap2.c
@@ -0,0 +1,62 @@
+/*
+ * Implementation of CLSID_FilterMapper2.
+ *
+ * FIXME - stub.
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "wine/obj_oleaut.h"
+#include "strmif.h"
+#include "control.h"
+#include "uuids.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "fmap2.h"
+
+/* can I use offsetof safely? - FIXME? */
+static QUARTZ_IFEntry IFEntries[] =
+{
+  { &IID_IFilterMapper2, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) },
+  { &IID_IFilterMapper3, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) },
+};
+
+
+static void QUARTZ_DestroyFilterMapper2(IUnknown* punk)
+{
+	CFilterMapper2_THIS(punk,unk);
+
+	CFilterMapper2_UninitIFilterMapper3( This );
+}
+
+HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj)
+{
+	CFilterMapper2*	pfm;
+
+	TRACE("(%p,%p)\n",punkOuter,ppobj);
+
+	pfm = (CFilterMapper2*)QUARTZ_AllocObj( sizeof(CFilterMapper2) );
+	if ( pfm == NULL )
+		return E_OUTOFMEMORY;
+
+	QUARTZ_IUnkInit( &pfm->unk, punkOuter );
+	CFilterMapper2_InitIFilterMapper3( pfm );
+
+	pfm->unk.pEntries = IFEntries;
+	pfm->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
+	pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper2;
+
+	*ppobj = (void*)(&pfm->unk);
+
+	return S_OK;
+}
diff --git a/dlls/quartz/fmap2.h b/dlls/quartz/fmap2.h
new file mode 100644
index 0000000..0ee05a1
--- /dev/null
+++ b/dlls/quartz/fmap2.h
@@ -0,0 +1,37 @@
+#ifndef	WINE_DSHOW_FMAP2_H
+#define	WINE_DSHOW_FMAP2_H
+
+/*
+		implements CLSID_FilterMapper2.
+
+	- At least, the following interfaces should be implemented:
+
+	IUnknown
+		+ IFilterMapper2 - IFilterMapper3
+ */
+
+#include "iunk.h"
+
+
+typedef struct FM2_IFilterMapper3Impl
+{
+	ICOM_VFIELD(IFilterMapper3);
+} FM2_IFilterMapper3Impl;
+
+typedef struct CFilterMapper2
+{
+	QUARTZ_IUnkImpl	unk;
+	FM2_IFilterMapper3Impl	fmap3;
+} CFilterMapper2;
+
+#define	CFilterMapper2_THIS(iface,member)		CFilterMapper2*	This = ((CFilterMapper2*)(((char*)iface)-offsetof(CFilterMapper2,member)))
+
+HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj);
+
+
+void CFilterMapper2_InitIFilterMapper3( CFilterMapper2* psde );
+void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* psde );
+
+
+#endif	/* WINE_DSHOW_FMAP2_H */
+
diff --git a/dlls/quartz/ibasaud.c b/dlls/quartz/ibasaud.c
index 0ed9a65..fbfe782 100644
--- a/dlls/quartz/ibasaud.c
+++ b/dlls/quartz/ibasaud.c
@@ -164,3 +164,8 @@
 	ICOM_VTBL(&pfg->basaud) = &ibasicaudio;
 }
 
+void CFilterGraph_UninitIBasicAudio( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
+
diff --git a/dlls/quartz/ibasvid.c b/dlls/quartz/ibasvid.c
index e70ef2b..3915b1b 100644
--- a/dlls/quartz/ibasvid.c
+++ b/dlls/quartz/ibasvid.c
@@ -485,3 +485,7 @@
 	ICOM_VTBL(&pfg->basvid) = &ibasicvideo;
 }
 
+void CFilterGraph_UninitIBasicVideo2( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
diff --git a/dlls/quartz/idevenum.c b/dlls/quartz/idevenum.c
new file mode 100644
index 0000000..cf62c15
--- /dev/null
+++ b/dlls/quartz/idevenum.c
@@ -0,0 +1,87 @@
+/*
+ * Implementation of ICreateDevEnum for CLSID_SystemDeviceEnum.
+ *
+ * FIXME - stub.
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "wine/obj_oleaut.h"
+#include "strmif.h"
+#include "control.h"
+#include "uuids.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "devenum.h"
+
+static HRESULT WINAPI
+ICreateDevEnum_fnQueryInterface(ICreateDevEnum* iface,REFIID riid,void** ppobj)
+{
+	CSysDevEnum_THIS(iface,createdevenum);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+ICreateDevEnum_fnAddRef(ICreateDevEnum* iface)
+{
+	CSysDevEnum_THIS(iface,createdevenum);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+ICreateDevEnum_fnRelease(ICreateDevEnum* iface)
+{
+	CSysDevEnum_THIS(iface,createdevenum);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+ICreateDevEnum_fnCreateClassEnumerator(ICreateDevEnum* iface,REFCLSID rclsidDeviceClass,IEnumMoniker** ppobj, DWORD dwFlags)
+{
+	CSysDevEnum_THIS(iface,createdevenum);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static ICOM_VTABLE(ICreateDevEnum) icreatedevenum =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	ICreateDevEnum_fnQueryInterface,
+	ICreateDevEnum_fnAddRef,
+	ICreateDevEnum_fnRelease,
+	/* ICreateDevEnum fields */
+	ICreateDevEnum_fnCreateClassEnumerator,
+};
+
+void CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde )
+{
+	TRACE("(%p)\n",psde);
+	ICOM_VTBL(&psde->createdevenum) = &icreatedevenum;
+}
+
+void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde )
+{
+	TRACE("(%p)\n",psde);
+}
diff --git a/dlls/quartz/ifgraph.c b/dlls/quartz/ifgraph.c
index 8d2697b..a6ef7d7 100644
--- a/dlls/quartz/ifgraph.c
+++ b/dlls/quartz/ifgraph.c
@@ -260,3 +260,8 @@
 	TRACE("(%p)\n",pfg);
 	ICOM_VTBL(&pfg->fgraph) = &ifgraph;
 }
+
+void CFilterGraph_UninitIFilterGraph2( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
diff --git a/dlls/quartz/ifmap.c b/dlls/quartz/ifmap.c
new file mode 100644
index 0000000..9927e16
--- /dev/null
+++ b/dlls/quartz/ifmap.c
@@ -0,0 +1,169 @@
+/*
+ * Implementation of IFilterMapper for CLSID_FilterMapper.
+ *
+ * FIXME - stub.
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "wine/obj_oleaut.h"
+#include "strmif.h"
+#include "control.h"
+#include "uuids.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "fmap.h"
+
+
+static HRESULT WINAPI
+IFilterMapper_fnQueryInterface(IFilterMapper* iface,REFIID riid,void** ppobj)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IFilterMapper_fnAddRef(IFilterMapper* iface)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IFilterMapper_fnRelease(IFilterMapper* iface)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+
+static HRESULT WINAPI
+IFilterMapper_fnRegisterFilter(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,DWORD dwMerit)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	TRACE("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IFilterMapper_fnRegisterFilterInstance(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,CLSID* pclsidMedia)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	TRACE("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IFilterMapper_fnRegisterPin(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,BOOL bRendered,BOOL bOutput,BOOL bZero,BOOL bMany,CLSID clsidReserved,LPCWSTR lpwszReserved)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	TRACE("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IFilterMapper_fnRegisterPinType(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,CLSID clsidMajorType,CLSID clsidSubType)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	TRACE("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IFilterMapper_fnUnregisterFilter(IFilterMapper* iface,CLSID clsidFilter)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	TRACE("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IFilterMapper_fnUnregisterFilterInstance(IFilterMapper* iface,CLSID clsidMedia)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	TRACE("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IFilterMapper_fnUnregisterPin(IFilterMapper* iface,CLSID clsidPin,LPCWSTR lpwszName)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	TRACE("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IFilterMapper_fnEnumMatchingFilters(IFilterMapper* iface,IEnumRegFilters** ppobj,DWORD dwMerit,BOOL bInputNeeded,CLSID clsInMajorType,CLSID clsidSubType,BOOL bRender,BOOL bOutputNeeded,CLSID clsOutMajorType,CLSID clsOutSubType)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	TRACE("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+
+static ICOM_VTABLE(IFilterMapper) ifmap =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IFilterMapper_fnQueryInterface,
+	IFilterMapper_fnAddRef,
+	IFilterMapper_fnRelease,
+	/* IFilterMapper fields */
+	IFilterMapper_fnRegisterFilter,
+	IFilterMapper_fnRegisterFilterInstance,
+	IFilterMapper_fnRegisterPin,
+	IFilterMapper_fnRegisterPinType,
+	IFilterMapper_fnUnregisterFilter,
+	IFilterMapper_fnUnregisterFilterInstance,
+	IFilterMapper_fnUnregisterPin,
+	IFilterMapper_fnEnumMatchingFilters,
+};
+
+
+void CFilterMapper_InitIFilterMapper( CFilterMapper* pfm )
+{
+	TRACE("(%p)\n",pfm);
+	ICOM_VTBL(&pfm->fmap) = &ifmap;
+}
+
+void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm )
+{
+	TRACE("(%p)\n",pfm);
+}
diff --git a/dlls/quartz/ifmap3.c b/dlls/quartz/ifmap3.c
new file mode 100644
index 0000000..d8b51c3
--- /dev/null
+++ b/dlls/quartz/ifmap3.c
@@ -0,0 +1,142 @@
+/*
+ * Implementation of IFilterMapper3 for CLSID_FilterMapper2.
+ *
+ * FIXME - stub.
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "wine/obj_oleaut.h"
+#include "strmif.h"
+#include "control.h"
+#include "uuids.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "fmap2.h"
+
+
+static HRESULT WINAPI
+IFilterMapper3_fnQueryInterface(IFilterMapper3* iface,REFIID riid,void** ppobj)
+{
+	CFilterMapper2_THIS(iface,fmap3);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IFilterMapper3_fnAddRef(IFilterMapper3* iface)
+{
+	CFilterMapper2_THIS(iface,fmap3);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IFilterMapper3_fnRelease(IFilterMapper3* iface)
+{
+	CFilterMapper2_THIS(iface,fmap3);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IFilterMapper3_fnCreateCategory(IFilterMapper3* iface,REFCLSID rclsidCategory,DWORD dwMerit,LPCWSTR lpwszDesc)
+{
+	CFilterMapper2_THIS(iface,fmap3);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static HRESULT WINAPI
+IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter)
+{
+	CFilterMapper2_THIS(iface,fmap3);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static HRESULT WINAPI
+IFilterMapper3_fnRegisterFilter(IFilterMapper3* iface,REFCLSID rclsidFilter,LPCWSTR lpName,IMoniker** ppMoniker,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,const REGFILTER2* pRF2)
+{
+	CFilterMapper2_THIS(iface,fmap3);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static HRESULT WINAPI
+IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,IEnumMoniker** ppMoniker,DWORD dwFlags,BOOL bExactMatch,DWORD dwMerit,BOOL bInputNeeded,DWORD cInputTypes,const GUID* pguidInputTypes,const REGPINMEDIUM* pPinMediumIn,const CLSID* pPinCategoryIn,BOOL bRender,BOOL bOutputNeeded,DWORD cOutputTypes,const GUID* pguidOutputTypes,const REGPINMEDIUM* pPinMediumOut,const CLSID* pPinCategoryOut)
+{
+	CFilterMapper2_THIS(iface,fmap3);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IFilterMapper3_fnGetICreateDevEnum(IFilterMapper3* iface,ICreateDevEnum** ppDevEnum)
+{
+	CFilterMapper2_THIS(iface,fmap3);
+
+	/* undocumented */
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+
+
+static ICOM_VTABLE(IFilterMapper3) ifmap3 =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IFilterMapper3_fnQueryInterface,
+	IFilterMapper3_fnAddRef,
+	IFilterMapper3_fnRelease,
+	/* IFilterMapper2 fields */
+	IFilterMapper3_fnCreateCategory,
+	IFilterMapper3_fnUnregisterFilter,
+	IFilterMapper3_fnRegisterFilter,
+	IFilterMapper3_fnEnumMatchingFilters,
+	/* IFilterMapper3 fields */
+	IFilterMapper3_fnGetICreateDevEnum,
+};
+
+
+void CFilterMapper2_InitIFilterMapper3( CFilterMapper2* pfm )
+{
+	TRACE("(%p)\n",pfm);
+	ICOM_VTBL(&pfm->fmap3) = &ifmap3;
+}
+
+void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* pfm )
+{
+	TRACE("(%p)\n",pfm);
+}
+
diff --git a/dlls/quartz/imcntl.c b/dlls/quartz/imcntl.c
index 5777c36..0e91bee 100644
--- a/dlls/quartz/imcntl.c
+++ b/dlls/quartz/imcntl.c
@@ -218,3 +218,8 @@
 	TRACE("(%p)\n",pfg);
 	ICOM_VTBL(&pfg->mediacontrol) = &imediacontrol;
 }
+
+void CFilterGraph_UninitIMediaControl( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
diff --git a/dlls/quartz/imevent.c b/dlls/quartz/imevent.c
index 676d50d..12a3078 100644
--- a/dlls/quartz/imevent.c
+++ b/dlls/quartz/imevent.c
@@ -220,3 +220,8 @@
 	TRACE("(%p)\n",pfg);
 	ICOM_VTBL(&pfg->mediaevent) = &imediaevent;
 }
+
+void CFilterGraph_UninitIMediaEventEx( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
diff --git a/dlls/quartz/impos.c b/dlls/quartz/impos.c
index 3a0300d..caf6e3f 100644
--- a/dlls/quartz/impos.c
+++ b/dlls/quartz/impos.c
@@ -239,3 +239,8 @@
 	TRACE("(%p)\n",pfg);
 	ICOM_VTBL(&pfg->mediaposition) = &imediaposition;
 }
+
+void CFilterGraph_UninitIMediaPosition( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
diff --git a/dlls/quartz/imseek.c b/dlls/quartz/imseek.c
index 9df7eb8..2dbc500 100644
--- a/dlls/quartz/imseek.c
+++ b/dlls/quartz/imseek.c
@@ -262,3 +262,8 @@
 	TRACE("(%p)\n",pfg);
 	ICOM_VTBL(&pfg->mediaseeking) = &imediaseeking;
 }
+
+void CFilterGraph_UninitIMediaSeeking( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
diff --git a/dlls/quartz/iunk.c b/dlls/quartz/iunk.c
index cfb2fc7..27cccfd 100644
--- a/dlls/quartz/iunk.c
+++ b/dlls/quartz/iunk.c
@@ -8,6 +8,7 @@
 
 #include "windef.h"
 #include "winerror.h"
+#include "winbase.h"
 #include "wine/obj_base.h"
 
 #include "debugtools.h"
@@ -66,17 +67,22 @@
 
 	TRACE("(%p)->()\n",This);
 
-	return ++(This->ref);
+	return InterlockedExchangeAdd(&(This->ref),1) + 1;
 }
 
 static ULONG WINAPI
 IUnknown_fnRelease(IUnknown* iface)
 {
 	ICOM_THIS(QUARTZ_IUnkImpl,iface);
+	LONG	ref;
 
 	TRACE("(%p)->()\n",This);
-	if ( (--(This->ref)) > 0 )
-		return This->ref;
+	ref = InterlockedExchangeAdd(&(This->ref),-1) - 1;
+	if ( ref > 0 )
+		return (ULONG)ref;
+
+	if ( This->pOnFinalRelease != NULL )
+		(*(This->pOnFinalRelease))(iface);
 
 	QUARTZ_FreeObj(This);
 
@@ -100,6 +106,7 @@
 	ICOM_VTBL(pImpl) = &iunknown;
 	pImpl->pEntries = NULL;
 	pImpl->dwEntries = 0;
+	pImpl->pOnFinalRelease = NULL;
 	pImpl->ref = 1;
 	pImpl->punkControl = (IUnknown*)pImpl;
 
diff --git a/dlls/quartz/iunk.h b/dlls/quartz/iunk.h
index d0ffa58..0555f3b 100644
--- a/dlls/quartz/iunk.h
+++ b/dlls/quartz/iunk.h
@@ -24,6 +24,9 @@
 
  */
 
+/* for InterlockedExchangeAdd. */
+#include <pshpack4.h>
+
 typedef struct QUARTZ_IFEntry
 {
 	REFIID		piid;		/* interface ID. */
@@ -38,12 +41,16 @@
 	/* array of supported IIDs and offsets. */
 	const QUARTZ_IFEntry*	pEntries;
 	DWORD	dwEntries;
+	/* called on final release. */
+	void (*pOnFinalRelease)(IUnknown* punk);
 
 	/* IUnknown fields. */
-	ULONG	ref;
+	LONG	ref;
 	IUnknown*	punkControl;
 } QUARTZ_IUnkImpl;
 
+#include <poppack.h>
+
 
 void QUARTZ_IUnkInit( QUARTZ_IUnkImpl* pImpl, IUnknown* punkOuter );
 
diff --git a/dlls/quartz/ividwin.c b/dlls/quartz/ividwin.c
index 3c6a42e..5feb73f 100644
--- a/dlls/quartz/ividwin.c
+++ b/dlls/quartz/ividwin.c
@@ -552,3 +552,9 @@
 	TRACE("(%p)\n",pfg);
 	ICOM_VTBL(&pfg->vidwin) = &ivideowindow;
 }
+
+void CFilterGraph_UninitIVideoWindow( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
+
diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c
index 6ac700e..b147958 100644
--- a/dlls/quartz/main.c
+++ b/dlls/quartz/main.c
@@ -17,6 +17,9 @@
 #include "fgraph.h"
 #include "sysclock.h"
 #include "memalloc.h"
+#include "devenum.h"
+#include "fmap.h"
+#include "fmap2.h"
 
 
 typedef struct QUARTZ_CLASSENTRY
@@ -57,6 +60,9 @@
 	{ &CLSID_FilterGraph, &QUARTZ_CreateFilterGraph },
 	{ &CLSID_SystemClock, &QUARTZ_CreateSystemClock },
 	{ &CLSID_MemoryAllocator, &QUARTZ_CreateMemoryAllocator },
+	{ &CLSID_SystemDeviceEnum, &QUARTZ_CreateSystemDeviceEnum },
+	{ &CLSID_FilterMapper, &QUARTZ_CreateFilterMapper },
+	{ &CLSID_FilterMapper2, &QUARTZ_CreateFilterMapper2 },
 	{ NULL, NULL },
 };
 
@@ -190,6 +196,7 @@
 	{
 		if ( IsEqualGUID( pclsid, pEntry->pclsid ) )
 			goto found;
+		pEntry ++;
 	}
 
 	return CLASS_E_CLASSNOTAVAILABLE;
@@ -198,6 +205,8 @@
 	if ( pImpl == NULL )
 		return E_OUTOFMEMORY;
 
+	TRACE( "allocated successfully.\n" );
+
 	ICOM_VTBL(pImpl) = &iclassfact;
 	pImpl->ref = 1;
 	pImpl->pEntry = pEntry;
@@ -323,3 +332,30 @@
 	return E_FAIL;
 }
 
+
+/***********************************************************************
+ *		AmpFactorToDB (QUARTZ.@)
+ *
+ *	undocumented.
+ *  (converting from Amp to dB?)
+ *
+ */
+DWORD WINAPI QUARTZ_AmpFactorToDB( DWORD dw )
+{
+	FIXME( "(%08lx): undocumented API - stub!\n", dw );
+	return 0;
+}
+
+/***********************************************************************
+ *		DBToAmpFactor (QUARTZ.@)
+ *
+ *	undocumented.
+ *  (converting from dB to Amp?)
+ */
+DWORD WINAPI QUARTZ_DBToAmpFactor( DWORD dw )
+{
+	FIXME( "(%08lx): undocumented API - stub!\n", dw );
+	return 0;
+}
+
+
diff --git a/dlls/quartz/quartz.spec b/dlls/quartz/quartz.spec
index d0d5c2e..b32471f 100644
--- a/dlls/quartz/quartz.spec
+++ b/dlls/quartz/quartz.spec
@@ -10,8 +10,8 @@
 
 @ stdcall AMGetErrorTextA(long ptr long) AMGetErrorTextA
 @ stdcall AMGetErrorTextW(long ptr long) AMGetErrorTextW
-@ stub AmpFactorToDB
-@ stub DBToAmpFactor
+@ stdcall AmpFactorToDB(long) QUARTZ_AmpFactorToDB
+@ stdcall DBToAmpFactor(long) QUARTZ_DBToAmpFactor
 @ stdcall DllCanUnloadNow() QUARTZ_DllCanUnloadNow
 @ stdcall DllGetClassObject(ptr ptr ptr) QUARTZ_DllGetClassObject
 @ stdcall DllRegisterServer() QUARTZ_DllRegisterServer
diff --git a/dlls/quartz/regsvr.c b/dlls/quartz/regsvr.c
new file mode 100644
index 0000000..3def276
--- /dev/null
+++ b/dlls/quartz/regsvr.c
@@ -0,0 +1,58 @@
+/*
+ * Regster/Unregister servers. (for internal use)
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winerror.h"
+#include "winreg.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "regsvr.h"
+
+
+HRESULT QUARTZ_RegisterDLLServer(
+	const CLSID* pclsid,
+	LPCSTR lpFriendlyName,
+	LPCSTR lpNameOfDLL )
+{
+	FIXME( "stub!\n" );
+	return E_FAIL;
+}
+
+HRESULT QUARTZ_UnregisterDLLServer(
+	const CLSID* pclsid )
+{
+	FIXME( "stub!\n" );
+	return E_FAIL;
+}
+
+
+HRESULT QUARTZ_RegisterFilter(
+	const CLSID* pguidFilterCategory,
+	const CLSID* pclsid,
+	const BYTE* pbFilterData,
+	DWORD cbFilterData,
+	LPCSTR lpFriendlyName )
+{
+	FIXME( "stub!\n" );
+	return E_FAIL;
+}
+
+HRESULT QUARTZ_UnregisterFilter(
+	const CLSID* pguidFilterCategory,
+	const CLSID* pclsid )
+{
+	FIXME( "stub!\n" );
+	return E_FAIL;
+}
+
+
+
diff --git a/dlls/quartz/regsvr.h b/dlls/quartz/regsvr.h
new file mode 100644
index 0000000..71028f7
--- /dev/null
+++ b/dlls/quartz/regsvr.h
@@ -0,0 +1,29 @@
+/*
+ * Regster/Unregister servers. (for internal use)
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#ifndef	QUARTZ_REGSVR_H
+#define	QUARTZ_REGSVR_H
+
+
+HRESULT QUARTZ_RegisterDLLServer(
+	const CLSID* pclsid,
+	LPCSTR lpFriendlyName,
+	LPCSTR lpNameOfDLL );
+HRESULT QUARTZ_UnregisterDLLServer(
+	const CLSID* pclsid );
+
+HRESULT QUARTZ_RegisterFilter(
+	const CLSID* pguidFilterCategory,
+	const CLSID* pclsid,
+	const BYTE* pbFilterData,
+	DWORD cbFilterData,
+	LPCSTR lpFriendlyName );
+HRESULT QUARTZ_UnregisterFilter(
+	const CLSID* pguidFilterCategory,
+	const CLSID* pclsid );
+
+
+#endif	/* QUARTZ_REGSVR_H */
diff --git a/winedefault.reg b/winedefault.reg
index f57875f..0190aa8 100644
--- a/winedefault.reg
+++ b/winedefault.reg
@@ -256,6 +256,20 @@
 @="quartz.dll"
 "ThreadingModel"="Both"
 
+# CLSID_SystemDeviceEnum
+[HKEY_CLASSES_ROOT\CLSID\{62BE5D10-60EB-11D0-BD3B-00A0C911CE86}\InprocServer32]
+@="quartz.dll"
+"ThreadingModel"="Both"
+
+# CLSID_FilterMapper
+[HKEY_CLASSES_ROOT\CLSID\{E436EBB2-524f-11CE-9F53-0020AF0BA770}\InprocServer32]
+@="quartz.dll"
+"ThreadingModel"="Both"
+
+# CLSID_FilterMapper2
+[HKEY_CLASSES_ROOT\CLSID\{CDA42200-BD88-11D0-BD4E-00A0C911CE86}\InprocServer32]
+@="quartz.dll"
+"ThreadingModel"="Both"
 
 #
 # Entries for Mozilla ActiveX control support