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.
441 lines
9.7 KiB
441 lines
9.7 KiB
//
|
|
// usersess.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "Fscfg.h"
|
|
#include "usersess.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
//
|
|
// Ftp user object
|
|
//
|
|
CFtpUserInfo::CFtpUserInfo(
|
|
LPFTP_USER_INFO lpUserInfo
|
|
)
|
|
: m_idUser(lpUserInfo->idUser),
|
|
m_strUser(lpUserInfo->pszUser),
|
|
m_fAnonymous(lpUserInfo->fAnonymous),
|
|
// Network Byte Order
|
|
// ||
|
|
// \/
|
|
m_iaHost((LONG)lpUserInfo->inetHost, TRUE),
|
|
m_tConnect(lpUserInfo->tConnect)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Sorting helper function. The CObjectPlus pointer
|
|
// really refers to another CFtpUserInfo
|
|
//
|
|
int
|
|
CFtpUserInfo::OrderByName (
|
|
const CObjectPlus * pobFtpUser
|
|
) const
|
|
{
|
|
const CFtpUserInfo * pob = (CFtpUserInfo *) pobFtpUser;
|
|
|
|
return QueryUserName().CompareNoCase(pob->QueryUserName());
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// CFtpUsersListBox - a listbox of FTP user objects
|
|
//
|
|
IMPLEMENT_DYNAMIC(CFtpUsersListBox, CListBoxEx);
|
|
|
|
const int CFtpUsersListBox::nBitmaps = 2;
|
|
|
|
CFtpUsersListBox::CFtpUsersListBox (
|
|
int nTab1,
|
|
int nTab2
|
|
)
|
|
{
|
|
SetTabs(nTab1, nTab2);
|
|
}
|
|
|
|
void
|
|
CFtpUsersListBox::SetTabs(
|
|
int nTab1,
|
|
int nTab2
|
|
)
|
|
{
|
|
m_nTab1 = nTab1;
|
|
m_nTab2 = nTab2;
|
|
}
|
|
|
|
void
|
|
CFtpUsersListBox::DrawItemEx(
|
|
CListBoxExDrawStruct& ds
|
|
)
|
|
{
|
|
CFtpUserInfo * p = (CFtpUserInfo *)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();
|
|
|
|
//
|
|
// Display a user bitmap
|
|
//
|
|
int nOffset = p->QueryAnonymous() ? 1 : 0;
|
|
int bm_h = (ds.m_Sel) ? 0 : bmh;
|
|
int bm_w = bmw * nOffset;
|
|
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, m_nTab1,
|
|
ds.m_Rect.bottom, p->QueryUserName());
|
|
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + m_nTab1, ds.m_Rect.top, m_nTab2,
|
|
ds.m_Rect.bottom, p->QueryHost());
|
|
|
|
//
|
|
// BUGBUG: Shouldn't hardcode the colon
|
|
//
|
|
CString strTime;
|
|
DWORD dwTime = p->QueryConnectTime();
|
|
DWORD dwHours = dwTime / (60L * 60L);
|
|
DWORD dwMinutes = (dwTime / 60L) % 60L;
|
|
DWORD dwSeconds = dwTime % 60L;
|
|
strTime.Format(_T("%d:%02d:%02d"),
|
|
dwHours, dwMinutes, dwSeconds);
|
|
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + m_nTab2, ds.m_Rect.top,
|
|
ds.m_Rect.right, ds.m_Rect.bottom, strTime);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// CUserSessionsDlg dialog
|
|
//
|
|
CUserSessionsDlg::CUserSessionsDlg(
|
|
LPCTSTR lpstrServerName,
|
|
CWnd* pParent /*=NULL*/
|
|
)
|
|
: m_list_Users(),
|
|
m_ListBoxRes(
|
|
IDB_USERS,
|
|
m_list_Users.nBitmaps
|
|
),
|
|
m_oblFtpUsers(),
|
|
m_strServerName(lpstrServerName),
|
|
CDialog(CUserSessionsDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CUserSessionsDlg)
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_list_Users.AttachResources( &m_ListBoxRes );
|
|
VERIFY(m_strTotalConnected.LoadString(IDS_USERS_TOTAL));
|
|
}
|
|
|
|
void
|
|
CUserSessionsDlg::DoDataExchange(
|
|
CDataExchange* pDX
|
|
)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CUserSessionsDlg)
|
|
DDX_Control(pDX, IDC_STATIC_NUM_CONNECTED, m_static_Total);
|
|
DDX_Control(pDX, IDC_STATIC_USERS, m_static_Users);
|
|
DDX_Control(pDX, IDC_STATIC_TIME, m_static_Time);
|
|
DDX_Control(pDX, IDC_STATIC_FROM, m_static_From);
|
|
DDX_Control(pDX, IDC_BUTTON_DISCONNECT_ALL, m_button_DisconnectAll);
|
|
DDX_Control(pDX, IDC_BUTTON_DISCONNECT, m_button_Disconnect);
|
|
//}}AFX_DATA_MAP
|
|
|
|
DDX_Control(pDX, IDC_LIST_USERS, m_list_Users);
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CUserSessionsDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CUserSessionsDlg)
|
|
ON_BN_CLICKED(IDC_BUTTON_DISCONNECT, OnButtonDisconnect)
|
|
ON_BN_CLICKED(IDC_BUTTON_DISCONNECT_ALL, OnButtonDisconnectAll)
|
|
ON_BN_CLICKED(IDC_BUTTON_REFRESH, OnButtonRefresh)
|
|
ON_LBN_SELCHANGE(IDC_LIST_USERS, OnSelchangeListUsers)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
//
|
|
// Sort the list of ftp users by user name
|
|
//
|
|
LONG
|
|
CUserSessionsDlg::SortUsersList()
|
|
{
|
|
if (m_oblFtpUsers.GetCount() < 2)
|
|
{
|
|
//
|
|
// Don't bother
|
|
//
|
|
return 0;
|
|
}
|
|
|
|
BeginWaitCursor();
|
|
LONG l = m_oblFtpUsers.Sort( (CObjectPlus::PCOBJPLUS_ORDER_FUNC) &CFtpUserInfo::OrderByName);
|
|
EndWaitCursor();
|
|
|
|
return l;
|
|
}
|
|
|
|
//
|
|
// Call the FtpEnum api and build the list of currently
|
|
// connected users
|
|
//
|
|
NET_API_STATUS
|
|
CUserSessionsDlg::BuildUserList()
|
|
{
|
|
NET_API_STATUS err;
|
|
LPFTP_USER_INFO lpUserInfo = NULL;
|
|
DWORD dwCount;
|
|
|
|
m_oblFtpUsers.RemoveAll();
|
|
|
|
BeginWaitCursor();
|
|
err = ::I_FtpEnumerateUsers(TWSTRREF((LPCTSTR)m_strServerName),
|
|
&dwCount,&lpUserInfo);
|
|
|
|
EndWaitCursor();
|
|
|
|
TRACEEOLID(_T("I_FtpEnumerateUsers returned ") << err);
|
|
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
return err;
|
|
}
|
|
|
|
TRY
|
|
{
|
|
for (DWORD i = 0; i < dwCount; ++i)
|
|
{
|
|
m_oblFtpUsers.AddTail(new CFtpUserInfo(lpUserInfo++));
|
|
}
|
|
SortUsersList();
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
err = ::GetLastError();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
return err;
|
|
}
|
|
|
|
//
|
|
// Disconnect a single user
|
|
//
|
|
NET_API_STATUS
|
|
CUserSessionsDlg::DisconnectUser(
|
|
CFtpUserInfo * pUserInfo
|
|
)
|
|
{
|
|
return ::I_FtpDisconnectUser(TWSTRREF((LPCTSTR)m_strServerName),
|
|
pUserInfo->QueryUserID());
|
|
}
|
|
|
|
//
|
|
// Update the count of total users
|
|
//
|
|
void
|
|
CUserSessionsDlg::UpdateTotalCount()
|
|
{
|
|
CString str;
|
|
str.Format(m_strTotalConnected, m_oblFtpUsers.GetCount() );
|
|
|
|
m_static_Total.SetWindowText(str);
|
|
}
|
|
|
|
//
|
|
// Show the users in the listbox
|
|
//
|
|
void
|
|
CUserSessionsDlg::FillListBox()
|
|
{
|
|
CObListIter obli( m_oblFtpUsers );
|
|
CFtpUserInfo * pUserEntry;
|
|
|
|
//
|
|
// Remember the selection.
|
|
//
|
|
int nCurSel = m_list_Users.GetCurSel();
|
|
|
|
m_list_Users.SetRedraw(FALSE);
|
|
m_list_Users.ResetContent();
|
|
int cItems = 0;
|
|
|
|
for ( /**/ ; pUserEntry = (CFtpUserInfo *) obli.Next() ; cItems++ )
|
|
{
|
|
m_list_Users.AddItem( pUserEntry );
|
|
}
|
|
|
|
m_list_Users.SetRedraw(TRUE);
|
|
m_list_Users.SetCurSel(nCurSel);
|
|
|
|
//
|
|
// Update the count text on the dialog
|
|
//
|
|
UpdateTotalCount();
|
|
}
|
|
|
|
//
|
|
// Set the connect/disconnect buttons depending on the
|
|
// selection state in the listbox.
|
|
//
|
|
void
|
|
CUserSessionsDlg::SetControlStates()
|
|
{
|
|
m_button_Disconnect.EnableWindow(m_list_Users.GetCurSel() != LB_ERR);
|
|
m_button_DisconnectAll.EnableWindow(m_list_Users.GetCount() > 0);
|
|
}
|
|
|
|
//
|
|
// CUserSessionsDlg message handlers
|
|
//
|
|
|
|
//
|
|
// Disconnect currently selected user
|
|
//
|
|
void
|
|
CUserSessionsDlg::OnButtonDisconnect()
|
|
{
|
|
int nCurSel = m_list_Users.GetCurSel();
|
|
|
|
if (nCurSel != LB_ERR)
|
|
{
|
|
CFtpUserInfo * pUserEntry = m_list_Users.GetItem(nCurSel);
|
|
|
|
//
|
|
// Ask for confirmation
|
|
//
|
|
CString strMsg, str;
|
|
VERIFY(strMsg.LoadString(IDS_CONFIRM_DISCONNECT_USER));
|
|
str.Format(strMsg, (LPCTSTR)pUserEntry->QueryUserName());
|
|
|
|
if (IDYES == ::AfxMessageBox(str,
|
|
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2))
|
|
{
|
|
NET_API_STATUS err = DisconnectUser(pUserEntry);
|
|
|
|
if (err == ERROR_SUCCESS)
|
|
{
|
|
m_oblFtpUsers.RemoveIndex(nCurSel);
|
|
m_list_Users.DeleteString(nCurSel);
|
|
if (nCurSel)
|
|
{
|
|
--nCurSel;
|
|
}
|
|
m_list_Users.SetCurSel(nCurSel);
|
|
UpdateTotalCount();
|
|
SetControlStates();
|
|
}
|
|
else
|
|
{
|
|
::DisplayMessage(err);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Disconnect all users
|
|
//
|
|
void
|
|
CUserSessionsDlg::OnButtonDisconnectAll()
|
|
{
|
|
//
|
|
// Ask for confirmation
|
|
//
|
|
CString strMsg;
|
|
VERIFY(strMsg.LoadString(IDS_CONFIRM_DISCONNECT_ALL));
|
|
|
|
if (IDYES == ::AfxMessageBox(strMsg,
|
|
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2))
|
|
{
|
|
CObListIter obli( m_oblFtpUsers );
|
|
CFtpUserInfo * pUserEntry;
|
|
|
|
m_list_Users.SetRedraw(FALSE);
|
|
int cItems = 0;
|
|
|
|
for ( /**/; pUserEntry = (CFtpUserInfo *) obli.Next(); cItems++ )
|
|
{
|
|
BeginWaitCursor();
|
|
NET_API_STATUS err = DisconnectUser(pUserEntry);
|
|
EndWaitCursor();
|
|
|
|
if (err == ERROR_SUCCESS)
|
|
{
|
|
m_oblFtpUsers.RemoveIndex(0);
|
|
m_list_Users.DeleteString(0);
|
|
}
|
|
else
|
|
{
|
|
::DisplayMessage(err);
|
|
break;
|
|
}
|
|
}
|
|
m_list_Users.SetRedraw(TRUE);
|
|
SetControlStates();
|
|
UpdateTotalCount();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Refresh user list
|
|
//
|
|
NET_API_STATUS
|
|
CUserSessionsDlg::RefreshUsersList()
|
|
{
|
|
NET_API_STATUS err = BuildUserList();
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
::DisplayMessage(err);
|
|
}
|
|
|
|
FillListBox();
|
|
SetControlStates();
|
|
|
|
return err;
|
|
}
|
|
|
|
void
|
|
CUserSessionsDlg::OnButtonRefresh()
|
|
{
|
|
RefreshUsersList();
|
|
}
|
|
|
|
void
|
|
CUserSessionsDlg::OnSelchangeListUsers()
|
|
{
|
|
SetControlStates();
|
|
}
|
|
|
|
BOOL
|
|
CUserSessionsDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
//
|
|
// Set tabs in listbox
|
|
//
|
|
RECT rc1, rc2, rc3;
|
|
m_static_Users.GetWindowRect(&rc1);
|
|
m_static_From.GetWindowRect(&rc2);
|
|
m_static_Time.GetWindowRect(&rc3);
|
|
m_list_Users.SetTabs(rc2.left - rc1.left - 1, rc3.left - rc1.left - 1);
|
|
|
|
if (ERROR_SUCCESS != RefreshUsersList())
|
|
{
|
|
EndDialog(IDCANCEL);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|