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 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.2.2"
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, cCallbackError;
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[16];
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(cCallbackError, "Illegal prototype '%c'",
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(cCallbackError, "Illegal return type '%s'",
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 16 parameters
218
- if(16 < RARRAY(v_proto)->len)
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(cAPIError, "LoadLibrary() function failed for '%s': %s",
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
- cAPIError,
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
- cAPIError,
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(cAPIError, "Illegal prototype '%s'",
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(cAPIError, "Illegal return type '%s'",
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 16 parameters
417
- if(16 < RARRAY(v_proto)->len)
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(cAPIError, "Illegal prototype '%s'",
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(cAPIError, "Illegal return type '%s'",
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[16];
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[16];
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(cCallbackError, "Illegal prototype '%s'",
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[16];
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
- /* For void prototypes, allow either no args or an explicit nil */
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
- for(i = 0; i < RARRAY(v_proto)->len; i++){
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
- /* Convert nil to NULL. Otherwise convert as appropriate. */
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 is raised if the constructor fails */
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 API::Callback::Error class is raised if the constructor fails */
822
- cCallbackError = rb_define_class_under(cCallback, "Error", rb_eRuntimeError);
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
@@ -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.2.2', API::VERSION)
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
- 1000.times{
83
- assert_nothing_raised{ API.new('GetUserName', 'P', 'P', 'advapi32') }
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' * 17), 'X') }
90
- assert_raise(API::Error){ API.new('GetUserName', 'PL', 'I', 'foo') }
91
- assert_raise(API::Error){ API.new('GetUserName', 'X', 'I', 'kernel32') }
92
- assert_raise(API::Error){ API.new('GetUserName', 'PL', 'X', 'kernel32') }
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::Callback::Error){ API::Callback.new('X') }
60
- assert_raise(API::Callback::Error){ API::Callback.new('L', 'Y') }
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::Error){ Win32::API::Function.new(1, 'X') }
49
- assert_raise(Win32::API::Error){ Win32::API::Function.new(1, 'X', 'Y') }
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.2.2
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: 2008-11-27 00:00:00 -07:00
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.0
59
+ rubygems_version: 1.3.1
60
60
  signing_key:
61
61
  specification_version: 2
62
62
  summary: A superior replacement for Win32API