pcsc_sys/
lib.rs

1//! Low level bindings to the PCSC C API.
2//!
3//! The following platforms are supported:
4//!
5//! - On Windows, the built-in `WinSCard.dll` library and "Smart Card"
6//!   service. See [MSDN][1] for documentation of the implemented API.
7//!
8//! - On macOS, the built-in PCSC framework.
9//!
10//! - On Linux, BSDs and (hopefully) other systems, the PCSC lite library
11//!   and pcscd daemon. See [pcsclite][2] for documentation of the
12//!   implemented API.
13//!
14//!   pcsclite is detected at build time using pkg-config. See the
15//!   [`pkg-config`][3] crate for more information.
16//!
17//!   If you do not want to use pkg-config, you may instead export the
18//!   following environment variables when building the crate:
19//!
20//!   - `PCSC_LIB_DIR`: A directory in which to search for a dynamic
21//!     library implementing the PCSC API.
22//!   - `PCSC_LIB_NAME`: The name of the library. Defaults to `pcsclite`.
23//!
24//! [1]: https://msdn.microsoft.com/EN-US/library/aa374731.aspx#smart_card_functions
25//! [2]: https://pcsclite.apdu.fr/
26//! [3]: https://docs.rs/pkg-config/
27
28#![allow(bad_style)]
29// Needed for the errors, they are given in hex for some reason, but if
30// LONG is i32 they are negative (which presumably was the intention).
31#![allow(overflowing_literals)]
32
33use std::os::raw::{c_char, c_void};
34#[cfg(not(target_os = "macos"))]
35use std::os::raw::{c_long, c_ulong};
36
37#[cfg(not(target_os = "macos"))]
38pub type DWORD = c_ulong;
39#[cfg(not(target_os = "macos"))]
40pub type LONG = c_long;
41#[cfg(not(target_os = "macos"))]
42pub type ULONG = c_ulong;
43
44#[cfg(target_os = "macos")]
45pub type DWORD = u32;
46#[cfg(target_os = "macos")]
47pub type LONG = i32;
48#[cfg(target_os = "macos")]
49pub type ULONG = u32;
50
51#[cfg(target_os = "windows")]
52pub type SCARDCONTEXT = usize;
53#[cfg(target_os = "windows")]
54pub type SCARDHANDLE = usize;
55
56#[cfg(not(target_os = "windows"))]
57pub type SCARDCONTEXT = LONG;
58#[cfg(not(target_os = "windows"))]
59pub type SCARDHANDLE = LONG;
60
61pub const SCARD_S_SUCCESS: LONG = 0x0000_0000;
62pub const SCARD_F_INTERNAL_ERROR: LONG = 0x8010_0001;
63pub const SCARD_E_CANCELLED: LONG = 0x8010_0002;
64pub const SCARD_E_INVALID_HANDLE: LONG = 0x8010_0003;
65pub const SCARD_E_INVALID_PARAMETER: LONG = 0x8010_0004;
66pub const SCARD_E_INVALID_TARGET: LONG = 0x8010_0005;
67pub const SCARD_E_NO_MEMORY: LONG = 0x8010_0006;
68pub const SCARD_F_WAITED_TOO_LONG: LONG = 0x8010_0007;
69pub const SCARD_E_INSUFFICIENT_BUFFER: LONG = 0x8010_0008;
70pub const SCARD_E_UNKNOWN_READER: LONG = 0x8010_0009;
71pub const SCARD_E_TIMEOUT: LONG = 0x8010_000A;
72pub const SCARD_E_SHARING_VIOLATION: LONG = 0x8010_000B;
73pub const SCARD_E_NO_SMARTCARD: LONG = 0x8010_000C;
74pub const SCARD_E_UNKNOWN_CARD: LONG = 0x8010_000D;
75pub const SCARD_E_CANT_DISPOSE: LONG = 0x8010_000E;
76pub const SCARD_E_PROTO_MISMATCH: LONG = 0x8010_000F;
77pub const SCARD_E_NOT_READY: LONG = 0x8010_0010;
78pub const SCARD_E_INVALID_VALUE: LONG = 0x8010_0011;
79pub const SCARD_E_SYSTEM_CANCELLED: LONG = 0x8010_0012;
80pub const SCARD_F_COMM_ERROR: LONG = 0x8010_0013;
81pub const SCARD_F_UNKNOWN_ERROR: LONG = 0x8010_0014;
82pub const SCARD_E_INVALID_ATR: LONG = 0x8010_0015;
83pub const SCARD_E_NOT_TRANSACTED: LONG = 0x8010_0016;
84pub const SCARD_E_READER_UNAVAILABLE: LONG = 0x8010_0017;
85pub const SCARD_P_SHUTDOWN: LONG = 0x8010_0018;
86pub const SCARD_E_PCI_TOO_SMALL: LONG = 0x8010_0019;
87pub const SCARD_E_READER_UNSUPPORTED: LONG = 0x8010_001A;
88pub const SCARD_E_DUPLICATE_READER: LONG = 0x8010_001B;
89pub const SCARD_E_CARD_UNSUPPORTED: LONG = 0x8010_001C;
90pub const SCARD_E_NO_SERVICE: LONG = 0x8010_001D;
91pub const SCARD_E_SERVICE_STOPPED: LONG = 0x8010_001E;
92pub const SCARD_E_UNEXPECTED: LONG = 0x8010_001F;
93// See: https://pcsclite.apdu.fr/api/group__API.html#differences
94#[cfg(not(target_os = "windows"))]
95pub const SCARD_E_UNSUPPORTED_FEATURE: LONG = 0x8010_001F;
96pub const SCARD_E_ICC_INSTALLATION: LONG = 0x8010_0020;
97pub const SCARD_E_ICC_CREATEORDER: LONG = 0x8010_0021;
98#[cfg(target_os = "windows")]
99pub const SCARD_E_UNSUPPORTED_FEATURE: LONG = 0x8010_0022;
100pub const SCARD_E_DIR_NOT_FOUND: LONG = 0x8010_0023;
101pub const SCARD_E_FILE_NOT_FOUND: LONG = 0x8010_0024;
102pub const SCARD_E_NO_DIR: LONG = 0x8010_0025;
103pub const SCARD_E_NO_FILE: LONG = 0x8010_0026;
104pub const SCARD_E_NO_ACCESS: LONG = 0x8010_0027;
105pub const SCARD_E_WRITE_TOO_MANY: LONG = 0x8010_0028;
106pub const SCARD_E_BAD_SEEK: LONG = 0x8010_0029;
107pub const SCARD_E_INVALID_CHV: LONG = 0x8010_002A;
108pub const SCARD_E_UNKNOWN_RES_MNG: LONG = 0x8010_002B;
109pub const SCARD_E_NO_SUCH_CERTIFICATE: LONG = 0x8010_002C;
110pub const SCARD_E_CERTIFICATE_UNAVAILABLE: LONG = 0x8010_002D;
111pub const SCARD_E_NO_READERS_AVAILABLE: LONG = 0x8010_002E;
112pub const SCARD_E_COMM_DATA_LOST: LONG = 0x8010_002F;
113pub const SCARD_E_NO_KEY_CONTAINER: LONG = 0x8010_0030;
114pub const SCARD_E_SERVER_TOO_BUSY: LONG = 0x8010_0031;
115
116pub const SCARD_W_UNSUPPORTED_CARD: LONG = 0x8010_0065;
117pub const SCARD_W_UNRESPONSIVE_CARD: LONG = 0x8010_0066;
118pub const SCARD_W_UNPOWERED_CARD: LONG = 0x8010_0067;
119pub const SCARD_W_RESET_CARD: LONG = 0x8010_0068;
120pub const SCARD_W_REMOVED_CARD: LONG = 0x8010_0069;
121
122pub const SCARD_W_SECURITY_VIOLATION: LONG = 0x8010_006A;
123pub const SCARD_W_WRONG_CHV: LONG = 0x8010_006B;
124pub const SCARD_W_CHV_BLOCKED: LONG = 0x8010_006C;
125pub const SCARD_W_EOF: LONG = 0x8010_006D;
126pub const SCARD_W_CANCELLED_BY_USER: LONG = 0x8010_006E;
127pub const SCARD_W_CARD_NOT_AUTHENTICATED: LONG = 0x8010_006F;
128
129pub const SCARD_W_CACHE_ITEM_NOT_FOUND: LONG = 0x8010_0070;
130pub const SCARD_W_CACHE_ITEM_STALE: LONG = 0x8010_0071;
131pub const SCARD_W_CACHE_ITEM_TOO_BIG: LONG = 0x8010_0072;
132
133pub const SCARD_SCOPE_USER: DWORD = 0x0000;
134pub const SCARD_SCOPE_TERMINAL: DWORD = 0x0001;
135pub const SCARD_SCOPE_SYSTEM: DWORD = 0x0002;
136pub const SCARD_SCOPE_GLOBAL: DWORD = 0x0003;
137
138pub const SCARD_PROTOCOL_UNDEFINED: DWORD = 0x0000_0000;
139pub const SCARD_PROTOCOL_UNSET: DWORD = SCARD_PROTOCOL_UNDEFINED;
140pub const SCARD_PROTOCOL_T0: DWORD = 0x0000_0001;
141pub const SCARD_PROTOCOL_T1: DWORD = 0x0000_0002;
142#[cfg(not(target_os = "windows"))]
143pub const SCARD_PROTOCOL_RAW: DWORD = 0x0000_0004;
144#[cfg(target_os = "windows")]
145pub const SCARD_PROTOCOL_RAW: DWORD = 0x0001_0000;
146pub const SCARD_PROTOCOL_T15: DWORD = 0x0000_0008;
147pub const SCARD_PROTOCOL_ANY: DWORD = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
148
149pub const SCARD_SHARE_EXCLUSIVE: DWORD = 0x0001;
150pub const SCARD_SHARE_SHARED: DWORD = 0x0002;
151pub const SCARD_SHARE_DIRECT: DWORD = 0x0003;
152
153pub const SCARD_LEAVE_CARD: DWORD = 0x0000;
154pub const SCARD_RESET_CARD: DWORD = 0x0001;
155pub const SCARD_UNPOWER_CARD: DWORD = 0x0002;
156pub const SCARD_EJECT_CARD: DWORD = 0x0003;
157
158/* Non-Windows (bitmask) */
159#[cfg(not(target_os = "windows"))]
160pub const SCARD_UNKNOWN: DWORD = 0x0001;
161#[cfg(not(target_os = "windows"))]
162pub const SCARD_ABSENT: DWORD = 0x0002;
163#[cfg(not(target_os = "windows"))]
164pub const SCARD_PRESENT: DWORD = 0x0004;
165#[cfg(not(target_os = "windows"))]
166pub const SCARD_SWALLOWED: DWORD = 0x0008;
167#[cfg(not(target_os = "windows"))]
168pub const SCARD_POWERED: DWORD = 0x0010;
169#[cfg(not(target_os = "windows"))]
170pub const SCARD_NEGOTIABLE: DWORD = 0x0020;
171#[cfg(not(target_os = "windows"))]
172pub const SCARD_SPECIFIC: DWORD = 0x0040;
173/* Windows (ordinal) */
174#[cfg(target_os = "windows")]
175pub const SCARD_UNKNOWN: DWORD = 0;
176#[cfg(target_os = "windows")]
177pub const SCARD_ABSENT: DWORD = 1;
178#[cfg(target_os = "windows")]
179pub const SCARD_PRESENT: DWORD = 2;
180#[cfg(target_os = "windows")]
181pub const SCARD_SWALLOWED: DWORD = 3;
182#[cfg(target_os = "windows")]
183pub const SCARD_POWERED: DWORD = 4;
184#[cfg(target_os = "windows")]
185pub const SCARD_NEGOTIABLE: DWORD = 5;
186#[cfg(target_os = "windows")]
187pub const SCARD_SPECIFIC: DWORD = 6;
188
189pub const SCARD_STATE_UNAWARE: DWORD = 0x0000;
190pub const SCARD_STATE_IGNORE: DWORD = 0x0001;
191pub const SCARD_STATE_CHANGED: DWORD = 0x0002;
192pub const SCARD_STATE_UNKNOWN: DWORD = 0x0004;
193pub const SCARD_STATE_UNAVAILABLE: DWORD = 0x0008;
194pub const SCARD_STATE_EMPTY: DWORD = 0x0010;
195pub const SCARD_STATE_PRESENT: DWORD = 0x0020;
196pub const SCARD_STATE_ATRMATCH: DWORD = 0x0040;
197pub const SCARD_STATE_EXCLUSIVE: DWORD = 0x0080;
198pub const SCARD_STATE_INUSE: DWORD = 0x0100;
199pub const SCARD_STATE_MUTE: DWORD = 0x0200;
200pub const SCARD_STATE_UNPOWERED: DWORD = 0x0400;
201
202pub const SCARD_AUTOALLOCATE: DWORD = !0;
203
204pub const INFINITE: DWORD = 0xFFFF_FFFF;
205
206pub const MAX_ATR_SIZE: usize = 33;
207pub const SCARD_ATR_LENGTH: usize = MAX_ATR_SIZE;
208pub const MAX_BUFFER_SIZE: usize = 264;
209pub const MAX_BUFFER_SIZE_EXTENDED: usize = 4 + 3 + (1 << 16) + 3 + 2;
210
211#[cfg_attr(not(target_os = "macos"), repr(C))]
212#[cfg_attr(target_os = "macos", repr(C, packed))]
213pub struct SCARD_IO_REQUEST {
214    pub dwProtocol: DWORD,
215    pub cbPciLength: DWORD,
216}
217
218#[cfg(not(target_os = "windows"))]
219pub const ATR_BUFFER_SIZE: usize = MAX_ATR_SIZE;
220#[cfg(target_os = "windows")]
221pub const ATR_BUFFER_SIZE: usize = 36;
222
223#[cfg_attr(not(target_os = "macos"), repr(C))]
224#[cfg_attr(target_os = "macos", repr(C, packed))]
225pub struct SCARD_READERSTATE {
226    pub szReader: *const c_char,
227    pub pvUserData: *mut c_void,
228    pub dwCurrentState: DWORD,
229    pub dwEventState: DWORD,
230    pub cbAtr: DWORD,
231    pub rgbAtr: [u8; ATR_BUFFER_SIZE],
232}
233
234pub const SCARD_CLASS_VENDOR_INFO: ULONG = 1;
235pub const SCARD_CLASS_COMMUNICATIONS: ULONG = 2;
236pub const SCARD_CLASS_PROTOCOL: ULONG = 3;
237pub const SCARD_CLASS_POWER_MGMT: ULONG = 4;
238pub const SCARD_CLASS_SECURITY: ULONG = 5;
239pub const SCARD_CLASS_MECHANICAL: ULONG = 6;
240pub const SCARD_CLASS_VENDOR_DEFINED: ULONG = 7;
241pub const SCARD_CLASS_IFD_PROTOCOL: ULONG = 8;
242pub const SCARD_CLASS_ICC_STATE: ULONG = 9;
243pub const SCARD_CLASS_SYSTEM: ULONG = 0;
244
245macro_rules! SCARD_ATTR_VALUE {
246    ($class:expr, $value:expr) => {
247        ($class << 16) | $value
248    };
249}
250
251pub const SCARD_ATTR_VENDOR_NAME: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_VENDOR_INFO, 0x0100);
252pub const SCARD_ATTR_VENDOR_IFD_TYPE: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_VENDOR_INFO, 0x0101);
253pub const SCARD_ATTR_VENDOR_IFD_VERSION: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_VENDOR_INFO, 0x0102);
254pub const SCARD_ATTR_VENDOR_IFD_SERIAL_NO: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_VENDOR_INFO, 0x0103);
255pub const SCARD_ATTR_CHANNEL_ID: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_COMMUNICATIONS, 0x0110);
256pub const SCARD_ATTR_ASYNC_PROTOCOL_TYPES: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_PROTOCOL, 0x0120);
257pub const SCARD_ATTR_DEFAULT_CLK: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_PROTOCOL, 0x0121);
258pub const SCARD_ATTR_MAX_CLK: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_PROTOCOL, 0x0122);
259pub const SCARD_ATTR_DEFAULT_DATA_RATE: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_PROTOCOL, 0x0123);
260pub const SCARD_ATTR_MAX_DATA_RATE: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_PROTOCOL, 0x0124);
261pub const SCARD_ATTR_MAX_IFSD: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_PROTOCOL, 0x0125);
262pub const SCARD_ATTR_SYNC_PROTOCOL_TYPES: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_PROTOCOL, 0x0126);
263pub const SCARD_ATTR_POWER_MGMT_SUPPORT: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_POWER_MGMT, 0x0131);
264pub const SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_SECURITY, 0x0140);
265pub const SCARD_ATTR_USER_AUTH_INPUT_DEVICE: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_SECURITY, 0x0142);
266pub const SCARD_ATTR_CHARACTERISTICS: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_MECHANICAL, 0x0150);
267
268pub const SCARD_ATTR_CURRENT_PROTOCOL_TYPE: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x0201);
269pub const SCARD_ATTR_CURRENT_CLK: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x0202);
270pub const SCARD_ATTR_CURRENT_F: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x0203);
271pub const SCARD_ATTR_CURRENT_D: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x0204);
272pub const SCARD_ATTR_CURRENT_N: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x0205);
273pub const SCARD_ATTR_CURRENT_W: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x0206);
274pub const SCARD_ATTR_CURRENT_IFSC: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x0207);
275pub const SCARD_ATTR_CURRENT_IFSD: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x0208);
276pub const SCARD_ATTR_CURRENT_BWT: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x0209);
277pub const SCARD_ATTR_CURRENT_CWT: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x020a);
278pub const SCARD_ATTR_CURRENT_EBC_ENCODING: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x020b);
279pub const SCARD_ATTR_EXTENDED_BWT: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_IFD_PROTOCOL, 0x020c);
280
281pub const SCARD_ATTR_ICC_PRESENCE: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_ICC_STATE, 0x0300);
282pub const SCARD_ATTR_ICC_INTERFACE_STATUS: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_ICC_STATE, 0x0301);
283pub const SCARD_ATTR_CURRENT_IO_STATE: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_ICC_STATE, 0x0302);
284pub const SCARD_ATTR_ATR_STRING: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_ICC_STATE, 0x0303);
285pub const SCARD_ATTR_ICC_TYPE_PER_ATR: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_ICC_STATE, 0x0304);
286
287pub const SCARD_ATTR_ESC_RESET: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_VENDOR_DEFINED, 0xA000);
288pub const SCARD_ATTR_ESC_CANCEL: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_VENDOR_DEFINED, 0xA003);
289pub const SCARD_ATTR_ESC_AUTHREQUEST: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_VENDOR_DEFINED, 0xA005);
290pub const SCARD_ATTR_MAXINPUT: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_VENDOR_DEFINED, 0xA007);
291
292pub const SCARD_ATTR_DEVICE_UNIT: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_SYSTEM, 0x0001);
293pub const SCARD_ATTR_DEVICE_IN_USE: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_SYSTEM, 0x0002);
294pub const SCARD_ATTR_DEVICE_FRIENDLY_NAME_A: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_SYSTEM, 0x0003);
295pub const SCARD_ATTR_DEVICE_SYSTEM_NAME_A: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_SYSTEM, 0x0004);
296pub const SCARD_ATTR_DEVICE_FRIENDLY_NAME_W: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_SYSTEM, 0x0005);
297pub const SCARD_ATTR_DEVICE_SYSTEM_NAME_W: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_SYSTEM, 0x0006);
298pub const SCARD_ATTR_SUPRESS_T1_IFS_REQUEST: DWORD = SCARD_ATTR_VALUE!(SCARD_CLASS_SYSTEM, 0x0007);
299
300// Assumes ASCII.
301pub const SCARD_ATTR_DEVICE_FRIENDLY_NAME: DWORD = SCARD_ATTR_DEVICE_FRIENDLY_NAME_A;
302pub const SCARD_ATTR_DEVICE_SYSTEM_NAME: DWORD = SCARD_ATTR_DEVICE_SYSTEM_NAME_A;
303
304#[cfg(target_os = "windows")]
305pub const fn SCARD_CTL_CODE(code: DWORD) -> DWORD {
306    0x0031_0000 | (code << 2)
307}
308#[cfg(not(target_os = "windows"))]
309pub const fn SCARD_CTL_CODE(code: DWORD) -> DWORD {
310    0x4200_0000 + code
311}
312
313// The g_* statics only link if this is applied, even though the link
314// is already specified in the build script. No idea why; oh well.
315#[cfg_attr(target_os = "windows", link(name = "winscard"))]
316extern "system" {
317    pub static g_rgSCardT0Pci: SCARD_IO_REQUEST;
318    pub static g_rgSCardT1Pci: SCARD_IO_REQUEST;
319    pub static g_rgSCardRawPci: SCARD_IO_REQUEST;
320
321    pub fn SCardEstablishContext(
322        dwScope: DWORD,
323        pvReserved1: *const c_void,
324        pvReserved2: *const c_void,
325        phContext: *mut SCARDCONTEXT,
326    ) -> LONG;
327
328    pub fn SCardReleaseContext(hContext: SCARDCONTEXT) -> LONG;
329
330    pub fn SCardIsValidContext(hContext: SCARDCONTEXT) -> LONG;
331
332    pub fn SCardCancel(hContext: SCARDCONTEXT) -> LONG;
333
334    #[cfg_attr(target_os = "windows", link_name = "SCardConnectA")]
335    pub fn SCardConnect(
336        hContext: SCARDCONTEXT,
337        szReader: *const c_char,
338        dwShareMode: DWORD,
339        dwPreferredProtocols: DWORD,
340        phCard: *mut SCARDHANDLE,
341        pdwActiveProtocol: *mut DWORD,
342    ) -> LONG;
343
344    pub fn SCardReconnect(
345        hCard: SCARDHANDLE,
346        dwShareMode: DWORD,
347        dwPreferredProtocols: DWORD,
348        dwInitialization: DWORD,
349        pdwActiveProtocol: *mut DWORD,
350    ) -> LONG;
351
352    pub fn SCardDisconnect(hCard: SCARDHANDLE, dwDisposition: DWORD) -> LONG;
353
354    #[cfg_attr(target_os = "windows", link_name = "SCardGetStatusChangeA")]
355    pub fn SCardGetStatusChange(
356        hContext: SCARDCONTEXT,
357        dwTimeout: DWORD,
358        rgReaderStates: *mut SCARD_READERSTATE,
359        cReaders: DWORD,
360    ) -> LONG;
361
362    #[cfg_attr(target_os = "windows", link_name = "SCardListReadersA")]
363    pub fn SCardListReaders(
364        hContext: SCARDCONTEXT,
365        mszGroups: *const c_char,
366        mszReaders: *mut c_char,
367        pcchReaders: *mut DWORD,
368    ) -> LONG;
369
370    pub fn SCardBeginTransaction(hCard: SCARDHANDLE) -> LONG;
371
372    pub fn SCardEndTransaction(hCard: SCARDHANDLE, dwDisposition: DWORD) -> LONG;
373
374    #[cfg_attr(target_os = "windows", link_name = "SCardStatusA")]
375    pub fn SCardStatus(
376        hCard: SCARDHANDLE,
377        szReaderName: *mut c_char,
378        pcchReaderLen: *mut DWORD,
379        pdwState: *mut DWORD,
380        pdwProtocol: *mut DWORD,
381        pbAtr: *mut u8,
382        pcbAtrLen: *mut DWORD,
383    ) -> LONG;
384
385    pub fn SCardGetAttrib(hCard: SCARDHANDLE, dwAttrId: DWORD, pbAttr: *mut u8, pcbAttrLen: *mut DWORD) -> LONG;
386
387    pub fn SCardSetAttrib(hCard: SCARDHANDLE, dwAttrId: DWORD, pbAttr: *const u8, pcbAttrLen: DWORD) -> LONG;
388
389    pub fn SCardTransmit(
390        hCard: SCARDHANDLE,
391        pioSendPci: *const SCARD_IO_REQUEST,
392        pbSendBuffer: *const u8,
393        cbSendLength: DWORD,
394        pioRecvPci: *mut SCARD_IO_REQUEST,
395        pbRecvBuffer: *mut u8,
396        pcbRecvLength: *mut DWORD,
397    ) -> LONG;
398
399    #[cfg_attr(target_os = "macos", link_name = "SCardControl132")]
400    pub fn SCardControl(
401        hCard: SCARDHANDLE,
402        dwControlCode: DWORD,
403        pbSendBuffer: *const u8,
404        cbSendLength: DWORD,
405        pbRecvBuffer: *mut u8,
406        cbRecvLength: DWORD,
407        lpBytesReturned: *mut DWORD,
408    ) -> LONG;
409}