📄 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; i<n; i++)
{
resApdu.len = sizeof(ResData);
ScReader.Select(TelFile[i].id,resApdu);
FileSize = (ResData[2]<<8)|ResData[3];
StructOfEF = ResData[13];
if(StructOfEF)//no transparent
{
RecordLen = ResData[14];
NumOfRecs = FileSize/RecordLen;
tmp_str.Format(_T("File size %d, Record length %d, Number of records %d"),
FileSize,RecordLen, NumOfRecs);
}else
tmp_str.Format(_T("File size %d"),FileSize);
TRACE("%s: %s\n",TelFile[i].name,tmp_str);
m_listInfo.AddItem(nItem,0,TelFile[i].name);
m_listInfo.AddItem(nItem,1,tmp_str);
m_listInfo.AddItem(nItem,2,TelFile[i].desc);
nItem++;
}
}catch(LONG e)
{
if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000)
;//AfxMessageBox(ScReader.FormatErrMsg(e));
else
Helper::ShowLastError(e);
}
}
void CScCardInfo::UpdateLP()
{
static LPCTSTR CC[] = {
_T("German"),
_T("English"),
_T("Italian"),
_T("French"),
_T("Spanish"),
_T("Dutch"),
_T("Swedish"),
_T("Danish"),
_T("Portuguese"),
_T("Finnish"),
_T("Norwegian"),
_T("Greek"),
_T("Turkish"),
_T("Reserved for European languages"),
_T("Reserved for European languages"),
_T("Language unspecified")
};
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(0x6f05,resApdu);
int FileSize = (ResData[2]<<8)|ResData[3];
resApdu.len = FileSize + 2;
ScReader.ReadBinary(0,0,resApdu);
CString str;
for(int i=0; i<FileSize; i++)
{
if(ResData[i] < 16)
{
str += CC[ResData[i]];
str += _T(" ");
}
else
break;
}
TRACE(_T("LP:%s\n"),str);
int nItem = m_listInfo.GetItemCount();
m_listInfo.AddItem(nItem,0,_T("LP"));
m_listInfo.AddItem(nItem,1,str);
m_listInfo.AddItem(nItem,2,_T("Language Preference"));
}catch(LONG e)
{
if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000)
AfxMessageBox(ScReader.FormatErrMsg(e));
else
Helper::ShowLastError(e);
}
}
void CScCardInfo::UpdateIMSI()
{
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(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()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -