You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1452 lines
43 KiB
1452 lines
43 KiB
/*++
|
|
Module Name:
|
|
|
|
DfsWiz.cpp
|
|
|
|
Abstract:
|
|
|
|
This module contains the implementation for CCreateDfsRootWizPage1, 2, 3, 4, 5, 6.
|
|
These classes implement pages in the CreateDfs Root wizard.
|
|
--*/
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "resource.h" // To be able to use the resource symbols
|
|
#include "DfsEnums.h" // for common enums, typedefs, etc
|
|
#include "NetUtils.h"
|
|
#include "ldaputils.h"
|
|
#include "Utils.h" // For the LoadStringFromResource method
|
|
|
|
#include "dfswiz.h" // For Ds Query Dialog
|
|
#include <shlobj.h>
|
|
#include <dsclient.h>
|
|
#include <initguid.h>
|
|
#include <cmnquery.h>
|
|
#include <dsquery.h>
|
|
#include <lmdfs.h>
|
|
#include <iads.h>
|
|
#include <icanon.h>
|
|
#include <dns.h>
|
|
|
|
HRESULT
|
|
ValidateFolderPath(
|
|
IN LPCTSTR lpszServer,
|
|
IN LPCTSTR lpszPath
|
|
);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// CCreateDfsRootWizPage1: Welcome page
|
|
CCreateDfsRootWizPage1::CCreateDfsRootWizPage1(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
|
|
: CQWizardPageImpl<CCreateDfsRootWizPage1>(false),
|
|
m_lpWizInfo(i_lpWizInfo)
|
|
{
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage1::OnSetActive()
|
|
{
|
|
::PropSheet_SetWizButtons(GetParent(), PSWIZB_NEXT);
|
|
::SetControlFont(m_lpWizInfo->hBigBoldFont, m_hWnd, IDC_WELCOME_BIG_TITLE);
|
|
::SetControlFont(m_lpWizInfo->hBoldFont, m_hWnd, IDC_WELCOME_SMALL_TITLE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// CCreateDfsRootWizPage2: Dfsroot type selection
|
|
CCreateDfsRootWizPage2::CCreateDfsRootWizPage2(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
|
|
: CQWizardPageImpl<CCreateDfsRootWizPage2>(true),
|
|
m_lpWizInfo(i_lpWizInfo)
|
|
{
|
|
CComBSTR bstrTitle;
|
|
LoadStringFromResource(IDS_WIZ_PAGE2_TITLE, &bstrTitle);
|
|
SetHeaderTitle(bstrTitle);
|
|
|
|
CComBSTR bstrSubTitle;
|
|
LoadStringFromResource(IDS_WIZ_PAGE2_SUBTITLE, &bstrSubTitle);
|
|
SetHeaderSubTitle(bstrSubTitle);
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage2::OnSetActive()
|
|
{
|
|
::PropSheet_SetWizButtons(GetParent(), PSWIZB_BACK | PSWIZB_NEXT);
|
|
|
|
if (DFS_TYPE_UNASSIGNED == m_lpWizInfo->DfsType)
|
|
{
|
|
CheckRadioButton(IDC_RADIO_FTDFSROOT, IDC_RADIO_STANDALONE_DFSROOT, IDC_RADIO_FTDFSROOT);
|
|
m_lpWizInfo->DfsType = DFS_TYPE_FTDFS;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage2::OnWizardNext()
|
|
{
|
|
m_lpWizInfo->DfsType = (IsDlgButtonChecked(IDC_RADIO_FTDFSROOT) ? DFS_TYPE_FTDFS : DFS_TYPE_STANDALONE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage2::OnWizardBack()
|
|
{
|
|
m_lpWizInfo->DfsType = DFS_TYPE_UNASSIGNED; // Reset the dfsroot type
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// CCreateDfsRootWizPage3: Domain selection
|
|
CCreateDfsRootWizPage3::CCreateDfsRootWizPage3(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
|
|
: CQWizardPageImpl<CCreateDfsRootWizPage3>(true),
|
|
m_lpWizInfo(i_lpWizInfo)
|
|
{
|
|
CComBSTR bstrTitle;
|
|
LoadStringFromResource(IDS_WIZ_PAGE3_TITLE, &bstrTitle);
|
|
SetHeaderTitle(bstrTitle);
|
|
|
|
CComBSTR bstrSubTitle;
|
|
LoadStringFromResource(IDS_WIZ_PAGE3_SUBTITLE, &bstrSubTitle);
|
|
SetHeaderSubTitle(bstrSubTitle);
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage3::OnSetActive()
|
|
{
|
|
// Skip this page for standalone dfs roots
|
|
if (DFS_TYPE_STANDALONE == m_lpWizInfo->DfsType)
|
|
return FALSE;
|
|
|
|
CWaitCursor WaitCursor;
|
|
|
|
SetDefaultValues();
|
|
|
|
::PropSheet_SetWizButtons(GetParent(), PSWIZB_BACK | PSWIZB_NEXT);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
HRESULT
|
|
CCreateDfsRootWizPage3::SetDefaultValues()
|
|
{
|
|
if (NULL == m_lpWizInfo->bstrSelectedDomain)
|
|
{
|
|
// Page is displayed for the first time, Set domain to current domain
|
|
CComBSTR bstrDomain;
|
|
HRESULT hr = GetServerInfo(NULL, &bstrDomain);
|
|
|
|
if (S_OK == hr && S_OK == Is50Domain(bstrDomain))
|
|
{
|
|
m_lpWizInfo->bstrSelectedDomain = bstrDomain.Detach();
|
|
}
|
|
}
|
|
|
|
SetDlgItemText(IDC_EDIT_SELECTED_DOMAIN,
|
|
m_lpWizInfo->bstrSelectedDomain ? m_lpWizInfo->bstrSelectedDomain : _T(""));
|
|
|
|
// select the matching item in the listbox
|
|
HWND hwndList = GetDlgItem(IDC_LIST_DOMAINS);
|
|
if ( ListView_GetItemCount(hwndList) > 0)
|
|
{
|
|
int nIndex = -1;
|
|
if (m_lpWizInfo->bstrSelectedDomain)
|
|
{
|
|
TCHAR szText[DNS_MAX_NAME_BUFFER_LENGTH];
|
|
while (-1 != (nIndex = ListView_GetNextItem(hwndList, nIndex, LVNI_ALL)))
|
|
{
|
|
ListView_GetItemText(hwndList, nIndex, 0, szText, DNS_MAX_NAME_BUFFER_LENGTH);
|
|
if (!lstrcmpi(m_lpWizInfo->bstrSelectedDomain, szText))
|
|
{
|
|
ListView_SetItemState(hwndList, nIndex, LVIS_SELECTED | LVIS_FOCUSED, 0xffffffff);
|
|
ListView_Update(hwndList, nIndex);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (-1 == nIndex)
|
|
{
|
|
ListView_SetItemState(hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, 0xffffffff);
|
|
ListView_Update(hwndList, 0);
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage3::OnWizardNext()
|
|
{
|
|
CWaitCursor WaitCursor;
|
|
|
|
DWORD dwTextLength = 0;
|
|
CComBSTR bstrCurrentText;
|
|
HRESULT hr = GetInputText(GetDlgItem(IDC_EDIT_SELECTED_DOMAIN), &bstrCurrentText, &dwTextLength);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBoxForHR(hr);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_DOMAIN));
|
|
return FALSE;
|
|
} else if (0 == dwTextLength)
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_EMPTY_FIELD);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_DOMAIN));
|
|
return FALSE;
|
|
}
|
|
|
|
CComBSTR bstrDnsDomain;
|
|
hr = Is50Domain(bstrCurrentText, &bstrDnsDomain);
|
|
if (S_OK != hr)
|
|
{ // Error message on incorrect domain.
|
|
DisplayMessageBox(::GetActiveWindow(), MB_OK, hr, IDS_MSG_INCORRECT_DOMAIN, bstrCurrentText);
|
|
return FALSE;
|
|
}
|
|
|
|
SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSelectedDomain);
|
|
|
|
m_lpWizInfo->bstrSelectedDomain = bstrDnsDomain.Detach();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage3::OnWizardBack()
|
|
{
|
|
SetDlgItemText(IDC_EDIT_SELECTED_DOMAIN, _T("")); // Set edit box to empty
|
|
SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSelectedDomain);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT
|
|
CCreateDfsRootWizPage3::OnNotify(
|
|
IN UINT i_uMsg,
|
|
IN WPARAM i_wParam,
|
|
IN LPARAM i_lParam,
|
|
IN OUT BOOL& io_bHandled
|
|
)
|
|
{
|
|
io_bHandled = FALSE; // So that the base class gets this notify too
|
|
|
|
NMHDR* pNMHDR = (NMHDR*)i_lParam;
|
|
if (!pNMHDR || IDC_LIST_DOMAINS != pNMHDR->idFrom) // We need to handle notifies only to the LV
|
|
return TRUE;
|
|
|
|
switch(pNMHDR->code)
|
|
{
|
|
case LVN_ITEMCHANGED:
|
|
case NM_CLICK:
|
|
{
|
|
OnItemChanged(((NM_LISTVIEW *)i_lParam)->iItem);
|
|
return 0; // Should be returning 0
|
|
}
|
|
case NM_DBLCLK: // Double click event
|
|
{
|
|
OnItemChanged(((NM_LISTVIEW *)i_lParam)->iItem);
|
|
if (0 <= ((NM_LISTVIEW *)i_lParam)->iItem)
|
|
::PropSheet_PressButton(GetParent(), PSBTN_NEXT);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage3::OnItemChanged(IN INT i_iItem)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handles item change notify. Change the edit box content to the current LV
|
|
selection
|
|
|
|
Arguments:
|
|
|
|
i_iItem - Selected Item number of the LV.
|
|
|
|
--*/
|
|
{
|
|
CComBSTR bstrDomain;
|
|
HRESULT hr = GetListViewItemText(GetDlgItem(IDC_LIST_DOMAINS), i_iItem, &bstrDomain);
|
|
if ((S_OK == hr) && (BSTR)bstrDomain)
|
|
SetDlgItemText(IDC_EDIT_SELECTED_DOMAIN, bstrDomain);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT
|
|
CCreateDfsRootWizPage3::OnInitDialog(
|
|
IN UINT i_uMsg,
|
|
IN WPARAM i_wParam,
|
|
IN LPARAM i_lParam,
|
|
IN OUT BOOL& io_bHandled
|
|
)
|
|
{
|
|
CWaitCursor WaitCursor;
|
|
|
|
::SendMessage(GetDlgItem(IDC_EDIT_SELECTED_DOMAIN), EM_LIMITTEXT, DNSNAMELIMIT, 0);
|
|
|
|
HIMAGELIST hImageList = NULL;
|
|
int nIconIDs[] = {IDI_16x16_DOMAIN};
|
|
HRESULT hr = CreateSmallImageList(
|
|
_Module.GetResourceInstance(),
|
|
nIconIDs,
|
|
sizeof(nIconIDs) / sizeof(nIconIDs[0]),
|
|
&hImageList);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// The current image list will be destroyed when the list-view control
|
|
// is destroyed unless the LVS_SHAREIMAGELISTS style is set. If you
|
|
// use this message to replace one image list with another, your
|
|
// application must explicitly destroy all image lists other than
|
|
// the current one.
|
|
HWND hwndDomainList = GetDlgItem(IDC_LIST_DOMAINS);
|
|
ListView_SetImageList(hwndDomainList, hImageList, LVSIL_SMALL);
|
|
|
|
AddDomainsToList(hwndDomainList); // Add domains to the list view
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
HRESULT
|
|
CCreateDfsRootWizPage3::AddDomainsToList(IN HWND i_hImageList)
|
|
{
|
|
RETURN_INVALIDARG_IF_NULL(i_hImageList);
|
|
|
|
NETNAMELIST ListOf50Domains;
|
|
HRESULT hr = Get50Domains(&ListOf50Domains); // Get all the domains
|
|
if (S_OK != hr)
|
|
return hr;
|
|
|
|
// Add domains to the LV
|
|
for(NETNAMELIST::iterator i = ListOf50Domains.begin(); i != ListOf50Domains.end(); i++)
|
|
{
|
|
if ((*i)->bstrNetName)
|
|
InsertIntoListView(i_hImageList, (*i)->bstrNetName);
|
|
}
|
|
|
|
if (!ListOf50Domains.empty())
|
|
{
|
|
for (NETNAMELIST::iterator i = ListOf50Domains.begin(); i != ListOf50Domains.end(); i++)
|
|
{
|
|
delete (*i);
|
|
}
|
|
|
|
ListOf50Domains.erase(ListOf50Domains.begin(), ListOf50Domains.end());
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// CCreateDfsRootWizPage4: Server selection
|
|
CCreateDfsRootWizPage4::CCreateDfsRootWizPage4(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
|
|
: CQWizardPageImpl<CCreateDfsRootWizPage4>(true),
|
|
m_lpWizInfo(i_lpWizInfo),
|
|
m_cfDsObjectNames(NULL)
|
|
{
|
|
CComBSTR bstrTitle;
|
|
LoadStringFromResource(IDS_WIZ_PAGE4_TITLE, &bstrTitle);
|
|
SetHeaderTitle(bstrTitle);
|
|
|
|
CComBSTR bstrSubTitle;
|
|
LoadStringFromResource(IDS_WIZ_PAGE4_SUBTITLE, &bstrSubTitle);
|
|
SetHeaderSubTitle(bstrSubTitle);
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage4::OnSetActive()
|
|
{
|
|
CWaitCursor WaitCursor;
|
|
|
|
::SendMessage(GetDlgItem(IDC_EDIT_SELECTED_SERVER), EM_LIMITTEXT, DNSNAMELIMIT, 0);
|
|
|
|
if (DFS_TYPE_STANDALONE == m_lpWizInfo->DfsType)
|
|
{
|
|
// Standalone Setup, set domain to current domain.
|
|
CComBSTR bstrDomain;
|
|
HRESULT hr = GetServerInfo(NULL, &bstrDomain);
|
|
if (S_OK == hr)
|
|
m_lpWizInfo->bstrSelectedDomain = bstrDomain.Detach();
|
|
}
|
|
|
|
// Is50Domain will call DsGetDCName which is too slow in case of standalone server.
|
|
// To improve the performance, we should always enable the Browse button, and report
|
|
// error if user clicks the button.
|
|
::EnableWindow(GetDlgItem(IDCSERVERS_BROWSE), m_lpWizInfo->bstrSelectedDomain && *m_lpWizInfo->bstrSelectedDomain);
|
|
|
|
SetDlgItemText(IDC_EDIT_SELECTED_SERVER, m_lpWizInfo->bstrSelectedServer ? m_lpWizInfo->bstrSelectedServer : _T(""));
|
|
|
|
if (m_lpWizInfo->bRootReplica) // If a root replica is being added
|
|
{
|
|
::PropSheet_SetWizButtons(GetParent(), PSWIZB_NEXT);
|
|
::ShowWindow(GetDlgItem(IDC_SERVER_SHARE_LABEL), SW_NORMAL);
|
|
::ShowWindow(GetDlgItem(IDC_SERVER_SHARE), SW_NORMAL);
|
|
SetDlgItemText(IDC_SERVER_SHARE, m_lpWizInfo->bstrDfsRootName);
|
|
} else
|
|
::PropSheet_SetWizButtons(GetParent(), PSWIZB_BACK | PSWIZB_NEXT);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage4::OnWizardNext()
|
|
{
|
|
CWaitCursor WaitCursor;
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD dwTextLength = 0;
|
|
CComBSTR bstrCurrentText;
|
|
hr = GetInputText(GetDlgItem(IDC_EDIT_SELECTED_SERVER), &bstrCurrentText, &dwTextLength);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBoxForHR(hr);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
|
|
return FALSE;
|
|
} else if (0 == dwTextLength)
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_EMPTY_FIELD);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
|
|
return FALSE;
|
|
}
|
|
|
|
// I_NetNameValidate will fail with \\server,
|
|
// hence, removing the whackwhack when passing it to this validation api.
|
|
PTSTR p = bstrCurrentText;
|
|
if (!mylstrncmpi(p, _T("\\\\"), 2))
|
|
p += 2;
|
|
|
|
if (I_NetNameValidate(0, p, NAMETYPE_COMPUTER, 0))
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_INVALID_SERVER_NAME, bstrCurrentText);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
|
|
return FALSE;
|
|
}
|
|
|
|
// remove the ending dot
|
|
if (bstrCurrentText[dwTextLength - 1] == _T('.'))
|
|
bstrCurrentText[dwTextLength - 1] = _T('\0');
|
|
|
|
CComBSTR bstrComputerName;
|
|
hr = CheckUserEnteredValues(bstrCurrentText, &bstrComputerName);
|
|
if (S_OK != hr) // If server is not a valid one. The above function has already displayed the message
|
|
{
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
|
|
return FALSE;
|
|
}
|
|
|
|
if (m_lpWizInfo->bRootReplica)
|
|
{
|
|
hr = CheckShare(bstrCurrentText, m_lpWizInfo->bstrDfsRootName, &m_lpWizInfo->bShareExists);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBoxForHR(hr);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
|
|
return FALSE;
|
|
} else if (S_FALSE == hr)
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_ROOTSHARE_NOGOOD, m_lpWizInfo->bstrDfsRootName);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
|
|
return FALSE;
|
|
}
|
|
|
|
if (m_lpWizInfo->bPostW2KVersion && m_lpWizInfo->bShareExists && !CheckReparsePoint(bstrCurrentText, m_lpWizInfo->bstrDfsRootName))
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_ROOTSHARE_NOTNTFS5, m_lpWizInfo->bstrDfsRootName);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSelectedServer);
|
|
m_lpWizInfo->bstrSelectedServer = bstrComputerName.Detach();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// S_OK: Yes, it belongs to the selected domain
|
|
// S_FALSE: No, it does not belong to the selected domain
|
|
// hr: other errors
|
|
HRESULT
|
|
CCreateDfsRootWizPage4::IsServerInDomain(IN LPCTSTR lpszServer)
|
|
{
|
|
if (DFS_TYPE_FTDFS != m_lpWizInfo->DfsType)
|
|
return S_OK;
|
|
|
|
CComBSTR bstrActualDomain;
|
|
HRESULT hr = GetServerInfo((LPTSTR)lpszServer, &bstrActualDomain);
|
|
if (S_OK == hr)
|
|
{
|
|
if (!lstrcmpi(bstrActualDomain, m_lpWizInfo->bstrSelectedDomain))
|
|
hr = S_OK;
|
|
else
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT IsHostingDfsRootEx(IN BSTR i_bstrServer, IN BSTR i_bstrRootEntryPath)
|
|
{
|
|
if (!i_bstrServer || !*i_bstrServer || !i_bstrRootEntryPath || !*i_bstrRootEntryPath)
|
|
return E_INVALIDARG;
|
|
|
|
int len = lstrlen(i_bstrServer);
|
|
|
|
DFS_INFO_3* pDfsInfo = NULL;
|
|
NET_API_STATUS dwRet = NetDfsGetInfo(
|
|
i_bstrRootEntryPath,
|
|
NULL,
|
|
NULL,
|
|
3,
|
|
(LPBYTE *)&pDfsInfo);
|
|
|
|
dfsDebugOut((_T("NetDfsGetInfo entry=%s, level 3 for IsHostingDfsRootEx, nRet=%d\n"),
|
|
i_bstrRootEntryPath, dwRet));
|
|
|
|
if (ERROR_NO_MORE_ITEMS == dwRet || ERROR_NOT_FOUND == dwRet)
|
|
return S_FALSE;
|
|
|
|
HRESULT hr = S_FALSE;
|
|
if (NERR_Success == dwRet)
|
|
{
|
|
if (pDfsInfo->NumberOfStorages > 0)
|
|
{
|
|
LPDFS_STORAGE_INFO pStorage = pDfsInfo->Storage;
|
|
for (DWORD i = 0; i < pDfsInfo->NumberOfStorages; i++)
|
|
{
|
|
//
|
|
// We're doing simple comparison here.
|
|
// In case of one server is IP address or a different name of the same machine,
|
|
// we'll just leave it to Dfs API.
|
|
//
|
|
int lenServer = lstrlen(pStorage[i].ServerName);
|
|
if (lenServer == len)
|
|
{
|
|
if (!lstrcmpi(pStorage[i].ServerName, i_bstrServer))
|
|
{
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
} else
|
|
{
|
|
//
|
|
// consider one is Netbios, the other is DNS
|
|
//
|
|
PTSTR pszLong = NULL;
|
|
PTSTR pszShort = NULL;
|
|
int minLen = 0;
|
|
|
|
if (lenServer > len)
|
|
{
|
|
pszLong = pStorage[i].ServerName;
|
|
pszShort = i_bstrServer;
|
|
minLen = len;
|
|
} else
|
|
{
|
|
pszShort = pStorage[i].ServerName;
|
|
pszLong = i_bstrServer;
|
|
minLen = lenServer;
|
|
}
|
|
|
|
if (!mylstrncmpi(pszLong, pszShort, minLen) && pszLong[minLen] == _T('.'))
|
|
{
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
NetApiBufferFree(pDfsInfo);
|
|
} else
|
|
{
|
|
hr = HRESULT_FROM_WIN32(dwRet);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CCreateDfsRootWizPage4::CheckUserEnteredValues(
|
|
IN LPCTSTR i_szMachineName,
|
|
OUT BSTR* o_pbstrComputerName
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Checks the value that user has given for this page.
|
|
This is done typically on "Next" key being pressed.
|
|
Check, if the machine name is a server that is NT 5.0, belongs to
|
|
the domain previously selected and is running dfs service.
|
|
|
|
Arguments:
|
|
|
|
i_szMachineName - Machine name given by the user
|
|
--*/
|
|
{
|
|
RETURN_INVALIDARG_IF_NULL(i_szMachineName);
|
|
RETURN_INVALIDARG_IF_NULL(o_pbstrComputerName);
|
|
|
|
HRESULT hr = S_OK;
|
|
BOOL bPostNTServer = FALSE;
|
|
LONG lMajorVer = 0;
|
|
LONG lMinorVer = 0;
|
|
|
|
SERVER_INFO_101* pServerInfo = NULL;
|
|
DWORD dwRet = NetServerGetInfo((LPTSTR)i_szMachineName, 101, (LPBYTE*)&pServerInfo);
|
|
if (NERR_Success == dwRet)
|
|
{
|
|
lMajorVer = pServerInfo->sv101_version_major & MAJOR_VERSION_MASK;
|
|
lMinorVer = pServerInfo->sv101_version_minor;
|
|
|
|
bPostNTServer = (pServerInfo->sv101_type & SV_TYPE_NT) &&
|
|
lMajorVer >= 5 &&
|
|
((pServerInfo->sv101_type & SV_TYPE_DOMAIN_CTRL) ||
|
|
(pServerInfo->sv101_type & SV_TYPE_DOMAIN_BAKCTRL) ||
|
|
(pServerInfo->sv101_type & SV_TYPE_SERVER_NT));
|
|
|
|
NetApiBufferFree(pServerInfo);
|
|
} else
|
|
{
|
|
hr = HRESULT_FROM_WIN32(dwRet);
|
|
DisplayMessageBox(::GetActiveWindow(), MB_OK, hr, IDS_MSG_INCORRECT_SERVER, i_szMachineName);
|
|
return hr;
|
|
}
|
|
|
|
if (!bPostNTServer)
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_NOT_50);
|
|
return S_FALSE;
|
|
}
|
|
/* LinanT 3/19/99: remove "check registry, if set, get dns server"
|
|
|
|
CComBSTR bstrDnsComputerName;
|
|
(void)GetServerInfo(
|
|
(LPTSTR)i_szMachineName,
|
|
NULL, // domain
|
|
NULL, // Netbios
|
|
NULL, // ValidDSObject
|
|
&bstrDnsComputerName, // Dns
|
|
NULL, // Guid
|
|
NULL, // FQDN
|
|
NULL, // lMajorVer
|
|
NULL //lMinorVer
|
|
);
|
|
*o_pbstrComputerName = SysAllocString(bstrDnsComputerName ? bstrDnsComputerName : bstrNetbiosComputerName);
|
|
*/
|
|
if ( !mylstrncmpi(i_szMachineName, _T("\\\\"), 2) )
|
|
*o_pbstrComputerName = SysAllocString(i_szMachineName + 2);
|
|
else
|
|
*o_pbstrComputerName = SysAllocString(i_szMachineName);
|
|
if (!*o_pbstrComputerName)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
DisplayMessageBoxForHR(hr);
|
|
return hr;
|
|
}
|
|
|
|
/*
|
|
//
|
|
// don't check, let DFS API handle it.
|
|
// This way, we have space to handle new DFS service if introduced in the future.
|
|
//
|
|
hr = IsServerRunningDfs(*o_pbstrComputerName);
|
|
if(S_OK != hr)
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_NOT_RUNNING_DFS, *o_pbstrComputerName);
|
|
return hr;
|
|
}
|
|
*/
|
|
|
|
hr = IsServerInDomain(*o_pbstrComputerName);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBox(::GetActiveWindow(), MB_OK, hr, IDS_MSG_INCORRECT_SERVER, *o_pbstrComputerName);
|
|
return hr;
|
|
} else if (S_FALSE == hr)
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_SERVER_FROM_ANOTHER_DOMAIN, *o_pbstrComputerName);
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// for W2K, check if server already has a dfs root set up
|
|
// do not check for Whistler (in which case the lMinorVer == 1).
|
|
//
|
|
if (lMajorVer == 5 && lMinorVer < 1 && S_OK == IsHostingDfsRoot(*o_pbstrComputerName))
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_WIZ_DFS_ALREADY_PRESENT,NULL);
|
|
return S_FALSE;
|
|
}
|
|
|
|
m_lpWizInfo->bPostW2KVersion = (lMajorVer >= 5 && lMinorVer >= 1);
|
|
|
|
//
|
|
// for postW2K in case of newRootTarget, check if server already host for this dfs root
|
|
//
|
|
if (m_lpWizInfo->bPostW2KVersion && m_lpWizInfo->bRootReplica)
|
|
{
|
|
CComBSTR bstrRootEntryPath = _T("\\\\");
|
|
bstrRootEntryPath += m_lpWizInfo->bstrSelectedDomain;
|
|
bstrRootEntryPath += _T("\\");
|
|
bstrRootEntryPath += m_lpWizInfo->bstrDfsRootName;
|
|
if (S_OK == IsHostingDfsRootEx(*o_pbstrComputerName, bstrRootEntryPath))
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_WIZ_ALREADY_ROOTTARGET,NULL);
|
|
return S_FALSE;
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage4::OnWizardBack()
|
|
{
|
|
SetDlgItemText(IDC_EDIT_SELECTED_SERVER, _T("")); // Set edit box to empty
|
|
SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSelectedServer);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
HRESULT
|
|
GetComputerDnsNameFromLDAP(
|
|
IN LPCTSTR lpszLDAPPath,
|
|
OUT BSTR *o_pbstrName
|
|
)
|
|
{
|
|
CComPtr<IADs> spIADs;
|
|
HRESULT hr = ADsGetObject(const_cast<LPTSTR>(lpszLDAPPath), IID_IADs, (void**)&spIADs);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
VARIANT var;
|
|
VariantInit(&var);
|
|
|
|
hr = spIADs->Get(_T("dnsHostName"), &var);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CComBSTR bstrComputer = V_BSTR(&var);
|
|
*o_pbstrName = bstrComputer.Detach();
|
|
|
|
VariantClear(&var);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
GetComputerNetbiosNameFromLDAP(
|
|
IN LPCTSTR lpszLDAPPath,
|
|
OUT BSTR *o_pbstrName
|
|
)
|
|
{
|
|
CComPtr<IADsPathname> spIAdsPath;
|
|
HRESULT hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER, IID_IADsPathname, (void**)&spIAdsPath);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = spIAdsPath->Set(const_cast<LPTSTR>(lpszLDAPPath), ADS_SETTYPE_FULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = spIAdsPath->SetDisplayType(ADS_DISPLAY_VALUE_ONLY);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Get first Component which is computer's Netbios name.
|
|
CComBSTR bstrComputer;
|
|
hr = spIAdsPath->GetElement(0, &bstrComputer);
|
|
if (SUCCEEDED(hr))
|
|
*o_pbstrName = bstrComputer.Detach();
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage4::OnBrowse(
|
|
IN WORD wNotifyCode,
|
|
IN WORD wID,
|
|
IN HWND hWndCtl,
|
|
IN BOOL& bHandled
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handles the mouse click of the Browse button.
|
|
Display the Computer Query Dialog.
|
|
|
|
--*/
|
|
{
|
|
CWaitCursor WaitCursor;
|
|
DSQUERYINITPARAMS dqip;
|
|
OPENQUERYWINDOW oqw;
|
|
CComPtr<ICommonQuery> pCommonQuery;
|
|
CComPtr<IDataObject> pDataObject;
|
|
HRESULT hr = S_OK;
|
|
|
|
do {
|
|
CComBSTR bstrDCName;
|
|
CComBSTR bstrLDAPDomainPath;
|
|
hr = GetDomainInfo(
|
|
m_lpWizInfo->bstrSelectedDomain,
|
|
&bstrDCName,
|
|
NULL, // domainDns
|
|
NULL, // domainDN
|
|
&bstrLDAPDomainPath);
|
|
if (FAILED(hr))
|
|
break;
|
|
|
|
dfsDebugOut((_T("OnBrowse bstrDCName=%s, bstrLDAPDomainPath=%s\n"),
|
|
bstrDCName, bstrLDAPDomainPath));
|
|
|
|
hr = CoCreateInstance(CLSID_CommonQuery, NULL, CLSCTX_INPROC_SERVER, IID_ICommonQuery, (void **)&pCommonQuery);
|
|
if (FAILED(hr)) break;
|
|
|
|
// Parameters for Query Dialog.
|
|
ZeroMemory(&dqip, sizeof(dqip));
|
|
dqip.cbStruct = sizeof(dqip);
|
|
dqip.dwFlags = DSQPF_HASCREDENTIALS;
|
|
dqip.pDefaultScope = bstrLDAPDomainPath;
|
|
dqip.pServer = bstrDCName;
|
|
|
|
ZeroMemory(&oqw, sizeof(oqw));
|
|
oqw.cbStruct = sizeof(oqw);
|
|
oqw.clsidHandler = CLSID_DsQuery; // Handler is Ds Query.
|
|
oqw.pHandlerParameters = &dqip;
|
|
oqw.clsidDefaultForm = CLSID_DsFindComputer; // Show Find Computers Query Dialog
|
|
oqw.dwFlags = OQWF_OKCANCEL |
|
|
OQWF_SINGLESELECT |
|
|
OQWF_DEFAULTFORM |
|
|
OQWF_REMOVEFORMS |
|
|
OQWF_ISSUEONOPEN |
|
|
OQWF_REMOVESCOPES ;
|
|
|
|
hr = pCommonQuery->OpenQueryWindow(m_hWnd, &oqw, &pDataObject);
|
|
if (S_OK != hr) break;
|
|
|
|
if (NULL == m_cfDsObjectNames )
|
|
{
|
|
m_cfDsObjectNames = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DSOBJECTNAMES);
|
|
}
|
|
|
|
FORMATETC fmte = {
|
|
CF_HDROP,
|
|
NULL,
|
|
DVASPECT_CONTENT,
|
|
-1,
|
|
TYMED_HGLOBAL
|
|
};
|
|
|
|
STGMEDIUM medium = {
|
|
TYMED_NULL,
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
fmte.cfFormat = m_cfDsObjectNames;
|
|
|
|
hr = pDataObject->GetData(&fmte, &medium);
|
|
if (FAILED(hr)) break;
|
|
|
|
LPDSOBJECTNAMES pDsObjects = (LPDSOBJECTNAMES)medium.hGlobal;
|
|
if (!pDsObjects || pDsObjects->cItems <= 0)
|
|
{
|
|
hr = S_FALSE;
|
|
break;
|
|
}
|
|
|
|
// retrieve the full LDAP path to the computer
|
|
LPTSTR lpszTemp =
|
|
(LPTSTR)(((LPBYTE)pDsObjects)+(pDsObjects->aObjects[0].offsetName));
|
|
|
|
// try to retrieve its Dns name
|
|
CComBSTR bstrComputer;
|
|
hr = GetComputerDnsNameFromLDAP(lpszTemp, &bstrComputer);
|
|
|
|
// if failed, try to retrieve its Netbios name
|
|
if (FAILED(hr))
|
|
hr = GetComputerNetbiosNameFromLDAP(lpszTemp, &bstrComputer);
|
|
|
|
if (FAILED(hr)) break;
|
|
|
|
SetDlgItemText(IDC_EDIT_SELECTED_SERVER, bstrComputer);
|
|
|
|
} while (0);
|
|
|
|
if (FAILED(hr))
|
|
DisplayMessageBox(::GetActiveWindow(), MB_OK, hr, IDS_FAILED_TO_BROWSE_SERVER, m_lpWizInfo->bstrSelectedDomain);
|
|
|
|
return (S_OK == hr);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// CCreateDfsRootWizPage5: Share selection
|
|
CCreateDfsRootWizPage5::CCreateDfsRootWizPage5(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
|
|
: CQWizardPageImpl<CCreateDfsRootWizPage5>(true),
|
|
m_lpWizInfo(i_lpWizInfo)
|
|
{
|
|
CComBSTR bstrTitle;
|
|
LoadStringFromResource(IDS_WIZ_PAGE5_TITLE, &bstrTitle);
|
|
SetHeaderTitle(bstrTitle);
|
|
|
|
CComBSTR bstrSubTitle;
|
|
LoadStringFromResource(IDS_WIZ_PAGE5_SUBTITLE, &bstrSubTitle);
|
|
SetHeaderSubTitle(bstrSubTitle);
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage5::OnSetActive()
|
|
{
|
|
if (m_lpWizInfo->bShareExists)
|
|
return FALSE; // root share exists, skip this page
|
|
|
|
::PropSheet_SetWizButtons(GetParent(), PSWIZB_BACK | PSWIZB_NEXT);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage5::OnWizardNext()
|
|
{
|
|
CWaitCursor WaitCursor;
|
|
CComBSTR bstrCurrentText;
|
|
DWORD dwTextLength = 0;
|
|
|
|
// get share path
|
|
HRESULT hr = GetInputText(GetDlgItem(IDC_EDIT_SHARE_PATH), &bstrCurrentText, &dwTextLength);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBoxForHR(hr);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SHARE_PATH));
|
|
return FALSE;
|
|
} else if (0 == dwTextLength)
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_EMPTY_FIELD);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SHARE_PATH));
|
|
return FALSE;
|
|
}
|
|
|
|
// Removing the ending backslash, otherwise, GetFileAttribute/NetShareAdd will fail.
|
|
TCHAR *p = bstrCurrentText + _tcslen(bstrCurrentText) - 1;
|
|
if (IsValidLocalAbsolutePath(bstrCurrentText) && *p == _T('\\') && *(p-1) != _T(':'))
|
|
*p = _T('\0');
|
|
|
|
if (S_OK != ValidateFolderPath(m_lpWizInfo->bstrSelectedServer, bstrCurrentText))
|
|
{
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SHARE_PATH));
|
|
return FALSE;
|
|
}
|
|
SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSharePath);
|
|
m_lpWizInfo->bstrSharePath = bstrCurrentText.Detach();
|
|
|
|
// Create the share.
|
|
hr = CreateShare(
|
|
m_lpWizInfo->bstrSelectedServer,
|
|
m_lpWizInfo->bstrDfsRootName,
|
|
_T(""), // Blank Comment
|
|
m_lpWizInfo->bstrSharePath
|
|
);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBoxForHR(hr);
|
|
return FALSE;
|
|
}
|
|
|
|
if (m_lpWizInfo->bPostW2KVersion && !CheckReparsePoint(m_lpWizInfo->bstrSelectedServer, m_lpWizInfo->bstrDfsRootName))
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_ROOTSHARE_NOTNTFS5, m_lpWizInfo->bstrDfsRootName);
|
|
NetShareDel(m_lpWizInfo->bstrSelectedServer, m_lpWizInfo->bstrDfsRootName, 0);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_SHARE_PATH));
|
|
return FALSE;
|
|
}
|
|
|
|
SetDlgItemText(IDC_EDIT_SHARE_PATH, _T(""));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage5::OnWizardBack()
|
|
{
|
|
SetDlgItemText(IDC_EDIT_SHARE_PATH, _T(""));
|
|
SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSharePath);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT CCreateDfsRootWizPage5::OnInitDialog(
|
|
IN UINT i_uMsg,
|
|
IN WPARAM i_wParam,
|
|
IN LPARAM i_lParam,
|
|
IN OUT BOOL& io_bHandled
|
|
)
|
|
{
|
|
::SendMessage(GetDlgItem(IDC_EDIT_SHARE_PATH), EM_LIMITTEXT, _MAX_DIR - 1, 0);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage5::OnBrowse(
|
|
IN WORD wNotifyCode,
|
|
IN WORD wID,
|
|
IN HWND hWndCtl,
|
|
IN BOOL& bHandled
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handles the mouse click of the Browse button.
|
|
Display the folder Dialog.
|
|
|
|
--*/
|
|
{
|
|
CWaitCursor WaitCursor;
|
|
|
|
BOOL bLocalComputer = (S_OK == IsComputerLocal(m_lpWizInfo->bstrSelectedServer));
|
|
|
|
TCHAR szDir[MAX_PATH * 2] = _T(""); // double the size in case the remote path is itself close to MAX_PATH
|
|
OpenBrowseDialog(m_hWnd, IDS_BROWSE_FOLDER, bLocalComputer, m_lpWizInfo->bstrSelectedServer, szDir);
|
|
|
|
CComBSTR bstrPath;
|
|
if (szDir[0])
|
|
{
|
|
if (bLocalComputer)
|
|
bstrPath = szDir;
|
|
else
|
|
{ // szDir is in the form of \\server\share or \\server\share\path....
|
|
LPTSTR pShare = _tcschr(szDir + 2, _T('\\'));
|
|
pShare++;
|
|
LPTSTR pLeftOver = _tcschr(pShare, _T('\\'));
|
|
if (pLeftOver && *pLeftOver)
|
|
*pLeftOver++ = _T('\0');
|
|
|
|
SHARE_INFO_2 *psi = NULL;
|
|
if (NERR_Success == NetShareGetInfo(m_lpWizInfo->bstrSelectedServer, pShare, 2, (LPBYTE *)&psi))
|
|
{
|
|
bstrPath = psi->shi2_path;
|
|
if (pLeftOver && *pLeftOver)
|
|
{
|
|
if (_T('\\') != bstrPath[lstrlen(bstrPath) - 1])
|
|
bstrPath += _T("\\");
|
|
bstrPath += pLeftOver;
|
|
}
|
|
NetApiBufferFree(psi);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((BSTR)bstrPath && *bstrPath)
|
|
SetDlgItemText(IDC_EDIT_SHARE_PATH, bstrPath);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// CCreateDfsRootWizPage6: DfsRoot name selection
|
|
CCreateDfsRootWizPage6::CCreateDfsRootWizPage6(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
|
|
: CQWizardPageImpl<CCreateDfsRootWizPage6>(true),
|
|
m_lpWizInfo(i_lpWizInfo)
|
|
{
|
|
CComBSTR bstrTitle;
|
|
LoadStringFromResource(IDS_WIZ_PAGE6_TITLE, &bstrTitle);
|
|
SetHeaderTitle(bstrTitle);
|
|
|
|
CComBSTR bstrSubTitle;
|
|
LoadStringFromResource(IDS_WIZ_PAGE6_SUBTITLE, &bstrSubTitle);
|
|
SetHeaderSubTitle(bstrSubTitle);
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage6::OnSetActive()
|
|
{
|
|
if (m_lpWizInfo->bRootReplica)
|
|
return FALSE; // we skip this page in case of creating new root target
|
|
|
|
::SendMessage(GetDlgItem(IDC_EDIT_DFSROOT_NAME), EM_LIMITTEXT, MAX_RDN_KEY_SIZE, 0);
|
|
|
|
if (NULL != m_lpWizInfo->bstrDfsRootName) // Set the default dfsroot name
|
|
SetDlgItemText(IDC_EDIT_DFSROOT_NAME, m_lpWizInfo->bstrDfsRootName);
|
|
|
|
::SendMessage(GetDlgItem(IDC_EDIT_DFSROOT_COMMENT), EM_LIMITTEXT, MAXCOMMENTSZ, 0);
|
|
|
|
UpdateLabels(); // Change the labels
|
|
|
|
::PropSheet_SetWizButtons(GetParent(), PSWIZB_BACK | PSWIZB_NEXT);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
HRESULT
|
|
CCreateDfsRootWizPage6::UpdateLabels()
|
|
{
|
|
CComBSTR bstrDfsRootName;
|
|
DWORD dwTextLength = 0;
|
|
(void)GetInputText(GetDlgItem(IDC_EDIT_DFSROOT_NAME), &bstrDfsRootName, &dwTextLength);
|
|
SetDlgItemText(IDC_ROOT_SHARE, bstrDfsRootName);
|
|
|
|
CComBSTR bstrFullPath = _T("\\\\");
|
|
RETURN_OUTOFMEMORY_IF_NULL((BSTR)bstrFullPath);
|
|
if (DFS_TYPE_FTDFS == m_lpWizInfo->DfsType)
|
|
bstrFullPath += m_lpWizInfo->bstrSelectedDomain;
|
|
else
|
|
bstrFullPath += m_lpWizInfo->bstrSelectedServer;
|
|
RETURN_OUTOFMEMORY_IF_NULL((BSTR)bstrFullPath);
|
|
bstrFullPath += _T("\\");
|
|
RETURN_OUTOFMEMORY_IF_NULL((BSTR)bstrFullPath);
|
|
bstrFullPath += bstrDfsRootName;
|
|
RETURN_OUTOFMEMORY_IF_NULL((BSTR)bstrFullPath);
|
|
|
|
SetDlgItemText(IDC_TEXT_DFSROOT_PREFIX, bstrFullPath);
|
|
|
|
::SendMessage(GetDlgItem(IDC_TEXT_DFSROOT_PREFIX), EM_SETSEL, 0, (LPARAM)-1);
|
|
::SendMessage(GetDlgItem(IDC_TEXT_DFSROOT_PREFIX), EM_SETSEL, (WPARAM)-1, 0);
|
|
::SendMessage(GetDlgItem(IDC_TEXT_DFSROOT_PREFIX), EM_SCROLLCARET, 0, 0);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
LRESULT
|
|
CCreateDfsRootWizPage6::OnChangeDfsRoot(
|
|
WORD wNotifyCode,
|
|
WORD wID,
|
|
HWND hWndCtl,
|
|
BOOL& bHandled)
|
|
{
|
|
UpdateLabels();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage6::OnWizardNext(
|
|
)
|
|
{
|
|
CWaitCursor WaitCursor;
|
|
HRESULT hr = S_OK;
|
|
CComBSTR bstrCurrentText;
|
|
DWORD dwTextLength = 0;
|
|
|
|
// get dfsroot name
|
|
hr = GetInputText(GetDlgItem(IDC_EDIT_DFSROOT_NAME), &bstrCurrentText, &dwTextLength);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBoxForHR(hr);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
|
|
return FALSE;
|
|
} else if (0 == dwTextLength)
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_EMPTY_FIELD);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
|
|
return FALSE;
|
|
}
|
|
|
|
// See if the Dfs Name has illegal Characters.
|
|
if (_tcscspn(bstrCurrentText, _T("\\/@")) != _tcslen(bstrCurrentText) ||
|
|
(DFS_TYPE_FTDFS == m_lpWizInfo->DfsType && I_NetNameValidate(NULL, bstrCurrentText, NAMETYPE_SHARE, 0)) )
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_WIZ_BAD_DFS_NAME,NULL);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
|
|
return FALSE;
|
|
}
|
|
|
|
// domain DFS only: See if the Dfs Name exists.
|
|
if (DFS_TYPE_FTDFS == m_lpWizInfo->DfsType)
|
|
{
|
|
BOOL bRootAlreadyExist = FALSE;
|
|
NETNAMELIST DfsRootList;
|
|
if (S_OK == GetDomainDfsRoots(&DfsRootList, m_lpWizInfo->bstrSelectedDomain))
|
|
{
|
|
for (NETNAMELIST::iterator i = DfsRootList.begin(); i != DfsRootList.end(); i++)
|
|
{
|
|
if (!lstrcmpi((*i)->bstrNetName, bstrCurrentText))
|
|
{
|
|
bRootAlreadyExist = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
FreeNetNameList(&DfsRootList);
|
|
}
|
|
if (bRootAlreadyExist)
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_ROOT_ALREADY_EXISTS, bstrCurrentText);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
hr = CheckShare(m_lpWizInfo->bstrSelectedServer, bstrCurrentText, &m_lpWizInfo->bShareExists);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBoxForHR(hr);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
|
|
return FALSE;
|
|
} else if (S_FALSE == hr)
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_ROOTSHARE_NOGOOD, bstrCurrentText);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
|
|
return FALSE;
|
|
}
|
|
|
|
if (m_lpWizInfo->bPostW2KVersion && m_lpWizInfo->bShareExists && !CheckReparsePoint(m_lpWizInfo->bstrSelectedServer, bstrCurrentText))
|
|
{
|
|
DisplayMessageBoxWithOK(IDS_MSG_ROOTSHARE_NOTNTFS5, bstrCurrentText);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
|
|
return FALSE;
|
|
}
|
|
|
|
SAFE_SYSFREESTRING(&m_lpWizInfo->bstrDfsRootName);
|
|
m_lpWizInfo->bstrDfsRootName = bstrCurrentText.Detach();
|
|
|
|
// get dfsroot comment
|
|
hr = GetInputText(GetDlgItem(IDC_EDIT_DFSROOT_COMMENT), &bstrCurrentText, &dwTextLength);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBoxForHR(hr);
|
|
::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_COMMENT));
|
|
return FALSE;
|
|
}
|
|
SAFE_SYSFREESTRING(&m_lpWizInfo->bstrDfsRootComment);
|
|
m_lpWizInfo->bstrDfsRootComment = bstrCurrentText.Detach();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage6::OnWizardBack()
|
|
{
|
|
SAFE_SYSFREESTRING(&m_lpWizInfo->bstrDfsRootName);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// CCreateDfsRootWizPage7: Completion page
|
|
CCreateDfsRootWizPage7::CCreateDfsRootWizPage7(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
|
|
: CQWizardPageImpl<CCreateDfsRootWizPage7>(false),
|
|
m_lpWizInfo(i_lpWizInfo)
|
|
{
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage7::OnSetActive()
|
|
{
|
|
CWaitCursor wait;
|
|
|
|
CComBSTR bstrText;
|
|
if (DFS_TYPE_FTDFS == m_lpWizInfo->DfsType)
|
|
{
|
|
FormatMessageString(&bstrText, 0, IDS_DFSWIZ_TEXT_FTDFS,
|
|
m_lpWizInfo->bstrSelectedDomain,
|
|
m_lpWizInfo->bstrSelectedServer,
|
|
m_lpWizInfo->bstrDfsRootName,
|
|
m_lpWizInfo->bstrDfsRootName);
|
|
} else
|
|
{
|
|
FormatMessageString(&bstrText, 0, IDS_DFSWIZ_TEXT_SADFS,
|
|
m_lpWizInfo->bstrSelectedServer,
|
|
m_lpWizInfo->bstrDfsRootName,
|
|
m_lpWizInfo->bstrDfsRootName);
|
|
}
|
|
|
|
SetDlgItemText(IDC_DFSWIZ_TEXT, bstrText);
|
|
|
|
::PropSheet_SetWizButtons(GetParent(), PSWIZB_FINISH | PSWIZB_BACK);
|
|
|
|
::SetControlFont(m_lpWizInfo->hBigBoldFont, m_hWnd, IDC_COMPLETE_BIG_TITLE);
|
|
::SetControlFont(m_lpWizInfo->hBoldFont, m_hWnd, IDC_COMPLETE_SMALL_TITLE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage7::OnWizardFinish()
|
|
{
|
|
return (S_OK == _SetUpDfs(m_lpWizInfo));
|
|
}
|
|
|
|
|
|
BOOL
|
|
CCreateDfsRootWizPage7::OnWizardBack()
|
|
{
|
|
//
|
|
// if share was created by the previous page, blow it away when we go back
|
|
//
|
|
if (!m_lpWizInfo->bShareExists)
|
|
NetShareDel(m_lpWizInfo->bstrSelectedServer, m_lpWizInfo->bstrDfsRootName, 0);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CCreateDfsRootWizPage7::OnQueryCancel()
|
|
{
|
|
//
|
|
// if share was created by the previous page, blow it away when we cancel the wizard
|
|
//
|
|
if (!m_lpWizInfo->bShareExists)
|
|
NetShareDel(m_lpWizInfo->bstrSelectedServer, m_lpWizInfo->bstrDfsRootName, 0);
|
|
|
|
return TRUE; // ok to cancel
|
|
}
|
|
|
|
HRESULT _SetUpDfs(
|
|
LPCREATEDFSROOTWIZINFO i_lpWizInfo
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Helper Function to Setup Dfs, called from wizard and new root replica,
|
|
Finish() method of Page5 if root level replca is created and Next() method of Page6
|
|
for Create New Dfs Root Wizard.
|
|
|
|
Arguments:
|
|
|
|
i_lpWizInfo - Wizard data.
|
|
|
|
Return value:
|
|
|
|
S_OK, on success
|
|
--*/
|
|
{
|
|
if (!i_lpWizInfo ||
|
|
!(i_lpWizInfo->bstrSelectedServer) ||
|
|
!(i_lpWizInfo->bstrDfsRootName))
|
|
return(E_INVALIDARG);
|
|
|
|
CWaitCursor WaitCursor;
|
|
NET_API_STATUS nstatRetVal = 0;
|
|
if (DFS_TYPE_FTDFS == i_lpWizInfo->DfsType)
|
|
{
|
|
nstatRetVal = NetDfsAddFtRoot(
|
|
i_lpWizInfo->bstrSelectedServer, // Remote Server
|
|
i_lpWizInfo->bstrDfsRootName, // Root Share
|
|
i_lpWizInfo->bstrDfsRootName, // FtDfs Name
|
|
i_lpWizInfo->bstrDfsRootComment, // Comment
|
|
0 // No Flags.
|
|
);
|
|
dfsDebugOut((_T("NetDfsAddFtRoot server=%s, share=%s, DfsName=%s, comment=%s, nRet=%d\n"),
|
|
i_lpWizInfo->bstrSelectedServer, i_lpWizInfo->bstrDfsRootName, i_lpWizInfo->bstrDfsRootName, i_lpWizInfo->bstrDfsRootComment, nstatRetVal));
|
|
} else
|
|
{
|
|
nstatRetVal = NetDfsAddStdRoot(
|
|
i_lpWizInfo->bstrSelectedServer, // Remote Server
|
|
i_lpWizInfo->bstrDfsRootName, // Root Share
|
|
i_lpWizInfo->bstrDfsRootComment, // Comment
|
|
0 // No Flags.
|
|
);
|
|
dfsDebugOut((_T("NetDfsAddStdRoot server=%s, share=%s, comment=%s, nRet=%d\n"),
|
|
i_lpWizInfo->bstrSelectedServer, i_lpWizInfo->bstrDfsRootName, i_lpWizInfo->bstrDfsRootComment, nstatRetVal));
|
|
}
|
|
|
|
HRESULT hr = S_OK;
|
|
if (NERR_Success != nstatRetVal)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(nstatRetVal);
|
|
DisplayMessageBox(::GetActiveWindow(), MB_OK, hr, IDS_FAILED_TO_CREATE_DFSROOT, i_lpWizInfo->bstrSelectedServer);
|
|
hr = S_FALSE; // failed to create dfsroot, wizard cannot be closed
|
|
} else
|
|
{
|
|
i_lpWizInfo->bDfsSetupSuccess = true;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
ValidateFolderPath(
|
|
IN LPCTSTR lpszServer,
|
|
IN LPCTSTR lpszPath
|
|
)
|
|
{
|
|
if (!lpszPath || !*lpszPath)
|
|
return E_INVALIDARG;
|
|
|
|
HWND hwnd = ::GetActiveWindow();
|
|
HRESULT hr = S_FALSE;
|
|
|
|
do {
|
|
if (!IsValidLocalAbsolutePath(lpszPath))
|
|
{
|
|
DisplayMessageBox(hwnd, MB_OK, 0, IDS_INVALID_FOLDER);
|
|
break;
|
|
}
|
|
|
|
hr = IsComputerLocal(lpszServer);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBox(hwnd, MB_OK, hr, IDS_FAILED_TO_VALIDATE_FOLDER, lpszPath);
|
|
break;
|
|
}
|
|
|
|
BOOL bLocal = (S_OK == hr);
|
|
|
|
hr = VerifyDriveLetter(lpszServer, lpszPath);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBox(hwnd, MB_OK, hr, IDS_FAILED_TO_VALIDATE_FOLDER, lpszPath);
|
|
break;
|
|
} else if (S_OK != hr)
|
|
{
|
|
DisplayMessageBox(hwnd, MB_OK, 0, IDS_INVALID_FOLDER);
|
|
break;
|
|
}
|
|
|
|
if (!bLocal)
|
|
{
|
|
hr = IsAdminShare(lpszServer, lpszPath);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBox(hwnd, MB_OK, hr, IDS_FAILED_TO_VALIDATE_FOLDER, lpszPath);
|
|
break;
|
|
} else if (S_OK != hr)
|
|
{
|
|
// there is no matching $ shares, hence, no need to call GetFileAttribute, CreateDirectory,
|
|
// assume lpszDir points to an existing directory
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CComBSTR bstrFullPath;
|
|
GetFullPath(lpszServer, lpszPath, &bstrFullPath);
|
|
|
|
hr = IsAnExistingFolder(hwnd, bstrFullPath);
|
|
if (FAILED(hr) || S_OK == hr)
|
|
break;
|
|
|
|
if ( IDYES != DisplayMessageBox(hwnd, MB_YESNO, 0, IDS_CREATE_FOLDER, lpszPath, lpszServer) )
|
|
{
|
|
hr = S_FALSE;
|
|
break;
|
|
}
|
|
|
|
// create the directories layer by layer
|
|
hr = CreateLayeredDirectory(lpszServer, lpszPath);
|
|
if (FAILED(hr))
|
|
{
|
|
DisplayMessageBox(hwnd, MB_OK, hr, IDS_FAILED_TO_CREATE_FOLDER, lpszPath, lpszServer);
|
|
break;
|
|
}
|
|
} while (0);
|
|
|
|
return hr;
|
|
}
|