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

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