Giter Site home page Giter Site logo

win32-api's Introduction

Description

This is a drop-in replacement for the Win32API library currently part of Ruby's standard library.

Synopsis

  require 'win32/api'
  include Win32

  # Typical example - Get user name
  buf = 0.chr * 260
  len = [buf.length].pack('L')

  GetUserName = API.new('GetUserName', 'PP', 'I', 'advapi32')
  GetUserName.call(buf, len)

  puts buf.strip

  # Callback example - Enumerate windows
  EnumWindows     = API.new('EnumWindows', 'KP', 'L', 'user32')
  GetWindowText   = API.new('GetWindowText', 'LPI', 'I', 'user32')
  EnumWindowsProc = API::Callback.new('LP', 'I'){ |handle, param|
    buf = "\0" * 200
    GetWindowText.call(handle, buf, 200);
    puts buf.strip unless buf.strip.empty?
    buf.index(param).nil? ? true : false
  }

  EnumWindows.call(EnumWindowsProc, 'UEDIT32')

  # Raw function pointer example - System beep
  LoadLibrary    = API.new('LoadLibrary', 'P', 'L')
  GetProcAddress = API.new('GetProcAddress', 'LP', 'L')

  hlib = LoadLibrary.call('user32')
  addr = GetProcAddress.call(hlib, 'MessageBeep')
  func = Win32::API::Function.new(addr, 'L', 'L')
  func.call(0)

Differences between win32-api and Win32API

  • This library has callback support
  • This library supports raw function pointers.
  • This library supports a separate string type for const char* (S).
  • Argument order change. The DLL name is now last, not first.
  • Removed the 'N' and 'n' prototypes. Always use 'L' for longs now.
  • Sensible default arguments for the prototype, return type and DLL name.
  • Reader methods for the function name, effective function name, prototype, return type and DLL.
  • Removed the support for lower case prototype and return types. Always use capital letters.

Developer's Notes

NOTE: Some of the information below is now out of date, but explains my motivation at the time the project was originally created.

The current Win32API library that ships with the standard library has been slated for removal from Ruby 2.0 and it will not receive any updates in the Ruby 1.8.x branch. I have far too many libraries invested in it to let it die at this point.

In addition, the current Win32API library was written in the bad old Ruby 1.6.x days, which means it doesn't use the newer allocation framework. There were several other refactorings that I felt it needed to more closely match how it was actually being used in practice.

The first order of business was changing the order of the arguments. By moving the DLL name from first to last, I was able to provide reasonable default arguments for the prototype, return type and the DLL. Only the function name is required now.

There was a laundry list of other refactorings that were needed: sensical instance variable names with proper accessors, removing support for lower case prototype and return value characters that no one used in practice, better naming conventions, the addition of RDoc ready comments and, especially, callback and raw function pointer support.

Most importantly, we can now add, modify and fix any features that we feel best benefit our end users.

Multiple Binaries

As of win32-api 1.4.8 a binary gem is shipped that contains binaries for both Ruby 1.8, Ruby 1.9, and 2.x. For Ruby 2.x, both 32 and 64 bit binaries are included as of release 1.5.0.

The file under lib/win32 dynamically requires the correct binary based on your version of Ruby.

Documentation

The source file contains inline RDoc documentation. If you installed this file as a gem, then you have the docs. Run "gem server" and point your browser at http://localhost:8808 to see them.

Warranty

This package is provided "as is" and without any express or implied warranties, including, without limitation, the implied warranties of merchantability and fitness for a particular purpose.

Known Issues

Possible callback issues when dealing with multi-threaded applications.

Please submit any bug reports to the project page at https://github.com/cosmo0920/win32-api

Contributions

Although this library is free, please consider having your company setup a gittip if used by your company professionally.

http://www.gittip.com/djberg96/

Future Plans

I really don't have future plans for this library since you should use FFI as your preferred C interface going forward. All of my own projects have since been converted to either use FFI or an analogous OLE interface.

I will continue to maintain this library as long as there are folks out there who are still using it, but I strongly encourage you to convert your projects to FFI when possible.

Copyright

(C) 2003-2015 Daniel J. Berger

(C) 2016-2020 Hiroshi Hatake

All Rights Reserved

License

Artistic 2.0

Authors

Daniel J. Berger

Park Heesob

Hiroshi Hatake

win32-api's People

Contributors

ashie avatar cosmo0920 avatar djberg96 avatar msp-greg avatar phasis68 avatar rickerliang avatar shirosaki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

win32-api's Issues

need a new gem release for ruby 2.1.3 on windows

rubyinstaller 2.1.3 has been released but this gem will not run under it.

it looks like the precompiled 2.0.0 libraries won't load into a 2.1.x VM and they error with a "The specified module could not be found" error even though the file exists (copy-paste from my windows VM currently isn't working for me).

Using win32-api under ruby-dev errors

I installed the win32-api gem and tried to use it and I am getting the following error:

C:\Users\Dominic E Sisneros>irb
DL is deprecated, please use Fiddle
irb(main):001:0> require 'win32/api'
LoadError: 126: The specified module could not be found. - c:/Dominic/ruby/ruby21_mingw/lib/ruby/gems/2.2.0/gems/win32-api-1.5.1
-universal-mingw32/lib/win32/ruby2_32/win32/api.so
from c:/Dominic/ruby/ruby21_mingw/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:55:in require' from c:/Dominic/ruby/ruby21_mingw/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:55:inrequire'
from c:/Dominic/ruby/ruby21_mingw/lib/ruby/gems/2.2.0/gems/win32-api-1.5.1-universal-mingw32/lib/win32/api.rb:10:in <top (required)>' from c:/Dominic/ruby/ruby21_mingw/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:135:inrequire'
from c:/Dominic/ruby/ruby21_mingw/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:135:in rescue in require' from c:/Dominic/ruby/ruby21_mingw/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:144:inrequire'
from (irb):1
from c:/Dominic/ruby/ruby21_mingw/bin/irb:11:in `

'
irb(main):002:0> exit

This works under ruby 2.0.0p451

C:\Users\Dominic E Sisneros>ruby -v
ruby 2.2.0dev (2014-08-07 trunk 47091) [i386-mingw]

C:\Users\Dominic E Sisneros>irb
DL is deprecated, please use Fiddle
irb(main):001:0> require 'win32/api'
=> true
irb(main):002:0> exit

C:\Users\Dominic E Sisneros>ruby -v
ruby 2.0.0p451 (2014-02-24) [x64-mingw32]

C:\Users\Dominic E Sisneros>

Ruby 3.1 require fails to define API constant

The universal-mingw32 gem 1.10.1 contains .so for Ruby 3.1 but the api.rb does not have support for Ruby 3.1.

I believe the code in between the comments is missing:

when '3'
    if RbConfig::CONFIG['MINOR'] == '0'
      if RbConfig::CONFIG['arch'] =~ /x64/i
        require File.join(File.dirname(__FILE__), 'ruby30_64/win32/api')
      else
        require File.join(File.dirname(__FILE__), 'ruby30_32/win32/api')
      end
    # start missing
    elseif RbConfig::CONFIG['MINOR'] == '1'
      if RbConfig::CONFIG['arch'] =~ /x64/i
        require File.join(File.dirname(__FILE__), 'ruby31_64/win32/api')
      else
        require File.join(File.dirname(__FILE__), 'ruby31_32/win32/api')
      end
    # end missing
    end

I have a work around but I thought I'd let you know.

Ship an updated gem

Was wondering if it would be possible to cut / ship a new gem based on the AV fix that most recently landed in master?

Thanks for the consideration!

function "api_call" in api.c cause stack corruption

"return_value = ptr->function(param)" in api_call function will cause stack corruption.
This statement cause the compiler generate assembly like this:

sub esp,50h
mov ecx,14h
lea esi,[ebp-58h]
mov edi,esp
rep movs dword ptr es:[edi],dword ptr [esi]
call windows_api

The calling convention of window api is __stdcall, callee pops its own arguments from the stack, so windows api's return statement usually like this (assembly) ret xxh, xxh == arguments count * 4 byte.
Argument counts are vary from api to api, not all windows api uses 20 arguments (and ret 50h) especially some api has no argument, in that situation, before and after api call, esp register can not keep the same value, stack corruption occur.
Pass the argument according to api's prototype could fix this problem.

Suggestion: Allow function parameters as symbols

Here are the parameters as Strings (Standard)

Memcpy = API.new('memcpy', 'PPL', 'V', 'Msvcrt')

In current version 1.5.0 setting parameters as symbols doesn't work

Memcpy = API.new(:memcpy, :PPL, :V, :Msvcrt)

What you think?

Feature request to publish x86 and x64 versions

Hi @djberg96, I've been trying to use bundler for a project that has dependencies on ffi and windows-api. The Gemfile is:

source "https://rubygems.org"

gem 'ffi'
gem 'windows-api'

When run on ruby 1.9.3 (x86) everything works:

C:\work\foo>ruby --version
ruby 1.9.3p374 (2013-01-15) [i386-mingw32]
C:\work\foo>bundle install --path .bundle
Fetching gem metadata from https://rubygems.org/...........
Fetching gem metadata from https://rubygems.org/..
Resolving dependencies...
Installing ffi (1.9.3)
Installing win32-api (1.5.1)
Installing windows-api (0.4.2)
Using bundler (1.2.4)
Your bundle is complete! It was installed into ./.bundle

When run on ruby 2.0 (x64) the ffi gem installs, but for some reason bundler resolves dependency info, and tries to install win32-api version 1.4.8, which is the pre-ffi version:

C:\work\foo>ruby --version
ruby 2.0.0p451 (2014-02-24) [x64-mingw32]
C:\work\foo>bundle install --path .bundle
DL is deprecated, please use Fiddle
Fetching gem metadata from https://rubygems.org/...........
Fetching additional metadata from https://rubygems.org/..
Resolving dependencies...
Installing ffi (1.9.3)

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
...
Gem files will remain installed in C:/work/foo/.bundle/ruby/2.0.0/gems/win32-api-1.4.8 for inspection.
Results logged to C:/work/foo/.bundle/ruby/2.0.0/gems/win32-api-1.4.8/ext/gem_make.out

Note I'm trying to do this without relying on the DevKit, since it won't necessarily be installed.

However, if I manually install the gems, using ruby's gem command, it works, I get the universal win32-api version as expected:

C:\work\foo>gem install windows-api
Fetching: win32-api-1.5.1-universal-mingw32.gem (100%)
Successfully installed win32-api-1.5.1-universal-mingw32
Fetching: windows-api-0.4.2.gem (100%)
Successfully installed windows-api-0.4.2
2 gems installed

I've even tried explicitly specify win32-api in my Gemfile:

gem 'win32-api'

But it appears bundler doesn't match on universal gems, and is likely a bug. I am guessing the same issue doesn't trigger with ffi, because version 1.9.3 is published as x86 and x64.

Would you be willing to publish win32-api as both x86 and x64?

release 1.6.0

  • Support Ruby 2.3.0 (both of 32 bit and 64 bit versions)
  • Add AppVeyor CI support (building and testing)
    • Change Ruby 2.0.0 installation paths
      • Ruby 2.0.0 x86 should be placed at C:\Ruby200\bin
      • Ruby 2.0.0 x64 should be placed at C:\Ruby200-x64\bin
  • Bump up version to 1.6.0
    • Because #18 drops Ruby 1.8.7 and 1.9.3. So, it should be treated as major version up.
  • Add CHANGES entry for 1.6.0
  • Remove maintainer wanted! section from README
  • Push win32-api-1.6.0-universal-mingw32.gem to rubygems
  • Add win32-api-1.6.0 tag

Appveyor.yml

Saw mention in Ruby bug 13746. I'm not sure, but I think that the appveyor.yml file could be simplified a bit if one added rdevkit as a parameter to the rake commands, ie

bundle exec rake test:all

with

bundle exec rake -rdevkit test:all

Since rdevkit should set up the compile env for all versions...

I could look at a PR. Interested in adding a trunk build?

A Wiki

This seems like a very useful gem! However there is no wiki, not even instructions on how to install this.

I know that may be "common" information, but it helps.

Callback function causes crash on latest RubyInstaller (e.g. 2.7.5)

Currently a test is omitted due to a crash bug on latest RubyInstaller such as v2.7.5:

https://github.com/cosmo0920/win32-api/runs/4948175686?check_suite_focus=true#step:5:63

2022-01-26T07:36:27.1610716Z -- C level backtrace information -------------------------------------------
2022-01-26T07:36:27.1669065Z C:\Windows\SYSTEM32\ntdll.dll(NtWaitForSingleObject+0x14) [0x00007ffdee1ffa74]
2022-01-26T07:36:27.1697069Z C:\Windows\System32\KERNELBASE.dll(WaitForSingleObjectEx+0x93) [0x00007ffdead985c3]
2022-01-26T07:36:27.1698753Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_vm_bugreport+0x34b) [0x00007ffdb8bc78bb]
2022-01-26T07:36:27.1703138Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_bug_for_fatal_signal+0x7f) [0x00007ffdb89e04cf]
2022-01-26T07:36:27.1708470Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(ruby_sysinit+0x790) [0x00007ffdb8b214c0]
2022-01-26T07:36:27.1725023Z  [0x00007ff6f3d71f32]
2022-01-26T07:36:27.1726769Z C:\Windows\System32\msvcrt.dll(_C_specific_handler+0x98) [0x00007ffdedd08068]
2022-01-26T07:36:27.1727500Z C:\Windows\SYSTEM32\ntdll.dll(_chkstk+0x11f) [0x00007ffdee204a2f]
2022-01-26T07:36:27.1728861Z C:\Windows\SYSTEM32\ntdll.dll(RtlWalkFrameChain+0x14bf) [0x00007ffdee164cef]
2022-01-26T07:36:27.1730164Z C:\Windows\SYSTEM32\ntdll.dll(KiUserExceptionDispatcher+0x2e) [0x00007ffdee20379e]
2022-01-26T07:36:27.1731281Z C:\Windows\System32\msvcrt.dll(strlen+0x31) [0x00007ffdedd3d721]
2022-01-26T07:36:27.1738352Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_str_new_cstr+0x1b) [0x00007ffdb8b3c74b]
2022-01-26T07:36:27.1738817Z  [0x00007ffdb94e36c5]
2022-01-26T07:36:27.1752100Z  [0x00007ffdb94e4b74]
2022-01-26T07:36:27.1754341Z C:\Windows\System32\USER32.dll(EnumChildWindows+0x18d) [0x00007ffded53082d]
2022-01-26T07:36:27.1755107Z C:\Windows\System32\USER32.dll(EnumWindows+0x25) [0x00007ffded530695]
2022-01-26T07:36:27.1755517Z  [0x00007ffdb94e21d3]
2022-01-26T07:36:27.1757371Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_error_arity+0x353) [0x00007ffdb8b9fd33]
2022-01-26T07:36:27.1759110Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_add_method+0x359) [0x00007ffdb8bb61c9]
2022-01-26T07:36:27.1760986Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_vm_exec+0x231) [0x00007ffdb8baa8d1]
2022-01-26T07:36:27.1762926Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_yield_force_blockarg+0x68d) [0x00007ffdb8bae40d]
2022-01-26T07:36:27.1764557Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_block_call_kw+0x2f8) [0x00007ffdb8ba5248]
2022-01-26T07:36:27.1766193Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_catch+0xe4) [0x00007ffdb8ba54d4]
2022-01-26T07:36:27.1768201Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_error_arity+0x353) [0x00007ffdb8b9fd33]
2022-01-26T07:36:27.1769841Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_add_method+0x359) [0x00007ffdb8bb61c9]
2022-01-26T07:36:27.1771793Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_vm_exec+0x231) [0x00007ffdb8baa8d1]
2022-01-26T07:36:27.1773569Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_yield_force_blockarg+0x68d) [0x00007ffdb8bae40d]
2022-01-26T07:36:27.1775181Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_block_call_kw+0x2f8) [0x00007ffdb8ba5248]
2022-01-26T07:36:27.1776703Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_catch+0xe4) [0x00007ffdb8ba54d4]
2022-01-26T07:36:27.1778605Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_error_arity+0x353) [0x00007ffdb8b9fd33]
2022-01-26T07:36:27.1780251Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_add_method+0x359) [0x00007ffdb8bb61c9]
2022-01-26T07:36:27.1781922Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_vm_exec+0x231) [0x00007ffdb8baa8d1]
2022-01-26T07:36:27.1783646Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_proc_call+0x81) [0x00007ffdb8aca3f1]
2022-01-26T07:36:27.1785256Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_ec_error_print+0x620) [0x00007ffdb89e8700]
2022-01-26T07:36:27.1786843Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_ec_error_print+0x9e7) [0x00007ffdb89e8ac7]
2022-01-26T07:36:27.1788117Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(rb_ec_error_print+0xca0) [0x00007ffdb89e8d80]
2022-01-26T07:36:27.1789805Z C:\hostedtoolcache\windows\Ruby\2.7.5\x64\bin\x64-msvcrt-ruby270.dll(ruby_run_node+0x9f) [0x00007ffdb89e980f]
2022-01-26T07:36:27.1790336Z  [0x00007ff6f3d727f9]
2022-01-26T07:36:27.1790745Z  [0x00007ff6f3d713b1]
2022-01-26T07:36:27.1808565Z  [0x00007ff6f3d714e6]
2022-01-26T07:36:27.1810018Z C:\Windows\System32\KERNEL32.DLL(BaseThreadInitThunk+0x14) [0x00007ffdeb5e7974]
2022-01-26T07:36:27.1817396Z 

I'm investigating it.

Getting-Started wiki page small typo

There is a small typo in the wiki, page Getting-Started.

The line
dwptr = [buf.size].pack('L') # This effectively gives us a pointer address

should be
dwptr = [buffer.size].pack('L') # This effectively gives us a pointer address

otherwise the code won't run as is.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.