/*++ Copyright (c) 1997-1999 Microsoft Corporation Module Name: ptreg.cpp Abstract: Implementation of Plug-Terminal Registration classes. --*/ #include "stdafx.h" #include "PTReg.h" #include "manager.h" #include #include // // CPlugTerminal class implementation // Create free thread marshaler // HRESULT CPlugTerminal::FinalConstruct(void) { LOG((MSP_TRACE, "CPlugTerminal::FinalConstruct - enter")); HRESULT hr = CoCreateFreeThreadedMarshaler( GetControllingUnknown(), & m_pFTM ); if ( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminal::FinalConstruct - " "create FTM returned 0x%08x; exit", hr)); return hr; } LOG((MSP_TRACE, "CPlugTerminal::FinalConstruct - exit S_OK")); return S_OK; } // // CPlugTerminal class implementation // --- ITPTRegTerminal interface --- // STDMETHODIMP CPlugTerminal::get_Name( /*[out, retval]*/ BSTR* pName ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::get_Name - enter")); // // Validates argument // if( TM_IsBadWritePtr( pName, sizeof(BSTR)) ) { LOG((MSP_ERROR, "CPlugTerminal::get_Name exit -" "pName invalid, returns E_POINTER")); return E_POINTER; } // // Validates the name // if( IsBadStringPtr( m_Terminal.m_bstrName, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminal::get_Name exit -" "m_bstrName invalid, returns E_UNEXPECTED")); return E_UNEXPECTED; } // // Return the name // *pName = SysAllocString( m_Terminal.m_bstrName ); // // Validates SysAllocString // if( *pName == NULL ) { LOG((MSP_ERROR, "CPlugTerminal::get_Name exit -" "SysAllocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } LOG((MSP_TRACE, "CPlugTerminal::get_Name - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::put_Name( /*[in]*/ BSTR bstrName ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::put_Name - enter")); // // Validates argument // if(IsBadStringPtr( bstrName, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminal::put_Name exit -" "bstrName invalid, returns E_POINTER")); return E_POINTER; } // // Clean-up the old name // if(!IsBadStringPtr( m_Terminal.m_bstrName, (UINT)-1) ) { SysFreeString( m_Terminal.m_bstrName ); m_Terminal.m_bstrName = NULL; } // // Set the new name // m_Terminal.m_bstrName = SysAllocString( bstrName ); // // Validates SysAllocString // if( NULL == m_Terminal.m_bstrName ) { LOG((MSP_ERROR, "CPlugTerminal::put_Name exit -" "SysAllocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } LOG((MSP_TRACE, "CPlugTerminal::put_Name - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::get_Company( /*[out, retval]*/ BSTR* pCompany ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::get_Company - enter")); // // Validates argument // if( TM_IsBadWritePtr( pCompany, sizeof(BSTR)) ) { LOG((MSP_ERROR, "CPlugTerminal::get_Company exit -" "pCompany invalid, returns E_POINTER")); return E_POINTER; } // // Validates the company // if( IsBadStringPtr( m_Terminal.m_bstrCompany, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminal::get_Company exit -" "m_bstrCompany invalid, returns E_UNEXPECTED")); return E_UNEXPECTED; } // // Return the Company // *pCompany = SysAllocString( m_Terminal.m_bstrCompany ); // // Validates SysAllocString // if( *pCompany == NULL ) { LOG((MSP_ERROR, "CPlugTerminal::get_Company exit -" "SysAllocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } LOG((MSP_TRACE, "CPlugTerminal::get_Company - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::put_Company( /*[in]*/ BSTR bstrCompany ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::put_Company - enter")); // // Validates argument // if(IsBadStringPtr( bstrCompany, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminal::put_Company exit -" "bstrCompany invalid, returns E_POINTER")); return E_POINTER; } // // Clean-up the old company // if(!IsBadStringPtr( m_Terminal.m_bstrCompany, (UINT)-1) ) { SysFreeString( m_Terminal.m_bstrCompany ); m_Terminal.m_bstrCompany = NULL; } // // Set the new company // m_Terminal.m_bstrCompany = SysAllocString( bstrCompany ); // // Validates SysAllocString // if( NULL == m_Terminal.m_bstrCompany ) { LOG((MSP_ERROR, "CPlugTerminal::put_Company exit -" "SysAllocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } LOG((MSP_TRACE, "CPlugTerminal::put_Company - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::get_Version( /*[out, retval]*/ BSTR* pVersion ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::get_Version - enter")); // // Validates argument // if( TM_IsBadWritePtr( pVersion, sizeof(BSTR)) ) { LOG((MSP_ERROR, "CPlugTerminal::get_Version exit -" "pVersion invalid, returns E_POINTER")); return E_POINTER; } // // Validates the version // if( IsBadStringPtr( m_Terminal.m_bstrVersion, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminal::get_Version exit -" "m_bstrVersion invalid, returns E_UNEXPECTED")); return E_UNEXPECTED; } // // Return the Version // *pVersion = SysAllocString( m_Terminal.m_bstrVersion ); // // Validates SysAllocString // if( *pVersion == NULL ) { LOG((MSP_ERROR, "CPlugTerminal::get_Version exit -" "SysAllocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } LOG((MSP_TRACE, "CPlugTerminal::get_Version - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::put_Version( /*[in]*/ BSTR bstrVersion ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::put_Version - enter")); // // Validates argument // if(IsBadStringPtr( bstrVersion, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminal::put_Version exit -" "bstrVersion invalid, returns E_POINTER")); return E_POINTER; } // // Clean-up the old version // if(!IsBadStringPtr( m_Terminal.m_bstrVersion, (UINT)-1) ) { SysFreeString( m_Terminal.m_bstrVersion ); m_Terminal.m_bstrVersion = NULL; } // // Set the new Version // m_Terminal.m_bstrVersion = SysAllocString( bstrVersion ); // // Validates SysAllocString // if( NULL == m_Terminal.m_bstrVersion ) { LOG((MSP_ERROR, "CPlugTerminal::put_Version exit -" "SysAllocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } LOG((MSP_TRACE, "CPlugTerminal::put_Version - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::get_TerminalClass( /*[out, retval]*/ BSTR* pTerminalClass ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::get_TerminalClass - enter")); // // Validates argument // if( TM_IsBadWritePtr( pTerminalClass, sizeof(BSTR)) ) { LOG((MSP_ERROR, "CPlugTerminal::get_TerminalClass exit -" "pTerminalClass invalid, returns E_POINTER")); return E_POINTER; } // // Return the TerminalClass // LPOLESTR lpszTerminalClass = NULL; HRESULT hr = StringFromCLSID( m_Terminal.m_clsidTerminalClass, &lpszTerminalClass ); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminal::get_TerminalClass exit -" "StringFromCLSID failed, returns 0x%08x", hr)); return hr; } *pTerminalClass = SysAllocString( lpszTerminalClass ); // Clean-up CoTaskMemFree( lpszTerminalClass ); // // Validates SysAllocString // if( *pTerminalClass == NULL ) { LOG((MSP_ERROR, "CPlugTerminal::get_TerminalClass exit -" "SysAllocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } LOG((MSP_TRACE, "CPlugTerminal::get_TerminalClass - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::put_TerminalClass( /*[in]*/ BSTR bstrTerminalClass ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::put_TerminalClass - enter")); // // Validates argument // if(IsBadStringPtr( bstrTerminalClass, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminal::put_TerminalClass exit -" "bstrTerminalClass invalid, returns E_POINTER")); return E_POINTER; } // // Is a real CLSID? // CLSID clsidTerminalClass; HRESULT hr = CLSIDFromString(bstrTerminalClass, &clsidTerminalClass); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminal::put_TerminalClass exit -" "bstrTerminalClass is not a CLSID, returns E_INVALIDARG")); return E_INVALIDARG; } // // Clean-up the old TerminalClass // m_Terminal.m_clsidTerminalClass = clsidTerminalClass; LOG((MSP_TRACE, "CPlugTerminal::put_TerminalClass - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::get_CLSID( /*[out, retval]*/ BSTR* pCLSID ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::get_CLSID - enter")); // // Validates argument // if( TM_IsBadWritePtr( pCLSID, sizeof(BSTR)) ) { LOG((MSP_ERROR, "CPlugTerminal::get_CLSID exit -" "pCLSID invalid, returns E_POINTER")); return E_POINTER; } if( m_Terminal.m_clsidCOM == CLSID_NULL ) { LOG((MSP_ERROR, "CPlugTerminal::get_CLSID exit -" "clsid is NULL, returns E_UNEXPECTED")); return E_UNEXPECTED; } // // Return the CLSID // LPOLESTR lpszCLSID = NULL; HRESULT hr = StringFromCLSID( m_Terminal.m_clsidCOM, &lpszCLSID); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminal::get_CLSID exit -" "StringFromCLSID failed, returns 0x%08x", hr)); return hr; } *pCLSID = SysAllocString( lpszCLSID ); // Clean-up CoTaskMemFree( lpszCLSID ); // // Validates SysAllocString // if( *pCLSID == NULL ) { LOG((MSP_ERROR, "CPlugTerminal::get_CLSID exit -" "SysAllocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } LOG((MSP_TRACE, "CPlugTerminal::get_CLSID - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::put_CLSID( /*[in]*/ BSTR bstrCLSID ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::put_CLSID - enter")); // // Validates argument // if(IsBadStringPtr( bstrCLSID, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminal::put_CLSID exit -" "bstrCLSID invalid, returns E_POINTER")); return E_POINTER; } // // Is a real CLSID? // CLSID clsidCOM; HRESULT hr = CLSIDFromString(bstrCLSID, &clsidCOM); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminal::put_CLSID exit -" "bstrCLSID is not a CLSID, returns E_INVALIDARG")); return E_INVALIDARG; } // // Clean-up the old CLSID // m_Terminal.m_clsidCOM = clsidCOM; LOG((MSP_TRACE, "CPlugTerminal::put_CLSID - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::get_Direction( /*[out, retval]*/ TMGR_DIRECTION* pDirection ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::get_Direction - enter")); // // Validates argument // if( TM_IsBadWritePtr( pDirection, sizeof(long)) ) { LOG((MSP_ERROR, "CPlugTerminal::get_Direction exit -" "pDirections invalid, returns E_POINTER")); return E_POINTER; } // // Return the Direction // *pDirection = (TMGR_DIRECTION)m_Terminal.m_dwDirections; LOG((MSP_TRACE, "CPlugTerminal::get_Direction - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::put_Direction( /*[in]*/ TMGR_DIRECTION nDirection ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::put_Direction - enter")); if( nDirection == 0 ) { LOG((MSP_ERROR, "CPlugTerminal::put_Direction exit -" "nDirections invalid, returns E_INVALIDARG")); return E_INVALIDARG; } if( (nDirection & ( ((long)TMGR_TD_RENDER) | ((long)TMGR_TD_CAPTURE))) != nDirection ) { LOG((MSP_ERROR, "CPlugTerminal::put_Direction exit -" "nDirections invalid, returns E_INVALIDARG")); return E_INVALIDARG; } // // Set the new direction // m_Terminal.m_dwDirections = nDirection; LOG((MSP_TRACE, "CPlugTerminal::put_Direction - exit S_OK")); return S_OK; } STDMETHODIMP CPlugTerminal::get_MediaTypes( /*[out, retval]*/ long* pMediaTypes ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::get_MediaTypes - enter")); // // Validates argument // if( TM_IsBadWritePtr( pMediaTypes, sizeof(long)) ) { LOG((MSP_ERROR, "CPlugTerminal::get_MediaTypes exit -" "pMediaTypes invalid, returns E_POINTER")); return E_POINTER; } // // Return the MediaTypes // *pMediaTypes = (long)m_Terminal.m_dwMediaTypes; LOG((MSP_TRACE, "CPlugTerminal::get_MediaTypes - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::put_MediaTypes( /*[in]*/ long nMediaTypes ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::put_MediaTypes - enter")); if( nMediaTypes == 0) { LOG((MSP_ERROR, "CPlugTerminal::put_MediaTypes exit -" "nMediaTypes invalid, returns E_INVALIDARG")); return E_INVALIDARG; } if( (nMediaTypes & ( ((long)TAPIMEDIATYPE_AUDIO) | ((long)TAPIMEDIATYPE_VIDEO) | ((long)TAPIMEDIATYPE_MULTITRACK))) != nMediaTypes ) { LOG((MSP_ERROR, "CPlugTerminal::put_MediaTypes exit -" "nMediaTypes invalid, returns E_INVALIDARG")); return E_INVALIDARG; } // // Set the new direction // m_Terminal.m_dwMediaTypes = nMediaTypes; LOG((MSP_TRACE, "CPlugTerminal::put_MediaTypes - exit")); return S_OK; } STDMETHODIMP CPlugTerminal::Add( /*[in]*/ BSTR bstrSuperclass ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::Add - enter")); // // Validates argument // if(IsBadStringPtr( bstrSuperclass, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminal::Add exit -" "bstrTermClassCLSID invalid, returns E_POINTER")); return E_POINTER; } // // Is a real CLSID // CLSID clsidSuperclass = CLSID_NULL; HRESULT hr = E_FAIL; hr = CLSIDFromString( bstrSuperclass, &clsidSuperclass); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminal::Add exit -" "bstrTermClassCLSID is not a CLSID, returns E_INVALIDARG")); return E_INVALIDARG; } // // Add // hr = m_Terminal.Add( clsidSuperclass ); LOG((MSP_TRACE, "CPlugTerminal::Add - exit 0x%08x", hr)); return hr; } STDMETHODIMP CPlugTerminal::Delete( /*[in]*/ BSTR bstrSuperclass ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::Delete - enter")); // // Validates argument // if(IsBadStringPtr( bstrSuperclass, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminal::Delete exit -" "bstrTermClassCLSID invalid, returns E_POINTER")); return E_POINTER; } // // Is a real CLSID // CLSID clsidSuperclass = CLSID_NULL; HRESULT hr = E_FAIL; hr = CLSIDFromString( bstrSuperclass, &clsidSuperclass); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminal::Delete exit -" "bstrTermClassCLSID is not a CLSID, returns E_INVALIDARG")); return E_INVALIDARG; } // // Delete // hr = m_Terminal.Delete( clsidSuperclass ); LOG((MSP_TRACE, "CPlugTerminal::Delete - exit 0x%08x", hr)); return hr; } STDMETHODIMP CPlugTerminal::GetTerminalClassInfo( /*[in]*/ BSTR bstrSuperclass ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminal::GetTerminal - enter")); // // Validates argument // if(IsBadStringPtr( bstrSuperclass, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminal::GetTerminal exit -" "bstrTermClassCLSID invalid, returns E_POINTER")); return E_POINTER; } // // Is a real CLSID // CLSID clsidSuperclass = CLSID_NULL; HRESULT hr = E_FAIL; hr = CLSIDFromString( bstrSuperclass, &clsidSuperclass); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminal::GetTerminal exit -" "bstrTermClassCLSID is not a CLSID, returns E_INVALIDARG")); return E_INVALIDARG; } // // Get terminal // hr = m_Terminal.Get( clsidSuperclass ); LOG((MSP_TRACE, "CPlugTerminal::GetTerminal - exit 0x%08x", hr)); return hr; } // // CPlugTerminalSuperlass class implementation // Create free thread marshaler // HRESULT CPlugTerminalSuperclass::FinalConstruct(void) { LOG((MSP_TRACE, "CPlugTerminalSuperclass::FinalConstruct - enter")); HRESULT hr = CoCreateFreeThreadedMarshaler( GetControllingUnknown(), & m_pFTM ); if ( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::FinalConstruct - " "create FTM returned 0x%08x; exit", hr)); return hr; } LOG((MSP_TRACE, "CPlugTerminalSuperclass::FinalConstruct - exit S_OK")); return S_OK; } // // CPlugTerminalSuperlass class implementation // --- ITPTRegTerminalClass interface --- // STDMETHODIMP CPlugTerminalSuperclass::get_Name( /*[out, retval]*/ BSTR* pName ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_Name - enter")); // // Validates argument // if( TM_IsBadWritePtr( pName, sizeof(BSTR)) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_Name exit -" "pName invalid, returns E_POINTER")); return E_POINTER; } // // Validate internal name // if( IsBadStringPtr( m_Superclass.m_bstrName, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_Name exit -" "bstrName invalid, returns E_UNEXPECTED")); return E_UNEXPECTED; } // // Returns name // *pName = SysAllocString( m_Superclass.m_bstrName); // // Validate SysAllocString // if( *pName == NULL ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_Name exit -" "SysAllocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_Name - exit")); return S_OK; } STDMETHODIMP CPlugTerminalSuperclass::put_Name( /*[in]*/ BSTR bstrName ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminalSuperclass::put_Name - enter")); // // Validates argument // if(IsBadStringPtr( bstrName, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::put_Name exit -" "bstrName invalid, returns E_POINTER")); return E_POINTER; } // // Clean-up the old name // if(!IsBadStringPtr( m_Superclass.m_bstrName, (UINT)-1) ) { SysFreeString( m_Superclass.m_bstrName ); m_Superclass.m_bstrName = NULL; } // // Set the new name // m_Superclass.m_bstrName = SysAllocString( bstrName ); // // Validates the sysAllocString // if( NULL == m_Superclass.m_bstrName ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::put_Name exit -" "SysAllocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } LOG((MSP_TRACE, "CPlugTerminalSuperclass::put_Name - exit")); return S_OK; } STDMETHODIMP CPlugTerminalSuperclass::get_CLSID( /*[out, retval]*/ BSTR* pCLSIDClass ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_CLSIDClass - enter")); // // Validates argument // if( TM_IsBadWritePtr( pCLSIDClass, sizeof(BSTR)) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_CLSIDClass exit -" "pCLSIDClass invalid, returns E_POINTER")); return E_POINTER; } // // Returns CLSID // LPOLESTR lpszSuperclassCLSID = NULL; HRESULT hr = StringFromCLSID( m_Superclass.m_clsidSuperclass, &lpszSuperclassCLSID); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_CLSIDClass exit -" "StringFromClSID failed, returns 0x%08x", hr)); return hr; } *pCLSIDClass = SysAllocString( lpszSuperclassCLSID); // Clean-up CoTaskMemFree( lpszSuperclassCLSID ); // // Validates SysAllocString // if( *pCLSIDClass == NULL ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_CLSIDClass exit -" "SysAllocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_CLSIDClass - exit")); return S_OK; } STDMETHODIMP CPlugTerminalSuperclass::put_CLSID( /*[in]*/ BSTR bstrCLSIDClass ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminalSuperclass::put_CLSIDClass - enter")); // // Validates argument // if(IsBadStringPtr( bstrCLSIDClass, (UINT)-1) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::put_CLSIDClass exit -" "bstrCLSIDClass invalid, returns E_POINTER")); return E_POINTER; } // // Is a real CLSID? // CLSID clsidSuperclassClSID; HRESULT hr = CLSIDFromString(bstrCLSIDClass, &clsidSuperclassClSID); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::put_CLSIDClass exit -" "bstrCLSIDClass is not a CLSID, returns E_INVALIDARG")); return E_INVALIDARG; } // // Clean-up the old CLSID // m_Superclass.m_clsidSuperclass = clsidSuperclassClSID; LOG((MSP_TRACE, "CPlugTerminalSuperclass::put_CLSIDClasse - exit")); return S_OK; } STDMETHODIMP CPlugTerminalSuperclass::Add( ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminalSuperclass::Add - enter")); // // Add terminal class // HRESULT hr = E_FAIL; hr = m_Superclass.Add(); LOG((MSP_TRACE, "CPlugTerminalSuperclass::Add - exit 0x%08x", hr)); return hr; } STDMETHODIMP CPlugTerminalSuperclass::Delete( ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminalSuperclass::Deletee - enter")); // // Delete terminalc class // HRESULT hr = E_FAIL; hr = m_Superclass.Delete(); LOG((MSP_TRACE, "CPlugTerminalSuperclass::Delete - exit 0x%08x",hr)); return hr; } STDMETHODIMP CPlugTerminalSuperclass::GetTerminalSuperclassInfo( ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminalSuperclass::GetTerminalSuperclassInfo - enter")); // // Get terminal class from registry // HRESULT hr = E_FAIL; hr = m_Superclass.Get(); LOG((MSP_TRACE, "CPlugTerminalSuperclass::GetTerminalSuperclassInfo - exit 0x%08x",hr)); return hr; } STDMETHODIMP CPlugTerminalSuperclass::get_TerminalClasses( /*[out, retval]*/ VARIANT* pVarTerminals ) { // // Critical section // CLock lock(m_CritSect); LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_TerminalClasses - enter")); // // Validates argument // if( TM_IsBadWritePtr( pVarTerminals, sizeof(VARIANT)) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -" "pTerminals invalid, returns E_POINTER")); return E_POINTER; } // // reset the output argument // pVarTerminals->parray = NULL; pVarTerminals->vt = VT_EMPTY; // // List the terminals // HRESULT hr = E_FAIL; CLSID* pTerminals = NULL; DWORD dwTerminals = 0; hr = m_Superclass.ListTerminalClasses( 0, &pTerminals, &dwTerminals ); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -" "ListTerminalClasses failed, returns 0x%08x", hr)); return hr; } // // Create a safe array for the terminasl // SAFEARRAY* psaTerminals = NULL; SAFEARRAYBOUND rgsabound; rgsabound.lLbound = 1; rgsabound.cElements = dwTerminals; psaTerminals = SafeArrayCreate( VT_BSTR, 1, &rgsabound); if( psaTerminals == NULL ) { // Clean-up delete[] pTerminals; LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -" "SafeArrayCreate failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } // // Copies into the safe array the elements // for( DWORD dwTerminal = 0; dwTerminal < dwTerminals; dwTerminal++) { LPOLESTR lpszTerminalClass = NULL; hr = StringFromCLSID( pTerminals[dwTerminal], &lpszTerminalClass); if( FAILED(hr) ) { // Clean-up delete[] pTerminals; SafeArrayDestroy( psaTerminals ); LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -" "StringFromCLSID failed, returns 0x%08x", hr)); return hr; } BSTR bstrTerminalClass = SysAllocString( lpszTerminalClass ); CoTaskMemFree( lpszTerminalClass ); if( bstrTerminalClass == NULL ) { // Clean-up delete[] pTerminals; SafeArrayDestroy( psaTerminals ); LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -" "sysAloocString failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } // Put the element into the array long nIndex = (long)(dwTerminal+1); hr = SafeArrayPutElement( psaTerminals, &nIndex, bstrTerminalClass ); if( FAILED(hr) ) { // Clean-up delete[] pTerminals; SafeArrayDestroy( psaTerminals ); SysFreeString( bstrTerminalClass ); LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -" "SafeArrayPutElement failed, returns 0x%08x", hr)); return hr; } } // Clean-up delete[] pTerminals; // Return values pVarTerminals->parray = psaTerminals; pVarTerminals->vt = VT_ARRAY | VT_BSTR; LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_TerminalClasses - exit 0x%08x", hr)); return hr; } STDMETHODIMP CPlugTerminalSuperclass::EnumerateTerminalClasses( OUT IEnumTerminalClass** ppTerminals ) { LOG((MSP_TRACE, "CPlugTerminalSuperclass::EnumerateTerminalClasses - enter")); // // Validate argument // if( TM_IsBadWritePtr( ppTerminals, sizeof(IEnumTerminalClass*)) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit -" "ppTerminals invalid, returns E_POINTER")); return E_POINTER; } CLSID* pTerminals = NULL; DWORD dwTerminals = 0; HRESULT hr = m_Superclass.ListTerminalClasses( 0, &pTerminals, &dwTerminals ); if( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit -" "ListTerminalClasses failed, returns 0x%08x", hr)); return hr; } // // Create a buffer with exactly dwTerminals size // CLSID* pTerminalsCLSID = new CLSID[dwTerminals]; if( pTerminalsCLSID == NULL ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit -" "new operator failed, returns E_OUTOFMEMORY")); return E_OUTOFMEMORY; } // // Copies into the new buffer // memcpy( pTerminalsCLSID, pTerminals, sizeof(CLSID)*dwTerminals); // // Delete the old buffer // delete[] pTerminals; // // Create the enumerator // typedef CSafeComEnum > CEnumerator; CComObject *pEnum = NULL; hr = CComObject::CreateInstance(&pEnum); if( FAILED(hr) ) { delete[] pTerminalsCLSID; LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit -" "CreateInstance failed, returns 0x%08x", hr)); return hr; } // // Initialize enumerator // hr = pEnum->Init(pTerminalsCLSID, pTerminalsCLSID+dwTerminals, NULL, AtlFlagTakeOwnership); if( FAILED(hr) ) { delete pEnum; delete[] pTerminalsCLSID; LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit -" "Init failed, returns 0x%08x", hr)); return hr; } // // Query for the desired interface. // hr = pEnum->_InternalQueryInterface( IID_IEnumTerminalClass, (void**) ppTerminals ); if ( FAILED(hr) ) { LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit - " "can't get enumerator interface - exit 0x%08x", hr)); delete pEnum; delete[] pTerminalsCLSID; return hr; } LOG((MSP_TRACE, "CPlugTerminalSuperclass::EnumerateTerminalClasses - exit S_OK")); return S_OK; } // eof