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

📄 pcscctrl.cpp

📁 usblsccid-0.9.2: ED1x Smart Card Reader Driver
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// PcScCtrl.cpp: implementation of the CPcScCtrl class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "PcScCtrl.h"
#include "Helper.h"

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

ISO7816_CMD SimCmd =
{
	0xa0,	//GSM SIM CLASS
	0xa4,	//Select
	0xf2,	//Status
	0xb0,	//Read Binary
	0xd6,	//UpdateBinary;
	0xb2,	//ReadRecord;
	0xdc,	//UpdateRecord;
	0xa2,	//Seek;
	0x32,	//Increase;
	0x20,	//VerifyChv;
	0x24,	//ChangeChv;
	0x26,	//DisableChv;
	0x28,	//EnableChv;
	0x2c,	//UnblockChv;
	0x04,	//Invalidate;
	0x44,	//Rehabilitate;
	0x88,	//RunGsmAlgorithm;
	0xfa,	//Sleep;
	0xc0,	//GetResponse;
};


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPcScCtrl::CPcScCtrl()
{
	m_bGetRes = TRUE;
	m_nCurReader = 0;
	hCard = NULL;
	hContext = NULL;
	LONG lResult = EstablishContext();
	if(lResult != SCARD_S_SUCCESS)
			Helper::ShowLastError(lResult);

}

CPcScCtrl::~CPcScCtrl()
{
	LONG lReturn;
	if(hCard)
	{
		lReturn = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
		ASSERT(lReturn == SCARD_S_SUCCESS);
	}

	if (hContext != NULL)
	{
		lReturn = SCardReleaseContext(hContext);
		ASSERT(lReturn == SCARD_S_SUCCESS);
	}

}

LONG CPcScCtrl::ListReaders()
{
    LONG	lResult;
	LPTSTR	lpmszReaderNames;
	LONG	nReaders = 0;	

	m_asReaderNames.RemoveAll();
	
	EstablishContext();
	if(hContext == NULL)
		return nReaders;
    //__try
    {
        //
        // Get the list of registered readers associated with the specified
        // group(s).
        // Note: The buffer is automatically allocated and must be freed
        //       by SCFree().
        //
        lResult = SCListReaders(hContext,
                                NULL,
                                (LPTSTR *) &lpmszReaderNames);
		//Helper::ShowLastError(lResult);
        if (lResult != SCARD_S_SUCCESS)
        {
            //__leave;
        }else{
			DWORD  dwNumReaders   = 0;
			LPTSTR lpszReaderName = lpmszReaderNames;

			TRACE(_T("\n"));
			TRACE(_T("Registered Reader(s)\n"));
			TRACE(_T("====================\n"));

			//
			// Walk through the list of readers and print out some information.
			// Note: The list of readers are in a multi-string structure.
			//
			while (*lpszReaderName != _T('\0'))
			{
				++dwNumReaders;
				TRACE(_T("%02d: %s\n"), dwNumReaders, lpszReaderName);
				CString ts(lpszReaderName); 
				m_asReaderNames.Add(ts);
				lpszReaderName += lstrlen(lpszReaderName) + 1;
				nReaders++;
			}

			//
			// Inform the user if no reader was found.
			//
			if (dwNumReaders == 0)
			{
				TRACE(_T("No registered reader was found"));
				AfxMessageBox(_T("No registered reader was found"));
			}
		}
    }
	// Don't forget to release memory, if allocated.
	//
	if (lpmszReaderNames != NULL)
		SCFree((LPVOID) lpmszReaderNames);
	return nReaders;
}

LONG CPcScCtrl::DoAPDU(LPBYTE cmdAPDU, DWORD len, LPBYTE resAPDU,DWORD &reslen)
{
    LONG lResult;
	
	if(hCard == NULL)
	{
		lResult = SCARD_E_NO_SMARTCARD;
		Helper::ShowLastError(lResult);
	}

    //
    // Send APDU to card
    //
    lResult = SCardTransmit(hCard,
                            SCARD_PCI_T0,
                            cmdAPDU,
                            len,
                            NULL,
                            resAPDU,
                            &reslen);
    //
    // If API successful but card operation failed, then
    // return SW1 and SW2 as error code
    //
    if (lResult == SCARD_S_SUCCESS)
    {
		//
		// Sanity check
		//
		if(len == 5)//Must be Read
		{
			ASSERT(reslen >= 2);
		}else{
			ASSERT(reslen == 2);
		}

		if(reslen == 2)
		{
			if ( m_bGetRes &&
				 (resAPDU[0] == 0x61 || resAPDU[0] == 0x9f)
			   )
			{
				BYTE len = resAPDU[1];
				DWORD dwStatusLen = len + 2;
				//BYTE apdu[5] = {0xa0, 0xc0, 0x00, 0x00, len};
				CMDAPDU cmdApdu;
				cmdApdu.klass = SimCmd.Klass;
				cmdApdu.inc = SimCmd.GetResponse;
				cmdApdu.p1 = 0;
				cmdApdu.p2 = 0;
				cmdApdu.p3 = len;

				//
				// Send APDU to card.
				//
				lResult = SCardTransmit(hCard,
                            SCARD_PCI_T0,
                            (LPBYTE)&cmdApdu,
                            5,
                            NULL,
                            resAPDU,
                            &dwStatusLen);
				if (lResult == SCARD_S_SUCCESS)
				{
					reslen = dwStatusLen;
					TRACE(_T("%d response bytes available\n"),reslen);
				}
			}
		}
		#ifdef _DEBUG
		if (reslen>=2)
		{
			BYTE errseq[2];
			errseq[0] = resAPDU[reslen-2];
			errseq[1] = resAPDU[reslen-1];
			TRACE("%s\n",FormatErrMsg(errseq));
		}
		#endif
		if(reslen >= 2)
		{
			UCHAR SW1 = resAPDU[reslen-2];
			LONG lRet = MAKELONG(MAKEWORD(resAPDU[reslen-1],SW1), 0x0000);
			return lRet;
		}
    }
	if(lResult != SCARD_S_SUCCESS)
		Helper::ShowLastError(lResult);
	return lResult;
}

LPVOID CPcScCtrl::SCMalloc(DWORD dwSize)
{
	return(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize));
}

LONG CPcScCtrl::SCFree(LPVOID lpMemory)
{
    LONG lResult;

    //
    // Parameters sanity check.
    //
    ASSERT(lpMemory != NULL);

    if (HeapFree(GetProcessHeap(), 0, lpMemory))
    {
        lResult = SCARD_S_SUCCESS;
    }
    else
    {
        lResult = GetLastError();
    }

    return lResult;

}

LONG CPcScCtrl::SCListReaders(SCARDCONTEXT hContext, LPCTSTR lpmszReaderGroups, LPTSTR *lplpmszReaderNames)
{
    LONG  lResult;
    DWORD dwReaders;

    //
    // Parameters sanity check.
    //
    ASSERT(lplpmszReaderNames != NULL);

    //
    // Initialize returned info.
    //
    * lplpmszReaderNames = NULL;

    //
    // First find the required buffer length.
    //
    lResult = SCardListReaders(hContext,
                               lpmszReaderGroups,
                               NULL,         // NULL to indicate we want to
                               &dwReaders);  // know the length of the buffer
    if (lResult != SCARD_S_SUCCESS)
    {
        return lResult;
    }

    //
    // Allocate memory.
    //
    LPTSTR lpmszReaderNames = (LPTSTR) SCMalloc(dwReaders * sizeof(_TCHAR));

    if (lpmszReaderNames == NULL)
    {
        return ERROR_OUTOFMEMORY;
    }

    //
    // Now actually get the list of reader names.
    //
    lResult = SCardListReaders(hContext,
                               lpmszReaderGroups,
                               lpmszReaderNames,
                               &dwReaders);
    if (lResult == SCARD_S_SUCCESS)
    {
        //
        // Successful, so return pointer to reader names.
        //
        *lplpmszReaderNames = lpmszReaderNames;
    }
    else
    {
        //
        // Error occurred, so free memory.
        //
        SCFree((LPVOID) lpmszReaderNames);
    }

    return lResult;

}

DWORD CPcScCtrl::TrackingCard(DWORD dwCurrentState)
{
	LONG lResult;

	EstablishContext();
	if(m_asReaderNames.GetSize() == 0 || hContext == NULL)
		return SCARD_STATE_UNKNOWN;

	SCARD_READERSTATE rsReaders;
	ZeroMemory((LPVOID)&rsReaders, sizeof(rsReaders));

	rsReaders.szReader = (LPCTSTR)m_asReaderNames[m_nCurReader];
	rsReaders.dwCurrentState = dwCurrentState;
	//
	// Now check state of the current reader
	//
	lResult = SCardGetStatusChange(hContext,
                                       INFINITE,
                                       &rsReaders,
                                       1);
	if (lResult != SCARD_S_SUCCESS)
		return SCARD_STATE_UNKNOWN;

	return rsReaders.dwEventState;
}

LONG CPcScCtrl::SetCurReader(INT n)
{
	if (m_asReaderNames.GetSize() == 0 || m_asReaderNames.GetSize() < n)
		return -1;
	m_nCurReader = n;
	if(hCard)
	{
			LONG lResult = SCardEndTransaction(
											hCard,  
											SCARD_LEAVE_CARD 
											);
//			if(lResult != SCARD_S_SUCCESS)
//			{
//				Helper::ShowLastError(lResult);
//				return lResult;
//			}

			lResult = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
			if(lResult != SCARD_S_SUCCESS)
			{
				Helper::ShowLastError(lResult);
				return lResult;
			}
			hCard = NULL;
	}
	DWORD dwActiveProtocol;
	//
	// Connect to the card
	//
	LONG lResult = SCardConnect(hContext,
							m_asReaderNames[m_nCurReader],
							SCARD_SHARE_SHARED,
							SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
							&hCard,
							&dwActiveProtocol);
	if(lResult != SCARD_S_SUCCESS)
		Helper::ShowLastError(lResult);
	if(lResult == SCARD_S_SUCCESS)
		lResult = SCardBeginTransaction(hCard);

	return lResult;
}

INT CPcScCtrl::GetCurReader()
{
	return m_nCurReader;
}

LONG CPcScCtrl::Select(UCHAR id[],RESAPDU &resApdu )
{
	CMDAPDU cmdApdu;
	cmdApdu.klass = SimCmd.Klass;
	cmdApdu.inc = SimCmd.Select;
	cmdApdu.p1 = 0;
	cmdApdu.p2 = 0;
	cmdApdu.p3 = 2;
	cmdApdu.data[0] = id[0];
	cmdApdu.data[1] = id[1];
	return DoAPDU((LPBYTE)&cmdApdu,5+2,resApdu.data,resApdu.len);
}

LONG CPcScCtrl::Select(ULONG id, RESAPDU &resApdu)
{
	UCHAR aid[2];
	aid[0] = (UCHAR)((id >> 8) & 0xff);
	aid[1] = (UCHAR)(id & 0xff);
	return Select(aid,resApdu);
}

LONG CPcScCtrl::Status(RESAPDU &resApdu)
{
	CMDAPDU cmdApdu;
	cmdApdu.klass = SimCmd.Klass;
	cmdApdu.inc = SimCmd.Status;
	cmdApdu.p1 = 0;

⌨️ 快捷键说明

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