516 lines
14 KiB
C++
516 lines
14 KiB
C++
// EdtBindD.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "resource.h"
|
|
|
|
#include "iiscnfg.h"
|
|
|
|
#include "KeyObjs.h"
|
|
#include "wrapmb.h"
|
|
#include "cmnkey.h"
|
|
#include "mdkey.h"
|
|
#include "mdserv.h"
|
|
|
|
#include "ListRow.h"
|
|
#include "BindsDlg.h"
|
|
#include "EdtBindD.h"
|
|
|
|
#include "W3Key.h"
|
|
#include "ipdlg.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEditBindingDlg dialog
|
|
|
|
|
|
//--------------------------------------------------------
|
|
CEditBindingDlg::CEditBindingDlg(WCHAR* pszw, CWnd* pParent /*=NULL*/)
|
|
: CDialog(CEditBindingDlg::IDD, pParent),
|
|
m_fPopulatedPortDropdown( FALSE ),
|
|
m_pszwMachineName( pszw )
|
|
{
|
|
//{{AFX_DATA_INIT(CEditBindingDlg)
|
|
m_int_ip_option = -1;
|
|
m_int_port_option = -1;
|
|
m_cstring_port = _T("");
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
void CEditBindingDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CEditBindingDlg)
|
|
DDX_Control(pDX, IDC_PORT_DROP, m_ccombobox_port);
|
|
DDX_Radio(pDX, IDC_ANY_IP, m_int_ip_option);
|
|
DDX_Radio(pDX, IDC_ANY_PORT, m_int_port_option);
|
|
DDX_CBString(pDX, IDC_PORT_DROP, m_cstring_port);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
BEGIN_MESSAGE_MAP(CEditBindingDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CEditBindingDlg)
|
|
ON_BN_CLICKED(IDC_RD_IP, OnRdIp)
|
|
ON_BN_CLICKED(IDC_RD_PORT, OnRdPort)
|
|
ON_BN_CLICKED(IDC_ANY_IP, OnAnyIp)
|
|
ON_BN_CLICKED(IDC_ANY_PORT, OnAnyPort)
|
|
ON_CBN_DROPDOWN(IDC_PORT_DROP, OnDropdownPortDrop)
|
|
ON_BN_CLICKED(IDC_BTN_SELECT_IPADDRESS, OnBtnSelectIpaddress)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
//--------------------------------------------------------
|
|
BOOL CEditBindingDlg::OnInitDialog()
|
|
{
|
|
CString szIP;
|
|
CString szPort;
|
|
int iColon;
|
|
|
|
// call the parental oninitdialog
|
|
BOOL f = CDialog::OnInitDialog();
|
|
|
|
// the initial values of the dialog as appropriate
|
|
// for the string that was passed. The easiest case
|
|
// is that of the default string - so do that first.
|
|
|
|
// check for the default
|
|
if ( m_szBinding == MDNAME_DEFAULT )
|
|
{
|
|
m_int_ip_option = OPTION_ANY_UNASSIGNED;
|
|
m_int_port_option = OPTION_ANY_UNASSIGNED;
|
|
m_cstring_port.Empty();
|
|
ClearIPAddress();
|
|
}
|
|
else
|
|
{
|
|
// the first thing we are going to do is seperate the IP and PORT into seperate strings
|
|
|
|
// look for the : and seperate
|
|
iColon = m_szBinding.Find(':');
|
|
|
|
// if we got the colon, we can seperate easy
|
|
if ( iColon >= 0 )
|
|
{
|
|
szIP = m_szBinding.Left(iColon);
|
|
szPort = m_szBinding.Right(m_szBinding.GetLength() - iColon - 1);
|
|
}
|
|
// we did not get the colon, so it is one or the other, look for a '.' to get the IP
|
|
else
|
|
{
|
|
if ( m_szBinding.Find('.') >= 0 )
|
|
szIP = m_szBinding;
|
|
else
|
|
szPort = m_szBinding;
|
|
}
|
|
|
|
// put the strings into the appropriate places
|
|
if ( szIP.IsEmpty() )
|
|
{
|
|
ClearIPAddress();
|
|
m_int_ip_option = OPTION_ANY_UNASSIGNED;
|
|
}
|
|
else
|
|
{
|
|
FSetIPAddress( szIP );
|
|
m_int_ip_option = OPTION_SPECIFIED;
|
|
}
|
|
|
|
// setting the port string is a bit easier
|
|
m_cstring_port = szPort;
|
|
if ( szPort.IsEmpty() )
|
|
m_int_port_option = OPTION_ANY_UNASSIGNED;
|
|
else
|
|
m_int_port_option = OPTION_SPECIFIED;
|
|
}
|
|
|
|
// update the data in the dialog
|
|
UpdateData( FALSE );
|
|
|
|
// enable the items as appropriate
|
|
EnableItems();
|
|
|
|
// return the answer
|
|
return f;
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// enable the itesm as appropriate
|
|
void CEditBindingDlg::EnableItems()
|
|
{
|
|
// get the data so we are up-to-date
|
|
UpdateData( TRUE );
|
|
|
|
// handle the ip addressing items
|
|
if ( m_int_ip_option == OPTION_ANY_UNASSIGNED )
|
|
{
|
|
GetDlgItem(IDC_IPA_IPADDRESS)->EnableWindow(FALSE);
|
|
// m_cbutton_delete.EnableWindow( FALSE );
|
|
}
|
|
else
|
|
{
|
|
GetDlgItem(IDC_IPA_IPADDRESS)->EnableWindow(TRUE);
|
|
// m_cbutton_delete.EnableWindow( TRUE );
|
|
}
|
|
|
|
// handle the port addressing items
|
|
if ( m_int_port_option == OPTION_ANY_UNASSIGNED )
|
|
{
|
|
m_ccombobox_port.EnableWindow( FALSE );
|
|
}
|
|
else
|
|
{
|
|
m_ccombobox_port.EnableWindow( TRUE );
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Set and get the ip STRING from the ip edit control
|
|
BOOL CEditBindingDlg::FSetIPAddress( CString& szAddress )
|
|
{
|
|
DWORD dword, b1, b2, b3, b4;
|
|
|
|
// break the string into 4 numerical bytes (reading left to right)
|
|
dword = sscanf( szAddress, "%d.%d.%d.%d", &b1, &b2, &b3, &b4 );
|
|
|
|
// if we didn't get all four, fail
|
|
if ( dword != 4 )
|
|
return FALSE;
|
|
|
|
// make the numerical ip address out of the bytes
|
|
dword = (DWORD)MAKEIPADDRESS(b1,b2,b3,b4);
|
|
|
|
// set the ip address into the control
|
|
SendDlgItemMessage( IDC_IPA_IPADDRESS, IPM_SETADDRESS, 0, dword );
|
|
|
|
#ifdef _DEBUG
|
|
dword = 0;
|
|
// dword = SendDlgItemMessage( IDC_IPA_IPADDRESS, IPM_GETADDRESS, 0, 0 );
|
|
#endif
|
|
|
|
// return success
|
|
return TRUE;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
CString CEditBindingDlg::GetIPAddress()
|
|
{
|
|
CString szAnswer;
|
|
DWORD dword, b1, b2, b3, b4;
|
|
|
|
// get the ip address from the control
|
|
SendDlgItemMessage( IDC_IPA_IPADDRESS, IPM_GETADDRESS, 0, (LPARAM)&dword );
|
|
|
|
|
|
// get the constituent parts
|
|
b1 = FIRST_IPADDRESS( dword );
|
|
b2 = SECOND_IPADDRESS( dword );
|
|
b3 = THIRD_IPADDRESS( dword );
|
|
b4 = FOURTH_IPADDRESS( dword );
|
|
|
|
// format the string
|
|
if ( dword )
|
|
szAnswer.Format( "%d.%d.%d.%d", b1, b2, b3, b4 );
|
|
else
|
|
szAnswer.Empty();
|
|
|
|
return szAnswer;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Set and get the ip STRING from the ip edit control
|
|
void CEditBindingDlg::ClearIPAddress()
|
|
{
|
|
// clear the ip address control
|
|
SendDlgItemMessage( IDC_IPA_IPADDRESS, IPM_CLEARADDRESS, 0, 0 );
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
BOOL CEditBindingDlg::FIsBindingSafeToUse( CString szBinding )
|
|
{
|
|
|
|
// start by testing the binding in the current dialog - uses
|
|
// the localized version of "Default"
|
|
if ( m_pBindingsDlg->FContainsBinding(szBinding) )
|
|
{
|
|
AfxMessageBox( IDS_THIS_KEY_HAS_BINDING, MB_OK );
|
|
return FALSE;
|
|
}
|
|
|
|
// now we check to see if any other keys have the specified binding. If
|
|
// they do, we ask the user if they want to give the binding to this key.
|
|
// but first we have to find the key. This means scanning the list of
|
|
// keys and asking each - but not this key - if they have the binding.
|
|
CMDKey* pKeyLocal = m_pBindingsDlg->m_pKey;
|
|
CMDKey* pKey;
|
|
|
|
if ( !pKeyLocal->m_pService )
|
|
return FALSE;
|
|
|
|
// get the first key in the service list
|
|
pKey = pKeyLocal->m_pService->GetFirstMDKey();
|
|
|
|
// loop the keys, testing each in turn
|
|
while ( pKey )
|
|
{
|
|
// if this is not the local key, test it
|
|
if ( pKey != pKeyLocal )
|
|
{
|
|
// test it
|
|
if ( pKey->FContainsBinding( szBinding ) )
|
|
{
|
|
// prepare the message for the user
|
|
CString szMessage;
|
|
AfxFormatString1( szMessage, IDS_ANOTHER_KEY_HAS_BINDING, pKey->m_szName );
|
|
// ask the user what to do
|
|
if ( AfxMessageBox( szMessage, MB_YESNO ) == IDYES )
|
|
{
|
|
// create a new removal object
|
|
CBingingRemoval* pRemoval = new CBingingRemoval( pKey, szBinding );
|
|
// add it to the queue
|
|
m_pBindingsDlg->rgbRemovals.Add( pRemoval );
|
|
// the key is safe use
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
// the user has thought better of this
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// get the next key in the list
|
|
pKey = pKeyLocal->m_pService->GetNextMDKey( pKey );
|
|
}
|
|
|
|
// no one else is using the binding. It is safe.
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEditBindingDlg message handlers
|
|
|
|
//------------------------------------------------------------------------------
|
|
void CEditBindingDlg::OnOK()
|
|
{
|
|
CString szIP;
|
|
CString szPort;
|
|
|
|
// start by building the final binding string
|
|
CString szBinding;
|
|
|
|
// use the current data
|
|
UpdateData( TRUE );
|
|
|
|
|
|
// first things first. We need to make sure that, if used, the
|
|
// custom fields actually have something in them
|
|
|
|
// check the IP address first
|
|
if ( m_int_ip_option == OPTION_SPECIFIED )
|
|
{
|
|
szIP = GetIPAddress();
|
|
if ( szIP.IsEmpty() )
|
|
{
|
|
// tell the user about it
|
|
AfxMessageBox( IDS_INVALID_IP );
|
|
|
|
// hilight the IP box
|
|
GetDlgItem( IDC_IPA_IPADDRESS )->SetFocus();
|
|
|
|
// return without closing the dialog
|
|
return;
|
|
}
|
|
}
|
|
|
|
// check the port address second
|
|
if ( m_int_port_option == OPTION_SPECIFIED )
|
|
{
|
|
if ( m_cstring_port.IsEmpty() )
|
|
{
|
|
// tell the user about it
|
|
AfxMessageBox( IDS_INVALID_PORT );
|
|
|
|
// hilight the port box
|
|
m_ccombobox_port.SetFocus();
|
|
m_ccombobox_port.SetEditSel(0,-1);
|
|
|
|
// return without closing the dialog
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
// the total default case is the easiest
|
|
if ( m_int_ip_option == OPTION_ANY_UNASSIGNED &&
|
|
m_int_port_option == OPTION_ANY_UNASSIGNED )
|
|
{
|
|
szBinding = MDNAME_DEFAULT;
|
|
}
|
|
else
|
|
{
|
|
// build from the ip and port pieces
|
|
if ( m_int_ip_option == OPTION_SPECIFIED )
|
|
szIP = GetIPAddress();
|
|
if ( m_int_port_option == OPTION_SPECIFIED )
|
|
szPort = m_cstring_port;
|
|
|
|
// build the string start with the IP
|
|
szBinding = szIP;
|
|
|
|
// if both are there, add a colon
|
|
if ( m_int_ip_option == OPTION_SPECIFIED &&
|
|
m_int_port_option == OPTION_SPECIFIED )
|
|
szBinding += ':';
|
|
|
|
// finish with the port
|
|
szBinding += szPort;
|
|
}
|
|
|
|
// finally, if the binding is safe to use, we can set the data and
|
|
// close the dialog
|
|
if ( FIsBindingSafeToUse(szBinding) )
|
|
{
|
|
// set the data
|
|
m_szBinding = szBinding;
|
|
|
|
// tell the dialog to close
|
|
CDialog::OnOK();
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void CEditBindingDlg::OnRdIp()
|
|
{
|
|
EnableItems();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void CEditBindingDlg::OnRdPort()
|
|
{
|
|
EnableItems();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void CEditBindingDlg::OnAnyIp()
|
|
{
|
|
EnableItems();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void CEditBindingDlg::OnAnyPort()
|
|
{
|
|
EnableItems();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void CEditBindingDlg::OnDropdownPortDrop()
|
|
{
|
|
CString sz;
|
|
DWORD dwPort;
|
|
|
|
// if we have already been here, don't do anything
|
|
if ( m_fPopulatedPortDropdown )
|
|
return;
|
|
|
|
// get the metabase going
|
|
if ( !FInitMetabaseWrapper(m_pszwMachineName) )
|
|
return;
|
|
|
|
// create the metabase wrapper object
|
|
CWrapMetaBase mbWrap;
|
|
if ( !mbWrap.FInit() )
|
|
{
|
|
ASSERT( FALSE );
|
|
return; // can't get to metabase
|
|
}
|
|
|
|
// we are now to populate the drop down menu
|
|
m_fPopulatedPortDropdown = TRUE;
|
|
|
|
// scan the available virtual servers and populate the drop down with
|
|
// their secure port numbers
|
|
for ( DWORD i = 1; TRUE; i++ )
|
|
{
|
|
// build the object name
|
|
sz.Format( "%s%d", MD_W3BASE, i );
|
|
|
|
// attempt to open the object in the metabase
|
|
if ( !mbWrap.Open( sz, METADATA_PERMISSION_READ ) )
|
|
break; // can't open - leave the loop
|
|
|
|
// load the string representing the bindings
|
|
DWORD cbData;
|
|
PVOID pData;
|
|
|
|
// extract the secure port address from the secure bindings stringlist
|
|
pData = mbWrap.GetData( "", MD_SECURE_BINDINGS, IIS_MD_UT_SERVER, MULTISZ_METADATA, &cbData );
|
|
if ( pData )
|
|
{
|
|
PTCHAR pBinding = (PTCHAR)pData;
|
|
|
|
// walk the bindings in the list
|
|
while ( TRUE )
|
|
{
|
|
sz = (PCHAR)pBinding;
|
|
if ( sz.IsEmpty() )
|
|
break;
|
|
|
|
// get the port address
|
|
sz = sz.Right( sz.GetLength() - sz.Find(':') - 1 );
|
|
if ( sz.Find(':') )
|
|
sz = sz.Left( sz.Find(':') );
|
|
if ( !sz.IsEmpty() )
|
|
{
|
|
// append the string to the dropdown
|
|
// but only if it isn't already there
|
|
if ( m_ccombobox_port.FindStringExact(-1,sz) == CB_ERR )
|
|
m_ccombobox_port.AddString( sz );
|
|
}
|
|
|
|
// advance the binding pointer
|
|
pBinding += strlen(pBinding)+1;
|
|
}
|
|
|
|
// free the buffer
|
|
mbWrap.FreeWrapData( pData );
|
|
}
|
|
|
|
// close the object
|
|
mbWrap.Close();
|
|
}
|
|
|
|
// now close the metabase again. We will open it when we need it
|
|
FCloseMetabaseWrapper();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void CEditBindingDlg::OnBtnSelectIpaddress()
|
|
{
|
|
// get the metabase going
|
|
if ( !FInitMetabaseWrapper(m_pszwMachineName) )
|
|
return;
|
|
|
|
// run the choose ip dialog here
|
|
CChooseIPDlg dlg;
|
|
|
|
// set up the ip dialog member variables
|
|
dlg.m_szIPAddress = GetIPAddress();
|
|
|
|
// run the dialog
|
|
if ( dlg.DoModal() == IDOK )
|
|
{
|
|
FSetIPAddress( dlg.m_szIPAddress );
|
|
}
|
|
|
|
// now close the metabase again. We will open it when we need it
|
|
FCloseMetabaseWrapper();
|
|
}
|