win32-api 1.2.2-x86-mswin32-60 → 1.3.0-x86-mswin32-60
Sign up to get free protection for your applications and to get access to all the features.
- 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
|