Source code of Windows XP (NT5)
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.

996 lines
34 KiB

  1. /*****************************************************************************
  2. @doc INT EXT
  3. ******************************************************************************
  4. * $ProjectName: $
  5. * $ProjectRevision: $
  6. *-----------------------------------------------------------------------------
  7. * $Source: z:/pr/cmeu0/sw/sccmusbm.ms/rcs/scusbsyn.c $
  8. * $Revision: 1.3 $
  9. *-----------------------------------------------------------------------------
  10. * $Author: TBruendl $
  11. *-----------------------------------------------------------------------------
  12. * History: see EOF
  13. *-----------------------------------------------------------------------------
  14. *
  15. * Copyright 2000 OMNIKEY AG
  16. ******************************************************************************/
  17. #include "wdm.h"
  18. #include "stdarg.h"
  19. #include "stdio.h"
  20. #include "usbdi.h"
  21. #include "usbdlib.h"
  22. #include "sccmusbm.h"
  23. /*****************************************************************************
  24. Routine Description: Powers a synchronous card and reads the ATR
  25. Arguments:
  26. Return Value:
  27. *****************************************************************************/
  28. NTSTATUS
  29. CMUSB_PowerOnSynchronousCard (
  30. IN PSMARTCARD_EXTENSION smartcardExtension,
  31. IN PUCHAR pbATR,
  32. OUT PULONG pulATRLength
  33. )
  34. {
  35. PDEVICE_OBJECT deviceObject;
  36. NTSTATUS status = STATUS_SUCCESS;
  37. NTSTATUS DebugStatus;
  38. UCHAR abMaxAtrBuffer[SCARD_ATR_LENGTH];
  39. UCHAR abSendBuffer[CMUSB_SYNCH_BUFFER_SIZE];
  40. UCHAR bResetMode;
  41. SmartcardDebug(DEBUG_TRACE,
  42. ("%s!PowerOnSynchronousCard: Enter\n",DRIVER_NAME));
  43. deviceObject = smartcardExtension->OsData->DeviceObject;
  44. // in case of warm reset we have to power off the card first
  45. if (smartcardExtension->MinorIoControlCode != SCARD_COLD_RESET)
  46. {
  47. status = CMUSB_PowerOffCard (smartcardExtension );
  48. if (status != STATUS_SUCCESS)
  49. {
  50. // if we can't turn off power there must be a serious error
  51. goto ExitPowerOnSynchronousCard;
  52. }
  53. }
  54. // set card parameters
  55. smartcardExtension->ReaderExtension->CardParameters.bBaudRate = 0;
  56. smartcardExtension->ReaderExtension->CardParameters.bCardType = CMUSB_SMARTCARD_SYNCHRONOUS;
  57. smartcardExtension->ReaderExtension->CardParameters.bStopBits = 0;
  58. status = CMUSB_SetCardParameters (deviceObject,
  59. smartcardExtension->ReaderExtension->CardParameters.bCardType,
  60. smartcardExtension->ReaderExtension->CardParameters.bBaudRate,
  61. smartcardExtension->ReaderExtension->CardParameters.bStopBits);
  62. if (status != STATUS_SUCCESS)
  63. {
  64. // if we can't set the card parameters there must be a serious error
  65. goto ExitPowerOnSynchronousCard;
  66. }
  67. RtlFillMemory((PVOID)abMaxAtrBuffer,
  68. sizeof(abMaxAtrBuffer),
  69. 0x00);
  70. // resync CardManUSB by reading the status byte
  71. // still necessary with synchronous cards ???
  72. smartcardExtension->SmartcardRequest.BufferLength = 0;
  73. status = CMUSB_WriteP0(deviceObject,
  74. 0x20, //bRequest,
  75. 0x00, //bValueLo,
  76. 0x00, //bValueHi,
  77. 0x00, //bIndexLo,
  78. 0x00 //bIndexHi,
  79. );
  80. if (status != STATUS_SUCCESS)
  81. {
  82. // if we can't read the status there must be a serious error
  83. goto ExitPowerOnSynchronousCard;
  84. }
  85. smartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1;
  86. status = CMUSB_ReadP1(deviceObject);
  87. if (status == STATUS_DEVICE_DATA_ERROR)
  88. {
  89. DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject);
  90. goto ExitPowerOnSynchronousCard;
  91. }
  92. else if (status != STATUS_SUCCESS)
  93. {
  94. // if we can't read the status there must be a serious error
  95. goto ExitPowerOnSynchronousCard;
  96. }
  97. // check if card is really inserted
  98. if (smartcardExtension->SmartcardReply.Buffer[0] == 0x00)
  99. {
  100. status = STATUS_NO_MEDIA;
  101. goto ExitPowerOnSynchronousCard;
  102. }
  103. // issue power on command
  104. // according to WZ nothing is sent back
  105. smartcardExtension->SmartcardRequest.BufferLength = 0;
  106. status = CMUSB_WriteP0(deviceObject,
  107. 0x10, //bRequest,
  108. SMARTCARD_COLD_RESET, //bValueLo,
  109. 0x00, //bValueHi,
  110. 0x00, //bIndexLo,
  111. 0x00 //bIndexHi,
  112. );
  113. if (status != STATUS_SUCCESS)
  114. {
  115. // if we can't issue the power on command there must be a serious error
  116. goto ExitPowerOnSynchronousCard;
  117. }
  118. // build control code for ATR
  119. abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 1,0,0,0);
  120. abSendBuffer[1]=CMUSB_CalcSynchControl(1,1,0,0, 1,0,0,0);
  121. abSendBuffer[2]=CMUSB_CalcSynchControl(0,0,0,0, 0,0,0,0);
  122. // fill memory so that we can discard first byte
  123. RtlFillMemory((PVOID)&abSendBuffer[3],5,abSendBuffer[2]);
  124. // now get 4 bytes ATR -> 32 bytes to send
  125. abSendBuffer[8]=CMUSB_CalcSynchControl(0,0,0,0, 0,1,0,0);
  126. RtlFillMemory((PVOID)&abSendBuffer[9],31,abSendBuffer[8]);
  127. //now set clock to low to finish operation
  128. //and of course additional fill bytes
  129. abSendBuffer[40]=CMUSB_CalcSynchControl(0,0,0,0, 0,0,0,0);
  130. RtlFillMemory((PVOID)&abSendBuffer[41],7,abSendBuffer[40]);
  131. // now send command type 08 to CardManUSB
  132. smartcardExtension->SmartcardRequest.BufferLength = 48;
  133. RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer,
  134. (PVOID) abSendBuffer,
  135. smartcardExtension->SmartcardRequest.BufferLength);
  136. status = CMUSB_WriteP0(deviceObject,
  137. 0x08, //bRequest,
  138. 0x00, //bValueLo,
  139. 0x00, //bValueHi,
  140. 0x00, //bIndexLo,
  141. 0x00 //bIndexHi,
  142. );
  143. if (status != STATUS_SUCCESS)
  144. {
  145. // if we can't write ATR command there must be a serious error
  146. if (status == STATUS_DEVICE_DATA_ERROR)
  147. {
  148. //error mapping necessary because there are CardManUSB
  149. //which have no support for synchronous cards
  150. status = STATUS_UNRECOGNIZED_MEDIA;
  151. }
  152. goto ExitPowerOnSynchronousCard;
  153. }
  154. status = CMUSB_ReadP1(deviceObject);
  155. if (status == STATUS_DEVICE_DATA_ERROR)
  156. {
  157. DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject);
  158. goto ExitPowerOnSynchronousCard;
  159. }
  160. else if (status != STATUS_SUCCESS)
  161. {
  162. // if we can't read the ATR -> there must be a serious error
  163. goto ExitPowerOnSynchronousCard;
  164. }
  165. if (smartcardExtension->SmartcardReply.BufferLength!=6)
  166. {
  167. // 48 bytes sent but not 6 bytes received
  168. // -> something went wrong
  169. status=STATUS_DEVICE_DATA_ERROR;
  170. goto ExitPowerOnSynchronousCard;
  171. }
  172. // now bytes 1-4 in SmartcardReply.Buffer should be ATR
  173. SmartcardDebug(DEBUG_ATR,
  174. ("%s!ATR = %02x %02x %02x %02x\n",DRIVER_NAME,
  175. smartcardExtension->SmartcardReply.Buffer[1],
  176. smartcardExtension->SmartcardReply.Buffer[2],
  177. smartcardExtension->SmartcardReply.Buffer[3],
  178. smartcardExtension->SmartcardReply.Buffer[4]));
  179. // check if ATR != 0xFF -> synchronous card
  180. if (smartcardExtension->SmartcardReply.Buffer[1]==0xFF &&
  181. smartcardExtension->SmartcardReply.Buffer[2]==0xFF &&
  182. smartcardExtension->SmartcardReply.Buffer[3]==0xFF &&
  183. smartcardExtension->SmartcardReply.Buffer[4]==0xFF )
  184. {
  185. status = STATUS_UNRECOGNIZED_MEDIA;
  186. *pulATRLength = 0;
  187. goto ExitPowerOnSynchronousCard;
  188. }
  189. //it seems we have a synchronous smart card and a valid ATR
  190. //let�s set the variables
  191. smartcardExtension->ReaderExtension->fRawModeNecessary = TRUE;
  192. *pulATRLength = 4;
  193. RtlCopyBytes((PVOID) pbATR,
  194. (PVOID) &(smartcardExtension->SmartcardReply.Buffer[1]),
  195. *pulATRLength );
  196. ExitPowerOnSynchronousCard:
  197. if (status!=STATUS_SUCCESS)
  198. {
  199. // turn off VCC again
  200. CMUSB_PowerOffCard (smartcardExtension );
  201. // ignor status
  202. }
  203. SmartcardDebug(DEBUG_TRACE,
  204. ("%s!PowerOnSynchronousCard: Exit %lx\n",DRIVER_NAME,status));
  205. return status;
  206. }
  207. /*****************************************************************************
  208. Routine Description: Data transfer to synchronous cards SLE 4442/4432
  209. Arguments:
  210. Return Value:
  211. *****************************************************************************/
  212. NTSTATUS
  213. CMUSB_Transmit2WBP (
  214. IN PSMARTCARD_EXTENSION smartcardExtension
  215. )
  216. {
  217. PDEVICE_OBJECT deviceObject;
  218. NTSTATUS status = STATUS_SUCCESS;
  219. NTSTATUS DebugStatus;
  220. PCHAR pbInData;
  221. ULONG ulBytesToRead;
  222. ULONG ulBitsToRead;
  223. ULONG ulBytesToReadThisStep;
  224. ULONG ulBytesRead;
  225. UCHAR abSendBuffer[CMUSB_SYNCH_BUFFER_SIZE];
  226. int i;
  227. SmartcardDebug(DEBUG_TRACE,
  228. ("%s!Transmit2WBP: Enter\n",DRIVER_NAME));
  229. deviceObject = smartcardExtension->OsData->DeviceObject;
  230. // resync CardManUSB by reading the status byte
  231. // still necessary with synchronous cards ???
  232. smartcardExtension->SmartcardRequest.BufferLength = 0;
  233. status = CMUSB_WriteP0(deviceObject,
  234. 0x20, //bRequest,
  235. 0x00, //bValueLo,
  236. 0x00, //bValueHi,
  237. 0x00, //bIndexLo,
  238. 0x00 //bIndexHi,
  239. );
  240. if (status != STATUS_SUCCESS)
  241. {
  242. // if we can't read the status there must be a serious error
  243. goto ExitTransmit2WBP;
  244. }
  245. smartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1;
  246. status = CMUSB_ReadP1(deviceObject);
  247. if (status == STATUS_DEVICE_DATA_ERROR)
  248. {
  249. DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject);
  250. goto ExitTransmit2WBP;
  251. }
  252. else if (status != STATUS_SUCCESS)
  253. {
  254. // if we can't read the status there must be a serious error
  255. goto ExitTransmit2WBP;
  256. }
  257. // check if card is really inserted
  258. if (smartcardExtension->SmartcardReply.Buffer[0] == 0x00)
  259. {
  260. // it is not sure, which error messages are accepted
  261. // status = STATUS_NO_MEDIA_IN_DEVICE;
  262. status = STATUS_UNRECOGNIZED_MEDIA;
  263. goto ExitTransmit2WBP;
  264. }
  265. pbInData = smartcardExtension->IoRequest.RequestBuffer + sizeof(SYNC_TRANSFER);
  266. ulBitsToRead = ((PSYNC_TRANSFER)(smartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToRead;
  267. ulBytesToRead = ulBitsToRead/8 + (ulBitsToRead % 8 ? 1 : 0);
  268. // ulBitsToWrite = ((PSYNC_TRANSFER)(smartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToWrite;
  269. // ulBytesToWrite = ulBitsToWrite/8;
  270. if (smartcardExtension->IoRequest.ReplyBufferLength < ulBytesToRead)
  271. {
  272. status = STATUS_BUFFER_OVERFLOW;
  273. goto ExitTransmit2WBP;
  274. }
  275. // send command
  276. status=CMUSB_SendCommand2WBP(smartcardExtension, pbInData);
  277. if (status != STATUS_SUCCESS)
  278. {
  279. // if we can't send the command -> proceeding is sensless
  280. goto ExitTransmit2WBP;
  281. }
  282. // now we have to differenciate, wheter card is in
  283. // outgoing data mode (after read command) or
  284. // in processing mode (after write/erase command)
  285. switch (*pbInData)
  286. {
  287. case SLE4442_READ:
  288. case SLE4442_READ_PROT_MEM:
  289. case SLE4442_READ_SEC_MEM:
  290. // outgoing data mode
  291. //now read data
  292. abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,1,0,0);
  293. RtlFillMemory((PVOID)&abSendBuffer[1],ATTR_MAX_IFSD_SYNCHRON_USB-1,abSendBuffer[0]);
  294. //read data in 6 byte packages
  295. ulBytesRead=0;
  296. do
  297. {
  298. if ((ulBytesToRead - ulBytesRead) > ATTR_MAX_IFSD_SYNCHRON_USB/8)
  299. ulBytesToReadThisStep = ATTR_MAX_IFSD_SYNCHRON_USB/8;
  300. else
  301. ulBytesToReadThisStep = ulBytesToRead - ulBytesRead;
  302. // now send command type 08 to CardManUSB
  303. smartcardExtension->SmartcardRequest.BufferLength = ulBytesToReadThisStep*8;
  304. RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer,
  305. (PVOID) abSendBuffer,
  306. smartcardExtension->SmartcardRequest.BufferLength);
  307. status = CMUSB_WriteP0(deviceObject,
  308. 0x08, //bRequest,
  309. 0x00, //bValueLo,
  310. 0x00, //bValueHi,
  311. 0x00, //bIndexLo,
  312. 0x00 //bIndexHi,
  313. );
  314. if (status != STATUS_SUCCESS)
  315. {
  316. // if we can't write command there must be a serious error
  317. goto ExitTransmit2WBP;
  318. }
  319. status = CMUSB_ReadP1(deviceObject);
  320. if (status == STATUS_DEVICE_DATA_ERROR)
  321. {
  322. DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject);
  323. goto ExitTransmit2WBP;
  324. }
  325. else if (status != STATUS_SUCCESS)
  326. {
  327. // if we can't read there must be a serious error
  328. goto ExitTransmit2WBP;
  329. }
  330. if (smartcardExtension->SmartcardReply.BufferLength!=ulBytesToReadThisStep)
  331. {
  332. // wrong number of bytes read
  333. // -> something went wrong
  334. status=STATUS_DEVICE_DATA_ERROR;
  335. goto ExitTransmit2WBP;
  336. }
  337. RtlCopyBytes((PVOID) &(smartcardExtension->IoRequest.ReplyBuffer[ulBytesRead]),
  338. (PVOID) smartcardExtension->SmartcardReply.Buffer,
  339. smartcardExtension->SmartcardReply.BufferLength);
  340. ulBytesRead+=smartcardExtension->SmartcardReply.BufferLength;
  341. }
  342. while ((status == STATUS_SUCCESS) && (ulBytesToRead > ulBytesRead));
  343. *(smartcardExtension->IoRequest.Information)=ulBytesRead;
  344. if (status!=STATUS_SUCCESS)
  345. {
  346. goto ExitTransmit2WBP;
  347. }
  348. // according to datasheet, clock should be set to low now
  349. // this is not necessary, because this is done before next command
  350. // or card is reseted respectivly
  351. break;
  352. case SLE4442_WRITE:
  353. case SLE4442_WRITE_PROT_MEM:
  354. case SLE4442_COMPARE_PIN:
  355. case SLE4442_UPDATE_SEC_MEM:
  356. // processing mode
  357. abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,1,0,0);
  358. RtlFillMemory((PVOID)&abSendBuffer[1],ATTR_MAX_IFSD_SYNCHRON_USB-1,abSendBuffer[0]);
  359. do
  360. {
  361. // now send command type 08 to CardManUSB
  362. smartcardExtension->SmartcardRequest.BufferLength = ATTR_MAX_IFSD_SYNCHRON_USB;
  363. RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer,
  364. (PVOID) abSendBuffer,
  365. smartcardExtension->SmartcardRequest.BufferLength);
  366. status = CMUSB_WriteP0(deviceObject,
  367. 0x08, //bRequest,
  368. 0x00, //bValueLo,
  369. 0x00, //bValueHi,
  370. 0x00, //bIndexLo,
  371. 0x00 //bIndexHi,
  372. );
  373. if (status != STATUS_SUCCESS)
  374. {
  375. // if we can't write command there must be a serious error
  376. goto ExitTransmit2WBP;
  377. }
  378. status = CMUSB_ReadP1(deviceObject);
  379. if (status == STATUS_DEVICE_DATA_ERROR)
  380. {
  381. DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject);
  382. goto ExitTransmit2WBP;
  383. }
  384. else if (status != STATUS_SUCCESS)
  385. {
  386. // if we can't read there must be a serious error
  387. goto ExitTransmit2WBP;
  388. }
  389. if (smartcardExtension->SmartcardReply.BufferLength!=ATTR_MAX_IFSD_SYNCHRON_USB/8)
  390. {
  391. // wrong number of bytes read
  392. // -> something went wrong
  393. status=STATUS_DEVICE_DATA_ERROR;
  394. goto ExitTransmit2WBP;
  395. }
  396. /* not necessary this way, check last byte only
  397. ulReplySum=0;
  398. for (i=0;i<(int)smartcardExtension->SmartcardReply.BufferLength;i++)
  399. {
  400. ulReplySum+=smartcardExtension->SmartcardReply.Buffer[i];
  401. }
  402. */
  403. }
  404. while ((status == STATUS_SUCCESS) &&
  405. (smartcardExtension->SmartcardReply.Buffer[smartcardExtension->SmartcardReply.BufferLength-1]==0));
  406. *(smartcardExtension->IoRequest.Information)=0;
  407. if (status!=STATUS_SUCCESS)
  408. {
  409. goto ExitTransmit2WBP;
  410. }
  411. // according to datasheet, clock should be set to low now
  412. // this is not necessary, because this is done before next command
  413. // or card is reseted respectivly
  414. break;
  415. default:
  416. // should not happen
  417. status=STATUS_ILLEGAL_INSTRUCTION;
  418. goto ExitTransmit2WBP;
  419. }
  420. ExitTransmit2WBP:
  421. SmartcardDebug(DEBUG_TRACE,
  422. ("%s!Transmit2WBP: Exit %lx\n",DRIVER_NAME,status));
  423. return status;
  424. }
  425. /*****************************************************************************
  426. Routine Description: Transmits a command (3 Bytes) to a SLE 4442/4432
  427. Arguments:
  428. Return Value:
  429. *****************************************************************************/
  430. NTSTATUS
  431. CMUSB_SendCommand2WBP (
  432. IN PSMARTCARD_EXTENSION smartcardExtension,
  433. IN PUCHAR pbCommandData
  434. )
  435. {
  436. PDEVICE_OBJECT deviceObject;
  437. NTSTATUS status = STATUS_SUCCESS;
  438. NTSTATUS DebugStatus;
  439. UCHAR abSendBuffer[CMUSB_SYNCH_BUFFER_SIZE];
  440. UCHAR* pByte;
  441. UCHAR bValue;
  442. int i,j;
  443. SmartcardDebug(DEBUG_TRACE,
  444. ("%s!SendCommand2WBP: Enter\n",DRIVER_NAME));
  445. SmartcardDebug(DEBUG_PROTOCOL,
  446. ("%s!SendCommand2WBP: 4442 Command = %02x %02x %02x\n",DRIVER_NAME,
  447. pbCommandData[0],
  448. pbCommandData[1],
  449. pbCommandData[2]));
  450. deviceObject = smartcardExtension->OsData->DeviceObject;
  451. // build control code for command to send
  452. // command is in first 3 Bytes of pbInData
  453. abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,0,0,0);
  454. abSendBuffer[1]=CMUSB_CalcSynchControl(0,0,1,1, 0,1,1,1);
  455. abSendBuffer[2]=CMUSB_CalcSynchControl(0,1,1,0, 0,1,1,0);
  456. pByte=&abSendBuffer[3];
  457. for (j=0;j<3;j++)
  458. {
  459. for (i=0;i<8;i++)
  460. {
  461. bValue=(pbCommandData[j]&(1<<i));
  462. *pByte=CMUSB_CalcSynchControl(0,0,1,bValue, 0,1,1,bValue);
  463. pByte++;
  464. }
  465. }
  466. abSendBuffer[27]=CMUSB_CalcSynchControl(0,0,1,0, 0,1,1,0);
  467. abSendBuffer[28]=CMUSB_CalcSynchControl(0,1,1,0, 0,1,1,0);
  468. RtlFillMemory((PVOID)&abSendBuffer[29],2,abSendBuffer[28]);
  469. abSendBuffer[31]=CMUSB_CalcSynchControl(0,1,1,0, 0,1,1,1);
  470. // now send command type 08 to CardManUSB
  471. smartcardExtension->SmartcardRequest.BufferLength = 32;
  472. RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer,
  473. (PVOID) abSendBuffer,
  474. smartcardExtension->SmartcardRequest.BufferLength);
  475. status = CMUSB_WriteP0(deviceObject,
  476. 0x08, //bRequest,
  477. 0x00, //bValueLo,
  478. 0x00, //bValueHi,
  479. 0x00, //bIndexLo,
  480. 0x00 //bIndexHi,
  481. );
  482. if (status != STATUS_SUCCESS)
  483. {
  484. // if we can't write command there must be a serious error
  485. goto ExitSendCommand2WBP;
  486. }
  487. status = CMUSB_ReadP1(deviceObject);
  488. if (status == STATUS_DEVICE_DATA_ERROR)
  489. {
  490. DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject);
  491. goto ExitSendCommand2WBP;
  492. }
  493. else if (status != STATUS_SUCCESS)
  494. {
  495. // if we can't read there must be a serious error
  496. goto ExitSendCommand2WBP;
  497. }
  498. if (smartcardExtension->SmartcardReply.BufferLength!=4)
  499. {
  500. // 32 bytes sent but not 4 bytes received
  501. // -> something went wrong
  502. status=STATUS_DEVICE_DATA_ERROR;
  503. goto ExitSendCommand2WBP;
  504. }
  505. ExitSendCommand2WBP:
  506. SmartcardDebug(DEBUG_TRACE,
  507. ("%s!SendCommand2WBP: Exit %lx\n",DRIVER_NAME,status));
  508. return status;
  509. }
  510. /*****************************************************************************
  511. Routine Description: Data transfer to synchronous cards SLE 4428/4418
  512. Arguments:
  513. Return Value:
  514. *****************************************************************************/
  515. NTSTATUS
  516. CMUSB_Transmit3WBP (
  517. IN PSMARTCARD_EXTENSION smartcardExtension
  518. )
  519. {
  520. PDEVICE_OBJECT deviceObject;
  521. NTSTATUS status = STATUS_SUCCESS;
  522. NTSTATUS DebugStatus;
  523. PCHAR pbInData;
  524. ULONG ulBytesToRead;
  525. ULONG ulBitsToRead;
  526. ULONG ulBytesToReadThisStep;
  527. ULONG ulBytesRead;
  528. UCHAR abSendBuffer[CMUSB_SYNCH_BUFFER_SIZE];
  529. int i;
  530. SmartcardDebug(DEBUG_TRACE,
  531. ("%s!Transmit3WBP: Enter\n",DRIVER_NAME));
  532. deviceObject = smartcardExtension->OsData->DeviceObject;
  533. // resync CardManUSB by reading the status byte
  534. // still necessary with synchronous cards ???
  535. smartcardExtension->SmartcardRequest.BufferLength = 0;
  536. status = CMUSB_WriteP0(deviceObject,
  537. 0x20, //bRequest,
  538. 0x00, //bValueLo,
  539. 0x00, //bValueHi,
  540. 0x00, //bIndexLo,
  541. 0x00 //bIndexHi,
  542. );
  543. if (status != STATUS_SUCCESS)
  544. {
  545. // if we can't read the status there must be a serious error
  546. goto ExitTransmit3WBP;
  547. }
  548. smartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1;
  549. status = CMUSB_ReadP1(deviceObject);
  550. if (status == STATUS_DEVICE_DATA_ERROR)
  551. {
  552. DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject);
  553. goto ExitTransmit3WBP;
  554. }
  555. else if (status != STATUS_SUCCESS)
  556. {
  557. // if we can't read the status there must be a serious error
  558. goto ExitTransmit3WBP;
  559. }
  560. // check if card is really inserted
  561. if (smartcardExtension->SmartcardReply.Buffer[0] == 0x00)
  562. {
  563. // it is not sure, which error messages are accepted
  564. // status = STATUS_NO_MEDIA_IN_DEVICE;
  565. status = STATUS_UNRECOGNIZED_MEDIA;
  566. goto ExitTransmit3WBP;
  567. }
  568. pbInData = smartcardExtension->IoRequest.RequestBuffer + sizeof(SYNC_TRANSFER);
  569. ulBitsToRead = ((PSYNC_TRANSFER)(smartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToRead;
  570. ulBytesToRead = ulBitsToRead/8 + (ulBitsToRead % 8 ? 1 : 0);
  571. // ulBitsToWrite = ((PSYNC_TRANSFER)(smartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToWrite;
  572. // ulBytesToWrite = ulBitsToWrite/8;
  573. if (smartcardExtension->IoRequest.ReplyBufferLength < ulBytesToRead)
  574. {
  575. status = STATUS_BUFFER_OVERFLOW;
  576. goto ExitTransmit3WBP;
  577. }
  578. // send command
  579. status=CMUSB_SendCommand3WBP(smartcardExtension, pbInData);
  580. if (status != STATUS_SUCCESS)
  581. {
  582. // if we can't send the command -> proceeding is useless
  583. goto ExitTransmit3WBP;
  584. }
  585. // now we have to differenciate, wheter card is in
  586. // outgoing data mode (after read command) or
  587. // in processing mode (after write/erase command)
  588. switch (*pbInData & 0x3F)
  589. {
  590. case SLE4428_READ:
  591. case SLE4428_READ_PROT:
  592. // outgoing data mode
  593. //now read data
  594. abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,1,0,0);
  595. RtlFillMemory((PVOID)&abSendBuffer[1],ATTR_MAX_IFSD_SYNCHRON_USB-1,abSendBuffer[0]);
  596. //read data in 6 byte packages
  597. ulBytesRead=0;
  598. do
  599. {
  600. if ((ulBytesToRead - ulBytesRead) > ATTR_MAX_IFSD_SYNCHRON_USB/8)
  601. ulBytesToReadThisStep = ATTR_MAX_IFSD_SYNCHRON_USB/8;
  602. else
  603. ulBytesToReadThisStep = ulBytesToRead - ulBytesRead;
  604. // now send command type 08 to CardManUSB
  605. smartcardExtension->SmartcardRequest.BufferLength = ulBytesToReadThisStep*8;
  606. RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer,
  607. (PVOID) abSendBuffer,
  608. smartcardExtension->SmartcardRequest.BufferLength);
  609. status = CMUSB_WriteP0(deviceObject,
  610. 0x08, //bRequest,
  611. 0x00, //bValueLo,
  612. 0x00, //bValueHi,
  613. 0x00, //bIndexLo,
  614. 0x00 //bIndexHi,
  615. );
  616. if (status != STATUS_SUCCESS)
  617. {
  618. // if we can't write command there must be a serious error
  619. goto ExitTransmit3WBP;
  620. }
  621. status = CMUSB_ReadP1(deviceObject);
  622. if (status == STATUS_DEVICE_DATA_ERROR)
  623. {
  624. DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject);
  625. goto ExitTransmit3WBP;
  626. }
  627. else if (status != STATUS_SUCCESS)
  628. {
  629. // if we can't read there must be a serious error
  630. goto ExitTransmit3WBP;
  631. }
  632. if (smartcardExtension->SmartcardReply.BufferLength!=ulBytesToReadThisStep)
  633. {
  634. // wrong number of bytes read
  635. // -> something went wrong
  636. status=STATUS_DEVICE_DATA_ERROR;
  637. goto ExitTransmit3WBP;
  638. }
  639. RtlCopyBytes((PVOID) &(smartcardExtension->IoRequest.ReplyBuffer[ulBytesRead]),
  640. (PVOID) smartcardExtension->SmartcardReply.Buffer,
  641. smartcardExtension->SmartcardReply.BufferLength);
  642. ulBytesRead+=smartcardExtension->SmartcardReply.BufferLength;
  643. }
  644. while ((status == STATUS_SUCCESS) && (ulBytesToRead > ulBytesRead));
  645. *(smartcardExtension->IoRequest.Information)=ulBytesRead;
  646. if (status!=STATUS_SUCCESS)
  647. {
  648. goto ExitTransmit3WBP;
  649. }
  650. // according to datasheet, clock should be set to low now
  651. // this is not necessary, because this is done before next command
  652. // or card is reseted respectivly
  653. break;
  654. case SLE4428_WRITE:
  655. case SLE4428_WRITE_PROT:
  656. case SLE4428_COMPARE:
  657. case SLE4428_SET_COUNTER&0x3F:
  658. case SLE4428_COMPARE_PIN&0x3F:
  659. // processing mode
  660. abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,1,0,0);
  661. RtlFillMemory((PVOID)&abSendBuffer[1],ATTR_MAX_IFSD_SYNCHRON_USB-1,abSendBuffer[0]);
  662. do
  663. {
  664. // now send command type 08 to CardManUSB
  665. smartcardExtension->SmartcardRequest.BufferLength = ATTR_MAX_IFSD_SYNCHRON_USB;
  666. RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer,
  667. (PVOID) abSendBuffer,
  668. smartcardExtension->SmartcardRequest.BufferLength);
  669. status = CMUSB_WriteP0(deviceObject,
  670. 0x08, //bRequest,
  671. 0x00, //bValueLo,
  672. 0x00, //bValueHi,
  673. 0x00, //bIndexLo,
  674. 0x00 //bIndexHi,
  675. );
  676. if (status != STATUS_SUCCESS)
  677. {
  678. // if we can't write command there must be a serious error
  679. goto ExitTransmit3WBP;
  680. }
  681. status = CMUSB_ReadP1(deviceObject);
  682. if (status == STATUS_DEVICE_DATA_ERROR)
  683. {
  684. DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject);
  685. goto ExitTransmit3WBP;
  686. }
  687. else if (status != STATUS_SUCCESS)
  688. {
  689. // if we can't read there must be a serious error
  690. goto ExitTransmit3WBP;
  691. }
  692. if (smartcardExtension->SmartcardReply.BufferLength!=ATTR_MAX_IFSD_SYNCHRON_USB/8)
  693. {
  694. // wrong number of bytes read
  695. // -> something went wrong
  696. status=STATUS_DEVICE_DATA_ERROR;
  697. goto ExitTransmit3WBP;
  698. }
  699. }
  700. while ((status == STATUS_SUCCESS) &&
  701. (smartcardExtension->SmartcardReply.Buffer[smartcardExtension->SmartcardReply.BufferLength-1]==0xFF));
  702. *(smartcardExtension->IoRequest.Information)=0;
  703. if (status!=STATUS_SUCCESS)
  704. {
  705. goto ExitTransmit3WBP;
  706. }
  707. // according to datasheet, clock should be set to low now
  708. // this is not necessary, because this is done before next command
  709. // or card is reseted respectivly
  710. break;
  711. default:
  712. // should not happen
  713. status=STATUS_ILLEGAL_INSTRUCTION;
  714. goto ExitTransmit3WBP;
  715. }
  716. ExitTransmit3WBP:
  717. SmartcardDebug(DEBUG_TRACE,
  718. ("%s!Transmit3WBP: Exit %lx\n",DRIVER_NAME,status));
  719. return status;
  720. }
  721. /*****************************************************************************
  722. Routine Description: Transmits a command (3 Bytes) to a SLE 4428/4418
  723. Arguments:
  724. Return Value:
  725. *****************************************************************************/
  726. NTSTATUS
  727. CMUSB_SendCommand3WBP (
  728. IN PSMARTCARD_EXTENSION smartcardExtension,
  729. IN PUCHAR pbCommandData
  730. )
  731. {
  732. PDEVICE_OBJECT deviceObject;
  733. NTSTATUS status = STATUS_SUCCESS;
  734. NTSTATUS DebugStatus;
  735. UCHAR abSendBuffer[CMUSB_SYNCH_BUFFER_SIZE];
  736. UCHAR* pByte;
  737. UCHAR bValue;
  738. int i,j;
  739. SmartcardDebug(DEBUG_TRACE,
  740. ("%s!SendCommand3WBP: Enter\n",DRIVER_NAME));
  741. SmartcardDebug(DEBUG_PROTOCOL,
  742. ("%s!SendCommand3WBP: 4442 Command = %02x %02x %02x\n",DRIVER_NAME,
  743. pbCommandData[0],
  744. pbCommandData[1],
  745. pbCommandData[2]));
  746. deviceObject = smartcardExtension->OsData->DeviceObject;
  747. // build control code for command to send
  748. // command is in first 3 Bytes of pbInData
  749. abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,0,0,0);
  750. pByte=&abSendBuffer[1];
  751. for (j=0;j<3;j++)
  752. {
  753. for (i=0;i<8;i++)
  754. {
  755. bValue=(pbCommandData[j]&(1<<i));
  756. *pByte=CMUSB_CalcSynchControl(1,0,1,bValue, 1,1,1,bValue);
  757. pByte++;
  758. }
  759. }
  760. abSendBuffer[25]=CMUSB_CalcSynchControl(1,0,1,0, 0,0,0,0);
  761. // one additional clock cycle, because
  762. // first bit is only read back after second clock
  763. // for write it has no influence
  764. abSendBuffer[26]=CMUSB_CalcSynchControl(0,0,0,0, 0,1,0,0);
  765. // fill rest with zeros
  766. abSendBuffer[27]=CMUSB_CalcSynchControl(0,0,0,0, 0,0,0,0);
  767. RtlFillMemory((PVOID)&abSendBuffer[28],4,abSendBuffer[27]);
  768. // now send command type 08 to CardManUSB
  769. smartcardExtension->SmartcardRequest.BufferLength = 32;
  770. RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer,
  771. (PVOID) abSendBuffer,
  772. smartcardExtension->SmartcardRequest.BufferLength);
  773. status = CMUSB_WriteP0(deviceObject,
  774. 0x08, //bRequest,
  775. 0x00, //bValueLo,
  776. 0x00, //bValueHi,
  777. 0x00, //bIndexLo,
  778. 0x00 //bIndexHi,
  779. );
  780. if (status != STATUS_SUCCESS)
  781. {
  782. // if we can't write command there must be a serious error
  783. goto ExitSendCommand3WBP;
  784. }
  785. status = CMUSB_ReadP1(deviceObject);
  786. if (status == STATUS_DEVICE_DATA_ERROR)
  787. {
  788. DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject);
  789. goto ExitSendCommand3WBP;
  790. }
  791. else if (status != STATUS_SUCCESS)
  792. {
  793. // if we can't read there must be a serious error
  794. goto ExitSendCommand3WBP;
  795. }
  796. if (smartcardExtension->SmartcardReply.BufferLength!=4)
  797. {
  798. // 32 bytes sent but not 4 bytes received
  799. // -> something went wrong
  800. status=STATUS_DEVICE_DATA_ERROR;
  801. goto ExitSendCommand3WBP;
  802. }
  803. ExitSendCommand3WBP:
  804. SmartcardDebug(DEBUG_TRACE,
  805. ("%s!SendCommand3WBP: Exit %lx\n",DRIVER_NAME,status));
  806. return status;
  807. }
  808. /*****************************************************************************
  809. * History:
  810. * $Log: scusbsyn.c $
  811. * Revision 1.3 2000/08/24 09:04:39 TBruendl
  812. * No comment given
  813. *
  814. * Revision 1.2 2000/07/24 11:35:00 WFrischauf
  815. * No comment given
  816. *
  817. * Revision 1.1 2000/07/20 11:50:16 WFrischauf
  818. * No comment given
  819. *
  820. *
  821. ******************************************************************************/