/*
 * File Source Filter
 *
 * Copyright 2003 Robert Shearman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "quartz_private.h"

#include "wine/debug.h"
#include "wine/unicode.h"
#include "pin.h"
#include "uuids.h"
#include "vfwmsgs.h"
#include "winbase.h"
#include "winreg.h"
#include "ntstatus.h"
#include <assert.h>

WINE_DEFAULT_DEBUG_CHANNEL(quartz);

static const WCHAR wszOutputPinName[] = { 'O','u','t','p','u','t',0 };

typedef struct AsyncReader
{
    const struct IBaseFilterVtbl * lpVtbl;
    const struct IFileSourceFilterVtbl * lpVtblFSF;

    ULONG refCount;
    FILTER_INFO filterInfo;
    FILTER_STATE state;
    CRITICAL_SECTION csFilter;

    IPin * pOutputPin;
    LPOLESTR pszFileName;
    AM_MEDIA_TYPE * pmt;
} AsyncReader;

static const struct IBaseFilterVtbl AsyncReader_Vtbl;
static const struct IFileSourceFilterVtbl FileSource_Vtbl;
static const struct IAsyncReaderVtbl FileAsyncReader_Vtbl;

static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);

#define _IFileSourceFilter_Offset ((int)(&(((AsyncReader*)0)->lpVtblFSF)))
#define ICOM_THIS_From_IFileSourceFilter(impl, iface) impl* This = (impl*)(((char*)iface)-_IFileSourceFilter_Offset);

#define _IAsyncReader_Offset ((int)(&(((FileAsyncReader*)0)->lpVtblAR)))
#define ICOM_THIS_From_IAsyncReader(impl, iface) impl* This = (impl*)(((char*)iface)-_IAsyncReader_Offset);

static HRESULT process_extensions(HKEY hkeyExtensions, LPCOLESTR pszFileName, GUID * majorType, GUID * minorType)
{
    /* FIXME: implement */
    return E_NOTIMPL;
}

static unsigned char byte_from_hex_char(WCHAR wHex)
{
    switch (tolowerW(wHex))
    {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
        return wHex - '0';
    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'e':
    case 'f':
        return wHex - 'a' + 10;
    default:
        return 0;
    }
}

static HRESULT process_pattern_string(LPCWSTR wszPatternString, IAsyncReader * pReader)
{
    ULONG ulOffset;
    ULONG ulBytes;
    BYTE * pbMask;
    BYTE * pbValue;
    BYTE * pbFile;
    HRESULT hr = S_OK;
    ULONG strpos;

    TRACE("\t\tPattern string: %s\n", debugstr_w(wszPatternString));
    
    /* format: "offset, bytestocompare, mask, value" */

    ulOffset = strtolW(wszPatternString, NULL, 10);

    if (!(wszPatternString = strchrW(wszPatternString, ',')))
        return E_INVALIDARG;

    wszPatternString++; /* skip ',' */

    ulBytes = strtolW(wszPatternString, NULL, 10);

    pbMask = HeapAlloc(GetProcessHeap(), 0, ulBytes);
    pbValue = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulBytes);
    pbFile = HeapAlloc(GetProcessHeap(), 0, ulBytes);

    /* default mask is match everything */
    memset(pbMask, 0xFF, ulBytes);

    if (!(wszPatternString = strchrW(wszPatternString, ',')))
        hr = E_INVALIDARG;

    wszPatternString++; /* skip ',' */

    if (hr == S_OK)
    {
        for ( ; !isxdigitW(*wszPatternString) && (*wszPatternString != ','); wszPatternString++)
            ;

        for (strpos = 0; isxdigitW(*wszPatternString) && (strpos/2 < ulBytes); wszPatternString++, strpos++)
        {
            if ((strpos % 2) == 1) /* odd numbered position */
                pbMask[strpos / 2] |= byte_from_hex_char(*wszPatternString);
            else
                pbMask[strpos / 2] = byte_from_hex_char(*wszPatternString) << 4;
        }

        if (!(wszPatternString = strchrW(wszPatternString, ',')))
            hr = E_INVALIDARG;
    
        wszPatternString++; /* skip ',' */
    }

    if (hr == S_OK)
    {
        for ( ; !isxdigitW(*wszPatternString) && (*wszPatternString != ','); wszPatternString++)
            ;

        for (strpos = 0; isxdigitW(*wszPatternString) && (strpos/2 < ulBytes); wszPatternString++, strpos++)
        {
            if ((strpos % 2) == 1) /* odd numbered position */
                pbValue[strpos / 2] |= byte_from_hex_char(*wszPatternString);
            else
                pbValue[strpos / 2] = byte_from_hex_char(*wszPatternString) << 4;
        }
    }

    if (hr == S_OK)
        hr = IAsyncReader_SyncRead(pReader, ulOffset, ulBytes, pbFile);

    if (hr == S_OK)
    {
        ULONG i;
        for (i = 0; i < ulBytes; i++)
            if ((pbFile[i] & pbMask[i]) != pbValue[i])
            {
                hr = S_FALSE;
                break;
            }
    }

    HeapFree(GetProcessHeap(), 0, pbMask);
    HeapFree(GetProcessHeap(), 0, pbValue);
    HeapFree(GetProcessHeap(), 0, pbFile);

    /* if we encountered no errors with this string, and there is a following tuple, then we
     * have to match that as well to succeed */
    if ((hr == S_OK) && (wszPatternString = strchrW(wszPatternString, ',')))
        return process_pattern_string(wszPatternString + 1, pReader);
    else
        return hr;
}

static HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, GUID * majorType, GUID * minorType)
{
    HKEY hkeyMediaType = NULL;
    HRESULT hr = S_OK;
    BOOL bFound = FALSE;
    static const WCHAR wszMediaType[] = {'M','e','d','i','a',' ','T','y','p','e',0};

    CopyMemory(majorType, &GUID_NULL, sizeof(*majorType));
    CopyMemory(minorType, &GUID_NULL, sizeof(*minorType));

    hr = HRESULT_FROM_WIN32(RegOpenKeyExW(HKEY_CLASSES_ROOT, wszMediaType, 0, KEY_READ, &hkeyMediaType));

    if (SUCCEEDED(hr))
    {
        DWORD indexMajor;

        for (indexMajor = 0; !bFound; indexMajor++)
        {
            HKEY hkeyMajor;
            WCHAR wszMajorKeyName[CHARS_IN_GUID];
            DWORD dwKeyNameLength = sizeof(wszMajorKeyName) / sizeof(wszMajorKeyName[0]);
            static const WCHAR wszExtensions[] = {'E','x','t','e','n','s','i','o','n','s',0};
    
            if (RegEnumKeyExW(hkeyMediaType, indexMajor, wszMajorKeyName, &dwKeyNameLength, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
                break;
            if (RegOpenKeyExW(hkeyMediaType, wszMajorKeyName, 0, KEY_READ, &hkeyMajor) != ERROR_SUCCESS)
                break;
            TRACE("%s\n", debugstr_w(wszMajorKeyName));
            if (!strcmpW(wszExtensions, wszMajorKeyName))
            {
                if (process_extensions(hkeyMajor, pszFileName, majorType, minorType) == S_OK)
                    bFound = TRUE;
            }
            else
            {
                DWORD indexMinor;

                for (indexMinor = 0; !bFound; indexMinor++)
                {
                    HKEY hkeyMinor;
                    WCHAR wszMinorKeyName[CHARS_IN_GUID];
                    DWORD dwMinorKeyNameLen = sizeof(wszMinorKeyName) / sizeof(wszMinorKeyName[0]);
                    DWORD maxValueLen;
                    DWORD indexValue;

                    if (RegEnumKeyExW(hkeyMajor, indexMinor, wszMinorKeyName, &dwMinorKeyNameLen, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
                        break;

                    if (RegOpenKeyExW(hkeyMajor, wszMinorKeyName, 0, KEY_READ, &hkeyMinor) != ERROR_SUCCESS)
                        break;

                    TRACE("\t%s\n", debugstr_w(wszMinorKeyName));
        
                    if (RegQueryInfoKeyW(hkeyMinor, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &maxValueLen, NULL, NULL) != ERROR_SUCCESS)
                        break;

                    for (indexValue = 0; !bFound; indexValue++)
                    {
                        DWORD dwType;
                        WCHAR wszValueName[14]; /* longest name we should encounter will be "Source Filter" */
                        LPWSTR wszPatternString = HeapAlloc(GetProcessHeap(), 0, maxValueLen);
                        DWORD dwValueNameLen = sizeof(wszValueName) / sizeof(wszValueName[0]); /* remember this is in chars */
                        DWORD dwDataLen = maxValueLen; /* remember this is in bytes */
                        static const WCHAR wszSourceFilter[] = {'S','o','u','r','c','e',' ','F','i','l','t','e','r',0};
                        LONG temp;

                        if ((temp = RegEnumValueW(hkeyMinor, indexValue, wszValueName, &dwValueNameLen, NULL, &dwType, (LPBYTE)wszPatternString, &dwDataLen)) != ERROR_SUCCESS)
                        {
                            HeapFree(GetProcessHeap(), 0, wszPatternString);
                            break;
                        }

                        /* if it is not the source filter value */
                        if (strcmpW(wszValueName, wszSourceFilter))
                        {
                            if (process_pattern_string(wszPatternString, pReader) == S_OK)
                            {
                                if (SUCCEEDED(CLSIDFromString(wszMajorKeyName, majorType)) &&
                                    SUCCEEDED(CLSIDFromString(wszMinorKeyName, minorType)))
                                    bFound = TRUE;
                            }
                        }
                        HeapFree(GetProcessHeap(), 0, wszPatternString);
                    }
                    CloseHandle(hkeyMinor);
                }
            }
            CloseHandle(hkeyMajor);
        }
    }
    CloseHandle(hkeyMediaType);

    if (SUCCEEDED(hr) && !bFound)
    {
        ERR("Media class not found\n");
        hr = S_FALSE;
    }
    else if (bFound)
        TRACE("Found file's class: major = %s, subtype = %s\n", qzdebugstr_guid(majorType), qzdebugstr_guid(minorType));

    return hr;
}

HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv)
{
    AsyncReader * pAsyncRead = CoTaskMemAlloc(sizeof(AsyncReader));

    if (!pAsyncRead)
        return E_OUTOFMEMORY;

    pAsyncRead->lpVtbl = &AsyncReader_Vtbl;
    pAsyncRead->lpVtblFSF = &FileSource_Vtbl;
    pAsyncRead->refCount = 1;
    pAsyncRead->filterInfo.achName[0] = '\0';
    pAsyncRead->filterInfo.pGraph = NULL;
    pAsyncRead->pOutputPin = NULL;

    InitializeCriticalSection(&pAsyncRead->csFilter);

    pAsyncRead->pszFileName = NULL;
    pAsyncRead->pmt = NULL;

    *ppv = (LPVOID)pAsyncRead;

    TRACE("-- created at %p\n", pAsyncRead);

    return S_OK;
}

/** IUnkown methods **/

static HRESULT WINAPI AsyncReader_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
{
    AsyncReader *This = (AsyncReader *)iface;

    TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);

    *ppv = NULL;

    if (IsEqualIID(riid, &IID_IUnknown))
        *ppv = (LPVOID)This;
    else if (IsEqualIID(riid, &IID_IPersist))
        *ppv = (LPVOID)This;
    else if (IsEqualIID(riid, &IID_IMediaFilter))
        *ppv = (LPVOID)This;
    else if (IsEqualIID(riid, &IID_IBaseFilter))
        *ppv = (LPVOID)This;
    else if (IsEqualIID(riid, &IID_IFileSourceFilter))
        *ppv = (LPVOID)(&This->lpVtblFSF);

    if (*ppv)
    {
        IUnknown_AddRef((IUnknown *)(*ppv));
        return S_OK;
    }

    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));

    return E_NOINTERFACE;
}

static ULONG WINAPI AsyncReader_AddRef(IBaseFilter * iface)
{
    AsyncReader *This = (AsyncReader *)iface;
    
    TRACE("()\n");
    
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI AsyncReader_Release(IBaseFilter * iface)
{
    AsyncReader *This = (AsyncReader *)iface;
    
    TRACE("()\n");
    
    if (!InterlockedDecrement(&This->refCount))
    {
        if (This->pOutputPin)
            IPin_Release(This->pOutputPin);
        DeleteCriticalSection(&This->csFilter);
        This->lpVtbl = NULL;
        CoTaskMemFree(This);
        return 0;
    }
    else
        return This->refCount;
}

/** IPersist methods **/

static HRESULT WINAPI AsyncReader_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
    TRACE("(%p)\n", pClsid);

    *pClsid = CLSID_AsyncReader;

    return S_OK;
}

/** IMediaFilter methods **/

static HRESULT WINAPI AsyncReader_Stop(IBaseFilter * iface)
{
    AsyncReader *This = (AsyncReader *)iface;

    TRACE("()\n");

    This->state = State_Stopped;
    
    return S_OK;
}

static HRESULT WINAPI AsyncReader_Pause(IBaseFilter * iface)
{
    AsyncReader *This = (AsyncReader *)iface;

    TRACE("()\n");

    This->state = State_Paused;

    return S_OK;
}

static HRESULT WINAPI AsyncReader_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
{
    AsyncReader *This = (AsyncReader *)iface;

    TRACE("(%lx%08lx)\n", (ULONG)(tStart >> 32), (ULONG)tStart);

    This->state = State_Running;

    return S_OK;
}

static HRESULT WINAPI AsyncReader_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
{
    AsyncReader *This = (AsyncReader *)iface;

    TRACE("(%lu, %p)\n", dwMilliSecsTimeout, pState);

    *pState = This->state;
    
    return S_OK;
}

static HRESULT WINAPI AsyncReader_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
/*    AsyncReader *This = (AsyncReader *)iface;*/

    TRACE("(%p)\n", pClock);

    return S_OK;
}

static HRESULT WINAPI AsyncReader_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
/*    AsyncReader *This = (AsyncReader *)iface;*/

    TRACE("(%p)\n", ppClock);

    return S_OK;
}

/** IBaseFilter methods **/

static HRESULT WINAPI AsyncReader_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
{
    ENUMPINDETAILS epd;
    AsyncReader *This = (AsyncReader *)iface;

    TRACE("(%p)\n", ppEnum);

    epd.cPins = This->pOutputPin ? 1 : 0;
    epd.ppPins = &This->pOutputPin;
    return IEnumPinsImpl_Construct(&epd, ppEnum);
}

static HRESULT WINAPI AsyncReader_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
{
    FIXME("(%s, %p)\n", debugstr_w(Id), ppPin);

    return E_NOTIMPL;
}

static HRESULT WINAPI AsyncReader_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
    AsyncReader *This = (AsyncReader *)iface;

    TRACE("(%p)\n", pInfo);

    strcpyW(pInfo->achName, This->filterInfo.achName);
    pInfo->pGraph = This->filterInfo.pGraph;

    if (pInfo->pGraph)
        IFilterGraph_AddRef(pInfo->pGraph);
    
    return S_OK;
}

static HRESULT WINAPI AsyncReader_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
{
    AsyncReader *This = (AsyncReader *)iface;

    TRACE("(%p, %s)\n", pGraph, debugstr_w(pName));

    if (pName)
        strcpyW(This->filterInfo.achName, pName);
    else
        *This->filterInfo.achName = 0;
    This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */

    return S_OK;
}

static HRESULT WINAPI AsyncReader_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
    FIXME("(%p)\n", pVendorInfo);

    return E_NOTIMPL;
}

static const IBaseFilterVtbl AsyncReader_Vtbl =
{
    AsyncReader_QueryInterface,
    AsyncReader_AddRef,
    AsyncReader_Release,
    AsyncReader_GetClassID,
    AsyncReader_Stop,
    AsyncReader_Pause,
    AsyncReader_Run,
    AsyncReader_GetState,
    AsyncReader_SetSyncSource,
    AsyncReader_GetSyncSource,
    AsyncReader_EnumPins,
    AsyncReader_FindPin,
    AsyncReader_QueryFilterInfo,
    AsyncReader_JoinFilterGraph,
    AsyncReader_QueryVendorInfo
};

static HRESULT WINAPI FileSource_QueryInterface(IFileSourceFilter * iface, REFIID riid, LPVOID * ppv)
{
    ICOM_THIS_From_IFileSourceFilter(AsyncReader, iface);

    return IBaseFilter_QueryInterface((IFileSourceFilter*)&This->lpVtbl, riid, ppv);
}

static ULONG WINAPI FileSource_AddRef(IFileSourceFilter * iface)
{
    ICOM_THIS_From_IFileSourceFilter(AsyncReader, iface);

    return IBaseFilter_AddRef((IFileSourceFilter*)&This->lpVtbl);
}

static ULONG WINAPI FileSource_Release(IFileSourceFilter * iface)
{
    ICOM_THIS_From_IFileSourceFilter(AsyncReader, iface);

    return IBaseFilter_Release((IFileSourceFilter*)&This->lpVtbl);
}

