mirror of https://github.com/lianthony/NT4.0
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.
1038 lines
24 KiB
1038 lines
24 KiB
//
|
|
// director.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "comprop.h"
|
|
#include "ipaddr.hpp"
|
|
#include "dirpropd.h"
|
|
|
|
//
|
|
// Column width relative weights
|
|
//
|
|
#define WT_DIRECTORY 4
|
|
#define WT_ALIAS 2
|
|
#define WT_IPADDRESS 2
|
|
#define WT_ERRORS 3
|
|
|
|
extern "C"
|
|
{
|
|
#include <lm.h>
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define THIS_PAGE_IS_COMMON FALSE
|
|
|
|
//
|
|
// CDirectoriesListBox : a listbox of CDirEntry structures
|
|
//
|
|
IMPLEMENT_DYNAMIC(CDirectoriesListBox, CListBoxEx);
|
|
|
|
const int CDirectoriesListBox::nBitmaps = 3;
|
|
|
|
CDirectoriesListBox::CDirectoriesListBox(
|
|
UINT nHomeDir, // String ID for <Home Directory> string
|
|
int * pnTabs // Array of tabs
|
|
)
|
|
{
|
|
if (pnTabs != NULL)
|
|
{
|
|
SetTabs(pnTabs);
|
|
}
|
|
|
|
VERIFY(m_strHomeDirectory.LoadString(nHomeDir));
|
|
}
|
|
|
|
BOOL
|
|
CDirectoriesListBox::ComputeTabs(
|
|
int nIndex,
|
|
int & nTab1,
|
|
int & nTab2
|
|
) const
|
|
{
|
|
if (m_anTabs[nIndex] > 0)
|
|
{
|
|
nTab1 = 0;
|
|
for (int n = 0; n < nIndex; ++n)
|
|
{
|
|
nTab1 += m_anTabs[n];
|
|
}
|
|
|
|
nTab2 = nTab1 + m_anTabs[nIndex];
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
CDirectoriesListBox::DrawItemEx(
|
|
CListBoxExDrawStruct& ds
|
|
)
|
|
{
|
|
CDirEntry * p = (CDirEntry *)ds.m_ItemData;
|
|
ASSERT(p != NULL);
|
|
|
|
CDC * pBmpDC = (CDC *)&ds.m_pResources->DcBitMap();
|
|
int bmh = ds.m_pResources->BitmapHeight();
|
|
int bmw = ds.m_pResources->BitmapWidth();
|
|
int nTab1, nTab2;
|
|
|
|
//
|
|
// Display a home directory bitmap
|
|
//
|
|
if (ComputeTabs(HI_DIRECTORY, nTab1, nTab2))
|
|
{
|
|
//
|
|
// Make sure there's room for the bitmap
|
|
//
|
|
if (m_anTabs[HI_DIRECTORY] > bmw)
|
|
{
|
|
int bm_h = (ds.m_Sel) ? 0 : bmh;
|
|
int bm_w = p->IsHome() ? 0 : (2 * bmw);
|
|
ds.m_pDC->BitBlt( ds.m_Rect.left+1, ds.m_Rect.top, bmw, bmh,
|
|
pBmpDC, bm_w, bm_h, SRCCOPY );
|
|
}
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + 3, ds.m_Rect.top, nTab2,
|
|
ds.m_Rect.bottom, p->QueryDirectory());
|
|
}
|
|
|
|
if (ComputeTabs(HI_ALIAS, nTab1, nTab2))
|
|
{
|
|
CString strAlias;
|
|
if (p->IsHome())
|
|
{
|
|
strAlias = m_strHomeDirectory;
|
|
}
|
|
else
|
|
{
|
|
strAlias = p->QueryAlias();
|
|
}
|
|
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + nTab1, ds.m_Rect.top,
|
|
nTab2, ds.m_Rect.bottom, strAlias);
|
|
}
|
|
|
|
if (ComputeTabs(HI_IPADDRESS, nTab1, nTab2))
|
|
{
|
|
CIpAddress ia(p->QueryIpAddress());
|
|
|
|
if ((LONG)ia != 0L)
|
|
{
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + nTab1, ds.m_Rect.top,
|
|
nTab2, ds.m_Rect.bottom, ia);
|
|
}
|
|
}
|
|
|
|
if (ComputeTabs(HI_ERRORS, nTab1, nTab2))
|
|
{
|
|
#define MAX_ERROR 255
|
|
|
|
DWORD dwError= p->QueryError();
|
|
|
|
if (dwError != ERROR_SUCCESS)
|
|
{
|
|
CString strError;
|
|
|
|
GetSystemMessage(dwError,
|
|
strError.GetBuffer(MAX_ERROR), MAX_ERROR);
|
|
|
|
strError.ReleaseBuffer();
|
|
|
|
if (m_anTabs[HI_ERRORS] > bmw)
|
|
{
|
|
int bm_h = (ds.m_Sel) ? 0 : bmh;
|
|
int bm_w = bmw;
|
|
ds.m_pDC->BitBlt( ds.m_Rect.left + nTab1, ds.m_Rect.top, bmw, bmh,
|
|
pBmpDC, bm_w, bm_h, SRCCOPY );
|
|
}
|
|
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + nTab1, ds.m_Rect.top,
|
|
nTab2, ds.m_Rect.bottom, strError);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// DirectoryPage property page
|
|
//
|
|
IMPLEMENT_DYNCREATE(DirectoryPage, INetPropertyPage)
|
|
|
|
DirectoryPage::DirectoryPage(
|
|
INetPropertySheet * pSheet,
|
|
BOOL fUseTCPIP,
|
|
BOOL fErrorColumn,
|
|
DWORD dwMask
|
|
)
|
|
: INetPropertyPage(DirectoryPage::IDD, pSheet,
|
|
::GetModuleHandle(COMPROP_DLL_NAME)),
|
|
m_list_Directories(
|
|
IDS_HOME_DIRECTORY,
|
|
0
|
|
),
|
|
m_ListBoxRes(
|
|
IDB_HOME,
|
|
m_list_Directories.nBitmaps
|
|
),
|
|
m_oblDirectories(),
|
|
m_nSortColumn(HI_DIRECTORY),
|
|
m_fDisplayErrorColumn(fErrorColumn),
|
|
m_fUseTCPIP(fUseTCPIP),
|
|
m_dwAccessMask(dwMask)
|
|
{
|
|
//{{AFX_DATA_INIT(DirectoryPage)
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_list_Directories.AttachResources( &m_ListBoxRes );
|
|
}
|
|
|
|
DirectoryPage::~DirectoryPage()
|
|
{
|
|
//
|
|
// The directories oblist will clean itself up
|
|
//
|
|
}
|
|
|
|
void
|
|
DirectoryPage::DoDataExchange(
|
|
CDataExchange* pDX
|
|
)
|
|
{
|
|
INetPropertyPage::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(DirectoryPage)
|
|
DDX_Control(pDX, IDC_ADD, m_button_Add);
|
|
DDX_Control(pDX, IDC_REMOVE, m_button_Remove);
|
|
DDX_Control(pDX, IDC_BUTTON_EDIT, m_button_Edit);
|
|
//}}AFX_DATA_MAP
|
|
|
|
DDX_Control(pDX, IDC_LIST_DIRECTORIES, m_list_Directories);
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(DirectoryPage, INetPropertyPage)
|
|
//{{AFX_MSG_MAP(DirectoryPage)
|
|
ON_BN_CLICKED(IDC_REMOVE, OnRemove)
|
|
ON_BN_CLICKED(IDC_BUTTON_EDIT, OnButtonEdit)
|
|
ON_BN_CLICKED(IDC_ADD, OnAdd)
|
|
ON_LBN_DBLCLK(IDC_LIST_DIRECTORIES, OnDblclkListDirectories)
|
|
ON_LBN_SELCHANGE(IDC_LIST_DIRECTORIES, OnSelchangeListDirectories)
|
|
ON_LBN_ERRSPACE(IDC_LIST_DIRECTORIES, OnErrspaceListDirectories)
|
|
ON_WM_VKEYTOITEM()
|
|
//}}AFX_MSG_MAP
|
|
|
|
ON_NOTIFY_RANGE( HDN_ENDTRACK, 0, 0xFFFF, OnHeaderEndTrack )
|
|
ON_NOTIFY_RANGE( HDN_ITEMCLICK, 0, 0xFFFF, OnHeaderItemClick )
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
//
|
|
// Set the edit/remove button states depending on
|
|
// whether anything is selected in the listbox.
|
|
//
|
|
void
|
|
DirectoryPage::SetControlStates()
|
|
{
|
|
BOOL fSelection = m_list_Directories.GetCurSel() != -1;
|
|
|
|
m_button_Remove.EnableWindow(fSelection);
|
|
m_button_Edit.EnableWindow(fSelection);
|
|
}
|
|
|
|
//
|
|
// Display the add/edit dialog. The return
|
|
// value is the value returned by the dialog
|
|
//
|
|
int
|
|
DirectoryPage::ShowPropertyDialog(
|
|
BOOL fAdd
|
|
)
|
|
{
|
|
CDirEntry dir; // Empty object for adding
|
|
CDirEntry * pDir = NULL;
|
|
int nCurSel = LB_ERR;
|
|
|
|
if (!fAdd)
|
|
{
|
|
nCurSel = m_list_Directories.GetCurSel();
|
|
if (nCurSel != LB_ERR)
|
|
{
|
|
//
|
|
// Get directory properties
|
|
//
|
|
pDir = m_list_Directories.GetItem(nCurSel);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Point to the empty directory entry
|
|
//
|
|
pDir = &dir;
|
|
}
|
|
|
|
ASSERT(pDir != NULL);
|
|
CDirPropDlg dlgDirProp(*pDir, &m_oblDirectories,
|
|
IsLocal(), fAdd, m_fUseTCPIP, m_dwAccessMask, this,
|
|
IDD_DIRECTORY_PROPERTIES, GetSheet()->IsVer3OrAbove());
|
|
|
|
int nReturn = dlgDirProp.DoModal();
|
|
|
|
if (nReturn == IDOK)
|
|
{
|
|
//
|
|
// When editing, delete and re-add (to make sure the
|
|
// list is properly sorted)
|
|
//
|
|
if (!fAdd)
|
|
{
|
|
m_oblDirectories.RemoveIndex(nCurSel);
|
|
}
|
|
|
|
//
|
|
// The check for duplicate home directories will
|
|
// already have been made in the directory properties
|
|
// dialog, and if we get to this point, any existing
|
|
// home directories will already have an alias name
|
|
// generated for it.
|
|
//
|
|
m_oblDirectories.AddTail(new CDirEntry(dlgDirProp.QueryDirEntry()));
|
|
|
|
switch(QuerySortColumn())
|
|
{
|
|
case HI_DIRECTORY:
|
|
SortByDirectory();
|
|
break;
|
|
|
|
case HI_ALIAS:
|
|
SortByAlias();
|
|
break;
|
|
|
|
case HI_IPADDRESS:
|
|
SortByAddress();
|
|
break;
|
|
|
|
case HI_ERRORS:
|
|
SortByError();
|
|
break;
|
|
}
|
|
|
|
FillListBox();
|
|
}
|
|
|
|
return nReturn;
|
|
}
|
|
|
|
//
|
|
// Given the column number, obtain the
|
|
// index in our directory column array
|
|
//
|
|
int
|
|
DirectoryPage::MapColumnToIndex(
|
|
int nCol
|
|
) const
|
|
{
|
|
ASSERT(nCol >= 0 && nCol < HI_NUM_COLUMNS);
|
|
int nIndex = -1;
|
|
for (int n = 0; n < HI_NUM_COLUMNS; ++n)
|
|
{
|
|
if (m_anColumns[n] != -1)
|
|
{
|
|
++nIndex;
|
|
}
|
|
|
|
if (nIndex == nCol)
|
|
{
|
|
return n;
|
|
}
|
|
}
|
|
|
|
//
|
|
// This should never happen!
|
|
//
|
|
ASSERT(0);
|
|
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// Ensure that the two columns take up the entire width
|
|
// of the control, by changing the size of the second
|
|
// column.
|
|
//
|
|
void
|
|
DirectoryPage::AdjustColumns(
|
|
HD_NOTIFY * pNotify // Or NULL
|
|
)
|
|
{
|
|
HD_ITEM hdi;
|
|
int nTabs[HI_NUM_COLUMNS];
|
|
|
|
hdi.mask = HDI_WIDTH;
|
|
for (int i = 0; i < HI_NUM_COLUMNS; ++i)
|
|
{
|
|
if (m_anColumns[i] == -1)
|
|
{
|
|
nTabs[i] = -1;
|
|
}
|
|
else
|
|
{
|
|
VERIFY(m_hdr.GetItem(m_anColumns[i], &hdi));
|
|
nTabs[i] = hdi.cxy;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Adjust for what was just dragged, since the size
|
|
// isn't updated until after we get the end-tracking
|
|
// message (btw this is highly annoying)
|
|
//
|
|
if (pNotify != NULL)
|
|
{
|
|
ASSERT(pNotify->pitem->mask & HDI_WIDTH);
|
|
ASSERT(pNotify->iItem >= 0 && pNotify->iItem < HI_NUM_COLUMNS);
|
|
|
|
nTabs[MapColumnToIndex(pNotify->iItem)] = pNotify->pitem->cxy;
|
|
}
|
|
|
|
m_list_Directories.SetTabs(nTabs);
|
|
}
|
|
|
|
//
|
|
// Populate the listbox with the directory
|
|
// entries
|
|
//
|
|
void
|
|
DirectoryPage::FillListBox()
|
|
{
|
|
CObListIter obli( m_oblDirectories );
|
|
const CDirEntry * pDirEntry;
|
|
|
|
//
|
|
// Remember the selection.
|
|
//
|
|
int nCurSel = m_list_Directories.GetCurSel();
|
|
|
|
m_list_Directories.SetRedraw(FALSE);
|
|
m_list_Directories.ResetContent();
|
|
int cItems = 0;
|
|
|
|
for ( /**/ ; pDirEntry = (CDirEntry *) obli.Next() ; cItems++ )
|
|
{
|
|
m_list_Directories.AddString( (LPCTSTR)pDirEntry );
|
|
}
|
|
|
|
m_list_Directories.SetRedraw(TRUE);
|
|
m_list_Directories.SetCurSel(nCurSel);
|
|
}
|
|
|
|
//
|
|
// Sorting the directory list by the directories names
|
|
// FillListBox() should be called after this because
|
|
// the listbox will no longer reflect the true status
|
|
// of the list of directories.
|
|
//
|
|
LONG
|
|
DirectoryPage::SortByDirectory()
|
|
{
|
|
m_nSortColumn = HI_DIRECTORY;
|
|
|
|
if (m_oblDirectories.GetCount() < 2)
|
|
{
|
|
//
|
|
// Don't bother
|
|
//
|
|
return 0;
|
|
}
|
|
|
|
BeginWaitCursor();
|
|
LONG l = m_oblDirectories.Sort(
|
|
(CObjectPlus::PCOBJPLUS_ORDER_FUNC) &CDirEntry::OrderByDirectory );
|
|
EndWaitCursor();
|
|
|
|
return l;
|
|
}
|
|
|
|
//
|
|
// As above, but sort by the alias names of the directories
|
|
//
|
|
LONG
|
|
DirectoryPage::SortByAlias()
|
|
{
|
|
m_nSortColumn = HI_ALIAS;
|
|
|
|
if (m_oblDirectories.GetCount() < 2)
|
|
{
|
|
//
|
|
// Don't bother
|
|
//
|
|
return 0;
|
|
}
|
|
|
|
BeginWaitCursor();
|
|
LONG l = m_oblDirectories.Sort(
|
|
(CObjectPlus::PCOBJPLUS_ORDER_FUNC) & CDirEntry::OrderByAlias );
|
|
EndWaitCursor();
|
|
|
|
return l;
|
|
}
|
|
|
|
//
|
|
// As above, but sort by the ip address of the directories
|
|
//
|
|
LONG
|
|
DirectoryPage::SortByAddress()
|
|
{
|
|
m_nSortColumn = HI_IPADDRESS;
|
|
|
|
if (m_oblDirectories.GetCount() < 2)
|
|
{
|
|
//
|
|
// Don't bother
|
|
//
|
|
return 0;
|
|
}
|
|
|
|
BeginWaitCursor();
|
|
LONG l = m_oblDirectories.Sort(
|
|
(CObjectPlus::PCOBJPLUS_ORDER_FUNC) & CDirEntry::OrderByIpAddress );
|
|
EndWaitCursor();
|
|
|
|
return l;
|
|
}
|
|
|
|
//
|
|
// As above, but sort by the error value of the directories
|
|
//
|
|
LONG
|
|
DirectoryPage::SortByError()
|
|
{
|
|
m_nSortColumn = HI_ERRORS;
|
|
|
|
if (m_oblDirectories.GetCount() < 2)
|
|
{
|
|
//
|
|
// Don't bother
|
|
//
|
|
return 0;
|
|
}
|
|
|
|
BeginWaitCursor();
|
|
LONG l = m_oblDirectories.Sort(
|
|
(CObjectPlus::PCOBJPLUS_ORDER_FUNC) & CDirEntry::OrderByError );
|
|
EndWaitCursor();
|
|
|
|
return l;
|
|
}
|
|
|
|
//
|
|
// Insert column. The width of the column is actually
|
|
// a relative "weight" of the column which needs to
|
|
// be adjusted later. The return value is the column
|
|
// number or -1 if the column is not inserted
|
|
//
|
|
int
|
|
DirectoryPage::InsertColumn(
|
|
BOOL fCondition, // Insert if TRUE
|
|
int & nCol, // Column number
|
|
int nWeight, // Relative weight of column
|
|
int & nTotalWeight, // Total weight
|
|
UINT nStringID // Resource string ID
|
|
)
|
|
{
|
|
if (fCondition)
|
|
{
|
|
CString strDirName;
|
|
HD_ITEM hdItem;
|
|
|
|
VERIFY(strDirName.LoadString(nStringID));
|
|
|
|
hdItem.mask = HDI_FORMAT | HDI_WIDTH | HDI_TEXT;
|
|
hdItem.fmt = HDF_STRING | HDF_LEFT;
|
|
hdItem.pszText = (LPTSTR)(LPCTSTR)strDirName;
|
|
hdItem.cchTextMax = strDirName.GetLength();
|
|
|
|
nTotalWeight += (hdItem.cxy = nWeight);
|
|
|
|
return m_hdr.InsertItem(nCol++, &hdItem);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// Convert weighted column width to actual width.
|
|
//
|
|
void
|
|
DirectoryPage::ConvertColumnWidth(
|
|
int nCol,
|
|
int nTotalWeight,
|
|
int nTotalWidth
|
|
)
|
|
{
|
|
if (nCol >= 0)
|
|
{
|
|
HD_ITEM hdItem;
|
|
|
|
hdItem.mask = HDI_WIDTH;
|
|
VERIFY(m_hdr.GetItem(nCol, &hdItem));
|
|
ASSERT(hdItem.cxy > 0);
|
|
hdItem.cxy = nTotalWidth * hdItem.cxy / nTotalWeight;
|
|
|
|
VERIFY(m_hdr.SetItem(nCol, &hdItem));
|
|
}
|
|
}
|
|
|
|
//
|
|
// DirectoryPage message handlers
|
|
//
|
|
BOOL
|
|
DirectoryPage::OnInitDialog()
|
|
{
|
|
INetPropertyPage::OnInitDialog();
|
|
|
|
RECT rc;
|
|
|
|
::GetDlgCtlRect(this->m_hWnd, m_list_Directories.m_hWnd, &rc);
|
|
|
|
//
|
|
// Create a header control just above the listbox. Set
|
|
// the width equal to the width of the listbox, and
|
|
// set the height equal to 7/8 the height of the edit
|
|
// button.
|
|
//
|
|
RECT rcButn;
|
|
m_button_Edit.GetClientRect(&rcButn);
|
|
rc.bottom = rc.top;
|
|
rc.top -= 7 * rcButn.bottom / 8;
|
|
int nWidth = rc.right - rc.left + 1;
|
|
|
|
m_hdr.Create( WS_VISIBLE | WS_CHILD | WS_BORDER
|
|
| HDS_BUTTONS | HDS_HORZ, rc, this, IDC_HEADER );
|
|
|
|
int nTotalWeight = 0;
|
|
int nCol = 0;
|
|
|
|
m_anColumns[HI_DIRECTORY] = InsertColumn(TRUE, nCol, WT_DIRECTORY,
|
|
nTotalWeight, IDS_DIRECTORY);
|
|
m_anColumns[HI_ALIAS] = InsertColumn(TRUE, nCol, WT_ALIAS, nTotalWeight,
|
|
IDS_ALIAS);
|
|
m_anColumns[HI_IPADDRESS] = InsertColumn(m_fUseTCPIP, nCol, WT_IPADDRESS,
|
|
nTotalWeight, IDS_IPADDRESS);
|
|
m_anColumns[HI_ERRORS] = InsertColumn(m_fDisplayErrorColumn, nCol, WT_ERRORS,
|
|
nTotalWeight, IDS_ERROR);
|
|
|
|
for (nCol = 0; nCol < HI_NUM_COLUMNS; ++nCol)
|
|
{
|
|
ConvertColumnWidth(m_anColumns[nCol], nTotalWeight, nWidth);
|
|
}
|
|
|
|
#ifdef NO_LSA
|
|
|
|
m_button_Add.EnableWindow(FALSE);
|
|
m_button_Remove.EnableWindow(FALSE);
|
|
m_button_Edit.EnableWindow(FALSE);
|
|
m_hdr.EnableWindow(FALSE);
|
|
m_list_Directories.EnableWindow(FALSE);
|
|
|
|
#else
|
|
|
|
TRY
|
|
{
|
|
if ( SingleServerSelected()
|
|
&& QueryConfigError() == ERROR_SUCCESS
|
|
&& GetInetConfigData()->VirtualRoots != NULL
|
|
)
|
|
{
|
|
|
|
for (DWORD i = 0; i < GetInetConfigData()->VirtualRoots->cEntries; i++)
|
|
{
|
|
CDirEntry * pDirEntry = new CDirEntry(
|
|
GetInetConfigData()->VirtualRoots->aVirtRootEntry[i].pszDirectory,
|
|
GetInetConfigData()->VirtualRoots->aVirtRootEntry[i].pszRoot,
|
|
GetInetConfigData()->VirtualRoots->aVirtRootEntry[i].pszAccountName,
|
|
GetInetConfigData()->VirtualRoots->aVirtRootEntry[i].AccountPassword,
|
|
GetInetConfigData()->VirtualRoots->aVirtRootEntry[i].pszAddress,
|
|
GetInetConfigData()->VirtualRoots->aVirtRootEntry[i].dwMask,
|
|
GetInetConfigData()->VirtualRoots->aVirtRootEntry[i].dwError
|
|
);
|
|
|
|
ASSERT(pDirEntry != NULL);
|
|
if (pDirEntry->IsHome())
|
|
{
|
|
int nSel;
|
|
CIpAddress ipaTarget = pDirEntry->QueryIpAddress();
|
|
|
|
if (::FindExistingHome(ipaTarget, m_oblDirectories, nSel))
|
|
{
|
|
//
|
|
// We already had a home dir for this ip -- can't have that
|
|
//
|
|
TRACEEOLID(_T("Duplicate home directories found for this ip address."));
|
|
::AfxMessageBox(IDS_WRN_MULTIPLE_HOMES,
|
|
MB_ICONINFORMATION | MB_OK);
|
|
pDirEntry->GenerateAutoAlias();
|
|
}
|
|
}
|
|
|
|
m_oblDirectories.AddTail(pDirEntry);
|
|
}
|
|
|
|
SortByDirectory();
|
|
FillListBox();
|
|
}
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
TRACEEOLID(_T("Exception in DirectoryPage::OnInitDialog() -- bailing out"));
|
|
::DisplayMessage(::GetLastError());
|
|
EndDialog(IDCANCEL);
|
|
|
|
return FALSE;
|
|
}
|
|
END_CATCH_ALL
|
|
#endif // NO_LSA
|
|
|
|
AdjustColumns();
|
|
SetControlStates();
|
|
|
|
return FALSE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
//
|
|
// "Apply now" or "OK" has been pressed. Save our stuff
|
|
// in the registry.
|
|
//
|
|
NET_API_STATUS
|
|
DirectoryPage::SaveInfo(
|
|
BOOL fUpdateData
|
|
)
|
|
{
|
|
if (!IsDirty() || (fUpdateData && !UpdateData(TRUE)))
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
TRACEEOLID(_T("Saving directory page now..."));
|
|
|
|
NET_API_STATUS err = 0;
|
|
|
|
#ifndef NO_LSA
|
|
CInetAConfigInfo config(GetConfig());
|
|
LPINETA_VIRTUAL_ROOT_LIST lpVirtualRoots = GetRoots();
|
|
if (lpVirtualRoots == NULL)
|
|
{
|
|
return ::GetLastError();
|
|
}
|
|
|
|
config.SetValues(
|
|
lpVirtualRoots
|
|
);
|
|
|
|
err = config.SetInfo(THIS_PAGE_IS_COMMON);
|
|
|
|
//
|
|
// Clean up
|
|
//
|
|
DestroyRoots(lpVirtualRoots);
|
|
#endif // NO_LSA
|
|
|
|
SetModified(FALSE);
|
|
|
|
return err;
|
|
}
|
|
|
|
//
|
|
// Build root table from private directory list
|
|
//
|
|
LPINETA_VIRTUAL_ROOT_LIST
|
|
DirectoryPage::GetRoots()
|
|
{
|
|
int cListItems = m_oblDirectories.GetCount();
|
|
DWORD cbNeeded = sizeof(INETA_VIRTUAL_ROOT_LIST) +
|
|
(sizeof(INETA_VIRTUAL_ROOT_ENTRY) * cListItems);;
|
|
LPINETA_VIRTUAL_ROOT_LIST pItemList = NULL;
|
|
int cItems;
|
|
|
|
TRY
|
|
{
|
|
TRACEEOLID(_T("Attempting to allocate rootlist of ") << cbNeeded
|
|
<< _T(" bytes"));
|
|
|
|
pItemList = (LPINETA_VIRTUAL_ROOT_LIST)new BYTE[cbNeeded];
|
|
|
|
ASSERT(pItemList);
|
|
//
|
|
// This shouldn't be necessary, but I tend
|
|
// to be paranoid about this sort of thing
|
|
//
|
|
::memset(pItemList, 0, cbNeeded);
|
|
pItemList->cEntries = cListItems;
|
|
|
|
CObListIter obli( m_oblDirectories );
|
|
const CDirEntry * pDirEntry;
|
|
|
|
cItems = 0;
|
|
for ( /**/ ; pDirEntry = (CDirEntry *) obli.Next() ; cItems++ )
|
|
{
|
|
TRACEEOLID(_T("Adding directory entry ") << cItems );
|
|
|
|
//
|
|
// Only fill in the IP address if the entry
|
|
// has a valid one. Otherwise, this will
|
|
// be a blank string.
|
|
//
|
|
CString strIpAddress;
|
|
if (pDirEntry->HasIPAddress())
|
|
{
|
|
strIpAddress = (CString)pDirEntry->QueryIpAddress();
|
|
}
|
|
ASSERT(strIpAddress.GetLength() <= 15); // xxx.xxx.xxx.xxx
|
|
|
|
pItemList->aVirtRootEntry[cItems].dwMask = pDirEntry->QueryMask();
|
|
|
|
::TextToText(pItemList->aVirtRootEntry[cItems].pszDirectory,
|
|
pDirEntry->QueryDirectory());
|
|
::TextToText(pItemList->aVirtRootEntry[cItems].pszRoot,
|
|
pDirEntry->QueryAlias());
|
|
::TextToText(pItemList->aVirtRootEntry[cItems].pszAccountName,
|
|
pDirEntry->QueryUserName());
|
|
::TextToText(pItemList->aVirtRootEntry[cItems].pszAddress,
|
|
strIpAddress);
|
|
TWSTRCPY(pItemList->aVirtRootEntry[cItems].AccountPassword,
|
|
pDirEntry->QueryPassword(),
|
|
STRSIZE(pItemList->aVirtRootEntry[cItems].AccountPassword));
|
|
|
|
TRACEEOLID(_T("password = ")
|
|
<< pItemList->aVirtRootEntry[cItems].AccountPassword);
|
|
TRACEEOLID(_T("directory = ")
|
|
<< pItemList->aVirtRootEntry[cItems].pszDirectory);
|
|
TRACEEOLID(_T("root = ")
|
|
<< pItemList->aVirtRootEntry[cItems].pszRoot);
|
|
TRACEEOLID(_T("account name = ")
|
|
<< pItemList->aVirtRootEntry[cItems].pszAccountName);
|
|
TRACEEOLID(_T("Address = ")
|
|
<< pItemList->aVirtRootEntry[cItems].pszAddress);
|
|
TRACEEOLID(_T("--"));
|
|
}
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
TRACEEOLID(_T("Exception in DirectoryPage::GetRoots() -- bailing out"));
|
|
return NULL;
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
//
|
|
// We should have added everything by now...
|
|
//
|
|
ASSERT(cItems == cListItems);
|
|
|
|
return pItemList;
|
|
}
|
|
|
|
//
|
|
// Destroy root list
|
|
//
|
|
void
|
|
DirectoryPage::DestroyRoots(
|
|
LPINETA_VIRTUAL_ROOT_LIST & pItemList
|
|
)
|
|
{
|
|
if (pItemList != NULL)
|
|
{
|
|
TRACEEOLID(_T("Destroying vroot list. Size of list = ")
|
|
<< pItemList->cEntries );
|
|
for (DWORD i = 0; i < pItemList->cEntries; ++i)
|
|
{
|
|
TRACEEOLID(_T("Destroying item #") << i);
|
|
delete pItemList->aVirtRootEntry[i].pszDirectory;
|
|
delete pItemList->aVirtRootEntry[i].pszRoot;
|
|
delete pItemList->aVirtRootEntry[i].pszAccountName;
|
|
delete pItemList->aVirtRootEntry[i].pszAddress;
|
|
}
|
|
|
|
delete pItemList;
|
|
pItemList = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Remove the currently selected directory
|
|
// entry
|
|
//
|
|
void
|
|
DirectoryPage::OnRemove()
|
|
{
|
|
//
|
|
// First get current selection
|
|
//
|
|
int nCurSel = m_list_Directories.GetCurSel();
|
|
if (nCurSel != LB_ERR)
|
|
{
|
|
//
|
|
// ISSUE: Do we ask for validation?
|
|
//
|
|
m_oblDirectories.RemoveIndex(nCurSel);
|
|
m_list_Directories.DeleteString(nCurSel);
|
|
if (nCurSel)
|
|
{
|
|
--nCurSel;
|
|
}
|
|
m_list_Directories.SetCurSel(nCurSel);
|
|
|
|
SetControlStates();
|
|
SetModified(TRUE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Edit currently selected directory
|
|
//
|
|
void
|
|
DirectoryPage::OnButtonEdit()
|
|
{
|
|
if (ShowPropertyDialog(FALSE) == IDOK)
|
|
{
|
|
SetControlStates();
|
|
SetModified(TRUE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add new directory entry
|
|
//
|
|
void
|
|
DirectoryPage::OnAdd()
|
|
{
|
|
if (ShowPropertyDialog(TRUE) == IDOK)
|
|
{
|
|
SetControlStates();
|
|
SetModified(TRUE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Message received when finished
|
|
// resizing the column widths with the
|
|
// header control
|
|
//
|
|
void
|
|
DirectoryPage::OnHeaderEndTrack(
|
|
UINT nId,
|
|
NMHDR *n,
|
|
LRESULT *l
|
|
)
|
|
{
|
|
//
|
|
// Make sure columns take up whole width of the
|
|
// list view
|
|
//
|
|
HD_NOTIFY *pNotify = (HD_NOTIFY *)n;
|
|
if ( pNotify->pitem->mask & HDI_WIDTH )
|
|
{
|
|
m_list_Directories.SetRedraw(FALSE);
|
|
AdjustColumns(pNotify);
|
|
m_list_Directories.SetRedraw(TRUE);
|
|
m_list_Directories.Invalidate();
|
|
}
|
|
}
|
|
|
|
//
|
|
// A button has been clicked in the header control
|
|
//
|
|
void
|
|
DirectoryPage::OnHeaderItemClick(
|
|
UINT nId,
|
|
NMHDR *n,
|
|
LRESULT *l
|
|
)
|
|
{
|
|
HD_NOTIFY *pNotify = (HD_NOTIFY *)n;
|
|
TRACEEOLID(_T("Header Button clicked."));
|
|
|
|
//
|
|
// Can't press a button out of range, surely...
|
|
//
|
|
ASSERT(pNotify->iItem < m_hdr.GetItemCount());
|
|
|
|
int nIndex = MapColumnToIndex(pNotify->iItem);
|
|
|
|
switch(nIndex)
|
|
{
|
|
case HI_DIRECTORY:
|
|
SortByDirectory();
|
|
break;
|
|
case HI_ALIAS:
|
|
SortByAlias();
|
|
break;
|
|
case HI_IPADDRESS:
|
|
SortByAddress();
|
|
break;
|
|
case HI_ERRORS:
|
|
SortByError();
|
|
break;
|
|
default:
|
|
TRACEEOLID(_T("Invalid column number ignored"));
|
|
}
|
|
|
|
FillListBox();
|
|
SetControlStates();
|
|
}
|
|
|
|
//
|
|
// Double-click means edit the currently selected
|
|
// entry.
|
|
//
|
|
void
|
|
DirectoryPage::OnDblclkListDirectories()
|
|
{
|
|
OnButtonEdit();
|
|
}
|
|
|
|
void
|
|
DirectoryPage::OnSelchangeListDirectories()
|
|
{
|
|
SetControlStates();
|
|
}
|
|
|
|
void
|
|
DirectoryPage::OnErrspaceListDirectories()
|
|
{
|
|
SetControlStates();
|
|
}
|
|
|
|
int
|
|
DirectoryPage::OnVKeyToItem(
|
|
UINT nKey,
|
|
CListBox* pListBox,
|
|
UINT nIndex
|
|
)
|
|
{
|
|
switch(nKey)
|
|
{
|
|
case VK_DELETE:
|
|
OnRemove();
|
|
break;
|
|
|
|
case VK_INSERT:
|
|
OnAdd();
|
|
break;
|
|
|
|
default:
|
|
//
|
|
// Not completely handled by this function, let
|
|
// windows handle the remaining default action.
|
|
//
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// No further action is neccesary.
|
|
//
|
|
return -2;
|
|
}
|