windows-nt/Source/XPSP1/NT/enduser/netmeeting/ui/conf/t120xprt.cpp
2020-09-26 16:20:57 +08:00

392 lines
11 KiB
C++

#include "precomp.h"
#include "iplgxprt.h"
#include "nmmanager.h"
IT120PluggableTransport * CNmManagerObj::ms_pT120Transport = NULL;
#ifdef ENABLE_UPDATE_CONNECTION
IPluggableTransportNotify * CNmManagerObj::ms_pPluggableTransportNotify = NULL;
#endif
BSTR LPSTR2BSTR(LPSTR pszConnID);
BOOL BSTR2LPSTR(BSTR bstrConnID, LPSTR pszConnID);
//////////////////////////////////////////////////
//
// CPluggableTransport
//
void CNmManagerObj::EnsureTransportInterface(void)
{
if (NULL == ms_pT120Transport)
{
T120Error rc = ::T120_CreatePluggableTransport(&ms_pT120Transport);
ASSERT(T120_NO_ERROR == rc);
}
}
BOOL CNmManagerObj::InitPluggableTransportSDK(void)
{
ms_pT120Transport = NULL;
#ifdef ENABLE_UPDATE_CONNECTION
ms_pPluggableTransportNotify = NULL;
#endif
return TRUE;
}
void CNmManagerObj::CleanupPluggableTransportSDK(void)
{
if (NULL != ms_pT120Transport)
{
ms_pT120Transport->ReleaseInterface();
ms_pT120Transport = NULL;
}
#ifdef ENABLE_UPDATE_CONNECTION
ms_pPluggableTransportNotify = NULL;
#endif
}
//////////////////////////////////////////////////
//
// Connection @ CApplet
//
HRESULT CNmManagerObj::CreateConnection
(
BSTR *pbstrConnID, // For placing a call and closing connection
PLUGXPRT_CALL_TYPE eCaller, // caller or callee
DWORD dwProcessID, // Used for DuplicateHandle
HCOMMDEV _hCommLink, // Handle to communications file handle
HEVENT _hevtRead, // Ready To Read event ( data avail )
HEVENT _hevtWrite, // Ready To Write event
HEVENT _hevtClosed, // Connection closed ( unexpectedly???)
PLUGXPRT_FRAMING eFraming, // framing of bits sent on link
PLUGXPRT_PARAMETERS *pParams // OPTIONAL framing specific paramters
)
{
EnsureTransportInterface();
if (NULL != ms_pT120Transport)
{
if (NULL != pbstrConnID)
{
if (dwProcessID && _hCommLink && _hevtRead && _hevtWrite && _hevtClosed)
{
HRESULT hr = E_ACCESSDENIED;
HANDLE hProcess = ::OpenProcess(PROCESS_DUP_HANDLE, TRUE, dwProcessID);
if (NULL != hProcess)
{
HANDLE hCommLink;
if (::DuplicateHandle(hProcess, (HANDLE) _hCommLink,
::GetCurrentProcess(), &hCommLink,
0, FALSE, DUPLICATE_SAME_ACCESS))
{
HANDLE hevtRead;
if (::DuplicateHandle(hProcess, (HANDLE) _hevtRead,
::GetCurrentProcess(), &hevtRead,
0, FALSE, DUPLICATE_SAME_ACCESS))
{
HANDLE hevtWrite;
if (::DuplicateHandle(hProcess, (HANDLE) _hevtWrite,
::GetCurrentProcess(), &hevtWrite,
0, FALSE, DUPLICATE_SAME_ACCESS))
{
HANDLE hevtClose;
if (::DuplicateHandle(hProcess, (HANDLE) _hevtClosed,
::GetCurrentProcess(), &hevtClose,
0, FALSE, DUPLICATE_SAME_ACCESS))
{
char szConnID[T120_CONNECTION_ID_LENGTH];
T120Error rc = ms_pT120Transport->CreateConnection(
szConnID, eCaller, hCommLink,
hevtRead, hevtWrite, hevtClose,
eFraming, pParams);
ASSERT(T120_NO_ERROR == rc);
if (T120_NO_ERROR == rc)
{
*pbstrConnID = ::LPSTR2BSTR(szConnID);
if (NULL != *pbstrConnID)
{
::CloseHandle(hProcess);
return S_OK;
}
hr = E_OUTOFMEMORY;
}
else
{
hr = E_HANDLE;
}
::CloseHandle(hevtClose);
}
::CloseHandle(hevtWrite);
}
::CloseHandle(hevtRead);
}
::CloseHandle(hCommLink);
}
::CloseHandle(hProcess);
}
return hr;
}
return E_INVALIDARG;
}
return E_POINTER;
}
return E_OUTOFMEMORY;
}
#ifdef ENABLE_UPDATE_CONNECTION
HRESULT CNmManagerObj::UpdateConnection
(
BSTR bstrConnID,
DWORD dwProcessID, // Used for DuplicateHandle
HCOMMDEV _hCommLink // Handle to communications file handle
)
{
EnsureTransportInterface();
if (NULL != ms_pT120Transport)
{
if (NULL != bstrConnID)
{
if (dwProcessID && _hCommLink)
{
HRESULT hr = E_ACCESSDENIED;
HANDLE hProcess = ::OpenProcess(PROCESS_DUP_HANDLE, TRUE, dwProcessID);
if (NULL != hProcess)
{
HANDLE hCommLink;
if (::DuplicateHandle(hProcess, (HANDLE) _hCommLink,
::GetCurrentProcess(), &hCommLink,
0, FALSE, DUPLICATE_SAME_ACCESS))
{
char szConnID[T120_CONNECTION_ID_LENGTH];
if (::BSTR2LPSTR(bstrConnID, szConnID))
{
T120Error rc = ms_pT120Transport->UpdateConnection(szConnID, hCommLink);
ASSERT(T120_NO_ERROR == rc);
if (T120_NO_ERROR == rc)
{
::CloseHandle(hProcess);
return S_OK;
}
hr = E_HANDLE;
}
::CloseHandle(hCommLink);
}
::CloseHandle(hProcess);
}
return hr;
}
return E_INVALIDARG;
}
return E_POINTER;
}
return E_OUTOFMEMORY;
}
#endif
HRESULT CNmManagerObj::CloseConnection(BSTR bstrConnID)
{
EnsureTransportInterface();
if (NULL != ms_pT120Transport)
{
if (NULL != bstrConnID)
{
char szConnID[T120_CONNECTION_ID_LENGTH];
if (::BSTR2LPSTR(bstrConnID, szConnID))
{
T120Error rc = ms_pT120Transport->CloseConnection(szConnID);
ASSERT(T120_NO_ERROR == rc);
return (T120_NO_ERROR == rc) ? S_OK : E_INVALIDARG;
}
return E_INVALIDARG;
}
return E_POINTER;
}
return E_OUTOFMEMORY;
}
//////////////////////////////////////////////////
//
// Winsock @ CApplet
//
HRESULT CNmManagerObj::EnableWinsock(void)
{
EnsureTransportInterface();
if (NULL != ms_pT120Transport)
{
T120Error rc = ms_pT120Transport->EnableWinsock();
ASSERT(T120_NO_ERROR == rc);
return (T120_NO_ERROR == rc) ? S_OK : E_ACCESSDENIED;
}
return E_OUTOFMEMORY;
}
HRESULT CNmManagerObj::DisableWinsock(void)
{
EnsureTransportInterface();
if (NULL != ms_pT120Transport)
{
T120Error rc = ms_pT120Transport->DisableWinsock();
ASSERT(T120_NO_ERROR == rc);
return (T120_NO_ERROR == rc) ? S_OK : E_ACCESSDENIED;
}
return E_OUTOFMEMORY;
}
#ifdef ENABLE_UPDATE_CONNECTION
void CALLBACK OnPluggableTransportNotify(PLUGXPRT_MESSAGE *pMsg)
{
if (NULL != pMsg->pContext)
{
CNmManagerObj *p = (CNmManagerObj *) pMsg->pContext;
IPluggableTransportNotify *pNotify = p->ms_pPluggableTransportNotify;
if (NULL != pNotify)
{
BSTR bstr = ::LPSTR2BSTR(pMsg->pszConnID);
if (NULL != bstr)
{
switch (pMsg->eState)
{
case PLUGXPRT_CONNECTING:
pNotify->OnConnecting(bstr, pMsg->eProtocol);
break;
case PLUGXPRT_CONNECTED:
pNotify->OnConnected(bstr, pMsg->eProtocol, pMsg->eResult);
break;
case PLUGXPRT_DISCONNECTING:
pNotify->OnDisconnecting(bstr, pMsg->eProtocol);
break;
case PLUGXPRT_DISCONNECTED:
pNotify->OnDisconnected(bstr, pMsg->eProtocol, pMsg->eResult);
break;
}
::SysFreeString(bstr);
}
}
}
}
#endif
#ifdef ENABLE_UPDATE_CONNECTION
HRESULT CNmManagerObj::AdvisePluggableTransport(IPluggableTransportNotify *pNotify, DWORD *pdwCookie)
{
EnsureTransportInterface();
if (NULL != ms_pT120Transport)
{
// only allow one advise
if (NULL == ms_pPluggableTransportNotify)
{
if (NULL != pNotify && NULL != pdwCookie)
{
pNotify->AddRef();
ms_pPluggableTransportNotify = pNotify;
AddRef();
ms_pT120Transport->Advise(OnPluggableTransportNotify, this);
*pdwCookie = (DWORD) this;
return S_OK;
}
return E_POINTER;
}
return E_ACCESSDENIED;
}
return E_OUTOFMEMORY;
}
#endif
#ifdef ENABLE_UPDATE_CONNECTION
HRESULT CNmManagerObj::UnAdvisePluggableTransport(DWORD dwCookie)
{
EnsureTransportInterface();
if (NULL != ms_pT120Transport)
{
if (NULL != ms_pPluggableTransportNotify)
{
if (dwCookie == (DWORD) this)
{
ms_pPluggableTransportNotify->Release();
ms_pPluggableTransportNotify = NULL;
ms_pT120Transport->UnAdvise();
Release();
return S_OK;
}
return E_ACCESSDENIED;
}
return E_POINTER;
}
return E_OUTOFMEMORY;
}
#endif
BSTR LPSTR2BSTR(LPSTR pszConnID)
{
WCHAR wszConnID[T120_CONNECTION_ID_LENGTH];
if (::MultiByteToWideChar(CP_ACP, 0, pszConnID, -1, wszConnID, T120_CONNECTION_ID_LENGTH))
{
return ::SysAllocString(wszConnID);
}
return NULL;
}
BOOL BSTR2LPSTR(BSTR bstrConnID, LPSTR pszConnID)
{
*pszConnID = '\0';
return ::WideCharToMultiByte(CP_ACP, 0, bstrConnID, -1, pszConnID, T120_CONNECTION_ID_LENGTH, NULL, NULL);
}