Module: Win32 Private

Defined in:
documented/init.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Namespace for Windows API bindings via Fiddle, providing access to kernel, user, shell, and registry operations. Available only on Windows platforms (mingw/win without darwin).

Defined Under Namespace

Modules: Advapi32, Kernel32, Shell32, User32

Constant Summary collapse

SIZEOF_CHAR =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Size of a C char in bytes, delegated from Fiddle.

Fiddle::SIZEOF_CHAR
SIZEOF_LONG =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Size of a C long in bytes, delegated from Fiddle.

Fiddle::SIZEOF_LONG
SEE_MASK_NOCLOSEPROCESS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows API flag for ShellExecuteEx: do not close the process handle automatically.

0x00000040
MB_OK =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows API message box button flag: OK button only.

0x00000000
MB_OKCANCEL =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows API message box button flag: OK and Cancel buttons.

0x00000001
MB_YESNO =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows API message box button flag: Yes and No buttons.

0x00000004
MB_ICONERROR =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows API message box icon flag: error icon.

0x00000010
MB_ICONQUESTION =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows API message box icon flag: question mark icon.

0x00000020
MB_ICONWARNING =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows API message box icon flag: warning/exclamation icon.

0x00000030
IDIOK =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

1
IDICANCEL =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

2
IDIYES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

6
IDINO =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

7
KEY_ALL_ACCESS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows registry access flag: all access permissions.

0xF003F
KEY_CREATE_SUB_KEY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows registry access flag: permission to create subkeys.

0x0004
KEY_ENUMERATE_SUB_KEYS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows registry access flag: permission to enumerate subkeys.

0x0008
KEY_EXECUTE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows registry access flag: permission to execute/read registry keys.

0x20019
KEY_NOTIFY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows registry access flag: permission to request change notifications.

0x0010
KEY_QUERY_VALUE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows registry access flag: permission to query registry value data.

0x0001
KEY_READ =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows registry access flag: read permissions for registry keys.

0x20019
KEY_SET_VALUE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows registry access flag: permission to set registry value data.

0x0002
KEY_WOW64_32KEY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows registry access flag: access 32-bit registry view on 64-bit Windows.

0x0200
KEY_WOW64_64KEY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows registry access flag: access 64-bit registry view on 64-bit Windows.

0x0100
KEY_WRITE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Windows registry access flag: write permissions for registry keys.

0x20006
TokenElevation =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

20
TOKEN_QUERY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

8
STILL_ACTIVE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

259
SW_SHOWNORMAL =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

1
SW_SHOW =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

5
PROCESS_QUERY_INFORMATION =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

1024
PROCESS_VM_READ =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

16
HKEY_LOCAL_MACHINE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

-2147483646
REG_NONE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

0
REG_SZ =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

1
REG_EXPAND_SZ =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

2
REG_BINARY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

3
REG_DWORD =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

4
REG_DWORD_LITTLE_ENDIAN =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

4
REG_DWORD_BIG_ENDIAN =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

5
6
REG_MULTI_SZ =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

7
REG_QWORD =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

11
REG_QWORD_LITTLE_ENDIAN =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

11

Class Method Summary collapse

Class Method Details

.admin? ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

def Win32.isWin8? r = Win32.GetVersionEx return ((r == 6) and (r >= 2)) end

Returns:

  • (Boolean)


568
569
570
571
572
573
574
575
576
577
# File 'documented/init.rb', line 568

def self.admin?
  if Win32.isXP?
    return true
  else
    r = Win32.OpenProcessToken(:ProcessHandle => Win32.GetCurrentProcess, :DesiredAccess => TOKEN_QUERY)
    token_handle = r[:TokenHandle]
    r = Win32.GetTokenInformation(:TokenInformationClass => TokenElevation, :TokenHandle => token_handle)
    return (r[:TokenIsElevated] != 0)
  end
end

.AdminShellExecute(args) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

Only executes if not already running in an eval/run context (to prevent infinite recursion)

This method returns an undefined value.

