📄 connectionmanagerservice.cpp
字号:
}
// service was registered successfully, we can release the smart pointer and store service ID
pIAVTransport.release();
itIDs->second.AVTID = *pAVTransportID;
}
}
// register virtual instance of AVTransport
if(pIRenderingControl)
{
if(!m_pRCS)
{
DEBUGMSG(ZONE_AV_ERROR, (TEXT("IConnectionManager::PrepareForConnection or CreateConnection returned non-NULL pIRenderingControl but")));
DEBUGMSG(ZONE_AV_ERROR, (TEXT("\tConnectionManagerServiceImpl::Init was called with NULL for pIRenderingControlService")));
}
else
{
const DWORD retRI = m_pRCS->RegisterInstance(pIRenderingControl, pRcsID);
if(SUCCESS_AV != retRI)
{
// cleanup after the incomplete connection
ConnectionComplete(*pConnectionID);
return m_ErrReport.ReportError(retRI);
}
// service was registered successfully, we can release the smart pointer and store service ID
pIRenderingControl.release();
itIDs->second.RCID = *pRcsID;
}
}
return S_OK;
}
STDMETHODIMP ConnectionManagerServiceImpl::ConnectionComplete(long ConnectionID)
{
if(!m_pIConnectionManager)
return m_ErrReport.ReportError(ERROR_AV_UPNP_ACTION_FAILED);
// Complete connection
const DWORD retCC = m_pIConnectionManager->ConnectionComplete(ConnectionID);
if(SUCCESS_AV != retCC)
return m_ErrReport.ReportError(retCC);
IDMap::iterator itIDs = m_mapIDs.find(ConnectionID);
if(itIDs != m_mapIDs.end())
{
// Unregister AVTransport instance
if(-1 != itIDs->second.AVTID)
{
assert(m_pAVTS);
if(SUCCESS_AV != m_pAVTS->UnregisterInstance(itIDs->second.AVTID))
assert(false);
}
// Unregister RenderingControl instance
if(-1 != itIDs->second.RCID)
{
assert(m_pRCS);
if(SUCCESS_AV != m_pRCS->UnregisterInstance(itIDs->second.RCID))
assert(false);
}
m_mapIDs.erase(itIDs);
}
return S_OK;
}
STDMETHODIMP ConnectionManagerServiceImpl::GetCurrentConnectionIDs(BSTR* pConnectionIDs)
{
return get_CurrentConnectionIDs(pConnectionIDs);
}
STDMETHODIMP ConnectionManagerServiceImpl::GetCurrentConnectionInfo(long ConnectionID,
long* pRcsID,
long* pAVTransportID,
BSTR* pProtocolInfo,
BSTR* pPeerConnectionManager,
long* pPeerConnectionID,
BSTR* pDirection,
BSTR* pStatus)
{
if(!pRcsID || !pAVTransportID || !pProtocolInfo || !pPeerConnectionManager || !pPeerConnectionID || !pDirection || !pStatus)
return E_POINTER;
if(!m_pIConnectionManager)
return m_ErrReport.ReportError(ERROR_AV_UPNP_ACTION_FAILED);
ConnectionInfo ConnectionInfo;
const DWORD retGCCI = m_pIConnectionManager->GetCurrentConnectionInfo(ConnectionID, &ConnectionInfo);
if(retGCCI != SUCCESS_AV)
return m_ErrReport.ReportError(retGCCI);
// Set out arguments
if(0 == m_mapIDs.size())
{
//
// Special case for when Connection Manager does not implement PrepareForConnection and ConnectionComplete.
// In this case while ConnectionManagerService does not know of the connection, there may an AVT and/or RC
// associated with the default ConnectionID 0
//
// Implementation of IConnectionManager may succeed only for special connection instance 0
assert(0 == ConnectionID);
// Return instance ID of 0 if default instance of AVTransport is registered or -1 otherwise
if(m_pAVTS && SUCCESS_AV == m_pAVTS->FindInstance(0, NULL))
*pAVTransportID = 0;
else
*pAVTransportID = -1;
// Return instance ID of 0 if default instance of RenderingControl is registered or -1 otherwise
if(m_pRCS && SUCCESS_AV == m_pRCS->FindInstance(0, NULL))
*pRcsID = 0;
else
*pRcsID = -1;
}
else
{
//
// General case, Connection Manager does implement PrepareForConnection and ConnectionComplete,
// thus it knows of all current connections.
//
const IDMap::const_iterator it = m_mapIDs.find(ConnectionID);
if(it == m_mapIDs.end())
return m_ErrReport.ReportError(ERROR_AV_UPNP_CM_INVALID_CONNECTION_REFERENCE);
*pAVTransportID = it->second.AVTID;
*pRcsID = it->second.RCID;
}
// RemoteProtocolInfo
if(NULL == (*pProtocolInfo = SysAllocString(ConnectionInfo.strRemoteProtocolInfo)))
return m_ErrReport.ReportError(ERROR_AV_OOM);
// PeerConnectionManager
if(NULL == (*pPeerConnectionManager = SysAllocString(ConnectionInfo.strPeerConnectionManager)))
return m_ErrReport.ReportError(ERROR_AV_OOM);
// PeerConnectionID
*pPeerConnectionID = ConnectionInfo.nPeerConnectionID;
// Direction
if(INPUT == ConnectionInfo.Direction)
*pDirection = SysAllocString(details::Direction::Input);
else
{
assert(OUTPUT == ConnectionInfo.Direction);
*pDirection = SysAllocString(details::Direction::Output);
}
// Status
if(NULL == *pDirection)
return m_ErrReport.ReportError(ERROR_AV_OOM);
if(NULL == (*pStatus = SysAllocString(ConnectionInfo.strStatus)))
return m_ErrReport.ReportError(ERROR_AV_OOM);
return S_OK;
}
// InvokeVendorAction
DWORD ConnectionManagerServiceImpl::InvokeVendorAction(
/* [in] */ LPCWSTR pszActionName,
/* [in] */ DISPPARAMS* pdispparams,
/* [in, out] */ VARIANT* pvarResult)
{
return m_pIConnectionManager->InvokeVendorAction(pszActionName, pdispparams, pvarResult);
}
//
// Private
//
HRESULT ConnectionManagerServiceImpl::InitToolkitErrs()
{
const int vErrMap[][2] =
{
{ERROR_AV_POINTER, ERROR_AV_UPNP_ACTION_FAILED},
{ERROR_AV_OOM, ERROR_AV_UPNP_CM_LOCAL_RESTRICTIONS},
{ERROR_AV_INVALID_INSTANCE, ERROR_AV_UPNP_ACTION_FAILED},
{ERROR_AV_INVALID_STATEVAR, ERROR_AV_UPNP_ACTION_FAILED},
{ERROR_AV_ALREADY_INITED, ERROR_AV_UPNP_ACTION_FAILED},
{0, 0} // 0 is used to denote the end of this array
};
for(unsigned int i=0; 0 != vErrMap[i][0]; ++i)
{
if(ERROR_AV_OOM == m_ErrReport.AddToolkitError(vErrMap[i][0], vErrMap[i][1]))
return E_OUTOFMEMORY;
}
return S_OK;
}
HRESULT ConnectionManagerServiceImpl::InitErrDescrips()
{
const int vErrNums[] =
{
// UPnP
ERROR_AV_UPNP_INVALID_ACTION,
ERROR_AV_UPNP_ACTION_FAILED,
// ConnectionManager
ERROR_AV_UPNP_CM_NOT_IN_NETWORK,
ERROR_AV_UPNP_CM_INCOMPATIBLE_PROTOCOL,
ERROR_AV_UPNP_CM_INCOMPATIBLE_DIRECTION,
ERROR_AV_UPNP_CM_INSUFFICIENT_NET_RESOURCES,
ERROR_AV_UPNP_CM_LOCAL_RESTRICTIONS,
ERROR_AV_UPNP_CM_ACCESS_DENIED,
ERROR_AV_UPNP_CM_INVALID_CONNECTION_REFERENCE,
0 // 0 is used to denote the end of this array
};
const wstring vErrDescrips[] =
{
// UPnP
L"Invalid Action",
L"Action Failed",
// ConnectionManager
L"Not in network",
L"Incompatible protocol info",
L"Incompatible directions",
L"Insufficient network resources",
L"Local restrictions",
L"Access denied",
L"Invalid connection reference"
};
for(unsigned int i=0; 0 != vErrNums[i]; ++i)
{
if(ERROR_AV_OOM == m_ErrReport.AddErrorDescription(vErrNums[i], vErrDescrips[i]))
return E_OUTOFMEMORY;
}
return S_OK;
}
void ConnectionManagerServiceImpl::InitDISPIDs()
{
// Evented variables for ConnectionManager
LPCWSTR vpszStateVarNames[] =
{
ConnectionManagerState::SourceProtocolInfo,
ConnectionManagerState::SinkProtocolInfo,
ConnectionManagerState::CurrentConnectionIDs,
0 // 0 is used to denote the end of this array
};
const DISPID vdispidStateVarDISPIDs[] =
{
DISPID_SOURCEPROTOCOLINFO,
DISPID_SINKPROTOCOLINFO,
DISPID_CURRENTCONNECTIONIDS
};
for(unsigned int i=0; 0 != vpszStateVarNames[i]; ++i)
{
if(m_mapDISPIDs.end() == m_mapDISPIDs.insert(vpszStateVarNames[i], vdispidStateVarDISPIDs[i]))
return;
}
}
HRESULT ConnectionManagerServiceImpl::generic_get_ProtocolInfo(BSTR* pSource, BSTR* pSink)
{
if(!m_pIConnectionManager)
return m_ErrReport.ReportError(ERROR_AV_UPNP_ACTION_FAILED);
wstring strSourceProtocolInfo, strSinkProtocolInfo;
const DWORD retGPI = m_pIConnectionManager->GetProtocolInfo(&strSourceProtocolInfo, &strSinkProtocolInfo);
if(SUCCESS_AV != retGPI)
return m_ErrReport.ReportError(retGPI);
if(pSource)
{
*pSource = SysAllocString(strSourceProtocolInfo);
if(!*pSource)
return m_ErrReport.ReportError(ERROR_AV_OOM);
}
if(pSink)
{
*pSink = SysAllocString(strSinkProtocolInfo);
if(!*pSink)
return m_ErrReport.ReportError(ERROR_AV_OOM);
}
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -