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

📄 pcscom.cpp

📁 RSA C++源代码DEMO,附加DESMD5等众多算法
💻 CPP
字号:
/*
 *  Card Application Class using PC/SC Standard
 *
 *  Writen by Alfred Meng
 *
 *  Oct. 15, 2000
 *
 *@ident "PCSCOM V1.0"
 */

#include <stdio.h>
#include <assert.h>

#include "pcscom.h"
#include "gdcmd.h"
#include "cardutil.h"

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


LONG SCFree (IN LPVOID lpMemory)
{
    LONG lResult;

    assert(lpMemory != NULL);

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

    return lResult;
}


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

    assert(lplpmszReaderNames != NULL);

    * lplpmszReaderNames = NULL;

    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;
    }

    LPTSTR lpmszReaderNames = (LPTSTR) SCMalloc(dwReaders * sizeof(char));

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

    lResult = SCardListReaders(hContext,
                               lpmszReaderGroups,
                               lpmszReaderNames,
                               &dwReaders);
    if (lResult == SCARD_S_SUCCESS)
    {
        *lplpmszReaderNames = lpmszReaderNames;
    }
    else
    {
        SCFree((LPVOID) lpmszReaderNames);
    }

    return lResult;
}


TPCSC::TPCSC()
{
    bStarted = FALSE;
    hContext = NULL;
    iso_case4( CASE4_Disable );
    //assign(GDCommand,TOTAL_CMD); // Using G&D Command Set
}

int   TPCSC::openterm(short  rid )
{
    if (bStarted==FALSE) Startup();

    if ( !Opened(rid-1) )
          return OpenReader(rid-1);
    return 1;
}

int   TPCSC::closeterm()
{
    // loop for all reader
    CloseReader(0);
    Shutdown();
    bStarted = FALSE;
    return 1;
}

int   TPCSC::opened()
{
    return Opened(0);
}

int   TPCSC::opensam(int plug)
{
    if ( plug <0 || plug>=dwNumReaders) return -1;
    if ( Opened(plug) ) return 1;

    return OpenReader(plug);
}

int   TPCSC::selectICC(int icc,bool reqATR)
{
    if (SelectReader(icc) != -1 ) {

        if (reqATR) RequestATR();
        return 1;
    }
    return -1;
}

int   TPCSC::hascard()
{
    DWORD dwReaderLen = 0;
    DWORD dwState;
    DWORD dwProtocol;
    BYTE  atr[MAXIMUM_ATTR_STRING_LENGTH];
    DWORD dwAtrLen;

    rc = SCardStatus(hCards[curReader],NULL,&dwReaderLen,&dwState,&dwProtocol,atr,&dwAtrLen);

    if ( rc == SCARD_S_SUCCESS && dwState == SCARD_SPECIFIC ) return 1;
    return 0;
}

int   TPCSC::ejectcard(bool beep)
{
    rc = SCardEndTransaction(hCards[curReader], SCARD_LEAVE_CARD );
    return 1;
}

char  TPCSC::TermType() const
{
    return 0x0F;
}

char *TPCSC::GetError() const
{
/*
    LPVOID lpMsgBuf;

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetLastError(),
        0, // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL
    );

// Process any inserts in lpMsgBuf.
// ...
// Display the string.
MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
*/
     return "ERROR";
}

void	TPCSC::Shutdown()
{
	if (lpmszReaderNames != NULL) SCFree((LPVOID) lpmszReaderNames);
    for ( int i=0; i<dwNumReaders;i++ ) if ( hCards[i] != NULL ) CloseReader(i);
}


LONG	TPCSC::Startup()
{
	LPTSTR lpszReaderName=NULL;

    curReader = -1;
	dwNumReaders   = 0;
	lpmszReaderNames = NULL;

    for ( int i=0; i<MAXIMUM_SMARTCARD_READERS; i++ )  hCards[i]  = NULL;

	rc=SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hContext);

	if ( rc != SCARD_S_SUCCESS ) return rc;

    SCListReaders(hContext,NULL,(LPTSTR *) &lpmszReaderNames);
    if (rc != SCARD_S_SUCCESS) return rc;

    if ( lpmszReaderNames != NULL ) {

       lpszReaderName = lpmszReaderNames;
       ZeroMemory((LPVOID)rsReaders, sizeof(rsReaders));

       while ((*lpszReaderName != 0x0 ) &&
               (dwNumReaders < MAXIMUM_SMARTCARD_READERS))
       {
            rsReaders[dwNumReaders].szReader = (LPCTSTR)lpszReaderName;
            rsReaders[dwNumReaders].dwCurrentState = SCARD_STATE_UNAWARE;

            dwNumReaders++;
            lpszReaderName += lstrlen(lpszReaderName) + 1;
        }
    }

    if (dwNumReaders == 0)
        {
			SetLastError(SCARD_E_READER_UNAVAILABLE);
			rc = SCARD_E_READER_UNAVAILABLE;
        }
	else    {
        //rc = SCardGetStatusChange(hContext,INFINITE,rsReaders,dwNumReaders);
        curReader = 0; // set default reader
    }
    bStarted = TRUE;
    return rc;
}


LONG	TPCSC::OpenReader(DWORD rid,DWORD prepro,DWORD smode)
{
    LPBYTE lpbResponse = NULL;

    if ( rid <0 || rid>=dwNumReaders) return -1;

    dwMode[rid] = smode;
    dwPrePro[rid] = prepro;

    rc = SCardGetStatusChange(hContext,INFINITE,rsReaders,dwNumReaders);

	if (!(rsReaders[rid].dwEventState & SCARD_STATE_PRESENT))
            {
                return SCARD_E_NO_SMARTCARD;
            }

    rc = SCardConnect(hContext,rsReaders[rid].szReader,
                      smode, prepro, &hCards[rid],&dwActivePro[rid]);

    if ( rc == SCARD_S_SUCCESS )  curReader = rid;
    return rc;
}

int     TPCSC::RequestATR()
{
    DWORD dwReaderLen = 0;
    DWORD dwState;
    DWORD dwProtocol;
    BYTE  atr[MAXIMUM_ATTR_STRING_LENGTH];
    DWORD dwAtrLen;
    DWORD cByte = MAXIMUM_ATTR_STRING_LENGTH;

    if ( curReader <0 || curReader>=dwNumReaders) return -1;

    // reconnect for smartcard changed

    rc = SCardReconnect(hCards[curReader],
                        dwMode[curReader],
                        dwPrePro[curReader],
                        SCARD_LEAVE_CARD  ,
                        &dwActivePro[curReader]);

    if ( rc != SCARD_S_SUCCESS ) return -1;

//    rc = SCardStatus(hCards[curReader],NULL,&dwReaderLen,&dwState,&dwProtocol,atr,&dwAtrLen);

    if ( rc == SCARD_S_SUCCESS /*&& dwState == SCARD_SPECIFIC */) {
	SCardBeginTransaction( hCards[curReader] );
        rc = SCardGetAttrib(hCards[curReader],SCARD_ATTR_ATR_STRING,
                         (LPBYTE)&atr, &cByte);
        if ( rc==SCARD_S_SUCCESS) {
            memcpy(Resp,atr,cByte);
            RespLen = cByte;
            SW1 = SW2 = 0x0;
        }
    }

    return rc;
}

LONG	TPCSC::CloseReader(DWORD rid)
{
    if ( rid<0 || rid >=dwNumReaders) return -1; // inVaild
    if ( rid == curReader ) curReader = -1; // NO Reader selected

    if (hCards[rid] != NULL) {
	rc = SCardEndTransaction(hCards[rid], SCARD_LEAVE_CARD );
	rc = SCardDisconnect(hCards[rid], SCARD_LEAVE_CARD);
        hCards[rid] = NULL;
    }

    return rc;
}

BOOL    TPCSC::Opened(DWORD rid)
{
    if ( rid <0 || rid >=dwNumReaders) return FALSE;
    return (hCards[rid]!=NULL)?TRUE:FALSE;
}

BOOL    TPCSC::SelectReader(DWORD rid)
{
    if ( rid <0 || rid>=dwNumReaders) return -1; // inVaild
    if ( hCards[rid]!=NULL ) return curReader = rid;
    return -1;
}

int   TPCSC::sendapdu(TAPDU *pApdu)
{
    unsigned long ulRespLen;
    TAPDU    tAPDU;

    if ( curReader <0 || curReader>=dwNumReaders) return -1;
    if ( hCards[curReader] == NULL) return -2; // NOT OPENED

    memcpy(&__apdu,pApdu,sizeof(TAPDU));
    memcpy(&tAPDU,pApdu,sizeof(TAPDU));

    if ( tAPDU.len != 5 ) // ! CASE 2
      if ( tAPDU.len > 4 )
         if ( tAPDU.len != (tAPDU.apdu[4] + 5) ) {
            tAPDU.len--;  // Because PCSC didn't support CASE 4, so...
         }

__redo:
    ulRespLen = 0xff;
    pApdu->gap = GetTickCount();
    switch (dwActivePro[curReader]) {
       case   SCARD_PROTOCOL_T0:
              rc = SCardTransmit(hCards[curReader],SCARD_PCI_T0,tAPDU.apdu,tAPDU.len,NULL,Resp,&ulRespLen);
              break;
       case   SCARD_PROTOCOL_T1:
              rc = SCardTransmit(hCards[curReader],SCARD_PCI_T1,tAPDU.apdu,tAPDU.len,NULL,Resp,&ulRespLen);
              break;
       default:
              rc = SCardTransmit(hCards[curReader],SCARD_PCI_RAW,tAPDU.apdu,tAPDU.len,NULL,Resp,&ulRespLen);
    }
    pApdu->gap = (GetTickCount() - pApdu->gap);
    tAPDU.gap = pApdu->gap;

    RespLen = ulRespLen;

    if ( RespLen == 0xff ){ // error with  CT
         Resp[0] = 0xF0;
         Resp[1] = 0x80;
         RespLen = 2;
    }

    if (__fHook!=NULL)
       (*__fHook)(&tAPDU, Resp, RespLen);

    SW1 = Resp[RespLen-2];	SW2 = Resp[RespLen-1];
    RespLen -= 2;

    if ( rc != SCARD_S_SUCCESS ) return rc;

    if ( SW1== 0x61 ) {
        memcpy(tAPDU.apdu,"\x00\xC0\x00\x00\x00",5);
        tAPDU.apdu[0] = __iso_cla;
        tAPDU.len = 5;
        tAPDU.apdu[4] = SW2;
        RespLen = SW2 + 2;
        tAPDU.tag = 0x0;
        goto __redo;
    }/* else if ( SW1== 0x6C )  {
        tAPDU.apdu[tAPDU.len-1] = SW2;
        tAPDU.tag = 0x0;
        goto __redo;
    }  */

    return rc;
}

⌨️ 快捷键说明

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