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.

6300 lines
199 KiB

  1. /*****************************************************************************
  2. @doc INT EXT
  3. ******************************************************************************
  4. * $ProjectName: $
  5. * $ProjectRevision: $
  6. *-----------------------------------------------------------------------------
  7. * $Source: z:/pr/cmbs0/sw/sccmn50m.ms/rcs/sccmcb.c $
  8. * $Revision: 1.7 $
  9. *-----------------------------------------------------------------------------
  10. * $Author: WFrischauf $
  11. *-----------------------------------------------------------------------------
  12. * History: see EOF
  13. *-----------------------------------------------------------------------------
  14. *
  15. * Copyright 2000 OMNIKEY AG
  16. ******************************************************************************/
  17. #include <stdio.h>
  18. #include <strsafe.h>
  19. #include "sccmn50m.h"
  20. static ULONG dataRatesSupported[] = {9600,38400};
  21. static ULONG CLKFrequenciesSupported[] = {4000,5000};
  22. /*****************************************************************************
  23. Routine Description:
  24. Arguments:
  25. Return Value:
  26. *****************************************************************************/
  27. NTSTATUS
  28. SCCMN50M_CardPower(PSMARTCARD_EXTENSION pSmartcardExtension)
  29. {
  30. NTSTATUS status = STATUS_SUCCESS;
  31. NTSTATUS DebugStatus = STATUS_SUCCESS;
  32. UCHAR pbAtrBuffer[MAXIMUM_ATR_LENGTH];
  33. UCHAR abSyncAtrBuffer[MAXIMUM_ATR_LENGTH];
  34. ULONG ulAtrLength;
  35. KIRQL irql;
  36. #if DBG
  37. ULONG i;
  38. #endif;
  39. SmartcardDebug(
  40. DEBUG_TRACE,
  41. ( "%s!CardPower: Enter\n",
  42. DRIVER_NAME)
  43. );
  44. #if DBG
  45. switch (pSmartcardExtension->MinorIoControlCode) {
  46. case SCARD_WARM_RESET:
  47. SmartcardDebug(
  48. DEBUG_ATR,
  49. ( "%s!SCARD_WARM_RESTART\n",
  50. DRIVER_NAME)
  51. );
  52. break;
  53. case SCARD_COLD_RESET:
  54. SmartcardDebug(
  55. DEBUG_ATR,
  56. ( "%s!SCARD_COLD_RESTART\n",
  57. DRIVER_NAME)
  58. );
  59. break;
  60. case SCARD_POWER_DOWN:
  61. SmartcardDebug(
  62. DEBUG_ATR,
  63. ( "%s!SCARD_POWER_DOWN\n",
  64. DRIVER_NAME)
  65. );
  66. break;
  67. }
  68. #endif
  69. switch (pSmartcardExtension->MinorIoControlCode) {
  70. case SCARD_WARM_RESET:
  71. case SCARD_COLD_RESET:
  72. status = SCCMN50M_PowerOn(pSmartcardExtension,
  73. &ulAtrLength,
  74. pbAtrBuffer,
  75. sizeof(pbAtrBuffer));
  76. if (status != STATUS_SUCCESS) {
  77. goto ExitReaderPower;
  78. }
  79. if (ulAtrLength > MAXIMUM_ATR_LENGTH) {
  80. status = STATUS_UNRECOGNIZED_MEDIA;
  81. goto ExitReaderPower;
  82. }
  83. pSmartcardExtension->CardCapabilities.ATR.Length = (UCHAR)ulAtrLength;
  84. if (pSmartcardExtension->ReaderExtension->fRawModeNecessary == FALSE) {
  85. // copy ATR to smart card structure
  86. // the lib needs the ATR for evaluation of the card parameters
  87. MemCpy(pSmartcardExtension->CardCapabilities.ATR.Buffer,
  88. sizeof(pSmartcardExtension->CardCapabilities.ATR.Buffer),
  89. pbAtrBuffer,
  90. ulAtrLength);
  91. pSmartcardExtension->CardCapabilities.ATR.Length = (UCHAR)ulAtrLength;
  92. KeAcquireSpinLock(&pSmartcardExtension->OsData->SpinLock,
  93. &irql);
  94. pSmartcardExtension->ReaderCapabilities.CurrentState = SCARD_NEGOTIABLE;
  95. pSmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  96. KeReleaseSpinLock(&pSmartcardExtension->OsData->SpinLock,
  97. irql);
  98. status = SmartcardUpdateCardCapabilities(pSmartcardExtension);
  99. if (status != STATUS_SUCCESS) {
  100. goto ExitReaderPower;
  101. }
  102. // add extra guard time value to card stop bits
  103. pSmartcardExtension->ReaderExtension->CardManConfig.CardStopBits = (UCHAR)(pSmartcardExtension->CardCapabilities.N);
  104. // copy ATR to user space
  105. MemCpy(pSmartcardExtension->IoRequest.ReplyBuffer,
  106. pSmartcardExtension->IoRequest.ReplyBufferLength,
  107. pbAtrBuffer,
  108. ulAtrLength);
  109. *pSmartcardExtension->IoRequest.Information = ulAtrLength;
  110. #if DBG
  111. SmartcardDebug(DEBUG_ATR,
  112. ("%s!ATR : ",
  113. DRIVER_NAME));
  114. for (i = 0;i < ulAtrLength;i++) {
  115. SmartcardDebug(DEBUG_ATR,
  116. ("%2.2x ",
  117. pSmartcardExtension->CardCapabilities.ATR.Buffer[i]));
  118. }
  119. SmartcardDebug(DEBUG_ATR,("\n"));
  120. #endif
  121. } else {
  122. if (ulAtrLength > MAXIMUM_ATR_LENGTH - 2) {
  123. status = STATUS_UNRECOGNIZED_MEDIA;
  124. goto ExitReaderPower;
  125. }
  126. abSyncAtrBuffer[0] = 0x3B;
  127. abSyncAtrBuffer[1] = 0x04;
  128. MemCpy(&abSyncAtrBuffer[2],
  129. sizeof(abSyncAtrBuffer)-2,
  130. pbAtrBuffer,
  131. ulAtrLength);
  132. ulAtrLength += 2;
  133. MemCpy(pSmartcardExtension->CardCapabilities.ATR.Buffer,
  134. sizeof(pSmartcardExtension->CardCapabilities.ATR.Buffer),
  135. abSyncAtrBuffer,
  136. ulAtrLength);
  137. pSmartcardExtension->CardCapabilities.ATR.Length = (UCHAR)(ulAtrLength);
  138. KeAcquireSpinLock(&pSmartcardExtension->OsData->SpinLock,
  139. &irql);
  140. pSmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  141. pSmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
  142. KeReleaseSpinLock(&pSmartcardExtension->OsData->SpinLock,
  143. irql);
  144. status = SmartcardUpdateCardCapabilities(pSmartcardExtension);
  145. if (status != STATUS_SUCCESS) {
  146. goto ExitReaderPower;
  147. }
  148. SmartcardDebug(DEBUG_ATR,("ATR of synchronous smart card : %2.2x %2.2x %2.2x %2.2x\n",
  149. pbAtrBuffer[0],pbAtrBuffer[1],pbAtrBuffer[2],pbAtrBuffer[3]));
  150. pSmartcardExtension->ReaderExtension->SyncParameters.fCardResetRequested = TRUE;
  151. // copy ATR to user space
  152. MemCpy(pSmartcardExtension->IoRequest.ReplyBuffer,
  153. pSmartcardExtension->IoRequest.ReplyBufferLength,
  154. abSyncAtrBuffer,
  155. ulAtrLength);
  156. *pSmartcardExtension->IoRequest.Information = ulAtrLength;
  157. }
  158. break;
  159. case SCARD_POWER_DOWN:
  160. status = SCCMN50M_PowerOff(pSmartcardExtension);
  161. if (status != STATUS_SUCCESS) {
  162. goto ExitReaderPower;
  163. }
  164. KeAcquireSpinLock(&pSmartcardExtension->OsData->SpinLock,
  165. &irql);
  166. pSmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SWALLOWED;
  167. pSmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  168. KeReleaseSpinLock(&pSmartcardExtension->OsData->SpinLock,
  169. irql);
  170. break;
  171. }
  172. ExitReaderPower:
  173. SmartcardDebug(
  174. DEBUG_TRACE,
  175. ( "%s!CardPower: Exit %lx\n",
  176. DRIVER_NAME,status)
  177. );
  178. return status;
  179. }
  180. /*****************************************************************************
  181. Routine Description:
  182. Arguments:
  183. Return Value:
  184. *****************************************************************************/
  185. NTSTATUS
  186. SCCMN50M_PowerOn (
  187. IN PSMARTCARD_EXTENSION pSmartcardExtension,
  188. OUT PULONG pulAtrLength,
  189. OUT PUCHAR pbAtrBuffer,
  190. IN ULONG ulAtrBufferSize
  191. )
  192. {
  193. NTSTATUS status;
  194. NTSTATUS DebugStatus;
  195. // We always use 0x80 for reset delay
  196. pSmartcardExtension->ReaderExtension->CardManConfig.ResetDelay = 0x80;
  197. if (SCCMN50M_IsAsynchronousSmartCard(pSmartcardExtension) == TRUE) {
  198. if (pSmartcardExtension->MinorIoControlCode == SCARD_COLD_RESET) {
  199. status = SCCMN50M_UseColdWarmResetStrategy(pSmartcardExtension,
  200. pulAtrLength,
  201. pbAtrBuffer,
  202. ulAtrBufferSize,
  203. FALSE);
  204. // if cold reset was not succesfull ,it maybe a SAMOS card with the sensor bug
  205. if (status != STATUS_SUCCESS) {
  206. status = SCCMN50M_UseColdWarmResetStrategy(pSmartcardExtension,
  207. pulAtrLength,
  208. pbAtrBuffer,
  209. ulAtrBufferSize,
  210. TRUE);
  211. if (status != STATUS_SUCCESS) {
  212. status = SCCMN50M_UseParsingStrategy(pSmartcardExtension,
  213. pulAtrLength,
  214. pbAtrBuffer,
  215. ulAtrBufferSize);
  216. }
  217. }
  218. } else {
  219. status = SCCMN50M_UseColdWarmResetStrategy(pSmartcardExtension,
  220. pulAtrLength,
  221. pbAtrBuffer,
  222. ulAtrBufferSize,
  223. TRUE);
  224. if (status != STATUS_SUCCESS) {
  225. status = SCCMN50M_UseParsingStrategy(pSmartcardExtension,
  226. pulAtrLength,
  227. pbAtrBuffer,
  228. ulAtrBufferSize);
  229. }
  230. }
  231. } else {
  232. SmartcardDebug(DEBUG_ATR,
  233. ("check if synchronous smart card is inserted\n"));
  234. // try to find a synchronous smart card
  235. status = SCCMN50M_UseSyncStrategy(pSmartcardExtension,
  236. pulAtrLength,
  237. pbAtrBuffer,
  238. ulAtrBufferSize);
  239. }
  240. if (status != STATUS_SUCCESS) {
  241. // smart card not powered
  242. status = STATUS_UNRECOGNIZED_MEDIA;
  243. *pulAtrLength = 0;
  244. DebugStatus = SCCMN50M_PowerOff(pSmartcardExtension);
  245. return status;
  246. } else {
  247. // add extra guard time value to card stop bits
  248. pSmartcardExtension->ReaderExtension->CardManConfig.CardStopBits = (UCHAR)(pSmartcardExtension->CardCapabilities.N);
  249. return status;
  250. }
  251. }
  252. /*****************************************************************************
  253. Routine Description:
  254. This routine inverts the buffer
  255. Bit0 -> Bit 7
  256. Bit1 -> Bit 6
  257. Bit2 -> Bit 5
  258. Bit3 -> Bit 4
  259. Bit4 -> Bit 3
  260. Bit5 -> Bit 2
  261. Bit6 -> Bit 1
  262. Bit7 -> Bit 0
  263. Arguments: pbBuffer ... pointer to buffer
  264. ulBufferSize ... size of buffer
  265. Return Value: none
  266. *****************************************************************************/
  267. VOID SCCMN50M_InverseBuffer (
  268. PUCHAR pbBuffer,
  269. ULONG ulBufferSize
  270. )
  271. {
  272. ULONG i;
  273. ULONG j;
  274. ULONG m;
  275. ULONG n;
  276. for (i=0; i<ulBufferSize; i++) {
  277. n = 0;
  278. for (j=1; j<=8; j++) {
  279. m = (pbBuffer[i] << j);
  280. m &= 0x00000100;
  281. n |= (m >> (9-j));
  282. }
  283. pbBuffer[i] = (UCHAR)~n;
  284. }
  285. return;
  286. }
  287. /*****************************************************************************
  288. Routine Description:
  289. This function always permforms a cold reset of the smart card.
  290. A SAMOS card with the sensor bug will not be powered by this function.
  291. Arguments:
  292. Return Value:
  293. *****************************************************************************/
  294. NTSTATUS
  295. SCCMN50M_UseParsingStrategy (IN PSMARTCARD_EXTENSION pSmartcardExtension,
  296. OUT PULONG pulAtrLength,
  297. OUT PUCHAR pbAtrBuffer,
  298. IN ULONG ulAtrBufferSize
  299. )
  300. {
  301. NTSTATUS status;
  302. NTSTATUS DebugStatus;
  303. UCHAR ulCardType;
  304. UCHAR ReadBuffer[SCARD_ATR_LENGTH];
  305. UCHAR bAtrBytesRead[SCARD_ATR_LENGTH];
  306. ULONG ulBytesRead;
  307. BOOLEAN fInverseAtr = FALSE;
  308. ULONG ulAtrBufferOffset = 0;
  309. ULONG ulHistoricalBytes;
  310. ULONG ulNextStepBytesToRead;
  311. ULONG ulPrevStepBytesRead;
  312. ULONG i;
  313. BOOLEAN fTDxSent;
  314. BOOLEAN fAtrParsed;
  315. BOOLEAN fOnlyT0 = TRUE;
  316. ULONG ulOldReadTotalTimeoutMultiplier;
  317. // DBGBreakPoint();
  318. // set ReadTotalTimeoutMultiplier to 250ms (9600 * 372/f = initial waiting time)
  319. ulOldReadTotalTimeoutMultiplier = pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier;
  320. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier = 250;
  321. pSmartcardExtension->ReaderExtension->CardManConfig.CardStopBits = 0x02;
  322. for (ulCardType = ASYNC3_CARD;ulCardType <= ASYNC5_CARD;ulCardType++) {
  323. // power off + resync
  324. status = SCCMN50M_PowerOff(pSmartcardExtension);
  325. if (status != STATUS_SUCCESS) {
  326. goto ExitUseParsingStrategy;
  327. }
  328. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ALL_FLAGS);
  329. SCCMN50M_SetSCRControlFlags(pSmartcardExtension,CARD_POWER| IGNORE_PARITY);
  330. if (ulCardType == ASYNC3_CARD)
  331. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_3MHZ);
  332. else
  333. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_5MHZ);
  334. SCCMN50M_SetCardManHeader(pSmartcardExtension,
  335. 0,
  336. 0,
  337. 0,
  338. 2); // TS and T0 expected
  339. SmartcardDebug(DEBUG_ATR,
  340. ("%s!ResetDelay = %d\n",
  341. DRIVER_NAME,
  342. pSmartcardExtension->ReaderExtension->CardManConfig.ResetDelay));
  343. // write config + header
  344. status = SCCMN50M_WriteCardMan(pSmartcardExtension,0,NULL);
  345. if (status != STATUS_SUCCESS) {
  346. goto ExitUseParsingStrategy;
  347. }
  348. // read state and length + TS + T0
  349. status = SCCMN50M_ReadCardMan(pSmartcardExtension,4,&ulBytesRead,ReadBuffer,sizeof(ReadBuffer));
  350. if (status != STATUS_SUCCESS) {
  351. continue; // try next card
  352. }
  353. // contents of read buffer
  354. // [0] ... state
  355. // [1] ... length
  356. // [2] ... TS
  357. // [3] ... T0
  358. // TS
  359. if (ReadBuffer[2] == CHAR_INV) {
  360. fInverseAtr = TRUE;
  361. }
  362. if (fInverseAtr)
  363. SCCMN50M_InverseBuffer(&ReadBuffer[3],1);
  364. ulHistoricalBytes = ReadBuffer[3] & 0x0F;
  365. ulPrevStepBytesRead = 2;
  366. // T0 codes following TA1 - TD1
  367. fAtrParsed = TRUE;
  368. SmartcardDebug(DEBUG_ATR,
  369. ("%s!Step : Bytes to read = 2\n",
  370. DRIVER_NAME));
  371. do {
  372. ulNextStepBytesToRead = ulPrevStepBytesRead;
  373. fTDxSent = FALSE;
  374. if (ReadBuffer[ulBytesRead - 1 ] & 0x10)
  375. ulNextStepBytesToRead++;
  376. if (ReadBuffer[ulBytesRead - 1 ] & 0x20)
  377. ulNextStepBytesToRead++;
  378. if (ReadBuffer[ulBytesRead - 1 ] & 0x40)
  379. ulNextStepBytesToRead++;
  380. if (ReadBuffer[ulBytesRead - 1 ] & 0x80) {
  381. ulNextStepBytesToRead++;
  382. fTDxSent = TRUE;
  383. }
  384. if (ulPrevStepBytesRead != 2 &&
  385. ReadBuffer[ulBytesRead -1 ] & 0x0f) {
  386. fOnlyT0 = FALSE;
  387. }
  388. // -----------------------
  389. // POWER OFF
  390. // -----------------------
  391. // turn power off and get state
  392. status = SCCMN50M_PowerOff(pSmartcardExtension);
  393. if (status != STATUS_SUCCESS) {
  394. fAtrParsed = FALSE;
  395. goto ExitUseParsingStrategy; // try next card
  396. }
  397. // -----------------------
  398. // POWER ON
  399. // -----------------------
  400. // turn on power flag
  401. SCCMN50M_SetSCRControlFlags(pSmartcardExtension,CARD_POWER| IGNORE_PARITY);
  402. if (ulCardType == ASYNC3_CARD)
  403. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_3MHZ);
  404. else
  405. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_5MHZ);
  406. SCCMN50M_SetCardManHeader(pSmartcardExtension,
  407. 0,
  408. 0,
  409. 0,
  410. (UCHAR)ulNextStepBytesToRead);
  411. // write config + header
  412. status = SCCMN50M_WriteCardMan(pSmartcardExtension,0,NULL);
  413. if (status != STATUS_SUCCESS) {
  414. fAtrParsed = FALSE;
  415. goto ExitUseParsingStrategy; // try next card
  416. }
  417. // read state and length + TAx,TBx,TCx,TDx
  418. SmartcardDebug(DEBUG_ATR,
  419. ("%s!Step : Bytes to read = %ld\n",
  420. DRIVER_NAME,
  421. ulNextStepBytesToRead));
  422. status = SCCMN50M_ReadCardMan(pSmartcardExtension,2 + ulNextStepBytesToRead,&ulBytesRead,ReadBuffer,sizeof(ReadBuffer));
  423. if (status != STATUS_SUCCESS) {
  424. fAtrParsed = FALSE;
  425. break; // try next card
  426. }
  427. if (fInverseAtr)
  428. SCCMN50M_InverseBuffer(&ReadBuffer[2],ulBytesRead-2);
  429. MemCpy(bAtrBytesRead,sizeof(bAtrBytesRead),&ReadBuffer[2],ulBytesRead -2);
  430. #if DBG
  431. SmartcardDebug(DEBUG_ATR,
  432. ("%s!read ATR bytes: ",
  433. DRIVER_NAME));
  434. for (i = 0;i < ulBytesRead-2;i++)
  435. SmartcardDebug(DEBUG_ATR,
  436. ("%2.2x ",
  437. bAtrBytesRead[i]));
  438. SmartcardDebug(DEBUG_ATR,("\n"));
  439. #endif
  440. ulPrevStepBytesRead = ulBytesRead - 2;
  441. } while (fTDxSent == TRUE);
  442. // +++++++++++++++++++++++++++++++++++++++
  443. // now we know how long the whole ATR is
  444. // +++++++++++++++++++++++++++++++++++++++
  445. // -----------------------
  446. // POWER OFF
  447. // -----------------------
  448. // turn power off and get state
  449. status = SCCMN50M_PowerOff(pSmartcardExtension);
  450. if (!NT_SUCCESS(status)) {
  451. goto ExitUseParsingStrategy;
  452. }
  453. // -----------------------
  454. // POWER ON
  455. // -----------------------
  456. // turn on power flag
  457. SCCMN50M_SetSCRControlFlags(pSmartcardExtension,CARD_POWER| IGNORE_PARITY);
  458. if (ulCardType == ASYNC3_CARD)
  459. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_3MHZ);
  460. else
  461. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_5MHZ);
  462. // bug fix : old SAMOS cards have a damaged ATR
  463. if (bAtrBytesRead[0] == 0x3b &&
  464. bAtrBytesRead[1] == 0xbf &&
  465. bAtrBytesRead[2] == 0x11 &&
  466. bAtrBytesRead[3] == 0x00 &&
  467. bAtrBytesRead[4] == 0x81 &&
  468. bAtrBytesRead[5] == 0x31 &&
  469. bAtrBytesRead[6] == 0x90 &&
  470. bAtrBytesRead[7] == 0x73 ) {
  471. ulHistoricalBytes = 4;
  472. }
  473. ulNextStepBytesToRead = ulPrevStepBytesRead + ulHistoricalBytes;
  474. if (fOnlyT0 == FALSE)
  475. ulNextStepBytesToRead++; // TCK !
  476. SCCMN50M_SetCardManHeader(pSmartcardExtension,
  477. 0,
  478. 0,
  479. 0,
  480. (UCHAR)ulNextStepBytesToRead);
  481. // write config + header
  482. status = SCCMN50M_WriteCardMan(pSmartcardExtension,0,NULL);
  483. if (status != STATUS_SUCCESS) {
  484. goto ExitUseParsingStrategy; // try next card
  485. }
  486. // read whole ATR
  487. SmartcardDebug(DEBUG_ATR,
  488. ("%s!Step : Bytes to read = %ld\n",
  489. DRIVER_NAME,
  490. ulNextStepBytesToRead));
  491. status = SCCMN50M_ReadCardMan(pSmartcardExtension,2+ulNextStepBytesToRead,&ulBytesRead,ReadBuffer,sizeof(ReadBuffer));
  492. if (!NT_SUCCESS(status)) {
  493. SmartcardDebug(DEBUG_ATR,
  494. ("%s!Reading of whole ATR failed\n !",
  495. DRIVER_NAME));
  496. continue; // try next card
  497. }
  498. // check ATR
  499. if (ulBytesRead - 2 < MIN_ATR_LEN) {
  500. status = STATUS_UNRECOGNIZED_MEDIA;
  501. DebugStatus = SCCMN50M_ReadCardMan(pSmartcardExtension,2+ulNextStepBytesToRead,&ulBytesRead,ReadBuffer,sizeof(ReadBuffer));
  502. goto ExitUseParsingStrategy;
  503. }
  504. if (ulBytesRead -2 > ulAtrBufferSize) {
  505. // the ATR is larger then 33 bytes !!!
  506. status = STATUS_BUFFER_OVERFLOW;
  507. goto ExitUseParsingStrategy;
  508. }
  509. SCCMN50M_CheckAtrModified(pbAtrBuffer,*pulAtrLength);
  510. // pass ATR and ATR length to calling function
  511. MemCpy(pbAtrBuffer,ulAtrBufferSize,&ReadBuffer[2],ulBytesRead -2);
  512. *pulAtrLength = ulBytesRead -2;
  513. if (fInverseAtr) {
  514. SCCMN50M_SetCardControlFlags(pSmartcardExtension,INVERSE_DATA);
  515. SCCMN50M_InverseBuffer(pbAtrBuffer,*pulAtrLength);
  516. pSmartcardExtension->ReaderExtension->fInverseAtr = TRUE;
  517. } else {
  518. pSmartcardExtension->ReaderExtension->fInverseAtr = FALSE;
  519. }
  520. pSmartcardExtension->ReaderExtension->fRawModeNecessary = FALSE;
  521. break;
  522. }
  523. ExitUseParsingStrategy:
  524. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier
  525. = ulOldReadTotalTimeoutMultiplier ;
  526. SCCMN50M_ClearSCRControlFlags(pSmartcardExtension,IGNORE_PARITY);
  527. SCCMN50M_ClearCardManHeader(pSmartcardExtension);
  528. return status;
  529. }
  530. /*****************************************************************************
  531. Routine Description:
  532. This function performs either a cold or a warm reset depending on
  533. the fWarmReset parameter .
  534. Arguments:
  535. Return Value:
  536. *****************************************************************************/
  537. NTSTATUS
  538. SCCMN50M_UseColdWarmResetStrategy (IN PSMARTCARD_EXTENSION pSmartcardExtension,
  539. OUT PULONG pulAtrLength,
  540. OUT PUCHAR pbAtrBuffer,
  541. IN ULONG ulAtrBufferSize,
  542. IN BOOLEAN fWarmReset
  543. )
  544. {
  545. NTSTATUS status;
  546. NTSTATUS DebugStatus;
  547. ULONG ulCardType;
  548. UCHAR bReadBuffer[SCARD_ATR_LENGTH];
  549. ULONG ulBytesRead;
  550. ULONG ulOldReadTotalTimeoutMultiplier;
  551. //DBGBreakPoint();
  552. // set ReadTotalTimeoutMultiplier to 250ms (9600 * 372/f = initial waiting time)
  553. ulOldReadTotalTimeoutMultiplier = pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier;
  554. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier = 250;
  555. if (fWarmReset == FALSE) {
  556. SCCMN50M_SetCardManHeader(pSmartcardExtension,0,0,COLD_RESET,ATR_LEN_ASYNC);
  557. } else {
  558. SCCMN50M_SetCardManHeader(pSmartcardExtension,0,0,0,ATR_LEN_ASYNC);
  559. }
  560. pSmartcardExtension->ReaderExtension->CardManConfig.CardStopBits = 0x02;
  561. for (ulCardType = ASYNC3_CARD;ulCardType <= ASYNC5_CARD;ulCardType++) {
  562. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ALL_FLAGS);
  563. SCCMN50M_SetSCRControlFlags(pSmartcardExtension,CARD_POWER| IGNORE_PARITY | CM2_GET_ATR);
  564. if (ulCardType == ASYNC3_CARD) {
  565. SmartcardDebug(
  566. DEBUG_ATR,
  567. ("%s!ASYNC_3\n",
  568. DRIVER_NAME));
  569. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_3MHZ);
  570. } else {
  571. SmartcardDebug(
  572. DEBUG_ATR,
  573. ("%s!ASYN_5\n",
  574. DRIVER_NAME));
  575. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_5MHZ);
  576. }
  577. status = SCCMN50M_ResyncCardManII(pSmartcardExtension);
  578. if (status != STATUS_SUCCESS) {
  579. goto ExitUseColdWarmResetStrategy;
  580. }
  581. // write config + header
  582. status = SCCMN50M_WriteCardMan(pSmartcardExtension,0,NULL);
  583. if (status != STATUS_SUCCESS) {
  584. goto ExitUseColdWarmResetStrategy;
  585. }
  586. pSmartcardExtension->ReaderExtension->ToRHConfig = FALSE;
  587. // read state and length
  588. status = SCCMN50M_ReadCardMan(pSmartcardExtension,2,&ulBytesRead,bReadBuffer,sizeof(bReadBuffer));
  589. if (status != STATUS_SUCCESS) {
  590. continue; // try next card
  591. }
  592. if (bReadBuffer[1] < MIN_ATR_LEN) {
  593. // read all remaining bytes from the CardMan
  594. DebugStatus = SCCMN50M_ReadCardMan(pSmartcardExtension,bReadBuffer[1],&ulBytesRead,bReadBuffer,sizeof(bReadBuffer));
  595. status = STATUS_UNRECOGNIZED_MEDIA;
  596. goto ExitUseColdWarmResetStrategy;
  597. }
  598. if (bReadBuffer[1] > ulAtrBufferSize) {
  599. status = STATUS_BUFFER_OVERFLOW;
  600. goto ExitUseColdWarmResetStrategy;
  601. }
  602. // read ATR
  603. status = SCCMN50M_ReadCardMan(pSmartcardExtension,bReadBuffer[1],pulAtrLength,pbAtrBuffer,ulAtrBufferSize);
  604. if (status != STATUS_SUCCESS) {
  605. continue;
  606. }
  607. switch (pbAtrBuffer[0]) {
  608. case CHAR_INV:
  609. pSmartcardExtension->ReaderExtension->fRawModeNecessary = FALSE;
  610. SCCMN50M_SetCardControlFlags(pSmartcardExtension,INVERSE_DATA);
  611. SCCMN50M_InverseBuffer(pbAtrBuffer,*pulAtrLength);
  612. pSmartcardExtension->ReaderExtension->fInverseAtr = TRUE;
  613. break;
  614. case CHAR_NORM:
  615. pSmartcardExtension->ReaderExtension->fRawModeNecessary = FALSE;
  616. pSmartcardExtension->ReaderExtension->fInverseAtr = FALSE;
  617. break;
  618. default :
  619. status = STATUS_UNRECOGNIZED_MEDIA;
  620. goto ExitUseColdWarmResetStrategy;
  621. break;
  622. }
  623. // the smart card has been powered
  624. SCCMN50M_CheckAtrModified(pbAtrBuffer,*pulAtrLength);
  625. MemCpy(pSmartcardExtension->CardCapabilities.ATR.Buffer,
  626. sizeof(pSmartcardExtension->CardCapabilities.ATR.Buffer),
  627. pbAtrBuffer,
  628. *pulAtrLength);
  629. pSmartcardExtension->CardCapabilities.ATR.Length = (UCHAR)*pulAtrLength;
  630. status = SmartcardUpdateCardCapabilities(pSmartcardExtension);
  631. if (status != STATUS_SUCCESS) {
  632. SmartcardDebug(DEBUG_ATR,
  633. ("%s!Invalid ATR received\n",
  634. DRIVER_NAME));
  635. goto ExitUseColdWarmResetStrategy;
  636. }
  637. if (SCCMN50M_IsAtrValid(pbAtrBuffer,*pulAtrLength) == FALSE) {
  638. SmartcardDebug(
  639. DEBUG_ATR,
  640. ("%s!Invalid ATR received\n",
  641. DRIVER_NAME));
  642. status = STATUS_UNRECOGNIZED_MEDIA;
  643. goto ExitUseColdWarmResetStrategy;
  644. }
  645. break;
  646. } // end for
  647. ExitUseColdWarmResetStrategy:
  648. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier
  649. = ulOldReadTotalTimeoutMultiplier ;
  650. SCCMN50M_ClearSCRControlFlags(pSmartcardExtension,CM2_GET_ATR | IGNORE_PARITY);
  651. SCCMN50M_ClearCardManHeader(pSmartcardExtension);
  652. return status;
  653. }
  654. /*****************************************************************************
  655. Routine Description:
  656. This function checks if the received ATR is valid.
  657. Arguments:
  658. Return Value:
  659. *****************************************************************************/
  660. BOOLEAN
  661. SCCMN50M_IsAtrValid(
  662. PUCHAR pbAtrBuffer,
  663. ULONG ulAtrLength
  664. )
  665. {
  666. BOOLEAN fAtrValid = TRUE;
  667. ULONG ulTD1Offset = 0;
  668. BOOLEAN fTD1Transmitted = FALSE;
  669. BOOLEAN fOnlyT0 = FALSE;
  670. BYTE bXor;
  671. ULONG ulHistoricalBytes;
  672. ULONG ulTx2Characters = 0;
  673. ULONG i;
  674. //DBGBreakPoint();
  675. SmartcardDebug(
  676. DEBUG_TRACE,
  677. ( "%s!IsAtrValid : Enter\n",
  678. DRIVER_NAME)
  679. );
  680. // basic checks
  681. if (ulAtrLength < 2 ||
  682. (pbAtrBuffer[0] != 0x3F &&
  683. pbAtrBuffer[0] != 0x3B ) ||
  684. (pbAtrBuffer[1] & 0xF0) == 0x00 ) {
  685. return FALSE;
  686. }
  687. if (pbAtrBuffer[1] & 0x10)
  688. ulTD1Offset++;
  689. if (pbAtrBuffer[1] & 0x20)
  690. ulTD1Offset++;
  691. if (pbAtrBuffer[1] & 0x40)
  692. ulTD1Offset++;
  693. ulHistoricalBytes = pbAtrBuffer[1] & 0x0F;
  694. if (pbAtrBuffer[1] & 0x80) { // TD1 in ATR ?
  695. fTD1Transmitted = TRUE;
  696. if ((pbAtrBuffer[2 + ulTD1Offset] & 0x0F) == 0x00) // T0 indicated ?
  697. fOnlyT0 = TRUE;
  698. } else {
  699. fOnlyT0 = TRUE;
  700. }
  701. if (fOnlyT0 == FALSE) {
  702. bXor = pbAtrBuffer[1];
  703. for (i=2;i<ulAtrLength;i++)
  704. bXor ^= pbAtrBuffer[i];
  705. if (bXor != 0x00)
  706. fAtrValid = FALSE;
  707. } else {
  708. // only T0 protocol is indicated
  709. if (fTD1Transmitted == TRUE) {
  710. if (pbAtrBuffer[2 + ulTD1Offset] & 0x10)
  711. ulTx2Characters++;
  712. if (pbAtrBuffer[2 + ulTD1Offset] & 0x20)
  713. ulTx2Characters++;
  714. if (pbAtrBuffer[2 + ulTD1Offset] & 0x40)
  715. ulTx2Characters++;
  716. if (ulAtrLength != 2 + ulTD1Offset + 1 + ulTx2Characters + ulHistoricalBytes)
  717. fAtrValid = FALSE;
  718. } else {
  719. if (ulAtrLength != 2 + ulTD1Offset + ulHistoricalBytes)
  720. fAtrValid = FALSE;
  721. }
  722. }
  723. SmartcardDebug(
  724. DEBUG_TRACE,
  725. ( "%s!IsAtrValid : Exit %d\n",
  726. DRIVER_NAME,fAtrValid)
  727. );
  728. return fAtrValid;
  729. }
  730. /*****************************************************************************
  731. Routine Description:
  732. This function checks if the received ATR is valid.
  733. Arguments:
  734. Return Value:
  735. *****************************************************************************/
  736. VOID SCCMN50M_CheckAtrModified (
  737. PUCHAR pbBuffer,
  738. ULONG ulBufferSize
  739. )
  740. {
  741. UCHAR bNumberHistoricalBytes;
  742. UCHAR bXorChecksum;
  743. ULONG i;
  744. if (ulBufferSize < 0x09) // mininmum length of a modified ATR
  745. return ; // ATR is ok
  746. // variant 2
  747. if (pbBuffer[0] == 0x3b &&
  748. pbBuffer[1] == 0xbf &&
  749. pbBuffer[2] == 0x11 &&
  750. pbBuffer[3] == 0x00 &&
  751. pbBuffer[4] == 0x81 &&
  752. pbBuffer[5] == 0x31 &&
  753. pbBuffer[6] == 0x90 &&
  754. pbBuffer[7] == 0x73 &&
  755. ulBufferSize == 13 ) {
  756. // correct number of historical bytes
  757. bNumberHistoricalBytes = 4;
  758. pbBuffer[1] &= 0xf0;
  759. pbBuffer[1] |= bNumberHistoricalBytes;
  760. // correct checksum byte
  761. bXorChecksum = pbBuffer[1];
  762. for (i=2;i<ulBufferSize-1;i++)
  763. bXorChecksum ^= pbBuffer[i];
  764. pbBuffer[ulBufferSize -1 ] = bXorChecksum;
  765. SmartcardDebug(DEBUG_ATR,
  766. ("%s!correcting SAMOS ATR (variant 2)\n",
  767. DRIVER_NAME));
  768. }
  769. // variant 1
  770. if (pbBuffer[0] == 0x3b &&
  771. pbBuffer[1] == 0xb4 &&
  772. pbBuffer[2] == 0x11 &&
  773. pbBuffer[3] == 0x00 &&
  774. pbBuffer[4] == 0x81 &&
  775. pbBuffer[5] == 0x31 &&
  776. pbBuffer[6] == 0x90 &&
  777. pbBuffer[7] == 0x73 &&
  778. ulBufferSize == 13 ) {
  779. // correct checksum byte
  780. bXorChecksum = pbBuffer[1];
  781. for (i=2;i<ulBufferSize-1;i++)
  782. bXorChecksum ^= pbBuffer[i];
  783. if (pbBuffer[ulBufferSize -1 ] != bXorChecksum ) {
  784. pbBuffer[ulBufferSize -1 ] = bXorChecksum;
  785. SmartcardDebug(DEBUG_ATR,
  786. ("%s!correcting SAMOS ATR (variant 1)\n",
  787. DRIVER_NAME));
  788. }
  789. }
  790. // variant 3
  791. if (pbBuffer[0] == 0x3b &&
  792. pbBuffer[1] == 0xbf &&
  793. pbBuffer[2] == 0x11 &&
  794. pbBuffer[3] == 0x00 &&
  795. pbBuffer[4] == 0x81 &&
  796. pbBuffer[5] == 0x31 &&
  797. pbBuffer[6] == 0x90 &&
  798. pbBuffer[7] == 0x73 &&
  799. ulBufferSize == 9 ) {
  800. // correct number of historical bytes
  801. bNumberHistoricalBytes = 0;
  802. pbBuffer[1] &= 0xf0;
  803. pbBuffer[1] |= bNumberHistoricalBytes;
  804. // correct checksum byte
  805. bXorChecksum = pbBuffer[1];
  806. for (i=2;i<ulBufferSize-1;i++)
  807. bXorChecksum ^= pbBuffer[i];
  808. pbBuffer[ulBufferSize -1 ] = bXorChecksum;
  809. SmartcardDebug(DEBUG_ATR,
  810. ("%s!correcting SAMOS ATR (variant 3)\n",
  811. DRIVER_NAME));
  812. }
  813. }
  814. /*****************************************************************************
  815. Routine Description:
  816. Arguments:
  817. Return Value:
  818. *****************************************************************************/
  819. NTSTATUS
  820. SCCMN50M_PowerOff (IN PSMARTCARD_EXTENSION pSmartcardExtension )
  821. {
  822. NTSTATUS status;
  823. NTSTATUS DebugStatus = STATUS_SUCCESS;
  824. UCHAR pReadBuffer[2];
  825. ULONG ulBytesRead;
  826. SmartcardDebug(
  827. DEBUG_TRACE,
  828. ( "%s!PowerOff: Enter\n",
  829. DRIVER_NAME)
  830. );
  831. // SCR control bytes
  832. SCCMN50M_ClearSCRControlFlags(pSmartcardExtension,CARD_POWER);
  833. // card control bytes
  834. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ALL_FLAGS);
  835. // header
  836. SCCMN50M_SetCardManHeader(pSmartcardExtension,0,0,0,1);
  837. // rx length = 1 because we don't want to receive a status
  838. // write config + header
  839. status = SCCMN50M_WriteCardMan(pSmartcardExtension,0,NULL);
  840. if (status != STATUS_SUCCESS) {
  841. goto ExitSCCMN50M_PowerOff;
  842. }
  843. // CardMan echoes a BRK which is recevied in the read functions
  844. DebugStatus = SCCMN50M_ReadCardMan(pSmartcardExtension,2,&ulBytesRead,pReadBuffer,sizeof(pReadBuffer));
  845. #if 0
  846. if (DebugStatus != STATUS_SUCCESS)
  847. SmartcardDebug(
  848. DEBUG_ERROR,
  849. ( "%s!PowerOffBRK received\n",
  850. DRIVER_NAME)
  851. );
  852. #endif
  853. ExitSCCMN50M_PowerOff:
  854. if (pSmartcardExtension->ReaderExtension->ulOldCardState == POWERED)
  855. pSmartcardExtension->ReaderExtension->ulOldCardState = INSERTED;
  856. SmartcardDebug(
  857. DEBUG_TRACE,
  858. ( "%s!PowerOff: Exit %lx\n",
  859. DRIVER_NAME,status)
  860. );
  861. return status;
  862. }
  863. /*****************************************************************************
  864. Routine Description:
  865. Arguments:
  866. Return Value:
  867. *****************************************************************************/
  868. NTSTATUS
  869. SCCMN50M_Transmit(PSMARTCARD_EXTENSION pSmartcardExtension)
  870. {
  871. NTSTATUS status;
  872. NTSTATUS DebugStatus;
  873. switch (pSmartcardExtension->CardCapabilities.Protocol.Selected) {
  874. case SCARD_PROTOCOL_RAW:
  875. status = STATUS_INVALID_DEVICE_REQUEST;
  876. break;
  877. case SCARD_PROTOCOL_T0:
  878. status = SCCMN50M_TransmitT0(pSmartcardExtension);
  879. break;
  880. case SCARD_PROTOCOL_T1:
  881. status = SCCMN50M_TransmitT1(pSmartcardExtension);
  882. break;
  883. default:
  884. status = STATUS_INVALID_DEVICE_REQUEST;
  885. break;
  886. }
  887. return status;
  888. }
  889. /*****************************************************************************
  890. Routine Description:
  891. Arguments:
  892. Return Value:
  893. *****************************************************************************/
  894. NTSTATUS
  895. SCCMN50M_TransmitT0(PSMARTCARD_EXTENSION pSmartcardExtension)
  896. {
  897. NTSTATUS status;
  898. NTSTATUS DebugStatus;
  899. UCHAR bWriteBuffer[MIN_BUFFER_SIZE];
  900. UCHAR bReadBuffer [MIN_BUFFER_SIZE];
  901. ULONG ulWriteBufferOffset;
  902. ULONG ulReadBufferOffset;
  903. ULONG ulBytesToWrite;
  904. ULONG ulBytesToRead;
  905. ULONG ulBytesToWriteThisStep;
  906. ULONG ulBytesToReadThisStep;
  907. ULONG ulBytesStillToWrite;
  908. ULONG ulBytesRead;
  909. ULONG ulBytesStillToRead;
  910. BOOLEAN fDataDirectionFromCard;
  911. BYTE bProcedureByte;
  912. BYTE bINS;
  913. BOOLEAN fT0TransferToCard = FALSE;
  914. BOOLEAN fT0TransferFromCard = FALSE;
  915. BOOLEAN fSW1SW2Sent = FALSE;
  916. ULONG ulReadTotalTimeoutMultiplier;
  917. ULONG ulStatBytesRead;
  918. BYTE abStatReadBuffer[2];
  919. //SmartcardDebug(DEBUG_TRACE,("TransmitT0 : Enter\n"));
  920. //
  921. // Let the lib build a T=0 packet
  922. //
  923. pSmartcardExtension->SmartcardRequest.BufferLength = 0; // no bytes additionally needed
  924. status = SmartcardT0Request(pSmartcardExtension);
  925. if (status != STATUS_SUCCESS) {
  926. //
  927. // This lib detected an error in the data to send.
  928. //
  929. // ------------------------------------------
  930. // ITSEC E2 requirements: clear write buffers
  931. // ------------------------------------------
  932. MemSet(bWriteBuffer,
  933. sizeof(bWriteBuffer),
  934. '\0',
  935. sizeof(bWriteBuffer));
  936. MemSet(pSmartcardExtension->SmartcardRequest.Buffer,
  937. pSmartcardExtension->SmartcardRequest.BufferSize,
  938. '\0',
  939. pSmartcardExtension->SmartcardRequest.BufferSize);
  940. return status;
  941. }
  942. // increase timeout for T0 Transmission
  943. ulReadTotalTimeoutMultiplier = pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier;
  944. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier =
  945. pSmartcardExtension->CardCapabilities.T0.WT/1000 + 1500;
  946. // ##################################
  947. // TRANSPARENT MODE
  948. // ##################################
  949. ulBytesStillToWrite = ulBytesToWrite = T0_HEADER_LEN + pSmartcardExtension->T0.Lc;
  950. ulBytesStillToRead = ulBytesToRead = pSmartcardExtension->T0.Le;
  951. if (pSmartcardExtension->T0.Lc)
  952. fT0TransferToCard = TRUE;
  953. if (pSmartcardExtension->T0.Le)
  954. fT0TransferFromCard = TRUE;
  955. // copy data to the write buffer
  956. MemCpy(bWriteBuffer,
  957. sizeof(bWriteBuffer),
  958. pSmartcardExtension->SmartcardRequest.Buffer,
  959. ulBytesToWrite);
  960. bINS = bWriteBuffer[1];
  961. if (pSmartcardExtension->ReaderExtension->fInverseAtr == TRUE) {
  962. SCCMN50M_InverseBuffer(bWriteBuffer,ulBytesToWrite);
  963. }
  964. status = SCCMN50M_EnterTransparentMode(pSmartcardExtension);
  965. if (status != STATUS_SUCCESS) {
  966. goto ExitTransparentTransmitT0;
  967. }
  968. // STEP 1 : write config + header to enter transparent mode
  969. SCCMN50M_SetCardManHeader(pSmartcardExtension,
  970. 0, // Tx control
  971. 0, // Tx length
  972. 0, // Rx control
  973. 0); // Rx length
  974. status = SCCMN50M_WriteCardMan (pSmartcardExtension,
  975. 0,
  976. NULL);
  977. if (NT_ERROR(status)) {
  978. goto ExitTransparentTransmitT0;
  979. }
  980. pSmartcardExtension->ReaderExtension->fTransparentMode = TRUE;
  981. // if the inserted card uses inverse convention , we must now switch the COM port
  982. // to odd parity
  983. if (pSmartcardExtension->ReaderExtension->fInverseAtr == TRUE) {
  984. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.StopBits = STOP_BITS_2;
  985. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.Parity = ODD_PARITY;
  986. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.WordLength = SERIAL_DATABITS_8;
  987. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_LINE_CONTROL;
  988. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  989. &pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl,
  990. sizeof(SERIAL_LINE_CONTROL));
  991. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_LINE_CONTROL);
  992. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  993. status = SCCMN50M_SerialIo(pSmartcardExtension);
  994. if (!NT_SUCCESS(status)) {
  995. goto ExitTransparentTransmitT0;
  996. }
  997. }
  998. ulWriteBufferOffset = 0;
  999. ulReadBufferOffset = 0;
  1000. // STEP 2 : write CLA INS P1 P2 Lc
  1001. ulBytesToWriteThisStep = 5;
  1002. status = SCCMN50M_WriteCardMan (pSmartcardExtension,
  1003. ulBytesToWriteThisStep,
  1004. bWriteBuffer+ulWriteBufferOffset);
  1005. if (NT_ERROR(status)) {
  1006. goto ExitTransparentTransmitT0;
  1007. }
  1008. ulWriteBufferOffset += ulBytesToWriteThisStep;
  1009. ulBytesStillToWrite -= ulBytesToWriteThisStep;
  1010. // STEP 2 : read procedure byte
  1011. do {
  1012. do {
  1013. pSmartcardExtension->ReaderExtension->ToRHConfig= FALSE;
  1014. status = SCCMN50M_ReadCardMan(pSmartcardExtension,1,&ulBytesRead,&bProcedureByte,sizeof(bProcedureByte));
  1015. if (NT_ERROR(status)) {
  1016. goto ExitTransparentTransmitT0;
  1017. }
  1018. if (pSmartcardExtension->ReaderExtension->fInverseAtr == TRUE) {
  1019. SCCMN50M_InverseBuffer(&bProcedureByte,ulBytesRead);
  1020. }
  1021. //SmartcardDebug(DEBUG_TRACE,("Procedure byte = %x\n",bProcedureByte));
  1022. //SmartcardDebug(DEBUG_TRACE,("waiting time = %x\n",pSmartcardExtension->CardCapabilities.T0.WT));
  1023. if (bProcedureByte == 0x60) {
  1024. // ISO 7816-3 :
  1025. // This byte is sent by the card to reset the work waiting time and to anticipate
  1026. // a subsequent procedure byte
  1027. // => we do nothing here
  1028. }
  1029. } while (bProcedureByte == 0x60);
  1030. // check for ACK
  1031. if ((bProcedureByte & 0xFE) == (bINS & 0xFE) ) {
  1032. if (fT0TransferToCard) {
  1033. ulBytesToWriteThisStep = ulBytesStillToWrite;
  1034. if ((ulWriteBufferOffset > MIN_BUFFER_SIZE) ||
  1035. (MIN_BUFFER_SIZE - ulWriteBufferOffset < ulBytesToWriteThisStep)) {
  1036. status = STATUS_DEVICE_PROTOCOL_ERROR;
  1037. goto ExitTransparentTransmitT0;
  1038. }
  1039. status = SCCMN50M_WriteCardMan (pSmartcardExtension,
  1040. ulBytesToWriteThisStep,
  1041. bWriteBuffer+ulWriteBufferOffset);
  1042. if (NT_ERROR(status)) {
  1043. goto ExitTransparentTransmitT0;
  1044. }
  1045. ulWriteBufferOffset += ulBytesToWriteThisStep;
  1046. ulBytesStillToWrite -= ulBytesToWriteThisStep;
  1047. }
  1048. if (fT0TransferFromCard) {
  1049. ulBytesToReadThisStep = ulBytesStillToRead;
  1050. pSmartcardExtension->ReaderExtension->ToRHConfig= FALSE;
  1051. if (ulReadBufferOffset > MIN_BUFFER_SIZE) {
  1052. status = STATUS_DEVICE_PROTOCOL_ERROR;
  1053. goto ExitTransparentTransmitT0;
  1054. }
  1055. status = SCCMN50M_ReadCardMan(pSmartcardExtension,
  1056. ulBytesToReadThisStep,
  1057. &ulBytesRead,
  1058. bReadBuffer + ulReadBufferOffset,
  1059. sizeof(bReadBuffer)-ulReadBufferOffset);
  1060. if (NT_ERROR(status)) {
  1061. goto ExitTransparentTransmitT0;
  1062. }
  1063. if (pSmartcardExtension->ReaderExtension->fInverseAtr == TRUE) {
  1064. SCCMN50M_InverseBuffer(bReadBuffer+ulReadBufferOffset,ulBytesRead);
  1065. }
  1066. ulReadBufferOffset += ulBytesRead;
  1067. ulBytesStillToRead -= ulBytesRead;
  1068. }
  1069. }
  1070. // check for NAK
  1071. else if ( (~bProcedureByte & 0xFE) == (bINS & 0xFE)) {
  1072. if (fT0TransferToCard) {
  1073. ulBytesToWriteThisStep = 1;
  1074. if ((ulWriteBufferOffset > MIN_BUFFER_SIZE) ||
  1075. (MIN_BUFFER_SIZE - ulWriteBufferOffset < ulBytesToWriteThisStep)) {
  1076. status = STATUS_DEVICE_PROTOCOL_ERROR;
  1077. goto ExitTransparentTransmitT0;
  1078. }
  1079. status = SCCMN50M_WriteCardMan (pSmartcardExtension,
  1080. ulBytesToWriteThisStep,
  1081. bWriteBuffer+ulWriteBufferOffset);
  1082. if (NT_ERROR(status)) {
  1083. goto ExitTransparentTransmitT0;
  1084. }
  1085. ulWriteBufferOffset += ulBytesToWriteThisStep;
  1086. ulBytesStillToWrite -= ulBytesToWriteThisStep;
  1087. }
  1088. if (fT0TransferFromCard) {
  1089. ulBytesToReadThisStep = 1;
  1090. pSmartcardExtension->ReaderExtension->ToRHConfig= FALSE;
  1091. if (ulReadBufferOffset > MIN_BUFFER_SIZE) {
  1092. status = STATUS_DEVICE_PROTOCOL_ERROR;
  1093. goto ExitTransparentTransmitT0;
  1094. }
  1095. status = SCCMN50M_ReadCardMan(pSmartcardExtension,
  1096. ulBytesToReadThisStep,
  1097. &ulBytesRead,
  1098. bReadBuffer + ulReadBufferOffset,
  1099. sizeof(bReadBuffer)-ulReadBufferOffset);
  1100. if (NT_ERROR(status)) {
  1101. goto ExitTransparentTransmitT0;
  1102. }
  1103. if (pSmartcardExtension->ReaderExtension->fInverseAtr == TRUE) {
  1104. SCCMN50M_InverseBuffer(bReadBuffer+ulReadBufferOffset,ulBytesRead);
  1105. }
  1106. ulReadBufferOffset += ulBytesRead;
  1107. ulBytesStillToRead -= ulBytesRead;
  1108. }
  1109. }
  1110. // check for SW1
  1111. else if ( (bProcedureByte > 0x60 && bProcedureByte <= 0x6F) ||
  1112. (bProcedureByte >= 0x90 && bProcedureByte <= 0x9F) ) {
  1113. pSmartcardExtension->ReaderExtension->ToRHConfig= FALSE;
  1114. bReadBuffer[ulReadBufferOffset] = bProcedureByte;
  1115. ulReadBufferOffset++;
  1116. if (ulReadBufferOffset > MIN_BUFFER_SIZE) {
  1117. status = STATUS_DEVICE_PROTOCOL_ERROR;
  1118. goto ExitTransparentTransmitT0;
  1119. }
  1120. status = SCCMN50M_ReadCardMan(pSmartcardExtension,
  1121. 1,
  1122. &ulBytesRead,
  1123. bReadBuffer+ulReadBufferOffset,
  1124. sizeof(bReadBuffer)-ulReadBufferOffset);
  1125. if (NT_ERROR(status)) {
  1126. goto ExitTransparentTransmitT0;
  1127. }
  1128. if (pSmartcardExtension->ReaderExtension->fInverseAtr == TRUE) {
  1129. SCCMN50M_InverseBuffer(bReadBuffer+ulReadBufferOffset,ulBytesRead);
  1130. }
  1131. ulReadBufferOffset += ulBytesRead;
  1132. fSW1SW2Sent = TRUE;
  1133. } else {
  1134. status = STATUS_UNSUCCESSFUL;
  1135. goto ExitTransparentTransmitT0;
  1136. }
  1137. }while (!fSW1SW2Sent);
  1138. // copy received bytes
  1139. MemCpy(pSmartcardExtension->SmartcardReply.Buffer,
  1140. pSmartcardExtension->SmartcardReply.BufferSize,
  1141. bReadBuffer,
  1142. ulReadBufferOffset);
  1143. pSmartcardExtension->SmartcardReply.BufferLength = ulReadBufferOffset;
  1144. // let the lib copy the received bytes to the user buffer
  1145. status = SmartcardT0Reply(pSmartcardExtension);
  1146. if (NT_ERROR(status)) {
  1147. goto ExitTransparentTransmitT0;
  1148. }
  1149. ExitTransparentTransmitT0:
  1150. // ------------------------------------------
  1151. // ITSEC E2 requirements: clear write buffers
  1152. // ------------------------------------------
  1153. MemSet(bWriteBuffer,
  1154. sizeof(bWriteBuffer),
  1155. '\0',
  1156. sizeof(bWriteBuffer));
  1157. MemSet(pSmartcardExtension->SmartcardRequest.Buffer,
  1158. pSmartcardExtension->SmartcardRequest.BufferSize,
  1159. '\0',
  1160. pSmartcardExtension->SmartcardRequest.BufferSize);
  1161. DebugStatus = SCCMN50M_ExitTransparentMode(pSmartcardExtension);
  1162. pSmartcardExtension->ReaderExtension->fTransparentMode = FALSE;
  1163. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier = ulReadTotalTimeoutMultiplier;
  1164. // to be sure that the new settings take effect
  1165. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant = 250;
  1166. DebugStatus = SCCMN50M_WriteCardMan(pSmartcardExtension,0,NULL);
  1167. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant = DEFAULT_READ_TOTAL_TIMEOUT_CONSTANT;
  1168. if (NT_SUCCESS(DebugStatus)) {
  1169. DebugStatus = SCCMN50M_ReadCardMan(pSmartcardExtension,2,&ulStatBytesRead,abStatReadBuffer,sizeof(abStatReadBuffer));
  1170. }
  1171. return status;
  1172. }
  1173. /*****************************************************************************
  1174. Routine Description:
  1175. Arguments:
  1176. Return Value:
  1177. *****************************************************************************/
  1178. NTSTATUS
  1179. SCCMN50M_TransmitT1(PSMARTCARD_EXTENSION pSmartcardExtension)
  1180. {
  1181. NTSTATUS status;
  1182. ULONG ulBytesToWrite;
  1183. UCHAR bWriteBuffer [256 + T1_HEADER_LEN + MAX_EDC_LEN];
  1184. UCHAR bReadBuffer [256 + T1_HEADER_LEN + MAX_EDC_LEN];
  1185. ULONG ulBytesRead;
  1186. ULONG ulBytesStillToRead;
  1187. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant =
  1188. pSmartcardExtension->CardCapabilities.T1.BWT/1000;
  1189. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier =
  1190. pSmartcardExtension->CardCapabilities.T1.CWT/1000;
  1191. // set T1 protocol flag for CardMan
  1192. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_T1);
  1193. if (pSmartcardExtension->CardCapabilities.T1.EDC == T1_CRC_CHECK) {
  1194. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_CRC);
  1195. }
  1196. do {
  1197. pSmartcardExtension->SmartcardRequest.BufferLength = 0; // no bytes additionally needed
  1198. status = SmartcardT1Request(pSmartcardExtension);
  1199. if (status != STATUS_SUCCESS) {
  1200. goto ExitTransmitT1;
  1201. }
  1202. ulBytesToWrite = pSmartcardExtension->SmartcardRequest.BufferLength;
  1203. SCCMN50M_SetCardManHeader(pSmartcardExtension,
  1204. 0, // Tx conrol
  1205. (UCHAR)ulBytesToWrite, // Tx length
  1206. 0, // Rx control
  1207. T1_HEADER_LEN); // Rx length
  1208. if (sizeof(bWriteBuffer) < ulBytesToWrite) {
  1209. status = STATUS_BUFFER_OVERFLOW;
  1210. goto ExitTransmitT1;
  1211. }
  1212. // copy data to the write buffer
  1213. MemCpy(bWriteBuffer,
  1214. sizeof(bWriteBuffer),
  1215. pSmartcardExtension->SmartcardRequest.Buffer,
  1216. ulBytesToWrite);
  1217. // write data to card
  1218. status = SCCMN50M_WriteCardMan (pSmartcardExtension,
  1219. ulBytesToWrite,
  1220. bWriteBuffer);
  1221. if (status == STATUS_SUCCESS) {
  1222. // read CardMan Header
  1223. pSmartcardExtension->ReaderExtension->ToRHConfig = FALSE;
  1224. status = SCCMN50M_ReadCardMan(pSmartcardExtension,
  1225. 2,
  1226. &ulBytesRead,
  1227. bReadBuffer,
  1228. sizeof(bReadBuffer));
  1229. if (status == STATUS_SUCCESS) {
  1230. ulBytesStillToRead = bReadBuffer[1];
  1231. status = SCCMN50M_ReadCardMan(pSmartcardExtension,
  1232. ulBytesStillToRead,
  1233. &ulBytesRead,
  1234. bReadBuffer,
  1235. sizeof(bReadBuffer));
  1236. if (status == STATUS_SUCCESS) {
  1237. if (bReadBuffer[1] == T1_WTX_REQUEST) {
  1238. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant =
  1239. (ULONG)(1000 +((pSmartcardExtension->CardCapabilities.T1.BWT*bReadBuffer[3])/1000));
  1240. SmartcardDebug(DEBUG_PROTOCOL,("%s!ReadTotalTimeoutConstant = %ld(ms)\n",
  1241. DRIVER_NAME,
  1242. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant));
  1243. } else {
  1244. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant =
  1245. pSmartcardExtension->CardCapabilities.T1.BWT/1000;
  1246. SmartcardDebug(DEBUG_PROTOCOL,("%s!ReadTotalTimeoutConstant = %ld(ms)\n",
  1247. DRIVER_NAME,
  1248. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant));
  1249. }
  1250. // copy received bytes
  1251. MemCpy(pSmartcardExtension->SmartcardReply.Buffer,
  1252. pSmartcardExtension->SmartcardReply.BufferSize,
  1253. bReadBuffer,
  1254. ulBytesRead);
  1255. pSmartcardExtension->SmartcardReply.BufferLength = ulBytesRead;
  1256. }
  1257. }
  1258. }
  1259. if (status != STATUS_SUCCESS) {
  1260. // reset serial timeout
  1261. SmartcardDebug(
  1262. DEBUG_PROTOCOL,
  1263. ( "%s!reseting timeout constant\n",
  1264. DRIVER_NAME)
  1265. );
  1266. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant =
  1267. pSmartcardExtension->CardCapabilities.T1.BWT/1000;
  1268. SmartcardDebug(DEBUG_PROTOCOL,("%s!ReadTotalTimeoutConstant = %ld(ms)\n",
  1269. DRIVER_NAME,
  1270. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant));
  1271. pSmartcardExtension->SmartcardReply.BufferLength = 0L;
  1272. }
  1273. // bug fix for smclib
  1274. if (pSmartcardExtension->T1.State == T1_IFS_RESPONSE &&
  1275. pSmartcardExtension->T1.OriginalState == T1_I_BLOCK) {
  1276. pSmartcardExtension->T1.State = T1_I_BLOCK;
  1277. }
  1278. status = SmartcardT1Reply(pSmartcardExtension);
  1279. }
  1280. while (status == STATUS_MORE_PROCESSING_REQUIRED);
  1281. ExitTransmitT1:
  1282. // ------------------------------------------
  1283. // ITSEC E2 requirements: clear write buffers
  1284. // ------------------------------------------
  1285. MemSet(bWriteBuffer,
  1286. sizeof(bWriteBuffer),
  1287. '\0',
  1288. sizeof(bWriteBuffer));
  1289. MemSet(pSmartcardExtension->SmartcardRequest.Buffer,
  1290. pSmartcardExtension->SmartcardRequest.BufferSize,
  1291. '\0',
  1292. pSmartcardExtension->SmartcardRequest.BufferSize);
  1293. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier =
  1294. DEFAULT_READ_TOTAL_TIMEOUT_MULTIPLIER;
  1295. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant =
  1296. DEFAULT_READ_TOTAL_TIMEOUT_CONSTANT;
  1297. return status;
  1298. }
  1299. /*****************************************************************************
  1300. Routine Description:
  1301. Arguments:
  1302. Return Value:
  1303. *****************************************************************************/
  1304. VOID
  1305. SCCMN50M_InitializeSmartcardExtension(
  1306. IN PSMARTCARD_EXTENSION pSmartcardExtension,
  1307. IN ULONG ulDeviceInstance
  1308. )
  1309. {
  1310. // ==================================
  1311. // Fill the Vendor_Attr structure
  1312. // ==================================
  1313. MemCpy(pSmartcardExtension->VendorAttr.VendorName.Buffer,
  1314. sizeof(pSmartcardExtension->VendorAttr.VendorName.Buffer),
  1315. ATTR_VENDOR_NAME,
  1316. sizeof(ATTR_VENDOR_NAME)
  1317. );
  1318. //
  1319. // Length of vendor name
  1320. //
  1321. pSmartcardExtension->VendorAttr.VendorName.Length = sizeof(ATTR_VENDOR_NAME);
  1322. //
  1323. // Version number
  1324. //
  1325. pSmartcardExtension->VendorAttr.IfdVersion.BuildNumber = IFD_NT_BUILDNUMBER_CARDMAN;
  1326. pSmartcardExtension->VendorAttr.IfdVersion.VersionMinor = IFD_NT_VERSIONMINOR_CARDMAN;
  1327. pSmartcardExtension->VendorAttr.IfdVersion.VersionMajor = IFD_NT_VERSIONMAJOR_CARDMAN;
  1328. MemCpy(pSmartcardExtension->VendorAttr.IfdType.Buffer,
  1329. sizeof(pSmartcardExtension->VendorAttr.IfdType.Buffer),
  1330. ATTR_IFD_TYPE_CM,
  1331. sizeof(ATTR_IFD_TYPE_CM));
  1332. //
  1333. // Length of reader name
  1334. //
  1335. pSmartcardExtension->VendorAttr.IfdType.Length = sizeof(ATTR_IFD_TYPE_CM);
  1336. //
  1337. // Unit number which is zero based
  1338. //
  1339. pSmartcardExtension->VendorAttr.UnitNo = ulDeviceInstance;
  1340. // ================================================
  1341. // Fill the SCARD_READER_CAPABILITIES structure
  1342. // ===============================================
  1343. //
  1344. // Supported protoclols by the reader
  1345. //
  1346. pSmartcardExtension->ReaderCapabilities.SupportedProtocols = SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_T0;
  1347. //
  1348. // Reader type serial, keyboard, ....
  1349. //
  1350. pSmartcardExtension->ReaderCapabilities.ReaderType = SCARD_READER_TYPE_SERIAL;
  1351. //
  1352. // Mechanical characteristics like swallows etc.
  1353. //
  1354. pSmartcardExtension->ReaderCapabilities.MechProperties = 0;
  1355. //
  1356. // Current state of the reader
  1357. //
  1358. pSmartcardExtension->ReaderCapabilities.CurrentState = SCARD_UNKNOWN;
  1359. //
  1360. // Data Rate
  1361. //
  1362. pSmartcardExtension->ReaderCapabilities.DataRate.Default =
  1363. pSmartcardExtension->ReaderCapabilities.DataRate.Max =
  1364. dataRatesSupported[0];
  1365. // reader could support higher data rates
  1366. pSmartcardExtension->ReaderCapabilities.DataRatesSupported.List =
  1367. dataRatesSupported;
  1368. pSmartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
  1369. sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
  1370. //
  1371. // CLKFrequency
  1372. //
  1373. pSmartcardExtension->ReaderCapabilities.CLKFrequency.Default =
  1374. pSmartcardExtension->ReaderCapabilities.CLKFrequency.Max =
  1375. CLKFrequenciesSupported[0];
  1376. pSmartcardExtension->ReaderCapabilities.CLKFrequenciesSupported.List =
  1377. CLKFrequenciesSupported;
  1378. pSmartcardExtension->ReaderCapabilities.CLKFrequenciesSupported.Entries =
  1379. sizeof(CLKFrequenciesSupported) / sizeof(CLKFrequenciesSupported[0]);
  1380. //pSmartcardExtension->ReaderCapabilities.CLKFrequency.Default = 3571; //3.571 MHz
  1381. //pSmartcardExtension->ReaderCapabilities.CLKFrequency.Max = 3571; //3.571 MHz
  1382. //
  1383. // MaxIFSD
  1384. //
  1385. pSmartcardExtension->ReaderCapabilities.MaxIFSD = ATTR_MAX_IFSD_CARDMAN_II;
  1386. }
  1387. /*****************************************************************************
  1388. Routine Description:
  1389. Arguments:
  1390. Return Value:
  1391. *****************************************************************************/
  1392. VOID
  1393. MemSet(PUCHAR pBuffer,
  1394. ULONG ulBufferSize,
  1395. UCHAR ucPattern,
  1396. ULONG ulCount)
  1397. {
  1398. ULONG i;
  1399. for (i=0; i<ulCount;i++) {
  1400. if (i >= ulBufferSize)
  1401. break;
  1402. pBuffer[i] = ucPattern;
  1403. }
  1404. return ;
  1405. }
  1406. /*****************************************************************************
  1407. Routine Description:
  1408. Arguments:
  1409. Return Value:
  1410. *****************************************************************************/
  1411. VOID
  1412. MemCpy(PUCHAR pDestination,
  1413. ULONG ulDestinationLen,
  1414. PUCHAR pSource,
  1415. ULONG ulCount)
  1416. {
  1417. ULONG i = 0;
  1418. while ( ulCount-- && ulDestinationLen-- ) {
  1419. pDestination[i] = pSource[i];
  1420. i++;
  1421. }
  1422. return;
  1423. }
  1424. /*****************************************************************************
  1425. Routine Description:
  1426. Arguments:
  1427. Return Value:
  1428. *****************************************************************************/
  1429. VOID
  1430. SCCMN50M_UpdateCurrentStateThread(
  1431. IN PVOID Context
  1432. )
  1433. {
  1434. PDEVICE_EXTENSION deviceExtension = Context;
  1435. PSMARTCARD_EXTENSION smartcardExtension;
  1436. NTSTATUS status;
  1437. LONG lRetry;
  1438. KIRQL irql;
  1439. LONG ulFailures;
  1440. BOOLEAN fPriorityIncreased;
  1441. LONG lOldPriority;
  1442. SmartcardDebug(DEBUG_DRIVER,
  1443. ("%s!UpdateCurrentStateThread started\n",DRIVER_NAME));
  1444. ulFailures = 0;
  1445. smartcardExtension = &deviceExtension->SmartcardExtension;
  1446. //
  1447. // Increase priority for first loop,
  1448. // because state of card must be known for resource manager
  1449. //
  1450. fPriorityIncreased=TRUE;
  1451. lOldPriority=KeSetPriorityThread(KeGetCurrentThread(),HIGH_PRIORITY);
  1452. do {
  1453. KeWaitForSingleObject(&smartcardExtension->ReaderExtension->CardManIOMutex,
  1454. Executive,
  1455. KernelMode,
  1456. FALSE,
  1457. NULL);
  1458. if ( smartcardExtension->ReaderExtension->TimeToTerminateThread ) {
  1459. KeReleaseMutex(&smartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  1460. smartcardExtension->ReaderExtension->TimeToTerminateThread = FALSE;
  1461. PsTerminateSystemThread( STATUS_SUCCESS );
  1462. }
  1463. lRetry = 1;
  1464. do {
  1465. status=SCCMN50M_UpdateCurrentState(smartcardExtension);
  1466. if (NT_SUCCESS(status)) {
  1467. break;
  1468. } else {
  1469. lRetry--;
  1470. }
  1471. }
  1472. while (lRetry >= 0);
  1473. if (lRetry < 0) {
  1474. ulFailures++;
  1475. if (ulFailures == 1) {
  1476. SmartcardDebug(
  1477. DEBUG_DRIVER,
  1478. ( "%s!CardMan removed\n",
  1479. DRIVER_NAME)
  1480. );
  1481. // issue a card removal event if reader has been removed
  1482. if (smartcardExtension->ReaderExtension->ulOldCardState == INSERTED ||
  1483. smartcardExtension->ReaderExtension->ulOldCardState == POWERED ) {
  1484. SmartcardDebug(
  1485. DEBUG_DRIVER,
  1486. ( "%s!issuing card removal event\n",
  1487. DRIVER_NAME)
  1488. );
  1489. SCCMN50M_CompleteCardTracking(smartcardExtension);
  1490. smartcardExtension->ReaderExtension->SyncParameters.fCardPowerRequested = TRUE;
  1491. KeAcquireSpinLock(&smartcardExtension->OsData->SpinLock,
  1492. &irql);
  1493. smartcardExtension->ReaderExtension->ulNewCardState = REMOVED;
  1494. smartcardExtension->ReaderExtension->ulOldCardState = smartcardExtension->ReaderExtension->ulNewCardState;
  1495. smartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
  1496. smartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1497. smartcardExtension->CardCapabilities.ATR.Length = 0;
  1498. KeReleaseSpinLock(&smartcardExtension->OsData->SpinLock,
  1499. irql);
  1500. SCCMN50M_ClearCardControlFlags(smartcardExtension,ALL_FLAGS);
  1501. smartcardExtension->ReaderExtension->CardManConfig.CardStopBits = 0;
  1502. smartcardExtension->ReaderExtension->CardManConfig.ResetDelay = 0;
  1503. }
  1504. }
  1505. if (ulFailures == 3) {
  1506. // remove the device and terminate this thread
  1507. if (KeReadStateEvent(&deviceExtension->SerialCloseDone) == 0l) {
  1508. SmartcardDebug(
  1509. DEBUG_DRIVER,
  1510. ( "%s!closing serial driver\n",
  1511. DRIVER_NAME)
  1512. );
  1513. SCCMN50M_CloseSerialDriver(smartcardExtension->OsData->DeviceObject);
  1514. KeReleaseMutex(&smartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  1515. smartcardExtension->ReaderExtension->TimeToTerminateThread = FALSE;
  1516. smartcardExtension->ReaderExtension->ThreadObjectPointer = NULL;
  1517. PsTerminateSystemThread( STATUS_SUCCESS );
  1518. }
  1519. }
  1520. } else {
  1521. ulFailures = 0;
  1522. }
  1523. KeReleaseMutex(&smartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  1524. if (fPriorityIncreased) {
  1525. fPriorityIncreased=FALSE;
  1526. KeSetPriorityThread(KeGetCurrentThread(),lOldPriority);
  1527. //
  1528. // Lower ourselves down just at tad so that we compete a
  1529. // little less.
  1530. //
  1531. KeSetBasePriorityThread(KeGetCurrentThread(),-1);
  1532. }
  1533. //SmartcardDebug(DEBUG_TRACE,( "...#\n"));
  1534. Wait (smartcardExtension,500 * ms_);
  1535. }
  1536. while (TRUE);
  1537. }
  1538. NTSTATUS SCCMN50M_UpdateCurrentState(
  1539. IN PSMARTCARD_EXTENSION smartcardExtension
  1540. )
  1541. {
  1542. NTSTATUS NTStatus;
  1543. UCHAR pbReadBuffer[2];
  1544. ULONG ulBytesRead;
  1545. BOOLEAN fCardStateChanged;
  1546. KIRQL irql;
  1547. fCardStateChanged = FALSE;
  1548. SCCMN50M_ClearCardManHeader(smartcardExtension);
  1549. smartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant = 250;
  1550. NTStatus = SCCMN50M_WriteCardMan(smartcardExtension,0,NULL);
  1551. smartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant = DEFAULT_READ_TOTAL_TIMEOUT_CONSTANT;
  1552. if (NT_SUCCESS(NTStatus)) {
  1553. NTStatus = SCCMN50M_ReadCardMan(smartcardExtension,2,&ulBytesRead,pbReadBuffer,sizeof(pbReadBuffer));
  1554. KeAcquireSpinLock(&smartcardExtension->OsData->SpinLock,
  1555. &irql);
  1556. if (ulBytesRead == 0x02 && // two bytes must have benn received
  1557. (pbReadBuffer[0] & 0x0F) && // at least one version bit must be set
  1558. ((pbReadBuffer[0] & 0x09) == 0x00)) { // Bit 0 and Bit 3 must be 0
  1559. if ((pbReadBuffer[0] & 0x04) == 0x04 &&
  1560. (pbReadBuffer[0] & 0x02) == 0x02)
  1561. smartcardExtension->ReaderExtension->ulNewCardState = INSERTED;
  1562. if ((pbReadBuffer[0] & 0x04) == 0x00 &&
  1563. (pbReadBuffer[0] & 0x02) == 0x02)
  1564. smartcardExtension->ReaderExtension->ulNewCardState = REMOVED;
  1565. if ((pbReadBuffer[0] & 0x04) == 0x04 &&
  1566. (pbReadBuffer[0] & 0x02) == 0x00)
  1567. smartcardExtension->ReaderExtension->ulNewCardState = POWERED;
  1568. if (smartcardExtension->ReaderExtension->ulNewCardState == INSERTED &&
  1569. smartcardExtension->ReaderExtension->ulOldCardState == POWERED ) {
  1570. // card has been removed and reinserted within 500ms
  1571. fCardStateChanged = TRUE;
  1572. SmartcardDebug(DEBUG_DRIVER,( "%s!Smartcard removed and reinserted\n",DRIVER_NAME));
  1573. smartcardExtension->ReaderExtension->ulOldCardState = REMOVED;
  1574. smartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
  1575. smartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1576. // clear any cardspecific data
  1577. smartcardExtension->CardCapabilities.ATR.Length = 0;
  1578. SCCMN50M_ClearCardControlFlags(smartcardExtension,ALL_FLAGS);
  1579. smartcardExtension->ReaderExtension->CardManConfig.CardStopBits = 0;
  1580. smartcardExtension->ReaderExtension->CardManConfig.ResetDelay = 0;
  1581. }
  1582. if (smartcardExtension->ReaderExtension->ulNewCardState == REMOVED &&
  1583. (smartcardExtension->ReaderExtension->ulOldCardState == UNKNOWN ||
  1584. smartcardExtension->ReaderExtension->ulOldCardState == INSERTED ||
  1585. smartcardExtension->ReaderExtension->ulOldCardState == POWERED ) ) {
  1586. // card has been removed
  1587. fCardStateChanged = TRUE;
  1588. SmartcardDebug(DEBUG_DRIVER,( "%s!Smartcard removed\n",DRIVER_NAME));
  1589. smartcardExtension->ReaderExtension->ulOldCardState = smartcardExtension->ReaderExtension->ulNewCardState;
  1590. smartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
  1591. smartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1592. // clear any cardspecific data
  1593. smartcardExtension->CardCapabilities.ATR.Length = 0;
  1594. SCCMN50M_ClearCardControlFlags(smartcardExtension,ALL_FLAGS);
  1595. smartcardExtension->ReaderExtension->CardManConfig.CardStopBits = 0;
  1596. smartcardExtension->ReaderExtension->CardManConfig.ResetDelay = 0;
  1597. }
  1598. if (smartcardExtension->ReaderExtension->ulNewCardState == INSERTED &&
  1599. (smartcardExtension->ReaderExtension->ulOldCardState == UNKNOWN ||
  1600. smartcardExtension->ReaderExtension->ulOldCardState == REMOVED ) ) {
  1601. // card has been inserted
  1602. fCardStateChanged = TRUE;
  1603. SmartcardDebug(DEBUG_DRIVER,( "%s!Smartcard inserted\n",DRIVER_NAME));
  1604. smartcardExtension->ReaderExtension->ulOldCardState = smartcardExtension->ReaderExtension->ulNewCardState;
  1605. smartcardExtension->ReaderCapabilities.CurrentState = SCARD_SWALLOWED;
  1606. smartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1607. }
  1608. // state after reset of the PC (only for CardMan Power+ possible)
  1609. if (smartcardExtension->ReaderExtension->ulNewCardState == POWERED &&
  1610. smartcardExtension->ReaderExtension->ulOldCardState == UNKNOWN ) {
  1611. // card has been inserted
  1612. fCardStateChanged = TRUE;
  1613. SmartcardDebug(DEBUG_DRIVER,( "%s!Smartcard inserted (and powered)\n",DRIVER_NAME));
  1614. smartcardExtension->ReaderExtension->ulOldCardState = smartcardExtension->ReaderExtension->ulNewCardState;
  1615. smartcardExtension->ReaderCapabilities.CurrentState = SCARD_SWALLOWED;
  1616. smartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1617. }
  1618. if (smartcardExtension->ReaderExtension->ulNewCardState == POWERED &&
  1619. smartcardExtension->ReaderExtension->ulOldCardState == INSERTED ) {
  1620. smartcardExtension->ReaderExtension->ulOldCardState = smartcardExtension->ReaderExtension->ulNewCardState;
  1621. }
  1622. }
  1623. KeReleaseSpinLock(&smartcardExtension->OsData->SpinLock,
  1624. irql);
  1625. // complete IOCTL_SMARTCARD_IS_ABSENT or IOCTL_SMARTCARD_IS_PRESENT
  1626. if (fCardStateChanged == TRUE) {
  1627. SCCMN50M_CompleteCardTracking(smartcardExtension);
  1628. }
  1629. }
  1630. return NTStatus;
  1631. }
  1632. /*****************************************************************************
  1633. Routine Description:
  1634. Arguments:
  1635. Return Value:
  1636. *****************************************************************************/
  1637. NTSTATUS Wait (PSMARTCARD_EXTENSION pSmartcardExtension,ULONG ulMilliseconds)
  1638. {
  1639. NTSTATUS status = STATUS_SUCCESS;
  1640. LARGE_INTEGER WaitTime;
  1641. WaitTime = RtlConvertLongToLargeInteger(ulMilliseconds * WAIT_MS);
  1642. KeDelayExecutionThread(KernelMode,FALSE,&WaitTime);
  1643. return status;
  1644. }
  1645. /*****************************************************************************
  1646. Routine Description:
  1647. Arguments:
  1648. Return Value:
  1649. *****************************************************************************/
  1650. VOID
  1651. SCCMN50M_SetSCRControlFlags(
  1652. IN PSMARTCARD_EXTENSION pSmartcardExtension,
  1653. IN UCHAR Flags
  1654. )
  1655. {
  1656. pSmartcardExtension->ReaderExtension->CardManConfig.SCRControl |= Flags;
  1657. }
  1658. /*****************************************************************************
  1659. Routine Description:
  1660. Arguments:
  1661. Return Value:
  1662. *****************************************************************************/
  1663. VOID
  1664. SCCMN50M_ClearSCRControlFlags(
  1665. IN PSMARTCARD_EXTENSION pSmartcardExtension,
  1666. IN UCHAR Flags
  1667. )
  1668. {
  1669. pSmartcardExtension->ReaderExtension->CardManConfig.SCRControl &= ~Flags;
  1670. }
  1671. /*****************************************************************************
  1672. Routine Description:
  1673. Arguments:
  1674. Return Value:
  1675. *****************************************************************************/
  1676. VOID
  1677. SCCMN50M_SetCardControlFlags(
  1678. IN PSMARTCARD_EXTENSION pSmartcardExtension,
  1679. IN UCHAR Flags
  1680. )
  1681. {
  1682. pSmartcardExtension->ReaderExtension->CardManConfig.CardControl |= Flags;
  1683. }
  1684. /*****************************************************************************
  1685. Routine Description:
  1686. Arguments:
  1687. Return Value:
  1688. *****************************************************************************/
  1689. VOID
  1690. SCCMN50M_ClearCardControlFlags(
  1691. IN PSMARTCARD_EXTENSION pSmartcardExtension,
  1692. IN UCHAR Flags
  1693. )
  1694. {
  1695. pSmartcardExtension->ReaderExtension->CardManConfig.CardControl &= ~Flags;
  1696. }
  1697. /*****************************************************************************
  1698. Routine Description:
  1699. Arguments:
  1700. Return Value:
  1701. *****************************************************************************/
  1702. VOID
  1703. SCCMN50M_ClearCardManHeader(
  1704. IN PSMARTCARD_EXTENSION pSmartcardExtension
  1705. )
  1706. {
  1707. pSmartcardExtension->ReaderExtension->CardManHeader.TxControl = 0x00;
  1708. pSmartcardExtension->ReaderExtension->CardManHeader.TxLength = 0x00;
  1709. pSmartcardExtension->ReaderExtension->CardManHeader.RxControl = 0x00;
  1710. pSmartcardExtension->ReaderExtension->CardManHeader.RxLength = 0x00;
  1711. }
  1712. /*****************************************************************************
  1713. Routine Description:
  1714. Arguments:
  1715. Return Value:
  1716. *****************************************************************************/
  1717. VOID
  1718. SCCMN50M_SetCardManHeader(
  1719. IN PSMARTCARD_EXTENSION pSmartcardExtension,
  1720. IN UCHAR TxControl,
  1721. IN UCHAR TxLength,
  1722. IN UCHAR RxControl,
  1723. IN UCHAR RxLength
  1724. )
  1725. {
  1726. pSmartcardExtension->ReaderExtension->CardManHeader.TxControl = TxControl;
  1727. pSmartcardExtension->ReaderExtension->CardManHeader.TxLength = TxLength;
  1728. pSmartcardExtension->ReaderExtension->CardManHeader.RxControl = RxControl;
  1729. pSmartcardExtension->ReaderExtension->CardManHeader.RxLength = RxLength;
  1730. }
  1731. /*****************************************************************************
  1732. Routine Description:
  1733. Arguments:
  1734. Return Value:
  1735. *****************************************************************************/
  1736. NTSTATUS
  1737. SCCMN50M_WriteCardMan (
  1738. IN PSMARTCARD_EXTENSION pSmartcardExtension,
  1739. IN ULONG ulBytesToWrite,
  1740. IN PUCHAR pbWriteBuffer
  1741. )
  1742. {
  1743. NTSTATUS status;
  1744. NTSTATUS DebugStatus;
  1745. PSERIAL_STATUS pSerialStatus;
  1746. // ===============================================
  1747. // Set up timeouts for following read operation
  1748. // ===============================================
  1749. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_TIMEOUTS;
  1750. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  1751. &pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts,
  1752. sizeof(SERIAL_TIMEOUTS));
  1753. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_TIMEOUTS);
  1754. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  1755. /*
  1756. SmartcardDebug(DEBUG_TRACE,("ReadTotalTimeoutMultiplier = %ld\n",
  1757. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier));
  1758. SmartcardDebug(DEBUG_TRACE,("ReadTotalTimeoutConstant = %ld\n",
  1759. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant));
  1760. */
  1761. status = SCCMN50M_SerialIo(pSmartcardExtension);
  1762. // ===============================================
  1763. // write to the CardMan
  1764. // ===============================================
  1765. DebugStatus = SCCMN50M_SetWrite(pSmartcardExtension,ulBytesToWrite,pbWriteBuffer);
  1766. // add pseudoboost (0x00) to write buffer for CardManII
  1767. if (pSmartcardExtension->ReaderExtension->fTransparentMode == FALSE ) {
  1768. pSmartcardExtension->SmartcardRequest.Buffer[pSmartcardExtension->SmartcardRequest.BufferLength] = 0x00;
  1769. pSmartcardExtension->SmartcardRequest.BufferLength++;
  1770. }
  1771. status = SCCMN50M_SerialIo(pSmartcardExtension);
  1772. // overwrite write buffer with '@'
  1773. RtlFillMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  1774. pSmartcardExtension->SmartcardRequest.BufferLength,
  1775. '@');
  1776. // ===============================================
  1777. // error checking
  1778. // ===============================================
  1779. DebugStatus = SCCMN50M_GetCommStatus(pSmartcardExtension);
  1780. pSerialStatus = (PSERIAL_STATUS) pSmartcardExtension->SmartcardReply.Buffer;
  1781. if (pSerialStatus->Errors || NT_ERROR(status)) {
  1782. pSmartcardExtension->ReaderExtension->SerialErrors = pSerialStatus->Errors;
  1783. if (!pSmartcardExtension->ReaderExtension->fTransparentMode )
  1784. DebugStatus = SCCMN50M_ResyncCardManII(pSmartcardExtension);
  1785. goto ExitSCCMN50M_WriteCardMan;
  1786. }
  1787. ExitSCCMN50M_WriteCardMan:
  1788. if (status != STATUS_SUCCESS) {
  1789. SmartcardDebug(
  1790. DEBUG_TRACE,
  1791. ( "%s!WriteCardMan: Failed, exit %lx\n",
  1792. DRIVER_NAME,status)
  1793. );
  1794. }
  1795. return status;
  1796. }
  1797. /*****************************************************************************
  1798. Routine Description:
  1799. Arguments:
  1800. Return Value:
  1801. *****************************************************************************/
  1802. NTSTATUS SCCMN50M_ResyncCardManI (IN PSMARTCARD_EXTENSION pSmartcardExtension )
  1803. {
  1804. NTSTATUS status;
  1805. // SmartcardDebug(DEBUG_TRACE,("%s!ResyncCardManI: Enter\n",DRIVER_NAME))
  1806. // clear error flags
  1807. pSmartcardExtension->ReaderExtension->SerialErrors = 0;
  1808. // clear any pending errors
  1809. status = SCCMN50M_GetCommStatus(pSmartcardExtension);
  1810. if (!NT_SUCCESS(status)) {
  1811. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_GetCommStatus failed ! status = %x\n",status))
  1812. goto ExitSCCMN50M_ResyncCardManI;
  1813. }
  1814. // clear COM buffers
  1815. status = SCCMN50M_PurgeComm(pSmartcardExtension);
  1816. if (!NT_SUCCESS(status)) {
  1817. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_PurgeComm failed ! status = %x\n",status))
  1818. goto ExitSCCMN50M_ResyncCardManI;
  1819. }
  1820. // ####################################################################
  1821. // set break
  1822. if (!pSmartcardExtension->ReaderExtension->fTransparentMode) {
  1823. status = SCCMN50M_SetBRK(pSmartcardExtension);
  1824. if (!NT_SUCCESS(status)) {
  1825. SmartcardDebug(DEBUG_ERROR,("SetBreak failed ! status = %x\n",status))
  1826. goto ExitSCCMN50M_ResyncCardManI;
  1827. }
  1828. }
  1829. // wait 1ms
  1830. Wait(pSmartcardExtension,1 * ms_);
  1831. // clear RTS
  1832. status = SCCMN50M_ClearRTS(pSmartcardExtension);
  1833. if (!NT_SUCCESS(status)) {
  1834. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_ClearRTS failed ! status = %x\n",status))
  1835. goto ExitSCCMN50M_ResyncCardManI;
  1836. }
  1837. // wait 2ms
  1838. Wait(pSmartcardExtension,2 * ms_);
  1839. // set RTS
  1840. status = SCCMN50M_SetRTS(pSmartcardExtension);
  1841. if (!NT_SUCCESS(status)) {
  1842. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_SetRTS failed ! status = %x\n",status))
  1843. goto ExitSCCMN50M_ResyncCardManI;
  1844. }
  1845. // wait 1ms
  1846. Wait(pSmartcardExtension,1 * ms_);
  1847. // clear break
  1848. if (!pSmartcardExtension->ReaderExtension->fTransparentMode) {
  1849. pSmartcardExtension->ReaderExtension->BreakSet = FALSE;
  1850. status = SCCMN50M_ClearBRK(pSmartcardExtension);
  1851. if (!NT_SUCCESS(status)) {
  1852. SmartcardDebug(DEBUG_ERROR,("ClearBreak failed ! status = %x\n",status))
  1853. goto ExitSCCMN50M_ResyncCardManI;
  1854. }
  1855. }
  1856. // ####################################################################
  1857. // next write operation must send config data
  1858. pSmartcardExtension->ReaderExtension->NoConfig = FALSE;
  1859. // clear COM buffers
  1860. status = SCCMN50M_PurgeComm(pSmartcardExtension);
  1861. if (!NT_SUCCESS(status)) {
  1862. goto ExitSCCMN50M_ResyncCardManI;
  1863. }
  1864. // clear any pending errors
  1865. status = SCCMN50M_GetCommStatus(pSmartcardExtension);
  1866. if (!NT_SUCCESS(status)) {
  1867. goto ExitSCCMN50M_ResyncCardManI;
  1868. }
  1869. ExitSCCMN50M_ResyncCardManI:
  1870. //SmartcardDebug(DEBUG_TRACE,("%s!ResyncCardManI: Exit %lx\n",DRIVER_NAME,status))
  1871. return status;
  1872. }
  1873. NTSTATUS SCCMN50M_ResyncCardManII (IN PSMARTCARD_EXTENSION pSmartcardExtension )
  1874. {
  1875. NTSTATUS status;
  1876. SmartcardDebug(
  1877. DEBUG_TRACE,
  1878. ( "%s!ResyncCardManII: Enter\n",
  1879. DRIVER_NAME)
  1880. );
  1881. // clear error flags
  1882. pSmartcardExtension->ReaderExtension->SerialErrors = 0;
  1883. // clear any pending errors
  1884. status = SCCMN50M_GetCommStatus(pSmartcardExtension);
  1885. if (!NT_SUCCESS(status)) {
  1886. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_GetCommStatus failed ! status = %x\n",status))
  1887. goto ExitSCCMN50M_ResyncCardManII;
  1888. }
  1889. // clear COM buffers
  1890. status = SCCMN50M_PurgeComm(pSmartcardExtension);
  1891. if (!NT_SUCCESS(status)) {
  1892. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_PurgeComm failed ! status = %x\n",status))
  1893. goto ExitSCCMN50M_ResyncCardManII;
  1894. }
  1895. // 150 * 0xFE
  1896. RtlFillMemory(pSmartcardExtension->SmartcardRequest.Buffer,150,0xFE);
  1897. pSmartcardExtension->SmartcardRequest.Buffer[150] = 0x00;
  1898. pSmartcardExtension->SmartcardRequest.BufferLength = 151;
  1899. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  1900. pSmartcardExtension->ReaderExtension->SerialIoControlCode = SMARTCARD_WRITE;
  1901. status = SCCMN50M_SerialIo(pSmartcardExtension);
  1902. if (!NT_SUCCESS(status)) {
  1903. Wait(pSmartcardExtension,2 * ms_);
  1904. // try resync once more
  1905. // clear error flags
  1906. pSmartcardExtension->ReaderExtension->SerialErrors = 0;
  1907. // clear any pending errors
  1908. status = SCCMN50M_GetCommStatus(pSmartcardExtension);
  1909. if (!NT_SUCCESS(status)) {
  1910. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_GetCommStatus failed ! status = %x\n",status))
  1911. goto ExitSCCMN50M_ResyncCardManII;
  1912. }
  1913. // clear COM buffers
  1914. status = SCCMN50M_PurgeComm(pSmartcardExtension);
  1915. if (!NT_SUCCESS(status)) {
  1916. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_PurgeComm failed ! status = %x\n",status))
  1917. goto ExitSCCMN50M_ResyncCardManII;
  1918. }
  1919. // 150 * 0xFE
  1920. RtlFillMemory(pSmartcardExtension->SmartcardRequest.Buffer,150,0xFE);
  1921. pSmartcardExtension->SmartcardRequest.Buffer[150] = 0x00;
  1922. pSmartcardExtension->SmartcardRequest.BufferLength = 151;
  1923. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  1924. pSmartcardExtension->ReaderExtension->SerialIoControlCode = SMARTCARD_WRITE;
  1925. status = SCCMN50M_SerialIo(pSmartcardExtension);
  1926. if (status != STATUS_SUCCESS) {
  1927. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_SerialIo failed ! status = %x\n",status))
  1928. goto ExitSCCMN50M_ResyncCardManII;
  1929. }
  1930. // normally the second resync command is always successful
  1931. }
  1932. // clear COM buffers
  1933. status = SCCMN50M_PurgeComm(pSmartcardExtension);
  1934. if (!NT_SUCCESS(status)) {
  1935. goto ExitSCCMN50M_ResyncCardManII;
  1936. }
  1937. // clear any pending errors
  1938. status = SCCMN50M_GetCommStatus(pSmartcardExtension);
  1939. if (!NT_SUCCESS(status)) {
  1940. goto ExitSCCMN50M_ResyncCardManII;
  1941. }
  1942. ExitSCCMN50M_ResyncCardManII:
  1943. SmartcardDebug(
  1944. DEBUG_TRACE,
  1945. ( "%s!ResyncCardManII: Exit %lx\n",
  1946. DRIVER_NAME,status)
  1947. );
  1948. return status;
  1949. }
  1950. /*****************************************************************************
  1951. Routine Description:
  1952. Arguments:
  1953. Return Value:
  1954. *****************************************************************************/
  1955. NTSTATUS
  1956. SCCMN50M_SerialIo(IN PSMARTCARD_EXTENSION pSmartcardExtension)
  1957. {
  1958. NTSTATUS status;
  1959. IO_STATUS_BLOCK ioStatus;
  1960. KEVENT event;
  1961. PIRP irp;
  1962. PIO_STACK_LOCATION irpNextStack;
  1963. PUCHAR pbRequestBuffer;
  1964. PUCHAR pbReplyBuffer;
  1965. ULONG ulRequestBufferLength;
  1966. ULONG ulReplyBufferLength ;
  1967. //
  1968. // Check if the buffers are large enough
  1969. //
  1970. ASSERT(pSmartcardExtension->SmartcardReply.BufferLength <=
  1971. pSmartcardExtension->SmartcardReply.BufferSize);
  1972. ASSERT(pSmartcardExtension->SmartcardRequest.BufferLength <=
  1973. pSmartcardExtension->SmartcardRequest.BufferSize);
  1974. if (pSmartcardExtension->SmartcardReply.BufferLength >
  1975. pSmartcardExtension->SmartcardReply.BufferSize ||
  1976. pSmartcardExtension->SmartcardRequest.BufferLength >
  1977. pSmartcardExtension->SmartcardRequest.BufferSize) {
  1978. SmartcardLogError(pSmartcardExtension->OsData->DeviceObject,
  1979. SCCMN50M_BUFFER_TOO_SMALL,
  1980. NULL,
  1981. 0);
  1982. return STATUS_BUFFER_TOO_SMALL;
  1983. }
  1984. // set pointer and length of request and reply buffer
  1985. ulRequestBufferLength = pSmartcardExtension->SmartcardRequest.BufferLength;
  1986. pbRequestBuffer = (ulRequestBufferLength ? pSmartcardExtension->SmartcardRequest.Buffer : NULL);
  1987. pbReplyBuffer = pSmartcardExtension->SmartcardReply.Buffer;
  1988. ulReplyBufferLength = pSmartcardExtension->SmartcardReply.BufferLength;
  1989. KeInitializeEvent(&event,
  1990. NotificationEvent,
  1991. FALSE);
  1992. //
  1993. // Build irp to be sent to serial driver
  1994. //
  1995. irp = IoBuildDeviceIoControlRequest(pSmartcardExtension->ReaderExtension->SerialIoControlCode,
  1996. pSmartcardExtension->ReaderExtension->AttachedDeviceObject,
  1997. pbRequestBuffer,
  1998. ulRequestBufferLength,
  1999. pbReplyBuffer,
  2000. ulReplyBufferLength,
  2001. FALSE,
  2002. &event,
  2003. &ioStatus);
  2004. ASSERT(irp != NULL);
  2005. if (irp == NULL) {
  2006. return STATUS_INSUFFICIENT_RESOURCES;
  2007. }
  2008. irpNextStack = IoGetNextIrpStackLocation(irp);
  2009. switch (pSmartcardExtension->ReaderExtension->SerialIoControlCode) {
  2010. //
  2011. // The serial driver transfers data from/to irp->AssociatedIrp.SystemBuffer
  2012. //
  2013. case SMARTCARD_WRITE:
  2014. irpNextStack->MajorFunction = IRP_MJ_WRITE;
  2015. irpNextStack->Parameters.Write.Length = pSmartcardExtension->SmartcardRequest.BufferLength;
  2016. break;
  2017. case SMARTCARD_READ:
  2018. irpNextStack->MajorFunction = IRP_MJ_READ;
  2019. irpNextStack->Parameters.Read.Length = pSmartcardExtension->SmartcardReply.BufferLength;
  2020. break;
  2021. }
  2022. status = IoCallDriver(pSmartcardExtension->ReaderExtension->AttachedDeviceObject,irp);
  2023. if (status == STATUS_PENDING) {
  2024. KeWaitForSingleObject(&event,
  2025. Suspended,
  2026. KernelMode,
  2027. FALSE,
  2028. NULL);
  2029. status = ioStatus.Status;
  2030. }
  2031. switch (pSmartcardExtension->ReaderExtension->SerialIoControlCode) {
  2032. case SMARTCARD_READ:
  2033. if (status == STATUS_TIMEOUT) {
  2034. SmartcardDebug(DEBUG_ERROR,
  2035. ("%s!Timeout while reading from CardMan\n",
  2036. DRIVER_NAME));
  2037. //
  2038. // STATUS_TIMEOUT isn't correctly mapped
  2039. // to a WIN32 error, that's why we change it here
  2040. // to STATUS_IO_TIMEOUT
  2041. //
  2042. status = STATUS_IO_TIMEOUT;
  2043. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  2044. }
  2045. break;
  2046. }
  2047. #if 0
  2048. if (status != STATUS_SUCCESS) {
  2049. SmartcardDebug(DEBUG_DRIVER,
  2050. ("%s!SerialIo = %lx\n",
  2051. DRIVER_NAME,
  2052. status));
  2053. }
  2054. #endif
  2055. return status;
  2056. }
  2057. /*****************************************************************************
  2058. Routine Description:
  2059. Arguments:
  2060. Return Value:
  2061. *****************************************************************************/
  2062. NTSTATUS
  2063. SCCMN50M_ReadCardMan (
  2064. IN PSMARTCARD_EXTENSION pSmartcardExtension,
  2065. IN ULONG BytesToRead,
  2066. OUT PULONG pBytesRead,
  2067. IN PUCHAR pReadBuffer,
  2068. IN ULONG ReadBufferSize
  2069. )
  2070. {
  2071. NTSTATUS status;
  2072. NTSTATUS DebugStatus;
  2073. BOOLEAN fRc;
  2074. // check if read buffer is large enough
  2075. ASSERT(BytesToRead <= ReadBufferSize);
  2076. *pBytesRead = 0; // default setting
  2077. DebugStatus = SCCMN50M_SetRead(pSmartcardExtension,BytesToRead);
  2078. //
  2079. // read operation
  2080. //
  2081. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2082. if (status == STATUS_SUCCESS) {
  2083. *pBytesRead = pSmartcardExtension->SmartcardReply.BufferLength;
  2084. MemCpy(pReadBuffer,
  2085. ReadBufferSize,
  2086. pSmartcardExtension->SmartcardReply.Buffer,
  2087. pSmartcardExtension->SmartcardReply.BufferLength);
  2088. // overwrite read buffer with '@'
  2089. MemSet(pSmartcardExtension->SmartcardReply.Buffer,
  2090. pSmartcardExtension->SmartcardReply.BufferSize,
  2091. '@',
  2092. pSmartcardExtension->SmartcardReply.BufferLength);
  2093. }
  2094. if (status != STATUS_SUCCESS || SCCMN50M_IOOperationFailed(pSmartcardExtension)) {
  2095. if (!pSmartcardExtension->ReaderExtension->fTransparentMode) {
  2096. DebugStatus = SCCMN50M_ResyncCardManII(pSmartcardExtension);
  2097. }
  2098. goto ExitSCCMN50M_ReadCardMan;
  2099. }
  2100. // *****************************************
  2101. // set CardManII to state RH Config
  2102. // *****************************************
  2103. // don't set CardMan to RH config if there are still bytes to be read
  2104. if (pSmartcardExtension->ReaderExtension->ToRHConfig == TRUE) {
  2105. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  2106. pSmartcardExtension->SmartcardRequest.Buffer [0] = 0x00;
  2107. pSmartcardExtension->SmartcardRequest.Buffer [1] = 0x00;
  2108. pSmartcardExtension->SmartcardRequest.Buffer [2] = 0x00;
  2109. pSmartcardExtension->SmartcardRequest.Buffer [3] = 0x00;
  2110. pSmartcardExtension->SmartcardRequest.Buffer [4] = 0x89;
  2111. pSmartcardExtension->SmartcardRequest.BufferLength = 5;
  2112. pSmartcardExtension->ReaderExtension->SerialIoControlCode = SMARTCARD_WRITE;
  2113. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2114. if (status != STATUS_SUCCESS || SCCMN50M_IOOperationFailed(pSmartcardExtension)) {
  2115. DebugStatus = SCCMN50M_ResyncCardManII(pSmartcardExtension);
  2116. goto ExitSCCMN50M_ReadCardMan;
  2117. }
  2118. }
  2119. ExitSCCMN50M_ReadCardMan:
  2120. // set default value;
  2121. pSmartcardExtension->ReaderExtension->ToRHConfig = TRUE;
  2122. if (status != STATUS_SUCCESS) {
  2123. SmartcardDebug(
  2124. DEBUG_TRACE,
  2125. ( "%s!ReadCardMan: Failed, exit %lx\n",
  2126. DRIVER_NAME,status)
  2127. );
  2128. }
  2129. return status;
  2130. }
  2131. /*****************************************************************************
  2132. Routine Description:
  2133. Arguments:
  2134. Return Value:
  2135. *****************************************************************************/
  2136. NTSTATUS
  2137. SCCMN50M_GetCommStatus (
  2138. IN PSMARTCARD_EXTENSION SmartcardExtension
  2139. )
  2140. {
  2141. PSERIAL_READER_CONFIG configData = &SmartcardExtension->ReaderExtension->SerialConfigData;
  2142. NTSTATUS status;
  2143. PUCHAR request = SmartcardExtension->SmartcardRequest.Buffer;
  2144. SmartcardExtension->SmartcardReply.BufferLength = SmartcardExtension->SmartcardReply.BufferSize;
  2145. SmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_GET_COMMSTATUS;
  2146. SmartcardExtension->SmartcardRequest.Buffer = (PUCHAR) &configData->SerialStatus;
  2147. SmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_STATUS);
  2148. status = SCCMN50M_SerialIo(SmartcardExtension);
  2149. //
  2150. // restore pointer to original request buffer
  2151. //
  2152. SmartcardExtension->SmartcardRequest.Buffer = request;
  2153. return status;
  2154. }
  2155. /*****************************************************************************
  2156. Routine Description:
  2157. Arguments:
  2158. Return Value:
  2159. *****************************************************************************/
  2160. BOOLEAN
  2161. SCCMN50M_IOOperationFailed(PSMARTCARD_EXTENSION pSmartcardExtension)
  2162. {
  2163. NTSTATUS DebugStatus;
  2164. PSERIAL_STATUS pSerialStatus;
  2165. DebugStatus = SCCMN50M_GetCommStatus(pSmartcardExtension);
  2166. pSerialStatus = (PSERIAL_STATUS)pSmartcardExtension->SmartcardReply.Buffer;
  2167. if (pSerialStatus->Errors)
  2168. return TRUE;
  2169. else
  2170. return FALSE;
  2171. }
  2172. /*****************************************************************************
  2173. Routine Description:
  2174. Arguments:
  2175. Return Value:
  2176. *****************************************************************************/
  2177. NTSTATUS SCCMN50M_PurgeComm (IN PSMARTCARD_EXTENSION pSmartcardExtension )
  2178. {
  2179. PSERIAL_READER_CONFIG configData = &pSmartcardExtension->ReaderExtension->SerialConfigData;
  2180. NTSTATUS status;
  2181. PUCHAR request = pSmartcardExtension->SmartcardRequest.Buffer;
  2182. pSmartcardExtension->SmartcardReply.BufferLength = pSmartcardExtension->SmartcardReply.BufferSize;
  2183. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_PURGE;
  2184. pSmartcardExtension->SmartcardRequest.Buffer = (PUCHAR) &configData->PurgeMask;
  2185. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(ULONG);
  2186. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2187. //
  2188. // restore pointer to original request buffer
  2189. //
  2190. pSmartcardExtension->SmartcardRequest.Buffer = request;
  2191. // under W2000 & CardMan P+ STATUS_CANCELLED may be returned
  2192. if (status == STATUS_CANCELLED)
  2193. status = STATUS_SUCCESS;
  2194. return status;
  2195. }
  2196. /*****************************************************************************
  2197. Routine Description:
  2198. Arguments:
  2199. Return Value:
  2200. *****************************************************************************/
  2201. NTSTATUS
  2202. SCCMN50M_SetRead(IN PSMARTCARD_EXTENSION pSmartcardExtension,
  2203. IN ULONG ulBytesToRead
  2204. )
  2205. {
  2206. pSmartcardExtension->ReaderExtension->SerialIoControlCode = SMARTCARD_READ;
  2207. pSmartcardExtension->SmartcardRequest.BufferLength = 0;
  2208. pSmartcardExtension->SmartcardReply.BufferLength = ulBytesToRead;
  2209. return STATUS_SUCCESS;
  2210. }
  2211. /*****************************************************************************
  2212. Routine Description:
  2213. Arguments:
  2214. Return Value:
  2215. *****************************************************************************/
  2216. NTSTATUS
  2217. SCCMN50M_SetWrite(IN PSMARTCARD_EXTENSION pSmartcardExtension,
  2218. IN ULONG BytesToWrite,
  2219. IN PUCHAR WriteBuffer
  2220. )
  2221. {
  2222. ULONG Offset = 0;
  2223. pSmartcardExtension->ReaderExtension->SerialIoControlCode = SMARTCARD_WRITE;
  2224. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  2225. if (pSmartcardExtension->ReaderExtension->fTransparentMode == FALSE) {
  2226. // send always config string for CardManII, expect we set it manualy
  2227. // to NoConfig = TRUE. (note: only one time)
  2228. if (pSmartcardExtension->ReaderExtension->NoConfig == FALSE) {
  2229. MemCpy(pSmartcardExtension->SmartcardRequest.Buffer,
  2230. pSmartcardExtension->SmartcardRequest.BufferSize,
  2231. (PUCHAR)&pSmartcardExtension->ReaderExtension->CardManConfig,
  2232. sizeof(CARDMAN_CONFIG));
  2233. Offset = 4;
  2234. } else {
  2235. pSmartcardExtension->ReaderExtension->NoConfig = FALSE;
  2236. }
  2237. MemCpy(pSmartcardExtension->SmartcardRequest.Buffer + Offset,
  2238. pSmartcardExtension->SmartcardRequest.BufferSize - Offset,
  2239. (PUCHAR)&pSmartcardExtension->ReaderExtension->CardManHeader,
  2240. sizeof(CARDMAN_HEADER));
  2241. Offset+=4;
  2242. }
  2243. if (BytesToWrite != 0) {
  2244. MemCpy(pSmartcardExtension->SmartcardRequest.Buffer + Offset,
  2245. pSmartcardExtension->SmartcardRequest.BufferSize - Offset,
  2246. WriteBuffer,
  2247. BytesToWrite);
  2248. }
  2249. pSmartcardExtension->SmartcardRequest.BufferLength = Offset + BytesToWrite;
  2250. return STATUS_SUCCESS;
  2251. }
  2252. /*****************************************************************************
  2253. Routine Description:
  2254. Arguments:
  2255. Return Value:
  2256. *****************************************************************************/
  2257. NTSTATUS
  2258. SCCMN50M_StartCardTracking(
  2259. PDEVICE_EXTENSION pDeviceExtension
  2260. )
  2261. {
  2262. NTSTATUS status;
  2263. HANDLE hThread;
  2264. PSMARTCARD_EXTENSION pSmartcardExtension = &pDeviceExtension->SmartcardExtension;
  2265. SmartcardDebug(DEBUG_TRACE,
  2266. ("%s!StartCardTracking: Enter\n",DRIVER_NAME));
  2267. KeWaitForSingleObject(&pSmartcardExtension->ReaderExtension->CardManIOMutex,
  2268. Executive,
  2269. KernelMode,
  2270. FALSE,
  2271. NULL);
  2272. if (pSmartcardExtension->ReaderExtension->ThreadObjectPointer == NULL) {
  2273. // create thread for updating current state
  2274. status = PsCreateSystemThread(&hThread,
  2275. THREAD_ALL_ACCESS,
  2276. NULL,
  2277. NULL,
  2278. NULL,
  2279. SCCMN50M_UpdateCurrentStateThread,
  2280. pDeviceExtension);
  2281. if (!NT_ERROR(status)) {
  2282. //
  2283. // We've got the thread. Now get a pointer to it.
  2284. //
  2285. status = ObReferenceObjectByHandle(hThread,
  2286. THREAD_ALL_ACCESS,
  2287. NULL,
  2288. KernelMode,
  2289. &pSmartcardExtension->ReaderExtension->ThreadObjectPointer,
  2290. NULL);
  2291. if (NT_ERROR(status)) {
  2292. pSmartcardExtension->ReaderExtension->TimeToTerminateThread = TRUE;
  2293. } else {
  2294. //
  2295. // Now that we have a reference to the thread
  2296. // we can simply close the handle.
  2297. //
  2298. ZwClose(hThread);
  2299. }
  2300. } else {
  2301. }
  2302. }
  2303. // Release the mutex
  2304. KeReleaseMutex(&pSmartcardExtension->ReaderExtension->CardManIOMutex,
  2305. FALSE);
  2306. SmartcardDebug(DEBUG_TRACE,
  2307. ("%s!StartCardTracking: Exit %lx\n",DRIVER_NAME,status));
  2308. return status;
  2309. }
  2310. /*****************************************************************************
  2311. Routine Description:
  2312. Arguments:
  2313. Return Value:
  2314. *****************************************************************************/
  2315. NTSTATUS
  2316. SCCMN50M_InitCommPort (PSMARTCARD_EXTENSION pSmartcardExtension)
  2317. {
  2318. NTSTATUS status;
  2319. SmartcardDebug(
  2320. DEBUG_TRACE,
  2321. ( "%s!InitCommPort: Enter\n",
  2322. DRIVER_NAME)
  2323. );
  2324. // ===============================
  2325. // clear any pending errors
  2326. // ===============================
  2327. status = SCCMN50M_GetCommStatus(pSmartcardExtension);
  2328. if (!NT_SUCCESS(status)) {
  2329. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_GetCommStatus failed ! status = %ld\n",status))
  2330. goto ExitInitCommPort;
  2331. }
  2332. // ==============================
  2333. // set baudrate for CardMan
  2334. // ==============================
  2335. pSmartcardExtension->ReaderExtension->SerialConfigData.BaudRate.BaudRate = 38400;
  2336. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_BAUD_RATE;
  2337. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  2338. &pSmartcardExtension->ReaderExtension->SerialConfigData.BaudRate.BaudRate,
  2339. sizeof(SERIAL_BAUD_RATE));
  2340. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_BAUD_RATE);
  2341. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  2342. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2343. if (!NT_SUCCESS(status)) {
  2344. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_BAUDRATE failed ! status = %ld\n",status))
  2345. goto ExitInitCommPort;
  2346. }
  2347. // ===============================
  2348. // set comm timeouts
  2349. // ===============================
  2350. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout = DEFAULT_READ_INTERVAL_TIMEOUT;
  2351. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant = DEFAULT_READ_TOTAL_TIMEOUT_CONSTANT;
  2352. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier = DEFAULT_READ_TOTAL_TIMEOUT_MULTIPLIER;
  2353. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.WriteTotalTimeoutConstant = DEFAULT_WRITE_TOTAL_TIMEOUT_CONSTANT;
  2354. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.WriteTotalTimeoutMultiplier = DEFAULT_WRITE_TOTAL_TIMEOUT_MULTIPLIER;
  2355. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_TIMEOUTS;
  2356. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  2357. &pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts,
  2358. sizeof(SERIAL_TIMEOUTS));
  2359. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_TIMEOUTS);
  2360. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  2361. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2362. if (!NT_SUCCESS(status)) {
  2363. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_TIMEOUTS failed ! status = %x\n",status))
  2364. goto ExitInitCommPort;
  2365. }
  2366. // ===============================
  2367. // set line control
  2368. // ===============================
  2369. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.StopBits = STOP_BITS_2;
  2370. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.Parity = EVEN_PARITY;
  2371. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.WordLength = 8;
  2372. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_LINE_CONTROL;
  2373. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  2374. &pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl,
  2375. sizeof(SERIAL_LINE_CONTROL));
  2376. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_LINE_CONTROL);
  2377. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  2378. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2379. if (!NT_SUCCESS(status)) {
  2380. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_LINE_CONTROL failed ! status = %x\n",status))
  2381. goto ExitInitCommPort;
  2382. }
  2383. // ===============================
  2384. // Set handflow
  2385. // ===============================
  2386. pSmartcardExtension->ReaderExtension->SerialConfigData.HandFlow.XonLimit = 0;
  2387. pSmartcardExtension->ReaderExtension->SerialConfigData.HandFlow.XoffLimit = 0;
  2388. pSmartcardExtension->ReaderExtension->SerialConfigData.HandFlow.FlowReplace = 0;
  2389. pSmartcardExtension->ReaderExtension->SerialConfigData.HandFlow.ControlHandShake = SERIAL_ERROR_ABORT | SERIAL_DTR_CONTROL;
  2390. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_HANDFLOW;
  2391. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  2392. &pSmartcardExtension->ReaderExtension->SerialConfigData.HandFlow,
  2393. sizeof(SERIAL_HANDFLOW));
  2394. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_HANDFLOW);
  2395. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  2396. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2397. if (!NT_SUCCESS(status)) {
  2398. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_HANDFLOW failed ! status = %x\n",status))
  2399. goto ExitInitCommPort;
  2400. }
  2401. // ===============================
  2402. // set purge mask
  2403. // ===============================
  2404. pSmartcardExtension->ReaderExtension->SerialConfigData.PurgeMask =
  2405. SERIAL_PURGE_TXABORT | SERIAL_PURGE_RXABORT |
  2406. SERIAL_PURGE_TXCLEAR | SERIAL_PURGE_RXCLEAR;
  2407. // ===============================
  2408. // set DTR
  2409. // ===============================
  2410. status = SCCMN50M_SetDTR(pSmartcardExtension);
  2411. if (!NT_SUCCESS(status)) {
  2412. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_DRT failed ! status = %x\n",status))
  2413. goto ExitInitCommPort;
  2414. }
  2415. // ===============================
  2416. // set RTS
  2417. // ===============================
  2418. status = SCCMN50M_SetRTS(pSmartcardExtension);
  2419. if (!NT_SUCCESS(status)) {
  2420. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_RTS failed ! status = %x\n",status))
  2421. goto ExitInitCommPort;
  2422. }
  2423. ExitInitCommPort:
  2424. SmartcardDebug(
  2425. DEBUG_TRACE,
  2426. ( "%s!InitCommPort: Exit %lx\n",
  2427. DRIVER_NAME,status)
  2428. );
  2429. return status;
  2430. }
  2431. /*****************************************************************************
  2432. Routine Description:
  2433. Arguments:
  2434. Return Value:
  2435. *****************************************************************************/
  2436. NTSTATUS
  2437. SCCMN50M_SetDTR(IN PSMARTCARD_EXTENSION pSmartcardExtension )
  2438. {
  2439. NTSTATUS status;
  2440. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  2441. pSmartcardExtension->SmartcardRequest.BufferLength = 0;
  2442. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_DTR;
  2443. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2444. // under W2000 & CardMan P+ STATUS_CANCELLED may be returned
  2445. if (status == STATUS_CANCELLED)
  2446. status = STATUS_SUCCESS;
  2447. return status;
  2448. }
  2449. /*****************************************************************************
  2450. Routine Description:
  2451. Arguments:
  2452. Return Value:
  2453. *****************************************************************************/
  2454. NTSTATUS
  2455. SCCMN50M_SetRTS(IN PSMARTCARD_EXTENSION pSmartcardExtension )
  2456. {
  2457. NTSTATUS status;
  2458. pSmartcardExtension->SmartcardReply.BufferLength = pSmartcardExtension->SmartcardReply.BufferSize;
  2459. pSmartcardExtension->SmartcardRequest.BufferLength = 0;
  2460. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_RTS;
  2461. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2462. // under W2000 & CardMan P+ STATUS_CANCELLED may be returned
  2463. if (status == STATUS_CANCELLED)
  2464. status = STATUS_SUCCESS;
  2465. return status;
  2466. }
  2467. /*****************************************************************************
  2468. Routine Description:
  2469. Arguments:
  2470. Return Value:
  2471. *****************************************************************************/
  2472. NTSTATUS
  2473. SCCMN50M_InitializeCardMan(IN PSMARTCARD_EXTENSION pSmartcardExtension)
  2474. {
  2475. NTSTATUS status;
  2476. UCHAR pReadBuffer[2];
  2477. ULONG ulBytesRead;
  2478. BOOLEAN fCardManFound = FALSE;
  2479. PREADER_EXTENSION readerExtension = pSmartcardExtension->ReaderExtension;
  2480. ULONG ulRetries;
  2481. SmartcardDebug(
  2482. DEBUG_TRACE,
  2483. ( "%s!InitializeCardMan: Enter\n",
  2484. DRIVER_NAME)
  2485. );
  2486. pSmartcardExtension->ReaderExtension->ulOldCardState = UNKNOWN;
  2487. // ==============================================
  2488. // CardManII
  2489. // ==============================================
  2490. pSmartcardExtension->ReaderExtension->NoConfig = FALSE;
  2491. pSmartcardExtension->ReaderExtension->ToRHConfig = TRUE;
  2492. // This waiting time if necessary for CardMan Power+, because
  2493. // the pnP string may be dumped
  2494. Wait(pSmartcardExtension,200);
  2495. status = SCCMN50M_InitCommPort(pSmartcardExtension);
  2496. if (status != STATUS_SUCCESS)
  2497. goto ExitInitializeCardMan;
  2498. //
  2499. // init CommPort was O.K.
  2500. // now try to find a reader
  2501. //
  2502. // To be sure wait make an additional wait
  2503. Wait(pSmartcardExtension,100);
  2504. status = SCCMN50M_ResyncCardManII(pSmartcardExtension);
  2505. status = SCCMN50M_ResyncCardManII(pSmartcardExtension);
  2506. // no data except config + header
  2507. pSmartcardExtension->ReaderExtension->CardManConfig.SCRControl = XMIT_HANDSHAKE_OFF;
  2508. pSmartcardExtension->ReaderExtension->CardManConfig.CardControl = 0x00;
  2509. pSmartcardExtension->ReaderExtension->CardManConfig.CardStopBits = 0x00;
  2510. pSmartcardExtension->ReaderExtension->CardManConfig.ResetDelay = 0x00;
  2511. pSmartcardExtension->ReaderExtension->CardManHeader.TxControl = 0x00;
  2512. pSmartcardExtension->ReaderExtension->CardManHeader.TxLength = 0x00;
  2513. pSmartcardExtension->ReaderExtension->CardManHeader.RxControl = 0x00;
  2514. pSmartcardExtension->ReaderExtension->CardManHeader.RxLength = 0x00;
  2515. status = SCCMN50M_WriteCardMan(pSmartcardExtension,0,NULL);
  2516. if (status == STATUS_SUCCESS) {
  2517. status = SCCMN50M_ReadCardMan(pSmartcardExtension,2,&ulBytesRead,pReadBuffer,sizeof(pReadBuffer));
  2518. if (status == STATUS_SUCCESS &&
  2519. ulBytesRead == 0x02 && // two bytes received
  2520. pReadBuffer[0] >= 0x40 && // at least one version bit must be set
  2521. pReadBuffer[1] == 0x00 &&
  2522. ((pReadBuffer[0] & 0x09) == 0) ) { // bit 0 and 3 must be cleared
  2523. pSmartcardExtension->ReaderExtension->ulFWVersion = (pReadBuffer[0] >> 4) * 30 + 120;
  2524. pSmartcardExtension->ReaderExtension->fSPESupported = FALSE;
  2525. SmartcardDebug(
  2526. DEBUG_DRIVER,
  2527. ( "%s!CardMan (FW %ld) found\n",
  2528. DRIVER_NAME,pSmartcardExtension->ReaderExtension->ulFWVersion)
  2529. );
  2530. fCardManFound = TRUE;
  2531. }
  2532. }
  2533. ExitInitializeCardMan:
  2534. if (fCardManFound == TRUE)
  2535. status = STATUS_SUCCESS;
  2536. else
  2537. status = STATUS_UNSUCCESSFUL;
  2538. SmartcardDebug(
  2539. DEBUG_TRACE,
  2540. ( "%s!InitializeCardMan: Exit %lx\n",
  2541. DRIVER_NAME,status)
  2542. );
  2543. return status;
  2544. }
  2545. /*****************************************************************************
  2546. Routine Description:
  2547. Arguments:
  2548. Return Value:
  2549. *****************************************************************************/
  2550. NTSTATUS
  2551. SCCMN50M_EnterTransparentMode (IN PSMARTCARD_EXTENSION pSmartcardExtension)
  2552. {
  2553. NTSTATUS status;
  2554. SmartcardDebug(DEBUG_TRACE,("EnterTransparentMode : enter\n"));
  2555. // Step 1 : Resync CardMan by RTS usage
  2556. status = SCCMN50M_ResyncCardManI(pSmartcardExtension);
  2557. if (status != STATUS_SUCCESS) {
  2558. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_ResyncCardManI failed ! status = %ld\n",status))
  2559. goto ExitEnterTransparentMode;
  2560. }
  2561. // Step 2 : set baud rate to 9600
  2562. pSmartcardExtension->ReaderExtension->SerialConfigData.BaudRate.BaudRate = 9600;
  2563. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_BAUD_RATE;
  2564. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  2565. &pSmartcardExtension->ReaderExtension->SerialConfigData.BaudRate.BaudRate,
  2566. sizeof(SERIAL_BAUD_RATE));
  2567. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_BAUD_RATE);
  2568. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  2569. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2570. if (!NT_SUCCESS(status)) {
  2571. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_BAUDRATE failed ! status = %ld\n",status))
  2572. goto ExitEnterTransparentMode;
  2573. }
  2574. ExitEnterTransparentMode:
  2575. // Step 3 : set ATR and DUMP_BUFFER flags
  2576. // During normal operation these two flags can never be set at the same time
  2577. SCCMN50M_SetSCRControlFlags(pSmartcardExtension,CM2_GET_ATR | TO_STATE_XH);
  2578. SmartcardDebug(DEBUG_TRACE,("EnterTransparentMode : exit\n"));
  2579. return status;
  2580. }
  2581. /*****************************************************************************
  2582. Routine Description:
  2583. Arguments:
  2584. Return Value:
  2585. *****************************************************************************/
  2586. NTSTATUS
  2587. SCCMN50M_ExitTransparentMode (IN PSMARTCARD_EXTENSION pSmartcardExtension)
  2588. {
  2589. NTSTATUS status;
  2590. SmartcardDebug(DEBUG_TRACE,("ExitTransparentMode : enter\n"));
  2591. // ===============================
  2592. // clear any pending errors
  2593. // ===============================
  2594. status = SCCMN50M_GetCommStatus(pSmartcardExtension);
  2595. if (!NT_SUCCESS(status)) {
  2596. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_GetCommStatus failed ! status = %ld\n",status))
  2597. goto ExitExitTransparentMode;
  2598. }
  2599. // Step 1 : Resync CardMan by RTS usage
  2600. status = SCCMN50M_ResyncCardManI(pSmartcardExtension);
  2601. if (status != STATUS_SUCCESS) {
  2602. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_ResyncCardManI failed ! status = %ld\n",status))
  2603. goto ExitExitTransparentMode;
  2604. }
  2605. // Step 2 : set baud rate to 38400
  2606. pSmartcardExtension->ReaderExtension->SerialConfigData.BaudRate.BaudRate = 38400;
  2607. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_BAUD_RATE;
  2608. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  2609. &pSmartcardExtension->ReaderExtension->SerialConfigData.BaudRate.BaudRate,
  2610. sizeof(SERIAL_BAUD_RATE));
  2611. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_BAUD_RATE);
  2612. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  2613. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2614. if (!NT_SUCCESS(status)) {
  2615. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_BAUDRATE failed ! status = %ld\n",status))
  2616. goto ExitExitTransparentMode;
  2617. }
  2618. // if the inserted card uses inverse convention , we must now switch the COM port
  2619. // back to even parity
  2620. if (pSmartcardExtension->ReaderExtension->fInverseAtr == TRUE) {
  2621. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.StopBits = STOP_BITS_2;
  2622. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.Parity = EVEN_PARITY;
  2623. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.WordLength = SERIAL_DATABITS_8;
  2624. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_LINE_CONTROL;
  2625. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  2626. &pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl,
  2627. sizeof(SERIAL_LINE_CONTROL));
  2628. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_LINE_CONTROL);
  2629. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  2630. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2631. if (!NT_SUCCESS(status)) {
  2632. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_LINE_CONTROL failed ! status = %x\n",status))
  2633. goto ExitExitTransparentMode;
  2634. }
  2635. }
  2636. ExitExitTransparentMode:
  2637. // Step 3 : set ATR and DUMP_BUFFER flags
  2638. // During normal operation these two flags can never be set at the same time
  2639. SCCMN50M_ClearSCRControlFlags(pSmartcardExtension,CM2_GET_ATR | TO_STATE_XH);
  2640. status = SCCMN50M_ResyncCardManII(pSmartcardExtension);
  2641. if (!NT_SUCCESS(status)) {
  2642. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_ResyncCardManII failed ! status = %x\n",status))
  2643. goto ExitExitTransparentMode;
  2644. }
  2645. SmartcardDebug(DEBUG_TRACE,("ExitTransparentMode : exit\n"));
  2646. return status;
  2647. }
  2648. /*****************************************************************************
  2649. Routine Description:
  2650. Arguments:
  2651. Return Value:
  2652. *****************************************************************************/
  2653. NTSTATUS
  2654. SCCMN50M_ClearRTS(IN PSMARTCARD_EXTENSION SmartcardExtension )
  2655. {
  2656. NTSTATUS status;
  2657. SmartcardExtension->SmartcardReply.BufferLength = SmartcardExtension->SmartcardReply.BufferSize;
  2658. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  2659. SmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_CLR_RTS;
  2660. status = SCCMN50M_SerialIo(SmartcardExtension);
  2661. return status;
  2662. }
  2663. /*****************************************************************************
  2664. Routine Description:
  2665. Arguments:
  2666. Return Value:
  2667. *****************************************************************************/
  2668. NTSTATUS
  2669. SCCMN50M_IoCtlVendor(PSMARTCARD_EXTENSION pSmartcardExtension)
  2670. {
  2671. NTSTATUS status = STATUS_SUCCESS;
  2672. NTSTATUS DebugStatus;
  2673. UCHAR pbAttrBuffer[MAXIMUM_ATR_LENGTH];
  2674. ULONG ulAtrLength;
  2675. SmartcardDebug(
  2676. DEBUG_TRACE,
  2677. ( "%s!IoCtlVendor : Enter\n",
  2678. DRIVER_NAME)
  2679. );
  2680. switch (pSmartcardExtension->MajorIoControlCode) {
  2681. case CM_IOCTL_SET_READER_9600_BAUD:
  2682. status = SCCMN50M_SetFl_1Dl_1(pSmartcardExtension);
  2683. break;
  2684. case CM_IOCTL_SET_READER_38400_BAUD:
  2685. status = SCCMN50M_SetFl_1Dl_3(pSmartcardExtension);
  2686. break;
  2687. case CM_IOCTL_CR80S_SAMOS_SET_HIGH_SPEED:
  2688. status = SCCMN50M_SetHighSpeed_CR80S_SAMOS(pSmartcardExtension);
  2689. break;
  2690. case CM_IOCTL_GET_FW_VERSION:
  2691. status = SCCMN50M_GetFWVersion(pSmartcardExtension);
  2692. break;
  2693. case CM_IOCTL_READ_DEVICE_DESCRIPTION:
  2694. status = SCCMN50M_ReadDeviceDescription(pSmartcardExtension);
  2695. break;
  2696. case CM_IOCTL_SET_SYNC_PARAMETERS :
  2697. status = SCCMN50M_SetSyncParameters(pSmartcardExtension);
  2698. break;
  2699. case CM_IOCTL_3WBP_TRANSFER : // for SLE4428
  2700. status = SCCMN50M_Transmit3WBP(pSmartcardExtension);
  2701. break;
  2702. case CM_IOCTL_2WBP_TRANSFER : // for SLE4442
  2703. status = SCCMN50M_Transmit2WBP(pSmartcardExtension);
  2704. break;
  2705. case CM_IOCTL_2WBP_RESET_CARD: // SLE4442 Reset Card
  2706. status = SCCMN50M_ResetCard2WBP(pSmartcardExtension);
  2707. break;
  2708. case CM_IOCTL_SYNC_CARD_POWERON:
  2709. status = SCCMN50M_SyncCardPowerOn(pSmartcardExtension);
  2710. break;
  2711. default:
  2712. status = STATUS_INVALID_DEVICE_REQUEST;
  2713. break;
  2714. }
  2715. SmartcardDebug(
  2716. DEBUG_TRACE,
  2717. ( "%s!IoCtlVendor : Exit %lx\n",
  2718. DRIVER_NAME,status)
  2719. );
  2720. return status;
  2721. }
  2722. /*****************************************************************************
  2723. Routine Description:
  2724. Arguments:
  2725. Return Value:
  2726. *****************************************************************************/
  2727. NTSTATUS
  2728. SCCMN50M_SetFl_1Dl_3(IN PSMARTCARD_EXTENSION pSmartcardExtension )
  2729. {
  2730. NTSTATUS status = STATUS_SUCCESS;
  2731. NTSTATUS DebugStatus;
  2732. SmartcardDebug(DEBUG_TRACE,
  2733. ("%s!SetFl_1Dl_3 Enter\n",
  2734. DRIVER_NAME));
  2735. // check if T=1 active
  2736. if (pSmartcardExtension->CardCapabilities.Protocol.Selected !=
  2737. SCARD_PROTOCOL_T1) {
  2738. status = STATUS_CTL_FILE_NOT_SUPPORTED;
  2739. goto ExitSetFl_1Dl_3;
  2740. }
  2741. // Fl=1
  2742. // Dl=3
  2743. // => 38400 Baud for 3.72 MHz
  2744. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ENABLE_3MHZ | ENABLE_5MHZ |
  2745. ENABLE_3MHZ_FAST | ENABLE_5MHZ_FAST );
  2746. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_3MHZ_FAST);
  2747. ExitSetFl_1Dl_3:
  2748. *pSmartcardExtension->IoRequest.Information = 0L;
  2749. SmartcardDebug(DEBUG_TRACE,
  2750. ("%s!SetFl_1Dl_3 Exit\n",
  2751. DRIVER_NAME));
  2752. return status;
  2753. }
  2754. /*****************************************************************************
  2755. Routine Description:
  2756. Arguments:
  2757. Return Value:
  2758. *****************************************************************************/
  2759. NTSTATUS
  2760. SCCMN50M_SetFl_1Dl_1(IN PSMARTCARD_EXTENSION pSmartcardExtension )
  2761. {
  2762. NTSTATUS status = STATUS_SUCCESS;
  2763. SmartcardDebug(DEBUG_TRACE,
  2764. ("%s!SetFl_1Dl_1 Enter\n",
  2765. DRIVER_NAME));
  2766. // Fl=1
  2767. // Dl=1
  2768. // => 9600 for 3.72 MHz
  2769. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ENABLE_3MHZ | ENABLE_5MHZ |
  2770. ENABLE_3MHZ_FAST | ENABLE_5MHZ_FAST );
  2771. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_3MHZ);
  2772. *pSmartcardExtension->IoRequest.Information = 0L;
  2773. SmartcardDebug(DEBUG_TRACE,
  2774. ("%s!SetFl_1Dl_1 Exit\n",
  2775. DRIVER_NAME));
  2776. return status;
  2777. }
  2778. /*****************************************************************************
  2779. Routine Description:
  2780. Arguments:
  2781. Return Value:
  2782. *****************************************************************************/
  2783. NTSTATUS
  2784. SCCMN50M_GetFWVersion (IN PSMARTCARD_EXTENSION pSmartcardExtension )
  2785. {
  2786. NTSTATUS status = STATUS_SUCCESS;
  2787. SmartcardDebug(
  2788. DEBUG_TRACE,
  2789. ( "%s!GetFWVersion : Enter\n",
  2790. DRIVER_NAME)
  2791. );
  2792. if (pSmartcardExtension->IoRequest.ReplyBufferLength < sizeof (ULONG)) {
  2793. status = STATUS_BUFFER_OVERFLOW;
  2794. goto ExitGetFWVersion;
  2795. } else {
  2796. *(PULONG)(pSmartcardExtension->IoRequest.ReplyBuffer) =
  2797. pSmartcardExtension->ReaderExtension->ulFWVersion;
  2798. }
  2799. ExitGetFWVersion:
  2800. *pSmartcardExtension->IoRequest.Information = sizeof(ULONG);
  2801. SmartcardDebug(
  2802. DEBUG_TRACE,
  2803. ( "%s!GetFWVersion : Exit %lx\n",
  2804. DRIVER_NAME,status)
  2805. );
  2806. return status;
  2807. }
  2808. /*****************************************************************************
  2809. Routine Description:
  2810. Arguments:
  2811. Return Value:
  2812. *****************************************************************************/
  2813. NTSTATUS
  2814. SCCMN50M_ReadDeviceDescription(IN PSMARTCARD_EXTENSION pSmartcardExtension )
  2815. {
  2816. NTSTATUS status = STATUS_SUCCESS;
  2817. HRESULT result;
  2818. SmartcardDebug(
  2819. DEBUG_TRACE,
  2820. ( "%s!ReadDeviceDescription : Enter\n",
  2821. DRIVER_NAME)
  2822. );
  2823. if (pSmartcardExtension->IoRequest.ReplyBufferLength < sizeof(pSmartcardExtension->ReaderExtension->abDeviceDescription)) {
  2824. status = STATUS_BUFFER_OVERFLOW;
  2825. *pSmartcardExtension->IoRequest.Information = 0L;
  2826. goto ExitReadDeviceDescription;
  2827. } else {
  2828. if (pSmartcardExtension->ReaderExtension->abDeviceDescription[0] == 0x00 &&
  2829. pSmartcardExtension->ReaderExtension->abDeviceDescription[1] == 0x00 ) {
  2830. status = SCCMN50M_GetDeviceDescription(pSmartcardExtension);
  2831. }
  2832. if (status == STATUS_SUCCESS) {
  2833. result = StringCchCopy(pSmartcardExtension->IoRequest.ReplyBuffer,
  2834. pSmartcardExtension->IoRequest.ReplyBufferLength,
  2835. pSmartcardExtension->ReaderExtension->abDeviceDescription);
  2836. if (FAILED(result)) {
  2837. *pSmartcardExtension->IoRequest.Information = 0;
  2838. status = STATUS_BUFFER_OVERFLOW;
  2839. } else {
  2840. size_t size;
  2841. StringCchLength(pSmartcardExtension->ReaderExtension->abDeviceDescription,
  2842. sizeof(pSmartcardExtension->ReaderExtension->abDeviceDescription),
  2843. &size);
  2844. *pSmartcardExtension->IoRequest.Information = (ULONG)size;
  2845. pSmartcardExtension->IoRequest.Information++;
  2846. }
  2847. } else {
  2848. MemSet(pSmartcardExtension->ReaderExtension->abDeviceDescription,
  2849. sizeof(pSmartcardExtension->ReaderExtension->abDeviceDescription),
  2850. 0x00,
  2851. sizeof(pSmartcardExtension->ReaderExtension->abDeviceDescription));
  2852. *pSmartcardExtension->IoRequest.Information = 0;
  2853. }
  2854. }
  2855. ExitReadDeviceDescription:
  2856. SmartcardDebug(
  2857. DEBUG_TRACE,
  2858. ( "%s!ReadDeviceDescription : Exit %lx\n",
  2859. DRIVER_NAME,status)
  2860. );
  2861. return status;
  2862. }
  2863. /*****************************************************************************
  2864. Routine Description:
  2865. Arguments:
  2866. Return Value:
  2867. *****************************************************************************/
  2868. NTSTATUS
  2869. SCCMN50M_SetHighSpeed_CR80S_SAMOS (IN PSMARTCARD_EXTENSION pSmartcardExtension )
  2870. {
  2871. NTSTATUS status;
  2872. NTSTATUS DebugStatus;
  2873. UCHAR bReadBuffer[16];
  2874. ULONG ulBytesRead;
  2875. BYTE bCR80S_SAMOS_SET_HIGH_SPEED[4] = {0xFF,0x11,0x94,0x7A};
  2876. ULONG ulAtrLength;
  2877. BYTE bAtr[MAXIMUM_ATR_LENGTH];
  2878. SmartcardDebug(
  2879. DEBUG_TRACE,
  2880. ( "%s!SetHighSpeed_CR80S_SAMOS : Enter\n",
  2881. DRIVER_NAME)
  2882. );
  2883. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ENABLE_SYN | ENABLE_T0 |
  2884. ENABLE_T1 );
  2885. SCCMN50M_SetCardManHeader(pSmartcardExtension,
  2886. 0, // Tx control
  2887. sizeof(bCR80S_SAMOS_SET_HIGH_SPEED), // Tx length
  2888. 0, // Rx control
  2889. sizeof(bCR80S_SAMOS_SET_HIGH_SPEED)); // Rx length
  2890. status = SCCMN50M_WriteCardMan(pSmartcardExtension,
  2891. sizeof(bCR80S_SAMOS_SET_HIGH_SPEED),
  2892. bCR80S_SAMOS_SET_HIGH_SPEED);
  2893. if (status != STATUS_SUCCESS)
  2894. goto ExitSetHighSpeed;
  2895. pSmartcardExtension->ReaderExtension->ToRHConfig = FALSE;
  2896. status = SCCMN50M_ReadCardMan(pSmartcardExtension,2,&ulBytesRead,bReadBuffer,sizeof(bReadBuffer));
  2897. if (status != STATUS_SUCCESS)
  2898. goto ExitSetHighSpeed;
  2899. if (bReadBuffer[1] > sizeof(bReadBuffer)) {
  2900. status = STATUS_BUFFER_OVERFLOW;
  2901. goto ExitSetHighSpeed;
  2902. }
  2903. status = SCCMN50M_ReadCardMan(pSmartcardExtension,bReadBuffer[1],&ulBytesRead,bReadBuffer,sizeof(bReadBuffer));
  2904. if (status != STATUS_SUCCESS)
  2905. goto ExitSetHighSpeed;
  2906. // if the card has accepted this string , the string is echoed
  2907. if (bReadBuffer[0] == bCR80S_SAMOS_SET_HIGH_SPEED[0] &&
  2908. bReadBuffer[1] == bCR80S_SAMOS_SET_HIGH_SPEED[1] &&
  2909. bReadBuffer[2] == bCR80S_SAMOS_SET_HIGH_SPEED[2] &&
  2910. bReadBuffer[3] == bCR80S_SAMOS_SET_HIGH_SPEED[3] ) {
  2911. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ENABLE_3MHZ | ENABLE_5MHZ |
  2912. ENABLE_3MHZ_FAST | ENABLE_5MHZ_FAST );
  2913. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_5MHZ_FAST);
  2914. } else {
  2915. DebugStatus = SCCMN50M_PowerOff(pSmartcardExtension);
  2916. DebugStatus = SCCMN50M_PowerOn(pSmartcardExtension,&ulAtrLength,bAtr,sizeof(bAtr));
  2917. status = STATUS_UNSUCCESSFUL;
  2918. }
  2919. ExitSetHighSpeed:
  2920. *pSmartcardExtension->IoRequest.Information = 0L;
  2921. SmartcardDebug(
  2922. DEBUG_TRACE,
  2923. ( "%s!SetHighSpeed_CR80S_SAMOS : Exit %lx\n",
  2924. DRIVER_NAME,status)
  2925. );
  2926. return status;
  2927. }
  2928. /*****************************************************************************
  2929. Routine Description:
  2930. Arguments:
  2931. Return Value:
  2932. *****************************************************************************/
  2933. NTSTATUS
  2934. SCCMN50M_SetBRK(IN PSMARTCARD_EXTENSION pSmartcardExtension )
  2935. {
  2936. NTSTATUS status;
  2937. pSmartcardExtension->SmartcardReply.BufferLength = pSmartcardExtension->SmartcardReply.BufferSize;
  2938. pSmartcardExtension->SmartcardRequest.BufferLength = 0;
  2939. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_BREAK_ON;
  2940. status = SCCMN50M_SerialIo(pSmartcardExtension);
  2941. return status;
  2942. }
  2943. /*****************************************************************************
  2944. Routine Description:
  2945. Arguments:
  2946. Return Value:
  2947. *****************************************************************************/
  2948. NTSTATUS
  2949. SCCMN50M_ClearBRK(IN PSMARTCARD_EXTENSION SmartcardExtension )
  2950. {
  2951. NTSTATUS status;
  2952. SmartcardExtension->SmartcardReply.BufferLength = SmartcardExtension->SmartcardReply.BufferSize;
  2953. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  2954. SmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_BREAK_OFF;
  2955. status = SCCMN50M_SerialIo(SmartcardExtension);
  2956. return status;
  2957. }
  2958. /*****************************************************************************
  2959. Routine Description:
  2960. Arguments:
  2961. Return Value:
  2962. *****************************************************************************/
  2963. NTSTATUS
  2964. SCCMN50M_SetProtocol(PSMARTCARD_EXTENSION pSmartcardExtension )
  2965. {
  2966. NTSTATUS status;
  2967. NTSTATUS DebugStatus;
  2968. ULONG ulNewProtocol;
  2969. UCHAR abPTSRequest[4];
  2970. UCHAR abReadBuffer[6];
  2971. UCHAR abPTSReply [4];
  2972. ULONG ulBytesRead;
  2973. UCHAR bTemp;
  2974. ULONG ulPtsType;
  2975. ULONG ulPTSReplyLength=0;
  2976. ULONG ulStatBytesRead;
  2977. BYTE abStatReadBuffer[2];
  2978. KIRQL irql;
  2979. SmartcardDebug(
  2980. DEBUG_TRACE,
  2981. ( "%s!SetProtocol : Enter\n",
  2982. DRIVER_NAME)
  2983. );
  2984. //
  2985. // Check if the card is already in specific state
  2986. // and if the caller wants to have the already selected protocol.
  2987. // We return success if this is the case.
  2988. //
  2989. if ((pSmartcardExtension->CardCapabilities.Protocol.Selected & pSmartcardExtension->MinorIoControlCode)) {
  2990. status = STATUS_SUCCESS;
  2991. goto ExitSetProtocol;
  2992. }
  2993. ulNewProtocol = pSmartcardExtension->MinorIoControlCode;
  2994. ulPtsType = PTS_TYPE_OPTIMAL;
  2995. // we are not sure if we need this at all
  2996. pSmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_OPTIMAL;
  2997. while (TRUE) {
  2998. // set initial character of PTS
  2999. abPTSRequest[0] = 0xFF;
  3000. // set the format character
  3001. if (pSmartcardExtension->CardCapabilities.Protocol.Supported &
  3002. ulNewProtocol &
  3003. SCARD_PROTOCOL_T1) {
  3004. // select T=1 and indicate that PTS1 follows
  3005. abPTSRequest[1] = 0x11;
  3006. pSmartcardExtension->CardCapabilities.Protocol.Selected =
  3007. SCARD_PROTOCOL_T1;
  3008. } else if (pSmartcardExtension->CardCapabilities.Protocol.Supported &
  3009. ulNewProtocol &
  3010. SCARD_PROTOCOL_T0) {
  3011. // select T=1 and indicate that PTS1 follows
  3012. abPTSRequest[1] = 0x10;
  3013. pSmartcardExtension->CardCapabilities.Protocol.Selected =
  3014. SCARD_PROTOCOL_T0;
  3015. } else {
  3016. status = STATUS_INVALID_DEVICE_REQUEST;
  3017. goto ExitSetProtocol;
  3018. }
  3019. // bug fix :
  3020. // don 't use the suggestion from smclib
  3021. pSmartcardExtension->CardCapabilities.PtsData.Fl =
  3022. pSmartcardExtension->CardCapabilities.Fl;
  3023. pSmartcardExtension->CardCapabilities.PtsData.Dl =
  3024. pSmartcardExtension->CardCapabilities.Dl;
  3025. // CardMan support higher baudrates only for T=1
  3026. // ==> Dl=1
  3027. if (abPTSRequest[1] == 0x10) {
  3028. SmartcardDebug(
  3029. DEBUG_PROTOCOL,
  3030. ( "%s!overwriting PTS1 for T=0\n",
  3031. DRIVER_NAME)
  3032. );
  3033. pSmartcardExtension->CardCapabilities.PtsData.Fl = 0x01;
  3034. pSmartcardExtension->CardCapabilities.PtsData.Dl = 0x01;
  3035. }
  3036. if (ulPtsType == PTS_TYPE_DEFAULT) {
  3037. SmartcardDebug(
  3038. DEBUG_PROTOCOL,
  3039. ( "%s!overwriting PTS1 with default values\n",
  3040. DRIVER_NAME)
  3041. );
  3042. pSmartcardExtension->CardCapabilities.PtsData.Fl = 0x01;
  3043. pSmartcardExtension->CardCapabilities.PtsData.Dl = 0x01;
  3044. }
  3045. // set pts1 which codes Fl and Dl
  3046. bTemp = (BYTE) (pSmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  3047. pSmartcardExtension->CardCapabilities.PtsData.Dl);
  3048. SmartcardDebug(
  3049. DEBUG_PROTOCOL,
  3050. ( "%s!PTS1 = %x (suggestion)\n",
  3051. DRIVER_NAME,bTemp)
  3052. );
  3053. switch (bTemp) {
  3054. case 0x11:
  3055. // do nothing
  3056. // we support these Fl/Dl parameters
  3057. break;
  3058. case 0x13:
  3059. case 0x94:
  3060. break ;
  3061. case 0x14:
  3062. // let's try it with 38400 baud
  3063. SmartcardDebug(
  3064. DEBUG_PROTOCOL,
  3065. ( "%s!trying 57600 baud\n",DRIVER_NAME)
  3066. );
  3067. // we must correct Fl/Dl
  3068. pSmartcardExtension->CardCapabilities.PtsData.Dl = 0x03;
  3069. pSmartcardExtension->CardCapabilities.PtsData.Fl = 0x01;
  3070. bTemp = (BYTE) (pSmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  3071. pSmartcardExtension->CardCapabilities.PtsData.Dl);
  3072. break;
  3073. default:
  3074. SmartcardDebug(
  3075. DEBUG_PROTOCOL,
  3076. ( "%s!overwriting PTS1(0x%x)\n",
  3077. DRIVER_NAME,bTemp)
  3078. );
  3079. // we must correct Fl/Dl
  3080. pSmartcardExtension->CardCapabilities.PtsData.Dl = 0x01;
  3081. pSmartcardExtension->CardCapabilities.PtsData.Fl = 0x01;
  3082. bTemp = (BYTE) (pSmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  3083. pSmartcardExtension->CardCapabilities.PtsData.Dl);
  3084. break;
  3085. }
  3086. abPTSRequest[2] = bTemp;
  3087. // set pck (check character)
  3088. abPTSRequest[3] = (BYTE)(abPTSRequest[0] ^ abPTSRequest[1] ^ abPTSRequest[2]);
  3089. SmartcardDebug(DEBUG_PROTOCOL,("%s!PTS request: 0x%x 0x%x 0x%x 0x%x\n",
  3090. DRIVER_NAME,
  3091. abPTSRequest[0],
  3092. abPTSRequest[1],
  3093. abPTSRequest[2],
  3094. abPTSRequest[3]));
  3095. MemSet(abPTSReply,sizeof(abPTSReply),0x00,sizeof(abPTSReply));
  3096. DebugStatus = SCCMN50M_EnterTransparentMode(pSmartcardExtension);
  3097. // STEP 1 : write config + header to enter transparent mode
  3098. SCCMN50M_SetCardManHeader(pSmartcardExtension,
  3099. 0, // Tx control
  3100. 0, // Tx length
  3101. 0, // Rx control
  3102. 0); // Rx length
  3103. status = SCCMN50M_WriteCardMan (pSmartcardExtension,
  3104. 0,
  3105. NULL);
  3106. if (NT_ERROR(status)) {
  3107. goto ExitSetProtocol;
  3108. }
  3109. pSmartcardExtension->ReaderExtension->fTransparentMode = TRUE;
  3110. SmartcardDebug(
  3111. DEBUG_PROTOCOL,
  3112. ( "%s!writing PTS request\n",
  3113. DRIVER_NAME)
  3114. );
  3115. status = SCCMN50M_WriteCardMan(pSmartcardExtension,
  3116. 4,
  3117. abPTSRequest);
  3118. if (status != STATUS_SUCCESS) {
  3119. SmartcardDebug(
  3120. DEBUG_PROTOCOL,
  3121. ( "%s!writing PTS request failed\n",
  3122. DRIVER_NAME)
  3123. );
  3124. goto ExitSetProtocol;
  3125. }
  3126. // read back pts data
  3127. SmartcardDebug(
  3128. DEBUG_PROTOCOL,
  3129. ( "%s!trying to read PTS reply\n",
  3130. DRIVER_NAME)
  3131. );
  3132. // first read CardMan header
  3133. pSmartcardExtension->ReaderExtension->ToRHConfig= FALSE;
  3134. status = SCCMN50M_ReadCardMan(pSmartcardExtension,3,&ulBytesRead,abReadBuffer,sizeof(abReadBuffer));
  3135. if (status != STATUS_SUCCESS &&
  3136. status != STATUS_IO_TIMEOUT ) {
  3137. SmartcardDebug(
  3138. DEBUG_PROTOCOL,
  3139. ( "%s!reading status failed\n",
  3140. DRIVER_NAME)
  3141. );
  3142. goto ExitSetProtocol;
  3143. }
  3144. ulPTSReplyLength = 3;
  3145. MemCpy(abPTSReply,sizeof(abPTSReply),abReadBuffer,3);
  3146. // check if bit 5 is set
  3147. if (abPTSReply[1] & 0x10) {
  3148. pSmartcardExtension->ReaderExtension->ToRHConfig= FALSE;
  3149. status = SCCMN50M_ReadCardMan(pSmartcardExtension,1,&ulBytesRead,abReadBuffer,sizeof(abReadBuffer));
  3150. if (status != STATUS_SUCCESS &&
  3151. status != STATUS_IO_TIMEOUT ) {
  3152. SmartcardDebug(
  3153. DEBUG_PROTOCOL,
  3154. ( "%s!reading status failed\n",
  3155. DRIVER_NAME)
  3156. );
  3157. goto ExitSetProtocol;
  3158. }
  3159. ulPTSReplyLength += 1;
  3160. MemCpy(&abPTSReply[3],sizeof(abPTSReply)-3,abReadBuffer,1);
  3161. }
  3162. DebugStatus = SCCMN50M_ExitTransparentMode(pSmartcardExtension);
  3163. pSmartcardExtension->ReaderExtension->fTransparentMode = FALSE;
  3164. // to be sure that the new settings take effect
  3165. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant = 250;
  3166. DebugStatus = SCCMN50M_WriteCardMan(pSmartcardExtension,0,NULL);
  3167. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant = DEFAULT_READ_TOTAL_TIMEOUT_CONSTANT;
  3168. if (NT_SUCCESS(DebugStatus)) {
  3169. DebugStatus = SCCMN50M_ReadCardMan(pSmartcardExtension,2,&ulStatBytesRead,abStatReadBuffer,sizeof(abStatReadBuffer));
  3170. }
  3171. #if DBG
  3172. if (ulPTSReplyLength == 3) {
  3173. SmartcardDebug(DEBUG_PROTOCOL,("PTS reply: 0x%x 0x%x 0x%x\n",
  3174. abPTSReply[0],
  3175. abPTSReply[1],
  3176. abPTSReply[2]));
  3177. }
  3178. if (ulPTSReplyLength == 4) {
  3179. SmartcardDebug(DEBUG_PROTOCOL,("PTS reply: 0x%x 0x%x 0x%x 0x%x\n",
  3180. abPTSReply[0],
  3181. abPTSReply[1],
  3182. abPTSReply[2],
  3183. abPTSReply[3]));
  3184. }
  3185. #endif
  3186. if (ulPTSReplyLength == 3 &&
  3187. abPTSReply[0] == abPTSRequest[0] &&
  3188. (abPTSReply[1] & 0x7F) == (abPTSRequest[1] & 0x0F) &&
  3189. abPTSReply[2] == (BYTE)(abPTSReply[0] ^ abPTSReply[1]) ) {
  3190. SmartcardDebug(
  3191. DEBUG_PROTOCOL,
  3192. ( "%s!short PTS reply received\n",
  3193. DRIVER_NAME)
  3194. );
  3195. break;
  3196. }
  3197. if (ulPTSReplyLength == 4 &&
  3198. abPTSReply[0] == abPTSRequest[0] &&
  3199. abPTSReply[1] == abPTSRequest[1] &&
  3200. abPTSReply[2] == abPTSRequest[2] &&
  3201. abPTSReply[3] == abPTSRequest[3]) {
  3202. SmartcardDebug(
  3203. DEBUG_PROTOCOL,
  3204. ( "%s!PTS request and reply match\n",
  3205. DRIVER_NAME)
  3206. );
  3207. switch (bTemp) {
  3208. case 0x11:
  3209. break;
  3210. case 0x13:
  3211. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ENABLE_3MHZ | ENABLE_5MHZ |
  3212. ENABLE_3MHZ_FAST | ENABLE_5MHZ_FAST );
  3213. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_3MHZ_FAST);
  3214. break ;
  3215. case 0x94:
  3216. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ENABLE_3MHZ | ENABLE_5MHZ |
  3217. ENABLE_3MHZ_FAST | ENABLE_5MHZ_FAST );
  3218. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_5MHZ_FAST);
  3219. break;
  3220. }
  3221. break;
  3222. }
  3223. if (pSmartcardExtension->CardCapabilities.PtsData.Type !=
  3224. PTS_TYPE_DEFAULT) {
  3225. SmartcardDebug(
  3226. DEBUG_PROTOCOL,
  3227. ( "%s!PTS failed : Trying default parameters\n",
  3228. DRIVER_NAME)
  3229. );
  3230. // the card did either not reply or it replied incorrectly
  3231. // so try default valies
  3232. ulPtsType = pSmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_DEFAULT;
  3233. pSmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  3234. status = SCCMN50M_CardPower(pSmartcardExtension);
  3235. continue;
  3236. }
  3237. // the card failed the pts request
  3238. status = STATUS_DEVICE_PROTOCOL_ERROR;
  3239. goto ExitSetProtocol;
  3240. }
  3241. ExitSetProtocol:
  3242. switch (status) {
  3243. case STATUS_IO_TIMEOUT:
  3244. pSmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  3245. *pSmartcardExtension->IoRequest.Information = 0;
  3246. break;
  3247. case STATUS_SUCCESS:
  3248. // now indicate that we're in specific mode
  3249. KeAcquireSpinLock(&pSmartcardExtension->OsData->SpinLock,
  3250. &irql);
  3251. pSmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  3252. KeReleaseSpinLock(&pSmartcardExtension->OsData->SpinLock,
  3253. irql);
  3254. // return the selected protocol to the caller
  3255. *(PULONG) pSmartcardExtension->IoRequest.ReplyBuffer =
  3256. pSmartcardExtension->CardCapabilities.Protocol.Selected;
  3257. *pSmartcardExtension->IoRequest.Information =
  3258. sizeof(pSmartcardExtension->CardCapabilities.Protocol.Selected);
  3259. SmartcardDebug(
  3260. DEBUG_PROTOCOL,
  3261. ( "%s!Selected protocol: T=%ld\n",
  3262. DRIVER_NAME,pSmartcardExtension->CardCapabilities.Protocol.Selected-1)
  3263. );
  3264. break;
  3265. default :
  3266. pSmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  3267. *pSmartcardExtension->IoRequest.Information = 0;
  3268. break;
  3269. }
  3270. SmartcardDebug(
  3271. DEBUG_TRACE,
  3272. ( "%s!SetProtocol : Exit %lx\n",
  3273. DRIVER_NAME,status)
  3274. );
  3275. return status;
  3276. }
  3277. /*****************************************************************************
  3278. Routine Description:
  3279. The smart card lib requires to have this function. It is called
  3280. to setup event tracking for card insertion and removal events.
  3281. Arguments:
  3282. pSmartcardExtension - pointer to the smart card data struct.
  3283. Return Value:
  3284. NTSTATUS
  3285. *****************************************************************************/
  3286. NTSTATUS
  3287. SCCMN50M_CardTracking(PSMARTCARD_EXTENSION pSmartcardExtension)
  3288. {
  3289. KIRQL oldIrql;
  3290. SmartcardDebug(
  3291. DEBUG_TRACE,
  3292. ( "%s!CardTracking: Enter\n",
  3293. DRIVER_NAME)
  3294. );
  3295. //
  3296. // Set cancel routine for the notification irp
  3297. //
  3298. IoAcquireCancelSpinLock(&oldIrql);
  3299. IoSetCancelRoutine(pSmartcardExtension->OsData->NotificationIrp,SCCMN50M_Cancel);
  3300. IoReleaseCancelSpinLock(oldIrql);
  3301. //
  3302. // Mark notification irp pending
  3303. //
  3304. IoMarkIrpPending(pSmartcardExtension->OsData->NotificationIrp);
  3305. SmartcardDebug(
  3306. DEBUG_TRACE,
  3307. ( "%s!CardTracking: Exit\n",
  3308. DRIVER_NAME)
  3309. );
  3310. return STATUS_PENDING;
  3311. }
  3312. /*****************************************************************************
  3313. Routine Description:
  3314. Arguments:
  3315. Return Value:
  3316. *****************************************************************************/
  3317. VOID
  3318. SCCMN50M_StopCardTracking(
  3319. IN PDEVICE_EXTENSION pDeviceExtension
  3320. )
  3321. {
  3322. PSMARTCARD_EXTENSION pSmartcardExtension = &pDeviceExtension->SmartcardExtension;
  3323. NTSTATUS status;
  3324. SmartcardDebug(
  3325. DEBUG_TRACE,
  3326. ( "%s!StopCardTracking: Enter\n",
  3327. DRIVER_NAME)
  3328. );
  3329. if (pSmartcardExtension->ReaderExtension->ThreadObjectPointer != NULL) {
  3330. // kill thread
  3331. KeWaitForSingleObject(&pSmartcardExtension->ReaderExtension->CardManIOMutex,
  3332. Executive,
  3333. KernelMode,
  3334. FALSE,
  3335. NULL
  3336. );
  3337. pSmartcardExtension->ReaderExtension->TimeToTerminateThread = TRUE;
  3338. KeReleaseMutex(&pSmartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  3339. //
  3340. // Wait on the thread handle, when the wait is satisfied, the
  3341. // thread has gone away.
  3342. //
  3343. status = KeWaitForSingleObject(
  3344. pSmartcardExtension->ReaderExtension->ThreadObjectPointer,
  3345. Executive,
  3346. KernelMode,
  3347. FALSE,
  3348. NULL
  3349. );
  3350. pSmartcardExtension->ReaderExtension->ThreadObjectPointer = NULL;
  3351. }
  3352. SmartcardDebug(
  3353. DEBUG_TRACE,
  3354. ( "%s!StopCardTracking: Exit %lx\n",
  3355. DRIVER_NAME,
  3356. status)
  3357. );
  3358. }
  3359. /*****************************************************************************
  3360. Routine Description:
  3361. Arguments:
  3362. Return Value:
  3363. *****************************************************************************/
  3364. NTSTATUS
  3365. SCCMN50M_GetDeviceDescription (PSMARTCARD_EXTENSION pSmartcardExtension)
  3366. {
  3367. NTSTATUS status;
  3368. NTSTATUS DebugStatus;
  3369. ULONG ulBytesRead;
  3370. BYTE bByteRead;
  3371. ULONG i,j;
  3372. BYTE abReadBuffer[256];
  3373. ULONG ulPnPStringLength = 0;
  3374. ULONG ulExtend;
  3375. SmartcardDebug(
  3376. DEBUG_TRACE,
  3377. ( "%s!GetDeviceDescriptiong: Enter\n",
  3378. DRIVER_NAME)
  3379. );
  3380. // ===============================
  3381. // clear any pending errors
  3382. // ===============================
  3383. status = SCCMN50M_GetCommStatus(pSmartcardExtension);
  3384. if (!NT_SUCCESS(status)) {
  3385. SmartcardDebug(DEBUG_ERROR,("SCCMN50M_GetCommStatus failed ! status = %ld\n",status))
  3386. goto ExitGetDeviceDescription;
  3387. }
  3388. // =================================
  3389. // set baudrate for CardMan to 1200
  3390. // =================================
  3391. pSmartcardExtension->ReaderExtension->SerialConfigData.BaudRate.BaudRate = 1200;
  3392. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_BAUD_RATE;
  3393. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  3394. &pSmartcardExtension->ReaderExtension->SerialConfigData.BaudRate.BaudRate,
  3395. sizeof(SERIAL_BAUD_RATE));
  3396. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_BAUD_RATE);
  3397. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  3398. status = SCCMN50M_SerialIo(pSmartcardExtension);
  3399. if (!NT_SUCCESS(status)) {
  3400. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_BAUDRATE failed ! status = %ld\n",status))
  3401. goto ExitGetDeviceDescription;
  3402. }
  3403. // ===============================
  3404. // set comm timeouts
  3405. // ===============================
  3406. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout = DEFAULT_READ_INTERVAL_TIMEOUT;
  3407. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant = DEFAULT_READ_TOTAL_TIMEOUT_CONSTANT + 5000;
  3408. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier = DEFAULT_READ_TOTAL_TIMEOUT_MULTIPLIER;
  3409. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.WriteTotalTimeoutConstant = DEFAULT_WRITE_TOTAL_TIMEOUT_CONSTANT;
  3410. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.WriteTotalTimeoutMultiplier = DEFAULT_WRITE_TOTAL_TIMEOUT_MULTIPLIER;
  3411. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_TIMEOUTS;
  3412. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  3413. &pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts,
  3414. sizeof(SERIAL_TIMEOUTS));
  3415. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_TIMEOUTS);
  3416. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  3417. status = SCCMN50M_SerialIo(pSmartcardExtension);
  3418. if (!NT_SUCCESS(status)) {
  3419. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_TIMEOUTS failed ! status = %x\n",status))
  3420. goto ExitGetDeviceDescription;
  3421. }
  3422. // ===============================
  3423. // set line control
  3424. // ===============================
  3425. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.StopBits = STOP_BITS_2;
  3426. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.Parity = NO_PARITY;
  3427. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.WordLength = 7;
  3428. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_LINE_CONTROL;
  3429. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  3430. &pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl,
  3431. sizeof(SERIAL_LINE_CONTROL));
  3432. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_LINE_CONTROL);
  3433. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  3434. status = SCCMN50M_SerialIo(pSmartcardExtension);
  3435. if (!NT_SUCCESS(status)) {
  3436. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_LINE_CONTROL failed ! status = %x\n",status))
  3437. goto ExitGetDeviceDescription;
  3438. }
  3439. // ===============================
  3440. // Set handflow
  3441. // ===============================
  3442. pSmartcardExtension->ReaderExtension->SerialConfigData.HandFlow.XonLimit = 0;
  3443. pSmartcardExtension->ReaderExtension->SerialConfigData.HandFlow.XoffLimit = 0;
  3444. pSmartcardExtension->ReaderExtension->SerialConfigData.HandFlow.FlowReplace = 0;
  3445. pSmartcardExtension->ReaderExtension->SerialConfigData.HandFlow.ControlHandShake = SERIAL_ERROR_ABORT | SERIAL_DTR_CONTROL;
  3446. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_HANDFLOW;
  3447. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  3448. &pSmartcardExtension->ReaderExtension->SerialConfigData.HandFlow,
  3449. sizeof(SERIAL_HANDFLOW));
  3450. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_HANDFLOW);
  3451. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  3452. status = SCCMN50M_SerialIo(pSmartcardExtension);
  3453. if (!NT_SUCCESS(status)) {
  3454. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_HANDFLOW failed ! status = %x\n",status))
  3455. goto ExitGetDeviceDescription;
  3456. }
  3457. // ===============================
  3458. // set purge mask
  3459. // ===============================
  3460. pSmartcardExtension->ReaderExtension->SerialConfigData.PurgeMask =
  3461. SERIAL_PURGE_TXABORT | SERIAL_PURGE_RXABORT |
  3462. SERIAL_PURGE_TXCLEAR | SERIAL_PURGE_RXCLEAR;
  3463. // ===============================
  3464. // clear RTS
  3465. // ===============================
  3466. status = SCCMN50M_ClearRTS(pSmartcardExtension);
  3467. if (!NT_SUCCESS(status)) {
  3468. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_RTS failed ! status = %x\n",status))
  3469. goto ExitGetDeviceDescription;
  3470. }
  3471. Wait(pSmartcardExtension,1);
  3472. // ===============================
  3473. // set DTR
  3474. // ===============================
  3475. status = SCCMN50M_SetDTR(pSmartcardExtension);
  3476. if (!NT_SUCCESS(status)) {
  3477. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_DRT failed ! status = %x\n",status))
  3478. goto ExitGetDeviceDescription;
  3479. }
  3480. Wait(pSmartcardExtension,1);
  3481. // ===============================
  3482. // set RTS
  3483. // ===============================
  3484. status = SCCMN50M_SetRTS(pSmartcardExtension);
  3485. if (!NT_SUCCESS(status)) {
  3486. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_RTS failed ! status = %x\n",status))
  3487. goto ExitGetDeviceDescription;
  3488. }
  3489. i=0;
  3490. while (i < sizeof(abReadBuffer)) {
  3491. pSmartcardExtension->ReaderExtension->ToRHConfig = FALSE;
  3492. status = SCCMN50M_ReadCardMan(pSmartcardExtension,1,&ulBytesRead,&bByteRead,sizeof(bByteRead));
  3493. if (status == STATUS_SUCCESS) {
  3494. abReadBuffer[i++] = bByteRead;
  3495. if (bByteRead == 0x29) {
  3496. ulPnPStringLength = i;
  3497. break;
  3498. }
  3499. } else {
  3500. break;
  3501. }
  3502. }
  3503. if (i >= sizeof(abReadBuffer)) {
  3504. status = STATUS_UNSUCCESSFUL;
  3505. goto ExitGetDeviceDescription;
  3506. }
  3507. if (ulPnPStringLength > 11 ) {
  3508. ulExtend = 0;
  3509. for (i=0;i<ulPnPStringLength;i++) {
  3510. if (abReadBuffer[i] == 0x5C)
  3511. ulExtend++;
  3512. if (ulExtend == 4) {
  3513. j = 0;
  3514. i++;
  3515. while (i < ulPnPStringLength - 3) {
  3516. pSmartcardExtension->ReaderExtension->abDeviceDescription[j] = abReadBuffer[i];
  3517. i++;
  3518. j++;
  3519. }
  3520. pSmartcardExtension->ReaderExtension->abDeviceDescription[j] = 0;
  3521. SmartcardDebug(
  3522. DEBUG_DRIVER,
  3523. ( "%s!Device=%s\n",
  3524. pSmartcardExtension->ReaderExtension->abDeviceDescription)
  3525. );
  3526. break;
  3527. }
  3528. }
  3529. }
  3530. // ===================
  3531. // restore baud rate
  3532. // ===================
  3533. pSmartcardExtension->ReaderExtension->SerialConfigData.BaudRate.BaudRate = 38400;
  3534. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_BAUD_RATE;
  3535. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  3536. &pSmartcardExtension->ReaderExtension->SerialConfigData.BaudRate.BaudRate,
  3537. sizeof(SERIAL_BAUD_RATE));
  3538. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_BAUD_RATE);
  3539. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  3540. status = SCCMN50M_SerialIo(pSmartcardExtension);
  3541. if (!NT_SUCCESS(status)) {
  3542. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_BAUDRATE failed ! status = %ld\n",status))
  3543. goto ExitGetDeviceDescription;
  3544. }
  3545. // ====================
  3546. // retore line control
  3547. // ====================
  3548. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.StopBits = STOP_BITS_2;
  3549. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.Parity = EVEN_PARITY;
  3550. pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl.WordLength = 8;
  3551. pSmartcardExtension->ReaderExtension->SerialIoControlCode = IOCTL_SERIAL_SET_LINE_CONTROL;
  3552. RtlCopyMemory(pSmartcardExtension->SmartcardRequest.Buffer,
  3553. &pSmartcardExtension->ReaderExtension->SerialConfigData.LineControl,
  3554. sizeof(SERIAL_LINE_CONTROL));
  3555. pSmartcardExtension->SmartcardRequest.BufferLength = sizeof(SERIAL_LINE_CONTROL);
  3556. pSmartcardExtension->SmartcardReply.BufferLength = 0;
  3557. status = SCCMN50M_SerialIo(pSmartcardExtension);
  3558. if (!NT_SUCCESS(status)) {
  3559. SmartcardDebug(DEBUG_ERROR,("IOCTL_SERIAL_SET_LINE_CONTROL failed ! status = %x\n",status))
  3560. goto ExitGetDeviceDescription;
  3561. }
  3562. ExitGetDeviceDescription:
  3563. DebugStatus = SCCMN50M_ResyncCardManII(pSmartcardExtension);
  3564. if (status != STATUS_SUCCESS) { // map all errors to STATUS_UNSUCCESSFULL;
  3565. status = STATUS_UNSUCCESSFUL;
  3566. }
  3567. SmartcardDebug(
  3568. DEBUG_TRACE,
  3569. ( "%s!GetDeviceDescriptiong: Exit %lx\n",
  3570. DRIVER_NAME,status)
  3571. );
  3572. return status;
  3573. }
  3574. /*****************************************************************************
  3575. Routine Description:
  3576. Arguments:
  3577. Return Value:
  3578. *****************************************************************************/
  3579. NTSTATUS
  3580. SCCMN50M_SetSyncParameters(IN PSMARTCARD_EXTENSION pSmartcardExtension )
  3581. {
  3582. NTSTATUS status = STATUS_SUCCESS;
  3583. SmartcardDebug(
  3584. DEBUG_TRACE,
  3585. ( "%s!SetSyncParameters: Enter\n",
  3586. DRIVER_NAME)
  3587. );
  3588. //DBGBreakPoint();
  3589. pSmartcardExtension->ReaderExtension->SyncParameters.ulProtocol =
  3590. ((PSYNC_PARAMETERS)pSmartcardExtension->IoRequest.RequestBuffer)->ulProtocol;
  3591. pSmartcardExtension->ReaderExtension->SyncParameters.ulStateResetLineWhileReading =
  3592. ((PSYNC_PARAMETERS)pSmartcardExtension->IoRequest.RequestBuffer)->ulStateResetLineWhileReading;
  3593. pSmartcardExtension->ReaderExtension->SyncParameters.ulStateResetLineWhileWriting =
  3594. ((PSYNC_PARAMETERS)pSmartcardExtension->IoRequest.RequestBuffer)->ulStateResetLineWhileWriting;
  3595. pSmartcardExtension->ReaderExtension->SyncParameters.ulWriteDummyClocks =
  3596. ((PSYNC_PARAMETERS)pSmartcardExtension->IoRequest.RequestBuffer)->ulWriteDummyClocks;
  3597. pSmartcardExtension->ReaderExtension->SyncParameters.ulHeaderLen =
  3598. ((PSYNC_PARAMETERS)pSmartcardExtension->IoRequest.RequestBuffer)->ulHeaderLen;
  3599. // Used for the 2 Wire Protocol. We must make a Card reset after Power On
  3600. pSmartcardExtension->ReaderExtension->SyncParameters.fCardResetRequested = TRUE;
  3601. // return length of reply
  3602. *pSmartcardExtension->IoRequest.Information = 0L;
  3603. SmartcardDebug(
  3604. DEBUG_TRACE,
  3605. ( "%s!SetSyncParameters: Exit\n",
  3606. DRIVER_NAME)
  3607. );
  3608. return status;
  3609. }
  3610. /*****************************************************************************
  3611. Routine Description:
  3612. Arguments:
  3613. Return Value:
  3614. *****************************************************************************/
  3615. UCHAR
  3616. SCCMN50M_CalcTxControlByte (IN PSMARTCARD_EXTENSION pSmartcardExtension,
  3617. IN ULONG ulBitsToWrite )
  3618. {
  3619. UCHAR bTxControlByte = 0;
  3620. if (pSmartcardExtension->ReaderExtension->SyncParameters.ulProtocol == SCARD_PROTOCOL_2WBP) {
  3621. bTxControlByte = CLOCK_FORCED_2WBP;
  3622. } else {
  3623. if (ulBitsToWrite >= 255 * 8)
  3624. bTxControlByte |= TRANSMIT_A8;
  3625. if (pSmartcardExtension->ReaderExtension->SyncParameters.ulStateResetLineWhileWriting ==
  3626. SCARD_RESET_LINE_HIGH)
  3627. bTxControlByte |= SYNC_RESET_LINE_HIGH;
  3628. }
  3629. bTxControlByte |= (BYTE)((ulBitsToWrite-1) & 0x00000007);
  3630. return bTxControlByte;
  3631. }
  3632. //---------------------------------------------------------------------------
  3633. //
  3634. //---------------------------------------------------------------------------
  3635. /*****************************************************************************
  3636. Routine Description:
  3637. Arguments:
  3638. Return Value:
  3639. *****************************************************************************/
  3640. UCHAR
  3641. SCCMN50M_CalcTxLengthByte (IN PSMARTCARD_EXTENSION pSmartcardExtension,
  3642. IN ULONG ulBitsToWrite )
  3643. {
  3644. UCHAR bTxLengthByte = 0;
  3645. bTxLengthByte = (BYTE)( ((ulBitsToWrite - 1) >> 3) + 1);
  3646. return bTxLengthByte;
  3647. }
  3648. //---------------------------------------------------------------------------
  3649. //
  3650. //---------------------------------------------------------------------------
  3651. /*****************************************************************************
  3652. Routine Description:
  3653. Arguments:
  3654. Return Value:
  3655. *****************************************************************************/
  3656. UCHAR
  3657. SCCMN50M_CalcRxControlByte (IN PSMARTCARD_EXTENSION pSmartcardExtension,
  3658. IN ULONG ulBitsToRead )
  3659. {
  3660. UCHAR bRxControlByte = 0;
  3661. if (pSmartcardExtension->ReaderExtension->SyncParameters.ulStateResetLineWhileReading ==
  3662. SCARD_RESET_LINE_HIGH)
  3663. bRxControlByte |= SYNC_RESET_LINE_HIGH;
  3664. if (ulBitsToRead == 0) {
  3665. ulBitsToRead = pSmartcardExtension->ReaderExtension->SyncParameters.ulWriteDummyClocks;
  3666. bRxControlByte |= SYNC_DUMMY_RECEIVE;
  3667. }
  3668. if (ulBitsToRead > 255 * 8)
  3669. bRxControlByte |= RECEIVE_A8;
  3670. bRxControlByte |= (BYTE)( (ulBitsToRead-1) & 0x00000007);
  3671. return bRxControlByte;
  3672. }
  3673. //----------------------------------------------------------------------------
  3674. //
  3675. //----------------------------------------------------------------------------
  3676. /*****************************************************************************
  3677. Routine Description:
  3678. Arguments:
  3679. Return Value:
  3680. *****************************************************************************/
  3681. UCHAR
  3682. SCCMN50M_CalcRxLengthByte (IN PSMARTCARD_EXTENSION pSmartcardExtension,
  3683. IN ULONG ulBitsToRead )
  3684. {
  3685. UCHAR bRxLengthByte = 0;
  3686. // if (pSmartcardExtension->ReaderExtension->SyncParameters.ulProtocol == SCARD_PROTOCOL_3WBP)
  3687. // {
  3688. if (ulBitsToRead == 0)
  3689. ulBitsToRead = pSmartcardExtension->ReaderExtension->SyncParameters.ulWriteDummyClocks;
  3690. bRxLengthByte = (BYTE)( ((ulBitsToRead - 1) >> 3) + 1);
  3691. // }
  3692. return bRxLengthByte;
  3693. }
  3694. /*****************************************************************************
  3695. Routine Description:
  3696. Arguments:
  3697. Return Value:
  3698. *****************************************************************************/
  3699. NTSTATUS
  3700. SCCMN50M_SyncCardPowerOn (
  3701. IN PSMARTCARD_EXTENSION pSmartcardExtension
  3702. )
  3703. {
  3704. NTSTATUS status;
  3705. UCHAR pbAtrBuffer[MAXIMUM_ATR_LENGTH];
  3706. UCHAR abSyncAtrBuffer[MAXIMUM_ATR_LENGTH];
  3707. ULONG ulAtrLength = 0;
  3708. KIRQL irql;
  3709. SmartcardDebug(
  3710. DEBUG_TRACE,
  3711. ( "%s!SyncCardPowerOn: Enter\n",
  3712. DRIVER_NAME)
  3713. );
  3714. status = SCCMN50M_UseSyncStrategy(pSmartcardExtension,
  3715. &ulAtrLength,
  3716. pbAtrBuffer,
  3717. sizeof(pbAtrBuffer));
  3718. abSyncAtrBuffer[0] = 0x3B;
  3719. abSyncAtrBuffer[1] = 0x04;
  3720. MemCpy(&abSyncAtrBuffer[2],
  3721. sizeof(abSyncAtrBuffer)-2,
  3722. pbAtrBuffer,
  3723. ulAtrLength);
  3724. ulAtrLength += 2;
  3725. MemCpy(pSmartcardExtension->CardCapabilities.ATR.Buffer,
  3726. sizeof(pSmartcardExtension->CardCapabilities.ATR.Buffer),
  3727. abSyncAtrBuffer,
  3728. ulAtrLength);
  3729. pSmartcardExtension->CardCapabilities.ATR.Length = (UCHAR)(ulAtrLength);
  3730. KeAcquireSpinLock(&pSmartcardExtension->OsData->SpinLock,
  3731. &irql);
  3732. pSmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  3733. pSmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
  3734. pSmartcardExtension->ReaderExtension->SyncParameters.fCardResetRequested = TRUE;
  3735. pSmartcardExtension->ReaderExtension->SyncParameters.fCardPowerRequested = FALSE;
  3736. KeReleaseSpinLock(&pSmartcardExtension->OsData->SpinLock,
  3737. irql);
  3738. SmartcardDebug(DEBUG_ATR,("ATR of synchronous smart card : %2.2x %2.2x %2.2x %2.2x\n",
  3739. pbAtrBuffer[0],pbAtrBuffer[1],pbAtrBuffer[2],pbAtrBuffer[3]));
  3740. SmartcardDebug(
  3741. DEBUG_TRACE,
  3742. ( "%s!SyncCardPowerOn: Exit %lx\n",
  3743. DRIVER_NAME,status)
  3744. );
  3745. return status;
  3746. }
  3747. /*****************************************************************************
  3748. Routine Description:
  3749. Arguments:
  3750. Return Value:
  3751. *****************************************************************************/
  3752. NTSTATUS
  3753. SCCMN50M_Transmit2WBP(PSMARTCARD_EXTENSION pSmartcardExtension)
  3754. {
  3755. NTSTATUS status = STATUS_SUCCESS;
  3756. UCHAR bWriteBuffer [128];
  3757. UCHAR bReadBuffer [128];
  3758. UCHAR bTxControlByte;
  3759. UCHAR bTxLengthByte;
  3760. UCHAR bRxControlByte;
  3761. UCHAR bRxLengthByte;
  3762. ULONG ulBytesToWrite;
  3763. ULONG ulBytesToRead;
  3764. ULONG ulBitsToWrite;
  3765. ULONG ulBitsToRead;
  3766. ULONG ulBytesRead;
  3767. // ULONG ulBitsRead;
  3768. ULONG ulBytesStillToRead;
  3769. ULONG ulMaxIFSD;
  3770. PCHAR pbInData;
  3771. SmartcardDebug(
  3772. DEBUG_TRACE,
  3773. ( "%s!Transmit2WBP: Enter\n",
  3774. DRIVER_NAME)
  3775. );
  3776. /*-----------------------------------------------------------------------*/
  3777. /** Power smartcard - if smartcard was removed and reinserted **/
  3778. /*-----------------------------------------------------------------------*/
  3779. if (pSmartcardExtension->ReaderExtension->SyncParameters.fCardPowerRequested == TRUE) {
  3780. status = SCCMN50M_SyncCardPowerOn (pSmartcardExtension);
  3781. if (status != STATUS_SUCCESS) {
  3782. goto ExitTransmit2WBP;
  3783. }
  3784. }
  3785. pbInData = pSmartcardExtension->IoRequest.RequestBuffer + sizeof(SYNC_TRANSFER);
  3786. ulBitsToWrite = ((PSYNC_TRANSFER)(pSmartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToWrite;
  3787. ulBitsToRead = ((PSYNC_TRANSFER)(pSmartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToRead;
  3788. ulBytesToWrite = ulBitsToWrite/8;
  3789. ulBytesToRead = ulBitsToRead/8 + (ulBitsToRead % 8 ? 1 : 0);
  3790. /*-----------------------------------------------------------------------*/
  3791. // check buffer sizes
  3792. /*-----------------------------------------------------------------------*/
  3793. ulMaxIFSD = ATTR_MAX_IFSD_CARDMAN_II;
  3794. if (ulBytesToRead > ulMaxIFSD ||
  3795. ulBytesToRead > pSmartcardExtension->SmartcardReply.BufferSize) {
  3796. status = STATUS_BUFFER_OVERFLOW;
  3797. goto ExitTransmit2WBP;
  3798. }
  3799. if (ulBytesToWrite > pSmartcardExtension->SmartcardRequest.BufferSize) {
  3800. status = STATUS_BUFFER_OVERFLOW;
  3801. goto ExitTransmit2WBP;
  3802. }
  3803. pSmartcardExtension->SmartcardRequest.BufferLength = ulBytesToWrite+1;
  3804. /*-----------------------------------------------------------------------*/
  3805. // copy data to the Smartcard Request Buffer
  3806. /*-----------------------------------------------------------------------*/
  3807. (pSmartcardExtension->SmartcardRequest.Buffer)[0] = '\x0F';
  3808. MemCpy((pSmartcardExtension->SmartcardRequest.Buffer+1),
  3809. pSmartcardExtension->SmartcardRequest.BufferSize-1,
  3810. pbInData,
  3811. ulBytesToWrite);
  3812. /*-----------------------------------------------------------------------*/
  3813. // copy data to the write buffer
  3814. /*-----------------------------------------------------------------------*/
  3815. MemCpy((bWriteBuffer),
  3816. sizeof(bWriteBuffer),
  3817. pSmartcardExtension->SmartcardRequest.Buffer,
  3818. (ulBytesToWrite+1));
  3819. /*-----------------------------------------------------------------------*/
  3820. // set SYNC protocol flag for CardMan
  3821. /*-----------------------------------------------------------------------*/
  3822. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_SYN);
  3823. /*-----------------------------------------------------------------------*/
  3824. // Header
  3825. /*-----------------------------------------------------------------------*/
  3826. if (pSmartcardExtension->ReaderExtension->SyncParameters.fCardResetRequested == TRUE) {
  3827. status = SCCMN50M_ResetCard2WBP(pSmartcardExtension);
  3828. if (NT_ERROR(status)) {
  3829. goto ExitTransmit2WBP;
  3830. }
  3831. pSmartcardExtension->ReaderExtension->SyncParameters.fCardResetRequested = FALSE;
  3832. }
  3833. /*-----------------------------------------------------------------------*/
  3834. // 1. Send Carman-Header 4-Byte
  3835. // 2. Send 0x0F, that builds a HIGH-LOW Edge for 4432 CC
  3836. // 3. Send the Data (CC command = 3 Byte)
  3837. /*-----------------------------------------------------------------------*/
  3838. bTxControlByte = SCCMN50M_CalcTxControlByte(pSmartcardExtension,ulBitsToWrite);
  3839. bTxLengthByte = (BYTE)(SCCMN50M_CalcTxLengthByte(pSmartcardExtension,ulBitsToWrite)+1);
  3840. bRxControlByte = 0;
  3841. bRxLengthByte = 0;
  3842. SCCMN50M_SetCardManHeader(pSmartcardExtension,
  3843. bTxControlByte,
  3844. bTxLengthByte,
  3845. bRxControlByte,
  3846. bRxLengthByte);
  3847. /*-----------------------------------------------------------------------*/
  3848. // write data to card
  3849. /*-----------------------------------------------------------------------*/
  3850. status = SCCMN50M_WriteCardMan (pSmartcardExtension,
  3851. (ulBytesToWrite+1),
  3852. bWriteBuffer);
  3853. if (NT_ERROR(status)) {
  3854. goto ExitTransmit2WBP;
  3855. }
  3856. /*-----------------------------------------------------------------------*/
  3857. // read CardMan Header
  3858. // no Data from CC received
  3859. /*-----------------------------------------------------------------------*/
  3860. pSmartcardExtension->ReaderExtension->ToRHConfig = FALSE;
  3861. status = SCCMN50M_ReadCardMan(pSmartcardExtension,
  3862. 2,
  3863. &ulBytesRead,
  3864. bReadBuffer,
  3865. sizeof(bReadBuffer));
  3866. if (NT_ERROR(status)) {
  3867. goto ExitTransmit2WBP;
  3868. }
  3869. /*-----------------------------------------------------------------------*/
  3870. // 1. Send Carman-Header 4-Byte
  3871. // 2. Send 0xF0, that builds a LOW-HIGH Edge for 4432 CC
  3872. // 3. Now the receiviing of card-data begins
  3873. /*-----------------------------------------------------------------------*/
  3874. bTxControlByte = SCCMN50M_CalcTxControlByte(pSmartcardExtension, 8);
  3875. bTxLengthByte = SCCMN50M_CalcTxLengthByte(pSmartcardExtension, 8);
  3876. bRxControlByte = SCCMN50M_CalcRxControlByte(pSmartcardExtension,ulBitsToRead);
  3877. bRxLengthByte = SCCMN50M_CalcRxLengthByte(pSmartcardExtension,ulBitsToRead);
  3878. SCCMN50M_SetCardManHeader(pSmartcardExtension,
  3879. bTxControlByte,
  3880. bTxLengthByte,
  3881. bRxControlByte,
  3882. bRxLengthByte);
  3883. /*-----------------------------------------------------------------------*/
  3884. // in this sequnce SCCMN50M_WriteCardMan must not send the Config string.
  3885. // write 0xF0 -> is the trigger to read data from card or start the
  3886. // processing.
  3887. /*-----------------------------------------------------------------------*/
  3888. pSmartcardExtension->ReaderExtension->NoConfig = TRUE;
  3889. status = SCCMN50M_WriteCardMan (pSmartcardExtension,
  3890. 1, // one byte to write
  3891. "\xF0"); // LOW-HIGH - Edge
  3892. if (NT_ERROR(status)) {
  3893. goto ExitTransmit2WBP;
  3894. }
  3895. /*-----------------------------------------------------------------------*/
  3896. // read CardMan Header
  3897. // Data from CC received will be received
  3898. /*-----------------------------------------------------------------------*/
  3899. pSmartcardExtension->ReaderExtension->ToRHConfig = FALSE;
  3900. status = SCCMN50M_ReadCardMan(pSmartcardExtension,
  3901. 2,
  3902. &ulBytesRead,
  3903. bReadBuffer,
  3904. sizeof(bReadBuffer));
  3905. if (NT_ERROR(status)) {
  3906. goto ExitTransmit2WBP;
  3907. }
  3908. /*-----------------------------------------------------------------------*/
  3909. // Read the data string
  3910. /*-----------------------------------------------------------------------*/
  3911. ulBytesStillToRead = (ULONG)bReadBuffer[1];
  3912. if (bReadBuffer[0] & RECEIVE_A8)
  3913. ulBytesStillToRead += 256;
  3914. status = SCCMN50M_ReadCardMan(pSmartcardExtension,
  3915. ulBytesStillToRead,
  3916. &ulBytesRead,
  3917. bReadBuffer,
  3918. sizeof(bReadBuffer));
  3919. if (NT_ERROR(status)) {
  3920. goto ExitTransmit2WBP;
  3921. }
  3922. /*-----------------------------------------------------------------------*/
  3923. /** calculate data length in bits - this value is not used **/
  3924. /*-----------------------------------------------------------------------*/
  3925. // ulBitsRead = ((ulBytesRead-1) * 8) + ((ulBitsToRead-1 ) & 0x00000007) + 1;
  3926. /*-----------------------------------------------------------------------*/
  3927. /** shift the bits in the last byte to the correct position **/
  3928. /*-----------------------------------------------------------------------*/
  3929. bReadBuffer[ulBytesRead-1] >>= (7 - ((ulBitsToRead-1) & 0x00000007));
  3930. /*-----------------------------------------------------------------------*/
  3931. // the first bit of the returned string is lost
  3932. // so we must shift the whole data string one bit left
  3933. // the first bit of the first data byte is lost while reading
  3934. // this bit maybe incorrect
  3935. /*-----------------------------------------------------------------------*/
  3936. SCCMN50M_Shift_Msg(bReadBuffer, ulBytesRead);
  3937. /*-----------------------------------------------------------------------*/
  3938. // copy received bytes to Smartcard Reply Buffer
  3939. /*-----------------------------------------------------------------------*/
  3940. MemCpy(pSmartcardExtension->SmartcardReply.Buffer,
  3941. pSmartcardExtension->SmartcardReply.BufferSize,
  3942. bReadBuffer,
  3943. ulBytesRead);
  3944. pSmartcardExtension->SmartcardReply.BufferLength = ulBytesRead;
  3945. /*-----------------------------------------------------------------------*/
  3946. // copy received bytes to IoReply Buffer
  3947. /*-----------------------------------------------------------------------*/
  3948. MemCpy(pSmartcardExtension->IoRequest.ReplyBuffer,
  3949. pSmartcardExtension->IoRequest.ReplyBufferLength,
  3950. pSmartcardExtension->SmartcardReply.Buffer,
  3951. ulBytesRead);
  3952. *(pSmartcardExtension->IoRequest.Information) = ulBytesRead;
  3953. ExitTransmit2WBP:
  3954. SmartcardDebug(
  3955. DEBUG_TRACE,
  3956. ( "%s!Transmit2WBP: Exit\n",
  3957. DRIVER_NAME,status)
  3958. );
  3959. return status;
  3960. }
  3961. /*****************************************************************************
  3962. Routine Description:
  3963. Arguments:
  3964. Return Value:
  3965. *****************************************************************************/
  3966. VOID
  3967. SCCMN50M_Shift_Msg (PUCHAR pbBuffer,
  3968. ULONG ulMsgLen)
  3969. {
  3970. UCHAR bTmp1, bTmp2;
  3971. int i;
  3972. for (i=(int)ulMsgLen-1; i>=0; i--) {
  3973. bTmp1=(BYTE)((pbBuffer[i] >> 7) & 0x01); /* bTmp1 = bit 7 naechstes byte */
  3974. if (i+1 != (int)ulMsgLen) {
  3975. bTmp2=(BYTE)((pbBuffer[i+1] << 1) | bTmp1);
  3976. pbBuffer[i+1] = bTmp2;
  3977. }
  3978. }
  3979. pbBuffer[0] = (BYTE)(pbBuffer[0] << 1);
  3980. return;
  3981. }
  3982. /*****************************************************************************
  3983. Routine Description:
  3984. Reset Card 4442
  3985. Arguments:
  3986. Return Value:
  3987. *****************************************************************************/
  3988. NTSTATUS
  3989. SCCMN50M_ResetCard2WBP(IN PSMARTCARD_EXTENSION pSmartcardExtension)
  3990. {
  3991. NTSTATUS status = STATUS_SUCCESS;
  3992. BYTE bBuffer[10];
  3993. ULONG ulBytesRead;
  3994. /*-----------------------------------------------------------------------*/
  3995. // Enter Card Reset
  3996. /*-----------------------------------------------------------------------*/
  3997. SmartcardDebug(
  3998. DEBUG_TRACE,
  3999. ( "%s!ResetCard2WBP: Enter\n",
  4000. DRIVER_NAME)
  4001. );
  4002. /*-----------------------------------------------------------------------*/
  4003. // bTxControlByte = 0;
  4004. // bTxLengthByte = 0;
  4005. // bRxControlByte = RESET_CARD;
  4006. // bRxLengthByte = 5;
  4007. /*-----------------------------------------------------------------------*/
  4008. SCCMN50M_SetCardManHeader(pSmartcardExtension,
  4009. 0, // bTxControlByte
  4010. 0, // bTxLengthByte
  4011. COLD_RESET, // bRxControlByte
  4012. 5); // bRxLengthByte
  4013. /*-----------------------------------------------------------------------*/
  4014. // write data to card
  4015. /*-----------------------------------------------------------------------*/
  4016. status = SCCMN50M_WriteCardMan (pSmartcardExtension,
  4017. 0,
  4018. NULL);
  4019. if (NT_ERROR(status)) {
  4020. goto ExitResetCard2WBP;
  4021. }
  4022. /*-----------------------------------------------------------------------*/
  4023. // read CardMan Header
  4024. /*-----------------------------------------------------------------------*/
  4025. pSmartcardExtension->ReaderExtension->ToRHConfig = FALSE;
  4026. status = SCCMN50M_ReadCardMan(pSmartcardExtension,
  4027. 2, &ulBytesRead, bBuffer, sizeof(bBuffer));
  4028. if (NT_ERROR(status)) {
  4029. goto ExitResetCard2WBP;
  4030. }
  4031. if (bBuffer[1] != 5) {
  4032. status = !STATUS_SUCCESS;
  4033. goto ExitResetCard2WBP;
  4034. }
  4035. /*-----------------------------------------------------------------------*/
  4036. // read ATR
  4037. /*-----------------------------------------------------------------------*/
  4038. status = SCCMN50M_ReadCardMan(pSmartcardExtension,
  4039. 5, &ulBytesRead, bBuffer, sizeof(bBuffer));
  4040. if (NT_ERROR(status)) {
  4041. goto ExitResetCard2WBP;
  4042. }
  4043. SmartcardDebug(DEBUG_ATR,("%s!Card Reset ATR : %02x %02x %02x %02x\n",
  4044. DRIVER_NAME,bBuffer[0],bBuffer[1],bBuffer[2],bBuffer[3]));
  4045. ExitResetCard2WBP:
  4046. SmartcardDebug(
  4047. DEBUG_TRACE,
  4048. ( "%s!ResetCard2WBP: Exit %lx\n",
  4049. DRIVER_NAME,status)
  4050. );
  4051. return status;
  4052. }
  4053. /*****************************************************************************
  4054. Routine Description:
  4055. Arguments:
  4056. Return Value:
  4057. *****************************************************************************/
  4058. NTSTATUS
  4059. SCCMN50M_Transmit3WBP(PSMARTCARD_EXTENSION pSmartcardExtension)
  4060. {
  4061. NTSTATUS status = STATUS_SUCCESS;
  4062. UCHAR bWriteBuffer [128];
  4063. UCHAR bReadBuffer [128];
  4064. UCHAR bTxControlByte;
  4065. UCHAR bTxLengthByte;
  4066. UCHAR bRxControlByte;
  4067. UCHAR bRxLengthByte;
  4068. ULONG ulBytesToWrite;
  4069. ULONG ulBytesToRead;
  4070. ULONG ulBitsToWrite;
  4071. ULONG ulBitsToRead;
  4072. ULONG ulBytesRead;
  4073. // ULONG ulBitsRead;
  4074. ULONG ulBytesStillToRead;
  4075. ULONG ulMaxIFSD;
  4076. PCHAR pbInData;
  4077. SmartcardDebug(
  4078. DEBUG_TRACE,
  4079. ( "%s!Transmit3WBP: Enter\n",
  4080. DRIVER_NAME)
  4081. );
  4082. // DBGBreakPoint();
  4083. /*-----------------------------------------------------------------------*/
  4084. /** Power smartcard - if smartcard was removed and reinserted **/
  4085. /*-----------------------------------------------------------------------*/
  4086. if (pSmartcardExtension->ReaderExtension->SyncParameters.fCardPowerRequested == TRUE) {
  4087. status = SCCMN50M_SyncCardPowerOn (pSmartcardExtension);
  4088. if (status != STATUS_SUCCESS) {
  4089. goto ExitTransmit3WBP;
  4090. }
  4091. }
  4092. pbInData = pSmartcardExtension->IoRequest.RequestBuffer + sizeof(SYNC_TRANSFER);
  4093. ulBitsToWrite = ((PSYNC_TRANSFER)(pSmartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToWrite;
  4094. ulBitsToRead = ((PSYNC_TRANSFER)(pSmartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToRead;
  4095. ulBytesToWrite = ulBitsToWrite/8;
  4096. ulBytesToRead = ulBitsToRead/8 + (ulBitsToRead % 8 ? 1 : 0);
  4097. /*-----------------------------------------------------------------------*/
  4098. // check buffer sizes
  4099. /*-----------------------------------------------------------------------*/
  4100. ulMaxIFSD = ATTR_MAX_IFSD_CARDMAN_II;
  4101. if (ulBytesToRead > ulMaxIFSD ||
  4102. ulBytesToRead > pSmartcardExtension->SmartcardReply.BufferSize) {
  4103. status = STATUS_BUFFER_OVERFLOW;
  4104. goto ExitTransmit3WBP;
  4105. }
  4106. if (ulBytesToWrite > pSmartcardExtension->SmartcardRequest.BufferSize) {
  4107. status = STATUS_BUFFER_OVERFLOW;
  4108. goto ExitTransmit3WBP;
  4109. }
  4110. pSmartcardExtension->SmartcardRequest.BufferLength = ulBytesToWrite;
  4111. /*-----------------------------------------------------------------------*/
  4112. // copy data to the Smartcard Request Buffer
  4113. /*-----------------------------------------------------------------------*/
  4114. MemCpy(pSmartcardExtension->SmartcardRequest.Buffer,
  4115. pSmartcardExtension->SmartcardRequest.BufferSize,
  4116. pbInData,
  4117. ulBytesToWrite);
  4118. /*-----------------------------------------------------------------------*/
  4119. // copy data to the write buffer
  4120. /*-----------------------------------------------------------------------*/
  4121. MemCpy(bWriteBuffer,
  4122. sizeof(bWriteBuffer),
  4123. pSmartcardExtension->SmartcardRequest.Buffer,
  4124. ulBytesToWrite);
  4125. /*-----------------------------------------------------------------------*/
  4126. // set SYNC protocol flag for CardMan
  4127. /*-----------------------------------------------------------------------*/
  4128. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_SYN);
  4129. /*-----------------------------------------------------------------------*/
  4130. // build cardman header
  4131. /*-----------------------------------------------------------------------*/
  4132. bTxControlByte = SCCMN50M_CalcTxControlByte(pSmartcardExtension,ulBitsToWrite);
  4133. bTxLengthByte = SCCMN50M_CalcTxLengthByte(pSmartcardExtension,ulBitsToWrite);
  4134. bRxControlByte = SCCMN50M_CalcRxControlByte(pSmartcardExtension,ulBitsToRead);
  4135. bRxLengthByte = SCCMN50M_CalcRxLengthByte(pSmartcardExtension,ulBitsToRead);
  4136. SCCMN50M_SetCardManHeader(pSmartcardExtension,
  4137. bTxControlByte,
  4138. bTxLengthByte,
  4139. bRxControlByte,
  4140. bRxLengthByte);
  4141. /*-----------------------------------------------------------------------*/
  4142. /** write data to card **/
  4143. /*-----------------------------------------------------------------------*/
  4144. status = SCCMN50M_WriteCardMan (pSmartcardExtension,
  4145. ulBytesToWrite,
  4146. bWriteBuffer);
  4147. if (NT_ERROR(status)) {
  4148. goto ExitTransmit3WBP;
  4149. }
  4150. /*-----------------------------------------------------------------------*/
  4151. /** read CardMan Header **/
  4152. /*-----------------------------------------------------------------------*/
  4153. pSmartcardExtension->ReaderExtension->ToRHConfig = FALSE;
  4154. status = SCCMN50M_ReadCardMan(pSmartcardExtension,2,&ulBytesRead,bReadBuffer,sizeof(bReadBuffer));
  4155. if (NT_ERROR(status)) {
  4156. goto ExitTransmit3WBP;
  4157. }
  4158. /*-----------------------------------------------------------------------*/
  4159. // calc data length to receive
  4160. /*-----------------------------------------------------------------------*/
  4161. ulBytesStillToRead = (ULONG)(bReadBuffer[1]);
  4162. if (bReadBuffer[0] & RECEIVE_A8)
  4163. ulBytesStillToRead += 256;
  4164. // read data from card
  4165. status = SCCMN50M_ReadCardMan(pSmartcardExtension,
  4166. ulBytesStillToRead,
  4167. &ulBytesRead,
  4168. bReadBuffer,
  4169. sizeof(bReadBuffer));
  4170. if (NT_ERROR(status)) {
  4171. goto ExitTransmit3WBP;
  4172. }
  4173. /*-----------------------------------------------------------------------*/
  4174. // calculate data length in bits - this value is not used
  4175. /*-----------------------------------------------------------------------*/
  4176. // ulBitsRead = ((ulBytesRead-1) * 8) + ((ulBitsToRead-1 ) & 0x00000007) + 1;
  4177. /*-----------------------------------------------------------------------*/
  4178. // shift the bits in the last byte to the correct position
  4179. /*-----------------------------------------------------------------------*/
  4180. bReadBuffer[ulBytesRead-1] >>= (7 - ((ulBitsToRead-1) & 0x00000007));
  4181. /*-----------------------------------------------------------------------*/
  4182. // copy received bytes to Smartcard Reply Buffer
  4183. /*-----------------------------------------------------------------------*/
  4184. MemCpy(pSmartcardExtension->SmartcardReply.Buffer,
  4185. pSmartcardExtension->SmartcardReply.BufferSize,
  4186. bReadBuffer,
  4187. ulBytesRead);
  4188. pSmartcardExtension->SmartcardReply.BufferLength = ulBytesRead;
  4189. /*-----------------------------------------------------------------------*/
  4190. // copy received bytes to IoReply Buffer
  4191. // this Memcpy should respond to SmartcardRawReply function
  4192. /*-----------------------------------------------------------------------*/
  4193. MemCpy(pSmartcardExtension->IoRequest.ReplyBuffer,
  4194. pSmartcardExtension->IoRequest.ReplyBufferLength,
  4195. pSmartcardExtension->SmartcardReply.Buffer,
  4196. ulBytesRead);
  4197. *pSmartcardExtension->IoRequest.Information = ulBytesRead;
  4198. ExitTransmit3WBP:
  4199. SmartcardDebug(
  4200. DEBUG_TRACE,
  4201. ( "%s!Transmit3WBP: Exit %lx\n",
  4202. DRIVER_NAME,status)
  4203. );
  4204. return status;
  4205. }
  4206. /*****************************************************************************
  4207. Routine Description:
  4208. This function powers a synchronous smart card.
  4209. Arguments:
  4210. Return Value:
  4211. *****************************************************************************/
  4212. NTSTATUS
  4213. SCCMN50M_UseSyncStrategy (
  4214. IN PSMARTCARD_EXTENSION pSmartcardExtension,
  4215. OUT PULONG pulAtrLength,
  4216. OUT PUCHAR pbAtrBuffer,
  4217. IN ULONG ulAtrBufferSize
  4218. )
  4219. {
  4220. NTSTATUS status;
  4221. NTSTATUS DebugStatus;
  4222. UCHAR bReadBuffer[SCARD_ATR_LENGTH];
  4223. ULONG ulBytesRead;
  4224. SmartcardDebug(
  4225. DEBUG_TRACE,
  4226. ( "%s!UseSyncStrategy: Enter\n",
  4227. DRIVER_NAME)
  4228. );
  4229. //DBGBreakPoint();
  4230. SCCMN50M_SetCardManHeader(pSmartcardExtension,0,0,SYNC_ATR_RX_CONTROL,ATR_LEN_SYNC);
  4231. pSmartcardExtension->ReaderExtension->CardManConfig.ResetDelay = SYNC_RESET_DELAY;
  4232. pSmartcardExtension->ReaderExtension->CardManConfig.CardStopBits = 0x02;
  4233. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ALL_FLAGS);
  4234. SCCMN50M_SetSCRControlFlags(pSmartcardExtension,CARD_POWER| IGNORE_PARITY );
  4235. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_SYN);
  4236. status = SCCMN50M_ResyncCardManII(pSmartcardExtension);
  4237. if (status != STATUS_SUCCESS) {
  4238. goto ExitPowerSynchronousCard;
  4239. }
  4240. // write config + header
  4241. status = SCCMN50M_WriteCardMan(pSmartcardExtension,0,NULL);
  4242. if (status != STATUS_SUCCESS) {
  4243. goto ExitPowerSynchronousCard;
  4244. }
  4245. pSmartcardExtension->ReaderExtension->ToRHConfig = FALSE;
  4246. // read state and length
  4247. status = SCCMN50M_ReadCardMan(pSmartcardExtension,2,&ulBytesRead,bReadBuffer,sizeof(bReadBuffer));
  4248. if (status != STATUS_SUCCESS) {
  4249. goto ExitPowerSynchronousCard;
  4250. }
  4251. if (bReadBuffer[1] < MIN_ATR_LEN ) {
  4252. // read all remaining bytes from the CardMan
  4253. DebugStatus = SCCMN50M_ReadCardMan(pSmartcardExtension,bReadBuffer[1],&ulBytesRead,bReadBuffer,sizeof(bReadBuffer));
  4254. status = STATUS_UNRECOGNIZED_MEDIA;
  4255. goto ExitPowerSynchronousCard;
  4256. }
  4257. if (bReadBuffer[1] > ulAtrBufferSize) {
  4258. status = STATUS_BUFFER_OVERFLOW;
  4259. goto ExitPowerSynchronousCard;
  4260. }
  4261. // read ATR
  4262. status = SCCMN50M_ReadCardMan(pSmartcardExtension,bReadBuffer[1],pulAtrLength,pbAtrBuffer,ulAtrBufferSize);
  4263. if (status != STATUS_SUCCESS) {
  4264. goto ExitPowerSynchronousCard;
  4265. }
  4266. if (pbAtrBuffer[0] == 0x00 ||
  4267. pbAtrBuffer[0] == 0xff ) {
  4268. status = STATUS_UNRECOGNIZED_MEDIA;
  4269. goto ExitPowerSynchronousCard;
  4270. }
  4271. pSmartcardExtension->ReaderExtension->fRawModeNecessary = TRUE;
  4272. ExitPowerSynchronousCard:
  4273. SmartcardDebug(
  4274. DEBUG_TRACE,
  4275. ( "%s!UseSyncStrategy: Exit %lx\n",
  4276. DRIVER_NAME,status)
  4277. );
  4278. SCCMN50M_ClearSCRControlFlags(pSmartcardExtension,IGNORE_PARITY | CM2_GET_ATR);
  4279. SCCMN50M_ClearCardManHeader(pSmartcardExtension);
  4280. return status;
  4281. }
  4282. /*****************************************************************************
  4283. Routine Description:
  4284. This function checks if the inserted card is a synchronous one
  4285. Arguments:
  4286. Return Value:
  4287. *****************************************************************************/
  4288. BOOLEAN
  4289. SCCMN50M_IsAsynchronousSmartCard(
  4290. IN PSMARTCARD_EXTENSION pSmartcardExtension
  4291. )
  4292. {
  4293. NTSTATUS status;
  4294. UCHAR ReadBuffer[3];
  4295. ULONG ulBytesRead;
  4296. BOOLEAN fIsAsynchronousSmartCard = TRUE;
  4297. UCHAR abATR[33];
  4298. SmartcardDebug(
  4299. DEBUG_TRACE,
  4300. ( "%s!IsAsynchronousSmartcard: Enter \n",
  4301. DRIVER_NAME)
  4302. );
  4303. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant = 200;
  4304. // 3MHz smart card ?
  4305. SCCMN50M_SetCardManHeader(pSmartcardExtension,0,0,0,1);
  4306. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ALL_FLAGS);
  4307. SCCMN50M_SetSCRControlFlags(pSmartcardExtension,CARD_POWER| IGNORE_PARITY | CM2_GET_ATR);
  4308. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_3MHZ);
  4309. // write config + header
  4310. status = SCCMN50M_WriteCardMan(pSmartcardExtension,0,NULL);
  4311. if (status != STATUS_SUCCESS) {
  4312. goto ExitIsAsynchronousSmartCard;
  4313. }
  4314. pSmartcardExtension->ReaderExtension->ToRHConfig = FALSE;
  4315. // read state and length
  4316. status = SCCMN50M_ReadCardMan(pSmartcardExtension,2,&ulBytesRead,ReadBuffer,sizeof(ReadBuffer));
  4317. if (status == STATUS_SUCCESS &&
  4318. ReadBuffer[1] == 0x01 ) {
  4319. goto ExitIsAsynchronousSmartCard;
  4320. }
  4321. // ---------------------------------------
  4322. // power off card
  4323. // ---------------------------------------
  4324. status = SCCMN50M_PowerOff(pSmartcardExtension);
  4325. if (status != STATUS_SUCCESS) {
  4326. goto ExitIsAsynchronousSmartCard;
  4327. }
  4328. // 5MHz smart card ?
  4329. SCCMN50M_SetCardManHeader(pSmartcardExtension,0,0,0,1);
  4330. SCCMN50M_ClearCardControlFlags(pSmartcardExtension,ALL_FLAGS);
  4331. SCCMN50M_SetSCRControlFlags(pSmartcardExtension,CARD_POWER| IGNORE_PARITY | CM2_GET_ATR);
  4332. SCCMN50M_SetCardControlFlags(pSmartcardExtension,ENABLE_5MHZ);
  4333. // write config + header
  4334. status = SCCMN50M_WriteCardMan(pSmartcardExtension,0,NULL);
  4335. if (status != STATUS_SUCCESS) {
  4336. goto ExitIsAsynchronousSmartCard;
  4337. }
  4338. pSmartcardExtension->ReaderExtension->ToRHConfig = FALSE;
  4339. // read state and length
  4340. status = SCCMN50M_ReadCardMan(pSmartcardExtension,2,&ulBytesRead,ReadBuffer,sizeof(ReadBuffer));
  4341. if (status == STATUS_SUCCESS &&
  4342. ReadBuffer[1] == 0x01 ) {
  4343. goto ExitIsAsynchronousSmartCard;
  4344. }
  4345. // now we assume that it is a synchronous smart card
  4346. fIsAsynchronousSmartCard = FALSE;
  4347. // ---------------------------------------
  4348. // power off card
  4349. // ---------------------------------------
  4350. status = SCCMN50M_PowerOff(pSmartcardExtension);
  4351. if (status != STATUS_SUCCESS) {
  4352. goto ExitIsAsynchronousSmartCard;
  4353. }
  4354. ExitIsAsynchronousSmartCard:
  4355. pSmartcardExtension->ReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant = DEFAULT_READ_TOTAL_TIMEOUT_CONSTANT;
  4356. SmartcardDebug(
  4357. DEBUG_TRACE,
  4358. ( "%s!IsAsynchronousSmartcard: Exit \n",
  4359. DRIVER_NAME)
  4360. );
  4361. return fIsAsynchronousSmartCard;
  4362. }
  4363. /*****************************************************************************
  4364. * History:
  4365. * $Log: sccmcb.c $
  4366. * Revision 1.7 2001/01/22 08:39:41 WFrischauf
  4367. * No comment given
  4368. *
  4369. * Revision 1.6 2000/09/25 10:46:22 WFrischauf
  4370. * No comment given
  4371. *
  4372. * Revision 1.5 2000/08/24 09:05:44 TBruendl
  4373. * No comment given
  4374. *
  4375. * Revision 1.4 2000/08/16 08:24:04 TBruendl
  4376. * warning :uninitialized memory removed
  4377. *
  4378. * Revision 1.3 2000/07/28 09:24:12 TBruendl
  4379. * Changes for OMNIKEY on Whistler CD
  4380. *
  4381. * Revision 1.16 2000/06/27 11:56:28 TBruendl
  4382. * workaraound for SAMOR smart cards with invalid ATR (ITSEC)
  4383. *
  4384. * Revision 1.15 2000/06/08 10:08:47 TBruendl
  4385. * bug fix : warm reset for ScfW
  4386. *
  4387. * Revision 1.14 2000/05/23 09:58:26 TBruendl
  4388. * OMNIKEY 3.0.0.1
  4389. *
  4390. * Revision 1.13 2000/04/13 08:07:22 TBruendl
  4391. * PPS bug fix for SCfW
  4392. *
  4393. * Revision 1.12 2000/04/04 07:52:18 TBruendl
  4394. * problem with the new WfsC fixed
  4395. *
  4396. * Revision 1.11 2000/03/03 09:50:50 TBruendl
  4397. * No comment given
  4398. *
  4399. * Revision 1.10 2000/03/01 09:32:04 TBruendl
  4400. * R02.20.0
  4401. *
  4402. * Revision 1.9 2000/01/04 10:40:33 TBruendl
  4403. * bug fix: status instead of DebugStatus used
  4404. *
  4405. * Revision 1.8 1999/12/16 14:10:16 TBruendl
  4406. * After transparent mode has been left, the status is read from the CardMan to be sure that
  4407. * the new settings are effective.
  4408. *
  4409. * Revision 1.6 1999/12/13 07:55:38 TBruendl
  4410. * Bug fix for P+ druing initialization
  4411. * PTS for 4.9 mhz smartcards added
  4412. *
  4413. * Revision 1.5 1999/11/04 07:53:21 WFrischauf
  4414. * bug fixes due to error reports 2 - 7
  4415. *
  4416. * Revision 1.4 1999/07/12 12:49:04 TBruendl
  4417. * Bug fix: Resync after GET_DEVICE_DESCRIPTION
  4418. * Power On SLE4428
  4419. *
  4420. * Revision 1.3 1999/06/10 09:03:57 TBruendl
  4421. * No comment given
  4422. *
  4423. * Revision 1.2 1999/02/25 10:12:22 TBruendl
  4424. * No comment given
  4425. *
  4426. * Revision 1.1 1999/02/02 13:34:37 TBruendl
  4427. * This is the first release (R01.00) of the IFD handler for CardMan running under NT5.0.
  4428. *
  4429. *
  4430. *****************************************************************************/