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

  1. #ifndef WIN32_LEAN_AND_MEAN
  2. #define WIN32_LEAN_AND_MEAN
  3. #endif
  4. #include <windows.h>
  5. #include "MarshalPC.h"
  6. #include <tchar.h>
  7. #include "carddbg.h"
  8. #if (!defined(UNICODE) && !defined(_UNICODE))
  9. #define SCARDSTATUS "SCardStatusA"
  10. #define GETOPENCARDNAME "GetOpenCardNameA"
  11. #else
  12. #define SCARDSTATUS "SCardStatusW"
  13. #define GETOPENCARDNAME "GetOpenCardNameW"
  14. #endif
  15. typedef LONG (WINAPI *LPFNSCARDESTABLISHCONTEXT)(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
  16. typedef LONG (WINAPI *LPFNSCARDSTATUS)(SCARDHANDLE, LPTSTR, LPDWORD, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
  17. typedef LONG (WINAPI *LPFNGETOPENCARDNAME)(LPOPENCARDNAME);
  18. typedef LONG (WINAPI *LPFNSCARDTRANSMIT)(SCARDHANDLE, LPCSCARD_IO_REQUEST, LPCBYTE, DWORD, LPSCARD_IO_REQUEST, LPBYTE, LPDWORD);
  19. typedef LONG (WINAPI *LPFNDISCONNECT)(SCARDHANDLE, DWORD);
  20. typedef LONG (WINAPI *LPFNSCARDRELEASECONTEXT)(SCARDCONTEXT);
  21. typedef LONG (WINAPI *LPFNSCARDBEGINTRANSACTION)(SCARDHANDLE);
  22. typedef LONG (WINAPI *LPFNSCARDENDTRANSACTION)(SCARDHANDLE, DWORD);
  23. typedef struct {
  24. HINSTANCE hPCSCInst; // winscard
  25. HINSTANCE hPCSCInst2; // scarddlg
  26. LPFNSCARDESTABLISHCONTEXT lpfnEstablish;
  27. LPFNGETOPENCARDNAME lpfnOpenCard;
  28. LPFNSCARDSTATUS lpfnStatus;
  29. LPFNSCARDTRANSMIT lpfnSCardTransmit;
  30. LPFNDISCONNECT lpfnDisconnect;
  31. LPFNSCARDRELEASECONTEXT lpfnRelease;
  32. LPFNSCARDBEGINTRANSACTION lpfnSCardBeginTransaction;
  33. LPFNSCARDENDTRANSACTION lpfnSCardEndTransaction;
  34. } PCSC_CTX;
  35. #define REAL_PCSC 0
  36. #define FAKE_PCSC 1
  37. static PCSC_CTX axCtx[2] = // Array of contexts for each PC/SC
  38. {
  39. {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
  40. {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
  41. };
  42. static LONG _GetCardHandle(LPCWSTR mszCardNames, LPMYSCARDHANDLE phCard);
  43. static LONG WINAPI _MySCWTransmit(SCARDHANDLE hCard, LPCBYTE lpbIn, DWORD dwIn, LPBYTE lpBOut, LPDWORD pdwOut);
  44. // bEnd = 0 -> LITTLE_ENDIAN ; otherwise -> BIG_ENDIAN
  45. static LONG WINAPI hScwSetEndianness(SCARDHANDLE hCard, BOOL bEnd);
  46. #define MAX_NAME 256
  47. SCODE WINAPI hScwAttachToCard(SCARDHANDLE hCard, LPCWSTR mszCardNames, LPSCARDHANDLE phCard)
  48. {
  49. return hScwAttachToCardEx(hCard, mszCardNames, 0x00, phCard);
  50. }
  51. SCODE WINAPI hScwAttachToCardEx(SCARDHANDLE hCard, LPCWSTR mszCardNames, BYTE byINS, LPSCARDHANDLE phCard)
  52. {
  53. LPMYSCARDHANDLE phTmp = NULL;
  54. SCODE ret = SCARD_S_SUCCESS;
  55. LOG_BEGIN_PROXY(hScwAttachToCardEx);
  56. __try {
  57. if (phCard == NULL)
  58. RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
  59. phTmp = (LPMYSCARDHANDLE)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, sizeof(MYSCARDHANDLE));
  60. if ((hCard == (SCARDHANDLE)NULL) && (mszCardNames == NULL)) // No PC/SC
  61. {
  62. phTmp->dwFlags = FLAG_NOT_PCSC;
  63. *phCard = (SCARDHANDLE)phTmp;
  64. return ret;
  65. }
  66. if ((hCard == (SCARDHANDLE)NULL) || (mszCardNames == NULL)) // real PC/SC
  67. {
  68. // In this case we will be using PC/SC so we init the structure
  69. if (axCtx[REAL_PCSC].hPCSCInst == NULL)
  70. {
  71. axCtx[REAL_PCSC].hPCSCInst = LoadLibrary(_T("winscard.dll"));
  72. axCtx[REAL_PCSC].hPCSCInst2 = LoadLibrary(_T("scarddlg.dll"));
  73. }
  74. if ((axCtx[REAL_PCSC].hPCSCInst == NULL) || (axCtx[REAL_PCSC].hPCSCInst2 == NULL))
  75. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  76. if (axCtx[REAL_PCSC].lpfnEstablish == NULL)
  77. {
  78. // Set all calls to DLL once and for all
  79. axCtx[REAL_PCSC].lpfnEstablish = (LPFNSCARDESTABLISHCONTEXT)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardEstablishContext");
  80. if (axCtx[REAL_PCSC].lpfnEstablish == NULL)
  81. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  82. axCtx[REAL_PCSC].lpfnOpenCard = (LPFNGETOPENCARDNAME)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst2, GETOPENCARDNAME);
  83. if (axCtx[REAL_PCSC].lpfnOpenCard == NULL)
  84. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  85. axCtx[REAL_PCSC].lpfnStatus = (LPFNSCARDSTATUS)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, SCARDSTATUS);
  86. if (axCtx[REAL_PCSC].lpfnStatus == NULL)
  87. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  88. axCtx[REAL_PCSC].lpfnSCardTransmit = (LPFNSCARDTRANSMIT)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardTransmit");
  89. if (axCtx[REAL_PCSC].lpfnSCardTransmit == NULL)
  90. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  91. axCtx[REAL_PCSC].lpfnDisconnect = (LPFNDISCONNECT)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardDisconnect");
  92. if (axCtx[REAL_PCSC].lpfnDisconnect == NULL)
  93. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  94. axCtx[REAL_PCSC].lpfnRelease = (LPFNSCARDRELEASECONTEXT)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardReleaseContext");
  95. if (axCtx[REAL_PCSC].lpfnRelease == NULL)
  96. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  97. axCtx[REAL_PCSC].lpfnSCardBeginTransaction = (LPFNSCARDBEGINTRANSACTION)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardBeginTransaction");
  98. if (axCtx[REAL_PCSC].lpfnSCardBeginTransaction == NULL)
  99. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  100. axCtx[REAL_PCSC].lpfnSCardEndTransaction = (LPFNSCARDENDTRANSACTION)GetProcAddress(axCtx[REAL_PCSC].hPCSCInst, "SCardEndTransaction");
  101. if (axCtx[REAL_PCSC].lpfnSCardEndTransaction == NULL)
  102. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  103. }
  104. phTmp->dwFlags = FLAG_REALPCSC;
  105. }
  106. else if ((hCard == NULL_TX) || (mszCardNames == NULL_TX_NAME)) // PC/SC for simulator
  107. {
  108. // In this case we will be using PC/SC so we init the structure
  109. if (axCtx[FAKE_PCSC].hPCSCInst == NULL)
  110. {
  111. axCtx[FAKE_PCSC].hPCSCInst = LoadLibrary(_T("scwwinscard.dll"));
  112. axCtx[FAKE_PCSC].hPCSCInst2 = axCtx[FAKE_PCSC].hPCSCInst;
  113. }
  114. if (axCtx[FAKE_PCSC].hPCSCInst == NULL)
  115. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  116. if (axCtx[FAKE_PCSC].lpfnEstablish == NULL)
  117. {
  118. // Set all calls to DLL once and for all
  119. axCtx[FAKE_PCSC].lpfnEstablish = (LPFNSCARDESTABLISHCONTEXT)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardEstablishContext");
  120. if (axCtx[FAKE_PCSC].lpfnEstablish == NULL)
  121. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  122. axCtx[FAKE_PCSC].lpfnOpenCard = (LPFNGETOPENCARDNAME)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst2, GETOPENCARDNAME);
  123. if (axCtx[FAKE_PCSC].lpfnOpenCard == NULL)
  124. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  125. axCtx[FAKE_PCSC].lpfnStatus = (LPFNSCARDSTATUS)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, SCARDSTATUS);
  126. if (axCtx[FAKE_PCSC].lpfnStatus == NULL)
  127. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  128. axCtx[FAKE_PCSC].lpfnSCardTransmit = (LPFNSCARDTRANSMIT)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardTransmit");
  129. if (axCtx[FAKE_PCSC].lpfnSCardTransmit == NULL)
  130. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  131. axCtx[FAKE_PCSC].lpfnDisconnect = (LPFNDISCONNECT)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardDisconnect");
  132. if (axCtx[FAKE_PCSC].lpfnDisconnect == NULL)
  133. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  134. axCtx[FAKE_PCSC].lpfnRelease = (LPFNSCARDRELEASECONTEXT)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardReleaseContext");
  135. if (axCtx[FAKE_PCSC].lpfnRelease == NULL)
  136. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  137. axCtx[FAKE_PCSC].lpfnSCardBeginTransaction = (LPFNSCARDBEGINTRANSACTION)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardBeginTransaction");
  138. if (axCtx[FAKE_PCSC].lpfnSCardBeginTransaction == NULL)
  139. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  140. axCtx[FAKE_PCSC].lpfnSCardEndTransaction = (LPFNSCARDENDTRANSACTION)GetProcAddress(axCtx[FAKE_PCSC].hPCSCInst, "SCardEndTransaction");
  141. if (axCtx[FAKE_PCSC].lpfnSCardEndTransaction == NULL)
  142. RaiseException(STATUS_NO_SERVICE, 0, 0, 0);
  143. }
  144. phTmp->dwFlags = FLAG_FAKEPCSC;
  145. }
  146. else
  147. RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
  148. if ((hCard == (SCARDHANDLE)NULL) || (hCard == NULL_TX)) // Dialog wanted
  149. {
  150. phTmp->dwFlags |= FLAG_MY_ATTACH;
  151. ret = (SCODE)_GetCardHandle(mszCardNames, phTmp);
  152. }
  153. else
  154. phTmp->hCard = hCard;
  155. // Get the protocol
  156. if (ret == SCARD_S_SUCCESS)
  157. {
  158. DWORD dwLenReader, dwState, dwATRLength;
  159. BYTE abyATR[32];
  160. TCHAR wszReader[MAX_NAME];
  161. dwLenReader = MAX_NAME;
  162. dwATRLength = 32;
  163. ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnStatus)(
  164. phTmp->hCard,
  165. wszReader,
  166. &dwLenReader,
  167. &dwState,
  168. &phTmp->dwProtocol,
  169. abyATR,
  170. &dwATRLength);
  171. // Set the default callback because we are in PC/SC config here
  172. if (ret == SCARD_S_SUCCESS)
  173. {
  174. phTmp->byINS = byINS;
  175. ret = hScwSetTransmitCallback((SCARDHANDLE)phTmp, _MySCWTransmit);
  176. if (ret == SCARD_S_SUCCESS)
  177. *phCard = (SCARDHANDLE)phTmp;
  178. }
  179. else
  180. RaiseException(STATUS_INTERNAL_ERROR, 0, 0, 0);
  181. }
  182. else
  183. RaiseException(STATUS_INTERNAL_ERROR, 0, 0, 0);
  184. }
  185. __except(EXCEPTION_EXECUTE_HANDLER) {
  186. if (phTmp)
  187. HeapFree(GetProcessHeap(), 0, phTmp);
  188. if (ret == SCARD_S_SUCCESS)
  189. {
  190. switch(GetExceptionCode())
  191. {
  192. case STATUS_INVALID_PARAM:
  193. ret = MAKESCODE(SCW_E_INVALIDPARAM);
  194. break;
  195. case STATUS_NO_MEMORY:
  196. case STATUS_ACCESS_VIOLATION:
  197. ret = MAKESCODE(SCW_E_BUFFERTOOSMALL);
  198. break;
  199. case STATUS_NO_SERVICE:
  200. ret = SCARD_E_NO_SERVICE;
  201. break;
  202. default:
  203. ret = SCARD_F_UNKNOWN_ERROR;
  204. }
  205. } // Otherwise ret was set already
  206. }
  207. return ret;
  208. }
  209. SCODE WINAPI hScwDetachFromCard(SCARDHANDLE hCard)
  210. {
  211. SCODE ret = SCARD_S_SUCCESS;
  212. LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
  213. LOG_BEGIN_PROXY(hScwDetachFromCard);
  214. __try {
  215. if (phTmp == NULL)
  216. RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
  217. if (phTmp->dwFlags & FLAG_MY_ATTACH)
  218. {
  219. (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnDisconnect)(phTmp->hCard, SCARD_LEAVE_CARD);
  220. (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnRelease)(phTmp->hCtx);
  221. }
  222. HeapFree(GetProcessHeap(), 0, phTmp);
  223. }
  224. __except(EXCEPTION_EXECUTE_HANDLER) {
  225. switch(GetExceptionCode())
  226. {
  227. case STATUS_INVALID_PARAM:
  228. ret = MAKESCODE(SCW_E_INVALIDPARAM);
  229. break;
  230. default:
  231. ret = SCARD_F_UNKNOWN_ERROR;
  232. }
  233. }
  234. return ret;
  235. }
  236. static LONG WINAPI hScwSetEndianness(SCARDHANDLE hCard, BOOL bEnd)
  237. {
  238. SCODE ret = SCARD_S_SUCCESS;
  239. LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
  240. LOG_BEGIN_PROXY(hScwSetEndianness);
  241. __try {
  242. if (phTmp == NULL)
  243. RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
  244. if (bEnd)
  245. phTmp->dwFlags |= FLAG_BIGENDIAN;
  246. else
  247. phTmp->dwFlags &= ~FLAG_BIGENDIAN;
  248. }
  249. __except(EXCEPTION_EXECUTE_HANDLER) {
  250. switch(GetExceptionCode())
  251. {
  252. case STATUS_INVALID_PARAM:
  253. ret = MAKESCODE(SCW_E_INVALIDPARAM);
  254. break;
  255. default:
  256. ret = SCARD_F_UNKNOWN_ERROR;
  257. }
  258. }
  259. return ret;
  260. }
  261. // This is the right time to get proxy information
  262. // Is proxy supported, what's the endianness and the buffer size
  263. SCODE WINAPI hScwSetTransmitCallback(SCARDHANDLE hCard, LPFNSCWTRANSMITPROC lpfnProc)
  264. {
  265. SCODE ret = SCARD_S_SUCCESS;
  266. LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
  267. __try {
  268. if ((phTmp == NULL) || (lpfnProc == NULL))
  269. RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
  270. phTmp->lpfnTransmit = lpfnProc;
  271. // Get the proxy info
  272. {
  273. ISO_HEADER xHdr;
  274. BYTE rgData[] = {2, 108, 0, 116, 0, 0}; // 2 param, 0 as UINT8 by ref, 0 as UINT16 by ref
  275. BYTE rgRes[1+1+2]; // RetCode + Endianness + TheBuffer size
  276. TCOUNT OutLen = sizeof(rgRes);
  277. UINT16 wSW;
  278. xHdr.CLA = 0;
  279. xHdr.INS = phTmp->byINS;
  280. xHdr.P1 = 0xFF; // Get proxy config
  281. xHdr.P2 = 0x00;
  282. ret = hScwExecute(hCard, &xHdr, rgData, sizeof(rgData), rgRes, &OutLen, &wSW);
  283. if (SCARD_S_SUCCESS == ret)
  284. { // Status OK & expected length & RC=SCW_S_OK
  285. if ((wSW == 0x9000) && (OutLen == sizeof(rgRes)) && (rgRes[0] == 0)) // Version 1.0
  286. {
  287. hScwSetEndianness(hCard, rgRes[1]);
  288. if (rgRes[1] == 0) // LITTLE_ENDIAN
  289. phTmp->bResLen = rgRes[2] - 2; // SW!!!
  290. else
  291. phTmp->bResLen = rgRes[3] - 2; // SW!!!
  292. phTmp->dwFlags |= FLAG_ISPROXY;
  293. phTmp->dwFlags |= VERSION_1_0;
  294. }
  295. else if ((wSW == 0x9011) && (OutLen == sizeof(rgRes) - 1)) // Version 1.1
  296. {
  297. hScwSetEndianness(hCard, rgRes[0]);
  298. if (rgRes[0] == 0) // LITTLE_ENDIAN
  299. phTmp->bResLen = rgRes[1] - 2; // SW!!!
  300. else
  301. phTmp->bResLen = rgRes[2] - 2; // SW!!!
  302. phTmp->dwFlags |= FLAG_ISPROXY;
  303. phTmp->dwFlags |= VERSION_1_1;
  304. }
  305. // else there will be no proxy support but you can still use the Dll
  306. }
  307. else // There will be no proxy support though but you can still use the Dll
  308. ret = SCARD_S_SUCCESS;
  309. }
  310. }
  311. __except(EXCEPTION_EXECUTE_HANDLER) {
  312. switch(GetExceptionCode())
  313. {
  314. case STATUS_INVALID_PARAM:
  315. ret = MAKESCODE(SCW_E_INVALIDPARAM);
  316. break;
  317. default:
  318. ret = SCARD_F_UNKNOWN_ERROR;
  319. }
  320. }
  321. return ret;
  322. }
  323. LONG WINAPI SCWTransmit(SCARDHANDLE hCard, LPCBYTE lpbIn, DWORD dwIn, LPBYTE lpBOut, LPDWORD pdwOut)
  324. {
  325. SCODE ret = SCARD_S_SUCCESS;
  326. LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
  327. __try {
  328. if (phTmp == NULL)
  329. RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
  330. DebugPrintBytes(L"bytes transmitted", (PBYTE) lpbIn, dwIn);
  331. ret = (*phTmp->lpfnTransmit)(hCard, lpbIn, dwIn, lpBOut, pdwOut);
  332. if (NULL != pdwOut)
  333. DebugPrintBytes(L"bytes received", lpBOut, *pdwOut);
  334. }
  335. __except(EXCEPTION_EXECUTE_HANDLER) {
  336. switch(GetExceptionCode())
  337. {
  338. case STATUS_INVALID_PARAM:
  339. ret = MAKESCODE(SCW_E_INVALIDPARAM);
  340. break;
  341. default:
  342. ret = SCARD_F_UNKNOWN_ERROR;
  343. }
  344. }
  345. return ret;
  346. }
  347. const SCARD_IO_REQUEST
  348. g_xIORT0 = { SCARD_PROTOCOL_T0, sizeof(SCARD_IO_REQUEST) },
  349. g_xIORT1 = { SCARD_PROTOCOL_T1, sizeof(SCARD_IO_REQUEST) };
  350. static LONG WINAPI _MySCWTransmit(SCARDHANDLE hCard, LPCBYTE lpbIn, DWORD dwIn, LPBYTE lpBOut, LPDWORD pdwOut)
  351. {
  352. SCARD_IO_REQUEST xIOR;
  353. LONG ret = SCARD_S_SUCCESS;
  354. LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
  355. __try {
  356. if (phTmp == NULL)
  357. RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
  358. if (phTmp->dwProtocol == SCARD_PROTOCOL_T1)
  359. {
  360. memcpy(&xIOR, &g_xIORT1, sizeof(xIOR));
  361. ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardTransmit)(phTmp->hCard,
  362. &xIOR, lpbIn, dwIn,
  363. &xIOR, lpBOut, pdwOut);
  364. }
  365. else
  366. {
  367. DWORD dwOut = *pdwOut;
  368. memcpy(&xIOR, &g_xIORT0, sizeof(xIOR));
  369. __try {
  370. ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardBeginTransaction)(phTmp->hCard);
  371. if (ret == SCARD_S_SUCCESS)
  372. {
  373. ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardTransmit)(phTmp->hCard,
  374. &xIOR, lpbIn, dwIn,
  375. &xIOR, lpBOut, &dwOut);
  376. }
  377. if (ret == SCARD_S_SUCCESS)
  378. {
  379. if ((dwOut == 2) && ((lpBOut[0] == 0x61) || (lpBOut[0] == 0x9F)))
  380. {
  381. BYTE abGR[] = {0x00, 0xC0, 0x00, 0x00, 0x00};
  382. abGR[4] = lpBOut[1];
  383. ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardTransmit)(phTmp->hCard,
  384. &xIOR, abGR, 5,
  385. &xIOR, lpBOut, pdwOut);
  386. }
  387. else
  388. *pdwOut = dwOut;
  389. }
  390. }
  391. __finally
  392. {
  393. (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardEndTransaction)(phTmp->hCard, SCARD_LEAVE_CARD);
  394. }
  395. }
  396. }
  397. __except(EXCEPTION_EXECUTE_HANDLER) {
  398. switch(GetExceptionCode())
  399. {
  400. case STATUS_INVALID_PARAM:
  401. ret = MAKESCODE(SCW_E_INVALIDPARAM);
  402. break;
  403. default:
  404. ret = SCARD_F_UNKNOWN_ERROR;
  405. }
  406. }
  407. return ret;
  408. }
  409. static TCHAR lpstrGroupNames[] = _TEXT("SCard$DefaultReaders\0");
  410. static LONG _GetCardHandle(LPCWSTR mszCardNames, LPMYSCARDHANDLE phCard)
  411. {
  412. LONG lRes;
  413. OPENCARDNAME xOCN;
  414. TCHAR wszReader[MAX_NAME];
  415. TCHAR wszCard[MAX_NAME];
  416. TCHAR wszCN[MAX_NAME];
  417. DWORD len;
  418. LPCWSTR lpwstr = mszCardNames;
  419. LPTSTR lpstrCardNames = wszCN;
  420. xOCN.nMaxCardNames = 0;
  421. #if (!defined(UNICODE) && !defined(_UNICODE))
  422. while (*lpwstr)
  423. {
  424. wsprintf(lpstrCardNames, "%S", lpwstr); // Conversion
  425. len = wcslen(lpwstr) + 1; // Add the trailing 0
  426. xOCN.nMaxCardNames += len;
  427. lpwstr += len;
  428. lpstrCardNames += len;
  429. }
  430. #else
  431. while (*lpwstr)
  432. {
  433. wcscpy(lpstrCardNames, lpwstr);
  434. len = wcslen(lpwstr) + 1; // Add the trailing 0
  435. xOCN.nMaxCardNames += len;
  436. lpwstr += len;
  437. lpstrCardNames += len;
  438. }
  439. #endif
  440. xOCN.nMaxCardNames++; // Add the trailing 0
  441. *lpstrCardNames = 0;
  442. lRes = (*axCtx[phCard->dwFlags & FLAG_MASKPCSC].lpfnEstablish)(SCARD_SCOPE_USER, NULL, NULL, &phCard->hCtx);
  443. if (lRes == SCARD_S_SUCCESS)
  444. {
  445. xOCN.dwStructSize = sizeof(xOCN);
  446. xOCN.hwndOwner = NULL; // probably called from console anyway
  447. xOCN.hSCardContext = phCard->hCtx;
  448. xOCN.lpstrGroupNames = lpstrGroupNames;
  449. xOCN.nMaxGroupNames = sizeof(lpstrGroupNames)/sizeof(TCHAR);
  450. xOCN.lpstrCardNames = wszCN;
  451. xOCN.rgguidInterfaces = NULL;
  452. xOCN.cguidInterfaces = 0;
  453. xOCN.lpstrRdr = wszReader;
  454. xOCN.nMaxRdr = MAX_NAME/sizeof(TCHAR);
  455. xOCN.lpstrCard = wszCard;
  456. xOCN.nMaxCard = MAX_NAME/sizeof(TCHAR);
  457. xOCN.lpstrTitle = _TEXT("Insert Card:");
  458. xOCN.dwFlags = SC_DLG_MINIMAL_UI;
  459. xOCN.pvUserData = NULL;
  460. xOCN.dwShareMode = SCARD_SHARE_SHARED;
  461. xOCN.dwPreferredProtocols = SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_T0;
  462. xOCN.lpfnConnect = NULL;
  463. xOCN.lpfnCheck = NULL;
  464. xOCN.lpfnDisconnect = NULL;
  465. lRes = (*axCtx[phCard->dwFlags & FLAG_MASKPCSC].lpfnOpenCard)(&xOCN);
  466. }
  467. if (lRes == SCARD_S_SUCCESS)
  468. {
  469. phCard->hCard = xOCN.hCardHandle;
  470. }
  471. return lRes;
  472. }
  473. SCODE WINAPI hScwSCardBeginTransaction(SCARDHANDLE hCard)
  474. {
  475. SCODE ret;
  476. LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
  477. if ((phTmp->dwFlags & FLAG_REALPCSC) == FLAG_REALPCSC)
  478. ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardBeginTransaction)(phTmp->hCard);
  479. else
  480. ret = SCARD_S_SUCCESS; // No transactions on simulator
  481. return ret;
  482. }
  483. SCODE WINAPI hScwSCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
  484. {
  485. SCODE ret;
  486. LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
  487. if ((phTmp->dwFlags & FLAG_REALPCSC) == FLAG_REALPCSC)
  488. ret = (*axCtx[phTmp->dwFlags & FLAG_MASKPCSC].lpfnSCardEndTransaction)(phTmp->hCard, dwDisposition);
  489. else
  490. ret = SCARD_S_SUCCESS; // No transactions on simulator
  491. return ret;
  492. }