803 lines
16 KiB
C++
803 lines
16 KiB
C++
// binding.cpp : Implementation of CServerBinding & CServerBindings.
|
|
|
|
#include "stdafx.h"
|
|
#include "smtpadm.h"
|
|
#include "cmultisz.h"
|
|
#include "binding.h"
|
|
#include "oleutil.h"
|
|
#include "smtpcmn.h"
|
|
|
|
|
|
HRESULT CBinding::SetProperties (
|
|
BSTR strIpAddress,
|
|
long dwTcpPort,
|
|
long dwSslPort
|
|
)
|
|
{
|
|
_ASSERT ( IS_VALID_STRING ( strIpAddress ) );
|
|
|
|
m_strIpAddress = strIpAddress;
|
|
m_dwTcpPort = dwTcpPort;
|
|
m_dwSslPort = dwSslPort;
|
|
|
|
if ( !m_strIpAddress ) {
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
// Must define THIS_FILE_* macros to use SmtpCreateException()
|
|
|
|
#define THIS_FILE_HELP_CONTEXT 0
|
|
#define THIS_FILE_PROG_ID _T("Smtpadm.VirtualServer.1")
|
|
#define THIS_FILE_IID IID_IServerBinding
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
STDMETHODIMP CServerBinding::InterfaceSupportsErrorInfo(REFIID riid)
|
|
{
|
|
static const IID* arr[] =
|
|
{
|
|
&IID_IServerBinding,
|
|
};
|
|
|
|
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
|
{
|
|
if (InlineIsEqualGUID(*arr[i],riid))
|
|
return S_OK;
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
|
|
CServerBinding::CServerBinding ()
|
|
// CComBSTR's are initialized to NULL by default.
|
|
{
|
|
}
|
|
|
|
CServerBinding::~CServerBinding ()
|
|
{
|
|
// All CComBSTR's are freed automatically.
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Properties:
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CServerBinding::get_IpAddress ( BSTR * pstrIpAddress )
|
|
{
|
|
return StdPropertyGet ( m_binding.m_strIpAddress, pstrIpAddress );
|
|
}
|
|
|
|
STDMETHODIMP CServerBinding::put_IpAddress ( BSTR strIpAddress )
|
|
{
|
|
return StdPropertyPut ( &m_binding.m_strIpAddress, strIpAddress );
|
|
}
|
|
|
|
STDMETHODIMP CServerBinding::get_TcpPort ( long * pdwTcpPort )
|
|
{
|
|
return StdPropertyGet ( m_binding.m_dwTcpPort, pdwTcpPort );
|
|
}
|
|
|
|
STDMETHODIMP CServerBinding::put_TcpPort ( long dwTcpPort )
|
|
{
|
|
return StdPropertyPut ( &m_binding.m_dwTcpPort, dwTcpPort );
|
|
}
|
|
|
|
STDMETHODIMP CServerBinding::get_SslPort ( long * plSslPort )
|
|
{
|
|
return StdPropertyGet ( m_binding.m_dwSslPort, plSslPort );
|
|
}
|
|
|
|
STDMETHODIMP CServerBinding::put_SslPort ( long lSslPort )
|
|
{
|
|
return StdPropertyPut ( &m_binding.m_dwSslPort, lSslPort );
|
|
}
|
|
|
|
//
|
|
// Must define THIS_FILE_* macros to use SmtpCreateException()
|
|
//
|
|
|
|
#undef THIS_FILE_HELP_CONTEXT
|
|
#undef THIS_FILE_PROG_ID
|
|
#undef THIS_FILE_IID
|
|
|
|
#define THIS_FILE_HELP_CONTEXT 0
|
|
#define THIS_FILE_PROG_ID _T("smtpadm.VirtualServer.1")
|
|
#define THIS_FILE_IID IID_IServerBindings
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
STDMETHODIMP CServerBindings::InterfaceSupportsErrorInfo(REFIID riid)
|
|
{
|
|
static const IID* arr[] =
|
|
{
|
|
&IID_IServerBindings,
|
|
};
|
|
|
|
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
|
{
|
|
if (InlineIsEqualGUID(*arr[i],riid))
|
|
return S_OK;
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
|
|
CServerBindings::CServerBindings () :
|
|
m_dwCount ( 0 ),
|
|
m_rgBindings ( NULL )
|
|
// CComBSTR's are initialized to NULL by default.
|
|
{
|
|
}
|
|
|
|
CServerBindings::~CServerBindings ()
|
|
{
|
|
// All CComBSTR's are freed automatically.
|
|
|
|
delete [] m_rgBindings;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Properties:
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CServerBindings::get_Count ( long * pdwCount )
|
|
{
|
|
return StdPropertyGet ( m_dwCount, pdwCount );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Methods:
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CServerBindings::Item (
|
|
long index,
|
|
IServerBinding ** ppBinding
|
|
)
|
|
{
|
|
TraceFunctEnter ( "CServerBindings::Item" );
|
|
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( ppBinding ) );
|
|
|
|
*ppBinding = NULL;
|
|
|
|
HRESULT hr = NOERROR;
|
|
CComObject<CServerBinding> * pBinding = NULL;
|
|
|
|
if ( index < 0 || index >= m_dwCount ) {
|
|
hr = SmtpCreateException ( IDS_SMTPEXCEPTION_INVALID_INDEX );
|
|
goto Exit;
|
|
}
|
|
|
|
hr = CComObject<CServerBinding>::CreateInstance ( &pBinding );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
_ASSERT ( pBinding );
|
|
hr = pBinding->SetProperties ( m_rgBindings[index] );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
hr = pBinding->QueryInterface ( IID_IServerBinding, (void **) ppBinding );
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
|
|
Exit:
|
|
if ( FAILED(hr) && hr != DISP_E_EXCEPTION ) {
|
|
hr = SmtpCreateExceptionFromHresult ( hr );
|
|
}
|
|
|
|
if ( FAILED(hr) ) {
|
|
delete pBinding;
|
|
}
|
|
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CServerBindings::ItemDispatch ( long index, IDispatch ** ppDispatch )
|
|
{
|
|
HRESULT hr;
|
|
CComPtr<IServerBinding> pBinding;
|
|
|
|
hr = Item ( index, &pBinding );
|
|
BAIL_ON_FAILURE ( hr );
|
|
|
|
hr = pBinding->QueryInterface ( IID_IDispatch, (void **) ppDispatch );
|
|
BAIL_ON_FAILURE ( hr );
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CServerBindings::Add (
|
|
BSTR strIpAddress,
|
|
long dwTcpPort,
|
|
long dwSslPort
|
|
)
|
|
{
|
|
TraceFunctEnter ( "CServerBindings::Add" );
|
|
|
|
_ASSERT ( IS_VALID_STRING ( strIpAddress ) );
|
|
|
|
HRESULT hr = NOERROR;
|
|
CBinding * rgNewBindings = NULL;
|
|
long i;
|
|
|
|
//
|
|
// Validate the new binding:
|
|
//
|
|
|
|
//
|
|
// See if we can merge this binding with an existing one:
|
|
//
|
|
if ( dwTcpPort == 0 || dwSslPort == 0 ) {
|
|
for ( i = 0; i < m_dwCount; i++ ) {
|
|
|
|
if ( (dwTcpPort == 0 && m_rgBindings[i].m_dwSslPort == 0) ||
|
|
(dwSslPort == 0 && m_rgBindings[i].m_dwTcpPort == 0) ) {
|
|
|
|
if ( lstrcmpi ( m_rgBindings[i].m_strIpAddress, strIpAddress ) == 0 ) {
|
|
|
|
if ( m_rgBindings[i].m_dwSslPort == 0 ) {
|
|
m_rgBindings[i].m_dwSslPort = dwSslPort;
|
|
}
|
|
else {
|
|
m_rgBindings[i].m_dwTcpPort = dwTcpPort;
|
|
}
|
|
hr = NOERROR;
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Allocate the new binding array:
|
|
rgNewBindings = new CBinding [ m_dwCount + 1 ];
|
|
if ( !rgNewBindings ) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
// Copy the old bindings to the new array:
|
|
for ( i = 0; i < m_dwCount; i++ ) {
|
|
hr = rgNewBindings[i].SetProperties ( m_rgBindings[i] );
|
|
if ( FAILED (hr) ) {
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
// Add the new binding to the end of the array:
|
|
hr = rgNewBindings[m_dwCount].SetProperties ( strIpAddress, dwTcpPort, dwSslPort );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
delete [] m_rgBindings;
|
|
m_rgBindings = rgNewBindings;
|
|
rgNewBindings = NULL;
|
|
m_dwCount++;
|
|
|
|
Exit:
|
|
if (FAILED(hr) && rgNewBindings)
|
|
delete [] rgNewBindings;
|
|
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CServerBindings::ChangeBinding (
|
|
long index,
|
|
IServerBinding * pBinding
|
|
)
|
|
{
|
|
TraceFunctEnter ( "CServerBindings::ChangeBinding" );
|
|
|
|
HRESULT hr = NOERROR;
|
|
|
|
CComBSTR strIpAddress;
|
|
long dwTcpPort;
|
|
long dwSslPort;
|
|
|
|
if ( index < 0 || index >= m_dwCount ) {
|
|
hr = SmtpCreateException ( IDS_SMTPEXCEPTION_INVALID_INDEX );
|
|
goto Exit;
|
|
}
|
|
|
|
hr = pBinding->get_IpAddress ( &strIpAddress );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
hr = pBinding->get_TcpPort ( &dwTcpPort );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
hr = pBinding->get_SslPort ( &dwSslPort );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
hr = m_rgBindings[index].SetProperties ( strIpAddress, dwTcpPort, dwSslPort );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CServerBindings::ChangeBindingDispatch ( long index, IDispatch * pDispatch )
|
|
{
|
|
HRESULT hr;
|
|
CComPtr<IServerBinding> pBinding;
|
|
|
|
hr = pDispatch->QueryInterface ( IID_IServerBinding, (void **) &pBinding );
|
|
BAIL_ON_FAILURE ( hr );
|
|
|
|
hr = ChangeBinding ( index, pBinding );
|
|
BAIL_ON_FAILURE ( hr );
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CServerBindings::Remove ( long index )
|
|
{
|
|
TraceFunctEnter ( "CServerBindings::Remove" );
|
|
|
|
HRESULT hr = NOERROR;
|
|
CBinding temp;
|
|
long cPositionsToSlide;
|
|
|
|
if ( index < 0 || index >= m_dwCount ) {
|
|
hr = SmtpCreateException ( IDS_SMTPEXCEPTION_INVALID_INDEX );
|
|
goto Exit;
|
|
}
|
|
|
|
// Slide the array down by one position:
|
|
|
|
_ASSERT ( m_rgBindings );
|
|
|
|
cPositionsToSlide = (m_dwCount - 1) - index;
|
|
|
|
_ASSERT ( cPositionsToSlide < m_dwCount );
|
|
|
|
if ( cPositionsToSlide > 0 ) {
|
|
// Save the deleted binding in temp:
|
|
CopyMemory ( &temp, &m_rgBindings[index], sizeof ( CBinding ) );
|
|
|
|
// Move the array down one:
|
|
MoveMemory ( &m_rgBindings[index], &m_rgBindings[index + 1], sizeof ( CBinding ) * cPositionsToSlide );
|
|
|
|
// Put the deleted binding on the end (so it gets destructed):
|
|
CopyMemory ( &m_rgBindings[m_dwCount - 1], &temp, sizeof ( CBinding ) );
|
|
|
|
// Zero out the temp binding:
|
|
ZeroMemory ( &temp, sizeof ( CBinding ) );
|
|
}
|
|
|
|
m_dwCount--;
|
|
|
|
Exit:
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CServerBindings::Clear ( )
|
|
{
|
|
delete [] m_rgBindings;
|
|
m_rgBindings = NULL;
|
|
m_dwCount = 0;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Useful routines to go from IServerBindings to
|
|
// Metabase data types.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
static DWORD CountBindingChars ( LPCWSTR strIpAddress, DWORD dwPort )
|
|
{
|
|
_ASSERT ( IS_VALID_STRING ( strIpAddress ) );
|
|
|
|
DWORD cchResult = 0;
|
|
WCHAR wszPort [256];
|
|
|
|
wsprintf ( wszPort, _T("%u"), dwPort );
|
|
|
|
cchResult += lstrlen ( strIpAddress ); // <IPADDRESS>
|
|
cchResult += 1; // :
|
|
cchResult += lstrlen ( wszPort ); // <PORT>
|
|
cchResult += 1; // :
|
|
// cchResult += lstrlen ( strPathHeader ); // <PATHHEADER>
|
|
|
|
cchResult += 1; // For the terminating NULL
|
|
|
|
return cchResult;
|
|
}
|
|
|
|
static void ToBindingString ( LPCWSTR strIpAddress, DWORD dwPort, LPWSTR wszBinding )
|
|
{
|
|
_ASSERT ( IS_VALID_STRING ( strIpAddress ) );
|
|
_ASSERT ( dwPort != 0 );
|
|
|
|
_ASSERT ( !IsBadWritePtr ( wszBinding, CountBindingChars ( strIpAddress, dwPort ) ) );
|
|
|
|
wsprintf ( wszBinding, _T("%s:%u:"), strIpAddress, dwPort );
|
|
}
|
|
|
|
static HRESULT FromBindingString ( LPCWSTR wszBinding, LPWSTR wszIpAddressOut, DWORD * pdwPort )
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
|
|
LPWSTR pchFirstColon;
|
|
LPWSTR pchSecondColon;
|
|
|
|
WCHAR wszIpAddress [ 256 ];
|
|
WCHAR wszPort [ 256 ];
|
|
long dwPort;
|
|
|
|
LPWSTR pchColon;
|
|
|
|
wszIpAddress[0] = NULL;
|
|
wszPort[0] = NULL;
|
|
|
|
pchFirstColon = wcschr ( wszBinding, _T(':') );
|
|
if ( pchFirstColon ) {
|
|
pchSecondColon = wcschr ( pchFirstColon + 1, _T(':') );
|
|
}
|
|
|
|
if ( !pchFirstColon || !pchSecondColon ) {
|
|
hr = E_FAIL;
|
|
goto Exit;
|
|
}
|
|
|
|
lstrcpyn ( wszIpAddress, wszBinding, 250 );
|
|
lstrcpyn ( wszPort, pchFirstColon + 1, 250 );
|
|
|
|
// Get the Port:
|
|
dwPort = _wtoi ( wszPort );
|
|
|
|
// Cutoff the IpAddress at the colon:
|
|
pchColon = wcschr ( wszIpAddress, _T(':') );
|
|
if ( pchColon ) {
|
|
*pchColon = NULL;
|
|
}
|
|
|
|
lstrcpy ( wszIpAddressOut, wszIpAddress );
|
|
*pdwPort = dwPort;
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
MDBindingsToIBindings (
|
|
CMultiSz * pmsz,
|
|
BOOL fTcpBindings,
|
|
IServerBindings * pBindings
|
|
)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
DWORD cBindings;
|
|
DWORD i;
|
|
LPCWSTR pchCurrent;
|
|
CBinding binding;
|
|
|
|
cBindings = pmsz->Count ();
|
|
|
|
for (
|
|
i = 0, pchCurrent = *pmsz;
|
|
i < cBindings;
|
|
i++, pchCurrent += lstrlen ( pchCurrent ) + 1
|
|
) {
|
|
|
|
WCHAR wszIpAddress[512];
|
|
DWORD dwPort;
|
|
|
|
hr = FromBindingString ( pchCurrent, wszIpAddress, &dwPort );
|
|
if ( FAILED(hr) ) {
|
|
// Skip bad binding strings:
|
|
hr = NOERROR;
|
|
continue;
|
|
}
|
|
|
|
if ( fTcpBindings ) {
|
|
hr = pBindings->Add ( wszIpAddress, dwPort, 0 );
|
|
}
|
|
else {
|
|
hr = pBindings->Add ( wszIpAddress, 0, dwPort );
|
|
}
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT IBindingsToMDBindings (
|
|
IServerBindings * pBindings,
|
|
BOOL fTcpBindings,
|
|
CMultiSz * pmsz
|
|
)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
long cBindings;
|
|
long i;
|
|
DWORD cbCount = 0;
|
|
LPWSTR wszBindings = NULL;
|
|
|
|
// Count the characters of the regular bindings list:
|
|
cbCount = 0;
|
|
pBindings->get_Count ( &cBindings );
|
|
|
|
for ( i = 0; i < cBindings; i++ ) {
|
|
CComPtr<IServerBinding> pBinding;
|
|
CComBSTR strIpAddress;
|
|
long lTcpPort;
|
|
long lSslPort;
|
|
|
|
hr = pBindings->Item ( i, &pBinding );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pBinding->get_IpAddress ( &strIpAddress );
|
|
pBinding->get_TcpPort ( &lTcpPort );
|
|
pBinding->get_SslPort ( &lSslPort );
|
|
|
|
if ( fTcpBindings ) {
|
|
if ( lTcpPort != 0 ) {
|
|
cbCount += CountBindingChars ( strIpAddress, lTcpPort );
|
|
}
|
|
}
|
|
else {
|
|
if ( lSslPort != 0 ) {
|
|
cbCount += CountBindingChars ( strIpAddress, lSslPort );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( cbCount == 0 ) {
|
|
cbCount = 2;
|
|
wszBindings = new WCHAR [ cbCount ];
|
|
|
|
if ( !wszBindings ) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
wszBindings[0] = NULL;
|
|
wszBindings[1] = NULL;
|
|
}
|
|
else {
|
|
cbCount++; // For double null terminator
|
|
|
|
wszBindings = new WCHAR [ cbCount ];
|
|
if ( !wszBindings ) {
|
|
BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
|
|
}
|
|
|
|
LPWSTR pchCurrent = wszBindings;
|
|
|
|
for ( i = 0; i < cBindings; i++ ) {
|
|
CComPtr<IServerBinding> pBinding;
|
|
CComBSTR strIpAddress;
|
|
long lTcpPort;
|
|
long lSslPort;
|
|
|
|
hr = pBindings->Item ( i, &pBinding );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pBinding->get_IpAddress ( &strIpAddress );
|
|
pBinding->get_TcpPort ( &lTcpPort );
|
|
pBinding->get_SslPort ( &lSslPort );
|
|
|
|
if ( fTcpBindings ) {
|
|
if ( lTcpPort != 0 ) {
|
|
ToBindingString ( strIpAddress, lTcpPort, pchCurrent );
|
|
pchCurrent += lstrlen ( pchCurrent ) + 1;
|
|
}
|
|
}
|
|
else {
|
|
if ( lSslPort != 0 ) {
|
|
ToBindingString ( strIpAddress, lSslPort, pchCurrent );
|
|
pchCurrent += lstrlen ( pchCurrent ) + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
*pchCurrent = NULL;
|
|
}
|
|
|
|
_ASSERT ( wszBindings[cbCount - 1] == NULL );
|
|
_ASSERT ( wszBindings[cbCount - 2] == NULL );
|
|
|
|
pmsz->Attach ( wszBindings );
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
#if 0
|
|
|
|
DWORD CBinding::SizeInChars ( )
|
|
{
|
|
DWORD cchResult = 0;
|
|
WCHAR wszTcpPort [256];
|
|
|
|
wsprintf ( wszTcpPort, _T("%d"), m_dwTcpPort );
|
|
|
|
cchResult += lstrlen ( m_strIpAddress ); // <IPADDRESS>
|
|
cchResult += 1; // :
|
|
cchResult += lstrlen ( wszTcpPort ); // <TCPPORT>
|
|
cchResult += 1; // :
|
|
// cchResult += lstrlen ( m_strPathHeader ); // <PATHHEADER>
|
|
|
|
return cchResult;
|
|
}
|
|
|
|
void CBinding::ToString ( LPWSTR wszBinding )
|
|
{
|
|
wsprintf ( wszBinding, _T("%s:%d:"), m_strIpAddress, m_dwTcpPort );
|
|
}
|
|
|
|
HRESULT CBinding::FromString ( LPCWSTR wszBinding )
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
|
|
LPWSTR pchFirstColon;
|
|
LPWSTR pchSecondColon;
|
|
|
|
WCHAR wszIpAddress [ 256 ];
|
|
WCHAR wszTcpPort [ 256 ];
|
|
long dwTcpPort;
|
|
|
|
LPWSTR pchColon;
|
|
|
|
wszIpAddress[0] = NULL;
|
|
wszTcpPort[0] = NULL;
|
|
|
|
pchFirstColon = wcschr ( wszBinding, _T(':') );
|
|
if ( pchFirstColon ) {
|
|
pchSecondColon = wcschr ( pchFirstColon + 1, _T(':') );
|
|
}
|
|
|
|
if ( !pchFirstColon || !pchSecondColon ) {
|
|
hr = E_FAIL;
|
|
goto Exit;
|
|
}
|
|
|
|
lstrcpyn ( wszIpAddress, wszBinding, 250 );
|
|
lstrcpyn ( wszTcpPort, pchFirstColon + 1, 250 );
|
|
|
|
// Get the TcpPort:
|
|
dwTcpPort = _wtoi ( wszTcpPort );
|
|
|
|
// Cutoff the IpAddress at the colon:
|
|
pchColon = wcschr ( wszIpAddress, _T(':') );
|
|
if ( pchColon ) {
|
|
*pchColon = NULL;
|
|
}
|
|
|
|
m_strIpAddress = wszIpAddress;
|
|
m_dwTcpPort = dwTcpPort;
|
|
|
|
if ( !m_strIpAddress ) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CServerBindings::FromMultiSz ( CMultiSz * pmsz )
|
|
{
|
|
HRESULT hr;
|
|
DWORD cBindings;
|
|
DWORD i;
|
|
LPCWSTR pchCurrent;
|
|
CBinding binding;
|
|
|
|
hr = Clear ();
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
|
|
cBindings = pmsz->Count ();
|
|
|
|
for (
|
|
i = 0, pchCurrent = *pmsz;
|
|
i < cBindings;
|
|
i++, pchCurrent += lstrlen ( pchCurrent ) + 1
|
|
) {
|
|
|
|
hr = binding.FromString ( pchCurrent );
|
|
if ( FAILED(hr) ) {
|
|
if ( hr == E_FAIL ) {
|
|
// Skip the bad binding strings.
|
|
continue;
|
|
}
|
|
else {
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
hr = Add ( binding.m_strIpAddress, binding.m_dwTcpPort );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CServerBindings::ToMultiSz ( CMultiSz * pmsz )
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
DWORD cchSize;
|
|
long i;
|
|
LPWSTR wszBindings;
|
|
LPWSTR pchCurrent;
|
|
|
|
// Special case - the empty binding list:
|
|
if ( m_dwCount == 0 ) {
|
|
cchSize = 2;
|
|
wszBindings = new WCHAR [ cchSize ];
|
|
|
|
if ( !wszBindings ) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
wszBindings[0] = NULL;
|
|
wszBindings[1] = NULL;
|
|
}
|
|
else {
|
|
|
|
cchSize = 0;
|
|
|
|
for ( i = 0; i < m_dwCount; i++ ) {
|
|
cchSize += m_rgBindings[i].SizeInChars ( ) + 1;
|
|
}
|
|
// Add the size of the final terminator:
|
|
cchSize += 1;
|
|
|
|
wszBindings = new WCHAR [ cchSize ];
|
|
if ( !wszBindings ) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
for ( i = 0, pchCurrent = wszBindings; i < m_dwCount; i++ ) {
|
|
|
|
m_rgBindings[i].ToString ( pchCurrent );
|
|
pchCurrent += lstrlen ( pchCurrent ) + 1;
|
|
}
|
|
|
|
// Add the final NULL terminator:
|
|
*pchCurrent = NULL;
|
|
}
|
|
|
|
_ASSERT ( wszBindings[cchSize - 1] == NULL );
|
|
_ASSERT ( wszBindings[cchSize - 2] == NULL );
|
|
|
|
pmsz->Attach ( wszBindings );
|
|
|
|
_ASSERT ( pmsz->Count () == (DWORD) m_dwCount );
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
#endif
|
|
|