📄 scardtpl.cpp
字号:
break ;
case CISTPL_LONGLINK_C:
p->fFlags = TUPLE_FLAG_LINK_TO_C ;
p->uLinkOffset = current->uLinkOffset ;
break ;
case CISTPL_LINKTARGET:
p->fFlags = 0 ;
p->uLinkOffset = 0 ;
break ;
case CISTPL_NO_LINK:
p->fFlags = TUPLE_FLAG_NO_LINK ;
p->uLinkOffset = 0 ;
break ;
default:
// Retain fFlags and uLinkOffset.
break ;
}
return 1 ;
}
STATUS SCard::scanTo (PCARD_TUPLE_PARMS p){
// This happens if there are no tuples.
if (!current)
return CERR_BAD_VERSION ;
UINT16 fAcceptLinks = p->fAttributes & 1 ;
while (scanOneStep (p)){
if (fAcceptLinks){
if (current->uTupleCode == p->uDesiredTuple)
return CERR_SUCCESS ;
if (isLink(current->uTupleCode))
return CERR_SUCCESS ;
if ((p->uDesiredTuple != CISTPL_END) && (current->uTupleCode == CISTPL_END))
return CERR_NO_MORE_ITEMS ;
}
else{
if (firstStopRejectLinks(p->uDesiredTuple))
return (current->uTupleCode == p->uDesiredTuple) ? CERR_SUCCESS : CERR_NO_MORE_ITEMS ;
if ((p->uDesiredTuple != CISTPL_END) && (current->uTupleCode == CISTPL_END))
return CERR_NO_MORE_ITEMS ;
}
}
return CERR_NO_MORE_ITEMS ;
}
// Check p and p->hSocket.
STATUS SCard::socketCheck (PCARD_TUPLE_PARMS p){
if (!p)
return CERR_BAD_ARGS ;
// With variable socket handle support it is no longer viable to check socket numbers
// if ((p->hSocket).uSocket || (p->hSocket).uFunction) return CERR_BAD_SOCKET ;
return CERR_SUCCESS ;
}
int SCard::isValid () {return head ? 1 : 0 ;}
VOID SCard::addTuple (PCARD_TUPLE_PARMS pParms, HCard *p){
PCARD_DATA_PARMS pData = newDataParmsFromTupleParms (pParms) ;
if (CERR_SUCCESS == p->CardGetTupleData(pData))
addTuple (pParms->uTupleCode, pParms->uTupleLink, pData) ;
delete pData ;
}
VOID SCard::addTuple (UINT8 cisTplCode, UINT8 length, PCARD_DATA_PARMS pParms){
// This might be the first tuple.
if (!head) {
current = head = new SCardTuple (cisTplCode, length, pParms) ;
return ;
}
// Straddle the target location.
SCardTuple *pLead = head, *pTrail = 0 ;
while (pLead && pLead->idPreceeds(pParms))
pLead = (pTrail=pLead)->link ;
// Maybe it is already there.
if (pLead && pLead->idMatches(pParms))
return ;
// Make a new tuple.
SCardTuple *pSCardTuple = new SCardTuple (cisTplCode, length, pParms) ;
if(pSCardTuple == NULL){
g_pKato->Log(LOG_FAIL,TEXT("-->SCard::addTuple<-- FAIL -- out of memory\r\n"));
return;
}
// Now add it.
pSCardTuple->link = pLead ;
if (pTrail)
pTrail->link = pSCardTuple ; // pTrail < pSCardTuple < pLead
else
head = pSCardTuple ; // pLead == head, add at the start.
}
int SCard::firstStopRejectLinks (UINT8 uDesiredTuple){
switch (current->uTupleCode){
case CISTPL_LONGLINK_CB:
case CISTPL_LONG_LINK_MFC:
case CISTPL_LONGLINK_A:
case CISTPL_LONGLINK_C:
case CISTPL_LINKTARGET:
case CISTPL_NO_LINK:
return 0 ;
}
if (!current)
return 1 ;
// Maybe this is it.
if (uDesiredTuple == current->uTupleCode)
return 1 ;
// Maybe the tuples are exhausted.
if (!(current->link))
return 1 ;
return 0 ;
}
int SCard::firstStopAcceptLinks (UINT8 uDesiredTuple){
if (!current)
return 1 ;
// Maybe this is it.
if (uDesiredTuple == current->uTupleCode)
return 1 ;
// Maybe the tuples are exhausted.
if (!(current->link))
return 1 ;
// Now we can accept link tuples.
switch (current->uTupleCode){
case CISTPL_LONGLINK_CB:
case CISTPL_LONG_LINK_MFC:
case CISTPL_LONGLINK_A:
case CISTPL_LONGLINK_C:
case CISTPL_LINKTARGET:
case CISTPL_END:
case CISTPL_NULL:
return 1;
default:
return 0 ;
}
}
int SCard::firstStop (UINT8 uDesiredTuple, UINT16 fAttributes){
int rtn = (fAttributes & 1) ? firstStopAcceptLinks (uDesiredTuple) :firstStopRejectLinks (uDesiredTuple) ;
return rtn ;
}
STATUS SCard::CardGetFirstTuple (PCARD_TUPLE_PARMS p){
STATUS rtnVal = socketCheck (p) ;
if (rtnVal != CERR_SUCCESS)
return rtnVal ;
// If we are looking for a link and specified skip links
if (!(p->fAttributes&1) && isLink(p->uDesiredTuple))
return CERR_NO_MORE_ITEMS ;
current = head ;
while (current && (p->uDesiredTuple != current->uTupleCode))
current = current->link ;
// Possible quick answer.
if (!current)
return CERR_NO_MORE_ITEMS ;
// Possible unacceptable link tuple
if (!(p->fAttributes&1) && isLink(current->uTupleCode))
return CERR_NO_MORE_ITEMS ;
// Mark the located tuple.
p->uTupleCode = current->uTupleCode ;
p->uTupleLink = current->uTupleLink ;
// Did we find what we were looking for ?
if (p->uDesiredTuple == current->uTupleCode){
return CERR_SUCCESS ;
}
//
if (p->uDesiredTuple == CISTPL_NULL)
return CERR_SUCCESS;
else
return CERR_NO_MORE_ITEMS ;
}
STATUS SCard::CardGetNextTuple (PCARD_TUPLE_PARMS p){
STATUS rtnVal = socketCheck (p) ;
if (rtnVal != CERR_SUCCESS)
return rtnVal ; // CISTPL_BAD_ARGS or CISTPL_BAD_SOCKET
if (current)
rtnVal = scanTo (p) ;
else
rtnVal = CERR_NO_MORE_ITEMS ;
if (rtnVal == CERR_NO_MORE_ITEMS)
current = head ;
if (current){
p->uTupleCode = current->uTupleCode ;
p->uTupleLink = current->uTupleLink ;
}
return rtnVal ;
}
STATUS SCard::CardGetTupleData (PCARD_DATA_PARMS p)
{
STATUS rtnVal = socketCheck ((PCARD_TUPLE_PARMS)p) ;
if (rtnVal != CERR_SUCCESS) return rtnVal ;
if (!current) return CERR_READ_FAILURE ;
if (!current->uTupleLink) {p->uDataLen = 0 ; return CERR_SUCCESS ;}
// Maybe we cannot store all the requested tuple data.
// uTupleOffset is the amount of the tuple to skip at the start.
// According to Mr. Kanz, we always get all data from uTupleOffset to the end.
if(current->uTupleCode == CISTPL_END){
NKDbgPrintfW(_T("tplend"));
return CERR_SUCCESS;
}
// Verify that we asked for at least 0 bytes.
if (p->uTupleOffset > current->uTupleLink) {
NKDbgPrintfW(_T("udatalen=0"));
return CERR_BAD_ARG_LENGTH ;}
// Verify that we will have p->uDataLen <= p->uBufLen.
if ((current->uTupleLink - p->uTupleOffset) > p->uBufLen) {
NKDbgPrintfW(_T("udatalen>ubuflen"));
return CERR_BAD_ARG_LENGTH ;}
// We will now have p->uDataLen <= p->uBufLen.
p->uDataLen = current->uTupleLink - p->uTupleOffset ;
// Now check to see if some data is actually requested.
if (!p->uDataLen) return CERR_SUCCESS ;
PUCHAR q = (PUCHAR)p + sizeof (CARD_DATA_PARMS) ;
memcpy (q, current->pTupleData + p->uTupleOffset, p->uDataLen) ;
NKDbgPrintfW(_T("Normal"));
return CERR_SUCCESS ;
}
STATUS SCard::CardGetParsedTuple (CARD_SOCKET_HANDLE hSocket,
UINT8 uDesiredTuple,
PVOID pBuf,
PUINT pnItems)
{
// Find the first uDesiredTuple, in pointer p.
for (SCardTuple *p = head ; p && (p->uTupleCode != uDesiredTuple) ; p = p->link) ;
// In case of no such tuple
if (!p) {
*pnItems = 0 ;
return CERR_NO_MORE_ITEMS ;
}
// In case of no data
if (!p->parsedSize) {
*pnItems = 0 ;
return CERR_NO_MORE_ITEMS ;
}
// Maybe we didn't even ask for any data
if (*pnItems == 0)
return CERR_BAD_ARG_LENGTH ;
UINT nCount = (*pnItems > p->nParsedItems) ? p->nParsedItems : *pnItems ;
// I do not have the size of pBuf to check it.
switch (uDesiredTuple){
case CISTPL_CFTABLE_ENTRY:
memcpy (pBuf, p->parsedBuf, nCount * sizeof(PARSED_CFTABLE)) ;
*pnItems = nCount ;
return CERR_SUCCESS ;
case CISTPL_CONFIG:
memcpy (pBuf, p->parsedBuf, nCount * sizeof(PARSED_CONFIG)) ;
*pnItems = nCount ;
return CERR_SUCCESS ;
default:
return CERR_READ_FAILURE ;
}
}
STATUS SCard::CardGetThisTuple (PCARD_TUPLE_PARMS p)
{
if (!p) return CERR_BAD_ARGS ;
if (!goToId(p)) return CERR_NO_MORE_ITEMS ;
p->uTupleCode = current->uTupleCode ;
p->uTupleLink = current->uTupleLink ;
return CERR_SUCCESS ;
}
int SCard::goToId (UINT16 flags, UINT32 offset){
for (SCardTuple *p = head ; p && !p->idMatches(flags,offset) ; p = p->link) ;
if (p) {
current = p ;
return 1 ;
}
return 0 ;
}
int SCard::goToId (PCARD_TUPLE_PARMS p) {return goToId (p->fFlags, p->uCISOffset) ;}
int SCard::goToId (PCARD_DATA_PARMS p) {return goToId (p->fFlags, p->uCISOffset) ;}
int SCard::idMatches (UINT16 flags, UINT32 offset, SCardTuple *p)
{return p->idMatches (flags, offset) ;}
int SCard::idMatches (PCARD_DATA_PARMS pData, SCardTuple *p)
{return idMatches ((PCARD_TUPLE_PARMS)pData, p) ;}
int SCard::idMatches (PCARD_TUPLE_PARMS pTuple, SCardTuple *p)
{return p->idMatches (pTuple) ;}
int SCard::isPresent (PCARD_TUPLE_PARMS p){
for (SCardTuple *q = head ; q ; q = q->link)
if (q->idMatches(p))
return 1 ;
return 0 ;
}
UINT8 SCard::getTupleType (PCARD_TUPLE_PARMS p){
for (SCardTuple *q = head ; q ; q = q->link)
if (q->idMatches(p))
return q->uTupleCode ;
return 0xFF ; // Unknown
}
VOID SCard::dump () {for (SCardTuple *q = head ; q ; q = q->link) q->dump () ;}
HCard::HCard () {;}
HCard::~HCard () {;}
STATUS HCard::CardGetFirstTuple (PCARD_TUPLE_PARMS p){
STATUS status = ::CardGetFirstTuple(p);
return status ;
}
STATUS HCard::CardGetNextTuple (PCARD_TUPLE_PARMS p){
STATUS status = ::CardGetNextTuple(p);
return status ;
}
STATUS HCard::CardGetTupleData (PCARD_DATA_PARMS p){
STATUS status = ::CardGetTupleData(p);
return status ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -