Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
4.5 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) SCM Microsystems, 1998 - 1999
  6. //
  7. // File: t0hndlr.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #if defined( SMCLIB_VXD )
  11. #include "Driver98.h"
  12. #else
  13. #include "DriverNT.h"
  14. #endif // SMCLIB_VXD
  15. #include "SerialIF.h"
  16. #include "STCCmd.h"
  17. #include "T0Hndlr.h"
  18. NTSTATUS
  19. T0_ExchangeData(
  20. PREADER_EXTENSION ReaderExtension,
  21. PUCHAR pRequest,
  22. ULONG RequestLen,
  23. PUCHAR pReply,
  24. PULONG pReplyLen
  25. )
  26. /*++
  27. Routine Description:
  28. Arguments:
  29. Return Value:
  30. --*/
  31. {
  32. NTSTATUS NTStatus = STATUS_SUCCESS;
  33. BOOLEAN restartWorkWaitingTime = FALSE;
  34. ULONG bytesWritten, totalBytesToWrite, totalBytesToRead;
  35. ULONG bytesToWrite, bytesRead, ioBufferLen;
  36. UCHAR ioBuffer[512];
  37. totalBytesToWrite = RequestLen;
  38. totalBytesToRead = ReaderExtension->SmartcardExtension->T0.Le + 2;
  39. bytesRead = 0;
  40. // start with writing the header of the request
  41. bytesToWrite = 5;
  42. bytesWritten = 0;
  43. __try {
  44. do {
  45. if (restartWorkWaitingTime == FALSE) {
  46. NTStatus = STCWriteICC1(
  47. ReaderExtension,
  48. pRequest + bytesWritten,
  49. bytesToWrite
  50. );
  51. ASSERT(NTStatus != STATUS_BUFFER_TOO_SMALL);
  52. if (NTStatus != STATUS_SUCCESS) {
  53. __leave;
  54. }
  55. bytesWritten += bytesToWrite;
  56. totalBytesToWrite -= bytesToWrite;
  57. }
  58. //
  59. // try to read the pcb, the card could
  60. // also answer with a status word
  61. //
  62. ioBufferLen = sizeof(ioBuffer);
  63. NTStatus = STCReadICC1(
  64. ReaderExtension,
  65. ioBuffer,
  66. &ioBufferLen,
  67. 1
  68. );
  69. ASSERT(NTStatus != STATUS_BUFFER_TOO_SMALL);
  70. restartWorkWaitingTime = FALSE;
  71. if (NTStatus != STATUS_SUCCESS) {
  72. __leave;
  73. }
  74. if (ioBuffer[0] == 0x60) {
  75. //
  76. // Set flag that we only should read the proc byte
  77. // without writing data to the card
  78. //
  79. restartWorkWaitingTime = TRUE;
  80. continue;
  81. }
  82. if ((ioBuffer[0] & 0xFE) == pRequest[1]) {
  83. // we can send all remaining bytes at once.
  84. bytesToWrite = totalBytesToWrite;
  85. } else if(ioBuffer[0] == (UCHAR) ~pRequest[1]) {
  86. // we can only send the next byte
  87. bytesToWrite = 1;
  88. } else {
  89. // this must be a status word
  90. totalBytesToWrite = 0;
  91. totalBytesToRead = 0;
  92. pReply[0] = ioBuffer[0];
  93. if (ioBufferLen == 2) {
  94. //
  95. // the reader returned already the
  96. // 2nd byte of the status word
  97. //
  98. pReply[1] = ioBuffer[1];
  99. } else {
  100. // we have to read the 2nd byte of the status word
  101. ioBufferLen = sizeof(ioBuffer);
  102. NTStatus = STCReadICC1(
  103. ReaderExtension,
  104. ioBuffer,
  105. &ioBufferLen,
  106. 1
  107. );
  108. ASSERT(NTStatus != STATUS_BUFFER_TOO_SMALL);
  109. if (NTStatus != STATUS_SUCCESS) {
  110. __leave;
  111. }
  112. if (ioBufferLen != 1) {
  113. NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
  114. __leave;
  115. }
  116. pReply[1] = ioBuffer[0];
  117. }
  118. *pReplyLen = 2;
  119. }
  120. } while (totalBytesToWrite || restartWorkWaitingTime);
  121. if (totalBytesToRead != 0) {
  122. ioBufferLen = *pReplyLen;
  123. NTStatus = STCReadICC1(
  124. ReaderExtension,
  125. pReply,
  126. &ioBufferLen,
  127. totalBytesToRead
  128. );
  129. if (NTStatus != STATUS_SUCCESS) {
  130. __leave;
  131. }
  132. *pReplyLen = ioBufferLen;
  133. }
  134. }
  135. __finally {
  136. }
  137. return NTStatus;
  138. }
  139. //---------------------------------------- END OF FILE ----------------------------------------