diff --git a/reactos/dll/directx/ksproxy/clockforward.cpp b/reactos/dll/directx/ksproxy/clockforward.cpp index cba65b3cdf0..80bf00fe421 100644 --- a/reactos/dll/directx/ksproxy/clockforward.cpp +++ b/reactos/dll/directx/ksproxy/clockforward.cpp @@ -8,7 +8,9 @@ */ #include "precomp.h" +#ifndef _MSC_VER const GUID KSCATEGORY_CLOCK = {0x53172480, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +#endif class CKsClockForwarder : public IDistributorNotify, public IKsObject diff --git a/reactos/dll/directx/ksproxy/datatype.cpp b/reactos/dll/directx/ksproxy/datatype.cpp index 3d2d925f19c..3d132890dfd 100644 --- a/reactos/dll/directx/ksproxy/datatype.cpp +++ b/reactos/dll/directx/ksproxy/datatype.cpp @@ -9,7 +9,9 @@ #include "precomp.h" /* FIXME guid mess */ +#ifndef _MSC_VER const GUID IID_IUnknown = {0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; +#endif const GUID IID_IClassFactory = {0x00000001, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; class CKsDataTypeHandler : public IKsDataTypeHandler diff --git a/reactos/dll/directx/ksproxy/enum_mediatypes.cpp b/reactos/dll/directx/ksproxy/enum_mediatypes.cpp index 9895c2290cc..462ffda24fc 100644 --- a/reactos/dll/directx/ksproxy/enum_mediatypes.cpp +++ b/reactos/dll/directx/ksproxy/enum_mediatypes.cpp @@ -103,7 +103,31 @@ CEnumMediaTypes::Next( if (!MediaType) break; - CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE)); + if (m_MediaTypes[m_Index + i].cbFormat) + { + LPBYTE pFormat = (LPBYTE)CoTaskMemAlloc(m_MediaTypes[m_Index + i].cbFormat); + if (!pFormat) + { + CoTaskMemFree(MediaType); + break; + } + + CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE)); + MediaType->pbFormat = pFormat; + CopyMemory(MediaType->pbFormat, m_MediaTypes[m_Index + i].pbFormat, m_MediaTypes[m_Index + i].cbFormat); + MediaType->pUnk = (IUnknown *)this; + MediaType->pUnk->AddRef(); + } + else + { + CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE)); + } + + if (MediaType->pUnk) + { + MediaType->pUnk->AddRef(); + } + ppMediaTypes[i] = MediaType; i++; } @@ -114,7 +138,6 @@ CEnumMediaTypes::Next( } m_Index += i; - if (i < cMediaTypes) return S_FALSE; else diff --git a/reactos/dll/directx/ksproxy/input_pin.cpp b/reactos/dll/directx/ksproxy/input_pin.cpp index 2b08b16e89e..ce2cef4600d 100644 --- a/reactos/dll/directx/ksproxy/input_pin.cpp +++ b/reactos/dll/directx/ksproxy/input_pin.cpp @@ -9,8 +9,12 @@ #include "precomp.h" const GUID IID_IKsPinEx = {0x7bb38260L, 0xd19c, 0x11d2, {0xb3, 0x8a, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e}}; -const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +#ifndef _MSC_VER +const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +#endif + +#ifndef _MSC_VER KSPIN_INTERFACE StandardPinInterface = { {STATIC_KSINTERFACESETID_Standard}, @@ -25,6 +29,23 @@ KSPIN_MEDIUM StandardPinMedium = 0 }; +#else + +KSPIN_INTERFACE StandardPinInterface = +{ + STATIC_KSINTERFACESETID_Standard, + KSINTERFACE_STANDARD_STREAMING, + 0 +}; + +KSPIN_MEDIUM StandardPinMedium = +{ + STATIC_KSMEDIUMSETID_Standard, + KSMEDIUM_TYPE_ANYINSTANCE, + 0 +}; + +#endif class CInputPin : public IPin, public IKsPropertySet, @@ -117,9 +138,9 @@ public: //--------------------------------------------------------------- HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt); - HRESULT STDMETHODCALLTYPE CreatePin(); - HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, PKSDATAFORMAT DataFormat); - CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId, KSPIN_COMMUNICATION Communication) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hFilter(hFilter), m_hPin(0), m_PinId(PinId), m_MemAllocator(0), m_IoCount(0), m_Communication(Communication), m_Pin(0){}; + HRESULT STDMETHODCALLTYPE CreatePin(const AM_MEDIA_TYPE *pmt); + HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, const AM_MEDIA_TYPE *pmt); + CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId, KSPIN_COMMUNICATION Communication) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hFilter(hFilter), m_hPin(0), m_PinId(PinId), m_MemAllocator(0), m_IoCount(0), m_Communication(Communication), m_Pin(0), m_ReadOnly(0){}; virtual ~CInputPin(){}; protected: @@ -135,6 +156,7 @@ protected: KSPIN_INTERFACE m_Interface; KSPIN_MEDIUM m_Medium; IPin * m_Pin; + BOOL m_ReadOnly; }; HRESULT @@ -160,39 +182,18 @@ CInputPin::QueryInterface( } else if (IsEqualGUID(refiid, IID_IKsObject)) { - if (!m_hPin) - { - HRESULT hr = CreatePin(); - if (FAILED(hr)) - return hr; - } - *Output = (IKsObject*)(this); reinterpret_cast(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IKsPropertySet)) { - if (!m_hPin) - { - HRESULT hr = CreatePin(); - if (FAILED(hr)) - return hr; - } - *Output = (IKsPropertySet*)(this); reinterpret_cast(*Output)->AddRef(); return NOERROR; } else if (IsEqualGUID(refiid, IID_IKsControl)) { - if (!m_hPin) - { - HRESULT hr = CreatePin(); - if (FAILED(hr)) - return hr; - } - *Output = (IKsControl*)(this); reinterpret_cast(*Output)->AddRef(); return NOERROR; @@ -200,13 +201,6 @@ CInputPin::QueryInterface( else if (IsEqualGUID(refiid, IID_IKsPin) || IsEqualGUID(refiid, IID_IKsPinEx)) { - if (!m_hPin) - { - HRESULT hr = CreatePin(); - if (FAILED(hr)) - return hr; - } - *Output = (IKsPinEx*)(this); reinterpret_cast(*Output)->AddRef(); return NOERROR; @@ -227,7 +221,7 @@ CInputPin::QueryInterface( // IMemInputPin // - // + HRESULT STDMETHODCALLTYPE CInputPin::GetAllocator(IMemAllocator **ppAllocator) @@ -251,6 +245,7 @@ CInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly) } m_MemAllocator = pAllocator; + m_ReadOnly = bReadOnly; return NOERROR; } @@ -466,7 +461,7 @@ CInputPin::KsNotifyError( //------------------------------------------------------------------- -// IKsPropertySet +// IKsControl // HRESULT STDMETHODCALLTYPE @@ -477,6 +472,7 @@ CInputPin::KsProperty( ULONG DataLength, ULONG* BytesReturned) { + assert(m_hPin != 0); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); } @@ -489,6 +485,7 @@ CInputPin::KsMethod( ULONG DataLength, ULONG* BytesReturned) { + assert(m_hPin != 0); return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned); } @@ -501,6 +498,8 @@ CInputPin::KsEvent( ULONG DataLength, ULONG* BytesReturned) { + assert(m_hPin != 0); + if (EventLength) return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned); else @@ -619,10 +618,7 @@ HANDLE STDMETHODCALLTYPE CInputPin::KsGetObjectHandle() { - OutputDebugStringW(L"CInputPin::KsGetObjectHandle CALLED\n"); - - //FIXME - // return pin handle + assert(m_hPin); return m_hPin; } @@ -645,7 +641,6 @@ CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) if (m_Pin) { - OutputDebugStringW(L"CInputPin::ReceiveConnection already connected\n"); return VFW_E_ALREADY_CONNECTED; } @@ -657,19 +652,36 @@ CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) if (FAILED(CheckFormat(pmt))) return hr; + hr = CreatePin(pmt); + if (FAILED(hr)) + { + return hr; + } + //FIXME create pin m_Pin = pConnector; m_Pin->AddRef(); - OutputDebugStringW(L"CInputPin::ReceiveConnection NotImplemented\n"); return S_OK; } HRESULT STDMETHODCALLTYPE CInputPin::Disconnect( void) { - OutputDebugStringW(L"CInputPin::Disconnect NotImplemented\n"); - return E_NOTIMPL; + if (!m_Pin) + { + // pin was not connected + return S_FALSE; + } + + //FIXME + //check if filter is active + + m_Pin->Release(); + m_Pin = NULL; + + OutputDebugStringW(L"CInputPin::Disconnect\n"); + return S_OK; } HRESULT STDMETHODCALLTYPE @@ -693,6 +705,9 @@ HRESULT STDMETHODCALLTYPE CInputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt) { + if (!m_Pin) + return VFW_E_NOT_CONNECTED; + OutputDebugStringW(L"CInputPin::ConnectionMediaType NotImplemented\n"); return E_NOTIMPL; } @@ -742,8 +757,41 @@ HRESULT STDMETHODCALLTYPE CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) { - return CEnumMediaTypes_fnConstructor(0, NULL, IID_IEnumMediaTypes, (void**)ppEnum); + HRESULT hr; + ULONG MediaTypeCount = 0, Index; + AM_MEDIA_TYPE * MediaTypes; + + // query media type count + hr = KsGetMediaTypeCount(m_hFilter, m_PinId, &MediaTypeCount); + if (FAILED(hr) || !MediaTypeCount) + return hr; + + // allocate media types + MediaTypes = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * MediaTypeCount); + if (!MediaTypes) + { + // not enough memory + return E_OUTOFMEMORY; + } + + // zero media types + ZeroMemory(MediaTypes, sizeof(AM_MEDIA_TYPE) * MediaTypeCount); + + for(Index = 0; Index < MediaTypeCount; Index++) + { + // get media type + hr = KsGetMediaType(Index, &MediaTypes[Index], m_hFilter, m_PinId); + if (FAILED(hr)) + { + // failed + CoTaskMemFree(MediaTypes); + return hr; + } + } + + return CEnumMediaTypes_fnConstructor(MediaTypeCount, MediaTypes, IID_IEnumMediaTypes, (void**)ppEnum); } + HRESULT STDMETHODCALLTYPE CInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin) @@ -799,6 +847,9 @@ CInputPin::CheckFormat( Property.PinId = m_PinId; Property.Reserved = 0; + if (!pmt) + return E_POINTER; + // query for size of dataranges hr = KsSynchronousDeviceControl(m_hFilter, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), NULL, 0, &BytesReturned); @@ -842,13 +893,12 @@ CInputPin::CheckFormat( HRESULT STDMETHODCALLTYPE -CInputPin::CreatePin() +CInputPin::CreatePin( + const AM_MEDIA_TYPE *pmt) { PKSMULTIPLE_ITEM MediumList; PKSMULTIPLE_ITEM InterfaceList; - PKSMULTIPLE_ITEM DataFormatList = NULL; PKSPIN_MEDIUM Medium; - PKSDATAFORMAT DataFormat; PKSPIN_INTERFACE Interface; HRESULT hr; @@ -866,19 +916,6 @@ CInputPin::CreatePin() return hr; } - // get data ranges - hr = KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&DataFormatList); - if (FAILED(hr) || DataFormatList->Count == 0) - { - // failed - CoTaskMemFree(MediumList); - CoTaskMemFree(InterfaceList); - if (DataFormatList) - CoTaskMemFree(DataFormatList); - - return hr; - } - if (MediumList->Count) { //use first available medium @@ -901,15 +938,10 @@ CInputPin::CreatePin() Interface = &StandardPinInterface; } - //FIXME determine format - // use first available format - DataFormat = (PKSDATAFORMAT) (DataFormatList + 1); - // now create pin - hr = CreatePinHandle(Medium, Interface, DataFormat); + hr = CreatePinHandle(Medium, Interface, pmt); // free medium / interface / dataformat - CoTaskMemFree(DataFormatList); CoTaskMemFree(MediumList); CoTaskMemFree(InterfaceList); @@ -921,14 +953,15 @@ STDMETHODCALLTYPE CInputPin::CreatePinHandle( PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, - PKSDATAFORMAT DataFormat) + const AM_MEDIA_TYPE *pmt) { PKSPIN_CONNECT PinConnect; + PKSDATAFORMAT DataFormat; ULONG Length; HRESULT hr; // calc format size - Length = sizeof(KSPIN_CONNECT) + DataFormat->FormatSize; + Length = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT) + pmt->cbFormat; // allocate pin connect PinConnect = (PKSPIN_CONNECT)CoTaskMemAlloc(Length); @@ -945,7 +978,24 @@ CInputPin::CreatePinHandle( PinConnect->PinToHandle = NULL; PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; PinConnect->Priority.PrioritySubClass = KSPRIORITY_NORMAL; - CopyMemory((PinConnect + 1), DataFormat, DataFormat->FormatSize); + + // get dataformat offset + DataFormat = (PKSDATAFORMAT)(PinConnect + 1); + + // copy data format + DataFormat->FormatSize = sizeof(KSDATAFORMAT) + pmt->cbFormat; + DataFormat->Flags = 0; + DataFormat->SampleSize = pmt->lSampleSize; + DataFormat->Reserved = 0; + CopyMemory(&DataFormat->MajorFormat, &pmt->majortype, sizeof(GUID)); + CopyMemory(&DataFormat->SubFormat, &pmt->subtype, sizeof(GUID)); + CopyMemory(&DataFormat->Specifier, &pmt->formattype, sizeof(GUID)); + + if (pmt->cbFormat) + { + // copy extended format + CopyMemory((DataFormat + 1), pmt->pbFormat, pmt->cbFormat); + } // create pin hr = KsCreatePin(m_hFilter, PinConnect, GENERIC_WRITE, &m_hPin); diff --git a/reactos/dll/directx/ksproxy/ksproxy.cpp b/reactos/dll/directx/ksproxy/ksproxy.cpp index 927a1dc14b2..237b0390427 100644 --- a/reactos/dll/directx/ksproxy/ksproxy.cpp +++ b/reactos/dll/directx/ksproxy/ksproxy.cpp @@ -10,14 +10,18 @@ #include "precomp.h" -const GUID KSPROPSETID_Pin = {0x8C134960, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; -const GUID KSINTERFACESETID_Standard = {STATIC_KSINTERFACESETID_Standard}; + const GUID CLSID_KsClockForwarder = {0x877e4351, 0x6fea, 0x11d0, {0xb8, 0x63, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}}; const GUID CLSID_KsQualityForwarder = {0xe05592e4, 0xc0b5, 0x11d0, {0xa4, 0x39, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96}}; const GUID CLSID_KsIBasicAudioInterfaceHandler = {0xb9f8ac3e, 0x0f71, 0x11d2, {0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d}}; -const GUID CLSID_Proxy = {0x17CCA71B, 0xECD7, 0x11D0, {0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +#ifndef _MSC_VER +const GUID KSPROPSETID_Pin = {0x8C134960, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; +const GUID KSINTERFACESETID_Standard = {STATIC_KSINTERFACESETID_Standard}; +const GUID CLSID_Proxy = {0x17CCA71B, 0xECD7, 0x11D0, {0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +#endif + static INTERFACE_TABLE InterfaceTable[] = { {&MEDIATYPE_Audio, CKsDataTypeHandler_Constructor}, @@ -258,7 +262,78 @@ KsGetMediaType( HANDLE FilterHandle, ULONG PinFactoryId) { - //UNIMPLEMENTED + HRESULT hr; + PKSMULTIPLE_ITEM ItemList; + int i = 0; + PKSDATAFORMAT DataFormat; + + if (Position < 0) + return E_INVALIDARG; + + // get current supported ranges + hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_CONSTRAINEDDATARANGES, (PVOID*)&ItemList); + if (FAILED(hr)) + { + // get standard dataranges + hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&ItemList); + + //check for success + if (FAILED(hr)) + return hr; + } + + if ((ULONG)Position >= ItemList->Count) + { + // out of bounds + CoTaskMemFree(ItemList); + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NO_MORE_ITEMS); + } + + // goto first datarange + DataFormat = (PKSDATAFORMAT)(ItemList + 1); + + while(i != Position) + { + // goto next format; + DataFormat = (PKSDATAFORMAT)(ULONG_PTR)(DataFormat + DataFormat->FormatSize); + i++; + } + + + DataFormat->FormatSize -= sizeof(KSDATAFORMAT); + if (DataFormat->FormatSize) + { + // copy extra format buffer + AmMediaType->pbFormat = (BYTE*)CoTaskMemAlloc(DataFormat->FormatSize); + if (!AmMediaType->pbFormat) + { + // not enough memory + CoTaskMemFree(ItemList); + return E_OUTOFMEMORY; + } + // copy format buffer + CopyMemory(AmMediaType->pbFormat, (DataFormat + 1), DataFormat->FormatSize); + AmMediaType->cbFormat = DataFormat->FormatSize; + } + else + { + // no format buffer + AmMediaType->pbFormat = NULL; + AmMediaType->cbFormat = 0; + } + + // copy type info + CopyMemory(&AmMediaType->majortype, &DataFormat->MajorFormat, sizeof(GUID)); + CopyMemory(&AmMediaType->subtype, &DataFormat->SubFormat, sizeof(GUID)); + CopyMemory(&AmMediaType->formattype, &DataFormat->Specifier, sizeof(GUID)); + AmMediaType->bTemporalCompression = FALSE; //FIXME verify + AmMediaType->pUnk = NULL; //FIXME + AmMediaType->lSampleSize = DataFormat->SampleSize; + AmMediaType->bFixedSizeSamples = (AmMediaType->lSampleSize) ? TRUE : FALSE; + + // free dataformat list + CoTaskMemFree(ItemList); + return NOERROR; } diff --git a/reactos/dll/directx/ksproxy/ksproxy.rc b/reactos/dll/directx/ksproxy/ksproxy.rc index cf8ecb41a6a..f917d67fa1d 100644 --- a/reactos/dll/directx/ksproxy/ksproxy.rc +++ b/reactos/dll/directx/ksproxy/ksproxy.rc @@ -1,9 +1,98 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource." -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS WDM Streaming ActiveMovie Proxy\0" -#define REACTOS_STR_INTERNAL_NAME "ksproxy\0" -#define REACTOS_STR_ORIGINAL_FILENAME "ksproxy.ax\0" +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" -#include +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Deutsch (Deutschland) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 5,3,2600,3264 + PRODUCTVERSION 5,3,2600,3264 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040704b0" + BEGIN + VALUE "CompanyName", "ReactOS WDM Streaming ActiveMovie Proxy" + VALUE "FileDescription", "ReactOS WDM Streaming ActiveMovie Proxy" + VALUE "FileVersion", "5, 3, 2600, 3264" + VALUE "InternalName", "ksproxy" + VALUE "LegalCopyright", "Copyright (C) 2010" + VALUE "OriginalFilename", "ksproxy.dll" + VALUE "ProductName", "ReactOS WDM Streaming ActiveMovie Proxy" + VALUE "ProductVersion", "5, 3, 2600, 3264" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x407, 1200 + END +END + +#endif // Deutsch (Deutschland) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + ///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED -#include diff --git a/reactos/dll/directx/ksproxy/output_pin.cpp b/reactos/dll/directx/ksproxy/output_pin.cpp index b29d12ac4b2..d21f3832f15 100644 --- a/reactos/dll/directx/ksproxy/output_pin.cpp +++ b/reactos/dll/directx/ksproxy/output_pin.cpp @@ -8,17 +8,21 @@ */ #include "precomp.h" +#ifndef _MSC_VER +const GUID IID_IKsPinFactory = {0xCD5EBE6BL, 0x8B6E, 0x11D1, {0x8A, 0xE0, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +#endif + class COutputPin : public IPin, - public IKsObject + public IKsObject, + public IKsPropertySet, + public IStreamBuilder, + public IKsPinFactory, + public ISpecifyPropertyPages, +// public IKsPinPipe, + public IKsControl /* public IQualityControl, public IKsPinEx, - public IKsPinPipe, - public ISpecifyPropertyPages, - public IStreamBuilder, - public IKsPropertySet, - public IKsPinFactory, - public IKsControl, public IKsAggregateControl public IMediaSeeking, public IAMStreamConfig, @@ -38,12 +42,25 @@ public: InterlockedDecrement(&m_Ref); if (!m_Ref) { - delete this; + //delete this; return 0; } return m_Ref; } + //IKsPinPipe + HRESULT STDMETHODCALLTYPE KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX *FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option); + HRESULT STDMETHODCALLTYPE KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option); + IPin* STDMETHODCALLTYPE KsGetConnectedPin(); + IKsAllocatorEx* STDMETHODCALLTYPE KsGetPipe(KSPEEKOPERATION Operation); + HRESULT STDMETHODCALLTYPE KsSetPipe(IKsAllocatorEx *KsAllocator); + ULONG STDMETHODCALLTYPE KsGetPipeAllocatorFlag(); + HRESULT STDMETHODCALLTYPE KsSetPipeAllocatorFlag(ULONG Flag); + GUID STDMETHODCALLTYPE KsGetPinBusCache(); + HRESULT STDMETHODCALLTYPE KsSetPinBusCache(GUID Bus); + PWCHAR STDMETHODCALLTYPE KsGetPinName(); + PWCHAR STDMETHODCALLTYPE KsGetFilterName(); + //IPin methods HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt); @@ -61,17 +78,58 @@ public: HRESULT STDMETHODCALLTYPE EndFlush(); HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); + // ISpecifyPropertyPages + HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages); + //IKsObject methods HANDLE STDMETHODCALLTYPE KsGetObjectHandle(); + //IKsPropertySet + HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData); + HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD *pcbReturned); + HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport); - COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName){}; - virtual ~COutputPin(){}; + //IKsControl + HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned); + HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned); + HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned); + + //IStreamBuilder + HRESULT STDMETHODCALLTYPE Render(IPin *ppinOut, IGraphBuilder *pGraph); + HRESULT STDMETHODCALLTYPE Backout(IPin *ppinOut, IGraphBuilder *pGraph); + + //IKsPinFactory + HRESULT STDMETHODCALLTYPE KsPinFactory(ULONG* PinFactory); + + COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId); + virtual ~COutputPin(); protected: LONG m_Ref; IBaseFilter * m_ParentFilter; LPCWSTR m_PinName; + HANDLE m_hPin; + ULONG m_PinId; + IKsObject * m_KsObjectParent; + IPin * m_Pin; +}; + +COutputPin::~COutputPin() +{ + if (m_KsObjectParent) + m_KsObjectParent->Release(); +} + +COutputPin::COutputPin( + IBaseFilter * ParentFilter, + LPCWSTR PinName, + ULONG PinId) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hPin(0), m_PinId(PinId), m_KsObjectParent(0), m_Pin(0) +{ + HRESULT hr; + + hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&m_KsObjectParent); + assert(hr == S_OK); + }; HRESULT @@ -94,6 +152,41 @@ COutputPin::QueryInterface( reinterpret_cast(*Output)->AddRef(); return NOERROR; } + else if (IsEqualGUID(refiid, IID_IKsPropertySet)) + { + *Output = (IKsPropertySet*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsControl)) + { + *Output = (IKsControl*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IStreamBuilder)) + { + *Output = (IStreamBuilder*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsPinFactory)) + { + *Output = (IKsPinFactory*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages)) + { + *Output = (ISpecifyPropertyPages*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IBaseFilter)) + { + OutputDebugStringW(L"COutputPin::QueryInterface query IID_IBaseFilter\n"); + DebugBreak(); + } WCHAR Buffer[MAX_PATH]; LPOLESTR lpstr; @@ -105,6 +198,60 @@ COutputPin::QueryInterface( return E_NOINTERFACE; } +//------------------------------------------------------------------- +// ISpecifyPropertyPages +// + +HRESULT +STDMETHODCALLTYPE +COutputPin::GetPages(CAUUID *pPages) +{ + OutputDebugStringW(L"COutputPin::GetPages NotImplemented\n"); + + if (!pPages) + return E_POINTER; + + pPages->cElems = 0; + pPages->pElems = NULL; + + return S_OK; +} + +//------------------------------------------------------------------- +// IKsPinFactory +// + +HRESULT +STDMETHODCALLTYPE +COutputPin::KsPinFactory( + ULONG* PinFactory) +{ + *PinFactory = m_PinId; + return S_OK; +} + + +//------------------------------------------------------------------- +// IStreamBuilder +// + +HRESULT +STDMETHODCALLTYPE +COutputPin::Render( + IPin *ppinOut, + IGraphBuilder *pGraph) +{ + return S_OK; +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::Backout( + IPin *ppinOut, + IGraphBuilder *pGraph) +{ + return S_OK; +} //------------------------------------------------------------------- // IKsObject // @@ -112,13 +259,161 @@ HANDLE STDMETHODCALLTYPE COutputPin::KsGetObjectHandle() { - OutputDebugStringW(L"COutputPin::KsGetObjectHandle CALLED\n"); - - //FIXME - // return pin handle - return NULL; + assert(m_hPin); + return m_hPin; } +//------------------------------------------------------------------- +// IKsControl +// +HRESULT +STDMETHODCALLTYPE +COutputPin::KsProperty( + PKSPROPERTY Property, + ULONG PropertyLength, + LPVOID PropertyData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hPin != 0); + return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::KsMethod( + PKSMETHOD Method, + ULONG MethodLength, + LPVOID MethodData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hPin != 0); + return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned); +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::KsEvent( + PKSEVENT Event, + ULONG EventLength, + LPVOID EventData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hPin != 0); + + if (EventLength) + return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned); + else + return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned); +} + + +//------------------------------------------------------------------- +// IKsPropertySet +// +HRESULT +STDMETHODCALLTYPE +COutputPin::Set( + REFGUID guidPropSet, + DWORD dwPropID, + LPVOID pInstanceData, + DWORD cbInstanceData, + LPVOID pPropData, + DWORD cbPropData) +{ + ULONG BytesReturned; + + if (cbInstanceData) + { + PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); + if (!Property) + return E_OUTOFMEMORY; + + Property->Set = guidPropSet; + Property->Id = dwPropID; + Property->Flags = KSPROPERTY_TYPE_SET; + + CopyMemory((Property+1), pInstanceData, cbInstanceData); + + HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); + CoTaskMemFree(Property); + return hr; + } + else + { + KSPROPERTY Property; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_SET; + + HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); + return hr; + } +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::Get( + REFGUID guidPropSet, + DWORD dwPropID, + LPVOID pInstanceData, + DWORD cbInstanceData, + LPVOID pPropData, + DWORD cbPropData, + DWORD *pcbReturned) +{ + ULONG BytesReturned; + + if (cbInstanceData) + { + PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); + if (!Property) + return E_OUTOFMEMORY; + + Property->Set = guidPropSet; + Property->Id = dwPropID; + Property->Flags = KSPROPERTY_TYPE_GET; + + CopyMemory((Property+1), pInstanceData, cbInstanceData); + + HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); + CoTaskMemFree(Property); + return hr; + } + else + { + KSPROPERTY Property; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_GET; + + HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); + return hr; + } +} + +HRESULT +STDMETHODCALLTYPE +COutputPin::QuerySupported( + REFGUID guidPropSet, + DWORD dwPropID, + DWORD *pTypeSupport) +{ + KSPROPERTY Property; + ULONG BytesReturned; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_SETSUPPORT; + + return KsProperty(&Property, sizeof(KSPROPERTY), pTypeSupport, sizeof(DWORD), &BytesReturned); +} + + //------------------------------------------------------------------- // IPin interface // @@ -126,30 +421,92 @@ HRESULT STDMETHODCALLTYPE COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) { + AM_MEDIA_TYPE MediaType; + HRESULT hr; + HANDLE hFilter; + OutputDebugStringW(L"COutputPin::Connect called\n"); - return E_NOTIMPL; + if (pmt) + { + hr = pReceivePin->QueryAccept(pmt); + if (FAILED(hr)) + return hr; + } + else + { + // get parent filter handle + hFilter = m_KsObjectParent->KsGetObjectHandle(); + + // get media type count + ZeroMemory(&MediaType, sizeof(AM_MEDIA_TYPE)); + hr = KsGetMediaType(0, &MediaType, hFilter, m_PinId); + if (FAILED(hr)) + return hr; + + // query accept + hr = pReceivePin->QueryAccept(&MediaType); + if (FAILED(hr)) + return hr; + + pmt = &MediaType; + } + + //FIXME create pin handle + + // receive connection; + hr = pReceivePin->ReceiveConnection((IPin*)this, pmt); + if (SUCCEEDED(hr)) + { + // increment reference count + pReceivePin->AddRef(); + m_Pin = pReceivePin; + OutputDebugStringW(L"COutputPin::Connect success\n"); + } + + return hr; } HRESULT STDMETHODCALLTYPE COutputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) { - OutputDebugStringW(L"COutputPin::ReceiveConnection called\n"); - return E_NOTIMPL; + return E_UNEXPECTED; } HRESULT STDMETHODCALLTYPE COutputPin::Disconnect( void) { - OutputDebugStringW(L"COutputPin::Disconnect called\n"); - return E_NOTIMPL; + if (!m_Pin) + { + // pin was not connected + return S_FALSE; + } + + //FIXME + //check if filter is active + + m_Pin->Release(); + m_Pin = NULL; + + OutputDebugStringW(L"COutputPin::Disconnect\n"); + return S_OK; } HRESULT STDMETHODCALLTYPE COutputPin::ConnectedTo(IPin **pPin) { + if (!pPin) + return E_POINTER; + + if (m_Pin) + { + // increment reference count + m_Pin->AddRef(); + *pPin = m_Pin; + return S_OK; + } + *pPin = NULL; - OutputDebugStringW(L"COutputPin::ConnectedTo called\n"); return VFW_E_NOT_CONNECTED; } HRESULT @@ -204,8 +561,56 @@ HRESULT STDMETHODCALLTYPE COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) { + HRESULT hr; + ULONG MediaTypeCount = 0, Index; + AM_MEDIA_TYPE * MediaTypes; + HANDLE hFilter; + OutputDebugStringW(L"COutputPin::EnumMediaTypes called\n"); - return E_NOTIMPL; + + if (!m_KsObjectParent) + { + // no interface + return E_NOINTERFACE; + } + + // get parent filter handle + hFilter = m_KsObjectParent->KsGetObjectHandle(); + + // query media type count + hr = KsGetMediaTypeCount(hFilter, m_PinId, &MediaTypeCount); + if (FAILED(hr) || !MediaTypeCount) + { + OutputDebugStringW(L"COutputPin::EnumMediaTypes failed1\n"); + return hr; + } + + // allocate media types + MediaTypes = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * MediaTypeCount); + if (!MediaTypes) + { + // not enough memory + OutputDebugStringW(L"COutputPin::EnumMediaTypes CoTaskMemAlloc\n"); + return E_OUTOFMEMORY; + } + + // zero media types + ZeroMemory(MediaTypes, sizeof(AM_MEDIA_TYPE) * MediaTypeCount); + + for(Index = 0; Index < MediaTypeCount; Index++) + { + // get media type + hr = KsGetMediaType(Index, &MediaTypes[Index], hFilter, m_PinId); + if (FAILED(hr)) + { + // failed + CoTaskMemFree(MediaTypes); + OutputDebugStringW(L"COutputPin::EnumMediaTypes failed2\n"); + return hr; + } + } + + return CEnumMediaTypes_fnConstructor(MediaTypeCount, MediaTypes, IID_IEnumMediaTypes, (void**)ppEnum); } HRESULT STDMETHODCALLTYPE @@ -248,10 +653,11 @@ WINAPI COutputPin_Constructor( IBaseFilter * ParentFilter, LPCWSTR PinName, + ULONG PinId, REFIID riid, LPVOID * ppv) { - COutputPin * handler = new COutputPin(ParentFilter, PinName); + COutputPin * handler = new COutputPin(ParentFilter, PinName, PinId); if (!handler) return E_OUTOFMEMORY; diff --git a/reactos/dll/directx/ksproxy/precomp.h b/reactos/dll/directx/ksproxy/precomp.h index 32953e94cb5..5078daef9a9 100644 --- a/reactos/dll/directx/ksproxy/precomp.h +++ b/reactos/dll/directx/ksproxy/precomp.h @@ -18,6 +18,7 @@ #include #include #include +#include //#include typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject); @@ -117,6 +118,7 @@ WINAPI COutputPin_Constructor( IBaseFilter * ParentFilter, LPCWSTR PinName, + ULONG PinId, REFIID riid, LPVOID * ppv); @@ -137,4 +139,4 @@ CEnumMediaTypes_fnConstructor( REFIID riid, LPVOID * ppv); - +extern const GUID IID_IKsObject; diff --git a/reactos/dll/directx/ksproxy/proxy.cpp b/reactos/dll/directx/ksproxy/proxy.cpp index 0ff397c2062..d6139622843 100644 --- a/reactos/dll/directx/ksproxy/proxy.cpp +++ b/reactos/dll/directx/ksproxy/proxy.cpp @@ -8,9 +8,16 @@ */ #include "precomp.h" +#ifndef _MSC_VER const GUID IID_IPersistPropertyBag = {0x37D84F60, 0x42CB, 0x11CE, {0x81, 0x35, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51}}; const GUID GUID_NULL = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +#endif + const GUID IID_IBDA_DeviceControl = {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}}; +const GUID IID_IKsAggregateControl = {0x7F40EAC0, 0x3947, 0x11D2, {0x87, 0x4E, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID IID_IKsClockPropertySet = {0x5C5CBD84, 0xE755, 0x11D0, {0xAC, 0x18, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID IID_IKsTopology = {0x28F54683, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; + /* Needs IKsClock, IKsNotifyEvent */ @@ -18,21 +25,19 @@ const GUID IID_IBDA_DeviceControl = {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x class CKsProxy : public IBaseFilter, public IAMovieSetup, public IPersistPropertyBag, - public IKsObject -/* + public IKsObject, public IPersistStream, + public IAMDeviceRemoval, public ISpecifyPropertyPages, public IReferenceClock, public IMediaSeeking, - public IKsObject, public IKsPropertySet, public IKsClockPropertySet, public IAMFilterMiscFlags, public IKsControl, public IKsTopology, - public IKsAggregateControl, - public IAMDeviceRemoval -*/ + public IKsAggregateControl + { public: typedef std::vectorProxyPluginVector; @@ -70,6 +75,64 @@ public: HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName); HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *pVendorInfo); + //IReferenceClock + HRESULT STDMETHODCALLTYPE GetTime(REFERENCE_TIME *pTime); + HRESULT STDMETHODCALLTYPE AdviseTime(REFERENCE_TIME baseTime, REFERENCE_TIME streamTime, HEVENT hEvent, DWORD_PTR *pdwAdviseCookie); + HRESULT STDMETHODCALLTYPE AdvisePeriodic(REFERENCE_TIME startTime, REFERENCE_TIME periodTime, HSEMAPHORE hSemaphore, DWORD_PTR *pdwAdviseCookie); + HRESULT STDMETHODCALLTYPE Unadvise(DWORD_PTR dwAdviseCookie); + + //IMediaSeeking + HRESULT STDMETHODCALLTYPE GetCapabilities(DWORD *pCapabilities); + HRESULT STDMETHODCALLTYPE CheckCapabilities(DWORD *pCapabilities); + HRESULT STDMETHODCALLTYPE IsFormatSupported(const GUID *pFormat); + HRESULT STDMETHODCALLTYPE QueryPreferredFormat(GUID *pFormat); + HRESULT STDMETHODCALLTYPE GetTimeFormat(GUID *pFormat); + HRESULT STDMETHODCALLTYPE IsUsingTimeFormat(const GUID *pFormat); + HRESULT STDMETHODCALLTYPE SetTimeFormat(const GUID *pFormat); + HRESULT STDMETHODCALLTYPE GetDuration(LONGLONG *pDuration); + HRESULT STDMETHODCALLTYPE GetStopPosition(LONGLONG *pStop); + HRESULT STDMETHODCALLTYPE GetCurrentPosition(LONGLONG *pCurrent); + HRESULT STDMETHODCALLTYPE ConvertTimeFormat(LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat); + HRESULT STDMETHODCALLTYPE SetPositions(LONGLONG *pCurrent, DWORD dwCurrentFlags, LONGLONG *pStop, DWORD dwStopFlags); + HRESULT STDMETHODCALLTYPE GetPositions(LONGLONG *pCurrent, LONGLONG *pStop); + HRESULT STDMETHODCALLTYPE GetAvailable(LONGLONG *pEarliest, LONGLONG *pLatest); + HRESULT STDMETHODCALLTYPE SetRate(double dRate); + HRESULT STDMETHODCALLTYPE GetRate(double *pdRate); + HRESULT STDMETHODCALLTYPE GetPreroll(LONGLONG *pllPreroll); + + //IKsPropertySet + HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData); + HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD *pcbReturned); + HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport); + + //IAMFilterMiscFlags + ULONG STDMETHODCALLTYPE GetMiscFlags( void); + + //IKsControl + HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned); + HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned); + HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned); + + //IKsTopolology + HRESULT STDMETHODCALLTYPE CreateNodeInstance(ULONG NodeId, ULONG Flags, ACCESS_MASK DesiredAccess, IUnknown* UnkOuter, REFGUID InterfaceId, LPVOID* Interface); + + //IKsAggregateControl + HRESULT STDMETHODCALLTYPE KsAddAggregate(IN REFGUID AggregateClass); + HRESULT STDMETHODCALLTYPE KsRemoveAggregate(REFGUID AggregateClass); + + //IKsClockPropertySet + HRESULT STDMETHODCALLTYPE KsGetTime(LONGLONG* Time); + HRESULT STDMETHODCALLTYPE KsSetTime(LONGLONG Time); + HRESULT STDMETHODCALLTYPE KsGetPhysicalTime(LONGLONG* Time); + HRESULT STDMETHODCALLTYPE KsSetPhysicalTime(LONGLONG Time); + HRESULT STDMETHODCALLTYPE KsGetCorrelatedTime(KSCORRELATED_TIME* CorrelatedTime); + HRESULT STDMETHODCALLTYPE KsSetCorrelatedTime(KSCORRELATED_TIME* CorrelatedTime); + HRESULT STDMETHODCALLTYPE KsGetCorrelatedPhysicalTime(KSCORRELATED_TIME* CorrelatedTime); + HRESULT STDMETHODCALLTYPE KsSetCorrelatedPhysicalTime(KSCORRELATED_TIME* CorrelatedTime); + HRESULT STDMETHODCALLTYPE KsGetResolution(KSRESOLUTION* Resolution); + HRESULT STDMETHODCALLTYPE KsGetState(KSSTATE* State); + + //IAMovieSetup methods HRESULT STDMETHODCALLTYPE Register( void); HRESULT STDMETHODCALLTYPE Unregister( void); @@ -82,8 +145,23 @@ public: // IKsObject HANDLE STDMETHODCALLTYPE KsGetObjectHandle(); - CKsProxy() : m_Ref(0), m_pGraph(0), m_ReferenceClock(0), m_FilterState(State_Stopped), m_hDevice(0), m_Plugins(), m_Pins() {}; - virtual ~CKsProxy() + //IAMDeviceRemoval + HRESULT STDMETHODCALLTYPE DeviceInfo(CLSID *pclsidInterfaceClass, LPWSTR *pwszSymbolicLink); + HRESULT STDMETHODCALLTYPE Reassociate(void); + HRESULT STDMETHODCALLTYPE Disassociate( void); + + //IPersistStream + HRESULT STDMETHODCALLTYPE IsDirty( void); + HRESULT STDMETHODCALLTYPE Load(IStream *pStm); + HRESULT STDMETHODCALLTYPE Save(IStream *pStm, BOOL fClearDirty); + HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize); + + // ISpecifyPropertyPages + HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages); + + + CKsProxy() : m_Ref(0), m_pGraph(0), m_ReferenceClock(0), m_FilterState(State_Stopped), m_hDevice(0), m_Plugins(), m_Pins(), m_DevicePath(0) {}; + ~CKsProxy() { if (m_hDevice) CloseHandle(m_hDevice); @@ -105,6 +183,8 @@ protected: HANDLE m_hDevice; ProxyPluginVector m_Plugins; PinVector m_Pins; + LPWSTR m_DevicePath; + CLSID m_DeviceInterfaceGUID; }; HRESULT @@ -113,7 +193,7 @@ CKsProxy::QueryInterface( IN REFIID refiid, OUT PVOID* Output) { - *Output = NULL; + *Output = (PVOID)0xDEADDEAD;//NULL; if (IsEqualGUID(refiid, IID_IUnknown) || IsEqualGUID(refiid, IID_IBaseFilter)) @@ -128,12 +208,78 @@ CKsProxy::QueryInterface( reinterpret_cast(*Output)->AddRef(); return NOERROR; } - if (IsEqualGUID(refiid, IID_IKsObject)) + else if (IsEqualGUID(refiid, IID_IAMDeviceRemoval)) + { + *Output = (IAMDeviceRemoval*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IPersistStream)) + { + *Output = (IPersistStream*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsObject)) { *Output = (IKsObject*)(this); reinterpret_cast(*Output)->AddRef(); return NOERROR; } + else if (IsEqualGUID(refiid, IID_IReferenceClock)) + { + *Output = (IReferenceClock*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IMediaSeeking)) + { + *Output = (IMediaSeeking*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IAMFilterMiscFlags)) + { + *Output = (IAMFilterMiscFlags*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsControl)) + { + *Output = (IKsControl*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsPropertySet)) + { + *Output = (IKsPropertySet*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsTopology)) + { + *Output = (IKsTopology*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsAggregateControl)) + { + *Output = (IKsAggregateControl*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_IKsClockPropertySet)) + { + *Output = (IKsClockPropertySet*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } + else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages)) + { + *Output = (ISpecifyPropertyPages*)(this); + reinterpret_cast(*Output)->AddRef(); + return NOERROR; + } for(ULONG Index = 0; Index < m_Plugins.size(); Index++) { @@ -164,6 +310,815 @@ CKsProxy::QueryInterface( return E_NOINTERFACE; } +//------------------------------------------------------------------- +// ISpecifyPropertyPages +// + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetPages(CAUUID *pPages) +{ + OutputDebugStringW(L"CKsProxy::GetPages NotImplemented\n"); + + if (!pPages) + return E_POINTER; + + pPages->cElems = 0; + pPages->pElems = NULL; + + return S_OK; +} + +//------------------------------------------------------------------- +// IKsClockPropertySet interface +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetTime( + LONGLONG* Time) +{ + OutputDebugStringW(L"CKsProxy::KsGetTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsSetTime( + LONGLONG Time) +{ + OutputDebugStringW(L"CKsProxy::KsSetTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetPhysicalTime( + LONGLONG* Time) +{ + OutputDebugStringW(L"CKsProxy::KsGetPhysicalTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsSetPhysicalTime( + LONGLONG Time) +{ + OutputDebugStringW(L"CKsProxy::KsSetPhysicalTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetCorrelatedTime( + KSCORRELATED_TIME* CorrelatedTime) +{ + OutputDebugStringW(L"CKsProxy::KsGetCorrelatedTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsSetCorrelatedTime( + KSCORRELATED_TIME* CorrelatedTime) +{ + OutputDebugStringW(L"CKsProxy::KsSetCorrelatedTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetCorrelatedPhysicalTime( + KSCORRELATED_TIME* CorrelatedTime) +{ + OutputDebugStringW(L"CKsProxy::KsGetCorrelatedPhysicalTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsSetCorrelatedPhysicalTime( + KSCORRELATED_TIME* CorrelatedTime) +{ + OutputDebugStringW(L"CKsProxy::KsSetCorrelatedPhysicalTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetResolution( + KSRESOLUTION* Resolution) +{ + OutputDebugStringW(L"CKsProxy::KsGetResolution NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsGetState( + KSSTATE* State) +{ + OutputDebugStringW(L"CKsProxy::KsGetState NotImplemented\n"); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IReferenceClock interface +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetTime( + REFERENCE_TIME *pTime) +{ + OutputDebugStringW(L"CKsProxy::GetTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::AdviseTime( + REFERENCE_TIME baseTime, + REFERENCE_TIME streamTime, + HEVENT hEvent, + DWORD_PTR *pdwAdviseCookie) +{ + OutputDebugStringW(L"CKsProxy::AdviseTime NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::AdvisePeriodic( + REFERENCE_TIME startTime, + REFERENCE_TIME periodTime, + HSEMAPHORE hSemaphore, + DWORD_PTR *pdwAdviseCookie) +{ + OutputDebugStringW(L"CKsProxy::AdvisePeriodic NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::Unadvise( + DWORD_PTR dwAdviseCookie) +{ + OutputDebugStringW(L"CKsProxy::Unadvise NotImplemented\n"); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IMediaSeeking interface +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetCapabilities( + DWORD *pCapabilities) +{ + OutputDebugStringW(L"CKsProxy::GetCapabilities NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::CheckCapabilities( + DWORD *pCapabilities) +{ + OutputDebugStringW(L"CKsProxy::CheckCapabilities NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::IsFormatSupported( + const GUID *pFormat) +{ + KSPROPERTY Property; + PKSMULTIPLE_ITEM FormatList; + LPGUID pGuid; + ULONG Index; + HRESULT hr = S_FALSE; + ULONG BytesReturned; + + OutputDebugStringW(L"CKsProxy::IsFormatSupported\n"); + + if (!pFormat) + return E_POINTER; + + Property.Set = KSPROPSETID_MediaSeeking; + Property.Id = KSPROPERTY_MEDIASEEKING_FORMATS; + Property.Flags = KSPROPERTY_TYPE_GET; + + // query for format size list + hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &BytesReturned); + + if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA)) + { + // allocate format list + FormatList = (PKSMULTIPLE_ITEM)CoTaskMemAlloc(BytesReturned); + if (!FormatList) + { + // not enough memory + return E_OUTOFMEMORY; + } + + // get format list + hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)FormatList, BytesReturned, &BytesReturned); + if (FAILED(hr)) + { + // failed to query format list + CoTaskMemFree(FormatList); + return hr; + } + + //iterate through format list + pGuid = (LPGUID)(FormatList + 1); + for(Index = 0; Index < FormatList->Count; Index++) + { + if (IsEqualGUID(*pGuid, *pFormat)) + { + OutputDebugStringW(L"CKsProxy::IsFormatSupported found format\n"); + CoTaskMemFree(FormatList); + return S_OK; + } + pGuid++; + } + + OutputDebugStringW(L"CKsProxy::IsFormatSupported FormatNotFound\n"); + // free format list + CoTaskMemFree(FormatList); + } + + // check if all plugins support it + for(Index = 0; Index < m_Plugins.size(); Index++) + { + // get plugin + IUnknown * Plugin = m_Plugins[Index]; + + if (!Plugin) + continue; + + // query for IMediaSeeking interface + IMediaSeeking *pSeek = NULL; + hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek); + if (FAILED(hr)) + { + // plugin does not support interface + hr = S_FALSE; + OutputDebugStringW(L"CKsProxy::IsFormatSupported plugin does not support IMediaSeeking interface\n"); + break; + } + + // query if it is supported + hr = pSeek->IsFormatSupported(pFormat); + // release interface + pSeek->Release(); + + if (FAILED(hr) || hr == S_FALSE) + break; + } + + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::QueryPreferredFormat( + GUID *pFormat) +{ + OutputDebugStringW(L"CKsProxy::QueryPreferredFormat NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetTimeFormat( + GUID *pFormat) +{ + OutputDebugStringW(L"CKsProxy::GetTimeFormat NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::IsUsingTimeFormat( + const GUID *pFormat) +{ + OutputDebugStringW(L"CKsProxy::IsUsingTimeFormat NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::SetTimeFormat( + const GUID *pFormat) +{ + OutputDebugStringW(L"CKsProxy::SetTimeFormat NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetDuration( + LONGLONG *pDuration) +{ + OutputDebugStringW(L"CKsProxy::GetDuration NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetStopPosition( + LONGLONG *pStop) +{ + OutputDebugStringW(L"CKsProxy::GetStopPosition NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetCurrentPosition( + LONGLONG *pCurrent) +{ + OutputDebugStringW(L"CKsProxy::GetCurrentPosition NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::ConvertTimeFormat( + LONGLONG *pTarget, + const GUID *pTargetFormat, + LONGLONG Source, + const GUID *pSourceFormat) +{ + OutputDebugStringW(L"CKsProxy::ConvertTimeFormat NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::SetPositions( + LONGLONG *pCurrent, + DWORD dwCurrentFlags, + LONGLONG *pStop, + DWORD dwStopFlags) +{ + OutputDebugStringW(L"CKsProxy::SetPositions NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetPositions( + LONGLONG *pCurrent, + LONGLONG *pStop) +{ + OutputDebugStringW(L"CKsProxy::GetPositions NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetAvailable( + LONGLONG *pEarliest, + LONGLONG *pLatest) +{ + OutputDebugStringW(L"CKsProxy::GetAvailable NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::SetRate( + double dRate) +{ + OutputDebugStringW(L"CKsProxy::SetRate NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetRate( + double *pdRate) +{ + OutputDebugStringW(L"CKsProxy::GetRate NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetPreroll( + LONGLONG *pllPreroll) +{ + OutputDebugStringW(L"CKsProxy::GetPreroll NotImplemented\n"); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IAMFilterMiscFlags interface +// + +ULONG +STDMETHODCALLTYPE +CKsProxy::GetMiscFlags() +{ + ULONG Index; + ULONG Flags = 0; + HRESULT hr; + PIN_DIRECTION PinDirection; + KSPIN_COMMUNICATION Communication; + + for(Index = 0; Index < m_Pins.size(); Index++) + { + // get current pin + IPin * pin = m_Pins[Index]; + // query direction + hr = pin->QueryDirection(&PinDirection); + if (SUCCEEDED(hr)) + { + if (PinDirection == PINDIR_INPUT) + { + if (SUCCEEDED(GetPinCommunication(Index, //FIXME verify PinId + &Communication))) + { + if (Communication == KSPIN_COMMUNICATION_NONE || Communication == KSPIN_COMMUNICATION_BRIDGE) + { + Flags |= AM_FILTER_MISC_FLAGS_IS_SOURCE; + } + } + } + } + } + + OutputDebugStringW(L"CKsProxy::GetMiscFlags stub\n"); + return Flags; +} + +//------------------------------------------------------------------- +// IKsControl +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsProperty( + PKSPROPERTY Property, + ULONG PropertyLength, + LPVOID PropertyData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hDevice != 0); + return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsMethod( + PKSMETHOD Method, + ULONG MethodLength, + LPVOID MethodData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hDevice != 0); + return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned); +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsEvent( + PKSEVENT Event, + ULONG EventLength, + LPVOID EventData, + ULONG DataLength, + ULONG* BytesReturned) +{ + assert(m_hDevice != 0); + + if (EventLength) + return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned); + else + return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned); +} + + +//------------------------------------------------------------------- +// IKsPropertySet +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::Set( + REFGUID guidPropSet, + DWORD dwPropID, + LPVOID pInstanceData, + DWORD cbInstanceData, + LPVOID pPropData, + DWORD cbPropData) +{ + ULONG BytesReturned; + + if (cbInstanceData) + { + PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); + if (!Property) + return E_OUTOFMEMORY; + + Property->Set = guidPropSet; + Property->Id = dwPropID; + Property->Flags = KSPROPERTY_TYPE_SET; + + CopyMemory((Property+1), pInstanceData, cbInstanceData); + + HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); + CoTaskMemFree(Property); + return hr; + } + else + { + KSPROPERTY Property; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_SET; + + HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); + return hr; + } +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::Get( + REFGUID guidPropSet, + DWORD dwPropID, + LPVOID pInstanceData, + DWORD cbInstanceData, + LPVOID pPropData, + DWORD cbPropData, + DWORD *pcbReturned) +{ + ULONG BytesReturned; + + if (cbInstanceData) + { + PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData); + if (!Property) + return E_OUTOFMEMORY; + + Property->Set = guidPropSet; + Property->Id = dwPropID; + Property->Flags = KSPROPERTY_TYPE_GET; + + CopyMemory((Property+1), pInstanceData, cbInstanceData); + + HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned); + CoTaskMemFree(Property); + return hr; + } + else + { + KSPROPERTY Property; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_GET; + + HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned); + return hr; + } +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::QuerySupported( + REFGUID guidPropSet, + DWORD dwPropID, + DWORD *pTypeSupport) +{ + KSPROPERTY Property; + ULONG BytesReturned; + + Property.Set = guidPropSet; + Property.Id = dwPropID; + Property.Flags = KSPROPERTY_TYPE_SETSUPPORT; + + return KsProperty(&Property, sizeof(KSPROPERTY), pTypeSupport, sizeof(DWORD), &BytesReturned); +} + + +//------------------------------------------------------------------- +// IKsTopology interface +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::CreateNodeInstance( + ULONG NodeId, + ULONG Flags, + ACCESS_MASK DesiredAccess, + IUnknown* UnkOuter, + REFGUID InterfaceId, + LPVOID* Interface) +{ + OutputDebugStringW(L"CKsProxy::CreateNodeInstance NotImplemented\n"); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IKsAggregateControl interface +// +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsAddAggregate( + IN REFGUID AggregateClass) +{ + OutputDebugStringW(L"CKsProxy::KsAddAggregate NotImplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::KsRemoveAggregate( + REFGUID AggregateClass) +{ + OutputDebugStringW(L"CKsProxy::KsRemoveAggregate NotImplemented\n"); + return E_NOTIMPL; +} + + +//------------------------------------------------------------------- +// IPersistStream interface +// + +HRESULT +STDMETHODCALLTYPE +CKsProxy::IsDirty() +{ + OutputDebugStringW(L"CKsProxy::IsDirty Notimplemented\n"); + DebugBreak(); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::Load( + IStream *pStm) +{ + HRESULT hr; + WCHAR Buffer[1000]; + AM_MEDIA_TYPE MediaType; + ULONG BytesReturned; + LONG Length; + + ULONG PinId; + LPOLESTR pMajor, pSub, pFormat; + + OutputDebugStringW(L"CKsProxy::Load\n"); + +#if 0 + ULONG Version = ReadInt(pStm, hr); + if (Version != 1) + return E_FAIL; +#endif + + hr = pStm->Read(&Length, sizeof(ULONG), &BytesReturned); + swprintf(Buffer, L"Length hr %x hr length %lu\n", hr, Length); + OutputDebugStringW(Buffer); + + do + { + hr = pStm->Read(&PinId, sizeof(ULONG), &BytesReturned); + swprintf(Buffer, L"Read: hr %08x PinId %lx BytesReturned %lu\n", hr, PinId, BytesReturned); + OutputDebugStringW(Buffer); + + if (FAILED(hr) || !BytesReturned) + break; + + Length -= BytesReturned; + + hr = pStm->Read(&MediaType, sizeof(AM_MEDIA_TYPE), &BytesReturned); + if (FAILED(hr) || BytesReturned != sizeof(AM_MEDIA_TYPE)) + { + swprintf(Buffer, L"Read failed with %lx\n", hr); + OutputDebugStringW(Buffer); + break; + } + + + StringFromIID(MediaType.majortype, &pMajor); + StringFromIID(MediaType.subtype , &pSub); + StringFromIID(MediaType.formattype, &pFormat); + + swprintf(Buffer, L"BytesReturned %lu majortype %s subtype %s bFixedSizeSamples %u bTemporalCompression %u lSampleSize %u formattype %s, pUnk %p cbFormat %u pbFormat %p\n", BytesReturned, pMajor, pSub, MediaType.bFixedSizeSamples, MediaType.bTemporalCompression, MediaType.lSampleSize, pFormat, MediaType.pUnk, MediaType.cbFormat, MediaType.pbFormat); + OutputDebugStringW(Buffer); + + Length -= BytesReturned; + + + if (MediaType.cbFormat) + { + MediaType.pbFormat = (BYTE*)CoTaskMemAlloc(MediaType.cbFormat); + if (!MediaType.pbFormat) + return E_OUTOFMEMORY; + + hr = pStm->Read(&MediaType.pbFormat, sizeof(MediaType.cbFormat), &BytesReturned); + if (FAILED(hr)) + { + swprintf(Buffer, L"ReadFormat failed with %lx\n", hr); + OutputDebugStringW(Buffer); + break; + } + Length -= BytesReturned; + } + + }while(Length > 0); + + DebugBreak(); + return S_OK; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::Save( + IStream *pStm, + BOOL fClearDirty) +{ + OutputDebugStringW(L"CKsProxy::Save Notimplemented\n"); + return E_NOTIMPL; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::GetSizeMax( + ULARGE_INTEGER *pcbSize) +{ + OutputDebugStringW(L"CKsProxy::GetSizeMax Notimplemented\n"); + DebugBreak(); + return E_NOTIMPL; +} + +//------------------------------------------------------------------- +// IAMDeviceRemoval interface +// + +HRESULT +STDMETHODCALLTYPE +CKsProxy::DeviceInfo(CLSID *pclsidInterfaceClass, LPWSTR *pwszSymbolicLink) +{ + if (!m_DevicePath) + { + // object not initialized + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND); + } + + // copy device interface guid + CopyMemory(pclsidInterfaceClass, &m_DeviceInterfaceGUID, sizeof(GUID)); + + if (pwszSymbolicLink) + { + *pwszSymbolicLink = (LPWSTR)CoTaskMemAlloc((wcslen(m_DevicePath)+1) * sizeof(WCHAR)); + if (!*pwszSymbolicLink) + return E_OUTOFMEMORY; + + wcscpy(*pwszSymbolicLink, m_DevicePath); + } + return S_OK; +} +HRESULT +STDMETHODCALLTYPE +CKsProxy::Reassociate(void) +{ + if (!m_DevicePath || m_hDevice) + { + // file path not available + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND); + } + + m_hDevice = CreateFileW(m_DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); + if (!m_hDevice) + { + // failed to open device + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); + } + + // success + return NOERROR; +} + +HRESULT +STDMETHODCALLTYPE +CKsProxy::Disassociate(void) +{ + if (!m_hDevice) + return E_HANDLE; + + CloseHandle(m_hDevice); + m_hDevice = NULL; + return NOERROR; +} + + + + //------------------------------------------------------------------- // IKsObject interface // @@ -523,7 +1478,7 @@ CKsProxy::CreatePins() } else { - hr = COutputPin_Constructor((IBaseFilter*)this, PinName, IID_IPin, (void**)&pPin); + hr = COutputPin_Constructor((IBaseFilter*)this, PinName, Index, IID_IPin, (void**)&pPin); if (FAILED(hr)) { CoTaskMemFree(PinName); @@ -551,6 +1506,9 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog) VARIANT varName; LPGUID pGuid; ULONG NumGuids = 0; + HDEVINFO hList; + SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; + // read device path varName.vt = VT_BSTR; @@ -563,6 +1521,27 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); } + // create device list + hList = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL); + if (hList == INVALID_HANDLE_VALUE) + { + // failed to create device list + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); + } + + DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + if (!SetupDiOpenDeviceInterfaceW(hList, (PCWSTR)varName.bstrVal, 0, &DeviceInterfaceData)) + { + // failed to open device interface + SetupDiDestroyDeviceInfoList(hList); + } + + // FIXME handle device interface links(aliases) + CopyMemory(&m_DeviceInterfaceGUID, &DeviceInterfaceData.InterfaceClassGuid, sizeof(GUID)); + + // close device info list + SetupDiDestroyDeviceInfoList(hList); + // open device m_hDevice = CreateFileW(varName.bstrVal, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); @@ -575,6 +1554,9 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); } + // store device path + m_DevicePath = varName.bstrVal; + // get all supported sets hr = GetSupportedSets(&pGuid, &NumGuids); if (FAILED(hr)) @@ -611,7 +1593,7 @@ CKsProxy::Save(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties //------------------------------------------------------------------- // IBaseFilter interface -// +// HRESULT STDMETHODCALLTYPE diff --git a/reactos/dll/directx/ksproxy/qualityforward.cpp b/reactos/dll/directx/ksproxy/qualityforward.cpp index 3081d834cbf..88459d8275d 100644 --- a/reactos/dll/directx/ksproxy/qualityforward.cpp +++ b/reactos/dll/directx/ksproxy/qualityforward.cpp @@ -8,7 +8,11 @@ */ #include "precomp.h" +#ifndef _MSC_VER const GUID KSCATEGORY_QUALITY = {0x97EBAACB, 0x95BD, 0x11D0, {0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +#endif + +#define IID_IKsQualityForwarder KSCATEGORY_QUALITY class CKsQualityForwarder : public IKsQualityForwarder {