win32-api 1.2.1-x86-mswin32-60 → 1.2.2-x86-mswin32-60
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/CHANGES +15 -0
- data/ext/win32/api.c +35 -14
- data/lib/win32/api.so +0 -0
- data/test/test_win32_api.rb +25 -31
- data/test/test_win32_api_callback.rb +16 -0
- data/test/test_win32_api_function.rb +19 -1
- metadata +3 -3
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.
|
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(
|
258
|
+
if(strstr(RSTRING(v_dll)->ptr, "msvcr")){
|
247
259
|
rb_raise(
|
248
260
|
cAPIError,
|
249
|
-
"
|
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
|
-
"
|
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'",
|
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
|
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'",
|
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
|
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 '%
|
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.
|
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
|
data/test/test_win32_api.rb
CHANGED
@@ -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.
|
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
|
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
|
-
|
95
|
-
API.new('
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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
|
-
|
107
|
-
API.new('
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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
|
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.
|
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-
|
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.
|
59
|
+
rubygems_version: 1.3.0
|
60
60
|
signing_key:
|
61
61
|
specification_version: 2
|
62
62
|
summary: A superior replacement for Win32API
|