www.pudn.com > SmartCardSrc.zip > SmartCardDlg.cpp
//------------------------------------------------------------------------------ // // Copyright (c) 1999-2005 Matt Brunk// // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License VERSION 2 as // published by the Free Software Foundation. You are not allowed to // use any other version of the license; unless you got the explicit // permission from the author to do so. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // //------------------------------------------------------------------------------ // SmartCardDlg.cpp : implementation file // #include "stdafx.h" #include "SmartCard.h" #include "SmartCardDlg.h" #include "DlgSetup.h" #include "EnumPorts.h" #include "sdes.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif typedef struct { unsigned long first; unsigned long last; } serialNumStruct; static const CString s_szSectionSettings = "Settings"; static const CString s_szPort = "Port"; static const CString s_szBaud = "Baud"; static const CString s_szClearOutput = "ClearOutput"; static const CString s_szEncrypt = "Encrypt"; static const CString s_szVerbose = "Verbose"; ///////////////////////////////////////////////////////////////////////////// // 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() ///////////////////////////////////////////////////////////////////////////// // CSmartCardDlg dialog CSmartCardDlg::CSmartCardDlg(CWnd* pParent /*=NULL*/) : CDialog(CSmartCardDlg::IDD, pParent) { //{{AFX_DATA_INIT(CSmartCardDlg) // 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(IDR_MAINFRAME); m_hSmallIcon = (HICON)::LoadImage ( AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, 0 ); m_iPort = 1; m_iBaud = 9600; m_first = 0; m_last = 0; } void CSmartCardDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CSmartCardDlg) DDX_Control(pDX, IDC_CHECK_VERBOSE, m_checkVerbose); DDX_Control(pDX, IDC_CHECK_ENCRYPT, m_checkEncrypt); DDX_Control(pDX, IDC_CHECK_CLEAR, m_checkClear); DDX_Control(pDX, IDC_COMBO_COM_PORT, m_comboPort); DDX_Control(pDX, IDC_COMBO_BAUD, m_comboBaud); DDX_Control(pDX, IDC_BUTTON_PROGRAM, m_BtnProgram); DDX_Control(pDX, IDC_COMBO_STOP_BITS, m_comboStopBits); DDX_Control(pDX, IDC_EDIT_REMAINING, m_EditRemaining); DDX_Control(pDX, IDC_EDIT_CURRENT, m_EditCurrent); DDX_Control(pDX, IDC_EDIT_OUT, m_EditOut); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CSmartCardDlg, CDialog) //{{AFX_MSG_MAP(CSmartCardDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_ATR, OnButtonAtr) ON_BN_CLICKED(IDC_BUTTON_START_SESSION, OnButtonStartSession) ON_BN_CLICKED(IDC_BUTTON_SUBMIT_CODE, OnButtonSubmitCode) ON_BN_CLICKED(IDC_BUTTON_SELECT_FILE, OnButtonSelectFile) ON_BN_CLICKED(IDC_BUTTON_READ_FILE, OnButtonReadFile) ON_BN_CLICKED(IDC_BUTTON_SETUP, OnButtonSetup) ON_BN_CLICKED(IDC_BUTTON_PROGRAM, OnButtonProgram) ON_CBN_SELCHANGE(IDC_COMBO_STOP_BITS, OnSelchangeComboStopBits) ON_BN_CLICKED(IDC_BUTTON_DUMP_DCB, OnButtonDumpDcb) ON_CBN_SELCHANGE(IDC_COMBO_BAUD, OnSelchangeComboBaud) ON_CBN_SELCHANGE(IDC_COMBO_COM_PORT, OnSelchangeComboComPort) ON_WM_DESTROY() ON_BN_CLICKED(IDC_CHECK_ENCRYPT, OnCheckEncrypt) ON_BN_CLICKED(IDC_CHECK_VERBOSE, OnCheckVerbose) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSmartCardDlg message handlers BOOL CSmartCardDlg::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_hSmallIcon, FALSE); // Set small icon CClientDC dc(this); int nHeight = -((dc.GetDeviceCaps(LOGPIXELSY) * 10) / 72); m_font.CreateFont ( nHeight, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, _T("Courier New") ); m_EditOut.SetLimitText(200000); m_EditOut.SetFont(&m_font); m_iPort = AfxGetApp()->GetProfileInt(s_szSectionSettings, s_szPort, 1); if ( !CEnumPorts::IsPortAvailable(m_iPort) ) { m_iPort = 1; } std::vector ports; CEnumPorts::GetAvailablePorts(ports); m_comboPort.ResetContent(); CString sss; int nSel = -1; CString szPort; szPort.Format("COM%d", m_iPort); for ( size_t nn = 0; nn < ports.size(); nn++ ) { sss.Format(_T("COM%d"), ports[nn]); m_comboPort.AddString(sss); if ( szPort.Compare(sss) == 0 ) { nSel = (int)nn; } } //m_comboPort.AddString(_T("COM254")); if ( nSel >= 0 ) { m_comboPort.SetCurSel(nSel); } m_iBaud = AfxGetApp()->GetProfileInt(s_szSectionSettings, s_szBaud, 9600); m_checkClear.SetCheck(AfxGetApp()->GetProfileInt(s_szSectionSettings, s_szClearOutput, 0)); m_checkEncrypt.SetCheck(AfxGetApp()->GetProfileInt(s_szSectionSettings, s_szEncrypt, 0)); m_checkVerbose.SetCheck(AfxGetApp()->GetProfileInt(s_szSectionSettings, s_szVerbose, 1)); m_acos1.EnableEncryption(m_checkEncrypt.GetCheck() != 0); m_acos1.SetVerbose(m_checkVerbose.GetCheck() != 0); m_comboPort.SetCurSel(m_iPort - 1); int idx = 0; CString ttt; sss.Format(_T("%d"), m_iBaud); bool found = false; for ( int bb = 0; bb < m_comboBaud.GetCount(); bb++ ) { m_comboBaud.GetLBText(bb, ttt); if ( sss.Compare(ttt) == 0 ) { idx = bb; found = true; break; } } if ( !found ) { idx = 0; m_iBaud = 9600; } m_comboBaud.SetCurSel(idx); m_comboStopBits.SetCurSel(1); m_acos1.SetPort(m_iPort); m_acos1.SetBaud(m_iBaud); m_acos1.SetEditControl(&m_EditOut); m_EditOut.SetLimitText(0x8000); return TRUE; // return TRUE unless you set the focus to a control } void CSmartCardDlg::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 CSmartCardDlg::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 CSmartCardDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CSmartCardDlg::OnButtonAtr() { DispatchCommand(COMMAND_ATR); } void CSmartCardDlg::OnButtonStartSession() { DispatchCommand(COMMAND_START_SESSION); } void CSmartCardDlg::OnButtonSubmitCode() { DispatchCommand(COMMAND_SUBMIT_CODE); } void CSmartCardDlg::OnButtonSelectFile() { DispatchCommand(COMMAND_SELECT_FILE); } void CSmartCardDlg::OnButtonReadFile() { DispatchCommand(COMMAND_READ_FILE); } void CSmartCardDlg::OnButtonSetup() { DispatchCommand(COMMAND_SETUP); } void CSmartCardDlg::OnButtonProgram() { DispatchCommand(COMMAND_PROGRAM); } bool CSmartCardDlg::DoATR() { unsigned char buf[64]; DWORD dwLength; dwLength = sizeof buf; return m_acos1.GetATR(buf, dwLength); } void CSmartCardDlg::DoStartSession() { unsigned char buf[128]; DWORD dwLength; if ( m_acos1.StartSession(buf, dwLength) ) { CString ccc; CString sss = _T("key = ");; for ( DWORD ii = 0; ii < dwLength; ii++ ) { ccc.Format(_T("%02X "), buf[ii]); sss += ccc; } sss += _T("\r\n"); AppendText(sss); } } bool CSmartCardDlg::DoSubmitCode() { unsigned char CODE[] = {'A', 'C', 'O', 'S', 'T', 'E', 'S', 'T'}; return m_acos1.SubmitIC(CODE); } bool CSmartCardDlg::DoSelectFile() { unsigned char FILE_DATA[] = {0xFF, 0x03}; return m_acos1.SelectFile(FILE_DATA); } void CSmartCardDlg::DoReadFile() { BOOL bEnableEncryption = m_checkEncrypt.GetCheck(); //if ( !DoATR() ) //{ // return; //} if ( !DoSubmitCode() ) { return; } if ( !DoSelectFile() ) { return; } unsigned char buf[128]; DWORD dwLength; if ( m_acos1.ReadRecord(6, 8, buf, dwLength) ) { if ( bEnableEncryption ) { for ( int ii = 0; ii < 8; ii++ ) { buf[ii] = SDES::Decrypt(buf[ii]); } } CString response; CString ccc; serialNumStruct serialNum; ::CopyMemory(&serialNum, buf, 8); m_first = serialNum.first; m_last = serialNum.last; m_BtnProgram.EnableWindow(m_first <= m_last); CString sss; sss.Format(_T("%lu"), serialNum.first); m_EditCurrent.SetWindowText(sss); sss.Format(_T("%lu"), serialNum.last - serialNum.first + 1); m_EditRemaining.SetWindowText(sss); if ( m_checkVerbose.GetCheck() ) { response.Format(_T("RECORD %2d: "), 6); for ( DWORD ii = 0; ii < dwLength; ii++ ) { ccc.Format(_T("%02X "), buf[ii]); response += ccc; } AppendText(response); } } } void CSmartCardDlg::DoSetup() { CDlgSetup dlg; int nResponse = dlg.DoModal(); if ( nResponse == IDOK ) { ClearOutput(); serialNumStruct serialNum; serialNum.first = dlg.m_uStartNum; serialNum.last = dlg.m_uStartNum + dlg.m_uCount - 1; m_BtnProgram.EnableWindow(serialNum.first <= serialNum.last); CString sss; if ( !m_acos1.OpenPort() ) { CString errMsg = m_acos1.GetLastErrorMsg(); sss.Format(_T("Error opening serial port.\n\n%s"), (LPCTSTR)errMsg); AfxMessageBox(sss, MB_OK | MB_ICONERROR ); return; } Sleep(200); unsigned char CODE[] = {'A', 'C', 'O', 'S', 'T', 'E', 'S', 'T'}; if ( m_acos1.SubmitIC(CODE) ) { unsigned char FILE_DATA[] = {0xFF, 0x03}; if ( m_acos1.SelectFile(FILE_DATA) ) { if ( m_acos1.WriteRecord(6, (unsigned char *)&serialNum, sizeof serialNum) ) { AppendText(_T("Success ")); DoReadFile(); } } } } } void CSmartCardDlg::DoProgram() { DoReadFile(); if ( m_first <= m_last ) { m_first++; serialNumStruct serialNum; serialNum.first = m_first; unsigned char CODE[] = {'A', 'C', 'O', 'S', 'T', 'E', 'S', 'T'}; if ( m_acos1.SubmitIC(CODE) ) { unsigned char FILE_DATA[] = {0xFF, 0x03}; if ( m_acos1.SelectFile(FILE_DATA) ) { if ( m_acos1.WriteRecord(6, (unsigned char *)&serialNum, 4) ) { AppendText(_T("Success ")); DoReadFile(); } } } } else { AfxMessageBox(_T("Serial numbers exhausted!"), MB_OK | MB_ICONWARNING ); } } void CSmartCardDlg::OnSelchangeComboStopBits() { m_acos1.SetStopBits(m_comboStopBits.GetCurSel() + 1); } void CSmartCardDlg::OnButtonDumpDcb() { if ( !m_acos1.OpenPort() ) { CString sss; CString errMsg = m_acos1.GetLastErrorMsg(); sss.Format(_T("Error opening serial port.\n\n%s"), (LPCTSTR)errMsg); AfxMessageBox(sss, MB_OK | MB_ICONERROR ); return; } ClearOutput(); m_acos1.DumpDCB(); m_acos1.ClosePort(); } void CSmartCardDlg::OnSelchangeComboBaud() { CString sss; m_comboBaud.GetLBText(m_comboBaud.GetCurSel(), sss); _stscanf(sss, "%d", &m_iBaud); m_acos1.SetBaud(m_iBaud); } void CSmartCardDlg::OnSelchangeComboComPort() { CString sss; if ( m_comboPort.GetCount() > 0 ) { m_comboPort.GetLBText(m_comboPort.GetCurSel(), sss); _stscanf(sss, "COM%d", &m_iPort); m_acos1.SetPort(m_iPort); } } void CSmartCardDlg::OnDestroy() { AfxGetApp()->WriteProfileInt(s_szSectionSettings, s_szPort, m_iPort); AfxGetApp()->WriteProfileInt(s_szSectionSettings, s_szBaud, m_iBaud); AfxGetApp()->WriteProfileInt(s_szSectionSettings, s_szClearOutput, m_checkClear.GetCheck()); AfxGetApp()->WriteProfileInt(s_szSectionSettings, s_szEncrypt, m_checkEncrypt.GetCheck()); AfxGetApp()->WriteProfileInt(s_szSectionSettings, s_szVerbose, m_checkVerbose.GetCheck()); CDialog::OnDestroy(); } void CSmartCardDlg::AppendText(LPCTSTR Text) { CString msg = Text; msg += _T("\r\n"); int Length = m_EditOut.GetWindowTextLength(); m_EditOut.SetSel(Length, Length); m_EditOut.ReplaceSel(msg); m_EditOut.LineScroll( m_EditOut.GetLineCount() ); } void CSmartCardDlg::ClearOutput() { if ( m_checkClear.GetCheck() ) { m_EditOut.SetWindowText(_T("")); } } void CSmartCardDlg::DispatchCommand(CommandEnum command) { CString sss; if ( command != COMMAND_SETUP ) { ClearOutput(); if ( !m_acos1.OpenPort() ) { CString errMsg = m_acos1.GetLastErrorMsg(); sss.Format(_T("Error opening serial port.\n\n%s"), (LPCTSTR)errMsg); AfxMessageBox(sss, MB_OK | MB_ICONERROR ); return; } } switch ( command ) { case COMMAND_ATR: { DoATR(); } break; case COMMAND_START_SESSION: { DoStartSession(); } break; case COMMAND_SUBMIT_CODE: { DoSubmitCode(); } break; case COMMAND_SELECT_FILE: { DoSelectFile(); } break; case COMMAND_READ_FILE: { DoReadFile(); } break; case COMMAND_SETUP: { DoSetup(); } break; case COMMAND_PROGRAM: { DoProgram(); } break; default: break; } m_acos1.ClosePort(); } void CSmartCardDlg::OnCheckEncrypt() { m_acos1.EnableEncryption(m_checkEncrypt.GetCheck() != 0); } void CSmartCardDlg::OnCheckVerbose() { m_acos1.SetVerbose(m_checkVerbose.GetCheck() != 0); }