win32-api 1.4.6 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (564) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +219 -132
  3. data/Dockerfile +113 -0
  4. data/Dockerfile.trunk +17 -0
  5. data/Gemfile +4 -0
  6. data/Gemfile.lock +23 -0
  7. data/MANIFEST +9 -9
  8. data/{README → README.md} +136 -101
  9. data/RELEASE.md +41 -0
  10. data/Rakefile +263 -105
  11. data/appveyor.yml +46 -0
  12. data/build-gem.bat +3 -0
  13. data/ext/Makefile +269 -0
  14. data/ext/api-x64-mingw32.def +2 -0
  15. data/ext/api.o +0 -0
  16. data/ext/api.so +0 -0
  17. data/ext/extconf.rb +15 -11
  18. data/ext/mkmf.log +39 -0
  19. data/ext/win32/api.c +1158 -946
  20. data/ext/win32/api.so +0 -0
  21. data/test.rb +10 -0
  22. data/test/test_win32_api.rb +151 -140
  23. data/test/test_win32_api_callback.rb +74 -74
  24. data/test/test_win32_api_function.rb +66 -66
  25. data/vendor/bundle/ruby/2.5.0/bin/rake +27 -0
  26. data/vendor/bundle/ruby/2.5.0/bin/rake-compiler-dock +27 -0
  27. data/vendor/bundle/ruby/2.5.0/bin/rake-compiler-dock.bat +6 -0
  28. data/vendor/bundle/ruby/2.5.0/bin/rake.bat +6 -0
  29. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/BSDL +22 -0
  30. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/COPYING +57 -0
  31. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/Gemfile +9 -0
  32. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/LEGAL +4 -0
  33. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/README.rdoc +81 -0
  34. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/Rakefile +59 -0
  35. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/bin/console +12 -0
  36. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/bin/setup +6 -0
  37. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/lib/power_assert.rb +98 -0
  38. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/lib/power_assert/colorize.rb +9 -0
  39. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/lib/power_assert/configuration.rb +46 -0
  40. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/lib/power_assert/context.rb +235 -0
  41. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/lib/power_assert/enable_tracepoint_events.rb +91 -0
  42. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/lib/power_assert/inspector.rb +61 -0
  43. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/lib/power_assert/parser.rb +251 -0
  44. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/lib/power_assert/version.rb +3 -0
  45. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.5/power_assert.gemspec +31 -0
  46. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/BSDL +22 -0
  47. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/COPYING +57 -0
  48. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/Gemfile +9 -0
  49. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/LEGAL +4 -0
  50. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/README.rdoc +81 -0
  51. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/Rakefile +59 -0
  52. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/bin/console +12 -0
  53. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/bin/setup +6 -0
  54. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/lib/power_assert.rb +98 -0
  55. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/lib/power_assert/colorize.rb +9 -0
  56. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/lib/power_assert/configuration.rb +46 -0
  57. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/lib/power_assert/context.rb +238 -0
  58. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/lib/power_assert/enable_tracepoint_events.rb +91 -0
  59. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/lib/power_assert/inspector.rb +61 -0
  60. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/lib/power_assert/parser.rb +251 -0
  61. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/lib/power_assert/version.rb +3 -0
  62. data/vendor/bundle/ruby/2.5.0/gems/power_assert-1.1.7/power_assert.gemspec +31 -0
  63. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/CONTRIBUTING.rdoc +43 -0
  64. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/Gemfile +10 -0
  65. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/History.rdoc +2368 -0
  66. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/MIT-LICENSE +21 -0
  67. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/README.rdoc +155 -0
  68. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/Rakefile +41 -0
  69. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/bin/bundle +105 -0
  70. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/bin/console +7 -0
  71. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/bin/rake +29 -0
  72. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/bin/rdoc +29 -0
  73. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/bin/rubocop +29 -0
  74. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/bin/setup +6 -0
  75. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/command_line_usage.rdoc +158 -0
  76. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/example/Rakefile1 +38 -0
  77. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/example/Rakefile2 +35 -0
  78. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/example/a.c +6 -0
  79. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/example/b.c +6 -0
  80. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/example/main.c +11 -0
  81. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/glossary.rdoc +42 -0
  82. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/jamis.rb +592 -0
  83. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/proto_rake.rdoc +127 -0
  84. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/rake.1 +156 -0
  85. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/rakefile.rdoc +622 -0
  86. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/doc/rational.rdoc +151 -0
  87. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/exe/rake +27 -0
  88. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake.rb +71 -0
  89. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/application.rb +824 -0
  90. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/backtrace.rb +24 -0
  91. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/clean.rb +78 -0
  92. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/cloneable.rb +17 -0
  93. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/cpu_counter.rb +107 -0
  94. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/default_loader.rb +15 -0
  95. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/dsl_definition.rb +195 -0
  96. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/early_time.rb +22 -0
  97. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/ext/core.rb +26 -0
  98. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/ext/string.rb +176 -0
  99. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/file_creation_task.rb +25 -0
  100. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/file_list.rb +435 -0
  101. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/file_task.rb +54 -0
  102. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/file_utils.rb +134 -0
  103. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/file_utils_ext.rb +134 -0
  104. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/invocation_chain.rb +57 -0
  105. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/invocation_exception_mixin.rb +17 -0
  106. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/late_time.rb +18 -0
  107. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/linked_list.rb +112 -0
  108. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/loaders/makefile.rb +54 -0
  109. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/multi_task.rb +14 -0
  110. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/name_space.rb +38 -0
  111. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/packagetask.rb +222 -0
  112. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/phony.rb +16 -0
  113. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/private_reader.rb +21 -0
  114. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/promise.rb +100 -0
  115. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/pseudo_status.rb +30 -0
  116. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/rake_module.rb +67 -0
  117. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/rake_test_loader.rb +27 -0
  118. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/rule_recursion_overflow_error.rb +20 -0
  119. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/scope.rb +43 -0
  120. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/task.rb +434 -0
  121. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/task_argument_error.rb +8 -0
  122. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/task_arguments.rb +109 -0
  123. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/task_manager.rb +331 -0
  124. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/tasklib.rb +12 -0
  125. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/testtask.rb +224 -0
  126. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/thread_history_display.rb +49 -0
  127. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/thread_pool.rb +163 -0
  128. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/trace_output.rb +23 -0
  129. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/version.rb +10 -0
  130. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/lib/rake/win32.rb +51 -0
  131. data/vendor/bundle/ruby/2.5.0/gems/rake-13.0.1/rake.gemspec +43 -0
  132. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/Dockerfile.jruby +61 -0
  133. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/Dockerfile.mri +122 -0
  134. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/Gemfile +8 -0
  135. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/History.md +130 -0
  136. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/LICENSE.txt +22 -0
  137. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/README.md +162 -0
  138. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/Rakefile +36 -0
  139. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/bin/rake-compiler-dock +18 -0
  140. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/build/mk_i686.rb +16 -0
  141. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/build/patches/rake-compiler-1.0.7/enable-static.diff +13 -0
  142. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/build/patches/ruby-2.5.3/no_sendfile.patch +24 -0
  143. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/build/runas +12 -0
  144. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/build/sigfw.c +45 -0
  145. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/build/strip_wrapper +30 -0
  146. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/build/sudoers +1 -0
  147. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/lib/rake_compiler_dock.rb +66 -0
  148. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/lib/rake_compiler_dock/colors.rb +43 -0
  149. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/lib/rake_compiler_dock/docker_check.rb +350 -0
  150. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/lib/rake_compiler_dock/gem_helper.rb +73 -0
  151. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/lib/rake_compiler_dock/predefined_user_group.rb +5 -0
  152. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/lib/rake_compiler_dock/starter.rb +155 -0
  153. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/lib/rake_compiler_dock/version.rb +4 -0
  154. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/rake-compiler-dock.gemspec +28 -0
  155. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/test/test_environment_variables.rb +54 -0
  156. data/vendor/bundle/ruby/2.5.0/gems/rake-compiler-dock-0.7.2/test/test_starter.rb +33 -0
  157. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/COPYING +67 -0
  158. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/GPL +339 -0
  159. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/LGPL +502 -0
  160. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/PSFL +271 -0
  161. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/README.md +101 -0
  162. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/Rakefile +80 -0
  163. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/doc/text/getting-started.md +246 -0
  164. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/doc/text/how-to.md +90 -0
  165. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/doc/text/news.md +1453 -0
  166. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test-unit.rb +34 -0
  167. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit.rb +514 -0
  168. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/assertion-failed-error.rb +25 -0
  169. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/assertions.rb +2256 -0
  170. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/attribute-matcher.rb +26 -0
  171. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/attribute.rb +227 -0
  172. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/auto-runner-loader.rb +17 -0
  173. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/autorunner.rb +537 -0
  174. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/code-snippet-fetcher.rb +56 -0
  175. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/collector.rb +73 -0
  176. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/collector/descendant.rb +19 -0
  177. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/collector/dir.rb +108 -0
  178. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/collector/load.rb +197 -0
  179. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/collector/objectspace.rb +34 -0
  180. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/collector/xml.rb +249 -0
  181. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/color-scheme.rb +198 -0
  182. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/color.rb +134 -0
  183. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/data-sets.rb +116 -0
  184. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/data.rb +371 -0
  185. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/diff.rb +746 -0
  186. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/error.rb +158 -0
  187. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/exception-handler.rb +82 -0
  188. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/failure.rb +169 -0
  189. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/fault-location-detector.rb +100 -0
  190. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/fixture.rb +298 -0
  191. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/notification.rb +138 -0
  192. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/omission.rb +198 -0
  193. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/pending.rb +155 -0
  194. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/priority.rb +196 -0
  195. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/runner/console.rb +84 -0
  196. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/runner/emacs.rb +8 -0
  197. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/runner/xml.rb +15 -0
  198. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/test-suite-creator.rb +103 -0
  199. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/testcase.rb +899 -0
  200. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/testresult.rb +132 -0
  201. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/testsuite.rb +175 -0
  202. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/ui/console/outputlevel.rb +15 -0
  203. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/ui/console/testrunner.rb +750 -0
  204. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/ui/emacs/testrunner.rb +49 -0
  205. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/ui/testrunner.rb +53 -0
  206. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/ui/testrunnermediator.rb +114 -0
  207. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  208. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/ui/xml/testrunner.rb +224 -0
  209. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/util/backtracefilter.rb +59 -0
  210. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/util/method-owner-finder.rb +28 -0
  211. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/util/observable.rb +90 -0
  212. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/util/output.rb +32 -0
  213. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/util/procwrapper.rb +48 -0
  214. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/lib/test/unit/version.rb +5 -0
  215. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/sample/adder.rb +13 -0
  216. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/sample/subtracter.rb +12 -0
  217. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/sample/test_adder.rb +20 -0
  218. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/sample/test_subtracter.rb +20 -0
  219. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/sample/test_user.rb +23 -0
  220. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/collector/test-descendant.rb +182 -0
  221. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/collector/test-load.rb +475 -0
  222. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/collector/test_dir.rb +407 -0
  223. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/collector/test_objectspace.rb +102 -0
  224. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/fixtures/header-label.csv +3 -0
  225. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/fixtures/header-label.tsv +3 -0
  226. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/fixtures/header.csv +3 -0
  227. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/fixtures/header.tsv +3 -0
  228. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/fixtures/no-header.csv +2 -0
  229. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/fixtures/no-header.tsv +2 -0
  230. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/fixtures/plus.csv +3 -0
  231. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/run-test.rb +22 -0
  232. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-assertions.rb +2187 -0
  233. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-attribute-matcher.rb +38 -0
  234. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-attribute.rb +123 -0
  235. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-code-snippet.rb +79 -0
  236. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-color-scheme.rb +82 -0
  237. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-color.rb +47 -0
  238. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-data.rb +419 -0
  239. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-diff.rb +518 -0
  240. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-emacs-runner.rb +60 -0
  241. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-error.rb +26 -0
  242. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-failure.rb +33 -0
  243. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-fault-location-detector.rb +163 -0
  244. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-fixture.rb +713 -0
  245. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-notification.rb +33 -0
  246. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-omission.rb +81 -0
  247. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-pending.rb +70 -0
  248. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-priority.rb +184 -0
  249. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-test-case.rb +1279 -0
  250. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-test-result.rb +113 -0
  251. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-test-suite-creator.rb +97 -0
  252. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/test-test-suite.rb +151 -0
  253. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/testunit-test-util.rb +33 -0
  254. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/ui/test_testrunmediator.rb +20 -0
  255. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/util/test-method-owner-finder.rb +38 -0
  256. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/util/test-output.rb +11 -0
  257. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/util/test_backtracefilter.rb +52 -0
  258. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/util/test_observable.rb +102 -0
  259. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.4/test/util/test_procwrapper.rb +36 -0
  260. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/COPYING +67 -0
  261. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/GPL +339 -0
  262. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/LGPL +502 -0
  263. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/PSFL +271 -0
  264. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/README.md +101 -0
  265. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/Rakefile +80 -0
  266. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/doc/text/getting-started.md +246 -0
  267. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/doc/text/how-to.md +90 -0
  268. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/doc/text/news.md +1464 -0
  269. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test-unit.rb +34 -0
  270. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit.rb +514 -0
  271. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/assertion-failed-error.rb +25 -0
  272. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/assertions.rb +2256 -0
  273. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/attribute-matcher.rb +26 -0
  274. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/attribute.rb +227 -0
  275. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/auto-runner-loader.rb +17 -0
  276. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/autorunner.rb +537 -0
  277. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/code-snippet-fetcher.rb +58 -0
  278. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/collector.rb +73 -0
  279. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/collector/descendant.rb +19 -0
  280. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/collector/dir.rb +108 -0
  281. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/collector/load.rb +197 -0
  282. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/collector/objectspace.rb +34 -0
  283. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/collector/xml.rb +249 -0
  284. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/color-scheme.rb +198 -0
  285. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/color.rb +134 -0
  286. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/data-sets.rb +116 -0
  287. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/data.rb +371 -0
  288. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/diff.rb +746 -0
  289. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/error.rb +158 -0
  290. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/exception-handler.rb +82 -0
  291. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/failure.rb +169 -0
  292. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/fault-location-detector.rb +100 -0
  293. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb +298 -0
  294. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/notification.rb +138 -0
  295. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/omission.rb +198 -0
  296. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/pending.rb +155 -0
  297. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/priority.rb +196 -0
  298. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/runner/console.rb +84 -0
  299. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/runner/emacs.rb +8 -0
  300. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/runner/xml.rb +15 -0
  301. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/test-suite-creator.rb +103 -0
  302. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb +899 -0
  303. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/testresult.rb +132 -0
  304. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb +175 -0
  305. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/outputlevel.rb +15 -0
  306. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb +750 -0
  307. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/ui/emacs/testrunner.rb +49 -0
  308. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunner.rb +53 -0
  309. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb +114 -0
  310. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  311. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/ui/xml/testrunner.rb +224 -0
  312. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/util/backtracefilter.rb +59 -0
  313. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/util/method-owner-finder.rb +28 -0
  314. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb +90 -0
  315. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/util/output.rb +32 -0
  316. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/util/procwrapper.rb +48 -0
  317. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/lib/test/unit/version.rb +5 -0
  318. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/sample/adder.rb +13 -0
  319. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/sample/subtracter.rb +12 -0
  320. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/sample/test_adder.rb +20 -0
  321. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/sample/test_subtracter.rb +20 -0
  322. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/sample/test_user.rb +23 -0
  323. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/collector/test-descendant.rb +182 -0
  324. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/collector/test-load.rb +475 -0
  325. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/collector/test_dir.rb +407 -0
  326. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/collector/test_objectspace.rb +102 -0
  327. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/fixtures/header-label.csv +3 -0
  328. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/fixtures/header-label.tsv +3 -0
  329. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/fixtures/header.csv +3 -0
  330. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/fixtures/header.tsv +3 -0
  331. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/fixtures/no-header.csv +2 -0
  332. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/fixtures/no-header.tsv +2 -0
  333. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/fixtures/plus.csv +3 -0
  334. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/run-test.rb +22 -0
  335. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-assertions.rb +2187 -0
  336. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-attribute-matcher.rb +38 -0
  337. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-attribute.rb +123 -0
  338. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-code-snippet.rb +79 -0
  339. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-color-scheme.rb +82 -0
  340. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-color.rb +47 -0
  341. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-data.rb +419 -0
  342. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-diff.rb +518 -0
  343. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-emacs-runner.rb +60 -0
  344. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-error.rb +26 -0
  345. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-failure.rb +33 -0
  346. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-fault-location-detector.rb +163 -0
  347. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-fixture.rb +713 -0
  348. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-notification.rb +33 -0
  349. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-omission.rb +81 -0
  350. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-pending.rb +70 -0
  351. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-priority.rb +184 -0
  352. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-test-case.rb +1279 -0
  353. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-test-result.rb +113 -0
  354. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-test-suite-creator.rb +97 -0
  355. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/test-test-suite.rb +151 -0
  356. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/testunit-test-util.rb +33 -0
  357. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/ui/test_testrunmediator.rb +20 -0
  358. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/util/test-method-owner-finder.rb +38 -0
  359. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/util/test-output.rb +11 -0
  360. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/util/test_backtracefilter.rb +52 -0
  361. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/util/test_observable.rb +102 -0
  362. data/vendor/bundle/ruby/2.5.0/gems/test-unit-3.3.5/test/util/test_procwrapper.rb +36 -0
  363. data/vendor/bundle/ruby/2.5.0/specifications/power_assert-1.1.5.gemspec +54 -0
  364. data/vendor/bundle/ruby/2.5.0/specifications/power_assert-1.1.7.gemspec +54 -0
  365. data/vendor/bundle/ruby/2.5.0/specifications/rake-13.0.1.gemspec +26 -0
  366. data/vendor/bundle/ruby/2.5.0/specifications/rake-compiler-dock-0.7.2.gemspec +40 -0
  367. data/vendor/bundle/ruby/2.5.0/specifications/test-unit-3.3.4.gemspec +48 -0
  368. data/vendor/bundle/ruby/2.5.0/specifications/test-unit-3.3.5.gemspec +48 -0
  369. data/vendor/bundle/ruby/2.7.0/bin/rake +27 -0
  370. data/vendor/bundle/ruby/2.7.0/bin/rake.bat +2 -0
  371. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/BSDL +22 -0
  372. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/COPYING +57 -0
  373. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/Gemfile +9 -0
  374. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/LEGAL +4 -0
  375. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/README.rdoc +81 -0
  376. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/Rakefile +59 -0
  377. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/bin/console +12 -0
  378. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/bin/setup +6 -0
  379. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/lib/power_assert.rb +98 -0
  380. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/lib/power_assert/colorize.rb +9 -0
  381. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/lib/power_assert/configuration.rb +46 -0
  382. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/lib/power_assert/context.rb +238 -0
  383. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/lib/power_assert/enable_tracepoint_events.rb +91 -0
  384. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/lib/power_assert/inspector.rb +61 -0
  385. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/lib/power_assert/parser.rb +251 -0
  386. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/lib/power_assert/version.rb +3 -0
  387. data/vendor/bundle/ruby/2.7.0/gems/power_assert-1.1.7/power_assert.gemspec +31 -0
  388. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/CONTRIBUTING.rdoc +43 -0
  389. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/Gemfile +10 -0
  390. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/History.rdoc +2368 -0
  391. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/MIT-LICENSE +21 -0
  392. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/README.rdoc +155 -0
  393. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/Rakefile +41 -0
  394. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/bin/bundle +105 -0
  395. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/bin/console +7 -0
  396. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/bin/rake +29 -0
  397. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/bin/rdoc +29 -0
  398. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/bin/rubocop +29 -0
  399. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/bin/setup +6 -0
  400. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/command_line_usage.rdoc +158 -0
  401. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/example/Rakefile1 +38 -0
  402. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/example/Rakefile2 +35 -0
  403. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/example/a.c +6 -0
  404. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/example/b.c +6 -0
  405. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/example/main.c +11 -0
  406. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/glossary.rdoc +42 -0
  407. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/jamis.rb +592 -0
  408. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/proto_rake.rdoc +127 -0
  409. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/rake.1 +156 -0
  410. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/rakefile.rdoc +622 -0
  411. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/doc/rational.rdoc +151 -0
  412. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/exe/rake +27 -0
  413. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake.rb +71 -0
  414. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/application.rb +824 -0
  415. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/backtrace.rb +24 -0
  416. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/clean.rb +78 -0
  417. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/cloneable.rb +17 -0
  418. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/cpu_counter.rb +107 -0
  419. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/default_loader.rb +15 -0
  420. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/dsl_definition.rb +195 -0
  421. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/early_time.rb +22 -0
  422. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/ext/core.rb +26 -0
  423. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/ext/string.rb +176 -0
  424. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/file_creation_task.rb +25 -0
  425. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/file_list.rb +435 -0
  426. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/file_task.rb +54 -0
  427. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/file_utils.rb +134 -0
  428. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/file_utils_ext.rb +134 -0
  429. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/invocation_chain.rb +57 -0
  430. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/invocation_exception_mixin.rb +17 -0
  431. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/late_time.rb +18 -0
  432. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/linked_list.rb +112 -0
  433. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/loaders/makefile.rb +54 -0
  434. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/multi_task.rb +14 -0
  435. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/name_space.rb +38 -0
  436. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/packagetask.rb +222 -0
  437. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/phony.rb +16 -0
  438. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/private_reader.rb +21 -0
  439. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/promise.rb +100 -0
  440. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/pseudo_status.rb +30 -0
  441. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/rake_module.rb +67 -0
  442. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/rake_test_loader.rb +27 -0
  443. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/rule_recursion_overflow_error.rb +20 -0
  444. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/scope.rb +43 -0
  445. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/task.rb +434 -0
  446. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/task_argument_error.rb +8 -0
  447. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/task_arguments.rb +109 -0
  448. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/task_manager.rb +331 -0
  449. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/tasklib.rb +12 -0
  450. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/testtask.rb +224 -0
  451. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/thread_history_display.rb +49 -0
  452. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/thread_pool.rb +163 -0
  453. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/trace_output.rb +23 -0
  454. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/version.rb +10 -0
  455. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/lib/rake/win32.rb +51 -0
  456. data/vendor/bundle/ruby/2.7.0/gems/rake-13.0.1/rake.gemspec +43 -0
  457. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/COPYING +67 -0
  458. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/GPL +339 -0
  459. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/LGPL +502 -0
  460. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/PSFL +271 -0
  461. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/README.md +101 -0
  462. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/Rakefile +80 -0
  463. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/doc/text/getting-started.md +246 -0
  464. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/doc/text/how-to.md +90 -0
  465. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/doc/text/news.md +1464 -0
  466. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test-unit.rb +34 -0
  467. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit.rb +514 -0
  468. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/assertion-failed-error.rb +25 -0
  469. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/assertions.rb +2256 -0
  470. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/attribute-matcher.rb +26 -0
  471. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/attribute.rb +227 -0
  472. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/auto-runner-loader.rb +17 -0
  473. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/autorunner.rb +537 -0
  474. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/code-snippet-fetcher.rb +58 -0
  475. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/collector.rb +73 -0
  476. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/collector/descendant.rb +19 -0
  477. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/collector/dir.rb +108 -0
  478. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/collector/load.rb +197 -0
  479. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/collector/objectspace.rb +34 -0
  480. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/collector/xml.rb +249 -0
  481. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/color-scheme.rb +198 -0
  482. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/color.rb +134 -0
  483. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/data-sets.rb +116 -0
  484. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/data.rb +371 -0
  485. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/diff.rb +746 -0
  486. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/error.rb +158 -0
  487. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/exception-handler.rb +82 -0
  488. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/failure.rb +169 -0
  489. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fault-location-detector.rb +100 -0
  490. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb +298 -0
  491. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/notification.rb +138 -0
  492. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/omission.rb +198 -0
  493. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/pending.rb +155 -0
  494. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/priority.rb +196 -0
  495. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/runner/console.rb +84 -0
  496. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/runner/emacs.rb +8 -0
  497. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/runner/xml.rb +15 -0
  498. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/test-suite-creator.rb +103 -0
  499. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb +899 -0
  500. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testresult.rb +132 -0
  501. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb +175 -0
  502. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/outputlevel.rb +15 -0
  503. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb +750 -0
  504. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/emacs/testrunner.rb +49 -0
  505. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunner.rb +53 -0
  506. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb +114 -0
  507. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  508. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/xml/testrunner.rb +224 -0
  509. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/backtracefilter.rb +59 -0
  510. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/method-owner-finder.rb +28 -0
  511. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb +90 -0
  512. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/output.rb +32 -0
  513. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/procwrapper.rb +48 -0
  514. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/version.rb +5 -0
  515. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/sample/adder.rb +13 -0
  516. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/sample/subtracter.rb +12 -0
  517. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/sample/test_adder.rb +20 -0
  518. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/sample/test_subtracter.rb +20 -0
  519. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/sample/test_user.rb +23 -0
  520. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/collector/test-descendant.rb +182 -0
  521. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/collector/test-load.rb +475 -0
  522. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/collector/test_dir.rb +407 -0
  523. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/collector/test_objectspace.rb +102 -0
  524. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/fixtures/header-label.csv +3 -0
  525. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/fixtures/header-label.tsv +3 -0
  526. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/fixtures/header.csv +3 -0
  527. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/fixtures/header.tsv +3 -0
  528. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/fixtures/no-header.csv +2 -0
  529. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/fixtures/no-header.tsv +2 -0
  530. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/fixtures/plus.csv +3 -0
  531. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/run-test.rb +22 -0
  532. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-assertions.rb +2187 -0
  533. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-attribute-matcher.rb +38 -0
  534. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-attribute.rb +123 -0
  535. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-code-snippet.rb +79 -0
  536. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-color-scheme.rb +82 -0
  537. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-color.rb +47 -0
  538. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-data.rb +419 -0
  539. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-diff.rb +518 -0
  540. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-emacs-runner.rb +60 -0
  541. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-error.rb +26 -0
  542. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-failure.rb +33 -0
  543. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-fault-location-detector.rb +163 -0
  544. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-fixture.rb +713 -0
  545. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-notification.rb +33 -0
  546. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-omission.rb +81 -0
  547. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-pending.rb +70 -0
  548. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-priority.rb +184 -0
  549. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-test-case.rb +1279 -0
  550. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-test-result.rb +113 -0
  551. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-test-suite-creator.rb +97 -0
  552. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/test-test-suite.rb +151 -0
  553. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/testunit-test-util.rb +33 -0
  554. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/ui/test_testrunmediator.rb +20 -0
  555. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/util/test-method-owner-finder.rb +38 -0
  556. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/util/test-output.rb +11 -0
  557. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/util/test_backtracefilter.rb +52 -0
  558. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/util/test_observable.rb +102 -0
  559. data/vendor/bundle/ruby/2.7.0/gems/test-unit-3.3.5/test/util/test_procwrapper.rb +36 -0
  560. data/vendor/bundle/ruby/2.7.0/specifications/power_assert-1.1.7.gemspec +46 -0
  561. data/vendor/bundle/ruby/2.7.0/specifications/rake-13.0.1.gemspec +26 -0
  562. data/vendor/bundle/ruby/2.7.0/specifications/test-unit-3.3.5.gemspec +41 -0
  563. data/win32-api.gemspec +27 -29
  564. metadata +613 -47
data/appveyor.yml ADDED
@@ -0,0 +1,46 @@
1
+ version: '{build}'
2
+
3
+ image: Visual Studio 2019
4
+
5
+ init:
6
+ # use a minimal path
7
+ - set PATH=C:\ruby%ruby_version%\bin;C:\Program Files\7-Zip;C:\Program Files\AppVeyor\BuildAgent;C:\Program Files\Git\cmd;C:\Windows\system32
8
+ # Load ruby trunk build
9
+ - if %ruby_version%==_trunk (
10
+ appveyor DownloadFile https://ci.appveyor.com/api/projects/MSP-Greg/ruby-loco/artifacts/ruby_trunk.7z -FileName C:\ruby_trunk.7z &
11
+ 7z x C:\ruby_trunk.7z -oC:\ruby_trunk
12
+ )
13
+
14
+ platform: x64
15
+
16
+ install:
17
+ - ruby --version
18
+ - gem --version
19
+ # Assume we can use the version of bundler that Appveyor has packaged with each ruby version
20
+ - bundle install
21
+
22
+ build: off
23
+
24
+ test_script:
25
+ - rake gem:binary
26
+ - rake -rdevkit test:all
27
+
28
+ environment:
29
+ matrix:
30
+ - ruby_version: _trunk
31
+ - ruby_version: 30-x64
32
+ - ruby_version: 30
33
+ - ruby_version: 27-x64
34
+ - ruby_version: 27
35
+ - ruby_version: 26-x64
36
+ - ruby_version: 26
37
+ - ruby_version: 25-x64
38
+ - ruby_version: 25
39
+ - ruby_version: 24-x64
40
+ - ruby_version: 24
41
+ - ruby_version: 23-x64
42
+ - ruby_version: 23
43
+
44
+ matrix:
45
+ allow_failures:
46
+ - ruby_version: _trunk
data/build-gem.bat ADDED
@@ -0,0 +1,3 @@
1
+ git clone https://github.com/cosmo0920/win32-api win32-api
2
+ cd win32-api
3
+ rake -rdevkit gem:binary
data/ext/Makefile ADDED
@@ -0,0 +1,269 @@
1
+
2
+ SHELL = /bin/sh
3
+
4
+ # V=0 quiet, V=1 verbose. other values don't work.
5
+ V = 0
6
+ Q1 = $(V:1=)
7
+ Q = $(Q1:0=@)
8
+ ECHO1 = $(V:1=@ :)
9
+ ECHO = $(ECHO1:0=@ echo)
10
+ NULLCMD = :
11
+
12
+ #### Start of system configuration section. ####
13
+
14
+ srcdir = win32
15
+ topdir = /C/Ruby27-x64/include/ruby-2.7.0
16
+ hdrdir = $(topdir)
17
+ arch_hdrdir = C:/Ruby27-x64/include/ruby-2.7.0/x64-mingw32
18
+ PATH_SEPARATOR = :
19
+ VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
20
+ prefix = $(DESTDIR)/C/Ruby27-x64
21
+ rubysitearchprefix = $(rubylibprefix)/$(sitearch)
22
+ rubyarchprefix = $(rubylibprefix)/$(arch)
23
+ rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
24
+ exec_prefix = $(prefix)
25
+ vendorarchhdrdir = $(vendorhdrdir)/$(sitearch)
26
+ sitearchhdrdir = $(sitehdrdir)/$(sitearch)
27
+ rubyarchhdrdir = $(rubyhdrdir)/$(arch)
28
+ vendorhdrdir = $(rubyhdrdir)/vendor_ruby
29
+ sitehdrdir = $(rubyhdrdir)/site_ruby
30
+ rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
31
+ vendorarchdir = $(vendorlibdir)/$(sitearch)
32
+ vendorlibdir = $(vendordir)/$(ruby_version)
33
+ vendordir = $(rubylibprefix)/vendor_ruby
34
+ sitearchdir = $(sitelibdir)/$(sitearch)
35
+ sitelibdir = $(sitedir)/$(ruby_version)
36
+ sitedir = $(rubylibprefix)/site_ruby
37
+ rubyarchdir = $(rubylibdir)/$(arch)
38
+ rubylibdir = $(rubylibprefix)/$(ruby_version)
39
+ sitearchincludedir = $(includedir)/$(sitearch)
40
+ archincludedir = $(includedir)/$(arch)
41
+ sitearchlibdir = $(libdir)/$(sitearch)
42
+ archlibdir = $(libdir)/$(arch)
43
+ ridir = $(datarootdir)/$(RI_BASE_NAME)
44
+ mandir = $(datarootdir)/man
45
+ localedir = $(datarootdir)/locale
46
+ libdir = $(exec_prefix)/lib
47
+ psdir = $(docdir)
48
+ pdfdir = $(docdir)
49
+ dvidir = $(docdir)
50
+ htmldir = $(docdir)
51
+ infodir = $(datarootdir)/info
52
+ docdir = $(datarootdir)/doc/$(PACKAGE)
53
+ oldincludedir = $(DESTDIR)/usr/include
54
+ includedir = $(prefix)/include
55
+ localstatedir = $(prefix)/var
56
+ sharedstatedir = $(prefix)/com
57
+ sysconfdir = $(DESTDIR)
58
+ datadir = $(datarootdir)
59
+ datarootdir = $(prefix)/share
60
+ libexecdir = $(exec_prefix)/libexec
61
+ sbindir = $(exec_prefix)/sbin
62
+ bindir = $(exec_prefix)/bin
63
+ archdir = $(rubyarchdir)
64
+
65
+
66
+ CC_WRAPPER =
67
+ CC = x86_64-w64-mingw32-gcc
68
+ CXX = x86_64-w64-mingw32-g++
69
+ LIBRUBY = lib$(RUBY_SO_NAME).dll.a
70
+ LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
71
+ LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
72
+ LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static $(MAINLIBS)
73
+ empty =
74
+ OUTFLAG = -o $(empty)
75
+ COUTFLAG = -o $(empty)
76
+ CSRCFLAG = $(empty)
77
+
78
+ RUBY_EXTCONF_H =
79
+ cflags = $(optflags) $(debugflags) $(warnflags)
80
+ cxxflags =
81
+ optflags = -O3 -fno-omit-frame-pointer
82
+ debugflags = -ggdb3
83
+ warnflags = -Wall -Wextra -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable
84
+ cppflags =
85
+ CCDLFLAGS =
86
+ CFLAGS = $(CCDLFLAGS) -O3 -fno-fast-math -fstack-protector-strong -fno-omit-frame-pointer $(ARCH_FLAG)
87
+ INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
88
+ DEFS = -D_FILE_OFFSET_BITS=64
89
+ CPPFLAGS = -DHAVE_STRNCPY_S -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT $(DEFS) $(cppflags)
90
+ CXXFLAGS = $(CCDLFLAGS) -march=x86-64 -mtune=generic -O2 -pipe $(ARCH_FLAG)
91
+ ldflags = -L. -pipe -s -fstack-protector-strong
92
+ dldflags = -pipe -s -fstack-protector-strong -Wl,--enable-auto-image-base,--enable-auto-import $(DEFFILE)
93
+ ARCH_FLAG =
94
+ DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
95
+ LDSHARED = $(CC) -shared
96
+ LDSHAREDXX = $(CXX) -shared
97
+ AR = ar
98
+ EXEEXT = .exe
99
+
100
+ RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)
101
+ RUBY_SO_NAME = x64-msvcrt-ruby270
102
+ RUBYW_INSTALL_NAME = $(RUBYW_BASE_NAME)
103
+ RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
104
+ RUBYW_BASE_NAME = rubyw
105
+ RUBY_BASE_NAME = ruby
106
+
107
+ arch = x64-mingw32
108
+ sitearch = x64-msvcrt
109
+ ruby_version = 2.7.0
110
+ ruby = $(bindir)/$(RUBY_BASE_NAME)
111
+ RUBY = $(ruby)
112
+ ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h
113
+
114
+ RM = rm -f
115
+ RM_RF = $(RUBY) -run -e rm -- -rf
116
+ RMDIRS = rmdir --ignore-fail-on-non-empty -p
117
+ MAKEDIRS = /usr/bin/mkdir -p
118
+ INSTALL = /usr/bin/install -c
119
+ INSTALL_PROG = $(INSTALL) -m 0755
120
+ INSTALL_DATA = $(INSTALL) -m 644
121
+ COPY = cp
122
+ TOUCH = exit >
123
+
124
+ #### End of system configuration section. ####
125
+
126
+ preload =
127
+ libpath = . $(libdir)
128
+ LIBPATH = -L. -L$(libdir)
129
+ DEFFILE = $(TARGET)-$(arch).def
130
+
131
+ CLEANFILES = mkmf.log $(DEFFILE)
132
+ DISTCLEANFILES =
133
+ DISTCLEANDIRS =
134
+
135
+ extout =
136
+ extout_prefix =
137
+ target_prefix = /win32
138
+ LOCAL_LIBS =
139
+ LIBS = $(LIBRUBYARG_SHARED) -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi
140
+ ORIG_SRCS = api.c
141
+ SRCS = $(ORIG_SRCS)
142
+ OBJS = api.o
143
+ HDRS =
144
+ LOCAL_HDRS =
145
+ TARGET = api
146
+ TARGET_NAME = api
147
+ TARGET_ENTRY = Init_$(TARGET_NAME)
148
+ DLLIB = $(TARGET).so
149
+ EXTSTATIC =
150
+ STATIC_LIB =
151
+
152
+ TIMESTAMP_DIR = .
153
+ BINDIR = $(bindir)
154
+ RUBYCOMMONDIR = $(sitedir)$(target_prefix)
155
+ RUBYLIBDIR = $(sitelibdir)$(target_prefix)
156
+ RUBYARCHDIR = $(sitearchdir)$(target_prefix)
157
+ HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
158
+ ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
159
+ TARGET_SO_DIR =
160
+ TARGET_SO = $(TARGET_SO_DIR)$(DLLIB)
161
+ CLEANLIBS = $(TARGET_SO)
162
+ CLEANOBJS = *.o *.bak
163
+
164
+ all: $(DLLIB)
165
+ static: $(STATIC_LIB)
166
+ .PHONY: all install static install-so install-rb
167
+ .PHONY: clean clean-so clean-static clean-rb
168
+
169
+ clean-static::
170
+ clean-rb-default::
171
+ clean-rb::
172
+ clean-so::
173
+ clean: clean-so clean-static clean-rb-default clean-rb
174
+ -$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
175
+
176
+ distclean-rb-default::
177
+ distclean-rb::
178
+ distclean-so::
179
+ distclean-static::
180
+ distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
181
+ -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
182
+ -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
183
+ -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
184
+
185
+ realclean: distclean
186
+ install: install-so install-rb
187
+
188
+ install-so: $(DLLIB) $(TIMESTAMP_DIR)/.sitearchdir.-.win32.time
189
+ $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
190
+ clean-static::
191
+ -$(Q)$(RM) $(STATIC_LIB)
192
+ install-rb: pre-install-rb do-install-rb install-rb-default
193
+ install-rb-default: pre-install-rb-default do-install-rb-default
194
+ pre-install-rb: Makefile
195
+ pre-install-rb-default: Makefile
196
+ do-install-rb:
197
+ do-install-rb-default:
198
+ pre-install-rb-default:
199
+ @$(NULLCMD)
200
+ $(TIMESTAMP_DIR)/.sitearchdir.-.win32.time:
201
+ $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR)
202
+ $(Q) $(TOUCH) $@
203
+
204
+ site-install: site-install-so site-install-rb
205
+ site-install-so: install-so
206
+ site-install-rb: install-rb
207
+
208
+ .SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S
209
+
210
+ .cc.o:
211
+ $(ECHO) compiling $(<)
212
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
213
+
214
+ .cc.S:
215
+ $(ECHO) translating $(<)
216
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
217
+
218
+ .mm.o:
219
+ $(ECHO) compiling $(<)
220
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
221
+
222
+ .mm.S:
223
+ $(ECHO) translating $(<)
224
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
225
+
226
+ .cxx.o:
227
+ $(ECHO) compiling $(<)
228
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
229
+
230
+ .cxx.S:
231
+ $(ECHO) translating $(<)
232
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
233
+
234
+ .cpp.o:
235
+ $(ECHO) compiling $(<)
236
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
237
+
238
+ .cpp.S:
239
+ $(ECHO) translating $(<)
240
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
241
+
242
+ .c.o:
243
+ $(ECHO) compiling $(<)
244
+ $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
245
+
246
+ .c.S:
247
+ $(ECHO) translating $(<)
248
+ $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
249
+
250
+ .m.o:
251
+ $(ECHO) compiling $(<)
252
+ $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
253
+
254
+ .m.S:
255
+ $(ECHO) translating $(<)
256
+ $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
257
+
258
+ $(TARGET_SO): $(DEFFILE) $(OBJS) Makefile
259
+ $(ECHO) linking shared-object win32/$(DLLIB)
260
+ -$(Q)$(RM) $(@)
261
+ $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
262
+
263
+
264
+
265
+ $(DEFFILE):
266
+ $(ECHO) generating $(@)
267
+ $(Q) (echo EXPORTS && echo $(TARGET_ENTRY)) > $@
268
+
269
+ $(OBJS): $(HDRS) $(ruby_headers)
@@ -0,0 +1,2 @@
1
+ EXPORTS
2
+ Init_api
data/ext/api.o ADDED
Binary file
data/ext/api.so ADDED
Binary file
data/ext/extconf.rb CHANGED
@@ -1,11 +1,15 @@
1
- ##########################################################################
2
- # extconf.rb
3
- #
4
- # The Windows::API binary should be built using the Rake task, i.e.
5
- # 'rake build' or 'rake install'.
6
- ##########################################################################
7
- require 'mkmf'
8
-
9
- have_func('strncpy_s')
10
-
11
- create_makefile('win32/api', 'win32')
1
+ ##########################################################################
2
+ # extconf.rb
3
+ #
4
+ # The Windows::API binary should be built using the Rake task, i.e.
5
+ # 'rake build' or 'rake install'.
6
+ ##########################################################################
7
+ require 'mkmf'
8
+
9
+ if RbConfig::CONFIG['host_os'] =~ /mingw/
10
+ $CFLAGS << ' -fno-omit-frame-pointer'
11
+ end
12
+
13
+ have_func('strncpy_s')
14
+
15
+ create_makefile('win32/api', 'win32')
data/ext/mkmf.log ADDED
@@ -0,0 +1,39 @@
1
+ have_func: checking for strncpy_s()... -------------------- yes
2
+
3
+ "x86_64-w64-mingw32-gcc -o conftest.exe -IC:/Ruby27-x64/include/ruby-2.7.0/x64-mingw32 -IC:/Ruby27-x64/include/ruby-2.7.0/ruby/backward -IC:/Ruby27-x64/include/ruby-2.7.0 -I. -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64 -O3 -fno-fast-math -fstack-protector-strong -fno-omit-frame-pointer conftest.c -L. -LC:/Ruby27-x64/lib -L. -pipe -s -fstack-protector-strong -lx64-msvcrt-ruby270 -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi "
4
+ checked program was:
5
+ /* begin */
6
+ 1: #include "ruby.h"
7
+ 2:
8
+ 3: #include <winsock2.h>
9
+ 4: #include <windows.h>
10
+ 5: int main(int argc, char **argv)
11
+ 6: {
12
+ 7: return !!argv[argc];
13
+ 8: }
14
+ /* end */
15
+
16
+ "x86_64-w64-mingw32-gcc -o conftest.exe -IC:/Ruby27-x64/include/ruby-2.7.0/x64-mingw32 -IC:/Ruby27-x64/include/ruby-2.7.0/ruby/backward -IC:/Ruby27-x64/include/ruby-2.7.0 -I. -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64 -O3 -fno-fast-math -fstack-protector-strong -fno-omit-frame-pointer conftest.c -L. -LC:/Ruby27-x64/lib -L. -pipe -s -fstack-protector-strong -lx64-msvcrt-ruby270 -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi "
17
+ checked program was:
18
+ /* begin */
19
+ 1: #include "ruby.h"
20
+ 2:
21
+ 3: #include <winsock2.h>
22
+ 4: #include <windows.h>
23
+ 5:
24
+ 6: /*top*/
25
+ 7: extern int t(void);
26
+ 8: int main(int argc, char **argv)
27
+ 9: {
28
+ 10: if (argc > 1000000) {
29
+ 11: int (* volatile tp)(void)=(int (*)(void))&t;
30
+ 12: printf("%d", (*tp)());
31
+ 13: }
32
+ 14:
33
+ 15: return !!argv[argc];
34
+ 16: }
35
+ 17: int t(void) { void ((*volatile p)()); p = (void ((*)()))strncpy_s; return !p; }
36
+ /* end */
37
+
38
+ --------------------
39
+
data/ext/win32/api.c CHANGED
@@ -1,946 +1,1158 @@
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
- #define MAX_BUF 1024
20
- #define WINDOWS_API_VERSION "1.4.5"
21
-
22
- #define _T_VOID 0
23
- #define _T_LONG 1
24
- #define _T_POINTER 2
25
- #define _T_INTEGER 3
26
- #define _T_CALLBACK 4
27
- #define _T_STRING 5
28
-
29
- VALUE cAPIError, cAPIProtoError, cAPILoadError;
30
- static VALUE ActiveCallback = Qnil;
31
-
32
- typedef struct {
33
- HANDLE library;
34
- FARPROC function;
35
- int return_type;
36
- int prototype[20];
37
- } Win32API;
38
-
39
- static void api_free(Win32API* ptr){
40
- if(ptr->library)
41
- FreeLibrary(ptr->library);
42
-
43
- if(ptr)
44
- free(ptr);
45
- }
46
-
47
- static VALUE api_allocate(VALUE klass){
48
- Win32API* ptr = malloc(sizeof(Win32API));
49
- return Data_Wrap_Struct(klass, 0, api_free, ptr);
50
- }
51
-
52
- /* Helper function that converts the error number returned by GetLastError()
53
- * into a human readable string. Note that we always use English for error
54
- * output because that's what Ruby itself does.
55
- *
56
- * Internal use only.
57
- */
58
- char* StringError(DWORD dwError){
59
- LPVOID lpMsgBuf;
60
- static char buf[MAX_PATH];
61
- DWORD dwLen;
62
-
63
- // Assume ASCII error messages from the Windows API
64
- dwLen = FormatMessageA(
65
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
66
- FORMAT_MESSAGE_FROM_SYSTEM |
67
- FORMAT_MESSAGE_IGNORE_INSERTS,
68
- NULL,
69
- dwError,
70
- MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
71
- (LPSTR)&lpMsgBuf,
72
- 0,
73
- NULL
74
- );
75
-
76
- /* It appears that Windows doesn't necessarily ship with the DLL
77
- * required to always use English error messages. Check for error
78
- * ERROR_MUI_FILE_NOT_FOUND (15100), and try again if necessary.
79
- */
80
- if(!dwLen && GetLastError() == 15100){
81
- dwLen = FormatMessageA(
82
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
83
- FORMAT_MESSAGE_FROM_SYSTEM |
84
- FORMAT_MESSAGE_IGNORE_INSERTS,
85
- NULL,
86
- dwError,
87
- 0,
88
- (LPSTR)&lpMsgBuf,
89
- 0,
90
- NULL
91
- );
92
- }
93
-
94
- if(!dwLen){
95
- rb_raise(
96
- cAPIError,
97
- "Attempt to format message failed (error = '%d')",
98
- GetLastError()
99
- );
100
- }
101
-
102
- memset(buf, 0, MAX_PATH);
103
-
104
- /* remove \r\n */
105
- #ifdef HAVE_STRNCPY_S
106
- strncpy_s(buf, MAX_PATH, lpMsgBuf, dwLen - 2);
107
- #else
108
- strncpy(buf, lpMsgBuf, dwLen - 2);
109
- #endif
110
-
111
- LocalFree(lpMsgBuf);
112
-
113
- return buf;
114
- }
115
-
116
- /*
117
- * call-seq:
118
- * Win32::API::Callback.new(prototype, return='L'){ |proto| ... }
119
- *
120
- * Creates and returns a new Win32::API::Callback object. The prototype
121
- * arguments are yielded back to the block in the same order they were
122
- * declared.
123
- *
124
- * The +prototype+ is the function prototype for the callback function. This
125
- * is a string. The possible valid characters are 'I' (integer), 'L' (long),
126
- * 'V' (void), 'P' (pointer) or 'S' (string). Unlike API objects, API::Callback
127
- * objects do not have a default prototype.
128
- *
129
- * The +return+ argument is the return type for the callback function. The
130
- * valid characters are the same as for the +prototype+. The default is
131
- * 'L' (long).
132
- *
133
- * Example:
134
- * require 'win32/api'
135
- * include Win32
136
- *
137
- * EnumWindows = API.new('EnumWindows', 'KP', 'L', 'user32')
138
- * GetWindowText = API.new('GetWindowText', 'LPI', 'I', 'user32')
139
- *
140
- * EnumWindowsProc = API::Callback.new('LP', 'I'){ |handle, param|
141
- * buf = "\0" * 200
142
- * GetWindowText.call(handle, buf, 200);
143
- * puts buf.strip unless buf.strip.empty?
144
- * buf.index(param).nil? ? true : false
145
- * }
146
- *
147
- * EnumWindows.call(EnumWindowsProc, 'UEDIT32')
148
- */
149
- static VALUE callback_init(int argc, VALUE* argv, VALUE self)
150
- {
151
- void *find_callback(VALUE,int);
152
- VALUE v_proto, v_return, v_proc;
153
- int i;
154
-
155
- rb_scan_args(argc, argv, "11&", &v_proto, &v_return, &v_proc);
156
-
157
- /* Validate prototype characters */
158
- for(i = 0; i < RSTRING_LEN(v_proto); i++){
159
- switch(RSTRING_PTR(v_proto)[i]){
160
- case 'I': case 'L': case 'P': case 'V': case 'S':
161
- break;
162
- default:
163
- rb_raise(cAPIProtoError, "Illegal prototype '%c'",
164
- RSTRING_PTR(v_proto)[i]
165
- );
166
- }
167
- }
168
-
169
- if(NIL_P(v_return) || RARRAY_LEN(v_return) == 0){
170
- v_return = rb_str_new2("L");
171
- }
172
- else{
173
- switch(*(char*)RSTRING_PTR(v_return)){
174
- case 'I': case 'L': case 'P': case 'V': case 'S':
175
- break;
176
- default:
177
- rb_raise(cAPIProtoError, "Illegal return type '%s'",
178
- RSTRING_PTR(v_return)
179
- );
180
- }
181
- }
182
-
183
- rb_iv_set(self, "@function", v_proc);
184
- rb_iv_set(self, "@prototype", v_proto);
185
- rb_iv_set(self, "@return_type", v_return);
186
- rb_iv_set(self, "@address", ULONG2NUM((LPARAM)find_callback(self,RSTRING_LEN(v_proto))));
187
- ActiveCallback = self;
188
-
189
- return self;
190
- }
191
-
192
- /*
193
- * call-seq:
194
- * Win32::API.new(function, prototype='V', return='L', dll='kernel32')
195
- *
196
- * Creates and returns a new Win32::API object. The +function+ is the name
197
- * of the Windows function.
198
- *
199
- * The +prototype+ is the function prototype for +function+. This can be a
200
- * string or an array of characters. The possible valid characters are 'I'
201
- * (integer), 'L' (long), 'V' (void), 'P' (pointer), 'K' (callback) or 'S'
202
- * (string).
203
- *
204
- * The default is void ('V').
205
- *
206
- * Constant (const char*) strings should use 'S'. Pass by reference string
207
- * buffers should use 'P'. The former is faster, but cannot be modified.
208
- *
209
- * The +return+ argument is the return type for the function. The valid
210
- * characters are the same as for the +prototype+. The default is 'L' (long).
211
- *
212
- * The +dll+ is the name of the DLL file that the function is exported from.
213
- * The default is 'kernel32'.
214
- *
215
- * If the function cannot be found then an API::Error is raised (a subclass
216
- * of RuntimeError).
217
- *
218
- * Example:
219
- *
220
- * require 'win32/api'
221
- * include Win32
222
- *
223
- * buf = 0.chr * 260
224
- * len = [buf.length].pack('L')
225
- *
226
- * GetUserName = API.new('GetUserName', 'PP', 'I', 'advapi32')
227
- * GetUserName.call(buf, len)
228
- *
229
- * puts buf.strip
230
- */
231
- static VALUE api_init(int argc, VALUE* argv, VALUE self)
232
- {
233
- HMODULE hLibrary;
234
- FARPROC fProc;
235
- Win32API* ptr;
236
- int i;
237
- char* first = "A";
238
- char* second = "W";
239
- VALUE v_proc, v_proto, v_return, v_dll;
240
-
241
- rb_scan_args(argc, argv, "13", &v_proc, &v_proto, &v_return, &v_dll);
242
-
243
- Data_Get_Struct(self, Win32API, ptr);
244
-
245
- // Convert a string prototype to an array of characters
246
- if(rb_respond_to(v_proto, rb_intern("split")))
247
- v_proto = rb_str_split(v_proto, "");
248
-
249
- // Convert a nil or empty prototype to 'V' (void) automatically
250
- if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
251
- v_proto = rb_ary_new();
252
- rb_ary_push(v_proto, rb_str_new2("V"));
253
- }
254
-
255
- // Set an arbitrary limit of 20 parameters
256
- if(20 < RARRAY_LEN(v_proto))
257
- rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY_LEN(v_proto));
258
-
259
- // Set the default dll to 'kernel32'
260
- if(NIL_P(v_dll))
261
- v_dll = rb_str_new2("kernel32");
262
-
263
- // Set the default return type to 'L' (DWORD)
264
- if(NIL_P(v_return))
265
- v_return = rb_str_new2("L");
266
-
267
- SafeStringValue(v_dll);
268
- SafeStringValue(v_proc);
269
-
270
- hLibrary = LoadLibrary(TEXT(RSTRING_PTR(v_dll)));
271
-
272
- // The most likely cause of failure is a bad DLL load path
273
- if(!hLibrary){
274
- rb_raise(cAPILoadError, "LoadLibrary() function failed for '%s': %s",
275
- RSTRING_PTR(v_dll),
276
- StringError(GetLastError())
277
- );
278
- }
279
-
280
- ptr->library = hLibrary;
281
-
282
- /* Attempt to get the function. If it fails, try again with an 'A'
283
- * appended. If that fails, try again with a 'W' appended. If that
284
- * still fails, raise an API::LoadLibraryError.
285
- */
286
-
287
- fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_proc)));
288
-
289
- // Skip the ANSI and Wide function checks for MSVCRT functions.
290
- if(!fProc){
291
- if(strstr(RSTRING_PTR(v_dll), "msvcr")){
292
- rb_raise(
293
- cAPILoadError,
294
- "Unable to load function '%s'",
295
- RSTRING_PTR(v_proc)
296
- );
297
- }
298
- else{
299
- VALUE v_ascii = rb_str_new3(v_proc);
300
- v_ascii = rb_str_cat(v_ascii, first, 1);
301
- fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_ascii)));
302
-
303
- if(!fProc){
304
- VALUE v_unicode = rb_str_new3(v_proc);
305
- v_unicode = rb_str_cat(v_unicode, second, 1);
306
- fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_unicode)));
307
-
308
- if(!fProc){
309
- rb_raise(
310
- cAPILoadError,
311
- "Unable to load function '%s', '%s', or '%s'",
312
- RSTRING_PTR(v_proc),
313
- RSTRING_PTR(v_ascii),
314
- RSTRING_PTR(v_unicode)
315
- );
316
- }
317
- else{
318
- rb_iv_set(self, "@effective_function_name", v_unicode);
319
- }
320
- }
321
- else{
322
- rb_iv_set(self, "@effective_function_name", v_ascii);
323
- }
324
- }
325
- }
326
- else{
327
- rb_iv_set(self, "@effective_function_name", v_proc);
328
- }
329
-
330
- ptr->function = fProc;
331
-
332
- // Push the numeric prototypes onto our int array for later use.
333
-
334
- for(i = 0; i < RARRAY_LEN(v_proto); i++){
335
- SafeStringValue(RARRAY_PTR(v_proto)[i]);
336
- switch(*(char*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
337
- case 'L':
338
- ptr->prototype[i] = _T_LONG;
339
- break;
340
- case 'P':
341
- ptr->prototype[i] = _T_POINTER;
342
- break;
343
- case 'I': case 'B':
344
- ptr->prototype[i] = _T_INTEGER;
345
- break;
346
- case 'V':
347
- ptr->prototype[i] = _T_VOID;
348
- break;
349
- case 'K':
350
- ptr->prototype[i] = _T_CALLBACK;
351
- break;
352
- case 'S':
353
- ptr->prototype[i] = _T_STRING;
354
- break;
355
- default:
356
- rb_raise(cAPIProtoError, "Illegal prototype '%s'",
357
- StringValuePtr(RARRAY_PTR(v_proto)[i])
358
- );
359
- }
360
- }
361
-
362
- // Store the return type for later use.
363
-
364
- // Automatically convert empty strings or nil to type void.
365
- if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
366
- v_return = rb_str_new2("V");
367
- ptr->return_type = _T_VOID;
368
- }
369
- else{
370
- SafeStringValue(v_return);
371
- switch(*RSTRING_PTR(v_return)){
372
- case 'L':
373
- ptr->return_type = _T_LONG;
374
- break;
375
- case 'P':
376
- ptr->return_type = _T_POINTER;
377
- break;
378
- case 'I': case 'B':
379
- ptr->return_type = _T_INTEGER;
380
- break;
381
- case 'V':
382
- ptr->return_type = _T_VOID;
383
- break;
384
- case 'S':
385
- ptr->return_type = _T_STRING;
386
- break;
387
- default:
388
- rb_raise(cAPIProtoError, "Illegal return type '%s'",
389
- RSTRING_PTR(v_return)
390
- );
391
- }
392
- }
393
-
394
- rb_iv_set(self, "@dll_name", v_dll);
395
- rb_iv_set(self, "@function_name", v_proc);
396
- rb_iv_set(self, "@prototype", v_proto);
397
- rb_iv_set(self, "@return_type", v_return);
398
-
399
- return self;
400
- }
401
-
402
- /*
403
- * call-seq:
404
- *
405
- * API::Function.new(address, prototype = 'V', return_type = 'L')
406
- *
407
- * Creates and returns an API::Function object. This object is similar to an
408
- * API object, except that instead of a character function name you pass a
409
- * function pointer address as the first argument, and there's no associated
410
- * DLL file.
411
- *
412
- * Once you have your API::Function object you can then call it the same way
413
- * you would an API object.
414
- *
415
- * Example:
416
- *
417
- * require 'win32/api'
418
- * include Win32
419
- *
420
- * LoadLibrary = API.new('LoadLibrary', 'P', 'L')
421
- * GetProcAddress = API.new('GetProcAddress', 'LP', 'L')
422
- *
423
- * # Play a system beep
424
- * hlib = LoadLibrary.call('user32')
425
- * addr = GetProcAddress.call(hlib, 'MessageBeep')
426
- * func = Win32::API::Function.new(addr, 'L', 'L')
427
- * func.call(0)
428
- */
429
- static VALUE func_init(int argc, VALUE* argv, VALUE self){
430
- Win32API* ptr;
431
- int i;
432
- VALUE v_address, v_proto, v_return;
433
-
434
- rb_scan_args(argc, argv, "12", &v_address, &v_proto, &v_return);
435
-
436
- Data_Get_Struct(self, Win32API, ptr);
437
-
438
- // Convert a string prototype to an array of characters
439
- if(rb_respond_to(v_proto, rb_intern("split")))
440
- v_proto = rb_str_split(v_proto, "");
441
-
442
- // Convert a nil or empty prototype to 'V' (void) automatically
443
- if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
444
- v_proto = rb_ary_new();
445
- rb_ary_push(v_proto, rb_str_new2("V"));
446
- }
447
-
448
- // Set an arbitrary limit of 20 parameters
449
- if(20 < RARRAY_LEN(v_proto))
450
- rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY_LEN(v_proto));
451
-
452
- // Set the default return type to 'L' (DWORD)
453
- if(NIL_P(v_return))
454
- v_return = rb_str_new2("L");
455
-
456
- ptr->function = (FARPROC)NUM2LONG(v_address);
457
-
458
- // Push the numeric prototypes onto our int array for later use.
459
-
460
- for(i = 0; i < RARRAY_LEN(v_proto); i++){
461
- SafeStringValue(RARRAY_PTR(v_proto)[i]);
462
- switch(*(char*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
463
- case 'L':
464
- ptr->prototype[i] = _T_LONG;
465
- break;
466
- case 'P':
467
- ptr->prototype[i] = _T_POINTER;
468
- break;
469
- case 'I': case 'B':
470
- ptr->prototype[i] = _T_INTEGER;
471
- break;
472
- case 'V':
473
- ptr->prototype[i] = _T_VOID;
474
- break;
475
- case 'K':
476
- ptr->prototype[i] = _T_CALLBACK;
477
- break;
478
- case 'S':
479
- ptr->prototype[i] = _T_STRING;
480
- break;
481
- default:
482
- rb_raise(cAPIProtoError, "Illegal prototype '%s'",
483
- StringValuePtr(RARRAY_PTR(v_proto)[i])
484
- );
485
- }
486
- }
487
-
488
- // Store the return type for later use.
489
-
490
- // Automatically convert empty strings or nil to type void.
491
- if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
492
- v_return = rb_str_new2("V");
493
- ptr->return_type = _T_VOID;
494
- }
495
- else{
496
- SafeStringValue(v_return);
497
- switch(*RSTRING_PTR(v_return)){
498
- case 'L':
499
- ptr->return_type = _T_LONG;
500
- break;
501
- case 'P':
502
- ptr->return_type = _T_POINTER;
503
- break;
504
- case 'I': case 'B':
505
- ptr->return_type = _T_INTEGER;
506
- break;
507
- case 'V':
508
- ptr->return_type = _T_VOID;
509
- break;
510
- case 'S':
511
- ptr->return_type = _T_STRING;
512
- break;
513
- default:
514
- rb_raise(cAPIProtoError, "Illegal return type '%s'",
515
- RSTRING_PTR(v_return)
516
- );
517
- }
518
- }
519
-
520
- rb_iv_set(self, "@address", v_address);
521
- rb_iv_set(self, "@prototype", v_proto);
522
- rb_iv_set(self, "@return_type", v_return);
523
-
524
- return self;
525
- }
526
-
527
- typedef struct {
528
- DWORD params[20];
529
- } CALLPARAM;
530
-
531
-
532
- DWORD CallbackFunction(CALLPARAM param, VALUE callback)
533
- {
534
- VALUE v_proto, v_return, v_proc, v_retval;
535
- VALUE argv[20];
536
- int i, argc;
537
- char *a_proto;
538
- char *a_return;
539
-
540
- if(callback && !NIL_P(callback)){
541
- v_proto = rb_iv_get(callback, "@prototype");
542
- a_proto = RSTRING_PTR(v_proto);
543
-
544
- v_return = rb_iv_get(callback, "@return_type");
545
- a_return = RSTRING_PTR(v_return);
546
-
547
- v_proc = rb_iv_get(callback, "@function");
548
- argc = RSTRING_LEN(v_proto);
549
-
550
- for(i=0; i < RSTRING_LEN(v_proto); i++){
551
- argv[i] = Qnil;
552
- switch(a_proto[i]){
553
- case 'L':
554
- argv[i] = ULONG2NUM(param.params[i]);
555
- break;
556
- case 'P':
557
- if(param.params[i])
558
- argv[i] = rb_str_new2((char *)param.params[i]);
559
- break;
560
- case 'I':
561
- argv[i] = INT2NUM(param.params[i]);
562
- break;
563
- default:
564
- rb_raise(cAPIProtoError, "Illegal prototype '%s'", a_proto[i]);
565
- }
566
- }
567
-
568
- v_retval = rb_funcall2(v_proc, rb_intern("call"), argc, argv);
569
-
570
- /* Handle true and false explicitly, as some CALLBACK functions
571
- * require TRUE or FALSE to break out of loops, etc.
572
- */
573
- if(v_retval == Qtrue)
574
- return TRUE;
575
- else if(v_retval == Qfalse)
576
- return FALSE;
577
-
578
- switch (*a_return) {
579
- case 'I':
580
- return NUM2INT(v_retval);
581
- break;
582
- case 'L':
583
- return NUM2ULONG(v_retval);
584
- break;
585
- case 'S':
586
- return (unsigned long)RSTRING_PTR(v_retval);
587
- break;
588
- case 'P':
589
- if(NIL_P(v_retval)){
590
- return 0;
591
- }
592
- else if(FIXNUM_P(v_retval)){
593
- return NUM2ULONG(v_retval);
594
- }
595
- else{
596
- StringValue(v_retval);
597
- rb_str_modify(v_retval);
598
- return (unsigned long)StringValuePtr(v_retval);
599
- }
600
- break;
601
- }
602
- }
603
-
604
- return 0;
605
- }
606
-
607
- #define CALLBACK0(x) DWORD CALLBACK CallbackFunction0_##x() {\
608
- CALLPARAM param = {0};\
609
- param.params[0] = 0;\
610
- return CallbackFunction(param,FuncTable[0][x]);\
611
- }
612
-
613
- #define CALLBACK1(x) DWORD CALLBACK CallbackFunction1_##x(DWORD p1) {\
614
- CALLPARAM param = {p1};\
615
- return CallbackFunction(param,FuncTable[1][x]);\
616
- }
617
-
618
- #define CALLBACK2(x) DWORD CALLBACK CallbackFunction2_##x(\
619
- DWORD p1, DWORD p2){\
620
- CALLPARAM param = {p1,p2};\
621
- return CallbackFunction(param,FuncTable[2][x]);\
622
- }
623
-
624
- #define CALLBACK3(x) DWORD CALLBACK CallbackFunction3_##x(\
625
- DWORD p1, DWORD p2, DWORD p3){\
626
- CALLPARAM param = {p1,p2,p3};\
627
- return CallbackFunction(param,FuncTable[3][x]);\
628
- }
629
-
630
- #define CALLBACK4(x) DWORD CALLBACK CallbackFunction4_##x(\
631
- DWORD p1, DWORD p2, DWORD p3, DWORD p4){\
632
- CALLPARAM param = {p1,p2,p3,p4};\
633
- return CallbackFunction(param,FuncTable[4][x]);\
634
- }
635
-
636
- #define CALLBACK5(x) DWORD CALLBACK CallbackFunction5_##x(\
637
- DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5\
638
- ){\
639
- CALLPARAM param = {p1,p2,p3,p4,p5};\
640
- return CallbackFunction(param,FuncTable[5][x]);\
641
- }
642
-
643
- #define CALLBACK6(x) DWORD CALLBACK CallbackFunction6_##x(\
644
- DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5, DWORD p6\
645
- ){\
646
- CALLPARAM param = {p1,p2,p3,p4,p5,p6};\
647
- return CallbackFunction(param,FuncTable[6][x]);\
648
- }
649
-
650
- #define CALLBACK7(x) DWORD CALLBACK CallbackFunction7_##x(\
651
- DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5, DWORD p6, DWORD p7\
652
- ){\
653
- CALLPARAM param = {p1,p2,p3,p4,p5,p6,p7};\
654
- return CallbackFunction(param,FuncTable[7][x]);\
655
- }
656
-
657
- #define CALLBACK8(x) DWORD CALLBACK CallbackFunction8_##x(\
658
- DWORD p1, DWORD p2, DWORD p3, DWORD p4,\
659
- DWORD p5, DWORD p6, DWORD p7, DWORD p8\
660
- ){\
661
- CALLPARAM param = {p1,p2,p3,p4,p5,p6,p7,p8};\
662
- return CallbackFunction(param,FuncTable[8][x]);\
663
- }
664
-
665
- #define CALLBACK9(x) DWORD CALLBACK CallbackFunction9_##x(\
666
- DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5,\
667
- DWORD p6, DWORD p7, DWORD p8, DWORD p9\
668
- ){\
669
- CALLPARAM param = {p1,p2,p3,p4,p5,p6,p7,p8,p9};\
670
- return CallbackFunction(param,FuncTable[9][x]);\
671
- }
672
-
673
- #define DEFCALLBACK(x) CALLBACK##x(0)\
674
- CALLBACK##x(1)\
675
- CALLBACK##x(2)\
676
- CALLBACK##x(3)\
677
- CALLBACK##x(4)\
678
- CALLBACK##x(5)\
679
- CALLBACK##x(6)\
680
- CALLBACK##x(7)\
681
- CALLBACK##x(8)\
682
- CALLBACK##x(9)
683
-
684
- #define CF(x,y) CallbackFunction##x##_##y
685
-
686
- static VALUE FuncTable[10][10];
687
-
688
- DEFCALLBACK(0)
689
- DEFCALLBACK(1)
690
- DEFCALLBACK(2)
691
- DEFCALLBACK(3)
692
- DEFCALLBACK(4)
693
- DEFCALLBACK(5)
694
- DEFCALLBACK(6)
695
- DEFCALLBACK(7)
696
- DEFCALLBACK(8)
697
- DEFCALLBACK(9)
698
-
699
- void *CallbackTable[10][10] = {
700
- {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)},
701
- {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)},
702
- {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)},
703
- {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)},
704
- {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)},
705
- {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)},
706
- {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)},
707
- {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)},
708
- {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)},
709
- {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)}};
710
-
711
-
712
- void *find_callback(VALUE obj,int len)
713
- {
714
- int i;
715
- for(i=0;i<10;i++)
716
- {
717
- if(FuncTable[len][i]==0)
718
- break;
719
- }
720
- if(i>=10)
721
- rb_raise(cAPIError,"too many callbacks are defined.");
722
- FuncTable[len][i] = obj;
723
- return CallbackTable[len][i];
724
- }
725
-
726
- /*
727
- * call-seq:
728
- * Win32::API#call(arg1, arg2, ...)
729
- *
730
- * Calls the function pointer with the given arguments (if any). Note that,
731
- * while this method will catch some prototype mismatches (raising a TypeError
732
- * in the process), it is not fulproof. It is ultimately your job to make
733
- * sure the arguments match the +prototype+ specified in the constructor.
734
- *
735
- * For convenience, nil is converted to NULL, true is converted to TRUE (1)
736
- * and false is converted to FALSE (0).
737
- */
738
- static VALUE api_call(int argc, VALUE* argv, VALUE self){
739
- VALUE v_proto, v_args, v_arg, v_return;
740
- Win32API* ptr;
741
- unsigned long return_value;
742
- int i = 0;
743
- int len;
744
-
745
- struct{
746
- unsigned long params[20];
747
- } param;
748
-
749
- Data_Get_Struct(self, Win32API, ptr);
750
-
751
- rb_scan_args(argc, argv, "0*", &v_args);
752
-
753
- v_proto = rb_iv_get(self, "@prototype");
754
-
755
- // For void prototypes, allow either no args or an explicit nil
756
- if(RARRAY_LEN(v_proto) != RARRAY_LEN(v_args)){
757
- char* c = StringValuePtr(RARRAY_PTR(v_proto)[0]);
758
- if(!strcmp(c, "V")){
759
- rb_ary_push(v_args, Qnil);
760
- }
761
- else{
762
- rb_raise(rb_eArgError,
763
- "wrong number of parameters: expected %d, got %d",
764
- RARRAY_LEN(v_proto), RARRAY_LEN(v_args)
765
- );
766
- }
767
- }
768
-
769
- len = RARRAY_LEN(v_proto);
770
-
771
- for(i = 0; i < len; i++){
772
- v_arg = RARRAY_PTR(v_args)[i];
773
-
774
- // Convert nil to NULL. Otherwise convert as appropriate.
775
- if(NIL_P(v_arg))
776
- param.params[i] = (unsigned long)NULL;
777
- else if(v_arg == Qtrue)
778
- param.params[i] = TRUE;
779
- else if(v_arg == Qfalse)
780
- param.params[i] = FALSE;
781
- else
782
- switch(ptr->prototype[i]){
783
- case _T_LONG:
784
- param.params[i] = NUM2ULONG(v_arg);
785
- break;
786
- case _T_INTEGER:
787
- param.params[i] = NUM2INT(v_arg);
788
- break;
789
- case _T_POINTER:
790
- if(FIXNUM_P(v_arg)){
791
- param.params[i] = NUM2ULONG(v_arg);
792
- }
793
- else{
794
- StringValue(v_arg);
795
- rb_str_modify(v_arg);
796
- param.params[i] = (unsigned long)StringValuePtr(v_arg);
797
- }
798
- break;
799
- case _T_CALLBACK:
800
- ActiveCallback = v_arg;
801
- v_proto = rb_iv_get(ActiveCallback, "@prototype");
802
- param.params[i] = (LPARAM)NUM2ULONG(rb_iv_get(ActiveCallback, "@address"));;
803
- break;
804
- case _T_STRING:
805
- param.params[i] = (unsigned long)RSTRING_PTR(v_arg);
806
- break;
807
- default:
808
- param.params[i] = NUM2ULONG(v_arg);
809
- }
810
- }
811
-
812
- /* Call the function, get the return value */
813
- return_value = ptr->function(param);
814
-
815
-
816
- /* Return the appropriate type based on the return type specified
817
- * in the constructor.
818
- */
819
- switch(ptr->return_type){
820
- case _T_INTEGER:
821
- v_return = INT2NUM(return_value);
822
- break;
823
- case _T_LONG:
824
- v_return = ULONG2NUM(return_value);
825
- break;
826
- case _T_VOID:
827
- v_return = Qnil;
828
- break;
829
- case _T_POINTER:
830
- if(!return_value){
831
- v_return = Qnil;
832
- }
833
- else{
834
- VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
835
- char* efunc = RSTRING_PTR(v_efunc);
836
- if(efunc[strlen(efunc)-1] == 'W'){
837
- v_return = rb_str_new(
838
- (TCHAR*)return_value,
839
- wcslen((wchar_t*)return_value)*2
840
- );
841
- }
842
- else{
843
- v_return = rb_str_new2((TCHAR*)return_value);
844
- }
845
- }
846
- break;
847
- case _T_STRING:
848
- {
849
- VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
850
- char* efunc = RSTRING_PTR(v_efunc);
851
-
852
- if(efunc[strlen(efunc)-1] == 'W'){
853
- v_return = rb_str_new(
854
- (TCHAR*)return_value,
855
- wcslen((wchar_t*)return_value)*2
856
- );
857
- }
858
- else{
859
- v_return = rb_str_new2((TCHAR*)return_value);
860
- }
861
- }
862
- break;
863
- default:
864
- v_return = INT2NUM(0);
865
- }
866
-
867
- return v_return;
868
- }
869
-
870
- /*
871
- * Wraps the Windows API functions in a Ruby interface.
872
- */
873
- void Init_api(){
874
- VALUE mWin32, cAPI, cCallback, cFunction;
875
-
876
- /* Modules and Classes */
877
-
878
- /* The Win32 module serves as a namespace only */
879
- mWin32 = rb_define_module("Win32");
880
-
881
- /* The API class encapsulates a function pointer to Windows API function */
882
- cAPI = rb_define_class_under(mWin32, "API", rb_cObject);
883
-
884
- /* The API::Callback class encapsulates a Windows CALLBACK function */
885
- cCallback = rb_define_class_under(cAPI, "Callback", rb_cObject);
886
-
887
- /* The API::Function class encapsulates a raw function pointer */
888
- cFunction = rb_define_class_under(cAPI, "Function", cAPI);
889
-
890
- /* The API::Error class serves as a base class for other errors */
891
- cAPIError = rb_define_class_under(cAPI, "Error", rb_eRuntimeError);
892
-
893
- /* The LoadError class is raised if a function cannot be found or loaded */
894
- cAPILoadError = rb_define_class_under(cAPI, "LoadLibraryError", cAPIError);
895
-
896
- /* The PrototypeError class is raised if an invalid prototype is passed */
897
- cAPIProtoError = rb_define_class_under(cAPI, "PrototypeError", cAPIError);
898
-
899
- /* Miscellaneous */
900
- rb_define_alloc_func(cAPI, api_allocate);
901
-
902
- /* Win32::API Instance Methods */
903
- rb_define_method(cAPI, "initialize", api_init, -1);
904
- rb_define_method(cAPI, "call", api_call, -1);
905
-
906
- /* Win32::API::Callback Instance Methods */
907
- rb_define_method(cCallback, "initialize", callback_init, -1);
908
-
909
- /* Win32::API::Function Instance Methods */
910
- rb_define_method(cFunction, "initialize", func_init, -1);
911
-
912
- /* The name of the DLL that exports the API function */
913
- rb_define_attr(cAPI, "dll_name", 1, 0);
914
-
915
- /* The name of the function passed to the constructor */
916
- rb_define_attr(cAPI, "function_name", 1, 0);
917
-
918
- /* The name of the actual function that is returned by the constructor.
919
- * For example, if you passed 'GetUserName' to the constructor, then the
920
- * effective function name would be either 'GetUserNameA' or 'GetUserNameW'.
921
- */
922
- rb_define_attr(cAPI, "effective_function_name", 1, 0);
923
-
924
- /* The prototype, returned as an array of characters */
925
- rb_define_attr(cAPI, "prototype", 1, 0);
926
-
927
- /* The return type, returned as a single character, S, P, L, I, V or B */
928
- rb_define_attr(cAPI, "return_type", 1, 0);
929
-
930
- /* Win32::API::Callback Instance Methods */
931
-
932
- /* The prototype, returned as an array of characters */
933
- rb_define_attr(cCallback, "prototype", 1, 0);
934
-
935
- /* The return type, returned as a single character, S, P, L, I, V or B */
936
- rb_define_attr(cCallback, "return_type", 1, 0);
937
-
938
- /* The numeric address of the function pointer */
939
- rb_define_attr(cCallback, "address", 1, 0);
940
- rb_define_attr(cFunction, "address", 1, 0);
941
-
942
- /* Constants */
943
-
944
- /* 1.4.5: The version of the win32-api library */
945
- rb_define_const(cAPI, "VERSION", rb_str_new2(WINDOWS_API_VERSION));
946
- }
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
+ /* Use Ruby defined macro definitions. */
20
+ #if !defined(NUM2SIZET) && !defined(NUM2SSIZET)
21
+ # if defined(HAVE_LONG_LONG) && SIZEOF_SIZE_T > SIZEOF_LONG
22
+ # define NUM2SIZET(x) ((size_t)NUM2ULL(x))
23
+ # define NUM2SSIZET(x) ((ssize_t)NUM2LL(x))
24
+ # else
25
+ # define NUM2SIZET(x) NUM2ULONG(x)
26
+ # define NUM2SSIZET(x) NUM2LONG(x)
27
+ # endif
28
+ #endif
29
+
30
+ /* Use Ruby defined macro definitions. */
31
+ #if !defined(SIZET2NUM) && !defined(SSIZET2NUM)
32
+ # if SIZEOF_SIZE_T > SIZEOF_LONG && defined(HAVE_LONG_LONG)
33
+ # define SIZET2NUM(v) ULL2NUM(v)
34
+ # define SSIZET2NUM(v) LL2NUM(v)
35
+ # elif SIZEOF_SIZE_T == SIZEOF_LONG
36
+ # define SIZET2NUM(v) ULONG2NUM(v)
37
+ # define SSIZET2NUM(v) LONG2NUM(v)
38
+ # else
39
+ # define SIZET2NUM(v) UINT2NUM(v)
40
+ # define SSIZET2NUM(v) INT2NUM(v)
41
+ # endif
42
+ #endif
43
+
44
+
45
+ #define MAX_BUF 1024
46
+ #define WINDOWS_API_VERSION "1.10.0"
47
+
48
+ #define _T_VOID 0
49
+ #define _T_LONG 1
50
+ #define _T_POINTER 2
51
+ #define _T_INTEGER 3
52
+ #define _T_CALLBACK 4
53
+ #define _T_STRING 5
54
+
55
+ VALUE cAPIError, cAPIProtoError, cAPILoadError;
56
+ static VALUE ActiveCallback = Qnil;
57
+
58
+ typedef struct {
59
+ HANDLE library;
60
+ FARPROC function;
61
+ int return_type;
62
+ int prototype[20];
63
+ } Win32API;
64
+
65
+ typedef struct ThreadData {
66
+ DWORD win32api_error;
67
+ } ThreadData;
68
+
69
+ static inline ThreadData* thread_data_get(void);
70
+ static ID id_thread_data;
71
+
72
+ static ThreadData* thread_data_init(void)
73
+ {
74
+ ThreadData* td;
75
+ VALUE obj;
76
+
77
+ obj = Data_Make_Struct(rb_cObject, ThreadData, NULL, -1, td);
78
+ rb_thread_local_aset(rb_thread_current(), id_thread_data, obj);
79
+
80
+ return td;
81
+ }
82
+
83
+ static inline ThreadData* thread_data_get()
84
+ {
85
+ VALUE obj = rb_thread_local_aref(rb_thread_current(), id_thread_data);
86
+
87
+ if(obj != Qnil && TYPE(obj) == T_DATA){
88
+ return (ThreadData*) DATA_PTR(obj);
89
+ }
90
+
91
+ return thread_data_init();
92
+ }
93
+
94
+ static void api_free(Win32API* ptr){
95
+ if(ptr->library)
96
+ FreeLibrary(ptr->library);
97
+
98
+ if(ptr)
99
+ free(ptr);
100
+ }
101
+
102
+ static VALUE api_allocate(VALUE klass){
103
+ Win32API* ptr = malloc(sizeof(Win32API));
104
+ memset(ptr, 0, sizeof(*ptr));
105
+ return Data_Wrap_Struct(klass, 0, api_free, ptr);
106
+ }
107
+
108
+ /* Helper function that converts the error number returned by GetLastError()
109
+ * into a human readable string. Note that we always use English for error
110
+ * output because that's what Ruby itself does.
111
+ *
112
+ * Internal use only.
113
+ */
114
+ char* StringError(DWORD dwError){
115
+ LPVOID lpMsgBuf;
116
+ static char buf[MAX_PATH];
117
+ DWORD dwLen, dwLastError;
118
+
119
+ // Assume ASCII (English) error messages from the Windows API
120
+ dwLen = FormatMessageA(
121
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
122
+ FORMAT_MESSAGE_FROM_SYSTEM |
123
+ FORMAT_MESSAGE_IGNORE_INSERTS,
124
+ NULL,
125
+ dwError,
126
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
127
+ (LPSTR)&lpMsgBuf,
128
+ 0,
129
+ NULL
130
+ );
131
+
132
+ dwLastError = GetLastError();
133
+
134
+ /* It appears that Windows doesn't necessarily ship with the DLL
135
+ * required to always use English error messages. Check for error
136
+ * ERROR_MUI_FILE_NOT_FOUND (15100) or ERROR_RESOURCE_LANG_NOT_FOUND (1815)
137
+ * and try again if necessary.
138
+ */
139
+ if(!dwLen && (dwLastError == 15100 || dwLastError == 1815)){
140
+ dwLen = FormatMessageA(
141
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
142
+ FORMAT_MESSAGE_FROM_SYSTEM |
143
+ FORMAT_MESSAGE_IGNORE_INSERTS,
144
+ NULL,
145
+ dwError,
146
+ 0,
147
+ (LPSTR)&lpMsgBuf,
148
+ 0,
149
+ NULL
150
+ );
151
+ }
152
+
153
+ if(!dwLen){
154
+ rb_raise(
155
+ cAPIError,
156
+ "Attempt to format message failed (error = '%lu')",
157
+ GetLastError()
158
+ );
159
+ }
160
+
161
+ memset(buf, 0, MAX_PATH);
162
+
163
+ // Remove \r\n at end of string.
164
+ #ifdef HAVE_STRNCPY_S
165
+ strncpy_s(buf, MAX_PATH, lpMsgBuf, dwLen - 2);
166
+ #else
167
+ strncpy(buf, lpMsgBuf, dwLen - 2);
168
+ #endif
169
+
170
+ LocalFree(lpMsgBuf);
171
+
172
+ return buf;
173
+ }
174
+
175
+ /*
176
+ * call-seq:
177
+ * Win32::API::Callback.new(prototype, return='L'){ |proto| ... }
178
+ *
179
+ * Creates and returns a new Win32::API::Callback object. The prototype
180
+ * arguments are yielded back to the block in the same order they were
181
+ * declared.
182
+ *
183
+ * The +prototype+ is the function prototype for the callback function. This
184
+ * is a string. The possible valid characters are 'I' (integer), 'L' (long),
185
+ * 'V' (void), 'P' (pointer) or 'S' (string). Unlike API objects, API::Callback
186
+ * objects do not have a default prototype.
187
+ *
188
+ * The +return+ argument is the return type for the callback function. The
189
+ * valid characters are the same as for the +prototype+. The default is
190
+ * 'L' (long).
191
+ *
192
+ * Example:
193
+ * require 'win32/api'
194
+ * include Win32
195
+ *
196
+ * EnumWindows = API.new('EnumWindows', 'KP', 'L', 'user32')
197
+ * GetWindowText = API.new('GetWindowText', 'LPI', 'I', 'user32')
198
+ *
199
+ * EnumWindowsProc = API::Callback.new('LP', 'I'){ |handle, param|
200
+ * buf = "\0" * 200
201
+ * GetWindowText.call(handle, buf, 200);
202
+ * puts buf.strip unless buf.strip.empty?
203
+ * buf.index(param).nil? ? true : false
204
+ * }
205
+ *
206
+ * EnumWindows.call(EnumWindowsProc, 'UEDIT32')
207
+ */
208
+ static VALUE callback_init(int argc, VALUE* argv, VALUE self)
209
+ {
210
+ void *find_callback(VALUE,int);
211
+ VALUE v_proto, v_return, v_proc;
212
+ int i;
213
+
214
+ rb_scan_args(argc, argv, "11&", &v_proto, &v_return, &v_proc);
215
+
216
+ /* Validate prototype characters */
217
+ for(i = 0; i < RSTRING_LEN(v_proto); i++){
218
+ switch(RSTRING_PTR(v_proto)[i]){
219
+ case 'I': case 'L': case 'P': case 'V': case 'S':
220
+ break;
221
+ default:
222
+ rb_raise(cAPIProtoError, "Illegal prototype '%c'",
223
+ RSTRING_PTR(v_proto)[i]
224
+ );
225
+ }
226
+ }
227
+
228
+ if(NIL_P(v_return) || RARRAY_LEN(v_return) == 0){
229
+ v_return = rb_str_new2("L");
230
+ }
231
+ else{
232
+ switch(*(TCHAR*)RSTRING_PTR(v_return)){
233
+ case 'I': case 'L': case 'P': case 'V': case 'S':
234
+ break;
235
+ default:
236
+ rb_raise(cAPIProtoError, "Illegal return type '%s'",
237
+ RSTRING_PTR(v_return)
238
+ );
239
+ }
240
+ }
241
+
242
+ rb_iv_set(self, "@function", v_proc);
243
+ rb_iv_set(self, "@prototype", v_proto);
244
+ rb_iv_set(self, "@return_type", v_return);
245
+ rb_iv_set(self, "@address", SIZET2NUM((LPARAM)find_callback(self,RSTRING_LEN(v_proto))));
246
+ ActiveCallback = self;
247
+
248
+ return self;
249
+ }
250
+
251
+ /*
252
+ * call-seq:
253
+ * Win32::API.new(function, prototype='V', return='L', dll='kernel32')
254
+ *
255
+ * Creates and returns a new Win32::API object. The +function+ is the name
256
+ * of the Windows function.
257
+ *
258
+ * The +prototype+ is the function prototype for +function+. This can be a
259
+ * string or an array of characters. The possible valid characters are 'I'
260
+ * (integer), 'L' (long), 'V' (void), 'P' (pointer), 'K' (callback) or 'S'
261
+ * (string).
262
+ *
263
+ * The default is void ('V').
264
+ *
265
+ * Constant (const char*) strings should use 'S'. Pass by reference string
266
+ * buffers should use 'P'. The former is faster, but cannot be modified.
267
+ *
268
+ * The +return+ argument is the return type for the function. The valid
269
+ * characters are the same as for the +prototype+. The default is 'L' (long).
270
+ *
271
+ * The +dll+ is the name of the DLL file that the function is exported from.
272
+ * The default is 'kernel32'.
273
+ *
274
+ * If the function cannot be found then an API::Error is raised (a subclass
275
+ * of RuntimeError).
276
+ *
277
+ * Example:
278
+ *
279
+ * require 'win32/api'
280
+ * include Win32
281
+ *
282
+ * buf = 0.chr * 260
283
+ * len = [buf.length].pack('L')
284
+ *
285
+ * GetUserName = API.new('GetUserName', 'PP', 'I', 'advapi32')
286
+ * GetUserName.call(buf, len)
287
+ *
288
+ * puts buf.strip
289
+ */
290
+ static VALUE api_init(int argc, VALUE* argv, VALUE self)
291
+ {
292
+ HMODULE hLibrary;
293
+ FARPROC fProc;
294
+ Win32API* ptr;
295
+ int i;
296
+ const char* first = "A";
297
+ const char* second = "W";
298
+ VALUE v_proc, v_proto, v_return, v_dll;
299
+
300
+ rb_scan_args(argc, argv, "13", &v_proc, &v_proto, &v_return, &v_dll);
301
+
302
+ Data_Get_Struct(self, Win32API, ptr);
303
+
304
+ // Convert a string prototype to an array of characters
305
+ if(rb_respond_to(v_proto, rb_intern("split")))
306
+ v_proto = rb_str_split(v_proto, "");
307
+
308
+ // Convert a nil or empty prototype to 'V' (void) automatically
309
+ if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
310
+ v_proto = rb_ary_new();
311
+ rb_ary_push(v_proto, rb_str_new2("V"));
312
+ }
313
+
314
+ // Set an arbitrary limit of 20 parameters
315
+ if(RARRAY_LEN(v_proto) > 20)
316
+ rb_raise(rb_eArgError, "too many parameters: %ld", RARRAY_LEN(v_proto));
317
+
318
+ // Set the default dll to 'kernel32'
319
+ if(NIL_P(v_dll))
320
+ v_dll = rb_str_new2("kernel32");
321
+
322
+ // Set the default return type to 'L' (DWORD)
323
+ if(NIL_P(v_return))
324
+ v_return = rb_str_new2("L");
325
+
326
+ #if defined TAINTING_SUPPORT
327
+ SafeStringValue(v_dll);
328
+ SafeStringValue(v_proc);
329
+ #endif
330
+
331
+ hLibrary = LoadLibrary(TEXT(RSTRING_PTR(v_dll)));
332
+
333
+ // The most likely cause of failure is a bad DLL load path
334
+ if(!hLibrary){
335
+ rb_raise(cAPILoadError, "LoadLibrary() function failed for '%s': %s",
336
+ RSTRING_PTR(v_dll),
337
+ StringError(GetLastError())
338
+ );
339
+ }
340
+
341
+ ptr->library = hLibrary;
342
+
343
+ /* Attempt to get the function. If it fails, try again with an 'A'
344
+ * appended. If that fails, try again with a 'W' appended. If that
345
+ * still fails, raise an API::LoadLibraryError.
346
+ */
347
+
348
+ fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_proc)));
349
+
350
+ // Skip the ANSI and Wide function checks for MSVCRT functions.
351
+ if(!fProc){
352
+ if(strstr(RSTRING_PTR(v_dll), "msvcr")){
353
+ rb_raise(
354
+ cAPILoadError,
355
+ "Unable to load function '%s'",
356
+ RSTRING_PTR(v_proc)
357
+ );
358
+ }
359
+ else{
360
+ VALUE v_ascii = rb_str_new3(v_proc);
361
+ v_ascii = rb_str_cat(v_ascii, first, 1);
362
+ fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_ascii)));
363
+
364
+ if(!fProc){
365
+ VALUE v_unicode = rb_str_new3(v_proc);
366
+ v_unicode = rb_str_cat(v_unicode, second, 1);
367
+ fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_unicode)));
368
+
369
+ if(!fProc){
370
+ rb_raise(
371
+ cAPILoadError,
372
+ "Unable to load function '%s', '%s', or '%s'",
373
+ RSTRING_PTR(v_proc),
374
+ RSTRING_PTR(v_ascii),
375
+ RSTRING_PTR(v_unicode)
376
+ );
377
+ }
378
+ else{
379
+ rb_iv_set(self, "@effective_function_name", v_unicode);
380
+ }
381
+ }
382
+ else{
383
+ rb_iv_set(self, "@effective_function_name", v_ascii);
384
+ }
385
+ }
386
+ }
387
+ else{
388
+ rb_iv_set(self, "@effective_function_name", v_proc);
389
+ }
390
+
391
+ ptr->function = fProc;
392
+
393
+ // Push the numeric prototypes onto our int array for later use.
394
+
395
+ for(i = 0; i < RARRAY_LEN(v_proto); i++){
396
+ #if defined TAINTING_SUPPORT
397
+ SafeStringValue(RARRAY_PTR(v_proto)[i]);
398
+ #endif
399
+ switch(*(TCHAR*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
400
+ case 'L':
401
+ ptr->prototype[i] = _T_LONG;
402
+ break;
403
+ case 'P':
404
+ ptr->prototype[i] = _T_POINTER;
405
+ break;
406
+ case 'I': case 'B':
407
+ ptr->prototype[i] = _T_INTEGER;
408
+ break;
409
+ case 'V':
410
+ ptr->prototype[i] = _T_VOID;
411
+ break;
412
+ case 'K':
413
+ ptr->prototype[i] = _T_CALLBACK;
414
+ break;
415
+ case 'S':
416
+ ptr->prototype[i] = _T_STRING;
417
+ break;
418
+ default:
419
+ rb_raise(cAPIProtoError, "Illegal prototype '%s'",
420
+ StringValuePtr(RARRAY_PTR(v_proto)[i])
421
+ );
422
+ }
423
+ }
424
+
425
+ // Store the return type for later use.
426
+
427
+ // Automatically convert empty strings or nil to type void.
428
+ if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
429
+ v_return = rb_str_new2("V");
430
+ ptr->return_type = _T_VOID;
431
+ }
432
+ else{
433
+ #if defined TAINTING_SUPPORT
434
+ SafeStringValue(v_return);
435
+ #endif
436
+ switch(*RSTRING_PTR(v_return)){
437
+ case 'L':
438
+ ptr->return_type = _T_LONG;
439
+ break;
440
+ case 'P':
441
+ ptr->return_type = _T_POINTER;
442
+ break;
443
+ case 'I': case 'B':
444
+ ptr->return_type = _T_INTEGER;
445
+ break;
446
+ case 'V':
447
+ ptr->return_type = _T_VOID;
448
+ break;
449
+ case 'S':
450
+ ptr->return_type = _T_STRING;
451
+ break;
452
+ default:
453
+ rb_raise(cAPIProtoError, "Illegal return type '%s'",
454
+ RSTRING_PTR(v_return)
455
+ );
456
+ }
457
+ }
458
+
459
+ rb_iv_set(self, "@dll_name", v_dll);
460
+ rb_iv_set(self, "@function_name", v_proc);
461
+ rb_iv_set(self, "@prototype", v_proto);
462
+ rb_iv_set(self, "@return_type", v_return);
463
+
464
+ return self;
465
+ }
466
+
467
+ /*
468
+ * call-seq:
469
+ *
470
+ * API::Function.new(address, prototype = 'V', return_type = 'L')
471
+ *
472
+ * Creates and returns an API::Function object. This object is similar to an
473
+ * API object, except that instead of a character function name you pass a
474
+ * function pointer address as the first argument, and there's no associated
475
+ * DLL file.
476
+ *
477
+ * Once you have your API::Function object you can then call it the same way
478
+ * you would an API object.
479
+ *
480
+ * Example:
481
+ *
482
+ * require 'win32/api'
483
+ * include Win32
484
+ *
485
+ * LoadLibrary = API.new('LoadLibrary', 'P', 'L')
486
+ * GetProcAddress = API.new('GetProcAddress', 'LP', 'L')
487
+ *
488
+ * # Play a system beep
489
+ * hlib = LoadLibrary.call('user32')
490
+ * addr = GetProcAddress.call(hlib, 'MessageBeep')
491
+ * func = Win32::API::Function.new(addr, 'L', 'L')
492
+ * func.call(0)
493
+ */
494
+ static VALUE func_init(int argc, VALUE* argv, VALUE self){
495
+ Win32API* ptr;
496
+ int i;
497
+ VALUE v_address, v_proto, v_return;
498
+
499
+ rb_scan_args(argc, argv, "12", &v_address, &v_proto, &v_return);
500
+
501
+ Data_Get_Struct(self, Win32API, ptr);
502
+
503
+ // Convert a string prototype to an array of characters
504
+ if(rb_respond_to(v_proto, rb_intern("split")))
505
+ v_proto = rb_str_split(v_proto, "");
506
+
507
+ // Convert a nil or empty prototype to 'V' (void) automatically
508
+ if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
509
+ v_proto = rb_ary_new();
510
+ rb_ary_push(v_proto, rb_str_new2("V"));
511
+ }
512
+
513
+ // Set an arbitrary limit of 20 parameters
514
+ if(20 < RARRAY_LEN(v_proto))
515
+ rb_raise(rb_eArgError, "too many parameters: %li\n", RARRAY_LEN(v_proto));
516
+
517
+ // Set the default return type to 'L' (DWORD)
518
+ if(NIL_P(v_return))
519
+ v_return = rb_str_new2("L");
520
+
521
+ ptr->function = (FARPROC)NUM2SIZET(v_address);
522
+
523
+ // Push the numeric prototypes onto our int array for later use.
524
+
525
+ for(i = 0; i < RARRAY_LEN(v_proto); i++){
526
+ #if defined TAINTING_SUPPORT
527
+ SafeStringValue(RARRAY_PTR(v_proto)[i]);
528
+ #endif
529
+ switch(*(char*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
530
+ case 'L':
531
+ ptr->prototype[i] = _T_LONG;
532
+ break;
533
+ case 'P':
534
+ ptr->prototype[i] = _T_POINTER;
535
+ break;
536
+ case 'I': case 'B':
537
+ ptr->prototype[i] = _T_INTEGER;
538
+ break;
539
+ case 'V':
540
+ ptr->prototype[i] = _T_VOID;
541
+ break;
542
+ case 'K':
543
+ ptr->prototype[i] = _T_CALLBACK;
544
+ break;
545
+ case 'S':
546
+ ptr->prototype[i] = _T_STRING;
547
+ break;
548
+ default:
549
+ rb_raise(cAPIProtoError, "Illegal prototype '%s'",
550
+ StringValuePtr(RARRAY_PTR(v_proto)[i])
551
+ );
552
+ }
553
+ }
554
+
555
+ // Store the return type for later use.
556
+
557
+ // Automatically convert empty strings or nil to type void.
558
+ if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
559
+ v_return = rb_str_new2("V");
560
+ ptr->return_type = _T_VOID;
561
+ }
562
+ else{
563
+ #if defined TAINTING_SUPPORT
564
+ SafeStringValue(v_return);
565
+ #endif
566
+ switch(*RSTRING_PTR(v_return)){
567
+ case 'L':
568
+ ptr->return_type = _T_LONG;
569
+ break;
570
+ case 'P':
571
+ ptr->return_type = _T_POINTER;
572
+ break;
573
+ case 'I': case 'B':
574
+ ptr->return_type = _T_INTEGER;
575
+ break;
576
+ case 'V':
577
+ ptr->return_type = _T_VOID;
578
+ break;
579
+ case 'S':
580
+ ptr->return_type = _T_STRING;
581
+ break;
582
+ default:
583
+ rb_raise(cAPIProtoError, "Illegal return type '%s'",
584
+ RSTRING_PTR(v_return)
585
+ );
586
+ }
587
+ }
588
+
589
+ rb_iv_set(self, "@address", v_address);
590
+ rb_iv_set(self, "@prototype", v_proto);
591
+ rb_iv_set(self, "@return_type", v_return);
592
+
593
+ return self;
594
+ }
595
+
596
+ typedef struct {
597
+ uintptr_t params[20];
598
+ } CALLPARAM;
599
+
600
+
601
+ DWORD CallbackFunction(CALLPARAM param, VALUE callback)
602
+ {
603
+ VALUE v_proto, v_return, v_proc, v_retval;
604
+ VALUE argv[20];
605
+ int i, argc;
606
+ char *a_proto;
607
+ char *a_return;
608
+
609
+ if(callback && !NIL_P(callback)){
610
+ v_proto = rb_iv_get(callback, "@prototype");
611
+ a_proto = RSTRING_PTR(v_proto);
612
+
613
+ v_return = rb_iv_get(callback, "@return_type");
614
+ a_return = RSTRING_PTR(v_return);
615
+
616
+ v_proc = rb_iv_get(callback, "@function");
617
+ argc = RSTRING_LEN(v_proto);
618
+
619
+ for(i=0; i < RSTRING_LEN(v_proto); i++){
620
+ argv[i] = Qnil;
621
+ switch(a_proto[i]){
622
+ case 'L':
623
+ argv[i] = SIZET2NUM(param.params[i]);
624
+ break;
625
+ case 'P':
626
+ if(param.params[i])
627
+ argv[i] = rb_str_new2((char *)param.params[i]);
628
+ break;
629
+ case 'I':
630
+ argv[i] = INT2NUM(param.params[i]);
631
+ break;
632
+ default:
633
+ rb_raise(cAPIProtoError, "Illegal prototype '%c'", a_proto[i]);
634
+ }
635
+ }
636
+
637
+ v_retval = rb_funcall2(v_proc, rb_intern("call"), argc, argv);
638
+
639
+ /* Handle true and false explicitly, as some CALLBACK functions
640
+ * require TRUE or FALSE to break out of loops, etc.
641
+ */
642
+ if(v_retval == Qtrue)
643
+ return TRUE;
644
+ else if(v_retval == Qfalse)
645
+ return FALSE;
646
+
647
+ switch (*a_return) {
648
+ case 'I':
649
+ return NUM2INT(v_retval);
650
+ break;
651
+ case 'L':
652
+ return NUM2SIZET(v_retval);
653
+ break;
654
+ case 'S':
655
+ return (uintptr_t)RSTRING_PTR(v_retval);
656
+ break;
657
+ case 'P':
658
+ if(NIL_P(v_retval)){
659
+ return 0;
660
+ }
661
+ else if(FIXNUM_P(v_retval)){
662
+ return NUM2SIZET(v_retval);
663
+ }
664
+ else{
665
+ StringValue(v_retval);
666
+ rb_str_modify(v_retval);
667
+ return (uintptr_t)StringValuePtr(v_retval);
668
+ }
669
+ break;
670
+ }
671
+ }
672
+
673
+ return 0;
674
+ }
675
+
676
+ #define CALLBACK0(x) DWORD CALLBACK CallbackFunction0_##x() {\
677
+ CALLPARAM param = {{0}};\
678
+ param.params[0] = 0;\
679
+ return CallbackFunction(param,FuncTable[0][x]);\
680
+ }
681
+
682
+ #define CALLBACK1(x) DWORD CALLBACK CallbackFunction1_##x(DWORD p1) {\
683
+ CALLPARAM param = {{p1}};\
684
+ return CallbackFunction(param,FuncTable[1][x]);\
685
+ }
686
+
687
+ #define CALLBACK2(x) DWORD CALLBACK CallbackFunction2_##x(\
688
+ DWORD p1, DWORD p2){\
689
+ CALLPARAM param = {{p1,p2}};\
690
+ return CallbackFunction(param,FuncTable[2][x]);\
691
+ }
692
+
693
+ #define CALLBACK3(x) DWORD CALLBACK CallbackFunction3_##x(\
694
+ DWORD p1, DWORD p2, DWORD p3){\
695
+ CALLPARAM param = {{p1,p2,p3}};\
696
+ return CallbackFunction(param,FuncTable[3][x]);\
697
+ }
698
+
699
+ #define CALLBACK4(x) DWORD CALLBACK CallbackFunction4_##x(\
700
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4){\
701
+ CALLPARAM param = {{p1,p2,p3,p4}};\
702
+ return CallbackFunction(param,FuncTable[4][x]);\
703
+ }
704
+
705
+ #define CALLBACK5(x) DWORD CALLBACK CallbackFunction5_##x(\
706
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5\
707
+ ){\
708
+ CALLPARAM param = {{p1,p2,p3,p4,p5}};\
709
+ return CallbackFunction(param,FuncTable[5][x]);\
710
+ }
711
+
712
+ #define CALLBACK6(x) DWORD CALLBACK CallbackFunction6_##x(\
713
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5, DWORD p6\
714
+ ){\
715
+ CALLPARAM param = {{p1,p2,p3,p4,p5,p6}};\
716
+ return CallbackFunction(param,FuncTable[6][x]);\
717
+ }
718
+
719
+ #define CALLBACK7(x) DWORD CALLBACK CallbackFunction7_##x(\
720
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5, DWORD p6, DWORD p7\
721
+ ){\
722
+ CALLPARAM param = {{p1,p2,p3,p4,p5,p6,p7}};\
723
+ return CallbackFunction(param,FuncTable[7][x]);\
724
+ }
725
+
726
+ #define CALLBACK8(x) DWORD CALLBACK CallbackFunction8_##x(\
727
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4,\
728
+ DWORD p5, DWORD p6, DWORD p7, DWORD p8\
729
+ ){\
730
+ CALLPARAM param = {{p1,p2,p3,p4,p5,p6,p7,p8}};\
731
+ return CallbackFunction(param,FuncTable[8][x]);\
732
+ }
733
+
734
+ #define CALLBACK9(x) DWORD CALLBACK CallbackFunction9_##x(\
735
+ DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5,\
736
+ DWORD p6, DWORD p7, DWORD p8, DWORD p9\
737
+ ){\
738
+ CALLPARAM param = {{p1,p2,p3,p4,p5,p6,p7,p8,p9}};\
739
+ return CallbackFunction(param,FuncTable[9][x]);\
740
+ }
741
+
742
+ #define DEFCALLBACK(x) CALLBACK##x(0)\
743
+ CALLBACK##x(1)\
744
+ CALLBACK##x(2)\
745
+ CALLBACK##x(3)\
746
+ CALLBACK##x(4)\
747
+ CALLBACK##x(5)\
748
+ CALLBACK##x(6)\
749
+ CALLBACK##x(7)\
750
+ CALLBACK##x(8)\
751
+ CALLBACK##x(9)
752
+
753
+ #define CF(x,y) CallbackFunction##x##_##y
754
+
755
+ static VALUE FuncTable[10][10];
756
+
757
+ DEFCALLBACK(0)
758
+ DEFCALLBACK(1)
759
+ DEFCALLBACK(2)
760
+ DEFCALLBACK(3)
761
+ DEFCALLBACK(4)
762
+ DEFCALLBACK(5)
763
+ DEFCALLBACK(6)
764
+ DEFCALLBACK(7)
765
+ DEFCALLBACK(8)
766
+ DEFCALLBACK(9)
767
+
768
+ void *CallbackTable[10][10] = {
769
+ {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)},
770
+ {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)},
771
+ {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)},
772
+ {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)},
773
+ {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)},
774
+ {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)},
775
+ {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)},
776
+ {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)},
777
+ {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)},
778
+ {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)}};
779
+
780
+
781
+ void *find_callback(VALUE obj,int len)
782
+ {
783
+ int i;
784
+ for(i=0;i<10;i++)
785
+ {
786
+ if(FuncTable[len][i]==0)
787
+ break;
788
+ }
789
+ if(i>=10)
790
+ rb_raise(cAPIError,"too many callbacks are defined.");
791
+ FuncTable[len][i] = obj;
792
+ return CallbackTable[len][i];
793
+ }
794
+
795
+ /*
796
+ * call-seq:
797
+ * Win32::API#call(arg1, arg2, ...)
798
+ *
799
+ * Calls the function pointer with the given arguments (if any). Note that,
800
+ * while this method will catch some prototype mismatches (raising a TypeError
801
+ * in the process), it is not fulproof. It is ultimately your job to make
802
+ * sure the arguments match the +prototype+ specified in the constructor.
803
+ *
804
+ * For convenience, nil is converted to NULL, true is converted to TRUE (1)
805
+ * and false is converted to FALSE (0).
806
+ */
807
+ static VALUE api_call(int argc, VALUE* argv, VALUE self){
808
+ VALUE v_proto, v_args, v_arg, v_return;
809
+ Win32API* ptr;
810
+ uintptr_t return_value;
811
+ int i = 0;
812
+ int len;
813
+ ThreadData* thread_data = thread_data_get();
814
+
815
+ struct{
816
+ uintptr_t params[20];
817
+ } param;
818
+
819
+ Data_Get_Struct(self, Win32API, ptr);
820
+
821
+ rb_scan_args(argc, argv, "0*", &v_args);
822
+
823
+ v_proto = rb_iv_get(self, "@prototype");
824
+
825
+ // For void prototypes, allow either no args or an explicit nil
826
+ if(RARRAY_LEN(v_proto) != RARRAY_LEN(v_args)){
827
+ char* c = StringValuePtr(RARRAY_PTR(v_proto)[0]);
828
+ if(!strcmp(c, "V")){
829
+ rb_ary_push(v_args, Qnil);
830
+ }
831
+ else{
832
+ rb_raise(rb_eArgError,
833
+ "wrong number of parameters: expected %ld, got %ld",
834
+ RARRAY_LEN(v_proto), RARRAY_LEN(v_args)
835
+ );
836
+ }
837
+ }
838
+
839
+ len = RARRAY_LEN(v_proto);
840
+
841
+ for(i = 0; i < len; i++){
842
+ v_arg = RARRAY_PTR(v_args)[i];
843
+
844
+ // Convert nil to NULL. Otherwise convert as appropriate.
845
+ if(NIL_P(v_arg))
846
+ param.params[i] = (uintptr_t)NULL;
847
+ else if(v_arg == Qtrue)
848
+ param.params[i] = TRUE;
849
+ else if(v_arg == Qfalse)
850
+ param.params[i] = FALSE;
851
+ else
852
+ switch(ptr->prototype[i]){
853
+ case _T_LONG:
854
+ param.params[i] = NUM2SIZET(v_arg);
855
+ break;
856
+ case _T_INTEGER:
857
+ param.params[i] = NUM2INT(v_arg);
858
+ break;
859
+ case _T_POINTER:
860
+ if(FIXNUM_P(v_arg)){
861
+ param.params[i] = NUM2SIZET(v_arg);
862
+ }
863
+ else{
864
+ StringValue(v_arg);
865
+ rb_str_modify(v_arg);
866
+ param.params[i] = (uintptr_t)StringValuePtr(v_arg);
867
+ }
868
+ break;
869
+ case _T_CALLBACK:
870
+ ActiveCallback = v_arg;
871
+ param.params[i] = (LPARAM)NUM2SIZET(rb_iv_get(ActiveCallback, "@address"));;
872
+ break;
873
+ case _T_STRING:
874
+ param.params[i] = (uintptr_t)RSTRING_PTR(v_arg);
875
+ break;
876
+ default:
877
+ param.params[i] = NUM2SIZET(v_arg);
878
+ }
879
+ }
880
+
881
+ /* Call the function, get the return value */
882
+ if(strcmp(StringValuePtr(RARRAY_PTR(v_proto)[0]), "V") == 0 && len == 1)
883
+ {
884
+ return_value = ptr->function();
885
+ }
886
+ else
887
+ {
888
+ switch(len)
889
+ {
890
+ case 0:
891
+ return_value = ptr->function();
892
+ break;
893
+ case 1:
894
+ return_value = ptr->function(param.params[0]);
895
+ break;
896
+ case 2:
897
+ return_value = ptr->function(param.params[0], param.params[1]);
898
+ break;
899
+ case 3:
900
+ return_value = ptr->function(param.params[0], param.params[1],
901
+ param.params[2]);
902
+ break;
903
+ case 4:
904
+ return_value = ptr->function(param.params[0], param.params[1],
905
+ param.params[2], param.params[3]);
906
+ break;
907
+ case 5:
908
+ return_value = ptr->function(param.params[0], param.params[1],
909
+ param.params[2], param.params[3], param.params[4]);
910
+ break;
911
+ case 6:
912
+ return_value = ptr->function(param.params[0], param.params[1],
913
+ param.params[2], param.params[3], param.params[4], param.params[5]);
914
+ break;
915
+ case 7:
916
+ return_value = ptr->function(param.params[0], param.params[1],
917
+ param.params[2], param.params[3], param.params[4], param.params[5],
918
+ param.params[6]);
919
+ break;
920
+ case 8:
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]);
924
+ break;
925
+ case 9:
926
+ return_value = ptr->function(param.params[0], param.params[1],
927
+ param.params[2], param.params[3], param.params[4], param.params[5],
928
+ param.params[6], param.params[7], param.params[8]);
929
+ break;
930
+ case 10:
931
+ return_value = ptr->function(param.params[0], param.params[1],
932
+ param.params[2], param.params[3], param.params[4], param.params[5],
933
+ param.params[6], param.params[7], param.params[8], param.params[9]);
934
+ break;
935
+ case 11:
936
+ return_value = ptr->function(param.params[0], param.params[1],
937
+ param.params[2], param.params[3], param.params[4], param.params[5],
938
+ param.params[6], param.params[7], param.params[8], param.params[9],
939
+ param.params[10]);
940
+ break;
941
+ case 12:
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]);
946
+ break;
947
+ case 13:
948
+ return_value = ptr->function(param.params[0], param.params[1],
949
+ param.params[2], param.params[3], param.params[4], param.params[5],
950
+ param.params[6], param.params[7], param.params[8], param.params[9],
951
+ param.params[10], param.params[11], param.params[12]);
952
+ break;
953
+ case 14:
954
+ return_value = ptr->function(param.params[0], param.params[1],
955
+ param.params[2], param.params[3], param.params[4], param.params[5],
956
+ param.params[6], param.params[7], param.params[8], param.params[9],
957
+ param.params[10], param.params[11], param.params[12], param.params[13]);
958
+ break;
959
+ case 15:
960
+ return_value = ptr->function(param.params[0], param.params[1],
961
+ param.params[2], param.params[3], param.params[4], param.params[5],
962
+ param.params[6], param.params[7], param.params[8], param.params[9],
963
+ param.params[10], param.params[11], param.params[12], param.params[13],
964
+ param.params[14]);
965
+ break;
966
+ case 16:
967
+ return_value = ptr->function(param.params[0], param.params[1],
968
+ param.params[2], param.params[3], param.params[4], param.params[5],
969
+ param.params[6], param.params[7], param.params[8], param.params[9],
970
+ param.params[10], param.params[11], param.params[12], param.params[13],
971
+ param.params[14], param.params[15]);
972
+ break;
973
+ case 17:
974
+ return_value = ptr->function(param.params[0], param.params[1],
975
+ param.params[2], param.params[3], param.params[4], param.params[5],
976
+ param.params[6], param.params[7], param.params[8], param.params[9],
977
+ param.params[10], param.params[11], param.params[12], param.params[13],
978
+ param.params[14], param.params[15], param.params[16]);
979
+ break;
980
+ case 18:
981
+ return_value = ptr->function(param.params[0], param.params[1],
982
+ param.params[2], param.params[3], param.params[4], param.params[5],
983
+ param.params[6], param.params[7], param.params[8], param.params[9],
984
+ param.params[10], param.params[11], param.params[12], param.params[13],
985
+ param.params[14], param.params[15], param.params[16], param.params[17]);
986
+ break;
987
+ case 19:
988
+ return_value = ptr->function(param.params[0], param.params[1],
989
+ param.params[2], param.params[3], param.params[4], param.params[5],
990
+ param.params[6], param.params[7], param.params[8], param.params[9],
991
+ param.params[10], param.params[11], param.params[12], param.params[13],
992
+ param.params[14], param.params[15], param.params[16], param.params[17],
993
+ param.params[18]);
994
+ break;
995
+ case 20:
996
+ return_value = ptr->function(param.params[0], param.params[1],
997
+ param.params[2], param.params[3], param.params[4], param.params[5],
998
+ param.params[6], param.params[7], param.params[8], param.params[9],
999
+ param.params[10], param.params[11], param.params[12], param.params[13],
1000
+ param.params[14], param.params[15], param.params[16], param.params[17],
1001
+ param.params[18], param.params[19]);
1002
+ break;
1003
+ default:
1004
+ rb_raise(rb_eArgError,"number of parameters exceed 20!");
1005
+ }
1006
+ }
1007
+
1008
+ thread_data->win32api_error = GetLastError();
1009
+
1010
+ /* Return the appropriate type based on the return type specified
1011
+ * in the constructor.
1012
+ */
1013
+ switch(ptr->return_type){
1014
+ case _T_INTEGER:
1015
+ v_return = INT2NUM(return_value);
1016
+ break;
1017
+ case _T_LONG:
1018
+ v_return = SIZET2NUM(return_value);
1019
+ break;
1020
+ case _T_VOID:
1021
+ v_return = Qnil;
1022
+ break;
1023
+ case _T_POINTER:
1024
+ if(!return_value){
1025
+ v_return = Qnil;
1026
+ }
1027
+ else{
1028
+ VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
1029
+ char* efunc = RSTRING_PTR(v_efunc);
1030
+ if(efunc[strlen(efunc)-1] == 'W'){
1031
+ v_return = rb_str_new(
1032
+ (TCHAR*)return_value,
1033
+ wcslen((wchar_t*)return_value)*2
1034
+ );
1035
+ }
1036
+ else{
1037
+ v_return = rb_str_new2((TCHAR*)return_value);
1038
+ }
1039
+ }
1040
+ break;
1041
+ case _T_STRING:
1042
+ {
1043
+ VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
1044
+ char* efunc = RSTRING_PTR(v_efunc);
1045
+
1046
+ if(efunc[strlen(efunc)-1] == 'W'){
1047
+ v_return = rb_str_new(
1048
+ (TCHAR*)return_value,
1049
+ wcslen((wchar_t*)return_value)*2
1050
+ );
1051
+ }
1052
+ else{
1053
+ v_return = rb_str_new2((TCHAR*)return_value);
1054
+ }
1055
+ }
1056
+ break;
1057
+ default:
1058
+ v_return = INT2NUM(0);
1059
+ }
1060
+
1061
+ return v_return;
1062
+ }
1063
+
1064
+ /*
1065
+ * call-seq:
1066
+ * Win32::API.last_error
1067
+ *
1068
+ * Return the last Win32 error code of the current executing thread.
1069
+ *
1070
+ * The error code shouldn't be retrieved by calling GetLastError() manually
1071
+ * because Ruby's internal code may call other Win32 API and reset the error
1072
+ * code before it.
1073
+ */
1074
+ static VALUE get_last_error(VALUE self)
1075
+ {
1076
+ return INT2NUM(thread_data_get()->win32api_error);
1077
+ }
1078
+
1079
+ /*
1080
+ * Wraps the Windows API functions in a Ruby interface.
1081
+ */
1082
+ void Init_api(){
1083
+ VALUE mWin32, cAPI, cCallback, cFunction;
1084
+
1085
+ /* Modules and Classes */
1086
+
1087
+ /* The Win32 module serves as a namespace only */
1088
+ mWin32 = rb_define_module("Win32");
1089
+
1090
+ /* The API class encapsulates a function pointer to Windows API function */
1091
+ cAPI = rb_define_class_under(mWin32, "API", rb_cObject);
1092
+
1093
+ /* The API::Callback class encapsulates a Windows CALLBACK function */
1094
+ cCallback = rb_define_class_under(cAPI, "Callback", rb_cObject);
1095
+
1096
+ /* The API::Function class encapsulates a raw function pointer */
1097
+ cFunction = rb_define_class_under(cAPI, "Function", cAPI);
1098
+
1099
+ /* The API::Error class serves as a base class for other errors */
1100
+ cAPIError = rb_define_class_under(cAPI, "Error", rb_eRuntimeError);
1101
+
1102
+ /* The LoadError class is raised if a function cannot be found or loaded */
1103
+ cAPILoadError = rb_define_class_under(cAPI, "LoadLibraryError", cAPIError);
1104
+
1105
+ /* The PrototypeError class is raised if an invalid prototype is passed */
1106
+ cAPIProtoError = rb_define_class_under(cAPI, "PrototypeError", cAPIError);
1107
+
1108
+ /* Miscellaneous */
1109
+ rb_define_alloc_func(cAPI, api_allocate);
1110
+
1111
+ /* GetLastError alternative */
1112
+ rb_define_singleton_method(cAPI, "last_error", get_last_error, 0);
1113
+
1114
+ /* Win32::API Instance Methods */
1115
+ rb_define_method(cAPI, "initialize", api_init, -1);
1116
+ rb_define_method(cAPI, "call", api_call, -1);
1117
+
1118
+ /* Win32::API::Callback Instance Methods */
1119
+ rb_define_method(cCallback, "initialize", callback_init, -1);
1120
+
1121
+ /* Win32::API::Function Instance Methods */
1122
+ rb_define_method(cFunction, "initialize", func_init, -1);
1123
+
1124
+ /* The name of the DLL that exports the API function */
1125
+ rb_define_attr(cAPI, "dll_name", 1, 0);
1126
+
1127
+ /* The name of the function passed to the constructor */
1128
+ rb_define_attr(cAPI, "function_name", 1, 0);
1129
+
1130
+ /* The name of the actual function that is returned by the constructor.
1131
+ * For example, if you passed 'GetUserName' to the constructor, then the
1132
+ * effective function name would be either 'GetUserNameA' or 'GetUserNameW'.
1133
+ */
1134
+ rb_define_attr(cAPI, "effective_function_name", 1, 0);
1135
+
1136
+ /* The prototype, returned as an array of characters */
1137
+ rb_define_attr(cAPI, "prototype", 1, 0);
1138
+
1139
+ /* The return type, returned as a single character, S, P, L, I, V or B */
1140
+ rb_define_attr(cAPI, "return_type", 1, 0);
1141
+
1142
+ /* Win32::API::Callback Instance Methods */
1143
+
1144
+ /* The prototype, returned as an array of characters */
1145
+ rb_define_attr(cCallback, "prototype", 1, 0);
1146
+
1147
+ /* The return type, returned as a single character, S, P, L, I, V or B */
1148
+ rb_define_attr(cCallback, "return_type", 1, 0);
1149
+
1150
+ /* The numeric address of the function pointer */
1151
+ rb_define_attr(cCallback, "address", 1, 0);
1152
+ rb_define_attr(cFunction, "address", 1, 0);
1153
+
1154
+ /* Constants */
1155
+
1156
+ /* 1.6.0: The version of the win32-api library */
1157
+ rb_define_const(cAPI, "VERSION", rb_str_new2(WINDOWS_API_VERSION));
1158
+ }