Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1080 lines
19 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1999 - 1999
//
// File: statdlg.cpp
//
//--------------------------------------------------------------------------
// StatDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ScAlert.h"
#include "miscdef.h"
#include "statmon.h"
#include "StatDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" { // Assume C declarations for C++
#endif // __cplusplus
#ifdef __cplusplus
}
#endif /* __cplusplus */
/////////////////////////////////////////////////////////////////////////////////////
//
// CSCStatusDlgThrd
//
IMPLEMENT_DYNCREATE(CSCStatusDlgThrd, CWinThread)
/*++
InitInstance
Must override init instance to perform UI thread initialization
Arguments:
Return Value:
TRUE on build start message loop. FALSE otherwise
Author:
Chris Dudley 2/27/1997
--*/
BOOL CSCStatusDlgThrd::InitInstance( void )
{
INT_PTR nResult = -1; // error creating dialog
LONG lReturn = SCARD_S_SUCCESS;
SCARDCONTEXT hSCardContext = NULL;
// Acquire context with resource manager
lReturn = SCardEstablishContext( SCARD_SCOPE_USER,
NULL,
NULL,
&hSCardContext);
if (lReturn != SCARD_S_SUCCESS)
{
nResult = IDCANCEL;
}
else
{
m_StatusDlg.SetContext(hSCardContext);
// Run the dialog as Modal
m_fStatusDlgUp = TRUE;
nResult = m_StatusDlg.DoModal();// if the dialog is shut down by a
// cancellation of the SCARDCONTEXT,
// it will return IDCANCEL
m_fStatusDlgUp = FALSE;
}
// Release context
if (NULL != hSCardContext)
{
SCardReleaseContext(hSCardContext);
}
// Post message that the thread is exiting, based on return...
if (NULL != m_hCallbackWnd)
{
::PostMessage( m_hCallbackWnd,
WM_SCARD_STATUS_DLG_EXITED, // CANCELLATION (0), or ERROR (1)
0, 0);
}
AfxEndThread(0);
return TRUE; // to make compiler happy
}
/*++
void ShowDialog:
Brings dialog to front if already open
Arguments:
None.
Return Value:
None.
Author:
Chris Dudley 7/30/1997
Note:
--*/
void CSCStatusDlgThrd::ShowDialog( int nCmdShow, CStringArray* paIdleList )
{
if (m_fStatusDlgUp)
{
m_StatusDlg.ShowWindow(nCmdShow);
m_StatusDlg.SetIdleList(paIdleList);
}
}
/*++
void UpdateStatus:
If the dialog is up, updates idle list and status text
Arguments:
None.
Return Value:
None.
Author:
Chris Dudley 7/30/1997
Note:
--*/
void CSCStatusDlgThrd::UpdateStatus( CStringArray* paIdleList )
{
if (m_fStatusDlgUp)
{
m_StatusDlg.UpdateLogonLockInfo();
m_StatusDlg.SetIdleList(paIdleList);
m_StatusDlg.UpdateStatusText();
}
}
/*++
void UpdateStatusText:
If the dialog is up, updates Status Text and
Arguments:
None.
Return Value:
None.
Author:
Chris Dudley 7/30/1997
Note:
--*/
void CSCStatusDlgThrd::UpdateStatusText( void )
{
if (m_fStatusDlgUp)
{
m_StatusDlg.UpdateStatusText();
}
}
/*++
void Close:
Closes modal dialog if already open
Arguments:
None.
Return Value:
None.
Author:
Chris Dudley 7/30/1997
Note:
--*/
void CSCStatusDlgThrd::Close( void )
{
// Setup for close
if (m_fStatusDlgUp)
{
m_StatusDlg.EndDialog(IDOK);
}
m_fStatusDlgUp = FALSE;
}
/*++
void Update:
This routine updates the UI.
Arguments:
None.
Return Value:
None.
Author:
Chris Dudley 7/30/1997
Note:
--*/
void CSCStatusDlgThrd::Update( void )
{
// Tell the dialog to update its statmonitor, if it's up.
if (m_fStatusDlgUp)
{
m_StatusDlg.RestartMonitor();
}
// Do other updating
UpdateStatusText();
}
/////////////////////////////////////////////////////////////////////////////
//
// CSCStatusDlg dialog
//
CSCStatusDlg::CSCStatusDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSCStatusDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSCStatusDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDI_SC_READERLOADED_V2);
// Other initialization
m_fEventsGood = FALSE;
m_hSCardContext = NULL;
m_aIdleList.RemoveAll();
UpdateLogonLockInfo();
}
void CSCStatusDlg::UpdateLogonLockInfo(void)
{
m_pstrLogonReader = &(((CSCStatusApp*)AfxGetApp())->m_strLogonReader);
m_pstrRemovalText = &(((CSCStatusApp*)AfxGetApp())->m_strRemovalText);
m_fLogonLock = (!(m_pstrLogonReader->IsEmpty()));
}
void CSCStatusDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSCStatusDlg)
DDX_Control(pDX, IDC_SCARD_LIST, m_SCardList);
DDX_Control(pDX, IDC_ALERT, m_btnAlert);
DDX_Control(pDX, IDC_INFO, m_ediInfo);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSCStatusDlg, CDialog)
//{{AFX_MSG_MAP(CSCStatusDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_CLOSE()
ON_MESSAGE( WM_READERSTATUSCHANGE, OnReaderStatusChange )
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_ALERT, OnAlertOptions)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//
// CSCStatusDlg Implementation
/*++
BOOL SetContext:
Sets the Context with the resource manager
Arguments:
SCardContext - the context
Return Value:
None.
Author:
Chris Dudley 3/6/1997
Revision History:
Chris Dudley 5/13/1997
--*/
void CSCStatusDlg::SetContext(SCARDCONTEXT hSCardContext)
{
m_hSCardContext = hSCardContext;
}
/*++
void CleanUp:
Routine cleans up for exit
Arguments:
None.
Return Value:
None.
Author:
Chris Dudley 3/11/1997
Revision History:
Chris Dudley 5/13/1997
--*/
void CSCStatusDlg::CleanUp ( void )
{
m_monitor.Stop();
m_SCardList.DeleteAllItems();
}
/*++
void SetIdleList:
Make a local copy of the app's list of readers with idle cards.
Notes:
--*/
void CSCStatusDlg::SetIdleList(CStringArray* paIdleList)
{
m_aIdleList.Copy(*paIdleList);
long lResult = UpdateSCardListCtrl();
}
/*++
void UpdateStatusText:
Reflect card usage status in text. (alert message, howto, etc.)
Notes:
Not localization friendly. Move strings to resources.
--*/
void CSCStatusDlg::UpdateStatusText( void )
{
CString str;
if (k_State_CardIdle == ((CSCStatusApp*)AfxGetApp())->m_dwState)
{
str = _T("A smart card has been left idle. You may safely remove it now.");
}
else
{
str = _T("Click the button on the left to change your alert options.");
}
m_ediInfo.SetWindowText(str);
}
/*++
void InitSCardListCtrl:
This routine sets up the CListCtrl properly for display
Arguments:
None.
Return Value:
None.
Author:
Chris Dudley 3/6/1997
Revision History:
Chris Dudley 5/13/1997
--*/
void CSCStatusDlg::InitSCardListCtrl( void )
{
CString strHeader;
CImageList imageList;
HICON hicon;
// Create columns in list control
strHeader.LoadString(IDS_SC_READER);
m_SCardList.InsertColumn(READER_COLUMN,
strHeader,
LVCFMT_LEFT,
100,
-1);
strHeader.LoadString(IDS_SC_CARDSTATUS);
m_SCardList.InsertColumn(STATUS_COLUMN,
strHeader,
LVCFMT_LEFT,
600,
-1);
strHeader.LoadString(IDS_SC_CARD);
m_SCardList.InsertColumn(CARD_COLUMN,
strHeader,
LVCFMT_LEFT,
100,
-1);
// Create the image list & give it to the list control
imageList.Create ( IMAGE_WIDTH,
IMAGE_HEIGHT,
TRUE, // list does not include masks
NUMBER_IMAGES,
0); // list won't grow
// Build the list
for (int ix = 0; ix < NUMBER_IMAGES; ix++ )
{
// Load icon and add it to image list
hicon = ::LoadIcon(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IMAGE_LIST_IDS[ix]) );
imageList.Add(hicon);
}
// Be sure that all the small icons were added.
_ASSERTE(imageList.GetImageCount() == NUMBER_IMAGES);
m_SCardList.SetImageList(&imageList, (int) LVSIL_SMALL);
imageList.Detach(); // leave the images intact when we go out of scope
}
/*++
LONG UpdateSCardListCtrl:
This routine updates the list box display.
Arguments:
None.
Return Value:
A LONG value indicating the status of the requested action. Please
see the Smartcard header files for additional information.
Author:
Chris Dudley 3/7/1997
Revision History:
Chris Dudley 5/13/1997
Notes:
1. Strings need to be converted from type stored in the smartcard
thread help classes to this dialog's build type (i.e. UNICODE/ANSI)!!!!
--*/
LONG CSCStatusDlg::UpdateSCardListCtrl( void )
{
LONG lReturn = SCARD_S_SUCCESS;
LONG lMoreReaders = SCARD_S_SUCCESS;
CSCardReaderState* pReader;
int nImage = 0;
LV_ITEM lv_item;
CString strCardStatus, strCardName;
//
// If the status monitor is not running,
// Don't bother to update SCardListCtrl
// If there used to be readers, display an error and shut down dialog
//
if (CScStatusMonitor::running != m_monitor.GetStatus())
{
m_SCardList.EnableWindow(FALSE);
DoErrorMessage();
return lReturn;
}
// Setup LV_ITEM struct
lv_item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
// Remove old items from list if required
m_SCardList.DeleteAllItems();
//
// Update the reader information
//
m_monitor.GetReaderStatus(m_aReaderState);
//
// Recreate the items in the reader list (UI)
//
int nNumReaders = (int)m_aReaderState.GetSize();
for(int nIndex = 0; nIndex < nNumReaders; nIndex++)
{
// Setup struct for system reader list
pReader = m_aReaderState[nIndex];
lv_item.state = 0;
lv_item.stateMask = 0;
lv_item.iItem = nIndex;
lv_item.iSubItem = 0;
lv_item.pszText = _T("");
lv_item.cchTextMax = MAX_ITEMLEN;
lv_item.iImage = (int)READEREMPTY;
if (NULL != pReader)
{
lv_item.pszText = (LPTSTR)(LPCTSTR)((m_aReaderState[nIndex])->strReader);
// Get the card status: image
DWORD dwState = (m_aReaderState[nIndex])->dwState;
if (dwState == SC_STATUS_NO_CARD)
{
lv_item.iImage = (int)READEREMPTY;
}
else if (dwState == SC_STATUS_ERROR)
{
lv_item.iImage = (int)READERERROR;
}
else
{
// normally, this would be a "card loaded"...
lv_item.iImage = (int)READERLOADED;
// ...unless the card is the logon/locked card or idle
if (m_fLogonLock &&
(0 == m_pstrLogonReader->Compare((m_aReaderState[nIndex])->strReader)))
{
lv_item.iImage = (int)READERLOCK;
}
else
{
for (int n1=(int)m_aIdleList.GetUpperBound(); n1>=0; n1--)
{
if (m_aIdleList[n1] == (m_aReaderState[nIndex])->strReader)
{
lv_item.iImage = (int)READERINFO;
break;
}
}
}
}
// Add Reader Item
m_SCardList.InsertItem(&lv_item);
// Add Card Name sub item
if (dwState != SC_STATUS_NO_CARD && dwState != SC_STATUS_ERROR)
{
// Set card name if not available
strCardName = (LPCTSTR)(m_aReaderState[nIndex])->strCard;
if (strCardName.IsEmpty())
{
strCardName.LoadString(IDS_SC_NAME_UNKNOWN);
}
m_SCardList.SetItemText(nIndex,
CARD_COLUMN,
strCardName);
}
// Add Card Status sub item
ASSERT(dwState >= SC_STATUS_FIRST && dwState <= SC_STATUS_LAST);
strCardStatus.LoadString(CARD_STATUS_IDS[dwState]);
if (m_fLogonLock &&
(0 == m_pstrLogonReader->Compare((m_aReaderState[nIndex])->strReader)))
{
CString strTemp = *m_pstrRemovalText + strCardStatus;
strCardStatus = strTemp;
}
m_SCardList.SetItemText(nIndex,
STATUS_COLUMN,
strCardStatus);
strCardStatus.Empty();
strCardName.Empty();
}
}
// If we got this far, things are OK. Make sure the window is enabled.
m_SCardList.EnableWindow(TRUE);
return lReturn;
}
/*++
void RestartMonitor:
This routine forces the monitor to refresh its list of readers.
Arguments:
None.
Return Value:
None.
Author:
Amanda Matlosz 11/04/1998
Notes:
--*/
void CSCStatusDlg::RestartMonitor( void )
{
m_monitor.Start(m_hWnd, WM_READERSTATUSCHANGE);
}
/////////////////////////////////////////////////////////////////////////////
//
// CSCStatusDlg message handlers
//
/*++
void OnInitDialog:
Performs dialog initialization.
Arguments:
None.
Return Value:
TRUE if successful and dialog should be displayed. FALSE otherwise.
Author:
Chris Dudley 7/30/1997
Note:
--*/
BOOL CSCStatusDlg::OnInitDialog()
{
LONG lReturn = SCARD_S_SUCCESS;
CDialog::OnInitDialog();
//
// Initialize the CScStatusMonitor
//
m_monitor.Start(m_hWnd, WM_READERSTATUSCHANGE);
//
// Initialize the list control -- whether or not the monitor has started!
//
InitSCardListCtrl();
lReturn = UpdateSCardListCtrl();
//
// Show the dialog IFF the above succeeded
//
if (SCARD_S_SUCCESS == lReturn)
{
// Set the status text
UpdateStatusText();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// set icon for Alerts button
HICON hIcon = AfxGetApp()->LoadIcon(IDI_SC_INFO);
SendDlgItemMessage(IDC_ALERT, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
// Center the dialog and bring it to top
CenterWindow();
SetWindowPos( &wndTop,
0,0,0,0,
SWP_NOMOVE | SWP_NOSIZE);
SetActiveWindow();
// Set Parent to desktop
SetParent(NULL);
}
else
{
//
// If any of the initialization depending on the resource manager failed,
// give up and report a death-due-to-some-error to the caller
//
PostMessage(WM_CLOSE, 0, 0); // need to CANCEL, instead of close...
TRACE_CATCH_UNKNOWN(_T("OnInitDialog"));
}
return TRUE; // return TRUE unless you set the focus to a control
}
/*++
void OnPaint:
Used to paint dialog. In this case, used to draw the icon for the dialog
while minimized/maximized.
Arguments:
None.
Return Value:
None.
Author:
Chris Dudley 7/30/1997
Note:
--*/
void CSCStatusDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
/*++
void OnQueryDragIcon:
The system calls this to obtain the cursor to display while the user drags
the minimized window.
Arguments:
None.
Return Value:
HCURSOR handle to cursor to display
Author:
Chris Dudley 7/30/1997
Note:
--*/
HCURSOR CSCStatusDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
/*++
void DestroyWindow:
This is called by MFC whenever the dialog is closed, whether that is
through WM_CLOSE (sysmenu "X") or EndDialog(IDOK/IDCANCEL)...
Arguments:
None.
Return Value:
Base class version of DestroyWindow.
Author:
Amanda Matlosz 4/29/98
Note:
--*/
BOOL CSCStatusDlg::DestroyWindow()
{
CleanUp();
return CDialog::DestroyWindow();
}
/*++
void OnReaderStatusChange:
This message handler is called by the status thread when smartcard status
has changed.
Arguments:
None.
Return Value:
None
Author:
Chris Dudley 3/9/1997
Revision History:
Chris Dudley 5/13/1997
Note:
1. No formal parameters are declared. These are not used and
will stop compiler warnings from being generated.
--*/
LONG CSCStatusDlg::OnReaderStatusChange( UINT , LONG )
{
// Update the display
UpdateSCardListCtrl();
return 0;
}
/*++
allow user to set alert options (sound, pop-up, neither)
--*/
void CSCStatusDlg::OnAlertOptions()
{
COptionsDlg dlg;
dlg.DoModal();
}
/*++
void DoErrorMessage:
This is a helper routine to keep the UI stuff in one place and make sure
the same error messages are handled consistently throughout.
Arguments:
None.
Return Value:
None
Author:
Amanda Matlosz 5/21/98
Revision History:
Note:
1. Consider taking an error code as well as m_monitor.GetStatus()
--*/
void CSCStatusDlg::DoErrorMessage( void )
{
CString strMsg;
BOOL fShutDownDlg = FALSE;
switch(m_monitor.GetStatus())
{
case CScStatusMonitor::no_service:
fShutDownDlg = TRUE;
strMsg.LoadString(IDS_NO_SYSTEM_STATUS);
break;
case CScStatusMonitor::no_readers:
// for now, do nothing!
break;
case CScStatusMonitor::stopped:
// do nothing! This is a clean stop on the way to shutting down.
break;
case CScStatusMonitor::uninitialized:
case CScStatusMonitor::unknown:
case CScStatusMonitor::running:
fShutDownDlg = TRUE;
strMsg.LoadString(IDS_UNKNOWN_ERROR);
}
if (!strMsg.IsEmpty())
{
CString strTitle;
strTitle.LoadString(IDS_TITLE_ERROR);
MessageBox(strMsg, strTitle, MB_OK | MB_ICONINFORMATION);
}
if (fShutDownDlg)
{
PostMessage(WM_CLOSE, 0, 0);
}
}
/////////////////////////////////////////////////////////////////////////////
// COptionsDlg dialog
COptionsDlg::COptionsDlg(CWnd* pParent /*=NULL*/)
: CDialog(COptionsDlg::IDD, pParent)
{
BOOL fSound = FALSE;
BOOL fDlg = FALSE;
switch(((CSCStatusApp*)AfxGetApp())->m_dwAlertOption)
{
case k_AlertOption_IconSound:
fSound = TRUE;
break;
case k_AlertOption_IconSoundMsg:
fSound = TRUE;
case k_AlertOption_IconMsg:
fDlg = TRUE;
break;
}
//{{AFX_DATA_INIT(COptionsDlg)
m_fDlg = fDlg;
m_fSound = fSound;
//}}AFX_DATA_INIT
}
void COptionsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(COptionsDlg)
DDX_Check(pDX, IDC_DIALOG, m_fDlg);
DDX_Check(pDX, IDC_SOUND, m_fSound);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(COptionsDlg, CDialog)
//{{AFX_MSG_MAP(COptionsDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COptionsDlg message handlers
void COptionsDlg::OnOK()
{
// use status of check boxes to set alert options state for app
UpdateData(TRUE);
if (TRUE == m_fSound)
{
if (TRUE == m_fDlg)
{
((CSCStatusApp*)AfxGetApp())->m_dwAlertOption = k_AlertOption_IconSoundMsg;
}
else
{
((CSCStatusApp*)AfxGetApp())->m_dwAlertOption = k_AlertOption_IconSound;
}
}
else if (TRUE == m_fDlg)
{
((CSCStatusApp*)AfxGetApp())->m_dwAlertOption = k_AlertOption_IconMsg;
}
else
{
((CSCStatusApp*)AfxGetApp())->m_dwAlertOption = k_AlertOption_IconOnly;
}
CDialog::OnOK();
}