📄 smcutil.c
字号:
status = STATUS_UNRECOGNIZED_MEDIA;
leave;
}
}
finally {
if (status != STATUS_SUCCESS) {
if (cardCapabilities->InversConvention == TRUE) {
SmartcardInvertData(
cardCapabilities->ATR.Buffer,
cardCapabilities->ATR.Length
);
cardCapabilities->InversConvention = FALSE;
}
}
}
if (status != STATUS_SUCCESS)
return status;
// store historical characters
RtlCopyMemory(
cardCapabilities->HistoricalChars.Buffer,
atrString,
cardCapabilities->HistoricalChars.Length
);
//
// Now convert TA - TD values to global interface bytes
//
// Clock rate conversion
cardCapabilities->Fl = (TA[0] & 0xf0) >> 4;
// bit rate adjustment
cardCapabilities->Dl = (TA[0] & 0x0f);
// Maximum programming current factor
cardCapabilities->II = (TB[0] & 0xc0) >> 6;
// Programming voltage in 0.1 Volts
cardCapabilities->P = (TB[1] ? TB[1] : (TB[0] & 0x1f) * 10);
// Extra guard time
cardCapabilities->N = TC[0];
//
// Check if the Dl and Fl values are valid
//
if (BitRateAdjustment[cardCapabilities->Dl].DNumerator == 0 ||
ClockRateConversion[cardCapabilities->Fl].F == 0) {
SmartcardDebug(
DEBUG_ATR,
(TEXT(" Dl = %02x or Fl = %02x invalid\n"),
cardCapabilities->Dl,
cardCapabilities->Fl)
);
return STATUS_UNRECOGNIZED_MEDIA;
}
ASSERT(readerCapabilities->CLKFrequency.Max != 0);
ASSERT(readerCapabilities->CLKFrequency.Default != 0);
SmartcardDebug(
DEBUG_ATR,
(TEXT(" Card parameters from ATR:\n Fl = %02x (%ld KHz), Dl = %02x, I = %02x, P = %02x, N = %02x\n"),
cardCapabilities->Fl,
ClockRateConversion[cardCapabilities->Fl].fs / 1000,
cardCapabilities->Dl,
cardCapabilities->II,
cardCapabilities->P,
cardCapabilities->N)
);
//
// assume default clock frequency
//
fs = readerCapabilities->CLKFrequency.Default * 1000l;
if (fs == 0) {
fs = 372 * 9600l;
}
if (cardCapabilities->PtsData.Type == PTS_TYPE_DEFAULT) {
//
// Assume default parameters
//
cardCapabilities->PtsData.Fl = 1;
cardCapabilities->PtsData.Dl = 1;
cardCapabilities->PtsData.DataRate =
readerCapabilities->DataRate.Default;
cardCapabilities->PtsData.CLKFrequency =
readerCapabilities->CLKFrequency.Default;
}
if (cardCapabilities->PtsData.Type != PTS_TYPE_DEFAULT) {
//
// Try to find optimal parameters:
// Highest possible clock frequency of the card
// combined with fastes data rate
//
//
// We now try to find a working Fl and Dl combination
//
if (cardCapabilities->PtsData.Type == PTS_TYPE_OPTIMAL) {
cardCapabilities->PtsData.Fl = cardCapabilities->Fl;
}
ASSERT(cardCapabilities->PtsData.Fl < 16);
ASSERT(ClockRateConversion[cardCapabilities->PtsData.Fl].F);
if (cardCapabilities->PtsData.Fl > 15 ||
ClockRateConversion[cardCapabilities->PtsData.Fl].F == 0) {
return STATUS_INVALID_PARAMETER;
}
do {
ULONG cardFreq;
if (readerCapabilities->CLKFrequenciesSupported.Entries == 0 ||
readerCapabilities->CLKFrequenciesSupported.List == NULL) {
//
// The clock freq. list supplied by the reader is empty
// We take the standard values supplied by the reader
//
readerCapabilities->CLKFrequenciesSupported.List =
&readerCapabilities->CLKFrequency.Default;
readerCapabilities->CLKFrequenciesSupported.Entries = 2;
}
//
// Find the highest possible clock freq. supported
// by the card and the reader
//
cardFreq =
ClockRateConversion[cardCapabilities->PtsData.Fl].fs /
1000;
cardCapabilities->PtsData.CLKFrequency = 0;
for (i = 0; i < readerCapabilities->CLKFrequenciesSupported.Entries; i++) {
// look for highes possible reader frequency
if (readerCapabilities->CLKFrequenciesSupported.List[i] >
cardCapabilities->PtsData.CLKFrequency &&
readerCapabilities->CLKFrequenciesSupported.List[i] <=
cardFreq) {
cardCapabilities->PtsData.CLKFrequency =
readerCapabilities->CLKFrequenciesSupported.List[i];
}
}
fs = cardCapabilities->PtsData.CLKFrequency * 1000;
cardCapabilities->PtsData.DataRate = 0;
ASSERT(fs != 0);
if (fs == 0) {
return STATUS_INVALID_PARAMETER;
}
if (cardCapabilities->PtsData.Type == PTS_TYPE_OPTIMAL) {
cardCapabilities->PtsData.Dl = cardCapabilities->Dl;
}
ASSERT(cardCapabilities->PtsData.Dl < 16);
ASSERT(BitRateAdjustment[cardCapabilities->PtsData.Dl].DNumerator);
if (cardCapabilities->PtsData.Dl > 15 ||
BitRateAdjustment[cardCapabilities->PtsData.Dl].DNumerator == 0) {
return STATUS_INVALID_PARAMETER;
}
if (readerCapabilities->DataRatesSupported.Entries == 0 ||
readerCapabilities->DataRatesSupported.List == NULL) {
//
// The data rate list supplied by the reader is empty.
// We take the standard min/max values of the reader
//
readerCapabilities->DataRatesSupported.List =
&readerCapabilities->DataRate.Default;
readerCapabilities->DataRatesSupported.Entries = 2;
}
//
// Now try to find the highest possible matching data rate
// (A matching data rate is one that VERY close
// to one supplied by the reader)
//
while(cardCapabilities->PtsData.Dl > 1) {
ULONG dataRate;
//
// Calculate the data rate using the current values
//
dataRate =
(BitRateAdjustment[cardCapabilities->PtsData.Dl].DNumerator *
fs) /
(BitRateAdjustment[cardCapabilities->PtsData.Dl].DDivisor *
ClockRateConversion[cardCapabilities->PtsData.Fl].F);
//
// Try to find a matching data rate
//
for (i = 0; i < readerCapabilities->DataRatesSupported.Entries; i++) {
if (readerCapabilities->DataRatesSupported.List[i] * 101 > dataRate * 100 &&
readerCapabilities->DataRatesSupported.List[i] * 99 < dataRate * 100) {
cardCapabilities->PtsData.DataRate =
readerCapabilities->DataRatesSupported.List[i];
break;
}
}
if (cardCapabilities->PtsData.DataRate) {
break;
}
//
// Select the next valid lower D value
//
while (BitRateAdjustment[--cardCapabilities->PtsData.Dl].DNumerator == 0)
;
}
if (cardCapabilities->PtsData.Fl == 1 &&
cardCapabilities->PtsData.Dl == 1) {
cardCapabilities->PtsData.DataRate =
readerCapabilities->DataRate.Default;
cardCapabilities->PtsData.CLKFrequency =
readerCapabilities->CLKFrequency.Default;
break;
}
if (cardCapabilities->PtsData.DataRate) {
break;
}
//
// Select the next valid lower F value
//
while (ClockRateConversion[--cardCapabilities->PtsData.Fl].F == 0)
;
} while(cardCapabilities->PtsData.DataRate == 0);
}
ASSERT(fs != 0);
ASSERT(cardCapabilities->PtsData.Dl < 16);
ASSERT(BitRateAdjustment[cardCapabilities->PtsData.Dl].DNumerator != 0);
//
// We calculate the ETU on basis of the timing supplied by the
// clk-frequency of the reader
//
//
// Work etu in units of time resolution(TR) (NOT in seconds)
//
cardCapabilities->etu =
1 + // required to round up
(TR *
BitRateAdjustment[cardCapabilities->PtsData.Dl].DDivisor *
ClockRateConversion[cardCapabilities->PtsData.Fl].F) /
(BitRateAdjustment[cardCapabilities->PtsData.Dl].DNumerator *
fs);
//
// guard time in micro seconds
// the guard time is the gap between the end of the
// current character and the beginning of the next character
//
cardCapabilities->GT = 0;
if (cardCapabilities->N == 0) {
cardCapabilities->PtsData.StopBits = 2;
} else if (cardCapabilities->N == 255) {
cardCapabilities->PtsData.StopBits = 1;
} else {
cardCapabilities->GT = cardCapabilities->N * cardCapabilities->etu;
}
SmartcardDebug(
DEBUG_ATR,
(TEXT(" PTS parameters (%s):\n Fl = %02x (%ld KHz), Dl = %02x (%ld Bps, %d Stop Bits)\n"),
ptsType[cardCapabilities->PtsData.Type],
cardCapabilities->PtsData.Fl,
cardCapabilities->PtsData.CLKFrequency,
cardCapabilities->PtsData.Dl,
cardCapabilities->PtsData.DataRate,
cardCapabilities->PtsData.StopBits)
);
SmartcardDebug(
DEBUG_ATR,
(TEXT(" Calculated timing values:\n Work etu = %ld micro sec, Guard time = %ld micro sec\n"),
cardCapabilities->etu,
cardCapabilities->GT)
);
if (TA2Present || numProtocols <= 1 && cardCapabilities->Fl == 1 && cardCapabilities->Dl == 1) {
//
// If the card supports only one protocol (or T=0 as default)
// and only standard paramters then PTS selection is not available
//
SmartcardExtension->ReaderCapabilities.CurrentState =
SCARD_SPECIFIC;
} else {
SmartcardExtension->ReaderCapabilities.CurrentState =
// SCARD_NEGOTIABLE;
SCARD_SPECIFIC;
}
//
// Now find protocol specific data
//
if (TD[0] == 0) {
cardCapabilities->Protocol.Supported |=
SCARD_PROTOCOL_T0;
cardCapabilities->T0.WI = TC[1];
if (cardCapabilities->PtsData.Dl > 0 &&
cardCapabilities->PtsData.Dl < 6) {
cardCapabilities->T0.WT = 1 +
cardCapabilities->T0.WI *
960 * cardCapabilities->etu *
Pow2((UCHAR) (cardCapabilities->PtsData.Dl - 1));
} else {
cardCapabilities->T0.WT = 1+
cardCapabilities->T0.WI *
960 * cardCapabilities->etu /
Pow2((UCHAR) (cardCapabilities->PtsData.Dl - 1));
}
SmartcardDebug(
DEBUG_ATR,
(TEXT(" T=0 Values from ATR:\n WI = %ld\n"),
cardCapabilities->T0.WI)
);
SmartcardDebug(
DEBUG_ATR,
(TEXT(" T=0 Timing from ATR:\n WT = %ld ms\n"),
cardCapabilities->T0.WT / 1000)
);
}
if (protocolTypes & SCARD_PROTOCOL_T1) {
for (i = 0; TD[i] != 1 && i < MAXIMUM_ATR_CODES; i++)
;
for (; TD[i] == 1 && i < MAXIMUM_ATR_CODES; i++)
;
if (i == MAXIMUM_ATR_CODES) {
return STATUS_UNRECOGNIZED_MEDIA;
}
cardCapabilities->Protocol.Supported |=
SCARD_PROTOCOL_T1;
cardCapabilities->T1.IFSC =
(TA[i] ? TA[i] : 32);
cardCapabilities->T1.CWI =
((TB[i] & 0x0f) ? (TB[i] & 0x0f) : T1_CWI_DEFAULT);
cardCapabilities->T1.BWI =
((TB[i] & 0xf0) >> 4 ? (TB[i] & 0xf0) >> 4 : T1_BWI_DEFAULT);
cardCapabilities->T1.EDC =
(TC[i] & 0x01);
cardCapabilities->T1.CWT = 1 +
(Pow2(cardCapabilities->T1.CWI) + 11) * cardCapabilities->etu;
cardCapabilities->T1.BWT = 1 +
((Pow2(cardCapabilities->T1.BWI) * TR) / 10) +
11 * cardCapabilities->etu;
SmartcardDebug(
DEBUG_ATR,
(TEXT(" T=1 Values from ATR:\n IFSC = %ld, CWI = %ld, BWI = %ld, EDC = %02x\n"),
cardCapabilities->T1.IFSC,
cardCapabilities->T1.CWI,
cardCapabilities->T1.BWI,
cardCapabilities->T1.EDC)
);
SmartcardDebug(
DEBUG_ATR,
(TEXT(" T=1 Timing from ATR:\n CWT = %ld ms, BWT = %ld ms\n"),
cardCapabilities->T1.CWT / 1000,
cardCapabilities->T1.BWT / 1000)
);
}
if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC) {
if (TA2Present) {
//
// TA2 is present in the ATR, so use
// the protocol indicated in the ATR
//
cardCapabilities->Protocol.Selected = 1 << TA[1];
} else {
//
// The card only supports one protocol
// So make that one protocol the current one to use
//
cardCapabilities->Protocol.Selected =
cardCapabilities->Protocol.Supported;
}
SmartcardDebug(
DEBUG_ATR,
(TEXT(" Mode: Specific %s\n\n"),
TA2Present ? TEXT("set by TA(2)") : TEXT(""))
);
} else {
SmartcardDebug(
DEBUG_ATR,
(TEXT(" Mode: Negotiable\n\n"))
);
}
//
// Every card has to support the 'raw' protocol
// It enables the usage of cards that have their own protocol defined
//
SmartcardExtension->CardCapabilities.Protocol.Supported |=
SCARD_PROTOCOL_RAW;
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -