quartz: COM cleanup for PullPin.
diff --git a/dlls/quartz/avisplit.c b/dlls/quartz/avisplit.c
index bcfdeb1..00b9cee 100644
--- a/dlls/quartz/avisplit.c
+++ b/dlls/quartz/avisplit.c
@@ -559,7 +559,7 @@
     if (!pIndex)
         return E_OUTOFMEMORY;
 
-    IAsyncReader_SyncRead(((PullPin *)This->Parser.ppPins[0])->pReader, qwOffset, cb, (BYTE *)pIndex);
+    IAsyncReader_SyncRead((impl_PullPin_from_IPin(This->Parser.ppPins[0]))->pReader, qwOffset, cb, (BYTE *)pIndex);
     rest = cb - sizeof(AVISUPERINDEX) + sizeof(RIFFCHUNK) + sizeof(pIndex->aIndex);
 
     TRACE("FOURCC: %s\n", debugstr_an((char *)&pIndex->fcc, 4));
@@ -1019,7 +1019,7 @@
 /* FIXME: fix leaks on failure here */
 static HRESULT AVISplitter_InputPin_PreConnect(IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *props)
 {
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
     HRESULT hr;
     RIFFLIST list;
     LONGLONG pos = 0; /* in bytes */
@@ -1301,7 +1301,7 @@
 
     EnterCriticalSection(&pPin->thread_lock);
     /* Send a flush to all output pins */
-    IPin_BeginFlush((IPin *)pPin);
+    IPin_BeginFlush(&pPin->pin.IPin_iface);
 
     /* Make sure this is done while stopped, BeginFlush takes care of this */
     EnterCriticalSection(&This->Parser.filter.csFilter);
@@ -1401,7 +1401,7 @@
     LeaveCriticalSection(&This->Parser.filter.csFilter);
 
     TRACE("Done flushing\n");
-    IPin_EndFlush((IPin *)pPin);
+    IPin_EndFlush(&pPin->pin.IPin_iface);
     LeaveCriticalSection(&pPin->thread_lock);
 
     return S_OK;
diff --git a/dlls/quartz/mpegsplit.c b/dlls/quartz/mpegsplit.c
index f2e1138..008a0a5 100644
--- a/dlls/quartz/mpegsplit.c
+++ b/dlls/quartz/mpegsplit.c
@@ -483,7 +483,7 @@
 
 static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATOR_PROPERTIES *props)
 {
-    PullPin *pPin = (PullPin *)iface;
+    PullPin *pPin = impl_PullPin_from_IPin(iface);
     MPEGSplitterImpl *This = (MPEGSplitterImpl*)pPin->pin.pinInfo.pFilter;
     HRESULT hr;
     LONGLONG pos = 0; /* in bytes */
@@ -705,7 +705,7 @@
         TRACE("Moving sound to %08u bytes!\n", (DWORD)bytepos);
 
         EnterCriticalSection(&pin->thread_lock);
-        IPin_BeginFlush((IPin *)pin);
+        IPin_BeginFlush(&pin->pin.IPin_iface);
 
         /* Make sure this is done while stopped, BeginFlush takes care of this */
         EnterCriticalSection(&This->Parser.filter.csFilter);
@@ -718,7 +718,7 @@
         LeaveCriticalSection(&This->Parser.filter.csFilter);
 
         TRACE("Done flushing\n");
-        IPin_EndFlush((IPin *)pin);
+        IPin_EndFlush(&pin->pin.IPin_iface);
         LeaveCriticalSection(&pin->thread_lock);
     }
     return hr;
diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c
index c1d041a..70a74cb 100644
--- a/dlls/quartz/parser.c
+++ b/dlls/quartz/parser.c
@@ -113,7 +113,7 @@
 
     if (SUCCEEDED(hr))
     {
-        pParser->ppPins[0] = (IPin *)pParser->pInputPin;
+        pParser->ppPins[0] = &pParser->pInputPin->pin.IPin_iface;
         pParser->pInputPin->fnPreConnect = fnPreConnect;
     }
     else
@@ -165,14 +165,14 @@
     PullPin_WaitForStateChange(This->pInputPin, INFINITE);
 
     /* Don't need to clean up output pins, freeing input pin will do that */
-    IPin_ConnectedTo((IPin *)This->pInputPin, &connected);
+    IPin_ConnectedTo(&This->pInputPin->pin.IPin_iface, &connected);
     if (connected)
     {
         assert(IPin_Disconnect(connected) == S_OK);
         IPin_Release(connected);
-        assert(IPin_Disconnect((IPin *)This->pInputPin) == S_OK);
+        assert(IPin_Disconnect(&This->pInputPin->pin.IPin_iface) == S_OK);
     }
-    pinref = IPin_Release((IPin *)This->pInputPin);
+    pinref = IPin_Release(&This->pInputPin->pin.IPin_iface);
     if (pinref)
     {
         /* Valgrind could find this, if I kill it here */
@@ -180,7 +180,7 @@
         assert((LONG)pinref > 0);
 
         while (pinref)
-            pinref = IPin_Release((IPin *)This->pInputPin);
+            pinref = IPin_Release(&This->pInputPin->pin.IPin_iface);
     }
 
     CoTaskMemFree(This->ppPins);
@@ -220,7 +220,7 @@
 HRESULT WINAPI Parser_Stop(IBaseFilter * iface)
 {
     ParserImpl *This = (ParserImpl *)iface;
-    PullPin *pin = (PullPin *)This->ppPins[0];
+    PullPin *pin = impl_PullPin_from_IPin(This->ppPins[0]);
     ULONG i;
 
     TRACE("()\n");
@@ -259,7 +259,7 @@
 {
     HRESULT hr = S_OK;
     ParserImpl *This = (ParserImpl *)iface;
-    PullPin *pin = (PullPin *)This->ppPins[0];
+    PullPin *pin = impl_PullPin_from_IPin(This->ppPins[0]);
 
     TRACE("()\n");
 
@@ -293,7 +293,7 @@
 {
     HRESULT hr = S_OK;
     ParserImpl *This = (ParserImpl *)iface;
-    PullPin *pin = (PullPin *)This->ppPins[0];
+    PullPin *pin = impl_PullPin_from_IPin(This->ppPins[0]);
 
     ULONG i;
 
@@ -340,7 +340,7 @@
 HRESULT WINAPI Parser_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
 {
     ParserImpl *This = (ParserImpl *)iface;
-    PullPin *pin = (PullPin *)This->ppPins[0];
+    PullPin *pin = impl_PullPin_from_IPin(This->ppPins[0]);
     HRESULT hr = S_OK;
 
     TRACE("(%d, %p)\n", dwMilliSecsTimeout, pState);
@@ -362,7 +362,7 @@
 HRESULT WINAPI Parser_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
 {
     ParserImpl *This = (ParserImpl *)iface;
-    PullPin *pin = (PullPin *)This->ppPins[0];
+    PullPin *pin = impl_PullPin_from_IPin(This->ppPins[0]);
 
     TRACE("(%p)\n", pClock);
 
@@ -704,7 +704,7 @@
 
 static HRESULT WINAPI Parser_PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
 {
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
 
     TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
 
@@ -730,7 +730,7 @@
 static HRESULT WINAPI Parser_PullPin_Disconnect(IPin * iface)
 {
     HRESULT hr;
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
 
     TRACE("()\n");
 
diff --git a/dlls/quartz/pin.c b/dlls/quartz/pin.c
index 82851a3..5067c17 100644
--- a/dlls/quartz/pin.c
+++ b/dlls/quartz/pin.c
@@ -254,7 +254,7 @@
 {
     PIN_DIRECTION pindirReceive;
     HRESULT hr = S_OK;
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
 
     TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt);
     dump_AM_MEDIA_TYPE(pmt);
@@ -344,7 +344,7 @@
 
 HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
 {
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
 
     TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
 
@@ -373,7 +373,7 @@
 
 ULONG WINAPI PullPin_Release(IPin *iface)
 {
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
     ULONG refCount = InterlockedDecrement(&This->pin.refCount);
 
     TRACE("(%p)->() Release from %d\n", This, refCount + 1);
@@ -449,7 +449,7 @@
 
     if (This->rtCurrent >= This->rtStop)
     {
-        IPin_EndOfStream((IPin *)This);
+        IPin_EndOfStream(&This->pin.IPin_iface);
         return;
     }
 
@@ -717,7 +717,7 @@
 
 HRESULT WINAPI PullPin_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt)
 {
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
 
     TRACE("(%p/%p)->(%p)\n", This, iface, pmt);
 
@@ -726,7 +726,7 @@
 
 HRESULT WINAPI PullPin_EndOfStream(IPin * iface)
 {
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
     HRESULT hr = S_FALSE;
 
     TRACE("(%p)->()\n", iface);
@@ -741,7 +741,7 @@
 
 HRESULT WINAPI PullPin_BeginFlush(IPin * iface)
 {
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
     TRACE("(%p)->()\n", This);
 
     EnterCriticalSection(This->pin.pCritSec);
@@ -775,7 +775,7 @@
 
 HRESULT WINAPI PullPin_EndFlush(IPin * iface)
 {
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
 
     TRACE("(%p)->()\n", iface);
 
@@ -806,7 +806,7 @@
 HRESULT WINAPI PullPin_Disconnect(IPin *iface)
 {
     HRESULT hr;
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
 
     TRACE("()\n");
 
diff --git a/dlls/quartz/pin.h b/dlls/quartz/pin.h
index de2ccd6..428fa6f 100644
--- a/dlls/quartz/pin.h
+++ b/dlls/quartz/pin.h
@@ -122,3 +122,9 @@
 HRESULT PullPin_StartProcessing(PullPin * This);
 HRESULT PullPin_PauseProcessing(PullPin * This);
 HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds);
+
+/* COM helpers */
+static inline PullPin *impl_PullPin_from_IPin( IPin *iface )
+{
+    return CONTAINING_RECORD(iface, PullPin, pin.IPin_iface);
+}
diff --git a/dlls/quartz/waveparser.c b/dlls/quartz/waveparser.c
index bc0615e..a7bce6f 100644
--- a/dlls/quartz/waveparser.c
+++ b/dlls/quartz/waveparser.c
@@ -215,7 +215,7 @@
     TRACE("Moving sound to %08u bytes!\n", (DWORD)BYTES_FROM_MEDIATIME(bytepos));
 
     EnterCriticalSection(&pPin->thread_lock);
-    IPin_BeginFlush((IPin *)pPin);
+    IPin_BeginFlush(&pPin->pin.IPin_iface);
 
     /* Make sure this is done while stopped, BeginFlush takes care of this */
     EnterCriticalSection(&This->Parser.filter.csFilter);
@@ -231,7 +231,7 @@
     LeaveCriticalSection(&This->Parser.filter.csFilter);
 
     TRACE("Done flushing\n");
-    IPin_EndFlush((IPin *)pPin);
+    IPin_EndFlush(&pPin->pin.IPin_iface);
     LeaveCriticalSection(&pPin->thread_lock);
 
     return S_OK;
@@ -239,7 +239,7 @@
 
 static HRESULT WAVEParser_InputPin_PreConnect(IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *props)
 {
-    PullPin *This = (PullPin *)iface;
+    PullPin *This = impl_PullPin_from_IPin(iface);
     HRESULT hr;
     RIFFLIST list;
     RIFFCHUNK chunk;