static HRESULT WINAPI FileSource_Load(IFileSourceFilter * iface, LPCOLESTR pszFileName, const AM_MEDIA_TYPE * pmt)
{
    HRESULT hr;
    HANDLE hFile;
    IAsyncReader * pReader = NULL;
    ICOM_THIS_From_IFileSourceFilter(AsyncReader, iface);

    TRACE("(%s, %p)\n", debugstr_w(pszFileName), pmt);

    /* open file */
    /* FIXME: check the sharing values that native uses */
    hFile = CreateFileW(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

    if (hFile == INVALID_HANDLE_VALUE)
    {
        return HRESULT_FROM_WIN32(GetLastError());
    }

    /* create pin */
    hr = FileAsyncReader_Construct(hFile, (IBaseFilter *)&This->lpVtbl, &This->csFilter, &This->pOutputPin);

    if (SUCCEEDED(hr))
        hr = IPin_QueryInterface(This->pOutputPin, &IID_IAsyncReader, (LPVOID *)&pReader);

    /* store file name & media type */
    if (SUCCEEDED(hr))
    {
        This->pszFileName = CoTaskMemAlloc((strlenW(pszFileName) + 1) * sizeof(WCHAR));
        strcpyW(This->pszFileName, pszFileName);
        This->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
        if (!pmt)
        {
            This->pmt->bFixedSizeSamples = TRUE;
            This->pmt->bTemporalCompression = FALSE;
            This->pmt->cbFormat = 0;
            This->pmt->pbFormat = NULL;
            This->pmt->pUnk = NULL;
            This->pmt->lSampleSize = 0;
            memcpy(&This->pmt->formattype, &FORMAT_None, sizeof(FORMAT_None));
            hr = GetClassMediaFile(pReader, pszFileName, &This->pmt->majortype, &This->pmt->subtype);
            if (FAILED(hr))
            {
                CoTaskMemFree(This->pmt);
                This->pmt = NULL;
            }
        }
        else
            CopyMediaType(This->pmt, pmt);
    }

    if (pReader)
        IAsyncReader_Release(pReader);

    if (FAILED(hr))
    {
        if (This->pOutputPin)
        {
            IPin_Release(This->pOutputPin);
            This->pOutputPin = NULL;
        }
        if (This->pszFileName)
        {
            CoTaskMemFree(This->pszFileName);
            This->pszFileName = NULL;
        }
        CloseHandle(hFile);
    }

    /* FIXME: check return codes */
    return hr;
}

static HRESULT WINAPI FileSource_GetCurFile(IFileSourceFilter * iface, LPOLESTR * ppszFileName, AM_MEDIA_TYPE * pmt)
{
    ICOM_THIS_From_IFileSourceFilter(AsyncReader, iface);
    
    TRACE("(%p, %p)\n", ppszFileName, pmt);

    /* copy file name & media type if available, otherwise clear the outputs */
    if (This->pszFileName)
    {
        *ppszFileName = CoTaskMemAlloc((strlenW(This->pszFileName) + 1) * sizeof(WCHAR));
        strcpyW(*ppszFileName, This->pszFileName);
    }
    else
        *ppszFileName = NULL;

    if (This->pmt)
    {
        CopyMediaType(pmt, This->pmt);
    }
    else
        ZeroMemory(pmt, sizeof(*pmt));

    return S_OK;
}

static const IFileSourceFilterVtbl FileSource_Vtbl = 
{
    FileSource_QueryInterface,
    FileSource_AddRef,
    FileSource_Release,
    FileSource_Load,
    FileSource_GetCurFile
};


/* the dwUserData passed back to user */
typedef struct DATAREQUEST
{
    IMediaSample * pSample; /* sample passed to us by user */
    DWORD_PTR dwUserData; /* user data passed to us */
    OVERLAPPED ovl; /* our overlapped structure */

    struct DATAREQUEST * pNext; /* next data request in list */
} DATAREQUEST;

void queue(DATAREQUEST * pHead, DATAREQUEST * pItem)
{
    DATAREQUEST * pCurrent;
    for (pCurrent = pHead; pCurrent->pNext; pCurrent = pCurrent->pNext)
        ;
    pCurrent->pNext = pItem;
}

typedef struct FileAsyncReader
{
    OutputPin pin;
    const struct IAsyncReaderVtbl * lpVtblAR;

    HANDLE hFile;
    HANDLE hEvent;
    BOOL bFlushing;
    DATAREQUEST * pHead; /* head of data request list */
    CRITICAL_SECTION csList; /* critical section to protect operations on list */
} FileAsyncReader;

static HRESULT AcceptProcAFR(LPVOID iface, const AM_MEDIA_TYPE *pmt)
{
    AsyncReader *This = (AsyncReader *)iface;
    
    FIXME("(%p, %p)\n", iface, pmt);

    if (IsEqualGUID(&pmt->majortype, &This->pmt->majortype) &&
        IsEqualGUID(&pmt->subtype, &This->pmt->subtype) &&
        IsEqualGUID(&pmt->formattype, &FORMAT_None))
        return S_OK;
    
    return S_FALSE;
}

/* overriden pin functions */

static HRESULT WINAPI FileAsyncReaderPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
{
    FileAsyncReader *This = (FileAsyncReader *)iface;
    TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);

    *ppv = NULL;

    if (IsEqualIID(riid, &IID_IUnknown))
        *ppv = (LPVOID)This;
    else if (IsEqualIID(riid, &IID_IPin))
        *ppv = (LPVOID)This;
    else if (IsEqualIID(riid, &IID_IAsyncReader))
        *ppv = (LPVOID)&This->lpVtblAR;

    if (*ppv)
    {
        IUnknown_AddRef((IUnknown *)(*ppv));
        return S_OK;
    }

    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));

    return E_NOINTERFACE;
}

static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface)
{
    FileAsyncReader *This = (FileAsyncReader *)iface;
    
    TRACE("()\n");
    
    if (!InterlockedDecrement(&This->pin.pin.refCount))
    {
        DATAREQUEST * pCurrent;
        DATAREQUEST * pNext;
        for (pCurrent = This->pHead; pCurrent; pCurrent = pNext)
        {
            pNext = pCurrent->pNext;
            CoTaskMemFree(pCurrent);
        }
        CloseHandle(This->hFile);
        CloseHandle(This->hEvent);
        CoTaskMemFree(This);
        return 0;
    }
    return This->pin.pin.refCount;
}

static HRESULT WINAPI FileAsyncReaderPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
{
    ENUMMEDIADETAILS emd;
    FileAsyncReader *This = (FileAsyncReader *)iface;

    TRACE("(%p)\n", ppEnum);

    emd.cMediaTypes = 1;
    emd.pMediaTypes = ((AsyncReader *)This->pin.pin.pinInfo.pFilter)->pmt;

    return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
}

static const IPinVtbl FileAsyncReaderPin_Vtbl = 
{
    FileAsyncReaderPin_QueryInterface,
    IPinImpl_AddRef,
    FileAsyncReaderPin_Release,
    OutputPin_Connect,
    OutputPin_ReceiveConnection,
    IPinImpl_Disconnect,
    IPinImpl_ConnectedTo,
    IPinImpl_ConnectionMediaType,
    IPinImpl_QueryPinInfo,
    IPinImpl_QueryDirection,
    IPinImpl_QueryId,
    IPinImpl_QueryAccept,
    FileAsyncReaderPin_EnumMediaTypes,
    IPinImpl_QueryInternalConnections,
    OutputPin_EndOfStream,
    OutputPin_BeginFlush,
    OutputPin_EndFlush,
    OutputPin_NewSegment
};

/* Function called as a helper to IPin_Connect */
/* specific AM_MEDIA_TYPE - it cannot be NULL */
/* this differs from standard OutputPin_ConnectSpecific only in that it
 * doesn't need the IMemInputPin interface on the receiving pin */
static HRESULT FileAsyncReaderPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
{
    OutputPin *This = (OutputPin *)iface;
    HRESULT hr;

    TRACE("(%p, %p)\n", pReceivePin, pmt);
    dump_AM_MEDIA_TYPE(pmt);

    /* FIXME: call queryacceptproc */

    This->pin.pConnectedTo = pReceivePin;
    IPin_AddRef(pReceivePin);
    CopyMediaType(&This->pin.mtCurrent, pmt);

    hr = IPin_ReceiveConnection(pReceivePin, iface, pmt);

    if (FAILED(hr))
    {
        IPin_Release(This->pin.pConnectedTo);
        This->pin.pConnectedTo = NULL;
        DeleteMediaType(&This->pin.mtCurrent);
    }

    TRACE(" -- %lx\n", hr);
    return hr;
}

static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
    FileAsyncReader * pPinImpl;
    PIN_INFO piOutput;

    *ppPin = NULL;

    pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));

    if (!pPinImpl)
        return E_OUTOFMEMORY;

    piOutput.dir = PINDIR_OUTPUT;
    piOutput.pFilter = pBaseFilter;
    strcpyW(piOutput.achName, wszOutputPinName);

    if (SUCCEEDED(OutputPin_Init(&piOutput, NULL, pBaseFilter, AcceptProcAFR, pCritSec, &pPinImpl->pin)))
    {
        pPinImpl->pin.pin.lpVtbl = &FileAsyncReaderPin_Vtbl;
        pPinImpl->lpVtblAR = &FileAsyncReader_Vtbl;
        pPinImpl->hFile = hFile;
        pPinImpl->hEvent = CreateEventW(NULL, 0, 0, NULL);
        pPinImpl->bFlushing = FALSE;
        pPinImpl->pHead = NULL;
        pPinImpl->pin.pConnectSpecific = FileAsyncReaderPin_ConnectSpecific;
        InitializeCriticalSection(&pPinImpl->csList);

        *ppPin = (IPin *)(&pPinImpl->pin.pin.lpVtbl);
        return S_OK;
    }
    return E_FAIL;
}

/* IAsyncReader */

static HRESULT WINAPI FileAsyncReader_QueryInterface(IAsyncReader * iface, REFIID riid, LPVOID * ppv)
{
    ICOM_THIS_From_IAsyncReader(FileAsyncReader, iface);

    return IPin_QueryInterface((IPin *)This, riid, ppv);
}

static ULONG WINAPI FileAsyncReader_AddRef(IAsyncReader * iface)
{
    ICOM_THIS_From_IAsyncReader(FileAsyncReader, iface);

    return IPin_AddRef((IPin *)This);
}

static ULONG WINAPI FileAsyncReader_Release(IAsyncReader * iface)
{
    ICOM_THIS_From_IAsyncReader(FileAsyncReader, iface);

    return IPin_Release((IPin *)This);
}

#define DEF_ALIGNMENT 1

static HRESULT WINAPI FileAsyncReader_RequestAllocator(IAsyncReader * iface, IMemAllocator * pPreferred, ALLOCATOR_PROPERTIES * pProps, IMemAllocator ** ppActual)
{
    HRESULT hr = S_OK;

    TRACE("(%p, %p, %p)\n", pPreferred, pProps, ppActual);

    if (!pProps->cbAlign || (pProps->cbAlign % DEF_ALIGNMENT) != 0)
        pProps->cbAlign = DEF_ALIGNMENT;

    if (pPreferred)
    {
        ALLOCATOR_PROPERTIES PropsActual;
        hr = IMemAllocator_SetProperties(pPreferred, pProps, &PropsActual);
        /* FIXME: check we are still aligned */
        if (SUCCEEDED(hr))
        {
            IMemAllocator_AddRef(pPreferred);
            *ppActual = pPreferred;
            TRACE("FileAsyncReader_RequestAllocator -- %lx\n", hr);
            return S_OK;
        }
    }

    pPreferred = NULL;

    hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC, &IID_IMemAllocator, (LPVOID *)&pPreferred);

    if (SUCCEEDED(hr))
    {
        ALLOCATOR_PROPERTIES PropsActual;
        hr = IMemAllocator_SetProperties(pPreferred, pProps, &PropsActual);
        /* FIXME: check we are still aligned */
        if (SUCCEEDED(hr))
        {
            IMemAllocator_AddRef(pPreferred);
            *ppActual = pPreferred;
            TRACE("FileAsyncReader_RequestAllocator -- %lx\n", hr);
            return S_OK;
        }
    }

    if (FAILED(hr))
    {
        *ppActual = NULL;
        if (pPreferred)
            IMemAllocator_Release(pPreferred);
    }

    TRACE("-- %lx\n", hr);
    return hr;
}

/* we could improve the Request/WaitForNext mechanism by allowing out of order samples.
 * however, this would be quite complicated to do and may be a bit error prone */
static HRESULT WINAPI FileAsyncReader_Request(IAsyncReader * iface, IMediaSample * pSample, DWORD_PTR dwUser)
{
    REFERENCE_TIME Start;
    REFERENCE_TIME Stop;
    DATAREQUEST * pDataRq;
    BYTE * pBuffer;
    HRESULT hr = S_OK;
    ICOM_THIS_From_IAsyncReader(FileAsyncReader, iface);

    TRACE("(%p, %lx)\n", pSample, dwUser);

    /* check flushing state */
    if (This->bFlushing)
        return VFW_E_WRONG_STATE;

    if (!(pDataRq = CoTaskMemAlloc(sizeof(*pDataRq))))
        hr = E_OUTOFMEMORY;

    /* get start and stop positions in bytes */
    if (SUCCEEDED(hr))
        hr = IMediaSample_GetTime(pSample, &Start, &Stop);

    if (SUCCEEDED(hr))
        hr = IMediaSample_GetPointer(pSample, &pBuffer);

    if (SUCCEEDED(hr))
    {
        DWORD dwLength = (DWORD) BYTES_FROM_MEDIATIME(Stop - Start);

        pDataRq->ovl.Offset = (DWORD) BYTES_FROM_MEDIATIME(Start);
        pDataRq->ovl.OffsetHigh = (DWORD)(BYTES_FROM_MEDIATIME(Start) >> (sizeof(DWORD) * 8));
        pDataRq->ovl.hEvent = This->hEvent;
        pDataRq->dwUserData = dwUser;
        pDataRq->pNext = NULL;
        /* we violate traditional COM rules here by maintaining
         * a reference to the sample, but not calling AddRef, but
         * that's what MSDN says to do */
        pDataRq->pSample = pSample;

        EnterCriticalSection(&This->csList);
        {
            if (This->pHead)
                /* adds data request to end of list */
                queue(This->pHead, pDataRq);
            else
                This->pHead = pDataRq;
        }
        LeaveCriticalSection(&This->csList);

        /* this is definitely not how it is implemented on Win9x
         * as they do not support async reads on files, but it is
         * sooo much easier to use this than messing around with threads!
         */
        if (!ReadFile(This->hFile, pBuffer, dwLength, NULL, &pDataRq->ovl))
            hr = HRESULT_FROM_WIN32(GetLastError());

        /* ERROR_IO_PENDING is not actually an error since this is what we want! */
        if (hr == HRESULT_FROM_WIN32(ERROR_IO_PENDING))
            hr = S_OK;
    }

    if (FAILED(hr) && pDataRq)
    {
        EnterCriticalSection(&This->csList);
        {
            DATAREQUEST * pCurrent;
            for (pCurrent = This->pHead; pCurrent && pCurrent->pNext; pCurrent = pCurrent->pNext)
                if (pCurrent->pNext == pDataRq)
                {
                    pCurrent->pNext = pDataRq->pNext;
                    break;
                }
        }
        LeaveCriticalSection(&This->csList);
        CoTaskMemFree(pDataRq);
    }

    TRACE("-- %lx\n", hr);
    return hr;
}

static HRESULT WINAPI FileAsyncReader_WaitForNext(IAsyncReader * iface, DWORD dwTimeout, IMediaSample ** ppSample, DWORD_PTR * pdwUser)
{
    HRESULT hr = S_OK;
    DATAREQUEST * pDataRq = NULL;
    ICOM_THIS_From_IAsyncReader(FileAsyncReader, iface);

    TRACE("(%lu, %p, %p)\n", dwTimeout, ppSample, pdwUser);

    /* FIXME: we could do with improving this by waiting for an array of event handles
     * and then determining which one finished and removing that from the list, otherwise
     * we will end up waiting for longer than we should do, if a later request finishes
     * before an earlier one */

    *ppSample = NULL;
    *pdwUser = 0;

    /* we return immediately if flushing */
    if (This->bFlushing)
        hr = VFW_E_WRONG_STATE;

    if (SUCCEEDED(hr))
    {
        /* wait for the read to finish or timeout */
        if (WaitForSingleObject(This->hEvent, dwTimeout) == WAIT_TIMEOUT)
            hr = VFW_E_TIMEOUT;
    }
    if (SUCCEEDED(hr))
    {
        EnterCriticalSection(&This->csList);
        {
            pDataRq = This->pHead;
            if (pDataRq == NULL)
                hr = E_FAIL;
            else
                This->pHead = pDataRq->pNext;
        }
        LeaveCriticalSection(&This->csList);
    }

    if (SUCCEEDED(hr))
    {
        DWORD dwBytes;
        /* get any errors */
        if (!GetOverlappedResult(This->hFile, &pDataRq->ovl, &dwBytes, FALSE))
            hr = HRESULT_FROM_WIN32(GetLastError());
    }

    if (SUCCEEDED(hr))
    {
        *ppSample = pDataRq->pSample;
        *pdwUser = pDataRq->dwUserData;
    }

    /* clean up */
    if (pDataRq)
    {
        /* no need to close event handle since we will close it when the pin is destroyed */
        CoTaskMemFree(pDataRq);
    }
    
    TRACE("-- %lx\n", hr);
    return hr;
}

static HRESULT WINAPI FileAsyncReader_SyncRead(IAsyncReader * iface, LONGLONG llPosition, LONG lLength, BYTE * pBuffer);

static HRESULT WINAPI FileAsyncReader_SyncReadAligned(IAsyncReader * iface, IMediaSample * pSample)
{
    BYTE * pBuffer;
    REFERENCE_TIME tStart;
    REFERENCE_TIME tStop;
    HRESULT hr;

    TRACE("(%p)\n", pSample);

    hr = IMediaSample_GetTime(pSample, &tStart, &tStop);

    if (SUCCEEDED(hr))
        hr = IMediaSample_GetPointer(pSample, &pBuffer);

    if (SUCCEEDED(hr))
        hr = FileAsyncReader_SyncRead(iface, 
            BYTES_FROM_MEDIATIME(tStart),
            (LONG) BYTES_FROM_MEDIATIME(tStop - tStart),
            pBuffer);

    TRACE("-- %lx\n", hr);
    return hr;
}

static HRESULT WINAPI FileAsyncReader_SyncRead(IAsyncReader * iface, LONGLONG llPosition, LONG lLength, BYTE * pBuffer)
{
    OVERLAPPED ovl;
    HRESULT hr = S_OK;
    ICOM_THIS_From_IAsyncReader(FileAsyncReader, iface);

    TRACE("(%lx%08lx, %ld, %p)\n", (ULONG)(llPosition >> 32), (ULONG)llPosition, lLength, pBuffer);

    ZeroMemory(&ovl, sizeof(ovl));

    ovl.hEvent = CreateEventW(NULL, 0, 0, NULL);
    /* NOTE: llPosition is the actual byte position to start reading from */
    ovl.Offset = (DWORD) llPosition;
    ovl.OffsetHigh = (DWORD) (llPosition >> (sizeof(DWORD) * 8));

    if (!ReadFile(This->hFile, pBuffer, lLength, NULL, &ovl))
        hr = HRESULT_FROM_WIN32(GetLastError());

    if (hr == HRESULT_FROM_WIN32(ERROR_IO_PENDING))
        hr = S_OK;

    if (SUCCEEDED(hr))
    {
        DWORD dwBytesRead;

        if (!GetOverlappedResult(This->hFile, &ovl, &dwBytesRead, TRUE))
            hr = HRESULT_FROM_WIN32(GetLastError());
    }

    CloseHandle(ovl.hEvent);

    TRACE("-- %lx\n", hr);
    return hr;
}

static HRESULT WINAPI FileAsyncReader_Length(IAsyncReader * iface, LONGLONG * pTotal, LONGLONG * pAvailable)
{
    DWORD dwSizeLow;
    DWORD dwSizeHigh;
    ICOM_THIS_From_IAsyncReader(FileAsyncReader, iface);

    TRACE("(%p, %p)\n", pTotal, pAvailable);

    if (((dwSizeLow = GetFileSize(This->hFile, &dwSizeHigh)) == -1) &&
        (GetLastError() != NO_ERROR))
        return HRESULT_FROM_WIN32(GetLastError());

    *pTotal = (LONGLONG)dwSizeLow | (LONGLONG)dwSizeHigh << (sizeof(DWORD) * 8);

    *pAvailable = *pTotal;

    return S_OK;
}

static HRESULT WINAPI FileAsyncReader_BeginFlush(IAsyncReader * iface)
{
    ICOM_THIS_From_IAsyncReader(FileAsyncReader, iface);

    TRACE("()\n");

    This->bFlushing = TRUE;
    CancelIo(This->hFile);
    SetEvent(This->hEvent);
    
    /* FIXME: free list */

    return S_OK;
}

static HRESULT WINAPI FileAsyncReader_EndFlush(IAsyncReader * iface)
{
    ICOM_THIS_From_IAsyncReader(FileAsyncReader, iface);

    TRACE("()\n");

    This->bFlushing = FALSE;

    return S_OK;
}

static const IAsyncReaderVtbl FileAsyncReader_Vtbl = 
{
    FileAsyncReader_QueryInterface,
    FileAsyncReader_AddRef,
    FileAsyncReader_Release,
    FileAsyncReader_RequestAllocator,
    FileAsyncReader_Request,
    FileAsyncReader_WaitForNext,
    FileAsyncReader_SyncReadAligned,
    FileAsyncReader_SyncRead,
    FileAsyncReader_Length,
    FileAsyncReader_BeginFlush,
    FileAsyncReader_EndFlush,
};
