📄 scard.c
字号:
if (!sendBuf) return SC_returnNoMemoryError(&lcHandle, in, out); in_uint8a(in, sendBuf, linkedLen); inRepos(in, linkedLen); } else sendBuf = NULL; if (cbRecvLength) { recvBuf = SC_xmalloc(&lcHandle, cbRecvLength); if (!recvBuf) return SC_returnNoMemoryError(&lcHandle, in, out); } if (map[4] & INPUT_LINKED) { pioRecvPci = SC_xmalloc(&lcHandle, sizeof(SERVER_SCARD_IO_REQUEST)); if (!pioRecvPci) return SC_returnNoMemoryError(&lcHandle, in, out); in_uint8a(in, pioRecvPci, sizeof(SERVER_SCARD_IO_REQUEST)); in_uint32_le(in, map[6]); if (map[6] & INPUT_LINKED) { in_uint32_le(in, linkedLen); pioRecvPci->cbPciLength = linkedLen + sizeof(SERVER_SCARD_IO_REQUEST); tmp = SC_xmalloc(&lcHandle, pioRecvPci->cbPciLength); if (!tmp) return SC_returnNoMemoryError(&lcHandle, in, out); in_uint8a(in, (void *) ((unsigned char *) tmp + sizeof(SERVER_SCARD_IO_REQUEST)), linkedLen); memcpy(tmp, pioRecvPci, sizeof(SERVER_SCARD_IO_REQUEST)); SC_xfree(&lcHandle, pioRecvPci); pioRecvPci = tmp; tmp = NULL; } else pioRecvPci->cbPciLength = sizeof(SERVER_SCARD_IO_REQUEST); } else pioRecvPci = NULL; DEBUG_SCARD(("SCARD: SCardTransmit(hcard: 0x%08x [0x%08lx], send: %d bytes, recv: %d bytes)\n", (unsigned) hCard, (unsigned long) myHCard, (int) cbSendLength, (int) cbRecvLength)); myCbRecvLength = cbRecvLength; myPioSendPci = SC_xmalloc(&lcHandle, sizeof(MYPCSC_SCARD_IO_REQUEST) + pioSendPci->cbPciLength - sizeof(SERVER_SCARD_IO_REQUEST)); if (!myPioSendPci) return SC_returnNoMemoryError(&lcHandle, in, out); copyIORequest_ServerToMyPCSC(pioSendPci, myPioSendPci); /* always a send, not always a recv */ if (pioRecvPci) { myPioRecvPci = SC_xmalloc(&lcHandle, sizeof(MYPCSC_SCARD_IO_REQUEST) + pioRecvPci->cbPciLength - sizeof(SERVER_SCARD_IO_REQUEST)); if (!myPioRecvPci) return SC_returnNoMemoryError(&lcHandle, in, out); copyIORequest_ServerToMyPCSC(pioRecvPci, myPioRecvPci); } else { myPioRecvPci = NULL; } rv = SCardTransmit(myHCard, myPioSendPci, sendBuf, (MYPCSC_DWORD) cbSendLength, myPioRecvPci, recvBuf, &myCbRecvLength); cbRecvLength = myCbRecvLength; /* FIXME: handle responses with length > 448 bytes */ if (cbRecvLength > 448) { warning("Card response limited from %d to 448 bytes!\n", cbRecvLength); DEBUG_SCARD(("SCARD: Truncated %d to %d\n", (unsigned int) cbRecvLength, 448)); cbRecvLength = 448; } if (pioRecvPci) { /* * pscs-lite mishandles this structure in some cases. * make sure we only copy it if it is valid. */ if (myPioRecvPci->cbPciLength >= sizeof(MYPCSC_SCARD_IO_REQUEST)) copyIORequest_MyPCSCToServer(myPioRecvPci, pioRecvPci); } if (rv != SCARD_S_SUCCESS) { DEBUG_SCARD(("SCARD: -> Failure: %s (0x%08x)\n", pcsc_stringify_error(rv), (unsigned int) rv)); } else { DEBUG_SCARD(("SCARD: -> Success (%d bytes)\n", (int) cbRecvLength));#if 0 if ((pioRecvPci != NULL) && (mypioRecvPci->cbPciLength > 0)) { out_uint32_le(out, (DWORD) pioRecvPci); /* if not NULL, this 4 bytes indicates that pioRecvPci is present */ } else#endif out_uint32_le(out, 0); /* pioRecvPci 0x00; */ outBufferStart(out, cbRecvLength); /* start of recvBuf output */#if 0 if ((pioRecvPci) && (mypioRecvPci->cbPciLength > 0)) { out_uint32_le(out, mypioRecvPci->dwProtocol); int len = mypioRecvPci->cbPciLength - sizeof(mypioRecvPci); outBufferStartWithLimit(out, len, 12); outBufferFinishWithLimit(out, (char *) ((DWORD) pioRecvPci + sizeof(pioRecvPci)), len, 12); }#endif outBufferFinish(out, (char *) recvBuf, cbRecvLength); } outForceAlignment(out, 8); SC_xfreeallmemory(&lcHandle); return rv;}static MYPCSC_DWORDTS_SCardStatus(STREAM in, STREAM out, RD_BOOL wide){ MYPCSC_DWORD rv; SERVER_SCARDCONTEXT hCard; MYPCSC_SCARDCONTEXT myHCard; SERVER_DWORD dwState = 0, dwProtocol = 0, dwReaderLen, dwAtrLen; MYPCSC_DWORD state, protocol, readerLen, atrLen; SERVER_DWORD dataLength; PMEM_HANDLE lcHandle = NULL; char *readerName; unsigned char *atr; in->p += 0x24; in_uint32_le(in, dwReaderLen); in_uint32_le(in, dwAtrLen); in->p += 0x0C; in_uint32_le(in, hCard); in->p += 0x04; myHCard = scHandleToMyPCSC(hCard); DEBUG_SCARD(("SCARD: SCardStatus(hcard: 0x%08x [0x%08lx], reader len: %d bytes, atr len: %d bytes)\n", (unsigned) hCard, (unsigned long) myHCard, (int) dwReaderLen, (int) dwAtrLen)); if (dwReaderLen <= 0 || dwReaderLen == SCARD_AUTOALLOCATE || dwReaderLen > SCARD_MAX_MEM) dwReaderLen = SCARD_MAX_MEM; if (dwAtrLen <= 0 || dwAtrLen == SCARD_AUTOALLOCATE || dwAtrLen > SCARD_MAX_MEM) dwAtrLen = SCARD_MAX_MEM;#if 1 /* * Active client sometimes sends a readerlen *just* big enough * SCardStatus doesn't seem to like this. This is a workaround, * aka hack! */ dwReaderLen = 200;#endif readerName = SC_xmalloc(&lcHandle, dwReaderLen + 2); if (!readerName) return SC_returnNoMemoryError(&lcHandle, in, out); atr = SC_xmalloc(&lcHandle, dwAtrLen + 1); if (!atr) return SC_returnNoMemoryError(&lcHandle, in, out); state = dwState; protocol = dwProtocol; readerLen = dwReaderLen; atrLen = dwAtrLen; rv = SCardStatus(myHCard, readerName, &readerLen, &state, &protocol, atr, &atrLen); dwAtrLen = atrLen; dwReaderLen = readerLen; dwProtocol = protocol; dwState = state; if (rv != SCARD_S_SUCCESS) { DEBUG_SCARD(("SCARD: -> Failure: %s (0x%08x)\n", pcsc_stringify_error(rv), (unsigned int) rv)); return SC_returnCode(rv, &lcHandle, in, out); } else { int i; DEBUG_SCARD(("SCARD: -> Success (state: 0x%08x, proto: 0x%08x)\n", (unsigned) dwState, (unsigned) dwProtocol)); DEBUG_SCARD(("SCARD: Reader: \"%s\"\n", readerName ? readerName : "NULL")); DEBUG_SCARD(("SCARD: ATR: ")); for (i = 0; i < dwAtrLen; i++) { DEBUG_SCARD(("%02x%c", atr[i], (i == dwAtrLen - 1) ? ' ' : ':')); } DEBUG_SCARD(("\n")); if (dwState & (SCARD_SPECIFIC | SCARD_NEGOTIABLE)) dwState = 0x00000006; else#if 0 if (dwState & SCARD_SPECIFIC) dwState = 0x00000006; else if (dwState & SCARD_NEGOTIABLE) dwState = 0x00000005; else#endif if (dwState & SCARD_POWERED) dwState = 0x00000004; else if (dwState & SCARD_SWALLOWED) dwState = 0x00000003; else if (dwState & SCARD_PRESENT) dwState = 0x00000002; else if (dwState & SCARD_ABSENT) dwState = 0x00000001; else dwState = 0x00000000; void *p_len1 = out->p; out_uint32_le(out, dwReaderLen); out_uint32_le(out, 0x00020000); out_uint32_le(out, dwState); out_uint32_le(out, dwProtocol); out_uint8p(out, atr, dwAtrLen); if (dwAtrLen < 32) { out_uint8s(out, 32 - dwAtrLen); } out_uint32_le(out, dwAtrLen); void *p_len2 = out->p; out_uint32_le(out, dwReaderLen); dataLength = outString(out, readerName, wide); dataLength += outString(out, "\0", wide); outRepos(out, dataLength); void *psave = out->p; out->p = p_len1; out_uint32_le(out, dataLength); out->p = p_len2; out_uint32_le(out, dataLength); out->p = psave; } outForceAlignment(out, 8); SC_xfreeallmemory(&lcHandle); return rv;}static MYPCSC_DWORDTS_SCardState(STREAM in, STREAM out){ MYPCSC_DWORD rv; SERVER_SCARDCONTEXT hCard; MYPCSC_SCARDCONTEXT myHCard; SERVER_DWORD dwState = 0, dwProtocol = 0, dwReaderLen, dwAtrLen; MYPCSC_DWORD state, protocol, readerLen, atrLen; PMEM_HANDLE lcHandle = NULL; char *readerName; unsigned char *atr; in->p += 0x24; in_uint32_le(in, dwAtrLen); in->p += 0x0C; in_uint32_le(in, hCard); in->p += 0x04; myHCard = scHandleToMyPCSC(hCard); DEBUG_SCARD(("SCARD: SCardState(hcard: 0x%08x [0x%08lx], atr len: %d bytes)\n", (unsigned) hCard, (unsigned long) myHCard, (int) dwAtrLen)); dwReaderLen = SCARD_MAX_MEM; if (dwAtrLen <= 0 || dwAtrLen == SCARD_AUTOALLOCATE || dwAtrLen > SCARD_MAX_MEM) dwAtrLen = SCARD_MAX_MEM; readerName = SC_xmalloc(&lcHandle, dwReaderLen + 2); if (!readerName) return SC_returnNoMemoryError(&lcHandle, in, out); atr = SC_xmalloc(&lcHandle, dwAtrLen + 1); if (!atr) return SC_returnNoMemoryError(&lcHandle, in, out); state = dwState; protocol = dwProtocol; readerLen = dwReaderLen; atrLen = dwAtrLen; rv = SCardStatus(myHCard, readerName, &readerLen, &state, &protocol, atr, &atrLen); dwAtrLen = atrLen; dwReaderLen = readerLen; dwProtocol = protocol; dwState = state; if (rv != SCARD_S_SUCCESS) { DEBUG_SCARD(("SCARD: -> Failure: %s (0x%08x)\n", pcsc_stringify_error(rv), (unsigned int) rv)); return SC_returnCode(rv, &lcHandle, in, out); } else { int i; DEBUG_SCARD(("SCARD: -> Success (state: 0x%08x, proto: 0x%08x)\n", (unsigned) dwState, (unsigned) dwProtocol)); DEBUG_SCARD(("SCARD: ATR: ")); for (i = 0; i < dwAtrLen; i++) { DEBUG_SCARD(("%02x%c", atr[i], (i == dwAtrLen - 1) ? ' ' : ':')); } DEBUG_SCARD(("\n")); if (dwState & (SCARD_SPECIFIC | SCARD_NEGOTIABLE)) dwState = 0x00000006; else#if 0 if (dwState & SCARD_SPECIFIC) dwState = 0x00000006; else if (dwState & SCARD_NEGOTIABLE) dwState = 0x00000005; else#endif if (dwState & SCARD_POWERED) dwState = 0x00000004; else if (dwState & SCARD_SWALLOWED) dwState = 0x00000003; else if (dwState & SCARD_PRESENT) dwState = 0x00000002; else if (dwState & SCARD_ABSENT) dwState = 0x00000001; else dwState = 0x00000000; out_uint32_le(out, dwState); out_uint32_le(out, dwProtocol); out_uint32_le(out, dwAtrLen); out_uint32_le(out, 0x00000001); out_uint32_le(out, dwAtrLen); out_uint8p(out, atr, dwAtrLen); outRepos(out, dwAtrLen); } outForceAlignment(out, 8); SC_xfreeallmemory(&lcHandle); return rv;}#ifndef WITH_PCSC120static MYPCSC_DWORDTS_SCardListReaderGroups(STREAM in, STREAM out){ MYPCSC_DWORD rv; SERVER_SCARDCONTEXT hContext; SERVER_DWORD dwGroups; MYPCSC_DWORD groups; char *szGroups; PMEM_HANDLE lcHandle = NULL; in->p += 0x20; in_uint32_le(in, dwGroups); in->p += 0x04; in_uint32_le(in, hContext); DEBUG_SCARD(("SCARD: SCardListReaderGroups(context: 0x%08x, groups: %d)\n", (unsigned) hContext, (int) dwGroups)); if (dwGroups <= 0 || dwGroups == SCARD_AUTOALLOCATE || dwGroups > SCARD_MAX_MEM) dwGroups = SCARD_MAX_MEM; szGroups = SC_xmalloc(&lcHandle, dwGroups); if (!szGroups) return SC_returnNoMemoryError(&lcHandle, in, out); groups = dwGroups; rv = SCardListReaderGroups((MYPCSC_SCARDCONTEXT) hContext, szGroups, &groups); dwGroups = groups; if (rv) { DEBUG_SCARD(("SCARD: -> Failure: %s (0x%08x)\n", pcsc_stringify_error(rv), (unsigned int) rv)); return SC_returnCode(rv, &lcHandle, in, out); } else { int i; char *cur; DEBUG_SCARD(("SCARD: -> Success\n")); for (i = 0, cur = szGroups; i < dwGroups; i++, cur += strlen(cur) + 1) { DEBUG_SCARD(("SCARD: %s\n", cur)); } } out_uint32_le(out, dwGroups); out_uint32_le(out, 0x00200000); out_uint32_le(out, dwGroups); out_uint8a(out, szGroups, dwGroups); outRepos(out, dwGroups); out_uint32_le(out, 0x00000000); outForceAlignment(out, 8); SC_xfreeallmemory(&lcHandle); return rv;}static MYPCSC_DWORDTS_SCardGetAttrib(STREAM in, STREAM out){ MYPCSC_DWORD rv; SERVER_SCARDCONTEXT hCard; MYPCSC_SCARDCONTEXT myHCard; SERVER_DWORD dwAttrId, dwAttrLen; MYPCSC_DWORD attrLen; unsigned char *pbAttr; PMEM_HANDLE lcHandle = NULL; in->p += 0x20; in_uint32_le(in, dwAttrId); in->p += 0x04; in_uint32_le(in, dwAttrLen); in->p += 0x0C; in_uint32_le(in, hCard); myHCard = scHandleToMyPCSC(hCard); dwAttrId = dwAttrId & 0x0000FFFF; DEBUG_SCARD(("SCARD: SCardGetAttrib(hcard: 0x%08x [0x%08lx], attrib: 0x%08x (%d bytes))\n", (unsigned) hCard, (unsigned long) myHCard, (unsigned) dwAttrId, (int) dwAttrLen)); if (dwAttrLen > MAX_BUFFER_SIZE) dwAttrLen = MAX_BUFFER_SIZE; if (dwAttrLen > SCARD_AUTOALLOCATE) pbAttr = NULL; else if ((dwAttrLen < 0) || (dwAttrLen > SCARD_MAX_MEM)) { dwAttrLen = SCARD_AUTOALLOCATE; pbAttr = NULL; } else { pbAttr = SC_xmalloc(&lcHandle, dwAttrLen); if (!pbAttr) return SC_returnNoMemoryError(&lcHandle, in, out); } attrLen = dwAttrLen; rv = SCardGetAttrib(myHCard, (MYPCSC_DWORD) dwAttrId, pbAttr, &attrLen); dwAttrLen = attrLen; if (dwAttrId == 0x00000100 && rv != SCARD_S_SUCCESS) { DEBUG_SCARD(("SCARD: Faking attribute ATTR_VENDOR_NAME\n")); pthread_mutex_lock(&hcardAccess); PSCHCardRec hcard = hcardFirst; while (hcard) { if (hcard->hCard == hCard) { dwAttrLen = strlen(hcard->vendor); memcpy(pbAttr, hcard->vendor, dwAttrLen); rv = SCARD_S_SUCCESS; break; } hcard = hcard->next; } pthread_mutex_unlock(&hcardAccess); DEBUG_SCARD(("[0x%.8x]\n", (unsigned int) rv)); } if (rv != SCARD_S_SUCCESS) { DEBUG_SCARD(("SCARD: -> Failure: %s (0x%08x)\n", pcsc_stringify_error(rv), (unsigned int) rv)); return SC_returnCode(rv, &lcHandle, in, out); } else { DEBUG_SCARD(("SCARD: -> Success (%d bytes)\n", (int) dwAttrLen)); out_uint32_le(out, dwAttrLen); out_uint32_le(out, 0x00000200); out_uint32_le(out, dwAttrLen); if (!pbAttr) { out_uint8s(out, dwAttrLen); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -