📄 usbcom.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
Copyright (c) 1997 SCM Microsystems, Inc.
Module Name:
usbcom.c
--*/
#include "common.h"
#include "stcCmd.h"
#include "usbcom.h"
// this is the longest transfer size we expect from the reader
static DWORD dwUsbReadLen = 64;
NTSTATUS STCtoNT(
UCHAR ucData[])
/*++
Routine Description:
Error code translation routine
Arguments:
ucData Error code returned by the STC
Return Value:
Corresponding NT error code
--*/
{
USHORT usCode = ucData[0]*0x100 +ucData[1];
NTSTATUS NtStatus;
switch (usCode)
{
case 0x9000:
NtStatus = STATUS_SUCCESS;
break;
case 0x5800:
NtStatus = STATUS_UNSUCCESSFUL;
break;
case 0x2000:
NtStatus = STATUS_UNSUCCESSFUL;
break;
case 0x4000:
NtStatus = STATUS_UNSUCCESSFUL;
break;
case 0x64A1:
NtStatus = STATUS_NO_MEDIA;
break;
case 0x64A0:
NtStatus = STATUS_MEDIA_CHANGED;
break;
case 0x6203:
NtStatus = STATUS_UNSUCCESSFUL;
break;
case 0x6300:
NtStatus = STATUS_UNSUCCESSFUL;
break;
case 0x6500:
NtStatus = STATUS_UNSUCCESSFUL;
break;
case 0x6A00:
NtStatus = STATUS_UNSUCCESSFUL;
break;
case 0x6A80:
NtStatus = STATUS_UNSUCCESSFUL;
break;
default:
NtStatus = STATUS_UNSUCCESSFUL;
break;
}
return(NtStatus);
}
NTSTATUS
UsbWriteSTCData(
PREADER_EXTENSION ReaderExtension,
PUCHAR pucData,
ULONG ulSize)
/*++
Routine Description:
Write data in the STC
Arguments:
ReaderExtension Context of the call
APDU Buffer to write
ulAPDULen Length of the buffer to write
Return Value:
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
PUCHAR pucCmd;
UCHAR ucResponse[3];
BOOLEAN resend = TRUE;
LONG Len;
ULONG Index;
LONG refLen = (LONG) ulSize;
pucCmd = malloc(MIN_BUFFER_SIZE);
if(pucCmd==NULL)
{
return(STATUS_NO_MEMORY);
}
ReaderExtension->ulReadBufferLen = 0;
// Build the write data command
Len = refLen;
Index=0;
while (resend == TRUE)
{
if(Len> 62)
{
Len = 62;
resend = TRUE;
}
else
{
resend = FALSE;
}
*pucCmd = 0xA0;
*(pucCmd+1) = (UCHAR) Len;
memcpy( pucCmd + 2, pucData+Index, Len );
// Send the Write data command
NTStatus = UsbWrite( ReaderExtension, pucCmd, 2 + Len);
if (NTStatus != STATUS_SUCCESS)
{
SmartcardDebug(
DEBUG_DRIVER,
(TEXT("%s!UsbWriteSTCData: write error %X \n"),
DRIVER_NAME,
NTStatus)
);
break;
}
// Read the response
NTStatus = UsbRead( ReaderExtension, ucResponse, 3);
if (NTStatus != STATUS_SUCCESS)
{
SmartcardDebug(
DEBUG_DRIVER,
(TEXT("%s!UsbWriteSTCData: read error %X \n"),
DRIVER_NAME,
NTStatus)
);
break;
}
else
{
// Test if what we read is really a response to a write
if(ucResponse[0] != 0xA0)
{
NTStatus = STCtoNT(ucResponse);
if (NTStatus == STATUS_SUCCESS)
NTStatus = STATUS_UNSUCCESSFUL; // 9000 won't do here
break;
}
}
Index +=62;
Len = refLen - 62;
refLen = refLen - 62;
}
free( pucCmd );
return(STATUS_SUCCESS);
}
NTSTATUS
UsbReadSTCData(
PREADER_EXTENSION ReaderExtension,
PUCHAR pucData,
ULONG ulDataLen)
/*++
Routine Description:
Read data from the STC
Arguments:
ReaderExtension Context of the call
ulAPDULen Length of the buffer to write
pucData Output Buffer
Return Value:
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
UCHAR ucCmd[1];
PUCHAR pucResponse;
ULONG ulLenExpected = ulDataLen;
ULONG Index=0;
BOOLEAN SendReadCommand = TRUE;
DWORD Begin;
SmartcardDebug(
DEBUG_DRIVER,
(TEXT("%s!UsbReadSTCData: Enter\n"),
DRIVER_NAME)
);
pucResponse = malloc( MIN_BUFFER_SIZE);
if(pucResponse==NULL)
{
return(STATUS_NO_MEMORY);
}
Begin = GetTickCount();
// First let see if we have not already read the data that
// we need
if(ReaderExtension->ulReadBufferLen != 0)
{
if(ReaderExtension->ulReadBufferLen >= ulLenExpected)
{
// all the data that we need are available
memcpy(pucData,ReaderExtension->ucReadBuffer,ulLenExpected);
ReaderExtension->ulReadBufferLen = ReaderExtension->ulReadBufferLen - ulLenExpected;
if(ReaderExtension->ulReadBufferLen != 0)
{
memcpy(
ReaderExtension->ucReadBuffer,
ReaderExtension->ucReadBuffer+ulLenExpected,
ReaderExtension->ulReadBufferLen);
}
SendReadCommand = FALSE;
}
else
{
// all the data that we need are not available
memcpy(pucData,ReaderExtension->ucReadBuffer,ReaderExtension->ulReadBufferLen);
ulLenExpected = ulLenExpected - ReaderExtension->ulReadBufferLen;
Index = ReaderExtension->ulReadBufferLen;
ReaderExtension->ulReadBufferLen = 0;
SendReadCommand = TRUE;
}
}
while( SendReadCommand == TRUE)
{
// Build the Read Register command
ucCmd[0] = 0xE0;
NTStatus = UsbWrite( ReaderExtension, ucCmd, 1);
if (NTStatus != STATUS_SUCCESS)
{
SmartcardDebug(
DEBUG_DRIVER,
(TEXT("%s!UsbReadSTCData: write error %X \n"),
DRIVER_NAME,
NTStatus)
);
break;
}
// Make buffer as big as possible since we're caching this data.
NTStatus = UsbRead( ReaderExtension, pucResponse, dwUsbReadLen);
if (NTStatus != STATUS_SUCCESS)
{
ReaderExtension->ulReadBufferLen = 0;
NTStatus =STATUS_IO_TIMEOUT;
SmartcardDebug(
DEBUG_DRIVER,
(TEXT("%s!UsbReadSTCData: read error %X \n"),
DRIVER_NAME,
NTStatus)
);
break;
}
// Test if what we read is really a READ DATA frame
if(*pucResponse != 0xE0)
{
if((*pucResponse == 0x64)&&(*(pucResponse+1) == 0xA0))
{
NTStatus = STATUS_NO_MEDIA;
}
else
{
NTStatus = STCtoNT(pucResponse);
if (NTStatus == STATUS_SUCCESS)
NTStatus = STATUS_UNSUCCESSFUL; // 9000 won't do here
}
break;
}
// If there is no data available
if (*(pucResponse+1) == 0)
{
if ( (GetTickCount() - Begin) <= ReaderExtension->ReadTimeout )
{
SendReadCommand = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -