1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2019 Joyent, Inc. 14 * Copyright 2022 Oxide Computer Company 15 */ 16 17 #ifndef _WINSCARD_H 18 #define _WINSCARD_H 19 20 /* 21 * This library provides a compatibility interface with programs designed 22 * against the PC SmartCard Library. This originates from Microsoft and has been 23 * used on a few different forms over the years by folks. The purpose of this 24 * library is for compatibility. 25 * 26 * At the time of this writing, Microsofts API documentation can be found here: 27 * https://docs.microsoft.com/en-us/windows/win32/api/winscard/ 28 * 29 * New consumers should not use this library and instead should leverage 30 * ccid(4D) instead. 31 */ 32 33 #include <stdint.h> 34 #include <wintypes.h> 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 /* 41 * This is a departure from the PCSC system which defines this as a LONG, 42 * which is the same size on 32bit and 64bit Windows (ILP32 and LLP64). 43 * We need to use the real native pointer size for the context handle as 44 * it wouldn't fit into a LONG on our LP64 platform. 45 */ 46 typedef void *SCARDCONTEXT; 47 typedef void **PSCARDCONTEXT; 48 typedef void **LPSCARDCONTEXT; 49 typedef void *SCARDHANDLE; 50 typedef void **PSCARDHANDLE; 51 typedef void **LPSCARDHANDLE; 52 53 /* 54 * Conventionally this is supposed to be packed. 55 */ 56 #pragma pack(1) 57 typedef struct { 58 unsigned long dwProtocol; 59 unsigned long cbPciLength; 60 } SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST; 61 #pragma pack() 62 63 extern SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci, g_rgSCardRawPci; 64 #define SCARD_PCI_T0 (&g_rgSCardT0Pci) 65 #define SCARD_PCI_T1 (&g_rgSCardT1Pci) 66 #define SCARD_PCI_RAW (&g_rgSCardRawPci) 67 68 /* 69 * Return values and error codes. We strive to use the same error codes as 70 * Microsoft. 71 */ 72 #define SCARD_S_SUCCESS ((LONG)0x00000000) 73 #define SCARD_F_INTERNAL_ERROR ((LONG)0x80100001) 74 #define SCARD_E_CANCELLED ((LONG)0x80100002) 75 #define SCARD_E_INVALID_HANDLE ((LONG)0x80100003) 76 #define SCARD_E_INVALID_PARAMETER ((LONG)0x80100004) 77 #define SCARD_E_NO_MEMORY ((LONG)0x80100006) 78 #define SCARD_E_INSUFFICIENT_BUFFER ((LONG)0x80100008) 79 #define SCARD_E_UNKNOWN_READER ((LONG)0x80100009) 80 #define SCARD_E_TIMEOUT ((LONG)0x8010000a) 81 #define SCARD_E_SHARING_VIOLATION ((LONG)0x8010000b) 82 #define SCARD_E_NO_SMARTCARD ((LONG)0x8010000c) 83 #define SCARD_E_UNKNOWN_CARD ((LONG)0x8010000d) 84 #define SCARD_E_PROTO_MISMATCH ((LONG)0x8010000f) 85 #define SCARD_E_INVALID_VALUE ((LONG)0x80100011) 86 #define SCARD_F_COMM_ERROR ((LONG)0x80100013) 87 #define SCARD_F_UNKNOWN_ERROR ((LONG)0x80100014) 88 #define SCARD_E_READER_UNAVAILABLE ((LONG)0x80100017) 89 #define SCARD_E_NO_SERVICE ((LONG)0x8010001D) 90 #define SCARD_E_SERVICE_STOPPED ((LONG)0x8010001E) 91 #define SCARD_E_UNSUPPORTED_FEATURE ((LONG)0x80100022) 92 #define SCARD_E_NO_READERS_AVAILABLE ((LONG)0x8010002E) 93 #define SCARD_W_UNSUPPORTED_CARD ((LONG)0x80100065) 94 #define SCARD_W_UNPOWERED_CARD ((LONG)0x80100067) 95 #define SCARD_W_RESET_CARD ((LONG)0x80100068) 96 #define SCARD_W_REMOVED_CARD ((LONG)0x80100069) 97 98 #define SCARD_SCOPE_USER 0x0000 99 #define SCARD_SCOPE_TERMINAL 0x0001 100 #define SCARD_SCOPE_SYSTEM 0x0002 101 #define SCARD_SCOPE_GLOBAL 0x0003 102 103 #define SCARD_SHARE_EXCLUSIVE 0x0001 104 #define SCARD_SHARE_SHARED 0x0002 105 #define SCARD_SHARE_DIRECT 0x0003 106 107 #define SCARD_PROTOCOL_UNDEFINED 0x0000 108 #define SCARD_PROTOCOL_T0 0x0001 109 #define SCARD_PROTOCOL_T1 0x0002 110 #define SCARD_PROTOCOL_RAW 0x0004 111 #define SCARD_PROTOCOL_T15 0x0008 112 113 #define SCARD_LEAVE_CARD 0x0000 114 #define SCARD_RESET_CARD 0x0001 115 #define SCARD_UNPOWER_CARD 0x0002 116 #define SCARD_EJECT_CARD 0x0003 117 118 /* 119 * Some versions of PCSClite treat the status value as a bitfield rather than 120 * an enumeration, though their documentation also suggests that "this 121 * difference may be resolved in a future version of pcsc-lite." We use 122 * bitfield-style values here in case we want to make changes in the future, 123 * but presently treat this as an enumeration (returning one value) as 124 * Microsoft does. 125 */ 126 #define SCARD_UNKNOWN 0x0001 127 #define SCARD_ABSENT 0x0002 128 #define SCARD_PRESENT 0x0004 129 #define SCARD_SWALLOWED 0x0008 130 #define SCARD_POWERED 0x0010 131 #define SCARD_NEGOTIABLE 0x0020 132 #define SCARD_SPECIFIC 0x0040 133 134 /* 135 * This is used to indicate that the framework should allocate memory. 136 */ 137 #define SCARD_AUTOALLOCATE UINT32_MAX 138 139 extern LONG SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT); 140 extern LONG SCardIsValidContext(SCARDCONTEXT); 141 extern LONG SCardReleaseContext(SCARDCONTEXT); 142 143 extern LONG SCardListReaders(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD); 144 145 extern LONG SCardFreeMemory(SCARDCONTEXT, LPCVOID); 146 147 extern LONG SCardConnect(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE, 148 LPDWORD); 149 extern LONG SCardDisconnect(SCARDHANDLE, DWORD); 150 151 extern LONG SCardStatus(SCARDHANDLE, LPSTR, LPDWORD, LPDWORD, LPDWORD, 152 LPBYTE, LPDWORD); 153 154 extern LONG SCardBeginTransaction(SCARDHANDLE); 155 extern LONG SCardEndTransaction(SCARDHANDLE, DWORD); 156 extern LONG SCardReconnect(SCARDHANDLE, DWORD, DWORD, DWORD, LPDWORD); 157 158 extern LONG SCardTransmit(SCARDHANDLE, const SCARD_IO_REQUEST *, LPCBYTE, 159 DWORD, SCARD_IO_REQUEST *, LPBYTE, LPDWORD); 160 161 extern const char *pcsc_stringify_error(const LONG); 162 163 #ifdef __cplusplus 164 } 165 #endif 166 167 #endif /* _WINSCARD_H */ 168