www.pudn.com > agsm2-1.2_src.zip > ScPinPage.cpp


// ScPin.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "agsm2.h" 
#include "agsm2Dlg.h" 
#include "ScPinPage.h" 
#include "PcScCtrl.h" 
#include "Helper.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CScPinPage property page 
 
IMPLEMENT_DYNCREATE(CScPinPage, CScPropertyPage) 
 
CScPinPage::CScPinPage() : CScPropertyPage(CScPinPage::IDD) 
{ 
	//{{AFX_DATA_INIT(CScPinPage) 
	m_Pin = _T(""); 
	m_newPin = _T(""); 
	m_Unblock = _T(""); 
	m_PinStatus = _T(""); 
	m_Freq = -1; 
	m_FlDl = 0; 
	//}}AFX_DATA_INIT 
} 
 
CScPinPage::~CScPinPage() 
{ 
} 
 
void CScPinPage::DoDataExchange(CDataExchange* pDX) 
{ 
	CScPropertyPage::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CScPinPage) 
	DDX_Control(pDX, IDC_BUTTON_VERIFY, m_ButtonVerify); 
	DDX_Control(pDX, IDC_BUTTON_UNBLOCK, m_ButtonUnblock); 
	DDX_Control(pDX, IDC_BUTTON_DISABLE, m_ButtonDisable); 
	DDX_Control(pDX, IDC_BUTTON_CHANGE, m_ButtonChange); 
	DDX_Text(pDX, IDC_EDIT_PIN, m_Pin); 
	DDV_MaxChars(pDX, m_Pin, 8); 
	DDX_Text(pDX, IDC_EDIT_NEW_PIN, m_newPin); 
	DDV_MaxChars(pDX, m_newPin, 8); 
	DDX_Text(pDX, IDC_EDIT_UNBLOCK, m_Unblock); 
	DDV_MaxChars(pDX, m_Unblock, 16); 
	DDX_Text(pDX, IDC_STATIC_PIN_STATUS, m_PinStatus); 
	DDX_Radio(pDX, IDC_RADIO1, m_Freq); 
	DDX_Radio(pDX, IDC_RADIO4, m_FlDl); 
	//}}AFX_DATA_MAP 
} 
 
 
BEGIN_MESSAGE_MAP(CScPinPage, CScPropertyPage) 
	//{{AFX_MSG_MAP(CScPinPage) 
	ON_EN_CHANGE(IDC_EDIT_PIN, OnChangeEditPin) 
	ON_BN_CLICKED(IDC_BUTTON_VERIFY, OnButtonVerify) 
	ON_BN_CLICKED(IDC_BUTTON_DISABLE, OnButtonDisable) 
	ON_EN_CHANGE(IDC_EDIT_NEW_PIN, OnChangeEditNewPin) 
	ON_BN_CLICKED(IDC_BUTTON_CHANGE, OnButtonChange) 
	ON_BN_CLICKED(IDC_RADIO1, OnRadio1) 
	ON_BN_CLICKED(IDC_RADIO4, OnRadio4) 
	ON_EN_CHANGE(IDC_EDIT_UNBLOCK, OnChangeEditUnblock) 
	ON_BN_CLICKED(IDC_BUTTON_UNBLOCK, OnButtonUnblock) 
	ON_BN_CLICKED(IDC_RADIO2, OnRadio1) 
	ON_BN_CLICKED(IDC_RADIO3, OnRadio1) 
	ON_BN_CLICKED(IDC_RADIO5, OnRadio4) 
	ON_BN_CLICKED(IDC_RADIO6, OnRadio4) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CScPinPage message handlers 
 
 
void CScPinPage::OnChangeEditPin()  
{ 
	// TODO: If this is a RICHEDIT control, the control will not 
	// send this notification unless you override the CScPropertyPage::OnInitDialog() 
	// function and call CRichEditCtrl().SetEventMask() 
	// with the ENM_CHANGE flag ORed into the mask. 
	 
	// TODO: Add your control notification handler code here 
	UpdateData(); 
	TRACE("OnChangeEditPin %s\n",m_Pin); 
	if(m_Pin.GetLength() >= 4) 
	{ 
		m_ButtonDisable.EnableWindow(); 
		CString disable((LPCSTR)IDS_STRING_DISABLE); 
		CString str; 
		m_ButtonDisable.GetWindowText(str); 
		if(str == disable) 
			m_ButtonVerify.EnableWindow(); 
		//UpdateData(FALSE); 
	}else{ 
		m_ButtonVerify.EnableWindow(FALSE); 
		m_ButtonDisable.EnableWindow(FALSE); 
	} 
 
} 
 
void CScPinPage::SelectMF() 
{ 
	RESAPDU resApdu; 
	resApdu.data = m_MFData; 
	resApdu.len = sizeof(m_MFData); 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = TRUE; 
		ScReader.Select(0x3f00,resApdu); 
		m_bCHV1Disabled = ((m_MFData[13] & 0x80) == 0x80); 
		m_bCHV1Initialised = ((m_MFData[18] & 0x80) == 0x80); 
		m_nCHV1FalseRemains = (m_MFData[18] & 0xf); 
		m_bUnblock1Initialised = ((m_MFData[19] & 0x80) == 0x80); 
		m_nUnblock1FalseRemains = (m_MFData[19] & 0xf); 
		m_bCHV2Initialised = ((m_MFData[20] & 0x80) == 0x80); 
		m_nCHV2FalseRemains = (m_MFData[20] & 0xf); 
		m_bUnblock2Initialised = ((m_MFData[21] & 0x80) == 0x80); 
		m_nUnblock2FalseRemains = (m_MFData[21] & 0xf); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
 
} 
 
BOOL CScPinPage::OnInitDialog()  
{ 
	CScPropertyPage::OnInitDialog(); 
	 
	// TODO: Add extra initialization here 
	int Fl=1,Dl=1; 
	GetRdrParameters(m_Freq, Fl, Dl); 
	UpdateUI(); 
 
	m_AuthPropSheet.AddPage(&m_GsmAuthPage); 
	m_AuthPropSheet.AddPage(&m_3GPPAuthPage); 
 
 
	CRect rcSheet; 
	GetDlgItem(IDC_STATIC_AUTH_POS)->GetWindowRect( &rcSheet );	 
	ScreenToClient( &rcSheet ); 
	//http://www.codeguru.com/Cpp/controls/propertysheet/article.php/c583/ 
	m_AuthPropSheet.Create(this, WS_CHILD | WS_VISIBLE, 0); 
	m_AuthPropSheet.ModifyStyleEx (0, WS_EX_CONTROLPARENT); 
	m_AuthPropSheet.ModifyStyle( 0, WS_TABSTOP ); 
	 
	m_AuthPropSheet.SetWindowPos(NULL, rcSheet.left, rcSheet.top, 
								rcSheet.Width(), rcSheet.Height(), 
								SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE ); 
 
	m_AuthPropSheet.ShowWindow(SW_NORMAL); 
 
 
	return TRUE;  // return TRUE unless you set the focus to a control 
	              // EXCEPTION: OCX Property Pages should return FALSE 
} 
 
void CScPinPage::UpdateUI() 
{ 
	SelectMF(); 
	CString enable((LPCSTR)IDS_STRING_ENABLE); 
	CString disable((LPCSTR)IDS_STRING_DISABLE); 
	if(m_bCHV1Disabled) 
	{ 
		m_ButtonDisable.SetWindowText(enable); 
		m_ButtonVerify.EnableWindow(FALSE); 
		m_ButtonChange.EnableWindow(FALSE); 
	}else{ 
		m_ButtonDisable.SetWindowText(disable); 
		if(!m_Pin.IsEmpty()) 
		{ 
			m_ButtonVerify.EnableWindow(); 
			if(!m_newPin.IsEmpty()) 
				m_ButtonChange.EnableWindow(); 
		} 
	} 
	if(!m_Pin.IsEmpty()) 
		m_ButtonDisable.EnableWindow(); 
 
	CString str; 
	CString format((LPCSTR)IDS_STRING144); 
	str.Format(format,m_nCHV1FalseRemains); 
	m_PinStatus = str; 
 
	UpdateData(FALSE); 
} 
 
BOOL CScPinPage::OnSetActive()  
{ 
	// TODO: Add your specialized code here and/or call the base class 
	int Fl=1,Dl=1; 
	GetRdrParameters(m_Freq, Fl, Dl); 
	UpdateUI();	 
	return CScPropertyPage::OnSetActive(); 
} 
 
void CScPinPage::OnButtonVerify()  
{ 
	// TODO: Add your control notification handler code here 
	LONG lResult = -1; 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
	BYTE chv[8]; 
	memset(chv,0xff,8); 
	memcpy(chv,m_Pin,m_Pin.GetLength()); 
	try{ 
		lResult = ScReader.VerifyChv(1,chv,8); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
	UpdateUI();	 
	if(lResult == 0x9000) 
	{ 
		CString str((LPCSTR)IDS_STRING145); 
		m_PinStatus = str; 
		UpdateData(FALSE); 
	} 
} 
 
void CScPinPage::OnButtonDisable()  
{ 
	// TODO: Add your control notification handler code here 
	LONG lResult = -1; 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
	BYTE chv[8]; 
	memset(chv,0xff,8); 
	memcpy(chv,m_Pin,m_Pin.GetLength()); 
	CString bs; 
	m_ButtonDisable.GetWindowText(bs); 
	CString enable((LPCSTR)IDS_STRING_ENABLE); 
	try{ 
		if(bs == enable) 
			lResult = ScReader.EnableChv(1,chv); 
		else 
			lResult = ScReader.DisableChv(1,chv); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
	UpdateUI();	 
	if(lResult == 0x9000) 
	{ 
		CString str; 
		CString format((LPCSTR)IDS_STRING146); 
		str.Format(format,bs); 
		m_PinStatus = str; 
		UpdateData(FALSE); 
	} 
	 
} 
 
void CScPinPage::OnChangeEditNewPin()  
{ 
	// TODO: If this is a RICHEDIT control, the control will not 
	// send this notification unless you override the CScPropertyPage::OnInitDialog() 
	// function and call CRichEditCtrl().SetEventMask() 
	// with the ENM_CHANGE flag ORed into the mask. 
	 
	// TODO: Add your control notification handler code here 
	UpdateData(); 
	TRACE("OnChangeEditPin %s\n",m_Pin); 
	if(m_newPin.GetLength() >= 4 && m_Pin.GetLength() >= 4 && 
		!m_bCHV1Disabled 
	  ) 
		m_ButtonChange.EnableWindow(); 
	else 
		m_ButtonChange.EnableWindow(FALSE); 
} 
 
void CScPinPage::OnButtonChange()  
{ 
	// TODO: Add your control notification handler code here 
	LONG lResult = -1; 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
	BYTE chv[16]; 
	memset(chv,0xff,16); 
	memcpy(chv,m_Pin,m_Pin.GetLength()); 
	memcpy(chv+8,m_newPin,m_newPin.GetLength()); 
	try{ 
		lResult = ScReader.ChangeChv(1,chv,16); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
	UpdateUI();	 
	if(lResult == 0x9000) 
	{ 
		CString str((LPCSTR)IDS_STRING147); 
		m_PinStatus = str; 
		UpdateData(FALSE); 
	} 
} 
 
void CScPinPage::OnRadio1()  
{ 
	// TODO: Add your control notification handler clode here 
	UpdateData(); 
	int Freq=1,Fl=1,Dl=1; 
	TRACE("Freq:%d\n",m_Freq); 
	SetRdrParameters(m_Freq, Fl,Dl); 
	GetRdrParameters(m_Freq, Fl, Dl); 
	UpdateData(FALSE); 
} 
 
LONG CScPinPage::GetRdrParameters(int &Freq, int &Fl, int &Dl) 
{ 
	UCHAR Buf[128]; 
	DWORD ret; 
	Buf[0] = PC_to_RDR_GetParameters; 
 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
	LONG lResult = ScReader.SCardControl(IOCTL_USCR_CCID, 
						Buf,128,Buf,128,&ret); 
	if(lResult == 0) 
	{ 
		Freq = Buf[0]; 
		for(DWORD i=0; i> 8) 
#define low(a)  (a&0xff) 
#define clk	0 //smart card clock:0 for 6M Hz,1 for 3M Hz,3 for 1.5M Hz 
 
LONG CScPinPage::SetRdrParameters(int Freq, int Fl, int Dl) 
{ 
	// TODO: Add your control notification handler code here 
	DWORD ret; 
	READER_RELATED_PARAMETER defaultReaderRelatedParameter = { 
		PC_to_RDR_SetParameters, 
		Freq, 
		200, 
		low(60000), 
		high(60000), 
		2, 
		low(124*(Freq+1)), 
		high(124*(Freq+1)), 
		low(372*(Freq+1)), 
		high(372*(Freq+1)), 
		low(744*(Freq+1)), 
		high(744*(Freq+1)) 
		}; 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
	LONG lResult = ScReader.SCardControl(IOCTL_USCR_CCID, 
						&defaultReaderRelatedParameter, 
						sizeof(READER_RELATED_PARAMETER), 
						NULL,0,&ret); 
	return lResult; 
} 
 
void CScPinPage::OnRadio4()  
{ 
	// TODO: Add your control notification handler code here 
	 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CPinDialog dialog 
 
 
CPinDialog::CPinDialog(CWnd* pParent /*=NULL*/) 
	: CDialog(CPinDialog::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CPinDialog) 
	m_pin = _T(""); 
	m_pinStatus = _T(""); 
	//}}AFX_DATA_INIT 
} 
 
 
void CPinDialog::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CPinDialog) 
	DDX_Text(pDX, IDC_EDIT_PIN, m_pin); 
	DDV_MaxChars(pDX, m_pin, 8); 
	DDX_Text(pDX, IDC_STATIC_PIN_STATUS, m_pinStatus); 
	//}}AFX_DATA_MAP 
} 
 
 
BEGIN_MESSAGE_MAP(CPinDialog, CDialog) 
	//{{AFX_MSG_MAP(CPinDialog) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CPinDialog message handlers 
 
void CPinDialog::OnOK()  
{ 
	// TODO: Add extra validation here 
	UpdateData(); 
	LONG lResult = -1; 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
	BYTE chv[8]; 
	memset(chv,0xff,8); 
	memcpy(chv,m_pin,m_pin.GetLength()); 
	try{ 
		lResult = ScReader.VerifyChv(1,chv,8); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
	if(lResult == 0x9000) 
	{ 
		CString str((LPCSTR)IDS_STRING145); 
		m_pinStatus = str; 
		UpdateData(FALSE); 
	}else{ 
		RequirePIN(); 
		CString str; 
		CString format((LPCSTR)IDS_STRING144); 
		str.Format(format,m_nCHV1FalseRemains); 
		m_pinStatus = str; 
		UpdateData(FALSE); 
		return; 
	} 
	 
	CDialog::OnOK(); 
} 
 
BOOL CPinDialog::RequirePIN() 
{ 
	RESAPDU resApdu; 
	resApdu.data = m_MFData; 
	resApdu.len = sizeof(m_MFData); 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = TRUE; 
		ScReader.Select(0x3f00,resApdu); 
		m_bCHV1Disabled = ((m_MFData[13] & 0x80) == 0x80); 
		m_bCHV1Initialised = ((m_MFData[18] & 0x80) == 0x80); 
		m_nCHV1FalseRemains = (m_MFData[18] & 0xf); 
		m_bUnblock1Initialised = ((m_MFData[19] & 0x80) == 0x80); 
		m_nUnblock1FalseRemains = (m_MFData[19] & 0xf); 
		m_bCHV2Initialised = ((m_MFData[20] & 0x80) == 0x80); 
		m_nCHV2FalseRemains = (m_MFData[20] & 0xf); 
		m_bUnblock2Initialised = ((m_MFData[21] & 0x80) == 0x80); 
		m_nUnblock2FalseRemains = (m_MFData[21] & 0xf); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
	return !m_bCHV1Disabled; 
 
} 
 
BOOL CPinDialog::OnInitDialog()  
{ 
	CDialog::OnInitDialog(); 
	 
	// TODO: Add extra initialization here 
	CString str; 
	CString format((LPCSTR)IDS_STRING144); 
	str.Format(format,m_nCHV1FalseRemains); 
	m_pinStatus = str; 
	UpdateData(FALSE); 
 
	return TRUE;  // return TRUE unless you set the focus to a control 
	              // EXCEPTION: OCX Property Pages should return FALSE 
} 
 
void CScPinPage::OnChangeEditUnblock()  
{ 
	// TODO: If this is a RICHEDIT control, the control will not 
	// send this notification unless you override the CScPropertyPage::OnInitDialog() 
	// function and call CRichEditCtrl().SetEventMask() 
	// with the ENM_CHANGE flag ORed into the mask. 
	 
	// TODO: Add your control notification handler code here 
	UpdateData(); 
	TRACE("OnChangeEditPin %s\n",m_Unblock); 
	if(m_Unblock.GetLength() >= 8) 
		m_ButtonUnblock.EnableWindow(); 
	else 
		m_ButtonUnblock.EnableWindow(FALSE); 
	 
} 
 
void CScPinPage::OnButtonUnblock()  
{ 
	// TODO: Add your control notification handler code here 
	// TODO: Add your control notification handler code here 
	LONG lResult = -1; 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
	BYTE unblock[16]; 
	memset(unblock,0xff,16); 
	memcpy(unblock,m_Unblock,m_Unblock.GetLength()); 
	try{ 
		lResult = ScReader.UnblockChv(0,unblock,16); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
	UpdateUI();	 
	if(lResult == 0x9000) 
	{ 
		CString str((LPCSTR)IDS_STRING148); 
		m_PinStatus = str; 
		UpdateData(FALSE); 
	} 
	 
}