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.

3692 lines
112 KiB

  1. /*****************************************************************************
  2. @doc INT EXT
  3. ******************************************************************************
  4. * $ProjectName: $
  5. * $ProjectRevision: $
  6. *-----------------------------------------------------------------------------
  7. * $Source: z:/pr/cmeu0/sw/sccmusbm.ms/rcs/scusbcb.c $
  8. * $Revision: 1.9 $
  9. *-----------------------------------------------------------------------------
  10. * $Author: WFrischauf $
  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. ULONG dataRatesSupported[] = { 9600, 19200, 38400, 76800, 115200};
  24. ULONG CLKFrequenciesSupported[] = {3571};
  25. /*****************************************************************************
  26. Routine Description:
  27. Arguments:
  28. Return Value:
  29. *****************************************************************************/
  30. NTSTATUS CMUSB_StartCardTracking(
  31. IN PDEVICE_OBJECT DeviceObject
  32. )
  33. {
  34. NTSTATUS NTStatus;
  35. HANDLE hThread;
  36. PDEVICE_EXTENSION DeviceExtension;
  37. PSMARTCARD_EXTENSION SmartcardExtension;
  38. DeviceExtension = DeviceObject->DeviceExtension;
  39. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  40. // settings for thread synchronization
  41. SmartcardExtension->ReaderExtension->TimeToTerminateThread = FALSE;
  42. SmartcardExtension->ReaderExtension->fThreadTerminated = FALSE;
  43. SmartcardDebug(DEBUG_TRACE,
  44. ("%s!StartCardTracking: Enter\n",DRIVER_NAME));
  45. KeWaitForSingleObject(&SmartcardExtension->ReaderExtension->CardManIOMutex,
  46. Executive,
  47. KernelMode,
  48. FALSE,
  49. NULL);
  50. // create thread for updating current state
  51. NTStatus = PsCreateSystemThread(&hThread,
  52. THREAD_ALL_ACCESS,
  53. NULL,
  54. NULL,
  55. NULL,
  56. CMUSB_UpdateCurrentStateThread,
  57. DeviceObject);
  58. if (!NT_ERROR(NTStatus))
  59. {
  60. //
  61. // We've got the thread. Now get a pointer to it.
  62. //
  63. NTStatus = ObReferenceObjectByHandle(hThread,
  64. THREAD_ALL_ACCESS,
  65. NULL,
  66. KernelMode,
  67. &SmartcardExtension->ReaderExtension->ThreadObjectPointer,
  68. NULL);
  69. if (NT_ERROR(NTStatus))
  70. {
  71. SmartcardExtension->ReaderExtension->TimeToTerminateThread = TRUE;
  72. }
  73. else
  74. {
  75. //
  76. // Now that we have a reference to the thread
  77. // we can simply close the handle.
  78. //
  79. ZwClose(hThread);
  80. }
  81. }
  82. SmartcardDebug(DEBUG_DRIVER,
  83. ("%s!StartCardTracking: -----------------------------------------------------------\n",DRIVER_NAME));
  84. SmartcardDebug(DEBUG_DRIVER,
  85. ("%s!StartCardTracking: STARTING THREAD\n",DRIVER_NAME));
  86. SmartcardDebug(DEBUG_DRIVER,
  87. ("%s!StartCardTracking: -----------------------------------------------------------\n",DRIVER_NAME));
  88. KeReleaseMutex(&SmartcardExtension->ReaderExtension->CardManIOMutex,
  89. FALSE);
  90. SmartcardDebug(DEBUG_TRACE,
  91. ("%s!StartCardTracking: Exit %lx\n",DRIVER_NAME,NTStatus));
  92. return NTStatus;
  93. }
  94. /*****************************************************************************
  95. Routine Description:
  96. Arguments:
  97. Return Value:
  98. *****************************************************************************/
  99. VOID CMUSB_StopCardTracking(
  100. IN PDEVICE_OBJECT DeviceObject
  101. )
  102. {
  103. PDEVICE_EXTENSION DeviceExtension;
  104. PSMARTCARD_EXTENSION SmartcardExtension;
  105. SmartcardDebug(DEBUG_TRACE,
  106. ("%s!StopCardTracking: Enter\n",DRIVER_NAME));
  107. DeviceExtension = DeviceObject->DeviceExtension;
  108. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  109. if (SmartcardExtension->ReaderExtension->fThreadTerminated == FALSE)
  110. {
  111. SmartcardDebug(DEBUG_DRIVER,
  112. ("%s!StopCardTracking: waiting for mutex\n",DRIVER_NAME));
  113. // kill thread
  114. KeWaitForSingleObject(&SmartcardExtension->ReaderExtension->CardManIOMutex,
  115. Executive,
  116. KernelMode,
  117. FALSE,
  118. NULL);
  119. SmartcardExtension->ReaderExtension->TimeToTerminateThread = TRUE;
  120. KeReleaseMutex(&SmartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  121. while (SmartcardExtension->ReaderExtension->fThreadTerminated==FALSE)
  122. {
  123. CMUSB_Wait(10);
  124. }
  125. }
  126. SmartcardDebug(DEBUG_TRACE,
  127. ("%s!StopCardTracking: Exit\n",DRIVER_NAME));
  128. }
  129. /*****************************************************************************
  130. Routine Description:
  131. Arguments:
  132. Return Value:
  133. *****************************************************************************/
  134. VOID CMUSB_UpdateCurrentStateThread(
  135. IN PVOID Context
  136. )
  137. {
  138. PDEVICE_OBJECT DeviceObject = Context;
  139. PDEVICE_EXTENSION DeviceExtension;
  140. PSMARTCARD_EXTENSION SmartcardExtension;
  141. NTSTATUS NTStatus,DebugStatus;
  142. ULONG ulInterval;
  143. DeviceExtension = DeviceObject->DeviceExtension;
  144. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  145. KeWaitForSingleObject(&DeviceExtension->CanRunUpdateThread,
  146. Executive,
  147. KernelMode,
  148. FALSE,
  149. NULL);
  150. SmartcardDebug(DEBUG_DRIVER,
  151. ("%s!UpdateCurrentStateThread started\n",DRIVER_NAME));
  152. do
  153. {
  154. // every 500 ms the s NTStatus request is sent
  155. ulInterval = 500;
  156. KeWaitForSingleObject(&SmartcardExtension->ReaderExtension->CardManIOMutex,
  157. Executive,
  158. KernelMode,
  159. FALSE,
  160. NULL);
  161. if ( SmartcardExtension->ReaderExtension->TimeToTerminateThread )
  162. {
  163. SmartcardDebug(DEBUG_DRIVER,
  164. ("%s!UpdateCurrentStateThread: -----------------------------------------\n",DRIVER_NAME));
  165. SmartcardDebug(DEBUG_DRIVER,
  166. ("%s!UpdateCurrentStateThread: STOPPING THREAD\n",DRIVER_NAME));
  167. SmartcardDebug(DEBUG_DRIVER,
  168. ("%s!UpdateCurrentStateThread: -----------------------------------------\n",DRIVER_NAME));
  169. KeReleaseMutex(&SmartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  170. SmartcardExtension->ReaderExtension->fThreadTerminated = TRUE;
  171. PsTerminateSystemThread( STATUS_SUCCESS );
  172. }
  173. NTStatus = CMUSB_UpdateCurrentState (DeviceObject);
  174. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  175. {
  176. SmartcardDebug(DEBUG_DRIVER,
  177. ("%s!setting update interval to 1ms\n",DRIVER_NAME));
  178. ulInterval = 1;
  179. }
  180. else if (NTStatus != STATUS_SUCCESS)
  181. {
  182. SmartcardDebug(DEBUG_DRIVER,
  183. ("%s!NO STATUS RECEIVED\n",DRIVER_NAME));
  184. }
  185. KeReleaseMutex(&SmartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  186. CMUSB_Wait (ulInterval);
  187. }
  188. while (TRUE);
  189. }
  190. NTSTATUS CMUSB_UpdateCurrentState(
  191. IN PDEVICE_OBJECT DeviceObject
  192. )
  193. {
  194. NTSTATUS NTStatus;
  195. PDEVICE_EXTENSION DeviceExtension;
  196. PSMARTCARD_EXTENSION SmartcardExtension;
  197. BOOLEAN fCardStateChanged = FALSE;
  198. ULONG ulBytesRead;
  199. DeviceExtension = DeviceObject->DeviceExtension;
  200. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  201. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  202. //#if DBG
  203. // ulDebugLevel = SmartcardGetDebugLevel();
  204. // SmartcardSetDebugLevel((ULONG)0);
  205. //#endif
  206. NTStatus = CMUSB_WriteP0(DeviceObject,
  207. 0x20, //bRequest,
  208. 0x00, //bValueLo,
  209. 0x00, //bValueHi,
  210. 0x00, //bIndexLo,
  211. 0x00 //bIndexHi,
  212. );
  213. //#if DBG
  214. // SmartcardSetDebugLevel(ulDebugLevel);
  215. //#endif
  216. if (NTStatus == STATUS_SUCCESS)
  217. {
  218. SmartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1;
  219. SmartcardExtension->SmartcardReply.BufferLength = 1;
  220. //#if DBG
  221. // ulDebugLevel = SmartcardGetDebugLevel();
  222. // SmartcardSetDebugLevel((ULONG)0);
  223. //#endif
  224. NTStatus = CMUSB_ReadP1(DeviceObject);
  225. //#if DBG
  226. // SmartcardSetDebugLevel(ulDebugLevel);
  227. //#endif
  228. ulBytesRead = SmartcardExtension->SmartcardReply.BufferLength;
  229. if (NTStatus == STATUS_SUCCESS && ulBytesRead == 1) /* we got the NTStatus information */
  230. {
  231. if ((SmartcardExtension->SmartcardReply.Buffer[0] & 0x40) == 0x40)
  232. {
  233. if ((SmartcardExtension->SmartcardReply.Buffer[0] & 0x80) == 0x80)
  234. {
  235. SmartcardExtension->ReaderExtension->ulNewCardState = POWERED;
  236. }
  237. else
  238. {
  239. SmartcardExtension->ReaderExtension->ulNewCardState = INSERTED;
  240. }
  241. }
  242. else
  243. {
  244. SmartcardExtension->ReaderExtension->ulNewCardState = REMOVED;
  245. }
  246. /*
  247. SmartcardDebug(DEBUG_DRIVER,
  248. ("old %x ",SmartcardExtension->ReaderExtension->ulOldCardState ));
  249. SmartcardDebug(DEBUG_DRIVER,
  250. ("new %x\n",SmartcardExtension->ReaderExtension->ulNewCardState ));
  251. */
  252. if (SmartcardExtension->ReaderExtension->ulNewCardState == INSERTED &&
  253. SmartcardExtension->ReaderExtension->ulOldCardState == POWERED )
  254. {
  255. // card has been removed and reinserted
  256. SmartcardExtension->ReaderExtension->ulNewCardState = REMOVED;
  257. }
  258. if (SmartcardExtension->ReaderExtension->ulNewCardState == INSERTED &&
  259. (SmartcardExtension->ReaderExtension->ulOldCardState == UNKNOWN ||
  260. SmartcardExtension->ReaderExtension->ulOldCardState == REMOVED ))
  261. {
  262. // card has been inserted
  263. SmartcardDebug(DEBUG_DRIVER,( "%s!UpdateCurrentStateThread Smartcard inserted\n",DRIVER_NAME));
  264. fCardStateChanged = TRUE;
  265. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SWALLOWED;
  266. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  267. }
  268. // state after reset of the PC
  269. if (SmartcardExtension->ReaderExtension->ulNewCardState == POWERED &&
  270. SmartcardExtension->ReaderExtension->ulOldCardState == UNKNOWN )
  271. {
  272. // card has been inserted
  273. SmartcardDebug(DEBUG_DRIVER,( "%s!UpdateCurrentStateThread Smartcard inserted (and powered)\n",DRIVER_NAME));
  274. fCardStateChanged = TRUE;
  275. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SWALLOWED;
  276. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  277. }
  278. if (SmartcardExtension->ReaderExtension->ulNewCardState == REMOVED &&
  279. (SmartcardExtension->ReaderExtension->ulOldCardState == UNKNOWN ||
  280. SmartcardExtension->ReaderExtension->ulOldCardState == INSERTED ||
  281. SmartcardExtension->ReaderExtension->ulOldCardState == POWERED ) )
  282. {
  283. // card has been removed
  284. fCardStateChanged = TRUE;
  285. SmartcardDebug(DEBUG_DRIVER,( "%s!UpdateCurrentStateThread Smartcard removed\n",DRIVER_NAME));
  286. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
  287. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  288. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  289. RtlFillMemory((PVOID)&SmartcardExtension->ReaderExtension->CardParameters,
  290. sizeof(CARD_PARAMETERS),
  291. 0x00);
  292. }
  293. // complete IOCTL_SMARTCARD_IS_ABSENT or IOCTL_SMARTCARD_IS_PRESENT
  294. if (fCardStateChanged == TRUE &&
  295. SmartcardExtension->OsData->NotificationIrp != NULL)
  296. {
  297. SmartcardDebug(DEBUG_DRIVER,("%s!UpdateCurrentStateThread: completing IRP\n",DRIVER_NAME));
  298. CMUSB_CompleteCardTracking(SmartcardExtension);
  299. }
  300. // save old state
  301. SmartcardExtension->ReaderExtension->ulOldCardState = SmartcardExtension->ReaderExtension->ulNewCardState;
  302. }
  303. }
  304. return NTStatus;
  305. }
  306. /*****************************************************************************
  307. Routine Description:
  308. Arguments:
  309. Return Value:
  310. *****************************************************************************/
  311. VOID CMUSB_CompleteCardTracking(
  312. IN PSMARTCARD_EXTENSION SmartcardExtension
  313. )
  314. {
  315. KIRQL ioIrql, keIrql;
  316. PIRP notificationIrp;
  317. IoAcquireCancelSpinLock(&ioIrql);
  318. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock, &keIrql);
  319. notificationIrp = SmartcardExtension->OsData->NotificationIrp;
  320. SmartcardExtension->OsData->NotificationIrp = NULL;
  321. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock, keIrql);
  322. if (notificationIrp)
  323. {
  324. IoSetCancelRoutine(notificationIrp,NULL);
  325. }
  326. IoReleaseCancelSpinLock(ioIrql);
  327. if (notificationIrp)
  328. {
  329. SmartcardDebug(DEBUG_DRIVER,
  330. ("%s!CompleteCardTracking: Completing NotificationIrp %lxh\n",DRIVER_NAME,notificationIrp));
  331. // finish the request
  332. if (notificationIrp->Cancel)
  333. {
  334. notificationIrp->IoStatus.Status = STATUS_CANCELLED;
  335. }
  336. else
  337. {
  338. notificationIrp->IoStatus.Status = STATUS_SUCCESS;
  339. }
  340. notificationIrp->IoStatus.Information = 0;
  341. IoCompleteRequest(notificationIrp, IO_NO_INCREMENT);
  342. }
  343. }
  344. /*****************************************************************************
  345. Routine Description:
  346. Arguments:
  347. Return Value:
  348. *****************************************************************************/
  349. NTSTATUS CMUSB_Wait (ULONG ulMilliseconds)
  350. {
  351. NTSTATUS NTStatus = STATUS_SUCCESS;
  352. LARGE_INTEGER WaitTime;
  353. // -10000 indicates 1ms relativ
  354. WaitTime = RtlConvertLongToLargeInteger(ulMilliseconds * -10000);
  355. KeDelayExecutionThread(KernelMode,FALSE,&WaitTime);
  356. return NTStatus;
  357. }
  358. /*****************************************************************************
  359. Routine Description:
  360. Arguments:
  361. Return Value:
  362. *****************************************************************************/
  363. NTSTATUS CMUSB_CreateClose(
  364. IN PDEVICE_OBJECT DeviceObject,
  365. IN PIRP Irp
  366. )
  367. {
  368. NTSTATUS NTStatus = STATUS_SUCCESS;
  369. PDEVICE_EXTENSION DeviceExtension;
  370. PSMARTCARD_EXTENSION SmartcardExtension;
  371. PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
  372. SmartcardDebug(DEBUG_TRACE,
  373. ("%s!CreateClose: Enter\n",DRIVER_NAME));
  374. DeviceExtension = DeviceObject->DeviceExtension;
  375. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  376. //
  377. // dispatch major function
  378. //
  379. switch (IrpStack->MajorFunction)
  380. {
  381. case IRP_MJ_CREATE:
  382. SmartcardDebug(DEBUG_DRIVER,
  383. ("%s!CreateClose: IRP_MJ_CREATE\n",DRIVER_NAME));
  384. if (DeviceExtension->RemoveDeviceRequested)
  385. {
  386. NTStatus = STATUS_DEVICE_BUSY;
  387. }
  388. else
  389. {
  390. if (InterlockedIncrement(&DeviceExtension->lOpenCount) > 1)
  391. {
  392. InterlockedDecrement(&DeviceExtension->lOpenCount);
  393. NTStatus = STATUS_ACCESS_DENIED;
  394. }
  395. }
  396. break;
  397. case IRP_MJ_CLOSE:
  398. SmartcardDebug(DEBUG_DRIVER,
  399. ("%s!CreateClose: IRP_MJ_CLOSE\n",DRIVER_NAME));
  400. if (InterlockedDecrement(&DeviceExtension->lOpenCount) < 0)
  401. {
  402. InterlockedIncrement(&DeviceExtension->lOpenCount);
  403. }
  404. // check if the device has been removed
  405. // if so free the resources
  406. if (DeviceExtension->DeviceRemoved == TRUE)
  407. {
  408. SmartcardDebug(DEBUG_DRIVER,
  409. ("%s!CreateClose: freeing resources\n",DRIVER_NAME));
  410. if (DeviceExtension->fPnPResourceManager == FALSE)
  411. {
  412. //
  413. // Free all allocated buffer
  414. //
  415. ExFreePool(DeviceExtension->DosDeviceName.Buffer);
  416. }
  417. ExFreePool(SmartcardExtension->ReaderExtension);
  418. SmartcardExtension->ReaderExtension = NULL;
  419. //
  420. // Let the lib free the send/receive buffers
  421. //
  422. SmartcardExit(SmartcardExtension);
  423. }
  424. break;
  425. default:
  426. //
  427. // unrecognized command
  428. //
  429. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  430. break;
  431. }
  432. Irp->IoStatus.Information = 0;
  433. Irp->IoStatus.Status = NTStatus;
  434. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  435. SmartcardDebug(DEBUG_TRACE,
  436. ("%s!CreateClose: Exit %lx\n",DRIVER_NAME,NTStatus));
  437. return NTStatus;
  438. }
  439. /*****************************************************************************
  440. Routine Description:
  441. Arguments:
  442. Return Value:
  443. *****************************************************************************/
  444. NTSTATUS CMUSB_Transmit(
  445. IN PSMARTCARD_EXTENSION SmartcardExtension
  446. )
  447. {
  448. NTSTATUS NTStatus;
  449. //this seems to make problems in Windows 98
  450. //KeSetPriorityThread(KeGetCurrentThread(),HIGH_PRIORITY);
  451. switch (SmartcardExtension->CardCapabilities.Protocol.Selected)
  452. {
  453. case SCARD_PROTOCOL_RAW:
  454. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  455. break;
  456. case SCARD_PROTOCOL_T0:
  457. NTStatus = CMUSB_TransmitT0(SmartcardExtension);
  458. break;
  459. case SCARD_PROTOCOL_T1:
  460. NTStatus = CMUSB_TransmitT1(SmartcardExtension);
  461. break;
  462. default:
  463. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  464. break;
  465. }
  466. //KeSetPriorityThread(KeGetCurrentThread(),LOW_REALTIME_PRIORITY);
  467. return NTStatus;
  468. }
  469. /*****************************************************************************
  470. Routine Description:
  471. Arguments:
  472. Return Value:
  473. *****************************************************************************/
  474. NTSTATUS CMUSB_ResetT0ReadBuffer(
  475. PSMARTCARD_EXTENSION SmartcardExtension
  476. )
  477. {
  478. SmartcardExtension->ReaderExtension->T0ReadBuffer_OffsetLastByte = -1;
  479. SmartcardExtension->ReaderExtension->T0ReadBuffer_OffsetLastByteRead = -1;
  480. return STATUS_SUCCESS;
  481. }
  482. /*****************************************************************************
  483. Routine Description:
  484. Arguments:
  485. Return Value:
  486. *****************************************************************************/
  487. NTSTATUS CMUSB_ReadT0(
  488. PSMARTCARD_EXTENSION SmartcardExtension
  489. )
  490. {
  491. NTSTATUS NTStatus = STATUS_SUCCESS;
  492. NTSTATUS DebugStatus;
  493. LONG lBytesToRead;
  494. LONG lBytesRead;
  495. LONG lLastByte;
  496. LONG lLastByteRead;
  497. PDEVICE_EXTENSION DeviceExtension;
  498. PUSBD_PIPE_INFORMATION pipeHandle = NULL;
  499. PUSBD_INTERFACE_INFORMATION interface;
  500. SmartcardDebug(DEBUG_TRACE,
  501. ("%s!ReadT0: Enter\n",DRIVER_NAME));
  502. DeviceExtension = SmartcardExtension->OsData->DeviceObject->DeviceExtension;
  503. interface = DeviceExtension->UsbInterface;
  504. pipeHandle = &interface->Pipes[0];
  505. lBytesToRead = (LONG)SmartcardExtension->SmartcardReply.BufferLength;
  506. lLastByte = SmartcardExtension->ReaderExtension->T0ReadBuffer_OffsetLastByte;
  507. lLastByteRead = SmartcardExtension->ReaderExtension->T0ReadBuffer_OffsetLastByteRead;
  508. // check if further bytes must be read from pipe 1
  509. while (lLastByteRead + lBytesToRead > lLastByte)
  510. {
  511. SmartcardExtension->SmartcardReply.BufferLength = 1;
  512. SmartcardExtension->ReaderExtension->ulTimeoutP1 = 1000 +
  513. (ULONG)((SmartcardExtension->CardCapabilities.T0.WT/1000) * lBytesToRead);
  514. NTStatus = CMUSB_ReadP1(SmartcardExtension->OsData->DeviceObject);
  515. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  516. {
  517. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  518. goto ExitReadT0;
  519. }
  520. else if (NTStatus != STATUS_SUCCESS)
  521. {
  522. goto ExitReadT0;
  523. }
  524. lBytesRead = (LONG)SmartcardExtension->SmartcardReply.BufferLength;
  525. RtlCopyBytes((PVOID)(SmartcardExtension->ReaderExtension->T0ReadBuffer + (lLastByte +1)),
  526. (PVOID)SmartcardExtension->SmartcardReply.Buffer,
  527. lBytesRead);
  528. lLastByte += lBytesRead;
  529. } // end of while
  530. // copy bytes
  531. SmartcardExtension->SmartcardReply.BufferLength = lBytesToRead;
  532. RtlCopyBytes ((PVOID)SmartcardExtension->SmartcardReply.Buffer,
  533. (PVOID)(SmartcardExtension->ReaderExtension->T0ReadBuffer + (lLastByteRead +1)),
  534. lBytesToRead);
  535. lLastByteRead += lBytesToRead;
  536. /*
  537. SmartcardDebug(DEBUG_TRACE,
  538. ("%s!lBytesToRead=%ld lLastByte=%ld lLastByteRead=%ld\n",
  539. DRIVER_NAME,
  540. lBytesToRead,
  541. lLastByte,
  542. lLastByteRead)
  543. );
  544. */
  545. SmartcardExtension->ReaderExtension->T0ReadBuffer_OffsetLastByte = lLastByte;
  546. SmartcardExtension->ReaderExtension->T0ReadBuffer_OffsetLastByteRead = lLastByteRead;
  547. SmartcardDebug(DEBUG_TRACE,
  548. ("%s!ReadT0: Exit %lx\n",DRIVER_NAME,NTStatus));
  549. ExitReadT0:
  550. return NTStatus;
  551. }
  552. /*****************************************************************************
  553. Routine Description:
  554. Arguments:
  555. Return Value:
  556. *****************************************************************************/
  557. #define T0_HEADER_LEN 0x05
  558. #define T0_STATE_LEN 0x02
  559. #define TIMEOUT_CANCEL_READ_P1 30000
  560. NTSTATUS CMUSB_TransmitT0(
  561. PSMARTCARD_EXTENSION SmartcardExtension
  562. )
  563. {
  564. NTSTATUS NTStatus;
  565. NTSTATUS DebugStatus;
  566. UCHAR bWriteBuffer[CMUSB_BUFFER_SIZE];
  567. UCHAR bReadBuffer [CMUSB_BUFFER_SIZE];
  568. ULONG ulWriteBufferOffset;
  569. ULONG ulReadBufferOffset;
  570. ULONG ulBytesToWrite;
  571. ULONG ulBytesToRead;
  572. ULONG ulBytesToWriteThisStep;
  573. ULONG ulBytesToReadThisStep;
  574. ULONG ulBytesStillToWrite;
  575. ULONG ulBytesRead;
  576. ULONG ulBytesStillToRead;
  577. BOOLEAN fDataDirectionFromCard;
  578. BYTE bProcedureByte;
  579. BYTE bINS;
  580. BOOLEAN fT0TransferToCard;
  581. BOOLEAN fT0TransferFromCard;
  582. BOOLEAN fSW1SW2Sent;
  583. ULONG ulUsedCWT;
  584. UCHAR bUsedCWTHi;
  585. LARGE_INTEGER liTimeout;
  586. PDEVICE_EXTENSION DeviceExtension;
  587. UCHAR bTmp;
  588. ULONG i;
  589. PUSBD_PIPE_INFORMATION pipeHandle = NULL;
  590. PUSBD_INTERFACE_INFORMATION interface;
  591. SmartcardDebug(DEBUG_TRACE,
  592. ("%s!TransmitT0 : Enter\n",DRIVER_NAME));
  593. fT0TransferToCard = FALSE;
  594. fT0TransferFromCard = FALSE;
  595. fSW1SW2Sent = FALSE;
  596. // resync CardManUSB by reading the NTStatus byte
  597. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  598. NTStatus = CMUSB_WriteP0(SmartcardExtension->OsData->DeviceObject,
  599. 0x20, //bRequest,
  600. 0x00, //bValueLo,
  601. 0x00, //bValueHi,
  602. 0x00, //bIndexLo,
  603. 0x00 //bIndexHi,
  604. );
  605. if (NTStatus != STATUS_SUCCESS)
  606. {
  607. // if we can't read the NTStatus there must be a serious error
  608. goto ExitTransmitT0;
  609. }
  610. SmartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1;
  611. SmartcardExtension->SmartcardReply.BufferLength = 1;
  612. NTStatus = CMUSB_ReadP1(SmartcardExtension->OsData->DeviceObject);
  613. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  614. {
  615. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  616. goto ExitTransmitT0;
  617. }
  618. else if (NTStatus != STATUS_SUCCESS)
  619. {
  620. // if we can't read the NTStatus there must be a serious error
  621. goto ExitTransmitT0;
  622. }
  623. DeviceExtension = SmartcardExtension->OsData->DeviceObject->DeviceExtension;
  624. interface = DeviceExtension->UsbInterface;
  625. pipeHandle = &interface->Pipes[0];
  626. SmartcardExtension->ReaderExtension->ulTimeoutP1 = (ULONG)(SmartcardExtension->CardCapabilities.T0.WT/1000);
  627. //
  628. // Let the lib build a T=0 packet
  629. //
  630. SmartcardExtension->SmartcardRequest.BufferLength = 0; // no bytes additionally needed
  631. NTStatus = SmartcardT0Request(SmartcardExtension);
  632. if (NTStatus != STATUS_SUCCESS)
  633. {
  634. //
  635. // This lib detected an error in the data to send.
  636. //
  637. goto ExitTransmitT0;
  638. }
  639. ulBytesStillToWrite = ulBytesToWrite = T0_HEADER_LEN + SmartcardExtension->T0.Lc;
  640. ulBytesStillToRead = ulBytesToRead = SmartcardExtension->T0.Le;
  641. if (SmartcardExtension->T0.Lc)
  642. fT0TransferToCard = TRUE;
  643. if (SmartcardExtension->T0.Le)
  644. fT0TransferFromCard = TRUE;
  645. // ----------------------------
  646. // smart card ==> CardMan USB
  647. // ----------------------------
  648. if (fT0TransferFromCard)
  649. {
  650. SmartcardDebug(DEBUG_PROTOCOL,
  651. ("%s!TransmitT0: MODE 3\n",DRIVER_NAME));
  652. // granularity 256 ms
  653. ulUsedCWT = (ULONG)(SmartcardExtension->CardCapabilities.T0.WT/1000);
  654. SmartcardDebug(DEBUG_PROTOCOL,
  655. ("%s!TransmitT0: ulUsedCWT= %ld\n",DRIVER_NAME,ulUsedCWT));
  656. bUsedCWTHi = (UCHAR)(((ulUsedCWT & 0x0000FF00)>>8) + 1 + 5) ;
  657. // copy data to the write buffer
  658. SmartcardDebug(DEBUG_PROTOCOL,
  659. ("%s!TransmitT0: CLA = %x INS = %x P1 = %x P2 = %x L = %x\n", DRIVER_NAME,
  660. SmartcardExtension->SmartcardRequest.Buffer[0],
  661. SmartcardExtension->SmartcardRequest.Buffer[1],
  662. SmartcardExtension->SmartcardRequest.Buffer[2],
  663. SmartcardExtension->SmartcardRequest.Buffer[3],
  664. SmartcardExtension->SmartcardRequest.Buffer[4]));
  665. RtlCopyBytes((PVOID)bWriteBuffer,
  666. (PVOID)SmartcardExtension->SmartcardRequest.Buffer,
  667. ulBytesToWrite);
  668. bINS = bWriteBuffer[1];
  669. ulWriteBufferOffset = 0;
  670. ulReadBufferOffset = 0;
  671. // STEP 1 : write CLA INS P1 P2 Lc
  672. ulBytesToWriteThisStep = 5;
  673. RtlCopyBytes((PVOID)(SmartcardExtension->SmartcardRequest.Buffer),
  674. (PVOID)(bWriteBuffer+ulWriteBufferOffset),
  675. ulBytesToWriteThisStep);
  676. if (SmartcardExtension->ReaderExtension->fInverseAtr == TRUE)
  677. {
  678. CMUSB_InverseBuffer(SmartcardExtension->SmartcardRequest.Buffer,
  679. SmartcardExtension->SmartcardRequest.BufferLength);
  680. }
  681. SmartcardExtension->SmartcardReply.BufferLength = 512;
  682. NTStatus = CMUSB_ReadP1_T0(SmartcardExtension->OsData->DeviceObject);
  683. if (NTStatus != STATUS_SUCCESS)
  684. {
  685. SmartcardDebug(DEBUG_PROTOCOL,
  686. ("%s!TransmitT0: CMUSB_ReadP1_T0 returned = %x\n",DRIVER_NAME,NTStatus));
  687. goto ExitTransmitT0;
  688. }
  689. SmartcardExtension->SmartcardRequest.BufferLength = ulBytesToWriteThisStep;
  690. NTStatus = CMUSB_WriteP0(SmartcardExtension->OsData->DeviceObject,
  691. 0x03, // mode 3
  692. bUsedCWTHi, //bValueLo,
  693. 0x00, //bValueHi,
  694. (UCHAR)(ulBytesToRead%256), //bIndexLo,
  695. (UCHAR)(SmartcardExtension->SmartcardRequest.Buffer[1]) //bIndexHi,
  696. );
  697. if (NTStatus != STATUS_SUCCESS)
  698. {
  699. SmartcardDebug(DEBUG_PROTOCOL,
  700. ("%s!TransmitT0: CMUSB_WriteP0 returned %x\n",DRIVER_NAME,NTStatus));
  701. goto ExitTransmitT0;
  702. }
  703. liTimeout = RtlConvertLongToLargeInteger(TIMEOUT_CANCEL_READ_P1 * -10000);
  704. SmartcardDebug(DEBUG_PROTOCOL,
  705. ("%s!TransmitT0: waiting for P1 event\n",DRIVER_NAME,NTStatus));
  706. NTStatus = KeWaitForSingleObject(&DeviceExtension->ReadP1Completed,
  707. Executive,
  708. KernelMode,
  709. FALSE,
  710. &liTimeout);
  711. // -----------------------------
  712. // check if P1 has been stalled
  713. // -----------------------------
  714. if (SmartcardExtension->ReaderExtension->fP1Stalled == TRUE)
  715. {
  716. SmartcardDebug(DEBUG_PROTOCOL,
  717. ("%s!STransmitT0: TATUS_DEVICE_DATA_ERROR\n",DRIVER_NAME));
  718. NTStatus = STATUS_DEVICE_DATA_ERROR;
  719. // P1 has been stalled ==> we must reset the pipe and send a NTStatus to enable it again
  720. DebugStatus = CMUSB_ResetPipe(SmartcardExtension->OsData->DeviceObject,
  721. pipeHandle);
  722. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  723. SmartcardExtension->SmartcardReply.BufferLength = 0;
  724. goto ExitTransmitT0;
  725. }
  726. // -------------------------------
  727. // check if a timeout has occured
  728. // -------------------------------
  729. else if (NTStatus == STATUS_TIMEOUT)
  730. {
  731. // probably the smart card does not work
  732. // cancel T0 read operation by sending any P0 command
  733. SmartcardDebug(DEBUG_PROTOCOL,
  734. ("%s!TransmitT0: cancelling read operation\n",DRIVER_NAME));
  735. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  736. NTStatus = CMUSB_WriteP0(SmartcardExtension->OsData->DeviceObject,
  737. 0x20, //bRequest,
  738. 0x00, //bValueLo,
  739. 0x00, //bValueHi,
  740. 0x00, //bIndexLo,
  741. 0x00 //bIndexHi,
  742. );
  743. NTStatus = STATUS_IO_TIMEOUT;
  744. goto ExitTransmitT0;
  745. }
  746. // -------------------------------------------
  747. // check if at least 9 bytes have been sent
  748. // -------------------------------------------
  749. else if (SmartcardExtension->SmartcardReply.BufferLength < 9)
  750. {
  751. NTStatus = STATUS_UNSUCCESSFUL;
  752. goto ExitTransmitT0;
  753. }
  754. else
  755. {
  756. #if DBG
  757. SmartcardDebug(DEBUG_PROTOCOL,
  758. ("%s!<==[P1] ",DRIVER_NAME));
  759. for (i=0;i< SmartcardExtension->SmartcardReply.BufferLength;i++)
  760. {
  761. bTmp = SmartcardExtension->SmartcardReply.Buffer[i];
  762. if (SmartcardExtension->ReaderExtension->fInverseAtr &&
  763. SmartcardExtension->ReaderExtension->ulTimeoutP1 != DEFAULT_TIMEOUT_P1)
  764. {
  765. //CMUSB_InverseBuffer(&bTmp,1);
  766. SmartcardDebug(DEBUG_PROTOCOL,("%x ",bTmp));
  767. }
  768. else
  769. {
  770. SmartcardDebug(DEBUG_PROTOCOL,("%x ",bTmp));
  771. }
  772. }
  773. SmartcardDebug(DEBUG_PROTOCOL,
  774. ("(%ld)\n",SmartcardExtension->SmartcardReply.BufferLength));
  775. #endif
  776. // ignore the first 8 dummy bytes
  777. SmartcardExtension->SmartcardReply.BufferLength -= 8;
  778. RtlCopyBytes((PVOID)(bReadBuffer),
  779. (PVOID)(SmartcardExtension->SmartcardReply.Buffer+8),
  780. SmartcardExtension->SmartcardReply.BufferLength);
  781. RtlCopyBytes((PVOID)(SmartcardExtension->SmartcardReply.Buffer),
  782. (PVOID)(bReadBuffer),
  783. SmartcardExtension->SmartcardReply.BufferLength);
  784. if (SmartcardExtension->ReaderExtension->fInverseAtr)
  785. {
  786. CMUSB_InverseBuffer(SmartcardExtension->SmartcardReply.Buffer,
  787. SmartcardExtension->SmartcardReply.BufferLength);
  788. }
  789. }
  790. }
  791. // -----------------------------
  792. // CardMan USB ==> smart card or
  793. // no transfer
  794. // -----------------------------
  795. else
  796. {
  797. SmartcardDebug(DEBUG_PROTOCOL,
  798. ("%s!TransmitT0: MODE 2\n",DRIVER_NAME));
  799. // copy data to the write buffer
  800. SmartcardDebug(DEBUG_PROTOCOL,
  801. ("%s!TransmitT0: CLA = %x INS = %x P1 = %x P2 = %X L = %x\n",DRIVER_NAME,
  802. SmartcardExtension->SmartcardRequest.Buffer[0],
  803. SmartcardExtension->SmartcardRequest.Buffer[1],
  804. SmartcardExtension->SmartcardRequest.Buffer[2],
  805. SmartcardExtension->SmartcardRequest.Buffer[3],
  806. SmartcardExtension->SmartcardRequest.Buffer[4]));
  807. RtlCopyBytes((PVOID)bWriteBuffer,
  808. (PVOID)SmartcardExtension->SmartcardRequest.Buffer,
  809. ulBytesToWrite);
  810. // SendingToCard:
  811. ulWriteBufferOffset = 0;
  812. ulReadBufferOffset = 0;
  813. bINS = bWriteBuffer[1];
  814. // STEP 1 : write CLA INS P1 P2 Lc
  815. ulBytesToWriteThisStep = 5;
  816. RtlCopyBytes((PVOID)(SmartcardExtension->SmartcardRequest.Buffer),
  817. (PVOID)(bWriteBuffer+ulWriteBufferOffset),
  818. ulBytesToWriteThisStep);
  819. SmartcardExtension->SmartcardRequest.BufferLength = ulBytesToWriteThisStep;
  820. if (SmartcardExtension->ReaderExtension->fInverseAtr == TRUE)
  821. {
  822. CMUSB_InverseBuffer(SmartcardExtension->SmartcardRequest.Buffer,
  823. SmartcardExtension->SmartcardRequest.BufferLength);
  824. }
  825. NTStatus = CMUSB_WriteP0(SmartcardExtension->OsData->DeviceObject,
  826. 0x02, //T=0
  827. 0x00, //bValueLo,
  828. 0x00, //bValueHi,
  829. 0x00, //bIndexLo,
  830. 0x00 //bIndexHi,
  831. );
  832. if (NTStatus != STATUS_SUCCESS)
  833. {
  834. goto ExitTransmitT0;
  835. }
  836. ulWriteBufferOffset += ulBytesToWriteThisStep;
  837. ulBytesStillToWrite -= ulBytesToWriteThisStep;
  838. NTStatus = CMUSB_ResetT0ReadBuffer(SmartcardExtension);
  839. // STEP 2 : read procedure byte
  840. do
  841. {
  842. do
  843. {
  844. SmartcardExtension->SmartcardReply.BufferLength = 1;
  845. NTStatus = CMUSB_ReadT0(SmartcardExtension);
  846. if (NTStatus != STATUS_SUCCESS)
  847. {
  848. goto ExitTransmitT0;
  849. }
  850. ulBytesRead = SmartcardExtension->SmartcardReply.BufferLength;
  851. bProcedureByte = SmartcardExtension->SmartcardReply.Buffer[0];
  852. if (SmartcardExtension->ReaderExtension->fInverseAtr)
  853. {
  854. CMUSB_InverseBuffer(&bProcedureByte,1);
  855. }
  856. SmartcardDebug(DEBUG_PROTOCOL,
  857. ("%s!TransmitT0: procedure byte = %x\n",
  858. DRIVER_NAME,
  859. bProcedureByte));
  860. if (bProcedureByte == 0x60)
  861. {
  862. // wait work waitung time;
  863. // we just try to read again
  864. }
  865. } while (bProcedureByte == 0x60);
  866. // check for ACK
  867. if ((bProcedureByte & 0xFE) == (bINS & 0xFE) )
  868. {
  869. ulBytesToWriteThisStep = ulBytesStillToWrite;
  870. if (ulBytesToWriteThisStep > 0) // at least one byte must be sent to the card
  871. {
  872. RtlCopyBytes((PVOID)(SmartcardExtension->SmartcardRequest.Buffer),
  873. (PVOID)(bWriteBuffer+ulWriteBufferOffset),
  874. ulBytesToWriteThisStep);
  875. SmartcardExtension->SmartcardRequest.BufferLength = ulBytesToWriteThisStep;
  876. if (SmartcardExtension->ReaderExtension->fInverseAtr == TRUE)
  877. {
  878. CMUSB_InverseBuffer(SmartcardExtension->SmartcardRequest.Buffer,
  879. SmartcardExtension->SmartcardRequest.BufferLength);
  880. }
  881. NTStatus = CMUSB_WriteP0(SmartcardExtension->OsData->DeviceObject,
  882. 0x02, //bRequest,
  883. 0x00, //bValueLo,
  884. 0x00, //bValueHi,
  885. 0x00, //bIndexLo,
  886. 0x00 //bIndexHi,
  887. );
  888. if (NTStatus != STATUS_SUCCESS)
  889. {
  890. goto ExitTransmitT0;
  891. }
  892. ulWriteBufferOffset += ulBytesToWriteThisStep;
  893. ulBytesStillToWrite -= ulBytesToWriteThisStep;
  894. }
  895. }
  896. // check for NAK
  897. else if ( (~bProcedureByte & 0xFE) == (bINS & 0xFE))
  898. {
  899. ulBytesToWriteThisStep = 1;
  900. RtlCopyBytes((PVOID)SmartcardExtension->SmartcardRequest.Buffer,
  901. (PVOID)(bWriteBuffer+ulWriteBufferOffset),
  902. ulBytesToWriteThisStep);
  903. SmartcardExtension->SmartcardRequest.BufferLength = ulBytesToWriteThisStep;
  904. if (SmartcardExtension->ReaderExtension->fInverseAtr == TRUE)
  905. {
  906. CMUSB_InverseBuffer(SmartcardExtension->SmartcardRequest.Buffer,
  907. SmartcardExtension->SmartcardRequest.BufferLength);
  908. }
  909. NTStatus = CMUSB_WriteP0(SmartcardExtension->OsData->DeviceObject,
  910. 0x02, //bRequest,
  911. 0x00, //bValueLo,
  912. 0x00, //bValueHi,
  913. 0x00, //bIndexLo,
  914. 0x00 //bIndexHi,
  915. );
  916. if (NTStatus != STATUS_SUCCESS)
  917. {
  918. goto ExitTransmitT0;
  919. }
  920. ulWriteBufferOffset += ulBytesToWriteThisStep;
  921. ulBytesStillToWrite -= ulBytesToWriteThisStep;
  922. }
  923. // check for SW1
  924. else if ( (bProcedureByte > 0x60 && bProcedureByte <= 0x6F) ||
  925. (bProcedureByte >= 0x90 && bProcedureByte <= 0x9F) )
  926. {
  927. bReadBuffer[ulReadBufferOffset] = SmartcardExtension->SmartcardReply.Buffer[0];
  928. ulReadBufferOffset++;
  929. SmartcardExtension->SmartcardReply.BufferLength = 1;
  930. NTStatus = CMUSB_ReadT0(SmartcardExtension);
  931. if (NTStatus != STATUS_SUCCESS)
  932. {
  933. goto ExitTransmitT0;
  934. }
  935. ulBytesRead = SmartcardExtension->SmartcardReply.BufferLength;
  936. RtlCopyBytes((PVOID)(bReadBuffer + ulReadBufferOffset),
  937. (PVOID)(SmartcardExtension->SmartcardReply.Buffer),
  938. SmartcardExtension->SmartcardReply.BufferLength);
  939. ulReadBufferOffset += ulBytesRead;
  940. fSW1SW2Sent = TRUE;
  941. }
  942. else
  943. {
  944. NTStatus = STATUS_UNSUCCESSFUL;
  945. goto ExitTransmitT0;
  946. }
  947. }while (!fSW1SW2Sent);
  948. if (SmartcardExtension->ReaderExtension->fInverseAtr)
  949. {
  950. CMUSB_InverseBuffer(bReadBuffer,
  951. ulReadBufferOffset);
  952. }
  953. // copy received bytes
  954. RtlCopyBytes((PVOID)SmartcardExtension->SmartcardReply.Buffer,
  955. (PVOID)bReadBuffer,
  956. ulReadBufferOffset);
  957. SmartcardExtension->SmartcardReply.BufferLength = ulReadBufferOffset;
  958. }
  959. // let the lib copy the received bytes to the user buffer
  960. NTStatus = SmartcardT0Reply(SmartcardExtension);
  961. ExitTransmitT0:
  962. // ------------------------------------------
  963. // ITSEC E2 requirements: clear write buffers
  964. // ------------------------------------------
  965. RtlFillMemory((PVOID)bWriteBuffer,sizeof(bWriteBuffer),0x00);
  966. RtlFillMemory((PVOID)SmartcardExtension->SmartcardRequest.Buffer,
  967. SmartcardExtension->SmartcardRequest.BufferSize,0x00);
  968. SmartcardDebug(DEBUG_TRACE,
  969. ("%s!TransmitT0 : Exit %lx\n",DRIVER_NAME,NTStatus));
  970. return NTStatus;
  971. }
  972. #undef T0_HEADER_LEN
  973. #undef T0_STATE_LEN
  974. #undef TIMEOUT_CANCEL_READ_P1
  975. /*****************************************************************************
  976. Routine Description:
  977. Arguments:
  978. Return Value:
  979. *****************************************************************************/
  980. NTSTATUS CMUSB_TransmitT1(
  981. PSMARTCARD_EXTENSION SmartcardExtension
  982. )
  983. {
  984. NTSTATUS NTStatus;
  985. NTSTATUS DebugStatus;
  986. ULONG ulBytesToRead;
  987. ULONG ulCurrentWaitTime;
  988. ULONG ulWTXWaitTime;
  989. LARGE_INTEGER waitTime;
  990. BOOLEAN fStateTimer;
  991. ULONG ulTemp;
  992. PDEVICE_EXTENSION DeviceExtension;
  993. PUSBD_INTERFACE_INFORMATION interface;
  994. PUSBD_PIPE_INFORMATION pipeHandle = NULL;
  995. BOOLEAN fCancelTimer = FALSE;
  996. BYTE bTemp;
  997. BYTE bMultiplier;
  998. SmartcardDebug(DEBUG_PROTOCOL,
  999. ("%s!TransmitT1: CWT = %ld(ms)\n",DRIVER_NAME,
  1000. SmartcardExtension->CardCapabilities.T1.CWT/1000));
  1001. SmartcardDebug(DEBUG_PROTOCOL,
  1002. ("%s!TransmitT1: BWT = %ld(ms)\n",DRIVER_NAME,
  1003. SmartcardExtension->CardCapabilities.T1.BWT/1000));
  1004. DeviceExtension = SmartcardExtension->OsData->DeviceObject->DeviceExtension;
  1005. interface = DeviceExtension->UsbInterface;
  1006. pipeHandle = &interface->Pipes[0];
  1007. ulCurrentWaitTime = (ULONG)(1000 + SmartcardExtension->CardCapabilities.T1.BWT/1000);
  1008. ulWTXWaitTime = 0;
  1009. do
  1010. {
  1011. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  1012. NTStatus = SmartcardT1Request(SmartcardExtension);
  1013. if (NTStatus != STATUS_SUCCESS)
  1014. {
  1015. // this should never happen, so we return immediately
  1016. goto ExitTransmitT1;
  1017. }
  1018. NTStatus = CMUSB_WriteP0(SmartcardExtension->OsData->DeviceObject,
  1019. 0x01, //T=1
  1020. 0x00, //bValueLo,
  1021. 0x00, //bValueHi,
  1022. 0x00, //bIndexLo,
  1023. 0x00 //bIndexHi,
  1024. );
  1025. if (NTStatus != STATUS_SUCCESS)
  1026. break; // there must be severe error
  1027. if (ulWTXWaitTime == 0 ) // use BWT
  1028. {
  1029. /*
  1030. SmartcardDebug(
  1031. DEBUG_TRACE,
  1032. ( "%s!ulCurrentWaitTime = %ld\n",
  1033. DRIVER_NAME,ulCurrentWaitTime)
  1034. );
  1035. */
  1036. waitTime = RtlConvertLongToLargeInteger(ulCurrentWaitTime * -10000);
  1037. }
  1038. else // use WTX time
  1039. {
  1040. /*
  1041. SmartcardDebug(
  1042. DEBUG_TRACE,
  1043. ( "%s!ulCurrentWaitTime = %ld\n",
  1044. DRIVER_NAME,ulWTXWaitTime)
  1045. );
  1046. */
  1047. waitTime = RtlConvertLongToLargeInteger(ulWTXWaitTime * -10000);
  1048. }
  1049. KeSetTimer(&SmartcardExtension->ReaderExtension->WaitTimer,
  1050. waitTime,
  1051. NULL);
  1052. // timer is now in the queue
  1053. fCancelTimer = TRUE;
  1054. ulTemp = 0;
  1055. do
  1056. {
  1057. NTStatus = CMUSB_ReadP1(SmartcardExtension->OsData->DeviceObject);
  1058. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  1059. {
  1060. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  1061. goto ExitTransmitT1;
  1062. }
  1063. fStateTimer = KeReadStateTimer(&SmartcardExtension->ReaderExtension->WaitTimer);
  1064. if (fStateTimer == TRUE)
  1065. {
  1066. // timer has been removed from the queue
  1067. fCancelTimer = FALSE;
  1068. SmartcardDebug(DEBUG_PROTOCOL,
  1069. ("%s!TransmitT1: T1 card does not respond in time\n",DRIVER_NAME));
  1070. NTStatus = STATUS_IO_TIMEOUT;
  1071. break;
  1072. }
  1073. if (SmartcardExtension->SmartcardReply.Buffer[0] >= 3)
  1074. {
  1075. if (SmartcardExtension->SmartcardReply.Buffer[1] > ulTemp)
  1076. {
  1077. // restart CWT for 32 bytes
  1078. ulCurrentWaitTime = (ULONG)(100 + 32*(SmartcardExtension->CardCapabilities.T1.CWT/1000));
  1079. waitTime = RtlConvertLongToLargeInteger(ulCurrentWaitTime * -10000);
  1080. KeSetTimer(&SmartcardExtension->ReaderExtension->WaitTimer,
  1081. waitTime,
  1082. NULL);
  1083. // timer is in the queue
  1084. fCancelTimer = TRUE;
  1085. ulTemp = SmartcardExtension->SmartcardReply.Buffer[1];
  1086. }
  1087. else
  1088. {
  1089. // CardMan USB has not received further bytes
  1090. // do nothing
  1091. }
  1092. }
  1093. } while (SmartcardExtension->SmartcardReply.Buffer[0] < 3 ||
  1094. (SmartcardExtension->SmartcardReply.Buffer[0] !=
  1095. SmartcardExtension->SmartcardReply.Buffer[1] + 4 ) );
  1096. // cancel timer now
  1097. if (fCancelTimer == TRUE)
  1098. {
  1099. fCancelTimer = FALSE;
  1100. KeCancelTimer(&SmartcardExtension->ReaderExtension->WaitTimer);
  1101. // timer is removed from the queue
  1102. }
  1103. if (NTStatus != STATUS_SUCCESS)
  1104. {
  1105. SmartcardExtension->SmartcardReply.BufferLength = 0L;
  1106. }
  1107. else
  1108. {
  1109. ulBytesToRead = SmartcardExtension->SmartcardReply.Buffer[0];
  1110. SmartcardExtension->SmartcardReply.BufferLength = SmartcardExtension->SmartcardReply.Buffer[0];
  1111. NTStatus = CMUSB_ReadP0(SmartcardExtension->OsData->DeviceObject);
  1112. }
  1113. bTemp = SmartcardExtension->SmartcardReply.Buffer[1];
  1114. bMultiplier = SmartcardExtension->SmartcardReply.Buffer[3];
  1115. if (SmartcardExtension->ReaderExtension->fInverseAtr == TRUE)
  1116. {
  1117. CMUSB_InverseBuffer(&bTemp,1);
  1118. CMUSB_InverseBuffer(&bMultiplier,1);
  1119. }
  1120. if (bTemp == T1_WTX_REQUEST)
  1121. {
  1122. SmartcardDebug(DEBUG_PROTOCOL,
  1123. ("%s!TransmitT1: T1_WTX_REQUEST received\n",DRIVER_NAME));
  1124. ulWTXWaitTime = (ULONG)(1000 +
  1125. bMultiplier * (SmartcardExtension->CardCapabilities.T1.BWT/1000));
  1126. }
  1127. else
  1128. {
  1129. ulWTXWaitTime = 0;
  1130. }
  1131. // bug fix for smclib
  1132. if (SmartcardExtension->T1.State == T1_IFS_RESPONSE &&
  1133. SmartcardExtension->T1.OriginalState == T1_I_BLOCK)
  1134. {
  1135. SmartcardExtension->T1.State = T1_I_BLOCK;
  1136. }
  1137. NTStatus = SmartcardT1Reply(SmartcardExtension);
  1138. }
  1139. while (NTStatus == STATUS_MORE_PROCESSING_REQUIRED);
  1140. ExitTransmitT1:
  1141. // ------------------------------------------
  1142. // ITSEC E2 requirements: clear write buffers
  1143. // ------------------------------------------
  1144. RtlFillMemory((PVOID)SmartcardExtension->SmartcardRequest.Buffer,
  1145. SmartcardExtension->SmartcardRequest.BufferSize,0x00);
  1146. // timer will be cancelled here if there was an error
  1147. if (fCancelTimer == TRUE)
  1148. {
  1149. KeCancelTimer(&SmartcardExtension->ReaderExtension->WaitTimer);
  1150. // timer is removed from the queue
  1151. }
  1152. return NTStatus;
  1153. }
  1154. /*****************************************************************************
  1155. Routine Description:
  1156. This function sets the desired protocol . If necessary a PTS is performed
  1157. Arguments: pointer to SMARTCARD_EXTENSION
  1158. Return Value: NT NTStatus
  1159. *****************************************************************************/
  1160. NTSTATUS CMUSB_SetProtocol(
  1161. PSMARTCARD_EXTENSION SmartcardExtension
  1162. )
  1163. {
  1164. NTSTATUS NTStatus = STATUS_SUCCESS;
  1165. NTSTATUS DebugStatus;
  1166. ULONG ulNewProtocol;
  1167. UCHAR abPTSRequest[4];
  1168. UCHAR abReadBuffer[6];
  1169. UCHAR abPTSReply [4];
  1170. ULONG ulBytesRead;
  1171. LARGE_INTEGER liWaitTime;
  1172. BOOLEAN fStateTimer;
  1173. ULONG ulWaitTime;
  1174. PDEVICE_EXTENSION DeviceExtension;
  1175. PUSBD_PIPE_INFORMATION pipeHandle = NULL;
  1176. PUSBD_INTERFACE_INFORMATION interface;
  1177. UCHAR bTemp;
  1178. BOOLEAN fCancelTimer = FALSE;
  1179. SmartcardDebug(DEBUG_TRACE,
  1180. ("%s!SetProtocol : Enter\n",DRIVER_NAME));
  1181. DeviceExtension = SmartcardExtension->OsData->DeviceObject->DeviceExtension;
  1182. interface = DeviceExtension->UsbInterface;
  1183. pipeHandle = &interface->Pipes[0];
  1184. //
  1185. // Check if the card is already in specific state
  1186. // and if the caller wants to have the already selected protocol.
  1187. // We return success if this is the case.
  1188. //
  1189. if ((SmartcardExtension->CardCapabilities.Protocol.Selected & SmartcardExtension->MinorIoControlCode))
  1190. {
  1191. NTStatus = STATUS_SUCCESS;
  1192. goto ExitSetProtocol;
  1193. }
  1194. ulNewProtocol = SmartcardExtension->MinorIoControlCode;
  1195. while (TRUE)
  1196. {
  1197. // set initial character of PTS
  1198. abPTSRequest[0] = 0xFF;
  1199. // set the format character
  1200. if (SmartcardExtension->CardCapabilities.Protocol.Supported &
  1201. ulNewProtocol &
  1202. SCARD_PROTOCOL_T1)
  1203. {
  1204. // select T=1 and indicate that PTS1 follows
  1205. abPTSRequest[1] = 0x11;
  1206. SmartcardExtension->CardCapabilities.Protocol.Selected =
  1207. SCARD_PROTOCOL_T1;
  1208. }
  1209. else if (SmartcardExtension->CardCapabilities.Protocol.Supported &
  1210. ulNewProtocol &
  1211. SCARD_PROTOCOL_T0)
  1212. {
  1213. // select T=1 and indicate that PTS1 follows
  1214. abPTSRequest[1] = 0x10;
  1215. SmartcardExtension->CardCapabilities.Protocol.Selected =
  1216. SCARD_PROTOCOL_T0;
  1217. }
  1218. else
  1219. {
  1220. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  1221. goto ExitSetProtocol;
  1222. }
  1223. // CardMan USB support higher baudrates only for T=1
  1224. // ==> Dl=1
  1225. if (abPTSRequest[1] == 0x10)
  1226. {
  1227. SmartcardDebug(DEBUG_PROTOCOL,
  1228. ("%s! overwriting PTS1 for T=0\n",DRIVER_NAME));
  1229. SmartcardExtension->CardCapabilities.PtsData.Dl = 0x01;
  1230. }
  1231. // set pts1 which codes Fl and Dl
  1232. bTemp = (BYTE) (SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  1233. SmartcardExtension->CardCapabilities.PtsData.Dl);
  1234. switch (bTemp)
  1235. {
  1236. case 0x11:
  1237. case 0x12:
  1238. case 0x13:
  1239. case 0x14:
  1240. case 0x18:
  1241. case 0x91:
  1242. case 0x92:
  1243. case 0x93:
  1244. case 0x94:
  1245. case 0x98:
  1246. // do nothing
  1247. // we support these Fl/Dl parameters
  1248. break ;
  1249. default:
  1250. SmartcardDebug(DEBUG_PROTOCOL,
  1251. ("%s! overwriting PTS1(0x%x)\n",DRIVER_NAME,bTemp));
  1252. // we must correct Fl/Dl
  1253. SmartcardExtension->CardCapabilities.PtsData.Dl = 0x01;
  1254. SmartcardExtension->CardCapabilities.PtsData.Fl = 0x01;
  1255. bTemp = (BYTE) (SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  1256. SmartcardExtension->CardCapabilities.PtsData.Dl);
  1257. break;
  1258. }
  1259. abPTSRequest[2] = bTemp;
  1260. // set pck (check character)
  1261. abPTSRequest[3] = (BYTE)(abPTSRequest[0] ^ abPTSRequest[1] ^ abPTSRequest[2]);
  1262. SmartcardDebug(DEBUG_PROTOCOL,
  1263. ("%s! writing PTS request\n",DRIVER_NAME));
  1264. RtlCopyBytes((PVOID)SmartcardExtension->SmartcardRequest.Buffer,
  1265. (PVOID)abPTSRequest,
  1266. 4);
  1267. SmartcardExtension->SmartcardRequest.BufferLength = 4;
  1268. NTStatus = CMUSB_WriteP0(SmartcardExtension->OsData->DeviceObject,
  1269. 0x01, //we can use T=1 setting for direct communication
  1270. 0x00, //bValueLo,
  1271. 0x00, //bValueHi,
  1272. 0x00, //bIndexLo,
  1273. 0x00); //bIndexHi,
  1274. if (NTStatus != STATUS_SUCCESS)
  1275. {
  1276. SmartcardDebug(DEBUG_ERROR,
  1277. ("%s! writing PTS request failed\n",DRIVER_NAME));
  1278. goto ExitSetProtocol;
  1279. }
  1280. // read back pts data
  1281. SmartcardDebug(DEBUG_PROTOCOL,
  1282. ("%s! reading PTS reply\n",DRIVER_NAME));
  1283. // maximim initial waiting time is 9600 * etu
  1284. // => 1 sec is sufficient
  1285. ulWaitTime = 1000;
  1286. liWaitTime = RtlConvertLongToLargeInteger(ulWaitTime * -10000);
  1287. KeSetTimer(&SmartcardExtension->ReaderExtension->WaitTimer,
  1288. liWaitTime,
  1289. NULL);
  1290. // timer is now in the queue
  1291. fCancelTimer = TRUE;
  1292. do
  1293. {
  1294. SmartcardExtension->ReaderExtension->ulTimeoutP1 = ulWaitTime;
  1295. DebugStatus = CMUSB_ReadP1(SmartcardExtension->OsData->DeviceObject);
  1296. // -----------------------------
  1297. // check if P1 has been stalled
  1298. // -----------------------------
  1299. if (SmartcardExtension->ReaderExtension->fP1Stalled == TRUE)
  1300. {
  1301. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  1302. SmartcardExtension->SmartcardReply.BufferLength = 0;
  1303. goto ExitSetProtocol;
  1304. }
  1305. fStateTimer = KeReadStateTimer(&SmartcardExtension->ReaderExtension->WaitTimer);
  1306. if (fStateTimer == TRUE)
  1307. {
  1308. // timer has timed out and has been removed from the queue
  1309. fCancelTimer = FALSE;
  1310. SmartcardDebug(DEBUG_PROTOCOL,
  1311. ("%s! Timeout while PTS reply\n",DRIVER_NAME));
  1312. NTStatus = STATUS_IO_TIMEOUT;
  1313. break;
  1314. }
  1315. } while (SmartcardExtension->SmartcardReply.Buffer[0] < 4 );
  1316. if (fCancelTimer == TRUE)
  1317. {
  1318. fCancelTimer = FALSE;
  1319. // timer is still in the queue, remove it
  1320. KeCancelTimer(&SmartcardExtension->ReaderExtension->WaitTimer);
  1321. }
  1322. if (NTStatus == STATUS_IO_TIMEOUT)
  1323. {
  1324. if (SmartcardExtension->SmartcardReply.Buffer[0] == 3)
  1325. {
  1326. SmartcardExtension->SmartcardReply.BufferLength = 3;
  1327. }
  1328. else
  1329. {
  1330. if (SmartcardExtension->CardCapabilities.PtsData.Type !=
  1331. PTS_TYPE_DEFAULT)
  1332. {
  1333. SmartcardDebug(DEBUG_PROTOCOL,
  1334. ("%s! PTS failed : Trying default parameters\n",DRIVER_NAME));
  1335. // the card did either not reply or it replied incorrectly
  1336. // so try default values
  1337. SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_DEFAULT;
  1338. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  1339. NTStatus = CMUSB_CardPower(SmartcardExtension);
  1340. continue;
  1341. }
  1342. goto ExitSetProtocol;
  1343. }
  1344. }
  1345. else
  1346. {
  1347. SmartcardExtension->SmartcardReply.BufferLength = 4;
  1348. }
  1349. NTStatus = CMUSB_ReadP0(SmartcardExtension->OsData->DeviceObject);
  1350. ulBytesRead = SmartcardExtension->SmartcardReply.BufferLength;
  1351. if (NTStatus != STATUS_SUCCESS ||
  1352. !(ulBytesRead == 4 || ulBytesRead == 3))
  1353. {
  1354. SmartcardDebug(DEBUG_ERROR,
  1355. ("%s! reading PTS reply failed\n",DRIVER_NAME));
  1356. goto ExitSetProtocol;
  1357. }
  1358. RtlCopyBytes((PVOID)abPTSReply,
  1359. (PVOID)SmartcardExtension->SmartcardReply.Buffer,
  1360. ulBytesRead);
  1361. if (ulBytesRead == 4 &&
  1362. abPTSReply[0] == abPTSRequest[0] &&
  1363. abPTSReply[1] == abPTSRequest[1] &&
  1364. abPTSReply[2] == abPTSRequest[2] &&
  1365. abPTSReply[3] == abPTSRequest[3] )
  1366. {
  1367. SmartcardDebug(DEBUG_PROTOCOL,
  1368. ("%s! PTS request and reply match\n",DRIVER_NAME));
  1369. NTStatus = STATUS_SUCCESS;
  1370. switch (abPTSRequest[2])
  1371. {
  1372. // Fl/Dl
  1373. case 0x11:
  1374. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1375. CMUSB_FREQUENCY_3_72MHZ + CMUSB_BAUDRATE_9600;
  1376. break ;
  1377. case 0x12:
  1378. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1379. CMUSB_FREQUENCY_3_72MHZ + CMUSB_BAUDRATE_19200;
  1380. break ;
  1381. case 0x13:
  1382. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1383. CMUSB_FREQUENCY_3_72MHZ + CMUSB_BAUDRATE_38400;
  1384. break ;
  1385. case 0x14:
  1386. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1387. CMUSB_FREQUENCY_3_72MHZ + CMUSB_BAUDRATE_76800;
  1388. break ;
  1389. case 0x18:
  1390. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1391. CMUSB_FREQUENCY_3_72MHZ + CMUSB_BAUDRATE_115200;
  1392. break ;
  1393. case 0x91:
  1394. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1395. CMUSB_FREQUENCY_5_12MHZ + CMUSB_BAUDRATE_9600;
  1396. break ;
  1397. case 0x92:
  1398. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1399. CMUSB_FREQUENCY_5_12MHZ + CMUSB_BAUDRATE_19200;
  1400. break ;
  1401. case 0x93:
  1402. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1403. CMUSB_FREQUENCY_5_12MHZ + CMUSB_BAUDRATE_38400;
  1404. break ;
  1405. case 0x94:
  1406. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1407. CMUSB_FREQUENCY_5_12MHZ + CMUSB_BAUDRATE_76800;
  1408. break ;
  1409. case 0x98:
  1410. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1411. CMUSB_FREQUENCY_5_12MHZ + CMUSB_BAUDRATE_115200;
  1412. break ;
  1413. }
  1414. break;
  1415. }
  1416. if (ulBytesRead == 3 &&
  1417. abPTSReply[0] == abPTSRequest[0] &&
  1418. (abPTSReply[1] & 0x7F) == (abPTSRequest[1] & 0x0F) &&
  1419. abPTSReply[2] == (BYTE)(abPTSReply[0] ^ abPTSReply[1] ))
  1420. {
  1421. SmartcardDebug(DEBUG_PROTOCOL,
  1422. ("%s! short PTS reply received\n",DRIVER_NAME));
  1423. NTStatus = STATUS_SUCCESS;
  1424. if ((abPTSRequest[2] & 0x90) == 0x90)
  1425. {
  1426. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1427. CMUSB_FREQUENCY_5_12MHZ + CMUSB_BAUDRATE_9600;
  1428. }
  1429. else
  1430. {
  1431. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate =
  1432. CMUSB_FREQUENCY_3_72MHZ + CMUSB_BAUDRATE_9600;
  1433. }
  1434. break ;
  1435. }
  1436. if (SmartcardExtension->CardCapabilities.PtsData.Type !=
  1437. PTS_TYPE_DEFAULT)
  1438. {
  1439. SmartcardDebug(DEBUG_PROTOCOL,
  1440. ("%s! PTS failed : Trying default parameters\n",DRIVER_NAME));
  1441. // the card did either not reply or it replied incorrectly
  1442. // so try default values
  1443. SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_DEFAULT;
  1444. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  1445. NTStatus = CMUSB_CardPower(SmartcardExtension);
  1446. continue;
  1447. }
  1448. // the card failed the pts request
  1449. NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
  1450. goto ExitSetProtocol;
  1451. }
  1452. ExitSetProtocol:
  1453. switch (NTStatus)
  1454. {
  1455. case STATUS_IO_TIMEOUT:
  1456. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1457. *SmartcardExtension->IoRequest.Information = 0;
  1458. break;
  1459. case STATUS_SUCCESS:
  1460. // now indicate that we're in specific mode
  1461. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  1462. // return the selected protocol to the caller
  1463. *(PULONG) SmartcardExtension->IoRequest.ReplyBuffer =
  1464. SmartcardExtension->CardCapabilities.Protocol.Selected;
  1465. *SmartcardExtension->IoRequest.Information =
  1466. sizeof(SmartcardExtension->CardCapabilities.Protocol.Selected);
  1467. SmartcardDebug(DEBUG_PROTOCOL,
  1468. ("%s! Selected protocol: T=%ld\n",DRIVER_NAME,
  1469. SmartcardExtension->CardCapabilities.Protocol.Selected-1));
  1470. // -----------------------
  1471. // set parameters
  1472. // -----------------------
  1473. if (SmartcardExtension->CardCapabilities.N != 0xff)
  1474. {
  1475. // 0 <= N <= 254
  1476. // if (SmartcardExtension->ReaderExtension->CardParameters.bBaudRate ==
  1477. // CMUSB_FREQUENCY_5_12MHZ + CMUSB_BAUDRATE_115200 ||
  1478. // SmartcardExtension->ReaderExtension->CardParameters.bBaudRate ==
  1479. // CMUSB_FREQUENCY_3_72MHZ + CMUSB_BAUDRATE_115200 )
  1480. // {
  1481. // SmartcardExtension->ReaderExtension->CardParameters.bStopBits = 1 + SmartcardExtension->CardCapabilities.N;
  1482. // }
  1483. // else
  1484. // {
  1485. SmartcardExtension->ReaderExtension->CardParameters.bStopBits = 2 + SmartcardExtension->CardCapabilities.N;
  1486. // }
  1487. }
  1488. else
  1489. {
  1490. // N = 255
  1491. if (SmartcardExtension->CardCapabilities.Protocol.Selected & SCARD_PROTOCOL_T0)
  1492. {
  1493. // 12 etu for T=0;
  1494. SmartcardExtension->ReaderExtension->CardParameters.bStopBits = 2;
  1495. }
  1496. else
  1497. {
  1498. // 11 etu for T=1
  1499. SmartcardExtension->ReaderExtension->CardParameters.bStopBits = 1;
  1500. }
  1501. }
  1502. NTStatus = CMUSB_SetCardParameters (SmartcardExtension->OsData->DeviceObject,
  1503. SmartcardExtension->ReaderExtension->CardParameters.bCardType,
  1504. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate,
  1505. SmartcardExtension->ReaderExtension->CardParameters.bStopBits);
  1506. break;
  1507. default :
  1508. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1509. *SmartcardExtension->IoRequest.Information = 0;
  1510. break;
  1511. }
  1512. SmartcardDebug(DEBUG_TRACE,
  1513. ("%s!SetProtocol : Exit %lx\n",DRIVER_NAME,NTStatus));
  1514. return NTStatus;
  1515. }
  1516. /*****************************************************************************
  1517. Routine Description:
  1518. Arguments:
  1519. Return Value:
  1520. *****************************************************************************/
  1521. NTSTATUS
  1522. CMUSB_CardPower(IN PSMARTCARD_EXTENSION SmartcardExtension)
  1523. {
  1524. NTSTATUS NTStatus = STATUS_SUCCESS;
  1525. NTSTATUS DebugStatus = STATUS_SUCCESS;
  1526. UCHAR pbAtrBuffer[MAXIMUM_ATR_LENGTH];
  1527. ULONG ulAtrLength;
  1528. #if DBG
  1529. ULONG i;
  1530. #endif;
  1531. SmartcardDebug(DEBUG_TRACE,
  1532. ("%s!CardPower: Enter\n",DRIVER_NAME));
  1533. #if DBG
  1534. switch (SmartcardExtension->MinorIoControlCode)
  1535. {
  1536. case SCARD_WARM_RESET:
  1537. SmartcardDebug(DEBUG_ATR,
  1538. ("%s!CardPower: SCARD_WARM_RESTART\n",DRIVER_NAME));
  1539. break;
  1540. case SCARD_COLD_RESET:
  1541. SmartcardDebug(DEBUG_ATR,
  1542. ("%s!CardPower: SCARD_COLD_RESTART\n",DRIVER_NAME));
  1543. break;
  1544. case SCARD_POWER_DOWN:
  1545. SmartcardDebug(DEBUG_ATR,
  1546. ("%s!CardPower: SCARD_POWER_DOWN\n",DRIVER_NAME));
  1547. break;
  1548. }
  1549. #endif
  1550. //DbgBreakPoint();
  1551. switch (SmartcardExtension->MinorIoControlCode)
  1552. {
  1553. case SCARD_WARM_RESET:
  1554. case SCARD_COLD_RESET:
  1555. // try asynchronous cards first
  1556. // because some asynchronous cards
  1557. // do not return 0xFF in the first byte
  1558. NTStatus = CMUSB_PowerOnCard(SmartcardExtension,
  1559. pbAtrBuffer,
  1560. &ulAtrLength);
  1561. if (NTStatus != STATUS_SUCCESS && NTStatus!= STATUS_NO_MEDIA)
  1562. {
  1563. NTStatus = CMUSB_PowerOnSynchronousCard(SmartcardExtension,
  1564. pbAtrBuffer,
  1565. &ulAtrLength);
  1566. }
  1567. if (NTStatus != STATUS_SUCCESS)
  1568. {
  1569. goto ExitCardPower;
  1570. }
  1571. if (SmartcardExtension->ReaderExtension->fRawModeNecessary == FALSE)
  1572. {
  1573. // copy ATR to smart card structure
  1574. // the lib needs the ATR for evaluation of the card parameters
  1575. RtlCopyBytes((PVOID)SmartcardExtension->CardCapabilities.ATR.Buffer,
  1576. (PVOID)pbAtrBuffer,
  1577. ulAtrLength);
  1578. SmartcardExtension->CardCapabilities.ATR.Length = (UCHAR)ulAtrLength;
  1579. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_NEGOTIABLE;
  1580. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1581. NTStatus = SmartcardUpdateCardCapabilities(SmartcardExtension);
  1582. if (NTStatus != STATUS_SUCCESS)
  1583. {
  1584. goto ExitCardPower;
  1585. }
  1586. // -----------------------
  1587. // set parameters
  1588. // -----------------------
  1589. if (SmartcardExtension->CardCapabilities.N != 0xff)
  1590. {
  1591. // 0 <= N <= 254
  1592. SmartcardExtension->ReaderExtension->CardParameters.bStopBits = 2 + SmartcardExtension->CardCapabilities.N;
  1593. }
  1594. else
  1595. {
  1596. // N = 255
  1597. if (SmartcardExtension->CardCapabilities.Protocol.Selected & SCARD_PROTOCOL_T0)
  1598. {
  1599. // 12 etu for T=0;
  1600. SmartcardExtension->ReaderExtension->CardParameters.bStopBits = 2;
  1601. }
  1602. else
  1603. {
  1604. // 11 etu for T=1
  1605. SmartcardExtension->ReaderExtension->CardParameters.bStopBits = 1;
  1606. }
  1607. }
  1608. NTStatus = CMUSB_SetCardParameters (SmartcardExtension->OsData->DeviceObject,
  1609. SmartcardExtension->ReaderExtension->CardParameters.bCardType,
  1610. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate,
  1611. SmartcardExtension->ReaderExtension->CardParameters.bStopBits);
  1612. #if DBG
  1613. SmartcardDebug(DEBUG_ATR,("%s!CardPower: ATR : ",DRIVER_NAME));
  1614. for (i = 0;i < ulAtrLength;i++)
  1615. SmartcardDebug(DEBUG_ATR,("%2.2x ",SmartcardExtension->CardCapabilities.ATR.Buffer[i]));
  1616. SmartcardDebug(DEBUG_ATR,("\n"));
  1617. #endif
  1618. }
  1619. else
  1620. {
  1621. SmartcardExtension->CardCapabilities.ATR.Buffer[0] = 0x3B;
  1622. SmartcardExtension->CardCapabilities.ATR.Buffer[1] = 0x04;
  1623. RtlCopyBytes((PVOID)&SmartcardExtension->CardCapabilities.ATR.Buffer[2],
  1624. (PVOID)pbAtrBuffer,
  1625. ulAtrLength);
  1626. ulAtrLength += 2;
  1627. SmartcardExtension->CardCapabilities.ATR.Length = (UCHAR)ulAtrLength;
  1628. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  1629. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
  1630. NTStatus = SmartcardUpdateCardCapabilities(SmartcardExtension);
  1631. if (NTStatus != STATUS_SUCCESS)
  1632. {
  1633. goto ExitCardPower;
  1634. }
  1635. SmartcardDebug(DEBUG_ATR,("CardPower: ATR of synchronous smart card : %2.2x %2.2x %2.2x %2.2x\n",
  1636. pbAtrBuffer[0],pbAtrBuffer[1],pbAtrBuffer[2],pbAtrBuffer[3]));
  1637. // copied from serial CardMan
  1638. //SmartcardExtension->ReaderExtension->SyncParameters.fCardResetRequested = TRUE;
  1639. }
  1640. // copy ATR to user space
  1641. RtlCopyBytes((PVOID)SmartcardExtension->IoRequest.ReplyBuffer,
  1642. (PVOID)SmartcardExtension->CardCapabilities.ATR.Buffer,
  1643. SmartcardExtension->CardCapabilities.ATR.Length);
  1644. *SmartcardExtension->IoRequest.Information = ulAtrLength;
  1645. break;
  1646. case SCARD_POWER_DOWN:
  1647. NTStatus = CMUSB_PowerOffCard(SmartcardExtension);
  1648. if (NTStatus != STATUS_SUCCESS)
  1649. {
  1650. goto ExitCardPower;
  1651. }
  1652. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SWALLOWED;
  1653. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1654. break;
  1655. }
  1656. ExitCardPower:
  1657. SmartcardDebug(DEBUG_TRACE,
  1658. ("%s!CardPower: Exit %lx\n",DRIVER_NAME,NTStatus));
  1659. return NTStatus;
  1660. }
  1661. /*****************************************************************************
  1662. Routine Description:
  1663. Arguments:
  1664. Return Value:
  1665. *****************************************************************************/
  1666. NTSTATUS CMUSB_PowerOffCard (
  1667. IN PSMARTCARD_EXTENSION SmartcardExtension
  1668. )
  1669. {
  1670. NTSTATUS NTStatus;
  1671. NTSTATUS DebugStatus;
  1672. PDEVICE_OBJECT DeviceObject;
  1673. ULONG ulBytesRead;
  1674. SmartcardDebug(DEBUG_TRACE,
  1675. ("%s!PowerOffCard: Enter\n",DRIVER_NAME));
  1676. DeviceObject = SmartcardExtension->OsData->DeviceObject;
  1677. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  1678. NTStatus = CMUSB_WriteP0(DeviceObject,
  1679. 0x11, //bRequest,
  1680. 0x00, //bValueLo,
  1681. 0x00, //bValueHi,
  1682. 0x00, //bIndexLo,
  1683. 0x00 //bIndexHi,
  1684. );
  1685. // now read the NTStatus
  1686. SmartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1;
  1687. NTStatus = CMUSB_ReadP1(DeviceObject);
  1688. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  1689. {
  1690. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  1691. goto ExitPowerOff;
  1692. }
  1693. ExitPowerOff:
  1694. // set card state for update thread
  1695. // otherwise a card removal/insertion would be recognized
  1696. if (SmartcardExtension->ReaderExtension->ulOldCardState == POWERED)
  1697. SmartcardExtension->ReaderExtension->ulOldCardState = INSERTED;
  1698. SmartcardDebug(DEBUG_TRACE,
  1699. ("%s!PowerOffCard: Exit %lx\n",DRIVER_NAME,NTStatus));
  1700. return NTStatus;
  1701. }
  1702. /*****************************************************************************
  1703. Routine Description:
  1704. Arguments:
  1705. Return Value:
  1706. *****************************************************************************/
  1707. NTSTATUS CMUSB_ReadStateAfterP1Stalled(
  1708. IN PDEVICE_OBJECT DeviceObject
  1709. )
  1710. {
  1711. NTSTATUS NTStatus;
  1712. PSMARTCARD_EXTENSION SmartcardExtension;
  1713. PDEVICE_EXTENSION DeviceExtension;
  1714. SmartcardDebug(DEBUG_TRACE,
  1715. ("%s!ReadStateAfterP1Stalled: Enter\n",DRIVER_NAME));
  1716. DeviceExtension = DeviceObject->DeviceExtension;
  1717. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1718. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  1719. NTStatus = CMUSB_WriteP0(DeviceObject,
  1720. 0x20, //bRequest,
  1721. 0x00, //bValueLo,
  1722. 0x00, //bValueHi,
  1723. 0x00, //bIndexLo,
  1724. 0x00 //bIndexHi,
  1725. );
  1726. if (NTStatus != STATUS_SUCCESS)
  1727. {
  1728. // if we can't read the NTStatus there must be a serious error
  1729. goto ExitReadState;
  1730. }
  1731. SmartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1;
  1732. SmartcardExtension->SmartcardReply.BufferLength = 1;
  1733. NTStatus = CMUSB_ReadP1(DeviceObject);
  1734. if (NTStatus != STATUS_SUCCESS)
  1735. {
  1736. // if we can't read the NTStatus there must be a serious error
  1737. goto ExitReadState;
  1738. }
  1739. SmartcardDebug(DEBUG_TRACE,
  1740. ("%s!ReadStateAfterP1Stalled: Exit %lx\n",DRIVER_NAME,NTStatus));
  1741. ExitReadState:
  1742. return NTStatus;
  1743. }
  1744. /*****************************************************************************
  1745. Routine Description:
  1746. Arguments:
  1747. Return Value:
  1748. *****************************************************************************/
  1749. NTSTATUS CMUSB_PowerOnCard (
  1750. IN PSMARTCARD_EXTENSION SmartcardExtension,
  1751. IN PUCHAR pbATR,
  1752. OUT PULONG pulATRLength
  1753. )
  1754. {
  1755. UCHAR abMaxAtrBuffer[SCARD_ATR_LENGTH];
  1756. ULONG ulCurrentLengthOfAtr;
  1757. ULONG ulPtrToCurrentAtrByte;
  1758. ULONG ulExpectedLengthOfAtr;
  1759. BOOLEAN fTryNextCard;
  1760. BOOLEAN fValidAtrReceived = FALSE;
  1761. ULONG ulBytesRead;
  1762. NTSTATUS NTStatus;
  1763. PDEVICE_OBJECT DeviceObject;
  1764. NTSTATUS DebugStatus;
  1765. BOOLEAN fInverseAtr = FALSE;
  1766. ULONG ulHistoricalBytes;
  1767. ULONG i;
  1768. BOOLEAN fTDxSent;
  1769. BOOLEAN fOnlyT0;
  1770. UCHAR bResetMode;
  1771. UCHAR abFrequency[2] = {CMUSB_FREQUENCY_3_72MHZ,
  1772. CMUSB_FREQUENCY_5_12MHZ};
  1773. ULONG ulCardType;
  1774. UCHAR bCardType;
  1775. UCHAR bStopBits;
  1776. UCHAR bBaudRate;
  1777. SmartcardDebug(DEBUG_TRACE,
  1778. ("%s!PowerOnCard: Enter\n",DRIVER_NAME));
  1779. DeviceObject = SmartcardExtension->OsData->DeviceObject;
  1780. if (SmartcardExtension->MinorIoControlCode == SCARD_COLD_RESET)
  1781. bResetMode = SMARTCARD_COLD_RESET;
  1782. else
  1783. bResetMode = SMARTCARD_WARM_RESET;
  1784. // clear card parameters
  1785. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate = 0;
  1786. SmartcardExtension->ReaderExtension->CardParameters.bCardType = 0;
  1787. SmartcardExtension->ReaderExtension->CardParameters.bStopBits = 0;
  1788. // set default card parameters
  1789. // asnyc, 9600 baud, even parity
  1790. bStopBits = 2;
  1791. bBaudRate = CMUSB_BAUDRATE_9600;
  1792. bCardType = CMUSB_SMARTCARD_ASYNCHRONOUS;
  1793. for (ulCardType = 0;ulCardType < 2;ulCardType++)
  1794. {
  1795. #if DBG
  1796. switch (ulCardType)
  1797. {
  1798. case 0:
  1799. SmartcardDebug(DEBUG_ATR,
  1800. ("%s!PowerOnCard: trying 3.72 Mhz smart card\n",DRIVER_NAME));
  1801. break;
  1802. case 1:
  1803. SmartcardDebug(DEBUG_ATR,
  1804. ("%s!PowerOnCard: trying 5.12 Mhz smart card\n",DRIVER_NAME));
  1805. break;
  1806. }
  1807. #endif
  1808. bBaudRate |= abFrequency[ulCardType];
  1809. NTStatus = CMUSB_SetCardParameters (SmartcardExtension->OsData->DeviceObject,
  1810. bCardType,
  1811. bBaudRate,
  1812. bStopBits);
  1813. if (NTStatus != STATUS_SUCCESS)
  1814. {
  1815. // if we can't set the card parameters there must be a serious error
  1816. goto ExitPowerOnCard;
  1817. }
  1818. ulCurrentLengthOfAtr = 0L;
  1819. ulPtrToCurrentAtrByte = 0L;
  1820. fOnlyT0 = TRUE;
  1821. fTryNextCard = FALSE;
  1822. fValidAtrReceived = FALSE;
  1823. RtlFillMemory((PVOID)abMaxAtrBuffer,
  1824. sizeof(abMaxAtrBuffer),
  1825. 0x00);
  1826. // resync CardManUSB by reading the NTStatus byte
  1827. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  1828. NTStatus = CMUSB_WriteP0(DeviceObject,
  1829. 0x20, //bRequest,
  1830. 0x00, //bValueLo,
  1831. 0x00, //bValueHi,
  1832. 0x00, //bIndexLo,
  1833. 0x00 //bIndexHi,
  1834. );
  1835. if (NTStatus != STATUS_SUCCESS)
  1836. {
  1837. // if we can't read the NTStatus there must be a serious error
  1838. goto ExitPowerOnCard;
  1839. }
  1840. SmartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1;
  1841. SmartcardExtension->SmartcardReply.BufferLength = 1;
  1842. NTStatus = CMUSB_ReadP1(DeviceObject);
  1843. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  1844. {
  1845. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  1846. goto ExitPowerOnCard;
  1847. }
  1848. else if (NTStatus != STATUS_SUCCESS)
  1849. {
  1850. // if we can't read the NTStatus there must be a serious error
  1851. goto ExitPowerOnCard;
  1852. }
  1853. // check if card is really inserted
  1854. if (SmartcardExtension->SmartcardReply.Buffer[0] == 0x00)
  1855. {
  1856. NTStatus = STATUS_NO_MEDIA;
  1857. goto ExitPowerOnCard;
  1858. }
  1859. // issue power on command
  1860. NTStatus = CMUSB_WriteP0(DeviceObject,
  1861. 0x10, //bRequest,
  1862. bResetMode, //bValueLo,
  1863. 0x00, //bValueHi,
  1864. 0x00, //bIndexLo,
  1865. 0x00 //bIndexHi,
  1866. );
  1867. if (NTStatus != STATUS_SUCCESS)
  1868. {
  1869. // if we can't issue the power on command there must be a serious error
  1870. goto ExitPowerOnCard;
  1871. }
  1872. SmartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1;
  1873. NTStatus = CMUSB_ReadP1(DeviceObject);
  1874. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  1875. {
  1876. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  1877. goto ExitPowerOnCard;
  1878. }
  1879. else if (NTStatus != STATUS_SUCCESS)
  1880. {
  1881. continue;
  1882. }
  1883. ulBytesRead = SmartcardExtension->SmartcardReply.BufferLength;
  1884. RtlCopyBytes((PVOID)(abMaxAtrBuffer+ulCurrentLengthOfAtr),
  1885. (PVOID)SmartcardExtension->SmartcardReply.Buffer,
  1886. ulBytesRead);
  1887. // check if inverse convention used
  1888. if (abMaxAtrBuffer[0] == 0x03)
  1889. {
  1890. fInverseAtr = TRUE;
  1891. }
  1892. if (fInverseAtr)
  1893. {
  1894. CMUSB_InverseBuffer(abMaxAtrBuffer+ulCurrentLengthOfAtr,
  1895. ulBytesRead);
  1896. }
  1897. if (abMaxAtrBuffer[0] != 0x3B &&
  1898. abMaxAtrBuffer[0] != 0x3F )
  1899. {
  1900. continue; // try next card
  1901. }
  1902. ulCurrentLengthOfAtr += ulBytesRead;
  1903. // ---------------------
  1904. // TS character
  1905. // ---------------------
  1906. SmartcardDebug(DEBUG_ATR,("PowerOnCard: TS = %2.2x\n",abMaxAtrBuffer[0]));
  1907. if (abMaxAtrBuffer[ulPtrToCurrentAtrByte] != 0x3B &&
  1908. abMaxAtrBuffer[ulPtrToCurrentAtrByte] != 0x3F )
  1909. {
  1910. continue;
  1911. }
  1912. // ---------------------
  1913. // T0 character
  1914. // ---------------------
  1915. ulExpectedLengthOfAtr = 2;
  1916. if (ulCurrentLengthOfAtr < ulExpectedLengthOfAtr)
  1917. {
  1918. NTStatus = CMUSB_ReadP1(DeviceObject);
  1919. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  1920. {
  1921. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  1922. goto ExitPowerOnCard;
  1923. }
  1924. else if (NTStatus != STATUS_SUCCESS)
  1925. {
  1926. continue;
  1927. }
  1928. ulBytesRead = SmartcardExtension->SmartcardReply.BufferLength;
  1929. RtlCopyBytes((PVOID)(abMaxAtrBuffer+ulCurrentLengthOfAtr),
  1930. (PVOID)SmartcardExtension->SmartcardReply.Buffer,
  1931. ulBytesRead);
  1932. if (fInverseAtr)
  1933. {
  1934. CMUSB_InverseBuffer(abMaxAtrBuffer+ulCurrentLengthOfAtr,
  1935. ulBytesRead);
  1936. }
  1937. ulCurrentLengthOfAtr += ulBytesRead;
  1938. }
  1939. SmartcardDebug(DEBUG_ATR,("PowerOnCard: T0 = %2.2x\n",abMaxAtrBuffer[1]));
  1940. ulHistoricalBytes = abMaxAtrBuffer[1] & 0x0F;
  1941. do
  1942. {
  1943. ulPtrToCurrentAtrByte = ulExpectedLengthOfAtr - 1;
  1944. fTDxSent = FALSE;
  1945. if (abMaxAtrBuffer[ulPtrToCurrentAtrByte] & 0x10)
  1946. ulExpectedLengthOfAtr++;
  1947. if (abMaxAtrBuffer[ulPtrToCurrentAtrByte] & 0x20)
  1948. ulExpectedLengthOfAtr++;
  1949. if (abMaxAtrBuffer[ulPtrToCurrentAtrByte] & 0x40)
  1950. ulExpectedLengthOfAtr++;
  1951. if (abMaxAtrBuffer[ulPtrToCurrentAtrByte] & 0x80)
  1952. {
  1953. ulExpectedLengthOfAtr++;
  1954. fTDxSent = TRUE;
  1955. }
  1956. if (fOnlyT0 == TRUE &&
  1957. ulPtrToCurrentAtrByte != 1 && // check if not T0
  1958. (abMaxAtrBuffer[ulPtrToCurrentAtrByte ] & 0x0f) )
  1959. {
  1960. fOnlyT0 = FALSE;
  1961. }
  1962. // TA1, TB1, TC1 , TD1
  1963. while (ulCurrentLengthOfAtr < ulExpectedLengthOfAtr)
  1964. {
  1965. NTStatus = CMUSB_ReadP1(DeviceObject);
  1966. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  1967. {
  1968. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  1969. goto ExitPowerOnCard;
  1970. }
  1971. else if (NTStatus != STATUS_SUCCESS)
  1972. {
  1973. fTryNextCard = TRUE;
  1974. break;
  1975. }
  1976. ulBytesRead = SmartcardExtension->SmartcardReply.BufferLength;
  1977. RtlCopyBytes((PVOID)(abMaxAtrBuffer+ulCurrentLengthOfAtr),
  1978. (PVOID)SmartcardExtension->SmartcardReply.Buffer,
  1979. ulBytesRead);
  1980. if (fInverseAtr)
  1981. {
  1982. CMUSB_InverseBuffer(abMaxAtrBuffer+ulCurrentLengthOfAtr,
  1983. ulBytesRead);
  1984. }
  1985. ulCurrentLengthOfAtr += ulBytesRead;
  1986. } // end of while
  1987. if (fTryNextCard == TRUE)
  1988. {
  1989. break;
  1990. }
  1991. #ifdef DBG
  1992. SmartcardDebug(DEBUG_ATR,("PowerOnCard: ATR read bytes: "));
  1993. for (i = 0;i < ulExpectedLengthOfAtr;i++)
  1994. SmartcardDebug(DEBUG_ATR,("%2.2x ",abMaxAtrBuffer[i]));
  1995. SmartcardDebug(DEBUG_ATR,("\n"));
  1996. #endif
  1997. } while (fTDxSent == TRUE);
  1998. if (fTryNextCard == TRUE)
  1999. {
  2000. continue;
  2001. }
  2002. // read historical bytes
  2003. // bug fix : old SAMOS cards have a damaged ATR
  2004. if (abMaxAtrBuffer[0] == 0x3b &&
  2005. abMaxAtrBuffer[1] == 0xbf &&
  2006. abMaxAtrBuffer[2] == 0x11 &&
  2007. abMaxAtrBuffer[3] == 0x00 &&
  2008. abMaxAtrBuffer[4] == 0x81 &&
  2009. abMaxAtrBuffer[5] == 0x31 &&
  2010. abMaxAtrBuffer[6] == 0x90 &&
  2011. abMaxAtrBuffer[7] == 0x73 )
  2012. {
  2013. ulHistoricalBytes = 4;
  2014. }
  2015. ulExpectedLengthOfAtr += ulHistoricalBytes;
  2016. if (fOnlyT0 == FALSE)
  2017. {
  2018. ulExpectedLengthOfAtr ++;
  2019. }
  2020. while (ulCurrentLengthOfAtr < ulExpectedLengthOfAtr)
  2021. {
  2022. NTStatus = CMUSB_ReadP1(DeviceObject);
  2023. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  2024. {
  2025. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  2026. goto ExitPowerOnCard;
  2027. }
  2028. else if (NTStatus != STATUS_SUCCESS)
  2029. {
  2030. fTryNextCard = TRUE;
  2031. break;
  2032. }
  2033. ulBytesRead = SmartcardExtension->SmartcardReply.BufferLength;
  2034. RtlCopyBytes((PVOID)(abMaxAtrBuffer+ulCurrentLengthOfAtr),
  2035. (PVOID)SmartcardExtension->SmartcardReply.Buffer,
  2036. ulBytesRead);
  2037. if (fInverseAtr)
  2038. {
  2039. CMUSB_InverseBuffer(abMaxAtrBuffer+ulCurrentLengthOfAtr,
  2040. ulBytesRead);
  2041. }
  2042. ulCurrentLengthOfAtr += ulBytesRead;
  2043. }
  2044. if (fTryNextCard == TRUE)
  2045. {
  2046. continue;
  2047. }
  2048. // check ATR
  2049. if (ulCurrentLengthOfAtr < 3 ||
  2050. ulCurrentLengthOfAtr > SCARD_ATR_LENGTH )
  2051. {
  2052. goto ExitPowerOnCard;
  2053. }
  2054. // check if the ATR of a SAMOS card with damaged ATR msut be corrected
  2055. CMUSB_CheckAtrModified(abMaxAtrBuffer,ulCurrentLengthOfAtr);
  2056. NTStatus = STATUS_SUCCESS;
  2057. fValidAtrReceived = TRUE;
  2058. RtlCopyBytes((PVOID)pbATR,
  2059. (PVOID)abMaxAtrBuffer,
  2060. ulCurrentLengthOfAtr);
  2061. *pulATRLength = ulCurrentLengthOfAtr;
  2062. if (fInverseAtr)
  2063. {
  2064. SmartcardExtension->ReaderExtension->fInverseAtr = TRUE;
  2065. }
  2066. else
  2067. {
  2068. SmartcardExtension->ReaderExtension->fInverseAtr = FALSE;
  2069. }
  2070. SmartcardExtension->ReaderExtension->fRawModeNecessary = FALSE;
  2071. // -------------------
  2072. // set card parameters
  2073. // -------------------
  2074. if (SmartcardExtension->ReaderExtension->fInverseAtr)
  2075. {
  2076. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate |= CMUSB_ODD_PARITY;
  2077. }
  2078. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate |= abFrequency[ulCardType];
  2079. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate |= CMUSB_BAUDRATE_9600;
  2080. SmartcardExtension->ReaderExtension->CardParameters.bCardType = CMUSB_SMARTCARD_ASYNCHRONOUS;
  2081. break;
  2082. }
  2083. ExitPowerOnCard:
  2084. // return correct error code
  2085. if (NTStatus != STATUS_NO_MEDIA && fValidAtrReceived == FALSE)
  2086. {
  2087. SmartcardDebug(DEBUG_ATR,
  2088. ("%s!PowerOnCard: no valid ATR received\n",DRIVER_NAME));
  2089. NTStatus = STATUS_UNRECOGNIZED_MEDIA;
  2090. }
  2091. if (NTStatus!=STATUS_SUCCESS)
  2092. {
  2093. // turn off VCC again
  2094. CMUSB_PowerOffCard (SmartcardExtension );
  2095. // ignor NTStatus
  2096. }
  2097. SmartcardDebug(DEBUG_TRACE,
  2098. ("%s!PowerOnCard: Exit %lx\n",DRIVER_NAME,NTStatus));
  2099. return NTStatus;
  2100. }
  2101. /*****************************************************************************
  2102. Routine Description:
  2103. Arguments:
  2104. Return Value:
  2105. *****************************************************************************/
  2106. NTSTATUS CMUSB_CardTracking(
  2107. PSMARTCARD_EXTENSION pSmartcardExtension
  2108. )
  2109. {
  2110. KIRQL oldIrql;
  2111. SmartcardDebug(DEBUG_TRACE,
  2112. ("%s!CardTracking: Enter\n",DRIVER_NAME ));
  2113. //
  2114. // Set cancel routine for the notification irp
  2115. //
  2116. IoAcquireCancelSpinLock(&oldIrql);
  2117. IoSetCancelRoutine(pSmartcardExtension->OsData->NotificationIrp,
  2118. CMUSB_CancelCardTracking);
  2119. IoReleaseCancelSpinLock(oldIrql);
  2120. //
  2121. // Mark notification irp pending
  2122. //
  2123. IoMarkIrpPending(pSmartcardExtension->OsData->NotificationIrp);
  2124. SmartcardDebug(DEBUG_TRACE,
  2125. ("%s!CardTracking: Exit\n",DRIVER_NAME ));
  2126. return STATUS_PENDING;
  2127. }
  2128. /*****************************************************************************
  2129. Routine Description:
  2130. Arguments:
  2131. Return Value:
  2132. *****************************************************************************/
  2133. NTSTATUS CMUSB_Cleanup(
  2134. IN PDEVICE_OBJECT DeviceObject,
  2135. IN PIRP Irp
  2136. )
  2137. {
  2138. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  2139. PSMARTCARD_EXTENSION SmartcardExtension = &DeviceExtension->SmartcardExtension;
  2140. SmartcardDebug(DEBUG_TRACE,
  2141. ("%s!Cleanup: Enter\n",DRIVER_NAME));
  2142. if (SmartcardExtension->OsData->NotificationIrp != NULL &&
  2143. // test if there is a pending IRP at all
  2144. SmartcardExtension->ReaderExtension != NULL &&
  2145. // if the device has been removed ReaderExtension == NULL
  2146. DeviceExtension->lOpenCount == 1 )
  2147. // complete card tracking only if this is the the last close call
  2148. // otherwise the card tracking of the resource manager is canceled
  2149. {
  2150. //
  2151. // We need to complete the notification irp
  2152. //
  2153. CMUSB_CompleteCardTracking(SmartcardExtension);
  2154. }
  2155. SmartcardDebug(DEBUG_DRIVER,
  2156. ("%s!Cleanup: Completing IRP %lx\n",DRIVER_NAME,Irp));
  2157. Irp->IoStatus.Information = 0;
  2158. Irp->IoStatus.Status = STATUS_SUCCESS;
  2159. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  2160. SmartcardDebug(DEBUG_TRACE,
  2161. ("%s!Cleanup: Exit\n",DRIVER_NAME));
  2162. return STATUS_SUCCESS;
  2163. }
  2164. /*****************************************************************************
  2165. Routine Description:
  2166. Arguments:
  2167. Return Value:
  2168. *****************************************************************************/
  2169. NTSTATUS CMUSB_CancelCardTracking(
  2170. IN PDEVICE_OBJECT DeviceObject,
  2171. IN PIRP Irp)
  2172. {
  2173. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  2174. PSMARTCARD_EXTENSION SmartcardExtension = &DeviceExtension->SmartcardExtension;
  2175. SmartcardDebug(DEBUG_TRACE,
  2176. ("%s!CancelCardTracking: Enter\n",DRIVER_NAME));
  2177. ASSERT(Irp == SmartcardExtension->OsData->NotificationIrp);
  2178. IoReleaseCancelSpinLock(Irp->CancelIrql);
  2179. CMUSB_CompleteCardTracking(SmartcardExtension);
  2180. SmartcardDebug(DEBUG_TRACE,
  2181. ("%s!CancelCardTracking: Exit\n",DRIVER_NAME));
  2182. return STATUS_CANCELLED;
  2183. }
  2184. /*****************************************************************************
  2185. Routine Description:
  2186. Arguments:
  2187. Return Value:
  2188. *****************************************************************************/
  2189. NTSTATUS CMUSB_IoCtlVendor(
  2190. PSMARTCARD_EXTENSION SmartcardExtension
  2191. )
  2192. {
  2193. NTSTATUS NTStatus = STATUS_SUCCESS;
  2194. NTSTATUS DebugStatus;
  2195. UCHAR pbAtrBuffer[MAXIMUM_ATR_LENGTH];
  2196. ULONG ulAtrLength;
  2197. SmartcardDebug(DEBUG_TRACE,
  2198. ("%s!IoCtlVendor : Enter\n",DRIVER_NAME));
  2199. switch (SmartcardExtension->MajorIoControlCode)
  2200. {
  2201. case CM_IOCTL_CR80S_SAMOS_SET_HIGH_SPEED:
  2202. NTStatus = CMUSB_SetHighSpeed_CR80S_SAMOS(SmartcardExtension);
  2203. break;
  2204. case CM_IOCTL_GET_FW_VERSION:
  2205. NTStatus = CMUSB_GetFWVersion(SmartcardExtension);
  2206. break;
  2207. case CM_IOCTL_READ_DEVICE_DESCRIPTION:
  2208. NTStatus = CMUSB_ReadDeviceDescription(SmartcardExtension);
  2209. break;
  2210. case CM_IOCTL_SET_READER_9600_BAUD:
  2211. NTStatus = CMUSB_SetReader_9600Baud(SmartcardExtension);
  2212. break;
  2213. case CM_IOCTL_SET_READER_38400_BAUD:
  2214. NTStatus = CMUSB_SetReader_38400Baud(SmartcardExtension);
  2215. break;
  2216. case CM_IOCTL_SET_SYNC_PARAMETERS:
  2217. // in case of CardManUSB do nothing
  2218. NTStatus = STATUS_SUCCESS;
  2219. break;
  2220. case CM_IOCTL_SYNC_CARD_POWERON:
  2221. NTStatus = CMUSB_PowerOnSynchronousCard(SmartcardExtension,
  2222. pbAtrBuffer,
  2223. &ulAtrLength);
  2224. break;
  2225. case CM_IOCTL_2WBP_RESET_CARD:
  2226. SmartcardExtension->MinorIoControlCode = SMARTCARD_WARM_RESET;
  2227. NTStatus = CMUSB_PowerOnSynchronousCard(SmartcardExtension,
  2228. pbAtrBuffer,
  2229. &ulAtrLength);
  2230. break;
  2231. case CM_IOCTL_2WBP_TRANSFER:
  2232. NTStatus = CMUSB_Transmit2WBP(SmartcardExtension);
  2233. break;
  2234. case CM_IOCTL_3WBP_TRANSFER:
  2235. NTStatus = CMUSB_Transmit3WBP(SmartcardExtension);
  2236. break;
  2237. default:
  2238. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  2239. break;
  2240. }
  2241. SmartcardDebug(DEBUG_TRACE,
  2242. ("%s!IoCtlVendor : Exit %lx\n",DRIVER_NAME,NTStatus));
  2243. return NTStatus;
  2244. }
  2245. /*****************************************************************************
  2246. Routine Description:
  2247. Arguments:
  2248. Return Value: STATUS_UNSUCCESSFUL
  2249. STATUS_SUCCESS
  2250. *****************************************************************************/
  2251. NTSTATUS CMUSB_SetHighSpeed_CR80S_SAMOS (
  2252. IN PSMARTCARD_EXTENSION SmartcardExtension
  2253. )
  2254. {
  2255. NTSTATUS NTStatus;
  2256. NTSTATUS DebugStatus;
  2257. UCHAR abReadBuffer[16];
  2258. ULONG ulBytesRead;
  2259. BYTE abCR80S_SAMOS_SET_HIGH_SPEED[4] = {0xFF,0x11,0x94,0x7A};
  2260. ULONG ulAtrLength;
  2261. BYTE abAtr[MAXIMUM_ATR_LENGTH];
  2262. LARGE_INTEGER liWaitTime;
  2263. BOOLEAN fStateTimer;
  2264. ULONG ulWaitTime;
  2265. BOOLEAN fCancelTimer = FALSE;
  2266. SmartcardDebug(DEBUG_TRACE,
  2267. ("%s!SetHighSpeed_CR80S_SAMOS: Enter\n",DRIVER_NAME));
  2268. SmartcardDebug(DEBUG_PROTOCOL,
  2269. ("%s!SetHighSpeed_CR80S_SAMOS: writing high speed command\n",DRIVER_NAME));
  2270. RtlCopyBytes((PVOID)SmartcardExtension->SmartcardRequest.Buffer,
  2271. (PVOID)abCR80S_SAMOS_SET_HIGH_SPEED,
  2272. sizeof(abCR80S_SAMOS_SET_HIGH_SPEED));
  2273. SmartcardExtension->SmartcardRequest.BufferLength = 4;
  2274. NTStatus = CMUSB_WriteP0(SmartcardExtension->OsData->DeviceObject,
  2275. 0x01, //we can use T=1 setting for direct communication
  2276. 0x00, //bValueLo,
  2277. 0x00, //bValueHi,
  2278. 0x00, //bIndexLo,
  2279. 0x00); //bIndexHi,
  2280. if (NTStatus != STATUS_SUCCESS)
  2281. {
  2282. SmartcardDebug(DEBUG_ERROR,
  2283. ("%s!SetHighSpeed_CR80S_SAMOS: writing high speed command failed\n",DRIVER_NAME));
  2284. goto ExitSetHighSpeed;
  2285. }
  2286. // read back pts data
  2287. SmartcardDebug(DEBUG_PROTOCOL,
  2288. ("%s!SetHighSpeed_CR80S_SAMOS: reading echo\n",DRIVER_NAME));
  2289. // maximim initial waiting time is 9600 * etu
  2290. // => 1 sec is sufficient
  2291. ulWaitTime = 1000;
  2292. liWaitTime = RtlConvertLongToLargeInteger(ulWaitTime * -10000);
  2293. KeSetTimer(&SmartcardExtension->ReaderExtension->WaitTimer,
  2294. liWaitTime,
  2295. NULL);
  2296. fCancelTimer = TRUE;
  2297. do
  2298. {
  2299. SmartcardExtension->ReaderExtension->ulTimeoutP1 = ulWaitTime;
  2300. NTStatus = CMUSB_ReadP1(SmartcardExtension->OsData->DeviceObject);
  2301. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  2302. {
  2303. DebugStatus = CMUSB_ReadStateAfterP1Stalled(SmartcardExtension->OsData->DeviceObject);
  2304. break;
  2305. }
  2306. fStateTimer = KeReadStateTimer(&SmartcardExtension->ReaderExtension->WaitTimer);
  2307. if (fStateTimer == TRUE)
  2308. {
  2309. fCancelTimer =FALSE;
  2310. SmartcardDebug(DEBUG_PROTOCOL,
  2311. ("%s!SetHighSpeed_CR80S_SAMOS: timeout while reading echo\n",DRIVER_NAME));
  2312. break;
  2313. }
  2314. } while (SmartcardExtension->SmartcardReply.Buffer[0] < 4 );
  2315. if (NTStatus != STATUS_SUCCESS)
  2316. {
  2317. goto ExitSetHighSpeed;
  2318. }
  2319. SmartcardExtension->SmartcardReply.BufferLength = 4;
  2320. NTStatus = CMUSB_ReadP0(SmartcardExtension->OsData->DeviceObject);
  2321. if (NTStatus != STATUS_SUCCESS)
  2322. {
  2323. SmartcardDebug(DEBUG_ERROR,
  2324. ("%s!SetHighSpeed_CR80S_SAMOS: reading echo failed\n",DRIVER_NAME));
  2325. goto ExitSetHighSpeed;
  2326. }
  2327. ulBytesRead = SmartcardExtension->SmartcardReply.BufferLength;
  2328. RtlCopyBytes((PVOID)abReadBuffer,
  2329. (PVOID)SmartcardExtension->SmartcardReply.Buffer,
  2330. ulBytesRead);
  2331. // if the card has accepted this string , the string is echoed
  2332. if (abReadBuffer[0] == abCR80S_SAMOS_SET_HIGH_SPEED[0] &&
  2333. abReadBuffer[1] == abCR80S_SAMOS_SET_HIGH_SPEED[1] &&
  2334. abReadBuffer[2] == abCR80S_SAMOS_SET_HIGH_SPEED[2] &&
  2335. abReadBuffer[3] == abCR80S_SAMOS_SET_HIGH_SPEED[3] )
  2336. {
  2337. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate = 0;
  2338. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate |= CMUSB_FREQUENCY_5_12MHZ;
  2339. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate |= CMUSB_BAUDRATE_76800;
  2340. SmartcardExtension->ReaderExtension->CardParameters.bCardType = CMUSB_SMARTCARD_ASYNCHRONOUS;
  2341. NTStatus = CMUSB_SetCardParameters (SmartcardExtension->OsData->DeviceObject,
  2342. SmartcardExtension->ReaderExtension->CardParameters.bCardType,
  2343. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate,
  2344. SmartcardExtension->ReaderExtension->CardParameters.bStopBits);
  2345. }
  2346. else
  2347. {
  2348. DebugStatus = CMUSB_PowerOffCard(SmartcardExtension);
  2349. // a cold reset is necessary now
  2350. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  2351. DebugStatus = CMUSB_PowerOnCard(SmartcardExtension,abAtr,&ulAtrLength);
  2352. NTStatus = STATUS_UNSUCCESSFUL;
  2353. }
  2354. ExitSetHighSpeed:
  2355. if (fCancelTimer == TRUE)
  2356. {
  2357. KeCancelTimer(&SmartcardExtension->ReaderExtension->WaitTimer);
  2358. }
  2359. *SmartcardExtension->IoRequest.Information = 0L;
  2360. if (NTStatus != STATUS_SUCCESS)
  2361. NTStatus = STATUS_UNSUCCESSFUL;
  2362. SmartcardDebug(DEBUG_TRACE,
  2363. ("%s!SetHighSpeed_CR80S_SAMOS: Exit %lx\n",DRIVER_NAME,NTStatus));
  2364. return NTStatus;
  2365. }
  2366. /*****************************************************************************
  2367. Routine Description:
  2368. Arguments:
  2369. Return Value:
  2370. *****************************************************************************/
  2371. NTSTATUS CMUSB_GetFWVersion (
  2372. IN PSMARTCARD_EXTENSION SmartcardExtension
  2373. )
  2374. {
  2375. NTSTATUS NTStatus = STATUS_SUCCESS;
  2376. SmartcardDebug(DEBUG_TRACE,
  2377. ("%s!GetFWVersion : Enter\n",DRIVER_NAME));
  2378. if (SmartcardExtension->IoRequest.ReplyBufferLength < sizeof (ULONG))
  2379. {
  2380. NTStatus = STATUS_BUFFER_OVERFLOW;
  2381. goto ExitGetFWVersion;
  2382. }
  2383. else
  2384. {
  2385. *(PULONG)(SmartcardExtension->IoRequest.ReplyBuffer) =
  2386. SmartcardExtension->ReaderExtension->ulFWVersion;
  2387. }
  2388. ExitGetFWVersion:
  2389. *SmartcardExtension->IoRequest.Information = sizeof(ULONG);
  2390. SmartcardDebug(DEBUG_TRACE,
  2391. ("%s!GetFWVersion : Exit %lx\n",DRIVER_NAME,NTStatus));
  2392. return NTStatus;
  2393. }
  2394. /*****************************************************************************
  2395. Routine Description:
  2396. Arguments:
  2397. Return Value: STATUS_UNSUCCESSFUL
  2398. STATUS_SUCCESS
  2399. *****************************************************************************/
  2400. NTSTATUS CMUSB_SetReader_9600Baud (
  2401. IN PSMARTCARD_EXTENSION SmartcardExtension
  2402. )
  2403. {
  2404. NTSTATUS NTStatus = STATUS_SUCCESS;;
  2405. SmartcardDebug(DEBUG_TRACE,
  2406. ("%s!SetReader_9600Baud: Enter\n",DRIVER_NAME));
  2407. // check if card is already in specific mode
  2408. if (SmartcardExtension->ReaderCapabilities.CurrentState != SCARD_SPECIFIC)
  2409. {
  2410. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  2411. goto ExitSetReader9600;
  2412. }
  2413. // set 9600 Baud for 3.58 MHz
  2414. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate = CMUSB_FREQUENCY_3_72MHZ + CMUSB_BAUDRATE_9600;
  2415. SmartcardExtension->ReaderExtension->CardParameters.bCardType = CMUSB_SMARTCARD_ASYNCHRONOUS;
  2416. NTStatus = CMUSB_SetCardParameters (SmartcardExtension->OsData->DeviceObject,
  2417. SmartcardExtension->ReaderExtension->CardParameters.bCardType,
  2418. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate,
  2419. SmartcardExtension->ReaderExtension->CardParameters.bStopBits);
  2420. ExitSetReader9600:
  2421. *SmartcardExtension->IoRequest.Information = 0L;
  2422. SmartcardDebug(DEBUG_TRACE,
  2423. ("%s!SetReader_9600Baud: Exit %lx\n",DRIVER_NAME,NTStatus));
  2424. return(NTStatus);
  2425. }
  2426. /*****************************************************************************
  2427. Routine Description:
  2428. Arguments:
  2429. Return Value: STATUS_UNSUCCESSFUL
  2430. STATUS_SUCCESS
  2431. *****************************************************************************/
  2432. NTSTATUS CMUSB_SetReader_38400Baud (
  2433. IN PSMARTCARD_EXTENSION SmartcardExtension
  2434. )
  2435. {
  2436. NTSTATUS NTStatus = STATUS_SUCCESS;;
  2437. SmartcardDebug(DEBUG_TRACE,
  2438. ("%s!SetReader_38400Baud: Enter\n",DRIVER_NAME));
  2439. // check if card is already in specific mode
  2440. if (SmartcardExtension->ReaderCapabilities.CurrentState != SCARD_SPECIFIC)
  2441. {
  2442. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  2443. goto ExitSetReader38400;
  2444. }
  2445. // set 384000 Baud for 3.58 MHz card
  2446. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate = CMUSB_FREQUENCY_3_72MHZ + CMUSB_BAUDRATE_38400;
  2447. SmartcardExtension->ReaderExtension->CardParameters.bCardType = CMUSB_SMARTCARD_ASYNCHRONOUS;
  2448. NTStatus = CMUSB_SetCardParameters (SmartcardExtension->OsData->DeviceObject,
  2449. SmartcardExtension->ReaderExtension->CardParameters.bCardType,
  2450. SmartcardExtension->ReaderExtension->CardParameters.bBaudRate,
  2451. SmartcardExtension->ReaderExtension->CardParameters.bStopBits);
  2452. ExitSetReader38400:
  2453. *SmartcardExtension->IoRequest.Information = 0L;
  2454. SmartcardDebug(DEBUG_TRACE,
  2455. ("%s!SetReader_38400Baud: Exit %lx\n",DRIVER_NAME,NTStatus));
  2456. return(NTStatus);
  2457. }
  2458. /*****************************************************************************
  2459. Routine Description:
  2460. Arguments:
  2461. Return Value:
  2462. *****************************************************************************/
  2463. VOID
  2464. CMUSB_InitializeSmartcardExtension(
  2465. IN PSMARTCARD_EXTENSION SmartcardExtension
  2466. )
  2467. {
  2468. // ==================================
  2469. // Fill the Vendor_Attr structure
  2470. // ==================================
  2471. RtlCopyBytes((PVOID)SmartcardExtension->VendorAttr.VendorName.Buffer,
  2472. (PVOID)CM2020_VENDOR_NAME,
  2473. sizeof(CM2020_VENDOR_NAME)
  2474. );
  2475. //
  2476. // Length of vendor name
  2477. //
  2478. SmartcardExtension->VendorAttr.VendorName.Length = sizeof(CM2020_VENDOR_NAME);
  2479. //
  2480. // Reader name
  2481. //
  2482. RtlCopyBytes((PVOID)SmartcardExtension->VendorAttr.IfdType.Buffer,
  2483. (PVOID)CM2020_PRODUCT_NAME,
  2484. sizeof(CM2020_PRODUCT_NAME));
  2485. //
  2486. // Length of reader name
  2487. //
  2488. SmartcardExtension->VendorAttr.IfdType.Length = sizeof(CM2020_PRODUCT_NAME);
  2489. //
  2490. // Version number
  2491. //
  2492. SmartcardExtension->VendorAttr.IfdVersion.BuildNumber = BUILDNUMBER_CARDMAN_USB;
  2493. SmartcardExtension->VendorAttr.IfdVersion.VersionMinor = VERSIONMINOR_CARDMAN_USB;
  2494. SmartcardExtension->VendorAttr.IfdVersion.VersionMajor = VERSIONMAJOR_CARDMAN_USB;
  2495. //
  2496. // Unit number which is zero based
  2497. //
  2498. SmartcardExtension->VendorAttr.UnitNo = SmartcardExtension->ReaderExtension->ulDeviceInstance;
  2499. // ================================================
  2500. // Fill the SCARD_READER_CAPABILITIES structure
  2501. // ===============================================
  2502. //
  2503. // Supported protoclols by the reader
  2504. //
  2505. SmartcardExtension->ReaderCapabilities.SupportedProtocols = SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_T0;
  2506. //
  2507. // Reader type serial, keyboard, ....
  2508. //
  2509. SmartcardExtension->ReaderCapabilities.ReaderType = SCARD_READER_TYPE_USB;
  2510. //
  2511. // Mechanical characteristics like swallows etc.
  2512. //
  2513. SmartcardExtension->ReaderCapabilities.MechProperties = 0;
  2514. //
  2515. // Current state of the reader
  2516. //
  2517. SmartcardExtension->ReaderExtension->ulOldCardState = UNKNOWN;
  2518. SmartcardExtension->ReaderExtension->ulNewCardState = UNKNOWN;
  2519. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_UNKNOWN;
  2520. //
  2521. // Data Rate
  2522. //
  2523. SmartcardExtension->ReaderCapabilities.DataRate.Default =
  2524. SmartcardExtension->ReaderCapabilities.DataRate.Max =
  2525. dataRatesSupported[0];
  2526. // reader could support higher data rates
  2527. SmartcardExtension->ReaderCapabilities.DataRatesSupported.List =
  2528. dataRatesSupported;
  2529. SmartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
  2530. sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
  2531. //
  2532. // CLK Frequency
  2533. //
  2534. SmartcardExtension->ReaderCapabilities.CLKFrequency.Default =
  2535. SmartcardExtension->ReaderCapabilities.CLKFrequency.Max =
  2536. CLKFrequenciesSupported[0];
  2537. // reader could support higher frequencies
  2538. SmartcardExtension->ReaderCapabilities.CLKFrequenciesSupported.List =
  2539. CLKFrequenciesSupported;
  2540. SmartcardExtension->ReaderCapabilities.CLKFrequenciesSupported.Entries =
  2541. sizeof(CLKFrequenciesSupported) / sizeof(CLKFrequenciesSupported[0]);
  2542. //
  2543. // MaxIFSD
  2544. //
  2545. SmartcardExtension->ReaderCapabilities.MaxIFSD = ATTR_MAX_IFSD_CARDMAN_USB;
  2546. }
  2547. /*****************************************************************************
  2548. Routine Description:
  2549. This function always returns 'CardManUSB'.
  2550. Arguments: pointer to SMARTCARD_EXTENSION
  2551. Return Value: NT NTStatus
  2552. *****************************************************************************/
  2553. NTSTATUS
  2554. CMUSB_ReadDeviceDescription(IN PSMARTCARD_EXTENSION SmartcardExtension )
  2555. {
  2556. NTSTATUS NTStatus = STATUS_SUCCESS;
  2557. BYTE abDeviceDescription[] = "CardManUSB";
  2558. SmartcardDebug(DEBUG_TRACE,
  2559. ("%s!ReadDeviceDescription : Enter\n",DRIVER_NAME));
  2560. if (SmartcardExtension->IoRequest.ReplyBufferLength < sizeof(abDeviceDescription))
  2561. {
  2562. NTStatus = STATUS_BUFFER_OVERFLOW;
  2563. *SmartcardExtension->IoRequest.Information = 0L;
  2564. goto ExitReadDeviceDescription;
  2565. }
  2566. else
  2567. {
  2568. RtlCopyBytes((PVOID)SmartcardExtension->IoRequest.ReplyBuffer,
  2569. (PVOID)abDeviceDescription,
  2570. sizeof(abDeviceDescription));
  2571. *SmartcardExtension->IoRequest.Information = sizeof(abDeviceDescription);
  2572. }
  2573. ExitReadDeviceDescription:
  2574. SmartcardDebug(DEBUG_TRACE,
  2575. ("%s!ReadDeviceDescription : Exit %lx\n",DRIVER_NAME,NTStatus));
  2576. return NTStatus;
  2577. }
  2578. /*****************************************************************************
  2579. Routine Description:
  2580. This routine always returns FALSE.
  2581. Arguments: pointer to SMARDCARD_EXTENSION
  2582. Return Value: NT NTStatus
  2583. *****************************************************************************/
  2584. NTSTATUS
  2585. CMUSB_IsSPESupported (IN PSMARTCARD_EXTENSION SmartcardExtension )
  2586. {
  2587. NTSTATUS NTStatus = STATUS_SUCCESS;
  2588. SmartcardDebug(DEBUG_TRACE,
  2589. ("%s!IsSPESupported: Enter\n",DRIVER_NAME));
  2590. if (SmartcardExtension->IoRequest.ReplyBufferLength < sizeof (ULONG))
  2591. {
  2592. NTStatus = STATUS_BUFFER_OVERFLOW;
  2593. *SmartcardExtension->IoRequest.Information = 0;
  2594. goto ExitIsSPESupported;
  2595. }
  2596. else
  2597. {
  2598. *(PULONG)(SmartcardExtension->IoRequest.ReplyBuffer) = FALSE;
  2599. *SmartcardExtension->IoRequest.Information = sizeof(ULONG);
  2600. }
  2601. ExitIsSPESupported:
  2602. SmartcardDebug(DEBUG_TRACE,
  2603. ("%s!IsSPESupported: Exit %lx\n",DRIVER_NAME,NTStatus));
  2604. return NTStatus;
  2605. }
  2606. /*****************************************************************************
  2607. Routine Description:
  2608. Arguments:
  2609. Return Value:
  2610. *****************************************************************************/
  2611. NTSTATUS CMUSB_SetCardParameters (
  2612. IN PDEVICE_OBJECT DeviceObject,
  2613. IN UCHAR bCardType,
  2614. IN UCHAR bBaudRate,
  2615. IN UCHAR bStopBits
  2616. )
  2617. {
  2618. NTSTATUS NTStatus;
  2619. PDEVICE_EXTENSION DeviceExtension;
  2620. PSMARTCARD_EXTENSION SmartcardExtension;
  2621. SmartcardDebug(DEBUG_TRACE,
  2622. ("%s!SetCardParameters: Enter\n",DRIVER_NAME));
  2623. SmartcardDebug(DEBUG_PROTOCOL,
  2624. ("%s!SetCardParameters: ##################################################\n",DRIVER_NAME));
  2625. SmartcardDebug(DEBUG_PROTOCOL,
  2626. ("%s!SetCardParameters: bCardType = %x bBaudRate = %x bStopBits = %x\n",DRIVER_NAME,
  2627. bCardType,bBaudRate,bStopBits));
  2628. SmartcardDebug(DEBUG_PROTOCOL,
  2629. ("%s!SetCardParameters: ##################################################\n",DRIVER_NAME));
  2630. DeviceExtension = DeviceObject->DeviceExtension;
  2631. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  2632. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  2633. NTStatus = CMUSB_WriteP0(DeviceObject,
  2634. 0x30, //bRequest,
  2635. bCardType, //bValueLo,
  2636. bBaudRate, //bValueHi,
  2637. bStopBits, //bIndexLo,
  2638. 0x00 //bIndexHi,
  2639. );
  2640. SmartcardDebug(DEBUG_TRACE,
  2641. ("%s!SetCardParameters: Exit %lx\n",DRIVER_NAME,NTStatus));
  2642. return NTStatus;
  2643. }
  2644. /*****************************************************************************
  2645. Routine Description:
  2646. Bit0 -> Bit 7
  2647. Bit1 -> Bit 6
  2648. Bit2 -> Bit 5
  2649. Bit3 -> Bit 4
  2650. Bit4 -> Bit 3
  2651. Bit5 -> Bit 2
  2652. Bit6 -> Bit 1
  2653. Bit7 -> Bit 0
  2654. Arguments:
  2655. Return Value:
  2656. *****************************************************************************/
  2657. VOID CMUSB_InverseBuffer (
  2658. PUCHAR pbBuffer,
  2659. ULONG ulBufferSize
  2660. )
  2661. {
  2662. ULONG i;
  2663. ULONG j;
  2664. ULONG m;
  2665. ULONG n;
  2666. for (i=0; i<ulBufferSize; i++)
  2667. {
  2668. n = 0;
  2669. for (j=1; j<=8; j++)
  2670. {
  2671. m = (pbBuffer[i] << j);
  2672. m &= 0x00000100;
  2673. n |= (m >> (9-j));
  2674. }
  2675. pbBuffer[i] = (UCHAR)~n;
  2676. }
  2677. return;
  2678. }
  2679. /*****************************************************************************
  2680. Routine Description:
  2681. This function checks if an incorrect ATR has been received.
  2682. It corrects the number of historical bytes and the checksum byte
  2683. Arguments: pointer to current ATR
  2684. length of ATR
  2685. Return Value: none
  2686. *****************************************************************************/
  2687. VOID CMUSB_CheckAtrModified (
  2688. PUCHAR pbBuffer,
  2689. ULONG ulBufferSize
  2690. )
  2691. {
  2692. UCHAR bNumberHistoricalBytes;
  2693. UCHAR bXorChecksum;
  2694. ULONG i;
  2695. if (ulBufferSize < 0x09) // mininmum length of a modified ATR
  2696. return ; // ATR is ok
  2697. // variant 2
  2698. if (pbBuffer[0] == 0x3b &&
  2699. pbBuffer[1] == 0xbf &&
  2700. pbBuffer[2] == 0x11 &&
  2701. pbBuffer[3] == 0x00 &&
  2702. pbBuffer[4] == 0x81 &&
  2703. pbBuffer[5] == 0x31 &&
  2704. pbBuffer[6] == 0x90 &&
  2705. pbBuffer[7] == 0x73 &&
  2706. ulBufferSize == 13 )
  2707. {
  2708. // correct number of historical bytes
  2709. bNumberHistoricalBytes = 4;
  2710. pbBuffer[1] &= 0xf0;
  2711. pbBuffer[1] |= bNumberHistoricalBytes;
  2712. // correct checksum byte
  2713. bXorChecksum = pbBuffer[1];
  2714. for (i=2;i<ulBufferSize-1;i++)
  2715. bXorChecksum ^= pbBuffer[i];
  2716. pbBuffer[ulBufferSize -1 ] = bXorChecksum;
  2717. SmartcardDebug(DEBUG_ATR,
  2718. ("%s!CheckAtrModified: correcting SAMOS ATR (variant 2)\n",
  2719. DRIVER_NAME));
  2720. }
  2721. // variant 1
  2722. if (pbBuffer[0] == 0x3b &&
  2723. pbBuffer[1] == 0xb4 &&
  2724. pbBuffer[2] == 0x11 &&
  2725. pbBuffer[3] == 0x00 &&
  2726. pbBuffer[4] == 0x81 &&
  2727. pbBuffer[5] == 0x31 &&
  2728. pbBuffer[6] == 0x90 &&
  2729. pbBuffer[7] == 0x73 &&
  2730. ulBufferSize == 13 )
  2731. {
  2732. // correct checksum byte
  2733. bXorChecksum = pbBuffer[1];
  2734. for (i=2;i<ulBufferSize-1;i++)
  2735. bXorChecksum ^= pbBuffer[i];
  2736. if (pbBuffer[ulBufferSize -1 ] != bXorChecksum )
  2737. {
  2738. pbBuffer[ulBufferSize -1 ] = bXorChecksum;
  2739. SmartcardDebug(DEBUG_ATR,
  2740. ("%s!CheckAtrModified: correcting SAMOS ATR (variant 1)\n",
  2741. DRIVER_NAME));
  2742. }
  2743. }
  2744. // variant 3
  2745. if (pbBuffer[0] == 0x3b &&
  2746. pbBuffer[1] == 0xbf &&
  2747. pbBuffer[2] == 0x11 &&
  2748. pbBuffer[3] == 0x00 &&
  2749. pbBuffer[4] == 0x81 &&
  2750. pbBuffer[5] == 0x31 &&
  2751. pbBuffer[6] == 0x90 &&
  2752. pbBuffer[7] == 0x73 &&
  2753. ulBufferSize == 9 )
  2754. {
  2755. // correct number of historical bytes
  2756. bNumberHistoricalBytes = 0;
  2757. pbBuffer[1] &= 0xf0;
  2758. pbBuffer[1] |= bNumberHistoricalBytes;
  2759. // correct checksum byte
  2760. bXorChecksum = pbBuffer[1];
  2761. for (i=2;i<ulBufferSize-1;i++)
  2762. bXorChecksum ^= pbBuffer[i];
  2763. pbBuffer[ulBufferSize -1 ] = bXorChecksum;
  2764. SmartcardDebug(DEBUG_ATR,
  2765. ("%s!CheckAtrModified: correcting SAMOS ATR (variant 3)\n",
  2766. DRIVER_NAME));
  2767. }
  2768. }
  2769. /*****************************************************************************
  2770. * History:
  2771. * $Log: scusbcb.c $
  2772. * Revision 1.9 2001/01/17 12:36:04 WFrischauf
  2773. * No comment given
  2774. *
  2775. * Revision 1.8 2000/09/25 13:38:21 WFrischauf
  2776. * No comment given
  2777. *
  2778. * Revision 1.7 2000/08/24 09:04:38 TBruendl
  2779. * No comment given
  2780. *
  2781. * Revision 1.6 2000/08/16 14:35:03 WFrischauf
  2782. * No comment given
  2783. *
  2784. * Revision 1.5 2000/08/16 08:25:06 TBruendl
  2785. * warning :uninitialized memory removed
  2786. *
  2787. * Revision 1.4 2000/07/24 11:34:59 WFrischauf
  2788. * No comment given
  2789. *
  2790. * Revision 1.1 2000/07/20 11:50:14 WFrischauf
  2791. * No comment given
  2792. *
  2793. *
  2794. *****************************************************************************/