win 0.3.11 → 0.3.16
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/HISTORY +20 -0
- data/VERSION +1 -1
- data/lib/win/gui/dialog.rb +30 -30
- data/lib/win/gui/input.rb +0 -1
- data/lib/win/gui/message.rb +25 -2
- data/lib/win/library.rb +114 -70
- data/lib/win/system/info.rb +163 -0
- data/lib/win/system/version.rb +571 -0
- data/spec/spec_helper.rb +15 -3
- data/spec/win/error_spec.rb +2 -2
- data/spec/win/gui/message_spec.rb +23 -7
- data/spec/win/library_spec.rb +181 -155
- data/spec/win/system/info_spec.rb +47 -0
- data/spec/win/system/version_spec.rb +169 -0
- metadata +9 -3
data/HISTORY
CHANGED
@@ -38,3 +38,23 @@
|
|
38
38
|
== 0.3.11 / 2010-06-03
|
39
39
|
|
40
40
|
* GetDlgCtrlID function added
|
41
|
+
|
42
|
+
== 0.3.12 / 2010-06-07
|
43
|
+
|
44
|
+
* Library::function improved: treatment of snake_case API fubctions changed
|
45
|
+
|
46
|
+
== 0.3.13 / 2010-06-09
|
47
|
+
|
48
|
+
* Win::System::Info module started
|
49
|
+
|
50
|
+
== 0.3.14 / 2010-06-10
|
51
|
+
|
52
|
+
* System::Version and System::Info functions added
|
53
|
+
|
54
|
+
== 0.3.15 / 2010-06-10
|
55
|
+
|
56
|
+
* System::Version specs added
|
57
|
+
|
58
|
+
== 0.3.16 / 2010-06-11
|
59
|
+
|
60
|
+
* System::Version module completed
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.16
|
data/lib/win/gui/dialog.rb
CHANGED
@@ -217,6 +217,36 @@ module Win
|
|
217
217
|
#
|
218
218
|
function :GetDlgItem, [:ulong, :int], :ulong, zeronil: true
|
219
219
|
|
220
|
+
##
|
221
|
+
# The GetDlgCtrlID function retrieves the identifier of the specified control. In other words,
|
222
|
+
# you give it a handle (say, for a button window inside a dialog), and it returns control ID
|
223
|
+
# that this window is associated with (say IDOK - meaning this window is in fact "OK" button.
|
224
|
+
#
|
225
|
+
# [*Syntax*] int GetDlgCtrlID( HWND hwndCtl );
|
226
|
+
#
|
227
|
+
# hwndCtl:: [in] Handle to the control.
|
228
|
+
#
|
229
|
+
# *Returns*:: If the function succeeds, the return value is the identifier of the control.
|
230
|
+
# If the function fails, the return value is zero. An invalid value for the hwndCtl parameter, for
|
231
|
+
# example, will cause the function to fail. To get extended error information, call GetLastError.
|
232
|
+
# ---
|
233
|
+
# *Remarks*:
|
234
|
+
# GetDlgCtrlID accepts child window handles as well as handles of controls in dialog boxes. An
|
235
|
+
# application sets the identifier for a child window when it creates the window by assigning the
|
236
|
+
# identifier value to the hmenu parameter when calling the CreateWindow or CreateWindowEx function.
|
237
|
+
# Although GetDlgCtrlID may return a value if hwndCtl is a handle to a top-level window, top-level
|
238
|
+
# windows cannot have identifiers and such a return value is never valid.
|
239
|
+
# ---
|
240
|
+
# *See* *Also*
|
241
|
+
# Dialog Boxes Overview, CreateWindow, CreateWindowEx, GetDlgItem
|
242
|
+
# ---
|
243
|
+
# <b>Enhanced (snake_case) API: returns nil instead of zero if function fails</b>
|
244
|
+
#
|
245
|
+
# :call-seq:
|
246
|
+
# control_id = get_dlg_ctrl_id(control_handle)
|
247
|
+
#
|
248
|
+
function :GetDlgCtrlID, [:HWND], :int, zeronil: true
|
249
|
+
|
220
250
|
##
|
221
251
|
# MessageBox Function
|
222
252
|
# --------------------------------------------------------------------------------
|
@@ -300,36 +330,6 @@ module Win
|
|
300
330
|
caption_pointer = FFI::MemoryPointer.from_string(caption)
|
301
331
|
api.call handle, text_pointer, caption_pointer, type }
|
302
332
|
|
303
|
-
##
|
304
|
-
# The GetDlgCtrlID function retrieves the identifier of the specified control. In other words,
|
305
|
-
# you give it a handle (say, for a button window inside a dialog), and it returns control ID
|
306
|
-
# that this window is associated with (say IDOK - meaning this window is in fact "OK" button.
|
307
|
-
#
|
308
|
-
# [*Syntax*] int GetDlgCtrlID( HWND hwndCtl );
|
309
|
-
#
|
310
|
-
# hwndCtl:: [in] Handle to the control.
|
311
|
-
#
|
312
|
-
# *Returns*:: If the function succeeds, the return value is the identifier of the control.
|
313
|
-
# If the function fails, the return value is zero. An invalid value for the hwndCtl parameter, for
|
314
|
-
# example, will cause the function to fail. To get extended error information, call GetLastError.
|
315
|
-
# ---
|
316
|
-
# *Remarks*:
|
317
|
-
# GetDlgCtrlID accepts child window handles as well as handles of controls in dialog boxes. An
|
318
|
-
# application sets the identifier for a child window when it creates the window by assigning the
|
319
|
-
# identifier value to the hmenu parameter when calling the CreateWindow or CreateWindowEx function.
|
320
|
-
# Although GetDlgCtrlID may return a value if hwndCtl is a handle to a top-level window, top-level
|
321
|
-
# windows cannot have identifiers and such a return value is never valid.
|
322
|
-
# ---
|
323
|
-
# *See* *Also*
|
324
|
-
# Dialog Boxes Overview, CreateWindow, CreateWindowEx, GetDlgItem
|
325
|
-
# ---
|
326
|
-
# <b>Enhanced (snake_case) API: returns nil instead of zero if function fails</b>
|
327
|
-
#
|
328
|
-
# :call-seq:
|
329
|
-
# control_id = get_dlg_ctrl_id(control_handle)
|
330
|
-
#
|
331
|
-
function :GetDlgCtrlID, [:HWND], :int, zeronil: true
|
332
|
-
|
333
333
|
# Untested:
|
334
334
|
|
335
335
|
##
|
data/lib/win/gui/input.rb
CHANGED
@@ -134,7 +134,6 @@ module Win
|
|
134
134
|
# Indicates NO data if dwFlags are NOT any of MOUSEEVENTF_WHEEL, MOUSEEVENTF_XDOWN, or MOUSEEVENTF_XUP
|
135
135
|
INPUT_MOUSE = 0
|
136
136
|
|
137
|
-
|
138
137
|
##
|
139
138
|
# The keybd_event function synthesizes a keystroke. The system can use such a synthesized keystroke to generate
|
140
139
|
# a WM_KEYUP or WM_KEYDOWN message. The keyboard driver's interrupt handler calls the keybd_event function.
|
data/lib/win/gui/message.rb
CHANGED
@@ -439,7 +439,7 @@ module Win
|
|
439
439
|
# with the dwThreadId parameter set to the identifier of the current thread.
|
440
440
|
# Msg:: <in> Specifies the message to be posted.
|
441
441
|
# wParam:: <in> Specifies additional message-specific information.
|
442
|
-
# lParam:: <in> Specifies additional message-specific information.
|
442
|
+
# lParam:: <in> Specifies additional message-specific information (can be either :pointer or :long).
|
443
443
|
#
|
444
444
|
# *Returns*:: Nonzero if the function succeeds, zero if it fails. For extended error info, call GetLastError.
|
445
445
|
# ---
|
@@ -456,11 +456,34 @@ module Win
|
|
456
456
|
# the operation will fail. The functions will return before the receiving thread has had a chance to
|
457
457
|
# process the message and the sender will free the memory before it is used. Use the PostQuitMessage
|
458
458
|
# instead of PostMessage to post WM_QUIT message.
|
459
|
+
# ---
|
460
|
+
# <b>Enhanced (snake_case) API: accepts either long or pointer lParam</b>
|
459
461
|
#
|
460
462
|
#:call-seq:
|
461
463
|
# success = post_message(handle, msg, w_param, l_param)
|
462
464
|
#
|
463
|
-
function :PostMessage, [:ulong, :uint, :uint, :pointer], :int,
|
465
|
+
function :PostMessage, [:ulong, :uint, :uint, :pointer], :int,
|
466
|
+
boolean: true, camel_name: :PostMessagePointer, snake_name: :post_message_pointer
|
467
|
+
function :PostMessage, [:ulong, :uint, :uint, :long], :int,
|
468
|
+
boolean: true, camel_name: :PostMessageLong, snake_name: :post_message_long
|
469
|
+
|
470
|
+
def PostMessage(handle, msg, w_param, l_param)
|
471
|
+
# Routes call depending on lParam type (:pointer or :long)
|
472
|
+
case l_param
|
473
|
+
when Fixnum
|
474
|
+
PostMessageLong(handle, msg, w_param, l_param)
|
475
|
+
else
|
476
|
+
PostMessagePointer(handle, msg, w_param, l_param)
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
def post_message(handle, msg, w_param, l_param, &block)
|
481
|
+
if block
|
482
|
+
block[PostMessage(handle, msg, w_param, l_param)]
|
483
|
+
else
|
484
|
+
PostMessage(handle, msg, w_param, l_param) != 0
|
485
|
+
end
|
486
|
+
end
|
464
487
|
|
465
488
|
##
|
466
489
|
# The SendMessage function sends the specified message to a window or windows. It calls the window procedure for
|
data/lib/win/library.rb
CHANGED
@@ -225,8 +225,9 @@ module Win
|
|
225
225
|
SHORT: :short, # A 16-bit integer. The range is –32768 through 32767 decimal.
|
226
226
|
SIZE_T: :ulong, # The maximum number of bytes to which a pointer can point. Use for a count that must span the full range of a pointer.
|
227
227
|
SSIZE_T: :long, # Signed SIZE_T.
|
228
|
-
TBYTE: :
|
229
|
-
|
228
|
+
TBYTE: :char, # A WCHAR if UNICODE is defined, a CHAR otherwise.TCHAR:
|
229
|
+
# http://msdn.microsoft.com/en-us/library/c426s321%28VS.80%29.aspx
|
230
|
+
TCHAR: :char, # A WCHAR if UNICODE is defined, a CHAR otherwise.TCHAR:
|
230
231
|
UCHAR: :uchar, # Unsigned CHAR (8 bit)
|
231
232
|
UHALF_PTR: :uint, # Unsigned HALF_PTR. Use within a structure that contains a pointer and two small fields.
|
232
233
|
UINT: :uint, # Unsigned INT. The range is 0 through 4294967295 decimal.
|
@@ -274,70 +275,22 @@ module Win
|
|
274
275
|
# - do other stuff that you think is appropriate to make Windows API function behavior more Ruby-like...
|
275
276
|
# ---
|
276
277
|
# Accepts following options:
|
277
|
-
# :dll:: Use this dll instead of default 'user32'
|
278
|
-
# :
|
278
|
+
# :dll:: Use this dll instead of default ['user32', 'kernel32']
|
279
|
+
# :snake_name:: Overrides default snake_case method name being defined
|
280
|
+
# :camel_name:: Overrides default CamelCase name for function being attached
|
281
|
+
# :camel_only:: If true, no snake_case method is defined
|
279
282
|
# :alias(es):: Provides additional alias(es) for defined method
|
280
283
|
# :boolean:: Forces method to return true/false instead of nonzero/zero
|
281
284
|
# :zeronil:: Forces method to return nil if function result is zero
|
282
285
|
#
|
283
286
|
def function(name, params, returns, options={}, &def_block)
|
284
|
-
snake_name, effective_names, aliases = generate_names(name, options)
|
285
|
-
params, returns = generate_signature(params, returns)
|
286
|
-
libs = ffi_libraries.map(&:name)
|
287
|
-
boolean = options[:boolean]
|
288
|
-
zeronil = options[:zeronil]
|
289
|
-
|
290
|
-
effective_name = effective_names.inject(nil) do |func, effective_name|
|
291
|
-
func || begin
|
292
|
-
# tries to attach basic CamelCase method via FFI
|
293
|
-
attach_function(name, effective_name, params.dup, returns)
|
294
|
-
effective_name
|
295
|
-
rescue FFI::NotFoundError
|
296
|
-
nil
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
raise Win::Errors::NotFoundError.new(name, libs) unless effective_name
|
301
|
-
|
302
|
-
# Create API object that holds information about function names, params, etc
|
303
|
-
api = API.new(namespace, name, effective_name, params, returns, libs)
|
304
|
-
|
305
|
-
# Only define enhanced API if snake_name is different from original name (e.g. keybd_event),
|
306
|
-
# If names are the same, this function is already "attached", not possible to enhance its API
|
307
|
-
unless snake_name.to_s == name.to_s
|
308
|
-
method_body = if def_block
|
309
|
-
if zeronil
|
310
|
-
->(*args, &block){ (res = def_block.(api, *args, &block)) != 0 ? res : nil }
|
311
|
-
elsif boolean
|
312
|
-
->(*args, &block){ def_block.(api, *args, &block) != 0 }
|
313
|
-
else
|
314
|
-
->(*args, &block){ def_block.(api, *args, &block) }
|
315
|
-
end
|
316
|
-
else
|
317
|
-
if zeronil
|
318
|
-
->(*args, &block){ (res = block ? block[api.call(*args)] : api.call(*args)) != 0 ? res : nil }
|
319
|
-
elsif boolean
|
320
|
-
->(*args, &block){ block ? block[api.call(*args)] : api.call(*args) != 0 }
|
321
|
-
else
|
322
|
-
->(*args, &block){ block ? block[api.call(*args)] : api.call(*args) }
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
326
|
-
define_method snake_name, &method_body # define snake_case instance method
|
287
|
+
snake_name, camel_name, effective_names, aliases = generate_names(name, options)
|
327
288
|
|
328
|
-
|
289
|
+
api = define_api(name, camel_name, effective_names, params, returns, options)
|
329
290
|
|
330
|
-
|
331
|
-
self;
|
332
|
-
end # Extracting eigenclass
|
291
|
+
define_snake_method(snake_name, aliases, api, options, &def_block) unless options[:camel_only]
|
333
292
|
|
334
|
-
|
335
|
-
define_method snake_name, &method_body # define snake_case class method
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
aliases.each {|ali| alias_method ali, snake_name } # define aliases
|
340
|
-
api #return api object from function declaration
|
293
|
+
api # Return api object from function declaration # TODO: Do we even NEED api object?
|
341
294
|
end
|
342
295
|
|
343
296
|
# Try to define platform-specific function, rescue error, return message
|
@@ -350,15 +303,82 @@ module Win
|
|
350
303
|
end
|
351
304
|
end
|
352
305
|
|
306
|
+
# Defines CamelCase method calling Win32 API function, and associated API object
|
307
|
+
#
|
308
|
+
def define_api(name, camel_name, effective_names, params, returns, options)
|
309
|
+
params, returns = generate_signature(params.dup, returns)
|
310
|
+
|
311
|
+
ffi_lib *(ffi_libraries.map(&:name) << options[:dll]) if options[:dll]
|
312
|
+
libs = ffi_libraries.map(&:name)
|
313
|
+
|
314
|
+
effective_name = if options[:alternative]
|
315
|
+
|
316
|
+
alt_params, alt_returns, condition = generate_signature(*options.dup[:alternative])
|
317
|
+
api = function name, params, returns,
|
318
|
+
options.dup.merge( camel_only: true, camel_name: "#{camel_name}Original")
|
319
|
+
alt_api = function name, alt_params, alt_returns,
|
320
|
+
options.dup.merge( camel_only: true, camel_name: "#{camel_name}Alternative")
|
321
|
+
define_method camel_name do |*args|
|
322
|
+
(condition[*args] ? alt_api : api).call(*args)
|
323
|
+
end
|
324
|
+
api.effective_name
|
325
|
+
else
|
326
|
+
effective_names.inject(nil) do |func, effective_name|
|
327
|
+
func || begin
|
328
|
+
# Try to attach basic CamelCase method via FFI
|
329
|
+
attach_function(camel_name, effective_name, params.dup, returns)
|
330
|
+
effective_name
|
331
|
+
rescue FFI::NotFoundError
|
332
|
+
nil
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
raise Win::Errors::NotFoundError.new(name, libs) unless effective_name
|
338
|
+
|
339
|
+
# Create API object that holds information about defined and effective function names, params, etc.
|
340
|
+
# This object is further used by enhanced snake_case method to reflect on underlying API and
|
341
|
+
# intelligently call it.
|
342
|
+
API.new(namespace, camel_name, effective_name, params, returns, libs)
|
343
|
+
end
|
344
|
+
|
345
|
+
# Defines enhanced snake_case method and (optionally) aliases to it.
|
346
|
+
# Both instance method and module-level method with the same name is defined
|
347
|
+
#
|
348
|
+
def define_snake_method(snake_name, aliases, api, options, &def_block)
|
349
|
+
# Generate body for snake_case method
|
350
|
+
method_body = generate_snake_method_body(api, options, &def_block)
|
351
|
+
|
352
|
+
# Define snake_case instance method
|
353
|
+
define_method snake_name, &method_body
|
354
|
+
|
355
|
+
# We need to define module(class) level method, but something went wrong with module_function :(
|
356
|
+
# module_function snake_name # TODO: Doesn't work as a perfect replacement for eigen_class stuff. :( Why?
|
357
|
+
|
358
|
+
# OK, instead of module_method we're going to directly modify eigenclass
|
359
|
+
eigen_class = class << self;
|
360
|
+
self;
|
361
|
+
end
|
362
|
+
|
363
|
+
# Define snake_case class method inside eigenclass, that should do it
|
364
|
+
eigen_class.class_eval do
|
365
|
+
define_method snake_name, &method_body
|
366
|
+
end
|
367
|
+
|
368
|
+
# Define (instance method!) aliases, if any
|
369
|
+
aliases.each {|ali| alias_method ali, snake_name }
|
370
|
+
end
|
371
|
+
|
353
372
|
# Generates possible effective names for function in Win32 dll (name+A/W),
|
354
|
-
#
|
373
|
+
# camel_case, snake_case and aliases method names
|
355
374
|
#
|
356
375
|
def generate_names(name, options={})
|
357
376
|
name = name.to_s
|
358
377
|
effective_names = [name]
|
359
378
|
effective_names += ["#{name}A", "#{name}W"] unless name =~ /[WA]$/
|
360
379
|
aliases = ([options[:alias]] + [options[:aliases]]).flatten.compact
|
361
|
-
snake_name = options[:
|
380
|
+
snake_name = options[:snake_name] || name.snake_case
|
381
|
+
camel_name = options[:camel_name] || name.camel_case
|
362
382
|
case snake_name
|
363
383
|
when /^is_/
|
364
384
|
aliases << snake_name.sub(/^is_/, '') + '?'
|
@@ -367,17 +387,40 @@ module Win
|
|
367
387
|
when /^get_/
|
368
388
|
aliases << snake_name.sub(/^get_/, '')
|
369
389
|
end
|
370
|
-
[snake_name, effective_names, aliases]
|
390
|
+
[snake_name, camel_name, effective_names, aliases]
|
371
391
|
end
|
372
392
|
|
373
393
|
##
|
374
394
|
# Generates params and returns (signature) containing only FFI-compliant types
|
375
395
|
#
|
376
|
-
def generate_signature(params, returns)
|
396
|
+
def generate_signature(params, returns, condition=nil)
|
377
397
|
params = params.split(//) if params.respond_to?(:split) # Convert params string into array
|
378
398
|
params.map! {|param| TYPES[param.to_sym] || param} # Convert chars into FFI type symbols
|
379
399
|
returns = TYPES[returns.to_sym] || returns # Convert chars into FFI type symbols
|
380
|
-
[params, returns]
|
400
|
+
[params, returns, condition]
|
401
|
+
end
|
402
|
+
|
403
|
+
# Generates body for snake_case method according to directives contained in options
|
404
|
+
# options (:boolean, :zeronil) currently supported
|
405
|
+
#
|
406
|
+
def generate_snake_method_body(api, options, &def_block)
|
407
|
+
if def_block
|
408
|
+
if options[:zeronil]
|
409
|
+
->(*args, &block){ (res = def_block.(api, *args, &block)) != 0 ? res : nil }
|
410
|
+
elsif options[:boolean]
|
411
|
+
->(*args, &block){ def_block.(api, *args, &block) != 0 }
|
412
|
+
else
|
413
|
+
->(*args, &block){ def_block.(api, *args, &block) }
|
414
|
+
end
|
415
|
+
else
|
416
|
+
if options[:zeronil]
|
417
|
+
->(*args, &block){ (res = block ? block[api.call(*args)] : api.call(*args)) != 0 ? res : nil }
|
418
|
+
elsif options[:boolean]
|
419
|
+
->(*args, &block){ block ? block[api.call(*args)] : api.call(*args) != 0 }
|
420
|
+
else
|
421
|
+
->(*args, &block){ block ? block[api.call(*args)] : api.call(*args) }
|
422
|
+
end
|
423
|
+
end
|
381
424
|
end
|
382
425
|
|
383
426
|
##
|
@@ -424,12 +467,13 @@ module Win
|
|
424
467
|
class API
|
425
468
|
|
426
469
|
# The name of the DLL(s) that export this API function
|
427
|
-
attr_reader :
|
470
|
+
attr_reader :dll
|
471
|
+
alias_method :dll_name, :dll
|
428
472
|
|
429
473
|
# Ruby namespace (module) where this API function is attached
|
430
474
|
attr_reader :namespace
|
431
475
|
|
432
|
-
# The name of the function passed to the constructor
|
476
|
+
# The name of the (CamelCase) function passed to the constructor
|
433
477
|
attr_reader :function_name
|
434
478
|
|
435
479
|
# The name of the actual Windows API function. For example, if you passed 'GetUserName' to the
|
@@ -442,18 +486,18 @@ module Win
|
|
442
486
|
# The return type (:void for no return value)
|
443
487
|
attr_reader :return_type
|
444
488
|
|
445
|
-
def initialize( namespace, function_name, effective_function_name, prototype, return_type,
|
489
|
+
def initialize( namespace, function_name, effective_function_name, prototype, return_type, dll )
|
446
490
|
@namespace = namespace
|
447
|
-
@function_name = function_name
|
448
|
-
@effective_function_name = effective_function_name
|
491
|
+
@function_name = function_name.to_sym
|
492
|
+
@effective_function_name = effective_function_name.to_sym
|
449
493
|
@prototype = prototype
|
450
494
|
@return_type = return_type
|
451
|
-
@
|
495
|
+
@dll = dll
|
452
496
|
end
|
453
497
|
|
454
498
|
# Calls underlying CamelCase Windows API function with supplied args
|
455
499
|
def call( *args )
|
456
|
-
@namespace.send(@function_name
|
500
|
+
@namespace.send(@function_name, *args)
|
457
501
|
end
|
458
502
|
|
459
503
|
# alias_method :[], :call
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'win/library'
|
2
|
+
|
3
|
+
module Win
|
4
|
+
module System
|
5
|
+
|
6
|
+
# Contains constants and Win32 API functions related to dialog manipulation.
|
7
|
+
# Windows dialog basics can be found here:
|
8
|
+
# http://msdn.microsoft.com/en-us/library/ms644996#init_box
|
9
|
+
module Info
|
10
|
+
extend Win::Library
|
11
|
+
|
12
|
+
# Enum COMPUTER_NAME_FORMAT (for GetComputerNameEx)
|
13
|
+
|
14
|
+
ComputerNameNetBIOS = 0
|
15
|
+
ComputerNameDnsHostname = 1
|
16
|
+
ComputerNameDnsDomain = 2
|
17
|
+
ComputerNameDnsFullyQualified = 3
|
18
|
+
ComputerNamePhysicalNetBIOS = 4
|
19
|
+
ComputerNamePhysicalDnsHostname = 5
|
20
|
+
ComputerNamePhysicalDnsDomain = 6
|
21
|
+
ComputerNamePhysicalDnsFullyQualified = 7
|
22
|
+
ComputerNameMax = 8
|
23
|
+
|
24
|
+
class << self
|
25
|
+
# Helper method that creates def_block returning (possibly encoded) string as a result of
|
26
|
+
# api function call or nil if api call was not successful. TODO: put this into some kind of helper?
|
27
|
+
#
|
28
|
+
def return_sized_string( encode = nil ) #:nodoc:
|
29
|
+
lambda do |api, *args|
|
30
|
+
namespace.enforce_count( args, api.prototype, -2)
|
31
|
+
buffer = FFI::MemoryPointer.new :char, 1024
|
32
|
+
size = FFI::MemoryPointer.new(:long).write_long(buffer.size)
|
33
|
+
args += [buffer, size]
|
34
|
+
success = api.call(*args)
|
35
|
+
return nil unless success
|
36
|
+
num_chars = size.read_long
|
37
|
+
if encode
|
38
|
+
string = buffer.get_bytes(0, num_chars*2)
|
39
|
+
string = string.force_encoding('utf-16LE').encode(encode)
|
40
|
+
else
|
41
|
+
string = buffer.get_bytes(0, num_chars)
|
42
|
+
end
|
43
|
+
string.rstrip
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private :return_sized_string
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# GetComputerName Function.
|
52
|
+
# Retrieves the NetBIOS name of the local computer. This name is established at system startup, when the
|
53
|
+
# system reads it from the registry.
|
54
|
+
# GetComputerName retrieves only the NetBIOS name of the local computer. To retrieve the DNS host name,
|
55
|
+
# DNS domain name, or the fully qualified DNS name, call the GetComputerNameEx function. Additional
|
56
|
+
# information is provided by the IADsADSystemInfo interface.
|
57
|
+
# The behavior of this function can be affected if the local computer is a node in a cluster. For more
|
58
|
+
# information, see ResUtilGetEnvironmentWithNetName and UseNetworkName.
|
59
|
+
#
|
60
|
+
# [*Syntax*] BOOL GetComputerName( LPTSTR lpBuffer, LPDWORD lpnSize );
|
61
|
+
#
|
62
|
+
# lpBuffer:: A pointer to a buffer that receives the computer name or the cluster virtual server name. The buffer
|
63
|
+
# size should be large enough to contain MAX_COMPUTERNAME_LENGTH + 1 characters.
|
64
|
+
# lpnSize:: On input, specifies the size of the buffer, in TCHARs. On output, the number of TCHARs copied to the
|
65
|
+
# destination buffer, not including the terminating null character.
|
66
|
+
# If the buffer is too small, the function fails and GetLastError returns ERROR_BUFFER_OVERFLOW. The
|
67
|
+
# lpnSize parameter specifies the size of the buffer required, not including the terminating null char.
|
68
|
+
#
|
69
|
+
# *Returns*:: If the function succeeds, the return value is a nonzero value.
|
70
|
+
# If the function fails, the return value is zero. To get extended error info, call GetLastError.
|
71
|
+
# ---
|
72
|
+
# *Remarks*:
|
73
|
+
# The GetComputerName function retrieves the NetBIOS name established at system startup. Name changes
|
74
|
+
# made by the SetComputerName or SetComputerNameEx functions do not take effect until the user restarts
|
75
|
+
# the computer.
|
76
|
+
# If the caller is running under a client session, this function returns the server name. To retrieve
|
77
|
+
# the client name, use the WTSQuerySessionInformation function.
|
78
|
+
# DLL Requires Kernel32.dll.
|
79
|
+
# Unicode Implemented as GetComputerNameW (Unicode) and GetComputerNameA (ANSI).
|
80
|
+
# ---
|
81
|
+
# *See* *Also*
|
82
|
+
# Computer Names
|
83
|
+
# GetComputerNameEx
|
84
|
+
# SetComputerName
|
85
|
+
# SetComputerNameEx
|
86
|
+
# System Information Functions
|
87
|
+
#
|
88
|
+
# ---
|
89
|
+
# <b>Enhanced (snake_case) API: no arguments needed</b>
|
90
|
+
#
|
91
|
+
# :call-seq:
|
92
|
+
# name = [get_]computer_name()
|
93
|
+
#
|
94
|
+
function :GetComputerName, [:pointer, :pointer], :int8, &return_sized_string
|
95
|
+
|
96
|
+
##
|
97
|
+
# GetUserName Function.
|
98
|
+
# Retrieves the name of the user associated with the current thread.
|
99
|
+
# Use the GetUserNameEx function to retrieve the user name in a specified format. Additional information
|
100
|
+
# is provided by the IADsADSystemInfo interface.
|
101
|
+
#
|
102
|
+
# [*Syntax*] BOOL WINAPI GetUserName( LPTSTR lpBuffer, LPDWORD lpnSize );
|
103
|
+
#
|
104
|
+
# lpBuffer:: A pointer to the buffer to receive the user's logon name. If this buffer is not large enough to
|
105
|
+
# contain the entire user name, the function fails. A buffer size of (UNLEN + 1) characters will hold
|
106
|
+
# the maximum length user name including the terminating null character. UNLEN is defined in Lmcons.h.
|
107
|
+
# lpnSize:: On input, this variable specifies the size of the lpBuffer buffer, in TCHARs. On output, the variable
|
108
|
+
# receives the number of TCHARs copied to the buffer, including the terminating null character.
|
109
|
+
# If lpBuffer is too small, the function fails and GetLastError returns ERROR_INSUFFICIENT_BUFFER. This
|
110
|
+
# parameter receives the required buffer size, including the terminating null character.
|
111
|
+
# If it is greater than 32767, function fails and GetLastError returns ERROR_INSUFFICIENT_BUFFER.
|
112
|
+
#
|
113
|
+
# *Returns*:: If the function succeeds, the return value is a nonzero value, and the variable pointed to
|
114
|
+
# by lpnSize contains the number of TCHARs copied to the buffer specified by lpBuffer,
|
115
|
+
# including the terminating null character. If the function fails, the return value is zero.
|
116
|
+
# To get extended error information, call GetLastError.
|
117
|
+
# ---
|
118
|
+
# *Remarks*:
|
119
|
+
# If the current thread is impersonating another client, the GetUserName function returns the user name
|
120
|
+
# of the client that the thread is impersonating.
|
121
|
+
# Example Code
|
122
|
+
# For an example, see Getting System Information.
|
123
|
+
# Requirements
|
124
|
+
# Client Requires Windows Vista, Windows XP, or Windows 2000 Professional.
|
125
|
+
# Server Requires Windows Server 2008, Windows Server 2003, or Windows 2000 Server.
|
126
|
+
# Header Declared in Winbase.h; include Windows.h.
|
127
|
+
# Library Use Advapi32.lib.
|
128
|
+
# DLL Requires Advapi32.dll.
|
129
|
+
# Unicode Implemented as GetUserNameW (Unicode) and GetUserNameA (ANSI).
|
130
|
+
# ---
|
131
|
+
# *See* *Also*:
|
132
|
+
# GetUserNameEx
|
133
|
+
# LookupAccountName
|
134
|
+
# System Information Functions
|
135
|
+
#
|
136
|
+
# ---
|
137
|
+
# <b>Enhanced (snake_case) API: no arguments needed</b>
|
138
|
+
#
|
139
|
+
# :call-seq:
|
140
|
+
# username = [get_]user_name()
|
141
|
+
#
|
142
|
+
function :GetUserName, [:pointer, :pointer], :int8, :dll=> 'advapi32', &return_sized_string
|
143
|
+
|
144
|
+
# Untested
|
145
|
+
|
146
|
+
##
|
147
|
+
function :GetComputerNameEx, 'PPP', :int8, boolean: true
|
148
|
+
##
|
149
|
+
function :GetUserNameEx, 'LPP', :int8, boolean: true, dll: 'secur32'
|
150
|
+
##
|
151
|
+
function :ExpandEnvironmentStrings, 'PPL', :long
|
152
|
+
##
|
153
|
+
function :GetSystemInfo, 'P', :void
|
154
|
+
##
|
155
|
+
function :GetWindowsDirectory, 'PI', :int
|
156
|
+
##
|
157
|
+
# XP or later
|
158
|
+
try_function :GetSystemWow64Directory, 'PI', :int
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|