1066 lines
28 KiB
C++
1066 lines
28 KiB
C++
|
// Copyright (C) Microsoft Corporation, 1998 - 1999
|
||
|
//
|
||
|
// create new site and new subnet wizards
|
||
|
//
|
||
|
// 4-24-98 sburns
|
||
|
// 9-23-98 jonn Subclassed off New Subnet Wizard
|
||
|
|
||
|
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "resource.h"
|
||
|
|
||
|
#include "dsutil.h"
|
||
|
|
||
|
#include "newobj.h"
|
||
|
|
||
|
#include "dlgcreat.h"
|
||
|
#include "querysup.h"
|
||
|
|
||
|
#pragma warning (disable: 4100)
|
||
|
|
||
|
#include <utility> // pair<>
|
||
|
#include <list>
|
||
|
|
||
|
#pragma warning (default: 4100)
|
||
|
|
||
|
extern "C"
|
||
|
{
|
||
|
#include <dsgetdc.h> // DsValidateSubnetName
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#define BREAK_ON_FAILED_HRESULT(hr) \
|
||
|
if (FAILED(hr)) \
|
||
|
{ \
|
||
|
ASSERT(FALSE); \
|
||
|
break; \
|
||
|
}
|
||
|
|
||
|
#define BREAK_ON_NULL(p) \
|
||
|
if (NULL == p) \
|
||
|
{ \
|
||
|
ASSERT(FALSE); \
|
||
|
break; \
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// first in the pair is name of link, second is dn of the link
|
||
|
typedef std::pair< CComBSTR, CComBSTR > TargetLinkInfo;
|
||
|
typedef std::list< TargetLinkInfo > TargetLinkList;
|
||
|
|
||
|
|
||
|
|
||
|
CreateNewSiteWizard::CreateNewSiteWizard(
|
||
|
CNewADsObjectCreateInfo* pNewADsObjectCreateInfo)
|
||
|
:
|
||
|
CCreateNewObjectWizardBase(pNewADsObjectCreateInfo)
|
||
|
{
|
||
|
AddPage(&page);
|
||
|
}
|
||
|
|
||
|
|
||
|
CreateNewSubnetWizard::CreateNewSubnetWizard(
|
||
|
CNewADsObjectCreateInfo* pNewADsObjectCreateInfo)
|
||
|
:
|
||
|
CCreateNewObjectWizardBase(pNewADsObjectCreateInfo)
|
||
|
{
|
||
|
AddPage(&page);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CreateAndChoosePage, CCreateNewNamedObjectPage)
|
||
|
ON_WM_DESTROY()
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CreateNewSubnetPage, CreateAndChoosePage)
|
||
|
ON_EN_CHANGE(IDC_SUBNET_ADDRESS, OnSubnetMaskChange)
|
||
|
ON_EN_CHANGE(IDC_SUBNET_MASK, OnSubnetMaskChange)
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
|
||
|
CreateAndChoosePage::CreateAndChoosePage(UINT nIDTemplate)
|
||
|
:
|
||
|
CCreateNewNamedObjectPage(nIDTemplate),
|
||
|
listview(0),
|
||
|
listview_imagelist(0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
CreateNewSitePage::CreateNewSitePage()
|
||
|
:
|
||
|
CreateAndChoosePage(IDD_CREATE_NEW_SITE)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
CreateNewSubnetPage::CreateNewSubnetPage()
|
||
|
:
|
||
|
CreateAndChoosePage(IDD_CREATE_NEW_SUBNET)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CreateNewSitePage::SetData(BOOL bSilent)
|
||
|
{
|
||
|
if (0 < ListView_GetItemCount(listview))
|
||
|
{
|
||
|
if (0 >= ListView_GetSelectedCount(listview))
|
||
|
{
|
||
|
if (!bSilent)
|
||
|
{
|
||
|
ReportErrorEx (::GetParent(m_hWnd),IDS_NEW_SITE_SELECT_SITELINK,S_OK,
|
||
|
MB_OK, NULL, 0);
|
||
|
}
|
||
|
(void) this->PostMessage( WM_NEXTDLGCTL,
|
||
|
(WPARAM)listview,
|
||
|
TRUE );
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
}
|
||
|
return CreateAndChoosePage::SetData(bSilent);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CreateNewSubnetPage::SetData(BOOL bSilent)
|
||
|
{
|
||
|
CNewADsObjectCreateInfo* info = GetWiz()->GetInfo();
|
||
|
ASSERT(info);
|
||
|
HRESULT hr = E_FAIL;
|
||
|
if (!info)
|
||
|
return hr;
|
||
|
int count = ListView_GetItemCount(listview);
|
||
|
if (count > 0)
|
||
|
{
|
||
|
if (0 >= ListView_GetSelectedCount(listview))
|
||
|
{
|
||
|
if (!bSilent)
|
||
|
{
|
||
|
ReportErrorEx (::GetParent(m_hWnd),IDS_NEW_SUBNET_SELECT_SITE,S_OK,
|
||
|
MB_OK, NULL, 0);
|
||
|
}
|
||
|
(void) this->PostMessage( WM_NEXTDLGCTL,
|
||
|
(WPARAM)listview,
|
||
|
TRUE );
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
for (int i = 0; i < count; i++)
|
||
|
{
|
||
|
if (ListView_GetItemState(listview, i, LVIS_SELECTED))
|
||
|
{
|
||
|
LVITEM item = {0};
|
||
|
item.mask = LVIF_PARAM;
|
||
|
item.iItem = i;
|
||
|
|
||
|
if (ListView_GetItem(listview, &item))
|
||
|
{
|
||
|
// the item.lParam field is the dn of the target site
|
||
|
CComBSTR* dn = reinterpret_cast<CComBSTR*>(item.lParam);
|
||
|
hr = info->HrAddVariantBstrIfNotEmpty(
|
||
|
const_cast<PWSTR>(gsz_siteObject),
|
||
|
*dn,
|
||
|
TRUE ); // HrCreateNew has not been called yet
|
||
|
if ( FAILED(hr) )
|
||
|
{
|
||
|
ASSERT(FALSE);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
// use the first site selected
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
ASSERT( i < count );
|
||
|
}
|
||
|
return CreateAndChoosePage::SetData(bSilent);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CreateNewSitePage::tweakSiteLink(LPCTSTR siteDN)
|
||
|
{
|
||
|
ASSERT(siteDN);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
do
|
||
|
{
|
||
|
// get the DN of the new site
|
||
|
// this is a pointer alias: no need to AddRef/Release
|
||
|
hr = E_FAIL;
|
||
|
CPathCracker pathCracker;
|
||
|
|
||
|
CCreateNewObjectWizardBase* pwiz = GetWiz();
|
||
|
BREAK_ON_NULL(pwiz);
|
||
|
CNewADsObjectCreateInfo* pinfo = pwiz->GetInfo();
|
||
|
BREAK_ON_NULL(pinfo);
|
||
|
IADs* piadsSite = pinfo->PGetIADsPtr();
|
||
|
BREAK_ON_NULL(piadsSite);
|
||
|
CComBSTR sbstrSitePath;
|
||
|
hr = piadsSite->get_ADsPath( &sbstrSitePath );
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
hr = pathCracker.Set(sbstrSitePath, ADS_SETTYPE_FULL);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
CComBSTR sbstrSiteDN;
|
||
|
hr = pathCracker.SetDisplayType(ADS_DISPLAY_FULL);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
hr = pathCracker.Retrieve(ADS_FORMAT_X500_DN, &sbstrSiteDN);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
// munge together the path name of the site link object
|
||
|
hr = pathCracker.Set( const_cast<LPTSTR>(siteDN), ADS_SETTYPE_DN);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
CComBSTR sbstrSiteLinkPath;
|
||
|
hr = pathCracker.Retrieve(ADS_FORMAT_X500, &sbstrSiteLinkPath);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
// bind to the site link
|
||
|
CComPtr<IADs> link;
|
||
|
hr = DSAdminOpenObject(sbstrSiteLinkPath,
|
||
|
IID_IADs,
|
||
|
(void**) &link,
|
||
|
FALSE /*bServer*/);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
ASSERT(link);
|
||
|
|
||
|
// Add the DN of the new site to the siteList attr of the link object
|
||
|
|
||
|
// build the new value
|
||
|
CComVariant var;
|
||
|
hr = ADsBuildVarArrayStr(&sbstrSiteDN, 1, &var);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
// write it. whew.
|
||
|
hr =
|
||
|
link->PutEx(
|
||
|
ADS_PROPERTY_APPEND,
|
||
|
const_cast<LPTSTR>(gsz_siteList),
|
||
|
var);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr = link->SetInfo();
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
}
|
||
|
while (0);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
ReportError(hr, IDS_ERROR_TWEAKING_SITE_LINK, m_hWnd);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CreateNewSitePage::OnPostCommit(BOOL bSilent)
|
||
|
{
|
||
|
ASSERT(listview);
|
||
|
|
||
|
int count = ListView_GetItemCount(listview);
|
||
|
if (count > 0)
|
||
|
{
|
||
|
for (int i = 0; i < count; i++)
|
||
|
{
|
||
|
if (ListView_GetItemState(listview, i, LVIS_SELECTED))
|
||
|
{
|
||
|
LVITEM item = {0};
|
||
|
item.mask = LVIF_PARAM;
|
||
|
item.iItem = i;
|
||
|
|
||
|
if (ListView_GetItem(listview, &item))
|
||
|
{
|
||
|
// the item.lParam field is the dn of the target link
|
||
|
CComBSTR* dn = reinterpret_cast<CComBSTR*>(item.lParam);
|
||
|
tweakSiteLink(*dn);
|
||
|
|
||
|
// only tweak the first site link selected
|
||
|
return S_OK;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!bSilent)
|
||
|
{
|
||
|
ReportMessageEx(
|
||
|
m_hWnd,
|
||
|
IDS_NEWSITE_WARNING,
|
||
|
MB_OK | MB_ICONWARNING,
|
||
|
NULL,
|
||
|
0,
|
||
|
IDS_WARNING_TITLE);
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
RecursiveFind(const CString& lpcwszADsPathDirectory,
|
||
|
LPCTSTR lpcwszTargetClass,
|
||
|
TargetLinkList& links,
|
||
|
LPWSTR pszAttribute = L"distinguishedName");
|
||
|
|
||
|
HRESULT
|
||
|
RecursiveFind(const CString& lpcwszADsPathDirectory,
|
||
|
LPCTSTR lpcwszTargetClass,
|
||
|
TargetLinkList& links,
|
||
|
LPWSTR pszAttribute)
|
||
|
{
|
||
|
links.clear();
|
||
|
|
||
|
CDSSearch Search;
|
||
|
Search.Init(lpcwszADsPathDirectory);
|
||
|
CString filter;
|
||
|
filter.Format(L"(objectClass=%s)", lpcwszTargetClass);
|
||
|
Search.SetFilterString(const_cast<LPTSTR>((LPCTSTR) filter));
|
||
|
LPWSTR pAttrs[2] =
|
||
|
{
|
||
|
L"name",
|
||
|
pszAttribute
|
||
|
};
|
||
|
Search.SetAttributeList(pAttrs, 2);
|
||
|
Search.SetSearchScope(ADS_SCOPE_SUBTREE);
|
||
|
|
||
|
HRESULT hr = Search.DoQuery();
|
||
|
while (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = Search.GetNextRow();
|
||
|
if (S_ADS_NOMORE_ROWS == hr)
|
||
|
{
|
||
|
hr = S_OK;
|
||
|
break;
|
||
|
}
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
ADS_SEARCH_COLUMN NameColumn;
|
||
|
::ZeroMemory(&NameColumn, sizeof(NameColumn));
|
||
|
hr = Search.GetColumn (pAttrs[0], &NameColumn);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
ASSERT(ADSTYPE_CASE_IGNORE_STRING == NameColumn.pADsValues->dwType);
|
||
|
|
||
|
ADS_SEARCH_COLUMN DistinguishedNameColumn;
|
||
|
::ZeroMemory(&DistinguishedNameColumn, sizeof(DistinguishedNameColumn));
|
||
|
hr = Search.GetColumn (pAttrs[1], &DistinguishedNameColumn);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
ASSERT(ADSTYPE_DN_STRING == DistinguishedNameColumn.pADsValues->dwType
|
||
|
|| ADSTYPE_CASE_IGNORE_STRING == DistinguishedNameColumn.pADsValues->dwType);
|
||
|
|
||
|
links.push_back(
|
||
|
TargetLinkInfo(
|
||
|
NameColumn.pADsValues->CaseIgnoreString,
|
||
|
DistinguishedNameColumn.pADsValues->DNString));
|
||
|
|
||
|
Search.FreeColumn(&NameColumn);
|
||
|
Search.FreeColumn(&DistinguishedNameColumn);
|
||
|
}
|
||
|
|
||
|
#ifdef DBG
|
||
|
// dump the list to the debugger
|
||
|
for (
|
||
|
TargetLinkList::iterator i = links.begin();
|
||
|
i != links.end();
|
||
|
i++)
|
||
|
{
|
||
|
OutputDebugString(i->first);
|
||
|
OutputDebugString(L"\n");
|
||
|
OutputDebugString(i->second);
|
||
|
OutputDebugString(L"\n");
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
CreateAndChoosePage::OnSetActive()
|
||
|
{
|
||
|
CComQIPtr<IADs, &IID_IADs> container(GetWiz()->GetInfo()->m_pIADsContainer);
|
||
|
|
||
|
if (container)
|
||
|
{
|
||
|
CComBSTR container_path;
|
||
|
container->get_ADsPath(&container_path);
|
||
|
initListContents(container_path);
|
||
|
}
|
||
|
|
||
|
return Base::OnSetActive();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void
|
||
|
destroyListContents(HWND listview)
|
||
|
{
|
||
|
ASSERT(listview);
|
||
|
|
||
|
for (int i = ListView_GetItemCount(listview) - 1; i >= 0; i--)
|
||
|
{
|
||
|
LVITEM item = {0};
|
||
|
item.mask = LVIF_PARAM;
|
||
|
item.iItem = i;
|
||
|
|
||
|
if (ListView_GetItem(listview, &item))
|
||
|
{
|
||
|
ASSERT(item.lParam);
|
||
|
|
||
|
delete reinterpret_cast<CComBSTR*>(item.lParam);
|
||
|
ListView_DeleteItem(listview, i);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void
|
||
|
CreateAndChoosePage::OnDestroy()
|
||
|
{
|
||
|
destroyListContents(listview);
|
||
|
|
||
|
Base::OnDestroy();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void
|
||
|
CreateNewSitePage::initListContents(LPCWSTR containerPath)
|
||
|
{
|
||
|
ASSERT(listview);
|
||
|
|
||
|
CWaitCursor cwait;
|
||
|
|
||
|
TargetLinkList links;
|
||
|
bool links_present = false;
|
||
|
HRESULT hr = RecursiveFind(containerPath, gsz_siteLink, links);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// walk the list and add nodes
|
||
|
for (
|
||
|
TargetLinkList::iterator i = links.begin();
|
||
|
i != links.end();
|
||
|
i++)
|
||
|
{
|
||
|
LVITEM item = {0};
|
||
|
memset(&item, 0, sizeof(item));
|
||
|
|
||
|
// this is deleted in destroyListContents
|
||
|
CComBSTR* dn = new CComBSTR(i->second);
|
||
|
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
||
|
item.iItem = 0;
|
||
|
item.iSubItem = 0;
|
||
|
item.pszText = static_cast<LPTSTR>(i->first);
|
||
|
item.lParam = reinterpret_cast<LPARAM>(dn);
|
||
|
item.iImage = 0; // always the same, first image
|
||
|
|
||
|
item.iItem = ListView_InsertItem(listview, &item);
|
||
|
ASSERT(item.iItem >= 0);
|
||
|
|
||
|
// add the transport sub-item to the list control
|
||
|
CPathCracker pathCracker;
|
||
|
hr =
|
||
|
pathCracker.Set(
|
||
|
static_cast<LPTSTR>(i->second),
|
||
|
ADS_SETTYPE_DN);
|
||
|
ASSERT(SUCCEEDED(hr));
|
||
|
hr = pathCracker.SetDisplayType(ADS_DISPLAY_VALUE_ONLY);
|
||
|
ASSERT(SUCCEEDED(hr));
|
||
|
|
||
|
CComBSTR b;
|
||
|
hr = pathCracker.GetElement(1, &b);
|
||
|
ASSERT(SUCCEEDED(hr));
|
||
|
hr = pathCracker.SetDisplayType(ADS_DISPLAY_FULL);
|
||
|
ASSERT(SUCCEEDED(hr));
|
||
|
|
||
|
item.mask = LVIF_TEXT;
|
||
|
item.iSubItem = 1;
|
||
|
item.pszText = b;
|
||
|
ListView_SetItem(listview, &item);
|
||
|
|
||
|
links_present = true;
|
||
|
}
|
||
|
if (!links_present)
|
||
|
{
|
||
|
ReportError(hr, IDS_WARNING_NO_SITE_LINKS, m_hWnd);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ReportError(hr, IDS_CANT_FIND_SITE_LINKS, m_hWnd);
|
||
|
}
|
||
|
|
||
|
if (!links_present)
|
||
|
{
|
||
|
GetDlgItem(IDC_LINKS)->EnableWindow(FALSE);
|
||
|
GetDlgItem(IDC_SITE_TEXT)->EnableWindow(FALSE);
|
||
|
}
|
||
|
else // JonN 3/28/01 319675
|
||
|
{
|
||
|
ListView_SetItemState( listview, 0, LVIS_FOCUSED, LVIS_FOCUSED );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
CreateNewSubnetPage::initListContents(LPCWSTR containerPath)
|
||
|
{
|
||
|
ASSERT(listview);
|
||
|
|
||
|
CWaitCursor cwait;
|
||
|
|
||
|
TargetLinkList links;
|
||
|
bool links_present = false;
|
||
|
|
||
|
CComBSTR sbstrSites;
|
||
|
|
||
|
CPathCracker pathCracker;
|
||
|
HRESULT hr = pathCracker.Set(
|
||
|
const_cast<LPTSTR>(containerPath),
|
||
|
ADS_SETTYPE_FULL);
|
||
|
if (SUCCEEDED(hr))
|
||
|
hr = pathCracker.RemoveLeafElement();
|
||
|
if (SUCCEEDED(hr))
|
||
|
hr = pathCracker.Retrieve(ADS_FORMAT_X500, &sbstrSites);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
hr = RecursiveFind((LPCTSTR)sbstrSites, gsz_site, links);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// walk the list and add nodes
|
||
|
for (
|
||
|
TargetLinkList::iterator i = links.begin();
|
||
|
i != links.end();
|
||
|
i++)
|
||
|
{
|
||
|
LVITEM item;
|
||
|
memset(&item, 0, sizeof(item));
|
||
|
|
||
|
// this is deleted in destroyListContents
|
||
|
CComBSTR* dn = new CComBSTR(i->second);
|
||
|
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
||
|
item.iItem = 0;
|
||
|
item.iSubItem = 0;
|
||
|
item.pszText = static_cast<LPTSTR>(i->first);
|
||
|
item.lParam = reinterpret_cast<LPARAM>(dn);
|
||
|
item.iImage = 0; // always the same, first image
|
||
|
|
||
|
item.iItem = ListView_InsertItem(listview, &item);
|
||
|
ASSERT(item.iItem >= 0);
|
||
|
|
||
|
links_present = true;
|
||
|
}
|
||
|
if (!links_present)
|
||
|
{
|
||
|
ReportError(hr, IDS_NEWSUBNET_WARNING_NO_SITES, m_hWnd);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ReportError(hr, IDS_NEWSUBNET_CANT_FIND_SITES, m_hWnd);
|
||
|
}
|
||
|
|
||
|
if (!links_present)
|
||
|
{
|
||
|
GetDlgItem(IDC_LINKS)->EnableWindow(FALSE);
|
||
|
GetDlgItem(IDC_SITE_TEXT)->EnableWindow(FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
CreateNewSitePage::OnInitDialog()
|
||
|
{
|
||
|
Base::OnInitDialog();
|
||
|
MyBasePathsInfo* pBasePathsInfo = GetWiz()->GetInfo()->GetBasePathsInfo();
|
||
|
|
||
|
listview = ::GetDlgItem(m_hWnd, IDC_LINKS);
|
||
|
ASSERT(listview);
|
||
|
|
||
|
LVCOLUMN column = {0};
|
||
|
column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||
|
column.fmt = LVCFMT_LEFT;
|
||
|
|
||
|
{ // open scope
|
||
|
CString w;
|
||
|
w.LoadString(IDS_NEW_SITE_NAME_COLUMN_WIDTH);
|
||
|
w.TrimLeft();
|
||
|
w.TrimRight();
|
||
|
long width = _tcstol(w, 0, 10);
|
||
|
ASSERT(width != 0 && width != LONG_MAX && width != LONG_MIN);
|
||
|
column.cx = width;
|
||
|
|
||
|
CString label;
|
||
|
label.LoadString(IDS_NEW_SITE_NAME_COLUMN);
|
||
|
column.pszText = const_cast<LPTSTR>((LPCTSTR) label);
|
||
|
|
||
|
ListView_InsertColumn(listview, 0, &column);
|
||
|
} // close scope
|
||
|
|
||
|
// add a column to the list view for parent transport.
|
||
|
|
||
|
{ // open scope
|
||
|
CString w;
|
||
|
w.LoadString(IDS_NEW_SITE_XPORT_COLUMN_WIDTH);
|
||
|
w.TrimLeft();
|
||
|
w.TrimRight();
|
||
|
long width = _tcstol(w, 0, 10);
|
||
|
ASSERT(width != 0 && width != LONG_MAX && width != LONG_MIN);
|
||
|
column.cx = width;
|
||
|
|
||
|
CString label;
|
||
|
label.LoadString(IDS_NEW_SITE_XPORT_COLUMN);
|
||
|
column.pszText = const_cast<LPTSTR>((LPCTSTR) label);
|
||
|
|
||
|
ListView_InsertColumn(listview, 1, &column);
|
||
|
} // close scope
|
||
|
|
||
|
// create the image list containing the site link icon
|
||
|
int cx = ::GetSystemMetrics(SM_CXSMICON);
|
||
|
int cy = ::GetSystemMetrics(SM_CYSMICON);
|
||
|
ASSERT(cx && cy);
|
||
|
|
||
|
// deleted in OnDestroy
|
||
|
listview_imagelist = ::ImageList_Create(cx, cy, ILC_MASK, 1, 0);
|
||
|
ASSERT(listview_imagelist);
|
||
|
|
||
|
HICON icon = pBasePathsInfo->GetIcon(
|
||
|
// someone really blew it with const correctness...
|
||
|
const_cast<LPTSTR>(gsz_siteLink),
|
||
|
DSGIF_ISNORMAL | DSGIF_GETDEFAULTICON,
|
||
|
16,
|
||
|
16);
|
||
|
ASSERT(icon);
|
||
|
|
||
|
int i = ::ImageList_AddIcon(listview_imagelist, icon);
|
||
|
ASSERT(i != -1);
|
||
|
|
||
|
DestroyIcon(icon);
|
||
|
|
||
|
ListView_SetImageList(listview, listview_imagelist, LVSIL_SMALL);
|
||
|
|
||
|
ListView_SetExtendedListViewStyleEx(
|
||
|
listview,
|
||
|
LVS_EX_FULLROWSELECT,
|
||
|
LVS_EX_FULLROWSELECT);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
CreateNewSubnetPage::OnInitDialog()
|
||
|
{
|
||
|
Base::OnInitDialog();
|
||
|
MyBasePathsInfo* pBasePathsInfo = GetWiz()->GetInfo()->GetBasePathsInfo();
|
||
|
|
||
|
(void) SendDlgItemMessage( IDC_SUBNET_ADDRESS,
|
||
|
IPM_SETADDRESS,
|
||
|
0,
|
||
|
(LPARAM)MAKEIPADDRESS(0,0,0,0) );
|
||
|
(void) SendDlgItemMessage( IDC_SUBNET_MASK,
|
||
|
IPM_SETADDRESS,
|
||
|
0,
|
||
|
(LPARAM)MAKEIPADDRESS(0,0,0,0) );
|
||
|
|
||
|
listview = ::GetDlgItem(m_hWnd, IDC_LINKS);
|
||
|
ASSERT(listview);
|
||
|
|
||
|
{ // open scope
|
||
|
LVCOLUMN column = {0};
|
||
|
column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||
|
column.fmt = LVCFMT_LEFT;
|
||
|
|
||
|
CString w;
|
||
|
w.LoadString(IDS_COLUMN_SITE_WIDTH);
|
||
|
w.TrimLeft();
|
||
|
w.TrimRight();
|
||
|
long width = _tcstol(w, 0, 10);
|
||
|
ASSERT(width != 0 && width != LONG_MAX && width != LONG_MIN);
|
||
|
column.cx = width;
|
||
|
|
||
|
CString label;
|
||
|
label.LoadString(IDS_COLUMN_SITE_NAME);
|
||
|
column.pszText = const_cast<LPTSTR>((LPCTSTR) label);
|
||
|
|
||
|
ListView_InsertColumn(listview, 0, &column);
|
||
|
} // close scope
|
||
|
|
||
|
// create the image list containing the site link icon
|
||
|
int cx = ::GetSystemMetrics(SM_CXSMICON);
|
||
|
int cy = ::GetSystemMetrics(SM_CYSMICON);
|
||
|
ASSERT(cx && cy);
|
||
|
|
||
|
// deleted in OnDestroy
|
||
|
listview_imagelist = ::ImageList_Create(cx, cy, ILC_MASK, 1, 0);
|
||
|
ASSERT(listview_imagelist);
|
||
|
|
||
|
HICON icon = pBasePathsInfo->GetIcon(
|
||
|
// someone really blew it with const correctness...
|
||
|
const_cast<LPTSTR>(gsz_site),
|
||
|
DSGIF_ISNORMAL | DSGIF_GETDEFAULTICON | DSGIF_DEFAULTISCONTAINER,
|
||
|
16,
|
||
|
16);
|
||
|
ASSERT(icon);
|
||
|
|
||
|
int i = ::ImageList_AddIcon(listview_imagelist, icon);
|
||
|
ASSERT(i != -1);
|
||
|
|
||
|
DestroyIcon(icon);
|
||
|
|
||
|
ListView_SetImageList(listview, listview_imagelist, LVSIL_SMALL);
|
||
|
|
||
|
ListView_SetExtendedListViewStyleEx(
|
||
|
listview,
|
||
|
LVS_EX_FULLROWSELECT,
|
||
|
LVS_EX_FULLROWSELECT);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CreateNewSitePage::ValidateName(LPCTSTR pcszName)
|
||
|
{
|
||
|
BOOL fNonRfcSiteName = FALSE;
|
||
|
BOOL fValidSiteName = IsValidSiteName( pcszName, &fNonRfcSiteName );
|
||
|
if ( !fValidSiteName )
|
||
|
{
|
||
|
ReportErrorEx (::GetParent(m_hWnd),IDS_SITE_NAME,S_OK,
|
||
|
MB_OK, NULL, 0);
|
||
|
}
|
||
|
else if ( fNonRfcSiteName )
|
||
|
{
|
||
|
PVOID apv[1];
|
||
|
apv[0] = (PVOID)pcszName;
|
||
|
if (IDYES != ReportMessageEx( ::GetParent(m_hWnd),
|
||
|
IDS_1_NON_RFC_SITE_NAME,
|
||
|
MB_YESNO | MB_ICONWARNING,
|
||
|
apv,
|
||
|
1 ) )
|
||
|
{
|
||
|
fValidSiteName = FALSE;
|
||
|
}
|
||
|
}
|
||
|
if ( !fValidSiteName )
|
||
|
{
|
||
|
// Yes, this really does have to be PostMessage, SendMessage doesn't work
|
||
|
// It also has to come after ReportErrorEx or else it doesn't work
|
||
|
(void) this->PostMessage( WM_NEXTDLGCTL,
|
||
|
(WPARAM)::GetDlgItem(m_hWnd, IDC_EDIT_OBJECT_NAME),
|
||
|
TRUE );
|
||
|
(void) ::PostMessage( ::GetDlgItem(m_hWnd, IDC_EDIT_OBJECT_NAME), EM_SETSEL, 0, -1 );
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
// JonN 5/11/01 251560 Disable OK until site link chosen
|
||
|
BEGIN_MESSAGE_MAP(CreateNewSitePage, CreateAndChoosePage)
|
||
|
ON_EN_CHANGE(IDC_EDIT_OBJECT_NAME, OnChange)
|
||
|
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LINKS, OnSelChange)
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
afx_msg void CreateNewSitePage::OnSelChange( NMHDR*, LRESULT* )
|
||
|
{
|
||
|
OnChange();
|
||
|
}
|
||
|
|
||
|
void CreateNewSitePage::OnChange()
|
||
|
{
|
||
|
if (0 >= ListView_GetSelectedCount(listview))
|
||
|
GetWiz()->SetWizardButtons(this, FALSE);
|
||
|
else
|
||
|
OnNameChange(); // Enable the OK button only if the name is not empty
|
||
|
}
|
||
|
|
||
|
// no need to validate subnet name, MapMaskAndAddress does this
|
||
|
// return -32 for invalid mask
|
||
|
int CountBits( DWORD dwOctet )
|
||
|
{
|
||
|
if ( 0xff < dwOctet )
|
||
|
{
|
||
|
ASSERT(FALSE);
|
||
|
return -32;
|
||
|
}
|
||
|
for (int nBits = 0; dwOctet & 0x80; nBits++)
|
||
|
dwOctet = (dwOctet & ~0x80) * 2;
|
||
|
if (dwOctet != 0)
|
||
|
return -32; // hole in the mask
|
||
|
return nBits;
|
||
|
}
|
||
|
|
||
|
// returns <0 for invalid mask
|
||
|
int CountMaskedBits( DWORD dwMask )
|
||
|
{
|
||
|
int nFirstOctet = FIRST_IPADDRESS(dwMask);
|
||
|
int nSecondOctet = SECOND_IPADDRESS(dwMask);
|
||
|
int nThirdOctet = THIRD_IPADDRESS(dwMask);
|
||
|
int nFourthOctet = FOURTH_IPADDRESS(dwMask);
|
||
|
if (nFirstOctet < 255)
|
||
|
{
|
||
|
if (0 != nSecondOctet || 0 != nThirdOctet || 0 != nFourthOctet)
|
||
|
return -1;
|
||
|
return CountBits(nFirstOctet);
|
||
|
}
|
||
|
if (nSecondOctet < 255)
|
||
|
{
|
||
|
if (255 != nFirstOctet || 0 != nThirdOctet || 0 != nFourthOctet)
|
||
|
return -1;
|
||
|
return 8 + CountBits(nSecondOctet);
|
||
|
}
|
||
|
if (nThirdOctet < 255)
|
||
|
{
|
||
|
if (255 != nFirstOctet || 255 != nSecondOctet || 0 != nFourthOctet)
|
||
|
return -1;
|
||
|
return 16 + CountBits(nThirdOctet);
|
||
|
}
|
||
|
if (255 != nFirstOctet || 255 != nSecondOctet || 255 != nThirdOctet)
|
||
|
return -1;
|
||
|
return 24 + CountBits(nFourthOctet);
|
||
|
|
||
|
}
|
||
|
|
||
|
// returns empty string for invalid address+mask
|
||
|
void MapMaskAndAddress(
|
||
|
OUT CString& strrefSubnetName,
|
||
|
IN DWORD dwAddress,
|
||
|
IN DWORD dwMask )
|
||
|
{
|
||
|
strrefSubnetName.Empty();
|
||
|
|
||
|
dwAddress &= dwMask; // clear all bits set in the address and not in the mask
|
||
|
|
||
|
int nMaskedBits = CountMaskedBits( dwMask );
|
||
|
if (0 > nMaskedBits)
|
||
|
return; // invalid mask
|
||
|
|
||
|
strrefSubnetName.Format(L"%d.%d.%d.%d/%d",
|
||
|
FIRST_IPADDRESS(dwAddress),
|
||
|
SECOND_IPADDRESS(dwAddress),
|
||
|
THIRD_IPADDRESS(dwAddress),
|
||
|
FOURTH_IPADDRESS(dwAddress),
|
||
|
nMaskedBits);
|
||
|
|
||
|
// final test for edge cases such as "0.0.0.0/0"
|
||
|
if (ERROR_SUCCESS != ::DsValidateSubnetName( strrefSubnetName ))
|
||
|
strrefSubnetName.Empty();
|
||
|
}
|
||
|
|
||
|
void CreateNewSubnetPage::OnSubnetMaskChange()
|
||
|
{
|
||
|
DWORD dwAddress, dwMask;
|
||
|
CString strSubnetName;
|
||
|
// IPM_GETADDRESS returns the number of octets filled in. Address is
|
||
|
// invalid if any of the four is left blank.
|
||
|
if ( 4 == SendDlgItemMessage( IDC_SUBNET_ADDRESS,
|
||
|
IPM_GETADDRESS,
|
||
|
0,
|
||
|
(LPARAM)&dwAddress )
|
||
|
&& 4 == SendDlgItemMessage( IDC_SUBNET_MASK,
|
||
|
IPM_GETADDRESS,
|
||
|
0,
|
||
|
(LPARAM)&dwMask ) )
|
||
|
{
|
||
|
MapMaskAndAddress( strSubnetName, dwAddress, dwMask );
|
||
|
}
|
||
|
SetDlgItemText(IDC_EDIT_OBJECT_NAME, strSubnetName);
|
||
|
OnNameChange();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CMoveServerDialog, CDialog)
|
||
|
//{{AFX_MSG_MAP(CMoveServerDialog)
|
||
|
ON_WM_DESTROY()
|
||
|
ON_NOTIFY(NM_DBLCLK, IDC_LINKS, OnDblclkListview)
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
|
||
|
CMoveServerDialog::CMoveServerDialog(LPCTSTR lpcszBrowseRootPath, HICON hIcon, CWnd* pParent /*=NULL*/)
|
||
|
: CDialog(CMoveServerDialog::IDD, pParent)
|
||
|
, m_strTargetContainer()
|
||
|
, m_strBrowseRootPath(lpcszBrowseRootPath)
|
||
|
, m_hIcon(hIcon)
|
||
|
, listview(0)
|
||
|
, listview_imagelist(0)
|
||
|
{}
|
||
|
|
||
|
BOOL
|
||
|
CMoveServerDialog::OnInitDialog()
|
||
|
{
|
||
|
CDialog::OnInitDialog();
|
||
|
|
||
|
CWaitCursor cwait;
|
||
|
|
||
|
listview = ::GetDlgItem(m_hWnd, IDC_LINKS);
|
||
|
ASSERT(listview);
|
||
|
|
||
|
{ // open scope
|
||
|
LVCOLUMN column = {0};
|
||
|
column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||
|
column.fmt = LVCFMT_LEFT;
|
||
|
|
||
|
CString w;
|
||
|
w.LoadString(IDS_COLUMN_SITE_WIDTH);
|
||
|
w.TrimLeft();
|
||
|
w.TrimRight();
|
||
|
long width = _tcstol(w, 0, 10);
|
||
|
ASSERT(width != 0 && width != LONG_MAX && width != LONG_MIN);
|
||
|
column.cx = width;
|
||
|
|
||
|
CString label;
|
||
|
label.LoadString(IDS_COLUMN_SITE_NAME);
|
||
|
column.pszText = const_cast<LPTSTR>((LPCTSTR) label);
|
||
|
|
||
|
ListView_InsertColumn(listview, 0, &column);
|
||
|
} // close scope
|
||
|
|
||
|
// create the image list containing the site link icon
|
||
|
int cx = ::GetSystemMetrics(SM_CXSMICON);
|
||
|
int cy = ::GetSystemMetrics(SM_CYSMICON);
|
||
|
ASSERT(cx && cy);
|
||
|
|
||
|
// deleted in OnDestroy
|
||
|
listview_imagelist = ::ImageList_Create(cx, cy, ILC_MASK, 1, 0);
|
||
|
ASSERT(listview_imagelist);
|
||
|
ASSERT(m_hIcon != NULL);
|
||
|
int i = ::ImageList_AddIcon(listview_imagelist, m_hIcon);
|
||
|
ASSERT(i != -1);
|
||
|
|
||
|
ListView_SetImageList(listview, listview_imagelist, LVSIL_SMALL);
|
||
|
|
||
|
ListView_SetExtendedListViewStyleEx(
|
||
|
listview,
|
||
|
LVS_EX_FULLROWSELECT,
|
||
|
LVS_EX_FULLROWSELECT);
|
||
|
|
||
|
// add sites to listview
|
||
|
TargetLinkList links;
|
||
|
bool links_present = false;
|
||
|
HRESULT hr = RecursiveFind(m_strBrowseRootPath, gsz_serversContainer, links, L"aDSPath");
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// walk the list and add nodes
|
||
|
for (
|
||
|
TargetLinkList::iterator itr = links.begin();
|
||
|
itr != links.end();
|
||
|
++itr)
|
||
|
{
|
||
|
LVITEM item;
|
||
|
memset(&item, 0, sizeof(item));
|
||
|
|
||
|
// Since the enumerated objects are of type serversContainer,
|
||
|
// we display the name of the parent. Also, the aDSPath attribute may
|
||
|
// contain a server indication, which must be removed.
|
||
|
|
||
|
CPathCracker pathCracker;
|
||
|
hr = pathCracker.Set( itr->second, ADS_SETTYPE_FULL );
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
hr = pathCracker.SetDisplayType(ADS_DISPLAY_VALUE_ONLY);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
CComBSTR sbstrName;
|
||
|
hr = pathCracker.GetElement( 1L, &sbstrName );
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
hr = pathCracker.SetDisplayType(ADS_DISPLAY_FULL);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
CComBSTR sbstrDN;
|
||
|
hr = pathCracker.Retrieve( ADS_FORMAT_X500, &sbstrDN );
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
// this is deleted in destroyListContents
|
||
|
CComBSTR* dn = new CComBSTR(sbstrDN);
|
||
|
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
||
|
item.iItem = 0;
|
||
|
item.iSubItem = 0;
|
||
|
item.pszText = static_cast<LPTSTR>(sbstrName);
|
||
|
item.lParam = reinterpret_cast<LPARAM>(dn);
|
||
|
item.iImage = 0; // always the same, first image
|
||
|
|
||
|
item.iItem = ListView_InsertItem(listview, &item);
|
||
|
ASSERT(item.iItem >= 0);
|
||
|
|
||
|
links_present = true;
|
||
|
}
|
||
|
if (!links_present)
|
||
|
{
|
||
|
ReportError(hr, IDS_MOVESERVER_ERROR_NO_SITES, m_hWnd);
|
||
|
OnCancel();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( FAILED(hr) )
|
||
|
{
|
||
|
ReportError(hr, IDS_MOVESERVER_ERROR_ENUMERATING_SITES, m_hWnd);
|
||
|
OnCancel();
|
||
|
}
|
||
|
|
||
|
return TRUE; // return TRUE unless you set the focus to a control
|
||
|
// EXCEPTION: OCX Property Pages should return FALSE
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CMoveServerDialog::OnDestroy()
|
||
|
{
|
||
|
destroyListContents(listview);
|
||
|
|
||
|
CDialog::OnDestroy();
|
||
|
}
|
||
|
|
||
|
void CMoveServerDialog::OnOK()
|
||
|
{
|
||
|
int count = ListView_GetItemCount(listview);
|
||
|
if (count > 0)
|
||
|
{
|
||
|
if (0 >= ListView_GetSelectedCount(listview))
|
||
|
{
|
||
|
ReportErrorEx (m_hWnd,IDS_MOVESERVER_SELECT_SITE,S_OK,
|
||
|
MB_OK, NULL, 0);
|
||
|
(void) this->PostMessage( WM_NEXTDLGCTL,
|
||
|
(WPARAM)listview,
|
||
|
TRUE );
|
||
|
return;
|
||
|
}
|
||
|
for (int i = 0; i < count; i++)
|
||
|
{
|
||
|
if (ListView_GetItemState(listview, i, LVIS_SELECTED))
|
||
|
{
|
||
|
LVITEM item = {0};
|
||
|
item.mask = LVIF_PARAM;
|
||
|
item.iItem = i;
|
||
|
|
||
|
if (ListView_GetItem(listview, &item))
|
||
|
{
|
||
|
// the item.lParam field is the dn of the target site
|
||
|
CComBSTR* dn = reinterpret_cast<CComBSTR*>(item.lParam);
|
||
|
m_strTargetContainer = *dn;
|
||
|
|
||
|
// use the first site selected
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
ASSERT( i < count );
|
||
|
}
|
||
|
|
||
|
CDialog::OnOK();
|
||
|
}
|
||
|
|
||
|
void CMoveServerDialog::OnDblclkListview(NMHDR*, LRESULT*)
|
||
|
{
|
||
|
OnOK();
|
||
|
}
|