smartcard 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,14 @@
1
+ v0.2.0 Added automatic builds
2
+ Rakefile for auto builds using echoe
3
+ extconf.rb: hack to fix Windows makefiles
4
+
5
+ v0.1.2 Added Windows compatibility
6
+ *.c: restructured code so VC2005 likes it
7
+ (variable declarations before function body)
8
+ docs: license, readme, and what the gem is
9
+
10
+ v0.1.1 Added support for Ubuntu 7.10
11
+ ext/smartcard_pcsc/extconf.rb: better header
12
+ detection
13
+
14
+ v0.1.0 Initial release for OSX Leopard
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2007 Victor Costan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+
data/Manifest ADDED
@@ -0,0 +1,19 @@
1
+ CHANGELOG
2
+ ext/smartcard_pcsc/extconf.rb
3
+ ext/smartcard_pcsc/pcsc.h
4
+ ext/smartcard_pcsc/pcsc_card.c
5
+ ext/smartcard_pcsc/pcsc_constants.c
6
+ ext/smartcard_pcsc/pcsc_context.c
7
+ ext/smartcard_pcsc/pcsc_io_request.c
8
+ ext/smartcard_pcsc/pcsc_main.c
9
+ ext/smartcard_pcsc/pcsc_multi_strings.c
10
+ ext/smartcard_pcsc/pcsc_namespace.c
11
+ ext/smartcard_pcsc/pcsc_reader_states.c
12
+ ext/smartcard_pcsc/pcsc_surrogate_reader.h
13
+ ext/smartcard_pcsc/pcsc_surrogate_wintypes.h
14
+ lib/smartcard.rb
15
+ LICENSE
16
+ README
17
+ test/test_all.rb
18
+ tests/ts_pcsc_ext.rb
19
+ Manifest
data/README ADDED
@@ -0,0 +1,22 @@
1
+ SUMMARY
2
+
3
+ 'smartcard' aims to become the de-facto support library for smart-card development on ruby.
4
+ At the moment, 'smartcard' offers a PC/SC binding that is working on ruby 1.8, under
5
+ linux, osx, and windows. Future plans include a high level abstraction for the PC/SC binding
6
+ (and any other bindings people need), and an interface for Java cards.
7
+
8
+ LICENSE
9
+
10
+ 'smartcard' is released under the MIT license. This means you're free to do whatever you want
11
+ with it. For the legalese version, please see the 'LICENSE' file.
12
+
13
+ DOCUMENTATION
14
+
15
+ The API is fully documented with RDoc. If you installed the 'smartcard' gem, you should be
16
+ able to use ri to see the documentation. If you're using the SVN version, you can use rdoc to
17
+ build the HTML and RI documentation yourself.
18
+
19
+ ACKNOWLEDGEMENTS
20
+
21
+ 'smartcard' was developed for Victor Costan while working as a Research Assistant for MIT.
22
+ The work was sponsored by a grant from Quanta Computer Inc (www.quanta.com.tw)
@@ -1,5 +1,4 @@
1
1
  require 'mkmf'
2
- require 'pp'
3
2
 
4
3
  $CFLAGS ||= ''
5
4
  $LDFLAGS ||= ''
@@ -7,7 +6,7 @@ $LDFLAGS ||= ''
7
6
  if RUBY_PLATFORM =~ /darwin/
8
7
  $LDFLAGS += ' -framework PCSC'
9
8
  elsif RUBY_PLATFORM =~ /win/
10
- # TODO: no clue what to do here
9
+ have_library('winscard')
11
10
  else
12
11
  # pcsc is retarded and uses stuff like '#include <wintypes.h>'
13
12
  $CFLAGS += ' -I /usr/include/PCSC -I /usr/local/include/pcsc'
@@ -26,9 +25,29 @@ end
26
25
 
27
26
  pcsc_defines = []
28
27
 
29
- File.open('pcsc_include.h', 'w') do |f|
28
+ File.open('pcsc_autogen.h', 'w') do |f|
30
29
  pcsc_defines.each { |d| f.write "\#define #{d}\n" }
31
30
  pcsc_headers.each { |h| f.write "\#include #{h}\n" }
32
31
  end
33
32
 
34
- create_makefile('smartcard/pcsc')
33
+ create_makefile('smartcard/pcsc')
34
+
35
+ def win32_hack(mf_name)
36
+ # evil, evil, evil -- hack the makefile to embed the manifest in the extension dll
37
+ make_contents = File.open(mf_name, 'r') { |f| f.read }
38
+ make_rules = make_contents.split(/(\n|\r)(\n|\r)+/)
39
+ new_make_rules = make_rules.map do |rule|
40
+ if rule =~ /^\$\(DLLIB\)\:/
41
+ rule + "\n\tmt.exe -manifest $(@).manifest -outputresource:$(@);2"
42
+ else
43
+ rule
44
+ end
45
+ end
46
+ File.open(mf_name, 'w') { |f| f.write new_make_rules.join("\n\n")}
47
+ end
48
+
49
+ case RUBY_PLATFORM
50
+ when /darwin/
51
+ when /win/
52
+ win32_hack 'Makefile'
53
+ end
@@ -1,7 +1,7 @@
1
1
  /* Ruby extension API. */
2
2
  #include <ruby.h>
3
3
  /* Generated by 'extconf.rb' to point to the PC/SC header. */
4
- #include "pcsc_include.h"
4
+ #include "pcsc_autogen.h"
5
5
 
6
6
  /* Entrypoint into the Ruby extension. */
7
7
  void Init_pcsc();
@@ -36,3 +36,11 @@ void Init_PCSC_Consts();
36
36
  /* Multi-string (win32 abomination) tools. */
37
37
  VALUE PCSC_Internal_multistring_to_ruby_array(char *mstr, size_t mstr_len);
38
38
  int PCSC_Internal_ruby_strings_to_multistring(VALUE rbStrings, char **strings);
39
+
40
+ /* Messing up with constants that aren't uniformly defined. */
41
+ #if !defined(MAX_ATR_SIZE)
42
+ #define MAX_ATR_SIZE 32
43
+ #endif
44
+ #if !defined(SCARD_PROTOCOL_ANY)
45
+ #define SCARD_PROTOCOL_ANY (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
46
+ #endif
@@ -43,24 +43,26 @@ static VALUE PCSC_Card_alloc(VALUE klass) {
43
43
  */
44
44
  static VALUE PCSC_Card_initialize(VALUE self, VALUE rbContext, VALUE rbReaderName, VALUE rbShareMode, VALUE rbPreferredProtocols) {
45
45
  struct SCardHandleEx *card;
46
+ SCARDCONTEXT context;
47
+ VALUE rbFinalReaderName;
48
+ DWORD share_mode, preferred_protocols, active_protocol;
49
+
46
50
  Data_Get_Struct(self, struct SCardHandleEx, card);
47
51
 
48
- SCARDCONTEXT context;
49
52
  if(_PCSC_Context_lowlevel_get(rbContext, &context) == 0) {
50
53
  rb_raise(rb_eArgError, "first argument is not a Context instance");
51
54
  return self;
52
55
  }
53
56
 
54
- VALUE rbFinalReaderName = rb_check_string_type(rbReaderName);
57
+ rbFinalReaderName = rb_check_string_type(rbReaderName);
55
58
  if(NIL_P(rbFinalReaderName)) {
56
59
  rb_raise(rb_eArgError, "second argument (should be reader name) does not convert to a String");
57
60
  return self;
58
61
  }
59
62
 
60
- DWORD share_mode = NUM2UINT(rbShareMode);
61
- DWORD preferred_protocols = NUM2UINT(rbPreferredProtocols);
63
+ share_mode = NUM2UINT(rbShareMode);
64
+ preferred_protocols = NUM2UINT(rbPreferredProtocols);
62
65
 
63
- DWORD active_protocol;
64
66
  card->pcsc_error = SCardConnect(context, RSTRING(rbFinalReaderName)->ptr, share_mode, preferred_protocols, &card->card_handle, &active_protocol);
65
67
  if(card->pcsc_error != SCARD_S_SUCCESS)
66
68
  rb_raise(rb_eRuntimeError, "SCardConnect: %s", pcsc_stringify_error(card->pcsc_error));
@@ -82,14 +84,15 @@ static VALUE PCSC_Card_initialize(VALUE self, VALUE rbContext, VALUE rbReaderNam
82
84
  */
83
85
  static VALUE PCSC_Card_reconnect(VALUE self, VALUE rbShareMode, VALUE rbPreferredProtocols, VALUE rbInitialization) {
84
86
  struct SCardHandleEx *card;
87
+ DWORD share_mode, preferred_protocols, initialization, active_protocol;
88
+
85
89
  Data_Get_Struct(self, struct SCardHandleEx, card);
86
90
  if(card == NULL) return self;
87
91
 
88
- DWORD share_mode = NUM2UINT(rbShareMode);
89
- DWORD preferred_protocols = NUM2UINT(rbPreferredProtocols);
90
- DWORD initialization = NUM2UINT(rbInitialization);
92
+ share_mode = NUM2UINT(rbShareMode);
93
+ preferred_protocols = NUM2UINT(rbPreferredProtocols);
94
+ initialization = NUM2UINT(rbInitialization);
91
95
 
92
- uint32_t active_protocol;
93
96
  card->pcsc_error = SCardReconnect(card->card_handle, share_mode, preferred_protocols, initialization, &active_protocol);
94
97
  if(card->pcsc_error != SCARD_S_SUCCESS)
95
98
  rb_raise(rb_eRuntimeError, "SCardReconnect: %s", pcsc_stringify_error(card->pcsc_error));
@@ -107,11 +110,13 @@ static VALUE PCSC_Card_reconnect(VALUE self, VALUE rbShareMode, VALUE rbPreferre
107
110
  * +disposition+:: action to be taken on the card inside the reader; use one of the Smartcard::PCSC::DISPOSITION_ constants
108
111
  */
109
112
  static VALUE PCSC_Card_disconnect(VALUE self, VALUE rbDisposition) {
110
- struct SCardHandleEx *card;
113
+ struct SCardHandleEx *card;
114
+ DWORD disposition;
115
+
111
116
  Data_Get_Struct(self, struct SCardHandleEx, card);
112
117
  if(card == NULL) return self;
113
118
 
114
- DWORD disposition = NUM2UINT(rbDisposition);
119
+ disposition = NUM2UINT(rbDisposition);
115
120
  if(!card->released) {
116
121
  card->pcsc_error = SCardDisconnect(card->card_handle, disposition);
117
122
  card->released = 1;
@@ -129,7 +134,8 @@ static VALUE PCSC_Card_disconnect(VALUE self, VALUE rbDisposition) {
129
134
  * Wraps _SCardBeginTransaction_ in PC/SC.
130
135
  */
131
136
  static VALUE PCSC_Card_begin_transaction(VALUE self) {
132
- struct SCardHandleEx *card;
137
+ struct SCardHandleEx *card;
138
+
133
139
  Data_Get_Struct(self, struct SCardHandleEx, card);
134
140
  if(card == NULL) return self;
135
141
 
@@ -149,11 +155,13 @@ static VALUE PCSC_Card_begin_transaction(VALUE self) {
149
155
  * +disposition+:: action to be taken on the card inside the reader; use one of the Smartcard::PCSC::DISPOSITION_ constants
150
156
  */
151
157
  static VALUE PCSC_Card_end_transaction(VALUE self, VALUE rbDisposition) {
152
- struct SCardHandleEx *card;
158
+ struct SCardHandleEx *card;
159
+ DWORD disposition;
160
+
153
161
  Data_Get_Struct(self, struct SCardHandleEx, card);
154
162
  if(card == NULL) return self;
155
163
 
156
- DWORD disposition = NUM2UINT(rbDisposition);
164
+ disposition = NUM2UINT(rbDisposition);
157
165
  card->pcsc_error = SCardEndTransaction(card->card_handle, disposition);
158
166
  if(card->pcsc_error != SCARD_S_SUCCESS)
159
167
  rb_raise(rb_eRuntimeError, "SCardEndTransaction: %s", pcsc_stringify_error(card->pcsc_error));
@@ -174,19 +182,23 @@ static VALUE PCSC_Card_end_transaction(VALUE self, VALUE rbDisposition) {
174
182
  * +attribute_id+:: identifies the attribute to be read; use one of the Smartcard::PCSC::ATTR_ constants
175
183
  */
176
184
  static VALUE PCSC_Card_get_attribute(VALUE self, VALUE rbAttributeId) {
177
- struct SCardHandleEx *card;
185
+ struct SCardHandleEx *card;
186
+ char *attribute_buffer;
187
+ DWORD attribute_id, attribute_length;
188
+ VALUE rbAttribute;
189
+
178
190
  Data_Get_Struct(self, struct SCardHandleEx, card);
179
191
  if(card == NULL) return Qnil;
180
192
 
181
- DWORD attribute_id = NUM2UINT(rbAttributeId);
182
- DWORD attribute_length;
193
+ attribute_id = NUM2UINT(rbAttributeId);
194
+ attribute_length;
183
195
  card->pcsc_error = SCardGetAttrib(card->card_handle, attribute_id, NULL, &attribute_length);
184
196
  if(card->pcsc_error == SCARD_S_SUCCESS) {
185
- char *attribute_buffer = ALLOC_N(char, attribute_length);
197
+ attribute_buffer = ALLOC_N(char, attribute_length);
186
198
  if(attribute_buffer != NULL) {
187
199
  card->pcsc_error = SCardGetAttrib(card->card_handle, attribute_id, (LPSTR)attribute_buffer, &attribute_length);
188
200
  if(card->pcsc_error == SCARD_S_SUCCESS) {
189
- VALUE rbAttribute = rb_str_new(attribute_buffer, attribute_length);
201
+ rbAttribute = rb_str_new(attribute_buffer, attribute_length);
190
202
  xfree(attribute_buffer);
191
203
  return rbAttribute;
192
204
  }
@@ -210,13 +222,16 @@ static VALUE PCSC_Card_get_attribute(VALUE self, VALUE rbAttributeId) {
210
222
  * +attribute_value+:: the value to be assigned to the attribute; wrap the bytes in a string-like object (low-level API, remember?)
211
223
  */
212
224
  static VALUE PCSC_Card_set_attribute(VALUE self, VALUE rbAttributeId, VALUE rbAttributeValue) {
213
- struct SCardHandleEx *card;
225
+ struct SCardHandleEx *card;
226
+ DWORD attribute_id;
227
+ VALUE rbFinalAttributeValue;
228
+
214
229
  Data_Get_Struct(self, struct SCardHandleEx, card);
215
230
  if(card == NULL) return self;
216
231
 
217
- DWORD attribute_id = NUM2UINT(rbAttributeId);
232
+ attribute_id = NUM2UINT(rbAttributeId);
218
233
 
219
- VALUE rbFinalAttributeValue = rb_check_string_type(rbAttributeValue);
234
+ rbFinalAttributeValue = rb_check_string_type(rbAttributeValue);
220
235
  if(NIL_P(rbFinalAttributeValue)) {
221
236
  rb_raise(rb_eArgError, "second argument (attribute buffer) does not convert to a String");
222
237
  return self;
@@ -242,35 +257,38 @@ static VALUE PCSC_Card_set_attribute(VALUE self, VALUE rbAttributeId, VALUE rbAt
242
257
  * +recv_io_request+:: Smartcard::PCSC::IoRequest instance receving information about the recv protocol; you can use the result of Smartcard::PCSC::IoRequest#new
243
258
  */
244
259
  static VALUE PCSC_Card_transmit(VALUE self, VALUE rbSendData, VALUE rbSendIoRequest, VALUE rbRecvIoRequest) {
245
- struct SCardHandleEx *card;
260
+ struct SCardHandleEx *card;
261
+ VALUE rbFinalSendData, rbRecvData;
262
+ SCARD_IO_REQUEST *send_io_request, *recv_io_request;
263
+ char *recv_buffer;
264
+ DWORD recv_length;
265
+
246
266
  Data_Get_Struct(self, struct SCardHandleEx, card);
247
267
  if(card == NULL) return Qnil;
248
268
 
249
- VALUE rbFinalSendData = rb_check_string_type(rbSendData);
269
+ rbFinalSendData = rb_check_string_type(rbSendData);
250
270
  if(NIL_P(rbFinalSendData)) {
251
271
  rb_raise(rb_eArgError, "first argument (send buffer) does not convert to a String");
252
272
  return Qnil;
253
273
  }
254
274
 
255
- SCARD_IO_REQUEST *send_io_request;
256
275
  if(_PCSC_IoRequest_lowlevel_get(rbSendIoRequest, &send_io_request) == 0) {
257
276
  rb_raise(rb_eArgError, "second argument (send io request) is not an IoRequest instance");
258
277
  return Qnil;
259
278
  }
260
- SCARD_IO_REQUEST *recv_io_request;
261
279
  if(_PCSC_IoRequest_lowlevel_get(rbRecvIoRequest, &recv_io_request) == 0) {
262
280
  rb_raise(rb_eArgError, "second argument (recv io request) is not an IoRequest instance");
263
281
  return Qnil;
264
282
  }
265
283
 
266
284
  #if defined(PCSCLITE_MAX_MESSAGE_SIZE)
267
- DWORD recv_length = PCSCLITE_MAX_MESSAGE_SIZE;
285
+ recv_length = PCSCLITE_MAX_MESSAGE_SIZE;
268
286
  #elif defined(MAX_BUFFER_SIZE_EXTENDED)
269
- DWORD recv_length = MAX_BUFFER_SIZE_EXTENDED;
287
+ recv_length = MAX_BUFFER_SIZE_EXTENDED;
270
288
  #else
271
- DWORD recv_length = 65536;
289
+ recv_length = 65536;
272
290
  #endif
273
- char *recv_buffer = ALLOC_N(char, recv_length);
291
+ recv_buffer = ALLOC_N(char, recv_length);
274
292
  if(recv_buffer == NULL) return Qnil;
275
293
 
276
294
  card->pcsc_error = SCardTransmit(card->card_handle, send_io_request,
@@ -282,7 +300,7 @@ static VALUE PCSC_Card_transmit(VALUE self, VALUE rbSendData, VALUE rbSendIoRequ
282
300
  return Qnil;
283
301
  }
284
302
 
285
- VALUE rbRecvData = rb_str_new(recv_buffer, recv_length);
303
+ rbRecvData = rb_str_new(recv_buffer, recv_length);
286
304
  xfree(recv_buffer);
287
305
  return rbRecvData;
288
306
  }
@@ -308,18 +326,22 @@ static VALUE PCSC_Card_transmit(VALUE self, VALUE rbSendData, VALUE rbSendIoRequ
308
326
  */
309
327
  static VALUE PCSC_Card_control(VALUE self, VALUE rbControlCode, VALUE rbSendData, VALUE rbMaxRecvBytes) {
310
328
  struct SCardHandleEx *card;
329
+ VALUE rbFinalSendData, rbRecvData;
330
+ char *recv_buffer;
331
+ DWORD control_code, recv_length;
332
+
311
333
  Data_Get_Struct(self, struct SCardHandleEx, card);
312
334
  if(card == NULL) return Qnil;
313
335
 
314
- VALUE rbFinalSendData = rb_check_string_type(rbSendData);
336
+ rbFinalSendData = rb_check_string_type(rbSendData);
315
337
  if(NIL_P(rbFinalSendData)) {
316
338
  rb_raise(rb_eArgError, "second argument (send buffer) does not convert to a String");
317
339
  return Qnil;
318
340
  }
319
341
 
320
- DWORD control_code = NUM2UINT(rbControlCode);
321
- DWORD recv_length = NUM2UINT(rbMaxRecvBytes);
322
- char *recv_buffer = ALLOC_N(char, recv_length);
342
+ control_code = NUM2UINT(rbControlCode);
343
+ recv_length = NUM2UINT(rbMaxRecvBytes);
344
+ recv_buffer = ALLOC_N(char, recv_length);
323
345
  if(recv_buffer == NULL) return Qnil;
324
346
 
325
347
  card->pcsc_error = SCardControl(card->card_handle, control_code,
@@ -331,7 +353,7 @@ static VALUE PCSC_Card_control(VALUE self, VALUE rbControlCode, VALUE rbSendData
331
353
  return Qnil;
332
354
  }
333
355
 
334
- VALUE rbRecvData = rb_str_new(recv_buffer, recv_length);
356
+ rbRecvData = rb_str_new(recv_buffer, recv_length);
335
357
  xfree(recv_buffer);
336
358
  return rbRecvData;
337
359
  }
@@ -352,21 +374,24 @@ static VALUE _rbStateKey, _rbProtocolKey, _rbAtrKey, _rbReaderNamesKey;
352
374
  * <tt>:reader_names</tt> :: array of strings containing all the names of the reader containing the smartcard
353
375
  */
354
376
  static VALUE PCSC_Card_status(VALUE self) {
355
- struct SCardHandleEx *card;
377
+ struct SCardHandleEx *card;
378
+ char *atr_buffer, *reader_names_buffer;
379
+ DWORD atr_length, reader_names_length, state, protocol;
380
+ VALUE rbStateVal, rbProtocolVal, rbAtrVal, rbReaderNamesVal, rbReturnHash;
381
+
356
382
  Data_Get_Struct(self, struct SCardHandleEx, card);
357
383
  if(card == NULL) return Qnil;
358
384
 
359
- DWORD atr_length = MAX_ATR_SIZE;
360
- char *atr_buffer = ALLOC_N(char, atr_length);
361
- DWORD reader_names_length = 4096;
362
- char *reader_names_buffer = ALLOC_N(char, reader_names_length);
385
+ atr_length = MAX_ATR_SIZE;
386
+ atr_buffer = ALLOC_N(char, atr_length);
387
+ reader_names_length = 4096;
388
+ reader_names_buffer = ALLOC_N(char, reader_names_length);
363
389
  if(atr_buffer == NULL || reader_names_buffer == NULL) {
364
390
  if(reader_names_buffer != NULL) xfree(reader_names_buffer);
365
391
  if(atr_buffer != NULL) xfree(atr_buffer);
366
392
  return Qnil;
367
393
  }
368
394
 
369
- DWORD state, protocol;
370
395
  card->pcsc_error = SCardStatus(card->card_handle, reader_names_buffer, &reader_names_length, &state, &protocol, (LPSTR)atr_buffer, &atr_length);
371
396
  if(card->pcsc_error != SCARD_S_SUCCESS) {
372
397
  xfree(reader_names_buffer); xfree(atr_buffer);
@@ -374,12 +399,12 @@ static VALUE PCSC_Card_status(VALUE self) {
374
399
  return Qnil;
375
400
  }
376
401
 
377
- VALUE rbStateVal = UINT2NUM(state);
378
- VALUE rbProtocolVal = UINT2NUM(protocol);
379
- VALUE rbAtrVal = rb_str_new(atr_buffer, atr_length);
380
- VALUE rbReaderNamesVal = PCSC_Internal_multistring_to_ruby_array(reader_names_buffer, reader_names_length);
402
+ rbStateVal = UINT2NUM(state);
403
+ rbProtocolVal = UINT2NUM(protocol);
404
+ rbAtrVal = rb_str_new(atr_buffer, atr_length);
405
+ rbReaderNamesVal = PCSC_Internal_multistring_to_ruby_array(reader_names_buffer, reader_names_length);
381
406
 
382
- VALUE rbReturnHash = rb_hash_new();
407
+ rbReturnHash = rb_hash_new();
383
408
  rb_hash_aset(rbReturnHash, _rbStateKey, rbStateVal);
384
409
  rb_hash_aset(rbReturnHash, _rbProtocolKey, rbProtocolVal);
385
410
  rb_hash_aset(rbReturnHash, _rbAtrKey, rbAtrVal);
@@ -398,6 +423,7 @@ static VALUE PCSC_Card_status(VALUE self) {
398
423
  */
399
424
  static VALUE PCSC_Card_last_error(VALUE self) {
400
425
  struct SCardHandleEx *card;
426
+
401
427
  Data_Get_Struct(self, struct SCardHandleEx, card);
402
428
  if(card == NULL) return Qnil;
403
429
 
@@ -414,16 +440,18 @@ static VALUE PCSC_Card_last_error(VALUE self) {
414
440
  * Wraps a _SCARDHANDLE_ structure.
415
441
  */
416
442
  void Init_PCSC_Card() {
417
- ID state_id = rb_intern("status"); _rbStateKey = ID2SYM(state_id);
418
- ID protocol_id = rb_intern("protocol"); _rbProtocolKey = ID2SYM(protocol_id);
419
- ID atr_id = rb_intern("atr"); _rbAtrKey = ID2SYM(atr_id);
420
- ID reader_names_id = rb_intern("reader_names"); _rbReaderNamesKey = ID2SYM(reader_names_id);
443
+ ID state_id, protocol_id, atr_id, reader_names_id;
444
+
445
+ state_id = rb_intern("status"); _rbStateKey = ID2SYM(state_id);
446
+ protocol_id = rb_intern("protocol"); _rbProtocolKey = ID2SYM(protocol_id);
447
+ atr_id = rb_intern("atr"); _rbAtrKey = ID2SYM(atr_id);
448
+ reader_names_id = rb_intern("reader_names"); _rbReaderNamesKey = ID2SYM(reader_names_id);
421
449
 
422
450
  cPcscCard = rb_define_class_under(mPcsc, "Card", rb_cObject);
423
451
  rb_define_alloc_func(cPcscCard, PCSC_Card_alloc);
424
452
  rb_define_method(cPcscCard, "initialize", PCSC_Card_initialize, 4);
425
- rb_define_method(cPcscCard, "reconnect", PCSC_Card_reconnect, 3);
426
453
  rb_define_method(cPcscCard, "disconnect", PCSC_Card_disconnect, 1);
454
+ rb_define_method(cPcscCard, "reconnect", PCSC_Card_reconnect, 3);
427
455
  rb_define_method(cPcscCard, "begin_transaction", PCSC_Card_begin_transaction, 0);
428
456
  rb_define_method(cPcscCard, "end_transaction", PCSC_Card_end_transaction, 1);
429
457
  rb_define_method(cPcscCard, "get_attribute", PCSC_Card_get_attribute, 1);
@@ -436,10 +464,11 @@ void Init_PCSC_Card() {
436
464
 
437
465
  /* Retrieves the SCARDHANDLE wrapped into a Smartcard::PCSC::Card instance. */
438
466
  int _PCSC_Card_lowlevel_get(VALUE rbCard, SCARDHANDLE *card_handle) {
467
+ struct SCardHandleEx *card;
468
+
439
469
  if(TYPE(rbCard) != T_DATA || RDATA(rbCard)->dfree != (void (*)(void *))PCSC_Card_free)
440
470
  return 0;
441
471
 
442
- struct SCardHandleEx *card;
443
472
  Data_Get_Struct(rbCard, struct SCardHandleEx, card);
444
473
  *card_handle = card->card_handle;
445
474
  return 1;
@@ -133,16 +133,20 @@ void Init_PCSC_Consts() {
133
133
  /* SCARD_SPECIFIC : PTS has been set. */
134
134
  rb_define_const(mPcsc, "STATUS_SPECIFIC", INT2NUM(SCARD_SPECIFIC));
135
135
 
136
+ #if defined(SCARD_PROTOCOL_UNSET)
136
137
  /* SCARD_PROTOCOL_UNSET : Protocol not set. */
137
138
  rb_define_const(mPcsc, "PROTOCOL_UNSET", INT2NUM(SCARD_PROTOCOL_UNSET));
139
+ #endif /* SCARD_PROTOCOL_UNSET */
138
140
  /* SCARD_PROTOCOL_T0 : T=0 active protocol. */
139
141
  rb_define_const(mPcsc, "PROTOCOL_T0", INT2NUM(SCARD_PROTOCOL_T0));
140
142
  /* SCARD_PROTOCOL_T1 : T=1 active protocol. */
141
143
  rb_define_const(mPcsc, "PROTOCOL_T1", INT2NUM(SCARD_PROTOCOL_T1));
142
144
  /* SCARD_PROTOCOL_RAW : Raw active protocol. */
143
145
  rb_define_const(mPcsc, "PROTOCOL_RAW", INT2NUM(SCARD_PROTOCOL_RAW));
146
+ #if defined(SCARD_PROTOCOL_UNSET)
144
147
  /* SCARD_PROTOCOL_T15 : T=15 protocol. */
145
148
  rb_define_const(mPcsc, "PROTOCOL_T15", INT2NUM(SCARD_PROTOCOL_T15));
149
+ #endif /* SCARD_PROTOCOL_UNSET */
146
150
  /* SCARD_PROTOCOL_ANY : IFD determines protocol. */
147
151
  rb_define_const(mPcsc, "PROTOCOL_ANY", INT2NUM(SCARD_PROTOCOL_ANY));
148
152
 
@@ -40,6 +40,7 @@ static VALUE PCSC_Context_alloc(VALUE klass) {
40
40
  */
41
41
  static VALUE PCSC_Context_initialize(VALUE self, VALUE scope) {
42
42
  struct SCardContextEx *context;
43
+
43
44
  Data_Get_Struct(self, struct SCardContextEx, context);
44
45
 
45
46
  context->pcsc_error = SCardEstablishContext(NUM2INT(scope), NULL, NULL, &context->pcsc_context);
@@ -60,6 +61,7 @@ static VALUE PCSC_Context_initialize(VALUE self, VALUE scope) {
60
61
  */
61
62
  static VALUE PCSC_Context_release(VALUE self) {
62
63
  struct SCardContextEx *context;
64
+
63
65
  Data_Get_Struct(self, struct SCardContextEx, context);
64
66
  if(context == NULL) return self;
65
67
 
@@ -87,8 +89,8 @@ static VALUE PCSC_Context_is_valid(VALUE self) {
87
89
  Data_Get_Struct(self, struct SCardContextEx, context);
88
90
  if(context == NULL) return self;
89
91
 
90
- DWORD pcsc_error = SCardIsValidContext(context->pcsc_context);
91
- return (pcsc_error == SCARD_S_SUCCESS) ? Qtrue : Qfalse;
92
+ context->pcsc_error = SCardIsValidContext(context->pcsc_context);
93
+ return (context->pcsc_error == SCARD_S_SUCCESS) ? Qtrue : Qfalse;
92
94
  }
93
95
 
94
96
  /* :Document-method: list_reader_groups
@@ -101,18 +103,21 @@ static VALUE PCSC_Context_is_valid(VALUE self) {
101
103
  * Returns an array of strings containing the names of all the smart-card readers in the system.
102
104
  */
103
105
  static VALUE PCSC_Context_list_reader_groups(VALUE self) {
104
- struct SCardContextEx *context;
106
+ struct SCardContextEx *context;
107
+ VALUE rbGroups;
108
+ char *groups;
109
+ DWORD groups_length;
110
+
105
111
  Data_Get_Struct(self, struct SCardContextEx, context);
106
112
  if(context == NULL) return Qnil;
107
113
 
108
- DWORD groups_length;
109
114
  context->pcsc_error = SCardListReaderGroups(context->pcsc_context, NULL, &groups_length);
110
115
  if(context->pcsc_error == SCARD_S_SUCCESS) {
111
- char *groups = ALLOC_N(char, groups_length);
116
+ groups = ALLOC_N(char, groups_length);
112
117
  if(groups != NULL) {
113
118
  context->pcsc_error = SCardListReaderGroups(context->pcsc_context, groups, &groups_length);
114
119
  if(context->pcsc_error == SCARD_S_SUCCESS) {
115
- VALUE rbGroups = PCSC_Internal_multistring_to_ruby_array(groups, groups_length);
120
+ rbGroups = PCSC_Internal_multistring_to_ruby_array(groups, groups_length);
116
121
  xfree(groups);
117
122
  return rbGroups;
118
123
  }
@@ -137,24 +142,26 @@ static VALUE PCSC_Context_list_reader_groups(VALUE self) {
137
142
  * +reader_groups+:: array of strings indicating the reader groups to list; also accepts a string or +nil+ (meaning all readers)
138
143
  */
139
144
  static VALUE PCSC_Context_list_readers(VALUE self, VALUE rbGroups) {
140
- struct SCardContextEx *context;
145
+ struct SCardContextEx *context;
146
+ VALUE rbReaders;
147
+ char *groups;
148
+ DWORD readers_length;
149
+
141
150
  Data_Get_Struct(self, struct SCardContextEx, context);
142
151
  if(context == NULL) return Qnil;
143
152
 
144
- char *groups;
145
153
  if(PCSC_Internal_ruby_strings_to_multistring(rbGroups, &groups) == 0) {
146
154
  rb_raise(rb_eArgError, "invalid reader groups set (expecting nil or string or array of strings)");
147
155
  return Qnil;
148
156
  }
149
157
 
150
- DWORD readers_length;
151
158
  context->pcsc_error = SCardListReaders(context->pcsc_context, groups, NULL, &readers_length);
152
159
  if(context->pcsc_error == SCARD_S_SUCCESS) {
153
160
  char *readers = ALLOC_N(char, readers_length);
154
161
  if(readers != NULL) {
155
162
  context->pcsc_error = SCardListReaders(context->pcsc_context, groups, readers, &readers_length);
156
163
  if(context->pcsc_error == SCARD_S_SUCCESS) {
157
- VALUE rbReaders = PCSC_Internal_multistring_to_ruby_array(readers, readers_length);
164
+ rbReaders = PCSC_Internal_multistring_to_ruby_array(readers, readers_length);
158
165
  xfree(readers);
159
166
  if(groups != NULL) xfree(groups);
160
167
  return rbReaders;
@@ -177,7 +184,8 @@ static VALUE PCSC_Context_list_readers(VALUE self, VALUE rbGroups) {
177
184
  * Wraps _SCardCancel_ in PC/SC.
178
185
  */
179
186
  static VALUE PCSC_Context_cancel(VALUE self) {
180
- struct SCardContextEx *context;
187
+ struct SCardContextEx *context;
188
+
181
189
  Data_Get_Struct(self, struct SCardContextEx, context);
182
190
  if(context == NULL) return self;
183
191
 
@@ -202,18 +210,19 @@ static VALUE PCSC_Context_cancel(VALUE self) {
202
210
  * ReaderStates#set_event_state_of and ReaderStates#event_state_of)
203
211
  */
204
212
  static VALUE PCSC_Context_get_status_change(VALUE self, VALUE rbReaderStates, VALUE rbTimeout) {
205
- struct SCardContextEx *context;
213
+ struct SCardContextEx *context;
214
+ SCARD_READERSTATE *reader_states;
215
+ size_t reader_states_count;
216
+ DWORD timeout;
217
+
206
218
  Data_Get_Struct(self, struct SCardContextEx, context);
207
219
  if(context == NULL) return self;
208
220
 
209
- unsigned int timeout;
210
221
  if(TYPE(rbTimeout) == T_NIL || TYPE(rbTimeout) == T_FALSE)
211
222
  timeout = INFINITE;
212
223
  else
213
224
  timeout = NUM2INT(rbTimeout);
214
225
 
215
- SCARD_READERSTATE *reader_states;
216
- size_t reader_states_count;
217
226
  if(_PCSC_ReaderStates_lowlevel_get(rbReaderStates, &reader_states, &reader_states_count) == 0)
218
227
  rb_raise(rb_eArgError, "first parameter is not a ReaderStates instance or nil");
219
228
  else {
@@ -235,6 +244,7 @@ static VALUE PCSC_Context_get_status_change(VALUE self, VALUE rbReaderStates, VA
235
244
  */
236
245
  static VALUE PCSC_Context_last_error(VALUE self) {
237
246
  struct SCardContextEx *context;
247
+
238
248
  Data_Get_Struct(self, struct SCardContextEx, context);
239
249
  if(context == NULL) return Qnil;
240
250
 
@@ -265,10 +275,11 @@ void Init_PCSC_Context() {
265
275
 
266
276
  /* Retrieves the SCARDCONTEXT wrapped into a Smartcard::PCSC::Context instance. */
267
277
  int _PCSC_Context_lowlevel_get(VALUE rbContext, SCARDCONTEXT *pcsc_context) {
278
+ struct SCardContextEx *context;
279
+
268
280
  if(TYPE(rbContext) != T_DATA || RDATA(rbContext)->dfree != (void (*)(void *))PCSC_Context_free)
269
281
  return 0;
270
282
 
271
- struct SCardContextEx *context;
272
283
  Data_Get_Struct(rbContext, struct SCardContextEx, context);
273
284
  *pcsc_context = context->pcsc_context;
274
285
  return 1;
@@ -26,6 +26,7 @@ static VALUE PCSC_IoRequest_alloc(VALUE klass) {
26
26
  */
27
27
  static VALUE PCSC_IoRequest_get_protocol(VALUE self) {
28
28
  SCARD_IO_REQUEST *request;
29
+
29
30
  Data_Get_Struct(self, SCARD_IO_REQUEST, request);
30
31
  if(request == NULL) return Qnil;
31
32
 
@@ -42,6 +43,7 @@ static VALUE PCSC_IoRequest_get_protocol(VALUE self) {
42
43
  */
43
44
  static VALUE PCSC_IoRequest_set_protocol(VALUE self, VALUE rbProtocol) {
44
45
  SCARD_IO_REQUEST *request;
46
+
45
47
  Data_Get_Struct(self, SCARD_IO_REQUEST, request);
46
48
  if(request == NULL) return self;
47
49
 
@@ -70,6 +72,8 @@ void Init_PCSC_IoRequest() {
70
72
 
71
73
  /* Retrieves the SCARD_IO_REQUEST wrapped into a Smartcard::PCSC::IoRequest instance. */
72
74
  int _PCSC_IoRequest_lowlevel_get(VALUE rbIoRequest, SCARD_IO_REQUEST **io_request) {
75
+ SCARD_IO_REQUEST *request;
76
+
73
77
  if(TYPE(rbIoRequest) == T_NIL || TYPE(rbIoRequest) == T_FALSE) {
74
78
  *io_request = NULL;
75
79
  return 1;
@@ -77,7 +81,6 @@ int _PCSC_IoRequest_lowlevel_get(VALUE rbIoRequest, SCARD_IO_REQUEST **io_reques
77
81
  if(TYPE(rbIoRequest) != T_DATA || RDATA(rbIoRequest)->dfree != (void (*)(void *))PCSC_IoRequest_free)
78
82
  return 0;
79
83
 
80
- SCARD_IO_REQUEST *request;
81
84
  Data_Get_Struct(rbIoRequest, SCARD_IO_REQUEST, request);
82
85
  *io_request = request;
83
86
  return 1;
@@ -3,14 +3,16 @@
3
3
 
4
4
  /* Converts a multi-string "str1\0str_2\0str3\0\0" into a Ruby array of Ruby strings. */
5
5
  VALUE PCSC_Internal_multistring_to_ruby_array(char *mstr, size_t mstr_len) {
6
- VALUE rbArray = rb_ary_new();
7
- int i = 0;
8
- for(; i < mstr_len; i++) {
6
+ VALUE rbArray, rbString;
7
+ size_t i, start_offset;
8
+
9
+ rbArray = rb_ary_new();
10
+ for(i = 0; i < mstr_len; i++) {
9
11
  if(mstr[i] == '\0') break;
10
- int start_offset = i;
12
+ start_offset = i;
11
13
  for(; i < mstr_len; i++)
12
14
  if(mstr[i] == '\0') break;
13
- VALUE rbString = rb_str_new(mstr + start_offset, i - start_offset);
15
+ rbString = rb_str_new(mstr + start_offset, i - start_offset);
14
16
  rb_ary_push(rbArray, rbString);
15
17
  }
16
18
  return rbArray;
@@ -21,6 +23,10 @@ VALUE PCSC_Internal_multistring_to_ruby_array(char *mstr, size_t mstr_len) {
21
23
  * If false is returned, something went wrong and the method did not return a buffer.
22
24
  */
23
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
+
24
30
  /* nil -> NULL */
25
31
  if(TYPE(rbStrings) == T_NIL || TYPE(rbStrings) == T_FALSE) {
26
32
  *strings = NULL;
@@ -28,8 +34,8 @@ int PCSC_Internal_ruby_strings_to_multistring(VALUE rbStrings, char **strings) {
28
34
  }
29
35
  /* string -> [string] */
30
36
  if(TYPE(rbStrings) == T_STRING) {
31
- size_t string_length = RSTRING(rbStrings)->len;
32
- char *buffer = ALLOC_N(char, string_length + 2);
37
+ string_length = RSTRING(rbStrings)->len;
38
+ buffer = ALLOC_N(char, string_length + 2);
33
39
  memcpy(buffer, RSTRING(rbStrings)->ptr, string_length);
34
40
  buffer[string_length] = buffer[string_length + 1] = '\0';
35
41
  *strings = buffer;
@@ -38,20 +44,19 @@ int PCSC_Internal_ruby_strings_to_multistring(VALUE rbStrings, char **strings) {
38
44
  /* array -> array */
39
45
  if(TYPE(rbStrings) == T_ARRAY) {
40
46
  /* compute buffer length */
41
- size_t array_length = RARRAY(rbStrings)->len;
42
- VALUE *array_elements = RARRAY(rbStrings)->ptr;
43
- size_t buffer_length = 1; /* for the trailing '\0' */
44
- int i = 0;
45
- for(; i < array_length; i++) {
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++) {
46
51
  if(TYPE(array_elements[i]) != T_STRING)
47
52
  return 0;
48
53
  buffer_length += RSTRING(array_elements[i])->len + 1;
49
54
  }
50
55
 
51
56
  /* concatenate strings into buffer */
52
- char *buffer = ALLOC_N(char, buffer_length);
57
+ buffer = ALLOC_N(char, buffer_length);
53
58
  for(buffer_length = 0, i = 0; i < array_length; i++) {
54
- size_t string_length = RSTRING(array_elements[i])->len;
59
+ string_length = RSTRING(array_elements[i])->len;
55
60
  memcpy(buffer + buffer_length, RSTRING(array_elements[i])->ptr, string_length);
56
61
  buffer[buffer_length] = '\0';
57
62
  buffer_length += string_length + 1;
@@ -63,3 +68,15 @@ int PCSC_Internal_ruby_strings_to_multistring(VALUE rbStrings, char **strings) {
63
68
 
64
69
  return 0;
65
70
  }
71
+
72
+ #if defined(WIN32)
73
+ char scard_error_buffer[128];
74
+
75
+ /* Produces a string for an error code yielded by the SCard* PC/SC functions. Returns a static global buffer. */
76
+ char *pcsc_stringify_error(DWORD scard_error) {
77
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
78
+ NULL, scard_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
79
+ scard_error_buffer, sizeof(scard_error_buffer), NULL );
80
+ return scard_error_buffer;
81
+ }
82
+ #endif
@@ -10,10 +10,10 @@ struct PCSCReaderStates {
10
10
 
11
11
  /* Custom free for Smartcard::PCSC::ReaderStates. Also releases the referenced buffers (for the reader names). */
12
12
  static void PCSC_ReaderStates_free(struct PCSCReaderStates *_states) {
13
+ size_t i;
13
14
  if(_states != NULL) {
14
15
  if(_states->states != NULL) {
15
- size_t i = 0;
16
- for(; i < _states->states_count; i++) {
16
+ for(i = 0; i < _states->states_count; i++) {
17
17
  if(_states->states[i].szReader != NULL)
18
18
  xfree((char *)_states->states[i].szReader);
19
19
  }
@@ -42,15 +42,16 @@ static VALUE PCSC_ReaderStates_alloc(VALUE klass) {
42
42
  */
43
43
  static VALUE PCSC_ReaderStates_initialize(VALUE self, VALUE rbNumStates) {
44
44
  struct PCSCReaderStates *states;
45
+ size_t states_count, i;
46
+
45
47
  Data_Get_Struct(self, struct PCSCReaderStates, states);
46
48
 
47
- size_t states_count = NUM2UINT(rbNumStates);
49
+ states_count = NUM2UINT(rbNumStates);
48
50
  if(states_count > 0) {
49
51
  states->states = ALLOC_N(SCARD_READERSTATE, states_count);
50
52
  if(states->states != NULL) {
51
53
  states->states_count = states_count;
52
- size_t i = 0;
53
- for(; i < states_count; i++) {
54
+ for(i = 0; i < states_count; i++) {
54
55
  states->states[i].szReader = NULL;
55
56
  states->states[i].dwCurrentState = SCARD_STATE_UNAWARE;
56
57
  }
@@ -86,6 +87,7 @@ static int _validate_readerstates_args(VALUE rbReaderStates, VALUE rbIndex, stru
86
87
  static VALUE PCSC_ReaderStates_current_state_of(VALUE self, VALUE rbIndex) {
87
88
  struct PCSCReaderStates *states;
88
89
  size_t index;
90
+
89
91
  if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
90
92
  return Qnil;
91
93
 
@@ -106,6 +108,7 @@ static VALUE PCSC_ReaderStates_current_state_of(VALUE self, VALUE rbIndex) {
106
108
  static VALUE PCSC_ReaderStates_event_state_of(VALUE self, VALUE rbIndex) {
107
109
  struct PCSCReaderStates *states;
108
110
  size_t index;
111
+
109
112
  if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
110
113
  return Qnil;
111
114
 
@@ -126,6 +129,7 @@ static VALUE PCSC_ReaderStates_event_state_of(VALUE self, VALUE rbIndex) {
126
129
  static VALUE PCSC_ReaderStates_set_current_state_of(VALUE self, VALUE rbIndex, VALUE rbCurrentState) {
127
130
  struct PCSCReaderStates *states;
128
131
  size_t index;
132
+
129
133
  if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
130
134
  return self;
131
135
 
@@ -146,6 +150,7 @@ static VALUE PCSC_ReaderStates_set_current_state_of(VALUE self, VALUE rbIndex, V
146
150
  static VALUE PCSC_ReaderStates_set_event_state_of(VALUE self, VALUE rbIndex, VALUE rbEventState) {
147
151
  struct PCSCReaderStates *states;
148
152
  size_t index;
153
+
149
154
  if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
150
155
  return self;
151
156
 
@@ -167,6 +172,7 @@ static VALUE PCSC_ReaderStates_set_event_state_of(VALUE self, VALUE rbIndex, VAL
167
172
  static VALUE PCSC_ReaderStates_atr_of(VALUE self, VALUE rbIndex) {
168
173
  struct PCSCReaderStates *states;
169
174
  size_t index;
175
+
170
176
  if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
171
177
  return Qnil;
172
178
 
@@ -186,10 +192,12 @@ static VALUE PCSC_ReaderStates_atr_of(VALUE self, VALUE rbIndex) {
186
192
  static VALUE PCSC_ReaderStates_set_atr_of(VALUE self, VALUE rbIndex, VALUE rbAtr) {
187
193
  struct PCSCReaderStates *states;
188
194
  size_t index;
195
+ VALUE rbFinalAtr;
196
+
189
197
  if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
190
198
  return self;
191
199
 
192
- VALUE rbFinalAtr = rb_check_string_type(rbAtr);
200
+ rbFinalAtr = rb_check_string_type(rbAtr);
193
201
  if(NIL_P(rbFinalAtr))
194
202
  return self;
195
203
 
@@ -215,6 +223,7 @@ static VALUE PCSC_ReaderStates_set_atr_of(VALUE self, VALUE rbIndex, VALUE rbAtr
215
223
  static VALUE PCSC_ReaderStates_reader_name_of(VALUE self, VALUE rbIndex) {
216
224
  struct PCSCReaderStates *states;
217
225
  size_t index;
226
+
218
227
  if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
219
228
  return Qnil;
220
229
 
@@ -233,15 +242,17 @@ static VALUE PCSC_ReaderStates_reader_name_of(VALUE self, VALUE rbIndex) {
233
242
  */
234
243
  static VALUE PCSC_ReaderStates_set_reader_name_of(VALUE self, VALUE rbIndex, VALUE rbReaderName) {
235
244
  struct PCSCReaderStates *states;
236
- size_t index;
245
+ size_t index, reader_name_length;
246
+ VALUE rbFinalReaderName;
247
+
237
248
  if(_validate_readerstates_args(self, rbIndex, &states, &index) == 0)
238
249
  return self;
239
250
 
240
- VALUE rbFinalReaderName = rb_check_string_type(rbReaderName);
251
+ rbFinalReaderName = rb_check_string_type(rbReaderName);
241
252
  if(NIL_P(rbFinalReaderName))
242
253
  return self;
243
254
 
244
- size_t reader_name_length = RSTRING(rbFinalReaderName)->len;
255
+ reader_name_length = RSTRING(rbFinalReaderName)->len;
245
256
  if(states->states[index].szReader != NULL)
246
257
  xfree((char *)states->states[index].szReader);
247
258
  states->states[index].szReader = ALLOC_N(char, reader_name_length + 1);
@@ -261,11 +272,12 @@ static VALUE PCSC_ReaderStates_set_reader_name_of(VALUE self, VALUE rbIndex, VAL
261
272
  * (and thus prepare for a new call).
262
273
  */
263
274
  static VALUE PCSC_ReaderStates_acknowledge_events(VALUE self) {
264
- struct PCSCReaderStates *states;
275
+ struct PCSCReaderStates *states;
276
+ size_t i;
277
+
265
278
  Data_Get_Struct(self, struct PCSCReaderStates, states);
266
279
  if(states != NULL) {
267
- size_t i = 0;
268
- for(; i < states->states_count; i++)
280
+ for(i = 0; i < states->states_count; i++)
269
281
  states->states[i].dwCurrentState = states->states[i].dwEventState;
270
282
  }
271
283
  return self;
@@ -297,6 +309,8 @@ void Init_PCSC_ReaderStates() {
297
309
 
298
310
  /* Retrieves the SCARD_READERSTATE array wrapped into a Smartcard::PCSC::ReaderStates instance. */
299
311
  int _PCSC_ReaderStates_lowlevel_get(VALUE rbReaderStates, SCARD_READERSTATE **reader_states, size_t *reader_states_count) {
312
+ struct PCSCReaderStates *states;
313
+
300
314
  if(TYPE(rbReaderStates) == T_NIL || TYPE(rbReaderStates) == T_FALSE) {
301
315
  *reader_states = NULL;
302
316
  *reader_states_count = 0;
@@ -305,7 +319,6 @@ int _PCSC_ReaderStates_lowlevel_get(VALUE rbReaderStates, SCARD_READERSTATE **re
305
319
  if(TYPE(rbReaderStates) != T_DATA || RDATA(rbReaderStates)->dfree != (void (*)(void *))PCSC_ReaderStates_free)
306
320
  return 0;
307
321
 
308
- struct PCSCReaderStates *states;
309
322
  Data_Get_Struct(rbReaderStates, struct PCSCReaderStates, states);
310
323
  *reader_states = states->states;
311
324
  *reader_states_count = states->states_count;
data/smartcard.gemspec ADDED
@@ -0,0 +1,53 @@
1
+
2
+ # Gem::Specification for Smartcard-0.2.0
3
+ # Originally generated by Echoe
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{smartcard}
7
+ s.version = "0.2.0"
8
+ s.date = %q{2007-11-18}
9
+ s.summary = %q{Interface with ISO 7816 smart cards.}
10
+ s.require_paths = ["lib", "ext"]
11
+ s.email = %q{victor@costan.us}
12
+ s.homepage = %q{http://www.costan.us/smartcard}
13
+ s.rubyforge_project = %q{smartcard}
14
+ s.description = %q{Interface with ISO 7816 smart cards.}
15
+ s.has_rdoc = true
16
+ s.authors = ["Victor Costan"]
17
+ s.files = ["CHANGELOG", "ext/smartcard_pcsc/extconf.rb", "ext/smartcard_pcsc/pcsc.h", "ext/smartcard_pcsc/pcsc_card.c", "ext/smartcard_pcsc/pcsc_constants.c", "ext/smartcard_pcsc/pcsc_context.c", "ext/smartcard_pcsc/pcsc_io_request.c", "ext/smartcard_pcsc/pcsc_main.c", "ext/smartcard_pcsc/pcsc_multi_strings.c", "ext/smartcard_pcsc/pcsc_namespace.c", "ext/smartcard_pcsc/pcsc_reader_states.c", "ext/smartcard_pcsc/pcsc_surrogate_reader.h", "ext/smartcard_pcsc/pcsc_surrogate_wintypes.h", "lib/smartcard.rb", "LICENSE", "README", "test/test_all.rb", "tests/ts_pcsc_ext.rb", "Manifest", "smartcard.gemspec"]
18
+ s.test_files = ["test/test_all.rb"]
19
+ s.extensions = ["ext/smartcard_pcsc/extconf.rb"]
20
+ end
21
+
22
+
23
+ # # Original Rakefile source (requires the Echoe gem):
24
+ #
25
+ # # Needs the 'echoe' gem
26
+ # require 'echoe'
27
+ #
28
+ # Echoe.new('smartcard') do |p|
29
+ # p.project = 'smartcard' # rubyforge project
30
+ #
31
+ # p.author = 'Victor Costan'
32
+ # p.email = 'victor@costan.us'
33
+ # p.summary = 'Interface with ISO 7816 smart cards.'
34
+ # p.url = 'http://www.costan.us/smartcard'
35
+ #
36
+ # p.need_tar_gz = false
37
+ # p.clean_pattern += ['ext/**/*.manifest', 'ext/**/*_autogen.h']
38
+ #
39
+ # p.eval = proc do |p|
40
+ # case RUBY_PLATFORM
41
+ # when /mswin/
42
+ # p.files += ['lib/smartcard/pcsc.so']
43
+ # p.platform = Gem::Platform::WIN32
44
+ #
45
+ # # take out the extension info from the gemspec
46
+ # task :postcompile_hacks => [:compile] do
47
+ # p.extensions.clear
48
+ # end
49
+ #
50
+ # task :package => [ :clean, :compile, :postcompile_hacks ]
51
+ # end
52
+ # end
53
+ # end
data/test/test_all.rb ADDED
File without changes
metadata CHANGED
@@ -3,16 +3,17 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: smartcard
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.1
7
- date: 2007-11-16 00:00:00 -05:00
6
+ version: 0.2.0
7
+ date: 2007-11-18 00:00:00 -05:00
8
8
  summary: Interface with ISO 7816 smart cards.
9
9
  require_paths:
10
10
  - lib
11
+ - ext
11
12
  email: victor@costan.us
12
13
  homepage: http://www.costan.us/smartcard
13
- rubyforge_project:
14
- description:
15
- autorequire: smartcard
14
+ rubyforge_project: smartcard
15
+ description: Interface with ISO 7816 smart cards.
16
+ autorequire:
16
17
  default_executable:
17
18
  bindir: bin
18
19
  has_rdoc: true
@@ -29,8 +30,7 @@ post_install_message:
29
30
  authors:
30
31
  - Victor Costan
31
32
  files:
32
- - lib/smartcard.rb
33
- - ext/smartcard_pcsc
33
+ - CHANGELOG
34
34
  - ext/smartcard_pcsc/extconf.rb
35
35
  - ext/smartcard_pcsc/pcsc.h
36
36
  - ext/smartcard_pcsc/pcsc_card.c
@@ -43,9 +43,15 @@ files:
43
43
  - ext/smartcard_pcsc/pcsc_reader_states.c
44
44
  - ext/smartcard_pcsc/pcsc_surrogate_reader.h
45
45
  - ext/smartcard_pcsc/pcsc_surrogate_wintypes.h
46
+ - lib/smartcard.rb
47
+ - LICENSE
48
+ - README
49
+ - test/test_all.rb
46
50
  - tests/ts_pcsc_ext.rb
47
- test_files: []
48
-
51
+ - Manifest
52
+ - smartcard.gemspec
53
+ test_files:
54
+ - test/test_all.rb
49
55
  rdoc_options: []
50
56
 
51
57
  extra_rdoc_files: []