⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialdllexampledlg.cpp

📁 基于pc/sc框架的读卡器读写接口程序
💻 CPP
字号:
// SerialDLLExampleDlg.cpp : implementation file
//

#include "stdafx.h"
#include "SerialDLLExample.h"
#include "SerialDLLExampleDlg.h"
#include <winscard.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSerialDLLExampleDlg dialog

CSerialDLLExampleDlg::CSerialDLLExampleDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSerialDLLExampleDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSerialDLLExampleDlg)
	m_Output = _T("");
	m_APDU = _T("");
	m_ErrCode = 0;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	ICDev = NULL;
}

void CSerialDLLExampleDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSerialDLLExampleDlg)
	DDX_Control(pDX, IDC_READERSLIST, m_ReadersList);
	DDX_Text(pDX, IDC_OUTPUT, m_Output);
	DDX_Text(pDX, IDC_APDU, m_APDU);
	DDX_Text(pDX, IDC_ERRCODE, m_ErrCode);
	DDV_MinMaxInt(pDX, m_ErrCode, 0, 120);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSerialDLLExampleDlg, CDialog)
	//{{AFX_MSG_MAP(CSerialDLLExampleDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_INIT, OnInit)
	ON_BN_CLICKED(IDC_EXITCOMM, OnExitcomm)
	ON_BN_CLICKED(IDC_CPURESET, OnCpureset)
	ON_BN_CLICKED(IDC_CHECKCPU, OnCheckcpu)
	ON_BN_CLICKED(IDC_CPUAPDU, OnCpuapdu)
	ON_BN_CLICKED(IDC_GETPROTOCOL, OnGetprotocol)
	ON_BN_CLICKED(IDC_ERRORCODE, OnErrorcode)
	ON_CBN_SELCHANGE(IDC_READERSLIST, OnSelchangeReaderslist)
	ON_BN_CLICKED(IDC_INITWITHNAME, OnInitwithname)
	ON_BN_CLICKED(IDC_INITTYPE, OnInittype)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSerialDLLExampleDlg message handlers

BOOL CSerialDLLExampleDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 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
	
	// TODO: Add extra initialization here
	ListReaders();

	CheckDlgButton(IDC_COM1, BST_CHECKED);   

	m_APDU = "0084000008";

	m_ErrCode = 100;

	UpdateData(false);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CSerialDLLExampleDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CSerialDLLExampleDlg::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();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CSerialDLLExampleDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}
void CSerialDLLExampleDlg::OnInit() 
{
	// TODO: Add your control notification handler code here
	UpdateData(true);

	if( IsDlgButtonChecked(IDC_COM1) )
		Port = 0;
	else if ( IsDlgButtonChecked(IDC_COM2) )
		Port = 1;
	else if( IsDlgButtonChecked(IDC_USB) )
		Port = 100;

	ICDev = IC_InitComm (Port);

	if( ICDev )
	{
		m_Output = " Smart card reader initial success \r\n";
	}
	else
		m_Output = " Smart card reader initial fail \r\n";

	UpdateData(false);
}

void CSerialDLLExampleDlg::OnExitcomm() 
{
	// TODO: Add your control notification handler code here
	short retValue = 0;

	if(ICDev)
		retValue = IC_ExitComm(ICDev);

	if( 0 == retValue )
	{
		m_Output += " Smart card reader exit success \r\n";
	}
	else
		m_Output += " Smart card reader exit fail \r\n";

	ICDev = NULL;

	UpdateData(false);
}

void CSerialDLLExampleDlg::OnCpureset() 
{
	// TODO: Add your control notification handler code here
	unsigned char rlen;
	unsigned char rbuff[32];
		
	LONG lAtrLen , i = 0;

	if( 0 == IC_CpuReset(ICDev,&rlen, rbuff) )
	{
		CString OutString;

        m_Output += "ATR in hex:";

		lAtrLen = rlen;

		while( i < lAtrLen )
		{
			m_Output += " ";
			m_Output += HexToAscii( 0x0F & rbuff[i] >> 4);
			m_Output += HexToAscii( 0x0F & ( rbuff[i]  ) );
			i++;
		}
		m_Output += "\r\n";

		m_Output += "\r\n";
		m_Output += "               ******************************\r\n";
		m_Output += "               * Connect and reset card OK! *\r\n";
		m_Output += "               *          Test OK!          *\r\n";
		m_Output += "               ******************************\r\n";
	}
	else
		m_Output = "CPU Card Reset fail \r\n";


	UpdateData(false);
}

void CSerialDLLExampleDlg::OnCheckcpu() 
{
	// TODO: Add your control notification handler code here
	short CardState = 0;

	CardState = IC_Check_CPU(ICDev);

	if( 0 == CardState )
	{
		m_Output += "Present T0 CPU card \r\n";
	}
	else if( 1 == CardState)
	{
		m_Output += "Present T1 CPU card \r\n";
	}
	else
	{
		m_Output += "Present not support card \r\n";
	}


	UpdateData(false);
}

char CSerialDLLExampleDlg::HexToAscii(unsigned char in)
{
    char out = 0;
    in = in & 0x0F;
    if( ( 0 <= in ) && ( in <= 9 ) )
    {
        out = in + '0';
    }
    else
    {
        out = in + 55;
    }
    return out;
}

void CSerialDLLExampleDlg::AsciiToHex(CString ascii_buf, char *hex_buf) {
	int len;
	int a = 0;
	char ch[3];
	char *end;
	long res;

	len = ascii_buf.GetLength() / 2;

	memset(hex_buf,0, len + 1);

	for(int i=0; i < len; i++) {
		ch[0] = ascii_buf.GetAt(a++);
		ch[1] = ascii_buf.GetAt(a++);
		ch[2] = 0;
		res = strtol(ch, &end, 16);
		hex_buf[i] = char(res);
	}
}

void CSerialDLLExampleDlg::OnCpuapdu() 
{
	// TODO: Add your control notification handler code here	
	UCHAR chDataBuf[256];
	BYTE ReceiveBuffer[261];
	DWORD nDataLength = 0;
	DWORD ReceiveBufferSize = 0;
	ULONG lReturn = 0;
	unsigned char rlen;
	unsigned char slen;
	__int16 iReturn = 0;

	if(!ICDev )
	{
		m_Output += " Device has not initial !\n";
		UpdateData(false);
		return;
	}

	UpdateData(true);

	memset( &ReceiveBuffer,0, sizeof(ReceiveBuffer) );
	ReceiveBufferSize =  sizeof(ReceiveBuffer);

	// Remove the space of the input data
	//
	m_APDU.Remove(' ');
	// Ascii To Hex change
	//
	AsciiToHex(m_APDU,(char *)chDataBuf);
	nDataLength = m_APDU.GetLength()/2;	

	slen = nDataLength;
	rlen = 0xFF;

	iReturn = IC_CpuApdu(ICDev,slen,(unsigned char *)chDataBuf,&rlen,(unsigned char *)ReceiveBuffer);

	if(0 == iReturn)
	{
		DWORD nRecieveLength = rlen;

		m_Output += " \r\n Read Data: \r\n";

		for(DWORD i=0; i < nRecieveLength; i++)
		{
			m_Output += " ";
			m_Output += HexToAscii( 0x0F & ReceiveBuffer[i] >> 4);
			m_Output += HexToAscii( 0x0F & ( ReceiveBuffer[i]  ) );

			if( (i+1) % 25 == 0 && i != 0)
				m_Output += "\r\n";
		}
		m_Output += "\r\n";
		m_Output += "               ******************************\r\n";
		m_Output += "               * Data read  card OK!        *\r\n";
		m_Output += "               *          Test OK!          *\r\n";
		m_Output += "               ******************************\r\n";	
	}
	else
	{
		m_Output += "\r\n";
		m_Output += "               ******************************\r\n";
		m_Output += "               * Data read  card Error!     *\r\n";
		m_Output += "               *          Test OK!          *\r\n";
		m_Output += "               ******************************\r\n";
	}

	UpdateData(false);
}

void CSerialDLLExampleDlg::OnGetprotocol() 
{
	// TODO: Add your control notification handler code here
	__int16 iReturn = 0;

	if(!ICDev )
	{
		m_Output = " Device has not initial !\n";
		return;
	}

	iReturn = IC_CpuGetProtocol( ICDev );
	
	switch (iReturn)
	{
	case SCARD_PROTOCOL_T1:
		m_Output += "Present smart card protocol T1 \r\n";
		break;
	case SCARD_PROTOCOL_T0:
		m_Output += "Present smart card protocol T0 \r\n";
		break;
	default:
		m_Output += "Present smart card protocol not sure \r\n";
		break;
	}

	UpdateData(false);
}

void CSerialDLLExampleDlg::OnErrorcode() 
{
	// TODO: Add your control notification handler code here
	char chErrMsg[100];
	
	UpdateData(true);

	memset(chErrMsg, 0 , sizeof(chErrMsg) );

	IC_GetErrorText( -m_ErrCode, chErrMsg);
	
	m_Output += chErrMsg;
	m_Output += "\r\n";

	UpdateData(false);
}

void CSerialDLLExampleDlg::ListReaders( bool DisplayNoReaderError )
{
	LPTSTR          pmszReaders = NULL;
	LPTSTR          pReader;
	LONG            lReturn, lReturn2;
	DWORD           cch = SCARD_AUTOALLOCATE;
	SCARDCONTEXT	hSCardContext;

	//Skaffa handle till resource manager.
	if((SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hSCardContext))!=SCARD_S_SUCCESS)
	{
		MessageBox("Could not load Resource manager", MB_OK);
		return;
	}

	// Retrieve the list the readers.
	// hSCardContext was set by a previous call to SCardEstablishContext.
	lReturn = SCardListReaders(hSCardContext,
							   NULL,
							   (LPTSTR)&pmszReaders,
							   &cch );
    m_ReadersList.ResetContent();
    m_ReadersList.AddString("");
    m_ReadersList.SetCurSel(0);
    m_CurrentSelectedReader = "";

	switch( lReturn )
	{
		case SCARD_S_SUCCESS:
            m_ReadersList.ResetContent();
			// A double-null terminates the list of values.
			pReader = pmszReaders;
			while ( '\0' != *pReader )
			{
				m_ReadersList.AddString(pReader);
				// Advance to the next value.
				pReader = pReader + strlen(pReader) + 1;
			}

			// Select the first item in the combo box.
			if( 0 < m_ReadersList.GetCount() )
			{
				m_ReadersList.SetCurSel(0);
				m_ReadersList.GetLBText(0, m_CurrentSelectedReader);
				// Free the memory.
			}
			else
			{
				m_CurrentSelectedReader = "";
    				if( DisplayNoReaderError )
				{
					AfxMessageBox("Error, No Readers installed!",MB_OK); 
				}
			}
			lReturn2 = SCardFreeMemory( hSCardContext, pmszReaders );
			if ( SCARD_S_SUCCESS != lReturn2 )
			{
				MessageBox("Error, Memory freeing failure!",NULL,MB_OK);
			}
			break;

		default:
			m_CurrentSelectedReader = "";
			if( DisplayNoReaderError )
			{
				AfxMessageBox("Error, No Readers installed!",NULL,MB_OK); 
			}
			break;
	}
	SCardReleaseContext(hSCardContext);
    UpdateData(false);
}

void CSerialDLLExampleDlg::OnSelchangeReaderslist() 
{
	// TODO: Add your control notification handler code here
	m_ReadersList.GetLBText(m_ReadersList.GetCurSel(), m_CurrentSelectedReader);
}

void CSerialDLLExampleDlg::OnInitwithname() 
{
	// TODO: Add your control notification handler code here
	if( m_CurrentSelectedReader.GetLength() > 0 )
	{
		ICDev = IC_InitCommWithName( m_CurrentSelectedReader );

		if( ICDev )
		{
			m_Output = " Smart card reader initial success \r\n";
		}
		else
			m_Output = " Smart card reader initial fail \r\n";
	}
	else
		m_Output = " No Smart card reader name spcified \r\n";	

	UpdateData(false);
}

void CSerialDLLExampleDlg::OnInittype() 
{
	// TODO: Add your control notification handler code here
	__int16 iReturn = 0;

	iReturn = IC_InitType( ICDev, 0x12 );

	if ( 0 == iReturn )
	{
		m_Output +=" \r\n Initial CPU card type successfully";
	}
	else if( AGM_CARD_NOT_SUPPORT == iReturn )
	{ 
		m_Output +=" \r\n Initial card type fail \r\n";
	}

	UpdateData(false);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -