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