windows-api 0.4.3 → 0.4.4
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.
- checksums.yaml +4 -4
- data/CHANGES +68 -64
- data/README +3 -3
- data/Rakefile +16 -0
- data/lib/windows/api.rb +503 -504
- data/lib/windows/wide_string.rb +59 -59
- data/test/test_windows_api.rb +171 -171
- data/windows-api.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a676d1572a63e8bce0c29b891ae0318037f06e59
|
4
|
+
data.tar.gz: cd3bf62aba802cec22554f1325946505eb8f3081
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 003418351fc46d6ffc391c3359562312dc71ec567300130236ce6b1b85caf10565c67b633f14a6735d1067117badc171220059f1f632d4e13eddcb8a4fcfb60d
|
7
|
+
data.tar.gz: 3caed1e8447b6e6841003ed428d916686c7168f5d3a4a50a050528ea59a4870e52e6127f4b40960774cf1156bd2f7d988a6b276952daac7c388b44d9d5ed7a2e
|
data/CHANGES
CHANGED
@@ -1,64 +1,68 @@
|
|
1
|
-
== 0.4.
|
2
|
-
*
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
*
|
22
|
-
*
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
*
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
*
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
*
|
45
|
-
|
46
|
-
|
47
|
-
== 0.2.
|
48
|
-
*
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
== 0.2.
|
57
|
-
*
|
58
|
-
|
59
|
-
|
60
|
-
== 0.
|
61
|
-
*
|
62
|
-
|
63
|
-
|
64
|
-
|
1
|
+
== 0.4.4 - 18-Mar-2015
|
2
|
+
* Removed a duplicate hash entry. Thanks go to Baptiste Courtois for the spot.
|
3
|
+
* Added some specialized test tasks.
|
4
|
+
|
5
|
+
== 0.4.3 - 20-Oct-2014
|
6
|
+
* Updates to the gemspec and Rakefile.
|
7
|
+
|
8
|
+
== 0.4.2 - 13-Jul-2012
|
9
|
+
* Fixed a bug in the way MSVCRT_DLL is set. Thanks go to Park Heesob for
|
10
|
+
the spot and patch.
|
11
|
+
* Some minor test refactoring and cosmetic udpates.
|
12
|
+
|
13
|
+
== 0.4.1 - 27-Jan-2012
|
14
|
+
* Switched Config to RbConfig to silence 1.9 warnings. Thanks go to
|
15
|
+
Cameron Cox for the patch.
|
16
|
+
* Some updates to the README, Rakefile, gemspec and test files.
|
17
|
+
|
18
|
+
== 0.4.0 - 18-Oct-2009
|
19
|
+
* Methods that begin with an underscore, such as _umask(), are now preserved.
|
20
|
+
A method alias is also created without an underscore, e.g. umask().
|
21
|
+
* Added the gem task to the Rakefile.
|
22
|
+
* Minor updates to the gemspec.
|
23
|
+
|
24
|
+
== 0.3.1 - 18-Aug-2009
|
25
|
+
* Changed license to Artistic 2.0.
|
26
|
+
* Some gemspec updates, including the addition of a license, an updated
|
27
|
+
description and a dependency update.
|
28
|
+
* One test update for VC++ 9.
|
29
|
+
|
30
|
+
== 0.3.0 - 1-Feb-2009
|
31
|
+
* No longer explicitly checks for an error in the constructor. It lets the
|
32
|
+
underlying Win32::API library deal with it.
|
33
|
+
* More dynamic handling and setting of the MSVCRT_DLL variable.
|
34
|
+
* Added a WideString implementation. Internal use only.
|
35
|
+
|
36
|
+
== 0.2.4 - 18-Jul-2008
|
37
|
+
* Eliminated unnecessary LoadLibrary() attempts for functions that explicitly
|
38
|
+
end with an 'A' or 'W', and all MSVCRT functions, since they have no 'A'
|
39
|
+
or 'W' equivalent.
|
40
|
+
* Replaced all of the attr_reader's with a delegation scheme using Forwardable.
|
41
|
+
All Win32::API functions now delegate to the internally stored Win32::API
|
42
|
+
object instead of reimplementing them. This change also fixed a bug where
|
43
|
+
the effective_function_name method did not work properly.
|
44
|
+
* Added more tests, and fixed one assertion that was wrong (the prototype).
|
45
|
+
* Some documentation additions.
|
46
|
+
|
47
|
+
== 0.2.3 - 26-Apr-2008
|
48
|
+
* Improved API.auto_constant and API.auto_method handling for functions that
|
49
|
+
start with a lower case character or an underscore.
|
50
|
+
|
51
|
+
== 0.2.2 - 17-Apr-2008
|
52
|
+
* Added the Windows::MSVCRT_DLL constant so that users can specify MSVCRT_DLL
|
53
|
+
for the DLL name and it will do the right thing, instead of having to worry
|
54
|
+
about specifying a DLL or associated DLL.
|
55
|
+
|
56
|
+
== 0.2.1 - 10-Feb-2008
|
57
|
+
* Added support for long data type names, e.g. 'DWORD' instead of 'L', for
|
58
|
+
both the prototype and return type.
|
59
|
+
|
60
|
+
== 0.2.0 - 20-Sep-2007
|
61
|
+
* Now requires the win32-api library.
|
62
|
+
* Replaced class variables with class instance variables to prevent conflicts.
|
63
|
+
|
64
|
+
== 0.1.1 - 25-May-2007
|
65
|
+
* Fixed a void parameter bug.
|
66
|
+
|
67
|
+
== 0.1.0 - 24-May-2007
|
68
|
+
* Initial release
|
data/README
CHANGED
@@ -79,15 +79,15 @@
|
|
79
79
|
if you installed this as a gem.
|
80
80
|
|
81
81
|
== Future Plans
|
82
|
-
|
83
|
-
|
82
|
+
I have no future plans for this library other than bug fixes. You should
|
83
|
+
use FFI instead of win32-api for all projects where possible.
|
84
84
|
|
85
85
|
== Bugs
|
86
86
|
None that I'm aware of. Please submit any bugs to the project page at
|
87
87
|
https://github.com/djberg96/windows-api.
|
88
88
|
|
89
89
|
== Copyright
|
90
|
-
(C) 2007-
|
90
|
+
(C) 2007-2015, Daniel J. Berger
|
91
91
|
|
92
92
|
== License
|
93
93
|
Artistic 2.0
|
data/Rakefile
CHANGED
@@ -28,4 +28,20 @@ Rake::TestTask.new do |test|
|
|
28
28
|
test.verbose = true
|
29
29
|
end
|
30
30
|
|
31
|
+
namespace :test do
|
32
|
+
desc "Test the core windows-api library"
|
33
|
+
Rake::TestTask.new(:api) do |t|
|
34
|
+
t.warning = true
|
35
|
+
t.verbose = true
|
36
|
+
t.test_files = FileList['test/test_windows_api.rb']
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Test the wide string methods"
|
40
|
+
Rake::TestTask.new(:wide) do |t|
|
41
|
+
t.warning = true
|
42
|
+
t.verbose = true
|
43
|
+
t.test_files = FileList['test/test_wide_string.rb']
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
31
47
|
task :default => :test
|
data/lib/windows/api.rb
CHANGED
@@ -1,504 +1,503 @@
|
|
1
|
-
require 'win32/api'
|
2
|
-
require 'rbconfig'
|
3
|
-
require 'forwardable'
|
4
|
-
include RbConfig
|
5
|
-
|
6
|
-
# The Windows module serves as a namespace only
|
7
|
-
module Windows
|
8
|
-
|
9
|
-
# With Microsoft Visual C++ 8 and later users should use the associated
|
10
|
-
# DLL instead of msvcrt directly, if possible.
|
11
|
-
if CONFIG['host_os'].split('_')[1]
|
12
|
-
if CONFIG['host_os'].split('_')[1].to_i >= 80
|
13
|
-
MSVCRT_DLL = 'msvcr' + CONFIG['host_os'].split('_')[1]
|
14
|
-
else
|
15
|
-
MSVCRT_DLL = 'msvcrt'
|
16
|
-
end
|
17
|
-
else
|
18
|
-
MSVCRT_DLL = 'msvcrt'
|
19
|
-
end
|
20
|
-
|
21
|
-
# Wrapper around the Win32::API class
|
22
|
-
class API
|
23
|
-
extend Forwardable
|
24
|
-
|
25
|
-
# The version of the windows-api library
|
26
|
-
VERSION = '0.4.
|
27
|
-
|
28
|
-
# The methods from Win32::API are delegated to the appropriate object
|
29
|
-
def_delegators(:@api, :function_name, :dll_name, :prototype)
|
30
|
-
def_delegators(:@api, :return_type, :effective_function_name)
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
# Verbose data types that can be used instead of single letters
|
35
|
-
DATA_TYPES = {
|
36
|
-
'ATOM' => 'I',
|
37
|
-
'BOOL' => 'B',
|
38
|
-
'BOOLEAN' => 'B',
|
39
|
-
'BYTE' => 'I',
|
40
|
-
'CALLBACK' => 'K',
|
41
|
-
'CHAR' => 'I',
|
42
|
-
'COLORREF' => 'L',
|
43
|
-
'DWORD' => 'L',
|
44
|
-
'DWORDLONG' => 'L',
|
45
|
-
'DWORD_PTR' => 'P',
|
46
|
-
'DWORD32' => 'I',
|
47
|
-
'DWORD64' => 'L',
|
48
|
-
'HACCEL' => 'L',
|
49
|
-
'HANDLE' => 'L',
|
50
|
-
'HBITMAP' => 'L',
|
51
|
-
'HBRUSH' => 'L',
|
52
|
-
'HCOLORSPACE' => 'L',
|
53
|
-
'HCONV' => 'L',
|
54
|
-
'HDC' => 'L',
|
55
|
-
'HFILE' => 'I',
|
56
|
-
'
|
57
|
-
'
|
58
|
-
'
|
59
|
-
'
|
60
|
-
'
|
61
|
-
'
|
62
|
-
'
|
63
|
-
'
|
64
|
-
'
|
65
|
-
'
|
66
|
-
'
|
67
|
-
'
|
68
|
-
'
|
69
|
-
'
|
70
|
-
'
|
71
|
-
'
|
72
|
-
'
|
73
|
-
'
|
74
|
-
'
|
75
|
-
'
|
76
|
-
'
|
77
|
-
'
|
78
|
-
'
|
79
|
-
'
|
80
|
-
'
|
81
|
-
'
|
82
|
-
'
|
83
|
-
'
|
84
|
-
'
|
85
|
-
'
|
86
|
-
'
|
87
|
-
'
|
88
|
-
'
|
89
|
-
'
|
90
|
-
'
|
91
|
-
'
|
92
|
-
'
|
93
|
-
'
|
94
|
-
'
|
95
|
-
'
|
96
|
-
'
|
97
|
-
'
|
98
|
-
'
|
99
|
-
'
|
100
|
-
'
|
101
|
-
'
|
102
|
-
'
|
103
|
-
'
|
104
|
-
'
|
105
|
-
'
|
106
|
-
'
|
107
|
-
'
|
108
|
-
'
|
109
|
-
'
|
110
|
-
'
|
111
|
-
'
|
112
|
-
'
|
113
|
-
'
|
114
|
-
'
|
115
|
-
'
|
116
|
-
'
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
@
|
123
|
-
@
|
124
|
-
@
|
125
|
-
|
126
|
-
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
#
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
145
|
-
#
|
146
|
-
#
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
# API.
|
155
|
-
# API.
|
156
|
-
#
|
157
|
-
#
|
158
|
-
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
|
163
|
-
|
164
|
-
#
|
165
|
-
#
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
#
|
172
|
-
#
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
#
|
179
|
-
#
|
180
|
-
# and/or
|
181
|
-
#
|
182
|
-
#
|
183
|
-
#
|
184
|
-
#
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
#
|
191
|
-
#
|
192
|
-
#
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
#
|
199
|
-
#
|
200
|
-
#
|
201
|
-
#
|
202
|
-
#
|
203
|
-
#
|
204
|
-
#
|
205
|
-
#
|
206
|
-
#
|
207
|
-
#
|
208
|
-
#
|
209
|
-
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
# API.
|
218
|
-
# API.
|
219
|
-
# API.
|
220
|
-
#
|
221
|
-
#
|
222
|
-
#
|
223
|
-
#
|
224
|
-
#
|
225
|
-
#
|
226
|
-
#
|
227
|
-
#
|
228
|
-
#
|
229
|
-
# '
|
230
|
-
#
|
231
|
-
#
|
232
|
-
#
|
233
|
-
#
|
234
|
-
#
|
235
|
-
#
|
236
|
-
#
|
237
|
-
#
|
238
|
-
#
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
#
|
245
|
-
#
|
246
|
-
#
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
#
|
253
|
-
#
|
254
|
-
#
|
255
|
-
#
|
256
|
-
#
|
257
|
-
#
|
258
|
-
#
|
259
|
-
#
|
260
|
-
#
|
261
|
-
#
|
262
|
-
#
|
263
|
-
# API.
|
264
|
-
# API.
|
265
|
-
# API.new('shlwapi', '
|
266
|
-
# API.new('shlwapi', '
|
267
|
-
#
|
268
|
-
#
|
269
|
-
#
|
270
|
-
#
|
271
|
-
#
|
272
|
-
#
|
273
|
-
#
|
274
|
-
#
|
275
|
-
# API.
|
276
|
-
# API.
|
277
|
-
# API.
|
278
|
-
#
|
279
|
-
#
|
280
|
-
#
|
281
|
-
#
|
282
|
-
#
|
283
|
-
#
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
#
|
290
|
-
#
|
291
|
-
#
|
292
|
-
#
|
293
|
-
#
|
294
|
-
#
|
295
|
-
#
|
296
|
-
#
|
297
|
-
#
|
298
|
-
#
|
299
|
-
#
|
300
|
-
#
|
301
|
-
#
|
302
|
-
#
|
303
|
-
#
|
304
|
-
#
|
305
|
-
#
|
306
|
-
#
|
307
|
-
#
|
308
|
-
# The
|
309
|
-
#
|
310
|
-
#
|
311
|
-
#
|
312
|
-
#
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
@
|
329
|
-
@
|
330
|
-
@
|
331
|
-
@
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
#
|
340
|
-
#
|
341
|
-
#
|
342
|
-
#
|
343
|
-
#
|
344
|
-
#
|
345
|
-
#
|
346
|
-
#
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
#
|
367
|
-
#
|
368
|
-
#
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
func_upper
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
func_upper
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
#
|
390
|
-
#
|
391
|
-
|
392
|
-
|
393
|
-
namespace.const_set("#{func}
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
#
|
399
|
-
#
|
400
|
-
#
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
#
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
#
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
#
|
495
|
-
#
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
result =
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
end
|
1
|
+
require 'win32/api'
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'forwardable'
|
4
|
+
include RbConfig
|
5
|
+
|
6
|
+
# The Windows module serves as a namespace only
|
7
|
+
module Windows
|
8
|
+
|
9
|
+
# With Microsoft Visual C++ 8 and later users should use the associated
|
10
|
+
# DLL instead of msvcrt directly, if possible.
|
11
|
+
if CONFIG['host_os'].split('_')[1]
|
12
|
+
if CONFIG['host_os'].split('_')[1].to_i >= 80
|
13
|
+
MSVCRT_DLL = 'msvcr' + CONFIG['host_os'].split('_')[1]
|
14
|
+
else
|
15
|
+
MSVCRT_DLL = 'msvcrt'
|
16
|
+
end
|
17
|
+
else
|
18
|
+
MSVCRT_DLL = 'msvcrt'
|
19
|
+
end
|
20
|
+
|
21
|
+
# Wrapper around the Win32::API class
|
22
|
+
class API
|
23
|
+
extend Forwardable
|
24
|
+
|
25
|
+
# The version of the windows-api library
|
26
|
+
VERSION = '0.4.4'
|
27
|
+
|
28
|
+
# The methods from Win32::API are delegated to the appropriate object
|
29
|
+
def_delegators(:@api, :function_name, :dll_name, :prototype)
|
30
|
+
def_delegators(:@api, :return_type, :effective_function_name)
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Verbose data types that can be used instead of single letters
|
35
|
+
DATA_TYPES = {
|
36
|
+
'ATOM' => 'I',
|
37
|
+
'BOOL' => 'B',
|
38
|
+
'BOOLEAN' => 'B',
|
39
|
+
'BYTE' => 'I',
|
40
|
+
'CALLBACK' => 'K',
|
41
|
+
'CHAR' => 'I',
|
42
|
+
'COLORREF' => 'L',
|
43
|
+
'DWORD' => 'L',
|
44
|
+
'DWORDLONG' => 'L',
|
45
|
+
'DWORD_PTR' => 'P',
|
46
|
+
'DWORD32' => 'I',
|
47
|
+
'DWORD64' => 'L',
|
48
|
+
'HACCEL' => 'L',
|
49
|
+
'HANDLE' => 'L',
|
50
|
+
'HBITMAP' => 'L',
|
51
|
+
'HBRUSH' => 'L',
|
52
|
+
'HCOLORSPACE' => 'L',
|
53
|
+
'HCONV' => 'L',
|
54
|
+
'HDC' => 'L',
|
55
|
+
'HFILE' => 'I',
|
56
|
+
'HFONT' => 'L',
|
57
|
+
'HINSTANCE' => 'L',
|
58
|
+
'HKEY' => 'L',
|
59
|
+
'HLOCAL' => 'L',
|
60
|
+
'HMENU' => 'L',
|
61
|
+
'HMODULE' => 'L',
|
62
|
+
'HRESULT' => 'L',
|
63
|
+
'HWND' => 'L',
|
64
|
+
'INT' => 'I',
|
65
|
+
'INT_PTR' => 'P',
|
66
|
+
'INT32' => 'I',
|
67
|
+
'INT64' => 'L',
|
68
|
+
'LANGID' => 'I',
|
69
|
+
'LCID' => 'L',
|
70
|
+
'LCTYPE' => 'L',
|
71
|
+
'LONG' => 'L',
|
72
|
+
'LONGLONG' => 'L',
|
73
|
+
'LONG_PTR' => 'P',
|
74
|
+
'LONG32' => 'L',
|
75
|
+
'LONG64' => 'L',
|
76
|
+
'LPARAM' => 'P',
|
77
|
+
'LPBOOL' => 'P',
|
78
|
+
'LPBYTE' => 'P',
|
79
|
+
'LPCOLORREF' => 'P',
|
80
|
+
'LPCSTR' => 'P',
|
81
|
+
'LPCTSTR' => 'P',
|
82
|
+
'LPCVOID' => 'L',
|
83
|
+
'LPCWSTR' => 'P',
|
84
|
+
'LPDWORD' => 'P',
|
85
|
+
'LPHANDLE' => 'P',
|
86
|
+
'LPINT' => 'P',
|
87
|
+
'LPLONG' => 'P',
|
88
|
+
'LPSTR' => 'P',
|
89
|
+
'LPTSTR' => 'P',
|
90
|
+
'LPVOID' => 'L',
|
91
|
+
'LPWORD' => 'P',
|
92
|
+
'LPWSTR' => 'P',
|
93
|
+
'LRESULT' => 'P',
|
94
|
+
'PBOOL' => 'P',
|
95
|
+
'PBOOLEAN' => 'P',
|
96
|
+
'PBYTE' => 'P',
|
97
|
+
'PHKEY' => 'P',
|
98
|
+
'SC_HANDLE' => 'L',
|
99
|
+
'SC_LOCK' => 'L',
|
100
|
+
'SERVICE_STATUS_HANDLE' => 'L',
|
101
|
+
'SHORT' => 'I',
|
102
|
+
'SIZE_T' => 'P',
|
103
|
+
'TCHAR' => 'L',
|
104
|
+
'UINT' => 'I',
|
105
|
+
'UINT_PTR' => 'P',
|
106
|
+
'UINT32' => 'I',
|
107
|
+
'UINT64' => 'L',
|
108
|
+
'ULONG' => 'L',
|
109
|
+
'ULONGLONG' => 'L',
|
110
|
+
'ULONG_PTR' => 'P',
|
111
|
+
'ULONG32' => 'L',
|
112
|
+
'ULONG64' => 'L',
|
113
|
+
'USHORT' => 'I',
|
114
|
+
'USN' => 'L',
|
115
|
+
'WINAPI' => 'L',
|
116
|
+
'WORD' => 'I'
|
117
|
+
}
|
118
|
+
|
119
|
+
public
|
120
|
+
|
121
|
+
@auto_constant = false
|
122
|
+
@auto_method = false
|
123
|
+
@auto_unicode = false
|
124
|
+
@auto_namespace = nil
|
125
|
+
|
126
|
+
# Returns the value of the @auto_constant class instance variable. The
|
127
|
+
# default is nil, i.e. none. See the Windows::API.auto_constant=
|
128
|
+
# documentation for more information.
|
129
|
+
#
|
130
|
+
def self.auto_constant
|
131
|
+
@auto_constant
|
132
|
+
end
|
133
|
+
|
134
|
+
# Automatically sets a constant to match the function name.
|
135
|
+
#
|
136
|
+
# The standard practice for defining Windows::API objects is to use
|
137
|
+
# a constant that matches the function name. For example, this is a
|
138
|
+
# typical idiom:
|
139
|
+
#
|
140
|
+
# module Windows
|
141
|
+
# module File
|
142
|
+
# GetFileAttributes = API.new('GetFileAttributes', 'P','L')
|
143
|
+
# end
|
144
|
+
# end
|
145
|
+
#
|
146
|
+
# With the API.auto_constant value set to true you can avoid the
|
147
|
+
# assignment step and the matching constant name will be automatically
|
148
|
+
# set for you in the namespace defined in API.auto_namespace. In other
|
149
|
+
# words, this example is identical to the one above:
|
150
|
+
#
|
151
|
+
# module Windows
|
152
|
+
# module File
|
153
|
+
# API.auto_constant = true
|
154
|
+
# API.auto_namespace = 'Windows::File'
|
155
|
+
# API.new('GetFileAttributes', 'P', 'L')
|
156
|
+
# end
|
157
|
+
# end
|
158
|
+
#
|
159
|
+
# If the auto_constant class variable is set to true, but no
|
160
|
+
# auto_namespace is set, an error will be raised. Note that the
|
161
|
+
# namespace must refer to an existing module (not a class).
|
162
|
+
#--
|
163
|
+
# TODO: If there's a way to automatically grab the namespace internally,
|
164
|
+
# nesting and all, I'd love to know the solution.
|
165
|
+
#
|
166
|
+
def self.auto_constant=(bool)
|
167
|
+
@auto_constant = bool
|
168
|
+
end
|
169
|
+
|
170
|
+
# Returns the value of the auto_namespace class instance variable. Used
|
171
|
+
# in conjunction with API.auto_constant and/or API.auto_method.
|
172
|
+
#
|
173
|
+
def self.auto_namespace
|
174
|
+
@auto_namespace
|
175
|
+
end
|
176
|
+
|
177
|
+
# Sets the value of the auto_namespace class nstance variable. The
|
178
|
+
# default is nil, i.e. none. Use in conjunction with the auto_constant
|
179
|
+
# and/or auto_method class variables, this method will automatically set
|
180
|
+
# a constant and/or method in +namespace+ equal to the function name set
|
181
|
+
# in the constructor.
|
182
|
+
#
|
183
|
+
# The +namespace+ must refer to an existing module, not a class.
|
184
|
+
#
|
185
|
+
def self.auto_namespace=(namespace)
|
186
|
+
@auto_namespace = namespace
|
187
|
+
end
|
188
|
+
|
189
|
+
# Returns the value of the auto_method class instance variable. Used in
|
190
|
+
# conjunction with auto_unicode. See API.auto_method= for more
|
191
|
+
# information.
|
192
|
+
#
|
193
|
+
def self.auto_method
|
194
|
+
@auto_method
|
195
|
+
end
|
196
|
+
|
197
|
+
# If this option is set to true then a corresponding method is
|
198
|
+
# automatically generated when you create a new Windows::API object.
|
199
|
+
#
|
200
|
+
# For example, instead of doing this:
|
201
|
+
#
|
202
|
+
# module Windows
|
203
|
+
# module File
|
204
|
+
# GetFileAttributes = API.new('GetFileAttributes', 'P', 'L')
|
205
|
+
#
|
206
|
+
# def GetFileAttributes(x)
|
207
|
+
# GetFileAttributes.call(x)
|
208
|
+
# end
|
209
|
+
# end
|
210
|
+
# end
|
211
|
+
#
|
212
|
+
# You can do this, and have the method autogenerated for you.
|
213
|
+
#
|
214
|
+
# module Windows
|
215
|
+
# module File
|
216
|
+
# API.auto_namespace = 'Windows::File'
|
217
|
+
# API.auto_constant = true
|
218
|
+
# API.auto_method = true
|
219
|
+
# API.new('GetFileAttributes', 'P', 'L')
|
220
|
+
# end
|
221
|
+
# end
|
222
|
+
#
|
223
|
+
# include Windows::File
|
224
|
+
# GetFileAttributes('C:/test.txt') # vs. GetFileAttributes.call
|
225
|
+
#
|
226
|
+
# If the Windows::API object is declared to be a boolean in the
|
227
|
+
# constructor, then the method definition automatically includes a
|
228
|
+
# '!= 0' clause at the end of the call. That way, you can do
|
229
|
+
# 'if SomeMethod(x)' instead of having to do 'if SomeMethod(x) != 0',
|
230
|
+
# and it will do the right thing.
|
231
|
+
#
|
232
|
+
# If the API.auto_unicode option is also set to true, then you will
|
233
|
+
# get three method definitions. The standard function name, the explicit
|
234
|
+
# ANSI ('A') version and the explicit Unicode/wide version ('W'). The
|
235
|
+
# exception to this rule is that the explicit ANSI and Unicode methods
|
236
|
+
# will NOT be generated if the function passed to the constructor
|
237
|
+
# already ends with 'A' or 'W'.
|
238
|
+
#
|
239
|
+
def self.auto_method=(bool)
|
240
|
+
@auto_method = bool
|
241
|
+
end
|
242
|
+
|
243
|
+
# Returns the value of the auto_unicode class instance variable. This
|
244
|
+
# is used in conjunction with the auto_method and/or auto_constant class
|
245
|
+
# variables. Not significant if neither of those variables are set.
|
246
|
+
#
|
247
|
+
def self.auto_unicode
|
248
|
+
@auto_unicode
|
249
|
+
end
|
250
|
+
|
251
|
+
# If set to true, and the auto_constant variable is set, then the
|
252
|
+
# automatic constant generation will generate the explicit ANSI ('A')
|
253
|
+
# and Unicode/wide ('W') versions of the function passed to the
|
254
|
+
# constructor, if such versions exist. Likewise, if the the
|
255
|
+
# auto_method variable is set, then explicit ANSI and Unicode methods
|
256
|
+
# are generated.
|
257
|
+
#
|
258
|
+
# Here's a typical idiom:
|
259
|
+
#
|
260
|
+
# module Windows
|
261
|
+
# module Path
|
262
|
+
# API.auto_namespace = Windows::Path
|
263
|
+
# API.auto_constant = true
|
264
|
+
# API.new('shlwapi', 'PathAddBackslash', 'P', 'P')
|
265
|
+
# API.new('shlwapi', 'PathAddBackslashA', 'P', 'P')
|
266
|
+
# API.new('shlwapi', 'PathAddBackslashW', 'P', 'P')
|
267
|
+
# end
|
268
|
+
# end
|
269
|
+
#
|
270
|
+
# That can be reduced to this:
|
271
|
+
#
|
272
|
+
# module Windows
|
273
|
+
# module Path
|
274
|
+
# API.auto_namespace = Windows::Path
|
275
|
+
# API.auto_constant = true
|
276
|
+
# API.auto_unicode = true
|
277
|
+
# API.new('shlwapi', 'PathAddBackslash', 'P', 'P')
|
278
|
+
# end
|
279
|
+
# end
|
280
|
+
#
|
281
|
+
# This value is ignored if the function passed to the constructor
|
282
|
+
# already ends with an 'A' or 'W'.
|
283
|
+
#
|
284
|
+
def self.auto_unicode=(bool)
|
285
|
+
@auto_unicode = bool
|
286
|
+
end
|
287
|
+
|
288
|
+
# call-seq:
|
289
|
+
# API.new(func, proto='V', rtype='L', dll='kernel32')
|
290
|
+
#
|
291
|
+
# Creates and returns a new Windows::API object. The +func+ is the
|
292
|
+
# name of the Windows function.
|
293
|
+
#
|
294
|
+
# The +proto+ is the function prototype for +func+. This can be a
|
295
|
+
# string or an array of characters. The possible valid characters
|
296
|
+
# are 'I' (integer), 'B' (BOOL), 'L' (long), 'V' (void), or 'P' (pointer).
|
297
|
+
# The default is void ('V').
|
298
|
+
#
|
299
|
+
# The +rtype+ argument is the return type for the function. The valid
|
300
|
+
# characters are the same as for the +proto+. The default is long ('L').
|
301
|
+
#
|
302
|
+
# The 'B' (BOOL) return type is the same as 'I' (Integer). This is
|
303
|
+
# significant only if the API.auto_method option is set to true, in which
|
304
|
+
# case it alters the generated method definition slightly. See the
|
305
|
+
# API.auto_method= class method for more information.
|
306
|
+
#
|
307
|
+
# The +dll+ is the name of the DLL file that the function is exported
|
308
|
+
# from. The default is 'kernel32'.
|
309
|
+
#
|
310
|
+
# If the function cannot be found then an API::Error is raised (a subclass
|
311
|
+
# of RuntimeError).
|
312
|
+
#
|
313
|
+
def initialize(func, proto='V', rtype='L', dll='kernel32')
|
314
|
+
# Convert literal data types to values that win32-api understands
|
315
|
+
if proto.is_a?(Array)
|
316
|
+
proto.each_with_index{ |pt, index|
|
317
|
+
if pt.length > 1
|
318
|
+
proto[index].replace(DATA_TYPES[pt])
|
319
|
+
end
|
320
|
+
}
|
321
|
+
end
|
322
|
+
|
323
|
+
if rtype.length > 1
|
324
|
+
rtype.replace(DATA_TYPES[rtype])
|
325
|
+
end
|
326
|
+
|
327
|
+
@function_name = func
|
328
|
+
@prototype = proto
|
329
|
+
@return_type = rtype == 'B' ? 'I' : rtype
|
330
|
+
@dll_name = dll
|
331
|
+
@boolean = rtype == 'B' ? true : false
|
332
|
+
|
333
|
+
@api = Win32::API.new(func, proto, rtype, dll)
|
334
|
+
|
335
|
+
api_a = nil
|
336
|
+
api_w = nil
|
337
|
+
|
338
|
+
# If the auto_unicode option is set, and the func is not already
|
339
|
+
# an explicit ANSI or Wide function name, generate Win32::API
|
340
|
+
# objects for those functions as well. Ignore errors because not
|
341
|
+
# all functions have explicit ANSI or Wide character implementations.
|
342
|
+
#
|
343
|
+
# This entire bit of logic is skipped if the DLL is msvcrt, since
|
344
|
+
# msvcrt functions never have explicit ANSI or Wide character
|
345
|
+
# versions.
|
346
|
+
#
|
347
|
+
if Windows::API.auto_unicode && dll !~ /msvcr/i
|
348
|
+
begin
|
349
|
+
unless ['A', 'W'].include?(func[-1].chr)
|
350
|
+
api_a = Win32::API.new("#{func}A", proto, rtype, dll)
|
351
|
+
end
|
352
|
+
rescue RuntimeError
|
353
|
+
end
|
354
|
+
|
355
|
+
begin
|
356
|
+
unless ['W', 'A'].include?(func[-1].chr)
|
357
|
+
api_w = Win32::API.new("#{func}W", proto, rtype, dll)
|
358
|
+
end
|
359
|
+
rescue RuntimeError
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
func_upper = nil
|
364
|
+
|
365
|
+
# Automatically define a constant matching the function name if the
|
366
|
+
# auto_constant option is set. Lower case method names will have a
|
367
|
+
# capitalized equivalent created, e.g. Memcpy for memcpy, etc.
|
368
|
+
#
|
369
|
+
if Windows::API.auto_constant && Windows::API.auto_namespace
|
370
|
+
if Windows::API.auto_namespace != 'Windows'
|
371
|
+
namespace = class_for(Windows::API.auto_namespace)
|
372
|
+
else
|
373
|
+
namespace = Windows::API.auto_namespace
|
374
|
+
end
|
375
|
+
|
376
|
+
# Convert e.g. 'strstr' to 'Strstr' as an equivalent constant
|
377
|
+
if ('A'..'Z').include?(func[0].chr)
|
378
|
+
namespace.const_set(func, @api)
|
379
|
+
else
|
380
|
+
func_upper = func.dup
|
381
|
+
if func_upper[0].chr == '_'
|
382
|
+
func_upper = func_upper[1, func_upper.length]
|
383
|
+
end
|
384
|
+
func_upper[0, 1] = func_upper[0].chr.capitalize
|
385
|
+
namespace.const_set(func_upper, @api)
|
386
|
+
end
|
387
|
+
|
388
|
+
# Automatically define the explicit ANSI and Unicode functions
|
389
|
+
# as constants as well, if appropriate.
|
390
|
+
#
|
391
|
+
if Windows::API.auto_unicode
|
392
|
+
namespace.const_set("#{func}A", api_a) if api_a
|
393
|
+
namespace.const_set("#{func}W", api_w) if api_w
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
# Automatically define a method in the auto_namespace if the
|
398
|
+
# auto_method option is set. The explicit ANSI and Unicode methods
|
399
|
+
# are added as well if the auto_unicode option is set to true.
|
400
|
+
#
|
401
|
+
if Windows::API.auto_method && Windows::API.auto_namespace
|
402
|
+
if proto == 'V'
|
403
|
+
proto = ''
|
404
|
+
else
|
405
|
+
n = 0
|
406
|
+
if proto.is_a?(String)
|
407
|
+
proto = proto.split('').map{ |e|
|
408
|
+
n += 1
|
409
|
+
e.downcase + n.to_s
|
410
|
+
}.join(', ')
|
411
|
+
else
|
412
|
+
proto = proto.map{ |e|
|
413
|
+
n += 1
|
414
|
+
e.downcase + n.to_s
|
415
|
+
}.join(', ')
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
# Use the upper case function equivalent if defined
|
420
|
+
call_func = func_upper || func
|
421
|
+
|
422
|
+
if @boolean
|
423
|
+
string = <<-EOC
|
424
|
+
module #{Windows::API.auto_namespace}
|
425
|
+
def #{func}(#{proto})
|
426
|
+
#{call_func}.call(#{proto}) != 0
|
427
|
+
end
|
428
|
+
EOC
|
429
|
+
|
430
|
+
if api_a
|
431
|
+
string << %Q{
|
432
|
+
def #{func}A(#{proto})
|
433
|
+
#{call_func}A.call(#{proto}) != 0
|
434
|
+
end
|
435
|
+
}
|
436
|
+
end
|
437
|
+
|
438
|
+
if api_w
|
439
|
+
string << %Q{
|
440
|
+
def #{func}W(#{proto})
|
441
|
+
#{call_func}W.call(#{proto}) != 0
|
442
|
+
end
|
443
|
+
}
|
444
|
+
end
|
445
|
+
|
446
|
+
string << 'end'
|
447
|
+
else
|
448
|
+
string = <<-EOC
|
449
|
+
module #{Windows::API.auto_namespace}
|
450
|
+
def #{func}(#{proto})
|
451
|
+
#{call_func}.call(#{proto})
|
452
|
+
end
|
453
|
+
EOC
|
454
|
+
|
455
|
+
if api_a
|
456
|
+
string << %Q{
|
457
|
+
def #{func}A(#{proto})
|
458
|
+
#{call_func}A.call(#{proto})
|
459
|
+
end
|
460
|
+
}
|
461
|
+
end
|
462
|
+
|
463
|
+
if api_w
|
464
|
+
string << %Q{
|
465
|
+
def #{func}W(#{proto})
|
466
|
+
#{call_func}W.call(#{proto})
|
467
|
+
end
|
468
|
+
}
|
469
|
+
end
|
470
|
+
|
471
|
+
# Create aliases for methods with an underscore that do not
|
472
|
+
# require an underscore, e.g. umask and _umask.
|
473
|
+
if func[0].chr == '_'
|
474
|
+
func_alias = func[1, func.length]
|
475
|
+
string << "alias #{func_alias} #{func}\n"
|
476
|
+
end
|
477
|
+
|
478
|
+
string << 'end'
|
479
|
+
end
|
480
|
+
|
481
|
+
eval(string)
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
485
|
+
# Calls the function name set in the constructor.
|
486
|
+
#
|
487
|
+
def call(*args)
|
488
|
+
@api.call(*args)
|
489
|
+
end
|
490
|
+
|
491
|
+
private
|
492
|
+
|
493
|
+
# Get a module's namespace. This is basically the equivalent of
|
494
|
+
# the rb_path2class() function from intern.h
|
495
|
+
#
|
496
|
+
def class_for(class_name)
|
497
|
+
names = class_name.split("::")
|
498
|
+
result = Object
|
499
|
+
names.each{ |n| result = result.const_get(n) }
|
500
|
+
result
|
501
|
+
end
|
502
|
+
end
|
503
|
+
end
|