📄 smcioctl.c
字号:
SmartcardExtension->CardCapabilities.ATR.Length
);
//**********************************
for(;i<SmartcardExtension->CardCapabilities.ATR.Length;i++)
{ DEBUGMSG(ZQ,(TEXT("0x%2X\r\n"),*SmartcardExtension->IoRequest.ReplyBuffer));
SmartcardExtension->IoRequest.ReplyBuffer++;
}
//***********************************
*SmartcardExtension->IoRequest.Information =
SmartcardExtension->CardCapabilities.ATR.Length;
break;
case SCARD_ATTR_ICC_TYPE_PER_ATR:
//
// Return ICC type, based on ATR.
// We currently support only T=0 and T=1, so return
// 1 for those protocols otherwise 0 (unknown ICC type)
//
CheckMinCardStatus(SCARD_NEGOTIABLE);
ReturnUChar(
((SmartcardExtension->CardCapabilities.Protocol.Selected &
(SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)) ? 1 : 0)
);
break;
case SCARD_ATTR_ICC_PRESENCE:
// Return the status of the card
AccessUnsafeData(&Irql);
switch (SmartcardExtension->ReaderCapabilities.CurrentState) {
case SCARD_UNKNOWN:
status = STATUS_INVALID_DEVICE_STATE;
break;
case SCARD_ABSENT:
ReturnUChar(0);
break;
case SCARD_PRESENT:
ReturnUChar(1);
break;
default:
ReturnUChar(2);
break;
}
EndAccessUnsafeData(Irql);
break;
case SCARD_ATTR_ICC_INTERFACE_STATUS:
// Return if card contacts are active
ReturnUChar(
(SmartcardExtension->ReaderCapabilities.CurrentState >=
SCARD_SWALLOWED ? (UCHAR) -1 : 0)
);
break;
case SCARD_ATTR_PROTOCOL_TYPES:
ReturnULong(
SmartcardExtension->ReaderCapabilities.SupportedProtocols
);
break;
case SCARD_ATTR_MAX_IFSD:
ReturnULong(
SmartcardExtension->ReaderCapabilities.MaxIFSD
);
break;
case SCARD_ATTR_POWER_MGMT_SUPPORT:
ReturnULong(
SmartcardExtension->ReaderCapabilities.PowerMgmtSupport
);
break;
default:
status = STATUS_NOT_SUPPORTED;
break;
}
break;
//IOCTL_SMARTCARD_SET_ATTRIBUTE////////////////////////////////////////////////
case IOCTL_SMARTCARD_SET_ATTRIBUTE:
DEBUGMSG(ZQ,(TEXT("==>>IOCTL_SMARTCARD_SET_ATTRIBUTE\r\n")));
switch (SmartcardExtension->MinorIoControlCode) {
case SCARD_ATTR_SUPRESS_T1_IFS_REQUEST:
//
// The card does not support ifs request, so
// we turn off ifs negotiation
//
SmartcardExtension->T1.State = T1_START;
break;
default:
status = STATUS_NOT_SUPPORTED;
break;
}
break;
//IOCTL_SMARTCARD_CONFISCATE/////////////////////////////////////////////////
case IOCTL_SMARTCARD_CONFISCATE:
DEBUGMSG(ZQ,(TEXT("IOCTL_SMARTCARD_CONFISCATE\r\n")));
if (SmartcardExtension->ReaderFunction[RDF_CARD_CONFISCATE] == NULL) {
status = STATUS_NOT_SUPPORTED;
break;
}
status = SmartcardExtension->ReaderFunction[RDF_CARD_CONFISCATE](
SmartcardExtension
);
break;
//IOCTL_SMARTCARD_EJECT////////////////////////////////////////////////////////
case IOCTL_SMARTCARD_EJECT:
DEBUGMSG(ZQ,(TEXT("IOCTL_SMARTCARD_EJECT\r\n")));
if (SmartcardExtension->ReaderFunction[RDF_CARD_EJECT] == NULL) {
status = STATUS_NOT_SUPPORTED;
break;
}
status = SmartcardExtension->ReaderFunction[RDF_CARD_EJECT](
SmartcardExtension
);
break;
#ifdef SMCLIB_VXD
case IOCTL_SMARTCARD_GET_LAST_ERROR:
//
// Return error of the last overlapped operation
// Used for Windows VxD's that can't return the
// error code within IoComplete like NT can
//
ReturnULong(SmartcardExtension->LastError);
break;
#endif
// IOCTL_SMARTCARD_GET_STATE///////////////////////////////////////////////////
case IOCTL_SMARTCARD_GET_STATE:
DEBUGMSG(ZQ,(TEXT("IOCTL_SMARTCARD_GET_STATE\r\n")));
// Return current state of the smartcard
CheckUserBuffer(sizeof(ULONG));
AccessUnsafeData(&Irql);
*(PULONG) SmartcardExtension->IoRequest.ReplyBuffer =
SmartcardExtension->ReaderCapabilities.CurrentState;
*SmartcardExtension->IoRequest.Information =
sizeof(ULONG);
EndAccessUnsafeData(Irql);
break;
//IOCTL_SMARTCARD_POWER///////////////////////////////////////////////////////////////////
case IOCTL_SMARTCARD_POWER:
if (SmartcardExtension->ReaderFunction[RDF_CARD_POWER] == NULL) {
status = STATUS_NOT_SUPPORTED;
break;
}
// Check if a card is present
if (SmartcardExtension->ReaderCapabilities.CurrentState <=
SCARD_ABSENT) {
status = STATUS_INVALID_DEVICE_STATE;
break;
}
// Initialize the card capabilities struct
SmartcardInitializeCardCapabilities(
SmartcardExtension
);
switch (SmartcardExtension->MinorIoControlCode) {
case SCARD_COLD_RESET:
case SCARD_WARM_RESET:
CheckUserBuffer(MAXIMUM_ATR_LENGTH);
case SCARD_POWER_DOWN:
status = SmartcardExtension->ReaderFunction[RDF_CARD_POWER](
SmartcardExtension
);
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
break;
//IOCTL_SMARTCARD_SET_PROTOCOL///////////////////////////////////////////////////////
case IOCTL_SMARTCARD_SET_PROTOCOL:
DEBUGMSG(ZQ,(TEXT("IOCTL_SMARTCARD_SET_PROTOCOL\r\n")));
//
// Since we return the selected protocol, the return buffer
// must be large enough to hold the result
//
CheckUserBuffer(sizeof(ULONG));
// Set the protocol to be used with the current card
if (SmartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] == NULL) {
status = STATUS_NOT_SUPPORTED;
break;
}
// Check if we're already in specific state
if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC &&
(SmartcardExtension->CardCapabilities.Protocol.Selected &
SmartcardExtension->MinorIoControlCode)) {
status = STATUS_SUCCESS;
break;
}
// Check if a card is present and not already in specific mode
if (SmartcardExtension->ReaderCapabilities.CurrentState <=
SCARD_ABSENT) {
status = STATUS_INVALID_DEVICE_STATE;
break;
}
// We only check the ATR when the user selects T=0 or T=1
if (SmartcardExtension->MinorIoControlCode & SCARD_PROTOCOL_Tx) {
if (SmartcardExtension->MinorIoControlCode & SCARD_PROTOCOL_DEFAULT) {
// Select default PTS values
SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_DEFAULT;
} else {
// Select best possible PTS data
SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_OPTIMAL;
}
// Evaluate ATR
status = SmartcardUpdateCardCapabilities(SmartcardExtension);
} else {
// caller doesn't want neither T=0 nor T=1 -> force callback
status = STATUS_UNRECOGNIZED_MEDIA;
}
if (status == STATUS_UNRECOGNIZED_MEDIA &&
SmartcardExtension->ReaderFunction[RDF_ATR_PARSE] != NULL) {
// let the driver evaluate the ATR, since we don't know it
status = SmartcardExtension->ReaderFunction[RDF_ATR_PARSE](
SmartcardExtension
);
}
if (status != STATUS_SUCCESS) {
// Evaluation of the ATR failed It doesn't make sense to continue
break;
}
// Check if card is now in the right status
if (SmartcardExtension->ReaderCapabilities.CurrentState <
SCARD_NEGOTIABLE) {
status = STATUS_INVALID_DEVICE_STATE;
break;
}
//
// Check if the user tries to select a protocol that
// the card doesn't support
//
if ((SmartcardExtension->CardCapabilities.Protocol.Supported &
SmartcardExtension->MinorIoControlCode) == 0) {
//
// Since the card does not support the request protocol
// we need to set back any automatic seletions done by
// SmartcardUpdateCardCapabilities()
//
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_NEGOTIABLE;
SmartcardExtension->CardCapabilities.Protocol.Selected = 0;
status = STATUS_NOT_SUPPORTED;
break;
}
// WinCE added: mask off protocols not supported by current card
SmartcardExtension->MinorIoControlCode &=
(SCARD_PROTOCOL_DEFAULT | SmartcardExtension->CardCapabilities.Protocol.Supported);
status = SmartcardExtension->ReaderFunction[RDF_SET_PROTOCOL](
SmartcardExtension
);
break;
//IOCTL_SMARTCARD_TRANSMIT////////////////////////////////////////////////////
case IOCTL_SMARTCARD_TRANSMIT:
DEBUGMSG(ZQ,(TEXT("IOCTL_SMARTCARD_TRANSMIT\r\n")));
if (SmartcardExtension->ReaderFunction[RDF_TRANSMIT] == NULL) {
status = STATUS_NOT_SUPPORTED;
break;
}
//
// Check if card is in the right status
//
if (SmartcardExtension->ReaderCapabilities.CurrentState !=
SCARD_SPECIFIC) {
status = STATUS_INVALID_DEVICE_STATE;
break;
}
if (SmartcardExtension->IoRequest.RequestBufferLength <
sizeof(SCARD_IO_REQUEST)) {
status = STATUS_INVALID_PARAMETER;
break;
}
//
// Check if the requested io-protocol matches
// the prev. seleced protocol
//
scardIoRequest = (PSCARD_IO_REQUEST)
SmartcardExtension->IoRequest.RequestBuffer;
if (scardIoRequest->dwProtocol !=
SmartcardExtension->CardCapabilities.Protocol.Selected) {
DEBUGMSG(1,(TEXT("ERROR :STATUS_INVALID_DEVICE_STATE\r\n")));
status = STATUS_INVALID_DEVICE_STATE;
break;
}
SmartcardExtension->SmartcardRequest.BufferLength = 0;
status = SmartcardExtension->ReaderFunction[RDF_TRANSMIT](
SmartcardExtension
);
break;
//IOCTL_SMARTCARD_SWALLOW//////////////////////////////////////////////////////
case IOCTL_SMARTCARD_SWALLOW:
DEBUGMSG(ZQ,(TEXT("IOCTL_SMARTCARD_SWALLOW\r\n")));
if (SmartcardExtension->ReaderFunction[RDF_READER_SWALLOW] == NULL) {
status = STATUS_NOT_SUPPORTED;
break;
}
status = SmartcardExtension->ReaderFunction[RDF_READER_SWALLOW](
SmartcardExtension
);
break;
#if DBG
case IOCTL_SMARTCARD_DEBUG:
//
// Toggle debug bit
//
CurrentDebugLevel =
SmartcardGetDebugLevel();
SmartcardSetDebugLevel(
SmartcardExtension->MinorIoControlCode ^ CurrentDebugLevel
);
break;
#endif
default:
//
// check if the bit for a vendor ioctl is set and if the driver
// has registered a callback function
//
if ((SmartcardExtension->MajorIoControlCode & CTL_CODE(0, 2048, 0, 0)) == 0 ||
SmartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR] == NULL) {
status = STATUS_INVALID_DEVICE_REQUEST;
} else {
//
// Call the driver if it has registered a callback for vendor calls
//
status = SmartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR](
SmartcardExtension
);
}
break;
} // end switch
DEBUGMSG(ZQ,(TEXT("<<==SMCDeviceIoControl( )\r\n")));
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -