smartcard 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []