win32-api 1.5.3-universal-mingw32 → 1.6.0-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (358) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +174 -169
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +24 -0
  5. data/README +129 -131
  6. data/Rakefile +185 -182
  7. data/appveyor.yml +42 -0
  8. data/ext/win32/api.c +1092 -1092
  9. data/lib/win32/api.rb +14 -8
  10. data/lib/win32/ruby21_32/win32/api.so +0 -0
  11. data/lib/win32/ruby21_64/win32/api.so +0 -0
  12. data/lib/win32/ruby22_32/win32/api.so +0 -0
  13. data/lib/win32/ruby22_64/win32/api.so +0 -0
  14. data/lib/win32/ruby23_32/win32/api.so +0 -0
  15. data/lib/win32/ruby23_64/win32/api.so +0 -0
  16. data/lib/win32/ruby2_32/win32/api.so +0 -0
  17. data/lib/win32/ruby2_64/win32/api.so +0 -0
  18. data/test/test_win32_api.rb +145 -145
  19. data/vendor/bundle/ruby/2.2.0/bin/devkit +23 -0
  20. data/vendor/bundle/ruby/2.2.0/bin/devkit.bat +6 -0
  21. data/vendor/bundle/ruby/2.2.0/bin/rake +23 -0
  22. data/vendor/bundle/ruby/2.2.0/bin/rake.bat +6 -0
  23. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/CHANGELOG +55 -0
  24. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/LICENSE +339 -0
  25. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/README.md +73 -0
  26. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/Rakefile +8 -0
  27. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/colorize.gemspec +35 -0
  28. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/lib/colorize.rb +12 -0
  29. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/lib/colorize/class_methods.rb +116 -0
  30. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/lib/colorize/instance_methods.rb +135 -0
  31. data/vendor/bundle/ruby/2.2.0/gems/colorize-0.7.7/test/test_colorize.rb +161 -0
  32. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/Gemfile +4 -0
  33. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/LICENSE.txt +22 -0
  34. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/README.md +34 -0
  35. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/Rakefile +1 -0
  36. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/Rspec-example-matchers.txt +184 -0
  37. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/bin/devkit +87 -0
  38. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/devkit.gemspec +27 -0
  39. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/lib/devkit.rb +18 -0
  40. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/lib/devkit/core.rb +53 -0
  41. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/lib/devkit/identity.rb +78 -0
  42. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/lib/devkit/ssh_identity.rb +53 -0
  43. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/lib/devkit/version.rb +3 -0
  44. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/spec/devkit/core_spec.rb +46 -0
  45. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/spec/devkit/identity_spec.rb +1 -0
  46. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/spec/devkit/ssh_identity_spec.rb +1 -0
  47. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/spec/devkit_spec.rb +5 -0
  48. data/vendor/bundle/ruby/2.2.0/gems/devkit-0.1.0/spec/spec_helper.rb +8 -0
  49. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/AUTHORS +3 -0
  50. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/COPYING +339 -0
  51. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/Changelog.md +415 -0
  52. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/Gemfile +9 -0
  53. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/INSTALL +59 -0
  54. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/LICENSE +7 -0
  55. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/README.rdoc +74 -0
  56. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/Rakefile +30 -0
  57. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/TODO +6 -0
  58. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/ansi_colors.rb +38 -0
  59. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/asking_for_arrays.rb +18 -0
  60. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/basic_usage.rb +75 -0
  61. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/color_scheme.rb +32 -0
  62. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/get_character.rb +12 -0
  63. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/limit.rb +12 -0
  64. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/menus.rb +65 -0
  65. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/overwrite.rb +19 -0
  66. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/page_and_wrap.rb +322 -0
  67. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/password.rb +7 -0
  68. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/repeat_entry.rb +21 -0
  69. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/trapping_eof.rb +22 -0
  70. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/examples/using_readline.rb +17 -0
  71. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/highline.gemspec +37 -0
  72. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline.rb +1048 -0
  73. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/color_scheme.rb +134 -0
  74. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/compatibility.rb +16 -0
  75. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/import.rb +41 -0
  76. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/menu.rb +381 -0
  77. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/question.rb +480 -0
  78. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/simulate.rb +48 -0
  79. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/style.rb +192 -0
  80. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/lib/highline/version.rb +4 -0
  81. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/setup.rb +1360 -0
  82. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/site/highline.css +65 -0
  83. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/site/images/logo.png +0 -0
  84. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/site/index.html +58 -0
  85. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/string_methods.rb +32 -0
  86. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_color_scheme.rb +96 -0
  87. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_highline.rb +1402 -0
  88. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_import.rb +52 -0
  89. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_menu.rb +439 -0
  90. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_simulator.rb +23 -0
  91. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_string_highline.rb +38 -0
  92. data/vendor/bundle/ruby/2.2.0/gems/highline-1.7.8/test/tc_style.rb +578 -0
  93. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/BSDL +22 -0
  94. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/COPYING +57 -0
  95. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/Gemfile +9 -0
  96. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/LEGAL +4 -0
  97. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/README.rdoc +19 -0
  98. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/Rakefile +16 -0
  99. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/benchmarks/bm_yhpg.rb +59 -0
  100. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/benchmarks/helper.rb +8 -0
  101. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/lib/power_assert.rb +338 -0
  102. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/lib/power_assert/enable_tracepoint_events.rb +82 -0
  103. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/lib/power_assert/version.rb +3 -0
  104. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/power_assert.gemspec +23 -0
  105. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/test/helper.rb +10 -0
  106. data/vendor/bundle/ruby/2.2.0/gems/power_assert-0.3.0/test/test_power_assert.rb +512 -0
  107. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/CONTRIBUTING.rdoc +38 -0
  108. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/History.rdoc +719 -0
  109. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/MIT-LICENSE +21 -0
  110. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/Manifest.txt +154 -0
  111. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/README.rdoc +157 -0
  112. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/Rakefile +82 -0
  113. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/bin/rake +33 -0
  114. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/command_line_usage.rdoc +158 -0
  115. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/example/Rakefile1 +38 -0
  116. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/example/Rakefile2 +35 -0
  117. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/example/a.c +6 -0
  118. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/example/b.c +6 -0
  119. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/example/main.c +11 -0
  120. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/glossary.rdoc +42 -0
  121. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/jamis.rb +591 -0
  122. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/proto_rake.rdoc +127 -0
  123. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/rake.1 +141 -0
  124. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/rakefile.rdoc +624 -0
  125. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/rational.rdoc +151 -0
  126. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.4.14.rdoc +23 -0
  127. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.4.15.rdoc +35 -0
  128. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.5.0.rdoc +53 -0
  129. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.5.3.rdoc +78 -0
  130. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.5.4.rdoc +46 -0
  131. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.6.0.rdoc +141 -0
  132. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.7.0.rdoc +119 -0
  133. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.7.1.rdoc +59 -0
  134. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.7.2.rdoc +121 -0
  135. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.7.3.rdoc +47 -0
  136. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.0.rdoc +114 -0
  137. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.2.rdoc +165 -0
  138. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.3.rdoc +112 -0
  139. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.4.rdoc +147 -0
  140. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.5.rdoc +53 -0
  141. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.6.rdoc +37 -0
  142. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.8.7.rdoc +55 -0
  143. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.0.rdoc +112 -0
  144. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.1.rdoc +52 -0
  145. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.2.2.rdoc +55 -0
  146. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.2.rdoc +49 -0
  147. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.3.rdoc +102 -0
  148. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.4.rdoc +60 -0
  149. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.5.rdoc +55 -0
  150. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-0.9.6.rdoc +64 -0
  151. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-10.0.0.rdoc +178 -0
  152. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-10.0.1.rdoc +58 -0
  153. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-10.0.2.rdoc +53 -0
  154. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-10.0.3.rdoc +191 -0
  155. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/doc/release_notes/rake-10.1.0.rdoc +61 -0
  156. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake.rb +73 -0
  157. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/application.rb +787 -0
  158. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/backtrace.rb +23 -0
  159. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/clean.rb +76 -0
  160. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/cloneable.rb +16 -0
  161. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/contrib/compositepublisher.rb +21 -0
  162. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/contrib/ftptools.rb +137 -0
  163. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/contrib/sshpublisher.rb +60 -0
  164. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/cpu_counter.rb +120 -0
  165. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/default_loader.rb +14 -0
  166. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/dsl_definition.rb +194 -0
  167. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/early_time.rb +21 -0
  168. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/file_creation_task.rb +24 -0
  169. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/file_list.rb +436 -0
  170. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/file_task.rb +46 -0
  171. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/file_utils.rb +123 -0
  172. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/invocation_chain.rb +56 -0
  173. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/invocation_exception_mixin.rb +16 -0
  174. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/late_time.rb +17 -0
  175. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/linked_list.rb +111 -0
  176. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/loaders/makefile.rb +53 -0
  177. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/multi_task.rb +13 -0
  178. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/name_space.rb +38 -0
  179. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/packagetask.rb +199 -0
  180. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/phony.rb +15 -0
  181. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/private_reader.rb +20 -0
  182. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/promise.rb +99 -0
  183. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/pseudo_status.rb +29 -0
  184. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/rake_module.rb +38 -0
  185. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/rake_test_loader.rb +22 -0
  186. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/rule_recursion_overflow_error.rb +20 -0
  187. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/scope.rb +42 -0
  188. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/task.rb +391 -0
  189. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/task_argument_error.rb +7 -0
  190. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/task_arguments.rb +102 -0
  191. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/task_manager.rb +316 -0
  192. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/tasklib.rb +11 -0
  193. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/testtask.rb +204 -0
  194. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/thread_history_display.rb +48 -0
  195. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/thread_pool.rb +163 -0
  196. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/trace_output.rb +22 -0
  197. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/version.rb +7 -0
  198. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/lib/rake/win32.rb +50 -0
  199. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/rakelib/test_times.rake +25 -0
  200. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/file_creation.rb +34 -0
  201. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/helper.rb +134 -0
  202. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/support/rakefile_definitions.rb +476 -0
  203. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/support/ruby_runner.rb +34 -0
  204. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_private_reader.rb +42 -0
  205. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake.rb +40 -0
  206. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_application.rb +659 -0
  207. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_application_options.rb +468 -0
  208. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_backtrace.rb +119 -0
  209. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_clean.rb +61 -0
  210. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_cpu_counter.rb +68 -0
  211. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_definitions.rb +84 -0
  212. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_directory_task.rb +76 -0
  213. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_dsl.rb +40 -0
  214. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_early_time.rb +31 -0
  215. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_file_creation_task.rb +56 -0
  216. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_file_list.rb +687 -0
  217. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_file_list_path_map.rb +15 -0
  218. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_file_task.rb +197 -0
  219. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_file_utils.rb +318 -0
  220. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_ftp_file.rb +74 -0
  221. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_functional.rb +484 -0
  222. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_invocation_chain.rb +64 -0
  223. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_late_time.rb +18 -0
  224. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_linked_list.rb +84 -0
  225. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_makefile_loader.rb +46 -0
  226. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_multi_task.rb +64 -0
  227. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_name_space.rb +57 -0
  228. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_package_task.rb +79 -0
  229. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_path_map.rb +168 -0
  230. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_path_map_explode.rb +34 -0
  231. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_path_map_partial.rb +18 -0
  232. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_pseudo_status.rb +21 -0
  233. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_rake_test_loader.rb +20 -0
  234. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_reduce_compat.rb +26 -0
  235. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_require.rb +40 -0
  236. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_rules.rb +388 -0
  237. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_scope.rb +44 -0
  238. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task.rb +430 -0
  239. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task_argument_parsing.rb +119 -0
  240. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task_arguments.rb +134 -0
  241. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task_manager.rb +178 -0
  242. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task_manager_argument_resolution.rb +19 -0
  243. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_task_with_arguments.rb +172 -0
  244. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_test_task.rb +130 -0
  245. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_thread_pool.rb +145 -0
  246. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_top_level_functions.rb +71 -0
  247. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_rake_win32.rb +72 -0
  248. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_thread_history_display.rb +101 -0
  249. data/vendor/bundle/ruby/2.2.0/gems/rake-11.1.2/test/test_trace_output.rb +52 -0
  250. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/COPYING +64 -0
  251. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/GPL +339 -0
  252. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/LGPL +502 -0
  253. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/PSFL +271 -0
  254. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/README.md +101 -0
  255. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/Rakefile +71 -0
  256. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test-unit.rb +34 -0
  257. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit.rb +505 -0
  258. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/assertion-failed-error.rb +25 -0
  259. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/assertions.rb +2218 -0
  260. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/attribute-matcher.rb +26 -0
  261. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/attribute.rb +158 -0
  262. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/auto-runner-loader.rb +17 -0
  263. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/autorunner.rb +536 -0
  264. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/code-snippet-fetcher.rb +58 -0
  265. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector.rb +73 -0
  266. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector/descendant.rb +19 -0
  267. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector/dir.rb +108 -0
  268. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector/load.rb +202 -0
  269. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector/objectspace.rb +34 -0
  270. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/collector/xml.rb +249 -0
  271. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/color-scheme.rb +198 -0
  272. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/color.rb +134 -0
  273. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/data.rb +262 -0
  274. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/diff.rb +746 -0
  275. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/error.rb +158 -0
  276. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/exception-handler.rb +82 -0
  277. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/failure.rb +169 -0
  278. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/fault-location-detector.rb +100 -0
  279. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/fixture.rb +295 -0
  280. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/notification.rb +136 -0
  281. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/omission.rb +195 -0
  282. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/pending.rb +154 -0
  283. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/priority.rb +192 -0
  284. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/runner/console.rb +59 -0
  285. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/runner/emacs.rb +8 -0
  286. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/runner/xml.rb +15 -0
  287. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/test-suite-creator.rb +89 -0
  288. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/testcase.rb +811 -0
  289. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/testresult.rb +132 -0
  290. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/testsuite.rb +175 -0
  291. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/console/outputlevel.rb +15 -0
  292. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/console/testrunner.rb +693 -0
  293. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/emacs/testrunner.rb +49 -0
  294. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/testrunner.rb +53 -0
  295. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/testrunnermediator.rb +114 -0
  296. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  297. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/ui/xml/testrunner.rb +224 -0
  298. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/util/backtracefilter.rb +59 -0
  299. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/util/method-owner-finder.rb +28 -0
  300. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/util/observable.rb +90 -0
  301. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/util/output.rb +31 -0
  302. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/util/procwrapper.rb +48 -0
  303. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/lib/test/unit/version.rb +5 -0
  304. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/sample/adder.rb +13 -0
  305. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/sample/subtracter.rb +12 -0
  306. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/sample/test_adder.rb +20 -0
  307. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/sample/test_subtracter.rb +20 -0
  308. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/sample/test_user.rb +23 -0
  309. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/collector/test-descendant.rb +178 -0
  310. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/collector/test-load.rb +442 -0
  311. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/collector/test_dir.rb +406 -0
  312. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/collector/test_objectspace.rb +100 -0
  313. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/header-label.csv +3 -0
  314. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/header-label.tsv +3 -0
  315. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/header.csv +3 -0
  316. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/header.tsv +3 -0
  317. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/no-header.csv +2 -0
  318. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/no-header.tsv +2 -0
  319. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/fixtures/plus.csv +3 -0
  320. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/run-test.rb +22 -0
  321. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-assertions.rb +2160 -0
  322. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-attribute-matcher.rb +38 -0
  323. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-attribute.rb +123 -0
  324. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-code-snippet.rb +37 -0
  325. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-color-scheme.rb +82 -0
  326. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-color.rb +47 -0
  327. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-data.rb +303 -0
  328. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-diff.rb +518 -0
  329. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-emacs-runner.rb +60 -0
  330. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-error.rb +26 -0
  331. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-failure.rb +33 -0
  332. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-fault-location-detector.rb +163 -0
  333. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-fixture.rb +713 -0
  334. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-notification.rb +33 -0
  335. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-omission.rb +81 -0
  336. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-pending.rb +70 -0
  337. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-priority.rb +173 -0
  338. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-test-case.rb +1171 -0
  339. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-test-result.rb +113 -0
  340. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-test-suite-creator.rb +97 -0
  341. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/test-test-suite.rb +150 -0
  342. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/testunit-test-util.rb +31 -0
  343. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/ui/test_testrunmediator.rb +20 -0
  344. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/util/test-method-owner-finder.rb +38 -0
  345. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/util/test-output.rb +11 -0
  346. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/util/test_backtracefilter.rb +52 -0
  347. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/util/test_observable.rb +102 -0
  348. data/vendor/bundle/ruby/2.2.0/gems/test-unit-3.1.9/test/util/test_procwrapper.rb +36 -0
  349. data/vendor/bundle/ruby/2.2.0/specifications/colorize-0.7.7.gemspec +38 -0
  350. data/vendor/bundle/ruby/2.2.0/specifications/devkit-0.1.0.gemspec +46 -0
  351. data/vendor/bundle/ruby/2.2.0/specifications/highline-1.7.8.gemspec +37 -0
  352. data/vendor/bundle/ruby/2.2.0/specifications/power_assert-0.3.0.gemspec +41 -0
  353. data/vendor/bundle/ruby/2.2.0/specifications/rake-11.1.2.gemspec +43 -0
  354. data/vendor/bundle/ruby/2.2.0/specifications/test-unit-3.1.9.gemspec +47 -0
  355. data/win32-api.gemspec +27 -27
  356. metadata +345 -5
  357. data/lib/win32/ruby18/win32/api.so +0 -0
  358. data/lib/win32/ruby19/win32/api.so +0 -0
data/Rakefile CHANGED
@@ -1,182 +1,185 @@
1
- require 'rake'
2
- require 'rake/clean'
3
- require 'rake/testtask'
4
- require 'rbconfig'
5
- include RbConfig
6
-
7
- CLEAN.include(
8
- '**/*.gem', # Gem files
9
- '**/*.rbc', # Rubinius
10
- '**/*.o', # C object file
11
- '**/*.log', # Ruby extension build log
12
- '**/Makefile', # C Makefile
13
- '**/*.def', # Definition files
14
- '**/*.exp',
15
- '**/*.lib',
16
- '**/*.pdb',
17
- '**/*.obj',
18
- '**/*.stackdump', # Junk that can happen on Windows
19
- "**/*.#{CONFIG['DLEXT']}" # C shared object
20
- )
21
-
22
- CLOBBER.include('lib') # Generated when building binaries
23
-
24
- make = CONFIG['host_os'] =~ /mingw|cygwin/i ? 'make' : 'nmake'
25
-
26
- desc 'Build the ruby.exe.manifest if it does not already exist'
27
- task :build_manifest do
28
- version = CONFIG['host_os'].split('_')[1]
29
-
30
- if version && version.to_i >= 80
31
- unless File.exist?(File.join(CONFIG['bindir'], 'ruby.exe.manifest'))
32
- Dir.chdir(CONFIG['bindir']) do
33
- sh "mt -nologo -inputresource:ruby.exe;2 -out:ruby.exe.manifest"
34
- end
35
- end
36
- end
37
- end
38
-
39
- desc "Build the win32-api library"
40
- task :build => [:clean, :build_manifest] do
41
- require 'devkit' if RbConfig::CONFIG['host_os'] =~ /mingw|cygwn/i
42
- Dir.chdir('ext') do
43
- ruby "extconf.rb"
44
- sh make
45
- cp 'api.so', 'win32' # For testing
46
- end
47
- end
48
-
49
- namespace 'gem' do
50
- require 'rubygems/package'
51
-
52
- desc 'Build the win32-api gem'
53
- task :create => [:clean] do
54
- spec = eval(IO.read('win32-api.gemspec'))
55
- if Gem::VERSION.to_f < 2.0
56
- Gem::Builder.new(spec).build
57
- else
58
- Gem::Package.build(spec)
59
- end
60
- end
61
-
62
- desc 'Build a binary gem'
63
- task :binary, :ruby18, :ruby19, :ruby2_32, :ruby2_64, :ruby21, :ruby21_64, :ruby22, :ruby22_64 do |task, args|
64
- require 'devkit' if RbConfig::CONFIG['host_os'] =~ /mingw|cygwn/i
65
-
66
- # These are just what's on my system at the moment. Adjust as needed.
67
- args.with_defaults(
68
- :ruby18 => "c:/ruby187/bin/ruby",
69
- :ruby19 => "c:/ruby193/bin/ruby",
70
- :ruby2_32 => "c:/ruby2/bin/ruby",
71
- :ruby2_64 => "c:/ruby264/bin/ruby",
72
- :ruby21_32 => "c:/ruby21/bin/ruby",
73
- :ruby21_64 => "c:/ruby21-x64/bin/ruby",
74
- :ruby22_32 => "c:/ruby22/bin/ruby",
75
- :ruby22_64 => "c:/ruby22-x64/bin/ruby"
76
- )
77
-
78
- Rake::Task[:clobber].invoke
79
-
80
- args.each{ |key, rubyx|
81
- # Adjust devkit paths as needed.
82
- if `"#{rubyx}" -v` =~ /x64/i
83
- ENV['PATH'] = "C:/Devkit64/bin;C:/Devkit64/mingw/bin;" + ENV['PATH']
84
- else
85
- ENV['PATH'] = "C:/Devkit/bin;C:/Devkit/mingw/bin;" + ENV['PATH']
86
- end
87
-
88
- mkdir_p "lib/win32/#{key}/win32"
89
-
90
- Dir.chdir('ext') do
91
- sh "make distclean" rescue nil
92
- sh "#{rubyx} extconf.rb"
93
- sh "make"
94
- cp 'api.so', "../lib/win32/#{key}/win32/api.so"
95
- end
96
- }
97
-
98
- text = <<HERE
99
- require 'rbconfig'
100
-
101
- case RbConfig::CONFIG['MAJOR']
102
- when '1'
103
- if RbConfig::CONFIG['MINOR'] == '8'
104
- require File.join(File.dirname(__FILE__), 'ruby18/win32/api')
105
- else
106
- require File.join(File.dirname(__FILE__), 'ruby19/win32/api')
107
- end
108
- when '2'
109
- if RbConfig::CONFIG['MINOR'] == '0'
110
- if RbConfig::CONFIG['arch'] =~ /x64/i
111
- require File.join(File.dirname(__FILE__), 'ruby2_64/win32/api')
112
- else
113
- require File.join(File.dirname(__FILE__), 'ruby2_32/win32/api')
114
- end
115
- end
116
-
117
- if RbConfig::CONFIG['MINOR'] == '1'
118
- if RbConfig::CONFIG['arch'] =~ /x64/i
119
- require File.join(File.dirname(__FILE__), 'ruby21_64/win32/api')
120
- else
121
- require File.join(File.dirname(__FILE__), 'ruby21_32/win32/api')
122
- end
123
- end
124
-
125
- if RbConfig::CONFIG['MINOR'] == '2'
126
- if RbConfig::CONFIG['arch'] =~ /x64/i
127
- require File.join(File.dirname(__FILE__), 'ruby22_64/win32/api')
128
- else
129
- require File.join(File.dirname(__FILE__), 'ruby22_32/win32/api')
130
- end
131
- end
132
- end
133
- HERE
134
-
135
- File.open('lib/win32/api.rb', 'w'){ |fh| fh.puts text }
136
-
137
- spec = eval(IO.read('win32-api.gemspec'))
138
- spec.platform = Gem::Platform.new(['universal', 'mingw32'])
139
- spec.extensions = nil
140
- spec.files = spec.files.reject{ |f| f.include?('ext') }
141
-
142
- if Gem::VERSION.to_f < 2.0
143
- Gem::Builder.new(spec).build
144
- else
145
- require 'rubygems/package'
146
- Gem::Package.build(spec)
147
- end
148
- end
149
-
150
- desc 'Install the gem'
151
- task :install => [:create] do
152
- file = Dir["*.gem"].first
153
- sh "gem install -l #{file}"
154
- end
155
- end
156
-
157
- namespace 'test' do
158
- Rake::TestTask.new(:all) do |test|
159
- task :all => [:build]
160
- test.libs << 'ext'
161
- test.warning = true
162
- test.verbose = true
163
- end
164
-
165
- Rake::TestTask.new(:callback) do |test|
166
- task :callback => [:build]
167
- test.test_files = FileList['test/test_win32_api_callback.rb']
168
- test.libs << 'ext'
169
- test.warning = true
170
- test.verbose = true
171
- end
172
-
173
- Rake::TestTask.new(:function) do |test|
174
- task :function => [:build]
175
- test.test_files = FileList['test/test_win32_api_function.rb']
176
- test.libs << 'ext'
177
- test.warning = true
178
- test.verbose = true
179
- end
180
- end
181
-
182
- task :default => 'test:all'
1
+ require 'rake'
2
+ require 'rake/clean'
3
+ require 'rake/testtask'
4
+ require 'rbconfig'
5
+ include RbConfig
6
+
7
+ CLEAN.include(
8
+ '**/*.gem', # Gem files
9
+ '**/*.rbc', # Rubinius
10
+ '**/*.o', # C object file
11
+ '**/*.log', # Ruby extension build log
12
+ '**/Makefile', # C Makefile
13
+ '**/*.def', # Definition files
14
+ '**/*.exp',
15
+ '**/*.lib',
16
+ '**/*.pdb',
17
+ '**/*.obj',
18
+ '**/*.stackdump', # Junk that can happen on Windows
19
+ "**/*.#{CONFIG['DLEXT']}" # C shared object
20
+ )
21
+
22
+ CLOBBER.include('lib') # Generated when building binaries
23
+
24
+ make = CONFIG['host_os'] =~ /mingw|cygwin/i ? 'make' : 'nmake'
25
+
26
+ desc 'Build the ruby.exe.manifest if it does not already exist'
27
+ task :build_manifest do
28
+ version = CONFIG['host_os'].split('_')[1]
29
+
30
+ if version && version.to_i >= 80
31
+ unless File.exist?(File.join(CONFIG['bindir'], 'ruby.exe.manifest'))
32
+ Dir.chdir(CONFIG['bindir']) do
33
+ sh "mt -nologo -inputresource:ruby.exe;2 -out:ruby.exe.manifest"
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ desc "Build the win32-api library"
40
+ task :build => [:clean, :build_manifest] do
41
+ Dir.chdir('ext') do
42
+ ruby "extconf.rb"
43
+ sh make
44
+ cp 'api.so', 'win32' # For testing
45
+ end
46
+ end
47
+
48
+ namespace 'gem' do
49
+ require 'rubygems/package'
50
+
51
+ desc 'Build the win32-api gem'
52
+ task :create => [:clean] do
53
+ spec = eval(IO.read('win32-api.gemspec'))
54
+ if Gem::VERSION.to_f < 2.0
55
+ Gem::Builder.new(spec).build
56
+ else
57
+ Gem::Package.build(spec)
58
+ end
59
+ end
60
+
61
+ desc 'Build a binary gem'
62
+ task :binary, :ruby2_32, :ruby2_64, :ruby21, :ruby21_64, :ruby22, :ruby22_64, :ruby23_32, :ruby23_64 do |task, args|
63
+ # These are just what's on my system at the moment. Adjust as needed.
64
+ args.with_defaults(
65
+ :ruby2_32 => "c:/ruby200/bin/ruby",
66
+ :ruby2_64 => "c:/ruby200-x64/bin/ruby",
67
+ :ruby21_32 => "c:/ruby21/bin/ruby",
68
+ :ruby21_64 => "c:/ruby21-x64/bin/ruby",
69
+ :ruby22_32 => "c:/ruby22/bin/ruby",
70
+ :ruby22_64 => "c:/ruby22-x64/bin/ruby",
71
+ :ruby23_32 => "c:/ruby23/bin/ruby",
72
+ :ruby23_64 => "c:/ruby23-x64/bin/ruby"
73
+ )
74
+
75
+ Rake::Task[:clobber].invoke
76
+
77
+ args.each{ |key, rubyx|
78
+ # Adjust devkit paths as needed.
79
+ if `"#{rubyx}" -v` =~ /x64/i
80
+ ENV['PATH'] = "C:/Devkit64/bin;C:/Devkit64/mingw/bin;" + ENV['PATH']
81
+ else
82
+ ENV['PATH'] = "C:/Devkit/bin;C:/Devkit/mingw/bin;" + ENV['PATH']
83
+ end
84
+
85
+ mkdir_p "lib/win32/#{key}/win32"
86
+
87
+ Dir.chdir('ext') do
88
+ sh "make distclean" rescue nil
89
+ sh "#{rubyx} extconf.rb"
90
+ sh "make"
91
+ cp 'api.so', "../lib/win32/#{key}/win32/api.so"
92
+ end
93
+ }
94
+
95
+ text = <<HERE
96
+ require 'rbconfig'
97
+ begin
98
+ case RbConfig::CONFIG['MAJOR']
99
+ when '2'
100
+ if RbConfig::CONFIG['MINOR'] == '0'
101
+ if RbConfig::CONFIG['arch'] =~ /x64/i
102
+ require File.join(File.dirname(__FILE__), 'ruby2_64/win32/api')
103
+ else
104
+ require File.join(File.dirname(__FILE__), 'ruby2_32/win32/api')
105
+ end
106
+ end
107
+
108
+ if RbConfig::CONFIG['MINOR'] == '1'
109
+ if RbConfig::CONFIG['arch'] =~ /x64/i
110
+ require File.join(File.dirname(__FILE__), 'ruby21_64/win32/api')
111
+ else
112
+ require File.join(File.dirname(__FILE__), 'ruby21_32/win32/api')
113
+ end
114
+ end
115
+
116
+ if RbConfig::CONFIG['MINOR'] == '2'
117
+ if RbConfig::CONFIG['arch'] =~ /x64/i
118
+ require File.join(File.dirname(__FILE__), 'ruby22_64/win32/api')
119
+ else
120
+ require File.join(File.dirname(__FILE__), 'ruby22_32/win32/api')
121
+ end
122
+ end
123
+
124
+ if RbConfig::CONFIG['MINOR'] == '3'
125
+ if RbConfig::CONFIG['arch'] =~ /x64/i
126
+ require File.join(File.dirname(__FILE__), 'ruby23_64/win32/api')
127
+ else
128
+ require File.join(File.dirname(__FILE__), 'ruby23_32/win32/api')
129
+ end
130
+ end
131
+
132
+ end
133
+ rescue LoadError
134
+ require File.join(File.dirname(__FILE__), '../../ext/api')
135
+ end
136
+ HERE
137
+
138
+ File.open('lib/win32/api.rb', 'w'){ |fh| fh.puts text }
139
+
140
+ spec = eval(IO.read('win32-api.gemspec'))
141
+ spec.platform = Gem::Platform.new(['universal', 'mingw32'])
142
+ spec.extensions = nil
143
+ spec.files = spec.files.reject{ |f| f.include?('ext') }
144
+
145
+ if Gem::VERSION.to_f < 2.0
146
+ Gem::Builder.new(spec).build
147
+ else
148
+ require 'rubygems/package'
149
+ Gem::Package.build(spec)
150
+ end
151
+ end
152
+
153
+ desc 'Install the gem'
154
+ task :install => [:create] do
155
+ file = Dir["*.gem"].first
156
+ sh "gem install -l #{file}"
157
+ end
158
+ end
159
+
160
+ namespace 'test' do
161
+ Rake::TestTask.new(:all) do |test|
162
+ task :all => [:build]
163
+ test.libs << 'ext'
164
+ test.warning = true
165
+ test.verbose = true
166
+ end
167
+
168
+ Rake::TestTask.new(:callback) do |test|
169
+ task :callback => [:build]
170
+ test.test_files = FileList['test/test_win32_api_callback.rb']
171
+ test.libs << 'ext'
172
+ test.warning = true
173
+ test.verbose = true
174
+ end
175
+
176
+ Rake::TestTask.new(:function) do |test|
177
+ task :function => [:build]
178
+ test.test_files = FileList['test/test_win32_api_function.rb']
179
+ test.libs << 'ext'
180
+ test.warning = true
181
+ test.verbose = true
182
+ end
183
+ end
184
+
185
+ task :default => 'test:all'
@@ -0,0 +1,42 @@
1
+ version: '{build}'
2
+
3
+ platform: x64
4
+
5
+ install:
6
+ - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
7
+ - "%devkit64%\\devkitvars.bat"
8
+ - "%devkit32%\\devkitvars.bat"
9
+ - ruby --version
10
+ - gem --version
11
+ - bundle install
12
+ build: off
13
+ test_script:
14
+ - bundle exec rake gem:binary
15
+ - bundle exec rake test:all
16
+
17
+ environment:
18
+ matrix:
19
+ - ruby_version: "23-x64"
20
+ devkit64: C:\Ruby23-x64\DevKit
21
+ devkit32: C:\Ruby23\DevKit
22
+ - ruby_version: "23"
23
+ devkit64: C:\Ruby23-x64\DevKit
24
+ devkit32: C:\Ruby23\DevKit
25
+ - ruby_version: "22-x64"
26
+ devkit64: C:\Ruby23-x64\DevKit
27
+ devkit32: C:\Ruby23\DevKit
28
+ - ruby_version: "22"
29
+ devkit64: C:\Ruby23-x64\DevKit
30
+ devkit32: C:\Ruby23\DevKit
31
+ - ruby_version: "21-x64"
32
+ devkit64: C:\Ruby23-x64\DevKit
33
+ devkit32: C:\Ruby23\DevKit
34
+ - ruby_version: "21"
35
+ devkit64: C:\Ruby23-x64\DevKit
36
+ devkit32: C:\Ruby23\DevKit
37
+ - ruby_version: "200-x64"
38
+ devkit64: C:\Ruby23-x64\DevKit
39
+ devkit32: C:\Ruby23\DevKit
40
+ - ruby_version: "200"
41
+ devkit64: C:\Ruby23-x64\DevKit
42
+ devkit32: C:\Ruby23\DevKit
@@ -1,1092 +1,1092 @@
1
- #include <ruby.h>
2
- #include <windows.h>
3
-
4
- // Ruby 1.9.x
5
- #ifndef RSTRING_PTR
6
- #define RSTRING_PTR(s) (RSTRING(s)->ptr)
7
- #endif
8
- #ifndef RSTRING_LEN
9
- #define RSTRING_LEN(s) (RSTRING(s)->len)
10
- #endif
11
-
12
- #ifndef RARRAY_PTR
13
- #define RARRAY_PTR(a) (RARRAY(a)->ptr)
14
- #endif
15
- #ifndef RARRAY_LEN
16
- #define RARRAY_LEN(a) (RARRAY(a)->len)
17
- #endif
18
-
19
- #if defined(HAVE_LONG_LONG) && SIZEOF_SIZE_T > SIZEOF_LONG
20
- # define NUM2SIZET(x) ((size_t)NUM2ULL(x))
21
- # define NUM2SSIZET(x) ((ssize_t)NUM2LL(x))
22
- #else
23
- # define NUM2SIZET(x) NUM2ULONG(x)
24
- # define NUM2SSIZET(x) NUM2LONG(x)
25
- #endif
26
-
27
- #if SIZEOF_SIZE_T > SIZEOF_LONG && defined(HAVE_LONG_LONG)
28
- # define SIZET2NUM(v) ULL2NUM(v)
29
- # define SSIZET2NUM(v) LL2NUM(v)
30
- #elif SIZEOF_SIZE_T == SIZEOF_LONG
31
- # define SIZET2NUM(v) ULONG2NUM(v)
32
- # define SSIZET2NUM(v) LONG2NUM(v)
33
- #else
34
- # define SIZET2NUM(v) UINT2NUM(v)
35
- # define SSIZET2NUM(v) INT2NUM(v)
36
- #endif
37
-
38
-
39
- #define MAX_BUF 1024
40
- #define WINDOWS_API_VERSION "1.5.3"
41
-
42
- #define _T_VOID 0
43
- #define _T_LONG 1
44
- #define _T_POINTER 2
45
- #define _T_INTEGER 3
46
- #define _T_CALLBACK 4
47
- #define _T_STRING 5
48
-
49
- VALUE cAPIError, cAPIProtoError, cAPILoadError;
50
- static VALUE ActiveCallback = Qnil;
51
-
52
- typedef struct {
53
- HANDLE library;
54
- FARPROC function;
55
- int return_type;
56
- int prototype[20];
57
- } Win32API;
58
-
59
- static void api_free(Win32API* ptr){
60
- if(ptr->library)
61
- FreeLibrary(ptr->library);
62
-
63
- if(ptr)
64
- free(ptr);
65
- }
66
-
67
- static VALUE api_allocate(VALUE klass){
68
- Win32API* ptr = malloc(sizeof(Win32API));
69
- memset(ptr, 0, sizeof(*ptr));
70
- return Data_Wrap_Struct(klass, 0, api_free, ptr);
71
- }
72
-
73
- /* Helper function that converts the error number returned by GetLastError()
74
- * into a human readable string. Note that we always use English for error
75
- * output because that's what Ruby itself does.
76
- *
77
- * Internal use only.
78
- */
79
- char* StringError(DWORD dwError){
80
- LPVOID lpMsgBuf;
81
- static char buf[MAX_PATH];
82
- DWORD dwLen, dwLastError;
83
-
84
- // Assume ASCII (English) error messages from the Windows API
85
- dwLen = FormatMessageA(
86
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
87
- FORMAT_MESSAGE_FROM_SYSTEM |
88
- FORMAT_MESSAGE_IGNORE_INSERTS,
89
- NULL,
90
- dwError,
91
- MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
92
- (LPSTR)&lpMsgBuf,
93
- 0,
94
- NULL
95
- );
96
-
97
- dwLastError = GetLastError();
98
-
99
- /* It appears that Windows doesn't necessarily ship with the DLL
100
- * required to always use English error messages. Check for error
101
- * ERROR_MUI_FILE_NOT_FOUND (15100) or ERROR_RESOURCE_LANG_NOT_FOUND (1815)
102
- * and try again if necessary.
103
- */
104
- if(!dwLen && (dwLastError == 15100 || dwLastError == 1815)){
105
- dwLen = FormatMessageA(
106
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
107
- FORMAT_MESSAGE_FROM_SYSTEM |
108
- FORMAT_MESSAGE_IGNORE_INSERTS,
109
- NULL,
110
- dwError,
111
- 0,
112
- (LPSTR)&lpMsgBuf,
113
- 0,
114
- NULL
115
- );
116
- }
117
-
118
- if(!dwLen){
119
- rb_raise(
120
- cAPIError,
121
- "Attempt to format message failed (error = '%lu')",
122
- GetLastError()
123
- );
124
- }
125
-
126
- memset(buf, 0, MAX_PATH);
127
-
128
- // Remove \r\n at end of string.
129
- #ifdef HAVE_STRNCPY_S
130
- strncpy_s(buf, MAX_PATH, lpMsgBuf, dwLen - 2);
131
- #else
132
- strncpy(buf, lpMsgBuf, dwLen - 2);
133
- #endif
134
-
135
- LocalFree(lpMsgBuf);
136
-
137
- return buf;
138
- }
139
-
140
- /*
141
- * call-seq:
142
- * Win32::API::Callback.new(prototype, return='L'){ |proto| ... }
143
- *
144
- * Creates and returns a new Win32::API::Callback object. The prototype
145
- * arguments are yielded back to the block in the same order they were
146
- * declared.
147
- *
148
- * The +prototype+ is the function prototype for the callback function. This
149
- * is a string. The possible valid characters are 'I' (integer), 'L' (long),
150
- * 'V' (void), 'P' (pointer) or 'S' (string). Unlike API objects, API::Callback
151
- * objects do not have a default prototype.
152
- *
153
- * The +return+ argument is the return type for the callback function. The
154
- * valid characters are the same as for the +prototype+. The default is
155
- * 'L' (long).
156
- *
157
- * Example:
158
- * require 'win32/api'
159
- * include Win32
160
- *
161
- * EnumWindows = API.new('EnumWindows', 'KP', 'L', 'user32')
162
- * GetWindowText = API.new('GetWindowText', 'LPI', 'I', 'user32')
163
- *
164
- * EnumWindowsProc = API::Callback.new('LP', 'I'){ |handle, param|
165
- * buf = "\0" * 200
166
- * GetWindowText.call(handle, buf, 200);
167
- * puts buf.strip unless buf.strip.empty?
168
- * buf.index(param).nil? ? true : false
169
- * }
170
- *
171
- * EnumWindows.call(EnumWindowsProc, 'UEDIT32')
172
- */
173
- static VALUE callback_init(int argc, VALUE* argv, VALUE self)
174
- {
175
- void *find_callback(VALUE,int);
176
- VALUE v_proto, v_return, v_proc;
177
- int i;
178
-
179
- rb_scan_args(argc, argv, "11&", &v_proto, &v_return, &v_proc);
180
-
181
- /* Validate prototype characters */
182
- for(i = 0; i < RSTRING_LEN(v_proto); i++){
183
- switch(RSTRING_PTR(v_proto)[i]){
184
- case 'I': case 'L': case 'P': case 'V': case 'S':
185
- break;
186
- default:
187
- rb_raise(cAPIProtoError, "Illegal prototype '%c'",
188
- RSTRING_PTR(v_proto)[i]
189
- );
190
- }
191
- }
192
-
193
- if(NIL_P(v_return) || RARRAY_LEN(v_return) == 0){
194
- v_return = rb_str_new2("L");
195
- }
196
- else{
197
- switch(*(TCHAR*)RSTRING_PTR(v_return)){
198
- case 'I': case 'L': case 'P': case 'V': case 'S':
199
- break;
200
- default:
201
- rb_raise(cAPIProtoError, "Illegal return type '%s'",
202
- RSTRING_PTR(v_return)
203
- );
204
- }
205
- }
206
-
207
- rb_iv_set(self, "@function", v_proc);
208
- rb_iv_set(self, "@prototype", v_proto);
209
- rb_iv_set(self, "@return_type", v_return);
210
- rb_iv_set(self, "@address", SIZET2NUM((LPARAM)find_callback(self,RSTRING_LEN(v_proto))));
211
- ActiveCallback = self;
212
-
213
- return self;
214
- }
215
-
216
- /*
217
- * call-seq:
218
- * Win32::API.new(function, prototype='V', return='L', dll='kernel32')
219
- *
220
- * Creates and returns a new Win32::API object. The +function+ is the name
221
- * of the Windows function.
222
- *
223
- * The +prototype+ is the function prototype for +function+. This can be a
224
- * string or an array of characters. The possible valid characters are 'I'
225
- * (integer), 'L' (long), 'V' (void), 'P' (pointer), 'K' (callback) or 'S'
226
- * (string).
227
- *
228
- * The default is void ('V').
229
- *
230
- * Constant (const char*) strings should use 'S'. Pass by reference string
231
- * buffers should use 'P'. The former is faster, but cannot be modified.
232
- *
233
- * The +return+ argument is the return type for the function. The valid
234
- * characters are the same as for the +prototype+. The default is 'L' (long).
235
- *
236
- * The +dll+ is the name of the DLL file that the function is exported from.
237
- * The default is 'kernel32'.
238
- *
239
- * If the function cannot be found then an API::Error is raised (a subclass
240
- * of RuntimeError).
241
- *
242
- * Example:
243
- *
244
- * require 'win32/api'
245
- * include Win32
246
- *
247
- * buf = 0.chr * 260
248
- * len = [buf.length].pack('L')
249
- *
250
- * GetUserName = API.new('GetUserName', 'PP', 'I', 'advapi32')
251
- * GetUserName.call(buf, len)
252
- *
253
- * puts buf.strip
254
- */
255
- static VALUE api_init(int argc, VALUE* argv, VALUE self)
256
- {
257
- HMODULE hLibrary;
258
- FARPROC fProc;
259
- Win32API* ptr;
260
- int i;
261
- const char* first = "A";
262
- const char* second = "W";
263
- VALUE v_proc, v_proto, v_return, v_dll;
264
-
265
- rb_scan_args(argc, argv, "13", &v_proc, &v_proto, &v_return, &v_dll);
266
-
267
- Data_Get_Struct(self, Win32API, ptr);
268
-
269
- // Convert a string prototype to an array of characters
270
- if(rb_respond_to(v_proto, rb_intern("split")))
271
- v_proto = rb_str_split(v_proto, "");
272
-
273
- // Convert a nil or empty prototype to 'V' (void) automatically
274
- if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
275
- v_proto = rb_ary_new();
276
- rb_ary_push(v_proto, rb_str_new2("V"));
277
- }
278
-
279
- // Set an arbitrary limit of 20 parameters
280
- if(RARRAY_LEN(v_proto) > 20)
281
- rb_raise(rb_eArgError, "too many parameters: %ld", RARRAY_LEN(v_proto));
282
-
283
- // Set the default dll to 'kernel32'
284
- if(NIL_P(v_dll))
285
- v_dll = rb_str_new2("kernel32");
286
-
287
- // Set the default return type to 'L' (DWORD)
288
- if(NIL_P(v_return))
289
- v_return = rb_str_new2("L");
290
-
291
- SafeStringValue(v_dll);
292
- SafeStringValue(v_proc);
293
-
294
- hLibrary = LoadLibrary(TEXT(RSTRING_PTR(v_dll)));
295
-
296
- // The most likely cause of failure is a bad DLL load path
297
- if(!hLibrary){
298
- rb_raise(cAPILoadError, "LoadLibrary() function failed for '%s': %s",
299
- RSTRING_PTR(v_dll),
300
- StringError(GetLastError())
301
- );
302
- }
303
-
304
- ptr->library = hLibrary;
305
-
306
- /* Attempt to get the function. If it fails, try again with an 'A'
307
- * appended. If that fails, try again with a 'W' appended. If that
308
- * still fails, raise an API::LoadLibraryError.
309
- */
310
-
311
- fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_proc)));
312
-
313
- // Skip the ANSI and Wide function checks for MSVCRT functions.
314
- if(!fProc){
315
- if(strstr(RSTRING_PTR(v_dll), "msvcr")){
316
- rb_raise(
317
- cAPILoadError,
318
- "Unable to load function '%s'",
319
- RSTRING_PTR(v_proc)
320
- );
321
- }
322
- else{
323
- VALUE v_ascii = rb_str_new3(v_proc);
324
- v_ascii = rb_str_cat(v_ascii, first, 1);
325
- fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_ascii)));
326
-
327
- if(!fProc){
328
- VALUE v_unicode = rb_str_new3(v_proc);
329
- v_unicode = rb_str_cat(v_unicode, second, 1);
330
- fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_unicode)));
331
-
332
- if(!fProc){
333
- rb_raise(
334
- cAPILoadError,
335
- "Unable to load function '%s', '%s', or '%s'",
336
- RSTRING_PTR(v_proc),
337
- RSTRING_PTR(v_ascii),
338
- RSTRING_PTR(v_unicode)
339
- );
340
- }
341
- else{
342
- rb_iv_set(self, "@effective_function_name", v_unicode);
343
- }
344
- }
345
- else{
346
- rb_iv_set(self, "@effective_function_name", v_ascii);
347
- }
348
- }
349
- }
350
- else{
351
- rb_iv_set(self, "@effective_function_name", v_proc);
352
- }
353
-
354
- ptr->function = fProc;
355
-
356
- // Push the numeric prototypes onto our int array for later use.
357
-
358
- for(i = 0; i < RARRAY_LEN(v_proto); i++){
359
- SafeStringValue(RARRAY_PTR(v_proto)[i]);
360
- switch(*(TCHAR*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
361
- case 'L':
362
- ptr->prototype[i] = _T_LONG;
363
- break;
364
- case 'P':
365
- ptr->prototype[i] = _T_POINTER;
366
- break;
367
- case 'I': case 'B':
368
- ptr->prototype[i] = _T_INTEGER;
369
- break;
370
- case 'V':
371
- ptr->prototype[i] = _T_VOID;
372
- break;
373
- case 'K':
374
- ptr->prototype[i] = _T_CALLBACK;
375
- break;
376
- case 'S':
377
- ptr->prototype[i] = _T_STRING;
378
- break;
379
- default:
380
- rb_raise(cAPIProtoError, "Illegal prototype '%s'",
381
- StringValuePtr(RARRAY_PTR(v_proto)[i])
382
- );
383
- }
384
- }
385
-
386
- // Store the return type for later use.
387
-
388
- // Automatically convert empty strings or nil to type void.
389
- if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
390
- v_return = rb_str_new2("V");
391
- ptr->return_type = _T_VOID;
392
- }
393
- else{
394
- SafeStringValue(v_return);
395
- switch(*RSTRING_PTR(v_return)){
396
- case 'L':
397
- ptr->return_type = _T_LONG;
398
- break;
399
- case 'P':
400
- ptr->return_type = _T_POINTER;
401
- break;
402
- case 'I': case 'B':
403
- ptr->return_type = _T_INTEGER;
404
- break;
405
- case 'V':
406
- ptr->return_type = _T_VOID;
407
- break;
408
- case 'S':
409
- ptr->return_type = _T_STRING;
410
- break;
411
- default:
412
- rb_raise(cAPIProtoError, "Illegal return type '%s'",
413
- RSTRING_PTR(v_return)
414
- );
415
- }
416
- }
417
-
418
- rb_iv_set(self, "@dll_name", v_dll);
419
- rb_iv_set(self, "@function_name", v_proc);
420
- rb_iv_set(self, "@prototype", v_proto);
421
- rb_iv_set(self, "@return_type", v_return);
422
-
423
- return self;
424
- }
425
-
426
- /*
427
- * call-seq:
428
- *
429
- * API::Function.new(address, prototype = 'V', return_type = 'L')
430
- *
431
- * Creates and returns an API::Function object. This object is similar to an
432
- * API object, except that instead of a character function name you pass a
433
- * function pointer address as the first argument, and there's no associated
434
- * DLL file.
435
- *
436
- * Once you have your API::Function object you can then call it the same way
437
- * you would an API object.
438
- *
439
- * Example:
440
- *
441
- * require 'win32/api'
442
- * include Win32
443
- *
444
- * LoadLibrary = API.new('LoadLibrary', 'P', 'L')
445
- * GetProcAddress = API.new('GetProcAddress', 'LP', 'L')
446
- *
447
- * # Play a system beep
448
- * hlib = LoadLibrary.call('user32')
449
- * addr = GetProcAddress.call(hlib, 'MessageBeep')
450
- * func = Win32::API::Function.new(addr, 'L', 'L')
451
- * func.call(0)
452
- */
453
- static VALUE func_init(int argc, VALUE* argv, VALUE self){
454
- Win32API* ptr;
455
- int i;
456
- VALUE v_address, v_proto, v_return;
457
-
458
- rb_scan_args(argc, argv, "12", &v_address, &v_proto, &v_return);
459
-
460
- Data_Get_Struct(self, Win32API, ptr);
461
-
462
- // Convert a string prototype to an array of characters
463
- if(rb_respond_to(v_proto, rb_intern("split")))
464
- v_proto = rb_str_split(v_proto, "");
465
-
466
- // Convert a nil or empty prototype to 'V' (void) automatically
467
- if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
468
- v_proto = rb_ary_new();
469
- rb_ary_push(v_proto, rb_str_new2("V"));
470
- }
471
-
472
- // Set an arbitrary limit of 20 parameters
473
- if(20 < RARRAY_LEN(v_proto))
474
- rb_raise(rb_eArgError, "too many parameters: %li\n", RARRAY_LEN(v_proto));
475
-
476
- // Set the default return type to 'L' (DWORD)
477
- if(NIL_P(v_return))
478
- v_return = rb_str_new2("L");
479
-
480
- ptr->function = (FARPROC)NUM2SIZET(v_address);
481
-
482
- // Push the numeric prototypes onto our int array for later use.
483
-
484
- for(i = 0; i < RARRAY_LEN(v_proto); i++){
485
- SafeStringValue(RARRAY_PTR(v_proto)[i]);
486
- switch(*(char*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
487
- case 'L':
488
- ptr->prototype[i] = _T_LONG;
489
- break;
490
- case 'P':
491
- ptr->prototype[i] = _T_POINTER;
492
- break;
493
- case 'I': case 'B':
494
- ptr->prototype[i] = _T_INTEGER;
495
- break;
496
- case 'V':
497
- ptr->prototype[i] = _T_VOID;
498
- break;
499
- case 'K':
500
- ptr->prototype[i] = _T_CALLBACK;
501
- break;
502
- case 'S':
503
- ptr->prototype[i] = _T_STRING;
504
- break;
505
- default:
506
- rb_raise(cAPIProtoError, "Illegal prototype '%s'",
507
- StringValuePtr(RARRAY_PTR(v_proto)[i])
508
- );
509
- }
510
- }
511
-
512
- // Store the return type for later use.
513
-
514
- // Automatically convert empty strings or nil to type void.
515
- if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
516
- v_return = rb_str_new2("V");
517
- ptr->return_type = _T_VOID;
518
- }
519
- else{
520
- SafeStringValue(v_return);
521
- switch(*RSTRING_PTR(v_return)){
522
- case 'L':
523
- ptr->return_type = _T_LONG;
524
- break;
525
- case 'P':
526
- ptr->return_type = _T_POINTER;
527
- break;
528
- case 'I': case 'B':
529
- ptr->return_type = _T_INTEGER;
530
- break;
531
- case 'V':
532
- ptr->return_type = _T_VOID;
533
- break;
534
- case 'S':
535
- ptr->return_type = _T_STRING;
536
- break;
537
- default:
538
- rb_raise(cAPIProtoError, "Illegal return type '%s'",
539
- RSTRING_PTR(v_return)
540
- );
541
- }
542
- }
543
-
544
- rb_iv_set(self, "@address", v_address);
545
- rb_iv_set(self, "@prototype", v_proto);
546
- rb_iv_set(self, "@return_type", v_return);
547
-
548
- return self;
549
- }
550
-
551
- typedef struct {
552
- uintptr_t params[20];
553
- } CALLPARAM;
554
-
555
-
556
- DWORD CallbackFunction(CALLPARAM param, VALUE callback)
557
- {
558
- VALUE v_proto, v_return, v_proc, v_retval;
559
- VALUE argv[20];
560
- int i, argc;
561
- char *a_proto;
562
- char *a_return;
563
-
564
- if(callback && !NIL_P(callback)){
565
- v_proto = rb_iv_get(callback, "@prototype");
566
- a_proto = RSTRING_PTR(v_proto);
567
-
568
- v_return = rb_iv_get(callback, "@return_type");
569
- a_return = RSTRING_PTR(v_return);
570
-
571
- v_proc = rb_iv_get(callback, "@function");
572
- argc = RSTRING_LEN(v_proto);
573
-
574
- for(i=0; i < RSTRING_LEN(v_proto); i++){
575
- argv[i] = Qnil;
576
- switch(a_proto[i]){
577
- case 'L':
578
- argv[i] = SIZET2NUM(param.params[i]);
579
- break;
580
- case 'P':
581
- if(param.params[i])
582
- argv[i] = rb_str_new2((char *)param.params[i]);
583
- break;
584
- case 'I':
585
- argv[i] = INT2NUM(param.params[i]);
586
- break;
587
- default:
588
- rb_raise(cAPIProtoError, "Illegal prototype '%c'", a_proto[i]);
589
- }
590
- }
591
-
592
- v_retval = rb_funcall2(v_proc, rb_intern("call"), argc, argv);
593
-
594
- /* Handle true and false explicitly, as some CALLBACK functions
595
- * require TRUE or FALSE to break out of loops, etc.
596
- */
597
- if(v_retval == Qtrue)
598
- return TRUE;
599
- else if(v_retval == Qfalse)
600
- return FALSE;
601
-
602
- switch (*a_return) {
603
- case 'I':
604
- return NUM2INT(v_retval);
605
- break;
606
- case 'L':
607
- return NUM2SIZET(v_retval);
608
- break;
609
- case 'S':
610
- return (uintptr_t)RSTRING_PTR(v_retval);
611
- break;
612
- case 'P':
613
- if(NIL_P(v_retval)){
614
- return 0;
615
- }
616
- else if(FIXNUM_P(v_retval)){
617
- return NUM2SIZET(v_retval);
618
- }
619
- else{
620
- StringValue(v_retval);
621
- rb_str_modify(v_retval);
622
- return (uintptr_t)StringValuePtr(v_retval);
623
- }
624
- break;
625
- }
626
- }
627
-
628
- return 0;
629
- }
630
-
631
- #define CALLBACK0(x) DWORD CALLBACK CallbackFunction0_##x() {\
632
- CALLPARAM param = {{0}};\
633
- param.params[0] = 0;\
634
- return CallbackFunction(param,FuncTable[0][x]);\
635
- }
636
-
637
- #define CALLBACK1(x) DWORD CALLBACK CallbackFunction1_##x(DWORD p1) {\
638
- CALLPARAM param = {{p1}};\
639
- return CallbackFunction(param,FuncTable[1][x]);\
640
- }
641
-
642
- #define CALLBACK2(x) DWORD CALLBACK CallbackFunction2_##x(\
643
- DWORD p1, DWORD p2){\
644
- CALLPARAM param = {{p1,p2}};\
645
- return CallbackFunction(param,FuncTable[2][x]);\
646
- }
647
-
648
- #define CALLBACK3(x) DWORD CALLBACK CallbackFunction3_##x(\
649
- DWORD p1, DWORD p2, DWORD p3){\
650
- CALLPARAM param = {{p1,p2,p3}};\
651
- return CallbackFunction(param,FuncTable[3][x]);\
652
- }
653
-
654
- #define CALLBACK4(x) DWORD CALLBACK CallbackFunction4_##x(\
655
- DWORD p1, DWORD p2, DWORD p3, DWORD p4){\
656
- CALLPARAM param = {{p1,p2,p3,p4}};\
657
- return CallbackFunction(param,FuncTable[4][x]);\
658
- }
659
-
660
- #define CALLBACK5(x) DWORD CALLBACK CallbackFunction5_##x(\
661
- DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5\
662
- ){\
663
- CALLPARAM param = {{p1,p2,p3,p4,p5}};\
664
- return CallbackFunction(param,FuncTable[5][x]);\
665
- }
666
-
667
- #define CALLBACK6(x) DWORD CALLBACK CallbackFunction6_##x(\
668
- DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5, DWORD p6\
669
- ){\
670
- CALLPARAM param = {{p1,p2,p3,p4,p5,p6}};\
671
- return CallbackFunction(param,FuncTable[6][x]);\
672
- }
673
-
674
- #define CALLBACK7(x) DWORD CALLBACK CallbackFunction7_##x(\
675
- DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5, DWORD p6, DWORD p7\
676
- ){\
677
- CALLPARAM param = {{p1,p2,p3,p4,p5,p6,p7}};\
678
- return CallbackFunction(param,FuncTable[7][x]);\
679
- }
680
-
681
- #define CALLBACK8(x) DWORD CALLBACK CallbackFunction8_##x(\
682
- DWORD p1, DWORD p2, DWORD p3, DWORD p4,\
683
- DWORD p5, DWORD p6, DWORD p7, DWORD p8\
684
- ){\
685
- CALLPARAM param = {{p1,p2,p3,p4,p5,p6,p7,p8}};\
686
- return CallbackFunction(param,FuncTable[8][x]);\
687
- }
688
-
689
- #define CALLBACK9(x) DWORD CALLBACK CallbackFunction9_##x(\
690
- DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5,\
691
- DWORD p6, DWORD p7, DWORD p8, DWORD p9\
692
- ){\
693
- CALLPARAM param = {{p1,p2,p3,p4,p5,p6,p7,p8,p9}};\
694
- return CallbackFunction(param,FuncTable[9][x]);\
695
- }
696
-
697
- #define DEFCALLBACK(x) CALLBACK##x(0)\
698
- CALLBACK##x(1)\
699
- CALLBACK##x(2)\
700
- CALLBACK##x(3)\
701
- CALLBACK##x(4)\
702
- CALLBACK##x(5)\
703
- CALLBACK##x(6)\
704
- CALLBACK##x(7)\
705
- CALLBACK##x(8)\
706
- CALLBACK##x(9)
707
-
708
- #define CF(x,y) CallbackFunction##x##_##y
709
-
710
- static VALUE FuncTable[10][10];
711
-
712
- DEFCALLBACK(0)
713
- DEFCALLBACK(1)
714
- DEFCALLBACK(2)
715
- DEFCALLBACK(3)
716
- DEFCALLBACK(4)
717
- DEFCALLBACK(5)
718
- DEFCALLBACK(6)
719
- DEFCALLBACK(7)
720
- DEFCALLBACK(8)
721
- DEFCALLBACK(9)
722
-
723
- void *CallbackTable[10][10] = {
724
- {CF(0,0),CF(0,1),CF(0,2),CF(0,3),CF(0,4),CF(0,5),CF(0,6),CF(0,7),CF(0,8),CF(0,9)},
725
- {CF(1,0),CF(1,1),CF(1,2),CF(1,3),CF(1,4),CF(1,5),CF(1,6),CF(1,7),CF(1,8),CF(1,9)},
726
- {CF(2,0),CF(2,1),CF(2,2),CF(2,3),CF(2,4),CF(2,5),CF(2,6),CF(2,7),CF(2,8),CF(2,9)},
727
- {CF(3,0),CF(3,1),CF(3,2),CF(3,3),CF(3,4),CF(3,5),CF(3,6),CF(3,7),CF(3,8),CF(3,9)},
728
- {CF(4,0),CF(4,1),CF(4,2),CF(4,3),CF(4,4),CF(4,5),CF(4,6),CF(4,7),CF(4,8),CF(4,9)},
729
- {CF(5,0),CF(5,1),CF(5,2),CF(5,3),CF(5,4),CF(5,5),CF(5,6),CF(5,7),CF(5,8),CF(5,9)},
730
- {CF(6,0),CF(6,1),CF(6,2),CF(6,3),CF(6,4),CF(6,5),CF(6,6),CF(6,7),CF(6,8),CF(6,9)},
731
- {CF(7,0),CF(7,1),CF(7,2),CF(7,3),CF(7,4),CF(7,5),CF(7,6),CF(7,7),CF(7,8),CF(7,9)},
732
- {CF(8,0),CF(8,1),CF(8,2),CF(8,3),CF(8,4),CF(8,5),CF(8,6),CF(8,7),CF(8,8),CF(8,9)},
733
- {CF(9,0),CF(9,1),CF(9,2),CF(9,3),CF(9,4),CF(9,5),CF(9,6),CF(9,7),CF(9,8),CF(9,9)}};
734
-
735
-
736
- void *find_callback(VALUE obj,int len)
737
- {
738
- int i;
739
- for(i=0;i<10;i++)
740
- {
741
- if(FuncTable[len][i]==0)
742
- break;
743
- }
744
- if(i>=10)
745
- rb_raise(cAPIError,"too many callbacks are defined.");
746
- FuncTable[len][i] = obj;
747
- return CallbackTable[len][i];
748
- }
749
-
750
- /*
751
- * call-seq:
752
- * Win32::API#call(arg1, arg2, ...)
753
- *
754
- * Calls the function pointer with the given arguments (if any). Note that,
755
- * while this method will catch some prototype mismatches (raising a TypeError
756
- * in the process), it is not fulproof. It is ultimately your job to make
757
- * sure the arguments match the +prototype+ specified in the constructor.
758
- *
759
- * For convenience, nil is converted to NULL, true is converted to TRUE (1)
760
- * and false is converted to FALSE (0).
761
- */
762
- static VALUE api_call(int argc, VALUE* argv, VALUE self){
763
- VALUE v_proto, v_args, v_arg, v_return;
764
- Win32API* ptr;
765
- uintptr_t return_value;
766
- int i = 0;
767
- int len;
768
-
769
- struct{
770
- uintptr_t params[20];
771
- } param;
772
-
773
- Data_Get_Struct(self, Win32API, ptr);
774
-
775
- rb_scan_args(argc, argv, "0*", &v_args);
776
-
777
- v_proto = rb_iv_get(self, "@prototype");
778
-
779
- // For void prototypes, allow either no args or an explicit nil
780
- if(RARRAY_LEN(v_proto) != RARRAY_LEN(v_args)){
781
- char* c = StringValuePtr(RARRAY_PTR(v_proto)[0]);
782
- if(!strcmp(c, "V")){
783
- rb_ary_push(v_args, Qnil);
784
- }
785
- else{
786
- rb_raise(rb_eArgError,
787
- "wrong number of parameters: expected %ld, got %ld",
788
- RARRAY_LEN(v_proto), RARRAY_LEN(v_args)
789
- );
790
- }
791
- }
792
-
793
- len = RARRAY_LEN(v_proto);
794
-
795
- for(i = 0; i < len; i++){
796
- v_arg = RARRAY_PTR(v_args)[i];
797
-
798
- // Convert nil to NULL. Otherwise convert as appropriate.
799
- if(NIL_P(v_arg))
800
- param.params[i] = (uintptr_t)NULL;
801
- else if(v_arg == Qtrue)
802
- param.params[i] = TRUE;
803
- else if(v_arg == Qfalse)
804
- param.params[i] = FALSE;
805
- else
806
- switch(ptr->prototype[i]){
807
- case _T_LONG:
808
- param.params[i] = NUM2SIZET(v_arg);
809
- break;
810
- case _T_INTEGER:
811
- param.params[i] = NUM2INT(v_arg);
812
- break;
813
- case _T_POINTER:
814
- if(FIXNUM_P(v_arg)){
815
- param.params[i] = NUM2SIZET(v_arg);
816
- }
817
- else{
818
- StringValue(v_arg);
819
- rb_str_modify(v_arg);
820
- param.params[i] = (uintptr_t)StringValuePtr(v_arg);
821
- }
822
- break;
823
- case _T_CALLBACK:
824
- ActiveCallback = v_arg;
825
- param.params[i] = (LPARAM)NUM2SIZET(rb_iv_get(ActiveCallback, "@address"));;
826
- break;
827
- case _T_STRING:
828
- param.params[i] = (uintptr_t)RSTRING_PTR(v_arg);
829
- break;
830
- default:
831
- param.params[i] = NUM2SIZET(v_arg);
832
- }
833
- }
834
-
835
- /* Call the function, get the return value */
836
- if(strcmp(StringValuePtr(RARRAY_PTR(v_proto)[0]), "V") == 0 && len == 1)
837
- {
838
- return_value = ptr->function();
839
- }
840
- else
841
- {
842
- switch(len)
843
- {
844
- case 0:
845
- return_value = ptr->function();
846
- break;
847
- case 1:
848
- return_value = ptr->function(param.params[0]);
849
- break;
850
- case 2:
851
- return_value = ptr->function(param.params[0], param.params[1]);
852
- break;
853
- case 3:
854
- return_value = ptr->function(param.params[0], param.params[1],
855
- param.params[2]);
856
- break;
857
- case 4:
858
- return_value = ptr->function(param.params[0], param.params[1],
859
- param.params[2], param.params[3]);
860
- break;
861
- case 5:
862
- return_value = ptr->function(param.params[0], param.params[1],
863
- param.params[2], param.params[3], param.params[4]);
864
- break;
865
- case 6:
866
- return_value = ptr->function(param.params[0], param.params[1],
867
- param.params[2], param.params[3], param.params[4], param.params[5]);
868
- break;
869
- case 7:
870
- return_value = ptr->function(param.params[0], param.params[1],
871
- param.params[2], param.params[3], param.params[4], param.params[5],
872
- param.params[6]);
873
- break;
874
- case 8:
875
- return_value = ptr->function(param.params[0], param.params[1],
876
- param.params[2], param.params[3], param.params[4], param.params[5],
877
- param.params[6], param.params[7]);
878
- break;
879
- case 9:
880
- return_value = ptr->function(param.params[0], param.params[1],
881
- param.params[2], param.params[3], param.params[4], param.params[5],
882
- param.params[6], param.params[7], param.params[8]);
883
- break;
884
- case 10:
885
- return_value = ptr->function(param.params[0], param.params[1],
886
- param.params[2], param.params[3], param.params[4], param.params[5],
887
- param.params[6], param.params[7], param.params[8], param.params[9]);
888
- break;
889
- case 11:
890
- return_value = ptr->function(param.params[0], param.params[1],
891
- param.params[2], param.params[3], param.params[4], param.params[5],
892
- param.params[6], param.params[7], param.params[8], param.params[9],
893
- param.params[10]);
894
- break;
895
- case 12:
896
- return_value = ptr->function(param.params[0], param.params[1],
897
- param.params[2], param.params[3], param.params[4], param.params[5],
898
- param.params[6], param.params[7], param.params[8], param.params[9],
899
- param.params[10], param.params[11]);
900
- break;
901
- case 13:
902
- return_value = ptr->function(param.params[0], param.params[1],
903
- param.params[2], param.params[3], param.params[4], param.params[5],
904
- param.params[6], param.params[7], param.params[8], param.params[9],
905
- param.params[10], param.params[11], param.params[12]);
906
- break;
907
- case 14:
908
- return_value = ptr->function(param.params[0], param.params[1],
909
- param.params[2], param.params[3], param.params[4], param.params[5],
910
- param.params[6], param.params[7], param.params[8], param.params[9],
911
- param.params[10], param.params[11], param.params[12], param.params[13]);
912
- break;
913
- case 15:
914
- return_value = ptr->function(param.params[0], param.params[1],
915
- param.params[2], param.params[3], param.params[4], param.params[5],
916
- param.params[6], param.params[7], param.params[8], param.params[9],
917
- param.params[10], param.params[11], param.params[12], param.params[13],
918
- param.params[14]);
919
- break;
920
- case 16:
921
- return_value = ptr->function(param.params[0], param.params[1],
922
- param.params[2], param.params[3], param.params[4], param.params[5],
923
- param.params[6], param.params[7], param.params[8], param.params[9],
924
- param.params[10], param.params[11], param.params[12], param.params[13],
925
- param.params[14], param.params[15]);
926
- break;
927
- case 17:
928
- return_value = ptr->function(param.params[0], param.params[1],
929
- param.params[2], param.params[3], param.params[4], param.params[5],
930
- param.params[6], param.params[7], param.params[8], param.params[9],
931
- param.params[10], param.params[11], param.params[12], param.params[13],
932
- param.params[14], param.params[15], param.params[16]);
933
- break;
934
- case 18:
935
- return_value = ptr->function(param.params[0], param.params[1],
936
- param.params[2], param.params[3], param.params[4], param.params[5],
937
- param.params[6], param.params[7], param.params[8], param.params[9],
938
- param.params[10], param.params[11], param.params[12], param.params[13],
939
- param.params[14], param.params[15], param.params[16], param.params[17]);
940
- break;
941
- case 19:
942
- return_value = ptr->function(param.params[0], param.params[1],
943
- param.params[2], param.params[3], param.params[4], param.params[5],
944
- param.params[6], param.params[7], param.params[8], param.params[9],
945
- param.params[10], param.params[11], param.params[12], param.params[13],
946
- param.params[14], param.params[15], param.params[16], param.params[17],
947
- param.params[18]);
948
- break;
949
- case 20:
950
- return_value = ptr->function(param.params[0], param.params[1],
951
- param.params[2], param.params[3], param.params[4], param.params[5],
952
- param.params[6], param.params[7], param.params[8], param.params[9],
953
- param.params[10], param.params[11], param.params[12], param.params[13],
954
- param.params[14], param.params[15], param.params[16], param.params[17],
955
- param.params[18], param.params[19]);
956
- break;
957
- default:
958
- rb_raise(rb_eArgError,"number of parameters exceed 20!");
959
- }
960
- }
961
-
962
- /* Return the appropriate type based on the return type specified
963
- * in the constructor.
964
- */
965
- switch(ptr->return_type){
966
- case _T_INTEGER:
967
- v_return = INT2NUM(return_value);
968
- break;
969
- case _T_LONG:
970
- v_return = SIZET2NUM(return_value);
971
- break;
972
- case _T_VOID:
973
- v_return = Qnil;
974
- break;
975
- case _T_POINTER:
976
- if(!return_value){
977
- v_return = Qnil;
978
- }
979
- else{
980
- VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
981
- char* efunc = RSTRING_PTR(v_efunc);
982
- if(efunc[strlen(efunc)-1] == 'W'){
983
- v_return = rb_str_new(
984
- (TCHAR*)return_value,
985
- wcslen((wchar_t*)return_value)*2
986
- );
987
- }
988
- else{
989
- v_return = rb_str_new2((TCHAR*)return_value);
990
- }
991
- }
992
- break;
993
- case _T_STRING:
994
- {
995
- VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
996
- char* efunc = RSTRING_PTR(v_efunc);
997
-
998
- if(efunc[strlen(efunc)-1] == 'W'){
999
- v_return = rb_str_new(
1000
- (TCHAR*)return_value,
1001
- wcslen((wchar_t*)return_value)*2
1002
- );
1003
- }
1004
- else{
1005
- v_return = rb_str_new2((TCHAR*)return_value);
1006
- }
1007
- }
1008
- break;
1009
- default:
1010
- v_return = INT2NUM(0);
1011
- }
1012
-
1013
- return v_return;
1014
- }
1015
-
1016
- /*
1017
- * Wraps the Windows API functions in a Ruby interface.
1018
- */
1019
- void Init_api(){
1020
- VALUE mWin32, cAPI, cCallback, cFunction;
1021
-
1022
- /* Modules and Classes */
1023
-
1024
- /* The Win32 module serves as a namespace only */
1025
- mWin32 = rb_define_module("Win32");
1026
-
1027
- /* The API class encapsulates a function pointer to Windows API function */
1028
- cAPI = rb_define_class_under(mWin32, "API", rb_cObject);
1029
-
1030
- /* The API::Callback class encapsulates a Windows CALLBACK function */
1031
- cCallback = rb_define_class_under(cAPI, "Callback", rb_cObject);
1032
-
1033
- /* The API::Function class encapsulates a raw function pointer */
1034
- cFunction = rb_define_class_under(cAPI, "Function", cAPI);
1035
-
1036
- /* The API::Error class serves as a base class for other errors */
1037
- cAPIError = rb_define_class_under(cAPI, "Error", rb_eRuntimeError);
1038
-
1039
- /* The LoadError class is raised if a function cannot be found or loaded */
1040
- cAPILoadError = rb_define_class_under(cAPI, "LoadLibraryError", cAPIError);
1041
-
1042
- /* The PrototypeError class is raised if an invalid prototype is passed */
1043
- cAPIProtoError = rb_define_class_under(cAPI, "PrototypeError", cAPIError);
1044
-
1045
- /* Miscellaneous */
1046
- rb_define_alloc_func(cAPI, api_allocate);
1047
-
1048
- /* Win32::API Instance Methods */
1049
- rb_define_method(cAPI, "initialize", api_init, -1);
1050
- rb_define_method(cAPI, "call", api_call, -1);
1051
-
1052
- /* Win32::API::Callback Instance Methods */
1053
- rb_define_method(cCallback, "initialize", callback_init, -1);
1054
-
1055
- /* Win32::API::Function Instance Methods */
1056
- rb_define_method(cFunction, "initialize", func_init, -1);
1057
-
1058
- /* The name of the DLL that exports the API function */
1059
- rb_define_attr(cAPI, "dll_name", 1, 0);
1060
-
1061
- /* The name of the function passed to the constructor */
1062
- rb_define_attr(cAPI, "function_name", 1, 0);
1063
-
1064
- /* The name of the actual function that is returned by the constructor.
1065
- * For example, if you passed 'GetUserName' to the constructor, then the
1066
- * effective function name would be either 'GetUserNameA' or 'GetUserNameW'.
1067
- */
1068
- rb_define_attr(cAPI, "effective_function_name", 1, 0);
1069
-
1070
- /* The prototype, returned as an array of characters */
1071
- rb_define_attr(cAPI, "prototype", 1, 0);
1072
-
1073
- /* The return type, returned as a single character, S, P, L, I, V or B */
1074
- rb_define_attr(cAPI, "return_type", 1, 0);
1075
-
1076
- /* Win32::API::Callback Instance Methods */
1077
-
1078
- /* The prototype, returned as an array of characters */
1079
- rb_define_attr(cCallback, "prototype", 1, 0);
1080
-
1081
- /* The return type, returned as a single character, S, P, L, I, V or B */
1082
- rb_define_attr(cCallback, "return_type", 1, 0);
1083
-
1084
- /* The numeric address of the function pointer */
1085
- rb_define_attr(cCallback, "address", 1, 0);
1086
- rb_define_attr(cFunction, "address", 1, 0);
1087
-
1088
- /* Constants */
1089
-
1090
- /* 1.5.3: The version of the win32-api library */
1091
- rb_define_const(cAPI, "VERSION", rb_str_new2(WINDOWS_API_VERSION));
1092
- }
1
+ #include <ruby.h>
2
+ #include <windows.h>
3
+
4
+ // Ruby 1.9.x
5
+ #ifndef RSTRING_PTR
6
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
7
+ #endif
8
+ #ifndef RSTRING_LEN
9
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
10
+ #endif
11
+
12
+ #ifndef RARRAY_PTR
13
+ #define RARRAY_PTR(a) (RARRAY(a)->ptr)
14
+ #endif
15
+ #ifndef RARRAY_LEN
16
+ #define RARRAY_LEN(a) (RARRAY(a)->len)
17
+ #endif
18
+
19
+ #if defined(HAVE_LONG_LONG) && SIZEOF_SIZE_T > SIZEOF_LONG
20
+ # define NUM2SIZET(x) ((size_t)NUM2ULL(x))
21
+ # define NUM2SSIZET(x) ((ssize_t)NUM2LL(x))
22
+ #else
23
+ # define NUM2SIZET(x) NUM2ULONG(x)
24
+ # define NUM2SSIZET(x) NUM2LONG(x)
25
+ #endif
26
+
27
+ #if SIZEOF_SIZE_T > SIZEOF_LONG && defined(HAVE_LONG_LONG)
28
+ # define SIZET2NUM(v) ULL2NUM(v)
29
+ # define SSIZET2NUM(v) LL2NUM(v)
30
+ #elif SIZEOF_SIZE_T == SIZEOF_LONG
31
+ # define SIZET2NUM(v) ULONG2NUM(v)
32
+ # define SSIZET2NUM(v) LONG2NUM(v)
33
+ #else
34
+ # define SIZET2NUM(v) UINT2NUM(v)
35
+ # define SSIZET2NUM(v) INT2NUM(v)
36
+ #endif
37
+
38
+
39
+ #define MAX_BUF 1024
40
+ #define WINDOWS_API_VERSION "1.6.0"
41
+
42
+ #define _T_VOID 0
43
+ #define _T_LONG 1
44
+ #define _T_POINTER 2
45
+ #define _T_INTEGER 3
46
+ #define _T_CALLBACK 4
47
+ #define _T_STRING 5
48
+
49
+ VALUE cAPIError, cAPIProtoError, cAPILoadError;
50
+ static VALUE ActiveCallback = Qnil;
51
+
52
+ typedef struct {
53
+ HANDLE library;
54
+ FARPROC function;
55
+ int return_type;
56
+ int prototype[20];
57
+ } Win32API;
58
+
59
+ static void api_free(Win32API* ptr){
60
+ if(ptr->library)
61
+ FreeLibrary(ptr->library);
62
+
63
+ if(ptr)
64
+ free(ptr);
65
+ }
66
+
67
+ static VALUE api_allocate(VALUE klass){
68
+ Win32API* ptr = malloc(sizeof(Win32API));
69
+ memset(ptr, 0, sizeof(*ptr));
70
+ return Data_Wrap_Struct(klass, 0, api_free, ptr);
71
+ }
72
+
73
+ /* Helper function that converts the error number returned by GetLastError()
74
+ * into a human readable string. Note that we always use English for error
75
+ * output because that's what Ruby itself does.
76
+ *
77
+ * Internal use only.
78
+ */
79
+ char* StringError(DWORD dwError){
80
+ LPVOID lpMsgBuf;
81
+ static char buf[MAX_PATH];
82
+ DWORD dwLen, dwLastError;
83
+
84
+ // Assume ASCII (English) error messages from the Windows API
85
+ dwLen = FormatMessageA(
86
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
87
+ FORMAT_MESSAGE_FROM_SYSTEM |
88
+ FORMAT_MESSAGE_IGNORE_INSERTS,
89
+ NULL,
90
+ dwError,
91
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
92
+ (LPSTR)&lpMsgBuf,
93
+ 0,
94
+ NULL
95
+ );
96
+
97
+ dwLastError = GetLastError();
98
+
99
+ /* It appears that Windows doesn't necessarily ship with the DLL
100
+ * required to always use English error messages. Check for error
101
+ * ERROR_MUI_FILE_NOT_FOUND (15100) or ERROR_RESOURCE_LANG_NOT_FOUND (1815)
102
+ * and try again if necessary.
103
+ */
104
+ if(!dwLen && (dwLastError == 15100 || dwLastError == 1815)){
105
+ dwLen = FormatMessageA(
106
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
107
+ FORMAT_MESSAGE_FROM_SYSTEM |
108
+ FORMAT_MESSAGE_IGNORE_INSERTS,
109
+ NULL,
110
+ dwError,
111
+ 0,
112
+ (LPSTR)&lpMsgBuf,
113
+ 0,
114
+ NULL
115
+ );
116
+ }
117
+
118
+ if(!dwLen){
119
+ rb_raise(
120
+ cAPIError,
121
+ "Attempt to format message failed (error = '%lu')",
122
+ GetLastError()
123
+ );
124
+ }
125
+
126
+ memset(buf, 0, MAX_PATH);
127
+
128
+ // Remove \r\n at end of string.
129
+ #ifdef HAVE_STRNCPY_S
130
+ strncpy_s(buf, MAX_PATH, lpMsgBuf, dwLen - 2);
131
+ #else
132
+ strncpy(buf, lpMsgBuf, dwLen - 2);
133
+ #endif
134
+
135
+ LocalFree(lpMsgBuf);
136
+
137
+ return buf;
138
+ }
139
+
140
+ /*
141
+ * call-seq:
142
+ * Win32::API::Callback.new(prototype, return='L'){ |proto| ... }
143
+ *
144
+ * Creates and returns a new Win32::API::Callback object. The prototype
145
+ * arguments are yielded back to the block in the same order they were
146
+ * declared.
147
+ *
148
+ * The +prototype+ is the function prototype for the callback function. This
149
+ * is a string. The possible valid characters are 'I' (integer), 'L' (long),
150
+ * 'V' (void), 'P' (pointer) or 'S' (string). Unlike API objects, API::Callback
151
+ * objects do not have a default prototype.
152
+ *
153
+ * The +return+ argument is the return type for the callback function. The
154
+ * valid characters are the same as for the +prototype+. The default is
155
+ * 'L' (long).
156
+ *
157
+ * Example:
158
+ * require 'win32/api'
159
+ * include Win32
160
+ *
161
+ * EnumWindows = API.new('EnumWindows', 'KP', 'L', 'user32')
162
+ * GetWindowText = API.new('GetWindowText', 'LPI', 'I', 'user32')
163
+ *
164
+ * EnumWindowsProc = API::Callback.new('LP', 'I'){ |handle, param|
165
+ * buf = "\0" * 200
166
+ * GetWindowText.call(handle, buf, 200);
167
+ * puts buf.strip unless buf.strip.empty?
168
+ * buf.index(param).nil? ? true : false
169
+ * }
170
+ *
171
+ * EnumWindows.call(EnumWindowsProc, 'UEDIT32')
172
+ */
173
+ static VALUE callback_init(int argc, VALUE* argv, VALUE self)
174
+ {
175
+ void *find_callback(VALUE,int);
176
+ VALUE v_proto, v_return, v_proc;
177
+ int i;
178
+
179
+ rb_scan_args(argc, argv, "11&", &v_proto, &v_return, &v_proc);
180
+
181
+ /* Validate prototype characters */
182
+ for(i = 0; i < RSTRING_LEN(v_proto); i++){
183
+ switch(RSTRING_PTR(v_proto)[i]){
184
+ case 'I': case 'L': case 'P': case 'V': case 'S':
185
+ break;
186
+ default:
187
+ rb_raise(cAPIProtoError, "Illegal prototype '%c'",
188
+ RSTRING_PTR(v_proto)[i]
189
+ );
190
+ }
191
+ }
192
+
193
+ if(NIL_P(v_return) || RARRAY_LEN(v_return) == 0){
194
+ v_return = rb_str_new2("L");
195
+ }
196
+ else{
197
+ switch(*(TCHAR*)RSTRING_PTR(v_return)){
198
+ case 'I': case 'L': case 'P': case 'V': case 'S':
199
+ break;
200
+ default:
201
+ rb_raise(cAPIProtoError, "Illegal return type '%s'",
202
+ RSTRING_PTR(v_return)
203
+ );
204
+ }
205
+ }
206
+
207
+ rb_iv_set(self, "@function", v_proc);
208
+ rb_iv_set(self, "@prototype", v_proto);
209
+ rb_iv_set(self, "@return_type", v_return);
210
+ rb_iv_set(self, "@address", SIZET2NUM((LPARAM)find_callback(self,RSTRING_LEN(v_proto))));
211
+ ActiveCallback = self;
212
+
213
+ return self;
214
+ }
215
+
216
+ /*
217
+ * call-seq:
218
+ * Win32::API.new(function, prototype='V', return='L', dll='kernel32')
219
+ *
220
+ * Creates and returns a new Win32::API object. The +function+ is the name
221
+ * of the Windows function.
222
+ *
223
+ * The +prototype+ is the function prototype for +function+. This can be a
224
+ * string or an array of characters. The possible valid characters are 'I'
225
+ * (integer), 'L' (long), 'V' (void), 'P' (pointer), 'K' (callback) or 'S'
226
+ * (string).
227
+ *
228
+ * The default is void ('V').
229
+ *
230
+ * Constant (const char*) strings should use 'S'. Pass by reference string
231
+ * buffers should use 'P'. The former is faster, but cannot be modified.
232
+ *
233
+ * The +return+ argument is the return type for the function. The valid
234
+ * characters are the same as for the +prototype+. The default is 'L' (long).
235
+ *
236
+ * The +dll+ is the name of the DLL file that the function is exported from.
237
+ * The default is 'kernel32'.
238
+ *
239
+ * If the function cannot be found then an API::Error is raised (a subclass
240
+ * of RuntimeError).
241
+ *
242
+ * Example:
243
+ *
244
+ * require 'win32/api'
245
+ * include Win32
246
+ *
247
+ * buf = 0.chr * 260
248
+ * len = [buf.length].pack('L')
249
+ *
250
+ * GetUserName = API.new('GetUserName', 'PP', 'I', 'advapi32')
251
+ * GetUserName.call(buf, len)
252
+ *
253
+ * puts buf.strip
254
+ */
255
+ static VALUE api_init(int argc, VALUE* argv, VALUE self)
256
+ {
257
+ HMODULE hLibrary;
258
+ FARPROC fProc;
259
+ Win32API* ptr;
260
+ int i;
261
+ const char* first = "A";
262
+ const char* second = "W";
263
+ VALUE v_proc, v_proto, v_return, v_dll;
264
+
265
+ rb_scan_args(argc, argv, "13", &v_proc, &v_proto, &v_return, &v_dll);
266
+
267
+ Data_Get_Struct(self, Win32API, ptr);
268
+
269
+ // Convert a string prototype to an array of characters
270
+ if(rb_respond_to(v_proto, rb_intern("split")))
271
+ v_proto = rb_str_split(v_proto, "");
272
+
273
+ // Convert a nil or empty prototype to 'V' (void) automatically
274
+ if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
275
+ v_proto = rb_ary_new();
276
+ rb_ary_push(v_proto, rb_str_new2("V"));
277
+ }
278
+
279
+ // Set an arbitrary limit of 20 parameters
280
+ if(RARRAY_LEN(v_proto) > 20)
281
+ rb_raise(rb_eArgError, "too many parameters: %ld", RARRAY_LEN(v_proto));
282
+
283
+ // Set the default dll to 'kernel32'
284
+ if(NIL_P(v_dll))
285
+ v_dll = rb_str_new2("kernel32");
286
+
287
+ // Set the default return type to 'L' (DWORD)
288
+ if(NIL_P(v_return))
289
+ v_return = rb_str_new2("L");
290
+
291
+ SafeStringValue(v_dll);
292
+ SafeStringValue(v_proc);
293
+
294
+ hLibrary = LoadLibrary(TEXT(RSTRING_PTR(v_dll)));
295
+
296
+ // The most likely cause of failure is a bad DLL load path
297
+ if(!hLibrary){
298
+ rb_raise(cAPILoadError, "LoadLibrary() function failed for '%s': %s",
299
+ RSTRING_PTR(v_dll),
300
+ StringError(GetLastError())
301
+ );
302
+ }
303
+
304
+ ptr->library = hLibrary;
305
+
306
+ /* Attempt to get the function. If it fails, try again with an 'A'
307
+ * appended. If that fails, try again with a 'W' appended. If that
308
+ * still fails, raise an API::LoadLibraryError.
309
+ */
310
+
311
+ fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_proc)));
312
+
313
+ // Skip the ANSI and Wide function checks for MSVCRT functions.
314
+ if(!fProc){
315
+ if(strstr(RSTRING_PTR(v_dll), "msvcr")){
316
+ rb_raise(
317
+ cAPILoadError,
318
+ "Unable to load function '%s'",
319
+ RSTRING_PTR(v_proc)
320
+ );
321
+ }
322
+ else{
323
+ VALUE v_ascii = rb_str_new3(v_proc);
324
+ v_ascii = rb_str_cat(v_ascii, first, 1);
325
+ fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_ascii)));
326
+
327
+ if(!fProc){
328
+ VALUE v_unicode = rb_str_new3(v_proc);
329
+ v_unicode = rb_str_cat(v_unicode, second, 1);
330
+ fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_unicode)));
331
+
332
+ if(!fProc){
333
+ rb_raise(
334
+ cAPILoadError,
335
+ "Unable to load function '%s', '%s', or '%s'",
336
+ RSTRING_PTR(v_proc),
337
+ RSTRING_PTR(v_ascii),
338
+ RSTRING_PTR(v_unicode)
339
+ );
340
+ }
341
+ else{
342
+ rb_iv_set(self, "@effective_function_name", v_unicode);
343
+ }
344
+ }
345
+ else{
346
+ rb_iv_set(self, "@effective_function_name", v_ascii);
347
+ }
348
+ }
349
+ }
350
+ else{
351
+ rb_iv_set(self, "@effective_function_name", v_proc);
352
+ }
353
+
354
+ ptr->function = fProc;
355
+
356
+ // Push the numeric prototypes onto our int array for later use.
357
+
358
+ for(i = 0; i < RARRAY_LEN(v_proto); i++){
359
+ SafeStringValue(RARRAY_PTR(v_proto)[i]);
360
+ switch(*(TCHAR*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
361
+ case 'L':
362
+ ptr->prototype[i] = _T_LONG;
363
+ break;
364
+ case 'P':
365
+ ptr->prototype[i] = _T_POINTER;
366
+ break;
367
+ case 'I': case 'B':
368
+ ptr->prototype[i] = _T_INTEGER;
369
+ break;
370
+ case 'V':
371
+ ptr->prototype[i] = _T_VOID;
372
+ break;
373
+ case 'K':
374
+ ptr->prototype[i] = _T_CALLBACK;
375
+ break;
376
+ case 'S':
377
+ ptr->prototype[i] = _T_STRING;
378
+ break;
379
+ default:
380
+ rb_raise(cAPIProtoError, "Illegal prototype '%s'",
381
+ StringValuePtr(RARRAY_PTR(v_proto)[i])
382
+ );
383
+ }
384
+ }
385
+
386
+ // Store the return type for later use.
387
+
388
+ // Automatically convert empty strings or nil to type void.
389
+ if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
390
+ v_return = rb_str_new2("V");
391
+ ptr->return_type = _T_VOID;
392
+ }
393
+ else{
394
+ SafeStringValue(v_return);
395
+ switch(*RSTRING_PTR(v_return)){
396
+ case 'L':
397
+ ptr->return_type = _T_LONG;
398
+ break;
399
+ case 'P':
400
+ ptr->return_type = _T_POINTER;
401
+ break;
402
+ case 'I': case 'B':
403
+ ptr->return_type = _T_INTEGER;
404
+ break;
405
+ case 'V':
406
+ ptr->return_type = _T_VOID;
407
+ break;
408
+ case 'S':
409
+ ptr->return_type = _T_STRING;
410
+ break;
411
+ default:
412
+ rb_raise(cAPIProtoError, "Illegal return type '%s'",
413
+ RSTRING_PTR(v_return)
414
+ );
415
+ }
416
+ }
417
+
418
+ rb_iv_set(self, "@dll_name", v_dll);
419
+ rb_iv_set(self, "@function_name", v_proc);
420
+ rb_iv_set(self, "@prototype", v_proto);
421
+ rb_iv_set(self, "@return_type", v_return);
422
+
423
+ return self;
424
+ }
425
+
426
+ /*
427
+ * call-seq:
428
+ *
429
+ * API::Function.new(address, prototype = 'V', return_type = 'L')
430
+ *
431
+ * Creates and returns an API::Function object. This object is similar to an
432
+ * API object, except that instead of a character function name you pass a
433
+ * function pointer address as the first argument, and there's no associated
434
+ * DLL file.
435
+ *
436
+ * Once you have your API::Function object you can then call it the same way
437
+ * you would an API object.
438
+ *
439
+ * Example:
440
+ *
441
+ * require 'win32/api'
442
+ * include Win32
443
+ *
444
+ * LoadLibrary = API.new('LoadLibrary', 'P', 'L')
445
+ * GetProcAddress = API.new('GetProcAddress', 'LP', 'L')
446
+ *
447
+ * # Play a system beep
448
+ * hlib = LoadLibrary.call('user32')
449
+ * addr = GetProcAddress.call(hlib, 'MessageBeep')
450
+ * func = Win32::API::Function.new(addr, 'L', 'L')
451
+ * func.call(0)
452
+ */
453
+ static VALUE func_init(int argc, VALUE* argv, VALUE self){
454
+ Win32API* ptr;
455
+ int i;
456
+ VALUE v_address, v_proto, v_return;
457
+
458
+ rb_scan_args(argc, argv, "12", &v_address, &v_proto, &v_return);
459
+
460
+ Data_Get_Struct(self, Win32API, ptr);
461
+
462
+ // Convert a string prototype to an array of characters
463
+ if(rb_respond_to(v_proto, rb_intern("split")))
464
+ v_proto = rb_str_split(v_proto, "");
465
+
466
+ // Convert a nil or empty prototype to 'V' (void) automatically
467
+ if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
468
+ v_proto = rb_ary_new();
469
+ rb_ary_push(v_proto, rb_str_new2("V"));
470
+ }
471
+
472
+ // Set an arbitrary limit of 20 parameters
473
+ if(20 < RARRAY_LEN(v_proto))
474
+ rb_raise(rb_eArgError, "too many parameters: %li\n", RARRAY_LEN(v_proto));
475
+
476
+ // Set the default return type to 'L' (DWORD)
477
+ if(NIL_P(v_return))
478
+ v_return = rb_str_new2("L");
479
+
480
+ ptr->function = (FARPROC)NUM2SIZET(v_address);
481
+
482
+ // Push the numeric prototypes onto our int array for later use.
483
+
484
+ for(i = 0; i < RARRAY_LEN(v_proto); i++){
485
+ SafeStringValue(RARRAY_PTR(v_proto)[i]);
486
+ switch(*(char*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
487
+ case 'L':
488
+ ptr->prototype[i] = _T_LONG;
489
+ break;
490
+ case 'P':
491
+ ptr->prototype[i] = _T_POINTER;
492
+ break;
493
+ case 'I': case 'B':
494
+ ptr->prototype[i] = _T_INTEGER;
495
+ break;
496
+ case 'V':
497
+ ptr->prototype[i] = _T_VOID;
498
+ break;
499
+ case 'K':
500
+ ptr->prototype[i] = _T_CALLBACK;
501
+ break;
502
+ case 'S':
503
+ ptr->prototype[i] = _T_STRING;
504
+ break;
505
+ default:
506
+ rb_raise(cAPIProtoError, "Illegal prototype '%s'",
507
+ StringValuePtr(RARRAY_PTR(v_proto)[i])
508
+ );
509
+ }
510
+ }
511
+
512
+ // Store the return type for later use.
513
+
514
+ // Automatically convert empty strings or nil to type void.
515
+ if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
516
+ v_return = rb_str_new2("V");
517
+ ptr->return_type = _T_VOID;
518
+ }
519
+ else{
520
+ SafeStringValue(v_return);
521
+ switch(*RSTRING_PTR(v_return)){
522
+ case 'L':
523
+ ptr->return_type = _T_LONG;
524
+ break;
525
+ case 'P':
526
+ ptr->return_type = _T_POINTER;
527
+ break;
528
+ case 'I': case 'B':
529
+ ptr->return_type = _T_INTEGER;
530
+ break;
531
+ case 'V':
532
+ ptr->return_type = _T_VOID;
533
+ break;
534
+ case 'S':
535
+ ptr->return_type = _T_STRING;
536
+ break;
537
+ default:
538
+ rb_raise(cAPIProtoError, "Illegal return type '%s'",
539
+ RSTRING_PTR(v_return)
540
+ );
541
+ }
542
+ }
543
+
544
+ rb_iv_set(self, "@address", v_address);
545
+ rb_iv_set(self, "@prototype", v_proto);
546
+ rb_iv_set(self, "@return_type", v_return);
547
+
548
+ return self;
549
+ }
550
+
551
+ typedef struct {
552
+ uintptr_t params[20];
553
+ } CALLPARAM;
554
+
555
+
556
+ DWORD CallbackFunction(CALLPARAM param, VALUE callback)
557
+ {
558
+ VALUE v_proto, v_return, v_proc, v_retval;
559
+ VALUE argv[20];
560
+ int i, argc;
561
+ char *a_proto;
562
+ char *a_return;
563
+
564
+ if(callback && !NIL_P(callback)){
565
+ v_proto = rb_iv_get(callback, "@prototype");
566
+ a_proto = RSTRING_PTR(v_proto);
567
+
568
+ v_return = rb_iv_get(callback, "@return_type");
569
+ a_return = RSTRING_PTR(v_return);
570
+
571
+ v_proc = rb_iv_get(callback, "@function");
572
+ argc = RSTRING_LEN(v_proto);
573
+
574
+ for(i=0; i < RSTRING_LEN(v_proto); i++){
575
+ argv[i] = Qnil;
576
+ switch(a_proto[i]){
577
+ case 'L':
578
+ argv[i] = SIZET2NUM(param.params[i]);
579
+ break;
580
+ case 'P':
581
+ if(param.params[i])
582
+ argv[i] = rb_str_new2((char *)param.params[i]);
583
+ break;
584
+ case 'I':
585
+ argv[i] = INT2NUM(param.params[i]);
586
+ break;
587
+ default:
588
+ rb_raise(cAPIProtoError, "Illegal prototype '%c'", a_proto[i]);
589
+ }
590
+ }
591
+
592
+ v_retval = rb_funcall2(v_proc, rb_intern("call"), argc, argv);
593
+
594
+ /* Handle true and false explicitly, as some CALLBACK functions
595
+ * require TRUE or FALSE to break out of loops, etc.
596
+ */
597
+ if(v_retval == Qtrue)
598
+ return TRUE;
599
+ else if(v_retval == Qfalse)
600
+ return FALSE;
601
+
602
+ switch (*a_return) {
603
+ case 'I':
604
+ return NUM2INT(v_retval);
605
+ break;
606
+ case 'L':
607
+ return NUM2SIZET(v_retval);
608
+ break;
609
+ case 'S':
610
+ return (uintptr_t)RSTRING_PTR(v_retval);
611
+ break;
612
+ case 'P':
613
+ if(NIL_P(v_retval)){
614
+ return 0;
615
+ }
616
+ else if(FIXNUM_P(v_retval)){
617
+ return NUM2SIZET(v_retval);
618
+ }
619
+ else{
620
+ StringValue(v_retval);
621
+ rb_str_modify(v_retval);
622
+ return (uintptr_t)StringValuePtr(v_retval);
623
+ }
624
+ break;
625
+ }
626
+ }
627
+
628
+ return 0;
629
+ }
630
+
631
+ #define CALLBACK0(x) DWORD CALLBACK CallbackFunction0_##x() {\
632
+ CALLPARAM param = {{0}};\
633
+ param.params[0] = 0;\
634
+ return CallbackFunction(param,FuncTable[0][x]);\
635
+ }
636
+
637
+ #define CALLBACK1(x) DWORD CALLBACK CallbackFunction1_##x(DWORD p1) {\
638
+ CALLPARAM param = {{p1}};\
639
+ return CallbackFunction(param,FuncTable[1][x]);\
640
+ }
641
+
642
+ #define CALLBACK2(x) DWORD CALLBACK CallbackFunction2_##x(\
643
+ DWORD p1, DWORD p2){\
644
+ CALLPARAM param = {{p1,p2}};\
645
+ return CallbackFunction(param,FuncTable[2][x]);\
646
+ }
647
+
648
+ #define CALLBACK3(x) DWORD CALLBACK CallbackFunction3_##x(\
649
+ DWORD p1, DWORD p2, DWORD p3){\
650
+ CALLPARAM param = {{p1,p2,p3}};\
651
+ return CallbackFunction(param,FuncTable[3][x]);\
652
+ }
653
+
654
+ #define CALLBACK4(x) DWORD CALLBACK CallbackFunction4_##x(\
655
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4){\
656
+ CALLPARAM param = {{p1,p2,p3,p4}};\
657
+ return CallbackFunction(param,FuncTable[4][x]);\
658
+ }
659
+
660
+ #define CALLBACK5(x) DWORD CALLBACK CallbackFunction5_##x(\
661
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5\
662
+ ){\
663
+ CALLPARAM param = {{p1,p2,p3,p4,p5}};\
664
+ return CallbackFunction(param,FuncTable[5][x]);\
665
+ }
666
+
667
+ #define CALLBACK6(x) DWORD CALLBACK CallbackFunction6_##x(\
668
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5, DWORD p6\
669
+ ){\
670
+ CALLPARAM param = {{p1,p2,p3,p4,p5,p6}};\
671
+ return CallbackFunction(param,FuncTable[6][x]);\
672
+ }
673
+
674
+ #define CALLBACK7(x) DWORD CALLBACK CallbackFunction7_##x(\
675
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5, DWORD p6, DWORD p7\
676
+ ){\
677
+ CALLPARAM param = {{p1,p2,p3,p4,p5,p6,p7}};\
678
+ return CallbackFunction(param,FuncTable[7][x]);\
679
+ }
680
+
681
+ #define CALLBACK8(x) DWORD CALLBACK CallbackFunction8_##x(\
682
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4,\
683
+ DWORD p5, DWORD p6, DWORD p7, DWORD p8\
684
+ ){\
685
+ CALLPARAM param = {{p1,p2,p3,p4,p5,p6,p7,p8}};\
686
+ return CallbackFunction(param,FuncTable[8][x]);\
687
+ }
688
+
689
+ #define CALLBACK9(x) DWORD CALLBACK CallbackFunction9_##x(\
690
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5,\
691
+ DWORD p6, DWORD p7, DWORD p8, DWORD p9\
692
+ ){\
693
+ CALLPARAM param = {{p1,p2,p3,p4,p5,p6,p7,p8,p9}};\
694
+ return CallbackFunction(param,FuncTable[9][x]);\
695
+ }
696
+
697
+ #define DEFCALLBACK(x) CALLBACK##x(0)\
698
+ CALLBACK##x(1)\
699
+ CALLBACK##x(2)\
700
+ CALLBACK##x(3)\
701
+ CALLBACK##x(4)\
702
+ CALLBACK##x(5)\
703
+ CALLBACK##x(6)\
704
+ CALLBACK##x(7)\
705
+ CALLBACK##x(8)\
706
+ CALLBACK##x(9)
707
+
708
+ #define CF(x,y) CallbackFunction##x##_##y
709
+
710
+ static VALUE FuncTable[10][10];
711
+
712
+ DEFCALLBACK(0)
713
+ DEFCALLBACK(1)
714
+ DEFCALLBACK(2)
715
+ DEFCALLBACK(3)
716
+ DEFCALLBACK(4)
717
+ DEFCALLBACK(5)
718
+ DEFCALLBACK(6)
719
+ DEFCALLBACK(7)
720
+ DEFCALLBACK(8)
721
+ DEFCALLBACK(9)
722
+
723
+ void *CallbackTable[10][10] = {
724
+ {CF(0,0),CF(0,1),CF(0,2),CF(0,3),CF(0,4),CF(0,5),CF(0,6),CF(0,7),CF(0,8),CF(0,9)},
725
+ {CF(1,0),CF(1,1),CF(1,2),CF(1,3),CF(1,4),CF(1,5),CF(1,6),CF(1,7),CF(1,8),CF(1,9)},
726
+ {CF(2,0),CF(2,1),CF(2,2),CF(2,3),CF(2,4),CF(2,5),CF(2,6),CF(2,7),CF(2,8),CF(2,9)},
727
+ {CF(3,0),CF(3,1),CF(3,2),CF(3,3),CF(3,4),CF(3,5),CF(3,6),CF(3,7),CF(3,8),CF(3,9)},
728
+ {CF(4,0),CF(4,1),CF(4,2),CF(4,3),CF(4,4),CF(4,5),CF(4,6),CF(4,7),CF(4,8),CF(4,9)},
729
+ {CF(5,0),CF(5,1),CF(5,2),CF(5,3),CF(5,4),CF(5,5),CF(5,6),CF(5,7),CF(5,8),CF(5,9)},
730
+ {CF(6,0),CF(6,1),CF(6,2),CF(6,3),CF(6,4),CF(6,5),CF(6,6),CF(6,7),CF(6,8),CF(6,9)},
731
+ {CF(7,0),CF(7,1),CF(7,2),CF(7,3),CF(7,4),CF(7,5),CF(7,6),CF(7,7),CF(7,8),CF(7,9)},
732
+ {CF(8,0),CF(8,1),CF(8,2),CF(8,3),CF(8,4),CF(8,5),CF(8,6),CF(8,7),CF(8,8),CF(8,9)},
733
+ {CF(9,0),CF(9,1),CF(9,2),CF(9,3),CF(9,4),CF(9,5),CF(9,6),CF(9,7),CF(9,8),CF(9,9)}};
734
+
735
+
736
+ void *find_callback(VALUE obj,int len)
737
+ {
738
+ int i;
739
+ for(i=0;i<10;i++)
740
+ {
741
+ if(FuncTable[len][i]==0)
742
+ break;
743
+ }
744
+ if(i>=10)
745
+ rb_raise(cAPIError,"too many callbacks are defined.");
746
+ FuncTable[len][i] = obj;
747
+ return CallbackTable[len][i];
748
+ }
749
+
750
+ /*
751
+ * call-seq:
752
+ * Win32::API#call(arg1, arg2, ...)
753
+ *
754
+ * Calls the function pointer with the given arguments (if any). Note that,
755
+ * while this method will catch some prototype mismatches (raising a TypeError
756
+ * in the process), it is not fulproof. It is ultimately your job to make
757
+ * sure the arguments match the +prototype+ specified in the constructor.
758
+ *
759
+ * For convenience, nil is converted to NULL, true is converted to TRUE (1)
760
+ * and false is converted to FALSE (0).
761
+ */
762
+ static VALUE api_call(int argc, VALUE* argv, VALUE self){
763
+ VALUE v_proto, v_args, v_arg, v_return;
764
+ Win32API* ptr;
765
+ uintptr_t return_value;
766
+ int i = 0;
767
+ int len;
768
+
769
+ struct{
770
+ uintptr_t params[20];
771
+ } param;
772
+
773
+ Data_Get_Struct(self, Win32API, ptr);
774
+
775
+ rb_scan_args(argc, argv, "0*", &v_args);
776
+
777
+ v_proto = rb_iv_get(self, "@prototype");
778
+
779
+ // For void prototypes, allow either no args or an explicit nil
780
+ if(RARRAY_LEN(v_proto) != RARRAY_LEN(v_args)){
781
+ char* c = StringValuePtr(RARRAY_PTR(v_proto)[0]);
782
+ if(!strcmp(c, "V")){
783
+ rb_ary_push(v_args, Qnil);
784
+ }
785
+ else{
786
+ rb_raise(rb_eArgError,
787
+ "wrong number of parameters: expected %ld, got %ld",
788
+ RARRAY_LEN(v_proto), RARRAY_LEN(v_args)
789
+ );
790
+ }
791
+ }
792
+
793
+ len = RARRAY_LEN(v_proto);
794
+
795
+ for(i = 0; i < len; i++){
796
+ v_arg = RARRAY_PTR(v_args)[i];
797
+
798
+ // Convert nil to NULL. Otherwise convert as appropriate.
799
+ if(NIL_P(v_arg))
800
+ param.params[i] = (uintptr_t)NULL;
801
+ else if(v_arg == Qtrue)
802
+ param.params[i] = TRUE;
803
+ else if(v_arg == Qfalse)
804
+ param.params[i] = FALSE;
805
+ else
806
+ switch(ptr->prototype[i]){
807
+ case _T_LONG:
808
+ param.params[i] = NUM2SIZET(v_arg);
809
+ break;
810
+ case _T_INTEGER:
811
+ param.params[i] = NUM2INT(v_arg);
812
+ break;
813
+ case _T_POINTER:
814
+ if(FIXNUM_P(v_arg)){
815
+ param.params[i] = NUM2SIZET(v_arg);
816
+ }
817
+ else{
818
+ StringValue(v_arg);
819
+ rb_str_modify(v_arg);
820
+ param.params[i] = (uintptr_t)StringValuePtr(v_arg);
821
+ }
822
+ break;
823
+ case _T_CALLBACK:
824
+ ActiveCallback = v_arg;
825
+ param.params[i] = (LPARAM)NUM2SIZET(rb_iv_get(ActiveCallback, "@address"));;
826
+ break;
827
+ case _T_STRING:
828
+ param.params[i] = (uintptr_t)RSTRING_PTR(v_arg);
829
+ break;
830
+ default:
831
+ param.params[i] = NUM2SIZET(v_arg);
832
+ }
833
+ }
834
+
835
+ /* Call the function, get the return value */
836
+ if(strcmp(StringValuePtr(RARRAY_PTR(v_proto)[0]), "V") == 0 && len == 1)
837
+ {
838
+ return_value = ptr->function();
839
+ }
840
+ else
841
+ {
842
+ switch(len)
843
+ {
844
+ case 0:
845
+ return_value = ptr->function();
846
+ break;
847
+ case 1:
848
+ return_value = ptr->function(param.params[0]);
849
+ break;
850
+ case 2:
851
+ return_value = ptr->function(param.params[0], param.params[1]);
852
+ break;
853
+ case 3:
854
+ return_value = ptr->function(param.params[0], param.params[1],
855
+ param.params[2]);
856
+ break;
857
+ case 4:
858
+ return_value = ptr->function(param.params[0], param.params[1],
859
+ param.params[2], param.params[3]);
860
+ break;
861
+ case 5:
862
+ return_value = ptr->function(param.params[0], param.params[1],
863
+ param.params[2], param.params[3], param.params[4]);
864
+ break;
865
+ case 6:
866
+ return_value = ptr->function(param.params[0], param.params[1],
867
+ param.params[2], param.params[3], param.params[4], param.params[5]);
868
+ break;
869
+ case 7:
870
+ return_value = ptr->function(param.params[0], param.params[1],
871
+ param.params[2], param.params[3], param.params[4], param.params[5],
872
+ param.params[6]);
873
+ break;
874
+ case 8:
875
+ return_value = ptr->function(param.params[0], param.params[1],
876
+ param.params[2], param.params[3], param.params[4], param.params[5],
877
+ param.params[6], param.params[7]);
878
+ break;
879
+ case 9:
880
+ return_value = ptr->function(param.params[0], param.params[1],
881
+ param.params[2], param.params[3], param.params[4], param.params[5],
882
+ param.params[6], param.params[7], param.params[8]);
883
+ break;
884
+ case 10:
885
+ return_value = ptr->function(param.params[0], param.params[1],
886
+ param.params[2], param.params[3], param.params[4], param.params[5],
887
+ param.params[6], param.params[7], param.params[8], param.params[9]);
888
+ break;
889
+ case 11:
890
+ return_value = ptr->function(param.params[0], param.params[1],
891
+ param.params[2], param.params[3], param.params[4], param.params[5],
892
+ param.params[6], param.params[7], param.params[8], param.params[9],
893
+ param.params[10]);
894
+ break;
895
+ case 12:
896
+ return_value = ptr->function(param.params[0], param.params[1],
897
+ param.params[2], param.params[3], param.params[4], param.params[5],
898
+ param.params[6], param.params[7], param.params[8], param.params[9],
899
+ param.params[10], param.params[11]);
900
+ break;
901
+ case 13:
902
+ return_value = ptr->function(param.params[0], param.params[1],
903
+ param.params[2], param.params[3], param.params[4], param.params[5],
904
+ param.params[6], param.params[7], param.params[8], param.params[9],
905
+ param.params[10], param.params[11], param.params[12]);
906
+ break;
907
+ case 14:
908
+ return_value = ptr->function(param.params[0], param.params[1],
909
+ param.params[2], param.params[3], param.params[4], param.params[5],
910
+ param.params[6], param.params[7], param.params[8], param.params[9],
911
+ param.params[10], param.params[11], param.params[12], param.params[13]);
912
+ break;
913
+ case 15:
914
+ return_value = ptr->function(param.params[0], param.params[1],
915
+ param.params[2], param.params[3], param.params[4], param.params[5],
916
+ param.params[6], param.params[7], param.params[8], param.params[9],
917
+ param.params[10], param.params[11], param.params[12], param.params[13],
918
+ param.params[14]);
919
+ break;
920
+ case 16:
921
+ return_value = ptr->function(param.params[0], param.params[1],
922
+ param.params[2], param.params[3], param.params[4], param.params[5],
923
+ param.params[6], param.params[7], param.params[8], param.params[9],
924
+ param.params[10], param.params[11], param.params[12], param.params[13],
925
+ param.params[14], param.params[15]);
926
+ break;
927
+ case 17:
928
+ return_value = ptr->function(param.params[0], param.params[1],
929
+ param.params[2], param.params[3], param.params[4], param.params[5],
930
+ param.params[6], param.params[7], param.params[8], param.params[9],
931
+ param.params[10], param.params[11], param.params[12], param.params[13],
932
+ param.params[14], param.params[15], param.params[16]);
933
+ break;
934
+ case 18:
935
+ return_value = ptr->function(param.params[0], param.params[1],
936
+ param.params[2], param.params[3], param.params[4], param.params[5],
937
+ param.params[6], param.params[7], param.params[8], param.params[9],
938
+ param.params[10], param.params[11], param.params[12], param.params[13],
939
+ param.params[14], param.params[15], param.params[16], param.params[17]);
940
+ break;
941
+ case 19:
942
+ return_value = ptr->function(param.params[0], param.params[1],
943
+ param.params[2], param.params[3], param.params[4], param.params[5],
944
+ param.params[6], param.params[7], param.params[8], param.params[9],
945
+ param.params[10], param.params[11], param.params[12], param.params[13],
946
+ param.params[14], param.params[15], param.params[16], param.params[17],
947
+ param.params[18]);
948
+ break;
949
+ case 20:
950
+ return_value = ptr->function(param.params[0], param.params[1],
951
+ param.params[2], param.params[3], param.params[4], param.params[5],
952
+ param.params[6], param.params[7], param.params[8], param.params[9],
953
+ param.params[10], param.params[11], param.params[12], param.params[13],
954
+ param.params[14], param.params[15], param.params[16], param.params[17],
955
+ param.params[18], param.params[19]);
956
+ break;
957
+ default:
958
+ rb_raise(rb_eArgError,"number of parameters exceed 20!");
959
+ }
960
+ }
961
+
962
+ /* Return the appropriate type based on the return type specified
963
+ * in the constructor.
964
+ */
965
+ switch(ptr->return_type){
966
+ case _T_INTEGER:
967
+ v_return = INT2NUM(return_value);
968
+ break;
969
+ case _T_LONG:
970
+ v_return = SIZET2NUM(return_value);
971
+ break;
972
+ case _T_VOID:
973
+ v_return = Qnil;
974
+ break;
975
+ case _T_POINTER:
976
+ if(!return_value){
977
+ v_return = Qnil;
978
+ }
979
+ else{
980
+ VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
981
+ char* efunc = RSTRING_PTR(v_efunc);
982
+ if(efunc[strlen(efunc)-1] == 'W'){
983
+ v_return = rb_str_new(
984
+ (TCHAR*)return_value,
985
+ wcslen((wchar_t*)return_value)*2
986
+ );
987
+ }
988
+ else{
989
+ v_return = rb_str_new2((TCHAR*)return_value);
990
+ }
991
+ }
992
+ break;
993
+ case _T_STRING:
994
+ {
995
+ VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
996
+ char* efunc = RSTRING_PTR(v_efunc);
997
+
998
+ if(efunc[strlen(efunc)-1] == 'W'){
999
+ v_return = rb_str_new(
1000
+ (TCHAR*)return_value,
1001
+ wcslen((wchar_t*)return_value)*2
1002
+ );
1003
+ }
1004
+ else{
1005
+ v_return = rb_str_new2((TCHAR*)return_value);
1006
+ }
1007
+ }
1008
+ break;
1009
+ default:
1010
+ v_return = INT2NUM(0);
1011
+ }
1012
+
1013
+ return v_return;
1014
+ }
1015
+
1016
+ /*
1017
+ * Wraps the Windows API functions in a Ruby interface.
1018
+ */
1019
+ void Init_api(){
1020
+ VALUE mWin32, cAPI, cCallback, cFunction;
1021
+
1022
+ /* Modules and Classes */
1023
+
1024
+ /* The Win32 module serves as a namespace only */
1025
+ mWin32 = rb_define_module("Win32");
1026
+
1027
+ /* The API class encapsulates a function pointer to Windows API function */
1028
+ cAPI = rb_define_class_under(mWin32, "API", rb_cObject);
1029
+
1030
+ /* The API::Callback class encapsulates a Windows CALLBACK function */
1031
+ cCallback = rb_define_class_under(cAPI, "Callback", rb_cObject);
1032
+
1033
+ /* The API::Function class encapsulates a raw function pointer */
1034
+ cFunction = rb_define_class_under(cAPI, "Function", cAPI);
1035
+
1036
+ /* The API::Error class serves as a base class for other errors */
1037
+ cAPIError = rb_define_class_under(cAPI, "Error", rb_eRuntimeError);
1038
+
1039
+ /* The LoadError class is raised if a function cannot be found or loaded */
1040
+ cAPILoadError = rb_define_class_under(cAPI, "LoadLibraryError", cAPIError);
1041
+
1042
+ /* The PrototypeError class is raised if an invalid prototype is passed */
1043
+ cAPIProtoError = rb_define_class_under(cAPI, "PrototypeError", cAPIError);
1044
+
1045
+ /* Miscellaneous */
1046
+ rb_define_alloc_func(cAPI, api_allocate);
1047
+
1048
+ /* Win32::API Instance Methods */
1049
+ rb_define_method(cAPI, "initialize", api_init, -1);
1050
+ rb_define_method(cAPI, "call", api_call, -1);
1051
+
1052
+ /* Win32::API::Callback Instance Methods */
1053
+ rb_define_method(cCallback, "initialize", callback_init, -1);
1054
+
1055
+ /* Win32::API::Function Instance Methods */
1056
+ rb_define_method(cFunction, "initialize", func_init, -1);
1057
+
1058
+ /* The name of the DLL that exports the API function */
1059
+ rb_define_attr(cAPI, "dll_name", 1, 0);
1060
+
1061
+ /* The name of the function passed to the constructor */
1062
+ rb_define_attr(cAPI, "function_name", 1, 0);
1063
+
1064
+ /* The name of the actual function that is returned by the constructor.
1065
+ * For example, if you passed 'GetUserName' to the constructor, then the
1066
+ * effective function name would be either 'GetUserNameA' or 'GetUserNameW'.
1067
+ */
1068
+ rb_define_attr(cAPI, "effective_function_name", 1, 0);
1069
+
1070
+ /* The prototype, returned as an array of characters */
1071
+ rb_define_attr(cAPI, "prototype", 1, 0);
1072
+
1073
+ /* The return type, returned as a single character, S, P, L, I, V or B */
1074
+ rb_define_attr(cAPI, "return_type", 1, 0);
1075
+
1076
+ /* Win32::API::Callback Instance Methods */
1077
+
1078
+ /* The prototype, returned as an array of characters */
1079
+ rb_define_attr(cCallback, "prototype", 1, 0);
1080
+
1081
+ /* The return type, returned as a single character, S, P, L, I, V or B */
1082
+ rb_define_attr(cCallback, "return_type", 1, 0);
1083
+
1084
+ /* The numeric address of the function pointer */
1085
+ rb_define_attr(cCallback, "address", 1, 0);
1086
+ rb_define_attr(cFunction, "address", 1, 0);
1087
+
1088
+ /* Constants */
1089
+
1090
+ /* 1.6.0: The version of the win32-api library */
1091
+ rb_define_const(cAPI, "VERSION", rb_str_new2(WINDOWS_API_VERSION));
1092
+ }