Added some stubs for CLSID_FilterGraph.

diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in
index 4bfd7e2..8361dbe 100644
--- a/dlls/quartz/Makefile.in
+++ b/dlls/quartz/Makefile.in
@@ -9,11 +9,19 @@
 SYMBOLFILE = $(MODULE).tmp.o
 
 C_SRCS = \
+	complist.c \
 	fgraph.c \
+	ibasaud.c \
+	ibasvid.c \
 	ifgraph.c \
+	imcntl.c \
 	imem.c \
+	imevent.c \
+	impos.c \
+	imseek.c \
 	irclock.c \
 	iunk.c \
+	ividwin.c \
 	main.c \
 	memalloc.c \
 	sysclock.c
diff --git a/dlls/quartz/complist.c b/dlls/quartz/complist.c
new file mode 100644
index 0000000..305a250
--- /dev/null
+++ b/dlls/quartz/complist.c
@@ -0,0 +1,178 @@
+/*
+ * List of components. (for internal use)
+ *
+ * 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 "strmif.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "complist.h"
+
+
+
+struct QUARTZ_CompList
+{
+	QUARTZ_CompListItem*	pFirst;
+	QUARTZ_CompListItem*	pLast;
+};
+
+struct QUARTZ_CompListItem
+{
+	IUnknown*	punk;
+	QUARTZ_CompListItem*	pNext;
+	QUARTZ_CompListItem*	pPrev;
+};
+
+
+QUARTZ_CompList* QUARTZ_CompList_Alloc( void )
+{
+	QUARTZ_CompList*	pList;
+
+	pList = (QUARTZ_CompList*)QUARTZ_AllocMem( sizeof(QUARTZ_CompList) );
+	if ( pList != NULL )
+	{
+		/* construct. */
+		pList->pFirst = NULL;
+		pList->pLast = NULL;
+	}
+
+	return pList;
+}
+
+void QUARTZ_CompList_Free( QUARTZ_CompList* pList )
+{
+	QUARTZ_CompListItem*	pCur;
+	QUARTZ_CompListItem*	pNext;
+
+	if ( pList != NULL )
+	{
+		pCur = pList->pFirst;
+		while ( pCur != NULL )
+		{
+			pNext = pCur->pNext;
+			if ( pCur->punk != NULL )
+				IUnknown_Release( pCur->punk );
+			QUARTZ_FreeMem( pCur );
+			pCur = pNext;
+		}
+		QUARTZ_FreeMem( pList );
+	}
+}
+
+QUARTZ_CompList* QUARTZ_CompList_Dup( QUARTZ_CompList* pList )
+{
+	QUARTZ_CompList*	pNewList;
+	QUARTZ_CompListItem*	pCur;
+	HRESULT	hr;
+
+	pNewList = QUARTZ_CompList_Alloc();
+	if ( pNewList == NULL )
+		return NULL;
+
+	pCur = pList->pFirst;
+	while ( pCur != NULL )
+	{
+		if ( pCur->punk != NULL )
+		{
+			hr = QUARTZ_CompList_AddComp( pNewList, pCur->punk );
+			if ( FAILED(hr) )
+			{
+				QUARTZ_CompList_Free( pNewList );
+				return NULL;
+			}
+		}
+		pCur = pCur->pNext;
+	}
+
+	return pNewList;
+}
+
+HRESULT QUARTZ_CompList_AddComp( QUARTZ_CompList* pList, IUnknown* punk )
+{
+	QUARTZ_CompListItem*	pItem;
+
+	pItem = (QUARTZ_CompListItem*)QUARTZ_AllocMem( sizeof(QUARTZ_CompListItem) );
+	if ( pItem == NULL )
+		return E_OUTOFMEMORY; /* out of memory. */
+	pItem->punk = punk; IUnknown_AddRef(punk);
+
+	if ( pList->pFirst != NULL )
+		pList->pFirst->pPrev = pItem;
+	else
+		pList->pLast = pItem;
+	pList->pFirst = pItem;
+	pItem->pNext = pList->pFirst;
+	pItem->pPrev = NULL;
+
+	return S_OK;
+}
+
+HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk )
+{
+	QUARTZ_CompListItem*	pCur;
+
+	pCur = QUARTZ_CompList_SearchComp( pList, punk );
+	if ( pCur == NULL )
+		return S_FALSE; /* already removed. */
+
+	/* remove from list. */
+	if ( pCur->pNext != NULL )
+		pCur->pNext->pPrev = pCur->pPrev;
+	else
+		pList->pLast = pCur->pPrev;
+	if ( pCur->pPrev != NULL )
+		pCur->pPrev->pNext = pCur->pNext;
+	else
+		pList->pFirst = pCur->pNext;
+
+	/* release this item. */
+	if ( pCur->punk != NULL )
+		IUnknown_Release( pCur->punk );
+	QUARTZ_FreeMem( pCur );
+
+	return S_OK;
+}
+
+QUARTZ_CompListItem* QUARTZ_CompList_SearchComp(
+	QUARTZ_CompList* pList, IUnknown* punk )
+{
+	QUARTZ_CompListItem*	pCur;
+
+	pCur = pList->pFirst;
+	while ( pCur != NULL )
+	{
+		if ( pCur->punk == punk )
+			return pCur;
+		pCur = pCur->pNext;
+	}
+
+	return NULL;
+}
+
+QUARTZ_CompListItem* QUARTZ_CompList_GetFirst(
+	QUARTZ_CompList* pList )
+{
+	return pList->pFirst;
+}
+
+QUARTZ_CompListItem* QUARTZ_CompList_GetNext(
+	QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev )
+{
+	return pPrev->pNext;
+}
+
+IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem )
+{
+	return pItem->punk;
+}
diff --git a/dlls/quartz/complist.h b/dlls/quartz/complist.h
new file mode 100644
index 0000000..c5b1c45
--- /dev/null
+++ b/dlls/quartz/complist.h
@@ -0,0 +1,27 @@
+/*
+ * List of components. (for internal use)
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#ifndef	QUARTZ_COMPLIST_H
+#define	QUARTZ_COMPLIST_H
+
+typedef struct QUARTZ_CompList	QUARTZ_CompList;
+typedef struct QUARTZ_CompListItem	QUARTZ_CompListItem;
+
+QUARTZ_CompList* QUARTZ_CompList_Alloc( void );
+void QUARTZ_CompList_Free( QUARTZ_CompList* pList );
+QUARTZ_CompList* QUARTZ_CompList_Dup( QUARTZ_CompList* pList );
+HRESULT QUARTZ_CompList_AddComp( QUARTZ_CompList* pList, IUnknown* punk );
+HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk );
+QUARTZ_CompListItem* QUARTZ_CompList_SearchComp(
+	QUARTZ_CompList* pList, IUnknown* punk );
+QUARTZ_CompListItem* QUARTZ_CompList_GetFirst(
+	QUARTZ_CompList* pList );
+QUARTZ_CompListItem* QUARTZ_CompList_GetNext(
+	QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev );
+IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem );
+
+
+#endif	/* QUARTZ_COMPLIST_H */
diff --git a/dlls/quartz/fgraph.c b/dlls/quartz/fgraph.c
index 8f7eeaa..e73aa4a 100644
--- a/dlls/quartz/fgraph.c
+++ b/dlls/quartz/fgraph.c
@@ -13,7 +13,9 @@
 #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"
@@ -28,6 +30,14 @@
   { &IID_IFilterGraph, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
   { &IID_IGraphBuilder, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
   { &IID_IFilterGraph2, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
+  { &IID_IMediaControl, offsetof(CFilterGraph,mediacontrol)-offsetof(CFilterGraph,unk) },
+  { &IID_IMediaEvent, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) },
+  { &IID_IMediaEventEx, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) },
+  { &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_IBasicAudio, offsetof(CFilterGraph,basaud)-offsetof(CFilterGraph,unk) },
+  { &IID_IVideoWindow, offsetof(CFilterGraph,vidwin)-offsetof(CFilterGraph,unk) },
 };
 
 HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj)
@@ -40,13 +50,20 @@
 	if ( pfg == NULL )
 		return E_OUTOFMEMORY;
 
-	QUARTZ_IUnkInit( &pfg->unk );
+	QUARTZ_IUnkInit( &pfg->unk, punkOuter );
 	CFilterGraph_InitIFilterGraph2( pfg );
+	CFilterGraph_InitIMediaControl( pfg );
+	CFilterGraph_InitIMediaEventEx( pfg );
+	CFilterGraph_InitIMediaPosition( pfg );
+	CFilterGraph_InitIMediaSeeking( pfg );
+	CFilterGraph_InitIBasicVideo2( pfg );
+	CFilterGraph_InitIBasicAudio( pfg );
+	CFilterGraph_InitIVideoWindow( pfg );
 
 	pfg->unk.pEntries = IFEntries;
 	pfg->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
 
-	*ppobj = (void*)pfg;
+	*ppobj = (void*)(&pfg->unk);
 
 	return S_OK;
 }
diff --git a/dlls/quartz/fgraph.h b/dlls/quartz/fgraph.h
index adc9f90..46f132e 100644
--- a/dlls/quartz/fgraph.h
+++ b/dlls/quartz/fgraph.h
@@ -10,6 +10,7 @@
 		+ IFilterGraph - IGraphBuilder - IFilterGraph2
 		+ IDispatch - IMediaControl
 		+ IDispatch - IMediaEvent - IMediaEventEx
+		+ IDispatch - IMediaPosition
 		+ IMediaSeeking
 		+ IDispatch - IBasicVideo (pass to a renderer)
 		+ IDispatch - IBasicAudio (pass to a renderer)
@@ -23,12 +24,62 @@
 	ICOM_VFIELD(IFilterGraph2);
 } FG_IFilterGraph2Impl;
 
+typedef struct FG_IMediaControlImpl
+{
+	ICOM_VFIELD(IMediaControl);
+} FG_IMediaControlImpl;
+
+typedef struct FG_IMediaEventImpl
+{
+	ICOM_VFIELD(IMediaEventEx);
+} FG_IMediaEventImpl;
+
+typedef struct FG_IMediaPositionImpl
+{
+	ICOM_VFIELD(IMediaPosition);
+} FG_IMediaPositionImpl;
+
+typedef struct FG_IMediaSeekingImpl
+{
+	ICOM_VFIELD(IMediaSeeking);
+} FG_IMediaSeekingImpl;
+
+typedef struct FG_IBasicVideoImpl
+{
+	ICOM_VFIELD(IBasicVideo2);
+} FG_IBasicVideoImpl;
+
+typedef struct FG_IBasicAudioImpl
+{
+	ICOM_VFIELD(IBasicAudio);
+} FG_IBasicAudioImpl;
+
+typedef struct FG_IVideoWindowImpl
+{
+	ICOM_VFIELD(IVideoWindow);
+} FG_IVideoWindowImpl;
+
+
 typedef struct CFilterGraph
 {
 	QUARTZ_IUnkImpl	unk;
 	FG_IFilterGraph2Impl	fgraph;
+	FG_IMediaControlImpl	mediacontrol;
+	FG_IMediaEventImpl	mediaevent;
+	FG_IMediaPositionImpl	mediaposition;
+	FG_IMediaSeekingImpl	mediaseeking;
+	FG_IBasicVideoImpl	basvid;
+	FG_IBasicAudioImpl	basaud;
+	FG_IVideoWindowImpl	vidwin;
 
 	/* IFilterGraph2 fields. */
+	/* IMediaControl fields. */
+	/* IMediaEvent fields. */
+	/* IMediaPosition fields. */
+	/* IMediaSeeking fields. */
+	/* IBasicVideo fields. */
+	/* IBasicAudio fields. */
+	/* IVideoWindow fields. */
 } CFilterGraph;
 
 #define	CFilterGraph_THIS(iface,member)		CFilterGraph*	This = ((CFilterGraph*)(((char*)iface)-offsetof(CFilterGraph,member)))
@@ -36,6 +87,13 @@
 HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj);
 
 void CFilterGraph_InitIFilterGraph2( CFilterGraph* pfg );
+void CFilterGraph_InitIMediaControl( CFilterGraph* pfg );
+void CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg );
+void CFilterGraph_InitIMediaPosition( CFilterGraph* pfg );
+void CFilterGraph_InitIMediaSeeking( CFilterGraph* pfg );
+void CFilterGraph_InitIBasicVideo2( CFilterGraph* pfg );
+void CFilterGraph_InitIBasicAudio( CFilterGraph* pfg );
+void CFilterGraph_InitIVideoWindow( CFilterGraph* pfg );
 
 
 #endif	/* WINE_DSHOW_FGRAPH_H */
diff --git a/dlls/quartz/ibasaud.c b/dlls/quartz/ibasaud.c
new file mode 100644
index 0000000..0ed9a65
--- /dev/null
+++ b/dlls/quartz/ibasaud.c
@@ -0,0 +1,166 @@
+/*
+ * Implementation of IBasicAudio for FilterGraph.
+ *
+ * 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 "fgraph.h"
+
+
+
+static HRESULT WINAPI
+IBasicAudio_fnQueryInterface(IBasicAudio* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,basaud);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IBasicAudio_fnAddRef(IBasicAudio* iface)
+{
+	CFilterGraph_THIS(iface,basaud);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IBasicAudio_fnRelease(IBasicAudio* iface)
+{
+	CFilterGraph_THIS(iface,basaud);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IBasicAudio_fnGetTypeInfoCount(IBasicAudio* iface,UINT* pcTypeInfo)
+{
+	CFilterGraph_THIS(iface,basaud);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicAudio_fnGetTypeInfo(IBasicAudio* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
+{
+	CFilterGraph_THIS(iface,basaud);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicAudio_fnGetIDsOfNames(IBasicAudio* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
+{
+	CFilterGraph_THIS(iface,basaud);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicAudio_fnInvoke(IBasicAudio* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
+{
+	CFilterGraph_THIS(iface,basaud);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static HRESULT WINAPI
+IBasicAudio_fnput_Volume(IBasicAudio* iface,long lVol)
+{
+	CFilterGraph_THIS(iface,basaud);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol)
+{
+	CFilterGraph_THIS(iface,basaud);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance)
+{
+	CFilterGraph_THIS(iface,basaud);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance)
+{
+	CFilterGraph_THIS(iface,basaud);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static ICOM_VTABLE(IBasicAudio) ibasicaudio =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IBasicAudio_fnQueryInterface,
+	IBasicAudio_fnAddRef,
+	IBasicAudio_fnRelease,
+	/* IDispatch fields */
+	IBasicAudio_fnGetTypeInfoCount,
+	IBasicAudio_fnGetTypeInfo,
+	IBasicAudio_fnGetIDsOfNames,
+	IBasicAudio_fnInvoke,
+	/* IBasicAudio fields */
+	IBasicAudio_fnput_Volume,
+	IBasicAudio_fnget_Volume,
+	IBasicAudio_fnput_Balance,
+	IBasicAudio_fnget_Balance,
+};
+
+
+void CFilterGraph_InitIBasicAudio( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->basaud) = &ibasicaudio;
+}
+
diff --git a/dlls/quartz/ibasvid.c b/dlls/quartz/ibasvid.c
new file mode 100644
index 0000000..e70ef2b
--- /dev/null
+++ b/dlls/quartz/ibasvid.c
@@ -0,0 +1,487 @@
+/*
+ * Implementation of IBasicVideo2 for FilterGraph.
+ *
+ * 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 "fgraph.h"
+
+
+static HRESULT WINAPI
+IBasicVideo2_fnQueryInterface(IBasicVideo2* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IBasicVideo2_fnAddRef(IBasicVideo2* iface)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IBasicVideo2_fnRelease(IBasicVideo2* iface)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetTypeInfoCount(IBasicVideo2* iface,UINT* pcTypeInfo)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetTypeInfo(IBasicVideo2* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetIDsOfNames(IBasicVideo2* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnInvoke(IBasicVideo2* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_AvgTimePerFrame(IBasicVideo2* iface,REFTIME* prefTime)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_BitRate(IBasicVideo2* iface,long* plRate)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_BitErrorRate(IBasicVideo2* iface,long* plRate)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_VideoWidth(IBasicVideo2* iface,long* plWidth)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_VideoHeight(IBasicVideo2* iface,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_SourceLeft(IBasicVideo2* iface,long lLeft)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_SourceLeft(IBasicVideo2* iface,long* plLeft)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_SourceWidth(IBasicVideo2* iface,long lWidth)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_SourceWidth(IBasicVideo2* iface,long* plWidth)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_SourceTop(IBasicVideo2* iface,long lTop)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_SourceTop(IBasicVideo2* iface,long* plTop)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_SourceHeight(IBasicVideo2* iface,long lHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_SourceHeight(IBasicVideo2* iface,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_DestinationLeft(IBasicVideo2* iface,long lLeft)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_DestinationLeft(IBasicVideo2* iface,long* plLeft)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_DestinationWidth(IBasicVideo2* iface,long lWidth)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_DestinationWidth(IBasicVideo2* iface,long* plWidth)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_DestinationTop(IBasicVideo2* iface,long lTop)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_DestinationTop(IBasicVideo2* iface,long* plTop)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_DestinationHeight(IBasicVideo2* iface,long lHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_DestinationHeight(IBasicVideo2* iface,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnSetSourcePosition(IBasicVideo2* iface,long lLeft,long lTop,long lWidth,long lHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetSourcePosition(IBasicVideo2* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnSetDefaultSourcePosition(IBasicVideo2* iface)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnSetDestinationPosition(IBasicVideo2* iface,long lLeft,long lTop,long lWidth,long lHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetDestinationPosition(IBasicVideo2* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnSetDefaultDestinationPosition(IBasicVideo2* iface)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetVideoSize(IBasicVideo2* iface,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetVideoPaletteEntries(IBasicVideo2* iface,long lStart,long lCount,long* plRet,long* plPaletteEntry)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetCurrentImage(IBasicVideo2* iface,long* plBufferSize,long* plDIBBuffer)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnIsUsingDefaultSource(IBasicVideo2* iface)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnIsUsingDefaultDestination(IBasicVideo2* iface)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetPreferredAspectRatio(IBasicVideo2* iface,long* plRateX,long* plRateY)
+{
+	CFilterGraph_THIS(iface,basvid);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+
+
+static ICOM_VTABLE(IBasicVideo2) ibasicvideo =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IBasicVideo2_fnQueryInterface,
+	IBasicVideo2_fnAddRef,
+	IBasicVideo2_fnRelease,
+	/* IDispatch fields */
+	IBasicVideo2_fnGetTypeInfoCount,
+	IBasicVideo2_fnGetTypeInfo,
+	IBasicVideo2_fnGetIDsOfNames,
+	IBasicVideo2_fnInvoke,
+	/* IBasicVideo fields */
+	IBasicVideo2_fnget_AvgTimePerFrame,
+	IBasicVideo2_fnget_BitRate,
+	IBasicVideo2_fnget_BitErrorRate,
+	IBasicVideo2_fnget_VideoWidth,
+	IBasicVideo2_fnget_VideoHeight,
+	IBasicVideo2_fnput_SourceLeft,
+	IBasicVideo2_fnget_SourceLeft,
+	IBasicVideo2_fnput_SourceWidth,
+	IBasicVideo2_fnget_SourceWidth,
+	IBasicVideo2_fnput_SourceTop,
+	IBasicVideo2_fnget_SourceTop,
+	IBasicVideo2_fnput_SourceHeight,
+	IBasicVideo2_fnget_SourceHeight,
+	IBasicVideo2_fnput_DestinationLeft,
+	IBasicVideo2_fnget_DestinationLeft,
+	IBasicVideo2_fnput_DestinationWidth,
+	IBasicVideo2_fnget_DestinationWidth,
+	IBasicVideo2_fnput_DestinationTop,
+	IBasicVideo2_fnget_DestinationTop,
+	IBasicVideo2_fnput_DestinationHeight,
+	IBasicVideo2_fnget_DestinationHeight,
+	IBasicVideo2_fnSetSourcePosition,
+	IBasicVideo2_fnGetSourcePosition,
+	IBasicVideo2_fnSetDefaultSourcePosition,
+	IBasicVideo2_fnSetDestinationPosition,
+	IBasicVideo2_fnGetDestinationPosition,
+	IBasicVideo2_fnSetDefaultDestinationPosition,
+	IBasicVideo2_fnGetVideoSize,
+	IBasicVideo2_fnGetVideoPaletteEntries,
+	IBasicVideo2_fnGetCurrentImage,
+	IBasicVideo2_fnIsUsingDefaultSource,
+	IBasicVideo2_fnIsUsingDefaultDestination,
+	/* IBasicVideo2 fields */
+	IBasicVideo2_fnGetPreferredAspectRatio,
+};
+
+
+void CFilterGraph_InitIBasicVideo2( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->basvid) = &ibasicvideo;
+}
+
diff --git a/dlls/quartz/ifgraph.c b/dlls/quartz/ifgraph.c
index a28ec06..8d2697b 100644
--- a/dlls/quartz/ifgraph.c
+++ b/dlls/quartz/ifgraph.c
@@ -14,7 +14,9 @@
 #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"
@@ -30,7 +32,7 @@
 
 	TRACE("(%p)->()\n",This);
 
-	return IUnknown_QueryInterface((IUnknown*)(&This->unk),riid,ppobj);
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
 }
 
 static ULONG WINAPI
@@ -40,7 +42,7 @@
 
 	TRACE("(%p)->()\n",This);
 
-	return IUnknown_AddRef((IUnknown*)(&This->unk));
+	return IUnknown_AddRef(This->unk.punkControl);
 }
 
 static ULONG WINAPI
@@ -50,7 +52,7 @@
 
 	TRACE("(%p)->()\n",This);
 
-	return IUnknown_Release((IUnknown*)(&This->unk));
+	return IUnknown_Release(This->unk.punkControl);
 }
 
 static HRESULT WINAPI
diff --git a/dlls/quartz/imcntl.c b/dlls/quartz/imcntl.c
new file mode 100644
index 0000000..5777c36
--- /dev/null
+++ b/dlls/quartz/imcntl.c
@@ -0,0 +1,220 @@
+/*
+ * Implementation of IMediaControl for FilterGraph.
+ *
+ * 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 "fgraph.h"
+
+
+
+static HRESULT WINAPI
+IMediaControl_fnQueryInterface(IMediaControl* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IMediaControl_fnAddRef(IMediaControl* iface)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IMediaControl_fnRelease(IMediaControl* iface)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IMediaControl_fnGetTypeInfoCount(IMediaControl* iface,UINT* pcTypeInfo)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaControl_fnGetTypeInfo(IMediaControl* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaControl_fnGetIDsOfNames(IMediaControl* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaControl_fnInvoke(IMediaControl* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static HRESULT WINAPI
+IMediaControl_fnRun(IMediaControl* iface)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaControl_fnPause(IMediaControl* iface)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaControl_fnStop(IMediaControl* iface)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaControl_fnGetState(IMediaControl* iface,LONG lTimeOut,OAFilterState* pFilterState)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaControl_fnRenderFile(IMediaControl* iface,BSTR bstrFileName)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaControl_fnAddSourceFilter(IMediaControl* iface,BSTR bstrFileName,IDispatch** ppobj)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaControl_fnget_FilterCollection(IMediaControl* iface,IDispatch** ppobj)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaControl_fnget_RegFilterCollection(IMediaControl* iface,IDispatch** ppobj)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaControl_fnStopWhenReady(IMediaControl* iface)
+{
+	CFilterGraph_THIS(iface,mediacontrol);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static ICOM_VTABLE(IMediaControl) imediacontrol =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IMediaControl_fnQueryInterface,
+	IMediaControl_fnAddRef,
+	IMediaControl_fnRelease,
+	/* IDispatch fields */
+	IMediaControl_fnGetTypeInfoCount,
+	IMediaControl_fnGetTypeInfo,
+	IMediaControl_fnGetIDsOfNames,
+	IMediaControl_fnInvoke,
+	/* IMediaControl fields */
+	IMediaControl_fnRun,
+	IMediaControl_fnPause,
+	IMediaControl_fnStop,
+	IMediaControl_fnGetState,
+	IMediaControl_fnRenderFile,
+	IMediaControl_fnAddSourceFilter,
+	IMediaControl_fnget_FilterCollection,
+	IMediaControl_fnget_RegFilterCollection,
+	IMediaControl_fnStopWhenReady,
+};
+
+
+void CFilterGraph_InitIMediaControl( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->mediacontrol) = &imediacontrol;
+}
diff --git a/dlls/quartz/imem.c b/dlls/quartz/imem.c
index dcf335e..5d7b1d6 100644
--- a/dlls/quartz/imem.c
+++ b/dlls/quartz/imem.c
@@ -30,7 +30,7 @@
 
 	TRACE("(%p)->()\n",This);
 
-	return IUnknown_QueryInterface((IUnknown*)(&This->unk),riid,ppobj);
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
 }
 
 static ULONG WINAPI
@@ -40,7 +40,7 @@
 
 	TRACE("(%p)->()\n",This);
 
-	return IUnknown_AddRef((IUnknown*)(&This->unk));
+	return IUnknown_AddRef(This->unk.punkControl);
 }
 
 static ULONG WINAPI
@@ -50,7 +50,7 @@
 
 	TRACE("(%p)->()\n",This);
 
-	return IUnknown_Release((IUnknown*)(&This->unk));
+	return IUnknown_Release(This->unk.punkControl);
 }
 
 static HRESULT WINAPI
diff --git a/dlls/quartz/imevent.c b/dlls/quartz/imevent.c
new file mode 100644
index 0000000..676d50d
--- /dev/null
+++ b/dlls/quartz/imevent.c
@@ -0,0 +1,222 @@
+/*
+ * Implementation of IMediaEvent[Ex] for FilterGraph.
+ *
+ * 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 "fgraph.h"
+
+
+
+static HRESULT WINAPI
+IMediaEventEx_fnQueryInterface(IMediaEventEx* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IMediaEventEx_fnAddRef(IMediaEventEx* iface)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IMediaEventEx_fnRelease(IMediaEventEx* iface)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnGetTypeInfoCount(IMediaEventEx* iface,UINT* pcTypeInfo)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnGetTypeInfo(IMediaEventEx* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnGetIDsOfNames(IMediaEventEx* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnInvoke(IMediaEventEx* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static HRESULT WINAPI
+IMediaEventEx_fnGetEventHandle(IMediaEventEx* iface,OAEVENT* hEvent)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnGetEvent(IMediaEventEx* iface,long* lEventCode,LONG_PTR* plParam1,LONG_PTR* plParam2,long lTimeOut)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnWaitForCompletion(IMediaEventEx* iface,long lTimeOut,long* plEventCode)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnCancelDefaultHandling(IMediaEventEx* iface,long lEventCode)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnRestoreDefaultHandling(IMediaEventEx* iface,long lEventCode)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnFreeEventParams(IMediaEventEx* iface,long lEventCode,LONG_PTR lParam1,LONG_PTR lParam2)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnSetNotifyWindow(IMediaEventEx* iface,OAHWND hwnd,long message,LONG_PTR lParam)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnSetNotifyFlags(IMediaEventEx* iface,long lNotifyFlags)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnGetNotifyFlags(IMediaEventEx* iface,long* plNotifyFlags)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+
+static ICOM_VTABLE(IMediaEventEx) imediaevent =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IMediaEventEx_fnQueryInterface,
+	IMediaEventEx_fnAddRef,
+	IMediaEventEx_fnRelease,
+	/* IDispatch fields */
+	IMediaEventEx_fnGetTypeInfoCount,
+	IMediaEventEx_fnGetTypeInfo,
+	IMediaEventEx_fnGetIDsOfNames,
+	IMediaEventEx_fnInvoke,
+	/* IMediaEvent fields */
+	IMediaEventEx_fnGetEventHandle,
+	IMediaEventEx_fnGetEvent,
+	IMediaEventEx_fnWaitForCompletion,
+	IMediaEventEx_fnCancelDefaultHandling,
+	IMediaEventEx_fnRestoreDefaultHandling,
+	IMediaEventEx_fnFreeEventParams,
+	/* IMediaEventEx fields */
+	IMediaEventEx_fnSetNotifyWindow,
+	IMediaEventEx_fnSetNotifyFlags,
+	IMediaEventEx_fnGetNotifyFlags,
+};
+
+
+void CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->mediaevent) = &imediaevent;
+}
diff --git a/dlls/quartz/impos.c b/dlls/quartz/impos.c
new file mode 100644
index 0000000..3a0300d
--- /dev/null
+++ b/dlls/quartz/impos.c
@@ -0,0 +1,241 @@
+/*
+ * Implementation of IMediaPosition for FilterGraph.
+ *
+ * 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 "fgraph.h"
+
+
+static HRESULT WINAPI
+IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IMediaPosition_fnAddRef(IMediaPosition* iface)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IMediaPosition_fnRelease(IMediaPosition* iface)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnInvoke(IMediaPosition* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static HRESULT WINAPI
+IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
+{
+	CFilterGraph_THIS(iface,mediaposition);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static ICOM_VTABLE(IMediaPosition) imediaposition =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IMediaPosition_fnQueryInterface,
+	IMediaPosition_fnAddRef,
+	IMediaPosition_fnRelease,
+	/* IDispatch fields */
+	IMediaPosition_fnGetTypeInfoCount,
+	IMediaPosition_fnGetTypeInfo,
+	IMediaPosition_fnGetIDsOfNames,
+	IMediaPosition_fnInvoke,
+	/* IMediaPosition fields */
+	IMediaPosition_fnget_Duration,
+	IMediaPosition_fnput_CurrentPosition,
+	IMediaPosition_fnget_CurrentPosition,
+	IMediaPosition_fnget_StopTime,
+	IMediaPosition_fnput_StopTime,
+	IMediaPosition_fnget_PrerollTime,
+	IMediaPosition_fnput_PrerollTime,
+	IMediaPosition_fnput_Rate,
+	IMediaPosition_fnget_Rate,
+	IMediaPosition_fnCanSeekForward,
+	IMediaPosition_fnCanSeekBackward,
+};
+
+
+void CFilterGraph_InitIMediaPosition( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->mediaposition) = &imediaposition;
+}
diff --git a/dlls/quartz/imseek.c b/dlls/quartz/imseek.c
new file mode 100644
index 0000000..9df7eb8
--- /dev/null
+++ b/dlls/quartz/imseek.c
@@ -0,0 +1,264 @@
+/*
+ * Implementation of IMediaSeeking for FilterGraph.
+ *
+ * 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 "fgraph.h"
+
+
+
+static HRESULT WINAPI
+IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IMediaSeeking_fnAddRef(IMediaSeeking* iface)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IMediaSeeking_fnRelease(IMediaSeeking* iface)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll)
+{
+	CFilterGraph_THIS(iface,mediaseeking);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+
+
+static ICOM_VTABLE(IMediaSeeking) imediaseeking =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IMediaSeeking_fnQueryInterface,
+	IMediaSeeking_fnAddRef,
+	IMediaSeeking_fnRelease,
+	/* IMediaSeeking fields */
+	IMediaSeeking_fnGetCapabilities,
+	IMediaSeeking_fnCheckCapabilities,
+	IMediaSeeking_fnIsFormatSupported,
+	IMediaSeeking_fnQueryPreferredFormat,
+	IMediaSeeking_fnGetTimeFormat,
+	IMediaSeeking_fnIsUsingTimeFormat,
+	IMediaSeeking_fnSetTimeFormat,
+	IMediaSeeking_fnGetDuration,
+	IMediaSeeking_fnGetStopPosition,
+	IMediaSeeking_fnGetCurrentPosition,
+	IMediaSeeking_fnConvertTimeFormat,
+	IMediaSeeking_fnSetPositions,
+	IMediaSeeking_fnGetPositions,
+	IMediaSeeking_fnGetAvailable,
+	IMediaSeeking_fnSetRate,
+	IMediaSeeking_fnGetRate,
+	IMediaSeeking_fnGetPreroll,
+};
+
+void CFilterGraph_InitIMediaSeeking( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->mediaseeking) = &imediaseeking;
+}
diff --git a/dlls/quartz/irclock.c b/dlls/quartz/irclock.c
index 24bf110..a780774 100644
--- a/dlls/quartz/irclock.c
+++ b/dlls/quartz/irclock.c
@@ -30,7 +30,7 @@
 
 	TRACE("(%p)->()\n",This);
 
-	return IUnknown_QueryInterface((IUnknown*)(&This->unk),riid,ppobj);
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
 }
 
 static ULONG WINAPI
@@ -40,7 +40,7 @@
 
 	TRACE("(%p)->()\n",This);
 
-	return IUnknown_AddRef((IUnknown*)(&This->unk));
+	return IUnknown_AddRef(This->unk.punkControl);
 }
 
 static ULONG WINAPI
@@ -50,7 +50,7 @@
 
 	TRACE("(%p)->()\n",This);
 
-	return IUnknown_Release((IUnknown*)(&This->unk));
+	return IUnknown_Release(This->unk.punkControl);
 }
 
 static HRESULT WINAPI
diff --git a/dlls/quartz/iunk.c b/dlls/quartz/iunk.c
index 5268cda..cfb2fc7 100644
--- a/dlls/quartz/iunk.c
+++ b/dlls/quartz/iunk.c
@@ -31,26 +31,30 @@
 	*ppobj = NULL;
 
 	ofs = 0;
-	for ( dwIndex = 0; dwIndex < This->dwEntries; dwIndex++ )
-	{
-		if ( IsEqualGUID( This->pEntries[dwIndex].piid, riid ) )
-		{
-			ofs = This->pEntries[dwIndex].ofsVTPtr;
-			break;
-		}
-	}
 
-	if ( dwIndex == This->dwEntries )
+	if ( IsEqualGUID( &IID_IUnknown, riid ) )
 	{
-		if ( !IsEqualGUID( &IID_IUnknown, riid ) )
+		TRACE("IID_IUnknown - returns inner object.\n");
+	}
+	else
+	{
+		for ( dwIndex = 0; dwIndex < This->dwEntries; dwIndex++ )
 		{
-			TRACE("unknown interface: %s\n",debugstr_guid(riid));
+			if ( IsEqualGUID( This->pEntries[dwIndex].piid, riid ) )
+			{
+				ofs = This->pEntries[dwIndex].ofsVTPtr;
+				break;
+			}
+		}
+		if ( dwIndex == This->dwEntries )
+		{
+			FIXME("unknown interface: %s\n",debugstr_guid(riid));
 			return E_NOINTERFACE;
 		}
 	}
 
 	*ppobj = (LPVOID)(((char*)This) + ofs);
-	IUnknown_AddRef(iface);
+	IUnknown_AddRef((IUnknown*)(*ppobj));
 
 	return S_OK;
 }
@@ -89,7 +93,7 @@
 };
 
 
-void QUARTZ_IUnkInit( QUARTZ_IUnkImpl* pImpl )
+void QUARTZ_IUnkInit( QUARTZ_IUnkImpl* pImpl, IUnknown* punkOuter )
 {
 	TRACE("(%p)\n",pImpl);
 
@@ -97,4 +101,10 @@
 	pImpl->pEntries = NULL;
 	pImpl->dwEntries = 0;
 	pImpl->ref = 1;
+	pImpl->punkControl = (IUnknown*)pImpl;
+
+	/* for delegation. */
+	if ( punkOuter != NULL )
+		pImpl->punkControl = punkOuter;
 }
+
diff --git a/dlls/quartz/iunk.h b/dlls/quartz/iunk.h
index 8ace995..d0ffa58 100644
--- a/dlls/quartz/iunk.h
+++ b/dlls/quartz/iunk.h
@@ -41,10 +41,11 @@
 
 	/* IUnknown fields. */
 	ULONG	ref;
+	IUnknown*	punkControl;
 } QUARTZ_IUnkImpl;
 
 
-void QUARTZ_IUnkInit( QUARTZ_IUnkImpl* pImpl );
+void QUARTZ_IUnkInit( QUARTZ_IUnkImpl* pImpl, IUnknown* punkOuter );
 
 
 #endif	/* WINE_DSHOW_IUNK_H */
diff --git a/dlls/quartz/ividwin.c b/dlls/quartz/ividwin.c
new file mode 100644
index 0000000..3c6a42e
--- /dev/null
+++ b/dlls/quartz/ividwin.c
@@ -0,0 +1,554 @@
+/*
+ * Implementation of IVideoWindow for FilterGraph.
+ *
+ * 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 "fgraph.h"
+
+
+
+static HRESULT WINAPI
+IVideoWindow_fnQueryInterface(IVideoWindow* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IVideoWindow_fnAddRef(IVideoWindow* iface)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IVideoWindow_fnRelease(IVideoWindow* iface)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnGetTypeInfoCount(IVideoWindow* iface,UINT* pcTypeInfo)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnGetTypeInfo(IVideoWindow* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnGetIDsOfNames(IVideoWindow* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnInvoke(IVideoWindow* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Caption(IVideoWindow* iface,BSTR strCaption)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Caption(IVideoWindow* iface,BSTR* pstrCaption)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_WindowStyle(IVideoWindow* iface,long lStyle)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_WindowStyle(IVideoWindow* iface,long* plStyle)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_WindowStyleEx(IVideoWindow* iface,long lExStyle)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_WindowStyleEx(IVideoWindow* iface,long* plExStyle)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_AutoShow(IVideoWindow* iface,long lAutoShow)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_AutoShow(IVideoWindow* iface,long* plAutoShow)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_WindowState(IVideoWindow* iface,long lState)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_WindowState(IVideoWindow* iface,long* plState)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_BackgroundPalette(IVideoWindow* iface,long lBackPal)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_BackgroundPalette(IVideoWindow* iface,long* plBackPal)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Visible(IVideoWindow* iface,long lVisible)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Visible(IVideoWindow* iface,long* plVisible)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Left(IVideoWindow* iface,long lLeft)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Left(IVideoWindow* iface,long* plLeft)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Width(IVideoWindow* iface,long lWidth)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Width(IVideoWindow* iface,long* plWidth)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Top(IVideoWindow* iface,long lTop)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Top(IVideoWindow* iface,long* plTop)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Height(IVideoWindow* iface,long lHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Height(IVideoWindow* iface,long* plHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Owner(IVideoWindow* iface,OAHWND hwnd)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Owner(IVideoWindow* iface,OAHWND* phwnd)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_MessageDrain(IVideoWindow* iface,OAHWND hwnd)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_MessageDrain(IVideoWindow* iface,OAHWND* phwnd)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_BorderColor(IVideoWindow* iface,long* plColor)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_BorderColor(IVideoWindow* iface,long lColor)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_FullScreenMode(IVideoWindow* iface,long* plMode)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_FullScreenMode(IVideoWindow* iface,long lMode)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnSetWindowForeground(IVideoWindow* iface,long lFocus)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnNotifyOwnerMessage(IVideoWindow* iface,OAHWND hwnd,long message,LONG_PTR wParam,LONG_PTR lParam)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnSetWindowPosition(IVideoWindow* iface,long lLeft,long lTop,long lWidth,long lHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnGetWindowPosition(IVideoWindow* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnGetMinIdealImageSize(IVideoWindow* iface,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnGetMaxIdealImageSize(IVideoWindow* iface,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnGetRestorePosition(IVideoWindow* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnHideCursor(IVideoWindow* iface,long lHide)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnIsCursorHidden(IVideoWindow* iface,long* plHide)
+{
+	CFilterGraph_THIS(iface,vidwin);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+
+
+static ICOM_VTABLE(IVideoWindow) ivideowindow =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IVideoWindow_fnQueryInterface,
+	IVideoWindow_fnAddRef,
+	IVideoWindow_fnRelease,
+	/* IDispatch fields */
+	IVideoWindow_fnGetTypeInfoCount,
+	IVideoWindow_fnGetTypeInfo,
+	IVideoWindow_fnGetIDsOfNames,
+	IVideoWindow_fnInvoke,
+	/* IVideoWindow fields */
+	IVideoWindow_fnput_Caption,
+	IVideoWindow_fnget_Caption,
+	IVideoWindow_fnput_WindowStyle,
+	IVideoWindow_fnget_WindowStyle,
+	IVideoWindow_fnput_WindowStyleEx,
+	IVideoWindow_fnget_WindowStyleEx,
+	IVideoWindow_fnput_AutoShow,
+	IVideoWindow_fnget_AutoShow,
+	IVideoWindow_fnput_WindowState,
+	IVideoWindow_fnget_WindowState,
+	IVideoWindow_fnput_BackgroundPalette,
+	IVideoWindow_fnget_BackgroundPalette,
+	IVideoWindow_fnput_Visible,
+	IVideoWindow_fnget_Visible,
+	IVideoWindow_fnput_Left,
+	IVideoWindow_fnget_Left,
+	IVideoWindow_fnput_Width,
+	IVideoWindow_fnget_Width,
+	IVideoWindow_fnput_Top,
+	IVideoWindow_fnget_Top,
+	IVideoWindow_fnput_Height,
+	IVideoWindow_fnget_Height,
+	IVideoWindow_fnput_Owner,
+	IVideoWindow_fnget_Owner,
+	IVideoWindow_fnput_MessageDrain,
+	IVideoWindow_fnget_MessageDrain,
+	IVideoWindow_fnget_BorderColor,
+	IVideoWindow_fnput_BorderColor,
+	IVideoWindow_fnget_FullScreenMode,
+	IVideoWindow_fnput_FullScreenMode,
+	IVideoWindow_fnSetWindowForeground,
+	IVideoWindow_fnNotifyOwnerMessage,
+	IVideoWindow_fnSetWindowPosition,
+	IVideoWindow_fnGetWindowPosition,
+	IVideoWindow_fnGetMinIdealImageSize,
+	IVideoWindow_fnGetMaxIdealImageSize,
+	IVideoWindow_fnGetRestorePosition,
+	IVideoWindow_fnHideCursor,
+	IVideoWindow_fnIsCursorHidden,
+
+};
+
+
+void CFilterGraph_InitIVideoWindow( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->vidwin) = &ivideowindow;
+}
diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c
index d0f88d6..6ac700e 100644
--- a/dlls/quartz/main.c
+++ b/dlls/quartz/main.c
@@ -5,7 +5,9 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "ole2.h"
+#include "wine/obj_oleaut.h"
 #include "strmif.h"
+#include "control.h"
 #include "uuids.h"
 
 #include "debugtools.h"
@@ -145,6 +147,8 @@
 
 	if ( ppobj == NULL )
 		return E_POINTER;
+	if ( pOuter != NULL && !IsEqualGUID( riid, &IID_IUnknown ) )
+		return CLASS_E_NOAGGREGATION;
 
 	*ppobj = NULL;
 
diff --git a/dlls/quartz/memalloc.c b/dlls/quartz/memalloc.c
index 894d548..16410bf 100644
--- a/dlls/quartz/memalloc.c
+++ b/dlls/quartz/memalloc.c
@@ -39,13 +39,13 @@
 	if ( pma == NULL )
 		return E_OUTOFMEMORY;
 
-	QUARTZ_IUnkInit( &pma->unk );
+	QUARTZ_IUnkInit( &pma->unk, punkOuter );
 	CMemoryAllocator_InitIMemAllocator( pma );
 
 	pma->unk.pEntries = IFEntries;
 	pma->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
 
-	*ppobj = (void*)pma;
+	*ppobj = (void*)(&pma->unk);
 
 	return S_OK;
 }
diff --git a/dlls/quartz/sysclock.c b/dlls/quartz/sysclock.c
index ca35ac2..fd611b8 100644
--- a/dlls/quartz/sysclock.c
+++ b/dlls/quartz/sysclock.c
@@ -39,13 +39,13 @@
 	if ( psc == NULL )
 		return E_OUTOFMEMORY;
 
-	QUARTZ_IUnkInit( &psc->unk );
+	QUARTZ_IUnkInit( &psc->unk, punkOuter );
 	CSystemClock_InitIReferenceClock( psc );
 
 	psc->unk.pEntries = IFEntries;
 	psc->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
 
-	*ppobj = (void*)psc;
+	*ppobj = (void*)(&psc->unk);
 
 	return S_OK;
 }