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

📄 tlp3cb.c

📁 基于windows ce环境下对smart card 基于pc/sc架构下驱动例程
💻 C
📖 第 1 页 / 共 4 页
字号:
                        // The third byte contains the length of the data in the packet
                        // and we additinally want to have the EDC bytes which 
                        // is one for LRC and 2 for CRC
                        //
                        *replyLength = 
                            replyBuffer[2] + 
                            (SmartcardExtension->CardCapabilities.T1.EDC & 0x01 ? 2 : 1);

                        // We want to have the remaining bytes just after the first 3
                        SmartcardExtension->SmartcardReply.Buffer += 3;

                        status = TLP3SerialIo(SmartcardExtension);

                        SmartcardExtension->SmartcardReply.Buffer -= 3;
                        SmartcardExtension->SmartcardReply.BufferLength += 3;

                        if (status != STATUS_SUCCESS && status != STATUS_TIMEOUT) {

                            leave;
                        }                         
                    }

                    if (status == STATUS_TIMEOUT) {

                        //
                        // Since the card did not reply we set the number of 
                        // bytes received to 0. This will trigger a resend 
                        // request 
                        //
                        SmartcardDebug(
                            DEBUG_PROTOCOL,
                            (TEXT("%s!TLP3TransmitT1: Timeout\n"),
                            szDriverName)
                            );
                        SmartcardExtension->SmartcardReply.BufferLength = 0;                         
                    }

                    status = SmartcardT1Reply(SmartcardExtension);
                    break;

                default:
                    status = STATUS_INVALID_DEVICE_REQUEST;
                    leave;
            }

        } while (status == STATUS_MORE_PROCESSING_REQUIRED);
    }

    _finally {

        if (status == STATUS_TIMEOUT) {

            // STATUS_TIMEOUT is not mapped to a Win32 error code
            status = STATUS_IO_TIMEOUT;             
        }
    }

    SmartcardDebug(
        DEBUG_TRACE,
        (TEXT("%s!TLP3Transmit: Exit(%lx)\n"),
        szDriverName,
        status)
        );

    return status;
}

NTSTATUS
TLP3CardTracking(
    PSMARTCARD_EXTENSION SmartcardExtension
    )
/*++

Routine Description:

    The smart card lib requires to have this function. It is called 
    to setup event tracking for card insertion and removal events.

Arguments:

    SmartcardExtension - pointer to the smart card data struct.

Return Value:

    NTSTATUS

--*/
{
    SmartcardDebug( 
        DEBUG_TRACE,
        ( TEXT("%s!CBCardTracking: Exit \n"),szDriverName )
        );

    return STATUS_PENDING;
}

NTSTATUS
TLP3VendorIoctl(
    PSMARTCARD_EXTENSION SmartcardExtension
    )
{
    NTSTATUS status;
    static TCHAR answer[] = _T("Vendor IOCTL");

    SmartcardDebug(
        DEBUG_PROTOCOL,
        (TEXT("%s!TLP3VendorIoctl: Enter\n"),
        szDriverName)
        );
#if BEFORECEDAR        
    if (SmartcardExtension->MajorIoControlCode==IOCTL_INIT_COMPLETE) {
        TCHAR szDeviceName[DEVNAME_LEN];
        TCHAR szFriendlyName[MAXIMUM_ATTR_STRING_LENGTH+DEVNAME_LEN+5];
        //
        // Called by the device manager after PSC_Init (assuming the "Ioctl" registry value has been set)
        // 
        // The device name should now be available
        status = GetDeviceName(SmartcardExtension->ReaderExtension->d_ActivePath,szDeviceName);
        if (NT_SUCCESS(status)) {
            PTCHAR pch = szDeviceName;
            while (*pch && (*pch < '0' || *pch > '9'))
                ++pch;
            if (*pch)
                SmartcardExtension->VendorAttr.UnitNo = *pch - '0';
            // Attempt to register a friendly name for this device 
            // for the benefit of the resource manager. 
            // The friendly name has the format "PRODUCTNAME [UNITNO]"
            // For example, "SCM SwapSmart [1]"
            //
            MakeFriendlyName(SmartcardExtension, szFriendlyName);
            SmartcardCreateLink(szFriendlyName,szDeviceName); 
            status=STATUS_SUCCESS;
        }
    }
    else
#endif
    if (SmartcardExtension->IoRequest.ReplyBuffer != NULL && 
            SmartcardExtension->IoRequest.ReplyBufferLength >= 
            (_tcslen(answer) + 1)*sizeof(TCHAR)) { 
        
        _tcscpy((TCHAR *)SmartcardExtension->IoRequest.ReplyBuffer, answer);
        *SmartcardExtension->IoRequest.Information = _tcslen(answer);
        status = STATUS_SUCCESS;

    } else {
         
        status = STATUS_BUFFER_TOO_SMALL;
    }

    SmartcardDebug(
        DEBUG_PROTOCOL,
        (TEXT("%s!TLP3VendorIoctl: Exit(%lx)\n"),
        szDriverName,
        status)
        );

    return status;
}

//*---------------------------instead of lib--------------------------*//
void bcdToAsc(
	unsigned char *psAsc,
	unsigned char *psBcd,
	unsigned int nLen,
	unsigned char byMode)
{
	unsigned int i;
	unsigned char byTmp;

	for(i=0;i<nLen;i++)
	{
		switch(byMode)
		{
			case 1:
				psAsc[2*i] = (psBcd[i]>>4)+0x30;
				psAsc[2*i+1] = (psBcd[i]&0xf)+0x30;
				break;
			case 0:
			default:
				byTmp = psBcd[i]>>4;
				if(byTmp<10)
					psAsc[2*i] = byTmp+0x30;
				else
					psAsc[2*i] = byTmp + 0x41 - 10;
				
				byTmp = psBcd[i]&0xf;
				if(byTmp<10)
					psAsc[2*i+1] = byTmp+0x30;
				else
					psAsc[2*i+1] = byTmp + 0x41 - 10;
				break;
		}
	}
}

unsigned char ascToBcd(
	unsigned char *psBcd,
	unsigned char *psAsc,
	unsigned int nLen,
	unsigned char byMode)
{
	unsigned int i;
	unsigned int nRetCode;

	nRetCode=SUC;

	for(i=0;i<nLen/2;i++)
	{
		switch(byMode)
		{
			case 1:
				psBcd[i] = (psAsc[2*i]<<4)+(psAsc[2*i+1]&0xf);
				break;
			case 0:
			default:
				if ((psAsc[2*i]<0x3a)&&(psAsc[2*i]>0x2f))
				{
					psBcd[i] = (psAsc[2*i]-0x30)<<4;
				}
				else
				{
					if((psAsc[2*i]>='A')&&(psAsc[2*i]<='F'))
					{
						psBcd[i] = (psAsc[2*i]-0x41+10)<<4;
					}
					else
					{
						psBcd[i] = psAsc[2*i]<<4;
						nRetCode=ERR;
					}	
				}
				if ((psAsc[2*i+1]<0x3a)&&(psAsc[2*i+1]>0x2f))
				{
					psBcd[i] += psAsc[2*i+1]-0x30;
				}
				else
				{
					if((psAsc[2*i+1]>='A')&&(psAsc[2*i+1]<='F'))
					{
						psBcd[i] += psAsc[2*i+1]-0x41+10;
					}
					else
					{
						psBcd[i] = psAsc[2*i]<<4;
						nRetCode=ERR;
					}	
				}
				break;
		}
	}
	return nRetCode;
}

NTSTATUS StarIccReceCommand(PSMARTCARD_EXTENSION SmartcardExtension)
{
	int i,j,nReceDataLen;
	unsigned char lrc=0;
	unsigned char sReceData[550];
	NTSTATUS status;
	char ch;

	i=0;
	RETAILMSG(1,(TEXT("\r\n@@@@@@stariccrecevcommand  start\r\n")));
	do
	{
		for(j=0;j<10;j++)
		{
			SmartcardExtension->ReaderExtension->SerialIoControlCode =
				SMARTCARD_READ;
			SmartcardExtension->SmartcardReply.BufferLength = 1;
			SmartcardExtension->SmartcardReply.Buffer = &ch;
			status = TLP3SerialIo(SmartcardExtension);
			if (status==STATUS_SUCCESS) break;
		}
		if (status!=STATUS_SUCCESS) return status;
		sReceData[i]=ch;
		if (sReceData[0]==0x36) i++;
		if ((i==2)&&(sReceData[1]!=0x30)) i=0;
	}while((ch!=ETX)||(i==0));
	sReceData[i]=0;

	RETAILMSG(1,(TEXT("\r\n@@@@@@stariccrecevcommand  sReceData = %s\r\n"),sReceData));
	RETAILMSG(1,(TEXT("\r\n@@@@@@stariccrecevcommand sReceDataLength=%d \r\n"),i));

	nReceDataLen=i-3;
	ascToBcd(sReceData,sReceData+2,nReceDataLen,0);
	nReceDataLen=nReceDataLen/2;
	
	for (i=0;i<nReceDataLen;i++)
	{
		lrc ^= sReceData[i];
	}
	lrc ^= STAR_ACK;

	if (lrc!=0)
	{
		return ICC_LRC_ERR;
	}

	if ((nReceDataLen-2) != sReceData[0])
	{
		return ICC_DATAPACK_ERR;
	}

	sReceData[nReceDataLen-2]=0;
	strcpy(SmartcardExtension->SmartcardReply.Buffer,sReceData+2);
	memcpy(&SmartcardExtension->SmartcardReply.BufferLength,sReceData,1);
	RETAILMSG(1,(TEXT("\r\n@@@@@@stariccrecevcommand SmartcardReply.Buffer = %s\r\n"),SmartcardExtension->SmartcardReply.Buffer));
	RETAILMSG(1,(TEXT("\r\n@@@@@@stariccrecevcommand SmartcardReply.BufferLength=%d \r\n"),SmartcardExtension->SmartcardReply.BufferLength));
	return status;
}

NTSTATUS StarIccSendCommand(
	UCHAR Command,
	UCHAR CardNo,
	PSMARTCARD_EXTENSION SmartcardExtension)
{

	UCHAR lrc,ch;
	int nDataLength,k;
	int i;
	UCHAR sDataBuffer[600];
	NTSTATUS status;
	PUCHAR requestBuffer = SmartcardExtension->SmartcardRequest.Buffer;
	PUCHAR replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
	PULONG requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
	PULONG replyLength = &SmartcardExtension->SmartcardReply.BufferLength;
	PULONG serialIoControlCode = &SmartcardExtension->ReaderExtension->SerialIoControlCode;

	RETAILMSG(1,(TEXT("\r\n@@@@@@stariccsendcommand  start \r\n")));
	nDataLength=(int) *requestLength+2;

	ch = 0x60;
	bcdToAsc(sDataBuffer,&ch,1,0);
	lrc = STAR_ACK ^ nDataLength ^ Command ^CardNo;
	k=2;
	bcdToAsc(sDataBuffer+k,(char *)(&nDataLength),1,0);		//type incompile
	
	k+=2;
	bcdToAsc(sDataBuffer+k,&Command,1,0);
	k+=2;
	bcdToAsc(sDataBuffer+k,&CardNo,1,0);
	k+=2;
	if((*requestLength) !=0)
	{
		bcdToAsc(sDataBuffer+k,requestBuffer,*requestLength,0);	
		k+=2*(*requestLength);
	}
	for(i=0;i< (int)*requestLength;i++)
	{
		lrc ^= requestBuffer[i];
	}
	bcdToAsc(sDataBuffer+k,&lrc,1,0);
	k+=2;
	sDataBuffer[k++]=ETX;
	sDataBuffer[k]=0x0;

	strcpy ( requestBuffer,sDataBuffer );
	*requestLength=k;
	*serialIoControlCode = SMARTCARD_WRITE;
	RETAILMSG(1,(TEXT("\r\n@@@@@@stariccsendcommand  requestbuffer = %s\r\n"),requestBuffer));
	RETAILMSG(1,(TEXT("\r\n@@@@@@stariccsendcommand requestLength=%d \r\n"),*requestLength));
	status = TLP3SerialIo(SmartcardExtension);
	return status;
}

NTSTATUS StarIccCommand(
	UCHAR Command,
	UCHAR CardNo,
	PSMARTCARD_EXTENSION SmartcardExtension)
{
	NTSTATUS status;

	status = StarIccSendCommand(Command,CardNo,SmartcardExtension);
	if (status != STATUS_SUCCESS) 
	{
		return status;  
	}

	status=StarIccReceCommand(SmartcardExtension);
	if (status != STATUS_SUCCESS) 
	{
		return status;  
	}
	return status;  
}

⌨️ 快捷键说明

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