Merged some C sources.
Fixed some bugs.
Started implementing some pass-through interfaces.

diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in
index 28e80f1..64fb6df 100644
--- a/dlls/quartz/Makefile.in
+++ b/dlls/quartz/Makefile.in
@@ -9,40 +9,30 @@
 SYMBOLFILE = $(MODULE).tmp.o
 
 C_SRCS = \
-	amerror.c \
 	amundoc.c \
+	basefilt.c \
+	basepin.c \
 	complist.c \
 	devenum.c \
 	devmon.c \
 	enumunk.c \
-	fgclsid.c \
+	fgevent.c \
 	fgidisp.c \
+	fgpass.c \
 	fgraph.c \
 	fmap.c \
 	fmap2.c \
-	ibasaud.c \
-	ibasvid.c \
-	idevenum.c \
 	ifgraph.c \
-	ifmap.c \
-	ifmap3.c \
+	igconfig.c \
 	igrver.c \
 	imcntl.c \
-	imem.c \
-	imesink.c \
-	imevent.c \
 	imfilter.c \
 	impos.c \
 	imseek.c \
-	irclock.c \
 	iunk.c \
-	ividwin.c \
 	main.c \
 	memalloc.c \
-	monprop.c \
-	ptimpl.c \
-	ptmpos.c \
-	ptmseek.c \
+	mtype.c \
 	regsvr.c \
 	sample.c \
 	seekpass.c \
diff --git a/dlls/quartz/README b/dlls/quartz/README
new file mode 100644
index 0000000..d248fa0
--- /dev/null
+++ b/dlls/quartz/README
@@ -0,0 +1,15 @@
+
+TODO
+
+  - merge some C sources.
+  - implements all filters.
+  - handles plug-in distributor.
+  - implements some interfaces as plug-ins(???)
+  - implements ICM
+  - implements mciqtz(mci driver for quartz)
+
+known BUGS
+
+  - all FIXMEs.
+  - some filters crash at CoCreateInstance. (ole???)
+
diff --git a/dlls/quartz/amerror.c b/dlls/quartz/amerror.c
deleted file mode 100644
index 73a37fa..0000000
--- a/dlls/quartz/amerror.c
+++ /dev/null
@@ -1,225 +0,0 @@
-
-#include "config.h"
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winerror.h"
-#include "winnls.h"
-#include "wine/obj_base.h"
-#include "strmif.h"
-#include "errors.h"
-
-#include "debugtools.h"
-DEFAULT_DEBUG_CHANNEL(quartz);
-
-
-static
-LPWSTR QUARTZ_strncpyAtoW( LPWSTR lpwstr, LPCSTR lpstr, INT wbuflen )
-{
-	INT	len;
-
-	len = MultiByteToWideChar( CP_ACP, 0, lpstr, -1, lpwstr, wbuflen );
-	if ( len == 0 )
-		*lpwstr = 0;
-	return lpwstr;
-}
-
-
-static LPCSTR hresult_to_string( HRESULT hr )
-{
-	switch ( hr )
-	{
-	#define	ENTRY(x)	case x: return (const char*)#x
-	/* some known codes */
-	ENTRY(S_OK);
-	ENTRY(S_FALSE);
-	ENTRY(E_FAIL);
-	ENTRY(E_POINTER);
-	ENTRY(E_NOTIMPL);
-	ENTRY(E_NOINTERFACE);
-	ENTRY(E_OUTOFMEMORY);
-	ENTRY(CLASS_E_CLASSNOTAVAILABLE);
-	ENTRY(CLASS_E_NOAGGREGATION);
-
-	/* vfwmsgs.h */
-	ENTRY(VFW_S_NO_MORE_ITEMS);
-	ENTRY(VFW_E_BAD_KEY);
-	ENTRY(VFW_E_INVALIDMEDIATYPE);
-	ENTRY(VFW_E_INVALIDSUBTYPE);
-	ENTRY(VFW_E_NEED_OWNER);
-	ENTRY(VFW_E_ENUM_OUT_OF_SYNC);
-	ENTRY(VFW_E_ALREADY_CONNECTED);
-	ENTRY(VFW_E_FILTER_ACTIVE);
-	ENTRY(VFW_E_NO_TYPES);
-	ENTRY(VFW_E_NO_ACCEPTABLE_TYPES);
-	ENTRY(VFW_E_INVALID_DIRECTION);
-	ENTRY(VFW_E_NOT_CONNECTED);
-	ENTRY(VFW_E_NO_ALLOCATOR);
-	ENTRY(VFW_E_RUNTIME_ERROR);
-	ENTRY(VFW_E_BUFFER_NOTSET);
-	ENTRY(VFW_E_BUFFER_OVERFLOW);
-	ENTRY(VFW_E_BADALIGN);
-	ENTRY(VFW_E_ALREADY_COMMITTED);
-	ENTRY(VFW_E_BUFFERS_OUTSTANDING);
-	ENTRY(VFW_E_NOT_COMMITTED);
-	ENTRY(VFW_E_SIZENOTSET);
-	ENTRY(VFW_E_NO_CLOCK);
-	ENTRY(VFW_E_NO_SINK);
-	ENTRY(VFW_E_NO_INTERFACE);
-	ENTRY(VFW_E_NOT_FOUND);
-	ENTRY(VFW_E_CANNOT_CONNECT);
-	ENTRY(VFW_E_CANNOT_RENDER);
-	ENTRY(VFW_E_CHANGING_FORMAT);
-	ENTRY(VFW_E_NO_COLOR_KEY_SET);
-	ENTRY(VFW_E_NOT_OVERLAY_CONNECTION);
-	ENTRY(VFW_E_NOT_SAMPLE_CONNECTION);
-	ENTRY(VFW_E_PALETTE_SET);
-	ENTRY(VFW_E_COLOR_KEY_SET);
-	ENTRY(VFW_E_NO_COLOR_KEY_FOUND);
-	ENTRY(VFW_E_NO_PALETTE_AVAILABLE);
-	ENTRY(VFW_E_NO_DISPLAY_PALETTE);
-	ENTRY(VFW_E_TOO_MANY_COLORS);
-	ENTRY(VFW_E_STATE_CHANGED);
-	ENTRY(VFW_E_NOT_STOPPED);
-	ENTRY(VFW_E_NOT_PAUSED);
-	ENTRY(VFW_E_NOT_RUNNING);
-	ENTRY(VFW_E_WRONG_STATE);
-	ENTRY(VFW_E_START_TIME_AFTER_END);
-	ENTRY(VFW_E_INVALID_RECT);
-	ENTRY(VFW_E_TYPE_NOT_ACCEPTED);
-	ENTRY(VFW_E_SAMPLE_REJECTED);
-	ENTRY(VFW_E_SAMPLE_REJECTED_EOS);
-	ENTRY(VFW_S_DUPLICATE_NAME);
-	ENTRY(VFW_E_DUPLICATE_NAME);
-	ENTRY(VFW_E_TIMEOUT);
-	ENTRY(VFW_E_INVALID_FILE_FORMAT);
-	ENTRY(VFW_E_ENUM_OUT_OF_RANGE);
-	ENTRY(VFW_E_CIRCULAR_GRAPH);
-	ENTRY(VFW_E_NOT_ALLOWED_TO_SAVE);
-	ENTRY(VFW_E_TIME_ALREADY_PASSED);
-	ENTRY(VFW_E_ALREADY_CANCELLED);
-	ENTRY(VFW_E_CORRUPT_GRAPH_FILE);
-	ENTRY(VFW_E_ADVISE_ALREADY_SET);
-	ENTRY(VFW_S_STATE_INTERMEDIATE);
-	ENTRY(VFW_E_NO_MODEX_AVAILABLE);
-	ENTRY(VFW_E_NO_ADVISE_SET);
-	ENTRY(VFW_E_NO_FULLSCREEN);
-	ENTRY(VFW_E_IN_FULLSCREEN_MODE);
-	ENTRY(VFW_E_UNKNOWN_FILE_TYPE);
-	ENTRY(VFW_E_CANNOT_LOAD_SOURCE_FILTER);
-	ENTRY(VFW_S_PARTIAL_RENDER);
-	ENTRY(VFW_E_FILE_TOO_SHORT);
-	ENTRY(VFW_E_INVALID_FILE_VERSION);
-	ENTRY(VFW_S_SOME_DATA_IGNORED);
-	ENTRY(VFW_S_CONNECTIONS_DEFERRED);
-	ENTRY(VFW_E_INVALID_CLSID);
-	ENTRY(VFW_E_INVALID_MEDIA_TYPE);
-	ENTRY(VFW_E_SAMPLE_TIME_NOT_SET);
-	ENTRY(VFW_S_RESOURCE_NOT_NEEDED);
-	ENTRY(VFW_E_MEDIA_TIME_NOT_SET);
-	ENTRY(VFW_E_NO_TIME_FORMAT_SET);
-	ENTRY(VFW_E_MONO_AUDIO_HW);
-	ENTRY(VFW_S_MEDIA_TYPE_IGNORED);
-	ENTRY(VFW_E_NO_DECOMPRESSOR);
-	ENTRY(VFW_E_NO_AUDIO_HARDWARE);
-	ENTRY(VFW_S_VIDEO_NOT_RENDERED);
-	ENTRY(VFW_S_AUDIO_NOT_RENDERED);
-	ENTRY(VFW_E_RPZA);
-	ENTRY(VFW_S_RPZA);
-	ENTRY(VFW_E_PROCESSOR_NOT_SUITABLE);
-	ENTRY(VFW_E_UNSUPPORTED_AUDIO);
-	ENTRY(VFW_E_UNSUPPORTED_VIDEO);
-	ENTRY(VFW_E_MPEG_NOT_CONSTRAINED);
-	ENTRY(VFW_E_NOT_IN_GRAPH);
-	ENTRY(VFW_S_ESTIMATED);
-	ENTRY(VFW_E_NO_TIME_FORMAT);
-	ENTRY(VFW_E_READ_ONLY);
-	ENTRY(VFW_S_RESERVED);
-	ENTRY(VFW_E_BUFFER_UNDERFLOW);
-	ENTRY(VFW_E_UNSUPPORTED_STREAM);
-	ENTRY(VFW_E_NO_TRANSPORT);
-	ENTRY(VFW_S_STREAM_OFF);
-	ENTRY(VFW_S_CANT_CUE);
-	ENTRY(VFW_E_BAD_VIDEOCD);
-	ENTRY(VFW_S_NO_STOP_TIME);
-	ENTRY(VFW_E_OUT_OF_VIDEO_MEMORY);
-	ENTRY(VFW_E_VP_NEGOTIATION_FAILED);
-	ENTRY(VFW_E_DDRAW_CAPS_NOT_SUITABLE);
-	ENTRY(VFW_E_NO_VP_HARDWARE);
-	ENTRY(VFW_E_NO_CAPTURE_HARDWARE);
-	ENTRY(VFW_E_DVD_OPERATION_INHIBITED);
-	ENTRY(VFW_E_DVD_INVALIDDOMAIN);
-	ENTRY(VFW_E_DVD_NO_BUTTON);
-	ENTRY(VFW_E_DVD_GRAPHNOTREADY);
-	ENTRY(VFW_E_DVD_RENDERFAIL);
-	ENTRY(VFW_E_DVD_DECNOTENOUGH);
-	ENTRY(VFW_E_DDRAW_VERSION_NOT_SUITABLE);
-	ENTRY(VFW_E_COPYPROT_FAILED);
-	ENTRY(VFW_S_NOPREVIEWPIN);
-	ENTRY(VFW_E_TIME_EXPIRED);
-	ENTRY(VFW_S_DVD_NON_ONE_SEQUENTIAL);
-	ENTRY(VFW_E_DVD_WRONG_SPEED);
-	ENTRY(VFW_E_DVD_MENU_DOES_NOT_EXIST);
-	ENTRY(VFW_E_DVD_CMD_CANCELLED);
-	ENTRY(VFW_E_DVD_STATE_WRONG_VERSION);
-	ENTRY(VFW_E_DVD_STATE_CORRUPT);
-	ENTRY(VFW_E_DVD_STATE_WRONG_DISC);
-	ENTRY(VFW_E_DVD_INCOMPATIBLE_REGION);
-	ENTRY(VFW_E_DVD_NO_ATTRIBUTES);
-	ENTRY(VFW_E_DVD_NO_GOUP_PGC);
-	ENTRY(VFW_E_DVD_LOW_PARENTAL_LEVEL);
-	ENTRY(VFW_E_DVD_NOT_IN_KARAOKE_MODE);
-	ENTRY(VFW_S_DVD_CHANNEL_CONTENTS_NOT_AVAILABLE);
-	ENTRY(VFW_S_DVD_NOT_ACCURATE);
-	ENTRY(VFW_E_FRAME_STEP_UNSUPPORTED);
-	ENTRY(VFW_E_DVD_STREAM_DISABLED);
-	ENTRY(VFW_E_DVD_TITLE_UNKNOWN);
-	ENTRY(VFW_E_DVD_INVALID_DISC);
-	ENTRY(VFW_E_DVD_NO_RESUME_INFORMATION);
-	ENTRY(VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD);
-	ENTRY(VFW_E_PIN_ALREADY_BLOCKED);
-	ENTRY(VFW_E_CERTIFICATION_FAILURE);
-	#undef	ENTRY
-	}
-
-	return NULL;
-}
-
-/***********************************************************************
- *	AMGetErrorTextA	(quartz.@)
- */
-DWORD WINAPI AMGetErrorTextA(HRESULT hr, LPSTR pszbuf, DWORD dwBufLen)
-{
-	LPCSTR	lpszRes;
-	DWORD len;
-
-	lpszRes = hresult_to_string( hr );
-	if ( lpszRes == NULL )
-		return 0;
-	len = (DWORD)(strlen(lpszRes)+1);
-	if ( len > dwBufLen )
-		return 0;
-
-	memcpy( pszbuf, lpszRes, len );
-	return len;
-}
-
-/***********************************************************************
- *	AMGetErrorTextW	(quartz.@)
- */
-DWORD WINAPI AMGetErrorTextW(HRESULT hr, LPWSTR pwszbuf, DWORD dwBufLen)
-{
-	CHAR	szBuf[MAX_ERROR_TEXT_LEN+1];
-	DWORD	dwLen;
-
-	dwLen = AMGetErrorTextA(hr,szBuf,MAX_ERROR_TEXT_LEN);
-	if ( dwLen == 0 )
-		return 0;
-	szBuf[dwLen] = 0;
-
-	QUARTZ_strncpyAtoW( pwszbuf, szBuf, dwBufLen );
-
-	return lstrlenW( pwszbuf );
-}
diff --git a/dlls/quartz/basefilt.c b/dlls/quartz/basefilt.c
new file mode 100644
index 0000000..1bb40f8
--- /dev/null
+++ b/dlls/quartz/basefilt.c
@@ -0,0 +1,453 @@
+/*
+ * Implements IBaseFilter. (internal)
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "strmif.h"
+#include "vfwmsgs.h"
+#include "wine/unicode.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "basefilt.h"
+#include "enumunk.h"
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnQueryInterface(IBaseFilter* iface,REFIID riid,void** ppobj)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+CBaseFilterImpl_fnAddRef(IBaseFilter* iface)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->punkControl);
+}
+
+static ULONG WINAPI
+CBaseFilterImpl_fnRelease(IBaseFilter* iface)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->punkControl);
+}
+
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnGetClassID(IBaseFilter* iface,CLSID* pclsid)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	if ( pclsid == NULL )
+		return E_POINTER;
+
+	memcpy( pclsid, This->pclsidFilter, sizeof(CLSID) );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnStop(IBaseFilter* iface)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	EnterCriticalSection( &This->csFilter );
+
+	/* FIXME - call OnStop() */
+
+	This->fstate = State_Stopped;
+	LeaveCriticalSection( &This->csFilter );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnPause(IBaseFilter* iface)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	EnterCriticalSection( &This->csFilter );
+
+	/* FIXME - call OnPause() */
+
+	This->fstate = State_Paused;
+
+	LeaveCriticalSection( &This->csFilter );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnRun(IBaseFilter* iface,REFERENCE_TIME rtStart)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	EnterCriticalSection( &This->csFilter );
+
+	/* FIXME - call OnRun() */
+
+	This->rtStart = rtStart;
+	This->fstate = State_Running;
+
+	LeaveCriticalSection( &This->csFilter );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnGetState(IBaseFilter* iface,DWORD dw,FILTER_STATE* pState)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	TRACE("(%p)->(%p)\n",This,pState);
+
+	if ( pState == NULL )
+		return E_POINTER;
+
+	/* FIXME - ignore 'intermediate state' now */
+
+	EnterCriticalSection( &This->csFilter );
+	*pState = This->fstate;
+	LeaveCriticalSection( &This->csFilter );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnSetSyncSource(IBaseFilter* iface,IReferenceClock* pobjClock)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	TRACE("(%p)->(%p)\n",This,pobjClock);
+
+	EnterCriticalSection( &This->csFilter );
+
+	if ( This->pClock != NULL )
+	{
+		IReferenceClock_Release( This->pClock );
+		This->pClock = NULL;
+	}
+
+	This->pClock = pobjClock;
+	if ( pobjClock != NULL )
+		IReferenceClock_AddRef( pobjClock );
+
+	LeaveCriticalSection( &This->csFilter );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnGetSyncSource(IBaseFilter* iface,IReferenceClock** ppobjClock)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+	HRESULT hr = VFW_E_NO_CLOCK;
+
+	TRACE("(%p)->(%p)\n",This,ppobjClock);
+
+	if ( ppobjClock == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->csFilter );
+
+	*ppobjClock = This->pClock;
+	if ( This->pClock != NULL )
+	{
+		hr = NOERROR;
+		IReferenceClock_AddRef( This->pClock );
+	}
+
+	LeaveCriticalSection( &This->csFilter );
+
+	return hr;
+}
+
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnEnumPins(IBaseFilter* iface,IEnumPins** ppenum)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+	HRESULT	hr = E_FAIL;
+	QUARTZ_CompList*	pListPins;
+	QUARTZ_CompListItem*	pItem;
+	IUnknown*	punkPin;
+
+	TRACE("(%p)->(%p)\n",This,ppenum);
+
+	if ( ppenum == NULL )
+		return E_POINTER;
+	*ppenum = NULL;
+
+	pListPins = QUARTZ_CompList_Alloc();
+	if ( pListPins == NULL )
+		return E_OUTOFMEMORY;
+
+	QUARTZ_CompList_Lock( This->pInPins );
+	QUARTZ_CompList_Lock( This->pOutPins );
+
+	pItem = QUARTZ_CompList_GetFirst( This->pInPins );
+	while ( pItem != NULL )
+	{
+		punkPin = QUARTZ_CompList_GetItemPtr( pItem );
+		hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
+		if ( FAILED(hr) )
+			goto err;
+		pItem = QUARTZ_CompList_GetNext( This->pInPins, pItem );
+	}
+
+	pItem = QUARTZ_CompList_GetFirst( This->pOutPins );
+	while ( pItem != NULL )
+	{
+		punkPin = QUARTZ_CompList_GetItemPtr( pItem );
+		hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
+		if ( FAILED(hr) )
+			goto err;
+		pItem = QUARTZ_CompList_GetNext( This->pOutPins, pItem );
+	}
+
+	hr = QUARTZ_CreateEnumUnknown(
+		&IID_IEnumPins, (void**)ppenum, pListPins );
+err:
+	QUARTZ_CompList_Unlock( This->pInPins );
+	QUARTZ_CompList_Unlock( This->pOutPins );
+
+	QUARTZ_CompList_Free( pListPins );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnFindPin(IBaseFilter* iface,LPCWSTR lpwszId,IPin** ppobj)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	FIXME("(%p)->(%s,%p) stub!\n",This,debugstr_w(lpwszId),ppobj);
+
+	if ( ppobj == NULL )
+		return E_POINTER;
+
+
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnQueryFilterInfo(IBaseFilter* iface,FILTER_INFO* pfi)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	TRACE("(%p)->(%p)\n",This,pfi);
+
+	if ( pfi == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->csFilter );
+
+	if ( This->cbNameGraph <= sizeof(WCHAR)*MAX_FILTER_NAME )
+	{
+		memcpy( pfi->achName, This->pwszNameGraph, This->cbNameGraph );
+	}
+	else
+	{
+		memcpy( pfi->achName, This->pwszNameGraph,
+				sizeof(WCHAR)*MAX_FILTER_NAME );
+		pfi->achName[MAX_FILTER_NAME-1] = (WCHAR)0;
+	}
+
+	pfi->pGraph = This->pfg;
+	if ( pfi->pGraph != NULL )
+		IFilterGraph_AddRef(pfi->pGraph);
+
+	LeaveCriticalSection( &This->csFilter );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnJoinFilterGraph(IBaseFilter* iface,IFilterGraph* pfg,LPCWSTR lpwszName)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+	HRESULT	hr;
+
+	TRACE("(%p)->(%p,%s)\n",This,pfg,debugstr_w(lpwszName));
+
+	EnterCriticalSection( &This->csFilter );
+
+	if ( This->pwszNameGraph != NULL )
+	{
+		QUARTZ_FreeMem( This->pwszNameGraph );
+		This->pwszNameGraph = NULL;
+		This->cbNameGraph = 0;
+	}
+
+	This->pfg = pfg;
+	This->cbNameGraph = sizeof(WCHAR) * (strlenW(lpwszName)+1);
+	This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
+	if ( This->pwszNameGraph == NULL )
+	{
+		hr = E_OUTOFMEMORY;
+		goto err;
+	}
+	memcpy( This->pwszNameGraph, lpwszName, This->cbNameGraph );
+
+	hr = NOERROR;
+err:
+	LeaveCriticalSection( &This->csFilter );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+CBaseFilterImpl_fnQueryVendorInfo(IBaseFilter* iface,LPWSTR* lpwszVendor)
+{
+	ICOM_THIS(CBaseFilterImpl,iface);
+
+	TRACE("(%p)->(%p)\n",This,lpwszVendor);
+
+	/* E_NOTIMPL means 'no vender information'. */
+	return E_NOTIMPL;
+}
+
+
+
+static ICOM_VTABLE(IBaseFilter) ibasefilter =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	CBaseFilterImpl_fnQueryInterface,
+	CBaseFilterImpl_fnAddRef,
+	CBaseFilterImpl_fnRelease,
+	/* IPersist fields */
+	CBaseFilterImpl_fnGetClassID,
+	/* IMediaFilter fields */
+	CBaseFilterImpl_fnStop,
+	CBaseFilterImpl_fnPause,
+	CBaseFilterImpl_fnRun,
+	CBaseFilterImpl_fnGetState,
+	CBaseFilterImpl_fnSetSyncSource,
+	CBaseFilterImpl_fnGetSyncSource,
+	/* IBaseFilter fields */
+	CBaseFilterImpl_fnEnumPins,
+	CBaseFilterImpl_fnFindPin,
+	CBaseFilterImpl_fnQueryFilterInfo,
+	CBaseFilterImpl_fnJoinFilterGraph,
+	CBaseFilterImpl_fnQueryVendorInfo,
+};
+
+
+HRESULT CBaseFilterImpl_InitIBaseFilter(
+	CBaseFilterImpl* This, IUnknown* punkControl,
+	const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph )
+{
+	TRACE("(%p,%p)\n",This,punkControl);
+
+	if ( punkControl == NULL )
+	{
+		ERR( "punkControl must not be NULL\n" );
+		return E_INVALIDARG;
+	}
+
+	ICOM_VTBL(This) = &ibasefilter;
+	This->punkControl = punkControl;
+	This->pclsidFilter = pclsidFilter;
+	This->pInPins = NULL;
+	This->pOutPins = NULL;
+	This->pfg = NULL;
+	This->cbNameGraph = 0;
+	This->pwszNameGraph = NULL;
+	This->pClock = NULL;
+	This->rtStart = 0;
+	This->fstate = State_Stopped;
+
+	This->cbNameGraph = sizeof(WCHAR) * (strlenW(lpwszNameGraph)+1);
+	This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
+	if ( This->pwszNameGraph == NULL )
+		return E_OUTOFMEMORY;
+	memcpy( This->pwszNameGraph, lpwszNameGraph, This->cbNameGraph );
+
+	InitializeCriticalSection( &This->csFilter );
+
+	return NOERROR;
+}
+
+void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This )
+{
+	QUARTZ_CompListItem*	pListItem;
+	IPin*	pPin;
+
+	TRACE("(%p)\n",This);
+
+	if ( This->pInPins != NULL )
+	{
+		while ( 1 )
+		{
+			pListItem = QUARTZ_CompList_GetFirst( This->pInPins );
+			if ( pListItem == NULL )
+				break;
+			pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
+			QUARTZ_CompList_RemoveComp( This->pInPins, (IUnknown*)pPin );
+			IPin_Release( pPin );
+		}
+
+		QUARTZ_CompList_Free( This->pInPins );
+		This->pInPins = NULL;
+	}
+	if ( This->pOutPins != NULL )
+	{
+		while ( 1 )
+		{
+			pListItem = QUARTZ_CompList_GetFirst( This->pOutPins );
+			if ( pListItem == NULL )
+				break;
+			pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
+			QUARTZ_CompList_RemoveComp( This->pOutPins, (IUnknown*)pPin );
+			IPin_Release( pPin );
+		}
+
+		QUARTZ_CompList_Free( This->pOutPins );
+		This->pOutPins = NULL;
+	}
+
+	if ( This->pwszNameGraph != NULL )
+	{
+		QUARTZ_FreeMem( This->pwszNameGraph );
+		This->pwszNameGraph = NULL;
+	}
+
+	if ( This->pClock != NULL )
+	{
+		IReferenceClock_Release( This->pClock );
+		This->pClock = NULL;
+	}
+
+	DeleteCriticalSection( &This->csFilter );
+}
diff --git a/dlls/quartz/basefilt.h b/dlls/quartz/basefilt.h
new file mode 100644
index 0000000..1d1d0ce
--- /dev/null
+++ b/dlls/quartz/basefilt.h
@@ -0,0 +1,94 @@
+#ifndef	WINE_DSHOW_BASEFILT_H
+#define	WINE_DSHOW_BASEFILT_H
+
+/*
+ * The following interfaces must be used as a part of aggregation.
+ * The punkControl must not be NULL since all IUnknown methods are
+ * implemented only for aggregation.
+ */
+
+/*
+ * implements IBaseFilter (internal)
+ *
+ * a base class for implementing IBaseFilter.
+ */
+
+#include "complist.h"
+typedef struct CBaseFilterImpl
+{
+	ICOM_VFIELD(IBaseFilter);
+
+	/* IUnknown fields */
+	IUnknown*	punkControl;
+	/* IBaseFilter fields */
+	CRITICAL_SECTION	csFilter;
+	const CLSID*	pclsidFilter;
+	QUARTZ_CompList*	pInPins;	/* a list of IPin-s. */
+	QUARTZ_CompList*	pOutPins;	/* a list of IPin-s. */
+	IFilterGraph*	pfg;
+	DWORD	cbNameGraph;
+	WCHAR*	pwszNameGraph;
+	IReferenceClock*	pClock;
+	REFERENCE_TIME	rtStart;
+	FILTER_STATE	fstate;
+} CBaseFilterImpl;
+
+HRESULT CBaseFilterImpl_InitIBaseFilter(
+	CBaseFilterImpl* This, IUnknown* punkControl,
+	const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph );
+void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This );
+
+
+/*
+ * Implements IPin and IMemInputPin. (internal)
+ *
+ * a base class for implementing IPin.
+ */
+
+typedef struct CPinBaseImpl
+{
+	ICOM_VFIELD(IPin);
+
+	/* IUnknown fields */
+	IUnknown*	punkControl;
+	/* IPin fields */
+	DWORD	cbIdLen;
+	WCHAR*	pwszId;
+	BOOL	bOutput;
+
+	CRITICAL_SECTION	csPin;
+	CBaseFilterImpl*	pFilter;
+	IPin*	pPinConnectedTo;
+	AM_MEDIA_TYPE*	pmtConn;
+} CPinBaseImpl;
+
+typedef struct CMemInputPinBaseImpl
+{
+	ICOM_VFIELD(IMemInputPin);
+
+	/* IUnknown fields */
+	IUnknown*	punkControl;
+	/* IMemInputPin fields */
+	CRITICAL_SECTION*	pcsPin;
+	IMemAllocator*	pAllocator;
+	BOOL	bReadonly;
+} CMemInputPinBaseImpl;
+
+
+HRESULT CPinBaseImpl_InitIPin(
+	CPinBaseImpl* This, IUnknown* punkControl,
+	CBaseFilterImpl* pFilter, LPCWSTR pwszId,
+	BOOL bOutput );
+void CPinBaseImpl_UninitIPin( CPinBaseImpl* This );
+
+
+HRESULT CMemInputPinBaseImpl_InitIMemInputPin(
+	CMemInputPinBaseImpl* This, IUnknown* punkControl,
+	CRITICAL_SECTION* pcsPin
+	);
+void CMemInputPinBaseImpl_UninitIMemInputPin(
+	CMemInputPinBaseImpl* This );
+
+
+
+#endif	/* WINE_DSHOW_BASEFILT_H */
diff --git a/dlls/quartz/basepin.c b/dlls/quartz/basepin.c
new file mode 100644
index 0000000..a1902df
--- /dev/null
+++ b/dlls/quartz/basepin.c
@@ -0,0 +1,664 @@
+/*
+ * Implements IPin and IMemInputPin. (internal)
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "strmif.h"
+#include "vfwmsgs.h"
+#include "wine/unicode.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "basefilt.h"
+#include "mtype.h"
+#include "memalloc.h"
+
+
+/***************************************************************************
+ *
+ *	CPinBaseImpl
+ *
+ */
+
+static HRESULT WINAPI
+CPinBaseImpl_fnQueryInterface(IPin* iface,REFIID riid,void** ppobj)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+CPinBaseImpl_fnAddRef(IPin* iface)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->punkControl);
+}
+
+static ULONG WINAPI
+CPinBaseImpl_fnRelease(IPin* iface)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->punkControl);
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnConnect(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+	HRESULT	hr = E_NOTIMPL;
+
+	FIXME("(%p)->(%p,%p) stub!\n",This,pPin,pmt);
+
+	if ( !This->bOutput )
+		return E_UNEXPECTED;
+	if ( pPin == NULL || pmt == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->csPin );
+
+	if ( This->pPinConnectedTo != NULL )
+	{
+		hr = VFW_E_ALREADY_CONNECTED;
+		goto err;
+	}
+
+	/* FIXME - return fail if running */
+
+	/* FIXME */
+
+	hr = E_NOTIMPL;
+err:
+	LeaveCriticalSection( &This->csPin );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnReceiveConnection(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+	HRESULT	hr = E_NOTIMPL;
+
+	FIXME("(%p)->(%p,%p) stub!\n",This,pPin,pmt);
+
+	if ( This->bOutput )
+		return E_UNEXPECTED;
+	if ( pPin == NULL || pmt == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->csPin );
+
+	if ( This->pPinConnectedTo != NULL )
+	{
+		hr = VFW_E_ALREADY_CONNECTED;
+		goto err;
+	}
+
+	/* FIXME - return fail if running */
+
+	/* FIXME */
+
+	hr = E_NOTIMPL;
+err:
+	LeaveCriticalSection( &This->csPin );
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnDisconnect(IPin* iface)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+	HRESULT hr = NOERROR;
+
+	FIXME("(%p)->() stub!\n",This);
+
+	EnterCriticalSection( &This->csPin );
+
+	/* FIXME - return fail if running */
+
+	if ( This->pPinConnectedTo != NULL )
+	{
+		/* FIXME - cleanup */
+
+		if ( This->pmtConn != NULL )
+		{
+			QUARTZ_MediaType_Destroy( This->pmtConn );
+			This->pmtConn = NULL;
+		}
+
+		IPin_Release(This->pPinConnectedTo);
+		This->pPinConnectedTo = NULL;
+		hr = NOERROR;
+	}
+	else
+	{
+		hr = S_FALSE; /* FIXME - is this correct??? */
+	}
+
+	LeaveCriticalSection( &This->csPin );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnConnectedTo(IPin* iface,IPin** ppPin)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+	HRESULT	hr = VFW_E_NOT_CONNECTED;
+
+	TRACE("(%p)->(%p)\n",This,ppPin);
+
+	if ( ppPin == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->csPin );
+
+	*ppPin = This->pPinConnectedTo;
+	if ( This->pPinConnectedTo != NULL )
+	{
+		IPin_AddRef(This->pPinConnectedTo);
+		hr = NOERROR;
+	}
+
+	LeaveCriticalSection( &This->csPin );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnConnectionMediaType(IPin* iface,AM_MEDIA_TYPE* pmt)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+	HRESULT hr = E_FAIL;
+
+	TRACE("(%p)->(%p)\n",This,pmt);
+
+	if ( pmt == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->csPin );
+
+	if ( This->pmtConn != NULL )
+	{
+		hr = QUARTZ_MediaType_Copy( pmt, This->pmtConn );
+	}
+	else
+	{
+		ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
+		pmt->bFixedSizeSamples = TRUE;
+		pmt->lSampleSize = 1;
+		hr = NOERROR;
+	}
+
+	LeaveCriticalSection( &This->csPin );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnQueryPinInfo(IPin* iface,PIN_INFO* pinfo)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	TRACE("(%p)->(%p)\n",This,pinfo);
+
+	if ( pinfo == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->csPin );
+
+	ZeroMemory( pinfo, sizeof(PIN_INFO) );
+	pinfo->pFilter = (IBaseFilter*)(This->pFilter);
+	if ( pinfo->pFilter != NULL )
+		IBaseFilter_AddRef( pinfo->pFilter );
+	pinfo->dir = This->bOutput ? PINDIR_OUTPUT : PINDIR_INPUT;
+	if ( This->cbIdLen <= sizeof(pinfo->achName) )
+		memcpy( pinfo->achName, This->pwszId, This->cbIdLen );
+	else
+	{
+		memcpy( pinfo->achName, This->pwszId, sizeof(pinfo->achName) );
+		pinfo->achName[sizeof(pinfo->achName)/sizeof(pinfo->achName[0])-1] = 0;
+	}
+
+	LeaveCriticalSection( &This->csPin );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnQueryDirection(IPin* iface,PIN_DIRECTION* pdir)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	TRACE("(%p)->(%p)\n",This,pdir);
+
+	if ( pdir == NULL )
+		return E_POINTER;
+
+	*pdir = This->bOutput ? PINDIR_OUTPUT : PINDIR_INPUT;
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnQueryId(IPin* iface,LPWSTR* lpwszId)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	TRACE("(%p)->(%p)\n",This,lpwszId);
+
+	if ( lpwszId == NULL )
+		return E_POINTER;
+
+	*lpwszId = (WCHAR*)CoTaskMemAlloc( This->cbIdLen );
+	if ( *lpwszId == NULL )
+		return E_OUTOFMEMORY;
+	memcpy( *lpwszId, This->pwszId, This->cbIdLen );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnQueryAccept(IPin* iface,const AM_MEDIA_TYPE* pmt)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnEnumMediaTypes(IPin* iface,IEnumMediaTypes** ppenum)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnQueryInternalConnections(IPin* iface,IPin** ppPin,ULONG* pul)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	TRACE("(%p)->(%p,%p)\n",This,ppPin,pul);
+
+	/* E_NOTIMPL means 'no internal connections'. */
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnEndOfStream(IPin* iface)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	if ( This->bOutput )
+		return E_UNEXPECTED;
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnBeginFlush(IPin* iface)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	if ( This->bOutput )
+		return E_UNEXPECTED;
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnEndFlush(IPin* iface)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	if ( This->bOutput )
+		return E_UNEXPECTED;
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+CPinBaseImpl_fnNewSegment(IPin* iface,REFERENCE_TIME rtStart,REFERENCE_TIME rtStop,double rate)
+{
+	ICOM_THIS(CPinBaseImpl,iface);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	if ( This->bOutput )
+		return E_UNEXPECTED;
+
+	return E_NOTIMPL;
+}
+
+
+
+
+static ICOM_VTABLE(IPin) ipin =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	CPinBaseImpl_fnQueryInterface,
+	CPinBaseImpl_fnAddRef,
+	CPinBaseImpl_fnRelease,
+	/* IPin fields */
+	CPinBaseImpl_fnConnect,
+	CPinBaseImpl_fnReceiveConnection,
+	CPinBaseImpl_fnDisconnect,
+	CPinBaseImpl_fnConnectedTo,
+	CPinBaseImpl_fnConnectionMediaType,
+	CPinBaseImpl_fnQueryPinInfo,
+	CPinBaseImpl_fnQueryDirection,
+	CPinBaseImpl_fnQueryId,
+	CPinBaseImpl_fnQueryAccept,
+	CPinBaseImpl_fnEnumMediaTypes,
+	CPinBaseImpl_fnQueryInternalConnections,
+	CPinBaseImpl_fnEndOfStream,
+	CPinBaseImpl_fnBeginFlush,
+	CPinBaseImpl_fnEndFlush,
+	CPinBaseImpl_fnNewSegment,
+};
+
+
+HRESULT CPinBaseImpl_InitIPin(
+	CPinBaseImpl* This, IUnknown* punkControl,
+	CBaseFilterImpl* pFilter, LPCWSTR pwszId,
+	BOOL bOutput )
+{
+	HRESULT	hr = NOERROR;
+
+	TRACE("(%p,%p,%p)\n",This,punkControl,pFilter);
+
+	if ( punkControl == NULL )
+	{
+		ERR( "punkControl must not be NULL\n" );
+		return E_INVALIDARG;
+	}
+
+	ICOM_VTBL(This) = &ipin;
+	This->punkControl = punkControl;
+	This->cbIdLen = sizeof(WCHAR)*(strlenW(pwszId)+1);
+	This->pwszId = NULL;
+	This->bOutput = bOutput;
+	This->pFilter = pFilter;
+	This->pPinConnectedTo = NULL;
+	This->pmtConn = NULL;
+
+	This->pwszId = (WCHAR*)QUARTZ_AllocMem( This->cbIdLen );
+	if ( This->pwszId == NULL )
+	{
+		hr = E_OUTOFMEMORY;
+		goto err;
+	}
+
+	InitializeCriticalSection( &This->csPin );
+
+	return NOERROR;
+
+err:;
+	CPinBaseImpl_UninitIPin( This );
+	return hr;
+}
+
+void CPinBaseImpl_UninitIPin( CPinBaseImpl* This )
+{
+	TRACE("(%p)\n",This);
+
+	IPin_Disconnect( (IPin*)(This) );
+
+	if ( This->pwszId != NULL )
+	{
+		QUARTZ_FreeMem( This->pwszId );
+		This->pwszId = NULL;
+	}
+
+	DeleteCriticalSection( &This->csPin );
+}
+
+
+/***************************************************************************
+ *
+ *	CMemInputPinBaseImpl
+ *
+ */
+
+
+static HRESULT WINAPI
+CMemInputPinBaseImpl_fnQueryInterface(IMemInputPin* iface,REFIID riid,void** ppobj)
+{
+	ICOM_THIS(CMemInputPinBaseImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+CMemInputPinBaseImpl_fnAddRef(IMemInputPin* iface)
+{
+	ICOM_THIS(CMemInputPinBaseImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->punkControl);
+}
+
+static ULONG WINAPI
+CMemInputPinBaseImpl_fnRelease(IMemInputPin* iface)
+{
+	ICOM_THIS(CMemInputPinBaseImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->punkControl);
+}
+
+
+static HRESULT WINAPI
+CMemInputPinBaseImpl_fnGetAllocator(IMemInputPin* iface,IMemAllocator** ppAllocator)
+{
+	ICOM_THIS(CMemInputPinBaseImpl,iface);
+	HRESULT hr = NOERROR;
+	IUnknown* punk;
+
+	TRACE("(%p)->()\n",This);
+
+	if ( ppAllocator == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( This->pcsPin );
+
+	if ( This->pAllocator == NULL )
+	{
+		hr = QUARTZ_CreateMemoryAllocator(NULL,(void**)&punk);
+		if ( hr == NOERROR )
+		{
+			hr = IUnknown_QueryInterface(punk,
+				&IID_IMemAllocator,(void**)&This->pAllocator);
+			IUnknown_Release(punk);
+		}
+	}
+
+	if ( hr == NOERROR )
+	{
+		*ppAllocator = This->pAllocator;
+		IMemAllocator_AddRef(This->pAllocator);
+	}
+
+	LeaveCriticalSection( This->pcsPin );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+CMemInputPinBaseImpl_fnNotifyAllocator(IMemInputPin* iface,IMemAllocator* pAllocator,BOOL bReadonly)
+{
+	ICOM_THIS(CMemInputPinBaseImpl,iface);
+
+	TRACE("(%p)->()\n",This);
+
+	if ( pAllocator == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( This->pcsPin );
+
+	if ( This->pAllocator != NULL )
+	{
+		IMemAllocator_Release(This->pAllocator);
+		This->pAllocator = NULL;
+	}
+	This->pAllocator = pAllocator;
+	IMemAllocator_AddRef(This->pAllocator);
+
+	This->bReadonly = bReadonly;
+
+	LeaveCriticalSection( This->pcsPin );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+CMemInputPinBaseImpl_fnGetAllocatorRequirements(IMemInputPin* iface,ALLOCATOR_PROPERTIES* pProp)
+{
+	ICOM_THIS(CMemInputPinBaseImpl,iface);
+
+	TRACE("(%p)->(%p)\n",This,pProp);
+
+	if ( pProp == NULL )
+		return E_POINTER;
+
+	/* E_MOTIMPL means 'no requirements' */
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+CMemInputPinBaseImpl_fnReceive(IMemInputPin* iface,IMediaSample* pSample)
+{
+	ICOM_THIS(CMemInputPinBaseImpl,iface);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+CMemInputPinBaseImpl_fnReceiveMultiple(IMemInputPin* iface,IMediaSample** ppSample,long nSample,long* pnSampleProcessed)
+{
+	ICOM_THIS(CMemInputPinBaseImpl,iface);
+	long	n;
+	HRESULT hr;
+
+	TRACE("(%p)->()\n",This);
+
+	if ( ppSample == NULL || pnSampleProcessed == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( This->pcsPin );
+
+	hr = NOERROR;
+	for ( n = 0; n < nSample; n++ )
+	{
+		hr = IMemInputPin_Receive(iface,ppSample[n]);
+		if ( FAILED(hr) )
+			break;
+	}
+
+	LeaveCriticalSection( This->pcsPin );
+
+	*pnSampleProcessed = n;
+	return hr;
+}
+
+static HRESULT WINAPI
+CMemInputPinBaseImpl_fnReceiveCanBlock(IMemInputPin* iface)
+{
+	ICOM_THIS(CMemInputPinBaseImpl,iface);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static ICOM_VTABLE(IMemInputPin) imeminputpin =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	CMemInputPinBaseImpl_fnQueryInterface,
+	CMemInputPinBaseImpl_fnAddRef,
+	CMemInputPinBaseImpl_fnRelease,
+	/* IMemInputPin fields */
+	CMemInputPinBaseImpl_fnGetAllocator,
+	CMemInputPinBaseImpl_fnNotifyAllocator,
+	CMemInputPinBaseImpl_fnGetAllocatorRequirements,
+	CMemInputPinBaseImpl_fnReceive,
+	CMemInputPinBaseImpl_fnReceiveMultiple,
+	CMemInputPinBaseImpl_fnReceiveCanBlock,
+};
+
+HRESULT CMemInputPinBaseImpl_InitIMemInputPin(
+	CMemInputPinBaseImpl* This, IUnknown* punkControl,
+	CRITICAL_SECTION* pcsPin
+	)
+{
+	TRACE("(%p,%p)\n",This,punkControl);
+
+	if ( punkControl == NULL )
+	{
+		ERR( "punkControl must not be NULL\n" );
+		return E_INVALIDARG;
+	}
+
+	ICOM_VTBL(This) = &imeminputpin;
+	This->punkControl = punkControl;
+	This->pcsPin = pcsPin;
+	This->pAllocator = NULL;
+	This->bReadonly = FALSE;
+
+	return NOERROR;
+}
+
+void CMemInputPinBaseImpl_UninitIMemInputPin(
+	CMemInputPinBaseImpl* This )
+{
+	TRACE("(%p)\n",This);
+
+	if ( This->pAllocator != NULL )
+	{
+		IMemAllocator_Release(This->pAllocator);
+		This->pAllocator = NULL;
+	}
+}
+
+
diff --git a/dlls/quartz/devenum.c b/dlls/quartz/devenum.c
index ccdb8b6..9832e35 100644
--- a/dlls/quartz/devenum.c
+++ b/dlls/quartz/devenum.c
@@ -1,7 +1,7 @@
 /*
  * Implementation of CLSID_SystemDeviceEnum.
  *
- * FIXME - stub.
+ * FIXME - not tested enough.
  *
  * hidenori@a2.ctktv.ne.jp
  */
@@ -12,18 +12,33 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "winuser.h"
+#include "winreg.h"
 #include "winerror.h"
 #include "wine/obj_base.h"
-#include "wine/obj_oleaut.h"
+#include "objidl.h"
+#include "oleidl.h"
+#include "ocidl.h"
 #include "strmif.h"
 #include "control.h"
 #include "uuids.h"
+#include "wine/unicode.h"
 
 #include "debugtools.h"
 DEFAULT_DEBUG_CHANNEL(quartz);
 
 #include "quartz_private.h"
 #include "devenum.h"
+#include "regsvr.h"
+#include "enumunk.h"
+#include "complist.h"
+#include "devmon.h"
+
+
+/***************************************************************************
+ *
+ *	new/delete for CLSID_SystemDeviceEnum
+ *
+ */
 
 /* can I use offsetof safely? - FIXME? */
 static QUARTZ_IFEntry IFEntries[] =
@@ -68,3 +83,159 @@
 	return S_OK;
 }
 
+
+/***************************************************************************
+ *
+ *	CSysDevEnum::ICreateDevEnum
+ *
+ */
+
+
+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);
+	HRESULT	hr;
+	HKEY	hKey;
+	QUARTZ_CompList*	pMonList;
+	IMoniker*	pMon;
+	DWORD	dwIndex;
+	LONG	lr;
+	WCHAR	wszPath[ 1024 ];
+	DWORD	dwLen;
+	DWORD	dwNameMax;
+	DWORD	cbName;
+	FILETIME	ftLastWrite;
+
+	TRACE("(%p)->(%s,%p,%08lx)\n",This,
+		debugstr_guid(rclsidDeviceClass),ppobj,dwFlags);
+	if ( dwFlags != 0 )
+	{
+		FIXME("unknown flags %08lx\n",dwFlags);
+		return E_NOTIMPL;
+	}
+
+	if ( ppobj == NULL )
+		return E_POINTER;
+	*ppobj = NULL;
+
+	hr = QUARTZ_CreateCLSIDPath(
+		wszPath, sizeof(wszPath)/sizeof(wszPath[0]),
+		rclsidDeviceClass, QUARTZ_wszInstance );
+	if ( FAILED(hr) )
+		return hr;
+
+	if ( RegOpenKeyExW( HKEY_CLASSES_ROOT, wszPath,
+		0, KEY_READ, &hKey ) != ERROR_SUCCESS )
+		return E_FAIL;
+
+	dwLen = strlenW(wszPath);
+	wszPath[dwLen++] = '\\'; wszPath[dwLen] = 0;
+	dwNameMax = sizeof(wszPath)/sizeof(wszPath[0]) - dwLen - 8;
+
+	pMonList = QUARTZ_CompList_Alloc();
+	if ( pMonList == NULL )
+	{
+		hr = E_OUTOFMEMORY;
+		goto err;
+	}
+
+	/* enumerate all subkeys. */
+	dwIndex = 0;
+	while ( 1 )
+	{
+		cbName = dwNameMax;
+		lr = RegEnumKeyExW(
+			hKey, dwIndex, &wszPath[dwLen], &cbName,
+			NULL, NULL, NULL, &ftLastWrite );
+		if ( lr == ERROR_NO_MORE_ITEMS )
+			break;
+		if ( lr != ERROR_SUCCESS )
+		{
+			hr = E_FAIL;
+			goto err;
+		}
+
+		hr = QUARTZ_CreateDeviceMoniker(
+			HKEY_CLASSES_ROOT, wszPath, &pMon );
+		if ( FAILED(hr) )
+			goto err;
+
+		hr = QUARTZ_CompList_AddComp(
+			pMonList, (IUnknown*)pMon, NULL, 0 );
+		IMoniker_Release( pMon );
+
+		if ( FAILED(hr) )
+			goto err;
+
+		dwIndex ++;
+	}
+
+	/* create an enumerator. */
+	hr = QUARTZ_CreateEnumUnknown(
+		&IID_IEnumMoniker, (void**)ppobj, pMonList );
+	if ( FAILED(hr) )
+		goto err;
+
+	hr = S_OK;
+err:
+	if ( pMonList != NULL )
+		QUARTZ_CompList_Free( pMonList );
+	RegCloseKey( hKey );
+
+	return hr;
+}
+
+static ICOM_VTABLE(ICreateDevEnum) icreatedevenum =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	ICreateDevEnum_fnQueryInterface,
+	ICreateDevEnum_fnAddRef,
+	ICreateDevEnum_fnRelease,
+	/* ICreateDevEnum fields */
+	ICreateDevEnum_fnCreateClassEnumerator,
+};
+
+HRESULT CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde )
+{
+	TRACE("(%p)\n",psde);
+	ICOM_VTBL(&psde->createdevenum) = &icreatedevenum;
+
+	return NOERROR;
+}
+
+void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde )
+{
+	TRACE("(%p)\n",psde);
+}
diff --git a/dlls/quartz/devmon.c b/dlls/quartz/devmon.c
index 317d5c7..7ed055d 100644
--- a/dlls/quartz/devmon.c
+++ b/dlls/quartz/devmon.c
@@ -1,5 +1,6 @@
 /*
  * Implements IMoniker for CLSID_CDeviceMoniker.
+ * Implements IPropertyBag. (internal)
  *
  * hidenori@a2.ctktv.ne.jp
  */
@@ -26,10 +27,15 @@
 
 #include "quartz_private.h"
 #include "devmon.h"
-#include "monprop.h"
 #include "regsvr.h"
 
 
+/***************************************************************************
+ *
+ *	CDeviceMoniker::IMoniker
+ *
+ */
+
 static HRESULT WINAPI
 IMoniker_fnQueryInterface(IMoniker* iface,REFIID riid,void** ppobj)
 {
@@ -149,8 +155,11 @@
 	if ( FAILED(hr) )
 		return hr;
 
-	return CoCreateInstance(
+	hr = CoCreateInstance(
 		&clsid, NULL, CLSCTX_INPROC_SERVER, riid, ppvResult );
+	TRACE( "hr = %08lx\n", hr );
+
+	return hr;
 }
 
 static HRESULT WINAPI IMoniker_fnBindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
@@ -373,6 +382,11 @@
 		QUARTZ_FreeMem( pdm->m_pwszPath );
 }
 
+/***************************************************************************
+ *
+ *	new/delete for CDeviceMoniker
+ *
+ */
 
 static void QUARTZ_DestroyDeviceMoniker(IUnknown* punk)
 {
@@ -382,7 +396,7 @@
 }
 
 /* can I use offsetof safely? - FIXME? */
-static QUARTZ_IFEntry IFEntries[] =
+static QUARTZ_IFEntry CDeviceMoniker_IFEntries[] =
 {
   { &IID_IPersist, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
   { &IID_IPersistStream, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
@@ -410,8 +424,8 @@
 		return hr;
 	}
 
-	pdm->unk.pEntries = IFEntries;
-	pdm->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
+	pdm->unk.pEntries = CDeviceMoniker_IFEntries;
+	pdm->unk.dwEntries = sizeof(CDeviceMoniker_IFEntries)/sizeof(CDeviceMoniker_IFEntries[0]);
 	pdm->unk.pOnFinalRelease = &QUARTZ_DestroyDeviceMoniker;
 
 	*ppMoniker = (IMoniker*)(&pdm->moniker);
@@ -420,3 +434,205 @@
 }
 
 
+/***************************************************************************
+ *
+ *	CRegPropertyBag::IPropertyBag
+ *
+ */
+
+static HRESULT WINAPI
+IPropertyBag_fnQueryInterface(IPropertyBag* iface,REFIID riid,void** ppobj)
+{
+	CRegPropertyBag_THIS(iface,propbag);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IPropertyBag_fnAddRef(IPropertyBag* iface)
+{
+	CRegPropertyBag_THIS(iface,propbag);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IPropertyBag_fnRelease(IPropertyBag* iface)
+{
+	CRegPropertyBag_THIS(iface,propbag);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IPropertyBag_fnRead(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar,IErrorLog* pLog)
+{
+	CRegPropertyBag_THIS(iface,propbag);
+	LONG	lr;
+	DWORD	dwSize;
+	DWORD	dwValueType;
+
+	TRACE("(%p)->(%s,%p,%p)\n",This,
+		debugstr_w(lpszPropName),pVar,pLog);
+
+	if ( lpszPropName == NULL || pVar == NULL )
+		return E_POINTER;
+
+	dwSize = 0;
+	lr = RegQueryValueExW(
+		This->m_hKey, lpszPropName, NULL,
+		&dwValueType, NULL, &dwSize );
+	if ( lr != ERROR_SUCCESS )
+	{
+		TRACE( "RegQueryValueExW failed.\n" );
+		return E_INVALIDARG;
+	}
+
+	switch ( dwValueType )
+	{
+	case REG_SZ:
+		TRACE( "REG_SZ / length = %lu\n", dwSize );
+		if ( pVar->n1.n2.vt == VT_EMPTY )
+			pVar->n1.n2.vt = VT_BSTR;
+		if ( pVar->n1.n2.vt != VT_BSTR )
+		{
+			TRACE( "type of VARIANT is not BSTR\n" );
+			return E_FAIL;
+		}
+
+		pVar->n1.n2.n3.bstrVal = SysAllocStringByteLen(
+			NULL, dwSize );
+		if ( pVar->n1.n2.n3.bstrVal == NULL )
+		{
+			TRACE( "out of memory.\n" );
+			return E_OUTOFMEMORY;
+		}
+		lr = RegQueryValueExW(
+			This->m_hKey, lpszPropName, NULL,
+			&dwValueType,
+			(BYTE*)pVar->n1.n2.n3.bstrVal, &dwSize );
+		if ( lr != ERROR_SUCCESS )
+		{
+			TRACE( "failed to query value\n" );
+			SysFreeString(pVar->n1.n2.n3.bstrVal);
+			return E_FAIL;
+		}
+		TRACE( "value is BSTR; %s\n", debugstr_w(pVar->n1.n2.n3.bstrVal) );
+		break;
+	default:
+		FIXME("(%p)->(%s,%p,%p) - unsupported value type.\n",This,
+			debugstr_w(lpszPropName),pVar,pLog);
+		return E_FAIL;
+	}
+
+	TRACE( "returned successfully.\n" );
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+IPropertyBag_fnWrite(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar)
+{
+	CRegPropertyBag_THIS(iface,propbag);
+
+	FIXME("(%p)->(%s,%p) stub!\n",This,
+		debugstr_w(lpszPropName),pVar);
+
+	if ( lpszPropName == NULL || pVar == NULL )
+		return E_POINTER;
+
+	return E_NOTIMPL;
+}
+
+
+
+
+static ICOM_VTABLE(IPropertyBag) ipropbag =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IPropertyBag_fnQueryInterface,
+	IPropertyBag_fnAddRef,
+	IPropertyBag_fnRelease,
+	/* IPropertyBag fields */
+	IPropertyBag_fnRead,
+	IPropertyBag_fnWrite,
+};
+
+static HRESULT CRegPropertyBag_InitIPropertyBag(
+	CRegPropertyBag* prpb, HKEY hkRoot, LPCWSTR lpKeyPath )
+{
+	ICOM_VTBL(&prpb->propbag) = &ipropbag;
+
+	if ( RegOpenKeyExW(
+		hkRoot, lpKeyPath, 0,
+		KEY_ALL_ACCESS, &prpb->m_hKey ) != ERROR_SUCCESS )
+		return E_FAIL;
+
+	return NOERROR;
+}
+
+static void CRegPropertyBag_UninitIPropertyBag(
+	CRegPropertyBag* prpb )
+{
+	RegCloseKey( prpb->m_hKey );
+}
+
+
+/***************************************************************************
+ *
+ *	new/delete for CRegPropertyBag
+ *
+ */
+
+static void QUARTZ_DestroyRegPropertyBag(IUnknown* punk)
+{
+	CRegPropertyBag_THIS(punk,unk);
+
+	CRegPropertyBag_UninitIPropertyBag(This);
+}
+
+
+/* can I use offsetof safely? - FIXME? */
+static QUARTZ_IFEntry CRegPropertyBag_IFEntries[] =
+{
+  { &IID_IPropertyBag, offsetof(CRegPropertyBag,propbag)-offsetof(CRegPropertyBag,unk) },
+};
+
+HRESULT QUARTZ_CreateRegPropertyBag(
+	HKEY hkRoot, LPCWSTR lpKeyPath,
+	IPropertyBag** ppPropBag )
+{
+	CRegPropertyBag*	prpb;
+	HRESULT	hr;
+
+	TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppPropBag );
+
+	prpb = (CRegPropertyBag*)QUARTZ_AllocObj( sizeof(CRegPropertyBag) );
+	if ( prpb == NULL )
+		return E_OUTOFMEMORY;
+
+	QUARTZ_IUnkInit( &prpb->unk, NULL );
+	hr = CRegPropertyBag_InitIPropertyBag( prpb, hkRoot, lpKeyPath );
+	if ( FAILED(hr) )
+	{
+		QUARTZ_FreeObj( prpb );
+		return hr;
+	}
+
+	prpb->unk.pEntries = CRegPropertyBag_IFEntries;
+	prpb->unk.dwEntries = sizeof(CRegPropertyBag_IFEntries)/sizeof(CRegPropertyBag_IFEntries[0]);
+	prpb->unk.pOnFinalRelease = &QUARTZ_DestroyRegPropertyBag;
+
+	*ppPropBag = (IPropertyBag*)(&prpb->propbag);
+
+	return S_OK;
+}
+
+
+
diff --git a/dlls/quartz/devmon.h b/dlls/quartz/devmon.h
index 7791a52..5c5073b 100644
--- a/dlls/quartz/devmon.h
+++ b/dlls/quartz/devmon.h
@@ -33,4 +33,34 @@
 	IMoniker** ppMoniker );
 
 
+/*
+		implements IPropertyBag for accessing registry.
+
+	- At least, the following interfaces should be implemented:
+
+	IUnknown
+		+ IPropertyBag
+ */
+
+#include "iunk.h"
+
+typedef struct DMON_IPropertyBagImpl
+{
+	ICOM_VFIELD(IPropertyBag);
+} DMON_IPropertyBagImpl;
+
+typedef struct CRegPropertyBag
+{
+	QUARTZ_IUnkImpl	unk;
+	DMON_IPropertyBagImpl	propbag;
+	/* IPropertyBag fields */
+	HKEY	m_hKey;
+} CRegPropertyBag;
+
+#define	CRegPropertyBag_THIS(iface,member)	CRegPropertyBag*	This = (CRegPropertyBag*)(((char*)iface)-offsetof(CRegPropertyBag,member))
+
+HRESULT QUARTZ_CreateRegPropertyBag(
+	HKEY hkRoot, LPCWSTR lpKeyPath,
+	IPropertyBag** ppPropBag );
+
 #endif	/* WINE_DSHOW_DEVMON_H */
diff --git a/dlls/quartz/enumunk.c b/dlls/quartz/enumunk.c
index e834f40..8552bf3 100644
--- a/dlls/quartz/enumunk.c
+++ b/dlls/quartz/enumunk.c
@@ -177,6 +177,7 @@
 		This->IFEntries[0].piid,
 		(void**)ppunk,
 		This->pCompList );
+	FIXME( "current pointer must be seeked correctly\n" );
 
 	QUARTZ_CompList_Unlock( This->pCompList );
 
diff --git a/dlls/quartz/fgclsid.c b/dlls/quartz/fgclsid.c
deleted file mode 100644
index 8702b92..0000000
--- a/dlls/quartz/fgclsid.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Implementation of IPersist for FilterGraph.
- *
- * FIXME - stub.
- *
- * hidenori@a2.ctktv.ne.jp
- */
-
-#include "config.h"
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.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
-IPersist_fnQueryInterface(IPersist* iface,REFIID riid,void** ppobj)
-{
-	CFilterGraph_THIS(iface,persist);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
-}
-
-static ULONG WINAPI
-IPersist_fnAddRef(IPersist* iface)
-{
-	CFilterGraph_THIS(iface,persist);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_AddRef(This->unk.punkControl);
-}
-
-static ULONG WINAPI
-IPersist_fnRelease(IPersist* iface)
-{
-	CFilterGraph_THIS(iface,persist);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_Release(This->unk.punkControl);
-}
-
-
-static HRESULT WINAPI
-IPersist_fnGetClassID(IPersist* iface,CLSID* pclsid)
-{
-	CFilterGraph_THIS(iface,persist);
-
-	TRACE("(%p)->()\n",This);
-
-	if ( pclsid == NULL )
-		return E_POINTER;
-	memcpy( pclsid, &CLSID_FilterGraph, sizeof(CLSID) );
-
-	return E_NOTIMPL;
-}
-
-
-static ICOM_VTABLE(IPersist) ipersist =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	/* IUnknown fields */
-	IPersist_fnQueryInterface,
-	IPersist_fnAddRef,
-	IPersist_fnRelease,
-	/* IPersist fields */
-	IPersist_fnGetClassID,
-};
-
-HRESULT CFilterGraph_InitIPersist( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-	ICOM_VTBL(&pfg->persist) = &ipersist;
-
-	return NOERROR;
-}
-
-void CFilterGraph_UninitIPersist( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-}
diff --git a/dlls/quartz/fgevent.c b/dlls/quartz/fgevent.c
new file mode 100644
index 0000000..db47c09
--- /dev/null
+++ b/dlls/quartz/fgevent.c
@@ -0,0 +1,446 @@
+/*
+ * CLSID_FilterGraph event handling.
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "wine/obj_oleaut.h"
+#include "strmif.h"
+#include "control.h"
+#include "evcode.h"
+#include "uuids.h"
+#include "vfwmsgs.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "fgraph.h"
+
+#define EVENTQUEUE_BLOCKSIZE	16
+#define EVENTQUEUE_MAX			1024
+
+struct FilterGraph_MEDIAEVENT
+{
+	long		lEventCode;
+	LONG_PTR	lParam1;
+	LONG_PTR	lParam2;
+};
+
+
+/***************************************************************************
+ *
+ *	CLSID_FilterGraph::IMediaEvent[Ex]
+ *
+ */
+
+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);
+
+	TRACE("(%p)->()\n",This);
+
+	*hEvent = (OAEVENT)This->m_hMediaEvent;
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnGetEvent(IMediaEventEx* iface,long* plEventCode,LONG_PTR* plParam1,LONG_PTR* plParam2,long lTimeOut)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+	ULONG cbQueued;
+	DWORD dw;
+	DWORD dwStart;
+	HRESULT	hr;
+	FilterGraph_MEDIAEVENT*	pEvent;
+
+	TRACE("(%p)->(%p,%p,%p,%ld)\n",This,plEventCode,
+		plParam1,plParam2,lTimeOut);
+
+	if ( plEventCode == NULL || plParam1 == NULL || plParam2 == NULL )
+		return E_POINTER;
+
+	while ( 1 )
+	{
+		dwStart = GetTickCount();
+		dw = WaitForSingleObject( This->m_hMediaEvent, lTimeOut );
+		if ( dw == WAIT_TIMEOUT )
+			return VFW_E_TIMEOUT;
+		if ( dw != WAIT_OBJECT_0 )
+			return E_FAIL;
+
+		EnterCriticalSection( &This->m_csMediaEvents );
+		hr = S_FALSE;
+		if ( This->m_cbMediaEventsMax > 0 )
+		{
+			cbQueued =
+				(This->m_cbMediaEventsMax +
+				 This->m_cbMediaEventsPut - This->m_cbMediaEventsGet) %
+					This->m_cbMediaEventsMax;
+			if ( cbQueued > 0 )
+			{
+				pEvent = &This->m_pMediaEvents[This->m_cbMediaEventsGet];
+				*plEventCode = pEvent->lEventCode;
+				*plParam1 = pEvent->lParam1;
+				*plParam2 = pEvent->lParam2;
+				This->m_cbMediaEventsGet = (This->m_cbMediaEventsGet + 1) %
+						This->m_cbMediaEventsMax;
+
+				hr = NOERROR;
+			}
+		}
+		LeaveCriticalSection( &This->m_csMediaEvents );
+
+		if ( hr != S_FALSE )
+			return hr;
+		if ( lTimeOut != INFINITE )
+		{
+			lTimeOut -= GetTickCount() - dwStart;
+			if ( lTimeOut < 0 )
+				return VFW_E_TIMEOUT;
+		}
+	}
+}
+
+static HRESULT WINAPI
+IMediaEventEx_fnWaitForCompletion(IMediaEventEx* iface,long lTimeOut,long* plEventCode)
+{
+	CFilterGraph_THIS(iface,mediaevent);
+	HRESULT hr;
+	long lEventCode;
+	LONG_PTR lParam1;
+	LONG_PTR lParam2;
+	DWORD dwTimePrev;
+	DWORD dwTimeCur;
+
+	TRACE("(%p)->(%ld,%p)\n",This,lTimeOut,plEventCode);
+
+	if ( plEventCode == NULL )
+		return E_POINTER;
+	*plEventCode = 0;
+
+	dwTimePrev = GetTickCount();
+
+	while ( 1 )
+	{
+		hr = IMediaEventEx_GetEvent(
+				CFilterGraph_IMediaEventEx(This),
+				&lEventCode,&lParam1,&lParam2,lTimeOut);
+		if ( hr == VFW_E_TIMEOUT )
+			hr = E_ABORT;
+		if ( hr != NOERROR )
+			return hr;
+		IMediaEventEx_FreeEventParams(
+				CFilterGraph_IMediaEventEx(This),
+				lEventCode,lParam1,lParam2);
+
+		if ( lEventCode == EC_COMPLETE ||
+			 lEventCode == EC_ERRORABORT ||
+			 lEventCode == EC_USERABORT )
+		{
+			*plEventCode = lEventCode;
+			return NOERROR;
+		}
+
+		if ( lTimeOut != INFINITE )
+		{
+			dwTimeCur = GetTickCount();
+			lTimeOut -= dwTimeCur - dwTimePrev;
+			dwTimePrev = dwTimeCur;
+			if ( lTimeOut < 0 )
+				return E_ABORT;
+		}
+	}
+}
+
+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,
+};
+
+
+HRESULT CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->mediaevent) = &imediaevent;
+
+	pfg->m_hMediaEvent = CreateEventA( NULL, TRUE, FALSE, NULL );
+	if ( pfg->m_hMediaEvent == (HANDLE)NULL )
+		return E_OUTOFMEMORY;
+
+	InitializeCriticalSection( &pfg->m_csMediaEvents );
+	pfg->m_pMediaEvents = NULL;
+	pfg->m_cbMediaEventsPut = 0;
+	pfg->m_cbMediaEventsGet = 0;
+	pfg->m_cbMediaEventsMax = 0;
+
+	return NOERROR;
+}
+
+void CFilterGraph_UninitIMediaEventEx( CFilterGraph* pfg )
+{
+	HRESULT hr;
+	long lEventCode;
+	LONG_PTR lParam1;
+	LONG_PTR lParam2;
+
+	TRACE("(%p)\n",pfg);
+
+	while ( 1 )
+	{
+		hr = IMediaEventEx_GetEvent(
+				CFilterGraph_IMediaEventEx(pfg),
+				&lEventCode,&lParam1,&lParam2,0);
+		if ( hr != NOERROR )
+			break;
+		IMediaEventEx_FreeEventParams(
+				CFilterGraph_IMediaEventEx(pfg),
+				lEventCode,lParam1,lParam2);
+	}
+
+	if ( pfg->m_pMediaEvents != NULL )
+	{
+		QUARTZ_FreeMem( pfg->m_pMediaEvents );
+		pfg->m_pMediaEvents = NULL;
+	}
+
+	DeleteCriticalSection( &pfg->m_csMediaEvents );
+	CloseHandle( pfg->m_hMediaEvent );
+}
+
+/***************************************************************************
+ *
+ *	CLSID_FilterGraph::IMediaEventSink
+ *
+ */
+
+static HRESULT WINAPI
+IMediaEventSink_fnQueryInterface(IMediaEventSink* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,mediaeventsink);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IMediaEventSink_fnAddRef(IMediaEventSink* iface)
+{
+	CFilterGraph_THIS(iface,mediaeventsink);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IMediaEventSink_fnRelease(IMediaEventSink* iface)
+{
+	CFilterGraph_THIS(iface,mediaeventsink);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IMediaEventSink_fnNotify(IMediaEventSink* iface,long lEventCode,LONG_PTR lParam1,LONG_PTR lParam2)
+{
+	CFilterGraph_THIS(iface,mediaeventsink);
+
+	FIXME("(%p)->(%ld,%08x,%08x) stub!\n",This,lEventCode,lParam1,lParam2);
+
+	return E_NOTIMPL;
+}
+
+
+static ICOM_VTABLE(IMediaEventSink) imediaeventsink =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IMediaEventSink_fnQueryInterface,
+	IMediaEventSink_fnAddRef,
+	IMediaEventSink_fnRelease,
+	/* IMediaEventSink fields */
+	IMediaEventSink_fnNotify,
+};
+
+
+
+HRESULT CFilterGraph_InitIMediaEventSink( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->mediaeventsink) = &imediaeventsink;
+
+	return NOERROR;
+}
+
+void CFilterGraph_UninitIMediaEventSink( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
+
diff --git a/dlls/quartz/fgpass.c b/dlls/quartz/fgpass.c
new file mode 100644
index 0000000..340a352
--- /dev/null
+++ b/dlls/quartz/fgpass.c
@@ -0,0 +1,1334 @@
+/*
+ * Implementation of IBasicAudio, IBasicVideo2, IVideoWindow for FilterGraph.
+ *
+ * FIXME - stub.
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.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 CFilterGraph_QueryBasicAudio(
+	CFilterGraph* This, IBasicAudio** ppAudio )
+{
+	FIXME("(%p,%p) stub!\n",This,ppAudio);
+	return E_NOTIMPL;
+}
+
+static HRESULT CFilterGraph_QueryBasicVideo(
+	CFilterGraph* This, IBasicVideo** ppVideo )
+{
+	FIXME("(%p,%p) stub!\n",This,ppVideo);
+	return E_NOTIMPL;
+}
+
+static HRESULT CFilterGraph_QueryBasicVideo2(
+	CFilterGraph* This, IBasicVideo2** ppVideo )
+{
+	FIXME("(%p,%p) stub!\n",This,ppVideo);
+	return E_NOTIMPL;
+}
+
+static HRESULT CFilterGraph_QueryVideoWindow(
+	CFilterGraph* This, IVideoWindow** ppVidWin )
+{
+	FIXME("(%p,%p) stub!\n",This,ppVidWin);
+	return E_NOTIMPL;
+}
+
+
+
+/***************************************************************************
+ *
+ *	CFilterGraph::IBasicAudio
+ *
+ */
+
+#define QUERYBASICAUDIO	\
+	IBasicAudio* pAudio = NULL; \
+	HRESULT hr; \
+	hr = CFilterGraph_QueryBasicAudio( This, &pAudio ); \
+	if ( FAILED(hr) ) return hr;
+
+
+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);
+	QUERYBASICAUDIO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicAudio_put_Volume(pAudio,lVol);
+}
+
+static HRESULT WINAPI
+IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol)
+{
+	CFilterGraph_THIS(iface,basaud);
+	QUERYBASICAUDIO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicAudio_get_Volume(pAudio,plVol);
+}
+
+static HRESULT WINAPI
+IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance)
+{
+	CFilterGraph_THIS(iface,basaud);
+	QUERYBASICAUDIO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicAudio_put_Balance(pAudio,lBalance);
+}
+
+static HRESULT WINAPI
+IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance)
+{
+	CFilterGraph_THIS(iface,basaud);
+	QUERYBASICAUDIO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicAudio_get_Balance(pAudio,plBalance);
+}
+
+
+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,
+};
+
+
+HRESULT CFilterGraph_InitIBasicAudio( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->basaud) = &ibasicaudio;
+
+	return NOERROR;
+}
+
+void CFilterGraph_UninitIBasicAudio( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
+
+#undef QUERYBASICAUDIO
+
+
+/***************************************************************************
+ *
+ *	CFilterGraph::IBasicVideo2
+ *
+ */
+
+
+#define QUERYBASICVIDEO	\
+	IBasicVideo* pVideo = NULL; \
+	HRESULT hr; \
+	hr = CFilterGraph_QueryBasicVideo( This, &pVideo ); \
+	if ( FAILED(hr) ) return hr;
+
+#define QUERYBASICVIDEO2	\
+	IBasicVideo2* pVideo = NULL; \
+	HRESULT hr; \
+	hr = CFilterGraph_QueryBasicVideo2( This, &pVideo ); \
+	if ( FAILED(hr) ) return hr;
+
+
+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);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_AvgTimePerFrame(pVideo,prefTime);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_BitRate(IBasicVideo2* iface,long* plRate)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_BitRate(pVideo,plRate);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_BitErrorRate(IBasicVideo2* iface,long* plRate)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_BitErrorRate(pVideo,plRate);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_VideoWidth(IBasicVideo2* iface,long* plWidth)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_VideoWidth(pVideo,plWidth);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_VideoHeight(IBasicVideo2* iface,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_VideoHeight(pVideo,plHeight);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_SourceLeft(IBasicVideo2* iface,long lLeft)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_put_SourceLeft(pVideo,lLeft);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_SourceLeft(IBasicVideo2* iface,long* plLeft)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_SourceLeft(pVideo,plLeft);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_SourceWidth(IBasicVideo2* iface,long lWidth)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_put_SourceWidth(pVideo,lWidth);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_SourceWidth(IBasicVideo2* iface,long* plWidth)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_SourceWidth(pVideo,plWidth);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_SourceTop(IBasicVideo2* iface,long lTop)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_put_SourceTop(pVideo,lTop);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_SourceTop(IBasicVideo2* iface,long* plTop)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_SourceTop(pVideo,plTop);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_SourceHeight(IBasicVideo2* iface,long lHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_put_SourceHeight(pVideo,lHeight);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_SourceHeight(IBasicVideo2* iface,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_SourceHeight(pVideo,plHeight);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_DestinationLeft(IBasicVideo2* iface,long lLeft)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_put_DestinationLeft(pVideo,lLeft);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_DestinationLeft(IBasicVideo2* iface,long* plLeft)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_DestinationLeft(pVideo,plLeft);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_DestinationWidth(IBasicVideo2* iface,long lWidth)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_put_DestinationWidth(pVideo,lWidth);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_DestinationWidth(IBasicVideo2* iface,long* plWidth)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_DestinationWidth(pVideo,plWidth);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_DestinationTop(IBasicVideo2* iface,long lTop)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_put_DestinationTop(pVideo,lTop);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_DestinationTop(IBasicVideo2* iface,long* plTop)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_DestinationTop(pVideo,plTop);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnput_DestinationHeight(IBasicVideo2* iface,long lHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_put_DestinationHeight(pVideo,lHeight);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnget_DestinationHeight(IBasicVideo2* iface,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_get_DestinationHeight(pVideo,plHeight);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnSetSourcePosition(IBasicVideo2* iface,long lLeft,long lTop,long lWidth,long lHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_SetSourcePosition(pVideo,lLeft,lTop,lWidth,lHeight);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetSourcePosition(IBasicVideo2* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_GetSourcePosition(pVideo,plLeft,plTop,plWidth,plHeight);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnSetDefaultSourcePosition(IBasicVideo2* iface)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_SetDefaultSourcePosition(pVideo);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnSetDestinationPosition(IBasicVideo2* iface,long lLeft,long lTop,long lWidth,long lHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_SetDestinationPosition(pVideo,lLeft,lTop,lWidth,lHeight);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetDestinationPosition(IBasicVideo2* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_GetDestinationPosition(pVideo,plLeft,plTop,plWidth,plHeight);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnSetDefaultDestinationPosition(IBasicVideo2* iface)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_SetDefaultDestinationPosition(pVideo);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetVideoSize(IBasicVideo2* iface,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_GetVideoSize(pVideo,plWidth,plHeight);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetVideoPaletteEntries(IBasicVideo2* iface,long lStart,long lCount,long* plRet,long* plPaletteEntry)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_GetVideoPaletteEntries(pVideo,lStart,lCount,plRet,plPaletteEntry);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetCurrentImage(IBasicVideo2* iface,long* plBufferSize,long* plDIBBuffer)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_GetCurrentImage(pVideo,plBufferSize,plDIBBuffer);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnIsUsingDefaultSource(IBasicVideo2* iface)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_IsUsingDefaultSource(pVideo);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnIsUsingDefaultDestination(IBasicVideo2* iface)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo_IsUsingDefaultDestination(pVideo);
+}
+
+static HRESULT WINAPI
+IBasicVideo2_fnGetPreferredAspectRatio(IBasicVideo2* iface,long* plRateX,long* plRateY)
+{
+	CFilterGraph_THIS(iface,basvid);
+	QUERYBASICVIDEO2
+
+	TRACE("(%p)->()\n",This);
+
+	return IBasicVideo2_GetPreferredAspectRatio(pVideo,plRateX,plRateY);
+}
+
+
+
+
+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,
+};
+
+
+HRESULT CFilterGraph_InitIBasicVideo2( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->basvid) = &ibasicvideo;
+
+	return NOERROR;
+}
+
+void CFilterGraph_UninitIBasicVideo2( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
+
+#undef QUERYBASICVIDEO2
+#undef QUERYBASICVIDEO
+
+/***************************************************************************
+ *
+ *	CFilterGraph::IVideoWindow
+ *
+ */
+
+#define QUERYVIDEOWINDOW \
+	IVideoWindow* pVidWin = NULL; \
+	HRESULT hr; \
+	hr = CFilterGraph_QueryVideoWindow( This, &pVidWin ); \
+	if ( FAILED(hr) ) return hr;
+
+
+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);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_Caption(pVidWin,strCaption);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Caption(IVideoWindow* iface,BSTR* pstrCaption)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_Caption(pVidWin,pstrCaption);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_WindowStyle(IVideoWindow* iface,long lStyle)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_WindowStyle(pVidWin,lStyle);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_WindowStyle(IVideoWindow* iface,long* plStyle)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_WindowStyle(pVidWin,plStyle);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_WindowStyleEx(IVideoWindow* iface,long lExStyle)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_WindowStyleEx(pVidWin,lExStyle);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_WindowStyleEx(IVideoWindow* iface,long* plExStyle)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_WindowStyleEx(pVidWin,plExStyle);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_AutoShow(IVideoWindow* iface,long lAutoShow)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_AutoShow(pVidWin,lAutoShow);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_AutoShow(IVideoWindow* iface,long* plAutoShow)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_AutoShow(pVidWin,plAutoShow);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_WindowState(IVideoWindow* iface,long lState)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_WindowState(pVidWin,lState);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_WindowState(IVideoWindow* iface,long* plState)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_WindowState(pVidWin,plState);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_BackgroundPalette(IVideoWindow* iface,long lBackPal)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_BackgroundPalette(pVidWin,lBackPal);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_BackgroundPalette(IVideoWindow* iface,long* plBackPal)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_BackgroundPalette(pVidWin,plBackPal);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Visible(IVideoWindow* iface,long lVisible)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_Visible(pVidWin,lVisible);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Visible(IVideoWindow* iface,long* plVisible)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_Visible(pVidWin,plVisible);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Left(IVideoWindow* iface,long lLeft)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_Left(pVidWin,lLeft);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Left(IVideoWindow* iface,long* plLeft)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_Left(pVidWin,plLeft);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Width(IVideoWindow* iface,long lWidth)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_Width(pVidWin,lWidth);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Width(IVideoWindow* iface,long* plWidth)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_Width(pVidWin,plWidth);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Top(IVideoWindow* iface,long lTop)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_Top(pVidWin,lTop);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Top(IVideoWindow* iface,long* plTop)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_Top(pVidWin,plTop);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Height(IVideoWindow* iface,long lHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_Height(pVidWin,lHeight);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Height(IVideoWindow* iface,long* plHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_Height(pVidWin,plHeight);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_Owner(IVideoWindow* iface,OAHWND hwnd)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_Owner(pVidWin,hwnd);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_Owner(IVideoWindow* iface,OAHWND* phwnd)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_Owner(pVidWin,phwnd);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_MessageDrain(IVideoWindow* iface,OAHWND hwnd)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_MessageDrain(pVidWin,hwnd);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_MessageDrain(IVideoWindow* iface,OAHWND* phwnd)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_MessageDrain(pVidWin,phwnd);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_BorderColor(IVideoWindow* iface,long* plColor)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_BorderColor(pVidWin,plColor);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_BorderColor(IVideoWindow* iface,long lColor)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_BorderColor(pVidWin,lColor);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnget_FullScreenMode(IVideoWindow* iface,long* plMode)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_get_FullScreenMode(pVidWin,plMode);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnput_FullScreenMode(IVideoWindow* iface,long lMode)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_put_FullScreenMode(pVidWin,lMode);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnSetWindowForeground(IVideoWindow* iface,long lFocus)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_SetWindowForeground(pVidWin,lFocus);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnNotifyOwnerMessage(IVideoWindow* iface,OAHWND hwnd,long message,LONG_PTR wParam,LONG_PTR lParam)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_NotifyOwnerMessage(pVidWin,hwnd,message,wParam,lParam);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnSetWindowPosition(IVideoWindow* iface,long lLeft,long lTop,long lWidth,long lHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_SetWindowPosition(pVidWin,lLeft,lTop,lWidth,lHeight);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnGetWindowPosition(IVideoWindow* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_GetWindowPosition(pVidWin,plLeft,plTop,plWidth,plHeight);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnGetMinIdealImageSize(IVideoWindow* iface,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_GetMinIdealImageSize(pVidWin,plWidth,plHeight);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnGetMaxIdealImageSize(IVideoWindow* iface,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_GetMaxIdealImageSize(pVidWin,plWidth,plHeight);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnGetRestorePosition(IVideoWindow* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_GetRestorePosition(pVidWin,plLeft,plTop,plWidth,plHeight);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnHideCursor(IVideoWindow* iface,long lHide)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_HideCursor(pVidWin,lHide);
+}
+
+static HRESULT WINAPI
+IVideoWindow_fnIsCursorHidden(IVideoWindow* iface,long* plHide)
+{
+	CFilterGraph_THIS(iface,vidwin);
+	QUERYVIDEOWINDOW
+
+	TRACE("(%p)->()\n",This);
+
+	return IVideoWindow_IsCursorHidden(pVidWin,plHide);
+}
+
+
+
+
+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,
+
+};
+
+
+HRESULT CFilterGraph_InitIVideoWindow( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->vidwin) = &ivideowindow;
+
+	return NOERROR;
+}
+
+void CFilterGraph_UninitIVideoWindow( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
+
+#undef QUERYVIDEOWINDOW
diff --git a/dlls/quartz/fgraph.c b/dlls/quartz/fgraph.c
index 0b66264..6efda00 100644
--- a/dlls/quartz/fgraph.c
+++ b/dlls/quartz/fgraph.c
@@ -23,6 +23,12 @@
 #include "quartz_private.h"
 #include "fgraph.h"
 
+/***************************************************************************
+ *
+ *	new/delete for CFilterGraph
+ *
+ */
+
 /* can I use offsetof safely? - FIXME? */
 static QUARTZ_IFEntry IFEntries[] =
 {
@@ -32,6 +38,7 @@
   { &IID_IGraphBuilder, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
   { &IID_IFilterGraph2, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
   { &IID_IGraphVersion, offsetof(CFilterGraph,graphversion)-offsetof(CFilterGraph,unk) },
+  { &IID_IGraphConfig, offsetof(CFilterGraph,grphconf)-offsetof(CFilterGraph,unk) },
   { &IID_IMediaControl, offsetof(CFilterGraph,mediacontrol)-offsetof(CFilterGraph,unk) },
   { &IID_IMediaFilter, offsetof(CFilterGraph,mediafilter)-offsetof(CFilterGraph,unk) },
   { &IID_IMediaEvent, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) },
@@ -60,6 +67,7 @@
 	FGENT(IDispatch)
 	FGENT(IFilterGraph2)
 	FGENT(IGraphVersion)
+	FGENT(IGraphConfig)
 	FGENT(IMediaControl)
 	FGENT(IMediaFilter)
 	FGENT(IMediaEventEx)
@@ -80,6 +88,8 @@
 	CFilterGraph_THIS(punk,unk);
 	int	i;
 
+	TRACE( "(%p)\n", punk );
+
 	/* At first, call Stop. */
 	IMediaControl_Stop( CFilterGraph_IMediaControl(This) );
 	IMediaFilter_Stop( CFilterGraph_IMediaFilter(This) );
@@ -136,3 +146,78 @@
 }
 
 
+/***************************************************************************
+ *
+ *	CFilterGraph::IPersist
+ *
+ */
+
+static HRESULT WINAPI
+IPersist_fnQueryInterface(IPersist* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,persist);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IPersist_fnAddRef(IPersist* iface)
+{
+	CFilterGraph_THIS(iface,persist);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IPersist_fnRelease(IPersist* iface)
+{
+	CFilterGraph_THIS(iface,persist);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+
+static HRESULT WINAPI
+IPersist_fnGetClassID(IPersist* iface,CLSID* pclsid)
+{
+	CFilterGraph_THIS(iface,persist);
+
+	TRACE("(%p)->()\n",This);
+
+	if ( pclsid == NULL )
+		return E_POINTER;
+	memcpy( pclsid, &CLSID_FilterGraph, sizeof(CLSID) );
+
+	return E_NOTIMPL;
+}
+
+
+static ICOM_VTABLE(IPersist) ipersist =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IPersist_fnQueryInterface,
+	IPersist_fnAddRef,
+	IPersist_fnRelease,
+	/* IPersist fields */
+	IPersist_fnGetClassID,
+};
+
+HRESULT CFilterGraph_InitIPersist( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->persist) = &ipersist;
+
+	return NOERROR;
+}
+
+void CFilterGraph_UninitIPersist( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
diff --git a/dlls/quartz/fgraph.h b/dlls/quartz/fgraph.h
index d038f6d..cdbd5d5 100644
--- a/dlls/quartz/fgraph.h
+++ b/dlls/quartz/fgraph.h
@@ -11,6 +11,7 @@
 		+ IDispatch
 		+ IFilterGraph - IGraphBuilder - IFilterGraph2
 		+ IGraphVersion
+		+ IGraphConfig
 		+ IDispatch - IMediaControl
 		+ IPersist - IMediaFilter
 		+ IDispatch - IMediaEvent - IMediaEventEx
@@ -50,6 +51,11 @@
 	ICOM_VFIELD(IGraphVersion);
 } FG_IGraphVersionImpl;
 
+typedef struct FG_IGraphConfigImpl
+{
+	ICOM_VFIELD(IGraphConfig);
+} FG_IGraphConfigImpl;
+
 typedef struct FG_IMediaControlImpl
 {
 	ICOM_VFIELD(IMediaControl);
@@ -95,6 +101,7 @@
 	ICOM_VFIELD(IVideoWindow);
 } FG_IVideoWindowImpl;
 
+typedef struct FilterGraph_MEDIAEVENT	FilterGraph_MEDIAEVENT;
 
 typedef struct CFilterGraph
 {
@@ -103,6 +110,7 @@
 	FG_IDispatchImpl	disp;
 	FG_IFilterGraph2Impl	fgraph;
 	FG_IGraphVersionImpl	graphversion;
+	FG_IGraphConfigImpl	grphconf;
 	FG_IMediaControlImpl	mediacontrol;
 	FG_IMediaFilterImpl	mediafilter;
 	FG_IMediaEventImpl	mediaevent;
@@ -123,8 +131,15 @@
 	/* IMediaFilter fields. */
 	CRITICAL_SECTION	m_csGraphState;
 	FILTER_STATE	m_stateGraph; /* must NOT accessed directly! */
+	CRITICAL_SECTION	m_csClock;
+	IReferenceClock*	m_pClock;
 	/* IMediaEvent fields. */
 	HANDLE	m_hMediaEvent;
+	CRITICAL_SECTION	m_csMediaEvents;
+	FilterGraph_MEDIAEVENT*	m_pMediaEvents;
+	ULONG	m_cbMediaEventsPut;
+	ULONG	m_cbMediaEventsGet;
+	ULONG	m_cbMediaEventsMax;
 	/* IMediaEventSink fields. */
 	/* IMediaPosition fields. */
 	/* IMediaSeeking fields. */
@@ -137,8 +152,10 @@
 #define	CFilterGraph_IPersist(th)		((IPersist*)&((th)->persist))
 #define	CFilterGraph_IDispatch(th)		((IDispatch*)&((th)->disp))
 #define	CFilterGraph_IFilterGraph2(th)		((IFilterGraph2*)&((th)->fgraph))
-#define	CFilterGraph_IMediaFilter(th)		((IMediaFilter*)&((th)->mediafilter))
 #define	CFilterGraph_IMediaControl(th)		((IMediaControl*)&((th)->mediacontrol))
+#define	CFilterGraph_IMediaFilter(th)		((IMediaFilter*)&((th)->mediafilter))
+#define	CFilterGraph_IMediaEventEx(th)		((IMediaEventEx*)&((th)->mediaevent))
+#define	CFilterGraph_IMediaEventSink(th)		((IMediaEventSink*)&((th)->mediaeventsink))
 
 HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj);
 
@@ -150,6 +167,8 @@
 void CFilterGraph_UninitIFilterGraph2( CFilterGraph* pfg );
 HRESULT CFilterGraph_InitIGraphVersion( CFilterGraph* pfg );
 void CFilterGraph_UninitIGraphVersion( CFilterGraph* pfg );
+HRESULT CFilterGraph_InitIGraphConfig( CFilterGraph* pfg );
+void CFilterGraph_UninitIGraphConfig( CFilterGraph* pfg );
 HRESULT CFilterGraph_InitIMediaControl( CFilterGraph* pfg );
 void CFilterGraph_UninitIMediaControl( CFilterGraph* pfg );
 HRESULT CFilterGraph_InitIMediaFilter( CFilterGraph* pfg );
diff --git a/dlls/quartz/fmap.c b/dlls/quartz/fmap.c
index 268c6e6..9234786 100644
--- a/dlls/quartz/fmap.c
+++ b/dlls/quartz/fmap.c
@@ -12,6 +12,7 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "winuser.h"
+#include "winreg.h"
 #include "winerror.h"
 #include "wine/obj_base.h"
 #include "wine/obj_oleaut.h"
@@ -24,6 +25,14 @@
 
 #include "quartz_private.h"
 #include "fmap.h"
+#include "regsvr.h"
+
+
+/***************************************************************************
+ *
+ *	new/delete for CLSID_FilterMapper
+ *
+ */
 
 /* can I use offsetof safely? - FIXME? */
 static QUARTZ_IFEntry IFEntries[] =
@@ -66,3 +75,182 @@
 
 	return S_OK;
 }
+
+/***************************************************************************
+ *
+ *	CLSID_FilterMapper::IFilterMapper
+ *
+ */
+
+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);
+
+	FIXME("(%p)->(%s,%s,%08lx)\n",This,
+		debugstr_guid(&clsid),debugstr_w(lpwszName),dwMerit);
+
+	/* FIXME */
+	/* FIXME - handle dwMerit! */
+	return QUARTZ_RegisterAMovieFilter(
+		&CLSID_LegacyAmFilterCategory,
+		&clsid,
+		NULL, 0,
+		lpwszName, NULL, TRUE );
+}
+
+static HRESULT WINAPI
+IFilterMapper_fnRegisterFilterInstance(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,CLSID* pclsidMedia)
+{
+	CFilterMapper_THIS(iface,fmap);
+	HRESULT	hr;
+
+	FIXME("(%p)->()\n",This);
+
+	if ( pclsidMedia == NULL )
+		return E_POINTER;
+	hr = CoCreateGuid(pclsidMedia);
+	if ( FAILED(hr) )
+		return hr;
+
+	/* FIXME */
+	/* this doesn't work. */
+	/* return IFilterMapper_RegisterFilter(iface,
+		*pclsidMedia,lpwszName,0x60000000); */
+
+	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);
+
+	FIXME("(%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);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IFilterMapper_fnUnregisterFilter(IFilterMapper* iface,CLSID clsidFilter)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidFilter));
+
+	/* FIXME */
+	return QUARTZ_RegisterAMovieFilter(
+		&CLSID_LegacyAmFilterCategory,
+		&clsidFilter,
+		NULL, 0, NULL, NULL, FALSE );
+}
+
+static HRESULT WINAPI
+IFilterMapper_fnUnregisterFilterInstance(IFilterMapper* iface,CLSID clsidMedia)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidMedia));
+
+	/* FIXME */
+	/* this doesn't work. */
+	/* return IFilterMapper_UnregisterFilter(iface,clsidMedia); */
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IFilterMapper_fnUnregisterPin(IFilterMapper* iface,CLSID clsidPin,LPCWSTR lpwszName)
+{
+	CFilterMapper_THIS(iface,fmap);
+
+	FIXME("(%p)->(%s,%s) stub!\n",This,
+		debugstr_guid(&clsidPin),debugstr_w(lpwszName));
+
+	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);
+
+	FIXME("(%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,
+};
+
+
+HRESULT CFilterMapper_InitIFilterMapper( CFilterMapper* pfm )
+{
+	TRACE("(%p)\n",pfm);
+	ICOM_VTBL(&pfm->fmap) = &ifmap;
+
+	return NOERROR;
+}
+
+void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm )
+{
+	TRACE("(%p)\n",pfm);
+}
diff --git a/dlls/quartz/fmap2.c b/dlls/quartz/fmap2.c
index 30a7ffd..315d231 100644
--- a/dlls/quartz/fmap2.c
+++ b/dlls/quartz/fmap2.c
@@ -11,8 +11,9 @@
 #include "windef.h"
 #include "winbase.h"
 #include "wingdi.h"
-#include "winerror.h"
 #include "winuser.h"
+#include "winreg.h"
+#include "winerror.h"
 #include "wine/obj_base.h"
 #include "wine/obj_oleaut.h"
 #include "strmif.h"
@@ -24,6 +25,14 @@
 
 #include "quartz_private.h"
 #include "fmap2.h"
+#include "regsvr.h"
+
+
+/***************************************************************************
+ *
+ *	new/delete for CLSID_FilterMapper2
+ *
+ */
 
 /* can I use offsetof safely? - FIXME? */
 static QUARTZ_IFEntry IFEntries[] =
@@ -67,3 +76,162 @@
 
 	return S_OK;
 }
+
+/***************************************************************************
+ *
+ *	CLSID_FilterMapper2::IFilterMapper3
+ *
+ */
+
+
+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)->(%s,%lu,%s) stub!\n",This,
+		debugstr_guid(rclsidCategory),
+		(unsigned long)dwMerit,debugstr_w(lpwszDesc));
+
+	return E_NOTIMPL;
+}
+
+
+static HRESULT WINAPI
+IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter)
+{
+	CFilterMapper2_THIS(iface,fmap3);
+
+	FIXME("(%p)->(%s,%s,%s) stub!\n",This,
+		debugstr_guid(pclsidCategory),
+		debugstr_w(lpwszInst),
+		debugstr_guid(rclsidFilter));
+
+	if ( pclsidCategory == NULL )
+		pclsidCategory = &CLSID_LegacyAmFilterCategory;
+
+	/* FIXME */
+	return QUARTZ_RegisterAMovieFilter(
+		pclsidCategory,
+		rclsidFilter,
+		NULL, 0,
+		NULL, lpwszInst, FALSE );
+}
+
+
+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)->(%s,%s,%p,%s,%s,%p) stub!\n",This,
+		debugstr_guid(rclsidFilter),debugstr_w(lpName),
+		ppMoniker,debugstr_guid(pclsidCategory),
+		debugstr_w(lpwszInst),pRF2 );
+
+	if ( lpName == NULL || pRF2 == NULL )
+		return E_POINTER;
+
+	if ( ppMoniker != NULL )
+	{
+		FIXME( "ppMoniker != NULL - not implemented!\n" );
+		return E_NOTIMPL;
+	}
+
+	if ( pclsidCategory == NULL )
+		pclsidCategory = &CLSID_LegacyAmFilterCategory;
+
+	/* FIXME!! - all members in REGFILTER2 are ignored ! */
+
+	return QUARTZ_RegisterAMovieFilter(
+		pclsidCategory,
+		rclsidFilter,
+		NULL, 0,
+		lpName, lpwszInst, TRUE );
+}
+
+
+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,
+};
+
+
+HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* pfm )
+{
+	TRACE("(%p)\n",pfm);
+	ICOM_VTBL(&pfm->fmap3) = &ifmap3;
+
+	return NOERROR;
+}
+
+void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* pfm )
+{
+	TRACE("(%p)\n",pfm);
+}
+
diff --git a/dlls/quartz/ibasaud.c b/dlls/quartz/ibasaud.c
deleted file mode 100644
index 89107c7..0000000
--- a/dlls/quartz/ibasaud.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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 "winuser.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,
-};
-
-
-HRESULT CFilterGraph_InitIBasicAudio( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-	ICOM_VTBL(&pfg->basaud) = &ibasicaudio;
-
-	return NOERROR;
-}
-
-void CFilterGraph_UninitIBasicAudio( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-}
-
diff --git a/dlls/quartz/ibasvid.c b/dlls/quartz/ibasvid.c
deleted file mode 100644
index dff5cd0..0000000
--- a/dlls/quartz/ibasvid.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * 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 "winuser.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,
-};
-
-
-HRESULT CFilterGraph_InitIBasicVideo2( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-	ICOM_VTBL(&pfg->basvid) = &ibasicvideo;
-
-	return NOERROR;
-}
-
-void CFilterGraph_UninitIBasicVideo2( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-}
diff --git a/dlls/quartz/idevenum.c b/dlls/quartz/idevenum.c
deleted file mode 100644
index 5c644be..0000000
--- a/dlls/quartz/idevenum.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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 "winuser.h"
-#include "winreg.h"
-#include "winerror.h"
-#include "wine/obj_base.h"
-#include "objidl.h"
-#include "oleidl.h"
-#include "ocidl.h"
-#include "strmif.h"
-#include "control.h"
-#include "uuids.h"
-#include "wine/unicode.h"
-
-#include "debugtools.h"
-DEFAULT_DEBUG_CHANNEL(quartz);
-
-#include "quartz_private.h"
-#include "devenum.h"
-#include "regsvr.h"
-#include "enumunk.h"
-#include "complist.h"
-#include "devmon.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);
-	HRESULT	hr;
-	HKEY	hKey;
-	QUARTZ_CompList*	pMonList;
-	IMoniker*	pMon;
-	DWORD	dwIndex;
-	LONG	lr;
-	WCHAR	wszPath[ 1024 ];
-	DWORD	dwLen;
-	DWORD	dwNameMax;
-	DWORD	cbName;
-	FILETIME	ftLastWrite;
-
-	TRACE("(%p)->(%s,%p,%08lx)\n",This,
-		debugstr_guid(rclsidDeviceClass),ppobj,dwFlags);
-	if ( dwFlags != 0 )
-	{
-		FIXME("unknown flags %08lx\n",dwFlags);
-		return E_NOTIMPL;
-	}
-
-	if ( ppobj == NULL )
-		return E_POINTER;
-	*ppobj = NULL;
-
-	hr = QUARTZ_CreateCLSIDPath(
-		wszPath, sizeof(wszPath)/sizeof(wszPath[0]),
-		rclsidDeviceClass, QUARTZ_wszInstance );
-	if ( FAILED(hr) )
-		return hr;
-
-	if ( RegOpenKeyExW( HKEY_CLASSES_ROOT, wszPath,
-		0, KEY_READ, &hKey ) != ERROR_SUCCESS )
-		return E_FAIL;
-
-	dwLen = strlenW(wszPath);
-	wszPath[dwLen++] = '\\'; wszPath[dwLen] = 0;
-	dwNameMax = sizeof(wszPath)/sizeof(wszPath[0]) - dwLen - 8;
-
-	pMonList = QUARTZ_CompList_Alloc();
-	if ( pMonList == NULL )
-	{
-		hr = E_OUTOFMEMORY;
-		goto err;
-	}
-
-	/* enumerate all subkeys. */
-	dwIndex = 0;
-	while ( 1 )
-	{
-		cbName = dwNameMax;
-		lr = RegEnumKeyExW(
-			hKey, dwIndex, &wszPath[dwLen], &cbName,
-			NULL, NULL, NULL, &ftLastWrite );
-		if ( lr == ERROR_NO_MORE_ITEMS )
-			break;
-		if ( lr != ERROR_SUCCESS )
-		{
-			hr = E_FAIL;
-			goto err;
-		}
-
-		hr = QUARTZ_CreateDeviceMoniker(
-			HKEY_CLASSES_ROOT, wszPath, &pMon );
-		if ( FAILED(hr) )
-			goto err;
-
-		hr = QUARTZ_CompList_AddComp(
-			pMonList, (IUnknown*)pMon, NULL, 0 );
-		IMoniker_Release( pMon );
-
-		if ( FAILED(hr) )
-			goto err;
-
-		dwIndex ++;
-	}
-
-	/* create an enumerator. */
-	hr = QUARTZ_CreateEnumUnknown(
-		&IID_IEnumMoniker, (void**)ppobj, pMonList );
-	if ( FAILED(hr) )
-		goto err;
-
-	hr = S_OK;
-err:
-	if ( pMonList != NULL )
-		QUARTZ_CompList_Free( pMonList );
-	RegCloseKey( hKey );
-
-	return hr;
-}
-
-static ICOM_VTABLE(ICreateDevEnum) icreatedevenum =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	/* IUnknown fields */
-	ICreateDevEnum_fnQueryInterface,
-	ICreateDevEnum_fnAddRef,
-	ICreateDevEnum_fnRelease,
-	/* ICreateDevEnum fields */
-	ICreateDevEnum_fnCreateClassEnumerator,
-};
-
-HRESULT CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde )
-{
-	TRACE("(%p)\n",psde);
-	ICOM_VTBL(&psde->createdevenum) = &icreatedevenum;
-
-	return NOERROR;
-}
-
-void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde )
-{
-	TRACE("(%p)\n",psde);
-}
diff --git a/dlls/quartz/ifgraph.c b/dlls/quartz/ifgraph.c
index 8e0f04d..ecff0de 100644
--- a/dlls/quartz/ifgraph.c
+++ b/dlls/quartz/ifgraph.c
@@ -1,8 +1,11 @@
 /*
  * Implementation of IFilterGraph.
  *
- * FIXME - stub.
- * FIXME - implement IGraphBuilder / IFilterGraph2.
+ * FIXME - create a thread to process some methods correctly.
+ *
+ * FIXME - ReconnectEx
+ * FIXME - process Pause/Stop asynchronously and notify when completed.
+ *
  *
  * hidenori@a2.ctktv.ne.jp
  */
@@ -21,6 +24,7 @@
 #include "uuids.h"
 #include "vfwmsgs.h"
 #include "wine/unicode.h"
+#include "evcode.h"
 
 #include "debugtools.h"
 DEFAULT_DEBUG_CHANNEL(quartz);
@@ -28,6 +32,7 @@
 #include "quartz_private.h"
 #include "fgraph.h"
 #include "enumunk.h"
+#include "sysclock.h"
 
 
 static HRESULT CFilterGraph_DisconnectAllPins( IBaseFilter* pFilter )
@@ -111,6 +116,7 @@
 IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pName)
 {
 	CFilterGraph_THIS(iface,fgraph);
+	FILTER_STATE fs;
 	FILTER_INFO	info;
 	HRESULT	hr;
 	HRESULT	hrSucceeded = S_OK;
@@ -121,6 +127,16 @@
 
 	QUARTZ_CompList_Lock( This->m_pFilterList );
 
+	hr = IMediaFilter_GetState(CFilterGraph_IMediaFilter(This),0,&fs);
+	if ( hr == VFW_S_STATE_INTERMEDIATE )
+		hr = VFW_E_STATE_CHANGED;
+	if ( fs != State_Stopped )
+		hr = VFW_E_NOT_STOPPED;
+	if ( FAILED(hr) )
+		goto end;
+
+	TRACE( "(%p) search the specified name.\n",This );
+
 	if ( pName != NULL )
 	{
 		pItem = QUARTZ_CompList_SearchData(
@@ -180,6 +196,8 @@
 	goto end;
 
 name_ok:
+	TRACE( "(%p) add this filter.\n",This );
+
 	/* register this filter. */
 	hr = QUARTZ_CompList_AddComp(
 		This->m_pFilterList, (IUnknown*)pFilter,
@@ -188,13 +206,23 @@
 		goto end;
 
 	hr = IBaseFilter_JoinFilterGraph(pFilter,(IFilterGraph*)iface,pName);
+	if ( SUCCEEDED(hr) )
+	{
+		EnterCriticalSection( &This->m_csClock );
+		hr = IBaseFilter_SetSyncSource( pFilter, This->m_pClock );
+		LeaveCriticalSection( &This->m_csClock );
+	}
 	if ( FAILED(hr) )
 	{
+		IBaseFilter_JoinFilterGraph(pFilter,NULL,pName);
 		QUARTZ_CompList_RemoveComp(
 			This->m_pFilterList,(IUnknown*)pFilter);
 		goto end;
 	}
 
+	/* IDistributorNotify_NotifyGraphChange() */
+	IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
+			EC_GRAPH_CHANGED, 0, 0);
 	EnterCriticalSection( &This->m_csGraphVersion );
 	This->m_lGraphVersion ++;
 	LeaveCriticalSection( &This->m_csGraphVersion );
@@ -203,6 +231,8 @@
 end:
 	QUARTZ_CompList_Unlock( This->m_pFilterList );
 
+	TRACE( "(%p) return %08lx\n", This, hr );
+
 	return hr;
 }
 
@@ -211,27 +241,42 @@
 {
 	CFilterGraph_THIS(iface,fgraph);
 	QUARTZ_CompListItem*	pItem;
+	FILTER_STATE fs;
 	HRESULT	hr = NOERROR;
 
 	TRACE( "(%p)->(%p)\n",This,pFilter );
 
 	QUARTZ_CompList_Lock( This->m_pFilterList );
 
+	hr = IMediaFilter_GetState(CFilterGraph_IMediaFilter(This),0,&fs);
+	if ( hr == VFW_S_STATE_INTERMEDIATE )
+		hr = VFW_E_STATE_CHANGED;
+	if ( fs != State_Stopped )
+		hr = VFW_E_NOT_STOPPED;
+	if ( FAILED(hr) )
+		goto end;
+
+	hr = S_FALSE; /* FIXME? */
 	pItem = QUARTZ_CompList_SearchComp(
 		This->m_pFilterList, (IUnknown*)pFilter );
 	if ( pItem != NULL )
 	{
 		CFilterGraph_DisconnectAllPins(pFilter);
+		IBaseFilter_SetSyncSource( pFilter, NULL );
 		hr = IBaseFilter_JoinFilterGraph(
 			pFilter, NULL, QUARTZ_CompList_GetDataPtr(pItem) );
 		QUARTZ_CompList_RemoveComp(
 			This->m_pFilterList, (IUnknown*)pFilter );
 	}
 
+	/* IDistributorNotify_NotifyGraphChange() */
+	IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
+			EC_GRAPH_CHANGED, 0, 0);
 	EnterCriticalSection( &This->m_csGraphVersion );
 	This->m_lGraphVersion ++;
 	LeaveCriticalSection( &This->m_csGraphVersion );
 
+end:;
 	QUARTZ_CompList_Unlock( This->m_pFilterList );
 
 	return hr;
@@ -332,34 +377,35 @@
 
 	pConnTo = NULL;
 	hr = IPin_ConnectedTo(pIn,&pConnTo);
-	if ( FAILED(hr) )
-		goto end;
-	if ( pConnTo != NULL )
+	if ( hr == NOERROR && pConnTo != NULL )
 	{
 		IPin_Release(pConnTo);
+		hr = VFW_E_ALREADY_CONNECTED;
 		goto end;
 	}
 
 	pConnTo = NULL;
 	hr = IPin_ConnectedTo(pOut,&pConnTo);
-	if ( FAILED(hr) )
-		goto end;
-	if ( pConnTo != NULL )
+	if ( hr == NOERROR && pConnTo != NULL )
 	{
 		IPin_Release(pConnTo);
+		hr = VFW_E_ALREADY_CONNECTED;
 		goto end;
 	}
 
-	hr = IPin_Connect(pIn,pOut,pmt);
-	if ( FAILED(hr) )
-		goto end;
+	TRACE("(%p) try to connect %p<->%p\n",This,pIn,pOut);
 	hr = IPin_Connect(pOut,pIn,pmt);
 	if ( FAILED(hr) )
 	{
+		TRACE("(%p)->Connect(%p,%p) hr = %08lx\n",pOut,pIn,pmt,hr);
+		IPin_Disconnect(pOut);
 		IPin_Disconnect(pIn);
 		goto end;
 	}
 
+	/* IDistributorNotify_NotifyGraphChange() */
+	IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
+			EC_GRAPH_CHANGED, 0, 0);
 	EnterCriticalSection( &This->m_csGraphVersion );
 	This->m_lGraphVersion ++;
 	LeaveCriticalSection( &This->m_csGraphVersion );
@@ -384,36 +430,67 @@
 {
 	CFilterGraph_THIS(iface,fgraph);
 
-	FIXME( "(%p)->(%p) stub!\n",This,pPin );
+	TRACE( "(%p)->(%p)\n",This,pPin );
 
-	EnterCriticalSection( &This->m_csGraphVersion );
-	This->m_lGraphVersion ++;
-	LeaveCriticalSection( &This->m_csGraphVersion );
-
-	return E_NOTIMPL;
+	return IFilterGraph2_ReconnectEx(iface,pPin,NULL);
 }
 
 static HRESULT WINAPI
 IFilterGraph2_fnDisconnect(IFilterGraph2* iface,IPin* pPin)
 {
 	CFilterGraph_THIS(iface,fgraph);
+	IPin* pConnTo;
+	HRESULT hr;
 
-	FIXME( "(%p)->(%p) stub!\n",This,pPin );
+	TRACE( "(%p)->(%p)\n",This,pPin );
 
+	QUARTZ_CompList_Lock( This->m_pFilterList );
+
+	pConnTo = NULL;
+	hr = IPin_ConnectedTo(pPin,&pConnTo);
+	if ( hr == NOERROR && pConnTo != NULL )
+	{
+		IPin_Disconnect(pConnTo);
+		IPin_Release(pConnTo);
+	}
+	hr = IPin_Disconnect(pPin);
+
+	/* IDistributorNotify_NotifyGraphChange() */
+	IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
+			EC_GRAPH_CHANGED, 0, 0);
 	EnterCriticalSection( &This->m_csGraphVersion );
 	This->m_lGraphVersion ++;
 	LeaveCriticalSection( &This->m_csGraphVersion );
 
-	return E_NOTIMPL;
+	QUARTZ_CompList_Unlock( This->m_pFilterList );
+
+	return hr;
 }
 
 static HRESULT WINAPI
 IFilterGraph2_fnSetDefaultSyncSource(IFilterGraph2* iface)
 {
 	CFilterGraph_THIS(iface,fgraph);
+	IUnknown* punk;
+	IReferenceClock* pClock;
+	HRESULT hr;
 
 	FIXME( "(%p)->() stub!\n", This );
-	return E_NOTIMPL;
+
+	/* FIXME - search all filters. */
+
+	hr = QUARTZ_CreateSystemClock( NULL, (void**)&punk );
+	if ( FAILED(hr) )
+		return hr;
+	hr = IUnknown_QueryInterface( punk, &IID_IReferenceClock, (void**)&pClock );	IUnknown_Release( punk );
+	if ( FAILED(hr) )
+		return hr;
+
+	hr = IMediaFilter_SetSyncSource(
+		CFilterGraph_IMediaFilter(This), pClock );
+	IReferenceClock_Release( pClock );
+
+	return hr;
 }
 
 static HRESULT WINAPI
@@ -583,6 +660,11 @@
 
 	FIXME( "(%p)->(%p,%p) stub!\n",This,pPin,pmt );
 
+	/* reconnect asynchronously. */
+
+	/* IDistributorNotify_NotifyGraphChange() */
+	IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
+			EC_GRAPH_CHANGED, 0, 0);
 	EnterCriticalSection( &This->m_csGraphVersion );
 	This->m_lGraphVersion ++;
 	LeaveCriticalSection( &This->m_csGraphVersion );
@@ -657,7 +739,7 @@
 		pItem = QUARTZ_CompList_GetFirst( pfg->m_pFilterList );
 		if ( pItem == NULL )
 			break;
-		IFilterGraph2_fnRemoveFilter(
+		IFilterGraph2_RemoveFilter(
 			(IFilterGraph2*)(&pfg->fgraph),
 			(IBaseFilter*)QUARTZ_CompList_GetItemPtr(pItem) );
 	}
diff --git a/dlls/quartz/ifmap.c b/dlls/quartz/ifmap.c
deleted file mode 100644
index 0e3424f..0000000
--- a/dlls/quartz/ifmap.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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 "winuser.h"
-#include "winreg.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"
-#include "regsvr.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);
-
-	FIXME("(%p)->(%s,%s,%08lx)\n",This,
-		debugstr_guid(&clsid),debugstr_w(lpwszName),dwMerit);
-
-	/* FIXME */
-	/* FIXME - handle dwMerit! */
-	return QUARTZ_RegisterAMovieFilter(
-		&CLSID_LegacyAmFilterCategory,
-		&clsid,
-		NULL, 0,
-		lpwszName, NULL, TRUE );
-}
-
-static HRESULT WINAPI
-IFilterMapper_fnRegisterFilterInstance(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,CLSID* pclsidMedia)
-{
-	CFilterMapper_THIS(iface,fmap);
-	HRESULT	hr;
-
-	FIXME("(%p)->()\n",This);
-
-	if ( pclsidMedia == NULL )
-		return E_POINTER;
-	hr = CoCreateGuid(pclsidMedia);
-	if ( FAILED(hr) )
-		return hr;
-
-	/* FIXME */
-	/* this doesn't work. */
-	/* return IFilterMapper_RegisterFilter(iface,
-		*pclsidMedia,lpwszName,0x60000000); */
-
-	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);
-
-	FIXME("(%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);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IFilterMapper_fnUnregisterFilter(IFilterMapper* iface,CLSID clsidFilter)
-{
-	CFilterMapper_THIS(iface,fmap);
-
-	FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidFilter));
-
-	/* FIXME */
-	return QUARTZ_RegisterAMovieFilter(
-		&CLSID_LegacyAmFilterCategory,
-		&clsidFilter,
-		NULL, 0, NULL, NULL, FALSE );
-}
-
-static HRESULT WINAPI
-IFilterMapper_fnUnregisterFilterInstance(IFilterMapper* iface,CLSID clsidMedia)
-{
-	CFilterMapper_THIS(iface,fmap);
-
-	FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidMedia));
-
-	/* FIXME */
-	/* this doesn't work. */
-	/* return IFilterMapper_UnregisterFilter(iface,clsidMedia); */
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IFilterMapper_fnUnregisterPin(IFilterMapper* iface,CLSID clsidPin,LPCWSTR lpwszName)
-{
-	CFilterMapper_THIS(iface,fmap);
-
-	FIXME("(%p)->(%s,%s) stub!\n",This,
-		debugstr_guid(&clsidPin),debugstr_w(lpwszName));
-
-	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);
-
-	FIXME("(%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,
-};
-
-
-HRESULT CFilterMapper_InitIFilterMapper( CFilterMapper* pfm )
-{
-	TRACE("(%p)\n",pfm);
-	ICOM_VTBL(&pfm->fmap) = &ifmap;
-
-	return NOERROR;
-}
-
-void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm )
-{
-	TRACE("(%p)\n",pfm);
-}
diff --git a/dlls/quartz/ifmap3.c b/dlls/quartz/ifmap3.c
deleted file mode 100644
index c5e8964..0000000
--- a/dlls/quartz/ifmap3.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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 "winuser.h"
-#include "winreg.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"
-#include "regsvr.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)->(%s,%lu,%s) stub!\n",This,
-		debugstr_guid(rclsidCategory),
-		(unsigned long)dwMerit,debugstr_w(lpwszDesc));
-
-	return E_NOTIMPL;
-}
-
-
-static HRESULT WINAPI
-IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter)
-{
-	CFilterMapper2_THIS(iface,fmap3);
-
-	FIXME("(%p)->(%s,%s,%s) stub!\n",This,
-		debugstr_guid(pclsidCategory),
-		debugstr_w(lpwszInst),
-		debugstr_guid(rclsidFilter));
-
-	if ( pclsidCategory == NULL )
-		pclsidCategory = &CLSID_LegacyAmFilterCategory;
-
-	/* FIXME */
-	return QUARTZ_RegisterAMovieFilter(
-		pclsidCategory,
-		rclsidFilter,
-		NULL, 0,
-		NULL, lpwszInst, FALSE );
-}
-
-
-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)->(%s,%s,%p,%s,%s,%p) stub!\n",This,
-		debugstr_guid(rclsidFilter),debugstr_w(lpName),
-		ppMoniker,debugstr_guid(pclsidCategory),
-		debugstr_w(lpwszInst),pRF2 );
-
-	if ( lpName == NULL || pRF2 == NULL )
-		return E_POINTER;
-
-	if ( ppMoniker != NULL )
-	{
-		FIXME( "ppMoniker != NULL - not implemented!\n" );
-		return E_NOTIMPL;
-	}
-
-	if ( pclsidCategory == NULL )
-		pclsidCategory = &CLSID_LegacyAmFilterCategory;
-
-	/* FIXME!! - all members in REGFILTER2 are ignored ! */
-
-	return QUARTZ_RegisterAMovieFilter(
-		pclsidCategory,
-		rclsidFilter,
-		NULL, 0,
-		lpName, lpwszInst, TRUE );
-}
-
-
-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,
-};
-
-
-HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* pfm )
-{
-	TRACE("(%p)\n",pfm);
-	ICOM_VTBL(&pfm->fmap3) = &ifmap3;
-
-	return NOERROR;
-}
-
-void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* pfm )
-{
-	TRACE("(%p)\n",pfm);
-}
-
diff --git a/dlls/quartz/igconfig.c b/dlls/quartz/igconfig.c
new file mode 100644
index 0000000..4f7465d
--- /dev/null
+++ b/dlls/quartz/igconfig.c
@@ -0,0 +1,200 @@
+/*
+ * Implementation of IGraphConfig for FilterGraph.
+ *
+ * FIXME - stub.
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.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
+IGraphConfig_fnQueryInterface(IGraphConfig* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IGraphConfig_fnAddRef(IGraphConfig* iface)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IGraphConfig_fnRelease(IGraphConfig* iface)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+
+
+static HRESULT WINAPI
+IGraphConfig_fnReconnect(IGraphConfig* iface,IPin* pOut,IPin* pIn,const AM_MEDIA_TYPE* pmt,IBaseFilter* pFilter,HANDLE hAbort,DWORD dwFlags)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnReconfigure(IGraphConfig* iface,IGraphConfigCallback* pCallback,PVOID pvParam,DWORD dwFlags,HANDLE hAbort)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnAddFilterToCache(IGraphConfig* iface,IBaseFilter* pFilter)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnEnumCacheFilter(IGraphConfig* iface,IEnumFilters** ppenum)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnRemoveFilterFromCache(IGraphConfig* iface,IBaseFilter* pFilter)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnGetStartTime(IGraphConfig* iface,REFERENCE_TIME* prt)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnPushThroughData(IGraphConfig* iface,IPin* pOut,IPinConnection* pConn,HANDLE hAbort)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnSetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnGetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD* pdwFlags)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnRemoveFilterEx(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+
+
+
+static ICOM_VTABLE(IGraphConfig) igraphconfig =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IGraphConfig_fnQueryInterface,
+	IGraphConfig_fnAddRef,
+	IGraphConfig_fnRelease,
+	/* IGraphConfig fields */
+	IGraphConfig_fnReconnect,
+	IGraphConfig_fnReconfigure,
+	IGraphConfig_fnAddFilterToCache,
+	IGraphConfig_fnEnumCacheFilter,
+	IGraphConfig_fnRemoveFilterFromCache,
+	IGraphConfig_fnGetStartTime,
+	IGraphConfig_fnPushThroughData,
+	IGraphConfig_fnSetFilterFlags,
+	IGraphConfig_fnGetFilterFlags,
+	IGraphConfig_fnRemoveFilterEx,
+};
+
+
+
+HRESULT CFilterGraph_InitIGraphConfig( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->grphconf) = &igraphconfig;
+
+	return NOERROR;
+}
+
+void CFilterGraph_UninitIGraphConfig( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
+
diff --git a/dlls/quartz/imem.c b/dlls/quartz/imem.c
deleted file mode 100644
index dea4429..0000000
--- a/dlls/quartz/imem.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Implementation of CLSID_MemoryAllocator.
- *
- * FIXME - not tested.
- *
- * hidenori@a2.ctktv.ne.jp
- */
-
-#include "config.h"
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winerror.h"
-#include "wine/obj_base.h"
-#include "strmif.h"
-#include "uuids.h"
-
-#include "debugtools.h"
-DEFAULT_DEBUG_CHANNEL(quartz);
-
-#include "quartz_private.h"
-#include "memalloc.h"
-
-
-static HRESULT WINAPI
-IMemAllocator_fnQueryInterface(IMemAllocator* iface,REFIID riid,void** ppobj)
-{
-	CMemoryAllocator_THIS(iface,memalloc);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
-}
-
-static ULONG WINAPI
-IMemAllocator_fnAddRef(IMemAllocator* iface)
-{
-	CMemoryAllocator_THIS(iface,memalloc);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_AddRef(This->unk.punkControl);
-}
-
-static ULONG WINAPI
-IMemAllocator_fnRelease(IMemAllocator* iface)
-{
-	CMemoryAllocator_THIS(iface,memalloc);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_Release(This->unk.punkControl);
-}
-
-static HRESULT WINAPI
-IMemAllocator_fnSetProperties(IMemAllocator* iface,ALLOCATOR_PROPERTIES* pPropReq,ALLOCATOR_PROPERTIES* pPropActual)
-{
-	CMemoryAllocator_THIS(iface,memalloc);
-	long	padding;
-	HRESULT	hr;
-
-	TRACE( "(%p)->(%p,%p)\n", This, pPropReq, pPropActual );
-
-	if ( pPropReq == NULL || pPropActual == NULL )
-		return E_POINTER;
-	if ( pPropReq->cBuffers < 0 ||
-	     pPropReq->cbBuffer < 0 ||
-	     pPropReq->cbAlign < 0 ||
-	     pPropReq->cbPrefix < 0 )
-		return E_INVALIDARG;
-
-	if ( ( pPropReq->cbAlign & (pPropReq->cbAlign-1) ) != 0 )
-		return E_INVALIDARG;
-
-	hr = NOERROR;
-
-	EnterCriticalSection( &This->csMem );
-
-	if ( This->pData != NULL || This->ppSamples != NULL )
-	{
-		/* if commited, properties must not be changed. */
-		hr = E_UNEXPECTED;
-		goto end;
-	}
-
-	This->prop.cBuffers = pPropReq->cBuffers;
-	This->prop.cbBuffer = pPropReq->cbBuffer;
-	This->prop.cbAlign = pPropReq->cbAlign;
-	This->prop.cbPrefix = pPropReq->cbPrefix;
-
-	if ( This->prop.cbAlign == 0 )
-		This->prop.cbAlign = 1;
-	padding = This->prop.cbAlign -
-		( (This->prop.cbBuffer+This->prop.cbPrefix) % This->prop.cbAlign );
-
-	This->prop.cbBuffer += padding;
-
-	memcpy( pPropActual, &This->prop, sizeof(ALLOCATOR_PROPERTIES) );
-
-end:
-	LeaveCriticalSection( &This->csMem );
-
-	return hr;
-}
-
-static HRESULT WINAPI
-IMemAllocator_fnGetProperties(IMemAllocator* iface,ALLOCATOR_PROPERTIES* pProp)
-{
-	CMemoryAllocator_THIS(iface,memalloc);
-
-	TRACE( "(%p)->(%p)\n", This, pProp );
-
-	if ( pProp == NULL )
-		return E_POINTER;
-
-	EnterCriticalSection( &This->csMem );
-
-	memcpy( pProp, &This->prop, sizeof(ALLOCATOR_PROPERTIES) );
-
-	LeaveCriticalSection( &This->csMem );
-
-	return NOERROR;
-}
-
-static HRESULT WINAPI
-IMemAllocator_fnCommit(IMemAllocator* iface)
-{
-	CMemoryAllocator_THIS(iface,memalloc);
-	HRESULT	hr;
-	LONG	lBufSize;
-	LONG	i;
-	BYTE*	pCur;
-
-	TRACE( "(%p)->()\n", This );
-
-	EnterCriticalSection( &This->csMem );
-
-	hr = NOERROR;
-	if ( This->pData != NULL || This->ppSamples != NULL ||
-	     This->prop.cBuffers <= 0 )
-		goto end;
-
-	lBufSize = This->prop.cBuffers *
-		(This->prop.cbBuffer + This->prop.cbPrefix) +
-		This->prop.cbAlign;
-	if ( lBufSize <= 0 )
-		lBufSize = 1;
-
-	This->pData = (BYTE*)QUARTZ_AllocMem( lBufSize );
-	if ( This->pData == NULL )
-	{
-		hr = E_OUTOFMEMORY;
-		goto end;
-	}
-
-	This->ppSamples = (CMemMediaSample**)QUARTZ_AllocMem(
-		sizeof(CMemMediaSample*) * This->prop.cBuffers );
-	if ( This->ppSamples == NULL )
-	{
-		hr = E_OUTOFMEMORY;
-		goto end;
-	}
-
-	for ( i = 0; i < This->prop.cBuffers; i++ )
-		This->ppSamples[i] = NULL;
-
-	pCur = This->pData + This->prop.cbAlign - ((This->pData-(BYTE*)NULL) & (This->prop.cbAlign-1));
-
-	for ( i = 0; i < This->prop.cBuffers; i++ )
-	{
-		hr = QUARTZ_CreateMemMediaSample(
-			pCur, (This->prop.cbBuffer + This->prop.cbPrefix),
-			iface, &This->ppSamples[i] );
-		if ( FAILED(hr) )
-			goto end;
-		pCur += (This->prop.cbBuffer + This->prop.cbPrefix);
-	}
-
-	hr = NOERROR;
-end:
-	if ( FAILED(hr) )
-		IMemAllocator_Decommit(iface);
-
-	LeaveCriticalSection( &This->csMem );
-
-	return hr;
-}
-
-static HRESULT WINAPI
-IMemAllocator_fnDecommit(IMemAllocator* iface)
-{
-	CMemoryAllocator_THIS(iface,memalloc);
-	HRESULT	hr;
-	LONG	i;
-	BOOL	bBlock;
-
-	TRACE( "(%p)->()\n", This );
-
-	EnterCriticalSection( &This->csMem );
-
-	hr = NOERROR;
-
-	if ( This->pData == NULL && This->ppSamples == NULL )
-		goto end;
-
-	while ( 1 )
-	{
-		bBlock = FALSE;
-		i = 0;
-
-		ResetEvent( This->hEventSample );
-
-		while ( 1 )
-		{
-			if ( i >= This->prop.cBuffers )
-				break;
-
-			if ( This->ppSamples[i] != NULL )
-			{
-				if ( This->ppSamples[i]->ref == 0 )
-				{
-					QUARTZ_DestroyMemMediaSample( This->ppSamples[i] );
-					This->ppSamples[i] = NULL;
-				}
-				else
-				{
-					bBlock = TRUE;
-				}
-			}
-			i++;
-		}
-
-		if ( !bBlock )
-		{
-			hr = NOERROR;
-			break;
-		}
-
-		WaitForSingleObject( This->hEventSample, INFINITE );
-	}
-
-end:
-	LeaveCriticalSection( &This->csMem );
-
-	return hr;
-}
-
-static HRESULT WINAPI
-IMemAllocator_fnGetBuffer(IMemAllocator* iface,IMediaSample** ppSample,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd,DWORD dwFlags)
-{
-	CMemoryAllocator_THIS(iface,memalloc);
-	LONG	i;
-	HRESULT	hr;
-
-	TRACE( "(%p)->(%p,%p,%p,%lu)\n", This, ppSample, prtStart, prtEnd, dwFlags );
-
-	if ( ppSample == NULL )
-		return E_POINTER;
-
-	EnterCriticalSection( &This->csMem );
-
-	hr = NOERROR;
-
-	if ( This->pData == NULL || This->ppSamples == NULL ||
-	     This->prop.cBuffers <= 0 )
-	{
-		hr = E_FAIL; /* FIXME? */
-		goto end;
-	}
-
-	while ( 1 )
-	{
-		ResetEvent( This->hEventSample );
-
-		for ( i = 0; i < This->prop.cBuffers; i++ )
-		{
-			if ( This->ppSamples[i]->ref == 0 )
-			{
-				*ppSample = (IMediaSample*)(This->ppSamples[i]);
-				IMediaSample_AddRef( *ppSample );
-				hr = NOERROR;
-				goto end;
-			}
-		}
-
-		if ( dwFlags & AM_GBF_NOWAIT )
-		{
-			hr = E_FAIL; /* FIXME? */
-			goto end;
-		}
-
-		WaitForSingleObject( This->hEventSample, INFINITE );
-	}
-
-end:
-	LeaveCriticalSection( &This->csMem );
-
-	return hr;
-}
-
-static HRESULT WINAPI
-IMemAllocator_fnReleaseBuffer(IMemAllocator* iface,IMediaSample* pSample)
-{
-	CMemoryAllocator_THIS(iface,memalloc);
-
-	TRACE( "(%p)->(%p)\n", This, pSample );
-	SetEvent( This->hEventSample );
-
-	return NOERROR;
-}
-
-
-
-static ICOM_VTABLE(IMemAllocator) imemalloc =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	/* IUnknown fields */
-	IMemAllocator_fnQueryInterface,
-	IMemAllocator_fnAddRef,
-	IMemAllocator_fnRelease,
-	/* IMemAllocator fields */
-	IMemAllocator_fnSetProperties,
-	IMemAllocator_fnGetProperties,
-	IMemAllocator_fnCommit,
-	IMemAllocator_fnDecommit,
-	IMemAllocator_fnGetBuffer,
-	IMemAllocator_fnReleaseBuffer,
-};
-
-
-HRESULT CMemoryAllocator_InitIMemAllocator( CMemoryAllocator* pma )
-{
-	TRACE("(%p)\n",pma);
-
-	ICOM_VTBL(&pma->memalloc) = &imemalloc;
-
-	ZeroMemory( &pma->prop, sizeof(pma->prop) );
-	pma->hEventSample = (HANDLE)NULL;
-	pma->pData = NULL;
-	pma->ppSamples = NULL;
-
-	pma->hEventSample = CreateEventA( NULL, TRUE, FALSE, NULL );
-	if ( pma->hEventSample == (HANDLE)NULL )
-		return E_OUTOFMEMORY;
-
-	InitializeCriticalSection( &pma->csMem );
-
-	return NOERROR;
-}
-
-void CMemoryAllocator_UninitIMemAllocator( CMemoryAllocator* pma )
-{
-	TRACE("(%p)\n",pma);
-
-	IMemAllocator_Decommit( (IMemAllocator*)(&pma->memalloc) );
-
-	DeleteCriticalSection( &pma->csMem );
-
-	if ( pma->hEventSample != (HANDLE)NULL )
-		CloseHandle( pma->hEventSample );
-}
diff --git a/dlls/quartz/imesink.c b/dlls/quartz/imesink.c
deleted file mode 100644
index bf3f7b9..0000000
--- a/dlls/quartz/imesink.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Implementation of IMediaEventSink for FilterGraph.
- *
- * FIXME - stub.
- *
- * hidenori@a2.ctktv.ne.jp
- */
-
-#include "config.h"
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.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
-IMediaEventSink_fnQueryInterface(IMediaEventSink* iface,REFIID riid,void** ppobj)
-{
-	CFilterGraph_THIS(iface,mediaeventsink);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
-}
-
-static ULONG WINAPI
-IMediaEventSink_fnAddRef(IMediaEventSink* iface)
-{
-	CFilterGraph_THIS(iface,mediaeventsink);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_AddRef(This->unk.punkControl);
-}
-
-static ULONG WINAPI
-IMediaEventSink_fnRelease(IMediaEventSink* iface)
-{
-	CFilterGraph_THIS(iface,mediaeventsink);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_Release(This->unk.punkControl);
-}
-
-static HRESULT WINAPI
-IMediaEventSink_fnNotify(IMediaEventSink* iface,long lEventCode,LONG_PTR lParam1,LONG_PTR lParam2)
-{
-	CFilterGraph_THIS(iface,mediaeventsink);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-
-static ICOM_VTABLE(IMediaEventSink) imediaeventsink =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	/* IUnknown fields */
-	IMediaEventSink_fnQueryInterface,
-	IMediaEventSink_fnAddRef,
-	IMediaEventSink_fnRelease,
-	/* IMediaEventSink fields */
-	IMediaEventSink_fnNotify,
-};
-
-
-
-HRESULT CFilterGraph_InitIMediaEventSink( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-	ICOM_VTBL(&pfg->mediaeventsink) = &imediaeventsink;
-
-	return NOERROR;
-}
-
-void CFilterGraph_UninitIMediaEventSink( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-}
-
diff --git a/dlls/quartz/imevent.c b/dlls/quartz/imevent.c
deleted file mode 100644
index dd3709f..0000000
--- a/dlls/quartz/imevent.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * 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 "winuser.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);
-
-	TRACE("(%p)->()\n",This);
-
-	*hEvent = (OAEVENT)This->m_hMediaEvent;
-
-	return NOERROR;
-}
-
-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,
-};
-
-
-HRESULT CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-	ICOM_VTBL(&pfg->mediaevent) = &imediaevent;
-
-	pfg->m_hMediaEvent = CreateEventA( NULL, TRUE, FALSE, NULL );
-	if ( pfg->m_hMediaEvent == (HANDLE)NULL )
-		return E_OUTOFMEMORY;
-
-	return NOERROR;
-}
-
-void CFilterGraph_UninitIMediaEventEx( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-
-	CloseHandle( pfg->m_hMediaEvent );
-}
diff --git a/dlls/quartz/imfilter.c b/dlls/quartz/imfilter.c
index a3c0aee..bafb553 100644
--- a/dlls/quartz/imfilter.c
+++ b/dlls/quartz/imfilter.c
@@ -19,6 +19,7 @@
 #include "control.h"
 #include "uuids.h"
 #include "vfwmsgs.h"
+#include "evcode.h"
 
 #include "debugtools.h"
 DEFAULT_DEBUG_CHANNEL(quartz);
@@ -127,6 +128,8 @@
 
 	if ( This->m_stateGraph != State_Stopped )
 	{
+		/* IDistributorNotify_Stop() */
+
 		QUARTZ_CompList_Lock( This->m_pFilterList );
 
 		pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
@@ -171,6 +174,8 @@
 
 	if ( This->m_stateGraph != State_Paused )
 	{
+		/* IDistributorNotify_Pause() */
+
 		QUARTZ_CompList_Lock( This->m_pFilterList );
 
 		pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
@@ -210,23 +215,32 @@
 
 	TRACE("(%p)->()\n",This);
 
-	/* handle the special time. */
-	if ( rtStart == (REFERENCE_TIME)0 )
+	EnterCriticalSection( &This->m_csGraphState );
+
+	if ( This->m_stateGraph == State_Stopped )
 	{
-		hr = IMediaFilter_GetSyncSource(iface,&pClock);
-		if ( hr == S_OK && pClock != NULL )
-		{
-			IReferenceClock_GetTime(pClock,&rtStart);
-			IReferenceClock_Release(pClock);
-		}
+		hr = IMediaFilter_Pause(iface);
+		if ( FAILED(hr) )
+			goto end;
 	}
 
-	hr = S_OK;
+        /* handle the special time. */
+        if ( rtStart == (REFERENCE_TIME)0 )
+        {
+                hr = IMediaFilter_GetSyncSource(iface,&pClock);
+                if ( hr == S_OK && pClock != NULL )
+                {
+                        IReferenceClock_GetTime(pClock,&rtStart);
+                        IReferenceClock_Release(pClock);
+                }
+        }
 
-	EnterCriticalSection( &This->m_csGraphState );
+	hr = NOERROR;
 
 	if ( This->m_stateGraph != State_Running )
 	{
+		/* IDistributorNotify_Run() */
+
 		QUARTZ_CompList_Lock( This->m_pFilterList );
 
 		pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
@@ -249,6 +263,7 @@
 		This->m_stateGraph = State_Running;
 	}
 
+end:
 	LeaveCriticalSection( &This->m_csGraphState );
 
 	return hr;
@@ -266,10 +281,6 @@
 	if ( pState == NULL )
 		return E_POINTER;
 
-	EnterCriticalSection( &This->m_csGraphState );
-	*pState = This->m_stateGraph;
-	LeaveCriticalSection( &This->m_csGraphState );
-
 	dwTickStart = GetTickCount();
 
 	while ( 1 )
@@ -292,6 +303,10 @@
 			dwTimeOut -= dwTickUsed;
 	}
 
+	EnterCriticalSection( &This->m_csGraphState );
+	*pState = This->m_stateGraph;
+	LeaveCriticalSection( &This->m_csGraphState );
+
 	return hr;
 }
 
@@ -299,20 +314,77 @@
 IMediaFilter_fnSetSyncSource(IMediaFilter* iface,IReferenceClock* pobjClock)
 {
 	CFilterGraph_THIS(iface,mediafilter);
+	QUARTZ_CompListItem*	pItem;
+	IBaseFilter*	pFilter;
+	HRESULT hr = NOERROR;
+	HRESULT hrCur;
 
-	FIXME("(%p)->() stub!\n",This);
+	TRACE("(%p)->(%p)\n",This,pobjClock);
 
-	return E_NOTIMPL;
+	/* IDistributorNotify_SetSyncSource() */
+
+	EnterCriticalSection( &This->m_csClock );
+	QUARTZ_CompList_Lock( This->m_pFilterList );
+
+	if ( This->m_pClock != NULL )
+	{
+		IReferenceClock_Release(This->m_pClock);
+		This->m_pClock = NULL;
+	}
+
+	This->m_pClock = pobjClock;
+	if ( pobjClock != NULL )
+		IReferenceClock_AddRef( pobjClock );
+
+	pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
+	while ( pItem != NULL )
+	{
+		pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
+		hrCur = IBaseFilter_SetSyncSource(pFilter,pobjClock);
+		if ( FAILED(hrCur) )
+			hr = hrCur;
+		pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
+	}
+
+	QUARTZ_CompList_Unlock( This->m_pFilterList );
+
+	if ( This->m_pClock != NULL )
+		IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
+			EC_CLOCK_CHANGED, 0, 0);
+	else
+		IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
+			EC_CLOCK_UNSET, 0, 0);
+
+	LeaveCriticalSection( &This->m_csClock );
+
+	TRACE( "hr = %08lx\n", hr );
+
+	return hr;
 }
 
 static HRESULT WINAPI
 IMediaFilter_fnGetSyncSource(IMediaFilter* iface,IReferenceClock** ppobjClock)
 {
 	CFilterGraph_THIS(iface,mediafilter);
+	HRESULT hr = VFW_E_NO_CLOCK;
 
-	FIXME("(%p)->() stub!\n",This);
+	TRACE("(%p)->(%p)\n",This,ppobjClock);
 
-	return E_NOTIMPL;
+	if ( ppobjClock == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->m_csClock );
+	*ppobjClock = This->m_pClock;
+	if ( This->m_pClock != NULL )
+	{
+		hr = NOERROR;
+		IReferenceClock_AddRef( This->m_pClock );
+	}
+	LeaveCriticalSection( &This->m_csClock );
+
+	TRACE( "hr = %08lx\n", hr );
+
+	return hr;
 }
 
 
@@ -342,7 +414,9 @@
 	ICOM_VTBL(&pfg->mediafilter) = &imediafilter;
 
 	InitializeCriticalSection( &pfg->m_csGraphState );
+	InitializeCriticalSection( &pfg->m_csClock );
 	pfg->m_stateGraph = State_Stopped;
+	pfg->m_pClock = NULL;
 
 	return NOERROR;
 }
@@ -351,5 +425,12 @@
 {
 	TRACE("(%p)\n",pfg);
 
+	if ( pfg->m_pClock != NULL )
+	{
+		IReferenceClock_Release( pfg->m_pClock );
+		pfg->m_pClock = NULL;
+	}
+
 	DeleteCriticalSection( &pfg->m_csGraphState );
+	DeleteCriticalSection( &pfg->m_csClock );
 }
diff --git a/dlls/quartz/imseek.c b/dlls/quartz/imseek.c
index 4d4a98c..2a515fb 100644
--- a/dlls/quartz/imseek.c
+++ b/dlls/quartz/imseek.c
@@ -2,6 +2,7 @@
  * Implementation of IMediaSeeking for FilterGraph.
  *
  * FIXME - stub.
+ * FIXME - this interface should be allocated as a plug-in(?)
  *
  * hidenori@a2.ctktv.ne.jp
  */
@@ -133,6 +134,7 @@
 {
 	CFilterGraph_THIS(iface,mediaseeking);
 
+	/* the following line may produce too many FIXMEs... */
 	FIXME("(%p)->() stub!\n",This);
 
 	return E_NOTIMPL;
diff --git a/dlls/quartz/irclock.c b/dlls/quartz/irclock.c
deleted file mode 100644
index e03623d..0000000
--- a/dlls/quartz/irclock.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Implementation of CLSID_SystemClock.
- *
- * FIXME - not tested yet.
- *
- * hidenori@a2.ctktv.ne.jp
- */
-
-#include "config.h"
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winerror.h"
-#include "wine/obj_base.h"
-#include "strmif.h"
-#include "uuids.h"
-
-#include "debugtools.h"
-DEFAULT_DEBUG_CHANNEL(quartz);
-
-#include "quartz_private.h"
-#include "sysclock.h"
-
-
-#define	QUARTZ_MSG_ADDTIMER			(WM_APP+0)
-#define	QUARTZ_MSG_REMOVETIMER		(WM_APP+1)
-#define	QUARTZ_MSG_EXITTHREAD		(WM_APP+2)
-
-
-/****************************************************************************/
-
-static QUARTZ_TimerEntry* IReferenceClock_AllocTimerEntry(CSystemClock* This)
-{
-	QUARTZ_TimerEntry*	pEntry;
-	DWORD	dw;
-
-	pEntry = &This->m_timerEntries[0];
-	for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
-	{
-		if ( pEntry->hEvent == (HANDLE)NULL )
-			return pEntry;
-		pEntry ++;
-	}
-
-	return NULL;
-}
-
-static QUARTZ_TimerEntry* IReferenceClock_SearchTimer(CSystemClock* This, DWORD dwAdvCookie)
-{
-	QUARTZ_TimerEntry*	pEntry;
-	DWORD	dw;
-
-	pEntry = &This->m_timerEntries[0];
-	for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
-	{
-		if ( pEntry->hEvent != (HANDLE)NULL &&
-			 pEntry->dwAdvCookie == dwAdvCookie )
-			return pEntry;
-		pEntry ++;
-	}
-
-	return NULL;
-}
-
-static void IReferenceClock_OnTimerUpdated(CSystemClock* This)
-{
-	QUARTZ_TimerEntry*	pEntry;
-	REFERENCE_TIME	rtCur;
-	REFERENCE_TIME	rtSignal;
-	REFERENCE_TIME	rtCount;
-	HRESULT	hr;
-	LONG	lCount;
-	DWORD	dw;
-
-	hr = IReferenceClock_GetTime((IReferenceClock*)(&This->refclk),&rtCur);
-	if ( hr != NOERROR )
-		return;
-
-	pEntry = &This->m_timerEntries[0];
-	for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
-	{
-		if ( pEntry->hEvent != (HANDLE)NULL )
-		{
-			rtSignal = pEntry->rtStart + pEntry->rtInterval;
-			if ( rtCur >= rtSignal )
-			{
-				if ( pEntry->fPeriodic )
-				{
-					rtCount = ((rtCur - pEntry->rtStart) / pEntry->rtInterval);
-					lCount = ( rtCount > (REFERENCE_TIME)0x7fffffff ) ?
-						(LONG)0x7fffffff : (LONG)rtCount;
-					if ( !ReleaseSemaphore( pEntry->hEvent, lCount, NULL ) )
-					{
-						while ( lCount > 0 )
-						{
-							if ( !ReleaseSemaphore( pEntry->hEvent, 1, NULL ) )
-								break;
-						}
-					}
-				}
-				else
-				{
-					SetEvent( pEntry->hEvent );
-					pEntry->hEvent = (HANDLE)NULL;
-				}
-			}
-		}
-		pEntry ++;
-	}
-}
-
-static
-DWORD WINAPI IReferenceClock_TimerEntry( LPVOID lpvParam )
-{
-	CSystemClock*	This = (CSystemClock*)lpvParam;
-	MSG	msg;
-	DWORD	dwRes;
-
-	/* initialize the message queue. */
-	PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE );
-	/* resume the owner thread. */
-	SetEvent( This->m_hEventInit );
-
-	/* message loop. */
-	while ( 1 )
-	{
-		dwRes = MsgWaitForMultipleObjects(
-			0, NULL, FALSE,
-			INFINITE, /* FIXME */
-			QS_ALLEVENTS );
-
-		EnterCriticalSection( &This->m_csClock );
-		IReferenceClock_OnTimerUpdated(This);
-		LeaveCriticalSection( &This->m_csClock );
-
-		while ( PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_REMOVE ) )
-		{
-			if ( msg.message == WM_QUIT )
-				goto quitthread;
-
-			if ( msg.hwnd != (HWND)NULL )
-			{
-				TranslateMessage( &msg );
-				DispatchMessageA( &msg );
-			}
-			else
-			{
-				switch ( msg.message )
-				{
-				case QUARTZ_MSG_ADDTIMER:
-				case QUARTZ_MSG_REMOVETIMER:
-					break;
-				case QUARTZ_MSG_EXITTHREAD:
-					PostQuitMessage(0);
-					break;
-				default:
-					FIXME( "invalid message %04u\n", (unsigned)msg.message );
-					break;
-				}
-			}
-		}
-	}
-
-quitthread:
-	return 0;
-}
-
-/****************************************************************************/
-
-static HRESULT WINAPI
-IReferenceClock_fnQueryInterface(IReferenceClock* iface,REFIID riid,void** ppobj)
-{
-	CSystemClock_THIS(iface,refclk);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
-}
-
-static ULONG WINAPI
-IReferenceClock_fnAddRef(IReferenceClock* iface)
-{
-	CSystemClock_THIS(iface,refclk);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_AddRef(This->unk.punkControl);
-}
-
-static ULONG WINAPI
-IReferenceClock_fnRelease(IReferenceClock* iface)
-{
-	CSystemClock_THIS(iface,refclk);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_Release(This->unk.punkControl);
-}
-
-static HRESULT WINAPI
-IReferenceClock_fnGetTime(IReferenceClock* iface,REFERENCE_TIME* prtTime)
-{
-	CSystemClock_THIS(iface,refclk);
-	DWORD	dwTimeCur;
-
-	TRACE( "(%p)->(%p)\n", This, prtTime );
-
-	if ( prtTime == NULL )
-		return E_POINTER;
-
-	EnterCriticalSection( &This->m_csClock );
-
-	dwTimeCur = GetTickCount();
-	This->m_rtLast += (REFERENCE_TIME)(DWORD)(dwTimeCur - This->m_dwTimeLast) * (REFERENCE_TIME)10000;
-
-	This->m_dwTimeLast = dwTimeCur;
-
-	*prtTime = This->m_dwTimeLast;
-
-	LeaveCriticalSection( &This->m_csClock );
-
-	return NOERROR;
-}
-
-static HRESULT WINAPI
-IReferenceClock_fnAdviseTime(IReferenceClock* iface,REFERENCE_TIME rtBase,REFERENCE_TIME rtStream,HEVENT hEvent,DWORD_PTR* pdwAdvCookie)
-{
-	CSystemClock_THIS(iface,refclk);
-	QUARTZ_TimerEntry*	pEntry;
-	HRESULT	hr;
-	REFERENCE_TIME	rtCur;
-
-	TRACE( "(%p)->()\n", This );
-
-	if ( pdwAdvCookie == NULL )
-		return E_POINTER;
-	if ( hEvent == (HANDLE)NULL )
-		return E_INVALIDARG;
-
-	EnterCriticalSection( &This->m_csClock );
-
-	*pdwAdvCookie = (DWORD_PTR)(This->m_dwAdvCookieNext ++);
-
-	hr = IReferenceClock_GetTime(iface,&rtCur);
-	if ( hr != NOERROR )
-		goto err;
-	if ( rtCur >= (rtBase+rtStream) )
-	{
-		SetEvent(hEvent);
-		hr = NOERROR;
-		goto err;
-	}
-
-	pEntry = IReferenceClock_AllocTimerEntry(This);
-	if ( pEntry == NULL )
-	{
-		hr = E_FAIL;
-		goto err;
-	}
-
-	if ( !PostThreadMessageA(
-			This->m_idThreadTimer,
-			QUARTZ_MSG_ADDTIMER,
-			0, 0 ) )
-	{
-		hr = E_FAIL;
-		goto err;
-	}
-
-	pEntry->dwAdvCookie = *pdwAdvCookie;
-	pEntry->fPeriodic = FALSE;
-	pEntry->hEvent = hEvent;
-	pEntry->rtStart = rtBase;
-	pEntry->rtInterval = rtStream;
-
-	hr = NOERROR;
-err:
-	LeaveCriticalSection( &This->m_csClock );
-
-	return hr;
-}
-
-static HRESULT WINAPI
-IReferenceClock_fnAdvisePeriodic(IReferenceClock* iface,REFERENCE_TIME rtStart,REFERENCE_TIME rtPeriod,HSEMAPHORE hSemaphore,DWORD_PTR* pdwAdvCookie)
-{
-	CSystemClock_THIS(iface,refclk);
-	QUARTZ_TimerEntry*	pEntry;
-	HRESULT	hr;
-
-	TRACE( "(%p)->()\n", This );
-
-	if ( pdwAdvCookie == NULL )
-		return E_POINTER;
-	if ( hSemaphore == (HSEMAPHORE)NULL )
-		return E_INVALIDARG;
-
-	EnterCriticalSection( &This->m_csClock );
-
-	*pdwAdvCookie = (DWORD_PTR)(This->m_dwAdvCookieNext ++);
-
-	pEntry = IReferenceClock_AllocTimerEntry(This);
-	if ( pEntry == NULL )
-	{
-		hr = E_FAIL;
-		goto err;
-	}
-
-	if ( !PostThreadMessageA(
-			This->m_idThreadTimer,
-			QUARTZ_MSG_ADDTIMER,
-			0, 0 ) )
-	{
-		hr = E_FAIL;
-		goto err;
-	}
-
-	pEntry->dwAdvCookie = *pdwAdvCookie;
-	pEntry->fPeriodic = TRUE;
-	pEntry->hEvent = (HANDLE)hSemaphore;
-	pEntry->rtStart = rtStart;
-	pEntry->rtInterval = rtPeriod;
-
-	hr = NOERROR;
-err:
-	LeaveCriticalSection( &This->m_csClock );
-
-	return hr;
-}
-
-static HRESULT WINAPI
-IReferenceClock_fnUnadvise(IReferenceClock* iface,DWORD_PTR dwAdvCookie)
-{
-	CSystemClock_THIS(iface,refclk);
-	QUARTZ_TimerEntry*	pEntry;
-
-	TRACE( "(%p)->(%lu)\n", This, (DWORD)dwAdvCookie );
-
-	EnterCriticalSection( &This->m_csClock );
-
-	pEntry = IReferenceClock_SearchTimer(This,(DWORD)dwAdvCookie);
-	if ( pEntry != NULL )
-	{
-		pEntry->hEvent = (HANDLE)NULL;
-	}
-
-	LeaveCriticalSection( &This->m_csClock );
-
-	return NOERROR;
-}
-
-static ICOM_VTABLE(IReferenceClock) irefclk =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	/* IUnknown fields */
-	IReferenceClock_fnQueryInterface,
-	IReferenceClock_fnAddRef,
-	IReferenceClock_fnRelease,
-	/* IReferenceClock fields */
-	IReferenceClock_fnGetTime,
-	IReferenceClock_fnAdviseTime,
-	IReferenceClock_fnAdvisePeriodic,
-	IReferenceClock_fnUnadvise,
-};
-
-
-HRESULT CSystemClock_InitIReferenceClock( CSystemClock* psc )
-{
-	HANDLE	hEvents[2];
-
-	TRACE("(%p)\n",psc);
-	ICOM_VTBL(&psc->refclk) = &irefclk;
-
-	InitializeCriticalSection( &psc->m_csClock );
-	psc->m_dwTimeLast = GetTickCount();
-	psc->m_rtLast = (REFERENCE_TIME)0;
-	psc->m_hThreadTimer = (HANDLE)NULL;
-	psc->m_hEventInit = (HANDLE)NULL;
-	psc->m_idThreadTimer = 0;
-	psc->m_dwAdvCookieNext = 1;
-	ZeroMemory( psc->m_timerEntries, sizeof(psc->m_timerEntries) );
-
-	psc->m_hEventInit = CreateEventA( NULL, TRUE, FALSE, NULL );
-	if ( psc->m_hEventInit == (HANDLE)NULL )
-		goto err;
-
-	psc->m_hThreadTimer = CreateThread(
-		NULL, 0,
-		IReferenceClock_TimerEntry,
-		psc, 0, &psc->m_idThreadTimer );
-
-	if ( psc->m_hThreadTimer == (HANDLE)NULL )
-	{
-		CloseHandle( psc->m_hEventInit );
-		psc->m_hEventInit = (HANDLE)NULL;
-		goto err;
-	}
-
-	hEvents[0] = psc->m_hEventInit;
-	hEvents[1] = psc->m_hThreadTimer;
-	if ( WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE )
-			!= WAIT_OBJECT_0 )
-	{
-		CloseHandle( psc->m_hEventInit );
-		psc->m_hEventInit = (HANDLE)NULL;
-		CloseHandle( psc->m_hThreadTimer );
-		psc->m_hThreadTimer = (HANDLE)NULL;
-		goto err;
-	}
-
-	return NOERROR;
-
-err:
-	DeleteCriticalSection( &psc->m_csClock );
-	return E_FAIL;
-}
-
-void CSystemClock_UninitIReferenceClock( CSystemClock* psc )
-{
-	TRACE("(%p)\n",psc);
-
-	if ( psc->m_hThreadTimer != (HANDLE)NULL )
-	{
-		if ( PostThreadMessageA(
-			psc->m_idThreadTimer,
-			QUARTZ_MSG_EXITTHREAD,
-			0, 0 ) )
-		{
-			WaitForSingleObject( psc->m_hThreadTimer, INFINITE );
-		}
-		CloseHandle( psc->m_hThreadTimer );
-		psc->m_hThreadTimer = (HANDLE)NULL;
-	}
-
-	DeleteCriticalSection( &psc->m_csClock );
-}
diff --git a/dlls/quartz/iunk.c b/dlls/quartz/iunk.c
index 4cfe4bc..ba23f65 100644
--- a/dlls/quartz/iunk.c
+++ b/dlls/quartz/iunk.c
@@ -65,7 +65,7 @@
 
 			if ( hr == E_NOINTERFACE )
 			{
-				FIXME("unknown interface: %s\n",debugstr_guid(riid));
+				FIXME("(%p) unknown interface: %s\n",This,debugstr_guid(riid));
 			}
 
 			return hr;
diff --git a/dlls/quartz/ividwin.c b/dlls/quartz/ividwin.c
deleted file mode 100644
index 3d2b3df..0000000
--- a/dlls/quartz/ividwin.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * 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 "winuser.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,
-
-};
-
-
-HRESULT CFilterGraph_InitIVideoWindow( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-	ICOM_VTBL(&pfg->vidwin) = &ivideowindow;
-
-	return NOERROR;
-}
-
-void CFilterGraph_UninitIVideoWindow( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-}
-
diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c
index 005547a..e10e47c 100644
--- a/dlls/quartz/main.c
+++ b/dlls/quartz/main.c
@@ -1,3 +1,9 @@
+/*
+ * Exported APIs.
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
 #include "config.h"
 
 #include "windef.h"
@@ -5,11 +11,13 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "winuser.h"
+#include "winnls.h"
 #include "ole2.h"
 #include "wine/obj_oleaut.h"
 #include "strmif.h"
 #include "control.h"
 #include "uuids.h"
+#include "errors.h"
 
 #include "debugtools.h"
 DEFAULT_DEBUG_CHANNEL(quartz);
@@ -106,6 +114,26 @@
 	HeapFree( hDLLHeap, 0, pMem );
 }
 
+void* QUARTZ_ReallocMem( void* pMem, DWORD dwSize )
+{
+	if ( pMem == NULL )
+		return QUARTZ_AllocMem( dwSize );
+
+	return HeapReAlloc( hDLLHeap, 0, pMem, dwSize );
+}
+
+static
+LPWSTR QUARTZ_strncpyAtoW( LPWSTR lpwstr, LPCSTR lpstr, INT wbuflen )
+{
+	INT	len;
+
+	len = MultiByteToWideChar( CP_ACP, 0, lpstr, -1, lpwstr, wbuflen );
+	if ( len == 0 )
+		*lpwstr = 0;
+	return lpwstr;
+}
+
+
 /************************************************************************/
 
 static HRESULT WINAPI
@@ -337,5 +365,204 @@
 	return E_FAIL;
 }
 
+/**************************************************************************/
+/**************************************************************************/
 
+/* FIXME - all string should be defined in the resource of quartz. */
 
+static LPCSTR hresult_to_string( HRESULT hr )
+{
+	switch ( hr )
+	{
+	#define	ENTRY(x)	case x: return (const char*)#x
+	/* some known codes */
+	ENTRY(S_OK);
+	ENTRY(S_FALSE);
+	ENTRY(E_FAIL);
+	ENTRY(E_POINTER);
+	ENTRY(E_NOTIMPL);
+	ENTRY(E_NOINTERFACE);
+	ENTRY(E_OUTOFMEMORY);
+	ENTRY(CLASS_E_CLASSNOTAVAILABLE);
+	ENTRY(CLASS_E_NOAGGREGATION);
+
+	/* vfwmsgs.h */
+	ENTRY(VFW_S_NO_MORE_ITEMS);
+	ENTRY(VFW_E_BAD_KEY);
+	ENTRY(VFW_E_INVALIDMEDIATYPE);
+	ENTRY(VFW_E_INVALIDSUBTYPE);
+	ENTRY(VFW_E_NEED_OWNER);
+	ENTRY(VFW_E_ENUM_OUT_OF_SYNC);
+	ENTRY(VFW_E_ALREADY_CONNECTED);
+	ENTRY(VFW_E_FILTER_ACTIVE);
+	ENTRY(VFW_E_NO_TYPES);
+	ENTRY(VFW_E_NO_ACCEPTABLE_TYPES);
+	ENTRY(VFW_E_INVALID_DIRECTION);
+	ENTRY(VFW_E_NOT_CONNECTED);
+	ENTRY(VFW_E_NO_ALLOCATOR);
+	ENTRY(VFW_E_RUNTIME_ERROR);
+	ENTRY(VFW_E_BUFFER_NOTSET);
+	ENTRY(VFW_E_BUFFER_OVERFLOW);
+	ENTRY(VFW_E_BADALIGN);
+	ENTRY(VFW_E_ALREADY_COMMITTED);
+	ENTRY(VFW_E_BUFFERS_OUTSTANDING);
+	ENTRY(VFW_E_NOT_COMMITTED);
+	ENTRY(VFW_E_SIZENOTSET);
+	ENTRY(VFW_E_NO_CLOCK);
+	ENTRY(VFW_E_NO_SINK);
+	ENTRY(VFW_E_NO_INTERFACE);
+	ENTRY(VFW_E_NOT_FOUND);
+	ENTRY(VFW_E_CANNOT_CONNECT);
+	ENTRY(VFW_E_CANNOT_RENDER);
+	ENTRY(VFW_E_CHANGING_FORMAT);
+	ENTRY(VFW_E_NO_COLOR_KEY_SET);
+	ENTRY(VFW_E_NOT_OVERLAY_CONNECTION);
+	ENTRY(VFW_E_NOT_SAMPLE_CONNECTION);
+	ENTRY(VFW_E_PALETTE_SET);
+	ENTRY(VFW_E_COLOR_KEY_SET);
+	ENTRY(VFW_E_NO_COLOR_KEY_FOUND);
+	ENTRY(VFW_E_NO_PALETTE_AVAILABLE);
+	ENTRY(VFW_E_NO_DISPLAY_PALETTE);
+	ENTRY(VFW_E_TOO_MANY_COLORS);
+	ENTRY(VFW_E_STATE_CHANGED);
+	ENTRY(VFW_E_NOT_STOPPED);
+	ENTRY(VFW_E_NOT_PAUSED);
+	ENTRY(VFW_E_NOT_RUNNING);
+	ENTRY(VFW_E_WRONG_STATE);
+	ENTRY(VFW_E_START_TIME_AFTER_END);
+	ENTRY(VFW_E_INVALID_RECT);
+	ENTRY(VFW_E_TYPE_NOT_ACCEPTED);
+	ENTRY(VFW_E_SAMPLE_REJECTED);
+	ENTRY(VFW_E_SAMPLE_REJECTED_EOS);
+	ENTRY(VFW_S_DUPLICATE_NAME);
+	ENTRY(VFW_E_DUPLICATE_NAME);
+	ENTRY(VFW_E_TIMEOUT);
+	ENTRY(VFW_E_INVALID_FILE_FORMAT);
+	ENTRY(VFW_E_ENUM_OUT_OF_RANGE);
+	ENTRY(VFW_E_CIRCULAR_GRAPH);
+	ENTRY(VFW_E_NOT_ALLOWED_TO_SAVE);
+	ENTRY(VFW_E_TIME_ALREADY_PASSED);
+	ENTRY(VFW_E_ALREADY_CANCELLED);
+	ENTRY(VFW_E_CORRUPT_GRAPH_FILE);
+	ENTRY(VFW_E_ADVISE_ALREADY_SET);
+	ENTRY(VFW_S_STATE_INTERMEDIATE);
+	ENTRY(VFW_E_NO_MODEX_AVAILABLE);
+	ENTRY(VFW_E_NO_ADVISE_SET);
+	ENTRY(VFW_E_NO_FULLSCREEN);
+	ENTRY(VFW_E_IN_FULLSCREEN_MODE);
+	ENTRY(VFW_E_UNKNOWN_FILE_TYPE);
+	ENTRY(VFW_E_CANNOT_LOAD_SOURCE_FILTER);
+	ENTRY(VFW_S_PARTIAL_RENDER);
+	ENTRY(VFW_E_FILE_TOO_SHORT);
+	ENTRY(VFW_E_INVALID_FILE_VERSION);
+	ENTRY(VFW_S_SOME_DATA_IGNORED);
+	ENTRY(VFW_S_CONNECTIONS_DEFERRED);
+	ENTRY(VFW_E_INVALID_CLSID);
+	ENTRY(VFW_E_INVALID_MEDIA_TYPE);
+	ENTRY(VFW_E_SAMPLE_TIME_NOT_SET);
+	ENTRY(VFW_S_RESOURCE_NOT_NEEDED);
+	ENTRY(VFW_E_MEDIA_TIME_NOT_SET);
+	ENTRY(VFW_E_NO_TIME_FORMAT_SET);
+	ENTRY(VFW_E_MONO_AUDIO_HW);
+	ENTRY(VFW_S_MEDIA_TYPE_IGNORED);
+	ENTRY(VFW_E_NO_DECOMPRESSOR);
+	ENTRY(VFW_E_NO_AUDIO_HARDWARE);
+	ENTRY(VFW_S_VIDEO_NOT_RENDERED);
+	ENTRY(VFW_S_AUDIO_NOT_RENDERED);
+	ENTRY(VFW_E_RPZA);
+	ENTRY(VFW_S_RPZA);
+	ENTRY(VFW_E_PROCESSOR_NOT_SUITABLE);
+	ENTRY(VFW_E_UNSUPPORTED_AUDIO);
+	ENTRY(VFW_E_UNSUPPORTED_VIDEO);
+	ENTRY(VFW_E_MPEG_NOT_CONSTRAINED);
+	ENTRY(VFW_E_NOT_IN_GRAPH);
+	ENTRY(VFW_S_ESTIMATED);
+	ENTRY(VFW_E_NO_TIME_FORMAT);
+	ENTRY(VFW_E_READ_ONLY);
+	ENTRY(VFW_S_RESERVED);
+	ENTRY(VFW_E_BUFFER_UNDERFLOW);
+	ENTRY(VFW_E_UNSUPPORTED_STREAM);
+	ENTRY(VFW_E_NO_TRANSPORT);
+	ENTRY(VFW_S_STREAM_OFF);
+	ENTRY(VFW_S_CANT_CUE);
+	ENTRY(VFW_E_BAD_VIDEOCD);
+	ENTRY(VFW_S_NO_STOP_TIME);
+	ENTRY(VFW_E_OUT_OF_VIDEO_MEMORY);
+	ENTRY(VFW_E_VP_NEGOTIATION_FAILED);
+	ENTRY(VFW_E_DDRAW_CAPS_NOT_SUITABLE);
+	ENTRY(VFW_E_NO_VP_HARDWARE);
+	ENTRY(VFW_E_NO_CAPTURE_HARDWARE);
+	ENTRY(VFW_E_DVD_OPERATION_INHIBITED);
+	ENTRY(VFW_E_DVD_INVALIDDOMAIN);
+	ENTRY(VFW_E_DVD_NO_BUTTON);
+	ENTRY(VFW_E_DVD_GRAPHNOTREADY);
+	ENTRY(VFW_E_DVD_RENDERFAIL);
+	ENTRY(VFW_E_DVD_DECNOTENOUGH);
+	ENTRY(VFW_E_DDRAW_VERSION_NOT_SUITABLE);
+	ENTRY(VFW_E_COPYPROT_FAILED);
+	ENTRY(VFW_S_NOPREVIEWPIN);
+	ENTRY(VFW_E_TIME_EXPIRED);
+	ENTRY(VFW_S_DVD_NON_ONE_SEQUENTIAL);
+	ENTRY(VFW_E_DVD_WRONG_SPEED);
+	ENTRY(VFW_E_DVD_MENU_DOES_NOT_EXIST);
+	ENTRY(VFW_E_DVD_CMD_CANCELLED);
+	ENTRY(VFW_E_DVD_STATE_WRONG_VERSION);
+	ENTRY(VFW_E_DVD_STATE_CORRUPT);
+	ENTRY(VFW_E_DVD_STATE_WRONG_DISC);
+	ENTRY(VFW_E_DVD_INCOMPATIBLE_REGION);
+	ENTRY(VFW_E_DVD_NO_ATTRIBUTES);
+	ENTRY(VFW_E_DVD_NO_GOUP_PGC);
+	ENTRY(VFW_E_DVD_LOW_PARENTAL_LEVEL);
+	ENTRY(VFW_E_DVD_NOT_IN_KARAOKE_MODE);
+	ENTRY(VFW_S_DVD_CHANNEL_CONTENTS_NOT_AVAILABLE);
+	ENTRY(VFW_S_DVD_NOT_ACCURATE);
+	ENTRY(VFW_E_FRAME_STEP_UNSUPPORTED);
+	ENTRY(VFW_E_DVD_STREAM_DISABLED);
+	ENTRY(VFW_E_DVD_TITLE_UNKNOWN);
+	ENTRY(VFW_E_DVD_INVALID_DISC);
+	ENTRY(VFW_E_DVD_NO_RESUME_INFORMATION);
+	ENTRY(VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD);
+	ENTRY(VFW_E_PIN_ALREADY_BLOCKED);
+	ENTRY(VFW_E_CERTIFICATION_FAILURE);
+	#undef	ENTRY
+	}
+
+	return NULL;
+}
+
+/***********************************************************************
+ *	AMGetErrorTextA	(quartz.@)
+ */
+DWORD WINAPI AMGetErrorTextA(HRESULT hr, LPSTR pszbuf, DWORD dwBufLen)
+{
+	LPCSTR	lpszRes;
+	DWORD len;
+
+	lpszRes = hresult_to_string( hr );
+	if ( lpszRes == NULL )
+		return 0;
+	len = (DWORD)(strlen(lpszRes)+1);
+	if ( len > dwBufLen )
+		return 0;
+
+	memcpy( pszbuf, lpszRes, len );
+	return len;
+}
+
+/***********************************************************************
+ *	AMGetErrorTextW	(quartz.@)
+ */
+DWORD WINAPI AMGetErrorTextW(HRESULT hr, LPWSTR pwszbuf, DWORD dwBufLen)
+{
+	CHAR	szBuf[MAX_ERROR_TEXT_LEN+1];
+	DWORD	dwLen;
+
+	dwLen = AMGetErrorTextA(hr,szBuf,MAX_ERROR_TEXT_LEN);
+	if ( dwLen == 0 )
+		return 0;
+	szBuf[dwLen] = 0;
+
+	QUARTZ_strncpyAtoW( pwszbuf, szBuf, dwBufLen );
+
+	return lstrlenW( pwszbuf );
+}
diff --git a/dlls/quartz/memalloc.c b/dlls/quartz/memalloc.c
index 40f98c7..6c2b473 100644
--- a/dlls/quartz/memalloc.c
+++ b/dlls/quartz/memalloc.c
@@ -1,8 +1,6 @@
 /*
  * Implementation of CLSID_MemoryAllocator.
  *
- * FIXME - stub.
- *
  * hidenori@a2.ctktv.ne.jp
  */
 
@@ -24,6 +22,12 @@
 #include "memalloc.h"
 
 
+/***************************************************************************
+ *
+ *	new/delete for CLSID_MemoryAllocator.
+ *
+ */
+
 /* can I use offsetof safely? - FIXME? */
 static QUARTZ_IFEntry IFEntries[] =
 {
@@ -64,3 +68,349 @@
 
 	return S_OK;
 }
+
+
+/***************************************************************************
+ *
+ *	CMemoryAllocator::IMemAllocator
+ *
+ */
+
+
+static HRESULT WINAPI
+IMemAllocator_fnQueryInterface(IMemAllocator* iface,REFIID riid,void** ppobj)
+{
+	CMemoryAllocator_THIS(iface,memalloc);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IMemAllocator_fnAddRef(IMemAllocator* iface)
+{
+	CMemoryAllocator_THIS(iface,memalloc);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IMemAllocator_fnRelease(IMemAllocator* iface)
+{
+	CMemoryAllocator_THIS(iface,memalloc);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IMemAllocator_fnSetProperties(IMemAllocator* iface,ALLOCATOR_PROPERTIES* pPropReq,ALLOCATOR_PROPERTIES* pPropActual)
+{
+	CMemoryAllocator_THIS(iface,memalloc);
+	long	padding;
+	HRESULT	hr;
+
+	TRACE( "(%p)->(%p,%p)\n", This, pPropReq, pPropActual );
+
+	if ( pPropReq == NULL || pPropActual == NULL )
+		return E_POINTER;
+	if ( pPropReq->cBuffers < 0 ||
+	     pPropReq->cbBuffer < 0 ||
+	     pPropReq->cbAlign < 0 ||
+	     pPropReq->cbPrefix < 0 )
+		return E_INVALIDARG;
+
+	if ( ( pPropReq->cbAlign & (pPropReq->cbAlign-1) ) != 0 )
+		return E_INVALIDARG;
+
+	hr = NOERROR;
+
+	EnterCriticalSection( &This->csMem );
+
+	if ( This->pData != NULL || This->ppSamples != NULL )
+	{
+		/* if commited, properties must not be changed. */
+		hr = E_UNEXPECTED;
+		goto end;
+	}
+
+	This->prop.cBuffers = pPropReq->cBuffers;
+	This->prop.cbBuffer = pPropReq->cbBuffer;
+	This->prop.cbAlign = pPropReq->cbAlign;
+	This->prop.cbPrefix = pPropReq->cbPrefix;
+
+	if ( This->prop.cbAlign == 0 )
+		This->prop.cbAlign = 1;
+	padding = This->prop.cbAlign -
+		( (This->prop.cbBuffer+This->prop.cbPrefix) % This->prop.cbAlign );
+
+	This->prop.cbBuffer += padding;
+
+	memcpy( pPropActual, &This->prop, sizeof(ALLOCATOR_PROPERTIES) );
+
+end:
+	LeaveCriticalSection( &This->csMem );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+IMemAllocator_fnGetProperties(IMemAllocator* iface,ALLOCATOR_PROPERTIES* pProp)
+{
+	CMemoryAllocator_THIS(iface,memalloc);
+
+	TRACE( "(%p)->(%p)\n", This, pProp );
+
+	if ( pProp == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->csMem );
+
+	memcpy( pProp, &This->prop, sizeof(ALLOCATOR_PROPERTIES) );
+
+	LeaveCriticalSection( &This->csMem );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+IMemAllocator_fnCommit(IMemAllocator* iface)
+{
+	CMemoryAllocator_THIS(iface,memalloc);
+	HRESULT	hr;
+	LONG	lBufSize;
+	LONG	i;
+	BYTE*	pCur;
+
+	TRACE( "(%p)->()\n", This );
+
+	EnterCriticalSection( &This->csMem );
+
+	hr = NOERROR;
+	if ( This->pData != NULL || This->ppSamples != NULL ||
+	     This->prop.cBuffers <= 0 )
+		goto end;
+
+	lBufSize = This->prop.cBuffers *
+		(This->prop.cbBuffer + This->prop.cbPrefix) +
+		This->prop.cbAlign;
+	if ( lBufSize <= 0 )
+		lBufSize = 1;
+
+	This->pData = (BYTE*)QUARTZ_AllocMem( lBufSize );
+	if ( This->pData == NULL )
+	{
+		hr = E_OUTOFMEMORY;
+		goto end;
+	}
+
+	This->ppSamples = (CMemMediaSample**)QUARTZ_AllocMem(
+		sizeof(CMemMediaSample*) * This->prop.cBuffers );
+	if ( This->ppSamples == NULL )
+	{
+		hr = E_OUTOFMEMORY;
+		goto end;
+	}
+
+	for ( i = 0; i < This->prop.cBuffers; i++ )
+		This->ppSamples[i] = NULL;
+
+	pCur = This->pData + This->prop.cbAlign - ((This->pData-(BYTE*)NULL) & (This->prop.cbAlign-1));
+
+	for ( i = 0; i < This->prop.cBuffers; i++ )
+	{
+		hr = QUARTZ_CreateMemMediaSample(
+			pCur, (This->prop.cbBuffer + This->prop.cbPrefix),
+			iface, &This->ppSamples[i] );
+		if ( FAILED(hr) )
+			goto end;
+		pCur += (This->prop.cbBuffer + This->prop.cbPrefix);
+	}
+
+	hr = NOERROR;
+end:
+	if ( FAILED(hr) )
+		IMemAllocator_Decommit(iface);
+
+	LeaveCriticalSection( &This->csMem );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+IMemAllocator_fnDecommit(IMemAllocator* iface)
+{
+	CMemoryAllocator_THIS(iface,memalloc);
+	HRESULT	hr;
+	LONG	i;
+	BOOL	bBlock;
+
+	TRACE( "(%p)->()\n", This );
+
+	EnterCriticalSection( &This->csMem );
+
+	hr = NOERROR;
+
+	if ( This->pData == NULL && This->ppSamples == NULL )
+		goto end;
+
+	while ( 1 )
+	{
+		bBlock = FALSE;
+		i = 0;
+
+		ResetEvent( This->hEventSample );
+
+		while ( 1 )
+		{
+			if ( i >= This->prop.cBuffers )
+				break;
+
+			if ( This->ppSamples[i] != NULL )
+			{
+				if ( This->ppSamples[i]->ref == 0 )
+				{
+					QUARTZ_DestroyMemMediaSample( This->ppSamples[i] );
+					This->ppSamples[i] = NULL;
+				}
+				else
+				{
+					bBlock = TRUE;
+				}
+			}
+			i++;
+		}
+
+		if ( !bBlock )
+		{
+			hr = NOERROR;
+			break;
+		}
+
+		WaitForSingleObject( This->hEventSample, INFINITE );
+	}
+
+end:
+	LeaveCriticalSection( &This->csMem );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+IMemAllocator_fnGetBuffer(IMemAllocator* iface,IMediaSample** ppSample,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd,DWORD dwFlags)
+{
+	CMemoryAllocator_THIS(iface,memalloc);
+	LONG	i;
+	HRESULT	hr;
+
+	TRACE( "(%p)->(%p,%p,%p,%lu)\n", This, ppSample, prtStart, prtEnd, dwFlags );
+
+	if ( ppSample == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->csMem );
+
+	hr = NOERROR;
+
+	if ( This->pData == NULL || This->ppSamples == NULL ||
+	     This->prop.cBuffers <= 0 )
+	{
+		hr = E_FAIL; /* FIXME? */
+		goto end;
+	}
+
+	while ( 1 )
+	{
+		ResetEvent( This->hEventSample );
+
+		for ( i = 0; i < This->prop.cBuffers; i++ )
+		{
+			if ( This->ppSamples[i]->ref == 0 )
+			{
+				*ppSample = (IMediaSample*)(This->ppSamples[i]);
+				IMediaSample_AddRef( *ppSample );
+				hr = NOERROR;
+				goto end;
+			}
+		}
+
+		if ( dwFlags & AM_GBF_NOWAIT )
+		{
+			hr = E_FAIL; /* FIXME? */
+			goto end;
+		}
+
+		WaitForSingleObject( This->hEventSample, INFINITE );
+	}
+
+end:
+	LeaveCriticalSection( &This->csMem );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+IMemAllocator_fnReleaseBuffer(IMemAllocator* iface,IMediaSample* pSample)
+{
+	CMemoryAllocator_THIS(iface,memalloc);
+
+	TRACE( "(%p)->(%p)\n", This, pSample );
+	SetEvent( This->hEventSample );
+
+	return NOERROR;
+}
+
+
+
+static ICOM_VTABLE(IMemAllocator) imemalloc =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IMemAllocator_fnQueryInterface,
+	IMemAllocator_fnAddRef,
+	IMemAllocator_fnRelease,
+	/* IMemAllocator fields */
+	IMemAllocator_fnSetProperties,
+	IMemAllocator_fnGetProperties,
+	IMemAllocator_fnCommit,
+	IMemAllocator_fnDecommit,
+	IMemAllocator_fnGetBuffer,
+	IMemAllocator_fnReleaseBuffer,
+};
+
+
+HRESULT CMemoryAllocator_InitIMemAllocator( CMemoryAllocator* pma )
+{
+	TRACE("(%p)\n",pma);
+
+	ICOM_VTBL(&pma->memalloc) = &imemalloc;
+
+	ZeroMemory( &pma->prop, sizeof(pma->prop) );
+	pma->hEventSample = (HANDLE)NULL;
+	pma->pData = NULL;
+	pma->ppSamples = NULL;
+
+	pma->hEventSample = CreateEventA( NULL, TRUE, FALSE, NULL );
+	if ( pma->hEventSample == (HANDLE)NULL )
+		return E_OUTOFMEMORY;
+
+	InitializeCriticalSection( &pma->csMem );
+
+	return NOERROR;
+}
+
+void CMemoryAllocator_UninitIMemAllocator( CMemoryAllocator* pma )
+{
+	TRACE("(%p)\n",pma);
+
+	IMemAllocator_Decommit( (IMemAllocator*)(&pma->memalloc) );
+
+	DeleteCriticalSection( &pma->csMem );
+
+	if ( pma->hEventSample != (HANDLE)NULL )
+		CloseHandle( pma->hEventSample );
+}
diff --git a/dlls/quartz/monprop.c b/dlls/quartz/monprop.c
deleted file mode 100644
index 81a029c..0000000
--- a/dlls/quartz/monprop.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Implements IPropertyBag. (internal)
- *
- * hidenori@a2.ctktv.ne.jp
- */
-
-#include "config.h"
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winreg.h"
-#include "winerror.h"
-#include "wine/obj_base.h"
-#include "objidl.h"
-#include "oleidl.h"
-#include "ocidl.h"
-#include "oleauto.h"
-#include "strmif.h"
-#include "wine/unicode.h"
-
-#include "debugtools.h"
-DEFAULT_DEBUG_CHANNEL(quartz);
-
-#include "quartz_private.h"
-#include "monprop.h"
-
-
-static HRESULT WINAPI
-IPropertyBag_fnQueryInterface(IPropertyBag* iface,REFIID riid,void** ppobj)
-{
-	CRegPropertyBag_THIS(iface,propbag);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
-}
-
-static ULONG WINAPI
-IPropertyBag_fnAddRef(IPropertyBag* iface)
-{
-	CRegPropertyBag_THIS(iface,propbag);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_AddRef(This->unk.punkControl);
-}
-
-static ULONG WINAPI
-IPropertyBag_fnRelease(IPropertyBag* iface)
-{
-	CRegPropertyBag_THIS(iface,propbag);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_Release(This->unk.punkControl);
-}
-
-static HRESULT WINAPI
-IPropertyBag_fnRead(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar,IErrorLog* pLog)
-{
-	CRegPropertyBag_THIS(iface,propbag);
-	LONG	lr;
-	DWORD	dwSize;
-	DWORD	dwValueType;
-
-	TRACE("(%p)->(%s,%p,%p)\n",This,
-		debugstr_w(lpszPropName),pVar,pLog);
-
-	if ( lpszPropName == NULL || pVar == NULL )
-		return E_POINTER;
-
-	dwSize = 0;
-	lr = RegQueryValueExW(
-		This->m_hKey, lpszPropName, NULL,
-		&dwValueType, NULL, &dwSize );
-	if ( lr != ERROR_SUCCESS )
-		return E_INVALIDARG;
-
-	switch ( dwValueType )
-	{
-	case REG_SZ:
-		if ( pVar->n1.n2.vt == VT_EMPTY )
-			pVar->n1.n2.vt = VT_BSTR;
-		if ( pVar->n1.n2.vt != VT_BSTR )
-			return E_FAIL;
-
-		pVar->n1.n2.n3.bstrVal = SysAllocStringByteLen(
-			NULL, dwSize );
-		if ( pVar->n1.n2.n3.bstrVal == NULL )
-			return E_OUTOFMEMORY;
-		lr = RegQueryValueExW(
-			This->m_hKey, lpszPropName, NULL,
-			&dwValueType,
-			(BYTE*)pVar->n1.n2.n3.bstrVal, &dwSize );
-		if ( lr != ERROR_SUCCESS )
-		{
-			SysFreeString(pVar->n1.n2.n3.bstrVal);
-			return E_FAIL;
-		}
-		break;
-	default:
-		FIXME("(%p)->(%s,%p,%p) - unsupported value type.\n",This,
-			debugstr_w(lpszPropName),pVar,pLog);
-		return E_FAIL;
-	}
-
-	return NOERROR;
-}
-
-static HRESULT WINAPI
-IPropertyBag_fnWrite(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar)
-{
-	CRegPropertyBag_THIS(iface,propbag);
-
-	FIXME("(%p)->(%s,%p) stub!\n",This,
-		debugstr_w(lpszPropName),pVar);
-
-	if ( lpszPropName == NULL || pVar == NULL )
-		return E_POINTER;
-
-	return E_NOTIMPL;
-}
-
-
-
-
-static ICOM_VTABLE(IPropertyBag) ipropbag =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	/* IUnknown fields */
-	IPropertyBag_fnQueryInterface,
-	IPropertyBag_fnAddRef,
-	IPropertyBag_fnRelease,
-	/* IPropertyBag fields */
-	IPropertyBag_fnRead,
-	IPropertyBag_fnWrite,
-};
-
-static HRESULT CRegPropertyBag_InitIPropertyBag(
-	CRegPropertyBag* prpb, HKEY hkRoot, LPCWSTR lpKeyPath )
-{
-	ICOM_VTBL(&prpb->propbag) = &ipropbag;
-
-	if ( RegOpenKeyExW(
-		hkRoot, lpKeyPath, 0,
-		KEY_ALL_ACCESS, &prpb->m_hKey ) != ERROR_SUCCESS )
-		return E_FAIL;
-
-	return NOERROR;
-}
-
-static void CRegPropertyBag_UninitIPropertyBag(
-	CRegPropertyBag* prpb )
-{
-	RegCloseKey( prpb->m_hKey );
-}
-
-
-static void QUARTZ_DestroyRegPropertyBag(IUnknown* punk)
-{
-	CRegPropertyBag_THIS(punk,unk);
-
-	CRegPropertyBag_UninitIPropertyBag(This);
-}
-
-
-/* can I use offsetof safely? - FIXME? */
-static QUARTZ_IFEntry IFEntries[] =
-{
-  { &IID_IPropertyBag, offsetof(CRegPropertyBag,propbag)-offsetof(CRegPropertyBag,unk) },
-};
-
-HRESULT QUARTZ_CreateRegPropertyBag(
-	HKEY hkRoot, LPCWSTR lpKeyPath,
-	IPropertyBag** ppPropBag )
-{
-	CRegPropertyBag*	prpb;
-	HRESULT	hr;
-
-	TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppPropBag );
-
-	prpb = (CRegPropertyBag*)QUARTZ_AllocObj( sizeof(CRegPropertyBag) );
-	if ( prpb == NULL )
-		return E_OUTOFMEMORY;
-
-	QUARTZ_IUnkInit( &prpb->unk, NULL );
-	hr = CRegPropertyBag_InitIPropertyBag( prpb, hkRoot, lpKeyPath );
-	if ( FAILED(hr) )
-	{
-		QUARTZ_FreeObj( prpb );
-		return hr;
-	}
-
-	prpb->unk.pEntries = IFEntries;
-	prpb->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
-	prpb->unk.pOnFinalRelease = &QUARTZ_DestroyRegPropertyBag;
-
-	*ppPropBag = (IPropertyBag*)(&prpb->propbag);
-
-	return S_OK;
-}
-
-
diff --git a/dlls/quartz/monprop.h b/dlls/quartz/monprop.h
deleted file mode 100644
index 25c4946..0000000
--- a/dlls/quartz/monprop.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef	WINE_DSHOW_MONPROP_H
-#define	WINE_DSHOW_MONPROP_H
-
-/*
-		implements IPropertyBag for accessing registry.
-
-	- At least, the following interfaces should be implemented:
-
-	IUnknown
-		+ IPropertyBag
- */
-
-#include "iunk.h"
-
-typedef struct DMON_IPropertyBagImpl
-{
-	ICOM_VFIELD(IPropertyBag);
-} DMON_IPropertyBagImpl;
-
-typedef struct CRegPropertyBag
-{
-	QUARTZ_IUnkImpl	unk;
-	DMON_IPropertyBagImpl	propbag;
-	/* IPropertyBag fields */
-	HKEY	m_hKey;
-} CRegPropertyBag;
-
-#define	CRegPropertyBag_THIS(iface,member)	CRegPropertyBag*	This = (CRegPropertyBag*)(((char*)iface)-offsetof(CRegPropertyBag,member))
-
-HRESULT QUARTZ_CreateRegPropertyBag(
-	HKEY hkRoot, LPCWSTR lpKeyPath,
-	IPropertyBag** ppPropBag );
-
-#endif	/* WINE_DSHOW_MONPROP_H */
diff --git a/dlls/quartz/mtype.c b/dlls/quartz/mtype.c
new file mode 100644
index 0000000..e356218
--- /dev/null
+++ b/dlls/quartz/mtype.c
@@ -0,0 +1,374 @@
+/*
+ * Implements IEnumMediaTypes and helper functions. (internal)
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "strmif.h"
+#include "vfwmsgs.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "mtype.h"
+#include "iunk.h"
+
+
+/****************************************************************************/
+
+
+
+HRESULT QUARTZ_MediaType_Copy(
+	AM_MEDIA_TYPE* pmtDst,
+	const AM_MEDIA_TYPE* pmtSrc )
+{
+	memcpy( &pmtDst->majortype, &pmtSrc->majortype, sizeof(GUID) );
+	memcpy( &pmtDst->subtype, &pmtSrc->subtype, sizeof(GUID) );
+	pmtDst->bFixedSizeSamples = pmtSrc->bFixedSizeSamples;
+	pmtDst->bTemporalCompression = pmtSrc->bTemporalCompression;
+	pmtDst->lSampleSize = pmtSrc->lSampleSize;
+	memcpy( &pmtDst->formattype, &pmtSrc->formattype, sizeof(GUID) );
+	pmtDst->pUnk = NULL;
+	pmtDst->cbFormat = pmtSrc->cbFormat;
+	pmtDst->pbFormat = NULL;
+
+	if ( pmtSrc->pbFormat != NULL && pmtSrc->cbFormat != 0 )
+	{
+		pmtDst->pbFormat = (BYTE*)CoTaskMemAlloc( pmtSrc->cbFormat );
+		if ( pmtDst->pbFormat == NULL )
+		{
+			CoTaskMemFree( pmtDst );
+			return E_OUTOFMEMORY;
+		}
+		memcpy( pmtDst->pbFormat, pmtSrc->pbFormat, pmtSrc->cbFormat );
+	}
+
+	if ( pmtSrc->pUnk != NULL )
+	{
+		pmtDst->pUnk = pmtSrc->pUnk;
+		IUnknown_AddRef( pmtSrc->pUnk );
+	}
+
+	return S_OK;
+}
+
+void QUARTZ_MediaType_Free(
+	AM_MEDIA_TYPE* pmt )
+{
+	if ( pmt->pUnk != NULL )
+	{
+		IUnknown_Release( pmt->pUnk );
+		pmt->pUnk = NULL;
+	}
+	if ( pmt->pbFormat != NULL )
+	{
+		CoTaskMemFree( pmt->pbFormat );
+		pmt->cbFormat = 0;
+		pmt->pbFormat = NULL;
+	}
+}
+
+AM_MEDIA_TYPE* QUARTZ_MediaType_Duplicate(
+	const AM_MEDIA_TYPE* pmtSrc )
+{
+	AM_MEDIA_TYPE*	pmtDup;
+
+	pmtDup = (AM_MEDIA_TYPE*)CoTaskMemAlloc( sizeof(AM_MEDIA_TYPE) );
+	if ( pmtDup == NULL )
+		return NULL;
+	if ( QUARTZ_MediaType_Copy( pmtDup, pmtSrc ) != S_OK )
+	{
+		CoTaskMemFree( pmtDup );
+		return NULL;
+	}
+
+	return pmtDup;
+}
+
+void QUARTZ_MediaType_Destroy(
+	AM_MEDIA_TYPE* pmt )
+{
+	QUARTZ_MediaType_Free( pmt );
+	CoTaskMemFree( pmt );
+}
+
+
+/****************************************************************************/
+
+typedef struct IEnumMediaTypesImpl
+{
+	ICOM_VFIELD(IEnumMediaTypes);
+} IEnumMediaTypesImpl;
+
+typedef struct
+{
+	QUARTZ_IUnkImpl	unk;
+	IEnumMediaTypesImpl	enummtype;
+	struct QUARTZ_IFEntry	IFEntries[1];
+	CRITICAL_SECTION	cs;
+	AM_MEDIA_TYPE*	pTypes;
+	ULONG	cTypes;
+	ULONG	cCur;
+} CEnumMediaTypes;
+
+#define	CEnumMediaTypes_THIS(iface,member)		CEnumMediaTypes*	This = ((CEnumMediaTypes*)(((char*)iface)-offsetof(CEnumMediaTypes,member)))
+
+
+
+static HRESULT WINAPI
+IEnumMediaTypes_fnQueryInterface(IEnumMediaTypes* iface,REFIID riid,void** ppobj)
+{
+	CEnumMediaTypes_THIS(iface,enummtype);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IEnumMediaTypes_fnAddRef(IEnumMediaTypes* iface)
+{
+	CEnumMediaTypes_THIS(iface,enummtype);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IEnumMediaTypes_fnRelease(IEnumMediaTypes* iface)
+{
+	CEnumMediaTypes_THIS(iface,enummtype);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IEnumMediaTypes_fnNext(IEnumMediaTypes* iface,ULONG cReq,AM_MEDIA_TYPE** ppmtype,ULONG* pcFetched)
+{
+	CEnumMediaTypes_THIS(iface,enummtype);
+	HRESULT	hr;
+	ULONG	cFetched;
+
+	TRACE("(%p)->(%lu,%p,%p)\n",This,cReq,ppmtype,pcFetched);
+
+	if ( pcFetched == NULL && cReq > 1 )
+		return E_INVALIDARG;
+	if ( ppmtype == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->cs );
+
+	hr = NOERROR;
+	cFetched = 0;
+	while ( cReq > 0 )
+	{
+		if ( This->cCur >= This->cTypes )
+		{
+			hr = S_FALSE;
+			break;
+		}
+		ppmtype[ cFetched ] =
+			QUARTZ_MediaType_Duplicate( &This->pTypes[ This->cCur ] );
+		if ( ppmtype[ cFetched ] == NULL )
+		{
+			hr = E_OUTOFMEMORY;
+			while ( cFetched > 0 )
+			{
+				cFetched --;
+				QUARTZ_MediaType_Destroy( ppmtype[ cFetched ] );
+			}
+			break;
+		}
+
+		cFetched ++;
+
+		This->cCur ++;
+		cReq --;
+	}
+
+	LeaveCriticalSection( &This->cs );
+
+	if ( pcFetched != NULL )
+		*pcFetched = cFetched;
+
+	return hr;
+}
+
+static HRESULT WINAPI
+IEnumMediaTypes_fnSkip(IEnumMediaTypes* iface,ULONG cSkip)
+{
+	CEnumMediaTypes_THIS(iface,enummtype);
+	HRESULT	hr;
+
+	TRACE("(%p)->()\n",This);
+
+	EnterCriticalSection( &This->cs );
+
+	hr = NOERROR;
+	while ( cSkip > 0 )
+	{
+		if ( This->cCur >= This->cTypes )
+		{
+			hr = S_FALSE;
+			break;
+		}
+		This->cCur ++;
+		cSkip --;
+	}
+
+	LeaveCriticalSection( &This->cs );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+IEnumMediaTypes_fnReset(IEnumMediaTypes* iface)
+{
+	CEnumMediaTypes_THIS(iface,enummtype);
+
+	TRACE("(%p)->()\n",This);
+
+	EnterCriticalSection( &This->cs );
+
+	This->cCur = 0;
+
+	LeaveCriticalSection( &This->cs );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+IEnumMediaTypes_fnClone(IEnumMediaTypes* iface,IEnumMediaTypes** ppobj)
+{
+	CEnumMediaTypes_THIS(iface,enummtype);
+	HRESULT	hr;
+
+	TRACE("(%p)->()\n",This);
+
+	if ( ppobj == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->cs );
+
+	hr = QUARTZ_CreateEnumMediaTypes(
+		ppobj,
+		This->pTypes, This->cTypes );
+	if ( SUCCEEDED(hr) )
+		IEnumMediaTypes_Skip( *ppobj, This->cCur );
+
+	LeaveCriticalSection( &This->cs );
+
+	return hr;
+}
+
+
+static ICOM_VTABLE(IEnumMediaTypes) ienummtype =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IEnumMediaTypes_fnQueryInterface,
+	IEnumMediaTypes_fnAddRef,
+	IEnumMediaTypes_fnRelease,
+	/* IEnumMediaTypes fields */
+	IEnumMediaTypes_fnNext,
+	IEnumMediaTypes_fnSkip,
+	IEnumMediaTypes_fnReset,
+	IEnumMediaTypes_fnClone,
+};
+
+
+/* can I use offsetof safely? - FIXME? */
+static QUARTZ_IFEntry IFEntries[] =
+{
+  { &IID_IEnumMediaTypes, offsetof(CEnumMediaTypes,enummtype)-offsetof(CEnumMediaTypes,unk) },
+};
+
+
+void QUARTZ_DestroyEnumMediaTypes(IUnknown* punk)
+{
+	CEnumMediaTypes_THIS(punk,unk);
+	ULONG	i;
+
+	if ( This->pTypes != NULL )
+	{
+		for ( i = 0; i < This->cTypes; i++ )
+			QUARTZ_MediaType_Free( &This->pTypes[i] );
+		QUARTZ_FreeMem( This->pTypes );
+	}
+
+	DeleteCriticalSection( &This->cs );
+}
+
+HRESULT QUARTZ_CreateEnumMediaTypes(
+	IEnumMediaTypes** ppobj,
+	const AM_MEDIA_TYPE* pTypes, ULONG cTypes )
+{
+	CEnumMediaTypes*	penum;
+	AM_MEDIA_TYPE*	pTypesDup = NULL;
+	ULONG	i;
+	HRESULT	hr;
+
+	TRACE("(%p,%p,%lu)\n",ppobj,pTypes,cTypes);
+
+	if ( cTypes > 0 )
+	{
+		pTypesDup = (AM_MEDIA_TYPE*)QUARTZ_AllocMem(
+			sizeof( AM_MEDIA_TYPE ) * cTypes );
+		if ( pTypesDup == NULL )
+			return E_OUTOFMEMORY;
+
+		i = 0;
+		while ( i < cTypes )
+		{
+			hr = QUARTZ_MediaType_Copy( &pTypesDup[i], &pTypes[i] );
+			if ( FAILED(hr) )
+			{
+				while ( i > 0 )
+				{
+					i --;
+					QUARTZ_MediaType_Free( &pTypesDup[i] );
+				}
+				QUARTZ_FreeMem( pTypesDup );
+				return hr;
+			}
+
+			i ++;
+		}
+	}
+
+	penum = (CEnumMediaTypes*)QUARTZ_AllocObj( sizeof(CEnumMediaTypes) );
+	if ( penum == NULL )
+	{
+		return E_OUTOFMEMORY;
+	}
+	penum->pTypes = pTypesDup;
+	penum->cTypes = cTypes;
+	penum->cCur = 0;
+
+	QUARTZ_IUnkInit( &penum->unk, NULL );
+	ICOM_VTBL(&penum->enummtype) = &ienummtype;
+
+	penum->unk.pEntries = IFEntries;
+	penum->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
+	penum->unk.pOnFinalRelease = QUARTZ_DestroyEnumMediaTypes;
+
+	InitializeCriticalSection( &penum->cs );
+
+	*ppobj = (IEnumMediaTypes*)(&penum->enummtype);
+
+	return S_OK;
+}
+
+
diff --git a/dlls/quartz/mtype.h b/dlls/quartz/mtype.h
new file mode 100644
index 0000000..502b593
--- /dev/null
+++ b/dlls/quartz/mtype.h
@@ -0,0 +1,26 @@
+/*
+ * Implements IEnumMediaTypes and helper functions. (internal)
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#ifndef WINE_DSHOW_MTYPE_H
+#define WINE_DSHOW_MTYPE_H
+
+HRESULT QUARTZ_MediaType_Copy(
+	AM_MEDIA_TYPE* pmtDst,
+	const AM_MEDIA_TYPE* pmtSrc );
+void QUARTZ_MediaType_Free(
+	AM_MEDIA_TYPE* pmt );
+AM_MEDIA_TYPE* QUARTZ_MediaType_Duplicate(
+	const AM_MEDIA_TYPE* pmtSrc );
+void QUARTZ_MediaType_Destroy(
+	AM_MEDIA_TYPE* pmt );
+
+
+HRESULT QUARTZ_CreateEnumMediaTypes(
+	IEnumMediaTypes** ppobj,
+	const AM_MEDIA_TYPE* pTypes, ULONG cTypes );
+
+
+#endif /* WINE_DSHOW_MTYPE_H */
diff --git a/dlls/quartz/ptimpl.c b/dlls/quartz/ptimpl.c
deleted file mode 100644
index 39c382f..0000000
--- a/dlls/quartz/ptimpl.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * A pass-through class.
- *
- * hidenori@a2.ctktv.ne.jp
- */
-
-#include "config.h"
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winerror.h"
-#include "wine/obj_base.h"
-#include "strmif.h"
-#include "control.h"
-#include "uuids.h"
-
-#include "debugtools.h"
-DEFAULT_DEBUG_CHANNEL(quartz);
-
-#include "quartz_private.h"
-#include "ptimpl.h"
-
-static
-HRESULT CPassThruImpl_GetConnected( CPassThruImpl* pImpl, IPin** ppPin )
-{
-	return IPin_ConnectedTo( pImpl->pPin, ppPin );
-}
-
-HRESULT CPassThruImpl_QueryPosPass(
-	CPassThruImpl* pImpl, IMediaPosition** ppPosition )
-{
-	IPin*	pPin;
-	HRESULT	hr;
-
-	hr = CPassThruImpl_GetConnected( pImpl, &pPin );
-	if ( FAILED(hr) )
-		return hr;
-	hr = IPin_QueryInterface(pPin,&IID_IMediaPosition,(void**)ppPosition);
-	IPin_Release(pPin);
-
-	return hr;
-}
-
-HRESULT CPassThruImpl_QuerySeekPass(
-	CPassThruImpl* pImpl, IMediaSeeking** ppSeeking )
-{
-	IPin*	pPin;
-	HRESULT	hr;
-
-	hr = CPassThruImpl_GetConnected( pImpl, &pPin );
-	if ( FAILED(hr) )
-		return hr;
-	hr = IPin_QueryInterface(pPin,&IID_IMediaSeeking,(void**)ppSeeking);
-	IPin_Release(pPin);
-
-	return hr;
-}
diff --git a/dlls/quartz/ptimpl.h b/dlls/quartz/ptimpl.h
deleted file mode 100644
index d615e3a..0000000
--- a/dlls/quartz/ptimpl.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef WINE_DSHOW_PTIMPL_H
-#define WINE_DSHOW_PTIMPL_H
-
-/*
- * A pass-through class.
- *
- * hidenori@a2.ctktv.ne.jp
- */
-
-typedef struct CPassThruImpl
-{
-	struct { ICOM_VFIELD(IMediaPosition); } mpos;
-	struct { ICOM_VFIELD(IMediaSeeking); } mseek;
-
-	IUnknown* punk;
-	IPin* pPin;
-} CPassThruImpl;
-
-#define	CPassThruImpl_THIS(iface,member)		CPassThruImpl*	This = ((CPassThruImpl*)(((char*)iface)-offsetof(CPassThruImpl,member)))
-
-HRESULT CPassThruImpl_InitIMediaPosition( CPassThruImpl* pImpl );
-void CPassThruImpl_UninitIMediaPosition( CPassThruImpl* pImpl );
-HRESULT CPassThruImpl_InitIMediaSeeking( CPassThruImpl* pImpl );
-void CPassThruImpl_UninitIMediaSeeking( CPassThruImpl* pImpl );
-
-HRESULT CPassThruImpl_QueryPosPass(
-	CPassThruImpl* pImpl, IMediaPosition** ppPosition );
-HRESULT CPassThruImpl_QuerySeekPass(
-	CPassThruImpl* pImpl, IMediaSeeking** ppSeeking );
-
-
-#endif  /* WINE_DSHOW_PTIMPL_H */
diff --git a/dlls/quartz/ptmpos.c b/dlls/quartz/ptmpos.c
deleted file mode 100644
index f843f5c..0000000
--- a/dlls/quartz/ptmpos.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * A pass-through class for IMediaPosition.
- *
- * hidenori@a2.ctktv.ne.jp
- */
-
-#include "config.h"
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winerror.h"
-#include "wine/obj_base.h"
-#include "strmif.h"
-#include "control.h"
-#include "uuids.h"
-
-#include "debugtools.h"
-DEFAULT_DEBUG_CHANNEL(quartz);
-
-#include "quartz_private.h"
-#include "ptimpl.h"
-
-
-#define QUERYPOSPASS \
-	IMediaPosition* pPos; \
-	HRESULT hr; \
-	hr = CPassThruImpl_QueryPosPass( This, &pPos ); \
-	if ( FAILED(hr) ) return hr;
-
-static HRESULT WINAPI
-IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj)
-{
-	CPassThruImpl_THIS(iface,mpos);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_QueryInterface(This->punk,riid,ppobj);
-}
-
-static ULONG WINAPI
-IMediaPosition_fnAddRef(IMediaPosition* iface)
-{
-	CPassThruImpl_THIS(iface,mpos);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_AddRef(This->punk);
-}
-
-static ULONG WINAPI
-IMediaPosition_fnRelease(IMediaPosition* iface)
-{
-	CPassThruImpl_THIS(iface,mpos);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_Release(This->punk);
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo)
-{
-	CPassThruImpl_THIS(iface,mpos);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
-{
-	CPassThruImpl_THIS(iface,mpos);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
-{
-	CPassThruImpl_THIS(iface,mpos);
-
-	FIXME("(%p)->() stub!\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)
-{
-	CPassThruImpl_THIS(iface,mpos);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-
-static HRESULT WINAPI
-IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
-{
-	CPassThruImpl_THIS(iface,mpos);
-	QUERYPOSPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaPosition_get_Duration(pPos,prefTime);
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
-{
-	CPassThruImpl_THIS(iface,mpos);
-	QUERYPOSPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaPosition_put_CurrentPosition(pPos,refTime);
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
-{
-	CPassThruImpl_THIS(iface,mpos);
-	QUERYPOSPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaPosition_get_CurrentPosition(pPos,prefTime);
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
-{
-	CPassThruImpl_THIS(iface,mpos);
-	QUERYPOSPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaPosition_get_StopTime(pPos,prefTime);
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
-{
-	CPassThruImpl_THIS(iface,mpos);
-	QUERYPOSPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaPosition_put_StopTime(pPos,refTime);
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
-{
-	CPassThruImpl_THIS(iface,mpos);
-	QUERYPOSPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaPosition_get_PrerollTime(pPos,prefTime);
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
-{
-	CPassThruImpl_THIS(iface,mpos);
-	QUERYPOSPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaPosition_put_PrerollTime(pPos,refTime);
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
-{
-	CPassThruImpl_THIS(iface,mpos);
-	QUERYPOSPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaPosition_put_Rate(pPos,dblRate);
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
-{
-	CPassThruImpl_THIS(iface,mpos);
-	QUERYPOSPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaPosition_get_Rate(pPos,pdblRate);
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
-{
-	CPassThruImpl_THIS(iface,mpos);
-	QUERYPOSPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaPosition_CanSeekForward(pPos,pCanSeek);
-}
-
-static HRESULT WINAPI
-IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
-{
-	CPassThruImpl_THIS(iface,mpos);
-	QUERYPOSPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaPosition_CanSeekBackward(pPos,pCanSeek);
-}
-
-
-static ICOM_VTABLE(IMediaPosition) impos =
-{
-	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,
-};
-
-
-HRESULT CPassThruImpl_InitIMediaPosition( CPassThruImpl* pImpl )
-{
-	TRACE("(%p)\n",pImpl);
-	ICOM_VTBL(&pImpl->mpos) = &impos;
-
-	return NOERROR;
-}
-
-void CPassThruImpl_UninitIMediaPosition( CPassThruImpl* pImpl )
-{
-	TRACE("(%p)\n",pImpl);
-}
diff --git a/dlls/quartz/ptmseek.c b/dlls/quartz/ptmseek.c
deleted file mode 100644
index 95f7c39..0000000
--- a/dlls/quartz/ptmseek.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * A pass-through class for IMediaSeeking.
- *
- * hidenori@a2.ctktv.ne.jp
- */
-
-#include "config.h"
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winerror.h"
-#include "wine/obj_base.h"
-#include "strmif.h"
-#include "control.h"
-#include "uuids.h"
-
-#include "debugtools.h"
-DEFAULT_DEBUG_CHANNEL(quartz);
-
-#include "quartz_private.h"
-#include "ptimpl.h"
-
-
-#define QUERYSEEKPASS \
-	IMediaSeeking* pSeek; \
-	HRESULT hr; \
-	hr = CPassThruImpl_QuerySeekPass( This, &pSeek ); \
-	if ( FAILED(hr) ) return hr;
-
-
-static HRESULT WINAPI
-IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj)
-{
-	CPassThruImpl_THIS(iface,mseek);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_QueryInterface(This->punk,riid,ppobj);
-}
-
-static ULONG WINAPI
-IMediaSeeking_fnAddRef(IMediaSeeking* iface)
-{
-	CPassThruImpl_THIS(iface,mseek);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_AddRef(This->punk);
-}
-
-static ULONG WINAPI
-IMediaSeeking_fnRelease(IMediaSeeking* iface)
-{
-	CPassThruImpl_THIS(iface,mseek);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_Release(This->punk);
-}
-
-
-static HRESULT WINAPI
-IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_GetCapabilities(pSeek,pdwCaps);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_CheckCapabilities(pSeek,pdwCaps);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_IsFormatSupported(pSeek,pidFormat);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_QueryPreferredFormat(pSeek,pidFormat);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_GetTimeFormat(pSeek,pidFormat);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_IsUsingTimeFormat(pSeek,pidFormat);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_SetTimeFormat(pSeek,pidFormat);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_GetDuration(pSeek,pllDuration);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_GetStopPosition(pSeek,pllPos);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_GetCurrentPosition(pSeek,pllPos);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_ConvertTimeFormat(pSeek,pllOut,pidFmtOut,llIn,pidFmtIn);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_SetPositions(pSeek,pllCur,dwCurFlags,pllStop,dwStopFlags);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_GetPositions(pSeek,pllCur,pllStop);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_GetAvailable(pSeek,pllFirst,pllLast);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_SetRate(pSeek,dblRate);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_GetRate(pSeek,pdblRate);
-}
-
-static HRESULT WINAPI
-IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll)
-{
-	CPassThruImpl_THIS(iface,mseek);
-	QUERYSEEKPASS
-
-	TRACE("(%p)->()\n",This);
-
-	return IMediaSeeking_GetPreroll(pSeek,pllPreroll);
-}
-
-
-
-
-static ICOM_VTABLE(IMediaSeeking) imseek =
-{
-	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,
-};
-
-
-
-HRESULT CPassThruImpl_InitIMediaSeeking( CPassThruImpl* pImpl )
-{
-	TRACE("(%p)\n",pImpl);
-	ICOM_VTBL(&pImpl->mseek) = &imseek;
-
-	return NOERROR;
-}
-
-void CPassThruImpl_UninitIMediaSeeking( CPassThruImpl* pImpl )
-{
-	TRACE("(%p)\n",pImpl);
-}
diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h
index b7f599d..5efb684 100644
--- a/dlls/quartz/quartz_private.h
+++ b/dlls/quartz/quartz_private.h
@@ -7,6 +7,7 @@
 void QUARTZ_FreeObj( void* pobj );
 void* QUARTZ_AllocMem( DWORD dwSize );
 void QUARTZ_FreeMem( void* pMem );
+void* QUARTZ_ReallocMem( void* pMem, DWORD dwSize );
 
 #endif	/* QUARTZ_PRIVATE_H */
 
diff --git a/dlls/quartz/sample.c b/dlls/quartz/sample.c
index 5e7aa1c..8094164 100644
--- a/dlls/quartz/sample.c
+++ b/dlls/quartz/sample.c
@@ -20,8 +20,14 @@
 
 #include "quartz_private.h"
 #include "sample.h"
+#include "mtype.h"
 
 
+/***************************************************************************
+ *
+ *	CMemMediaSample::IMediaSample2
+ *
+ */
 
 static HRESULT WINAPI
 IMediaSample2_fnQueryInterface(IMediaSample2* iface,REFIID riid,void** ppobj)
@@ -67,6 +73,16 @@
 	if ( ref > 0 )
 		return (ULONG)ref;
 
+	/* this class would be reused.. */
+	if ( This->prop.pMediaType != NULL )
+	{
+		QUARTZ_MediaType_Destroy( This->prop.pMediaType );
+		This->prop.pMediaType = NULL;
+	}
+	This->prop.dwTypeSpecificFlags = 0;
+	This->prop.dwSampleFlags = 0;
+	This->prop.lActual = This->prop.cbBuffer;
+
 	IMemAllocator_ReleaseBuffer(This->pOwner,(IMediaSample*)iface);
 
 	return 0;
@@ -226,28 +242,47 @@
 
 	if ( ppmt == NULL )
 		return E_POINTER;
+	*ppmt = NULL;
 	if ( !(This->prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) )
 		return S_FALSE;
 
-	/* FIXME - not implemented! */
+	*ppmt = QUARTZ_MediaType_Duplicate( This->prop.pMediaType );
+	if ( *ppmt == NULL )
+		return E_OUTOFMEMORY;
 
-	FIXME("(%p)->(%p) not implemented!\n",This,ppmt);
-
-	/* return CoTaskMemAlloc-ed memory. */
-
-	return E_NOTIMPL;
+	return NOERROR;
 }
 
 static HRESULT WINAPI
 IMediaSample2_fnSetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE* pmt)
 {
 	ICOM_THIS(CMemMediaSample,iface);
+	AM_MEDIA_TYPE* pmtDup;
 
-	FIXME("(%p)->() stub!\n",This);
+	TRACE("(%p)->(%p)\n",This,pmt);
 
-	/* FIXME - not implemented! */
+	if ( pmt == NULL )
+	{
+		/* FIXME? */
+		if ( This->prop.pMediaType != NULL )
+		{
+			QUARTZ_MediaType_Destroy( This->prop.pMediaType );
+			This->prop.pMediaType = NULL;
+		}
+		This->prop.dwSampleFlags &= ~AM_SAMPLE_TYPECHANGED;
+		return NOERROR;
+	}
 
-	return E_NOTIMPL;
+	pmtDup = QUARTZ_MediaType_Duplicate( pmt );
+	if ( pmtDup == NULL )
+		return E_OUTOFMEMORY;
+
+	if ( This->prop.pMediaType != NULL )
+		QUARTZ_MediaType_Destroy( This->prop.pMediaType );
+	This->prop.dwSampleFlags |= AM_SAMPLE_TYPECHANGED;
+	This->prop.pMediaType = pmtDup;
+
+	return NOERROR;
 }
 
 static HRESULT WINAPI
@@ -281,7 +316,7 @@
 {
 	ICOM_THIS(CMemMediaSample,iface);
 
-	FIXME("(%p)->() stub!\n",This);
+	TRACE("(%p)->(%p,%p)\n",This,pTimeStart,pTimeEnd);
 
 	if ( pTimeStart == NULL || pTimeEnd == NULL )
 		return E_POINTER;
@@ -336,14 +371,56 @@
 IMediaSample2_fnSetProperties(IMediaSample2* iface,DWORD cbProp,const BYTE* pbProp)
 {
 	ICOM_THIS(CMemMediaSample,iface);
+	const AM_SAMPLE2_PROPERTIES* pProp;
+	AM_SAMPLE2_PROPERTIES propNew;
+	AM_MEDIA_TYPE* pmtDup = NULL;
+	HRESULT hr = E_INVALIDARG;
 
-	FIXME("(%p)->() stub!\n",This);
+	TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
 
-	return E_NOTIMPL;
+	if ( pbProp == NULL )
+		return E_POINTER;
+	pProp = (const AM_SAMPLE2_PROPERTIES*)pbProp;
+	if ( cbProp != sizeof(AM_SAMPLE2_PROPERTIES) )
+		goto err;
+
+	CopyMemory( &propNew, pProp, sizeof(AM_SAMPLE2_PROPERTIES) );
+	if ( propNew.cbData != sizeof(AM_SAMPLE2_PROPERTIES) )
+		goto err;
+
+	if ( This->prop.cbBuffer < propNew.lActual )
+		goto err;
+
+	if ( propNew.dwSampleFlags & AM_SAMPLE_TYPECHANGED )
+	{
+		pmtDup = QUARTZ_MediaType_Duplicate( propNew.pMediaType );
+		if ( pmtDup == NULL )
+		{
+			hr = E_OUTOFMEMORY;
+			goto err;
+		}
+	}
+
+	if ( propNew.pbBuffer != NULL && propNew.pbBuffer != This->prop.pbBuffer )
+		goto err;
+	if ( propNew.cbBuffer != 0 && propNew.cbBuffer != This->prop.cbBuffer )
+		goto err;
+
+	if ( This->prop.pMediaType != NULL )
+		QUARTZ_MediaType_Destroy( This->prop.pMediaType );
+	CopyMemory( &This->prop, &propNew, sizeof(AM_SAMPLE2_PROPERTIES) );
+	This->prop.pMediaType = pmtDup;
+	pmtDup = NULL;
+
+	hr= NOERROR;
+err:
+	if ( pmtDup != NULL )
+		QUARTZ_MediaType_Destroy( pmtDup );
+
+	return hr;
 }
 
 
-
 static ICOM_VTABLE(IMediaSample2) imediasample2 =
 {
 	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
@@ -374,6 +451,11 @@
 };
 
 
+/***************************************************************************
+ *
+ *	new/delete for CMemMediaSample
+ *
+ */
 
 HRESULT QUARTZ_CreateMemMediaSample(
 	BYTE* pbData, DWORD dwDataLength,
@@ -388,7 +470,7 @@
 		return E_OUTOFMEMORY;
 
 	ICOM_VTBL(pms) = &imediasample2;
-	pms->ref = 1;
+	pms->ref = 0;
 	pms->pOwner = pOwner;
 	pms->fMediaTimeIsValid = FALSE;
 	pms->llMediaTimeStart = 0;
diff --git a/dlls/quartz/seekpass.c b/dlls/quartz/seekpass.c
index 63ed7f0..c8c45f6 100644
--- a/dlls/quartz/seekpass.c
+++ b/dlls/quartz/seekpass.c
@@ -1,5 +1,7 @@
 /*
- * Implementation of CLSID_SeekingPassThru.
+ *	Implementation of CLSID_SeekingPassThru
+ *
+ *	FIXME - not tested yet.
  *
  * hidenori@a2.ctktv.ne.jp
  */
@@ -23,6 +25,11 @@
 #include "seekpass.h"
 
 
+/***************************************************************************
+ *
+ *	CSeekingPassThru::ISeekingPassThru
+ *
+ */
 
 static HRESULT WINAPI
 ISeekingPassThru_fnQueryInterface(ISeekingPassThru* iface,REFIID riid,void** ppobj)
@@ -64,7 +71,7 @@
 	if ( pPin == NULL )
 		return E_POINTER;
 
-	/* Why 'bRendering' is given as an argument?? */
+	/* Why is 'bRendering' given as an argument?? */
 	EnterCriticalSection( &This->cs );
 
 	if ( This->passthru.pPin != NULL )
@@ -112,6 +119,11 @@
 	DeleteCriticalSection( &This->cs );
 }
 
+/***************************************************************************
+ *
+ *	new/delete for CLSID_SeekingPassThru.
+ *
+ */
 
 /* can I use offsetof safely? - FIXME? */
 static QUARTZ_IFEntry IFEntries[] =
@@ -157,3 +169,574 @@
 	return S_OK;
 }
 
+
+
+
+/***************************************************************************
+ *
+ *	CPassThruImpl Helper methods.
+ *
+ */
+
+static
+HRESULT CPassThruImpl_GetConnected( CPassThruImpl* pImpl, IPin** ppPin )
+{
+	return IPin_ConnectedTo( pImpl->pPin, ppPin );
+}
+
+HRESULT CPassThruImpl_QueryPosPass(
+	CPassThruImpl* pImpl, IMediaPosition** ppPosition )
+{
+	IPin*	pPin;
+	HRESULT	hr;
+
+	hr = CPassThruImpl_GetConnected( pImpl, &pPin );
+	if ( FAILED(hr) )
+		return hr;
+	hr = IPin_QueryInterface(pPin,&IID_IMediaPosition,(void**)ppPosition);
+	IPin_Release(pPin);
+
+	return hr;
+}
+
+HRESULT CPassThruImpl_QuerySeekPass(
+	CPassThruImpl* pImpl, IMediaSeeking** ppSeeking )
+{
+	IPin*	pPin;
+	HRESULT	hr;
+
+	hr = CPassThruImpl_GetConnected( pImpl, &pPin );
+	if ( FAILED(hr) )
+		return hr;
+	hr = IPin_QueryInterface(pPin,&IID_IMediaSeeking,(void**)ppSeeking);
+	IPin_Release(pPin);
+
+	return hr;
+}
+
+/***************************************************************************
+ *
+ *	An implementation for CPassThruImpl::IMediaPosition.
+ *
+ */
+
+
+#define QUERYPOSPASS \
+	IMediaPosition* pPos = NULL; \
+	HRESULT hr; \
+	hr = CPassThruImpl_QueryPosPass( This, &pPos ); \
+	if ( FAILED(hr) ) return hr;
+
+static HRESULT WINAPI
+IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj)
+{
+	CPassThruImpl_THIS(iface,mpos);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->punk,riid,ppobj);
+}
+
+static ULONG WINAPI
+IMediaPosition_fnAddRef(IMediaPosition* iface)
+{
+	CPassThruImpl_THIS(iface,mpos);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->punk);
+}
+
+static ULONG WINAPI
+IMediaPosition_fnRelease(IMediaPosition* iface)
+{
+	CPassThruImpl_THIS(iface,mpos);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->punk);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo)
+{
+	CPassThruImpl_THIS(iface,mpos);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
+{
+	CPassThruImpl_THIS(iface,mpos);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
+{
+	CPassThruImpl_THIS(iface,mpos);
+
+	FIXME("(%p)->() stub!\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)
+{
+	CPassThruImpl_THIS(iface,mpos);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+static HRESULT WINAPI
+IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
+{
+	CPassThruImpl_THIS(iface,mpos);
+	QUERYPOSPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaPosition_get_Duration(pPos,prefTime);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
+{
+	CPassThruImpl_THIS(iface,mpos);
+	QUERYPOSPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaPosition_put_CurrentPosition(pPos,refTime);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
+{
+	CPassThruImpl_THIS(iface,mpos);
+	QUERYPOSPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaPosition_get_CurrentPosition(pPos,prefTime);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
+{
+	CPassThruImpl_THIS(iface,mpos);
+	QUERYPOSPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaPosition_get_StopTime(pPos,prefTime);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
+{
+	CPassThruImpl_THIS(iface,mpos);
+	QUERYPOSPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaPosition_put_StopTime(pPos,refTime);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
+{
+	CPassThruImpl_THIS(iface,mpos);
+	QUERYPOSPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaPosition_get_PrerollTime(pPos,prefTime);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
+{
+	CPassThruImpl_THIS(iface,mpos);
+	QUERYPOSPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaPosition_put_PrerollTime(pPos,refTime);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
+{
+	CPassThruImpl_THIS(iface,mpos);
+	QUERYPOSPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaPosition_put_Rate(pPos,dblRate);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
+{
+	CPassThruImpl_THIS(iface,mpos);
+	QUERYPOSPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaPosition_get_Rate(pPos,pdblRate);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
+{
+	CPassThruImpl_THIS(iface,mpos);
+	QUERYPOSPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaPosition_CanSeekForward(pPos,pCanSeek);
+}
+
+static HRESULT WINAPI
+IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
+{
+	CPassThruImpl_THIS(iface,mpos);
+	QUERYPOSPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaPosition_CanSeekBackward(pPos,pCanSeek);
+}
+
+
+static ICOM_VTABLE(IMediaPosition) impos =
+{
+	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,
+};
+
+
+HRESULT CPassThruImpl_InitIMediaPosition( CPassThruImpl* pImpl )
+{
+	TRACE("(%p)\n",pImpl);
+	ICOM_VTBL(&pImpl->mpos) = &impos;
+
+	return NOERROR;
+}
+
+void CPassThruImpl_UninitIMediaPosition( CPassThruImpl* pImpl )
+{
+	TRACE("(%p)\n",pImpl);
+}
+
+#undef QUERYPOSPASS
+
+
+/***************************************************************************
+ *
+ *	An implementation for CPassThruImpl::IMediaSeeking.
+ *
+ */
+
+#define QUERYSEEKPASS \
+	IMediaSeeking* pSeek = NULL; \
+	HRESULT hr; \
+	hr = CPassThruImpl_QuerySeekPass( This, &pSeek ); \
+	if ( FAILED(hr) ) return hr;
+
+
+static HRESULT WINAPI
+IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj)
+{
+	CPassThruImpl_THIS(iface,mseek);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->punk,riid,ppobj);
+}
+
+static ULONG WINAPI
+IMediaSeeking_fnAddRef(IMediaSeeking* iface)
+{
+	CPassThruImpl_THIS(iface,mseek);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->punk);
+}
+
+static ULONG WINAPI
+IMediaSeeking_fnRelease(IMediaSeeking* iface)
+{
+	CPassThruImpl_THIS(iface,mseek);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->punk);
+}
+
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_GetCapabilities(pSeek,pdwCaps);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_CheckCapabilities(pSeek,pdwCaps);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_IsFormatSupported(pSeek,pidFormat);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_QueryPreferredFormat(pSeek,pidFormat);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_GetTimeFormat(pSeek,pidFormat);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_IsUsingTimeFormat(pSeek,pidFormat);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_SetTimeFormat(pSeek,pidFormat);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_GetDuration(pSeek,pllDuration);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_GetStopPosition(pSeek,pllPos);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_GetCurrentPosition(pSeek,pllPos);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_ConvertTimeFormat(pSeek,pllOut,pidFmtOut,llIn,pidFmtIn);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_SetPositions(pSeek,pllCur,dwCurFlags,pllStop,dwStopFlags);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_GetPositions(pSeek,pllCur,pllStop);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_GetAvailable(pSeek,pllFirst,pllLast);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_SetRate(pSeek,dblRate);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_GetRate(pSeek,pdblRate);
+}
+
+static HRESULT WINAPI
+IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll)
+{
+	CPassThruImpl_THIS(iface,mseek);
+	QUERYSEEKPASS
+
+	TRACE("(%p)->()\n",This);
+
+	return IMediaSeeking_GetPreroll(pSeek,pllPreroll);
+}
+
+
+
+
+static ICOM_VTABLE(IMediaSeeking) imseek =
+{
+	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,
+};
+
+
+
+HRESULT CPassThruImpl_InitIMediaSeeking( CPassThruImpl* pImpl )
+{
+	TRACE("(%p)\n",pImpl);
+	ICOM_VTBL(&pImpl->mseek) = &imseek;
+
+	return NOERROR;
+}
+
+void CPassThruImpl_UninitIMediaSeeking( CPassThruImpl* pImpl )
+{
+	TRACE("(%p)\n",pImpl);
+}
+
+#undef QUERYSEEKPASS
diff --git a/dlls/quartz/seekpass.h b/dlls/quartz/seekpass.h
index e89f511..6c2b1e7 100644
--- a/dlls/quartz/seekpass.h
+++ b/dlls/quartz/seekpass.h
@@ -12,14 +12,38 @@
 */
 
 #include "iunk.h"
-#include "ptimpl.h"
+
+
+/****************************************************************************/
+
+typedef struct CPassThruImpl
+{
+	struct { ICOM_VFIELD(IMediaPosition); } mpos;
+	struct { ICOM_VFIELD(IMediaSeeking); } mseek;
+
+	IUnknown* punk;
+	IPin* pPin;
+} CPassThruImpl;
+
+#define	CPassThruImpl_THIS(iface,member)		CPassThruImpl*	This = ((CPassThruImpl*)(((char*)iface)-offsetof(CPassThruImpl,member)))
+
+HRESULT CPassThruImpl_InitIMediaPosition( CPassThruImpl* pImpl );
+void CPassThruImpl_UninitIMediaPosition( CPassThruImpl* pImpl );
+HRESULT CPassThruImpl_InitIMediaSeeking( CPassThruImpl* pImpl );
+void CPassThruImpl_UninitIMediaSeeking( CPassThruImpl* pImpl );
+
+HRESULT CPassThruImpl_QueryPosPass(
+	CPassThruImpl* pImpl, IMediaPosition** ppPosition );
+HRESULT CPassThruImpl_QuerySeekPass(
+	CPassThruImpl* pImpl, IMediaSeeking** ppSeeking );
+
+/****************************************************************************/
 
 typedef struct QUARTZ_ISeekingPassThruImpl
 {
 	ICOM_VFIELD(ISeekingPassThru);
 } QUARTZ_ISeekingPassThruImpl;
 
-
 typedef struct CSeekingPassThru
 {
 	QUARTZ_IUnkImpl	unk;
diff --git a/dlls/quartz/sysclock.c b/dlls/quartz/sysclock.c
index def4edd..b2b64f7 100644
--- a/dlls/quartz/sysclock.c
+++ b/dlls/quartz/sysclock.c
@@ -1,8 +1,6 @@
 /*
  * Implementation of CLSID_SystemClock.
  *
- * FIXME - stub.
- *
  * hidenori@a2.ctktv.ne.jp
  */
 
@@ -24,6 +22,12 @@
 #include "sysclock.h"
 
 
+/***************************************************************************
+ *
+ *	new/delete for CLSID_SystemClock
+ *
+ */
+
 /* can I use offsetof safely? - FIXME? */
 static QUARTZ_IFEntry IFEntries[] =
 {
@@ -65,3 +69,449 @@
 
 	return S_OK;
 }
+
+
+/***************************************************************************
+ *
+ *	CLSID_SystemClock::IReferenceClock
+ *
+ */
+
+#define	QUARTZ_MSG_ADDTIMER			(WM_APP+0)
+#define	QUARTZ_MSG_REMOVETIMER		(WM_APP+1)
+#define	QUARTZ_MSG_EXITTHREAD		(WM_APP+2)
+
+
+/****************************************************************************/
+
+static QUARTZ_TimerEntry* IReferenceClock_AllocTimerEntry(CSystemClock* This)
+{
+	QUARTZ_TimerEntry*	pEntry;
+	DWORD	dw;
+
+	pEntry = &This->m_timerEntries[0];
+	for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
+	{
+		if ( pEntry->hEvent == (HANDLE)NULL )
+			return pEntry;
+		pEntry ++;
+	}
+
+	return NULL;
+}
+
+static QUARTZ_TimerEntry* IReferenceClock_SearchTimer(CSystemClock* This, DWORD dwAdvCookie)
+{
+	QUARTZ_TimerEntry*	pEntry;
+	DWORD	dw;
+
+	pEntry = &This->m_timerEntries[0];
+	for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
+	{
+		if ( pEntry->hEvent != (HANDLE)NULL &&
+			 pEntry->dwAdvCookie == dwAdvCookie )
+			return pEntry;
+		pEntry ++;
+	}
+
+	return NULL;
+}
+
+static DWORD IReferenceClock_OnTimerUpdated(CSystemClock* This)
+{
+	QUARTZ_TimerEntry*	pEntry;
+	REFERENCE_TIME	rtCur;
+	REFERENCE_TIME	rtSignal;
+	REFERENCE_TIME	rtCount;
+	HRESULT	hr;
+	LONG	lCount;
+	DWORD	dw;
+	DWORD	dwTimeout = INFINITE;
+	DWORD	dwTimeoutCur;
+
+	hr = IReferenceClock_GetTime((IReferenceClock*)(&This->refclk),&rtCur);
+	if ( hr != NOERROR )
+		return INFINITE;
+
+	pEntry = &This->m_timerEntries[0];
+	for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
+	{
+		if ( pEntry->hEvent != (HANDLE)NULL )
+		{
+			rtSignal = pEntry->rtStart + pEntry->rtInterval;
+			if ( rtCur >= rtSignal )
+			{
+				if ( pEntry->fPeriodic )
+				{
+					rtCount = ((rtCur - pEntry->rtStart) / pEntry->rtInterval);
+					lCount = ( rtCount > (REFERENCE_TIME)0x7fffffff ) ?
+						(LONG)0x7fffffff : (LONG)rtCount;
+					if ( !ReleaseSemaphore( pEntry->hEvent, lCount, NULL ) )
+					{
+						while ( lCount > 0 )
+						{
+							if ( !ReleaseSemaphore( pEntry->hEvent, 1, NULL ) )
+								break;
+						}
+					}
+					dwTimeout = 0;
+				}
+				else
+				{
+					TRACE( "signal an event\n" );
+					SetEvent( pEntry->hEvent );
+					pEntry->hEvent = (HANDLE)NULL;
+				}
+			}
+			else
+			{
+				rtCount = rtSignal - rtCur;
+				/* [100ns] -> [ms] */
+				rtCount = (rtCount+(REFERENCE_TIME)9999)/(REFERENCE_TIME)10000;
+				dwTimeoutCur = (rtCount >= 0xfffffffe) ? (DWORD)0xfffffffe : (DWORD)rtCount;
+				if ( dwTimeout > dwTimeoutCur )
+					dwTimeout = dwTimeoutCur;
+			}
+		}
+		pEntry ++;
+	}
+
+	return dwTimeout;
+}
+
+static
+DWORD WINAPI IReferenceClock_TimerEntry( LPVOID lpvParam )
+{
+	CSystemClock*	This = (CSystemClock*)lpvParam;
+	MSG	msg;
+	DWORD	dwRes;
+	DWORD	dwTimeout;
+
+	/* initialize the message queue. */
+	PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE );
+	/* resume the owner thread. */
+	SetEvent( This->m_hEventInit );
+
+	TRACE( "Enter message loop.\n" );
+
+	/* message loop. */
+	dwTimeout = INFINITE;
+	while ( 1 )
+	{
+		if ( dwTimeout > 0 )
+		{
+			dwRes = MsgWaitForMultipleObjects(
+				0, NULL, FALSE,
+				dwTimeout,
+				QS_ALLEVENTS );
+		}
+
+		EnterCriticalSection( &This->m_csClock );
+		dwTimeout = IReferenceClock_OnTimerUpdated(This);
+		LeaveCriticalSection( &This->m_csClock );
+		TRACE( "catch an event / timeout %lu\n", dwTimeout );
+
+		while ( PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_REMOVE ) )
+		{
+			if ( msg.message == WM_QUIT )
+				goto quitthread;
+
+			if ( msg.hwnd != (HWND)NULL )
+			{
+				TranslateMessage( &msg );
+				DispatchMessageA( &msg );
+			}
+			else
+			{
+				switch ( msg.message )
+				{
+				case QUARTZ_MSG_ADDTIMER:
+				case QUARTZ_MSG_REMOVETIMER:
+					dwTimeout = 0;
+					break;
+				case QUARTZ_MSG_EXITTHREAD:
+					PostQuitMessage(0);
+					break;
+				default:
+					FIXME( "invalid message %04u\n", (unsigned)msg.message );
+					break;
+				}
+			}
+		}
+	}
+
+quitthread:
+	TRACE( "quit thread\n" );
+	return 0;
+}
+
+/****************************************************************************/
+
+static HRESULT WINAPI
+IReferenceClock_fnQueryInterface(IReferenceClock* iface,REFIID riid,void** ppobj)
+{
+	CSystemClock_THIS(iface,refclk);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IReferenceClock_fnAddRef(IReferenceClock* iface)
+{
+	CSystemClock_THIS(iface,refclk);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IReferenceClock_fnRelease(IReferenceClock* iface)
+{
+	CSystemClock_THIS(iface,refclk);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IReferenceClock_fnGetTime(IReferenceClock* iface,REFERENCE_TIME* prtTime)
+{
+	CSystemClock_THIS(iface,refclk);
+	DWORD	dwTimeCur;
+
+	TRACE( "(%p)->(%p)\n", This, prtTime );
+
+	if ( prtTime == NULL )
+		return E_POINTER;
+
+	EnterCriticalSection( &This->m_csClock );
+
+	dwTimeCur = GetTickCount();
+	This->m_rtLast += (REFERENCE_TIME)(DWORD)(dwTimeCur - This->m_dwTimeLast) * (REFERENCE_TIME)10000;
+
+	This->m_dwTimeLast = dwTimeCur;
+
+	*prtTime = This->m_rtLast;
+
+	LeaveCriticalSection( &This->m_csClock );
+
+	return NOERROR;
+}
+
+static HRESULT WINAPI
+IReferenceClock_fnAdviseTime(IReferenceClock* iface,REFERENCE_TIME rtBase,REFERENCE_TIME rtStream,HEVENT hEvent,DWORD_PTR* pdwAdvCookie)
+{
+	CSystemClock_THIS(iface,refclk);
+	QUARTZ_TimerEntry*	pEntry;
+	HRESULT	hr;
+	REFERENCE_TIME	rtCur;
+
+	TRACE( "(%p)->()\n", This );
+
+	if ( pdwAdvCookie == NULL )
+		return E_POINTER;
+	if ( hEvent == (HANDLE)NULL )
+		return E_INVALIDARG;
+
+	EnterCriticalSection( &This->m_csClock );
+
+	*pdwAdvCookie = (DWORD_PTR)(This->m_dwAdvCookieNext ++);
+
+	hr = IReferenceClock_GetTime(iface,&rtCur);
+	if ( hr != NOERROR )
+		goto err;
+	if ( rtCur >= (rtBase+rtStream) )
+	{
+		SetEvent(hEvent);
+		hr = NOERROR;
+		goto err;
+	}
+
+	pEntry = IReferenceClock_AllocTimerEntry(This);
+	if ( pEntry == NULL )
+	{
+		hr = E_FAIL;
+		goto err;
+	}
+
+        pEntry->dwAdvCookie = *pdwAdvCookie;
+        pEntry->fPeriodic = FALSE;
+        pEntry->hEvent = hEvent;
+        pEntry->rtStart = rtBase;
+        pEntry->rtInterval = rtStream;
+
+	if ( !PostThreadMessageA(
+			This->m_idThreadTimer,
+			QUARTZ_MSG_ADDTIMER,
+			0, 0 ) )
+	{
+		pEntry->hEvent = (HANDLE)NULL;
+		hr = E_FAIL;
+		goto err;
+	}
+
+	hr = NOERROR;
+err:
+	LeaveCriticalSection( &This->m_csClock );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+IReferenceClock_fnAdvisePeriodic(IReferenceClock* iface,REFERENCE_TIME rtStart,REFERENCE_TIME rtPeriod,HSEMAPHORE hSemaphore,DWORD_PTR* pdwAdvCookie)
+{
+	CSystemClock_THIS(iface,refclk);
+	QUARTZ_TimerEntry*	pEntry;
+	HRESULT	hr;
+
+	TRACE( "(%p)->()\n", This );
+
+	if ( pdwAdvCookie == NULL )
+		return E_POINTER;
+	if ( hSemaphore == (HSEMAPHORE)NULL )
+		return E_INVALIDARG;
+
+	EnterCriticalSection( &This->m_csClock );
+
+	*pdwAdvCookie = (DWORD_PTR)(This->m_dwAdvCookieNext ++);
+
+	pEntry = IReferenceClock_AllocTimerEntry(This);
+	if ( pEntry == NULL )
+	{
+		hr = E_FAIL;
+		goto err;
+	}
+
+        pEntry->dwAdvCookie = *pdwAdvCookie;
+        pEntry->fPeriodic = TRUE;
+        pEntry->hEvent = (HANDLE)hSemaphore;
+        pEntry->rtStart = rtStart;
+        pEntry->rtInterval = rtPeriod;
+
+	if ( !PostThreadMessageA(
+			This->m_idThreadTimer,
+			QUARTZ_MSG_ADDTIMER,
+			0, 0 ) )
+	{
+		pEntry->hEvent = (HANDLE)NULL;
+		hr = E_FAIL;
+		goto err;
+	}
+
+	hr = NOERROR;
+err:
+	LeaveCriticalSection( &This->m_csClock );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+IReferenceClock_fnUnadvise(IReferenceClock* iface,DWORD_PTR dwAdvCookie)
+{
+	CSystemClock_THIS(iface,refclk);
+	QUARTZ_TimerEntry*	pEntry;
+
+	TRACE( "(%p)->(%lu)\n", This, (DWORD)dwAdvCookie );
+
+	EnterCriticalSection( &This->m_csClock );
+
+	pEntry = IReferenceClock_SearchTimer(This,(DWORD)dwAdvCookie);
+	if ( pEntry != NULL )
+	{
+		pEntry->hEvent = (HANDLE)NULL;
+	}
+
+	LeaveCriticalSection( &This->m_csClock );
+
+	return NOERROR;
+}
+
+static ICOM_VTABLE(IReferenceClock) irefclk =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IReferenceClock_fnQueryInterface,
+	IReferenceClock_fnAddRef,
+	IReferenceClock_fnRelease,
+	/* IReferenceClock fields */
+	IReferenceClock_fnGetTime,
+	IReferenceClock_fnAdviseTime,
+	IReferenceClock_fnAdvisePeriodic,
+	IReferenceClock_fnUnadvise,
+};
+
+
+HRESULT CSystemClock_InitIReferenceClock( CSystemClock* psc )
+{
+	HANDLE	hEvents[2];
+
+	TRACE("(%p)\n",psc);
+	ICOM_VTBL(&psc->refclk) = &irefclk;
+
+	InitializeCriticalSection( &psc->m_csClock );
+	psc->m_dwTimeLast = GetTickCount();
+	psc->m_rtLast = (REFERENCE_TIME)0;
+	psc->m_hThreadTimer = (HANDLE)NULL;
+	psc->m_hEventInit = (HANDLE)NULL;
+	psc->m_idThreadTimer = 0;
+	psc->m_dwAdvCookieNext = 1;
+	ZeroMemory( psc->m_timerEntries, sizeof(psc->m_timerEntries) );
+
+	psc->m_hEventInit = CreateEventA( NULL, TRUE, FALSE, NULL );
+	if ( psc->m_hEventInit == (HANDLE)NULL )
+		goto err;
+
+	psc->m_hThreadTimer = CreateThread(
+		NULL, 0,
+		IReferenceClock_TimerEntry,
+		psc, 0, &psc->m_idThreadTimer );
+
+	if ( psc->m_hThreadTimer == (HANDLE)NULL )
+	{
+		CloseHandle( psc->m_hEventInit );
+		psc->m_hEventInit = (HANDLE)NULL;
+		goto err;
+	}
+
+	hEvents[0] = psc->m_hEventInit;
+	hEvents[1] = psc->m_hThreadTimer;
+	if ( WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE )
+			!= WAIT_OBJECT_0 )
+	{
+		CloseHandle( psc->m_hEventInit );
+		psc->m_hEventInit = (HANDLE)NULL;
+		CloseHandle( psc->m_hThreadTimer );
+		psc->m_hThreadTimer = (HANDLE)NULL;
+		goto err;
+	}
+
+	return NOERROR;
+
+err:
+	DeleteCriticalSection( &psc->m_csClock );
+	return E_FAIL;
+}
+
+void CSystemClock_UninitIReferenceClock( CSystemClock* psc )
+{
+	TRACE("(%p)\n",psc);
+
+	if ( psc->m_hThreadTimer != (HANDLE)NULL )
+	{
+		if ( PostThreadMessageA(
+			psc->m_idThreadTimer,
+			QUARTZ_MSG_EXITTHREAD,
+			0, 0 ) )
+		{
+			WaitForSingleObject( psc->m_hThreadTimer, INFINITE );
+		}
+		CloseHandle( psc->m_hThreadTimer );
+		psc->m_hThreadTimer = (HANDLE)NULL;
+	}
+
+	DeleteCriticalSection( &psc->m_csClock );
+}