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


// ScCardInfo.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "agsm2.h" 
#include "agsm2Dlg.h" 
#include "ScCardInfo.h" 
#include "PcScCtrl.h" 
#include "Helper.h" 
#include "ref/parseATR.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CScCardInfo property page 
 
IMPLEMENT_DYNCREATE(CScCardInfo, CScPropertyPage) 
 
CScCardInfo::CScCardInfo() : CScPropertyPage(CScCardInfo::IDD) 
{ 
	//{{AFX_DATA_INIT(CScCardInfo) 
	//}}AFX_DATA_INIT 
} 
 
CScCardInfo::~CScCardInfo() 
{ 
} 
 
void CScCardInfo::DoDataExchange(CDataExchange* pDX) 
{ 
	CPropertyPage::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CScCardInfo) 
	DDX_Control(pDX, IDC_LIST_INFO, m_listInfo); 
	//}}AFX_DATA_MAP 
} 
 
 
BEGIN_MESSAGE_MAP(CScCardInfo, CScPropertyPage) 
	//{{AFX_MSG_MAP(CScCardInfo) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CScCardInfo message handlers 
 
BOOL CScCardInfo::OnInitDialog()  
{ 
	CScPropertyPage::OnInitDialog(); 
	 
	// TODO: Add extra initialization here 
	m_listInfo.SetExtendedStyle(LVS_EX_FULLROWSELECT| 
								//	LVS_EX_GRIDLINES| 
									LVS_EX_HEADERDRAGDROP); 
	CString name((LPCSTR)IDS_STRING130); 
	CString value((LPCSTR)IDS_STRING_VALUE); 
	CString desc((LPCSTR)IDS_STRING_DESC); 
	m_listInfo.InsertColumn(0,name,LVCFMT_LEFT,80); 
	m_listInfo.InsertColumn(1,value,LVCFMT_LEFT,250); 
	m_listInfo.InsertColumn(2,desc,LVCFMT_LEFT,150); 
 
	UpdateATR(); 
	UpdateICCID(); 
	UpdateMF(); 
	//Telecom 
	int nItem = m_listInfo.GetItemCount(); 
	m_listInfo.AddItem(nItem,0,_T("DF(TELECOM)")); 
	m_listInfo.AddItem(nItem,1,_T("---------------------------------------")); 
	UpdateFileSize(); 
	//GSM 
	nItem = m_listInfo.GetItemCount(); 
	m_listInfo.AddItem(nItem,0,_T("DF(GSM)")); 
	m_listInfo.AddItem(nItem,1,_T("---------------------------------------")); 
	UpdateLP(); 
	UpdateIMSI(); 
	UpdateKc(); 
	UpdatePLMNsel(); 
	UpdateACMmax(); 
	UpdateSST(); 
	UpdateSPN(); 
	UpdatePUCT(); 
	UpdatePhase(); 
	return TRUE;  // return TRUE unless you set the focus to a control 
	              // EXCEPTION: OCX Property Pages should return FALSE 
} 
 
CScListCtrl* CScCardInfo::GetListCtrl() 
{ 
	return &m_listInfo; 
} 
 
 
void CScCardInfo::UpdateATR() 
{ 
			// TODO: Add your control notification handler code here 
	TCHAR           szReader[200]; 
	DWORD           cch = 200; 
	BYTE            bAttr[32]; 
	DWORD           cByte = 32; 
	DWORD           dwState, dwProtocol; 
	LONG            lReturn; 
 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
 
	// Determine the status. 
	// hCardHandle was set by an earlier call to SCardConnect. 
	lReturn = ScReader.SCardStatus( 
						  szReader, 
						  &cch, 
						  &dwState, 
						  &dwProtocol, 
						  (LPBYTE)&bAttr, 
						  &cByte);  
 
	if ( SCARD_S_SUCCESS != lReturn ) 
	{ 
		TRACE("Failed SCardStatus\n"); 
	} 
 
	// Examine retrieved status elements. 
	// Here, we'll look at the reader name and card state. 
	TRACE("%S\n", szReader ); 
	switch ( dwState ) 
	{ 
		case SCARD_ABSENT: 
			TRACE("Card absent.\n"); 
			break; 
		case SCARD_PRESENT: 
			TRACE("Card present.\n"); 
			break; 
		case SCARD_SWALLOWED: 
			TRACE("Card swallowed.\n"); 
			break; 
		case SCARD_POWERED: 
			TRACE("Card has power.\n"); 
			break; 
		case SCARD_NEGOTIABLE: 
			TRACE("Card reset and waiting PTS negotiation.\n"); 
			break; 
		case SCARD_SPECIFIC: 
			TRACE("Card has specific communication protocols set.\n"); 
			break; 
		default: 
			TRACE("Unknown or unexpected card state.\n"); 
			break; 
	} 
	//BYTE GiDeAtr[] = {0x3B, 0xB7, 0x94, 0x00, 0x81, 0x31, 0xFE, 0x65, 0x53, 0x50, 0x4B, 0x32, 0x33, 0x90, 0x00, 0xD1}; 
 
	LPSTR atrStr = Helper::BinToHex(bAttr,cByte); 
	//LPSTR atrStr = Helper::BinToHex(GiDeAtr,sizeof(GiDeAtr)); 
	TRACE("ATR:%s\n",atrStr); 
	int nItem = m_listInfo.GetItemCount(); 
	m_listInfo.AddItem(nItem,0,_T("ATR")); 
	m_listInfo.AddItem(nItem,1,atrStr); 
	m_listInfo.AddItem(nItem,2,_T("Answer To Reset")); 
 
	SCARD_CARD_CAPABILITIES ScardCapabilities; 
	memset(&ScardCapabilities,0,sizeof(SCARD_CARD_CAPABILITIES)); 
	CString retStr = parseATR(bAttr,cByte,&ScardCapabilities); 
	//CString retStr = parseATR(GiDeAtr,sizeof(GiDeAtr),&ScardCapabilities); 
	nItem++; 
	if(!retStr.IsEmpty()) 
	{ 
		m_listInfo.AddItem(nItem,0,_T("")); 
		m_listInfo.AddItem(nItem,1,retStr); 
	}else{ 
		retStr.Format( 
			_T("Card parameters from ATR: Fl = %02x (%ld KHz), Dl = %02x, I = %02x, P = %02x, N = %02x"), 
			ScardCapabilities.Fl, 
			ClockRateConversion[ScardCapabilities.Fl].fs / 1000, 
			ScardCapabilities.Dl, 
			ScardCapabilities.II, 
			ScardCapabilities.P, 
			ScardCapabilities.N 
			); 
		m_listInfo.AddItem(nItem,0,_T("")); 
		m_listInfo.AddItem(nItem,1,retStr); 
 
		nItem++; 
		retStr.Format( 
			_T("Calculated timing values: Work etu = %ld micro sec, Guard time = %ld micro sec"), 
			ScardCapabilities.etu, 
			ScardCapabilities.GT); 
		m_listInfo.AddItem(nItem,0,_T("")); 
		m_listInfo.AddItem(nItem,1,retStr); 
 
		if(ScardCapabilities.Protocol.Supported & SCARD_PROTOCOL_T0) 
		{ 
			nItem++; 
			retStr.Format( 
				_T("T=0 Values from ATR:WI = %ld, WT = %ld ms\n"), 
				ScardCapabilities.T0.WI, 
				ScardCapabilities.T0.WT / 1000 
				); 
			m_listInfo.AddItem(nItem,0,_T("")); 
			m_listInfo.AddItem(nItem,1,retStr); 
		} 
		if(ScardCapabilities.Protocol.Supported & SCARD_PROTOCOL_T1) 
		{ 
			nItem++; 
			retStr.Format( 
				_T("T=1 Values from ATR:IFSC = %ld, CWI = %ld, BWI = %ld, EDC = %02x"), 
				ScardCapabilities.T1.IFSC, 
				ScardCapabilities.T1.CWI, 
				ScardCapabilities.T1.BWI, 
				ScardCapabilities.T1.EDC 
				); 
			m_listInfo.AddItem(nItem,0,_T("")); 
			m_listInfo.AddItem(nItem,1,retStr); 
 
			nItem++; 
			retStr.Format( 
				_T("T=1 Timing from ATR:CWT = %ld ms, BWT = %ld ms\n"), 
				ScardCapabilities.T1.CWT / 1000, 
				ScardCapabilities.T1.BWT / 1000 
				); 
			m_listInfo.AddItem(nItem,0,_T("")); 
			m_listInfo.AddItem(nItem,1,retStr); 
	 
		} 
 
 
 
	} 
 
 
	free(atrStr); 
 
} 
 
 
void CScCardInfo::UpdateICCID() 
{ 
	BYTE ResData[255]; 
	RESAPDU resApdu; 
	resApdu.data = ResData; 
	resApdu.len = sizeof(ResData); 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = FALSE; 
		ScReader.Select(0x3f00,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x2fe2,resApdu); 
		ScReader.m_bGetRes = TRUE; 
		resApdu.len = 12; 
		ScReader.ReadBinary(0,0,resApdu); 
		CString str = Helper::BcdToAscii(ResData, 10); 
		TRACE(_T("ICCID:%s\n"),str); 
		int nItem = m_listInfo.GetItemCount(); 
		m_listInfo.AddItem(nItem,0,_T("ICCID")); 
		m_listInfo.AddItem(nItem,1,str); 
		m_listInfo.AddItem(nItem,2,_T("ICC Identification")); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
 
 
} 
 
void CScCardInfo::UpdateFileSize() 
{ 
	static struct { 
		USHORT	id; 
		LPCTSTR	name; 
		LPCTSTR desc; 
	}TelFile[] = { 
		{0x6f3a, _T("ADN"), _T("Abbreviated numbers(΅η»°²Ύ)")}, 
		{0x6f3b, _T("FDN"), _T("Fixed dialling numbers")}, 
		{0x6f3c, _T("SMS"), _T("Short messages(ΆΜΠΕ)")}, 
		{0x6f40, _T("MSISDN"), _T("")}, 
		{0x6f42, _T("SMSP"), _T("Short message service parameters")}, 
		{0x6f43, _T("SMSS"), _T("SMS status")}, 
		{0x6f44, _T("LND"), _T("Last number dialled")}, 
		{0x6f4a, _T("EXT1"), _T("Extension1")}, 
		{0x6f4b, _T("EXT2"), _T("Extension2")}, 
		{0x6f3d, _T("CCP"), _T("Capability configuration parameters")} 
	}; 
 
	BYTE ResData[255]; 
	RESAPDU resApdu; 
	resApdu.data = ResData; 
	resApdu.len = sizeof(ResData); 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = FALSE; 
		ScReader.Select(0x3f00,resApdu); 
 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x7f10,resApdu); 
 
		ScReader.m_bGetRes = TRUE; 
		int FileSize,RecordLen,NumOfRecs,StructOfEF; 
		int nItem = m_listInfo.GetItemCount(); 
		CString tmp_str; 
		int n = sizeof(TelFile)/sizeof(TelFile[0]); 
		for(int i=0; im_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = FALSE; 
		ScReader.Select(0x3f00,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x7f20,resApdu); 
		ScReader.m_bGetRes = TRUE; 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f05,resApdu); 
		 
		int FileSize = (ResData[2]<<8)|ResData[3]; 
		resApdu.len = FileSize + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		CString str; 
		for(int i=0; im_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = FALSE; 
		ScReader.Select(0x3f00,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x7f20,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f07,resApdu); 
		ScReader.m_bGetRes = TRUE; 
	 
		resApdu.len = 9 + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		CString str = Helper::BcdToAscii(ResData+1, ResData[0]); 
		TRACE(_T("IMSI:%s\n"),str); 
		int nItem = m_listInfo.GetItemCount(); 
		m_listInfo.AddItem(nItem,0,_T("IMSI")); 
		m_listInfo.AddItem(nItem,1,str); 
		m_listInfo.AddItem(nItem,2,_T("International Mobile Subscriber Identity")); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
 
} 
 
void CScCardInfo::UpdatePhase() 
{ 
	BYTE ResData[255]; 
	RESAPDU resApdu; 
	resApdu.data = ResData; 
	resApdu.len = sizeof(ResData); 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = FALSE; 
		ScReader.Select(0x3f00,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x7f20,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6fae,resApdu); 
		ScReader.m_bGetRes = TRUE; 
	 
		resApdu.len = 1 + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		CString str; 
		str.Format(_T("%d"),ResData[0]); 
		TRACE(_T("Phase:%s\n"),str); 
		int nItem = m_listInfo.GetItemCount(); 
		m_listInfo.AddItem(nItem,0,_T("Phase")); 
		m_listInfo.AddItem(nItem,1,str); 
		m_listInfo.AddItem(nItem,2,_T("Phase Identification")); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
 
 
} 
 
void CScCardInfo::UpdateSPN() 
{ 
	BYTE ResData[255]; 
	RESAPDU resApdu; 
	resApdu.data = ResData; 
	resApdu.len = sizeof(ResData); 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = FALSE; 
		ScReader.Select(0x3f00,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x7f20,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f46,resApdu); 
		ScReader.m_bGetRes = TRUE; 
	 
		resApdu.len = 17 + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		CString str = Helper::Gsm11EncStrToCStr(ResData+1,16); 
		TRACE(_T("SPN:%s\n"),str); 
		int nItem = m_listInfo.GetItemCount(); 
		m_listInfo.AddItem(nItem,0,_T("SPN")); 
		m_listInfo.AddItem(nItem,1,str); 
		m_listInfo.AddItem(nItem,2,_T("Service Provider Name")); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			;//AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
} 
 
void CScCardInfo::UpdateMF() 
{ 
	static LPCTSTR const ClockStopStr[] = { 
		_T("Clock stop not allow"), 
		_T("Clock stop not allowed,unless at low level"), 
		_T("Clock stop not allowed,unless at high level"), 
		_T(""), 
		_T("Clock stop allowed,no preferred level"), 
		_T("Clock stop allowed,low level preferred"), 
		_T("Clock stop allowed,high level preferred") 
	}; 
 
	BYTE m_MFData[255]; 
	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); 
		int nClockStopMode = (  ((m_MFData[13]&0x01) << 2) |  
								((m_MFData[13]&0x04) >> 1) | 
								((m_MFData[13]&0x08) >> 3) 
							 ); 
		int nNumOfDFs = m_MFData[14]; 
		int nNumOfEFs = m_MFData[15]; 
		int nNumOfChvs = m_MFData[16]; 
		BOOL bCHV1Disabled = ((m_MFData[13] & 0x80) == 0x80); 
		BOOL bCHV1Initialised = ((m_MFData[18] & 0x80) == 0x80); 
		int nCHV1FalseRemains = (m_MFData[18] & 0xf); 
		BOOL bUnblock1Initialised = ((m_MFData[19] & 0x80) == 0x80); 
		int nUnblock1FalseRemains = (m_MFData[19] & 0xf); 
		BOOL bCHV2Initialised = ((m_MFData[20] & 0x80) == 0x80); 
		int nCHV2FalseRemains = (m_MFData[20] & 0xf); 
		BOOL bUnblock2Initialised = ((m_MFData[21] & 0x80) == 0x80); 
		int nUnblock2FalseRemains = (m_MFData[21] & 0xf); 
		int nItem = m_listInfo.GetItemCount(); 
		m_listInfo.AddItem(nItem,0,_T("MF")); 
		CString str; 
		str.Format(_T("CHV1 %s"),bCHV1Disabled ? _T("Disabled") : _T("Enabled")); 
		m_listInfo.AddItem(nItem,1,str); 
 
		nItem++; 
		m_listInfo.AddItem(nItem,0,_T("")); 
		m_listInfo.AddItem(nItem,1,ClockStopStr[nClockStopMode]); 
 
		nItem++; 
		str.Format(_T("Number of DFs %d"),nNumOfDFs); 
		m_listInfo.AddItem(nItem,0,_T("")); 
		m_listInfo.AddItem(nItem,1,str); 
 
		nItem++; 
		str.Format(_T("Number of EFs %d"),nNumOfEFs); 
		m_listInfo.AddItem(nItem,0,_T("")); 
		m_listInfo.AddItem(nItem,1,str); 
 
		nItem++; 
		str.Format(_T("CHVs UNBLOCK CHVs length %d"),nNumOfChvs); 
		m_listInfo.AddItem(nItem,0,_T("")); 
		m_listInfo.AddItem(nItem,1,str); 
 
		nItem++; 
		str.Format(_T("CHV1 secret code %s,False presentations remaining %d"), 
						bCHV1Initialised ? _T("initialised") : _T("not initialised"), 
						nCHV1FalseRemains); 
		m_listInfo.AddItem(nItem,0,_T("")); 
		m_listInfo.AddItem(nItem,1,str); 
 
		nItem++; 
		str.Format(_T("UNBLOCK CHV1 secret code %s,False presentations remaining %d"), 
						bUnblock1Initialised ? _T("initialised") : _T("not initialised"), 
						nUnblock1FalseRemains); 
		m_listInfo.AddItem(nItem,0,_T("")); 
		m_listInfo.AddItem(nItem,1,str); 
 
		nItem++; 
		str.Format(_T("CHV2 secret code %s,False presentations remaining %d"), 
						bCHV2Initialised ? _T("initialised") : _T("not initialised"), 
						nCHV2FalseRemains); 
		m_listInfo.AddItem(nItem,0,_T("")); 
		m_listInfo.AddItem(nItem,1,str); 
 
		nItem++; 
		str.Format(_T("UNBLOCK CHV2 secret code %s,False presentations remaining %d"), 
						bUnblock2Initialised ? _T("initialised") : _T("not initialised"), 
						nUnblock2FalseRemains); 
		m_listInfo.AddItem(nItem,0,_T("")); 
		m_listInfo.AddItem(nItem,1,str); 
 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
 
 
} 
 
void CScCardInfo::UpdateKc() 
{ 
	BYTE ResData[255]; 
	RESAPDU resApdu; 
	resApdu.data = ResData; 
	resApdu.len = sizeof(ResData); 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = FALSE; 
		ScReader.Select(0x3f00,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x7f20,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f20,resApdu); 
		ScReader.m_bGetRes = TRUE; 
	 
		resApdu.len = 9 + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		LPSTR pStr = Helper::BinToHex(ResData, 9); 
		TRACE(_T("Kc:%s\n"),pStr); 
		int nItem = m_listInfo.GetItemCount(); 
		m_listInfo.AddItem(nItem,0,_T("Kc")); 
		m_listInfo.AddItem(nItem,1,pStr); 
		m_listInfo.AddItem(nItem,2,_T("ciphering key Kc")); 
		free(pStr); 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
 
} 
 
void CScCardInfo::UpdatePLMNsel() 
{ 
	BYTE ResData[255]; 
	RESAPDU resApdu; 
	resApdu.data = ResData; 
	resApdu.len = sizeof(ResData); 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = FALSE; 
		ScReader.Select(0x3f00,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x7f20,resApdu); 
 
		ScReader.m_bGetRes = TRUE; 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f30,resApdu); 
		 
		int FileSize = (ResData[2]<<8)|ResData[3]; 
		resApdu.len = FileSize + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		LPSTR pStr = Helper::BinToHex(ResData, FileSize); 
		TRACE(_T("PLMNsel:%s\n"),pStr); 
		int nItem = m_listInfo.GetItemCount(); 
		m_listInfo.AddItem(nItem,0,_T("PLMNsel")); 
		m_listInfo.AddItem(nItem,1,pStr); 
		m_listInfo.AddItem(nItem,2,_T("PLMN selector")); 
		free(pStr); 
 
		ScReader.m_bGetRes = FALSE; 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f31,resApdu); 
		resApdu.len = 1 + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		CString str; 
		str.Format(_T("%d"),ResData[0]); 
		TRACE(_T("HPLMN:%s\n"),str); 
		nItem++; 
		m_listInfo.AddItem(nItem,0,_T("HPLMN")); 
		m_listInfo.AddItem(nItem,1,str); 
		m_listInfo.AddItem(nItem,2,_T("HPLMN search period")); 
 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
 
} 
 
void CScCardInfo::UpdateACMmax() 
{ 
	BYTE ResData[255]; 
	RESAPDU resApdu; 
	resApdu.data = ResData; 
	resApdu.len = sizeof(ResData); 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = FALSE; 
		ScReader.Select(0x3f00,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x7f20,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f37,resApdu); 
 
		resApdu.len = 3 + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		CString str; 
		str.Format(_T("%d"),(ResData[0] << 16) | (ResData[1] << 8) | ResData[2]); 
		int nItem = m_listInfo.GetItemCount(); 
		m_listInfo.AddItem(nItem,0,_T("ACMmax")); 
		m_listInfo.AddItem(nItem,1,str); 
		m_listInfo.AddItem(nItem,2,_T("Maximum value of accumulated call meter")); 
 
		resApdu.len = sizeof(ResData); 
		ScReader.m_bGetRes = TRUE; 
		ScReader.Select(0x6f39,resApdu); 
		int FileSize = (ResData[2]<<8)|ResData[3]; 
		int RecordLen = ResData[14]; 
		int NumOfRecs = FileSize/RecordLen; 
 
		nItem++; 
		m_listInfo.AddItem(nItem,0,_T("ACM")); 
		m_listInfo.AddItem(nItem,2,_T("Accumulated call meter")); 
		resApdu.len = RecordLen + 2; 
		ScReader.ReadRecord(0,RRM_NextRecord,resApdu); 
		CString sstr; 
		sstr.Format(_T("%d"),(ResData[0] << 16) | (ResData[1] << 8) | ResData[2]); 
		for(int i=1; im_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = FALSE; 
		ScReader.Select(0x3f00,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x7f20,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f38,resApdu); 
 
		resApdu.len = 5 + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		int nItem = m_listInfo.GetItemCount(); 
		m_listInfo.AddItem(nItem,0,_T("SST")); 
		m_listInfo.AddItem(nItem,1,"++(allocated activated)"); 
		m_listInfo.AddItem(nItem,2,_T("SIM service table")); 
		CString str; 
		UCHAR a,b,s; 
		for(int i=0; i>s; 
			str += MinusPlus[b&1]; 
			str += MinusPlus[(b&2)>>1]; 
			m_listInfo.AddItem(nItem,1,str); 
		} 
 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
} 
 
void CScCardInfo::UpdatePUCT() 
{ 
	BYTE ResData[255]; 
	RESAPDU resApdu; 
	resApdu.data = ResData; 
	resApdu.len = sizeof(ResData); 
	CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader; 
 
	try{ 
		ScReader.m_bGetRes = FALSE; 
		ScReader.Select(0x3f00,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x7f20,resApdu); 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f41,resApdu); 
	 
		resApdu.len = 5 + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		LPSTR pStr = Helper::BinToHex(ResData, 5); 
		TRACE(_T("PUCT:%s\n"),pStr); 
		int nItem = m_listInfo.GetItemCount(); 
		m_listInfo.AddItem(nItem,0,_T("PUCT")); 
		m_listInfo.AddItem(nItem,1,pStr); 
		m_listInfo.AddItem(nItem,2,_T("Price per unit and currency table")); 
		free(pStr); 
 
		nItem++; 
		ScReader.m_bGetRes = TRUE; 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f45,resApdu); 
		int FileSize = (ResData[2]<<8)|ResData[3]; 
		resApdu.len = FileSize + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		pStr = Helper::BinToHex(ResData, FileSize); 
		TRACE(_T("CBMI:%s\n"),pStr); 
		m_listInfo.AddItem(nItem,0,_T("CBMI")); 
		m_listInfo.AddItem(nItem,1,pStr); 
		m_listInfo.AddItem(nItem,2,_T("Cell broadcast message identifier selection")); 
		free(pStr); 
 
		nItem++; 
		ScReader.m_bGetRes = TRUE; 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f74,resApdu); 
		FileSize = (ResData[2]<<8)|ResData[3]; 
		resApdu.len = FileSize + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		pStr = Helper::BinToHex(ResData, FileSize); 
		TRACE(_T("BCCH:%s\n"),pStr); 
		m_listInfo.AddItem(nItem,0,_T("BCCH")); 
		m_listInfo.AddItem(nItem,1,pStr); 
		m_listInfo.AddItem(nItem,2,_T("Broadcast control channels")); 
		free(pStr); 
 
		nItem++; 
		ScReader.m_bGetRes = TRUE; 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f78,resApdu); 
		FileSize = (ResData[2]<<8)|ResData[3]; 
		resApdu.len = FileSize + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		pStr = Helper::BinToHex(ResData, FileSize); 
		TRACE(_T("ACC:%s\n"),pStr); 
		m_listInfo.AddItem(nItem,0,_T("ACC")); 
		m_listInfo.AddItem(nItem,1,pStr); 
		m_listInfo.AddItem(nItem,2,_T("Access control class")); 
		free(pStr); 
 
		nItem++; 
		ScReader.m_bGetRes = TRUE; 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f7b,resApdu); 
		FileSize = (ResData[2]<<8)|ResData[3]; 
		resApdu.len = FileSize + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		pStr = Helper::BinToHex(ResData, FileSize); 
		TRACE(_T("FPLMN:%s\n"),pStr); 
		m_listInfo.AddItem(nItem,0,_T("FPLMN")); 
		m_listInfo.AddItem(nItem,1,pStr); 
		m_listInfo.AddItem(nItem,2,_T("Forbidden PLMNs")); 
		free(pStr); 
 
		nItem++; 
		ScReader.m_bGetRes = TRUE; 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6f7e,resApdu); 
		FileSize = (ResData[2]<<8)|ResData[3]; 
		resApdu.len = FileSize + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		pStr = Helper::BinToHex(ResData, FileSize); 
		TRACE(_T("LOCI:%s\n"),pStr); 
		m_listInfo.AddItem(nItem,0,_T("LOCI")); 
		m_listInfo.AddItem(nItem,1,pStr); 
		m_listInfo.AddItem(nItem,2,_T("Location information")); 
		free(pStr); 
 
		nItem++; 
		ScReader.m_bGetRes = TRUE; 
		resApdu.len = sizeof(ResData); 
		ScReader.Select(0x6fad,resApdu); 
		FileSize = (ResData[2]<<8)|ResData[3]; 
		resApdu.len = FileSize + 2; 
		ScReader.ReadBinary(0,0,resApdu); 
		pStr = Helper::BinToHex(ResData, FileSize); 
		TRACE(_T("AD:%s\n"),pStr); 
		m_listInfo.AddItem(nItem,0,_T("AD")); 
		m_listInfo.AddItem(nItem,1,pStr); 
		m_listInfo.AddItem(nItem,2,_T("Administrative data")); 
		free(pStr); 
 
 
	}catch(LONG e) 
	{ 
		if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000) 
			AfxMessageBox(ScReader.FormatErrMsg(e)); 
		else 
			Helper::ShowLastError(e); 
	} 
 
 
}