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
         |