ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

proxy.cpp
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS WDM Streaming ActiveMovie Proxy
00004  * FILE:            dll/directx/ksproxy/proxy.cpp
00005  * PURPOSE:         IKsProxy interface
00006  *
00007  * PROGRAMMERS:     Johannes Anderwald (janderwald@reactos.org)
00008  */
00009 #include "precomp.h"
00010 
00011 #ifndef _MSC_VER
00012 const GUID IID_IPersistPropertyBag = {0x37D84F60, 0x42CB, 0x11CE, {0x81, 0x35, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51}};
00013 const GUID GUID_NULL                     = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
00014 const GUID IID_ISpecifyPropertyPages = {0xB196B28B, 0xBAB4, 0x101A, {0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}};
00015 const GUID IID_IPersistStream = {0x00000109, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
00016 const GUID KSPROPSETID_MediaSeeking = {0xEE904F0CL, 0xD09B, 0x11D0, {0xAB, 0xE9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
00017 const GUID KSPROPSETID_Clock = {0xDF12A4C0L, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
00018 const GUID KSEVENTSETID_Clock = {0x364D8E20L, 0x62C7, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
00019 const GUID KSPROPSETID_Stream = {0x65aaba60L, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
00020 const GUID IID_IPersist = {0x0000010c, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
00021 #endif
00022 
00023 const GUID IID_IBDA_DeviceControl = {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}};
00024 const GUID IID_IKsAggregateControl = {0x7F40EAC0, 0x3947, 0x11D2, {0x87, 0x4E, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
00025 const GUID IID_IKsClockPropertySet = {0x5C5CBD84, 0xE755, 0x11D0, {0xAC, 0x18, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
00026 const GUID IID_IKsTopology             = {0x28F54683, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
00027 const GUID IID_IKsClock            = {0x877E4351, 0x6FEA, 0x11D0, {0xB8, 0x63, 0x00, 0xAA, 0x00, 0xA2, 0x16, 0xA1}};
00028 /*
00029     Needs IKsClock, IKsNotifyEvent
00030 */
00031 
00032 class CKsProxy : public IBaseFilter,
00033                  public IAMovieSetup,
00034                  public IPersistPropertyBag,
00035                  public IKsObject,
00036                  public IPersistStream,
00037                  public IAMDeviceRemoval,
00038                  public ISpecifyPropertyPages,
00039                  public IReferenceClock,
00040                  public IMediaSeeking,
00041                  public IKsPropertySet,
00042                  public IKsClock,
00043                  public IKsClockPropertySet,
00044                  public IAMFilterMiscFlags,
00045                  public IKsControl,
00046                  public IKsTopology,
00047                  public IKsAggregateControl
00048 
00049 {
00050 public:
00051     typedef std::vector<IUnknown *>ProxyPluginVector;
00052     typedef std::vector<IPin *> PinVector;
00053 
00054     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
00055 
00056     STDMETHODIMP_(ULONG) AddRef()
00057     {
00058         InterlockedIncrement(&m_Ref);
00059         return m_Ref;
00060     }
00061     STDMETHODIMP_(ULONG) Release()
00062     {
00063         InterlockedDecrement(&m_Ref);
00064         if (!m_Ref)
00065         {
00066             //delete this;
00067             return 0;
00068         }
00069         return m_Ref;
00070     }
00071 
00072     // IBaseFilter methods
00073     HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
00074     HRESULT STDMETHODCALLTYPE Stop( void);
00075     HRESULT STDMETHODCALLTYPE Pause( void);
00076     HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart);
00077     HRESULT STDMETHODCALLTYPE GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *State);
00078     HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock);
00079     HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock **pClock);
00080     HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins **ppEnum);
00081     HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR Id, IPin **ppPin);
00082     HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO *pInfo);
00083     HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName);
00084     HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *pVendorInfo);
00085 
00086     //IReferenceClock
00087     HRESULT STDMETHODCALLTYPE GetTime(REFERENCE_TIME *pTime);
00088     HRESULT STDMETHODCALLTYPE AdviseTime(REFERENCE_TIME baseTime, REFERENCE_TIME streamTime, HEVENT hEvent, DWORD_PTR *pdwAdviseCookie);
00089     HRESULT STDMETHODCALLTYPE AdvisePeriodic(REFERENCE_TIME startTime, REFERENCE_TIME periodTime, HSEMAPHORE hSemaphore, DWORD_PTR *pdwAdviseCookie);
00090     HRESULT STDMETHODCALLTYPE Unadvise(DWORD_PTR dwAdviseCookie);
00091 
00092     //IMediaSeeking
00093     HRESULT STDMETHODCALLTYPE GetCapabilities(DWORD *pCapabilities);
00094     HRESULT STDMETHODCALLTYPE CheckCapabilities(DWORD *pCapabilities);
00095     HRESULT STDMETHODCALLTYPE IsFormatSupported(const GUID *pFormat);
00096     HRESULT STDMETHODCALLTYPE QueryPreferredFormat(GUID *pFormat);
00097     HRESULT STDMETHODCALLTYPE GetTimeFormat(GUID *pFormat);
00098     HRESULT STDMETHODCALLTYPE IsUsingTimeFormat(const GUID *pFormat);
00099     HRESULT STDMETHODCALLTYPE SetTimeFormat(const GUID *pFormat);
00100     HRESULT STDMETHODCALLTYPE GetDuration(LONGLONG *pDuration);
00101     HRESULT STDMETHODCALLTYPE GetStopPosition(LONGLONG *pStop);
00102     HRESULT STDMETHODCALLTYPE GetCurrentPosition(LONGLONG *pCurrent);
00103     HRESULT STDMETHODCALLTYPE ConvertTimeFormat(LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat);
00104     HRESULT STDMETHODCALLTYPE SetPositions(LONGLONG *pCurrent, DWORD dwCurrentFlags, LONGLONG *pStop, DWORD dwStopFlags);
00105     HRESULT STDMETHODCALLTYPE GetPositions(LONGLONG *pCurrent, LONGLONG *pStop);
00106     HRESULT STDMETHODCALLTYPE GetAvailable(LONGLONG *pEarliest, LONGLONG *pLatest);
00107     HRESULT STDMETHODCALLTYPE SetRate(double dRate);
00108     HRESULT STDMETHODCALLTYPE GetRate(double *pdRate);
00109     HRESULT STDMETHODCALLTYPE GetPreroll(LONGLONG *pllPreroll);
00110 
00111     //IKsPropertySet
00112     HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData);
00113     HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD *pcbReturned);
00114     HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport);
00115 
00116     //IAMFilterMiscFlags
00117     ULONG STDMETHODCALLTYPE GetMiscFlags( void);
00118 
00119     //IKsControl
00120     HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned);
00121     HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned);
00122     HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned);
00123 
00124     //IKsTopolology
00125     HRESULT STDMETHODCALLTYPE CreateNodeInstance(ULONG NodeId, ULONG Flags, ACCESS_MASK DesiredAccess, IUnknown* UnkOuter, REFGUID InterfaceId, LPVOID* Interface);
00126 
00127     //IKsAggregateControl
00128     HRESULT STDMETHODCALLTYPE KsAddAggregate(IN REFGUID AggregateClass);
00129     HRESULT STDMETHODCALLTYPE KsRemoveAggregate(REFGUID AggregateClass);
00130 
00131     //IKsClockPropertySet
00132     HRESULT STDMETHODCALLTYPE KsGetTime(LONGLONG* Time);
00133     HRESULT STDMETHODCALLTYPE KsSetTime(LONGLONG Time);
00134     HRESULT STDMETHODCALLTYPE KsGetPhysicalTime(LONGLONG* Time);
00135     HRESULT STDMETHODCALLTYPE KsSetPhysicalTime(LONGLONG Time);
00136     HRESULT STDMETHODCALLTYPE KsGetCorrelatedTime(KSCORRELATED_TIME* CorrelatedTime);
00137     HRESULT STDMETHODCALLTYPE KsSetCorrelatedTime(KSCORRELATED_TIME* CorrelatedTime);
00138     HRESULT STDMETHODCALLTYPE KsGetCorrelatedPhysicalTime(KSCORRELATED_TIME* CorrelatedTime);
00139     HRESULT STDMETHODCALLTYPE KsSetCorrelatedPhysicalTime(KSCORRELATED_TIME* CorrelatedTime);
00140     HRESULT STDMETHODCALLTYPE KsGetResolution(KSRESOLUTION* Resolution);
00141     HRESULT STDMETHODCALLTYPE KsGetState(KSSTATE* State);
00142 
00143 
00144     //IAMovieSetup methods
00145     HRESULT STDMETHODCALLTYPE Register( void);
00146     HRESULT STDMETHODCALLTYPE Unregister( void);
00147 
00148     // IPersistPropertyBag methods
00149     HRESULT STDMETHODCALLTYPE InitNew( void);
00150     HRESULT STDMETHODCALLTYPE Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog);
00151     HRESULT STDMETHODCALLTYPE Save(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties);
00152 
00153     // IKsObject
00154     HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
00155 
00156     // IKsClock
00157     HANDLE STDMETHODCALLTYPE KsGetClockHandle();
00158 
00159     //IAMDeviceRemoval
00160     HRESULT STDMETHODCALLTYPE DeviceInfo(CLSID *pclsidInterfaceClass, LPWSTR *pwszSymbolicLink);
00161     HRESULT STDMETHODCALLTYPE Reassociate(void);
00162     HRESULT STDMETHODCALLTYPE Disassociate( void);
00163 
00164     //IPersistStream
00165     HRESULT STDMETHODCALLTYPE IsDirty( void);
00166     HRESULT STDMETHODCALLTYPE Load(IStream *pStm);
00167     HRESULT STDMETHODCALLTYPE Save(IStream *pStm, BOOL fClearDirty);
00168     HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize);
00169 
00170     // ISpecifyPropertyPages
00171     HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages);
00172 
00173 
00174     CKsProxy();
00175     ~CKsProxy()
00176     {
00177         if (m_hDevice)
00178             CloseHandle(m_hDevice);
00179     };
00180 
00181     HRESULT STDMETHODCALLTYPE GetSupportedSets(LPGUID * pOutGuid, PULONG NumGuids);
00182     HRESULT STDMETHODCALLTYPE LoadProxyPlugins(LPGUID pGuids, ULONG NumGuids);
00183     HRESULT STDMETHODCALLTYPE GetNumberOfPins(PULONG NumPins);
00184     HRESULT STDMETHODCALLTYPE GetPinInstanceCount(ULONG PinId, PKSPIN_CINSTANCES Instances);
00185     HRESULT STDMETHODCALLTYPE GetPinDataflow(ULONG PinId, KSPIN_DATAFLOW * DataFlow);
00186     HRESULT STDMETHODCALLTYPE GetPinName(ULONG PinId, KSPIN_DATAFLOW DataFlow, ULONG PinCount, LPWSTR * OutPinName);
00187     HRESULT STDMETHODCALLTYPE GetPinCommunication(ULONG PinId, KSPIN_COMMUNICATION * Communication);
00188     HRESULT STDMETHODCALLTYPE CreatePins();
00189     HRESULT STDMETHODCALLTYPE GetMediaSeekingFormats(PKSMULTIPLE_ITEM *FormatList);
00190     HRESULT STDMETHODCALLTYPE CreateClockInstance();
00191     HRESULT STDMETHODCALLTYPE PerformClockProperty(ULONG PropertyId, ULONG PropertyFlags, PVOID OutputBuffer, ULONG OutputBufferSize);
00192     HRESULT STDMETHODCALLTYPE SetPinState(KSSTATE State);
00193 
00194 
00195 protected:
00196     LONG m_Ref;
00197     IFilterGraph *m_pGraph;
00198     IReferenceClock * m_ReferenceClock;
00199     FILTER_STATE m_FilterState;
00200     HANDLE m_hDevice;
00201     ProxyPluginVector m_Plugins;
00202     PinVector m_Pins;
00203     LPWSTR m_DevicePath;
00204     CLSID m_DeviceInterfaceGUID;
00205     HANDLE m_hClock;
00206     CRITICAL_SECTION m_Lock;
00207 };
00208 
00209 CKsProxy::CKsProxy() : m_Ref(0),
00210                        m_pGraph(0),
00211                        m_ReferenceClock((IReferenceClock*)this),
00212                        m_FilterState(State_Stopped),
00213                        m_hDevice(0),
00214                        m_Plugins(),
00215                        m_Pins(),
00216                        m_DevicePath(0),
00217                        m_hClock(0)
00218 {
00219     InitializeCriticalSection(&m_Lock);
00220 }
00221 
00222 
00223 HRESULT
00224 STDMETHODCALLTYPE
00225 CKsProxy::QueryInterface(
00226     IN  REFIID refiid,
00227     OUT PVOID* Output)
00228 {
00229     *Output = NULL;
00230 
00231     if (IsEqualGUID(refiid, IID_IUnknown) ||
00232         IsEqualGUID(refiid, IID_IBaseFilter))
00233     {
00234         *Output = PVOID(this);
00235         reinterpret_cast<IUnknown*>(*Output)->AddRef();
00236         return NOERROR;
00237     }
00238     else if (IsEqualGUID(refiid, IID_IPersistPropertyBag))
00239     {
00240         *Output = (IPersistPropertyBag*)(this);
00241         reinterpret_cast<IPersistPropertyBag*>(*Output)->AddRef();
00242         return NOERROR;
00243     }
00244     else if (IsEqualGUID(refiid, IID_IAMDeviceRemoval))
00245     {
00246         *Output = (IAMDeviceRemoval*)(this);
00247         reinterpret_cast<IAMDeviceRemoval*>(*Output)->AddRef();
00248         return NOERROR;
00249     }
00250     else if (IsEqualGUID(refiid, IID_IPersistStream))
00251     {
00252         *Output = (IPersistStream*)(this);
00253         reinterpret_cast<IPersistStream*>(*Output)->AddRef();
00254         return NOERROR;
00255     }
00256     else if (IsEqualGUID(refiid, IID_IPersist))
00257     {
00258         *Output = (IPersistStream*)(this);
00259         reinterpret_cast<IPersist*>(*Output)->AddRef();
00260         return NOERROR;
00261     }
00262     else if (IsEqualGUID(refiid, IID_IKsObject))
00263     {
00264         *Output = (IKsObject*)(this);
00265         reinterpret_cast<IKsObject*>(*Output)->AddRef();
00266         return NOERROR;
00267     }
00268     else if (IsEqualGUID(refiid, IID_IKsClock))
00269     {
00270         *Output = (IKsClock*)(this);
00271         reinterpret_cast<IKsClock*>(*Output)->AddRef();
00272         return NOERROR;
00273     }
00274     else if (IsEqualGUID(refiid, IID_IReferenceClock))
00275     {
00276         if (!m_hClock)
00277         {
00278             HRESULT hr = CreateClockInstance();
00279             if (FAILED(hr))
00280                 return hr;
00281         }
00282 
00283         *Output = (IReferenceClock*)(this);
00284         reinterpret_cast<IReferenceClock*>(*Output)->AddRef();
00285         return NOERROR;
00286     }
00287     else if (IsEqualGUID(refiid, IID_IMediaSeeking))
00288     {
00289         *Output = (IMediaSeeking*)(this);
00290         reinterpret_cast<IMediaSeeking*>(*Output)->AddRef();
00291         return NOERROR;
00292     }
00293     else if (IsEqualGUID(refiid, IID_IAMFilterMiscFlags))
00294     {
00295         *Output = (IAMFilterMiscFlags*)(this);
00296         reinterpret_cast<IAMFilterMiscFlags*>(*Output)->AddRef();
00297         return NOERROR;
00298     }
00299     else if (IsEqualGUID(refiid, IID_IKsControl))
00300     {
00301         *Output = (IKsControl*)(this);
00302         reinterpret_cast<IKsControl*>(*Output)->AddRef();
00303         return NOERROR;
00304     }
00305     else if (IsEqualGUID(refiid, IID_IKsPropertySet))
00306     {
00307         *Output = (IKsPropertySet*)(this);
00308         reinterpret_cast<IKsPropertySet*>(*Output)->AddRef();
00309         return NOERROR;
00310     }
00311     else if (IsEqualGUID(refiid, IID_IKsTopology))
00312     {
00313         *Output = (IKsTopology*)(this);
00314         reinterpret_cast<IKsTopology*>(*Output)->AddRef();
00315         return NOERROR;
00316     }
00317     else if (IsEqualGUID(refiid, IID_IKsAggregateControl))
00318     {
00319         *Output = (IKsAggregateControl*)(this);
00320         reinterpret_cast<IKsAggregateControl*>(*Output)->AddRef();
00321         return NOERROR;
00322     }
00323     else if (IsEqualGUID(refiid, IID_IKsClockPropertySet))
00324     {
00325         if (!m_hClock)
00326         {
00327             HRESULT hr = CreateClockInstance();
00328             if (FAILED(hr))
00329                 return hr;
00330         }
00331 
00332         *Output = (IKsClockPropertySet*)(this);
00333         reinterpret_cast<IKsClockPropertySet*>(*Output)->AddRef();
00334         return NOERROR;
00335     }
00336     else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages))
00337     {
00338         *Output = (ISpecifyPropertyPages*)(this);
00339         reinterpret_cast<ISpecifyPropertyPages*>(*Output)->AddRef();
00340         return NOERROR;
00341     }
00342 
00343     for(ULONG Index = 0; Index < m_Plugins.size(); Index++)
00344     {
00345         if (m_Pins[Index])
00346         {
00347             HRESULT hr = m_Plugins[Index]->QueryInterface(refiid, Output);
00348             if (SUCCEEDED(hr))
00349             {
00350 #ifdef KSPROXY_TRACE
00351                 WCHAR Buffer[100];
00352                 LPOLESTR lpstr;
00353                 StringFromCLSID(refiid, &lpstr);
00354                 swprintf(Buffer, L"CKsProxy::QueryInterface plugin %lu supports interface %s\n", Index, lpstr);
00355                 OutputDebugStringW(Buffer);
00356                 CoTaskMemFree(lpstr);
00357 #endif
00358                 return hr;
00359             }
00360         }
00361     }
00362 #ifdef KSPROXY_TRACE
00363     WCHAR Buffer[MAX_PATH];
00364     LPOLESTR lpstr;
00365     StringFromCLSID(refiid, &lpstr);
00366     swprintf(Buffer, L"CKsProxy::QueryInterface: NoInterface for %s !!!\n", lpstr);
00367     OutputDebugStringW(Buffer);
00368     CoTaskMemFree(lpstr);
00369 #endif
00370 
00371     return E_NOINTERFACE;
00372 }
00373 
00374 //-------------------------------------------------------------------
00375 // ISpecifyPropertyPages
00376 //
00377 
00378 HRESULT
00379 STDMETHODCALLTYPE
00380 CKsProxy::GetPages(CAUUID *pPages)
00381 {
00382 #ifdef KSPROXY_TRACE
00383     OutputDebugStringW(L"CKsProxy::GetPages NotImplemented\n");
00384 #endif
00385 
00386     if (!pPages)
00387         return E_POINTER;
00388 
00389     pPages->cElems = 0;
00390     pPages->pElems = NULL;
00391 
00392     return S_OK;
00393 }
00394 
00395 //-------------------------------------------------------------------
00396 // IKsClockPropertySet interface
00397 //
00398 
00399 HRESULT
00400 STDMETHODCALLTYPE
00401 CKsProxy::CreateClockInstance()
00402 {
00403     HRESULT hr;
00404     HANDLE hPin = INVALID_HANDLE_VALUE;
00405     ULONG Index;
00406     PIN_DIRECTION PinDir;
00407     IKsObject *pObject;
00408     KSCLOCK_CREATE ClockCreate;
00409 
00410     // find output pin and handle
00411     for(Index = 0; Index < m_Pins.size(); Index++)
00412     {
00413         //get pin
00414         IPin * pin = m_Pins[Index];
00415         if (!pin)
00416             continue;
00417 
00418         // get direction
00419         hr = pin->QueryDirection(&PinDir);
00420         if (FAILED(hr))
00421             continue;
00422 
00423         // query IKsObject interface
00424         hr = pin->QueryInterface(IID_IKsObject, (void**)&pObject);
00425         if (FAILED(hr))
00426             continue;
00427 
00428 
00429         // get pin handle
00430         hPin = pObject->KsGetObjectHandle();
00431 
00432         //release IKsObject
00433         pObject->Release();
00434 
00435         if (hPin != INVALID_HANDLE_VALUE)
00436             break;
00437     }
00438 
00439     if (hPin == INVALID_HANDLE_VALUE)
00440     {
00441         // clock can only be instantiated on a pin handle
00442         return E_NOTIMPL;
00443     }
00444 
00445     if (m_hClock)
00446     {
00447         // release clock handle
00448         CloseHandle(m_hClock);
00449     }
00450 
00451     //setup clock create request
00452     ClockCreate.CreateFlags = 0;
00453 
00454     // setup clock create request
00455     hr = KsCreateClock(hPin, &ClockCreate, &m_hClock); // FIXME KsCreateClock returns NTSTATUS
00456     if (SUCCEEDED(hr))
00457     {
00458         // failed to create clock
00459         return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
00460     }
00461 
00462     return S_OK;
00463 }
00464 
00465 HRESULT
00466 STDMETHODCALLTYPE
00467 CKsProxy::PerformClockProperty(
00468     ULONG PropertyId,
00469     ULONG PropertyFlags,
00470     PVOID OutputBuffer,
00471     ULONG OutputBufferSize)
00472 {
00473     KSPROPERTY Property;
00474     HRESULT hr;
00475     ULONG BytesReturned;
00476 
00477     if (!m_hClock)
00478     {
00479         // create clock
00480         hr = CreateClockInstance();
00481         if (FAILED(hr))
00482             return hr;
00483     }
00484 
00485     // setup request
00486     Property.Set = KSPROPSETID_Clock;
00487     Property.Id = PropertyId;
00488     Property.Flags = PropertyFlags;
00489 
00490     hr = KsSynchronousDeviceControl(m_hClock, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)OutputBuffer, OutputBufferSize, &BytesReturned);
00491 
00492     return hr;
00493 }
00494 
00495 HRESULT
00496 STDMETHODCALLTYPE
00497 CKsProxy::KsGetTime(
00498     LONGLONG* Time)
00499 {
00500 #ifdef KSPROXY_TRACE
00501     OutputDebugStringW(L"CKsProxy::KsGetTime\n");
00502 #endif
00503 
00504     return PerformClockProperty(KSPROPERTY_CLOCK_TIME, KSPROPERTY_TYPE_GET, (PVOID)Time, sizeof(LONGLONG));
00505 }
00506 
00507 HRESULT
00508 STDMETHODCALLTYPE
00509 CKsProxy::KsSetTime(
00510     LONGLONG Time)
00511 {
00512 #ifdef KSPROXY_TRACE
00513     OutputDebugStringW(L"CKsProxy::KsSetTime\n");
00514 #endif
00515 
00516     return PerformClockProperty(KSPROPERTY_CLOCK_TIME, KSPROPERTY_TYPE_SET, (PVOID)&Time, sizeof(LONGLONG));
00517 }
00518 
00519 HRESULT
00520 STDMETHODCALLTYPE
00521 CKsProxy::KsGetPhysicalTime(
00522     LONGLONG* Time)
00523 {
00524 #ifdef KSPROXY_TRACE
00525     OutputDebugStringW(L"CKsProxy::KsGetPhysicalTime\n");
00526 #endif
00527 
00528     return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME, KSPROPERTY_TYPE_GET, (PVOID)Time, sizeof(LONGLONG));
00529 }
00530 
00531 HRESULT
00532 STDMETHODCALLTYPE
00533 CKsProxy::KsSetPhysicalTime(
00534     LONGLONG Time)
00535 {
00536 #ifdef KSPROXY_TRACE
00537     OutputDebugStringW(L"CKsProxy::KsSetPhysicalTime\n");
00538 #endif
00539 
00540     return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME, KSPROPERTY_TYPE_SET, (PVOID)&Time, sizeof(LONGLONG));
00541 }
00542 
00543 HRESULT
00544 STDMETHODCALLTYPE
00545 CKsProxy::KsGetCorrelatedTime(
00546     KSCORRELATED_TIME* CorrelatedTime)
00547 {
00548 #ifdef KSPROXY_TRACE
00549     OutputDebugStringW(L"CKsProxy::KsGetCorrelatedTime\n");
00550 #endif
00551 
00552     return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME, KSPROPERTY_TYPE_GET, (PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
00553 }
00554 
00555 HRESULT
00556 STDMETHODCALLTYPE
00557 CKsProxy::KsSetCorrelatedTime(
00558     KSCORRELATED_TIME* CorrelatedTime)
00559 {
00560 #ifdef KSPROXY_TRACE
00561     OutputDebugStringW(L"CKsProxy::KsSetCorrelatedTime\n");
00562 #endif
00563     return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME, KSPROPERTY_TYPE_SET, (PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
00564 }
00565 
00566 HRESULT
00567 STDMETHODCALLTYPE
00568 CKsProxy::KsGetCorrelatedPhysicalTime(
00569     KSCORRELATED_TIME* CorrelatedTime)
00570 {
00571 #ifdef KSPROXY_TRACE
00572     OutputDebugStringW(L"CKsProxy::KsGetCorrelatedPhysicalTime\n");
00573 #endif
00574     return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME, KSPROPERTY_TYPE_GET, (PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
00575 }
00576 
00577 HRESULT
00578 STDMETHODCALLTYPE
00579 CKsProxy::KsSetCorrelatedPhysicalTime(
00580     KSCORRELATED_TIME* CorrelatedTime)
00581 {
00582 #ifdef KSPROXY_TRACE
00583     OutputDebugStringW(L"CKsProxy::KsSetCorrelatedPhysicalTime\n");
00584 #endif
00585 
00586     return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME, KSPROPERTY_TYPE_SET, (PVOID)CorrelatedTime, sizeof(KSCORRELATED_TIME));
00587 }
00588 
00589 HRESULT
00590 STDMETHODCALLTYPE
00591 CKsProxy::KsGetResolution(
00592     KSRESOLUTION* Resolution)
00593 {
00594 #ifdef KSPROXY_TRACE
00595     OutputDebugStringW(L"CKsProxy::KsGetResolution\n");
00596 #endif
00597     return PerformClockProperty(KSPROPERTY_CLOCK_RESOLUTION, KSPROPERTY_TYPE_GET, (PVOID)Resolution, sizeof(KSRESOLUTION));
00598 }
00599 
00600 HRESULT
00601 STDMETHODCALLTYPE
00602 CKsProxy::KsGetState(
00603     KSSTATE* State)
00604 {
00605 #ifdef KSPROXY_TRACE
00606     OutputDebugStringW(L"CKsProxy::KsGetState\n");
00607 #endif
00608     return PerformClockProperty(KSPROPERTY_CLOCK_STATE, KSPROPERTY_TYPE_GET, (PVOID)State, sizeof(KSSTATE));
00609 }
00610 
00611 //-------------------------------------------------------------------
00612 // IReferenceClock interface
00613 //
00614 HRESULT
00615 STDMETHODCALLTYPE
00616 CKsProxy::GetTime(
00617     REFERENCE_TIME *pTime)
00618 {
00619     HRESULT hr;
00620     KSPROPERTY Property;
00621     ULONG BytesReturned;
00622 
00623 #ifdef KSPROXY_TRACE
00624     OutputDebugStringW(L"CKsProxy::GetTime\n");
00625 #endif
00626 
00627     if (!pTime)
00628         return E_POINTER;
00629 
00630     //
00631     //FIXME locks
00632     //
00633 
00634     if (!m_hClock)
00635     {
00636         // create clock
00637         hr = CreateClockInstance();
00638         if (FAILED(hr))
00639             return hr;
00640     }
00641 
00642     // setup request
00643     Property.Set = KSPROPSETID_Clock;
00644     Property.Id = KSPROPERTY_CLOCK_TIME;
00645     Property.Flags = KSPROPERTY_TYPE_GET;
00646 
00647     // perform request
00648     hr = KsSynchronousDeviceControl(m_hClock, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pTime, sizeof(REFERENCE_TIME), &BytesReturned);
00649 
00650     // TODO
00651     // increment value
00652     //
00653 
00654     return hr;
00655 }
00656 
00657 HRESULT
00658 STDMETHODCALLTYPE
00659 CKsProxy::AdviseTime(
00660     REFERENCE_TIME baseTime,
00661     REFERENCE_TIME streamTime,
00662     HEVENT hEvent,
00663     DWORD_PTR *pdwAdviseCookie)
00664 {
00665     HRESULT hr;
00666     KSEVENT Property;
00667     ULONG BytesReturned;
00668     PKSEVENT_TIME_MARK Event;
00669 
00670 #ifdef KSPROXY_TRACE
00671     OutputDebugStringW(L"CKsProxy::AdviseTime\n");
00672 #endif
00673 
00674     //
00675     //FIXME locks
00676     //
00677 
00678     if (!pdwAdviseCookie)
00679         return E_POINTER;
00680 
00681     if (!m_hClock)
00682     {
00683         // create clock
00684         hr = CreateClockInstance();
00685         if (FAILED(hr))
00686             return hr;
00687     }
00688 
00689     // allocate event entry
00690     Event = (PKSEVENT_TIME_MARK)CoTaskMemAlloc(sizeof(KSEVENT_TIME_MARK));
00691     if (Event)
00692     {
00693         // setup request
00694         Property.Set = KSEVENTSETID_Clock;
00695         Property.Id = KSEVENT_CLOCK_POSITION_MARK;
00696         Property.Flags = KSEVENT_TYPE_ENABLE;
00697 
00698         Event->EventData.NotificationType = KSEVENTF_EVENT_HANDLE;
00699         Event->EventData.EventHandle.Event = (HANDLE)hEvent;
00700         Event->EventData.Alignment.Alignment[0] = 0;
00701         Event->EventData.Alignment.Alignment[1] = 0;
00702         Event->MarkTime = baseTime + streamTime;
00703 
00704         // perform request
00705         hr = KsSynchronousDeviceControl(m_hClock, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSEVENT), (PVOID)Event, sizeof(KSEVENT_TIME_MARK), &BytesReturned);
00706         if (SUCCEEDED(hr))
00707         {
00708             // store event handle
00709             *pdwAdviseCookie = (DWORD_PTR)Event;
00710         }
00711         else
00712         {
00713             // failed to enable event
00714             CoTaskMemFree(Event);
00715         }
00716     }
00717     else
00718     {
00719          hr = E_OUTOFMEMORY;
00720     }
00721 
00722     return hr;
00723 }
00724 
00725 HRESULT
00726 STDMETHODCALLTYPE
00727 CKsProxy::AdvisePeriodic(
00728     REFERENCE_TIME startTime,
00729     REFERENCE_TIME periodTime,
00730     HSEMAPHORE hSemaphore,
00731     DWORD_PTR *pdwAdviseCookie)
00732 {
00733     HRESULT hr;
00734     KSEVENT Property;
00735     ULONG BytesReturned;
00736     PKSEVENT_TIME_INTERVAL Event;
00737 
00738 #ifdef KSPROXY_TRACE
00739     OutputDebugStringW(L"CKsProxy::AdvisePeriodic\n");
00740 #endif
00741 
00742     //
00743     //FIXME locks
00744     //
00745 
00746     if (!pdwAdviseCookie)
00747         return E_POINTER;
00748 
00749     if (!m_hClock)
00750     {
00751         // create clock
00752         hr = CreateClockInstance();
00753         if (FAILED(hr))
00754             return hr;
00755     }
00756 
00757     // allocate event entry
00758     Event = (PKSEVENT_TIME_INTERVAL)CoTaskMemAlloc(sizeof(KSEVENT_TIME_INTERVAL));
00759     if (Event)
00760     {
00761         // setup request
00762         Property.Set = KSEVENTSETID_Clock;
00763         Property.Id = KSEVENT_CLOCK_INTERVAL_MARK;
00764         Property.Flags = KSEVENT_TYPE_ENABLE;
00765 
00766         Event->EventData.NotificationType = KSEVENTF_SEMAPHORE_HANDLE;
00767         Event->EventData.SemaphoreHandle.Semaphore = (HANDLE)hSemaphore;
00768         Event->EventData.SemaphoreHandle.Reserved = 0;
00769         Event->EventData.SemaphoreHandle.Adjustment = 1;
00770         Event->TimeBase = startTime;
00771         Event->Interval = periodTime;
00772 
00773         // perform request
00774         hr = KsSynchronousDeviceControl(m_hClock, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSEVENT), (PVOID)Event, sizeof(KSEVENT_TIME_INTERVAL), &BytesReturned);
00775         if (SUCCEEDED(hr))
00776         {
00777             // store event handle
00778             *pdwAdviseCookie = (DWORD_PTR)Event;
00779         }
00780         else
00781         {
00782             // failed to enable event
00783             CoTaskMemFree(Event);
00784         }
00785     }
00786     else
00787     {
00788          hr = E_OUTOFMEMORY;
00789     }
00790 
00791     return hr;
00792 }
00793 
00794 HRESULT
00795 STDMETHODCALLTYPE
00796 CKsProxy::Unadvise(
00797     DWORD_PTR dwAdviseCookie)
00798 {
00799     HRESULT hr;
00800     ULONG BytesReturned;
00801 
00802 #ifdef KSPROXY_TRACE
00803     OutputDebugStringW(L"CKsProxy::Unadvise\n");
00804 #endif
00805 
00806     if (m_hClock)
00807     {
00808         //lets disable the event
00809         hr = KsSynchronousDeviceControl(m_hClock, IOCTL_KS_DISABLE_EVENT, (PVOID)dwAdviseCookie, sizeof(KSEVENTDATA), 0, 0, &BytesReturned);
00810         if (SUCCEEDED(hr))
00811         {
00812             // lets free event data
00813             CoTaskMemFree((LPVOID)dwAdviseCookie);
00814         }
00815     }
00816     else
00817     {
00818         // no clock available
00819         hr = E_FAIL;
00820     }
00821 
00822     return hr;
00823 }
00824 
00825 //-------------------------------------------------------------------
00826 // IMediaSeeking interface
00827 //
00828 HRESULT
00829 STDMETHODCALLTYPE
00830 CKsProxy::GetCapabilities(
00831     DWORD *pCapabilities)
00832 {
00833     KSPROPERTY Property;
00834     ULONG BytesReturned, Index;
00835     HRESULT hr = S_OK;
00836     DWORD TempCaps;
00837 
00838     Property.Set = KSPROPSETID_MediaSeeking;
00839     Property.Id = KSPROPERTY_MEDIASEEKING_CAPABILITIES;
00840     Property.Flags = KSPROPERTY_TYPE_GET;
00841 
00842 #ifdef KSPROXY_TRACE
00843     OutputDebugStringW(L"CKsProxy::GetCapabilities\n");
00844 #endif
00845 
00846 
00847     if (!pCapabilities)
00848         return E_POINTER;
00849 
00850 
00851     *pCapabilities = (KS_SEEKING_CanSeekAbsolute | KS_SEEKING_CanSeekForwards | KS_SEEKING_CanSeekBackwards | KS_SEEKING_CanGetCurrentPos |
00852                       KS_SEEKING_CanGetStopPos | KS_SEEKING_CanGetDuration | KS_SEEKING_CanPlayBackwards);
00853 
00854     KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pCapabilities, sizeof(KS_SEEKING_CAPABILITIES), &BytesReturned);
00855     // check if plugins support it
00856     for(Index = 0; Index < m_Plugins.size(); Index++)
00857     {
00858         // get plugin
00859         IUnknown * Plugin = m_Plugins[Index];
00860 
00861         if (!Plugin)
00862            continue;
00863 
00864         // query for IMediaSeeking interface
00865         IMediaSeeking *pSeek = NULL;
00866         hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
00867         if (FAILED(hr))
00868         {
00869             *pCapabilities = 0;
00870             return hr;
00871         }
00872 
00873         TempCaps = 0;
00874         // set time format
00875         hr = pSeek->GetCapabilities(&TempCaps);
00876         if (SUCCEEDED(hr))
00877         {
00878             // and with supported flags
00879             *pCapabilities = (*pCapabilities & TempCaps);
00880         }
00881         // release IMediaSeeking interface
00882         pSeek->Release();
00883     }
00884     return hr;
00885 }
00886 
00887 HRESULT
00888 STDMETHODCALLTYPE
00889 CKsProxy::CheckCapabilities(
00890     DWORD *pCapabilities)
00891 {
00892     DWORD Capabilities;
00893     HRESULT hr;
00894 
00895 #ifdef KSPROXY_TRACE
00896     OutputDebugStringW(L"CKsProxy::CheckCapabilities\n");
00897 #endif
00898 
00899     if (!pCapabilities)
00900         return E_POINTER;
00901 
00902     if (!*pCapabilities)
00903         return E_FAIL;
00904 
00905     hr = GetCapabilities(&Capabilities);
00906     if (SUCCEEDED(hr))
00907     {
00908         if ((Capabilities | *pCapabilities) == Capabilities)
00909         {
00910             // all present
00911             return S_OK;
00912         }
00913 
00914         Capabilities = (Capabilities & *pCapabilities);
00915         if (Capabilities)
00916         {
00917             // not all present
00918             *pCapabilities = Capabilities;
00919             return S_FALSE;
00920         }
00921         // no capabilities are present
00922         return E_FAIL;
00923     }
00924 
00925     return hr;
00926 }
00927 
00928 HRESULT
00929 STDMETHODCALLTYPE
00930 CKsProxy::GetMediaSeekingFormats(
00931     PKSMULTIPLE_ITEM *FormatList)
00932 {
00933     KSPROPERTY Property;
00934     HRESULT hr;
00935     ULONG BytesReturned;
00936 
00937     Property.Set = KSPROPSETID_MediaSeeking;
00938     Property.Id = KSPROPERTY_MEDIASEEKING_FORMATS;
00939     Property.Flags = KSPROPERTY_TYPE_GET;
00940 
00941     // query for format size list
00942     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &BytesReturned);
00943 
00944     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA))
00945     {
00946         // allocate format list
00947         *FormatList = (PKSMULTIPLE_ITEM)CoTaskMemAlloc(BytesReturned);
00948         if (!*FormatList)
00949         {
00950             // not enough memory
00951             return E_OUTOFMEMORY;
00952         }
00953 
00954         // get format list
00955         hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)*FormatList, BytesReturned, &BytesReturned);
00956         if (FAILED(hr))
00957         {
00958             // failed to query format list
00959             CoTaskMemFree(FormatList);
00960         }
00961     }
00962     return hr;
00963 }
00964 
00965 HRESULT
00966 STDMETHODCALLTYPE
00967 CKsProxy::IsFormatSupported(
00968     const GUID *pFormat)
00969 {
00970     PKSMULTIPLE_ITEM FormatList;
00971     LPGUID pGuid;
00972     ULONG Index;
00973     HRESULT hr = S_FALSE;
00974 
00975 #ifdef KSPROXY_TRACE
00976     WCHAR Buffer[100];
00977     LPOLESTR pstr;
00978     StringFromCLSID(*pFormat, &pstr);
00979     swprintf(Buffer, L"CKsProxy::IsFormatSupported %s\n",pstr);
00980     OutputDebugStringW(Buffer);
00981 #endif
00982 
00983     if (!pFormat)
00984         return E_POINTER;
00985 
00986     // get media formats
00987     hr = GetMediaSeekingFormats(&FormatList);
00988     if (SUCCEEDED(hr))
00989     {
00990 #ifdef KSPROXY_TRACE
00991         swprintf(Buffer, L"CKsProxy::IsFormatSupported NumFormat %lu\n",FormatList->Count);
00992         OutputDebugStringW(Buffer);
00993 #endif
00994 
00995         //iterate through format list
00996         pGuid = (LPGUID)(FormatList + 1);
00997         for(Index = 0; Index < FormatList->Count; Index++)
00998         {
00999             if (IsEqualGUID(*pGuid, *pFormat))
01000             {
01001                 CoTaskMemFree(FormatList);
01002                 return S_OK;
01003             }
01004             pGuid++;
01005         }
01006         // free format list
01007         CoTaskMemFree(FormatList);
01008     }
01009 
01010     // check if all plugins support it
01011     for(Index = 0; Index < m_Plugins.size(); Index++)
01012     {
01013         // get plugin
01014         IUnknown * Plugin = m_Plugins[Index];
01015 
01016         if (!Plugin)
01017             continue;
01018 
01019         // query for IMediaSeeking interface
01020         IMediaSeeking *pSeek = NULL;
01021         hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
01022         if (FAILED(hr))
01023         {
01024             // plugin does not support interface
01025             hr = S_FALSE;
01026 #ifdef KSPROXY_TRACE
01027             OutputDebugStringW(L"CKsProxy::IsFormatSupported plugin does not support IMediaSeeking interface\n");
01028 #endif
01029             break;
01030         }
01031 
01032         // query if it is supported
01033         hr = pSeek->IsFormatSupported(pFormat);
01034         // release interface
01035         pSeek->Release();
01036 
01037         if (FAILED(hr) || hr == S_FALSE)
01038             break;
01039     }
01040 
01041     return hr;
01042 }
01043 
01044 HRESULT
01045 STDMETHODCALLTYPE
01046 CKsProxy::QueryPreferredFormat(
01047     GUID *pFormat)
01048 {
01049     PKSMULTIPLE_ITEM FormatList;
01050     HRESULT hr;
01051     ULONG Index;
01052 
01053 #ifdef KSPROXY_TRACE
01054     OutputDebugStringW(L"CKsProxy::QueryPreferredFormat\n");
01055 #endif
01056 
01057     if (!pFormat)
01058         return E_POINTER;
01059 
01060     hr = GetMediaSeekingFormats(&FormatList);
01061     if (SUCCEEDED(hr))
01062     {
01063         if (FormatList->Count)
01064         {
01065             CopyMemory(pFormat, (FormatList + 1), sizeof(GUID));
01066             CoTaskMemFree(FormatList);
01067             return S_OK;
01068         }
01069         CoTaskMemFree(FormatList);
01070     }
01071     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
01072     {
01073         // check if plugins support it
01074         for(Index = 0; Index < m_Plugins.size(); Index++)
01075         {
01076             // get plugin
01077             IUnknown * Plugin = m_Plugins[Index];
01078 
01079             if (!Plugin)
01080                continue;
01081 
01082             // query for IMediaSeeking interface
01083             IMediaSeeking *pSeek = NULL;
01084             hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
01085             if (SUCCEEDED(hr))
01086             {
01087                 // get preferred time format
01088                 hr = pSeek->QueryPreferredFormat(pFormat);
01089                 // release IMediaSeeking interface
01090                 pSeek->Release();
01091 
01092                 if (hr != S_FALSE)
01093                     return hr;
01094             }
01095         }
01096         hr = S_FALSE;
01097     }
01098 
01099     return hr;
01100 }
01101 
01102 HRESULT
01103 STDMETHODCALLTYPE
01104 CKsProxy::GetTimeFormat(
01105     GUID *pFormat)
01106 {
01107     KSPROPERTY Property;
01108     ULONG BytesReturned, Index;
01109     HRESULT hr;
01110 
01111     Property.Set = KSPROPSETID_MediaSeeking;
01112     Property.Id = KSPROPERTY_MEDIASEEKING_TIMEFORMAT;
01113     Property.Flags = KSPROPERTY_TYPE_GET;
01114 
01115 #ifdef KSPROXY_TRACE
01116     OutputDebugStringW(L"CKsProxy::GetTimeFormat\n");
01117 #endif
01118 
01119     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pFormat, sizeof(GUID), &BytesReturned);
01120     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
01121     {
01122         // check if plugins support it
01123         for(Index = 0; Index < m_Plugins.size(); Index++)
01124         {
01125             hr = E_NOTIMPL;
01126             // get plugin
01127             IUnknown * Plugin = m_Plugins[Index];
01128 
01129             if (!Plugin)
01130                continue;
01131 
01132             // query for IMediaSeeking interface
01133             IMediaSeeking *pSeek = NULL;
01134             hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
01135             if (SUCCEEDED(hr))
01136             {
01137                 // set time format
01138                 hr = pSeek->GetTimeFormat(pFormat);
01139                 // release IMediaSeeking interface
01140                 pSeek->Release();
01141 
01142                 if (hr != S_FALSE)
01143                     break;
01144             }
01145         }
01146     }
01147     return hr;
01148 }
01149 
01150 HRESULT
01151 STDMETHODCALLTYPE
01152 CKsProxy::IsUsingTimeFormat(
01153     const GUID *pFormat)
01154 {
01155     GUID Format;
01156 
01157 #ifdef KSPROXY_TRACE
01158     OutputDebugStringW(L"CKsProxy::IsUsingTimeFormat\n");
01159 #endif
01160 
01161     if (FAILED(QueryPreferredFormat(&Format)))
01162         return S_FALSE;
01163 
01164     if (IsEqualGUID(Format, *pFormat))
01165         return S_OK;
01166     else
01167         return S_FALSE;
01168 }
01169 
01170 HRESULT
01171 STDMETHODCALLTYPE
01172 CKsProxy::SetTimeFormat(
01173     const GUID *pFormat)
01174 {
01175     KSPROPERTY Property;
01176     ULONG BytesReturned, Index;
01177     HRESULT hr;
01178 
01179     Property.Set = KSPROPSETID_MediaSeeking;
01180     Property.Id = KSPROPERTY_MEDIASEEKING_TIMEFORMAT;
01181     Property.Flags = KSPROPERTY_TYPE_SET;
01182 
01183 #ifdef KSPROXY_TRACE
01184     OutputDebugStringW(L"CKsProxy::SetTimeFormat\n");
01185 #endif
01186 
01187     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pFormat, sizeof(GUID), &BytesReturned);
01188     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
01189     {
01190         // check if plugins support it
01191         for(Index = 0; Index < m_Plugins.size(); Index++)
01192         {
01193             hr = E_NOTIMPL;
01194             // get plugin
01195             IUnknown * Plugin = m_Plugins[Index];
01196 
01197             if (!Plugin)
01198                continue;
01199 
01200             // query for IMediaSeeking interface
01201             IMediaSeeking *pSeek = NULL;
01202             hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
01203             if (FAILED(hr))
01204             {
01205                 //not supported
01206                 break;
01207             }
01208             // set time format
01209             hr = pSeek->SetTimeFormat(pFormat);
01210             // release IMediaSeeking interface
01211             pSeek->Release();
01212 
01213             if (FAILED(hr))
01214                 break;
01215         }
01216     }
01217     return hr;
01218 }
01219 
01220 HRESULT
01221 STDMETHODCALLTYPE
01222 CKsProxy::GetDuration(
01223     LONGLONG *pDuration)
01224 {
01225     KSPROPERTY Property;
01226     ULONG BytesReturned, Index;
01227     HRESULT hr;
01228 
01229     Property.Set = KSPROPSETID_MediaSeeking;
01230     Property.Id = KSPROPERTY_MEDIASEEKING_DURATION;
01231     Property.Flags = KSPROPERTY_TYPE_GET;
01232 
01233 #ifdef KSPROXY_TRACE
01234     OutputDebugStringW(L"CKsProxy::GetDuration\n");
01235 #endif
01236 
01237     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pDuration, sizeof(LONGLONG), &BytesReturned);
01238     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
01239     {
01240         // check if plugins support it
01241         for(Index = 0; Index < m_Plugins.size(); Index++)
01242         {
01243             hr = E_NOTIMPL;
01244             // get plugin
01245             IUnknown * Plugin = m_Plugins[Index];
01246 
01247             if (!Plugin)
01248                continue;
01249 
01250             // query for IMediaSeeking interface
01251             IMediaSeeking *pSeek = NULL;
01252             hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
01253             if (SUCCEEDED(hr))
01254             {
01255                 // get duration
01256                 hr = pSeek->GetStopPosition(pDuration);
01257                 // release IMediaSeeking interface
01258                 pSeek->Release();
01259 
01260                 if (hr != S_FALSE) // plugin implements it
01261                      break;
01262             }
01263         }
01264     }
01265     return hr;
01266 }
01267 
01268 HRESULT
01269 STDMETHODCALLTYPE
01270 CKsProxy::GetStopPosition(
01271     LONGLONG *pStop)
01272 {
01273     KSPROPERTY Property;
01274     ULONG BytesReturned, Index;
01275     HRESULT hr;
01276 
01277     Property.Set = KSPROPSETID_MediaSeeking;
01278     Property.Id = KSPROPERTY_MEDIASEEKING_STOPPOSITION;
01279     Property.Flags = KSPROPERTY_TYPE_GET;
01280 
01281 #ifdef KSPROXY_TRACE
01282     OutputDebugStringW(L"CKsProxy::GetStopPosition\n");
01283 #endif
01284 
01285     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pStop, sizeof(LONGLONG), &BytesReturned);
01286     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
01287     {
01288         // check if plugins support it
01289         for(Index = 0; Index < m_Plugins.size(); Index++)
01290         {
01291             hr = E_NOTIMPL;
01292             // get plugin
01293             IUnknown * Plugin = m_Plugins[Index];
01294 
01295             if (!Plugin)
01296                continue;
01297 
01298             // query for IMediaSeeking interface
01299             IMediaSeeking *pSeek = NULL;
01300             hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
01301             if (SUCCEEDED(hr))
01302             {
01303                 // get stop position
01304                 hr = pSeek->GetStopPosition(pStop);
01305                 // release IMediaSeeking interface
01306                 pSeek->Release();
01307 
01308                 if (hr != S_FALSE) // plugin implements it
01309                      break;
01310             }
01311         }
01312     }
01313     return hr;
01314 }
01315 
01316 HRESULT
01317 STDMETHODCALLTYPE
01318 CKsProxy::GetCurrentPosition(
01319     LONGLONG *pCurrent)
01320 {
01321     KSPROPERTY Property;
01322     ULONG BytesReturned, Index;
01323     HRESULT hr;
01324 
01325     Property.Set = KSPROPSETID_MediaSeeking;
01326     Property.Id = KSPROPERTY_MEDIASEEKING_POSITION;
01327     Property.Flags = KSPROPERTY_TYPE_GET;
01328 
01329 #ifdef KSPROXY_TRACE
01330     OutputDebugStringW(L"CKsProxy::GetCurrentPosition\n");
01331 #endif
01332 
01333     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pCurrent, sizeof(LONGLONG), &BytesReturned);
01334     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
01335     {
01336         // check if plugins support it
01337         for(Index = 0; Index < m_Plugins.size(); Index++)
01338         {
01339             hr = E_NOTIMPL;
01340             // get plugin
01341             IUnknown * Plugin = m_Plugins[Index];
01342 
01343             if (!Plugin)
01344                continue;
01345 
01346             // query for IMediaSeeking interface
01347             IMediaSeeking *pSeek = NULL;
01348             hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
01349             if (SUCCEEDED(hr))
01350             {
01351                 // get current position
01352                 hr = pSeek->GetCurrentPosition(pCurrent);
01353                 // release IMediaSeeking interface
01354                 pSeek->Release();
01355 
01356                 if (hr != S_FALSE) // plugin implements it
01357                      break;
01358             }
01359         }
01360     }
01361     return hr;
01362 }
01363 
01364 HRESULT
01365 STDMETHODCALLTYPE
01366 CKsProxy::ConvertTimeFormat(
01367     LONGLONG *pTarget,
01368     const GUID *pTargetFormat,
01369     LONGLONG Source,
01370     const GUID *pSourceFormat)
01371 {
01372     KSP_TIMEFORMAT Property;
01373     ULONG BytesReturned, Index;
01374     GUID SourceFormat, TargetFormat;
01375     HRESULT hr;
01376 
01377     Property.Property.Set = KSPROPSETID_MediaSeeking;
01378     Property.Property.Id = KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT;
01379     Property.Property.Flags = KSPROPERTY_TYPE_GET;
01380 
01381 #ifdef KSPROXY_TRACE
01382     OutputDebugStringW(L"CKsProxy::ConvertTimeFormat\n");
01383 #endif
01384 
01385     if (!pTargetFormat)
01386     {
01387         // get current format
01388         hr = GetTimeFormat(&TargetFormat);
01389         if (FAILED(hr))
01390             return hr;
01391 
01392         pTargetFormat = &TargetFormat;
01393     }
01394 
01395     if (!pSourceFormat)
01396     {
01397         // get current format
01398         hr = GetTimeFormat(&SourceFormat);
01399         if (FAILED(hr))
01400             return hr;
01401 
01402         pSourceFormat = &SourceFormat;
01403     }
01404 
01405     Property.SourceFormat = *pSourceFormat;
01406     Property.TargetFormat = *pTargetFormat;
01407     Property.Time = Source;
01408 
01409 
01410     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_TIMEFORMAT), (PVOID)pTarget, sizeof(LONGLONG), &BytesReturned);
01411     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
01412     {
01413         //default error
01414         hr = E_NOTIMPL;
01415 
01416         // check if plugins support it
01417         for(Index = 0; Index < m_Plugins.size(); Index++)
01418         {
01419             // get plugin
01420             IUnknown * Plugin = m_Plugins[Index];
01421 
01422             if (!Plugin)
01423                continue;
01424 
01425             // query for IMediaSeeking interface
01426             IMediaSeeking *pSeek = NULL;
01427             hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
01428             if (SUCCEEDED(hr))
01429             {
01430                 // convert time format
01431                 hr = pSeek->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat);
01432                 // release IMediaSeeking interface
01433                 pSeek->Release();
01434 
01435                 if (hr != S_FALSE) // plugin implements it
01436                      break;
01437             }
01438         }
01439     }
01440 
01441     return hr;
01442 }
01443 
01444 HRESULT
01445 STDMETHODCALLTYPE
01446 CKsProxy::SetPositions(
01447     LONGLONG *pCurrent,
01448     DWORD dwCurrentFlags,
01449     LONGLONG *pStop,
01450     DWORD dwStopFlags)
01451 {
01452     KSPROPERTY Property;
01453     KSPROPERTY_POSITIONS Positions;
01454     ULONG BytesReturned, Index;
01455     HRESULT hr;
01456 
01457     Property.Set = KSPROPSETID_MediaSeeking;
01458     Property.Id = KSPROPERTY_MEDIASEEKING_POSITIONS;
01459     Property.Flags = KSPROPERTY_TYPE_SET;
01460 
01461     Positions.Current = *pCurrent;
01462     Positions.CurrentFlags = (KS_SEEKING_FLAGS)dwCurrentFlags;
01463     Positions.Stop = *pStop;
01464     Positions.StopFlags = (KS_SEEKING_FLAGS)dwStopFlags;
01465 
01466 #ifdef KSPROXY_TRACE
01467     OutputDebugStringW(L"CKsProxy::SetPositions\n");
01468 #endif
01469 
01470     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Positions, sizeof(KSPROPERTY_POSITIONS), &BytesReturned);
01471     if (SUCCEEDED(hr))
01472     {
01473         if (dwCurrentFlags & AM_SEEKING_ReturnTime)
01474         {
01475             // retrieve current position
01476             hr = GetCurrentPosition(pCurrent);
01477         }
01478 
01479         if (SUCCEEDED(hr))
01480         {
01481             if (dwStopFlags & AM_SEEKING_ReturnTime)
01482             {
01483                 // retrieve current position
01484                 hr = GetStopPosition(pStop);
01485             }
01486         }
01487         return hr;
01488     }
01489     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
01490     {
01491         hr = E_NOTIMPL;
01492 
01493         // check if plugins support it
01494         for(Index = 0; Index < m_Plugins.size(); Index++)
01495         {
01496             // get plugin
01497             IUnknown * Plugin = m_Plugins[Index];
01498 
01499             if (!Plugin)
01500                continue;
01501 
01502             // query for IMediaSeeking interface
01503             IMediaSeeking *pSeek = NULL;
01504             hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
01505             if (SUCCEEDED(hr))
01506             {
01507                 // set positions
01508                 hr = pSeek->SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
01509                 // release IMediaSeeking interface
01510                 pSeek->Release();
01511 
01512                 if (FAILED(hr))
01513                     break;
01514             }
01515         }
01516     }
01517 
01518     return hr;
01519 }
01520 
01521 HRESULT
01522 STDMETHODCALLTYPE
01523 CKsProxy::GetPositions(
01524     LONGLONG *pCurrent,
01525     LONGLONG *pStop)
01526 {
01527     HRESULT hr;
01528 
01529 #ifdef KSPROXY_TRACE
01530     OutputDebugStringW(L"CKsProxy::GetPositions\n");
01531 #endif
01532 
01533     hr = GetCurrentPosition(pCurrent);
01534     if (SUCCEEDED(hr))
01535         hr = GetStopPosition(pStop);
01536 
01537     return hr;
01538 }
01539 
01540 HRESULT
01541 STDMETHODCALLTYPE
01542 CKsProxy::GetAvailable(
01543     LONGLONG *pEarliest,
01544     LONGLONG *pLatest)
01545 {
01546     KSPROPERTY Property;
01547     KSPROPERTY_MEDIAAVAILABLE Media;
01548     ULONG BytesReturned, Index;
01549     HRESULT hr;
01550 
01551     Property.Set = KSPROPSETID_MediaSeeking;
01552     Property.Id = KSPROPERTY_MEDIASEEKING_AVAILABLE;
01553     Property.Flags = KSPROPERTY_TYPE_GET;
01554 
01555 #ifdef KSPROXY_TRACE
01556     OutputDebugStringW(L"CKsProxy::GetAvailable\n");
01557 #endif
01558 
01559     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Media, sizeof(KSPROPERTY_MEDIAAVAILABLE), &BytesReturned);
01560     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
01561     {
01562         // check if plugins support it
01563         for(Index = 0; Index < m_Plugins.size(); Index++)
01564         {
01565             hr = E_NOTIMPL;
01566             // get plugin
01567             IUnknown * Plugin = m_Plugins[Index];
01568 
01569             if (!Plugin)
01570                continue;
01571 
01572             // query for IMediaSeeking interface
01573             IMediaSeeking *pSeek = NULL;
01574             hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
01575             if (SUCCEEDED(hr))
01576             {
01577                 // delegate call
01578                 hr = pSeek->GetAvailable(pEarliest, pLatest);
01579                 // release IMediaSeeking interface
01580                 pSeek->Release();
01581 
01582                 if (hr != S_FALSE) // plugin implements it
01583                      break;
01584             }
01585         }
01586     }
01587     else if (SUCCEEDED(hr))
01588     {
01589         *pEarliest = Media.Earliest;
01590         *pLatest = Media.Latest;
01591     }
01592 
01593     return hr;
01594 }
01595 
01596 HRESULT
01597 STDMETHODCALLTYPE
01598 CKsProxy::SetRate(
01599     double dRate)
01600 {
01601 #ifdef KSPROXY_TRACE
01602     OutputDebugStringW(L"CKsProxy::SetRate\n");
01603 #endif
01604     return E_NOTIMPL;
01605 }
01606 
01607 HRESULT
01608 STDMETHODCALLTYPE
01609 CKsProxy::GetRate(
01610     double *pdRate)
01611 {
01612 #ifdef KSPROXY_TRACE
01613     OutputDebugStringW(L"CKsProxy::GetRate\n");
01614 #endif
01615     return E_NOTIMPL;
01616 }
01617 
01618 HRESULT
01619 STDMETHODCALLTYPE
01620 CKsProxy::GetPreroll(
01621     LONGLONG *pllPreroll)
01622 {
01623     KSPROPERTY Property;
01624     ULONG BytesReturned, Index;
01625     HRESULT hr;
01626 
01627     Property.Set = KSPROPSETID_MediaSeeking;
01628     Property.Id = KSPROPERTY_MEDIASEEKING_PREROLL;
01629     Property.Flags = KSPROPERTY_TYPE_GET;
01630 
01631 #ifdef KSPROXY_TRACE
01632     OutputDebugStringW(L"CKsProxy::GetPreroll\n");
01633 #endif
01634 
01635     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pllPreroll, sizeof(LONGLONG), &BytesReturned);
01636     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND))
01637     {
01638         // check if all plugins support it
01639         for(Index = 0; Index < m_Plugins.size(); Index++)
01640         {
01641             // get plugin
01642             IUnknown * Plugin = m_Plugins[Index];
01643 
01644             if (!Plugin)
01645                continue;
01646 
01647             // query for IMediaSeeking interface
01648             IMediaSeeking *pSeek = NULL;
01649             hr = Plugin->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
01650             if (SUCCEEDED(hr))
01651             {
01652                 // get preroll
01653                 hr = pSeek->GetPreroll(pllPreroll);
01654                 // release IMediaSeeking interface
01655                 pSeek->Release();
01656 
01657                 if (hr != S_FALSE) // plugin implements it
01658                      break;
01659             }
01660         }
01661         hr = E_NOTIMPL;
01662     }
01663     return hr;
01664 }
01665 
01666 //-------------------------------------------------------------------
01667 // IAMFilterMiscFlags interface
01668 //
01669 
01670 ULONG
01671 STDMETHODCALLTYPE
01672 CKsProxy::GetMiscFlags()
01673 {
01674     ULONG Index;
01675     ULONG Flags = 0;
01676     HRESULT hr;
01677     PIN_DIRECTION PinDirection;
01678     KSPIN_COMMUNICATION Communication;
01679 
01680 
01681     for(Index = 0; Index < m_Pins.size(); Index++)
01682     {
01683         // get current pin
01684         IPin * pin = m_Pins[Index];
01685         // query direction
01686         hr = pin->QueryDirection(&PinDirection);
01687         if (SUCCEEDED(hr))
01688         {
01689             if (PinDirection == PINDIR_INPUT)
01690             {
01691                 if (SUCCEEDED(GetPinCommunication(Index, //FIXME verify PinId
01692                                         &Communication)))
01693                 {
01694                     if (Communication != KSPIN_COMMUNICATION_NONE && Communication != KSPIN_COMMUNICATION_BRIDGE)
01695                     {
01696                         Flags |= AM_FILTER_MISC_FLAGS_IS_SOURCE;
01697                     }
01698                 }
01699             }
01700         }
01701     }
01702 
01703 #ifdef KSPROXY_TRACE
01704     WCHAR Buffer[100];
01705     swprintf(Buffer, L"CKsProxy::GetMiscFlags stub Flags %x\n", Flags);
01706     OutputDebugStringW(Buffer);
01707 #endif
01708 
01709     return Flags;
01710 }
01711 
01712 //-------------------------------------------------------------------
01713 // IKsControl
01714 //
01715 HRESULT
01716 STDMETHODCALLTYPE
01717 CKsProxy::KsProperty(
01718     PKSPROPERTY Property,
01719     ULONG PropertyLength,
01720     LPVOID PropertyData,
01721     ULONG DataLength,
01722     ULONG* BytesReturned)
01723 {
01724 #ifdef KSPROXY_TRACE
01725     OutputDebugStringW(L"CKsProxy::KsProperty\n");
01726 #endif
01727 
01728     assert(m_hDevice != 0);
01729     return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
01730 }
01731 
01732 HRESULT
01733 STDMETHODCALLTYPE
01734 CKsProxy::KsMethod(
01735     PKSMETHOD Method,
01736     ULONG MethodLength,
01737     LPVOID MethodData,
01738     ULONG DataLength,
01739     ULONG* BytesReturned)
01740 {
01741 #ifdef KSPROXY_TRACE
01742     OutputDebugStringW(L"CKsProxy::KsMethod\n");
01743 #endif
01744 
01745     assert(m_hDevice != 0);
01746     return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
01747 }
01748 
01749 HRESULT
01750 STDMETHODCALLTYPE
01751 CKsProxy::KsEvent(
01752     PKSEVENT Event,
01753     ULONG EventLength,
01754     LPVOID EventData,
01755     ULONG DataLength,
01756     ULONG* BytesReturned)
01757 {
01758 #ifdef KSPROXY_TRACE
01759     OutputDebugStringW(L"CKsProxy::KsEvent\n");
01760 #endif
01761 
01762     assert(m_hDevice != 0);
01763     if (EventLength)
01764         return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned);
01765     else
01766         return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned);
01767 }
01768 
01769 
01770 //-------------------------------------------------------------------
01771 // IKsPropertySet
01772 //
01773 HRESULT
01774 STDMETHODCALLTYPE
01775 CKsProxy::Set(
01776     REFGUID guidPropSet,
01777     DWORD dwPropID,
01778     LPVOID pInstanceData,
01779     DWORD cbInstanceData,
01780     LPVOID pPropData,
01781     DWORD cbPropData)
01782 {
01783     ULONG BytesReturned;
01784 
01785 #ifdef KSPROXY_TRACE
01786     OutputDebugStringW(L"CKsProxy::Set\n");
01787 #endif
01788 
01789     if (cbInstanceData)
01790     {
01791         PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData);
01792         if (!Property)
01793             return E_OUTOFMEMORY;
01794 
01795         Property->Set = guidPropSet;
01796         Property->Id = dwPropID;
01797         Property->Flags = KSPROPERTY_TYPE_SET;
01798 
01799         CopyMemory((Property+1), pInstanceData, cbInstanceData);
01800 
01801         HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned);
01802         CoTaskMemFree(Property);
01803         return hr;
01804     }
01805     else
01806     {
01807         KSPROPERTY Property;
01808 
01809         Property.Set = guidPropSet;
01810         Property.Id = dwPropID;
01811         Property.Flags = KSPROPERTY_TYPE_SET;
01812 
01813         HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned);
01814         return hr;
01815     }
01816 }
01817 
01818 HRESULT
01819 STDMETHODCALLTYPE
01820 CKsProxy::Get(
01821     REFGUID guidPropSet,
01822     DWORD dwPropID,
01823     LPVOID pInstanceData,
01824     DWORD cbInstanceData,
01825     LPVOID pPropData,
01826     DWORD cbPropData,
01827     DWORD *pcbReturned)
01828 {
01829     ULONG BytesReturned;
01830 
01831 #ifdef KSPROXY_TRACE
01832     OutputDebugStringW(L"CKsProxy::Get\n");
01833 #endif
01834 
01835     if (cbInstanceData)
01836     {
01837         PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData);
01838         if (!Property)
01839             return E_OUTOFMEMORY;
01840 
01841         Property->Set = guidPropSet;
01842         Property->Id = dwPropID;
01843         Property->Flags = KSPROPERTY_TYPE_GET;
01844 
01845         CopyMemory((Property+1), pInstanceData, cbInstanceData);
01846 
01847         HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned);
01848         CoTaskMemFree(Property);
01849         return hr;
01850     }
01851     else
01852     {
01853         KSPROPERTY Property;
01854 
01855         Property.Set = guidPropSet;
01856         Property.Id = dwPropID;
01857         Property.Flags = KSPROPERTY_TYPE_GET;
01858 
01859         HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned);
01860         return hr;
01861     }
01862 }
01863 
01864 HRESULT
01865 STDMETHODCALLTYPE
01866 CKsProxy::QuerySupported(
01867     REFGUID guidPropSet,
01868     DWORD dwPropID,
01869     DWORD *pTypeSupport)
01870 {
01871     KSPROPERTY Property;
01872     ULONG BytesReturned;
01873 
01874 #ifdef KSPROXY_TRACE
01875     OutputDebugStringW(L"CKsProxy::QuerySupported\n");
01876 #endif
01877 
01878     Property.Set = guidPropSet;
01879     Property.Id = dwPropID;
01880     Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
01881 
01882     return KsProperty(&Property, sizeof(KSPROPERTY), pTypeSupport, sizeof(DWORD), &BytesReturned);
01883 }
01884 
01885 
01886 //-------------------------------------------------------------------
01887 // IKsTopology interface
01888 //
01889 HRESULT
01890 STDMETHODCALLTYPE
01891 CKsProxy::CreateNodeInstance(
01892     ULONG NodeId,
01893     ULONG Flags,
01894     ACCESS_MASK DesiredAccess,
01895     IUnknown* UnkOuter,
01896     REFGUID InterfaceId,
01897     LPVOID* Interface)
01898 {
01899     HRESULT hr;
01900 
01901 #ifdef KSPROXY_TRACE
01902     OutputDebugStringW(L"CKsProxy::CreateNodeInstance\n");
01903 #endif
01904 
01905     *Interface = NULL;
01906 
01907     if (IsEqualIID(IID_IUnknown, InterfaceId) || !UnkOuter)
01908     {
01909         hr = CKsNode_Constructor(UnkOuter, m_hDevice, NodeId, DesiredAccess, InterfaceId, Interface);
01910     }
01911     else
01912     {
01913         // interface not supported
01914         hr = E_NOINTERFACE;
01915     }
01916 
01917     return hr;
01918 }
01919 
01920 //-------------------------------------------------------------------
01921 // IKsAggregateControl interface
01922 //
01923 HRESULT
01924 STDMETHODCALLTYPE
01925 CKsProxy::KsAddAggregate(
01926     IN REFGUID AggregateClass)
01927 {
01928 #ifdef KSPROXY_TRACE
01929     OutputDebugStringW(L"CKsProxy::KsAddAggregate NotImplemented\n");
01930 #endif
01931     return E_NOTIMPL;
01932 }
01933 
01934 HRESULT
01935 STDMETHODCALLTYPE
01936 CKsProxy::KsRemoveAggregate(
01937     REFGUID AggregateClass)
01938 {
01939 #ifdef KSPROXY_TRACE
01940     OutputDebugStringW(L"CKsProxy::KsRemoveAggregate NotImplemented\n");
01941 #endif
01942 
01943     return E_NOTIMPL;
01944 }
01945 
01946 
01947 //-------------------------------------------------------------------
01948 // IPersistStream interface
01949 //
01950 
01951 HRESULT
01952 STDMETHODCALLTYPE
01953 CKsProxy::IsDirty()
01954 {
01955 #ifdef KSPROXY_TRACE
01956     OutputDebugStringW(L"CKsProxy::IsDirty Notimplemented\n");
01957 #endif
01958     return E_NOTIMPL;
01959 }
01960 
01961 HRESULT
01962 STDMETHODCALLTYPE
01963 CKsProxy::Load(
01964     IStream *pStm)
01965 {
01966     HRESULT hr;
01967     WCHAR Buffer[1000];
01968     AM_MEDIA_TYPE MediaType;
01969     ULONG BytesReturned;
01970     LONG Length;
01971 
01972     ULONG PinId;
01973     LPOLESTR pMajor, pSub, pFormat;
01974 
01975 #ifdef KSPROXY_TRACE
01976     OutputDebugStringW(L"CKsProxy::Load\n");
01977 #endif
01978 
01979 #if 0
01980     ULONG Version = ReadInt(pStm, hr);
01981     if (Version != 1)
01982         return E_FAIL;
01983 #endif
01984 
01985     hr = pStm->Read(&Length, sizeof(ULONG), &BytesReturned);
01986     swprintf(Buffer, L"Length hr %x hr length %lu\n", hr, Length);
01987     OutputDebugStringW(Buffer);
01988 
01989     do
01990     {
01991         hr = pStm->Read(&PinId, sizeof(ULONG), &BytesReturned);
01992         swprintf(Buffer, L"Read: hr %08x PinId %lx BytesReturned %lu\n", hr, PinId, BytesReturned);
01993         OutputDebugStringW(Buffer);
01994 
01995         if (FAILED(hr) || !BytesReturned)
01996             break;
01997 
01998         Length -= BytesReturned;
01999 
02000         hr = pStm->Read(&MediaType, sizeof(AM_MEDIA_TYPE), &BytesReturned);
02001         if (FAILED(hr) || BytesReturned != sizeof(AM_MEDIA_TYPE))
02002         {
02003             swprintf(Buffer, L"Read failed with %lx\n", hr);
02004             OutputDebugStringW(Buffer);
02005             break;
02006         }
02007 
02008 
02009         StringFromIID(MediaType.majortype, &pMajor);
02010         StringFromIID(MediaType.subtype , &pSub);
02011         StringFromIID(MediaType.formattype, &pFormat);
02012 
02013         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);
02014         OutputDebugStringW(Buffer);
02015 
02016         Length -= BytesReturned;
02017 
02018 
02019         if (MediaType.cbFormat)
02020         {
02021             MediaType.pbFormat = (BYTE*)CoTaskMemAlloc(MediaType.cbFormat);
02022             if (!MediaType.pbFormat)
02023                 return E_OUTOFMEMORY;
02024 
02025             hr = pStm->Read(&MediaType.pbFormat, sizeof(MediaType.cbFormat), &BytesReturned);
02026             if (FAILED(hr))
02027             {
02028                 swprintf(Buffer, L"ReadFormat failed with %lx\n", hr);
02029                 OutputDebugStringW(Buffer);
02030                 break;
02031             }
02032             Length -= BytesReturned;
02033         }
02034 
02035     }while(Length > 0);
02036 
02037     return S_OK;
02038 }
02039 
02040 HRESULT
02041 STDMETHODCALLTYPE
02042 CKsProxy::Save(
02043     IStream *pStm,
02044     BOOL fClearDirty)
02045 {
02046 #ifdef KSPROXY_TRACE
02047     OutputDebugStringW(L"CKsProxy::Save Notimplemented\n");
02048 #endif
02049 
02050     return E_NOTIMPL;
02051 }
02052 
02053 HRESULT
02054 STDMETHODCALLTYPE
02055 CKsProxy::GetSizeMax(
02056     ULARGE_INTEGER *pcbSize)
02057 {
02058 #ifdef KSPROXY_TRACE
02059     OutputDebugStringW(L"CKsProxy::GetSizeMax Notimplemented\n");
02060 #endif
02061 
02062     return E_NOTIMPL;
02063 }
02064 
02065 //-------------------------------------------------------------------
02066 // IAMDeviceRemoval interface
02067 //
02068 
02069 HRESULT
02070 STDMETHODCALLTYPE
02071 CKsProxy::DeviceInfo(CLSID *pclsidInterfaceClass, LPWSTR *pwszSymbolicLink)
02072 {
02073 #ifdef KSPROXY_TRACE
02074     OutputDebugStringW(L"CKsProxy::DeviceInfo\n");
02075 #endif
02076 
02077     if (!m_DevicePath)
02078     {
02079         // object not initialized
02080         return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND);
02081     }
02082 
02083     // copy device interface guid
02084     CopyMemory(pclsidInterfaceClass, &m_DeviceInterfaceGUID, sizeof(GUID));
02085 
02086     if (pwszSymbolicLink)
02087     {
02088         *pwszSymbolicLink = (LPWSTR)CoTaskMemAlloc((wcslen(m_DevicePath)+1) * sizeof(WCHAR));
02089         if (!*pwszSymbolicLink)
02090             return E_OUTOFMEMORY;
02091 
02092         wcscpy(*pwszSymbolicLink, m_DevicePath);
02093     }
02094     return S_OK;
02095 }
02096 HRESULT
02097 STDMETHODCALLTYPE
02098 CKsProxy::Reassociate(void)
02099 {
02100 #ifdef KSPROXY_TRACE
02101     OutputDebugStringW(L"CKsProxy::Reassociate\n");
02102 #endif
02103 
02104     if (!m_DevicePath || m_hDevice)
02105     {
02106         // file path not available
02107         return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND);
02108     }
02109 
02110     m_hDevice = CreateFileW(m_DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
02111     if (!m_hDevice)
02112     {
02113         // failed to open device
02114         return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
02115     }
02116 
02117     // success
02118     return NOERROR;
02119 }
02120 
02121 HRESULT
02122 STDMETHODCALLTYPE
02123 CKsProxy::Disassociate(void)
02124 {
02125 #ifdef KSPROXY_TRACE
02126     OutputDebugStringW(L"CKsProxy::Disassociate\n");
02127 #endif
02128 
02129     if (!m_hDevice)
02130         return E_HANDLE;
02131 
02132     CloseHandle(m_hDevice);
02133     m_hDevice = NULL;
02134     return NOERROR;
02135 }
02136 
02137 //-------------------------------------------------------------------
02138 // IKsClock interface
02139 //
02140 
02141 HANDLE
02142 STDMETHODCALLTYPE
02143 CKsProxy::KsGetClockHandle()
02144 {
02145 #ifdef KSPROXY_TRACE
02146     OutputDebugStringW(L"CKsProxy::KsGetClockHandle\n");
02147 #endif
02148 
02149     return m_hClock;
02150 }
02151 
02152 
02153 //-------------------------------------------------------------------
02154 // IKsObject interface
02155 //
02156 
02157 HANDLE
02158 STDMETHODCALLTYPE
02159 CKsProxy::KsGetObjectHandle()
02160 {
02161 #ifdef KSPROXY_TRACE
02162     OutputDebugStringW(L"CKsProxy::KsGetObjectHandle\n");
02163 #endif
02164 
02165     return m_hDevice;
02166 }
02167 
02168 //-------------------------------------------------------------------
02169 // IPersistPropertyBag interface
02170 //
02171 HRESULT
02172 STDMETHODCALLTYPE
02173 CKsProxy::InitNew( void)
02174 {
02175 #ifdef KSPROXY_TRACE
02176     OutputDebugStringW(L"CKsProxy::InitNew\n");
02177 #endif
02178 
02179     return S_OK;
02180 }
02181 
02182 HRESULT
02183 STDMETHODCALLTYPE
02184 CKsProxy::GetSupportedSets(
02185     LPGUID * pOutGuid,
02186     PULONG NumGuids)
02187 {
02188     KSPROPERTY Property;
02189     LPGUID pGuid;
02190     ULONG NumProperty = 0;
02191     ULONG NumMethods = 0;
02192     ULONG NumEvents = 0;
02193     ULONG Length;
02194     ULONG BytesReturned;
02195     HRESULT hr;
02196 
02197     Property.Set = GUID_NULL;
02198     Property.Id = 0;
02199     Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
02200 
02201     KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumProperty);
02202     KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumMethods);
02203     KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumEvents);
02204 
02205     Length = NumProperty + NumMethods + NumEvents;
02206 
02207     // allocate guid buffer
02208     pGuid = (LPGUID)CoTaskMemAlloc(Length);
02209     if (!pGuid)
02210     {
02211         // failed
02212         return E_OUTOFMEMORY;
02213     }
02214 
02215     NumProperty /= sizeof(GUID);
02216     NumMethods /= sizeof(GUID);
02217     NumEvents /= sizeof(GUID);
02218 
02219     // get all properties
02220     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pGuid, Length, &BytesReturned);
02221     if (FAILED(hr))
02222     {
02223         CoTaskMemFree(pGuid);
02224         return E_FAIL;
02225     }
02226     Length -= BytesReturned;
02227 
02228     // get all methods
02229     if (Length)
02230     {
02231         hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty], Length, &BytesReturned);
02232         if (FAILED(hr))
02233         {
02234             CoTaskMemFree(pGuid);
02235             return E_FAIL;
02236         }
02237         Length -= BytesReturned;
02238     }
02239 
02240     // get all events
02241     if (Length)
02242     {
02243         hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty+NumMethods], Length, &BytesReturned);
02244         if (FAILED(hr))
02245         {
02246             CoTaskMemFree(pGuid);
02247             return E_FAIL;
02248         }
02249         Length -= BytesReturned;
02250     }
02251 
02252 #ifdef KSPROXY_TRACE
02253     WCHAR Buffer[200];
02254     swprintf(Buffer, L"NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty, NumMethods, NumEvents);
02255     OutputDebugStringW(Buffer);
02256 #endif
02257 
02258     *pOutGuid = pGuid;
02259     *NumGuids = NumProperty+NumEvents+NumMethods;
02260     return S_OK;
02261 }
02262 
02263 HRESULT
02264 STDMETHODCALLTYPE
02265 CKsProxy::LoadProxyPlugins(
02266     LPGUID pGuids,
02267     ULONG NumGuids)
02268 {
02269     ULONG Index;
02270     LPOLESTR pStr;
02271     HKEY hKey, hSubKey;
02272     HRESULT hr;
02273     IUnknown * pUnknown;
02274 
02275     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
02276     {
02277         OutputDebugStringW(L"CKsProxy::LoadProxyPlugins failed to open MediaInterfaces key\n");
02278         return E_FAIL;
02279     }
02280 
02281     // enumerate all sets
02282     for(Index = 0; Index < NumGuids; Index++)
02283     {
02284         // convert to string
02285         hr = StringFromCLSID(pGuids[Index], &pStr);
02286         if (FAILED(hr))
02287             return E_FAIL;
02288 
02289         // now try open class key
02290         if (RegOpenKeyExW(hKey, pStr, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
02291         {
02292             // no plugin for that set exists
02293             CoTaskMemFree(pStr);
02294             continue;
02295         }
02296 
02297         // try load plugin
02298         hr = CoCreateInstance(pGuids[Index], (IBaseFilter*)this, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnknown);
02299         if (SUCCEEDED(hr))
02300         {
02301             // store plugin
02302             m_Plugins.push_back(pUnknown);
02303         }
02304         // close key
02305         RegCloseKey(hSubKey);
02306     }
02307 
02308     // close media interfaces key
02309     RegCloseKey(hKey);
02310     return S_OK;
02311 }
02312 
02313 HRESULT
02314 STDMETHODCALLTYPE
02315 CKsProxy::GetNumberOfPins(
02316     PULONG NumPins)
02317 {
02318     KSPROPERTY Property;
02319     ULONG BytesReturned;
02320 
02321     // setup request
02322     Property.Set = KSPROPSETID_Pin;
02323     Property.Id = KSPROPERTY_PIN_CTYPES;
02324     Property.Flags = KSPROPERTY_TYPE_GET;
02325 
02326     return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)NumPins, sizeof(ULONG), &BytesReturned);
02327 }
02328 
02329 HRESULT
02330 STDMETHODCALLTYPE
02331 CKsProxy::GetPinInstanceCount(
02332     ULONG PinId,
02333     PKSPIN_CINSTANCES Instances)
02334 {
02335     KSP_PIN Property;
02336     ULONG BytesReturned;
02337 
02338     // setup request
02339     Property.Property.Set = KSPROPSETID_Pin;
02340     Property.Property.Id = KSPROPERTY_PIN_CINSTANCES;
02341     Property.Property.Flags = KSPROPERTY_TYPE_GET;
02342     Property.PinId = PinId;
02343     Property.Reserved = 0;
02344 
02345     return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)Instances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
02346 }
02347 
02348 HRESULT
02349 STDMETHODCALLTYPE
02350 CKsProxy::GetPinCommunication(
02351     ULONG PinId,
02352     KSPIN_COMMUNICATION * Communication)
02353 {
02354     KSP_PIN Property;
02355     ULONG BytesReturned;
02356 
02357     // setup request
02358     Property.Property.Set = KSPROPSETID_Pin;
02359     Property.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
02360     Property.Property.Flags = KSPROPERTY_TYPE_GET;
02361     Property.PinId = PinId;
02362     Property.Reserved = 0;
02363 
02364     return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
02365 }
02366 
02367 HRESULT
02368 STDMETHODCALLTYPE
02369 CKsProxy::GetPinDataflow(
02370     ULONG PinId,
02371     KSPIN_DATAFLOW * DataFlow)
02372 {
02373     KSP_PIN Property;
02374     ULONG BytesReturned;
02375 
02376     // setup request
02377     Property.Property.Set = KSPROPSETID_Pin;
02378     Property.Property.Id = KSPROPERTY_PIN_DATAFLOW;
02379     Property.Property.Flags = KSPROPERTY_TYPE_GET;
02380     Property.PinId = PinId;
02381     Property.Reserved = 0;
02382 
02383     return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned);
02384 }
02385 
02386 HRESULT
02387 STDMETHODCALLTYPE
02388 CKsProxy::GetPinName(
02389     ULONG PinId,
02390     KSPIN_DATAFLOW DataFlow,
02391     ULONG PinCount,
02392     LPWSTR * OutPinName)
02393 {
02394     KSP_PIN Property;
02395     LPWSTR PinName;
02396     ULONG BytesReturned;
02397     HRESULT hr;
02398     WCHAR Buffer[100];
02399 
02400     // setup request
02401     Property.Property.Set = KSPROPSETID_Pin;
02402     Property.Property.Id = KSPROPERTY_PIN_NAME;
02403     Property.Property.Flags = KSPROPERTY_TYPE_GET;
02404     Property.PinId = PinId;
02405     Property.Reserved = 0;
02406 
02407     // #1 try get it from pin directly
02408     hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
02409 
02410     if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA))
02411     {
02412         // allocate pin name
02413         PinName = (LPWSTR)CoTaskMemAlloc(BytesReturned);
02414         if (!PinName)
02415             return E_OUTOFMEMORY;
02416 
02417         // retry with allocated buffer
02418         hr = KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), PinName, BytesReturned, &BytesReturned);
02419         if (SUCCEEDED(hr))
02420         {
02421             *OutPinName = PinName;
02422             return hr;
02423         }
02424 
02425         //free buffer
02426         CoTaskMemFree(PinName);
02427     }
02428 
02429     //
02430     // TODO: retrieve pin name from topology node
02431     //
02432 
02433     if (DataFlow == KSPIN_DATAFLOW_IN)
02434     {
02435         swprintf(Buffer, L"Input%lu", PinCount);
02436     }
02437     else
02438     {
02439         swprintf(Buffer, L"Output%lu", PinCount);
02440     }
02441 
02442     // allocate pin name 
02443     PinName = (LPWSTR)CoTaskMemAlloc((wcslen(Buffer)+1) * sizeof(WCHAR));
02444     if (!PinName)
02445         return E_OUTOFMEMORY;
02446 
02447     // copy pin name
02448     wcscpy(PinName, Buffer);
02449 
02450     // store result
02451     *OutPinName = PinName;
02452     // done
02453     return S_OK;
02454 }
02455 
02456 HRESULT
02457 STDMETHODCALLTYPE
02458 CKsProxy::CreatePins()
02459 {
02460     ULONG NumPins, Index;
02461     KSPIN_CINSTANCES Instances;
02462     KSPIN_DATAFLOW DataFlow;
02463     KSPIN_COMMUNICATION Communication;
02464     HRESULT hr;
02465     LPWSTR PinName;
02466     IPin * pPin;
02467     ULONG InputPin = 0;
02468     ULONG OutputPin = 0;
02469 
02470     // get number of pins
02471     hr = GetNumberOfPins(&NumPins);
02472     if (FAILED(hr))
02473         return hr;
02474 
02475     for(Index = 0; Index < NumPins; Index++)
02476     {
02477         // query current instance count
02478         hr = GetPinInstanceCount(Index, &Instances);
02479         if (FAILED(hr))
02480         {
02481 #ifdef KSPROXY_TRACE
02482             WCHAR Buffer[100];
02483             swprintf(Buffer, L"CKsProxy::CreatePins GetPinInstanceCount failed with %lx\n", hr);
02484             OutputDebugStringW(Buffer);
02485 #endif
02486             continue;
02487         }
02488 
02489 
02490         // query pin communication;
02491         hr = GetPinCommunication(Index, &Communication);
02492         if (FAILED(hr))
02493         {
02494 #ifdef KSPROXY_TRACE
02495             WCHAR Buffer[100];
02496             swprintf(Buffer, L"CKsProxy::CreatePins GetPinCommunication failed with %lx\n", hr);
02497             OutputDebugStringW(Buffer);
02498 #endif
02499             continue;
02500         }
02501 
02502         if (Instances.CurrentCount == Instances.PossibleCount)
02503         {
02504             // already maximum reached for this pin
02505 #ifdef KSPROXY_TRACE
02506             WCHAR Buffer[100];
02507             swprintf(Buffer, L"CKsProxy::CreatePins Instances.CurrentCount == Instances.PossibleCount\n");
02508             OutputDebugStringW(Buffer);
02509 #endif
02510             continue;
02511         }
02512 
02513         // get direction of pin
02514         hr = GetPinDataflow(Index, &DataFlow);
02515         if (FAILED(hr))
02516         {
02517 #ifdef KSPROXY_TRACE
02518             WCHAR Buffer[100];
02519             swprintf(Buffer, L"CKsProxy::CreatePins GetPinDataflow failed with %lx\n", hr);
02520             OutputDebugStringW(Buffer);
02521 #endif
02522             continue;
02523         }
02524 
02525         if (DataFlow == KSPIN_DATAFLOW_IN)
02526             hr = GetPinName(Index, DataFlow, InputPin, &PinName);
02527         else
02528             hr = GetPinName(Index, DataFlow, OutputPin, &PinName);
02529 
02530         if (FAILED(hr))
02531         {
02532 #ifdef KSPROXY_TRACE
02533             WCHAR Buffer[100];
02534             swprintf(Buffer, L"CKsProxy::CreatePins GetPinName failed with %lx\n", hr);
02535             OutputDebugStringW(Buffer);
02536 #endif
02537             continue;
02538         }
02539 
02540         // construct the pins
02541         if (DataFlow == KSPIN_DATAFLOW_IN)
02542         {
02543             hr = CInputPin_Constructor((IBaseFilter*)this, PinName, m_hDevice, Index, Communication, IID_IPin, (void**)&pPin);
02544             if (FAILED(hr))
02545             {
02546 #ifdef KSPROXY_TRACE
02547                 WCHAR Buffer[100];
02548                 swprintf(Buffer, L"CKsProxy::CreatePins CInputPin_Constructor failed with %lx\n", hr);
02549                 OutputDebugStringW(Buffer);
02550 #endif
02551                 CoTaskMemFree(PinName);
02552                 continue;
02553             }
02554             InputPin++;
02555         }
02556         else
02557         {
02558             hr = COutputPin_Constructor((IBaseFilter*)this, PinName, Index, Communication, IID_IPin, (void**)&pPin);
02559             if (FAILED(hr))
02560             {
02561 #ifdef KSPROXY_TRACE
02562                 WCHAR Buffer[100];
02563                 swprintf(Buffer, L"CKsProxy::CreatePins COutputPin_Constructor failed with %lx\n", hr);
02564                 OutputDebugStringW(Buffer);
02565 #endif
02566                 CoTaskMemFree(PinName);
02567                 continue;
02568             }
02569             OutputPin++;
02570         }
02571 
02572         // store pins
02573         m_Pins.push_back(pPin);
02574 
02575 #ifdef KSPROXY_TRACE
02576         WCHAR Buffer[100];
02577         swprintf(Buffer, L"Index %lu DataFlow %lu Name %s\n", Index, DataFlow, PinName);
02578         OutputDebugStringW(Buffer);
02579 #endif
02580 
02581     }
02582 
02583     return S_OK;
02584 }
02585 
02586 HRESULT
02587 STDMETHODCALLTYPE
02588 CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog)
02589 {
02590     HRESULT hr;
02591     VARIANT varName;
02592     LPGUID pGuid;
02593     ULONG NumGuids = 0;
02594     HDEVINFO hList;
02595     SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
02596 
02597 #ifdef KSPROXY_TRACE
02598     WCHAR Buffer[100];
02599     OutputDebugStringW(L"CKsProxy::Load\n");
02600 #endif
02601 
02602     // read device path
02603     varName.vt = VT_BSTR;
02604     hr = pPropBag->Read(L"DevicePath", &varName, pErrorLog);
02605 
02606     if (FAILED(hr))
02607     {
02608 #ifdef KSPROXY_TRACE
02609         swprintf(Buffer, L"CKsProxy::Load Read %lx\n", hr);
02610         OutputDebugStringW(Buffer);
02611 #endif
02612         return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
02613     }
02614 
02615 #ifdef KSPROXY_TRACE
02616     OutputDebugStringW(L"DevicePath: ");
02617     OutputDebugStringW(varName.bstrVal);
02618     OutputDebugStringW(L"\n");
02619 #endif
02620 
02621     // create device list
02622     hList = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL);
02623     if (hList == INVALID_HANDLE_VALUE)
02624     {
02625         // failed to create device list
02626         return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
02627     }
02628 
02629     DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
02630     if (!SetupDiOpenDeviceInterfaceW(hList, (PCWSTR)varName.bstrVal, 0, &DeviceInterfaceData))
02631     {
02632         // failed to open device interface
02633         SetupDiDestroyDeviceInfoList(hList);
02634     }
02635 
02636     // FIXME handle device interface links(aliases)
02637     CopyMemory(&m_DeviceInterfaceGUID, &DeviceInterfaceData.InterfaceClassGuid, sizeof(GUID));
02638 
02639     // close device info list
02640    SetupDiDestroyDeviceInfoList(hList);
02641 
02642     // open device
02643     m_hDevice = CreateFileW(varName.bstrVal, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
02644 
02645     if (m_hDevice == INVALID_HANDLE_VALUE)
02646     {
02647         // failed to open device
02648 #ifdef KSPROXY_TRACE
02649         swprintf(Buffer, L"CKsProxy:: failed to open device with %lx\n", GetLastError());
02650         OutputDebugStringW(Buffer);
02651 #endif
02652         return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
02653     }
02654 
02655     // store device path
02656     m_DevicePath = varName.bstrVal;
02657 
02658     // get all supported sets
02659     hr = GetSupportedSets(&pGuid, &NumGuids);
02660     if (FAILED(hr))
02661     {
02662         CloseHandle(m_hDevice);
02663         m_hDevice = NULL;
02664         return hr;
02665     }
02666 
02667     // load all proxy plugins
02668     hr = LoadProxyPlugins(pGuid, NumGuids);
02669     if (FAILED(hr))
02670     {
02671 #if 0 //HACK
02672         CloseHandle(m_hDevice);
02673         m_hDevice = NULL;
02674         return hr;
02675 #endif
02676         OutputDebugStringW(L"CKsProxy::LoadProxyPlugins failed!\n");
02677     }
02678 
02679     // free sets
02680     CoTaskMemFree(pGuid);
02681 
02682     // now create the input / output pins
02683     hr = CreatePins();
02684 
02685 #ifdef KSPROXY_TRACE
02686     swprintf(Buffer, L"CKsProxy::Load CreatePins %lx\n", hr);
02687     OutputDebugStringW(Buffer);
02688 #endif
02689 
02690     //HACK
02691     hr = S_OK;
02692 
02693     return hr;
02694 }
02695 
02696 HRESULT
02697 STDMETHODCALLTYPE
02698 CKsProxy::Save(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
02699 {
02700 #ifdef KSPROXY_TRACE
02701     OutputDebugStringW(L"CKsProxy::Save\n");
02702 #endif
02703     return E_NOTIMPL;
02704 }
02705 
02706 //-------------------------------------------------------------------
02707 // IBaseFilter interface
02708 //  
02709 
02710 HRESULT
02711 STDMETHODCALLTYPE
02712 CKsProxy::GetClassID(
02713     CLSID *pClassID)
02714 {
02715 #ifdef KSPROXY_TRACE
02716     OutputDebugStringW(L"CKsProxy::GetClassID\n");
02717 #endif
02718     CopyMemory(pClassID, &CLSID_Proxy, sizeof(GUID));
02719 
02720     return S_OK;
02721 }
02722 
02723 HRESULT
02724 STDMETHODCALLTYPE
02725 CKsProxy::Stop()
02726 {
02727     HRESULT hr;
02728 
02729 #ifdef KSPROXY_TRACE
02730     OutputDebugStringW(L"CKsProxy::Stop\n");
02731 #endif
02732 
02733     EnterCriticalSection(&m_Lock);
02734 
02735     hr = SetPinState(KSSTATE_STOP);
02736     if (SUCCEEDED(hr))
02737         m_FilterState = State_Stopped;
02738 
02739     LeaveCriticalSection(&m_Lock);
02740 
02741     return hr;
02742 }
02743 
02744 HRESULT
02745 STDMETHODCALLTYPE
02746 CKsProxy::Pause()
02747 {
02748     HRESULT hr = S_OK;
02749 
02750 #ifdef KSPROXY_TRACE
02751     OutputDebugStringW(L"CKsProxy::Pause\n");
02752 #endif
02753 
02754     EnterCriticalSection(&m_Lock);
02755 
02756     if (m_FilterState == State_Running)
02757     {
02758         hr = SetPinState(KSSTATE_STOP);
02759     }
02760     if (SUCCEEDED(hr))
02761     {
02762         if (m_FilterState == State_Stopped)
02763         {
02764             hr = SetPinState(KSSTATE_PAUSE);
02765         }
02766     }
02767 
02768     if (SUCCEEDED(hr))
02769         m_FilterState = State_Paused;
02770 
02771     LeaveCriticalSection(&m_Lock);
02772     return hr;
02773 
02774 }
02775 
02776 HRESULT
02777 STDMETHODCALLTYPE
02778 CKsProxy::Run(
02779     REFERENCE_TIME tStart)
02780 {
02781     HRESULT hr;
02782 
02783 #ifdef KSPROXY_TRACE
02784     OutputDebugStringW(L"CKsProxy::Run\n");
02785 #endif
02786 
02787     EnterCriticalSection(&m_Lock);
02788 
02789     if (m_FilterState == State_Stopped)
02790     {
02791         LeaveCriticalSection(&m_Lock);
02792         // setting filter state to pause
02793         hr = Pause();
02794         if (FAILED(hr))
02795             return hr;
02796 
02797         EnterCriticalSection(&m_Lock);
02798         assert(m_FilterState == State_Paused);
02799     }
02800 
02801     hr = SetPinState(KSSTATE_RUN);
02802 
02803     if (SUCCEEDED(hr))
02804     {
02805         m_FilterState = State_Running;
02806     }
02807 
02808     LeaveCriticalSection(&m_Lock);
02809     return hr;
02810 }
02811 
02812 HRESULT
02813 STDMETHODCALLTYPE
02814 CKsProxy::SetPinState(
02815     KSSTATE State)
02816 {
02817     HRESULT hr = S_OK;
02818     ULONG Index;
02819     IKsObject *pObject;
02820     ULONG BytesReturned;
02821     KSPROPERTY Property;
02822     PIN_INFO PinInfo;
02823 
02824     Property.Set = KSPROPSETID_Connection;
02825     Property.Id = KSPROPERTY_CONNECTION_STATE;
02826     Property.Flags = KSPROPERTY_TYPE_SET;
02827 
02828     // set all pins to running state
02829     for(Index = 0; Index < m_Pins.size(); Index++)
02830     {
02831         IPin * Pin = m_Pins[Index];
02832         if (!Pin)
02833             continue;
02834 
02835         //check if the pin is connected
02836         IPin * TempPin;
02837         hr = Pin->ConnectedTo(&TempPin);
02838         if (FAILED(hr))
02839         {
02840             // skip unconnected pins
02841             continue;
02842         }
02843 
02844         // release connected pin
02845         TempPin->Release();
02846 
02847         // query for the pin info
02848         hr = Pin->QueryPinInfo(&PinInfo);
02849 
02850         if (SUCCEEDED(hr))
02851         {
02852             if (PinInfo.pFilter)
02853                 PinInfo.pFilter->Release();
02854 
02855             if (PinInfo.dir == PINDIR_OUTPUT)
02856             {
02857                 hr = COutputPin_SetState(Pin, State);
02858                 if (SUCCEEDED(hr))
02859                     continue;
02860             }
02861         }
02862 
02863         //query IKsObject interface
02864         hr = Pin->QueryInterface(IID_IKsObject, (void**)&pObject);
02865 
02866         // get pin handle
02867         HANDLE hPin = pObject->KsGetObjectHandle();
02868 
02869         // sanity check
02870         assert(hPin && hPin != INVALID_HANDLE_VALUE);
02871 
02872         // now set state
02873         hr = KsSynchronousDeviceControl(hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&State, sizeof(KSSTATE), &BytesReturned);
02874 
02875 #ifdef KSPROXY_TRACE
02876         WCHAR Buffer[100];
02877         swprintf(Buffer, L"CKsProxy::SetPinState Index %u State %u hr %lx\n", Index, State, hr);
02878         OutputDebugStringW(Buffer);
02879 #endif
02880 
02881         if (FAILED(hr))
02882             return hr;
02883     }
02884     return hr;
02885 }
02886 
02887 HRESULT
02888 STDMETHODCALLTYPE
02889 CKsProxy::GetState(
02890     DWORD dwMilliSecsTimeout,
02891     FILTER_STATE *State)
02892 {
02893     if (!State)
02894         return E_POINTER;
02895 
02896     *State = m_FilterState;
02897     return S_OK;
02898 }
02899 
02900 HRESULT
02901 STDMETHODCALLTYPE
02902 CKsProxy::SetSyncSource(
02903     IReferenceClock *pClock)
02904 {
02905     HRESULT hr;
02906     IKsClock *pKsClock;
02907     HANDLE hClock, hPin;
02908     ULONG Index;
02909     IPin * pin;
02910     IKsObject * pObject;
02911     KSPROPERTY Property;
02912     ULONG BytesReturned;
02913     PIN_DIRECTION PinDir;
02914 
02915 #ifdef KSPROXY_TRACE
02916     OutputDebugStringW(L"CKsProxy::SetSyncSource\n");
02917 #endif
02918 
02919     // FIXME
02920     // need locks
02921 
02922     if (pClock)
02923     {
02924         hr = pClock->QueryInterface(IID_IKsClock, (void**)&pKsClock);
02925         if (FAILED(hr))
02926         {
02927             hr = m_ReferenceClock->QueryInterface(IID_IKsClock, (void**)&pKsClock);
02928             if (FAILED(hr))
02929                 return hr;
02930         }
02931 
02932         // get clock handle
02933         hClock = pKsClock->KsGetClockHandle();
02934 
02935         // release IKsClock interface
02936         pKsClock->Release();
02937         m_hClock = hClock;
02938     }
02939     else
02940     {
02941         // no clock handle
02942         m_hClock = NULL;
02943     }
02944 
02945 
02946     // distribute clock to all pins
02947     for(Index = 0; Index < m_Pins.size(); Index++)
02948     {
02949         // get current pin
02950         pin = m_Pins[Index];
02951         if (!pin)
02952             continue;
02953 
02954         // get IKsObject interface
02955         hr = pin->QueryInterface(IID_IKsObject, (void **)&pObject);
02956         if (SUCCEEDED(hr))
02957         {
02958             // get pin handle
02959             hPin = pObject->KsGetObjectHandle();
02960             if (hPin != INVALID_HANDLE_VALUE && hPin)
02961             {
02962                 // set clock
02963                 Property.Set = KSPROPSETID_Stream;
02964                 Property.Id = KSPROPERTY_STREAM_MASTERCLOCK;
02965                 Property.Flags = KSPROPERTY_TYPE_SET;
02966 
02967                 // set master clock
02968                 hr = KsSynchronousDeviceControl(hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&m_hClock, sizeof(HANDLE), &BytesReturned);
02969 
02970                 if (FAILED(hr))
02971                 {
02972                     if (hr != MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND) &&
02973                         hr != MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND))
02974                     {
02975                         // failed to set master clock
02976                         pObject->Release();
02977                         WCHAR Buffer[100];
02978                         swprintf(Buffer, L"CKsProxy::SetSyncSource KSPROPERTY_STREAM_MASTERCLOCK failed with %lx\n", hr);
02979                         OutputDebugStringW(Buffer);
02980                         return hr;
02981                     }
02982                 }
02983             }
02984             // release IKsObject
02985             pObject->Release();
02986         }
02987 
02988         // now get the direction
02989         hr = pin->QueryDirection(&PinDir);
02990         if (SUCCEEDED(hr))
02991         {
02992             if (PinDir == PINDIR_OUTPUT)
02993             {
02994                 // notify pin via
02995                 //CBaseStreamControl::SetSyncSource(pClock)
02996             }
02997         }
02998     }
02999 
03000     if (pClock)
03001     {
03002         pClock->AddRef();
03003     }
03004 
03005     if (m_ReferenceClock)
03006     {
03007         m_ReferenceClock->Release();
03008     }
03009 
03010     m_ReferenceClock = pClock;
03011 #ifdef KSPROXY_TRACE
03012     OutputDebugStringW(L"CKsProxy::SetSyncSource done\n");
03013 #endif
03014     return S_OK;
03015 }
03016 
03017 HRESULT
03018 STDMETHODCALLTYPE
03019 CKsProxy::GetSyncSource(
03020     IReferenceClock **pClock)
03021 {
03022 #ifdef KSPROXY_TRACE
03023     OutputDebugStringW(L"CKsProxy::GetSyncSource\n");
03024 #endif
03025 
03026     if (!pClock)
03027         return E_POINTER;
03028 
03029     if (m_ReferenceClock)
03030         m_ReferenceClock->AddRef();
03031 
03032     *pClock = m_ReferenceClock;
03033     return S_OK;
03034 }
03035 
03036 HRESULT
03037 STDMETHODCALLTYPE
03038 CKsProxy::EnumPins(
03039     IEnumPins **ppEnum)
03040 {
03041     return CEnumPins_fnConstructor(m_Pins, IID_IEnumPins, (void**)ppEnum);
03042 }
03043 
03044 HRESULT
03045 STDMETHODCALLTYPE
03046 CKsProxy::FindPin(
03047     LPCWSTR Id, IPin **ppPin)
03048 {
03049     ULONG PinId;
03050 
03051 #ifdef KSPROXY_TRACE
03052     OutputDebugStringW(L"CKsProxy::FindPin\n");
03053 #endif
03054 
03055     if (!ppPin)
03056         return E_POINTER;
03057 
03058     // convert to pin
03059     int ret = swscanf(Id, L"%u", &PinId);
03060 
03061     if (!ret || ret == EOF)
03062     {
03063         // invalid id
03064         return VFW_E_NOT_FOUND;
03065     }
03066 
03067     if (PinId >= m_Pins.size() || m_Pins[PinId] == NULL)
03068     {
03069         // invalid id
03070         return VFW_E_NOT_FOUND;
03071     }
03072 
03073     // found pin
03074     *ppPin = m_Pins[PinId];
03075     m_Pins[PinId]->AddRef();
03076 
03077     return S_OK;
03078 }
03079 
03080 
03081 HRESULT
03082 STDMETHODCALLTYPE
03083 CKsProxy::QueryFilterInfo(
03084     FILTER_INFO *pInfo)
03085 {
03086     if (!pInfo)
03087         return E_POINTER;
03088 
03089 #ifdef KSPROXY_TRACE
03090     OutputDebugStringW(L"CKsProxy::QueryFilterInfo\n");
03091 #endif
03092 
03093     pInfo->achName[0] = L'\0';
03094     pInfo->pGraph = m_pGraph;
03095 
03096     if (m_pGraph)
03097         m_pGraph->AddRef();
03098 
03099     return S_OK;
03100 }
03101 
03102 HRESULT
03103 STDMETHODCALLTYPE
03104 CKsProxy::JoinFilterGraph(
03105     IFilterGraph *pGraph,
03106     LPCWSTR pName)
03107 {
03108 #ifdef KSPROXY_TRACE
03109     WCHAR Buffer[100];
03110     swprintf(Buffer, L"CKsProxy::JoinFilterGraph pName %s pGraph %p m_Ref %u\n", pName, pGraph, m_Ref);
03111     OutputDebugStringW(Buffer);
03112 #endif
03113 
03114     if (pGraph)
03115     {
03116         // joining filter graph
03117         m_pGraph = pGraph;
03118     }
03119     else
03120     {
03121         // leaving graph
03122         m_pGraph = 0;
03123     }
03124 
03125     return S_OK;
03126 }
03127 
03128 
03129 HRESULT
03130 STDMETHODCALLTYPE
03131 CKsProxy::QueryVendorInfo(
03132     LPWSTR *pVendorInfo)
03133 {
03134 #ifdef KSPROXY_TRACE
03135     OutputDebugStringW(L"CKsProxy::QueryVendorInfo\n");
03136 #endif
03137     return StringFromCLSID(CLSID_Proxy, pVendorInfo);
03138 }
03139 
03140 //-------------------------------------------------------------------
03141 // IAMovieSetup interface
03142 //
03143 
03144 HRESULT
03145 STDMETHODCALLTYPE
03146 CKsProxy::Register()
03147 {
03148 #ifdef KSPROXY_TRACE
03149     OutputDebugStringW(L"CKsProxy::Register : NotImplemented\n");
03150 #endif
03151 
03152     return E_NOTIMPL;
03153 }
03154 
03155 HRESULT
03156 STDMETHODCALLTYPE
03157 CKsProxy::Unregister()
03158 {
03159 #ifdef KSPROXY_TRACE
03160     OutputDebugStringW(L"CKsProxy::Unregister : NotImplemented\n");
03161 #endif
03162     return E_NOTIMPL;
03163 }
03164 
03165 HRESULT
03166 WINAPI
03167 CKsProxy_Constructor(
03168     IUnknown * pUnkOuter,
03169     REFIID riid,
03170     LPVOID * ppv)
03171 {
03172 #ifdef KSPROXY_TRACE
03173     WCHAR Buffer[100];
03174     LPOLESTR pstr;
03175     StringFromCLSID(riid, &pstr);
03176     swprintf(Buffer, L"CKsProxy_Constructor pUnkOuter %p riid %s\n", pUnkOuter, pstr);
03177     OutputDebugStringW(Buffer);
03178 #endif
03179 
03180     CKsProxy * handler = new CKsProxy();
03181 
03182     if (!handler)
03183         return E_OUTOFMEMORY;
03184 
03185     if (FAILED(handler->QueryInterface(riid, ppv)))
03186     {
03187         /* not supported */
03188         delete handler;
03189         return E_NOINTERFACE;
03190     }
03191 
03192     return S_OK;
03193 }

Generated on Sun May 27 2012 04:21:52 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.