win32-api 1.2.2-x86-mswin32-60 → 1.3.0-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 +13 -0
- data/MANIFEST +9 -9
- data/ext/win32/api.c +32 -26
- data/lib/win32/api.so +0 -0
- data/test/test_win32_api.rb +20 -8
- data/test/test_win32_api_callback.rb +2 -2
- data/test/test_win32_api_function.rb +2 -2
- metadata +3 -3
data/CHANGES
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
= 1.3.0 - 1-Jan-2009
|
2
|
+
* Fixed RubyForge bug #23395, which was caused by inadvertently modifying
|
3
|
+
a variable within a loop. This caused callbacks to fail in certain
|
4
|
+
situations.
|
5
|
+
* Added the Win32::API::LoadLibraryError and Win32::API::PrototypeError classes
|
6
|
+
to provide more fine grained handling of possible error conditions in the
|
7
|
+
constructor. These are both subclasses of Win32::API::Error.
|
8
|
+
* Removed the Win32::API::CallbackError class.
|
9
|
+
* Changed the upper limit on prototypes from 16 to 20. It turns out that
|
10
|
+
there are actually Windows functions with more than 16 prototypes.
|
11
|
+
* Refactored a high iteration test so that it counts as only one test
|
12
|
+
instead of 1000.
|
13
|
+
|
1
14
|
= 1.2.2 - 27-Nov-2008
|
2
15
|
* Fixed bug in the error message for illegal prototypes and illegal return
|
3
16
|
types where the character in question would come out as empty or garbage.
|
data/MANIFEST
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
* CHANGES
|
2
|
-
* MANIFEST
|
3
|
-
* README
|
4
|
-
* Rakefile
|
5
|
-
* win32-api.gemspec
|
6
|
-
* ext/extconf.rb
|
7
|
-
* ext/win32/api.c
|
8
|
-
* test/test_win32_api.rb
|
9
|
-
* test/test_win32_api_callback.rb
|
1
|
+
* CHANGES
|
2
|
+
* MANIFEST
|
3
|
+
* README
|
4
|
+
* Rakefile
|
5
|
+
* win32-api.gemspec
|
6
|
+
* ext/extconf.rb
|
7
|
+
* ext/win32/api.c
|
8
|
+
* test/test_win32_api.rb
|
9
|
+
* test/test_win32_api_callback.rb
|
10
10
|
* test/test_win32_api_function.rb
|
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.
|
5
|
+
#define WINDOWS_API_VERSION "1.3.0"
|
6
6
|
|
7
7
|
#define _T_VOID 0
|
8
8
|
#define _T_LONG 1
|
@@ -11,14 +11,14 @@
|
|
11
11
|
#define _T_CALLBACK 4
|
12
12
|
#define _T_STRING 5
|
13
13
|
|
14
|
-
VALUE cAPIError,
|
14
|
+
VALUE cAPIError, cAPIProtoError, cAPILoadError;
|
15
15
|
static VALUE ActiveCallback = Qnil;
|
16
16
|
|
17
17
|
typedef struct {
|
18
18
|
HANDLE library;
|
19
19
|
FARPROC function;
|
20
20
|
int return_type;
|
21
|
-
int prototype[
|
21
|
+
int prototype[20];
|
22
22
|
} Win32API;
|
23
23
|
|
24
24
|
static void api_free(Win32API* ptr){
|
@@ -122,7 +122,7 @@ static VALUE callback_init(int argc, VALUE* argv, VALUE self)
|
|
122
122
|
case 'I': case 'L': case 'P': case 'V': case 'S':
|
123
123
|
break;
|
124
124
|
default:
|
125
|
-
rb_raise(
|
125
|
+
rb_raise(cAPIProtoError, "Illegal prototype '%c'",
|
126
126
|
RSTRING(v_proto)->ptr[i]
|
127
127
|
);
|
128
128
|
}
|
@@ -136,7 +136,7 @@ static VALUE callback_init(int argc, VALUE* argv, VALUE self)
|
|
136
136
|
case 'I': case 'L': case 'P': case 'V': case 'S':
|
137
137
|
break;
|
138
138
|
default:
|
139
|
-
rb_raise(
|
139
|
+
rb_raise(cAPIProtoError, "Illegal return type '%s'",
|
140
140
|
RSTRING(v_return)->ptr
|
141
141
|
);
|
142
142
|
}
|
@@ -214,8 +214,8 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
214
214
|
rb_ary_push(v_proto, rb_str_new2("V"));
|
215
215
|
}
|
216
216
|
|
217
|
-
// Set an arbitrary limit of
|
218
|
-
if(
|
217
|
+
// Set an arbitrary limit of 20 parameters
|
218
|
+
if(20 < RARRAY(v_proto)->len)
|
219
219
|
rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY(v_proto)->len);
|
220
220
|
|
221
221
|
// Set the default dll to 'kernel32'
|
@@ -233,7 +233,7 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
233
233
|
|
234
234
|
// The most likely cause of failure is a bad DLL load path
|
235
235
|
if(!hLibrary){
|
236
|
-
rb_raise(
|
236
|
+
rb_raise(cAPILoadError, "LoadLibrary() function failed for '%s': %s",
|
237
237
|
RSTRING(v_dll)->ptr,
|
238
238
|
StringError(GetLastError())
|
239
239
|
);
|
@@ -257,7 +257,7 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
257
257
|
if(!fProc){
|
258
258
|
if(strstr(RSTRING(v_dll)->ptr, "msvcr")){
|
259
259
|
rb_raise(
|
260
|
-
|
260
|
+
cAPILoadError,
|
261
261
|
"Unable to load function '%s'",
|
262
262
|
RSTRING(v_proc)->ptr,
|
263
263
|
StringError(GetLastError())
|
@@ -275,7 +275,7 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
275
275
|
|
276
276
|
if(!fProc){
|
277
277
|
rb_raise(
|
278
|
-
|
278
|
+
cAPILoadError,
|
279
279
|
"Unable to load function '%s', '%s', or '%s'",
|
280
280
|
RSTRING(v_proc)->ptr,
|
281
281
|
RSTRING(v_ascii)->ptr,
|
@@ -321,7 +321,7 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
321
321
|
ptr->prototype[i] = _T_STRING;
|
322
322
|
break;
|
323
323
|
default:
|
324
|
-
rb_raise(
|
324
|
+
rb_raise(cAPIProtoError, "Illegal prototype '%s'",
|
325
325
|
StringValuePtr(RARRAY(v_proto)->ptr[i])
|
326
326
|
);
|
327
327
|
}
|
@@ -353,7 +353,7 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
353
353
|
ptr->return_type = _T_STRING;
|
354
354
|
break;
|
355
355
|
default:
|
356
|
-
rb_raise(
|
356
|
+
rb_raise(cAPIProtoError, "Illegal return type '%s'",
|
357
357
|
RSTRING(v_return)->ptr
|
358
358
|
);
|
359
359
|
}
|
@@ -413,8 +413,8 @@ static VALUE func_init(int argc, VALUE* argv, VALUE self){
|
|
413
413
|
rb_ary_push(v_proto, rb_str_new2("V"));
|
414
414
|
}
|
415
415
|
|
416
|
-
// Set an arbitrary limit of
|
417
|
-
if(
|
416
|
+
// Set an arbitrary limit of 20 parameters
|
417
|
+
if(20 < RARRAY(v_proto)->len)
|
418
418
|
rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY(v_proto)->len);
|
419
419
|
|
420
420
|
// Set the default return type to 'L' (DWORD)
|
@@ -447,7 +447,7 @@ static VALUE func_init(int argc, VALUE* argv, VALUE self){
|
|
447
447
|
ptr->prototype[i] = _T_STRING;
|
448
448
|
break;
|
449
449
|
default:
|
450
|
-
rb_raise(
|
450
|
+
rb_raise(cAPIProtoError, "Illegal prototype '%s'",
|
451
451
|
StringValuePtr(RARRAY(v_proto)->ptr[i])
|
452
452
|
);
|
453
453
|
}
|
@@ -479,7 +479,7 @@ static VALUE func_init(int argc, VALUE* argv, VALUE self){
|
|
479
479
|
ptr->return_type = _T_STRING;
|
480
480
|
break;
|
481
481
|
default:
|
482
|
-
rb_raise(
|
482
|
+
rb_raise(cAPIProtoError, "Illegal return type '%s'",
|
483
483
|
RSTRING(v_return)->ptr
|
484
484
|
);
|
485
485
|
}
|
@@ -493,14 +493,14 @@ static VALUE func_init(int argc, VALUE* argv, VALUE self){
|
|
493
493
|
}
|
494
494
|
|
495
495
|
typedef struct {
|
496
|
-
DWORD params[
|
496
|
+
DWORD params[20];
|
497
497
|
} CALLPARAM;
|
498
498
|
|
499
499
|
|
500
500
|
DWORD CallbackFunction(CALLPARAM param)
|
501
501
|
{
|
502
502
|
VALUE v_proto, v_return, v_proc, v_retval;
|
503
|
-
VALUE argv[
|
503
|
+
VALUE argv[20];
|
504
504
|
int i, argc;
|
505
505
|
char *a_proto;
|
506
506
|
char *a_return;
|
@@ -529,7 +529,7 @@ DWORD CallbackFunction(CALLPARAM param)
|
|
529
529
|
argv[i] = INT2NUM(param.params[i]);
|
530
530
|
break;
|
531
531
|
default:
|
532
|
-
rb_raise(
|
532
|
+
rb_raise(cAPIProtoError, "Illegal prototype '%s'",
|
533
533
|
RSTRING(a_proto[i])->ptr
|
534
534
|
);
|
535
535
|
}
|
@@ -671,9 +671,10 @@ static VALUE api_call(int argc, VALUE* argv, VALUE self){
|
|
671
671
|
Win32API* ptr;
|
672
672
|
unsigned long return_value;
|
673
673
|
int i = 0;
|
674
|
+
int len;
|
674
675
|
|
675
676
|
struct{
|
676
|
-
unsigned long params[
|
677
|
+
unsigned long params[20];
|
677
678
|
} param;
|
678
679
|
|
679
680
|
Data_Get_Struct(self, Win32API, ptr);
|
@@ -682,7 +683,7 @@ static VALUE api_call(int argc, VALUE* argv, VALUE self){
|
|
682
683
|
|
683
684
|
v_proto = rb_iv_get(self, "@prototype");
|
684
685
|
|
685
|
-
|
686
|
+
// For void prototypes, allow either no args or an explicit nil
|
686
687
|
if(RARRAY(v_proto)->len != RARRAY(v_args)->len){
|
687
688
|
char* c = StringValuePtr(RARRAY(v_proto)->ptr[0]);
|
688
689
|
if(!strcmp(c, "V")){
|
@@ -696,10 +697,12 @@ static VALUE api_call(int argc, VALUE* argv, VALUE self){
|
|
696
697
|
}
|
697
698
|
}
|
698
699
|
|
699
|
-
|
700
|
+
len = RARRAY(v_proto)->len;
|
701
|
+
|
702
|
+
for(i = 0; i < len; i++){
|
700
703
|
v_arg = RARRAY(v_args)->ptr[i];
|
701
704
|
|
702
|
-
|
705
|
+
// Convert nil to NULL. Otherwise convert as appropriate.
|
703
706
|
if(NIL_P(v_arg))
|
704
707
|
param.params[i] = (unsigned long)NULL;
|
705
708
|
else if(v_arg == Qtrue)
|
@@ -815,11 +818,14 @@ void Init_api(){
|
|
815
818
|
/* The API::Function class encapsulates a raw function pointer */
|
816
819
|
cFunction = rb_define_class_under(cAPI, "Function", cAPI);
|
817
820
|
|
818
|
-
/* The API::Error class
|
821
|
+
/* The API::Error class serves as a base class for other errors */
|
819
822
|
cAPIError = rb_define_class_under(cAPI, "Error", rb_eRuntimeError);
|
820
823
|
|
821
|
-
/* The
|
822
|
-
|
824
|
+
/* The LoadError class is raised if a function cannot be found or loaded */
|
825
|
+
cAPILoadError = rb_define_class_under(cAPI, "LoadLibraryError", cAPIError);
|
826
|
+
|
827
|
+
/* The PrototypeError class is raised if an invalid prototype is passed */
|
828
|
+
cAPIProtoError = rb_define_class_under(cAPI, "PrototypeError", cAPIError);
|
823
829
|
|
824
830
|
/* Miscellaneous */
|
825
831
|
rb_define_alloc_func(cAPI, api_allocate);
|
data/lib/win32/api.so
CHANGED
Binary file
|
data/test/test_win32_api.rb
CHANGED
@@ -20,7 +20,7 @@ class TC_Win32_API < Test::Unit::TestCase
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def test_version
|
23
|
-
assert_equal('1.
|
23
|
+
assert_equal('1.3.0', API::VERSION)
|
24
24
|
end
|
25
25
|
|
26
26
|
def test_constructor_basic
|
@@ -79,17 +79,17 @@ class TC_Win32_API < Test::Unit::TestCase
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def test_constructor_high_iteration
|
82
|
-
|
83
|
-
|
82
|
+
assert_nothing_raised{
|
83
|
+
1000.times{ API.new('GetUserName', 'P', 'P', 'advapi32') }
|
84
84
|
}
|
85
85
|
end
|
86
86
|
|
87
87
|
def test_constructor_expected_failures
|
88
88
|
assert_raise(ArgumentError){ API.new }
|
89
|
-
assert_raise(ArgumentError){ API.new('GetUserName', ('L' *
|
90
|
-
assert_raise(API::
|
91
|
-
assert_raise(API::
|
92
|
-
assert_raise(API::
|
89
|
+
assert_raise(ArgumentError){ API.new('GetUserName', ('L' * 21), 'X') }
|
90
|
+
assert_raise(API::LoadLibraryError){ API.new('GetUserName', 'PL', 'I', 'foo') }
|
91
|
+
assert_raise(API::PrototypeError){ API.new('GetUserName', 'X', 'I', 'advapi32') }
|
92
|
+
assert_raise(API::PrototypeError){ API.new('GetUserName', 'PL', 'X', 'advapi32') }
|
93
93
|
end
|
94
94
|
|
95
95
|
def test_constructor_expected_failure_messages
|
@@ -113,7 +113,19 @@ class TC_Win32_API < Test::Unit::TestCase
|
|
113
113
|
def test_call_expected_failures
|
114
114
|
assert_raise(TypeError){ @gcd.call('test', @buf) }
|
115
115
|
end
|
116
|
-
|
116
|
+
|
117
|
+
def test_error_classes
|
118
|
+
assert_not_nil(Win32::API::Error)
|
119
|
+
assert_not_nil(Win32::API::LoadLibraryError)
|
120
|
+
assert_not_nil(Win32::API::PrototypeError)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_error_class_relationships
|
124
|
+
assert_kind_of(RuntimeError, Win32::API::Error.new)
|
125
|
+
assert_kind_of(Win32::API::Error, Win32::API::LoadLibraryError.new)
|
126
|
+
assert_kind_of(Win32::API::Error, Win32::API::PrototypeError.new)
|
127
|
+
end
|
128
|
+
|
117
129
|
def teardown
|
118
130
|
@buf = nil
|
119
131
|
@gcd = nil
|
@@ -56,8 +56,8 @@ class TC_Win32_API_Callback < Test::Unit::TestCase
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def test_constructor_expected_errors
|
59
|
-
assert_raise(API::
|
60
|
-
assert_raise(API::
|
59
|
+
assert_raise(API::PrototypeError){ API::Callback.new('X') }
|
60
|
+
assert_raise(API::PrototypeError){ API::Callback.new('L', 'Y') }
|
61
61
|
end
|
62
62
|
|
63
63
|
def test_constructor_expected_error_messages
|
@@ -45,8 +45,8 @@ class TC_Win32_API_Function < Test::Unit::TestCase
|
|
45
45
|
def test_expected_errors_from_arguments
|
46
46
|
assert_raise(ArgumentError){ Win32::API::Function.new }
|
47
47
|
assert_raise(TypeError){ Win32::API::Function.new('L') }
|
48
|
-
assert_raise(Win32::API::
|
49
|
-
assert_raise(Win32::API::
|
48
|
+
assert_raise(Win32::API::PrototypeError){ Win32::API::Function.new(1, 'X') }
|
49
|
+
assert_raise(Win32::API::PrototypeError){ Win32::API::Function.new(1, 'X', 'Y') }
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_expected_error_messages
|
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.
|
4
|
+
version: 1.3.0
|
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:
|
13
|
+
date: 2009-01-01 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.3.
|
59
|
+
rubygems_version: 1.3.1
|
60
60
|
signing_key:
|
61
61
|
specification_version: 2
|
62
62
|
summary: A superior replacement for Win32API
|