smartcard 0.4.11 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,39 +0,0 @@
1
- #include "pcsc.h"
2
-
3
- VALUE ePcscException;
4
-
5
- #if defined(WIN32)
6
- static char scard_error_buffer[128];
7
-
8
- /* Produces a string for an error code yielded by the SCard* PC/SC functions. Returns a static global buffer. */
9
- static char *pcsc_stringify_error(DWORD scard_error) {
10
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
11
- NULL, scard_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
12
- scard_error_buffer, sizeof(scard_error_buffer), NULL );
13
- return scard_error_buffer;
14
- }
15
- #endif
16
-
17
-
18
- #ifdef MAKE_RDOC_HAPPY
19
- mSmartcard = rb_define_module("Smartcard");
20
- mPcsc = rb_define_module_under(mSmartcard, "PCSC");
21
- #endif
22
-
23
- /* :Document-class: Smartcard::PCSC::Exception
24
- * Contains information about an exception at the PC/SC layer.
25
- */
26
- void Init_PCSC_Exception() {
27
- ePcscException = rb_define_class_under(mPcsc, "PcscException", rb_eRuntimeError);
28
- }
29
-
30
- /* Raises a PC/SC error. */
31
- void _PCSC_Exception_raise(DWORD pcsc_error, char *pcsc_function) {
32
- char buf[BUFSIZ];
33
- VALUE exception;
34
-
35
- sprintf(buf, "%s: %s", pcsc_function, pcsc_stringify_error(pcsc_error));
36
- exception = rb_exc_new2(ePcscException, buf);
37
- rb_iv_set(exception, "@errno", INT2NUM(pcsc_error));
38
- rb_exc_raise(exception);
39
- }
@@ -1,129 +0,0 @@
1
- #include "pcsc.h"
2
-
3
- VALUE cPcscIoRequest;
4
-
5
- /* Wraps a SCARD_IO_REQUEST, tracking its allocation etc. */
6
- struct SCardIoRequestEx {
7
- SCARD_IO_REQUEST *pcsc_request;
8
- int mallocd;
9
- };
10
-
11
- /* Custom free for Smartcard::PCSC::IoRequest. */
12
- static void PCSC_IoRequest_free(struct SCardIoRequestEx *_request) {
13
- if(_request != NULL) {
14
- if(_request->mallocd)
15
- xfree(_request->pcsc_request);
16
- xfree(_request);
17
- }
18
- }
19
-
20
- /* Custom allocation for Smartcard::PCSC::Card. Wraps a SCardIoRequestEx. */
21
- static VALUE PCSC_IoRequest_alloc(VALUE klass) {
22
- struct SCardIoRequestEx *request;
23
-
24
- VALUE rbIoRequest = Data_Make_Struct(klass, struct SCardIoRequestEx, NULL, PCSC_IoRequest_free, request);
25
- request->pcsc_request = NULL;
26
- request->mallocd = 0;
27
- return rbIoRequest;
28
- }
29
-
30
- /* :Document-method: new
31
- * call-seq:
32
- * new() --> io_request
33
- *
34
- * Creates an uninitialized IoRequest.
35
- * The request can be used as a receiving IoRequest in Smartcard::PCSC::Card#transmit.
36
- */
37
- static VALUE PCSC_IoRequest_initialize(VALUE self) {
38
- struct SCardIoRequestEx *request;
39
-
40
- Data_Get_Struct(self, struct SCardIoRequestEx, request);
41
- request->pcsc_request = ALLOC(SCARD_IO_REQUEST);
42
- request->mallocd = 1;
43
-
44
- return self;
45
- }
46
-
47
- /* :Document-method: protocol
48
- * call-seq:
49
- * io_request.protocol --> protocol
50
- *
51
- * The protocol of this instance.
52
- *
53
- * The returned protocol is a number, and should be checked against one of the Smartcard::PCSC::PROTOCOL_ constants.
54
- */
55
- static VALUE PCSC_IoRequest_get_protocol(VALUE self) {
56
- struct SCardIoRequestEx *request;
57
-
58
- Data_Get_Struct(self, struct SCardIoRequestEx, request);
59
- if(request == NULL) return Qnil;
60
-
61
- return UINT2NUM(request->pcsc_request->dwProtocol);
62
- }
63
-
64
- /* :Document-method: protocol=
65
- * call-seq:
66
- * io_request.protocol = protocol
67
- *
68
- * Sets the protocol of this instance.
69
- *
70
- * +protocol+:: use one of the Smartcard::PCSC::PROTOCOL_ constants
71
- */
72
- static VALUE PCSC_IoRequest_set_protocol(VALUE self, VALUE rbProtocol) {
73
- struct SCardIoRequestEx *request;
74
-
75
- Data_Get_Struct(self, struct SCardIoRequestEx, request);
76
- if(request == NULL) return self;
77
-
78
- if(request->mallocd == 0)
79
- rb_raise(rb_eSecurityError, "cannot modify PC/SC-global (read-only) IO_REQUEST");
80
- else
81
- request->pcsc_request->dwProtocol = NUM2UINT(rbProtocol);
82
- return self;
83
- }
84
-
85
- #ifdef MAKE_RDOC_HAPPY
86
- mSmartcard = rb_define_module("Smartcard");
87
- mPcsc = rb_define_module_under(mSmartcard, "PCSC");
88
- #endif
89
-
90
- /* :Document-class: Smartcard::PCSC::IoRequest
91
- * Protocol information used in Smartcard::PCSC::Card#transmit.
92
- * Wraps a _SCARD_IO_REQUEST_ structure.
93
- *
94
- * I know the name is retarded, but it reflects the PC/SC name well. The choice makes sense given that this
95
- * is an API meant for people familiar with the PC/SC specification.
96
- */
97
- void Init_PCSC_IoRequest() {
98
- cPcscIoRequest = rb_define_class_under(mPcsc, "IoRequest", rb_cObject);
99
- rb_define_alloc_func(cPcscIoRequest, PCSC_IoRequest_alloc);
100
- rb_define_method(cPcscIoRequest, "initialize", PCSC_IoRequest_initialize, 0);
101
- rb_define_method(cPcscIoRequest, "protocol", PCSC_IoRequest_get_protocol, 0);
102
- rb_define_method(cPcscIoRequest, "protocol=", PCSC_IoRequest_set_protocol, 1);
103
- }
104
-
105
- /* Retrieves the SCARD_IO_REQUEST wrapped into a Smartcard::PCSC::IoRequest instance. */
106
- int _PCSC_IoRequest_lowlevel_get(VALUE rbIoRequest, SCARD_IO_REQUEST **io_request) {
107
- struct SCardIoRequestEx *request;
108
-
109
- if(!RTEST(rbIoRequest)) {
110
- *io_request = NULL;
111
- return 1;
112
- }
113
- if(TYPE(rbIoRequest) != T_DATA || RDATA(rbIoRequest)->dfree != (void (*)(void *))PCSC_IoRequest_free)
114
- return 0;
115
-
116
- Data_Get_Struct(rbIoRequest, struct SCardIoRequestEx, request);
117
- *io_request = request->pcsc_request;
118
- return 1;
119
- }
120
-
121
- /* Creates a Smartcard::PCSC::IoRequest instance wrapping a given SCARD_IO_REQUEST. */
122
- VALUE _PCSC_IoRequest_lowlevel_new(const SCARD_IO_REQUEST *io_request) {
123
- struct SCardIoRequestEx *request;
124
-
125
- VALUE rbIoRequest = Data_Make_Struct(cPcscIoRequest, struct SCardIoRequestEx, NULL, PCSC_IoRequest_free, request);
126
- request->pcsc_request = io_request;
127
- request->mallocd = 0;
128
- return rbIoRequest;
129
- }
@@ -1,11 +0,0 @@
1
- #include "pcsc.h"
2
-
3
- void Init_pcsc() {
4
- Init_PCSC_Namespace();
5
- Init_PCSC_ReaderStates();
6
- Init_PCSC_IoRequest();
7
- Init_PCSC_Context();
8
- Init_PCSC_Card();
9
- Init_PCSC_Consts();
10
- Init_PCSC_Exception();
11
- }
@@ -1,70 +0,0 @@
1
- #include <string.h>
2
- #include "pcsc.h"
3
-
4
- /* Converts a multi-string "str1\0str_2\0str3\0\0" into a Ruby array of Ruby strings. */
5
- VALUE PCSC_Internal_multistring_to_ruby_array(char *mstr, size_t mstr_len) {
6
- VALUE rbArray, rbString;
7
- size_t i, start_offset;
8
-
9
- rbArray = rb_ary_new();
10
- for(i = 0; i < mstr_len; i++) {
11
- if(mstr[i] == '\0') break;
12
- start_offset = i;
13
- for(; i < mstr_len; i++)
14
- if(mstr[i] == '\0') break;
15
- rbString = rb_str_new(mstr + start_offset, i - start_offset);
16
- rb_ary_push(rbArray, rbString);
17
- }
18
- return rbArray;
19
- }
20
-
21
- /* Constructs a multi-string "str1\0str_2\0str3\0\0". Takes nil, a string, or an array of strings.
22
- * The returned buffer must be released with xfree.
23
- * If false is returned, something went wrong and the method did not return a buffer.
24
- */
25
- int PCSC_Internal_ruby_strings_to_multistring(VALUE rbStrings, char **strings) {
26
- VALUE *array_elements;
27
- char *buffer;
28
- size_t string_length, array_length, buffer_length, i;
29
-
30
- /* nil -> NULL */
31
- if(TYPE(rbStrings) == T_NIL || TYPE(rbStrings) == T_FALSE) {
32
- *strings = NULL;
33
- return 1;
34
- }
35
- /* string -> [string] */
36
- if(TYPE(rbStrings) == T_STRING) {
37
- string_length = RSTRING(rbStrings)->len;
38
- buffer = ALLOC_N(char, string_length + 2);
39
- memcpy(buffer, RSTRING(rbStrings)->ptr, string_length);
40
- buffer[string_length] = buffer[string_length + 1] = '\0';
41
- *strings = buffer;
42
- return 1;
43
- }
44
- /* array -> array */
45
- if(TYPE(rbStrings) == T_ARRAY) {
46
- /* compute buffer length */
47
- array_length = RARRAY(rbStrings)->len;
48
- array_elements = RARRAY(rbStrings)->ptr;
49
- buffer_length = 1; /* for the trailing '\0' */
50
- for(i = 0; i < array_length; i++) {
51
- if(TYPE(array_elements[i]) != T_STRING)
52
- return 0;
53
- buffer_length += RSTRING(array_elements[i])->len + 1;
54
- }
55
-
56
- /* concatenate strings into buffer */
57
- buffer = ALLOC_N(char, buffer_length);
58
- for(buffer_length = 0, i = 0; i < array_length; i++) {
59
- string_length = RSTRING(array_elements[i])->len;
60
- memcpy(buffer + buffer_length, RSTRING(array_elements[i])->ptr, string_length);
61
- buffer[buffer_length] = '\0';
62
- buffer_length += string_length + 1;
63
- }
64
- buffer[buffer_length] = '\0';
65
- *strings = buffer;
66
- return 1;
67
- }
68
-
69
- return 0;
70
- }
@@ -1,18 +0,0 @@
1
- #include "pcsc.h"
2
-
3
- VALUE mSmartcard;
4
- VALUE mPcsc;
5
-
6
- /* :Document-class: Smartcard::PCSC
7
- * Bindings to the PC/SC Smartcard API.
8
- *
9
- */
10
- static void Init_PCSC() {
11
- mPcsc = rb_define_module_under(mSmartcard, "PCSC");
12
- }
13
-
14
- void Init_PCSC_Namespace() {
15
- mSmartcard = rb_define_module("Smartcard");
16
- Init_PCSC();
17
- }
18
-
@@ -1,331 +0,0 @@
1
- #include "pcsc.h"
2
-
3
- VALUE cPcscReaderStates;
4
-
5
- /* Wraps an array of SCARD_READERSTATE elements. */
6
- struct PCSCReaderStates {
7
- size_t states_count;
8
- SCARD_READERSTATE *states;
9
- };
10
-
11
- /* Custom free for Smartcard::PCSC::ReaderStates. Also releases the referenced buffers (for the reader names). */
12
- static void PCSC_ReaderStates_free(struct PCSCReaderStates *_states) {
13
- size_t i;
14
- if(_states != NULL) {
15
- if(_states->states != NULL) {
16
- for(i = 0; i < _states->states_count; i++) {
17
- if(_states->states[i].szReader != NULL)
18
- xfree((char *)_states->states[i].szReader);
19
- }
20
- xfree(_states->states);
21
- }
22
- xfree(_states);
23
- }
24
- }
25
-
26
- /* Custom allocation for Smartcard::PCSC::ReaderStates. Wraps a reference to an array of SCARD_READERSTATE. */
27
- static VALUE PCSC_ReaderStates_alloc(VALUE klass) {
28
- struct PCSCReaderStates *states;
29
-
30
- VALUE rbReaderStates = Data_Make_Struct(klass, struct PCSCReaderStates, NULL, PCSC_ReaderStates_free, states);
31
- states->states_count = 0;
32
- states->states = NULL;
33
- return rbReaderStates;
34
- }
35
-
36
- /* :Document-method: new
37
- * call-seq:
38
- * new(num_states) --> reader_states
39
- *
40
- * Creates an array of +num_states+ reader state elements.
41
- * The states are unusable until they are assigned reader names by calling
42
- * Smartcard::PCSC::ReaderStates#set_reader_name_of.
43
- */
44
- static VALUE PCSC_ReaderStates_initialize(VALUE self, VALUE rbNumStates) {
45
- struct PCSCReaderStates *states;
46
- size_t states_count, i;
47
-
48
- Data_Get_Struct(self, struct PCSCReaderStates, states);
49
-
50
- states_count = NUM2UINT(rbNumStates);
51
- if(states_count > 0) {
52
- states->states = ALLOC_N(SCARD_READERSTATE, states_count);
53
- if(states->states != NULL) {
54
- states->states_count = states_count;
55
- for(i = 0; i < states_count; i++) {
56
- states->states[i].szReader = NULL;
57
- states->states[i].dwCurrentState = SCARD_STATE_UNAWARE;
58
- }
59
- }
60
- }
61
- return self;
62
- }
63
-
64
- static int _validate_readerstates_args(VALUE rbReaderStates, VALUE rbIndex, struct PCSCReaderStates **states, size_t *index) {
65
- Data_Get_Struct(rbReaderStates, struct PCSCReaderStates, *states);
66
- if(*states == NULL) return 0;
67
-
68
- *index = NUM2UINT(rbIndex);
69
- if(*index >= (*states)->states_count) {
70
- rb_raise(rb_eIndexError, "index %u is invalid (states array has %u elements)", *index, (*states)->states_count);
71
- return 0;
72
- }
73
-
74
- return 1;
75
- }
76
-
77
- /* :Document-method: current_state_of
78
- * call-seq:
79
- * current_state_of(index) --> current_state
80
- *
81
- * The current state (_dwCurrentState_ in PC/SC) in the <tt>index</tt>th reader
82
- * state element. Smartcard::PCSC::Context#get_status_change blocks as long as
83
- * the reader state equals this value.
84
- *
85
- * The returned state is a bitfield; the bits are defined in the
86
- * Smartcard::PCSC::STATE_ constants. See Smartcard::PCSC::STATE_UNAWARE.
87
- *
88
- * +index+:: the 0-based index of the reader state element to be queried
89
- */
90
- static VALUE PCSC_ReaderStates_current_state_of(VALUE self, VALUE rbIndex) {
91
- struct PCSCReaderStates *states;
92
- size_t index;
93
-
94
- if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
95
- return Qnil;
96
-
97
- return UINT2NUM(states->states[index].dwCurrentState);
98
- }
99
-
100
- /* :Document-method: event_state_of
101
- * call-seq:
102
- * event_state_of(index) --> event_state
103
- *
104
- * The event state (_dwEventState_ in PC/SC) in the <tt>index</tt>th reader
105
- * state element. Smartcard::PCSC::Context#get_status_change stores the updated
106
- * reader state in this value.
107
- *
108
- * The returned state is a bitfield; the bits are defined in the
109
- * Smartcard::PCSC::STATE_ constants. See Smartcard::PCSC::STATE_UNAWARE.
110
- *
111
- * +index+:: the 0-based index of the reader state element to be queried
112
- */
113
- static VALUE PCSC_ReaderStates_event_state_of(VALUE self, VALUE rbIndex) {
114
- struct PCSCReaderStates *states;
115
- size_t index;
116
-
117
- if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
118
- return Qnil;
119
-
120
- return UINT2NUM(states->states[index].dwEventState);
121
- }
122
-
123
- /* :Document-method: set_current_state_of!
124
- * call-seq:
125
- * set_current_state_of!(index, current_state) --> self
126
- *
127
- * Sets the current state (_dwCurrentState_ in PC/SC) in the <tt>index</tt>th reader state element.
128
- * Smartcard::PCSC::Context#get_status_change blocks as long as the reader state equals this value.
129
- *
130
- *
131
- * +index+:: the 0-based index of the reader state element to be modified
132
- * +current_state+:: a bitfield; the bits are defined in the Smartcard::PCSC::STATE_ constants.
133
- */
134
- static VALUE PCSC_ReaderStates_set_current_state_of(VALUE self, VALUE rbIndex, VALUE rbCurrentState) {
135
- struct PCSCReaderStates *states;
136
- size_t index;
137
-
138
- if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
139
- return self;
140
-
141
- states->states[index].dwCurrentState = NUM2UINT(rbCurrentState);
142
- return self;
143
- }
144
-
145
- /* :Document-method: set_event_state_of!
146
- * call-seq:
147
- * set_event_state_of!(index, event_state) --> self
148
- *
149
- * Sets the event state (_dwEventState_ in PC/SC) in the <tt>index</tt>th reader state element.
150
- * Smartcard::PCSC::Context#get_status_change stores the updated reader state in this value.
151
- *
152
- * +index+:: the 0-based index of the reader state element to be modified
153
- * +event_state+:: a bitfield; the bits are defined in the Smartcard::PCSC::STATE_ constants.
154
- */
155
- static VALUE PCSC_ReaderStates_set_event_state_of(VALUE self, VALUE rbIndex, VALUE rbEventState) {
156
- struct PCSCReaderStates *states;
157
- size_t index;
158
-
159
- if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
160
- return self;
161
-
162
- states->states[index].dwEventState = NUM2UINT(rbEventState);
163
- return self;
164
- }
165
-
166
- /* :Document-method: atr_of
167
- * call-seq:
168
- * atr_of(index) --> atr
169
- *
170
- * The card ATR string in the <tt>index</tt>th reader state element.
171
- * Smartcard::PCSC::Context#get_status_change stores the updated ATR string in this value.
172
- *
173
- * The returned ATR bytes are wrapped into a string. (don't complain, it's a low-level API)
174
- *
175
- * +index+:: the 0-based index of the reader state element to be queried
176
- */
177
- static VALUE PCSC_ReaderStates_atr_of(VALUE self, VALUE rbIndex) {
178
- struct PCSCReaderStates *states;
179
- size_t index;
180
-
181
- if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
182
- return Qnil;
183
-
184
- return rb_str_new((char *)states->states[index].rgbAtr, states->states[index].cbAtr);
185
- }
186
-
187
- /* :Document-method: set_atr_of!
188
- * call-seq:
189
- * set_atr_of!(index, atr) --> self
190
- *
191
- * Sets the card ATR string in the <tt>index</tt>th reader state element.
192
- * Smartcard::PCSC::Context#get_status_change stores the updated ATR string in this value.
193
- *
194
- * +index+:: the 0-based index of the reader state element to be modified
195
- * +atr+:: ATR bytes wrapped into a string (low-level API, remember?)
196
- */
197
- static VALUE PCSC_ReaderStates_set_atr_of(VALUE self, VALUE rbIndex, VALUE rbAtr) {
198
- struct PCSCReaderStates *states;
199
- size_t index;
200
- VALUE rbFinalAtr;
201
-
202
- if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
203
- return self;
204
-
205
- rbFinalAtr = rb_check_string_type(rbAtr);
206
- if(NIL_P(rbFinalAtr))
207
- return self;
208
-
209
- if(RSTRING(rbFinalAtr)->len > MAX_ATR_SIZE) {
210
- rb_raise(rb_eArgError, "given ATR is too long (%d characters given; can do at most MAX_ATR_SIZE = %d)", RSTRING(rbFinalAtr)->len, MAX_ATR_SIZE);
211
- return self;
212
- }
213
-
214
- states->states[index].cbAtr = RSTRING(rbAtr)->len;
215
- memcpy(states->states[index].rgbAtr, RSTRING(rbAtr)->ptr, states->states[index].cbAtr);
216
- return self;
217
- }
218
-
219
- /* :Document-method: reader_name_of
220
- * call-seq:
221
- * reader_name_of(index) --> reader_name
222
- *
223
- * The name of the reader whose status is represented in the <tt>index</tt>th reader state element.
224
- * Smartcard::PCSC::Context#get_status_change reads this value, and never updates it.
225
- *
226
- * +index+:: the 0-based index of the reader state element to be queried
227
- */
228
- static VALUE PCSC_ReaderStates_reader_name_of(VALUE self, VALUE rbIndex) {
229
- struct PCSCReaderStates *states;
230
- size_t index;
231
-
232
- if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
233
- return Qnil;
234
-
235
- return rb_str_new2(states->states[index].szReader);
236
- }
237
-
238
- /* :Document-method: set_reader_name_of!
239
- * call-seq:
240
- * set_reader_name_of!(index, reader_name) --> self
241
- *
242
- * The name of the reader whose status is represented in the <tt>index</tt>th reader state element.
243
- * Smartcard::PCSC::Context#get_status_change reads this value, and never updates it.
244
- *
245
- * +index+:: the 0-based index of the reader state element to be modified
246
- * +reader_name+:: a string-like object containing the reader name to be associated with the state element
247
- */
248
- static VALUE PCSC_ReaderStates_set_reader_name_of(VALUE self, VALUE rbIndex, VALUE rbReaderName) {
249
- struct PCSCReaderStates *states;
250
- size_t index, reader_name_length;
251
- VALUE rbFinalReaderName;
252
-
253
- if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
254
- return self;
255
-
256
- rbFinalReaderName = rb_check_string_type(rbReaderName);
257
- if(NIL_P(rbFinalReaderName))
258
- return self;
259
-
260
- reader_name_length = RSTRING(rbFinalReaderName)->len;
261
- if(states->states[index].szReader != NULL)
262
- xfree((char *)states->states[index].szReader);
263
- states->states[index].szReader = ALLOC_N(char, reader_name_length + 1);
264
- if(states->states[index].szReader != NULL) {
265
- memcpy((char *)states->states[index].szReader, RSTRING(rbFinalReaderName)->ptr, reader_name_length);
266
- ((char *)states->states[index].szReader)[reader_name_length] = '\0';
267
- }
268
- return self;
269
- }
270
-
271
- /* :Document-method: acknowledge_events!
272
- * call-seq:
273
- * acknowledge_events!() --> self
274
- *
275
- * Mass-assigns +current_state+ to +event_state+ for each reader state element.
276
- * Useful to acknowledge all the status changed communicated after a call to Smartcard::PCSC::Context#get_status_change
277
- * (and thus prepare for a new call).
278
- */
279
- static VALUE PCSC_ReaderStates_acknowledge_events(VALUE self) {
280
- struct PCSCReaderStates *states;
281
- size_t i;
282
-
283
- Data_Get_Struct(self, struct PCSCReaderStates, states);
284
- if(states != NULL) {
285
- for(i = 0; i < states->states_count; i++)
286
- states->states[i].dwCurrentState = states->states[i].dwEventState;
287
- }
288
- return self;
289
- }
290
-
291
- #ifdef MAKE_RDOC_HAPPY
292
- mSmartcard = rb_define_module("Smartcard");
293
- mPcsc = rb_define_module_under(mSmartcard, "PCSC");
294
- #endif
295
-
296
- /* :Document-class: Smartcard::PCSC::ReaderStates
297
- * Tracks reader status information, and is used in Smartcard::PCSC::Context#get_status_change.
298
- * Wraps an array of <i>SCARD_READERSTATE</i> structures.
299
- */
300
- void Init_PCSC_ReaderStates() {
301
- cPcscReaderStates = rb_define_class_under(mPcsc, "ReaderStates", rb_cObject);
302
- rb_define_alloc_func(cPcscReaderStates, PCSC_ReaderStates_alloc);
303
- rb_define_method(cPcscReaderStates, "initialize", PCSC_ReaderStates_initialize, 1);
304
- rb_define_method(cPcscReaderStates, "current_state_of", PCSC_ReaderStates_current_state_of, 1);
305
- rb_define_method(cPcscReaderStates, "set_current_state_of!", PCSC_ReaderStates_set_current_state_of, 2);
306
- rb_define_method(cPcscReaderStates, "event_state_of", PCSC_ReaderStates_event_state_of, 1);
307
- rb_define_method(cPcscReaderStates, "set_event_state_of!", PCSC_ReaderStates_set_event_state_of, 2);
308
- rb_define_method(cPcscReaderStates, "reader_name_of", PCSC_ReaderStates_reader_name_of, 1);
309
- rb_define_method(cPcscReaderStates, "set_reader_name_of!", PCSC_ReaderStates_set_reader_name_of, 2);
310
- rb_define_method(cPcscReaderStates, "atr_of", PCSC_ReaderStates_atr_of, 1);
311
- rb_define_method(cPcscReaderStates, "set_atr_of!", PCSC_ReaderStates_set_atr_of, 2);
312
- rb_define_method(cPcscReaderStates, "acknowledge_events!", PCSC_ReaderStates_acknowledge_events, 0);
313
- }
314
-
315
- /* Retrieves the SCARD_READERSTATE array wrapped into a Smartcard::PCSC::ReaderStates instance. */
316
- int _PCSC_ReaderStates_lowlevel_get(VALUE rbReaderStates, SCARD_READERSTATE **reader_states, size_t *reader_states_count) {
317
- struct PCSCReaderStates *states;
318
-
319
- if(!RTEST(rbReaderStates)) {
320
- *reader_states = NULL;
321
- *reader_states_count = 0;
322
- return 1;
323
- }
324
- if(TYPE(rbReaderStates) != T_DATA || RDATA(rbReaderStates)->dfree != (void (*)(void *))PCSC_ReaderStates_free)
325
- return 0;
326
-
327
- Data_Get_Struct(rbReaderStates, struct PCSCReaderStates, states);
328
- *reader_states = states->states;
329
- *reader_states_count = states->states_count;
330
- return 1;
331
- }