win32-api 1.0.6 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ = 1.1.0 - 12-Jun-2008
2
+ * Added the Windows::API::Function class. This is a subclass of Win32::API
3
+ meant only for use with raw function pointers.
4
+ * Some documentation updates in the source and README files.
5
+
1
6
  = 1.0.6 - 18-Apr-2008
2
7
  * Added the effective_function_name method. This allows you to see what the
3
8
  actual function name is that was defined, e.g. GetUserNameA vs GetUserNameW.
data/MANIFEST CHANGED
@@ -5,5 +5,6 @@
5
5
  * win32-api.gemspec
6
6
  * ext/extconf.rb
7
7
  * ext/win32/api.c
8
- * test/tc_win32_api_callback.rb
9
- * test/tc_win32_api.rb
8
+ * test/test_win32_api.rb
9
+ * test/test_win32_api_callback.rb
10
+ * test/test_win32_api_function.rb
data/README CHANGED
@@ -1,85 +1,98 @@
1
- = Description
2
- This is a drop-in replacement for the Win32API library currently part of
3
- Ruby's standard library.
4
-
5
- = Synopsis
6
- require 'win32/api'
7
- include Win32
8
-
9
- buf = 0.chr * 260
10
- len = [@buf.length].pack('L')
11
-
12
- GetUserName = API.new('GetUserName', 'PP', 'I', 'advapi32')
13
- GetUserName.call(buf, len)
14
-
15
- puts buf.strip
16
-
17
- # Callback example
18
- EnumWindows = API.new('EnumWindows', 'KP', 'L', 'user32')
19
- GetWindowText = API.new('GetWindowText', 'LPI', 'I', 'user32')
20
- EnumWindowsProc = API::Callback.new('LP', 'I'){ |handle, param|
21
- buf = "\0" * 200
22
- GetWindowText.call(handle, buf, 200);
23
- puts buf.strip
24
- buf.index(param).nil? ? true : false
25
- }
26
-
27
- = Differences between win32-api and Win32API
28
- * This library has callback support!
29
- * Argument order change. The DLL name is now last, not first.
30
- * Removed the 'N' and 'n'. Always use 'L' for longs now.
31
- * Sensible default arguments for the prototype, return type and DLL name.
32
- * Reader methods for the function name, prototype, return type and DLL.
33
- * Removed the support for lower case prototype and return types. Always
34
- use capital letters.
35
- * Resorts to wide character functions (where possible) when $KCODE is set
36
- to UTF8.
37
-
38
- = Developer's Notes
39
- The current Win32API library that ships with the standard library has been
40
- slated for removal from Ruby 2.0 and it will not receive any updates in the
41
- Ruby 1.8.x branch. I have far too many libraries invested in it to let it
42
- die at this point.
43
-
44
- In addition, the current Win32API library was written in the bad old Ruby
45
- 1.6.x days, which means it doesn't use the newer allocation framework.
46
- There were several other refactorings that I felt it needed to more closely
47
- match how it was actually being used in practice.
48
-
49
- The first order of business was changing the order of the arguments. By
50
- moving the DLL name from first to last, I was able to provide reasonable
51
- default arguments for the prototype, return type and the DLL. Only the
52
- function name is required now.
53
-
54
- There was a laundry list of other refactorings that were needed: sensical
55
- instance variable names with proper accessors, removing support for lower
56
- case prototype and return value characters that no one used in practice,
57
- better naming conventions, the addition of RDoc ready comments and,
58
- especially, callback support.
59
-
60
- Most importantly, we can now add, modify and fix any features that we feel
61
- best benefit our end users.
62
-
63
- = Documentation
64
- The source file contains inline RDoc documentation. If you installed
65
- this file as a gem, then you have the docs.
66
-
67
- = Warranty
68
- This package is provided "as is" and without any express or
69
- implied warranties, including, without limitation, the implied
70
- warranties of merchantability and fitness for a particular purpose.
71
-
72
- = Known Bugs
73
- None that I'm aware of. Please submit any bug reports to the project page
74
- at http://www.rubyforge.org/projects/win32utils.
75
-
76
- = Copyright
77
- (C) 2003-2007 Daniel J. Berger
78
- All Rights Reserved
79
-
80
- = License
81
- Ruby's
82
-
83
- = Authors
84
- Daniel J. Berger
1
+ = Description
2
+ This is a drop-in replacement for the Win32API library currently part of
3
+ Ruby's standard library.
4
+
5
+ = Synopsis
6
+ require 'win32/api'
7
+ include Win32
8
+
9
+ # Typical example - Get user name
10
+ buf = 0.chr * 260
11
+ len = [buf.length].pack('L')
12
+
13
+ GetUserName = API.new('GetUserName', 'PP', 'I', 'advapi32')
14
+ GetUserName.call(buf, len)
15
+
16
+ puts buf.strip
17
+
18
+ # Callback example - Enumerate windows
19
+ EnumWindows = API.new('EnumWindows', 'KP', 'L', 'user32')
20
+ GetWindowText = API.new('GetWindowText', 'LPI', 'I', 'user32')
21
+ EnumWindowsProc = API::Callback.new('LP', 'I'){ |handle, param|
22
+ buf = "\0" * 200
23
+ GetWindowText.call(handle, buf, 200);
24
+ puts buf.strip unless buf.strip.empty?
25
+ buf.index(param).nil? ? true : false
26
+ }
27
+
28
+ EnumWindows.call(EnumWindowsProc, 'UEDIT32')
29
+
30
+ # Raw function pointer example - System beep
31
+ LoadLibrary = API.new('LoadLibrary', 'P', 'L')
32
+ GetProcAddress = API.new('GetProcAddress', 'LP', 'L')
33
+
34
+ hlib = LoadLibrary.call('user32')
35
+ addr = GetProcAddress.call(hlib, 'MessageBeep')
36
+ func = Win32::API::Function.new(addr, 'L', 'L')
37
+ func.call(0)
38
+
39
+ = Differences between win32-api and Win32API
40
+ * This library has callback support
41
+ * This library supports raw function pointers.
42
+ * Argument order change. The DLL name is now last, not first.
43
+ * Removed the 'N' and 'n'. Always use 'L' for longs now.
44
+ * Sensible default arguments for the prototype, return type and DLL name.
45
+ * Reader methods for the function name, prototype, return type and DLL.
46
+ * Removed the support for lower case prototype and return types. Always
47
+ use capital letters.
48
+ * Resorts to wide character functions (where possible) when $KCODE is set
49
+ to UTF8.
50
+
51
+ = Developer's Notes
52
+ The current Win32API library that ships with the standard library has been
53
+ slated for removal from Ruby 2.0 and it will not receive any updates in the
54
+ Ruby 1.8.x branch. I have far too many libraries invested in it to let it
55
+ die at this point.
56
+
57
+ In addition, the current Win32API library was written in the bad old Ruby
58
+ 1.6.x days, which means it doesn't use the newer allocation framework.
59
+ There were several other refactorings that I felt it needed to more closely
60
+ match how it was actually being used in practice.
61
+
62
+ The first order of business was changing the order of the arguments. By
63
+ moving the DLL name from first to last, I was able to provide reasonable
64
+ default arguments for the prototype, return type and the DLL. Only the
65
+ function name is required now.
66
+
67
+ There was a laundry list of other refactorings that were needed: sensical
68
+ instance variable names with proper accessors, removing support for lower
69
+ case prototype and return value characters that no one used in practice,
70
+ better naming conventions, the addition of RDoc ready comments and,
71
+ especially, callback support.
72
+
73
+ Most importantly, we can now add, modify and fix any features that we feel
74
+ best benefit our end users.
75
+
76
+ = Documentation
77
+ The source file contains inline RDoc documentation. If you installed
78
+ this file as a gem, then you have the docs.
79
+
80
+ = Warranty
81
+ This package is provided "as is" and without any express or
82
+ implied warranties, including, without limitation, the implied
83
+ warranties of merchantability and fitness for a particular purpose.
84
+
85
+ = Known Bugs
86
+ None that I'm aware of. Please submit any bug reports to the project page
87
+ at http://www.rubyforge.org/projects/win32utils.
88
+
89
+ = Copyright
90
+ (C) 2003-2008 Daniel J. Berger
91
+ All Rights Reserved
92
+
93
+ = License
94
+ Ruby's
95
+
96
+ = Authors
97
+ Daniel J. Berger
85
98
  Park Heesob
@@ -2,7 +2,7 @@
2
2
  #include <windows.h>
3
3
 
4
4
  #define MAX_BUF 1024
5
- #define WINDOWS_API_VERSION "1.0.6"
5
+ #define WINDOWS_API_VERSION "1.1.0"
6
6
 
7
7
  #define _T_VOID 0
8
8
  #define _T_LONG 1
@@ -12,8 +12,28 @@
12
12
 
13
13
  VALUE cAPIError, cCallbackError;
14
14
 
15
+ typedef struct {
16
+ HANDLE library;
17
+ FARPROC function;
18
+ int return_type;
19
+ int prototype[16];
20
+ } Win32API;
21
+
22
+ static void api_free(Win32API* ptr){
23
+ if(ptr->library)
24
+ FreeLibrary(ptr->library);
25
+
26
+ if(ptr)
27
+ free(ptr);
28
+ }
29
+
30
+ static VALUE api_allocate(VALUE klass){
31
+ Win32API* ptr = malloc(sizeof(Win32API));
32
+ return Data_Wrap_Struct(klass, 0, api_free, ptr);
33
+ }
34
+
15
35
  /* Helper function that converts the error number returned by GetLastError()
16
- * into a human readable string. Internal use only.
36
+ * into a human readable string. Internal use only.
17
37
  */
18
38
  char* StringError(DWORD dwError){
19
39
  LPVOID lpMsgBuf;
@@ -52,10 +72,11 @@ char* StringError(DWORD dwError){
52
72
 
53
73
  /*
54
74
  * call-seq:
55
- * Win32::API::Callback.new(prototype, return='L')
75
+ * Win32::API::Callback.new(prototype, return='L'){ |proto| ... }
56
76
  *
57
- * Creates and returns a new Win32::API::Callback object. The +function+ is
58
- * the name of the Windows function.
77
+ * Creates and returns a new Win32::API::Callback object. The prototype
78
+ * arguments are yielded back to the block in the same order they were
79
+ * declared.
59
80
  *
60
81
  * The +prototype+ is the function prototype for the callback function. This
61
82
  * is a string. The possible valid characters are 'I' (integer), 'L' (long),
@@ -65,6 +86,21 @@ char* StringError(DWORD dwError){
65
86
  * The +return+ argument is the return type for the callback function. The
66
87
  * valid characters are the same as for the +prototype+. The default is
67
88
  * 'L' (long).
89
+ *
90
+ * Example:
91
+ * require 'win32/api'
92
+ * include Win32
93
+ *
94
+ * EnumWindows = API.new('EnumWindows', 'KP', 'L', 'user32')
95
+ * GetWindowText = API.new('GetWindowText', 'LPI', 'I', 'user32')
96
+ * EnumWindowsProc = API::Callback.new('LP', 'I'){ |handle, param|
97
+ * buf = "\0" * 200
98
+ * GetWindowText.call(handle, buf, 200);
99
+ * puts buf.strip unless buf.strip.empty?
100
+ * buf.index(param).nil? ? true : false
101
+ * }
102
+ *
103
+ * EnumWindows.call(EnumWindowsProc, 'UEDIT32')
68
104
  */
69
105
  static VALUE callback_init(int argc, VALUE* argv, VALUE self)
70
106
  {
@@ -91,27 +127,7 @@ static VALUE callback_init(int argc, VALUE* argv, VALUE self)
91
127
  rb_iv_set(self, "@prototype", v_proto);
92
128
  rb_iv_set(self, "@return_type", v_return);
93
129
 
94
- return self;
95
- }
96
-
97
-
98
- typedef struct {
99
- HANDLE library;
100
- FARPROC function;
101
- int return_type;
102
- int prototype[16];
103
- } Win32API;
104
-
105
- static void api_free(Win32API* ptr){
106
- if(ptr->library)
107
- FreeLibrary(ptr->library);
108
-
109
- free(ptr);
110
- }
111
-
112
- static VALUE api_allocate(VALUE klass){
113
- Win32API* ptr = malloc(sizeof(Win32API));
114
- return Data_Wrap_Struct(klass, 0, api_free, ptr);
130
+ return self;
115
131
  }
116
132
 
117
133
  /*
@@ -134,6 +150,19 @@ static VALUE api_allocate(VALUE klass){
134
150
  *
135
151
  * If the function cannot be found then an API::Error is raised (a subclass
136
152
  * of RuntimeError).
153
+ *
154
+ * Example:
155
+ *
156
+ * require 'win32/api'
157
+ * include Win32
158
+ *
159
+ * buf = 0.chr * 260
160
+ * len = [buf.length].pack('L')
161
+ *
162
+ * GetUserName = API.new('GetUserName', 'PP', 'I', 'advapi32')
163
+ * GetUserName.call(buf, len)
164
+ *
165
+ * puts buf.strip
137
166
  */
138
167
  static VALUE api_init(int argc, VALUE* argv, VALUE self)
139
168
  {
@@ -149,25 +178,25 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
149
178
 
150
179
  Data_Get_Struct(self, Win32API, ptr);
151
180
 
152
- /* Convert a string prototype to an array of characters */
181
+ // Convert a string prototype to an array of characters
153
182
  if(rb_respond_to(v_proto, rb_intern("split")))
154
183
  v_proto = rb_str_split(v_proto, "");
155
184
 
156
- /* Set an arbitrary limit of 16 parameters */
157
- if(16 < RARRAY(v_proto)->len)
158
- rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY(v_proto)->len);
159
-
160
- /* Convert a nil or empty prototype to 'V' (void) automatically */
185
+ // Convert a nil or empty prototype to 'V' (void) automatically
161
186
  if(NIL_P(v_proto) || RARRAY(v_proto)->len == 0){
162
187
  v_proto = rb_ary_new();
163
188
  rb_ary_push(v_proto, rb_str_new2("V"));
164
189
  }
190
+
191
+ // Set an arbitrary limit of 16 parameters
192
+ if(16 < RARRAY(v_proto)->len)
193
+ rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY(v_proto)->len);
165
194
 
166
- /* Set the default dll to 'kernel32' */
195
+ // Set the default dll to 'kernel32'
167
196
  if(NIL_P(v_dll))
168
197
  v_dll = rb_str_new2("kernel32");
169
198
 
170
- /* Set the default return type to 'L' (DWORD) */
199
+ // Set the default return type to 'L' (DWORD)
171
200
  if(NIL_P(v_return))
172
201
  v_return = rb_str_new2("L");
173
202
 
@@ -176,7 +205,7 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
176
205
 
177
206
  hLibrary = LoadLibrary(TEXT(RSTRING(v_dll)->ptr));
178
207
 
179
- /* The most likely cause of failure is a bad DLL load path */
208
+ // The most likely cause of failure is a bad DLL load path
180
209
  if(!hLibrary){
181
210
  rb_raise(cAPIError, "LoadLibrary() function failed for '%s': %s",
182
211
  RSTRING(v_dll)->ptr,
@@ -192,7 +221,7 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
192
221
  */
193
222
  fProc = GetProcAddress(hLibrary, TEXT(RSTRING(v_proc)->ptr));
194
223
 
195
- /* The order of 'A' and 'W' is reversed if $KCODE is set to 'UTF8'. */
224
+ // The order of 'A' and 'W' is reversed if $KCODE is set to 'UTF8'.
196
225
  if(!strcmp(rb_get_kcode(), "UTF8")){
197
226
  first = "W";
198
227
  second = "A";
@@ -232,7 +261,8 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
232
261
 
233
262
  ptr->function = fProc;
234
263
 
235
- /* Push the numeric prototypes onto our int array for later use. */
264
+ // Push the numeric prototypes onto our int array for later use.
265
+
236
266
  for(i = 0; i < RARRAY(v_proto)->len; i++){
237
267
  SafeStringValue(RARRAY(v_proto)->ptr[i]);
238
268
  switch(*(char*)StringValuePtr(RARRAY(v_proto)->ptr[i])){
@@ -256,9 +286,9 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
256
286
  }
257
287
  }
258
288
 
259
- /* Store the return type for later use. Automatically convert empty
260
- * strings or nil to type void.
261
- */
289
+ // Store the return type for later use.
290
+
291
+ // Automatically convert empty strings or nil to type void.
262
292
  if(NIL_P(v_return) || RSTRING(v_return)->len == 0){
263
293
  v_return = rb_str_new2("V");
264
294
  ptr->return_type = _T_VOID;
@@ -291,6 +321,121 @@ static VALUE api_init(int argc, VALUE* argv, VALUE self)
291
321
  return self;
292
322
  }
293
323
 
324
+ /*
325
+ * call-seq:
326
+ *
327
+ * API::Function.new(address, prototype = 'V', return_type = 'L')
328
+ *
329
+ * Creates and returns an API::Function object. This object is similar to an
330
+ * API object, except that instead of a character function name you pass a
331
+ * function pointer address as the first argument, and there's no associated
332
+ * DLL file.
333
+ *
334
+ * Once you have your API::Function object you can then call it the same way
335
+ * you would an API object.
336
+ *
337
+ * Example:
338
+ *
339
+ * require 'win32/api'
340
+ * include Win32
341
+ *
342
+ * LoadLibrary = API.new('LoadLibrary', 'P', 'L')
343
+ * GetProcAddress = API.new('GetProcAddress', 'LP', 'L')
344
+ *
345
+ * # Play a system beep
346
+ * hlib = LoadLibrary.call('user32')
347
+ * addr = GetProcAddress.call(hlib, 'MessageBeep')
348
+ * func = Win32::API::Function.new(addr, 'L', 'L')
349
+ * func.call(0)
350
+ */
351
+ static VALUE func_init(int argc, VALUE* argv, VALUE self){
352
+ Win32API* ptr;
353
+ int i;
354
+ VALUE v_address, v_proto, v_return;
355
+
356
+ rb_scan_args(argc, argv, "12", &v_address, &v_proto, &v_return);
357
+
358
+ Data_Get_Struct(self, Win32API, ptr);
359
+
360
+ // Convert a string prototype to an array of characters
361
+ if(rb_respond_to(v_proto, rb_intern("split")))
362
+ v_proto = rb_str_split(v_proto, "");
363
+
364
+ // Convert a nil or empty prototype to 'V' (void) automatically
365
+ if(NIL_P(v_proto) || RARRAY(v_proto)->len == 0){
366
+ v_proto = rb_ary_new();
367
+ rb_ary_push(v_proto, rb_str_new2("V"));
368
+ }
369
+
370
+ // Set an arbitrary limit of 16 parameters
371
+ if(16 < RARRAY(v_proto)->len)
372
+ rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY(v_proto)->len);
373
+
374
+ // Set the default return type to 'L' (DWORD)
375
+ if(NIL_P(v_return))
376
+ v_return = rb_str_new2("L");
377
+
378
+ ptr->function = (FARPROC)NUM2LONG(v_address);
379
+
380
+ // Push the numeric prototypes onto our int array for later use.
381
+
382
+ for(i = 0; i < RARRAY(v_proto)->len; i++){
383
+ SafeStringValue(RARRAY(v_proto)->ptr[i]);
384
+ switch(*(char*)StringValuePtr(RARRAY(v_proto)->ptr[i])){
385
+ case 'L':
386
+ ptr->prototype[i] = _T_LONG;
387
+ break;
388
+ case 'P':
389
+ ptr->prototype[i] = _T_POINTER;
390
+ break;
391
+ case 'I': case 'B':
392
+ ptr->prototype[i] = _T_INTEGER;
393
+ break;
394
+ case 'V':
395
+ ptr->prototype[i] = _T_VOID;
396
+ break;
397
+ case 'K':
398
+ ptr->prototype[i] = _T_CALLBACK;
399
+ break;
400
+ default:
401
+ rb_raise(cAPIError, "Illegal prototype '%s'", RARRAY(v_proto)->ptr[i]);
402
+ }
403
+ }
404
+
405
+ // Store the return type for later use.
406
+
407
+ // Automatically convert empty strings or nil to type void.
408
+ if(NIL_P(v_return) || RSTRING(v_return)->len == 0){
409
+ v_return = rb_str_new2("V");
410
+ ptr->return_type = _T_VOID;
411
+ }
412
+ else{
413
+ SafeStringValue(v_return);
414
+ switch(*RSTRING(v_return)->ptr){
415
+ case 'L':
416
+ ptr->return_type = _T_LONG;
417
+ break;
418
+ case 'P':
419
+ ptr->return_type = _T_POINTER;
420
+ break;
421
+ case 'I': case 'B':
422
+ ptr->return_type = _T_INTEGER;
423
+ break;
424
+ case 'V':
425
+ ptr->return_type = _T_VOID;
426
+ break;
427
+ default:
428
+ rb_raise(cAPIError, "Illegal prototype '%s'", RARRAY(v_proto)->ptr[i]);
429
+ }
430
+ }
431
+
432
+ rb_iv_set(self, "@address", v_address);
433
+ rb_iv_set(self, "@prototype", v_proto);
434
+ rb_iv_set(self, "@return_type", v_return);
435
+
436
+ return self;
437
+ }
438
+
294
439
  typedef struct {
295
440
  DWORD params[1];
296
441
  } PARAM;
@@ -481,7 +626,7 @@ static VALUE api_call(int argc, VALUE* argv, VALUE self){
481
626
  * Wraps the Windows API functions in a Ruby interface.
482
627
  */
483
628
  void Init_api(){
484
- VALUE mWin32, cAPI, cCallback;
629
+ VALUE mWin32, cAPI, cCallback, cFunction;
485
630
 
486
631
  /* Modules and Classes */
487
632
 
@@ -493,6 +638,9 @@ void Init_api(){
493
638
 
494
639
  /* The API::Callback class encapsulates a Windows CALLBACK function */
495
640
  cCallback = rb_define_class_under(cAPI, "Callback", rb_cObject);
641
+
642
+ /* The API::Function class encapsulates a raw function pointer */
643
+ cFunction = rb_define_class_under(cAPI, "Function", cAPI);
496
644
 
497
645
  /* The API::Error class is raised if the constructor fails */
498
646
  cAPIError = rb_define_class_under(cAPI, "Error", rb_eRuntimeError);
@@ -507,7 +655,11 @@ void Init_api(){
507
655
  rb_define_method(cAPI, "initialize", api_init, -1);
508
656
  rb_define_method(cAPI, "call", api_call, -1);
509
657
 
658
+ /* Win32::API::Callback Instance Methods */
510
659
  rb_define_method(cCallback, "initialize", callback_init, -1);
660
+
661
+ /* Win32::API::Function Instance Methods */
662
+ rb_define_method(cFunction, "initialize", func_init, -1);
511
663
 
512
664
  /* The name of the DLL that exports the API function */
513
665
  rb_define_attr(cAPI, "dll_name", 1, 0);
@@ -534,6 +686,9 @@ void Init_api(){
534
686
 
535
687
  /* The return type, returned as a single character, P, L, I, V or B */
536
688
  rb_define_attr(cCallback, "return_type", 1, 0);
689
+
690
+ /* The numeric address of the function pointer */
691
+ rb_define_attr(cFunction, "address", 1, 0);
537
692
 
538
693
  /* Constants */
539
694
 
@@ -1,5 +1,5 @@
1
1
  ############################################################################
2
- # tc_win32_api.rb
2
+ # test_win32_api.rb
3
3
  #
4
4
  # Test case for the Win32::API class. You should run this as Rake task,
5
5
  # i.e. 'rake test', instead of running it directly.
@@ -16,7 +16,7 @@ class TC_Win32_API < Test::Unit::TestCase
16
16
  end
17
17
 
18
18
  def test_version
19
- assert_equal('1.0.6', API::VERSION)
19
+ assert_equal('1.1.0', API::VERSION)
20
20
  end
21
21
 
22
22
  def test_call
@@ -43,6 +43,12 @@ class TC_Win32_API < Test::Unit::TestCase
43
43
  def test_effective_function_name
44
44
  assert_respond_to(@api, :effective_function_name)
45
45
  assert_equal('GetCurrentDirectoryA', @api.effective_function_name)
46
+
47
+ @api = API.new('GetCurrentDirectoryA', 'LP')
48
+ assert_equal('GetCurrentDirectoryA', @api.effective_function_name)
49
+
50
+ @api = API.new('GetCurrentDirectoryW', 'LP')
51
+ assert_equal('GetCurrentDirectoryW', @api.effective_function_name)
46
52
  end
47
53
 
48
54
  def test_prototype
@@ -1,5 +1,5 @@
1
1
  ############################################################################
2
- # tc_win32_api_callback.rb
2
+ # test_win32_api_callback.rb
3
3
  #
4
4
  # Test case for the Win32::API::Callback class. You should run this as Rake
5
5
  # task, i.e. 'rake test', instead of running it directly.
@@ -55,4 +55,4 @@ class TC_Win32_API_Callback < Test::Unit::TestCase
55
55
  @api_gwt = nil
56
56
  @callback = nil
57
57
  end
58
- end
58
+ end
@@ -0,0 +1,48 @@
1
+ ########################################################################
2
+ # test_win32_api_function.rb
3
+ #
4
+ # Test case for the Win32::API::Function class. You should run these
5
+ # tests via the 'rake test' task.
6
+ ########################################################################
7
+ require 'test/unit'
8
+ require 'win32/api'
9
+
10
+ class TC_Win32_API_Function < Test::Unit::TestCase
11
+ def setup
12
+ @func = Win32::API::Function.new(123456789, 'LP', 'L')
13
+ end
14
+
15
+ def test_constructor
16
+ assert_nothing_raised{ Win32::API::Function.new(1) }
17
+ assert_nothing_raised{ Win32::API::Function.new(1, 'LL') }
18
+ assert_nothing_raised{ Win32::API::Function.new(1, 'LL', 'I') }
19
+ end
20
+
21
+ def test_subclass
22
+ assert_kind_of(Win32::API, @func)
23
+ assert_respond_to(@func, :call)
24
+ end
25
+
26
+ def test_address
27
+ assert_respond_to(@func, :address)
28
+ assert_equal(123456789, @func.address)
29
+ end
30
+
31
+ def test_prototype
32
+ assert_respond_to(@func, :prototype)
33
+ assert_equal(['L', 'P'], @func.prototype)
34
+ end
35
+
36
+ def test_return_type
37
+ assert_respond_to(@func, :return_type)
38
+ assert_equal('L', @func.return_type)
39
+ end
40
+
41
+ def test_expected_errors
42
+ assert_raise(ArgumentError){ Win32::API::Function.new }
43
+ end
44
+
45
+ def teardown
46
+ @func = nil
47
+ end
48
+ end
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.0.6
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel J. Berger
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-04-18 00:00:00 -06:00
12
+ date: 2008-06-12 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -25,20 +25,12 @@ extra_rdoc_files:
25
25
  - MANIFEST
26
26
  - ext/win32/api.c
27
27
  files:
28
- - ext/api-i386-mswin32.def
29
- - ext/api-i386-mswin32.exp
30
- - ext/api-i386-mswin32.lib
31
- - ext/api-i386-mswin32.pdb
32
- - ext/api.obj
33
28
  - ext/extconf.rb
34
- - ext/Makefile
35
- - ext/mkmf.log
36
- - ext/vc60.pdb
37
29
  - ext/win32
38
30
  - ext/win32/api.c
39
- - ext/win32/api.so
40
- - test/tc_win32_api.rb
41
- - test/tc_win32_api_callback.rb
31
+ - test/test_win32_api.rb
32
+ - test/test_win32_api_callback.rb
33
+ - test/test_win32_api_function.rb
42
34
  - README
43
35
  - CHANGES
44
36
  - MANIFEST
@@ -53,7 +45,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
53
45
  requirements:
54
46
  - - ">="
55
47
  - !ruby/object:Gem::Version
56
- version: 1.8.0
48
+ version: 1.8.2
57
49
  version:
58
50
  required_rubygems_version: !ruby/object:Gem::Requirement
59
51
  requirements:
@@ -68,6 +60,5 @@ rubygems_version: 1.1.1
68
60
  signing_key:
69
61
  specification_version: 2
70
62
  summary: A superior replacement for Win32API
71
- test_files:
72
- - test/tc_win32_api.rb
73
- - test/tc_win32_api_callback.rb
63
+ test_files: []
64
+
@@ -1,181 +0,0 @@
1
-
2
- SHELL = /bin/sh
3
-
4
- #### Start of system configuration section. ####
5
-
6
- srcdir = win32
7
- topdir = C:/ruby/lib/ruby/1.8/i386-mswin32
8
- hdrdir = $(topdir)
9
- VPATH = $(srcdir);$(topdir);$(hdrdir)
10
-
11
- DESTDIR = C:
12
- prefix = $(DESTDIR)/ruby
13
- exec_prefix = $(DESTDIR)/ruby
14
- sitedir = $(prefix)/lib/ruby/site_ruby
15
- rubylibdir = $(libdir)/ruby/$(ruby_version)
16
- top_srcdir = $(DESTDIR)/develop/win/ruby/ruby-1.8.5
17
- archdir = $(rubylibdir)/$(arch)
18
- sbindir = $(exec_prefix)/sbin
19
- datadir = $(prefix)/share
20
- includedir = $(prefix)/include
21
- infodir = $(prefix)/info
22
- sysconfdir = $(prefix)/etc
23
- mandir = $(prefix)/man
24
- libdir = $(DESTDIR)/ruby/lib
25
- sharedstatedir = $(DESTDIR)/etc
26
- oldincludedir = $(DESTDIR)/usr/include
27
- sitearchdir = $(sitelibdir)/$(sitearch)
28
- localstatedir = $(DESTDIR)/var
29
- bindir = $(exec_prefix)/bin
30
- sitelibdir = $(sitedir)/$(ruby_version)
31
- libexecdir = $(exec_prefix)/libexec
32
-
33
- CC = cl -nologo
34
- LIBRUBY = $(RUBY_SO_NAME).lib
35
- LIBRUBY_A = msvcrt-ruby18-static.lib
36
- LIBRUBYARG_SHARED = $(LIBRUBY)
37
- LIBRUBYARG_STATIC = $(LIBRUBY_A)
38
-
39
- RUBY_EXTCONF_H =
40
- CFLAGS = -MD -Zi -O2b2xg- -G6
41
- INCFLAGS = -I. -I. -IC:/ruby/lib/ruby/1.8/i386-mswin32 -I.
42
- CPPFLAGS =
43
- CXXFLAGS = $(CFLAGS)
44
- DLDFLAGS = -link -incremental:no -debug -opt:ref -opt:icf -dll $(LIBPATH) -def:$(DEFFILE) -implib:$(*F:.so=)-$(arch).lib -pdb:$(*F:.so=)-$(arch).pdb
45
- LDSHARED = cl -nologo -LD
46
- AR = lib -nologo
47
- EXEEXT = .exe
48
-
49
- RUBY_INSTALL_NAME = ruby
50
- RUBY_SO_NAME = msvcrt-ruby18
51
- arch = i386-mswin32
52
- sitearch = i386-msvcrt
53
- ruby_version = 1.8
54
- ruby = C:/ruby/bin/ruby
55
- RUBY = $(ruby:/=\)
56
- RM = $(RUBY) -run -e rm -- -f
57
- MAKEDIRS = @$(RUBY) -run -e mkdir -- -p
58
- INSTALL = copy > nul
59
- INSTALL_PROG = $(INSTALL)
60
- INSTALL_DATA = $(INSTALL)
61
- COPY = copy > nul
62
-
63
- #### End of system configuration section. ####
64
-
65
- preload =
66
-
67
- libpath = $(libdir)
68
- LIBPATH = -libpath:"$(libdir)"
69
- DEFFILE = $(TARGET)-$(arch).def
70
-
71
- CLEANFILES =
72
- DISTCLEANFILES = vc*.pdb $(DEFFILE)
73
-
74
- extout =
75
- extout_prefix =
76
- target_prefix = /win32
77
- LOCAL_LIBS =
78
- LIBS = $(LIBRUBYARG_SHARED) oldnames.lib user32.lib advapi32.lib wsock32.lib
79
- SRCS = api.c
80
- OBJS = api.obj
81
- TARGET = api
82
- DLLIB = $(TARGET).so
83
- EXTSTATIC =
84
- STATIC_LIB =
85
-
86
- RUBYCOMMONDIR = $(sitedir)$(target_prefix)
87
- RUBYLIBDIR = $(sitelibdir)$(target_prefix)
88
- RUBYARCHDIR = $(sitearchdir)$(target_prefix)
89
-
90
- TARGET_SO = $(DLLIB)
91
- CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
92
- CLEANOBJS = *.obj *.lib *.s[ol] *.pdb *.exp *.bak
93
-
94
- all: $(DLLIB)
95
- static: $(STATIC_LIB)
96
-
97
- clean:
98
- @-$(RM) $(CLEANLIBS:/=\) $(CLEANOBJS:/=\) $(CLEANFILES:/=\)
99
-
100
- distclean: clean
101
- @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
102
- @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES:/=\)
103
-
104
- realclean: distclean
105
- install: install-so install-rb
106
-
107
- install-so: $(RUBYARCHDIR)
108
- install-so: $(RUBYARCHDIR)/$(DLLIB)
109
- $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
110
- $(INSTALL_PROG) $(DLLIB:/=\) $(RUBYARCHDIR:/=\)
111
- install-rb: pre-install-rb install-rb-default
112
- install-rb-default: pre-install-rb-default
113
- pre-install-rb: Makefile
114
- pre-install-rb-default: Makefile
115
- $(RUBYARCHDIR):
116
- $(MAKEDIRS) $@
117
-
118
- site-install: site-install-so site-install-rb
119
- site-install-so: install-so
120
- site-install-rb: install-rb
121
-
122
- .SUFFIXES: .c .m .cc .cxx .cpp .obj
123
-
124
- {$(srcdir)}.cc{}.obj:
125
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
126
-
127
- {$(topdir)}.cc{}.obj:
128
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
129
-
130
- {$(hdrdir)}.cc{}.obj:
131
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
132
-
133
- .cc.obj:
134
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
135
-
136
- {$(srcdir)}.cxx{}.obj:
137
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
138
-
139
- {$(topdir)}.cxx{}.obj:
140
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
141
-
142
- {$(hdrdir)}.cxx{}.obj:
143
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
144
-
145
- .cxx.obj:
146
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
147
-
148
- {$(srcdir)}.cpp{}.obj:
149
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
150
-
151
- {$(topdir)}.cpp{}.obj:
152
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
153
-
154
- {$(hdrdir)}.cpp{}.obj:
155
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
156
-
157
- .cpp.obj:
158
- $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/)
159
-
160
- {$(srcdir)}.c{}.obj:
161
- $(CC) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) -c -Tc$(<:\=/)
162
-
163
- {$(topdir)}.c{}.obj:
164
- $(CC) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) -c -Tc$(<:\=/)
165
-
166
- {$(hdrdir)}.c{}.obj:
167
- $(CC) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) -c -Tc$(<:\=/)
168
-
169
- .c.obj:
170
- $(CC) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) -c -Tc$(<:\=/)
171
-
172
- $(DLLIB): $(DEFFILE) $(OBJS)
173
- @-$(RM) $@
174
- $(LDSHARED) -Fe$(@) $(OBJS) $(LIBS) $(LOCAL_LIBS) $(DLDFLAGS)
175
-
176
-
177
-
178
- $(DEFFILE):
179
- $(RUBY) -e "puts 'EXPORTS', 'Init_$(TARGET)'" > $@
180
-
181
- $(OBJS): {.;$(srcdir);$(topdir);$(hdrdir)}ruby.h {.;$(srcdir);$(topdir);$(hdrdir)}defines.h
@@ -1,2 +0,0 @@
1
- EXPORTS
2
- Init_api
Binary file
Binary file
Binary file
Binary file
@@ -1,28 +0,0 @@
1
- have_func: checking for strncpy_s()... -------------------- no
2
-
3
- "cl -nologo -Feconftest -I. -IC:/ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib oldnames.lib user32.lib advapi32.lib wsock32.lib -link -libpath:"C:/ruby/lib" -stack:0x2000000"
4
- conftest.c
5
- conftest.obj : error LNK2001: unresolved external symbol _strncpy_s
6
- conftest.exe : fatal error LNK1120: 1 unresolved externals
7
- checked program was:
8
- /* begin */
9
- 1: /*top*/
10
- 2: int main() { return 0; }
11
- 3: int t() { strncpy_s(); return 0; }
12
- /* end */
13
-
14
- "cl -nologo -Feconftest -I. -IC:/ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib oldnames.lib user32.lib advapi32.lib wsock32.lib -link -libpath:"C:/ruby/lib" -stack:0x2000000"
15
- conftest.c
16
- conftest.c(6) : error C2065: 'strncpy_s' : undeclared identifier
17
- checked program was:
18
- /* begin */
19
- 1: #include <windows.h>
20
- 2: #include <winsock.h>
21
- 3:
22
- 4: /*top*/
23
- 5: int main() { return 0; }
24
- 6: int t() { void ((*volatile p)()); p = (void ((*)()))strncpy_s; return 0; }
25
- /* end */
26
-
27
- --------------------
28
-
Binary file
Binary file