win32-api 1.3.0-x86-mswin32-60 → 1.4.0-x86-mswin32-60
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.
- data/CHANGES +10 -0
- data/ext/win32/api.c +69 -60
- data/lib/win32/api.so +0 -0
- data/test/test_win32_api.rb +1 -1
- metadata +2 -2
data/CHANGES
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
= 1.4.0 - 19-Feb-2009
|
2
|
+
* Now compatible with Ruby 1.9.x.
|
3
|
+
* In what will go down as, "It seemed like a good idea at the time", I have
|
4
|
+
removed the feature where W (wide) character functions were used first if
|
5
|
+
your $KCODE environment variable was set to "UTF8". It caused too many
|
6
|
+
headaches in practice, especially amongst Rails users. You must now always
|
7
|
+
explicitly specify 'W' in the constructor if that's what you want.
|
8
|
+
* Fixed RF bug #23944 - bad error message for MSVCRT functions that failed
|
9
|
+
to load properly.
|
10
|
+
|
1
11
|
= 1.3.0 - 1-Jan-2009
|
2
12
|
* Fixed RubyForge bug #23395, which was caused by inadvertently modifying
|
3
13
|
a variable within a loop. This caused callbacks to fail in certain
|
data/ext/win32/api.c
CHANGED
@@ -1,8 +1,23 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
#include <windows.h>
|
3
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
|
+
|
4
19
|
#define MAX_BUF 1024
|
5
|
-
#define WINDOWS_API_VERSION "1.
|
20
|
+
#define WINDOWS_API_VERSION "1.4.0"
|
6
21
|
|
7
22
|
#define _T_VOID 0
|
8
23
|
#define _T_LONG 1
|
@@ -117,27 +132,27 @@ static VALUE callback_init(int argc, VALUE* argv, VALUE self)
|
|
117
132
|
rb_scan_args(argc, argv, "11&", &v_proto, &v_return, &v_proc);
|
118
133
|
|
119
134
|
/* Validate prototype characters */
|
120
|
-
for(i = 0; i <
|
121
|
-
switch(
|
135
|
+
for(i = 0; i < RSTRING_LEN(v_proto); i++){
|
136
|
+
switch(RSTRING_PTR(v_proto)[i]){
|
122
137
|
case 'I': case 'L': case 'P': case 'V': case 'S':
|
123
138
|
break;
|
124
139
|
default:
|
125
140
|
rb_raise(cAPIProtoError, "Illegal prototype '%c'",
|
126
|
-
|
141
|
+
RSTRING_PTR(v_proto)[i]
|
127
142
|
);
|
128
143
|
}
|
129
144
|
}
|
130
145
|
|
131
|
-
if(NIL_P(v_return) ||
|
146
|
+
if(NIL_P(v_return) || RARRAY_LEN(v_return) == 0){
|
132
147
|
v_return = rb_str_new2("L");
|
133
148
|
}
|
134
149
|
else{
|
135
|
-
switch(*(char*)
|
150
|
+
switch(*(char*)RSTRING_PTR(v_return)){
|
136
151
|
case 'I': case 'L': case 'P': case 'V': case 'S':
|
137
152
|
break;
|
138
153
|
default:
|
139
154
|
rb_raise(cAPIProtoError, "Illegal return type '%s'",
|
140
|
-
|
155
|
+
RSTRING_PTR(v_return)
|
141
156
|
);
|
142
157
|
}
|
143
158
|
}
|
@@ -145,7 +160,7 @@ static VALUE callback_init(int argc, VALUE* argv, VALUE self)
|
|
145
160
|
rb_iv_set(self, "@function", v_proc);
|
146
161
|
rb_iv_set(self, "@prototype", v_proto);
|
147
162
|
rb_iv_set(self, "@return_type", v_return);
|
148
|
-
rb_iv_set(self, "@address", ULONG2NUM((LPARAM)CallbackTable[
|
163
|
+
rb_iv_set(self, "@address", ULONG2NUM((LPARAM)CallbackTable[RSTRING_LEN(v_proto)]));
|
149
164
|
ActiveCallback = self;
|
150
165
|
|
151
166
|
return self;
|
@@ -209,14 +224,14 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
209
224
|
v_proto = rb_str_split(v_proto, "");
|
210
225
|
|
211
226
|
// Convert a nil or empty prototype to 'V' (void) automatically
|
212
|
-
if(NIL_P(v_proto) ||
|
227
|
+
if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
|
213
228
|
v_proto = rb_ary_new();
|
214
229
|
rb_ary_push(v_proto, rb_str_new2("V"));
|
215
230
|
}
|
216
231
|
|
217
232
|
// Set an arbitrary limit of 20 parameters
|
218
|
-
if(20 <
|
219
|
-
rb_raise(rb_eArgError, "too many parameters: %d\n",
|
233
|
+
if(20 < RARRAY_LEN(v_proto))
|
234
|
+
rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY_LEN(v_proto));
|
220
235
|
|
221
236
|
// Set the default dll to 'kernel32'
|
222
237
|
if(NIL_P(v_dll))
|
@@ -229,12 +244,12 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
229
244
|
SafeStringValue(v_dll);
|
230
245
|
SafeStringValue(v_proc);
|
231
246
|
|
232
|
-
hLibrary = LoadLibrary(TEXT(
|
247
|
+
hLibrary = LoadLibrary(TEXT(RSTRING_PTR(v_dll)));
|
233
248
|
|
234
249
|
// The most likely cause of failure is a bad DLL load path
|
235
250
|
if(!hLibrary){
|
236
251
|
rb_raise(cAPILoadError, "LoadLibrary() function failed for '%s': %s",
|
237
|
-
|
252
|
+
RSTRING_PTR(v_dll),
|
238
253
|
StringError(GetLastError())
|
239
254
|
);
|
240
255
|
}
|
@@ -243,43 +258,37 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
243
258
|
|
244
259
|
/* Attempt to get the function. If it fails, try again with an 'A'
|
245
260
|
* appended. If that fails, try again with a 'W' appended. If that
|
246
|
-
* still fails, raise an API::
|
261
|
+
* still fails, raise an API::LoadLibraryError.
|
247
262
|
*/
|
248
|
-
fProc = GetProcAddress(hLibrary, TEXT(RSTRING(v_proc)->ptr));
|
249
263
|
|
250
|
-
|
251
|
-
if(!strcmp(rb_get_kcode(), "UTF8")){
|
252
|
-
first = "W";
|
253
|
-
second = "A";
|
254
|
-
}
|
264
|
+
fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_proc)));
|
255
265
|
|
256
266
|
// Skip the ANSI and Wide function checks for MSVCRT functions.
|
257
267
|
if(!fProc){
|
258
|
-
if(strstr(
|
268
|
+
if(strstr(RSTRING_PTR(v_dll), "msvcr")){
|
259
269
|
rb_raise(
|
260
270
|
cAPILoadError,
|
261
271
|
"Unable to load function '%s'",
|
262
|
-
|
263
|
-
StringError(GetLastError())
|
272
|
+
RSTRING_PTR(v_proc)
|
264
273
|
);
|
265
274
|
}
|
266
275
|
else{
|
267
276
|
VALUE v_ascii = rb_str_new3(v_proc);
|
268
277
|
v_ascii = rb_str_cat(v_ascii, first, 1);
|
269
|
-
fProc = GetProcAddress(hLibrary, TEXT(
|
278
|
+
fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_ascii)));
|
270
279
|
|
271
280
|
if(!fProc){
|
272
281
|
VALUE v_unicode = rb_str_new3(v_proc);
|
273
282
|
v_unicode = rb_str_cat(v_unicode, second, 1);
|
274
|
-
fProc = GetProcAddress(hLibrary, TEXT(
|
283
|
+
fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_unicode)));
|
275
284
|
|
276
285
|
if(!fProc){
|
277
286
|
rb_raise(
|
278
287
|
cAPILoadError,
|
279
288
|
"Unable to load function '%s', '%s', or '%s'",
|
280
|
-
|
281
|
-
|
282
|
-
|
289
|
+
RSTRING_PTR(v_proc),
|
290
|
+
RSTRING_PTR(v_ascii),
|
291
|
+
RSTRING_PTR(v_unicode)
|
283
292
|
);
|
284
293
|
}
|
285
294
|
else{
|
@@ -299,9 +308,9 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
299
308
|
|
300
309
|
// Push the numeric prototypes onto our int array for later use.
|
301
310
|
|
302
|
-
for(i = 0; i <
|
303
|
-
SafeStringValue(
|
304
|
-
switch(*(char*)StringValuePtr(
|
311
|
+
for(i = 0; i < RARRAY_LEN(v_proto); i++){
|
312
|
+
SafeStringValue(RARRAY_PTR(v_proto)[i]);
|
313
|
+
switch(*(char*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
|
305
314
|
case 'L':
|
306
315
|
ptr->prototype[i] = _T_LONG;
|
307
316
|
break;
|
@@ -322,7 +331,7 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
322
331
|
break;
|
323
332
|
default:
|
324
333
|
rb_raise(cAPIProtoError, "Illegal prototype '%s'",
|
325
|
-
StringValuePtr(
|
334
|
+
StringValuePtr(RARRAY_PTR(v_proto)[i])
|
326
335
|
);
|
327
336
|
}
|
328
337
|
}
|
@@ -330,13 +339,13 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
330
339
|
// Store the return type for later use.
|
331
340
|
|
332
341
|
// Automatically convert empty strings or nil to type void.
|
333
|
-
if(NIL_P(v_return) ||
|
342
|
+
if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
|
334
343
|
v_return = rb_str_new2("V");
|
335
344
|
ptr->return_type = _T_VOID;
|
336
345
|
}
|
337
346
|
else{
|
338
347
|
SafeStringValue(v_return);
|
339
|
-
switch(*
|
348
|
+
switch(*RSTRING_PTR(v_return)){
|
340
349
|
case 'L':
|
341
350
|
ptr->return_type = _T_LONG;
|
342
351
|
break;
|
@@ -354,7 +363,7 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
|
|
354
363
|
break;
|
355
364
|
default:
|
356
365
|
rb_raise(cAPIProtoError, "Illegal return type '%s'",
|
357
|
-
|
366
|
+
RSTRING_PTR(v_return)
|
358
367
|
);
|
359
368
|
}
|
360
369
|
}
|
@@ -408,14 +417,14 @@ static VALUE func_init(int argc, VALUE* argv, VALUE self){
|
|
408
417
|
v_proto = rb_str_split(v_proto, "");
|
409
418
|
|
410
419
|
// Convert a nil or empty prototype to 'V' (void) automatically
|
411
|
-
if(NIL_P(v_proto) ||
|
420
|
+
if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
|
412
421
|
v_proto = rb_ary_new();
|
413
422
|
rb_ary_push(v_proto, rb_str_new2("V"));
|
414
423
|
}
|
415
424
|
|
416
425
|
// Set an arbitrary limit of 20 parameters
|
417
|
-
if(20 <
|
418
|
-
rb_raise(rb_eArgError, "too many parameters: %d\n",
|
426
|
+
if(20 < RARRAY_LEN(v_proto))
|
427
|
+
rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY_LEN(v_proto));
|
419
428
|
|
420
429
|
// Set the default return type to 'L' (DWORD)
|
421
430
|
if(NIL_P(v_return))
|
@@ -425,9 +434,9 @@ static VALUE func_init(int argc, VALUE* argv, VALUE self){
|
|
425
434
|
|
426
435
|
// Push the numeric prototypes onto our int array for later use.
|
427
436
|
|
428
|
-
for(i = 0; i <
|
429
|
-
SafeStringValue(
|
430
|
-
switch(*(char*)StringValuePtr(
|
437
|
+
for(i = 0; i < RARRAY_LEN(v_proto); i++){
|
438
|
+
SafeStringValue(RARRAY_PTR(v_proto)[i]);
|
439
|
+
switch(*(char*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
|
431
440
|
case 'L':
|
432
441
|
ptr->prototype[i] = _T_LONG;
|
433
442
|
break;
|
@@ -448,7 +457,7 @@ static VALUE func_init(int argc, VALUE* argv, VALUE self){
|
|
448
457
|
break;
|
449
458
|
default:
|
450
459
|
rb_raise(cAPIProtoError, "Illegal prototype '%s'",
|
451
|
-
StringValuePtr(
|
460
|
+
StringValuePtr(RARRAY_PTR(v_proto)[i])
|
452
461
|
);
|
453
462
|
}
|
454
463
|
}
|
@@ -456,13 +465,13 @@ static VALUE func_init(int argc, VALUE* argv, VALUE self){
|
|
456
465
|
// Store the return type for later use.
|
457
466
|
|
458
467
|
// Automatically convert empty strings or nil to type void.
|
459
|
-
if(NIL_P(v_return) ||
|
468
|
+
if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
|
460
469
|
v_return = rb_str_new2("V");
|
461
470
|
ptr->return_type = _T_VOID;
|
462
471
|
}
|
463
472
|
else{
|
464
473
|
SafeStringValue(v_return);
|
465
|
-
switch(*
|
474
|
+
switch(*RSTRING_PTR(v_return)){
|
466
475
|
case 'L':
|
467
476
|
ptr->return_type = _T_LONG;
|
468
477
|
break;
|
@@ -480,7 +489,7 @@ static VALUE func_init(int argc, VALUE* argv, VALUE self){
|
|
480
489
|
break;
|
481
490
|
default:
|
482
491
|
rb_raise(cAPIProtoError, "Illegal return type '%s'",
|
483
|
-
|
492
|
+
RSTRING_PTR(v_return)
|
484
493
|
);
|
485
494
|
}
|
486
495
|
}
|
@@ -507,15 +516,15 @@ DWORD CallbackFunction(CALLPARAM param)
|
|
507
516
|
|
508
517
|
if(!NIL_P(ActiveCallback)){
|
509
518
|
v_proto = rb_iv_get(ActiveCallback, "@prototype");
|
510
|
-
a_proto =
|
519
|
+
a_proto = RSTRING_PTR(v_proto);
|
511
520
|
|
512
521
|
v_return = rb_iv_get(ActiveCallback, "@return_type");
|
513
|
-
a_return =
|
522
|
+
a_return = RSTRING_PTR(v_return);
|
514
523
|
|
515
524
|
v_proc = rb_iv_get(ActiveCallback, "@function");
|
516
|
-
argc =
|
525
|
+
argc = RSTRING_LEN(v_proto);
|
517
526
|
|
518
|
-
for(i=0; i <
|
527
|
+
for(i=0; i < RSTRING_LEN(v_proto); i++){
|
519
528
|
argv[i] = Qnil;
|
520
529
|
switch(a_proto[i]){
|
521
530
|
case 'L':
|
@@ -530,7 +539,7 @@ DWORD CallbackFunction(CALLPARAM param)
|
|
530
539
|
break;
|
531
540
|
default:
|
532
541
|
rb_raise(cAPIProtoError, "Illegal prototype '%s'",
|
533
|
-
|
542
|
+
RSTRING_PTR(a_proto[i])
|
534
543
|
);
|
535
544
|
}
|
536
545
|
}
|
@@ -553,7 +562,7 @@ DWORD CallbackFunction(CALLPARAM param)
|
|
553
562
|
return NUM2ULONG(v_retval);
|
554
563
|
break;
|
555
564
|
case 'S':
|
556
|
-
return (unsigned long)
|
565
|
+
return (unsigned long)RSTRING_PTR(v_retval);
|
557
566
|
break;
|
558
567
|
case 'P':
|
559
568
|
if(NIL_P(v_retval)){
|
@@ -684,23 +693,23 @@ static VALUE api_call(int argc, VALUE* argv, VALUE self){
|
|
684
693
|
v_proto = rb_iv_get(self, "@prototype");
|
685
694
|
|
686
695
|
// For void prototypes, allow either no args or an explicit nil
|
687
|
-
if(
|
688
|
-
char* c = StringValuePtr(
|
696
|
+
if(RARRAY_LEN(v_proto) != RARRAY_LEN(v_args)){
|
697
|
+
char* c = StringValuePtr(RARRAY_PTR(v_proto)[0]);
|
689
698
|
if(!strcmp(c, "V")){
|
690
699
|
rb_ary_push(v_args, Qnil);
|
691
700
|
}
|
692
701
|
else{
|
693
702
|
rb_raise(rb_eArgError,
|
694
703
|
"wrong number of parameters: expected %d, got %d",
|
695
|
-
|
704
|
+
RARRAY_LEN(v_proto), RARRAY_LEN(v_args)
|
696
705
|
);
|
697
706
|
}
|
698
707
|
}
|
699
708
|
|
700
|
-
len =
|
709
|
+
len = RARRAY_LEN(v_proto);
|
701
710
|
|
702
711
|
for(i = 0; i < len; i++){
|
703
|
-
v_arg =
|
712
|
+
v_arg = RARRAY_PTR(v_args)[i];
|
704
713
|
|
705
714
|
// Convert nil to NULL. Otherwise convert as appropriate.
|
706
715
|
if(NIL_P(v_arg))
|
@@ -730,10 +739,10 @@ static VALUE api_call(int argc, VALUE* argv, VALUE self){
|
|
730
739
|
case _T_CALLBACK:
|
731
740
|
ActiveCallback = v_arg;
|
732
741
|
v_proto = rb_iv_get(ActiveCallback, "@prototype");
|
733
|
-
param.params[i] = (LPARAM)CallbackTable[
|
742
|
+
param.params[i] = (LPARAM)CallbackTable[RSTRING_LEN(v_proto)];
|
734
743
|
break;
|
735
744
|
case _T_STRING:
|
736
|
-
param.params[i] = (unsigned long)
|
745
|
+
param.params[i] = (unsigned long)RSTRING_PTR(v_arg);
|
737
746
|
break;
|
738
747
|
default:
|
739
748
|
param.params[i] = NUM2ULONG(v_arg);
|
@@ -763,7 +772,7 @@ static VALUE api_call(int argc, VALUE* argv, VALUE self){
|
|
763
772
|
}
|
764
773
|
else{
|
765
774
|
VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
|
766
|
-
char* efunc =
|
775
|
+
char* efunc = RSTRING_PTR(v_efunc);
|
767
776
|
if(efunc[strlen(efunc)-1] == 'W'){
|
768
777
|
v_return = rb_str_new(
|
769
778
|
(TCHAR*)return_value,
|
@@ -778,7 +787,7 @@ static VALUE api_call(int argc, VALUE* argv, VALUE self){
|
|
778
787
|
case _T_STRING:
|
779
788
|
{
|
780
789
|
VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
|
781
|
-
char* efunc =
|
790
|
+
char* efunc = RSTRING_PTR(v_efunc);
|
782
791
|
|
783
792
|
if(efunc[strlen(efunc)-1] == 'W'){
|
784
793
|
v_return = rb_str_new(
|
data/lib/win32/api.so
CHANGED
Binary file
|
data/test/test_win32_api.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win32-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: x86-mswin32-60
|
6
6
|
authors:
|
7
7
|
- Daniel J. Berger
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-
|
13
|
+
date: 2009-02-19 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|