|
|
// 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(); }
|