Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Network Provider for MPEG2 based networks * FILE: dll/directx/msdvbnp/scanningtuner.cpp * PURPOSE: IScanningTunner interface * * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) */#include "precomp.h"
class CScanningTunner : public IScanningTuner{public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
STDMETHODIMP_(ULONG) AddRef() { InterlockedIncrement(&m_Ref); return m_Ref; } STDMETHODIMP_(ULONG) Release() { InterlockedDecrement(&m_Ref); if (!m_Ref) { delete this; return 0; } return m_Ref; }
//ITuner methods HRESULT STDMETHODCALLTYPE get_TuningSpace(ITuningSpace **TuningSpace); HRESULT STDMETHODCALLTYPE put_TuningSpace(ITuningSpace *TuningSpace); HRESULT STDMETHODCALLTYPE EnumTuningSpaces(IEnumTuningSpaces **ppEnum); HRESULT STDMETHODCALLTYPE get_TuneRequest(ITuneRequest **TuneRequest); HRESULT STDMETHODCALLTYPE put_TuneRequest(ITuneRequest *TuneRequest); HRESULT STDMETHODCALLTYPE Validate(ITuneRequest *TuneRequest); HRESULT STDMETHODCALLTYPE get_PreferredComponentTypes(IComponentTypes **ComponentTypes); HRESULT STDMETHODCALLTYPE put_PreferredComponentTypes(IComponentTypes *ComponentTypes); HRESULT STDMETHODCALLTYPE get_SignalStrength(long *Strength); HRESULT STDMETHODCALLTYPE TriggerSignalEvents(long Interval);
//IScanningTuner methods HRESULT STDMETHODCALLTYPE SeekUp(); HRESULT STDMETHODCALLTYPE SeekDown(); HRESULT STDMETHODCALLTYPE ScanUp(long MillisecondsPause); HRESULT STDMETHODCALLTYPE ScanDown(long MillisecondsPause); HRESULT STDMETHODCALLTYPE AutoProgram();
CScanningTunner(std::vector<IUnknown*> & DeviceFilters) : m_Ref(0), m_TuningSpace(0), m_DeviceFilters(DeviceFilters){}; virtual ~CScanningTunner() {}; HRESULT STDMETHODCALLTYPE StartChanges(); HRESULT STDMETHODCALLTYPE CommitChanges(); HRESULT STDMETHODCALLTYPE CheckChanges(); HRESULT STDMETHODCALLTYPE SetLnbInfo(IBDA_LNBInfo * pLnbInfo, ULONG ulLOFLow, ULONG ulLOFHigh, ULONG ulSwitchFrequency); HRESULT STDMETHODCALLTYPE SetDigitalDemodulator(IBDA_DigitalDemodulator * pDigitalDemo, ModulationType ModType, FECMethod InnerFEC, BinaryConvolutionCodeRate InnerFECRate, FECMethod OuterFEC, BinaryConvolutionCodeRate OuterFECRate, ULONG SymbolRate); HRESULT SetFrequency(IBDA_FrequencyFilter * pFrequency, ULONG FrequencyMultiplier, ULONG Frequency, Polarisation Polarity, ULONG Range, ULONG Bandwidth); HRESULT STDMETHODCALLTYPE performDVBTTune(IDVBTuneRequest * pDVBTRequest, IDVBTLocator *pDVBTLocator);protected: LONG m_Ref; ITuningSpace * m_TuningSpace; std::vector<IUnknown*> & m_DeviceFilters;};
HRESULTSTDMETHODCALLTYPECScanningTunner::QueryInterface( IN REFIID refiid, OUT PVOID* Output){ if (IsEqualGUID(refiid, IID_IUnknown)) { *Output = PVOID(this); reinterpret_cast<IUnknown*>(*Output)->AddRef(); return NOERROR; } if (IsEqualGUID(refiid, IID_ITuner)) { *Output = (ITuner*)(this); reinterpret_cast<ITuner*>(*Output)->AddRef(); return NOERROR; }
if (IsEqualGUID(refiid, IID_IScanningTuner)) { *Output = (IScanningTuner*)(this); reinterpret_cast<IScanningTuner*>(*Output)->AddRef(); return NOERROR; }
WCHAR Buffer[MAX_PATH]; LPOLESTR lpstr; StringFromCLSID(refiid, &lpstr); swprintf(Buffer, L"CScanningTunner::QueryInterface: NoInterface for %s\n", lpstr); OutputDebugStringW(Buffer); CoTaskMemFree(lpstr);
return E_NOINTERFACE;}
//-------------------------------------------------------------------//ITuner//HRESULTSTDMETHODCALLTYPECScanningTunner::get_TuningSpace( ITuningSpace **TuningSpace){ OutputDebugStringW(L"CScanningTunner::get_TuningSpace\n");
*TuningSpace = m_TuningSpace; return S_OK;}
HRESULTSTDMETHODCALLTYPECScanningTunner::put_TuningSpace( ITuningSpace *TuningSpace){ OutputDebugStringW(L"CScanningTunner::put_TuningSpace\n"); m_TuningSpace = TuningSpace; return S_OK;}
HRESULTSTDMETHODCALLTYPECScanningTunner::EnumTuningSpaces( IEnumTuningSpaces **ppEnum){ OutputDebugStringW(L"CScanningTunner::EnumTuningSpaces : NotImplemented\n"); return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECScanningTunner::get_TuneRequest( ITuneRequest **TuneRequest){ OutputDebugStringW(L"CScanningTunner::get_TuneRequest : NotImplemented\n"); return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECScanningTunner::put_TuneRequest( ITuneRequest *TuneRequest){ IDVBTuneRequest * pDVBTRequest; ILocator *pLocator; IDVBTLocator *pDVBTLocator; HRESULT hr;
OutputDebugStringW(L"CScanningTunner::put_TuneRequest\n");
// query for IDVBTuneRequest interface hr = TuneRequest->QueryInterface(IID_IDVBTuneRequest, (void**)&pDVBTRequest);
// sanity check assert(hr == NOERROR);
// get the IDVBTLocator hr = pDVBTRequest->get_Locator((ILocator**)&pLocator);
// sanity check assert(hr == NOERROR); assert(pLocator);
hr = pLocator->QueryInterface(IID_ILocator, (void**)&pDVBTLocator);
// sanity check assert(hr == NOERROR);
StartChanges(); CommitChanges(); StartChanges();
hr = performDVBTTune(pDVBTRequest, pDVBTLocator);
pDVBTLocator->Release(); pDVBTRequest->Release();
CheckChanges(); CommitChanges(); StartChanges();
return NOERROR;}
HRESULTSTDMETHODCALLTYPECScanningTunner::Validate( ITuneRequest *TuneRequest){ OutputDebugStringW(L"CScanningTunner::Validate : NotImplemented\n"); return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECScanningTunner::get_PreferredComponentTypes( IComponentTypes **ComponentTypes){ OutputDebugStringW(L"CScanningTunner::get_PreferredComponentTypes : NotImplemented\n"); return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECScanningTunner::put_PreferredComponentTypes( IComponentTypes *ComponentTypes){ OutputDebugStringW(L"CScanningTunner::put_PreferredComponentTypes : NotImplemented\n"); return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECScanningTunner::get_SignalStrength( long *Strength){ OutputDebugStringW(L"CScanningTunner::get_SignalStrength : NotImplemented\n"); return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECScanningTunner::TriggerSignalEvents( long Interval){ OutputDebugStringW(L"CScanningTunner::TriggerSignalEvents : NotImplemented\n"); return E_NOTIMPL;}
//-------------------------------------------------------------------//IScanningTunerHRESULTSTDMETHODCALLTYPECScanningTunner::SeekUp(){ OutputDebugStringW(L"CScanningTunner::SeekUp : NotImplemented\n"); return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECScanningTunner::SeekDown(){ OutputDebugStringW(L"CScanningTunner::SeekDown : NotImplemented\n"); return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECScanningTunner::ScanUp( long MillisecondsPause){ OutputDebugStringW(L"CScanningTunner::ScanUp : NotImplemented\n"); return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECScanningTunner::ScanDown( long MillisecondsPause){ OutputDebugStringW(L"CScanningTunner::ScanDown : NotImplemented\n"); return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECScanningTunner::AutoProgram(){ OutputDebugStringW(L"CScanningTunner::AutoProgram : NotImplemented\n"); return E_NOTIMPL;}
//-------------------------------------------------------------------HRESULTSTDMETHODCALLTYPECScanningTunner::performDVBTTune( IDVBTuneRequest * pDVBTRequest, IDVBTLocator *pDVBTLocator){ HRESULT hr = S_OK; ULONG Index; IBDA_Topology *pTopo; IUnknown *pNode; IBDA_FrequencyFilter * pFrequency; IBDA_LNBInfo * pLnbInfo; IBDA_DigitalDemodulator *pDigitalDemo; LONG BandWidth; LONG Frequency; LONG SymbolRate; FECMethod InnerFEC, OuterFEC; BinaryConvolutionCodeRate InnerFECRate, OuterFECRate; ModulationType Modulation;
pDVBTLocator->get_Bandwidth(&BandWidth); pDVBTLocator->get_CarrierFrequency(&Frequency); pDVBTLocator->get_InnerFEC(&InnerFEC); pDVBTLocator->get_InnerFECRate(&InnerFECRate); pDVBTLocator->get_Modulation(&Modulation); pDVBTLocator->get_OuterFEC(&OuterFEC); pDVBTLocator->get_OuterFECRate(&OuterFECRate); pDVBTLocator->get_SymbolRate(&SymbolRate);
WCHAR Buffer[1000]; swprintf(Buffer, L"BandWidth %lu Frequency %lu Rate %lu InnerFEC %ld OuterFEC %ld InnerFECRate %ld OuterFECRate %ld Modulation %lu\n", BandWidth, Frequency, SymbolRate, InnerFEC, OuterFEC, InnerFECRate, OuterFECRate, Modulation);
OutputDebugStringW(Buffer);
for(Index = 0; Index < m_DeviceFilters.size(); Index++) { // get device filter IUnknown * pFilter = m_DeviceFilters[Index];
if (!pFilter) continue;
hr = pFilter->QueryInterface(IID_IBDA_Topology, (void**)&pTopo); // sanity check assert(hr == NOERROR);
pNode = NULL; hr = pTopo->GetControlNode(0, 1, 0, &pNode); //HACK
WCHAR Buffer[100]; swprintf(Buffer, L"CScanningTunner::performDVBTTune GetControlNode %lx\n", hr); OutputDebugStringW(Buffer);
if (FAILED(hr)) continue;
// sanity check assert(hr == NOERROR); assert(pNode);
hr = pNode->QueryInterface(IID_IBDA_FrequencyFilter, (void**)&pFrequency);
swprintf(Buffer, L"CScanningTunner::performDVBTTune IID_IBDA_FrequencyFilter hr %lx\n", hr); OutputDebugStringW(Buffer);
// sanity check assert(hr == NOERROR);
hr = SetFrequency(pFrequency, 1000 /* FIXME */, Frequency, BDA_POLARISATION_NOT_DEFINED /* FIXME */, BDA_RANGE_NOT_SET /* FIXME */, BandWidth);
swprintf(Buffer, L"CScanningTunner::performDVBTTune SetFrequency hr %lx\n", hr); OutputDebugStringW(Buffer);
//sanity check assert(hr == NOERROR);
// release interface pFrequency->Release();
hr = pNode->QueryInterface(IID_IBDA_LNBInfo, (void**)&pLnbInfo);
swprintf(Buffer, L"CScanningTunner::performDVBTTune IID_IBDA_LNBInfo hr %lx\n", hr); OutputDebugStringW(Buffer);
// sanity check assert(hr == NOERROR);
hr = SetLnbInfo(pLnbInfo, ULONG_MAX /* FIXME */, ULONG_MAX /* FIXME*/, ULONG_MAX /*FIXME*/);
swprintf(Buffer, L"CScanningTunner::performDVBTTune SetLnbInfo hr %lx\n", hr); OutputDebugStringW(Buffer);
// sanity check assert(hr == NOERROR);
// release interface pLnbInfo->Release();
hr = pNode->QueryInterface(IID_IBDA_DigitalDemodulator, (void**)&pDigitalDemo);
swprintf(Buffer, L"CScanningTunner::performDVBTTune IID_IBDA_DigitalDemodulator hr %lx\n", hr); OutputDebugStringW(Buffer);
// sanity check assert(hr == NOERROR);
hr = SetDigitalDemodulator(pDigitalDemo, Modulation, InnerFEC, InnerFECRate, OuterFEC, OuterFECRate, SymbolRate);
swprintf(Buffer, L"CScanningTunner::performDVBTTune SetDigitalDemodulator hr %lx\n", hr); OutputDebugStringW(Buffer);
// sanity check assert(hr == NOERROR);
// release interface pDigitalDemo->Release();
// release control node pNode->Release();
// release IBDA_Topology; pTopo->Release();
} return hr;}
HRESULTSTDMETHODCALLTYPECScanningTunner::CheckChanges(){ ULONG Index; HRESULT hResult = NOERROR; IBDA_DeviceControl * pDeviceControl;
for(Index = 0; Index < m_DeviceFilters.size(); Index++) { // get filter IUnknown * pFilter = m_DeviceFilters[Index];
if (!pFilter) continue;
// query for IBDA_DeviceControl interface hResult = pFilter->QueryInterface(IID_IBDA_DeviceControl, (void**)&pDeviceControl);
// sanity check assert(hResult == NOERROR);
//start changes hResult = pDeviceControl->CheckChanges();
// fix for unimplemented if (hResult == E_NOTIMPL) hResult = NOERROR;
// release interface pDeviceControl->Release();
if (FAILED(hResult)) { //shouldnt happen break; } } // done return hResult;}
HRESULTSTDMETHODCALLTYPECScanningTunner::CommitChanges(){ ULONG Index; HRESULT hResult = NOERROR; IBDA_DeviceControl * pDeviceControl;
for(Index = 0; Index < m_DeviceFilters.size(); Index++) { // get filter IUnknown * pFilter = m_DeviceFilters[Index];
if (!pFilter) continue;
// query for IBDA_DeviceControl interface HRESULT hr = pFilter->QueryInterface(IID_IBDA_DeviceControl, (void**)&pDeviceControl);
// sanity check assert(hr == NOERROR);
//start changes hr = pDeviceControl->CommitChanges();
// fix for unimplemented if (hr == E_NOTIMPL) hr = NOERROR;
if (FAILED(hr)) { pDeviceControl->StartChanges(); pDeviceControl->CommitChanges(); hResult = E_UNEXPECTED; }
// release interface pDeviceControl->Release();
}
//done return hResult;}
HRESULTSTDMETHODCALLTYPECScanningTunner::StartChanges(){ ULONG Index; IBDA_DeviceControl * pDeviceControl;
for(Index = 0; Index < m_DeviceFilters.size(); Index++) { // get filter IUnknown * pFilter = m_DeviceFilters[Index];
if (!pFilter) continue;
// query for IBDA_DeviceControl interface HRESULT hr = pFilter->QueryInterface(IID_IBDA_DeviceControl, (void**)&pDeviceControl);
// sanity check assert(hr == NOERROR);
//start changes hr = pDeviceControl->StartChanges();
// release interface pDeviceControl->Release();
// fix for unimplemented if (hr == E_NOTIMPL) hr = NOERROR;
if (FAILED(hr)) return hr;
}
// now commit the changes for(Index = 0; Index < m_DeviceFilters.size(); Index++) { // get filter IUnknown * pFilter = m_DeviceFilters[Index];
if (!pFilter) continue;
// query for IBDA_DeviceControl interface HRESULT hr = pFilter->QueryInterface(IID_IBDA_DeviceControl, (void**)&pDeviceControl);
// sanity check assert(hr == NOERROR);
hr = pDeviceControl->CommitChanges();
// release interface pDeviceControl->Release(); }
// done return NOERROR;}
HRESULTSTDMETHODCALLTYPECScanningTunner::SetLnbInfo( IBDA_LNBInfo * pLnbInfo, ULONG ulLOFLow, ULONG ulLOFHigh, ULONG ulSwitchFrequency){ HRESULT hr;
hr = pLnbInfo->put_LocalOscillatorFrequencyLowBand(ulLOFLow); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND)) hr = NOERROR;
if (FAILED(hr)) return hr;
hr = pLnbInfo->put_LocalOscillatorFrequencyHighBand(ulLOFHigh); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND)) hr = NOERROR;
if (FAILED(hr)) return hr;
hr = pLnbInfo->put_HighLowSwitchFrequency(ulSwitchFrequency); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND)) hr = NOERROR;
return hr;}
HRESULTCScanningTunner::SetFrequency( IBDA_FrequencyFilter * pFrequency, ULONG FrequencyMultiplier, ULONG Frequency, Polarisation Polarity, ULONG Range, ULONG Bandwidth){ HRESULT hr;
hr = pFrequency->put_FrequencyMultiplier(FrequencyMultiplier); if (FAILED(hr)) return hr;
hr = pFrequency->put_Frequency(Frequency); if (FAILED(hr)) return hr;
hr = pFrequency->put_Polarity(Polarity); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND)) hr = NOERROR;
if (FAILED(hr)) return hr;
hr = pFrequency->put_Range(Range); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND)) hr = NOERROR;
if (FAILED(hr)) return hr;
hr = pFrequency->put_Bandwidth(Bandwidth); return hr;}
HRESULTSTDMETHODCALLTYPECScanningTunner::SetDigitalDemodulator( IBDA_DigitalDemodulator * pDigitalDemo, ModulationType ModType, FECMethod InnerFEC, BinaryConvolutionCodeRate InnerFECRate, FECMethod OuterFEC, BinaryConvolutionCodeRate OuterFECRate, ULONG SymbolRate){ HRESULT hr;
hr = pDigitalDemo->put_ModulationType(&ModType); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND)) hr = NOERROR;
if (FAILED(hr)) return hr;
hr = pDigitalDemo->put_InnerFECMethod(&InnerFEC); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND)) hr = NOERROR; if (FAILED(hr)) return hr;
hr = pDigitalDemo->put_InnerFECRate(&InnerFECRate); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND)) hr = NOERROR; if (FAILED(hr)) return hr;
hr = pDigitalDemo->put_OuterFECMethod(&OuterFEC); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND)) hr = NOERROR; if (FAILED(hr)) return hr;
hr = pDigitalDemo->put_OuterFECRate(&OuterFECRate); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND)) hr = NOERROR; if (FAILED(hr)) return hr;
hr = pDigitalDemo->put_SymbolRate(&SymbolRate); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND)) hr = NOERROR; if (FAILED(hr)) return hr;
SpectralInversion Inversion = BDA_SPECTRAL_INVERSION_NOT_DEFINED; hr = pDigitalDemo->put_SpectralInversion(&Inversion); if (hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_FOUND) || hr == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_SET_NOT_FOUND)) hr = NOERROR;
return hr;}
HRESULTWINAPICScanningTunner_fnConstructor( std::vector<IUnknown*> & DeviceFilter, REFIID riid, LPVOID * ppv){ CScanningTunner * handler = new CScanningTunner(DeviceFilter);
#ifdef MSDVBNP_TRACE WCHAR Buffer[MAX_PATH]; LPOLESTR lpstr; StringFromCLSID(riid, &lpstr); swprintf(Buffer, L"CScanningTunner_fnConstructor riid %s\n", lpstr); OutputDebugStringW(Buffer);#endif
if (!handler) return E_OUTOFMEMORY;
if (FAILED(handler->QueryInterface(riid, ppv))) { /* not supported */ delete handler; return E_NOINTERFACE; }
return NOERROR;}