Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenproxy.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
1.7.6.1
|