Reactos
at master 577 lines 14 kB view raw
1/* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Network Provider for MPEG2 based networks 4 * FILE: dll/directx/msdvbnp/networkprovider.cpp 5 * PURPOSE: IBDA_NetworkProvider interface 6 * 7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) 8 */ 9#include "precomp.h" 10 11#define DEVICE_FILTER_MASK (0x80000000) 12 13class CNetworkProvider : public IBaseFilter, 14 public IAMovieSetup, 15 public IBDA_NetworkProvider 16{ 17public: 18 typedef std::vector<IUnknown*>DeviceFilterStack; 19 20 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 21 22 STDMETHODIMP_(ULONG) AddRef() 23 { 24 InterlockedIncrement(&m_Ref); 25 return m_Ref; 26 } 27 STDMETHODIMP_(ULONG) Release() 28 { 29 InterlockedDecrement(&m_Ref); 30 if (!m_Ref) 31 { 32 delete this; 33 return 0; 34 } 35 return m_Ref; 36 } 37 38 // IBaseFilter methods 39 HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID); 40 HRESULT STDMETHODCALLTYPE Stop( void); 41 HRESULT STDMETHODCALLTYPE Pause( void); 42 HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart); 43 HRESULT STDMETHODCALLTYPE GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *State); 44 HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock); 45 HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock **pClock); 46 HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins **ppEnum); 47 HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR Id, IPin **ppPin); 48 HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO *pInfo); 49 HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName); 50 HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *pVendorInfo); 51 52 //IAMovieSetup methods 53 HRESULT STDMETHODCALLTYPE Register( void); 54 HRESULT STDMETHODCALLTYPE Unregister( void); 55 56 //IBDA_NetworkProvider methods 57 HRESULT STDMETHODCALLTYPE PutSignalSource(ULONG ulSignalSource); 58 HRESULT STDMETHODCALLTYPE GetSignalSource(ULONG *pulSignalSource); 59 HRESULT STDMETHODCALLTYPE GetNetworkType(GUID *pguidNetworkType); 60 HRESULT STDMETHODCALLTYPE PutTuningSpace(REFGUID guidTuningSpace); 61 HRESULT STDMETHODCALLTYPE GetTuningSpace(GUID *pguidTuingSpace); 62 HRESULT STDMETHODCALLTYPE RegisterDeviceFilter(IUnknown *pUnkFilterControl, ULONG *ppvRegistrationContext); 63 HRESULT STDMETHODCALLTYPE UnRegisterDeviceFilter(ULONG pvRegistrationContext); 64 65 CNetworkProvider(LPCGUID ClassID); 66 virtual ~CNetworkProvider(){}; 67 68protected: 69 LONG m_Ref; 70 IFilterGraph *m_pGraph; 71 IReferenceClock * m_ReferenceClock; 72 FILTER_STATE m_FilterState; 73 IPin * m_Pins[1]; 74 GUID m_ClassID; 75 DeviceFilterStack m_DeviceFilters; 76 IScanningTuner * m_Tuner; 77 IBDA_IPV6Filter * m_IPV6Filter; 78 IBDA_IPV4Filter * m_IPV4Filter; 79 IBDA_EthernetFilter * m_EthernetFilter; 80}; 81 82HRESULT 83STDMETHODCALLTYPE 84CNetworkProvider::QueryInterface( 85 IN REFIID refiid, 86 OUT PVOID* Output) 87{ 88 ULONG Index; 89 HRESULT hr; 90 91 *Output = NULL; 92 93 if (IsEqualGUID(refiid, IID_IUnknown)) 94 { 95 *Output = PVOID(this); 96 reinterpret_cast<IUnknown*>(*Output)->AddRef(); 97 return NOERROR; 98 } 99 if (IsEqualGUID(refiid, IID_IBaseFilter)) 100 { 101 *Output = (IBaseFilter*)(this); 102 reinterpret_cast<IBaseFilter*>(*Output)->AddRef(); 103 return NOERROR; 104 } 105 106 if (IsEqualGUID(refiid, IID_ITuner) || 107 IsEqualGUID(refiid, IID_IScanningTuner)) 108 { 109 // construct scanning tuner 110 if (!m_Tuner) 111 { 112 HRESULT hr = CScanningTunner_fnConstructor(m_DeviceFilters, refiid, (void**)&m_Tuner); 113 if (FAILED(hr)) 114 return hr; 115 } 116 m_Tuner->AddRef(); 117 *Output = (IUnknown*)m_Tuner; 118 119 return NOERROR; 120 } 121 122 if (IsEqualGUID(refiid, IID_IBDA_IPV6Filter)) 123 { 124 // construct scanning tuner 125 if (!m_IPV6Filter) 126 { 127 HRESULT hr = CIPV6Filter_fnConstructor((IBDA_NetworkProvider*)this, refiid, (void**)&m_IPV6Filter); 128 if (FAILED(hr)) 129 return hr; 130 } 131 m_IPV6Filter->AddRef(); 132 *Output = (IUnknown*)m_IPV6Filter; 133 134 return NOERROR; 135 } 136 137 if (IsEqualGUID(refiid, IID_IBDA_IPV4Filter)) 138 { 139 // construct scanning tuner 140 if (!m_IPV4Filter) 141 { 142 HRESULT hr = CIPV4Filter_fnConstructor((IBDA_NetworkProvider*)this, refiid, (void**)&m_IPV4Filter); 143 if (FAILED(hr)) 144 return hr; 145 } 146 m_IPV4Filter->AddRef(); 147 *Output = (IUnknown*)m_IPV4Filter; 148 149 return NOERROR; 150 } 151 152 if (IsEqualGUID(refiid, IID_IBDA_EthernetFilter)) 153 { 154 // construct scanning tuner 155 if (!m_EthernetFilter) 156 { 157 HRESULT hr = CIPV4Filter_fnConstructor((IBDA_NetworkProvider*)this, refiid, (void**)&m_EthernetFilter); 158 if (FAILED(hr)) 159 return hr; 160 } 161 m_EthernetFilter->AddRef(); 162 *Output = (IUnknown*)m_EthernetFilter; 163 164 return NOERROR; 165 } 166 167 if (IsEqualGUID(refiid, IID_IBDA_NetworkProvider)) 168 { 169 *Output = (IBDA_NetworkProvider*)(this); 170 reinterpret_cast<IBDA_NetworkProvider*>(*Output)->AddRef(); 171 return NOERROR; 172 } 173 174 for(Index = 0; Index < m_DeviceFilters.size(); Index++) 175 { 176 // get device filter 177 IUnknown *pFilter = m_DeviceFilters[Index]; 178 179 if (!pFilter) 180 continue; 181 182 // query for requested interface 183 hr = pFilter->QueryInterface(refiid, Output); 184 if (SUCCEEDED(hr)) 185 { 186#ifdef MSDVBNP_TRACE 187 WCHAR Buffer[MAX_PATH]; 188 LPOLESTR lpstr; 189 StringFromCLSID(refiid, &lpstr); 190 swprintf(Buffer, L"CNetworkProvider::QueryInterface: DeviceFilter %lu supports %s !!!\n", Index, lpstr); 191 OutputDebugStringW(Buffer); 192 CoTaskMemFree(lpstr); 193#endif 194 return hr; 195 } 196 } 197 198 WCHAR Buffer[MAX_PATH]; 199 LPOLESTR lpstr; 200 StringFromCLSID(refiid, &lpstr); 201 swprintf(Buffer, L"CNetworkProvider::QueryInterface: NoInterface for %s !!!\n", lpstr); 202 OutputDebugStringW(Buffer); 203 CoTaskMemFree(lpstr); 204 205 return E_NOINTERFACE; 206} 207 208CNetworkProvider::CNetworkProvider(LPCGUID ClassID) : m_Ref(0), 209 m_pGraph(0), 210 m_ReferenceClock(0), 211 m_FilterState(State_Stopped), 212 m_DeviceFilters(), 213 m_Tuner(0), 214 m_IPV6Filter(0), 215 m_IPV4Filter(0), 216 m_EthernetFilter(0) 217{ 218 m_Pins[0] = 0; 219 220 CopyMemory(&m_ClassID, ClassID, sizeof(GUID)); 221}; 222 223//------------------------------------------------------------------- 224// IBaseFilter interface 225// 226 227HRESULT 228STDMETHODCALLTYPE 229CNetworkProvider::GetClassID( 230 CLSID *pClassID) 231{ 232 OutputDebugStringW(L"CNetworkProvider::GetClassID\n"); 233 CopyMemory(&pClassID, &m_ClassID, sizeof(GUID)); 234 235 return S_OK; 236} 237 238HRESULT 239STDMETHODCALLTYPE 240CNetworkProvider::Stop() 241{ 242 OutputDebugStringW(L"CNetworkProvider::Stop\n"); 243 m_FilterState = State_Stopped; 244 return S_OK; 245} 246 247HRESULT 248STDMETHODCALLTYPE 249CNetworkProvider::Pause() 250{ 251 OutputDebugStringW(L"CNetworkProvider::Pause\n"); 252 253 m_FilterState = State_Paused; 254 return S_OK; 255} 256 257HRESULT 258STDMETHODCALLTYPE 259CNetworkProvider::Run( 260 REFERENCE_TIME tStart) 261{ 262 OutputDebugStringW(L"CNetworkProvider::Run\n"); 263 264 m_FilterState = State_Running; 265 return S_OK; 266} 267 268HRESULT 269STDMETHODCALLTYPE 270CNetworkProvider::GetState( 271 DWORD dwMilliSecsTimeout, 272 FILTER_STATE *State) 273{ 274 *State = m_FilterState; 275 return S_OK; 276} 277 278HRESULT 279STDMETHODCALLTYPE 280CNetworkProvider::SetSyncSource( 281 IReferenceClock *pClock) 282{ 283 if (pClock) 284 { 285 pClock->AddRef(); 286 287 } 288 if (m_ReferenceClock) 289 { 290 m_ReferenceClock->Release(); 291 } 292 293 m_ReferenceClock = pClock; 294 return S_OK; 295} 296 297HRESULT 298STDMETHODCALLTYPE 299CNetworkProvider::GetSyncSource( 300 IReferenceClock **pClock) 301{ 302 if (!pClock) 303 return E_POINTER; 304 305 if (m_ReferenceClock) 306 m_ReferenceClock->AddRef(); 307 308 *pClock = m_ReferenceClock; 309 return S_OK; 310} 311 312HRESULT 313STDMETHODCALLTYPE 314CNetworkProvider::EnumPins( 315 IEnumPins **ppEnum) 316{ 317 if (m_Pins[0] == 0) 318 { 319 HRESULT hr = CPin_fnConstructor(NULL, (IBaseFilter*)this, IID_IUnknown, (void**)&m_Pins[0]); 320 if (FAILED(hr)) 321 return hr; 322 } 323 324 return CEnumPins_fnConstructor(NULL, 1, m_Pins, IID_IEnumPins, (void**)ppEnum); 325} 326 327HRESULT 328STDMETHODCALLTYPE 329CNetworkProvider::FindPin( 330 LPCWSTR Id, IPin **ppPin) 331{ 332 OutputDebugStringW(L"CNetworkProvider::FindPin : NotImplemented\n"); 333 return E_NOTIMPL; 334} 335 336 337HRESULT 338STDMETHODCALLTYPE 339CNetworkProvider::QueryFilterInfo( 340 FILTER_INFO *pInfo) 341{ 342 if (!pInfo) 343 return E_POINTER; 344 345 pInfo->achName[0] = L'\0'; 346 pInfo->pGraph = m_pGraph; 347 348 if (m_pGraph) 349 m_pGraph->AddRef(); 350 351 return S_OK; 352} 353 354HRESULT 355STDMETHODCALLTYPE 356CNetworkProvider::JoinFilterGraph( 357 IFilterGraph *pGraph, 358 LPCWSTR pName) 359{ 360 if (pGraph) 361 { 362 // joining filter graph 363 m_pGraph = pGraph; 364 } 365 else 366 { 367 // leaving graph 368 m_pGraph = 0; 369 } 370 371 OutputDebugStringW(L"CNetworkProvider::JoinFilterGraph\n"); 372 return S_OK; 373} 374 375 376HRESULT 377STDMETHODCALLTYPE 378CNetworkProvider::QueryVendorInfo( 379 LPWSTR *pVendorInfo) 380{ 381 return E_NOTIMPL; 382} 383 384//------------------------------------------------------------------- 385// IAMovieSetup interface 386// 387 388HRESULT 389STDMETHODCALLTYPE 390CNetworkProvider::Register() 391{ 392 OutputDebugStringW(L"CNetworkProvider::Register : NotImplemented\n"); 393 return E_NOTIMPL; 394} 395 396HRESULT 397STDMETHODCALLTYPE 398CNetworkProvider::Unregister() 399{ 400 OutputDebugStringW(L"CNetworkProvider::Unregister : NotImplemented\n"); 401 return E_NOTIMPL; 402} 403 404//------------------------------------------------------------------- 405// IBDA_NetworkProvider interface 406// 407 408HRESULT 409STDMETHODCALLTYPE 410CNetworkProvider::PutSignalSource( 411 ULONG ulSignalSource) 412{ 413 OutputDebugStringW(L"CNetworkProvider::PutSignalSource : NotImplemented\n"); 414 return E_NOTIMPL; 415} 416 417HRESULT 418STDMETHODCALLTYPE 419CNetworkProvider::GetSignalSource( 420 ULONG *pulSignalSource) 421{ 422 OutputDebugStringW(L"CNetworkProvider::GetSignalSource : NotImplemented\n"); 423 return E_NOTIMPL; 424} 425 426HRESULT 427STDMETHODCALLTYPE 428CNetworkProvider::GetNetworkType( 429 GUID *pguidNetworkType) 430{ 431 OutputDebugStringW(L"CNetworkProvider::GetNetworkType : NotImplemented\n"); 432 return E_NOTIMPL; 433} 434 435HRESULT 436STDMETHODCALLTYPE 437CNetworkProvider::PutTuningSpace( 438 REFGUID guidTuningSpace) 439{ 440 OutputDebugStringW(L"CNetworkProvider::PutTuningSpace : NotImplemented\n"); 441 return E_NOTIMPL; 442} 443 444HRESULT 445STDMETHODCALLTYPE 446CNetworkProvider::GetTuningSpace( 447 GUID *pguidTuingSpace) 448{ 449 OutputDebugStringW(L"CNetworkProvider::GetTuningSpace : NotImplemented\n"); 450 return E_NOTIMPL; 451} 452 453HRESULT 454STDMETHODCALLTYPE 455CNetworkProvider::RegisterDeviceFilter( 456 IUnknown *pUnkFilterControl, 457 ULONG *ppvRegistrationContext) 458{ 459 HRESULT hr; 460 IBDA_DeviceControl * pDeviceControl = NULL; 461 IBDA_Topology *pTopology = NULL; 462 463 OutputDebugStringW(L"CNetworkProvider::RegisterDeviceFilter\n"); 464 465 if (!pUnkFilterControl || !ppvRegistrationContext) 466 { 467 //invalid argument 468 return E_POINTER; 469 } 470 471 // the filter must support IBDA_DeviceControl and IBDA_Topology 472 hr = pUnkFilterControl->QueryInterface(IID_IBDA_DeviceControl, (void**)&pDeviceControl); 473 if (FAILED(hr)) 474 { 475 OutputDebugStringW(L"CNetworkProvider::RegisterDeviceFilter Filter does not support IBDA_DeviceControl\n"); 476 return hr; 477 } 478 479 hr = pUnkFilterControl->QueryInterface(IID_IBDA_Topology, (void**)&pTopology); 480 if (FAILED(hr)) 481 { 482 pDeviceControl->Release(); 483 OutputDebugStringW(L"CNetworkProvider::RegisterDeviceFilter Filter does not support IID_IBDA_Topology\n"); 484 return hr; 485 } 486 487 //TODO 488 // analyize device filter 489 490 // increment reference 491 pUnkFilterControl->AddRef(); 492 493 // release IBDA_DeviceControl interface 494 pDeviceControl->Release(); 495 496 // release IBDA_Topology interface 497 pTopology->Release(); 498 499 // store registration ctx 500 *ppvRegistrationContext = (m_DeviceFilters.size() | DEVICE_FILTER_MASK); 501 502 // store filter 503 m_DeviceFilters.push_back(pUnkFilterControl); 504 505 OutputDebugStringW(L"CNetworkProvider::RegisterDeviceFilter complete\n"); 506 507 return S_OK; 508} 509 510HRESULT 511STDMETHODCALLTYPE 512CNetworkProvider::UnRegisterDeviceFilter(ULONG pvRegistrationContext) 513{ 514 ULONG Index; 515 IUnknown * pUnknown; 516 517 OutputDebugStringW(L"CNetworkProvider::UnRegisterDeviceFilter\n"); 518 519 if (!(pvRegistrationContext & DEVICE_FILTER_MASK)) 520 { 521 // invalid argument 522 return E_INVALIDARG; 523 } 524 525 // get real index 526 Index = pvRegistrationContext & ~DEVICE_FILTER_MASK; 527 528 if (Index >= m_DeviceFilters.size()) 529 { 530 // invalid argument 531 return E_INVALIDARG; 532 } 533 534 pUnknown = m_DeviceFilters[Index]; 535 if (!pUnknown) 536 { 537 // filter was already de-registered 538 return E_INVALIDARG; 539 } 540 541 // remove from vector 542 m_DeviceFilters[Index] = NULL; 543 544 // release extra reference 545 pUnknown->Release(); 546 547 return NOERROR; 548} 549 550HRESULT 551WINAPI 552CNetworkProvider_fnConstructor( 553 IUnknown *pUnknown, 554 REFIID riid, 555 LPVOID * ppv) 556{ 557 CNetworkProvider * handler = new CNetworkProvider(&CLSID_DVBTNetworkProvider); 558 559#ifdef MSDVBNP_TRACE 560 WCHAR Buffer[MAX_PATH]; 561 LPOLESTR lpstr; 562 StringFromCLSID(riid, &lpstr); 563 swprintf(Buffer, L"CNetworkProvider_fnConstructor riid %s pUnknown %p\n", lpstr, pUnknown); 564 OutputDebugStringW(Buffer); 565#endif 566 567 if (!handler) 568 return E_OUTOFMEMORY; 569 570 if (FAILED(handler->QueryInterface(riid, ppv))) 571 { 572 /* not supported */ 573 delete handler; 574 return E_NOINTERFACE; 575 } 576 return NOERROR; 577}