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- REG_LINK =
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- 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
- .admin? ⇒ Boolean private
-
.AdminShellExecute(args) ⇒ void
private
Elevates the current Lich process via UAC and executes a shell command with admin privileges.
-
.CreateProcess(args) ⇒ Hash
private
Creates a new process on Windows.
- .GetCurrentProcess ⇒ Object private
-
.GetExitCodeProcess(args) ⇒ Hash
private
Retrieves the exit code of a process.
-
.GetLastError ⇒ Integer
private
Retrieves the last error code from the Windows API.
-
.GetModuleFileName(args = {}) ⇒ Hash
private
Retrieves the filename of a loaded module.
-
.GetTokenInformation(args) ⇒ Hash?
private
Retrieves information about an access token.
-
.GetVersionEx ⇒ Hash
private
Retrieves Windows OS version information.
-
.isXP? ⇒ Boolean
private
Checks whether the operating system is Windows XP or earlier.
-
.MessageBox(args) ⇒ Integer
private
Displays a message box dialog on Windows.
-
.OpenProcessToken(args) ⇒ Hash
private
Opens an access token associated with a process.
-
.RegCloseKey(args) ⇒ Integer
private
Closes a registry key handle.
-
.RegDeleteValue(args) ⇒ Integer
private
Deletes a registry value.
-
.RegOpenKeyEx(args) ⇒ Hash
private
Opens a registry key with extended options.
-
.RegQueryValueEx(args) ⇒ Hash
private
Queries a registry value, automatically converting to the appropriate Ruby type.
-
.RegSetValueEx(args) ⇒ Integer
private
Sets a registry value, converting from Ruby types to Windows registry format.
-
.ShellExecute(args) ⇒ Integer
private
Executes a file with basic shell options.
-
.ShellExecuteEx(args) ⇒ Hash
private
Executes a file with extended shell options (includes UAC elevation support).
Class Method Details
.admin? ⇒ 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.
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.
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.($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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
REG_SZ, REG_EXPAND_SZ, REG_LINK are returned as String; REG_MULTI_SZ as Array
Queries a registry value, automatically converting to the appropriate Ruby 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.
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.
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).
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 |