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.

518 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: ifdtest.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #define min(a, b) (((a) < (b)) ? (a) : (b))
  11. // Status codes
  12. #define IFDSTATUS_SUCCESS 0
  13. #define IFDSTATUS_FAILED 1
  14. #define IFDSTATUS_CARD_UNKNOWN 2
  15. #define IFDSTATUS_TEST_UNKNOWN 3
  16. #define IFDSTATUS_NO_PROVIDER 4
  17. #define IFDSTATUS_NO_FUNCTION 5
  18. #define IFDSTATUS_END 7
  19. // query codes
  20. #define IFDQUERY_CARD_TESTED 0
  21. #define IFDQUERY_CARD_NAME 1
  22. #define IFDQUERY_TEST_RESULT 2
  23. #define READER_TYPE_WDM "WDM PnP"
  24. #define READER_TYPE_NT "NT 4.00"
  25. #define READER_TYPE_VXD "Win9x VxD"
  26. #define OS_WINNT4 "Windows NT 4.0"
  27. #define OS_WINNT5 "Windows NT 5.0"
  28. #define OS_WIN95 "Windows 95"
  29. #define OS_WIN98 "Windows 98"
  30. #define MAX_NUM_ATR 3
  31. // Prototypes
  32. void LogMessage(PCHAR in_pchFormat, ...);
  33. void LogOpen(PCHAR in_pchLogFile);
  34. void TestStart(PCHAR in_pchFormat, ...);
  35. void TestCheck(BOOL in_bResult, PCHAR in_pchFormat, ...);
  36. void TestEnd(void);
  37. BOOL TestFailed(void);
  38. BOOL ReaderFailed(void);
  39. CString & GetOperatingSystem(void);
  40. void
  41. TestCheck(
  42. ULONG in_lResult,
  43. const PCHAR in_pchOperator,
  44. const ULONG in_uExpectedResult,
  45. ULONG in_uResultLength,
  46. ULONG in_uExpectedLength,
  47. UCHAR in_chSw1,
  48. UCHAR in_chSw2,
  49. UCHAR in_chExpectedSw1,
  50. UCHAR in_chExpectedSw2,
  51. PBYTE in_pchData,
  52. PBYTE in_pchExpectedData,
  53. ULONG in_uDataLength
  54. );
  55. extern "C" {
  56. LONG MapWinErrorToNtStatus(ULONG in_uErrorCode);
  57. }
  58. //
  59. // some useful macros
  60. //
  61. #define TEST_END() {TestEnd(); if(TestFailed()) return IFDSTATUS_FAILED;}
  62. #define TEST_CHECK_SUCCESS(Text, Result) \
  63. TestCheck( \
  64. Result == ERROR_SUCCESS, \
  65. "%s.\nReturned %8lxH (NTSTATUS %8lxH)\nExpected 0H (NTSTATUS 0H)", \
  66. Text, \
  67. Result, \
  68. MapWinErrorToNtStatus(Result) \
  69. );
  70. #define TEST_CHECK_NOT_SUPPORTED(Text, Result) \
  71. TestCheck( \
  72. Result == ERROR_NOT_SUPPORTED, \
  73. "%s.\nReturned %8lxH (NTSTATUS %8xH)\nExpected %38xH (NTSTATUS %8lxH)", \
  74. Text, \
  75. Result, \
  76. MapWinErrorToNtStatus(Result), \
  77. ERROR_NOT_SUPPORTED, \
  78. MapWinErrorToNtStatus(ERROR_NOT_SUPPORTED) \
  79. );
  80. //
  81. // Class definitions
  82. //
  83. class CAtr {
  84. UCHAR m_rgbAtr[SCARD_ATR_LENGTH];
  85. ULONG m_uAtrLength;
  86. public:
  87. CAtr() {
  88. m_uAtrLength = 0;
  89. memset(m_rgbAtr, 0, SCARD_ATR_LENGTH);
  90. }
  91. CAtr(
  92. BYTE in_rgbAtr[],
  93. ULONG in_uAtrLength
  94. )
  95. {
  96. *this = CAtr();
  97. m_uAtrLength = min(SCARD_ATR_LENGTH, in_uAtrLength);
  98. memcpy(m_rgbAtr, in_rgbAtr, m_uAtrLength);
  99. }
  100. PCHAR GetAtrString(PCHAR io_pchBuffer);
  101. PBYTE GetAtr(PBYTE *io_pchBuffer, PULONG io_puAtrLength) {
  102. *io_pchBuffer = (PBYTE) m_rgbAtr;
  103. *io_puAtrLength = m_uAtrLength;
  104. return (PBYTE) m_rgbAtr;
  105. }
  106. ULONG GetLength() {
  107. return m_uAtrLength;
  108. }
  109. operator==(const CAtr& a) {
  110. return (m_uAtrLength &&
  111. a.m_uAtrLength == m_uAtrLength &&
  112. memcmp(m_rgbAtr, a.m_rgbAtr, m_uAtrLength) == 0);
  113. }
  114. operator!=(const CAtr& a) {
  115. return !(*this == a);
  116. }
  117. };
  118. class CReader {
  119. // device name. E.g. SCReader0
  120. CString m_CDeviceName;
  121. // Name of the reader to be tested. E.g. Bull
  122. CString m_CVendorName;
  123. // Name of the reader to be tested. E.g. Bull
  124. CString m_CIfdType;
  125. // Atr of the current card
  126. class CAtr m_CAtr;
  127. // handle to the reader device
  128. HANDLE m_hReader;
  129. // Overlapped structure used by DeviceIoControl
  130. OVERLAPPED m_Ovr;
  131. // Overlapped structure used by WaitFor...
  132. OVERLAPPED m_OvrWait;
  133. // io-request struct used for transmissions
  134. SCARD_IO_REQUEST m_ScardIoRequest;
  135. // Storage area for smart card i/o
  136. UCHAR m_rgbReplyBuffer[1024];
  137. // size of the reply buffer
  138. ULONG m_uReplyBufferSize;
  139. // Number of bytes returned by the card
  140. ULONG m_uReplyLength;
  141. // function used by WaitForCardInsertion|Removal
  142. LONG WaitForCard(const ULONG);
  143. LONG StartWaitForCard(const ULONG);
  144. LONG PowerCard(ULONG in_uMinorIoControlCode);
  145. BOOL m_fDump;
  146. public:
  147. CReader();
  148. // Close reader
  149. void Close(void);
  150. // power functions
  151. LONG CReader::ColdResetCard(void) {
  152. return PowerCard(SCARD_COLD_RESET);
  153. }
  154. LONG CReader::WarmResetCard(void) {
  155. return PowerCard(SCARD_WARM_RESET);
  156. }
  157. LONG CReader::PowerDownCard(void) {
  158. return PowerCard(SCARD_POWER_DOWN);
  159. }
  160. PBYTE GetAtr(PBYTE *io_pchBuffer, PULONG io_puAtrLength) {
  161. return m_CAtr.GetAtr(io_pchBuffer, io_puAtrLength);
  162. }
  163. PCHAR GetAtrString(PCHAR io_pchBuffer) {
  164. return m_CAtr.GetAtrString(io_pchBuffer);
  165. }
  166. HANDLE GetHandle(void) {
  167. return m_hReader;
  168. }
  169. CString &GetDeviceName(void) {
  170. return m_CDeviceName;
  171. }
  172. LONG VendorIoctl(CString &o_CAnswer);
  173. CString &GetVendorName(void);
  174. CString &GetIfdType(void);
  175. ULONG GetDeviceUnit(void);
  176. LONG GetState(PULONG io_puState);
  177. // Open the reader
  178. BOOL Open(
  179. CString &in_CReaderName
  180. );
  181. // (Re)Open reader using the existing name
  182. BOOL Open(void);
  183. //
  184. // Set size of the reply buffer
  185. // (Only for testing purposes)
  186. //
  187. void SetReplyBufferSize(ULONG in_uSize) {
  188. if (in_uSize > sizeof(m_rgbReplyBuffer)) {
  189. m_uReplyBufferSize = sizeof(m_rgbReplyBuffer);
  190. } else {
  191. m_uReplyBufferSize = in_uSize;
  192. }
  193. }
  194. // assigns an ATR
  195. void SetAtr(PBYTE in_pchAtr, ULONG in_uAtrLength) {
  196. m_CAtr = CAtr(in_pchAtr, in_uAtrLength);
  197. }
  198. // returns the ATR of the current card
  199. class CAtr &GetAtr() {
  200. return m_CAtr;
  201. }
  202. // set protocol to be used
  203. LONG SetProtocol(const ULONG in_uProtocol);
  204. // transmits an APDU to the reader/card
  205. LONG Transmit(
  206. PBYTE in_pchRequest,
  207. ULONG in_uRequestLength,
  208. PBYTE *out_pchReply,
  209. PULONG out_puReplyLength
  210. );
  211. // wait to insert card
  212. LONG WaitForCardInsertion() {
  213. return WaitForCard(IOCTL_SMARTCARD_IS_PRESENT);
  214. };
  215. // wait to remove card
  216. LONG WaitForCardRemoval() {
  217. return WaitForCard(IOCTL_SMARTCARD_IS_ABSENT);
  218. };
  219. LONG StartWaitForCardRemoval() {
  220. return StartWaitForCard(IOCTL_SMARTCARD_IS_ABSENT);
  221. };
  222. LONG StartWaitForCardInsertion() {
  223. return StartWaitForCard(IOCTL_SMARTCARD_IS_PRESENT);
  224. };
  225. LONG FinishWaitForCard(const BOOL in_bWait);
  226. void SetDump(BOOL in_fOn) {
  227. m_fDump = in_fOn;
  228. }
  229. };
  230. class CCardProvider {
  231. // Start of list pointer
  232. static class CCardProvider *s_pFirst;
  233. // Pointer to next provider
  234. class CCardProvider *m_pNext;
  235. // name of the card to be tested
  236. CString m_CCardName;
  237. // atr of this card
  238. CAtr m_CAtr[3];
  239. // test no to run
  240. ULONG m_uTestNo;
  241. // max number of tests
  242. ULONG m_uTestMax;
  243. // This flag indicates that the card test was unsuccessful
  244. BOOL m_bTestFailed;
  245. // This flag indicates that the card has been tested
  246. BOOL m_bCardTested;
  247. // set protocol function
  248. ULONG ((*m_pSetProtocol)(class CCardProvider&, class CReader&));
  249. // set protocol function
  250. ULONG ((*m_pCardTest)(class CCardProvider&, class CReader&));
  251. public:
  252. // Constructor
  253. CCardProvider(void);
  254. // Constructor to be used by plug-in
  255. CCardProvider(void (*pEntryFunction)(class CCardProvider&));
  256. // Method that mangages all card tests
  257. void CardTest(class CReader&, ULONG in_uTestNo);
  258. // return if there are still untested cards
  259. BOOL CardsUntested(void);
  260. // List all cards that have not been tested
  261. void ListUntestedCards(void);
  262. // Assigns a friendly name to a card
  263. void SetCardName(CHAR in_rgchCardName[]);
  264. // Set ATR of the card
  265. void SetAtr(PBYTE in_rgbAtr, ULONG in_uAtrLength);
  266. // Assign callback functions
  267. void SetProtocol(ULONG ((in_pFunction)(class CCardProvider&, class CReader&))) {
  268. m_pSetProtocol = in_pFunction;
  269. }
  270. void SetCardTest(ULONG ((in_pFunction)(class CCardProvider&, class CReader&))) {
  271. m_pCardTest = in_pFunction;
  272. }
  273. // returns the test number to perform
  274. ULONG GetTestNo(void) {
  275. return m_uTestNo;
  276. }
  277. BOOL IsValidAtr(CAtr in_CAtr) {
  278. for (int i = 0; i < MAX_NUM_ATR; i++) {
  279. if (m_CAtr[i] == in_CAtr) {
  280. return TRUE;
  281. }
  282. }
  283. return FALSE;
  284. }
  285. };
  286. // represents a list of all installed readers
  287. class CReaderList {
  288. // number of constructor calls to avoid multiple build of reader list
  289. static ULONG m_uRefCount;
  290. // number of currently installed readers
  291. static ULONG m_uNumReaders;
  292. // pointer to array of reader list
  293. static class CReaderList **m_pList;
  294. ULONG m_uCurrentReader;
  295. CString m_CDeviceName;
  296. CString m_CPnPType;
  297. CString m_CVendorName;
  298. CString m_CIfdType;
  299. public:
  300. CReaderList();
  301. CReaderList(
  302. CString &in_CDeviceName,
  303. CString &in_CPnPType,
  304. CString &in_CVendorName,
  305. CString &in_CIfdType
  306. );
  307. ~CReaderList();
  308. void AddDevice(
  309. CString in_pchDeviceName,
  310. CString in_pchPnPType
  311. );
  312. CString &GetVendorName(ULONG in_uIndex);
  313. CString &GetDeviceName(ULONG in_uIndex);
  314. CString &GetIfdType(ULONG in_uIndex);
  315. CString &GetPnPType(ULONG in_uIndex);
  316. ULONG GetNumReaders(void) {
  317. return m_uNumReaders;
  318. }
  319. };
  320. // This structure represents the T=0 result file of a smart card
  321. typedef struct _T0_RESULT_FILE_HEADER {
  322. // Offset to first test result
  323. UCHAR Offset;
  324. // Number of times the card has been reset
  325. UCHAR CardResetCount;
  326. // Version number of this card
  327. UCHAR CardMajorVersion;
  328. UCHAR CardMinorVersion;
  329. } T0_RESULT_FILE_HEADER, *PT0_RESULT_FILE_HEADER;
  330. typedef struct _T0_RESULT_FILE {
  331. //
  332. // The following structures store the results
  333. // of the tests. Each result comes with the
  334. // reset count when the test was performed.
  335. // This is used to make sure that we read not
  336. // the result from an old test, maybe even
  337. // performed with another reader/driver.
  338. //
  339. struct {
  340. UCHAR Result;
  341. UCHAR ResetCount;
  342. } TransferAllBytes;
  343. struct {
  344. UCHAR Result;
  345. UCHAR ResetCount;
  346. } TransferNextByte;
  347. struct {
  348. UCHAR Result;
  349. UCHAR ResetCount;
  350. } Read256Bytes;
  351. struct {
  352. UCHAR Result;
  353. UCHAR ResetCount;
  354. } Case1Apdu;
  355. struct {
  356. UCHAR Result;
  357. UCHAR ResetCount;
  358. } RestartWorkWaitingTime;
  359. struct {
  360. UCHAR Result;
  361. UCHAR ResetCount;
  362. } PTS;
  363. struct {
  364. UCHAR Result;
  365. UCHAR ResetCount;
  366. } PTSDataCheck;
  367. } T0_RESULT_FILE, *PT0_RESULT_FILE;