Module: PDK::Util::Windows::Process

Extended by:
FFI::Library, String
Defined in:
lib/pdk/util/windows/process.rb

Class Method Summary collapse

Methods included from String

wide_string

Methods included from FFI::Library

attach_function_private

Class Method Details

.environment_hashObject



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/pdk/util/windows/process.rb', line 11

def environment_hash
  env_ptr = GetEnvironmentStringsW()

  contains_unicode_replacement = lambda do |string|
    return false unless string.include?("\uFFFD")

    PDK.logger.warning "Discarding environment variable #{string} which contains invalid bytes"
    true
  end

  # pass :invalid => :replace to the Ruby String#encode to use replacement
  # characters
  pairs = env_ptr.read_arbitrary_wide_string_up_to(65_534, :double_null, invalid: :replace)
                 .split(?\x00)
                 .reject { |env_str| env_str.nil? || env_str.empty? || env_str[0] == '=' }
                 .reject { |env_str| contains_unicode_replacement.call(env_str) }
                 .map { |env_pair| env_pair.split('=', 2) }
  pairs.to_h
ensure
  PDK.logger.debug 'FreeEnvironmentStringsW memory leak' if env_ptr && !env_ptr.null? && (FreeEnvironmentStringsW(env_ptr) == PDK::Util::Windows::WIN32_FALSE)
end

.set_environment_variable(name, val) ⇒ Object

Raises:

  • (ArgumentError)


34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/pdk/util/windows/process.rb', line 34

def set_environment_variable(name, val)
  raise ArgumentError, 'Environment variable name must not be nil or empty' if name.nil? || name.empty?

  FFI::MemoryPointer.from_string_to_wide_string(name) do |name_ptr|
    if val.nil?
      raise format('Failed to remove environment variable: %{name}', name: name) if SetEnvironmentVariableW(name_ptr, FFI::MemoryPointer::NULL) == PDK::Util::Windows::WIN32_FALSE
    else
      FFI::MemoryPointer.from_string_to_wide_string(val) do |val_ptr|
        raise format('Failed to set environment variaible: %{name}', name: name) if SetEnvironmentVariableW(name_ptr, val_ptr) == PDK::Util::Windows::WIN32_FALSE
      end
    end
  end
end