Elevates the current Lich process via UAC and executes a shell command with admin privileges.

Parameters:

  • args (Hash) —

    shell execution parameters (see .Win32.ShellExecute)



585
586
587
588
589
590
591
592
593
594
595
# File 'documented/init.rb', line 585

def self.AdminShellExecute(args)
  # open ruby/lich as admin and tell it to open something else
  if not caller.any? { |c| c =~ /eval|run/ }
    r = Win32.GetModuleFileName
    if r[:return] > 0
      if File.exist?(r[:lpFilename])
        Win32.ShellExecuteEx(:lpVerb => 'runas', :lpFile => r[:lpFilename], :lpParameters => "#{File.expand_path($PROGRAM_NAME)} shellexecute #{[Marshal.dump(args)].pack('m').gsub("\n", '')}")
      end
    end
  end
end

.CreateProcess(args) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates a new process on Windows.

Parameters:

  • args (Hash) —

    process creation parameters

Options Hash (args):

  • :lpCommandLine (String) —

    command line string (will be duplicated internally)

  • :bInheritHandles (Boolean, Integer) —

    whether to inherit handles; true/false or 0/1

  • :lpApplicationName (String, nil) —

    application executable path

  • :lpProcessAttributes (String, nil) —

    process security attributes

  • :lpThreadAttributes (String, nil) —

    thread security attributes

  • :dwCreationFlags (Integer) —

    process creation flags

  • :lpEnvironment (String, nil) —

    environment block (Array not yet supported)

  • :lpCurrentDirectory (String, nil) —

    working directory

  • :dwX (Integer) —

    window X position

  • :dwY (Integer) —

    window Y position

  • :dwXSize (Integer) —

    window width

  • :dwYSize (Integer) —

    window height

Returns:

  • (Hash) —

    result hash with keys: :return (Boolean), :hProcess, :hThread, :dwProcessId, :dwThreadId



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
# File 'documented/init.rb', line 181

def self.CreateProcess(args)
  if args[:lpCommandLine]
    lpCommandLine = args[:lpCommandLine].dup
  else
    lpCommandLine = nil
  end
  if args[:bInheritHandles] == false
    bInheritHandles = 0
  elsif args[:bInheritHandles] == true
    bInheritHandles = 1
  else
    bInheritHandles = args[:bInheritHandles].to_i
  end
  if args[:lpEnvironment].is_a?(Array)
    # fixme
  end
  lpStartupInfo = [68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  lpStartupInfo_index = { :lpDesktop => 2, :lpTitle => 3, :dwX => 4, :dwY => 5, :dwXSize => 6, :dwYSize => 7, :dwXCountChars => 8, :dwYCountChars => 9, :dwFillAttribute => 10, :dwFlags => 11, :wShowWindow => 12, :hStdInput => 15, :hStdOutput => 16, :hStdError => 17 }
  for sym in [:lpDesktop, :lpTitle]
    if args[sym]
      args[sym] = "#{args[sym]}\0" unless args[sym][-1, 1] == "\0"
      lpStartupInfo[lpStartupInfo_index[sym]] = Fiddle::Pointer.to_ptr(args[sym]).to_i
    end
  end
  for sym in [:dwX, :dwY, :dwXSize, :dwYSize, :dwXCountChars, :dwYCountChars, :dwFillAttribute, :dwFlags, :wShowWindow, :hStdInput, :hStdOutput, :hStdError]
    if args[sym]
      lpStartupInfo[lpStartupInfo_index[sym]] = args[sym]
    end
  end
  lpStartupInfo = lpStartupInfo.pack('LLLLLLLLLLLLSSLLLL')
  lpProcessInformation = [0, 0, 0, 0,].pack('LLLL')
  r = Kernel32.CreateProcess(args[:lpApplicationName], lpCommandLine, args[:lpProcessAttributes], args[:lpThreadAttributes], bInheritHandles, args[:dwCreationFlags].to_i, args[:lpEnvironment], args[:lpCurrentDirectory], lpStartupInfo, lpProcessInformation)
  lpProcessInformation = lpProcessInformation.unpack('LLLL')
  return :return => (r > 0 ? true : false), :hProcess => lpProcessInformation[0], :hThread => lpProcessInformation[1], :dwProcessId => lpProcessInformation[2], :dwThreadId => lpProcessInformation[3]
end

.GetCurrentProcess ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Win32.CreateProcess(:lpApplicationName => 'Launcher.exe', :lpCommandLine => 'lich2323.sal', :lpCurrentDirectory => 'C:\PROGRA~1\SIMU') def Win32.OpenProcess(args={}) return Kernel32.OpenProcess(args.to_i, args.to_i, args.to_i) end



221
222
223
# File 'documented/init.rb', line 221

def self.GetCurrentProcess
  return Kernel32.GetCurrentProcess
end

.GetExitCodeProcess(args) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Retrieves the exit code of a process.

Parameters:

  • args (Hash) —

    process handle parameters

Options Hash (args):

  • :hProcess (Integer) —

    handle to the process

Returns:

  • (Hash) —

    result hash with keys: :return (Integer), :lpExitCode (Integer)



231
232
233
234
235
# File 'documented/init.rb', line 231

def self.GetExitCodeProcess(args)
  lpExitCode = [0].pack('L')
  r = Kernel32.GetExitCodeProcess(args[:hProcess].to_i, lpExitCode)
  return :return => r, :lpExitCode => lpExitCode.unpack('L')[0]
end

.GetLastError ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Retrieves the last error code from the Windows API.

Returns:

  • (Integer) —

    the error code



160
161
162
# File 'documented/init.rb', line 160

def self.GetLastError
  return Kernel32.GetLastError()
end

.GetModuleFileName(args = {}) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Retrieves the filename of a loaded module.

Parameters:

  • args (Hash) (defaults to: {}) —

    module parameters

Options Hash (args):

  • :hModule (Integer) —

    module handle (defaults to current process if omitted)

  • :nSize (Integer) —

    buffer size in bytes (default: 256)

Returns:

  • (Hash) —

    result hash with keys: :return (Integer), :lpFilename (String without null terminators)



244
245
246
247
248
249
# File 'documented/init.rb', line 244

def self.GetModuleFileName(args = {})
  args[:nSize] ||= 256
  buffer = "\0" * args[:nSize].to_i
  r = Kernel32.GetModuleFileName(args[:hModule].to_i, buffer, args[:nSize].to_i)
  return :return => r, :lpFilename => buffer.gsub("\0", '')
end

.GetTokenInformation(args) ⇒ Hash?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Retrieves information about an access token.

Parameters:

  • args (Hash) —

    token parameters

Options Hash (args):

  • :TokenHandle (Integer) —

    handle to the access token

  • :TokenInformationClass (Integer) —

    information class (e.g., TokenElevation)

Returns:

  • (Hash, nil) —

    result hash with keys: :return (Integer), :TokenIsElevated (Integer); nil if TokenInformationClass is not TokenElevation



307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'documented/init.rb', line 307

def self.GetTokenInformation(args)
  if args[:TokenInformationClass] == TokenElevation
    token_information_length = SIZEOF_LONG
    token_information = [0].pack('L')
  else
    return nil
  end
  return_length = [0].pack('L')
  r = Advapi32.GetTokenInformation(args[:TokenHandle].to_i, args[:TokenInformationClass], token_information, token_information_length, return_length)
  if args[:TokenInformationClass] == TokenElevation
    return :return => r, :TokenIsElevated => token_information.unpack('L')[0]
  end
end

.GetVersionEx ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Retrieves Windows OS version information.

Returns:

  • (Hash) —

    result hash with keys: :return (Integer), :dwOSVersionInfoSize, :dwMajorVersion, :dwMinorVersion, :dwBuildNumber, :dwPlatformId, :szCSDVersion (String), :wServicePackMajor, :wServicePackMinor, :wSuiteMask, :wProductType



255
256
257
258
259
260
# File 'documented/init.rb', line 255

def self.GetVersionEx
  a = [156, 0, 0, 0, 0, ("\0" * 128), 0, 0, 0, 0, 0].pack('LLLLLa128SSSCC')
  r = Kernel32.GetVersionEx(a)
  a = a.unpack('LLLLLa128SSSCC')
  return :return => r, :dwOSVersionInfoSize => a[0], :dwMajorVersion => a[1], :dwMinorVersion => a[2], :dwBuildNumber => a[3], :dwPlatformId => a[4], :szCSDVersion => a[5].strip, :wServicePackMajor => a[6], :wServicePackMinor => a[7], :wSuiteMask => a[8], :wProductType => a[9]
end

.isXP? ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks whether the operating system is Windows XP or earlier.

Returns:

  • (Boolean) —

    true if OS major version is less than 6 (XP and below), false otherwise



560
561
562
# File 'documented/init.rb', line 560

def self.isXP?
  return (Win32.GetVersionEx[:dwMajorVersion] < 6)
end

.MessageBox(args) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Displays a message box dialog on Windows.

Parameters:

  • args (Hash) —

    message box parameters

Options Hash (args):

  • :hWnd (Integer) —

    parent window handle

  • :lpText (String) —

    message text

  • :lpCaption (String) —

    window title (default: "Lich v#LICH_VERSION")

  • :uType (Integer) —

    message box type flags (buttons and icons)

Returns:

  • (Integer) —

    dialog result code



280
281
282
283
# File 'documented/init.rb', line 280

def self.MessageBox(args)
  args[:lpCaption] ||= "Lich v#{LICH_VERSION}"
  return User32.MessageBox(args[:hWnd].to_i, args[:lpText], args[:lpCaption], args[:uType].to_i)
end

.OpenProcessToken(args) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Opens an access token associated with a process.

Parameters:

  • args (Hash) —

    process token parameters

Options Hash (args):

  • :ProcessHandle (Integer) —

    process handle

  • :DesiredAccess (Integer) —

    desired access level (e.g., TOKEN_QUERY)

Returns:

  • (Hash) —

    result hash with keys: :return (Integer), :TokenHandle (Integer)



328
329
330
331
332
# File 'documented/init.rb', line 328

def self.OpenProcessToken(args)
  token_handle = [0].pack('L')
  r = Advapi32.OpenProcessToken(args[:ProcessHandle].to_i, args[:DesiredAccess].to_i, token_handle)
  return :return => r, :TokenHandle => token_handle.unpack('L')[0]
end

.RegCloseKey(args) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Closes a registry key handle.

Parameters:

  • args (Hash) —

    registry key parameters

Options Hash (args):

  • :hKey (Integer) —

    registry key handle

Returns:

  • (Integer) —

    Windows API result code



444
445
446
# File 'documented/init.rb', line 444

def self.RegCloseKey(args)
  return Advapi32.RegCloseKey(args[:hKey])
end

.RegDeleteValue(args) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Deletes a registry value.

Parameters:

  • args (Hash) —

    registry value parameters

Options Hash (args):

  • :hKey (Integer) —

    registry key handle

  • :lpValueName (String) —

    value name (default: nil)

Returns:

  • (Integer) —

    Windows API result code



433
434
435
436
# File 'documented/init.rb', line 433

def self.RegDeleteValue(args)
  args[:lpValueName] ||= 0
  return Advapi32.RegDeleteValue(args[:hKey].to_i, args[:lpValueName])
end

.RegOpenKeyEx(args) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Opens a registry key with extended options.

Parameters:

  • args (Hash) —

    registry key parameters

Options Hash (args):

  • :hKey (Integer) —

    parent registry key handle

  • :lpSubKey (String) —

    subkey path

  • :samDesired (Integer) —

    desired access level

Returns:

  • (Hash) —

    result hash with keys: :return (Integer), :phkResult (Integer, opened key handle)



342
343
344
345
346
# File 'documented/init.rb', line 342

def self.RegOpenKeyEx(args)
  phkResult = [0].pack('L')
  r = Advapi32.RegOpenKeyEx(args[:hKey].to_i, args[:lpSubKey].to_s, 0, args[:samDesired].to_i, phkResult)
  return :return => r, :phkResult => phkResult.unpack('L')[0]
end

.RegQueryValueEx(args) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

REG_SZ, REG_EXPAND_SZ, REG_LINK are returned as String; REG_MULTI_SZ as Array; REG_DWORD as Integer; REG_QWORD as Integer; others are unparsed

Queries a registry value, automatically converting to the appropriate Ruby type.

Parameters:

  • args (Hash) —

    registry value parameters

Options Hash (args):

  • :hKey (Integer) —

    registry key handle

  • :lpValueName (String) —

    value name (default: nil)

Returns:

  • (Hash) —

    result hash with keys: :return (Integer), :lpType (Integer, registry type), :lpcbData (Integer, size), :lpData (String, Integer, Array, or nil depending on type)



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
382
383
384
385
386
387
# File 'documented/init.rb', line 356

def self.RegQueryValueEx(args)
  args[:lpValueName] ||= 0
  lpcbData = [0].pack('L')
  r = Advapi32.RegQueryValueEx(args[:hKey].to_i, args[:lpValueName], 0, 0, 0, lpcbData)
  if r == 0
    lpcbData = lpcbData.unpack('L')[0]
    lpData = String.new.rjust(lpcbData, "\x00")
    lpcbData = [lpcbData].pack('L')
    lpType = [0].pack('L')
    r = Advapi32.RegQueryValueEx(args[:hKey].to_i, args[:lpValueName], 0, lpType, lpData, lpcbData)
    lpType = lpType.unpack('L')[0]
    lpcbData = lpcbData.unpack('L')[0]
    if [REG_EXPAND_SZ, REG_SZ, REG_LINK].include?(lpType)
      lpData.gsub!("\x00", '')
    elsif lpType == REG_MULTI_SZ
      lpData = lpData.gsub("\x00\x00", '').split("\x00")
    elsif lpType == REG_DWORD
      lpData = lpData.unpack('L')[0]
    elsif lpType == REG_QWORD
      lpData = lpData.unpack('Q')[0]
    elsif lpType == REG_BINARY
      # fixme
    elsif lpType == REG_DWORD_BIG_ENDIAN
      # fixme
    else
      # fixme
    end
    return :return => r, :lpType => lpType, :lpcbData => lpcbData, :lpData => lpData
  else
    return :return => r
  end
end

.RegSetValueEx(args) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Sets a registry value, converting from Ruby types to Windows registry format.

Parameters:

  • args (Hash) —

    registry value parameters

Options Hash (args):

  • :hKey (Integer) —

    registry key handle

  • :lpValueName (String) —

    value name (default: nil)

  • :dwType (Integer) —

    registry data type (REG_SZ, REG_DWORD, REG_MULTI_SZ, REG_QWORD, etc.)

  • :lpData (String, Integer, Array) —

    data to store (must match dwType)

Returns:

  • (Integer) —

    Windows API result code; false if dwType is REG_BINARY or REG_DWORD_BIG_ENDIAN (not yet implemented)



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
# File 'documented/init.rb', line 398

def self.RegSetValueEx(args)
  if [REG_EXPAND_SZ, REG_SZ, REG_LINK].include?(args[:dwType]) and (args[:lpData].is_a?(String))
    lpData = args[:lpData].dup
    lpData.concat("\x00")
    cbData = lpData.length
  elsif (args[:dwType] == REG_MULTI_SZ) and (args[:lpData].is_a?(Array))
    lpData = args[:lpData].join("\x00").concat("\x00\x00")
    cbData = lpData.length
  elsif (args[:dwType] == REG_DWORD) and (args[:lpData].is_a?(Integer))
    lpData = [args[:lpData]].pack('L')
    cbData = 4
  elsif (args[:dwType] == REG_QWORD) and (args[:lpData].is_a?(Integer))
    lpData = [args[:lpData]].pack('Q')
    cbData = 8
  elsif args[:dwType] == REG_BINARY
    # fixme
    return false
  elsif args[:dwType] == REG_DWORD_BIG_ENDIAN
    # fixme
    return false
  else
    # fixme
    return false
  end
  args[:lpValueName] ||= 0
  return Advapi32.RegSetValueEx(args[:hKey].to_i, args[:lpValueName], 0, args[:dwType], lpData, cbData)
end

.ShellExecute(args) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Executes a file with basic shell options.

Parameters:

  • args (Hash) —

    shell execution parameters

Options Hash (args):

  • :hwnd (Integer) —

    parent window handle

  • :lpOperation (String) —

    verb ('open', 'edit', etc.; default: nil)

  • :lpFile (String) —

    file or URL to execute

  • :lpParameters (String) —

    command-line arguments (default: nil)

  • :lpDirectory (String) —

    working directory (default: nil)

  • :nShowCmd (Integer) —

    window display flag (default: 1)

Returns:

  • (Integer) —

    Windows API result code



506
507
508
509
510
511
512
# File 'documented/init.rb', line 506

def self.ShellExecute(args)
  args[:lpOperation] ||= 0
  args[:lpParameters] ||= 0
  args[:lpDirectory] ||= 0
  args[:nShowCmd] ||= 1
  return Shell32.ShellExecute(args[:hwnd].to_i, args[:lpOperation], args[:lpFile], args[:lpParameters], args[:lpDirectory], args[:nShowCmd])
end

.ShellExecuteEx(args) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Executes a file with extended shell options (includes UAC elevation support).

Parameters:

  • args (Hash) —

    shell execution parameters

Options Hash (args):

  • :lpVerb (String) —

    verb to perform, e.g. 'open', 'edit', 'runas' (for elevation)

  • :lpFile (String) —

    file or URL to execute

  • :lpParameters (String) —

    command-line arguments

  • :lpDirectory (String) —

    working directory

  • :nShow (Integer) —

    window display flag (e.g., SW_SHOW, SW_SHOWNORMAL)

  • :fMask (Integer) —

    operation flags

  • :hwnd (Integer) —

    parent window handle

  • :hkeyClass (Integer) —

    registry key for file class

  • :dwHotKey (Integer) —

    hot key

  • :hIcon (Integer) —

    icon handle

  • :hMonitor (Integer) —

    monitor handle

Returns:

  • (Hash) —

    result hash with keys: :return (Integer), :hProcess (Integer), :hInstApp (Integer)



474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
# File 'documented/init.rb', line 474

def self.ShellExecuteEx(args)
  #         struct = [ (SIZEOF_LONG * 15), 0, 0, 0, 0, 0, 0, SW_SHOWNORMAL, 0, 0, 0, 0, 0, 0, 0 ]
  struct = [(SIZEOF_LONG * 15), 0, 0, 0, 0, 0, 0, SW_SHOW, 0, 0, 0, 0, 0, 0, 0]
  struct_index = { :cbSize => 0, :fMask => 1, :hwnd => 2, :lpVerb => 3, :lpFile => 4, :lpParameters => 5, :lpDirectory => 6, :nShow => 7, :hInstApp => 8, :lpIDList => 9, :lpClass => 10, :hkeyClass => 11, :dwHotKey => 12, :hIcon => 13, :hMonitor => 13, :hProcess => 14 }
  for sym in [:lpVerb, :lpFile, :lpParameters, :lpDirectory, :lpIDList, :lpClass]
    if args[sym]
      args[sym] = "#{args[sym]}\0" unless args[sym][-1, 1] == "\0"
      struct[struct_index[sym]] = Fiddle::Pointer.to_ptr(args[sym]).to_i
    end
  end
  for sym in [:fMask, :hwnd, :nShow, :hkeyClass, :dwHotKey, :hIcon, :hMonitor, :hProcess]
    if args[sym]
      struct[struct_index[sym]] = args[sym]
    end
  end
  struct = struct.pack('LLLLLLLLLLLLLLL')
  r = Shell32.ShellExecuteEx(struct)
  struct = struct.unpack('LLLLLLLLLLLLLLL')
  return :return => r, :hProcess => struct[struct_index[:hProcess]], :hInstApp => struct[struct_index[:hInstApp]]
end