win32-api 1.4.6 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }