win32-api 1.2.1-x86-mswin32-60 → 1.2.2-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,18 @@
1
+ = 1.2.2 - 27-Nov-2008
2
+ * Fixed bug in the error message for illegal prototypes and illegal return
3
+ types where the character in question would come out as empty or garbage.
4
+ * Passing a bad return type to Win32::API::Callback now raises an error.
5
+ * Updated the error message for illegal return types to say, "Illegal return
6
+ type" instead of "Illegal prototype" as it did previously.
7
+ * The error message for a bad function name passed to Win32::API.new now
8
+ matches JRuby's FFI error message.
9
+ * Improved the handling of msvcrt functions with regards to skipping 'A'
10
+ and 'W' checks. Previously it was checking against the literal string
11
+ 'msvcrt'. Now it checks against any string that starts with 'msvcr'.
12
+ * Added test-unit 2.x as a prerequisite.
13
+ * Added tests for the Win32::API::Callback#address method.
14
+ * Added tests to all Win32::API classes that explicitly check error messages.
15
+
1
16
  = 1.2.1 - 14-Nov-2008
2
17
  * Fixed and updated callback handling.
3
18
  * Fixed wide string return handling for pointers and strings.
data/ext/win32/api.c CHANGED
@@ -2,7 +2,7 @@
2
2
  #include <windows.h>
3
3
 
4
4
  #define MAX_BUF 1024
5
- #define WINDOWS_API_VERSION "1.2.1"
5
+ #define WINDOWS_API_VERSION "1.2.2"
6
6
 
7
7
  #define _T_VOID 0
8
8
  #define _T_LONG 1
@@ -123,12 +123,24 @@ static VALUE callback_init(int argc, VALUE* argv, VALUE self)
123
123
  break;
124
124
  default:
125
125
  rb_raise(cCallbackError, "Illegal prototype '%c'",
126
- RSTRING(v_proto)->ptr[i]);
126
+ RSTRING(v_proto)->ptr[i]
127
+ );
127
128
  }
128
129
  }
129
130
 
130
- if(NIL_P(v_return) || RARRAY(v_return)->len == 0)
131
+ if(NIL_P(v_return) || RARRAY(v_return)->len == 0){
131
132
  v_return = rb_str_new2("L");
133
+ }
134
+ else{
135
+ switch(*(char*)RSTRING(v_return)->ptr){
136
+ case 'I': case 'L': case 'P': case 'V': case 'S':
137
+ break;
138
+ default:
139
+ rb_raise(cCallbackError, "Illegal return type '%s'",
140
+ RSTRING(v_return)->ptr
141
+ );
142
+ }
143
+ }
132
144
 
133
145
  rb_iv_set(self, "@function", v_proc);
134
146
  rb_iv_set(self, "@prototype", v_proto);
@@ -243,10 +255,10 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
243
255
 
244
256
  // Skip the ANSI and Wide function checks for MSVCRT functions.
245
257
  if(!fProc){
246
- if(!strcmp(RSTRING(v_dll)->ptr, "msvcrt")){
258
+ if(strstr(RSTRING(v_dll)->ptr, "msvcr")){
247
259
  rb_raise(
248
260
  cAPIError,
249
- "GetProcAddress() failed for '%s': %s",
261
+ "Unable to load function '%s'",
250
262
  RSTRING(v_proc)->ptr,
251
263
  StringError(GetLastError())
252
264
  );
@@ -264,11 +276,10 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
264
276
  if(!fProc){
265
277
  rb_raise(
266
278
  cAPIError,
267
- "GetProcAddress() failed for '%s', '%s' and '%s': %s",
279
+ "Unable to load function '%s', '%s', or '%s'",
268
280
  RSTRING(v_proc)->ptr,
269
281
  RSTRING(v_ascii)->ptr,
270
- RSTRING(v_unicode)->ptr,
271
- StringError(GetLastError())
282
+ RSTRING(v_unicode)->ptr
272
283
  );
273
284
  }
274
285
  else{
@@ -310,7 +321,9 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
310
321
  ptr->prototype[i] = _T_STRING;
311
322
  break;
312
323
  default:
313
- rb_raise(cAPIError, "Illegal prototype '%s'", RARRAY(v_proto)->ptr[i]);
324
+ rb_raise(cAPIError, "Illegal prototype '%s'",
325
+ StringValuePtr(RARRAY(v_proto)->ptr[i])
326
+ );
314
327
  }
315
328
  }
316
329
 
@@ -340,7 +353,9 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
340
353
  ptr->return_type = _T_STRING;
341
354
  break;
342
355
  default:
343
- rb_raise(cAPIError, "Illegal prototype '%s'", RARRAY(v_proto)->ptr[i]);
356
+ rb_raise(cAPIError, "Illegal return type '%s'",
357
+ RSTRING(v_return)->ptr
358
+ );
344
359
  }
345
360
  }
346
361
 
@@ -432,7 +447,9 @@ static VALUE func_init(int argc, VALUE* argv, VALUE self){
432
447
  ptr->prototype[i] = _T_STRING;
433
448
  break;
434
449
  default:
435
- rb_raise(cAPIError, "Illegal prototype '%s'", RARRAY(v_proto)->ptr[i]);
450
+ rb_raise(cAPIError, "Illegal prototype '%s'",
451
+ StringValuePtr(RARRAY(v_proto)->ptr[i])
452
+ );
436
453
  }
437
454
  }
438
455
 
@@ -462,7 +479,9 @@ static VALUE func_init(int argc, VALUE* argv, VALUE self){
462
479
  ptr->return_type = _T_STRING;
463
480
  break;
464
481
  default:
465
- rb_raise(cAPIError, "Illegal prototype '%s'", RARRAY(v_proto)->ptr[i]);
482
+ rb_raise(cAPIError, "Illegal return type '%s'",
483
+ RSTRING(v_return)->ptr
484
+ );
466
485
  }
467
486
  }
468
487
 
@@ -510,7 +529,9 @@ DWORD CallbackFunction(CALLPARAM param)
510
529
  argv[i] = INT2NUM(param.params[i]);
511
530
  break;
512
531
  default:
513
- rb_raise(cCallbackError, "Illegal prototype '%c'", a_proto[i]);
532
+ rb_raise(cCallbackError, "Illegal prototype '%s'",
533
+ RSTRING(a_proto[i])->ptr
534
+ );
514
535
  }
515
536
  }
516
537
 
@@ -845,6 +866,6 @@ void Init_api(){
845
866
 
846
867
  /* Constants */
847
868
 
848
- /* 1.2.0: The version of this library, returned as a String */
869
+ /* 1.2.2: The version of this library, returned as a String */
849
870
  rb_define_const(cAPI, "VERSION", rb_str_new2(WINDOWS_API_VERSION));
850
871
  }
data/lib/win32/api.so CHANGED
Binary file
@@ -4,6 +4,9 @@
4
4
  # Test case for the Win32::API class. You should run this as Rake task,
5
5
  # i.e. 'rake test', instead of running it directly.
6
6
  ############################################################################
7
+ require 'rubygems'
8
+ gem 'test-unit'
9
+
7
10
  require 'win32/api'
8
11
  require 'test/unit'
9
12
  include Win32
@@ -17,7 +20,7 @@ class TC_Win32_API < Test::Unit::TestCase
17
20
  end
18
21
 
19
22
  def test_version
20
- assert_equal('1.2.1', API::VERSION)
23
+ assert_equal('1.2.2', API::VERSION)
21
24
  end
22
25
 
23
26
  def test_constructor_basic
@@ -49,14 +52,18 @@ class TC_Win32_API < Test::Unit::TestCase
49
52
  assert_equal('strstr', @str.function_name)
50
53
  end
51
54
 
52
- def test_effective_function_name
55
+ def test_effective_function_name_default
53
56
  assert_respond_to(@gcd, :effective_function_name)
54
57
  assert_equal('GetCurrentDirectoryA', @gcd.effective_function_name)
55
58
  assert_equal('strstr', @str.effective_function_name)
59
+ end
56
60
 
61
+ def test_effective_function_name_default_explicit_ansi
57
62
  @gcd = API.new('GetCurrentDirectoryA', 'LP')
58
63
  assert_equal('GetCurrentDirectoryA', @gcd.effective_function_name)
64
+ end
59
65
 
66
+ def test_effective_function_name_default_explicit_wide
60
67
  @gcd = API.new('GetCurrentDirectoryW', 'LP')
61
68
  assert_equal('GetCurrentDirectoryW', @gcd.effective_function_name)
62
69
  end
@@ -79,43 +86,30 @@ class TC_Win32_API < Test::Unit::TestCase
79
86
 
80
87
  def test_constructor_expected_failures
81
88
  assert_raise(ArgumentError){ API.new }
89
+ assert_raise(ArgumentError){ API.new('GetUserName', ('L' * 17), 'X') }
82
90
  assert_raise(API::Error){ API.new('GetUserName', 'PL', 'I', 'foo') }
83
91
  assert_raise(API::Error){ API.new('GetUserName', 'X', 'I', 'kernel32') }
84
92
  assert_raise(API::Error){ API.new('GetUserName', 'PL', 'X', 'kernel32') }
85
93
  end
86
94
 
87
- # Compare MSVCRT error messages vs regular error messages. This validates
88
- # that we're skipping the 'A' and 'W' lookups for MSVCRT functions.
89
- #
90
- # The JRuby test message is somewhat different because we're not using
91
- # GetLastError().
92
- #
93
95
  def test_constructor_expected_failure_messages
94
- begin
95
- API.new('GetBlah')
96
- rescue API::Error => err
97
- if RUBY_PLATFORM.match('java')
98
- expected = "Unable to load function 'GetBlah', 'GetBlahA', or 'GetBlahW'"
99
- else
100
- expected = "GetProcAddress() failed for 'GetBlah', 'GetBlahA' and "
101
- expected += "'GetBlahW': The specified procedure could not be found."
102
- end
103
- assert_equal(expected, err.to_s)
104
- end
96
+ assert_raise_message("Unable to load function 'Zap', 'ZapA', or 'ZapW'"){
97
+ API.new('Zap')
98
+ }
99
+
100
+ assert_raise_message("Unable to load function 'strxxx'"){
101
+ API.new('strxxx', 'P', 'L', 'msvcrt')
102
+ }
105
103
 
106
- begin
107
- API.new('strxxx', 'P', 'P', 'msvcrt')
108
- rescue API::Error => err
109
- if RUBY_PLATFORM.match('java')
110
- expected = "Unable to load function 'strxxx'"
111
- else
112
- expected = "GetProcAddress() failed for 'strxxx': The specified "
113
- expected += "procedure could not be found."
114
- end
115
- assert_equal(expected, err.to_s)
116
- end
104
+ assert_raise_message("Illegal prototype 'X'"){
105
+ API.new('GetUserName', 'X', 'I', 'advapi32')
106
+ }
107
+
108
+ assert_raise_message("Illegal return type 'Y'"){
109
+ API.new('GetUserName', 'PL', 'Y', 'advapi32')
110
+ }
117
111
  end
118
-
112
+
119
113
  def test_call_expected_failures
120
114
  assert_raise(TypeError){ @gcd.call('test', @buf) }
121
115
  end
@@ -4,6 +4,9 @@
4
4
  # Test case for the Win32::API::Callback class. You should run this as Rake
5
5
  # task, i.e. 'rake test', instead of running it directly.
6
6
  ############################################################################
7
+ require 'rubygems'
8
+ gem 'test-unit'
9
+
7
10
  require 'win32/api'
8
11
  require 'test/unit'
9
12
  include Win32
@@ -33,6 +36,13 @@ class TC_Win32_API_Callback < Test::Unit::TestCase
33
36
  assert_respond_to(@callback, :return_type)
34
37
  assert_equal('I', @callback.return_type)
35
38
  end
39
+
40
+ def test_address
41
+ assert_nothing_raised{ @callback = API::Callback.new('LP', 'I') }
42
+ assert_respond_to(@callback, :address)
43
+ assert_kind_of(Fixnum, @callback.address)
44
+ assert_equal(true, @callback.address > 0)
45
+ end
36
46
 
37
47
  def test_callback
38
48
  assert_nothing_raised{
@@ -47,6 +57,12 @@ class TC_Win32_API_Callback < Test::Unit::TestCase
47
57
 
48
58
  def test_constructor_expected_errors
49
59
  assert_raise(API::Callback::Error){ API::Callback.new('X') }
60
+ assert_raise(API::Callback::Error){ API::Callback.new('L', 'Y') }
61
+ end
62
+
63
+ def test_constructor_expected_error_messages
64
+ assert_raise_message("Illegal prototype 'X'"){ API::Callback.new('X') }
65
+ assert_raise_message("Illegal return type 'Y'"){ API::Callback.new('L', 'Y') }
50
66
  end
51
67
 
52
68
  def teardown
@@ -4,8 +4,12 @@
4
4
  # Test case for the Win32::API::Function class. You should run these
5
5
  # tests via the 'rake test' task.
6
6
  ########################################################################
7
+ require 'rubygems'
8
+ gem 'test-unit'
9
+
7
10
  require 'test/unit'
8
11
  require 'win32/api'
12
+ include Win32
9
13
 
10
14
  class TC_Win32_API_Function < Test::Unit::TestCase
11
15
  def setup
@@ -38,8 +42,22 @@ class TC_Win32_API_Function < Test::Unit::TestCase
38
42
  assert_equal('L', @func.return_type)
39
43
  end
40
44
 
41
- def test_expected_errors
45
+ def test_expected_errors_from_arguments
42
46
  assert_raise(ArgumentError){ Win32::API::Function.new }
47
+ assert_raise(TypeError){ Win32::API::Function.new('L') }
48
+ assert_raise(Win32::API::Error){ Win32::API::Function.new(1, 'X') }
49
+ assert_raise(Win32::API::Error){ Win32::API::Function.new(1, 'X', 'Y') }
50
+ end
51
+
52
+ def test_expected_error_messages
53
+ assert_raise_message("Illegal prototype 'X'"){ API::Function.new(1, 'X') }
54
+ assert_raise_message("Illegal return type 'Y'"){ API::Function.new(1, 'L', 'Y') }
55
+ end
56
+
57
+ def test_expected_errors_from_call
58
+ assert_raise(ArgumentError){ @func.call }
59
+ assert_raise(ArgumentError){ @func.call(1) }
60
+ assert_raise(ArgumentError){ @func.call(1, 'a', 2) }
43
61
  end
44
62
 
45
63
  def teardown
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: win32-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  platform: x86-mswin32-60
6
6
  authors:
7
7
  - Daniel J. Berger
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2008-11-14 00:00:00 -07:00
13
+ date: 2008-11-27 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -56,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
56
56
  requirements: []
57
57
 
58
58
  rubyforge_project: win32utils
59
- rubygems_version: 1.2.0
59
+ rubygems_version: 1.3.0
60
60
  signing_key:
61
61
  specification_version: 2
62
62
  summary: A superior replacement for Win32API