Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

596 lines
21 KiB

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include "MarshalPC.h"
#include <tchar.h>
#include "carddbg.h"
#if (!defined(UNICODE) && !defined(_UNICODE))
#define SCARDSTATUS "SCardStatusA"
#define GETOPENCARDNAME "GetOpenCardNameA"
#else
#define SCARDSTATUS "SCardStatusW"
#define GETOPENCARDNAME "GetOpenCardNameW"
#endif
typedef LONG (WINAPI *LPFNSCARDESTABLISHCONTEXT)(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
typedef LONG (WINAPI *LPFNSCARDSTATUS)(SCARDHANDLE, LPTSTR, LPDWORD, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
typedef LONG (WINAPI *LPFNGETOPENCARDNAME)(LPOPENCARDNAME);
typedef LONG (WINAPI *LPFNSCARDTRANSMIT)(SCARDHANDLE, LPCSCARD_IO_REQUEST, LPCBYTE, DWORD, LPSCARD_IO_REQUEST, LPBYTE, LPDWORD);
typedef LONG (WINAPI *LPFNDISCONNECT)(SCARDHANDLE, DWORD);
typedef LONG (WINAPI *LPFNSCARDRELEASECONTEXT)(SCARDCONTEXT);
typedef LONG (WINAPI *LPFNSCARDBEGINTRANSACTION)(SCARDHANDLE);
typedef LONG (WINAPI *LPFNSCARDENDTRANSACTION)(SCARDHANDLE, DWORD);
typedef struct {
HINSTANCE hPCSCInst; // winscard
HINSTANCE hPCSCInst2; // scarddlg
LPFNSCARDESTABLISHCONTEXT lpfnEstablish;
LPFNGETOPENCARDNAME lpfnOpenCard;
LPFNSCARDSTATUS lpfnStatus;
LPFNSCARDTRANSMIT lpfnSCardTransmit;
LPFNDISCONNECT lpfnDisconnect;
LPFNSCARDRELEASECONTEXT lpfnRelease;
LPFNSCARDBEGINTRANSACTION lpfnSCardBeginTransaction;
LPFNSCARDENDTRANSACTION lpfnSCardEndTransaction;
} PCSC_CTX;
#define REAL_PCSC 0
#define FAKE_PCSC 1
static PCSC_CTX axCtx[2] = // Array of contexts for each PC/SC
{
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};
static LONG _GetCardHandle(LPCWSTR mszCardNames, LPMYSCARDHANDLE phCard);
static LONG WINAPI _MySCWTransmit(SCARDHANDLE hCard, LPCBYTE lpbIn, DWORD dwIn, LPBYTE lpBOut, LPDWORD pdwOut);
// bEnd = 0 -> LITTLE_ENDIAN ; otherwise -> BIG_ENDIAN
static LONG WINAPI hScwSetEndianness(SCARDHANDLE hCard, BOOL bEnd);
#define MAX_NAME 256
SCODE WINAPI hScwAttachToCard(SCARDHANDLE hCard, LPCWSTR mszCardNames, LPSCARDHANDLE phCard)
{
return hScwAttachToCardEx(hCard, mszCardNames, 0x00, phCard);
}
SCODE WINAPI hScwAttachToCardEx(SCARDHANDLE hCard, LPCWSTR mszCardNames, BYTE byINS, LPSCARDHANDLE phCard)
{
LPMYSCARDHANDLE phTmp = NULL;
SCODE ret = SCARD_S_SUCCESS;
LOG_BEGIN_PROXY(hScwAttachToCardEx);
__try {
if (phCard == NULL)
RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
phTmp = (LPMYSCARDHANDLE)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, sizeof(MYSCARDHANDLE));
if ((hCard == (SCARDHANDLE)NULL) && (mszCardNames == NULL)) // No PC/SC
{
phTmp->dwFlags = FLAG_NOT_PCSC;
*phCard = (SCARDHANDLE)phTmp;
return ret;
}
if ((hCard == (SCARDHANDLE)NULL) || (mszCardNames == NULL)) // real PC/SC
{
// In this case we will be using PC/SC so we init the structure
if (axCtx[REAL_PCSC].hPCSCInst == NULL)
{
axCtx[REAL_PCSC].hPCSCInst = LoadLibrary(_T("winscard.dll"));
axCtx[REAL_PCSC].hPCSCInst2 = LoadLibrary(_T("scarddlg.dll"));
}
if ((axCtx[REAL_PCSC].hPCSCInst == NULL) || (axCtx[REAL_PCSC].hPCSCInst2 == NULL))
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
if (axCtx[REAL_PCSC].lpfnEstablish == NULL)
{
// Set all calls to DLL once and for all
axCtx[REAL_PCSC].lpfnEstablish = (LPFNSCARDESTABLISHCONTEXT)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardEstablishContext");
if (axCtx[REAL_PCSC].lpfnEstablish == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[REAL_PCSC].lpfnOpenCard = (LPFNGETOPENCARDNAME)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst2, GETOPENCARDNAME);
if (axCtx[REAL_PCSC].lpfnOpenCard == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[REAL_PCSC].lpfnStatus = (LPFNSCARDSTATUS)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, SCARDSTATUS);
if (axCtx[REAL_PCSC].lpfnStatus == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[REAL_PCSC].lpfnSCardTransmit = (LPFNSCARDTRANSMIT)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardTransmit");
if (axCtx[REAL_PCSC].lpfnSCardTransmit == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[REAL_PCSC].lpfnDisconnect = (LPFNDISCONNECT)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardDisconnect");
if (axCtx[REAL_PCSC].lpfnDisconnect == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[REAL_PCSC].lpfnRelease = (LPFNSCARDRELEASECONTEXT)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardReleaseContext");
if (axCtx[REAL_PCSC].lpfnRelease == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[REAL_PCSC].lpfnSCardBeginTransaction = (LPFNSCARDBEGINTRANSACTION)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardBeginTransaction");
if (axCtx[REAL_PCSC].lpfnSCardBeginTransaction == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[REAL_PCSC].lpfnSCardEndTransaction = (LPFNSCARDENDTRANSACTION)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardEndTransaction");
if (axCtx[REAL_PCSC].lpfnSCardEndTransaction == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
}
phTmp->dwFlags = FLAG_REALPCSC;
}
else if ((hCard == NULL_TX) || (mszCardNames == NULL_TX_NAME)) // PC/SC for simulator
{
// In this case we will be using PC/SC so we init the structure
if (axCtx[FAKE_PCSC].hPCSCInst == NULL)
{
axCtx[FAKE_PCSC].hPCSCInst = LoadLibrary(_T("scwwinscard.dll"));
axCtx[FAKE_PCSC].hPCSCInst2 = axCtx[FAKE_PCSC].hPCSCInst;
}
if (axCtx[FAKE_PCSC].hPCSCInst == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
if (axCtx[FAKE_PCSC].lpfnEstablish == NULL)
{
// Set all calls to DLL once and for all
axCtx[FAKE_PCSC].lpfnEstablish = (LPFNSCARDESTABLISHCONTEXT)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardEstablishContext");
if (axCtx[FAKE_PCSC].lpfnEstablish == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[FAKE_PCSC].lpfnOpenCard = (LPFNGETOPENCARDNAME)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst2, GETOPENCARDNAME);
if (axCtx[FAKE_PCSC].lpfnOpenCard == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[FAKE_PCSC].lpfnStatus = (LPFNSCARDSTATUS)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, SCARDSTATUS);
if (axCtx[FAKE_PCSC].lpfnStatus == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[FAKE_PCSC].lpfnSCardTransmit = (LPFNSCARDTRANSMIT)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardTransmit");
if (axCtx[FAKE_PCSC].lpfnSCardTransmit == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[FAKE_PCSC].lpfnDisconnect = (LPFNDISCONNECT)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardDisconnect");
if (axCtx[FAKE_PCSC].lpfnDisconnect == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[FAKE_PCSC].lpfnRelease = (LPFNSCARDRELEASECONTEXT)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardReleaseContext");
if (axCtx[FAKE_PCSC].lpfnRelease == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[FAKE_PCSC].lpfnSCardBeginTransaction = (LPFNSCARDBEGINTRANSACTION)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardBeginTransaction");
if (axCtx[FAKE_PCSC].lpfnSCardBeginTransaction == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
axCtx[FAKE_PCSC].lpfnSCardEndTransaction = (LPFNSCARDENDTRANSACTION)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardEndTransaction");
if (axCtx[FAKE_PCSC].lpfnSCardEndTransaction == NULL)
RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
}
phTmp->dwFlags = FLAG_FAKEPCSC;
}
else
RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((hCard == (SCARDHANDLE)NULL) || (hCard == NULL_TX)) // Dialog wanted
{
phTmp->dwFlags |= FLAG_MY_ATTACH;
ret = (SCODE)_GetCardHandle(mszCardNames, phTmp);
}
else
phTmp->hCard = hCard;
// Get the protocol
if (ret == SCARD_S_SUCCESS)
{
DWORD dwLenReader, dwState, dwATRLength;
BYTE abyATR[32];
TCHAR wszReader[MAX_NAME];
dwLenReader = MAX_NAME;
dwATRLength = 32;
ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnStatus)(
phTmp->hCard,
wszReader,
&dwLenReader,
&dwState,
&phTmp->dwProtocol,
abyATR,
&dwATRLength);
// Set the default callback because we are in PC/SC config here
if (ret == SCARD_S_SUCCESS)
{
phTmp->byINS = byINS;
ret = hScwSetTransmitCallback((SCARDHANDLE)phTmp, _MySCWTransmit);
if (ret == SCARD_S_SUCCESS)
*phCard = (SCARDHANDLE)phTmp;
}
else
RaiseException(STATUS_INTERNAL_ERROR, 0, 0, 0);
}
else
RaiseException(STATUS_INTERNAL_ERROR, 0, 0, 0);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
if (phTmp)
HeapFree(GetProcessHeap(), 0, phTmp);
if (ret == SCARD_S_SUCCESS)
{
switch(GetExceptionCode())
{
case STATUS_INVALID_PARAM:
ret = MAKESCODE(SCW_E_INVALIDPARAM);
break;
case STATUS_NO_MEMORY:
case STATUS_ACCESS_VIOLATION:
ret = MAKESCODE(SCW_E_BUFFERTOOSMALL);
break;
case STATUS_NO_SERVICE:
ret = SCARD_E_NO_SERVICE;
break;
default:
ret = SCARD_F_UNKNOWN_ERROR;
}
} // Otherwise ret was set already
}
return ret;
}
SCODE WINAPI hScwDetachFromCard(SCARDHANDLE hCard)
{
SCODE ret = SCARD_S_SUCCESS;
LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwDetachFromCard);
__try {
if (phTmp == NULL)
RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if (phTmp->dwFlags & FLAG_MY_ATTACH)
{
(*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnDisconnect)(phTmp->hCard, SCARD_LEAVE_CARD);
(*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnRelease)(phTmp->hCtx);
}
HeapFree(GetProcessHeap(), 0, phTmp);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode())
{
case STATUS_INVALID_PARAM:
ret = MAKESCODE(SCW_E_INVALIDPARAM);
break;
default:
ret = SCARD_F_UNKNOWN_ERROR;
}
}
return ret;
}
static LONG WINAPI hScwSetEndianness(SCARDHANDLE hCard, BOOL bEnd)
{
SCODE ret = SCARD_S_SUCCESS;
LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwSetEndianness);
__try {
if (phTmp == NULL)
RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if (bEnd)
phTmp->dwFlags |= FLAG_BIGENDIAN;
else
phTmp->dwFlags &= ~FLAG_BIGENDIAN;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode())
{
case STATUS_INVALID_PARAM:
ret = MAKESCODE(SCW_E_INVALIDPARAM);
break;
default:
ret = SCARD_F_UNKNOWN_ERROR;
}
}
return ret;
}
// This is the right time to get proxy information
// Is proxy supported, what's the endianness and the buffer size
SCODE WINAPI hScwSetTransmitCallback(SCARDHANDLE hCard, LPFNSCWTRANSMITPROC lpfnProc)
{
SCODE ret = SCARD_S_SUCCESS;
LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
__try {
if ((phTmp == NULL) || (lpfnProc == NULL))
RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
phTmp->lpfnTransmit = lpfnProc;
// Get the proxy info
{
ISO_HEADER xHdr;
BYTE rgData[] = {2, 108, 0, 116, 0, 0}; // 2 param, 0 as UINT8 by ref, 0 as UINT16 by ref
BYTE rgRes[1+1+2]; // RetCode + Endianness + TheBuffer size
TCOUNT OutLen = sizeof(rgRes);
UINT16 wSW;
xHdr.CLA = 0;
xHdr.INS = phTmp->byINS;
xHdr.P1 = 0xFF; // Get proxy config
xHdr.P2 = 0x00;
ret = hScwExecute(hCard, &xHdr, rgData, sizeof(rgData), rgRes, &OutLen, &wSW);
if (SCARD_S_SUCCESS == ret)
{ // Status OK & expected length & RC=SCW_S_OK
if ((wSW == 0x9000) && (OutLen == sizeof(rgRes)) && (rgRes[0] == 0)) // Version 1.0
{
hScwSetEndianness(hCard, rgRes[1]);
if (rgRes[1] == 0) // LITTLE_ENDIAN
phTmp->bResLen = rgRes[2] - 2; // SW!!!
else
phTmp->bResLen = rgRes[3] - 2; // SW!!!
phTmp->dwFlags |= FLAG_ISPROXY;
phTmp->dwFlags |= VERSION_1_0;
}
else if ((wSW == 0x9011) && (OutLen == sizeof(rgRes) - 1)) // Version 1.1
{
hScwSetEndianness(hCard, rgRes[0]);
if (rgRes[0] == 0) // LITTLE_ENDIAN
phTmp->bResLen = rgRes[1] - 2; // SW!!!
else
phTmp->bResLen = rgRes[2] - 2; // SW!!!
phTmp->dwFlags |= FLAG_ISPROXY;
phTmp->dwFlags |= VERSION_1_1;
}
// else there will be no proxy support but you can still use the Dll
}
else // There will be no proxy support though but you can still use the Dll
ret = SCARD_S_SUCCESS;
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode())
{
case STATUS_INVALID_PARAM:
ret = MAKESCODE(SCW_E_INVALIDPARAM);
break;
default:
ret = SCARD_F_UNKNOWN_ERROR;
}
}
return ret;
}
LONG WINAPI SCWTransmit(SCARDHANDLE hCard, LPCBYTE lpbIn, DWORD dwIn, LPBYTE lpBOut, LPDWORD pdwOut)
{
SCODE ret = SCARD_S_SUCCESS;
LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
__try {
if (phTmp == NULL)
RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
DebugPrintBytes(L"bytes transmitted", (PBYTE) lpbIn, dwIn);
ret = (*phTmp->lpfnTransmit)(hCard, lpbIn, dwIn, lpBOut, pdwOut);
if (NULL != pdwOut)
DebugPrintBytes(L"bytes received", lpBOut, *pdwOut);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode())
{
case STATUS_INVALID_PARAM:
ret = MAKESCODE(SCW_E_INVALIDPARAM);
break;
default:
ret = SCARD_F_UNKNOWN_ERROR;
}
}
return ret;
}
const SCARD_IO_REQUEST
g_xIORT0 = { SCARD_PROTOCOL_T0, sizeof(SCARD_IO_REQUEST) },
g_xIORT1 = { SCARD_PROTOCOL_T1, sizeof(SCARD_IO_REQUEST) };
static LONG WINAPI _MySCWTransmit(SCARDHANDLE hCard, LPCBYTE lpbIn, DWORD dwIn, LPBYTE lpBOut, LPDWORD pdwOut)
{
SCARD_IO_REQUEST xIOR;
LONG ret = SCARD_S_SUCCESS;
LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
__try {
if (phTmp == NULL)
RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if (phTmp->dwProtocol == SCARD_PROTOCOL_T1)
{
memcpy(&xIOR, &g_xIORT1, sizeof(xIOR));
ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardTransmit)(phTmp->hCard,
&xIOR, lpbIn, dwIn,
&xIOR, lpBOut, pdwOut);
}
else
{
DWORD dwOut = *pdwOut;
memcpy(&xIOR, &g_xIORT0, sizeof(xIOR));
__try {
ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardBeginTransaction)(phTmp->hCard);
if (ret == SCARD_S_SUCCESS)
{
ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardTransmit)(phTmp->hCard,
&xIOR, lpbIn, dwIn,
&xIOR, lpBOut, &dwOut);
}
if (ret == SCARD_S_SUCCESS)
{
if ((dwOut == 2) && ((lpBOut[0] == 0x61) || (lpBOut[0] == 0x9F)))
{
BYTE abGR[] = {0x00, 0xC0, 0x00, 0x00, 0x00};
abGR[4] = lpBOut[1];
ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardTransmit)(phTmp->hCard,
&xIOR, abGR, 5,
&xIOR, lpBOut, pdwOut);
}
else
*pdwOut = dwOut;
}
}
__finally
{
(*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardEndTransaction)(phTmp->hCard, SCARD_LEAVE_CARD);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode())
{
case STATUS_INVALID_PARAM:
ret = MAKESCODE(SCW_E_INVALIDPARAM);
break;
default:
ret = SCARD_F_UNKNOWN_ERROR;
}
}
return ret;
}
static TCHAR lpstrGroupNames[] = _TEXT("SCard$DefaultReaders\0");
static LONG _GetCardHandle(LPCWSTR mszCardNames, LPMYSCARDHANDLE phCard)
{
LONG lRes;
OPENCARDNAME xOCN;
TCHAR wszReader[MAX_NAME];
TCHAR wszCard[MAX_NAME];
TCHAR wszCN[MAX_NAME];
DWORD len;
LPCWSTR lpwstr = mszCardNames;
LPTSTR lpstrCardNames = wszCN;
xOCN.nMaxCardNames = 0;
#if (!defined(UNICODE) && !defined(_UNICODE))
while (*lpwstr)
{
wsprintf(lpstrCardNames, "%S", lpwstr); // Conversion
len = wcslen(lpwstr) + 1; // Add the trailing 0
xOCN.nMaxCardNames += len;
lpwstr += len;
lpstrCardNames += len;
}
#else
while (*lpwstr)
{
wcscpy(lpstrCardNames, lpwstr);
len = wcslen(lpwstr) + 1; // Add the trailing 0
xOCN.nMaxCardNames += len;
lpwstr += len;
lpstrCardNames += len;
}
#endif
xOCN.nMaxCardNames++; // Add the trailing 0
*lpstrCardNames = 0;
lRes = (*axCtx[phCard->dwFlags & FLAG_MASKPCSC].lpfnEstablish)(SCARD_SCOPE_USER, NULL, NULL, &phCard->hCtx);
if (lRes == SCARD_S_SUCCESS)
{
xOCN.dwStructSize = sizeof(xOCN);
xOCN.hwndOwner = NULL; // probably called from console anyway
xOCN.hSCardContext = phCard->hCtx;
xOCN.lpstrGroupNames = lpstrGroupNames;
xOCN.nMaxGroupNames = sizeof(lpstrGroupNames)/sizeof(TCHAR);
xOCN.lpstrCardNames = wszCN;
xOCN.rgguidInterfaces = NULL;
xOCN.cguidInterfaces = 0;
xOCN.lpstrRdr = wszReader;
xOCN.nMaxRdr = MAX_NAME/sizeof(TCHAR);
xOCN.lpstrCard = wszCard;
xOCN.nMaxCard = MAX_NAME/sizeof(TCHAR);
xOCN.lpstrTitle = _TEXT("Insert Card:");
xOCN.dwFlags = SC_DLG_MINIMAL_UI;
xOCN.pvUserData = NULL;
xOCN.dwShareMode = SCARD_SHARE_SHARED;
xOCN.dwPreferredProtocols = SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_T0;
xOCN.lpfnConnect = NULL;
xOCN.lpfnCheck = NULL;
xOCN.lpfnDisconnect = NULL;
lRes = (*axCtx[phCard->dwFlags & FLAG_MASKPCSC].lpfnOpenCard)(&xOCN);
}
if (lRes == SCARD_S_SUCCESS)
{
phCard->hCard = xOCN.hCardHandle;
}
return lRes;
}
SCODE WINAPI hScwSCardBeginTransaction(SCARDHANDLE hCard)
{
SCODE ret;
LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
if ((phTmp->dwFlags & FLAG_REALPCSC) == FLAG_REALPCSC)
ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardBeginTransaction)(phTmp->hCard);
else
ret = SCARD_S_SUCCESS; // No transactions on simulator
return ret;
}
SCODE WINAPI hScwSCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
{
SCODE ret;
LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
if ((phTmp->dwFlags & FLAG_REALPCSC) == FLAG_REALPCSC)
ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardEndTransaction)(phTmp->hCard, dwDisposition);
else
ret = SCARD_S_SUCCESS; // No transactions on simulator
return ret;
}